static void mac802154_subif_rx(struct ieee802154_dev *hw, struct sk_buff *skb, u8 lqi) { struct mac802154_priv *priv = mac802154_to_priv(hw); mac_cb(skb)->lqi = lqi; skb->protocol = htons(ETH_P_IEEE802154); skb_reset_mac_header(skb); BUILD_BUG_ON(sizeof(struct ieee802154_mac_cb) > sizeof(skb->cb)); if (!(priv->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { u16 crc; if (skb->len < 2) { pr_debug("got invalid frame\n"); goto out; } crc = crc_ccitt(0, skb->data, skb->len); if (crc) { pr_debug("CRC mismatch\n"); goto out; } skb_trim(skb, skb->len - 2); /* CRC */ } mac802154_monitors_rx(priv, skb); out: dev_kfree_skb(skb); return; }
// handle_pcdata() testet, ob im Receive-Buffer Paket-Daten (auch unvollst.) liegen // und kopiert diese nach 'rxdatapaket' um. // Bei g�ltigen Paketen, wird 'handle_pc_paket()' // aufgerufen. void handle_pcdata(void) { int rxbytes, burst_cnt = 5; do { rxbytes = data_received(); if (rxbytes > 4) { // a frame shout be have D0 length and crc U16 length = 0; if (data_look_byte(0) != FRAMESTARTID) { data_flushrx(); // destroy garbage on COM/USB } else { length = data_look_word(1); if (length <= (sizeof(rxdatapacket)-5)) { if (length <= (rxbytes-5)) { data_copyrx(rxdatapacket.data, length+5); // data_flushrx(); // needed for buggy software, obsolete - using timeout } else // packet still in receiving (on slow serial) length = 0; } else { data_flushrx(); // incorrect packet length = 0; // remove all data from buffer } // fi incomplete } // esle if (length > 0) { // packet begins with a valid frame / FRAMESTARTID checked before U16 pkt_crc = 0; if (status_control&STA_CRCENABLE_MASK) { // check CRC only, if needed. pkt_crc = crc_ccitt(rxdatapacket.data, length+5); } // fi check CRC if (pkt_crc==0) handle_pc_paket(length); // crc correct } // fi payload } // fi was da } while ( (rxbytes > 4) && ((--burst_cnt)>0) ); }
static bool rt2800usb_check_crc(const u8 *data, const size_t len) { u16 fw_crc; u16 crc; /* * The last 2 bytes in the firmware array are the crc checksum itself, * this means that we should never pass those 2 bytes to the crc * algorithm. */ fw_crc = (data[len - 2] << 8 | data[len - 1]); /* * Use the crc ccitt algorithm. * This will return the same value as the legacy driver which * used bit ordering reversion on the both the firmware bytes * before input input as well as on the final output. * Obviously using crc ccitt directly is much more efficient. */ crc = crc_ccitt(~0, data, len - 2); /* * There is a small difference between the crc-itu-t + bitrev and * the crc-ccitt crc calculation. In the latter method the 2 bytes * will be swapped, use swab16 to convert the crc to the correct * value. */ crc = swab16(crc); return fw_crc == crc; }
/* * Returns: * <= 0: driver handled the data exchange * 1: driver doesn't especially handle, please do standard processing */ static int microread_im_transceive(struct nfc_hci_dev *hdev, struct nfc_target *target, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context) { struct microread_info *info = nfc_hci_get_clientdata(hdev); u8 control_bits; u16 crc; pr_info("data exchange to gate 0x%x\n", target->hci_reader_gate); if (target->hci_reader_gate == MICROREAD_GATE_ID_P2P_INITIATOR) { *skb_push(skb, 1) = 0; return nfc_hci_send_event(hdev, target->hci_reader_gate, MICROREAD_EVT_P2P_INITIATOR_EXCHANGE_TO_RF, skb->data, skb->len); } switch (target->hci_reader_gate) { case MICROREAD_GATE_ID_MREAD_ISO_A: control_bits = 0xCB; break; case MICROREAD_GATE_ID_MREAD_ISO_A_3: control_bits = 0xCB; break; case MICROREAD_GATE_ID_MREAD_ISO_B: control_bits = 0xCB; break; case MICROREAD_GATE_ID_MREAD_NFC_T1: control_bits = 0x1B; crc = crc_ccitt(0xffff, skb->data, skb->len); crc = ~crc; *skb_put(skb, 1) = crc & 0xff; *skb_put(skb, 1) = crc >> 8; break; case MICROREAD_GATE_ID_MREAD_NFC_T3: control_bits = 0xDB; break; default: pr_info("Abort im_transceive to invalid gate 0x%x\n", target->hci_reader_gate); return 1; } *skb_push(skb, 1) = control_bits; info->async_cb_type = MICROREAD_CB_TYPE_READER_ALL; info->async_cb = cb; info->async_cb_context = cb_context; return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, MICROREAD_CMD_MREAD_EXCHANGE, skb->data, skb->len, microread_im_transceive_cb, info); }
// convert human readable UID to 128 bit fdx-b binary array BOOL uid_to_hdx_bin(BYTE *bin, BYTE *uid) { BYTE tmp1[64], crc[8], i; unsigned int country, crctag; unsigned long long id; memset(tmp1, 0x00, 64); // set animal flag if(uid[0] == 'A') tmp1[0]= 0x01; else if(uid[0] != '0') return FALSE; // set data flag if(uid[1] == 'D') tmp1[15]= 0x01; else if(uid[1] != '0') return FALSE; // set country code - 4 hex digits -> 10 bits country= bcdtouint(uid + 2, 4); inttobinarray(tmp1 + 16, country, 10); // set national ID - 12 hex digits -> 38 bits id= bcdtoulonglong(uid + 6, 12); ulonglongtobinarray(tmp1 + 26, id, 38); // reverse binary string_reverse(tmp1, 64); // add header for over-the-air: 10 x 0x00 + 0x01 memset(bin, 0x00, 10); // every 9th bit is 0x01, but we can just fill the rest with 0x01 and overwrite memset(bin + 10, 0x01, 118); //data is 8 blocks of 8 bits, plus obfuscation bit for(i= 0 ; i < 8 ; ++i) memcpy(bin + 11 + i * 9, tmp1 + i * 8, 8); // calculate & append crc for 64 bits of data for(i= 0 ; i < 8 ; ++i) crc[i]= (BYTE) binarraytoint(tmp1 + i * 8, 8); crctag= crc_ccitt(crc, 8); inttobinarray(bin + 83, crctag >> 8, 8); inttobinarray(bin + 92, crctag, 8); // add trailer for(i= 0 ; i < 3 ; ++i) memset(bin + 101 + i * 9, 0x00, 8); return TRUE; }
static void nfc_shdlc_add_len_crc(struct sk_buff *skb) { u16 crc; int len; len = skb->len + 2; *skb_push(skb, 1) = len; crc = crc_ccitt(0xffff, skb->data, skb->len); crc = ~crc; *skb_put(skb, 1) = crc & 0xff; *skb_put(skb, 1) = crc >> 8; }
int crc_testRun(void) { char vector[9] = "123456789"; uint16_t crc = CRC_CCITT_INIT_VAL; crc = crc_ccitt(crc, vector, sizeof(vector)); kprintf("crc_ccitt [%04X]\n", crc); ASSERT(crc == 0x6F91); crc = CRC16_INIT_VAL; crc = crc16(crc, vector, sizeof(vector)); kprintf("crc16 [%04X]\n", crc); ASSERT(crc == 0x31C3); return 0; }
static void subcode_toc(struct burn_drive *d, int mode, unsigned char *data) { unsigned char *q; int track; int crc; int min, sec, frame; track = d->toc_temp / 3; memset(data, 0, 96); q = data + 12; burn_lba_to_msf(d->rlba, &min, &sec, &frame); /*XXX track numbers are BCD a0 - 1st track ctrl a1 - last track ctrl a2 - lout ctrl */ q[0] = (d->toc_entry[track].control << 4) + 1; q[1] = 0; if (d->toc_entry[track].point < 100) q[2] = dec_to_bcd(d->toc_entry[track].point); else q[2] = d->toc_entry[track].point; q[3] = dec_to_bcd(min); q[4] = dec_to_bcd(sec); q[5] = dec_to_bcd(frame); q[6] = 0; q[7] = dec_to_bcd(d->toc_entry[track].pmin); q[8] = dec_to_bcd(d->toc_entry[track].psec); q[9] = dec_to_bcd(d->toc_entry[track].pframe); #ifdef Libburn_no_crc_C crc = 0; /* dummy */ #else crc = crc_ccitt(q, 10); #endif q[10] = crc >> 8; q[11] = crc & 0xFF; d->toc_temp++; d->toc_temp %= (d->toc_entries * 3); }
static netdev_tx_t ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb) { struct net_device *dev = skb->dev; int ret; if (!(local->hw.flags & IEEE802154_HW_TX_OMIT_CKSUM)) { u16 crc = crc_ccitt(0, skb->data, skb->len); put_unaligned_le16(crc, skb_put(skb, 2)); } if (skb_cow_head(skb, local->hw.extra_tx_headroom)) goto err_tx; /* Stop the netif queue on each sub_if_data object. */ ieee802154_stop_queue(&local->hw); /* async is priority, otherwise sync is fallback */ if (local->ops->xmit_async) { ret = drv_xmit_async(local, skb); if (ret) { ieee802154_wake_queue(&local->hw); goto err_tx; } dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; } else { local->tx_skb = skb; queue_work(local->workqueue, &local->tx_work); } return NETDEV_TX_OK; err_tx: kfree_skb(skb); return NETDEV_TX_OK; }
// convert 32 hex digit/128 bit FDXB ID to 64 bit raw UID // safe to do in-place as we use a scratchpad BOOL hdx_hex_to_bin(BYTE *response, BYTE *fdxb) { BYTE i, crc_check[8], trailer[9]= {0,0,0,0,0,0,0,0,1}, tmp[128]; unsigned int crctag; hextobinarray(tmp, fdxb); // check header - should be 10 x 0x00 + 0x01 for(i= 0 ; i < 10 ; ++i) if(tmp[i] != 0x00) return FALSE; if(tmp[10] != 0x01) return FALSE; // check CRC // calculate crc for 64 bits of data (8 blocks of 8 plus obfuscation bit) for(i= 0 ; i < 8 ; ++i) crc_check[i]= (BYTE) binarraytoint(tmp + 11 + i * 9, 8); // stored crc (2 x 8 + 1) is at offset 83 (11 + 64 + 8) crctag= binarraytoint(tmp + 83, 8) << 8; crctag += binarraytoint(tmp + 92, 8); if (crctag != crc_ccitt(crc_check, 8)) return FALSE; // check trailer - '000000001' x 3 at offset 101 for(i= 0 ; i < 3 ; ++i) if(memcmp(tmp + 101 + i * 9, trailer, 9) != 0) return FALSE; // data is 8 blocks of 8 bits, plus obfuscation bit so check and strip every 9th bit for(i= 0 ; i < 8 ; ++i) { if(tmp[11 + ((i + 1) * 9) - 1] != 0x01) return FALSE; memcpy(response + i * 8, tmp + 11 + (i * 9), 8); } return TRUE; }
static int rt2800pci_check_firmware(struct rt2x00_dev *rt2x00dev, const u8 *data, const size_t len) { u16 fw_crc; u16 crc; /* * Only support 8kb firmware files. */ if (len != 8192) return FW_BAD_LENGTH; /* * The last 2 bytes in the firmware array are the crc checksum itself, * this means that we should never pass those 2 bytes to the crc * algorithm. */ fw_crc = (data[len - 2] << 8 | data[len - 1]); /* * Use the crc ccitt algorithm. * This will return the same value as the legacy driver which * used bit ordering reversion on the both the firmware bytes * before input input as well as on the final output. * Obviously using crc ccitt directly is much more efficient. */ crc = crc_ccitt(~0, data, len - 2); /* * There is a small difference between the crc-itu-t + bitrev and * the crc-ccitt crc calculation. In the latter method the 2 bytes * will be swapped, use swab16 to convert the crc to the correct * value. */ crc = swab16(crc); return (fw_crc == crc) ? FW_OK : FW_BAD_CRC; }
int nci_spi_send(struct nci_spi *nspi, struct completion *write_handshake_completion, struct sk_buff *skb) { unsigned int payload_len = skb->len; unsigned char *hdr; int ret; long completion_rc; /* add the NCI SPI header to the start of the buffer */ hdr = skb_push(skb, NCI_SPI_HDR_LEN); hdr[0] = NCI_SPI_DIRECT_WRITE; hdr[1] = nspi->acknowledge_mode; hdr[2] = payload_len >> 8; hdr[3] = payload_len & 0xFF; if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED) { u16 crc; crc = crc_ccitt(CRC_INIT, skb->data, skb->len); *skb_put(skb, 1) = crc >> 8; *skb_put(skb, 1) = crc & 0xFF; }
static void subcode_lout(struct burn_write_opts *o, unsigned char control, unsigned char *data) { struct burn_drive *d = o->drive; unsigned char *q; int crc; int rmin, min, rsec, sec, rframe, frame; memset(data, 0, 96); q = data + 12; burn_lba_to_msf(d->alba, &min, &sec, &frame); burn_lba_to_msf(d->rlba, &rmin, &rsec, &rframe); if (((rmin == 0) && (rsec == 0) && (rframe == 0)) || ((rsec >= 2) && !((rframe / 19) % 2))) memset(data, 0xFF, 12); q[0] = (control << 4) + 1; q[1] = 0xAA; q[2] = 0x01; q[3] = dec_to_bcd(rmin); q[4] = dec_to_bcd(rsec); q[5] = dec_to_bcd(rframe); q[6] = 0; q[7] = dec_to_bcd(min); q[8] = dec_to_bcd(sec); q[9] = dec_to_bcd(frame); #ifdef Libburn_no_crc_C crc = 0; /* dummy */ #else crc = crc_ccitt(q, 10); #endif q[10] = crc >> 8; q[11] = crc & 0xFF; }
int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) { struct p54_common *priv = dev->priv; struct eeprom_pda_wrap *wrap; struct pda_entry *entry; unsigned int data_len, entry_len; void *tmp; int err; u8 *end = (u8 *)eeprom + len; u16 synth = 0; u16 crc16 = ~0; wrap = (struct eeprom_pda_wrap *) eeprom; entry = (void *)wrap->data + le16_to_cpu(wrap->len); /* verify that at least the entry length/code fits */ while ((u8 *)entry <= end - sizeof(*entry)) { entry_len = le16_to_cpu(entry->len); data_len = ((entry_len - 1) << 1); /* abort if entry exceeds whole structure */ if ((u8 *)entry + sizeof(*entry) + data_len > end) break; switch (le16_to_cpu(entry->code)) { case PDR_MAC_ADDRESS: if (data_len != ETH_ALEN) break; SET_IEEE80211_PERM_ADDR(dev, entry->data); break; case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS: if (priv->output_limit) break; err = p54_convert_output_limits(dev, entry->data, data_len); if (err) goto err; break; case PDR_PRISM_PA_CAL_CURVE_DATA: { struct pda_pa_curve_data *curve_data = (struct pda_pa_curve_data *)entry->data; if (data_len < sizeof(*curve_data)) { err = -EINVAL; goto err; } switch (curve_data->cal_method_rev) { case 0: err = p54_convert_rev0(dev, curve_data); break; case 1: err = p54_convert_rev1(dev, curve_data); break; default: wiphy_err(dev->wiphy, "unknown curve data revision %d\n", curve_data->cal_method_rev); err = -ENODEV; break; } if (err) goto err; } break; case PDR_PRISM_ZIF_TX_IQ_CALIBRATION: priv->iq_autocal = kmemdup(entry->data, data_len, GFP_KERNEL); if (!priv->iq_autocal) { err = -ENOMEM; goto err; } priv->iq_autocal_len = data_len / sizeof(struct pda_iq_autocal_entry); break; case PDR_DEFAULT_COUNTRY: p54_parse_default_country(dev, entry->data, data_len); break; case PDR_INTERFACE_LIST: tmp = entry->data; while ((u8 *)tmp < entry->data + data_len) { struct exp_if *exp_if = tmp; if (exp_if->if_id == cpu_to_le16(IF_ID_ISL39000)) synth = le16_to_cpu(exp_if->variant); tmp += sizeof(*exp_if); } break; case PDR_HARDWARE_PLATFORM_COMPONENT_ID: if (data_len < 2) break; priv->version = *(u8 *)(entry->data + 1); break; case PDR_RSSI_LINEAR_APPROXIMATION: case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND: case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED: err = p54_parse_rssical(dev, entry->data, data_len, le16_to_cpu(entry->code)); if (err) goto err; break; case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2: { struct pda_custom_wrapper *pda = (void *) entry->data; __le16 *src; u16 *dst; int i; if (priv->rssi_db || data_len < sizeof(*pda)) break; priv->rssi_db = p54_convert_db(pda, data_len); if (!priv->rssi_db) break; src = (void *) priv->rssi_db->data; dst = (void *) priv->rssi_db->data; for (i = 0; i < priv->rssi_db->entries; i++) *(dst++) = (s16) le16_to_cpu(*(src++)); } break; case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: { struct pda_custom_wrapper *pda = (void *) entry->data; if (priv->output_limit || data_len < sizeof(*pda)) break; priv->output_limit = p54_convert_db(pda, data_len); } break; case PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM: { struct pda_custom_wrapper *pda = (void *) entry->data; if (priv->curve_data || data_len < sizeof(*pda)) break; priv->curve_data = p54_convert_db(pda, data_len); } break; case PDR_END: crc16 = ~crc_ccitt(crc16, (u8 *) entry, sizeof(*entry)); if (crc16 != le16_to_cpup((__le16 *)entry->data)) { wiphy_err(dev->wiphy, "eeprom failed checksum " "test!\n"); err = -ENOMSG; goto err; } else { goto good_eeprom; } break; default: break; } crc16 = crc_ccitt(crc16, (u8 *)entry, (entry_len + 1) * 2); entry = (void *)entry + (entry_len + 1) * 2; } wiphy_err(dev->wiphy, "unexpected end of eeprom data.\n"); err = -ENODATA; goto err; good_eeprom: if (!synth || !priv->iq_autocal || !priv->output_limit || !priv->curve_data) { wiphy_err(dev->wiphy, "not all required entries found in eeprom!\n"); err = -EINVAL; goto err; } err = p54_generate_channel_lists(dev); if (err) goto err; priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK; if (priv->rxhw == PDR_SYNTH_FRONTEND_XBOW) p54_init_xbow_synth(priv); if (!(synth & PDR_SYNTH_24_GHZ_DISABLED)) dev->wiphy->bands[IEEE80211_BAND_2GHZ] = priv->band_table[IEEE80211_BAND_2GHZ]; if (!(synth & PDR_SYNTH_5_GHZ_DISABLED)) dev->wiphy->bands[IEEE80211_BAND_5GHZ] = priv->band_table[IEEE80211_BAND_5GHZ]; if ((synth & PDR_SYNTH_RX_DIV_MASK) == PDR_SYNTH_RX_DIV_SUPPORTED) priv->rx_diversity_mask = 3; if ((synth & PDR_SYNTH_TX_DIV_MASK) == PDR_SYNTH_TX_DIV_SUPPORTED) priv->tx_diversity_mask = 3; if (!is_valid_ether_addr(dev->wiphy->perm_addr)) { u8 perm_addr[ETH_ALEN]; wiphy_warn(dev->wiphy, "Invalid hwaddr! Using randomly generated MAC addr\n"); random_ether_addr(perm_addr); SET_IEEE80211_PERM_ADDR(dev, perm_addr); } priv->cur_rssi = &p54_rssi_default; wiphy_info(dev->wiphy, "hwaddr %pM, MAC:isl38%02x RF:%s\n", dev->wiphy->perm_addr, priv->version, p54_rf_chips[priv->rxhw]); return 0; err: kfree(priv->iq_autocal); kfree(priv->output_limit); kfree(priv->curve_data); kfree(priv->rssi_db); priv->iq_autocal = NULL; priv->output_limit = NULL; priv->curve_data = NULL; priv->rssi_db = NULL; wiphy_err(dev->wiphy, "eeprom parse failed!\n"); return err; }
void subcode_user(struct burn_write_opts *o, unsigned char *subcodes, unsigned char tno, unsigned char control, unsigned char indx, struct isrc *isrc, int psub) { struct burn_drive *d = o->drive; unsigned char *p, *q; int crc; int m, s, f, c, qmode; /* 1, 2 or 3 */ memset(subcodes, 0, 96); p = subcodes; if ((tno == 1) && (d->rlba == -150)) memset(p, 0xFF, 12); if (psub) memset(p, 0xFF, 12); q = subcodes + 12; qmode = 1; /* every 1 in 10 we can do something different */ if (d->rlba % 10 == 0) { /* each of these can occur 1 in 100 */ if ((d->rlba / 10) % 10 == 0) { if (o->has_mediacatalog) qmode = 2; } else if ((d->rlba / 10) % 10 == 1) { if (isrc && isrc->has_isrc) qmode = 3; } } /* ts A61010 : this cannot happen. Assert for fun ? */ /* a ssert(qmode == 1 || qmode == 2 || qmode == 3); */ switch (qmode) { case 1: q[1] = dec_to_bcd(tno); /* track number */ q[2] = dec_to_bcd(indx); /* index XXX read this shit from the track array */ burn_lba_to_msf(d->rlba, &m, &s, &f); q[3] = dec_to_bcd(m); /* rel min */ q[4] = dec_to_bcd(s); /* rel sec */ q[5] = dec_to_bcd(f); /* rel frame */ q[6] = 0; /* zero */ burn_lba_to_msf(d->alba, &m, &s, &f); q[7] = dec_to_bcd(m); /* abs min */ q[8] = dec_to_bcd(s); /* abs sec */ q[9] = dec_to_bcd(f); /* abs frame */ break; case 2: /* media catalog number */ q[1] = (o->mediacatalog[0] << 4) + o->mediacatalog[1]; q[2] = (o->mediacatalog[2] << 4) + o->mediacatalog[3]; q[3] = (o->mediacatalog[4] << 4) + o->mediacatalog[5]; q[4] = (o->mediacatalog[6] << 4) + o->mediacatalog[7]; q[5] = (o->mediacatalog[8] << 4) + o->mediacatalog[9]; q[6] = (o->mediacatalog[10] << 4) + o->mediacatalog[11]; q[7] = o->mediacatalog[12] << 4; q[8] = 0; burn_lba_to_msf(d->alba, &m, &s, &f); q[9] = dec_to_bcd(f); /* abs frame */ break; case 3: c = char_to_isrc(isrc->country[0]); /* top 6 bits of [1] is the first country code */ q[1] = c << 2; c = char_to_isrc(isrc->country[1]); /* bottom 2 bits of [1] is part of the second country code */ q[1] += (c >> 4); /* top 4 bits if [2] is the rest of the second country code */ q[2] = c << 4; c = char_to_isrc(isrc->owner[0]); /* bottom 4 bits of [2] is part of the first owner code */ q[2] += (c >> 2); /* top 2 bits of [3] is the rest of the first owner code */ q[3] = c << 6; c = char_to_isrc(isrc->owner[1]); /* bottom 6 bits of [3] is the entire second owner code */ q[3] += c; c = char_to_isrc(isrc->owner[2]); /* top 6 bits of [4] are the third owner code */ q[4] = c << 2; /* [5] is the year in 2 BCD numbers */ q[5] = dec_to_bcd(isrc->year % 100); /* [6] is the first 2 digits in the serial */ q[6] = dec_to_bcd(isrc->serial % 100); /* [7] is the next 2 digits in the serial */ q[7] = dec_to_bcd((isrc->serial / 100) % 100); /* the top 4 bits of [8] is the last serial digit, the rest is zeros */ q[8] = dec_to_bcd((isrc->serial / 10000) % 10) << 4; burn_lba_to_msf(d->alba, &m, &s, &f); q[9] = dec_to_bcd(f); /* abs frame */ break; } q[0] = (control << 4) + qmode; #ifdef Libburn_no_crc_C crc = 0; /* dummy */ #else crc = crc_ccitt(q, 10); #endif q[10] = crc >> 8; q[11] = crc & 0xff; }
static const struct firmware *rtmp_get_firmware(struct rt_rtmp_adapter *adapter) { const char *name; const struct firmware *fw = NULL; u8 min_version; struct device *dev; int err; if (adapter->firmware) return adapter->firmware; #ifdef RTMP_MAC_USB if (IS_RT3071(adapter)) { name = FIRMWARE_3071_FILENAME; min_version = FIRMWARE_3071_MIN_VERSION; } else if (IS_RT3070(adapter)) { name = FIRMWARE_3070_FILENAME; min_version = FIRMWARE_3070_MIN_VERSION; } else { name = FIRMWARE_2870_FILENAME; min_version = FIRMWARE_2870_MIN_VERSION; } dev = &((struct os_cookie *)adapter->OS_Cookie)->pUsb_Dev->dev; #else /* RTMP_MAC_PCI */ if (IS_RT3090(adapter) || IS_RT3390(adapter)) { name = FIRMWARE_3090_FILENAME; min_version = FIRMWARE_3090_MIN_VERSION; } else { name = FIRMWARE_2860_FILENAME; min_version = FIRMWARE_2860_MIN_VERSION; } dev = &((struct os_cookie *)adapter->OS_Cookie)->pci_dev->dev; #endif err = request_firmware(&fw, name, dev); if (err) { dev_err(dev, "firmware file %s request failed (%d)\n", name, err); return NULL; } if (fw->size < FIRMWAREIMAGE_LENGTH) { dev_err(dev, "firmware file %s size is invalid\n", name); goto invalid; } /* is it new enough? */ adapter->FirmwareVersion = fw->data[FIRMWAREIMAGE_LENGTH - 3]; if (adapter->FirmwareVersion < min_version) { dev_err(dev, "firmware file %s is too old;" " driver requires v%d or later\n", name, min_version); goto invalid; } /* is the internal CRC correct? */ if (crc_ccitt(0xffff, fw->data, FIRMWAREIMAGE_LENGTH - 2) != (fw->data[FIRMWAREIMAGE_LENGTH - 2] | (fw->data[FIRMWAREIMAGE_LENGTH - 1] << 8))) { dev_err(dev, "firmware file %s failed internal CRC\n", name); goto invalid; } adapter->firmware = fw; return fw; invalid: release_firmware(fw); return NULL; }