⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rt2500usb.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 4 页
字号:
{	u16 reg;	u16 reg2;	unsigned int i;	char put_to_sleep;	char bbp_state;	char rf_state;	put_to_sleep = (state != STATE_AWAKE);	reg = 0;	rt2x00_set_field16(&reg, MAC_CSR17_BBP_DESIRE_STATE, state);	rt2x00_set_field16(&reg, MAC_CSR17_RF_DESIRE_STATE, state);	rt2x00_set_field16(&reg, MAC_CSR17_PUT_TO_SLEEP, put_to_sleep);	rt2500usb_register_write(rt2x00dev, MAC_CSR17, reg);	rt2x00_set_field16(&reg, MAC_CSR17_SET_STATE, 1);	rt2500usb_register_write(rt2x00dev, MAC_CSR17, reg);	/*	 * Device is not guaranteed to be in the requested state yet.	 * We must wait until the register indicates that the	 * device has entered the correct state.	 */	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {		rt2500usb_register_read(rt2x00dev, MAC_CSR17, &reg2);		bbp_state = rt2x00_get_field16(reg2, MAC_CSR17_BBP_CURR_STATE);		rf_state = rt2x00_get_field16(reg2, MAC_CSR17_RF_CURR_STATE);		if (bbp_state == state && rf_state == state)			return 0;		rt2500usb_register_write(rt2x00dev, MAC_CSR17, reg);		msleep(30);	}	NOTICE(rt2x00dev, "Device failed to enter state %d, "	       "current device state: bbp %d and rf %d.\n",	       state, bbp_state, rf_state);	return -EBUSY;}static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev,				      enum dev_state state){	int retval = 0;	switch (state) {	case STATE_RADIO_ON:		retval = rt2500usb_enable_radio(rt2x00dev);		break;	case STATE_RADIO_OFF:		rt2500usb_disable_radio(rt2x00dev);		break;	case STATE_RADIO_RX_ON:	case STATE_RADIO_RX_OFF:		rt2500usb_toggle_rx(rt2x00dev, state);		break;	case STATE_DEEP_SLEEP:	case STATE_SLEEP:	case STATE_STANDBY:	case STATE_AWAKE:		retval = rt2500usb_set_state(rt2x00dev, state);		break;	default:		retval = -ENOTSUPP;		break;	}	return retval;}/* * TX descriptor initialization */static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,				    struct data_desc *txd,				    struct txdata_entry_desc *desc,				    struct ieee80211_hdr *ieee80211hdr,				    unsigned int length,				    struct ieee80211_tx_control *control){	u32 word;	/*	 * Start writing the descriptor words.	 */	rt2x00_desc_read(txd, 1, &word);	rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER);	rt2x00_set_field32(&word, TXD_W1_AIFS, desc->aifs);	rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min);	rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max);	rt2x00_desc_write(txd, 1, word);	rt2x00_desc_read(txd, 2, &word);	rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal);	rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service);	rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low);	rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, desc->length_high);	rt2x00_desc_write(txd, 2, word);	rt2x00_desc_read(txd, 0, &word);	rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, control->retry_limit);	rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,			   test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags));	rt2x00_set_field32(&word, TXD_W0_ACK,			   !(control->flags & IEEE80211_TXCTL_NO_ACK));	rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags));	rt2x00_set_field32(&word, TXD_W0_OFDM,			   test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags));	rt2x00_set_field32(&word, TXD_W0_NEW_SEQ,			   !!(control->flags & IEEE80211_TXCTL_FIRST_FRAGMENT));	rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs);	rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, length);	rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE);	rt2x00_desc_write(txd, 0, word);}static int rt2500usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev,				     struct sk_buff *skb){	int length;	/*	 * The length _must_ be a multiple of 2,	 * but it must _not_ be a multiple of the USB packet size.	 */	length = roundup(skb->len, 2);	length += (2 * !(length % rt2x00dev->usb_maxpacket));	return length;}/* * TX data initialization */static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,				    unsigned int queue){	u16 reg;	if (queue != IEEE80211_TX_QUEUE_BEACON)		return;	rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg);	if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) {		rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 1);		/*		 * Beacon generation will fail initially.		 * To prevent this we need to register the TXRX_CSR19		 * register several times.		 */		rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);		rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0);		rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);		rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0);		rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);	}}/* * RX control handlers */static void rt2500usb_fill_rxdone(struct data_entry *entry,				  struct rxdata_entry_desc *desc){	struct urb *urb = entry->priv;	struct data_desc *rxd = (struct data_desc *)(entry->skb->data +						     (urb->actual_length -						      entry->ring->desc_size));	u32 word0;	u32 word1;	rt2x00_desc_read(rxd, 0, &word0);	rt2x00_desc_read(rxd, 1, &word1);	desc->flags = 0;	if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))		desc->flags |= RX_FLAG_FAILED_FCS_CRC;	if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR))		desc->flags |= RX_FLAG_FAILED_PLCP_CRC;	/*	 * Obtain the status about this packet.	 */	desc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL);	desc->rssi = rt2x00_get_field32(word1, RXD_W1_RSSI) -	    entry->ring->rt2x00dev->rssi_offset;	desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);	desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);	return;}/* * Interrupt functions. */static void rt2500usb_beacondone(struct urb *urb){	struct data_entry *entry = (struct data_entry *)urb->context;	struct data_ring *ring = entry->ring;	if (!test_bit(DEVICE_ENABLED_RADIO, &ring->rt2x00dev->flags))		return;	/*	 * Check if this was the guardian beacon,	 * if that was the case we need to send the real beacon now.	 * Otherwise we should free the sk_buffer, the device	 * should be doing the rest of the work now.	 */	if (ring->index == 1) {		rt2x00_ring_index_done_inc(ring);		entry = rt2x00_get_data_entry(ring);		usb_submit_urb(entry->priv, GFP_ATOMIC);		rt2x00_ring_index_inc(ring);	} else if (ring->index_done == 1) {		entry = rt2x00_get_data_entry_done(ring);		if (entry->skb) {			dev_kfree_skb(entry->skb);			entry->skb = NULL;		}		rt2x00_ring_index_done_inc(ring);	}}/* * Device probe functions. */static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev){	u16 word;	u8 *mac;	rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, EEPROM_SIZE);	/*	 * Start validation of the data that has been read.	 */	mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);	if (!is_valid_ether_addr(mac)) {		DECLARE_MAC_BUF(macbuf);		random_ether_addr(mac);		EEPROM(rt2x00dev, "MAC: %s\n", print_mac(macbuf, mac));	}	rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);	if (word == 0xffff) {		rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2);		rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, 0);		rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, 0);		rt2x00_set_field16(&word, EEPROM_ANTENNA_LED_MODE, 0);		rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0);		rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0);		rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2522);		rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);		EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word);	}	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word);	if (word == 0xffff) {		rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0);		rt2x00_set_field16(&word, EEPROM_NIC_DYN_BBP_TUNE, 0);		rt2x00_set_field16(&word, EEPROM_NIC_CCK_TX_POWER, 0);		rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word);		EEPROM(rt2x00dev, "NIC: 0x%04x\n", word);	}	rt2x00_eeprom_read(rt2x00dev, EEPROM_CALIBRATE_OFFSET, &word);	if (word == 0xffff) {		rt2x00_set_field16(&word, EEPROM_CALIBRATE_OFFSET_RSSI,				   DEFAULT_RSSI_OFFSET);		rt2x00_eeprom_write(rt2x00dev, EEPROM_CALIBRATE_OFFSET, word);		EEPROM(rt2x00dev, "Calibrate offset: 0x%04x\n", word);	}	rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE, &word);	if (word == 0xffff) {		rt2x00_set_field16(&word, EEPROM_BBPTUNE_THRESHOLD, 45);		rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE, word);		EEPROM(rt2x00dev, "BBPtune: 0x%04x\n", word);	}	rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &word);	if (word == 0xffff) {		rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCUPPER, 0x40);		rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word);		EEPROM(rt2x00dev, "BBPtune vgc: 0x%04x\n", word);	}	rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R17, &word);	if (word == 0xffff) {		rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_LOW, 0x48);		rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_HIGH, 0x41);		rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R17, word);		EEPROM(rt2x00dev, "BBPtune r17: 0x%04x\n", word);	}	rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &word);	if (word == 0xffff) {		rt2x00_set_field16(&word, EEPROM_BBPTUNE_R24_LOW, 0x40);		rt2x00_set_field16(&word, EEPROM_BBPTUNE_R24_HIGH, 0x80);		rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R24, word);		EEPROM(rt2x00dev, "BBPtune r24: 0x%04x\n", word);	}	rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R25, &word);	if (word == 0xffff) {		rt2x00_set_field16(&word, EEPROM_BBPTUNE_R25_LOW, 0x40);		rt2x00_set_field16(&word, EEPROM_BBPTUNE_R25_HIGH, 0x50);		rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R25, word);		EEPROM(rt2x00dev, "BBPtune r25: 0x%04x\n", word);	}	rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R61, &word);	if (word == 0xffff) {		rt2x00_set_field16(&word, EEPROM_BBPTUNE_R61_LOW, 0x60);		rt2x00_set_field16(&word, EEPROM_BBPTUNE_R61_HIGH, 0x6d);		rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R61, word);		EEPROM(rt2x00dev, "BBPtune r61: 0x%04x\n", word);	}	return 0;}static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev){	u16 reg;	u16 value;	u16 eeprom;	/*	 * Read EEPROM word for configuration.	 */	rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);	/*	 * Identify RF chipset.	 */	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);	rt2500usb_register_read(rt2x00dev, MAC_CSR0, &reg);	rt2x00_set_chip(rt2x00dev, RT2570, value, reg);	if (!rt2x00_check_rev(&rt2x00dev->chip, 0)) {		ERROR(rt2x00dev, "Invalid RT chipset detected.\n");		return -ENODEV;	}	if (!rt2x00_rf(&rt2x00dev->chip, RF2522) &&	    !rt2x00_rf(&rt2x00dev->chip, RF2523) &&	    !rt2x00_rf(&rt2x00dev->chip, RF2524) &&	    !rt2x00_rf(&rt2x00dev->chip, RF2525) &&	    !rt2x00_rf(&rt2x00dev->chip, RF2525E) &&	    !rt2x00_rf(&rt2x00dev->chip, RF5222)) {		ERROR(rt2x00dev, "Invalid RF chipset detected.\n");		return -ENODEV;	}	/*	 * Identify default antenna configuration.	 */	rt2x00dev->hw->conf.antenna_sel_tx =	    rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT);	rt2x00dev->hw->conf.antenna_sel_rx =	    rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT);	/*	 * Store led mode, for correct led behaviour.	 */	rt2x00dev->led_mode =	    rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);	/*	 * Check if the BBP tuning should be disabled.	 */	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);	if (rt2x00_get_field16(eeprom, EEPROM_NIC_DYN_BBP_TUNE))		__set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags);	/*	 * Read the RSSI <-> dBm offset information.	 */	rt2x00_eeprom_read(rt2x00dev, EEPROM_CALIBRATE_OFFSET, &eeprom);	rt2x00dev->rssi_offset =	    rt2x00_get_field16(eeprom, EEPROM_CALIBRATE_OFFSET_RSSI);	return 0;}/* * RF value list for RF2522 * Supports: 2.4 GHz */static const struct rf_channel rf_vals_bg_2522[] = {	{ 1,  0x00002050, 0x000c1fda, 0x00000101, 0 },	{ 2,  0x00002050, 0x000c1fee, 0x00000101, 0 },	{ 3,  0x00002050, 0x000c2002, 0x00000101, 0 },	{ 4,  0x00002050, 0x000c2016, 0x00000101, 0 },	{ 5,  0x00002050, 0x000c202a, 0x00000101, 0 },	{ 6,  0x00002050, 0x000c203e, 0x00000101, 0 },	{ 7,  0x00002050, 0x000c2052, 0x00000101, 0 },	{ 8,  0x00002050, 0x000c2066, 0x00000101, 0 },	{ 9,  0x00002050, 0x000c207a, 0x00000101, 0 },	{ 10, 0x00002050, 0x000c208e, 0x00000101, 0 },	{ 11, 0x00002050, 0x000c20a2, 0x00000101, 0 },	{ 12, 0x00002050, 0x000c20b6, 0x00000101, 0 },	{ 13, 0x00002050, 0x000c20ca, 0x00000101, 0 },	{ 14, 0x00002050, 0x000c20fa, 0x00000101, 0 },};/* * RF value list for RF2523 * Supports: 2.4 GHz */static const struct rf_channel rf_vals_bg_2523[] = {	{ 1,  0x00022010, 0x00000c9e, 0x000e0111, 0x00000a1b },	{ 2,  0x00022010, 0x00000ca2, 0x000e0111, 0x00000a1b },	{ 3,  0x00022010, 0x00000ca6, 0x000e0111, 0x00000a1b },	{ 4,  0x00022010, 0x00000caa, 0x000e0111, 0x00000a1b },	{ 5,  0x00022010, 0x00000cae, 0x000e0111, 0x00000a1b },	{ 6,  0x00022010, 0x00000cb2, 0x000e0111, 0x00000a1b },	{ 7,  0x00022010, 0x00000cb6, 0x000e0111, 0x00000a1b },	{ 8,  0x00022010, 0x00000cba, 0x000e0111, 0x00000a1b },	{ 9,  0x00022010, 0x00000cbe, 0x000e0111, 0x00000a1b },	{ 10, 0x00022010, 0x00000d02, 0x000e0111, 0x00000a1b },	{ 11, 0x00022010, 0x00000d06, 0x000e0111, 0x00000a1b },	{ 12, 0x00022010, 0x00000d0a, 0x000e0111, 0x00000a1b },	{ 13, 0x00022010, 0x00000d0e, 0x000e0111, 0x00000a1b },	{ 14, 0x00022010, 0x00000d1a, 0x000e0111, 0x00000a03 },};/* * RF value list for RF2524 * Supports: 2.4 GHz */static const struct rf_channel rf_vals_bg_2524[] = {	{ 1,  0x00032020, 0x00000c9e, 0x00000101, 0x00000a1b },	{ 2,  0x00032020, 0x00000ca2, 0x00000101, 0x00000a1b },	{ 3,  0x00032020, 0x00000ca6, 0x00000101, 0x00000a1b },	{ 4,  0x00032020, 0x00000caa, 0x00000101, 0x00000a1b },	{ 5,  0x00032020, 0x00000cae, 0x00000101, 0x00000a1b },	{ 6,  0x00032020, 0x00000cb2, 0x00000101, 0x00000a1b },	{ 7,  0x00032020, 0x00000cb6, 0x00000101, 0x00000a1b },	{ 8,  0x00032020, 0x00000cba, 0x00000101, 0x00000a1b },	{ 9,  0x00032020, 0x00000cbe, 0x00000101, 0x00000a1b },	{ 10, 0x00032020, 0x00000d02, 0x00000101, 0x00000a1b },	{ 11, 0x00032020, 0x00000d06, 0x00000101, 0x00000a1b },	{ 12, 0x00032020, 0x00000d0a, 0x00000101, 0x00000a1b },	{ 13, 0x00032020, 0x00000d0e, 0x00000101, 0x00000a1b },	{ 14, 0x00032020, 0x00000d1a, 0x00000101, 0x00000a03 },};/* * RF value list for RF2525 * Supports: 2.4 GHz */static const struct rf_channel rf_vals_bg_2525[] = {	{ 1,  0x00022020, 0x00080c9e, 0x00060111, 0x00000a1b },

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -