Пример #1
0
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;
}
Пример #2
0
// 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) );
}
Пример #3
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;
}
Пример #4
0
/*
 * 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);
}
Пример #5
0
// 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;
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
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);
}
Пример #9
0
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;
}
Пример #10
0
// 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;
}
Пример #11
0
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;
}
Пример #12
0
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;
	}
Пример #13
0
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;
}
Пример #14
0
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;
}
Пример #15
0
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;
}
Пример #16
0
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;
}