📄 rt2500usb.c
字号:
{ 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(®, MAC_CSR17_BBP_DESIRE_STATE, state); rt2x00_set_field16(®, MAC_CSR17_RF_DESIRE_STATE, state); rt2x00_set_field16(®, MAC_CSR17_PUT_TO_SLEEP, put_to_sleep); rt2500usb_register_write(rt2x00dev, MAC_CSR17, reg); rt2x00_set_field16(®, 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, ®2); 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, ®); if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) { rt2x00_set_field16(®, 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, ®); 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 + -