diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00')
29 files changed, 485 insertions, 418 deletions
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index 4396d4b9bfb..6f383cd684b 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig @@ -53,51 +53,41 @@ config RT61PCI When compiled as a module, this driver will be called rt61pci. -config RT2800PCI_PCI - boolean - depends on PCI - default y - -config RT2800PCI_SOC - boolean - depends on RALINK_RT288X || RALINK_RT305X - default y - config RT2800PCI - tristate "Ralink rt28xx/rt30xx/rt35xx (PCI/PCIe/PCMCIA) support (EXPERIMENTAL)" - depends on (RT2800PCI_PCI || RT2800PCI_SOC) && EXPERIMENTAL + tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support" + depends on PCI || RALINK_RT288X || RALINK_RT305X select RT2800_LIB - select RT2X00_LIB_PCI if RT2800PCI_PCI - select RT2X00_LIB_SOC if RT2800PCI_SOC + select RT2X00_LIB_PCI if PCI + select RT2X00_LIB_SOC if RALINK_RT288X || RALINK_RT305X select RT2X00_LIB_HT select RT2X00_LIB_FIRMWARE select RT2X00_LIB_CRYPTO select CRC_CCITT select EEPROM_93CX6 ---help--- - This adds support for rt2800/rt3000/rt3500 wireless chipset family. - Supported chips: RT2760, RT2790, RT2860, RT2880, RT2890 & RT3052 - - This driver is non-functional at the moment and is intended for - developers. + This adds support for rt27xx/rt28xx/rt30xx wireless chipset family. + Supported chips: RT2760, RT2790, RT2860, RT2880, RT2890, RT3052, + RT3090, RT3091 & RT3092 When compiled as a module, this driver will be called "rt2800pci.ko". if RT2800PCI -config RT2800PCI_RT30XX - bool "rt2800pci - Include support for rt30xx (PCI/PCIe/PCMCIA) devices" - default y +config RT2800PCI_RT33XX + bool "rt2800pci - Include support for rt33xx devices (EXPERIMENTAL)" + depends on EXPERIMENTAL + default n ---help--- - This adds support for rt30xx wireless chipset family to the + This adds support for rt33xx wireless chipset family to the rt2800pci driver. - Supported chips: RT3090, RT3091 & RT3092 + Supported chips: RT3390 Support for these devices is non-functional at the moment and is intended for testers and developers. config RT2800PCI_RT35XX - bool "rt2800pci - Include support for rt35xx (PCI/PCIe/PCMCIA) devices" + bool "rt2800pci - Include support for rt35xx devices (EXPERIMENTAL)" + depends on EXPERIMENTAL default n ---help--- This adds support for rt35xx wireless chipset family to the @@ -134,8 +124,8 @@ config RT73USB When compiled as a module, this driver will be called rt73usb. config RT2800USB - tristate "Ralink rt2800 (USB) support (EXPERIMENTAL)" - depends on USB && EXPERIMENTAL + tristate "Ralink rt27xx/rt28xx/rt30xx (USB) support" + depends on USB select RT2800_LIB select RT2X00_LIB_USB select RT2X00_LIB_HT @@ -143,30 +133,28 @@ config RT2800USB select RT2X00_LIB_CRYPTO select CRC_CCITT ---help--- - This adds experimental support for rt2800 wireless chipset family. - Supported chips: RT2770, RT2870 & RT3070. - - Known issues: - - support for RT2870 chips doesn't work with 802.11n APs yet - - support for RT3070 chips is non-functional at the moment + This adds support for rt27xx/rt28xx/rt30xx wireless chipset family. + Supported chips: RT2770, RT2870 & RT3070, RT3071 & RT3072 When compiled as a module, this driver will be called "rt2800usb.ko". if RT2800USB -config RT2800USB_RT30XX - bool "rt2800usb - Include support for rt30xx (USB) devices" - default y +config RT2800USB_RT33XX + bool "rt2800usb - Include support for rt33xx devices (EXPERIMENTAL)" + depends on EXPERIMENTAL + default n ---help--- - This adds support for rt30xx wireless chipset family to the + This adds support for rt33xx wireless chipset family to the rt2800usb driver. - Supported chips: RT3070, RT3071 & RT3072 + Supported chips: RT3370 Support for these devices is non-functional at the moment and is intended for testers and developers. config RT2800USB_RT35XX - bool "rt2800usb - Include support for rt35xx (USB) devices" + bool "rt2800usb - Include support for rt35xx devices (EXPERIMENTAL)" + depends on EXPERIMENTAL default n ---help--- This adds support for rt35xx wireless chipset family to the @@ -180,9 +168,9 @@ config RT2800USB_UNKNOWN bool "rt2800usb - Include support for unknown (USB) devices" default n ---help--- - This adds support for rt2800 family devices that are known to - have a rt2800 family chipset, but for which the exact chipset - is unknown. + This adds support for rt2800usb devices that are known to + have a rt28xx family compatible chipset, but for which the exact + chipset is unknown. Support status for these devices is unknown, and enabling these devices may or may not work. diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 4f420a9ec5d..9ec6691adf0 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -885,8 +885,7 @@ static void rt2400pci_toggle_rx(struct rt2x00_dev *rt2x00dev, rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); rt2x00_set_field32(®, RXCSR0_DISABLE_RX, - (state == STATE_RADIO_RX_OFF) || - (state == STATE_RADIO_RX_OFF_LINK)); + (state == STATE_RADIO_RX_OFF)); rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); } @@ -989,9 +988,7 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt2400pci_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: - case STATE_RADIO_RX_ON_LINK: case STATE_RADIO_RX_OFF: - case STATE_RADIO_RX_OFF_LINK: rt2400pci_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: @@ -1612,6 +1609,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = { .get_tsf = rt2400pci_get_tsf, .tx_last_beacon = rt2400pci_tx_last_beacon, .rfkill_poll = rt2x00mac_rfkill_poll, + .flush = rt2x00mac_flush, }; static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { @@ -1640,28 +1638,28 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { }; static const struct data_queue_desc rt2400pci_queue_rx = { - .entry_num = RX_ENTRIES, + .entry_num = 24, .data_size = DATA_FRAME_SIZE, .desc_size = RXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt2400pci_queue_tx = { - .entry_num = TX_ENTRIES, + .entry_num = 24, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt2400pci_queue_bcn = { - .entry_num = BEACON_ENTRIES, + .entry_num = 1, .data_size = MGMT_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt2400pci_queue_atim = { - .entry_num = ATIM_ENTRIES, + .entry_num = 8, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h index c048b18f413..d3a4a68cc43 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.h +++ b/drivers/net/wireless/rt2x00/rt2400pci.h @@ -809,8 +809,8 @@ /* * DMA descriptor defines. */ -#define TXD_DESC_SIZE ( 8 * sizeof(__le32) ) -#define RXD_DESC_SIZE ( 8 * sizeof(__le32) ) +#define TXD_DESC_SIZE (8 * sizeof(__le32)) +#define RXD_DESC_SIZE (8 * sizeof(__le32)) /* * TX descriptor format for TX, PRIO, ATIM and Beacon Ring. @@ -948,6 +948,6 @@ ((__CLAMP_TX(__txpower) - MAX_TXPOWER) + MIN_TXPOWER) #define TXPOWER_TO_DEV(__txpower) \ - MAX_TXPOWER - (__CLAMP_TX(__txpower) - MIN_TXPOWER) + (MAX_TXPOWER - (__CLAMP_TX(__txpower) - MIN_TXPOWER)) #endif /* RT2400PCI_H */ diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 97feb7aef80..3e7f2034624 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1040,8 +1040,7 @@ static void rt2500pci_toggle_rx(struct rt2x00_dev *rt2x00dev, rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); rt2x00_set_field32(®, RXCSR0_DISABLE_RX, - (state == STATE_RADIO_RX_OFF) || - (state == STATE_RADIO_RX_OFF_LINK)); + (state == STATE_RADIO_RX_OFF)); rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); } @@ -1144,9 +1143,7 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt2500pci_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: - case STATE_RADIO_RX_ON_LINK: case STATE_RADIO_RX_OFF: - case STATE_RADIO_RX_OFF_LINK: rt2500pci_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: @@ -1193,9 +1190,9 @@ static void rt2500pci_write_tx_desc(struct queue_entry *entry, rt2x00_desc_read(txd, 2, &word); rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER); - rt2x00_set_field32(&word, TXD_W2_AIFS, txdesc->aifs); - rt2x00_set_field32(&word, TXD_W2_CWMIN, txdesc->cw_min); - rt2x00_set_field32(&word, TXD_W2_CWMAX, txdesc->cw_max); + rt2x00_set_field32(&word, TXD_W2_AIFS, entry->queue->aifs); + rt2x00_set_field32(&word, TXD_W2_CWMIN, entry->queue->cw_min); + rt2x00_set_field32(&word, TXD_W2_CWMAX, entry->queue->cw_max); rt2x00_desc_write(txd, 2, word); rt2x00_desc_read(txd, 3, &word); @@ -1909,6 +1906,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = { .get_tsf = rt2500pci_get_tsf, .tx_last_beacon = rt2500pci_tx_last_beacon, .rfkill_poll = rt2x00mac_rfkill_poll, + .flush = rt2x00mac_flush, }; static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { @@ -1937,28 +1935,28 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { }; static const struct data_queue_desc rt2500pci_queue_rx = { - .entry_num = RX_ENTRIES, + .entry_num = 32, .data_size = DATA_FRAME_SIZE, .desc_size = RXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt2500pci_queue_tx = { - .entry_num = TX_ENTRIES, + .entry_num = 32, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt2500pci_queue_bcn = { - .entry_num = BEACON_ENTRIES, + .entry_num = 1, .data_size = MGMT_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt2500pci_queue_atim = { - .entry_num = ATIM_ENTRIES, + .entry_num = 8, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h index d708031361a..2aad7ba8a10 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.h +++ b/drivers/net/wireless/rt2x00/rt2500pci.h @@ -1088,8 +1088,8 @@ /* * DMA descriptor defines. */ -#define TXD_DESC_SIZE ( 11 * sizeof(__le32) ) -#define RXD_DESC_SIZE ( 11 * sizeof(__le32) ) +#define TXD_DESC_SIZE (11 * sizeof(__le32)) +#define RXD_DESC_SIZE (11 * sizeof(__le32)) /* * TX descriptor format for TX, PRIO, ATIM and Beacon Ring. diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 93e44c7f3a7..8152fec3175 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -39,7 +39,7 @@ /* * Allow hardware encryption to be disabled. */ -static int modparam_nohwcrypt = 0; +static int modparam_nohwcrypt; module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); @@ -938,8 +938,7 @@ static void rt2500usb_toggle_rx(struct rt2x00_dev *rt2x00dev, rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®); rt2x00_set_field16(®, TXRX_CSR2_DISABLE_RX, - (state == STATE_RADIO_RX_OFF) || - (state == STATE_RADIO_RX_OFF_LINK)); + (state == STATE_RADIO_RX_OFF)); rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg); } @@ -1019,9 +1018,7 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, rt2500usb_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: - case STATE_RADIO_RX_ON_LINK: case STATE_RADIO_RX_OFF: - case STATE_RADIO_RX_OFF_LINK: rt2500usb_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: @@ -1081,9 +1078,9 @@ static void rt2500usb_write_tx_desc(struct queue_entry *entry, rt2x00_desc_read(txd, 1, &word); rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset); - rt2x00_set_field32(&word, TXD_W1_AIFS, txdesc->aifs); - rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); - rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); + rt2x00_set_field32(&word, TXD_W1_AIFS, entry->queue->aifs); + rt2x00_set_field32(&word, TXD_W1_CWMIN, entry->queue->cw_min); + rt2x00_set_field32(&word, TXD_W1_CWMAX, entry->queue->cw_max); rt2x00_desc_write(txd, 1, word); rt2x00_desc_read(txd, 2, &word); @@ -1801,6 +1798,7 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = { .bss_info_changed = rt2x00mac_bss_info_changed, .conf_tx = rt2x00mac_conf_tx, .rfkill_poll = rt2x00mac_rfkill_poll, + .flush = rt2x00mac_flush, }; static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { @@ -1829,28 +1827,28 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { }; static const struct data_queue_desc rt2500usb_queue_rx = { - .entry_num = RX_ENTRIES, + .entry_num = 32, .data_size = DATA_FRAME_SIZE, .desc_size = RXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), }; static const struct data_queue_desc rt2500usb_queue_tx = { - .entry_num = TX_ENTRIES, + .entry_num = 32, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), }; static const struct data_queue_desc rt2500usb_queue_bcn = { - .entry_num = BEACON_ENTRIES, + .entry_num = 1, .data_size = MGMT_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb_bcn), }; static const struct data_queue_desc rt2500usb_queue_atim = { - .entry_num = ATIM_ENTRIES, + .entry_num = 8, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index eb8b6cab992..a81c4371835 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -47,6 +47,7 @@ * RF3021 2.4G 1T2R * RF3022 2.4G 2T2R * RF3052 2.4G 2T2R + * RF3320 2.4G 1T1R */ #define RF2820 0x0001 #define RF2850 0x0002 @@ -412,10 +413,22 @@ #define BCN_OFFSET1_BCN7 FIELD32(0xff000000) /* - * PBF registers - * Most are for debug. Driver doesn't touch PBF register. + * TXRXQ_PCNT: PBF register + * PCNT_TX0Q: Page count for TX hardware queue 0 + * PCNT_TX1Q: Page count for TX hardware queue 1 + * PCNT_TX2Q: Page count for TX hardware queue 2 + * PCNT_RX0Q: Page count for RX hardware queue */ #define TXRXQ_PCNT 0x0438 +#define TXRXQ_PCNT_TX0Q FIELD32(0x000000ff) +#define TXRXQ_PCNT_TX1Q FIELD32(0x0000ff00) +#define TXRXQ_PCNT_TX2Q FIELD32(0x00ff0000) +#define TXRXQ_PCNT_RX0Q FIELD32(0xff000000) + +/* + * PBF register + * Debug. Driver doesn't touch PBF register. + */ #define PBF_DBG 0x043c /* @@ -960,8 +973,31 @@ /* * TXOP_CTRL_CFG: + * TIMEOUT_TRUN_EN: Enable/Disable TXOP timeout truncation + * AC_TRUN_EN: Enable/Disable truncation for AC change + * TXRATEGRP_TRUN_EN: Enable/Disable truncation for TX rate group change + * USER_MODE_TRUN_EN: Enable/Disable truncation for user TXOP mode + * MIMO_PS_TRUN_EN: Enable/Disable truncation for MIMO PS RTS/CTS + * RESERVED_TRUN_EN: Reserved + * LSIG_TXOP_EN: Enable/Disable L-SIG TXOP protection + * EXT_CCA_EN: Enable/Disable extension channel CCA reference (Defer 40Mhz + * transmissions if extension CCA is clear). + * EXT_CCA_DLY: Extension CCA signal delay time (unit: us) + * EXT_CWMIN: CwMin for extension channel backoff + * 0: Disabled + * */ #define TXOP_CTRL_CFG 0x1340 +#define TXOP_CTRL_CFG_TIMEOUT_TRUN_EN FIELD32(0x00000001) +#define TXOP_CTRL_CFG_AC_TRUN_EN FIELD32(0x00000002) +#define TXOP_CTRL_CFG_TXRATEGRP_TRUN_EN FIELD32(0x00000004) +#define TXOP_CTRL_CFG_USER_MODE_TRUN_EN FIELD32(0x00000008) +#define TXOP_CTRL_CFG_MIMO_PS_TRUN_EN FIELD32(0x00000010) +#define TXOP_CTRL_CFG_RESERVED_TRUN_EN FIELD32(0x00000020) +#define TXOP_CTRL_CFG_LSIG_TXOP_EN FIELD32(0x00000040) +#define TXOP_CTRL_CFG_EXT_CCA_EN FIELD32(0x00000080) +#define TXOP_CTRL_CFG_EXT_CCA_DLY FIELD32(0x0000ff00) +#define TXOP_CTRL_CFG_EXT_CWMIN FIELD32(0x000f0000) /* * TX_RTS_CFG: @@ -1485,17 +1521,17 @@ #define SHARED_KEY_MODE_BASE 0x7000 #define MAC_WCID_ENTRY(__idx) \ - ( MAC_WCID_BASE + ((__idx) * sizeof(struct mac_wcid_entry)) ) + (MAC_WCID_BASE + ((__idx) * sizeof(struct mac_wcid_entry))) #define PAIRWISE_KEY_ENTRY(__idx) \ - ( PAIRWISE_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) ) + (PAIRWISE_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry))) #define MAC_IVEIV_ENTRY(__idx) \ - ( MAC_IVEIV_TABLE_BASE + ((__idx) * sizeof(struct mac_iveiv_entry)) ) + (MAC_IVEIV_TABLE_BASE + ((__idx) * sizeof(struct mac_iveiv_entry))) #define MAC_WCID_ATTR_ENTRY(__idx) \ - ( MAC_WCID_ATTRIBUTE_BASE + ((__idx) * sizeof(u32)) ) + (MAC_WCID_ATTRIBUTE_BASE + ((__idx) * sizeof(u32))) #define SHARED_KEY_ENTRY(__idx) \ - ( SHARED_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) ) + (SHARED_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry))) #define SHARED_KEY_MODE_ENTRY(__idx) \ - ( SHARED_KEY_MODE_BASE + ((__idx) * sizeof(u32)) ) + (SHARED_KEY_MODE_BASE + ((__idx) * sizeof(u32))) struct mac_wcid_entry { u8 mac[6]; @@ -1635,9 +1671,9 @@ struct mac_iveiv_entry { #define HW_BEACON_BASE7 0x5bc0 #define HW_BEACON_OFFSET(__index) \ - ( ((__index) < 4) ? ( HW_BEACON_BASE0 + (__index * 0x0200) ) : \ - (((__index) < 6) ? ( HW_BEACON_BASE4 + ((__index - 4) * 0x0200) ) : \ - (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))) ) + (((__index) < 4) ? (HW_BEACON_BASE0 + (__index * 0x0200)) : \ + (((__index) < 6) ? (HW_BEACON_BASE4 + ((__index - 4) * 0x0200)) : \ + (HW_BEACON_BASE6 - ((__index - 6) * 0x0200)))) /* * BBP registers. @@ -1987,8 +2023,8 @@ struct mac_iveiv_entry { /* * DMA descriptor defines. */ -#define TXWI_DESC_SIZE ( 4 * sizeof(__le32) ) -#define RXWI_DESC_SIZE ( 4 * sizeof(__le32) ) +#define TXWI_DESC_SIZE (4 * sizeof(__le32)) +#define RXWI_DESC_SIZE (4 * sizeof(__le32)) /* * TX WI structure diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 5f00e00789d..75631614aba 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -277,13 +277,17 @@ int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev) unsigned int i; u32 reg; + /* + * Some devices are really slow to respond here. Wait a whole second + * before timing out. + */ for (i = 0; i < REGISTER_BUSY_COUNT; i++) { rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) && !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY)) return 0; - msleep(1); + msleep(10); } ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n"); @@ -483,7 +487,7 @@ void rt2800_write_tx_data(struct queue_entry *entry, txdesc->key_idx : 0xff); rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, txdesc->length); - rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, txdesc->qid); + rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, entry->queue->qid); rt2x00_set_field32(&word, TXWI_W1_PACKETID_ENTRY, (entry->entry_idx % 3) + 1); rt2x00_desc_write(txwi, 1, word); @@ -727,7 +731,7 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) * that the TX_STA_FIFO stack has a size of 16. We stick to our * tx ring size for now. */ - for (i = 0; i < TX_ENTRIES; i++) { + for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { rt2800_register_read(rt2x00dev, TX_STA_FIFO, ®); if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) break; @@ -824,7 +828,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) } EXPORT_SYMBOL_GPL(rt2800_write_beacon); -static void inline rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev, +static inline void rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev, unsigned int beacon_base) { int i; @@ -1144,6 +1148,7 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, struct rt2x00intf_conf *conf, const unsigned int flags) { u32 reg; + bool update_bssid = false; if (flags & CONFIG_UPDATE_TYPE) { /* @@ -1173,6 +1178,16 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, } if (flags & CONFIG_UPDATE_MAC) { + if (flags & CONFIG_UPDATE_TYPE && + conf->sync == TSF_SYNC_AP_NONE) { + /* + * The BSSID register has to be set to our own mac + * address in AP mode. + */ + memcpy(conf->bssid, conf->mac, sizeof(conf->mac)); + update_bssid = true; + } + if (!is_zero_ether_addr((const u8 *)conf->mac)) { reg = le32_to_cpu(conf->mac[1]); rt2x00_set_field32(®, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff); @@ -1183,7 +1198,7 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, conf->mac, sizeof(conf->mac)); } - if (flags & CONFIG_UPDATE_BSSID) { + if ((flags & CONFIG_UPDATE_BSSID) || update_bssid) { if (!is_zero_ether_addr((const u8 *)conf->bssid)) { reg = le32_to_cpu(conf->bssid[1]); rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 3); @@ -1529,7 +1544,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2x00_rf(rt2x00dev, RF3020) || rt2x00_rf(rt2x00dev, RF3021) || rt2x00_rf(rt2x00dev, RF3022) || - rt2x00_rf(rt2x00dev, RF3052)) + rt2x00_rf(rt2x00dev, RF3052) || + rt2x00_rf(rt2x00dev, RF3320)) rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); else rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); @@ -2097,7 +2113,23 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); } - rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, 0x0000583f); + /* + * The legacy driver also sets TXOP_CTRL_CFG_RESERVED_TRUN_EN to 1 + * although it is reserved. + */ + rt2800_register_read(rt2x00dev, TXOP_CTRL_CFG, ®); + rt2x00_set_field32(®, TXOP_CTRL_CFG_TIMEOUT_TRUN_EN, 1); + rt2x00_set_field32(®, TXOP_CTRL_CFG_AC_TRUN_EN, 1); + rt2x00_set_field32(®, TXOP_CTRL_CFG_TXRATEGRP_TRUN_EN, 1); + rt2x00_set_field32(®, TXOP_CTRL_CFG_USER_MODE_TRUN_EN, 1); + rt2x00_set_field32(®, TXOP_CTRL_CFG_MIMO_PS_TRUN_EN, 1); + rt2x00_set_field32(®, TXOP_CTRL_CFG_RESERVED_TRUN_EN, 1); + rt2x00_set_field32(®, TXOP_CTRL_CFG_LSIG_TXOP_EN, 0); + rt2x00_set_field32(®, TXOP_CTRL_CFG_EXT_CCA_EN, 0); + rt2x00_set_field32(®, TXOP_CTRL_CFG_EXT_CCA_DLY, 88); + rt2x00_set_field32(®, TXOP_CTRL_CFG_EXT_CWMIN, 0); + rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, reg); + rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, 0x00000002); rt2800_register_read(rt2x00dev, TX_RTS_CFG, ®); @@ -2134,7 +2166,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) SHARED_KEY_MODE_ENTRY(i), 0); for (i = 0; i < 256; i++) { - u32 wcid[2] = { 0xffffffff, 0x00ffffff }; + static const u32 wcid[2] = { 0xffffffff, 0x00ffffff }; rt2800_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i), wcid, sizeof(wcid)); @@ -2981,7 +3013,8 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) !rt2x00_rf(rt2x00dev, RF2020) && !rt2x00_rf(rt2x00dev, RF3021) && !rt2x00_rf(rt2x00dev, RF3022) && - !rt2x00_rf(rt2x00dev, RF3052)) { + !rt2x00_rf(rt2x00dev, RF3052) && + !rt2x00_rf(rt2x00dev, RF3320)) { ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); return -ENODEV; } @@ -3245,7 +3278,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) } else if (rt2x00_rf(rt2x00dev, RF3020) || rt2x00_rf(rt2x00dev, RF2020) || rt2x00_rf(rt2x00dev, RF3021) || - rt2x00_rf(rt2x00dev, RF3022)) { + rt2x00_rf(rt2x00dev, RF3022) || + rt2x00_rf(rt2x00dev, RF3320)) { spec->num_channels = 14; spec->channels = rf_vals_3x; } else if (rt2x00_rf(rt2x00dev, RF3052)) { diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index b2673953598..433c7f3ef83 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -84,20 +84,22 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token) rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); } -#ifdef CONFIG_RT2800PCI_SOC +#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) static void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) { - u32 *base_addr = (u32 *) KSEG1ADDR(0x1F040000); /* XXX for RT3052 */ + void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE); memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE); + + iounmap(base_addr); } #else static inline void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) { } -#endif /* CONFIG_RT2800PCI_SOC */ +#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */ -#ifdef CONFIG_RT2800PCI_PCI +#ifdef CONFIG_PCI static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom) { struct rt2x00_dev *rt2x00dev = eeprom->data; @@ -181,7 +183,7 @@ static inline int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev) static inline void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) { } -#endif /* CONFIG_RT2800PCI_PCI */ +#endif /* CONFIG_PCI */ /* * Firmware functions @@ -328,8 +330,7 @@ static void rt2800pci_toggle_rx(struct rt2x00_dev *rt2x00dev, rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, - (state == STATE_RADIO_RX_ON) || - (state == STATE_RADIO_RX_ON_LINK)); + (state == STATE_RADIO_RX_ON)); rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); } @@ -442,7 +443,7 @@ static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev, * if the device is booting and wasn't asleep it will return * failure when attempting to wakeup. */ - rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 2); + rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0xff, 2); if (state == STATE_AWAKE) { rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKUP, 0, 0); @@ -477,9 +478,7 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt2800pci_set_state(rt2x00dev, STATE_SLEEP); break; case STATE_RADIO_RX_ON: - case STATE_RADIO_RX_ON_LINK: case STATE_RADIO_RX_OFF: - case STATE_RADIO_RX_OFF_LINK: rt2800pci_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: @@ -777,7 +776,7 @@ static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) * Since we have only one producer and one consumer we don't * need to lock the kfifo. */ - for (i = 0; i < TX_ENTRIES; i++) { + for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { rt2800_register_read(rt2x00dev, TX_STA_FIFO, &status); if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) @@ -943,6 +942,7 @@ static const struct ieee80211_ops rt2800pci_mac80211_ops = { .get_tsf = rt2800_get_tsf, .rfkill_poll = rt2x00mac_rfkill_poll, .ampdu_action = rt2800_ampdu_action, + .flush = rt2x00mac_flush, }; static const struct rt2800_ops rt2800pci_rt2800_ops = { @@ -991,21 +991,21 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { }; static const struct data_queue_desc rt2800pci_queue_rx = { - .entry_num = RX_ENTRIES, + .entry_num = 128, .data_size = AGGREGATION_SIZE, .desc_size = RXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt2800pci_queue_tx = { - .entry_num = TX_ENTRIES, + .entry_num = 64, .data_size = AGGREGATION_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt2800pci_queue_bcn = { - .entry_num = 8 * BEACON_ENTRIES, + .entry_num = 8, .data_size = 0, /* No DMA required for beacons */ .desc_size = TXWI_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), @@ -1033,12 +1033,15 @@ static const struct rt2x00_ops rt2800pci_ops = { /* * RT2800pci module information. */ -#ifdef CONFIG_RT2800PCI_PCI +#ifdef CONFIG_PCI static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { { PCI_DEVICE(0x1814, 0x0601), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1814, 0x0701), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1814, 0x0781), PCI_DEVICE_DATA(&rt2800pci_ops) }, + { PCI_DEVICE(0x1814, 0x3090), PCI_DEVICE_DATA(&rt2800pci_ops) }, + { PCI_DEVICE(0x1814, 0x3091), PCI_DEVICE_DATA(&rt2800pci_ops) }, + { PCI_DEVICE(0x1814, 0x3092), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1432, 0x7708), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1432, 0x7727), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1432, 0x7728), PCI_DEVICE_DATA(&rt2800pci_ops) }, @@ -1046,12 +1049,10 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { { PCI_DEVICE(0x1432, 0x7748), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1432, 0x7758), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1432, 0x7768), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1a3b, 0x1059), PCI_DEVICE_DATA(&rt2800pci_ops) }, -#ifdef CONFIG_RT2800PCI_RT30XX - { PCI_DEVICE(0x1814, 0x3090), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1814, 0x3091), PCI_DEVICE_DATA(&rt2800pci_ops) }, - { PCI_DEVICE(0x1814, 0x3092), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1462, 0x891a), PCI_DEVICE_DATA(&rt2800pci_ops) }, + { PCI_DEVICE(0x1a3b, 0x1059), PCI_DEVICE_DATA(&rt2800pci_ops) }, +#ifdef CONFIG_RT2800PCI_RT33XX + { PCI_DEVICE(0x1814, 0x3390), PCI_DEVICE_DATA(&rt2800pci_ops) }, #endif #ifdef CONFIG_RT2800PCI_RT35XX { PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) }, @@ -1062,19 +1063,19 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { #endif { 0, } }; -#endif /* CONFIG_RT2800PCI_PCI */ +#endif /* CONFIG_PCI */ MODULE_AUTHOR(DRV_PROJECT); MODULE_VERSION(DRV_VERSION); MODULE_DESCRIPTION("Ralink RT2800 PCI & PCMCIA Wireless LAN driver."); MODULE_SUPPORTED_DEVICE("Ralink RT2860 PCI & PCMCIA chipset based cards"); -#ifdef CONFIG_RT2800PCI_PCI +#ifdef CONFIG_PCI MODULE_FIRMWARE(FIRMWARE_RT2860); MODULE_DEVICE_TABLE(pci, rt2800pci_device_table); -#endif /* CONFIG_RT2800PCI_PCI */ +#endif /* CONFIG_PCI */ MODULE_LICENSE("GPL"); -#ifdef CONFIG_RT2800PCI_SOC +#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) static int rt2800soc_probe(struct platform_device *pdev) { return rt2x00soc_probe(pdev, &rt2800pci_ops); @@ -1091,9 +1092,9 @@ static struct platform_driver rt2800soc_driver = { .suspend = rt2x00soc_suspend, .resume = rt2x00soc_resume, }; -#endif /* CONFIG_RT2800PCI_SOC */ +#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */ -#ifdef CONFIG_RT2800PCI_PCI +#ifdef CONFIG_PCI static struct pci_driver rt2800pci_driver = { .name = KBUILD_MODNAME, .id_table = rt2800pci_device_table, @@ -1102,21 +1103,21 @@ static struct pci_driver rt2800pci_driver = { .suspend = rt2x00pci_suspend, .resume = rt2x00pci_resume, }; -#endif /* CONFIG_RT2800PCI_PCI */ +#endif /* CONFIG_PCI */ static int __init rt2800pci_init(void) { int ret = 0; -#ifdef CONFIG_RT2800PCI_SOC +#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) ret = platform_driver_register(&rt2800soc_driver); if (ret) return ret; #endif -#ifdef CONFIG_RT2800PCI_PCI +#ifdef CONFIG_PCI ret = pci_register_driver(&rt2800pci_driver); if (ret) { -#ifdef CONFIG_RT2800PCI_SOC +#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) platform_driver_unregister(&rt2800soc_driver); #endif return ret; @@ -1128,10 +1129,10 @@ static int __init rt2800pci_init(void) static void __exit rt2800pci_exit(void) { -#ifdef CONFIG_RT2800PCI_PCI +#ifdef CONFIG_PCI pci_unregister_driver(&rt2800pci_driver); #endif -#ifdef CONFIG_RT2800PCI_SOC +#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) platform_driver_unregister(&rt2800soc_driver); #endif } diff --git a/drivers/net/wireless/rt2x00/rt2800pci.h b/drivers/net/wireless/rt2x00/rt2800pci.h index 5a8dda9b5b5..70e050d904c 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.h +++ b/drivers/net/wireless/rt2x00/rt2800pci.h @@ -38,10 +38,10 @@ * Queue register offset macros */ #define TX_QUEUE_REG_OFFSET 0x10 -#define TX_BASE_PTR(__x) TX_BASE_PTR0 + ((__x) * TX_QUEUE_REG_OFFSET) -#define TX_MAX_CNT(__x) TX_MAX_CNT0 + ((__x) * TX_QUEUE_REG_OFFSET) -#define TX_CTX_IDX(__x) TX_CTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET) -#define TX_DTX_IDX(__x) TX_DTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET) +#define TX_BASE_PTR(__x) (TX_BASE_PTR0 + ((__x) * TX_QUEUE_REG_OFFSET)) +#define TX_MAX_CNT(__x) (TX_MAX_CNT0 + ((__x) * TX_QUEUE_REG_OFFSET)) +#define TX_CTX_IDX(__x) (TX_CTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET)) +#define TX_DTX_IDX(__x) (TX_DTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET)) /* * 8051 firmware image. @@ -52,8 +52,8 @@ /* * DMA descriptor defines. */ -#define TXD_DESC_SIZE ( 4 * sizeof(__le32) ) -#define RXD_DESC_SIZE ( 4 * sizeof(__le32) ) +#define TXD_DESC_SIZE (4 * sizeof(__le32)) +#define RXD_DESC_SIZE (4 * sizeof(__le32)) /* * TX descriptor format for TX, PRIO and Beacon Ring. diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 3dff56ec195..935b76d3ce4 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -45,7 +45,7 @@ /* * Allow hardware encryption to be disabled. */ -static int modparam_nohwcrypt = 0; +static int modparam_nohwcrypt; module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); @@ -114,8 +114,7 @@ static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev, rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, - (state == STATE_RADIO_RX_ON) || - (state == STATE_RADIO_RX_ON_LINK)); + (state == STATE_RADIO_RX_ON)); rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); } @@ -165,7 +164,8 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) * this limit so reduce the number to prevent errors. */ rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_AGG_LIMIT, - ((RX_ENTRIES * DATA_FRAME_SIZE) / 1024) - 3); + ((rt2x00dev->ops->rx->entry_num * DATA_FRAME_SIZE) + / 1024) - 3); rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_EN, 1); rt2x00_set_field32(®, USB_DMA_CFG_TX_BULK_EN, 1); rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg); @@ -183,9 +183,9 @@ static int rt2800usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) { if (state == STATE_AWAKE) - rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0); + rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 2); else - rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 2); + rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0xff, 2); return 0; } @@ -215,9 +215,7 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev, rt2800usb_set_state(rt2x00dev, STATE_SLEEP); break; case STATE_RADIO_RX_ON: - case STATE_RADIO_RX_ON_LINK: case STATE_RADIO_RX_OFF: - case STATE_RADIO_RX_OFF_LINK: rt2800usb_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: @@ -245,6 +243,49 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev, } /* + * Watchdog handlers + */ +static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev) +{ + unsigned int i; + u32 reg; + + rt2800_register_read(rt2x00dev, TXRXQ_PCNT, ®); + if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) { + WARNING(rt2x00dev, "TX HW queue 0 timed out," + " invoke forced kick"); + + rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40012); + + for (i = 0; i < 10; i++) { + udelay(10); + if (!rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) + break; + } + + rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006); + } + + rt2800_register_read(rt2x00dev, TXRXQ_PCNT, ®); + if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) { + WARNING(rt2x00dev, "TX HW queue 1 timed out," + " invoke forced kick"); + + rt2800_register_write(rt2x00dev, PBF_CFG, 0xf4000a); + + for (i = 0; i < 10; i++) { + udelay(10); + if (!rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) + break; + } + + rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006); + } + + rt2x00usb_watchdog(rt2x00dev); +} + +/* * TX descriptor initialization */ static __le32 *rt2800usb_get_txwi(struct queue_entry *entry) @@ -266,8 +307,14 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry, * Initialize TXINFO descriptor */ rt2x00_desc_read(txi, 0, &word); + + /* + * The size of TXINFO_W0_USB_DMA_TX_PKT_LEN is + * TXWI + 802.11 header + L2 pad + payload + pad, + * so need to decrease size of TXINFO and USB end pad. + */ rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, - entry->skb->len - TXINFO_DESC_SIZE); + entry->skb->len - TXINFO_DESC_SIZE - 4); rt2x00_set_field32(&word, TXINFO_W0_WIV, !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); @@ -285,22 +332,29 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry, skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE; } -/* - * TX data initialization - */ -static int rt2800usb_get_tx_data_len(struct queue_entry *entry) +static void rt2800usb_write_tx_data(struct queue_entry *entry, + struct txentry_desc *txdesc) { - int length; + u8 padding_len; /* - * The length _must_ include 4 bytes padding, - * it should always be multiple of 4, - * but it must _not_ be a multiple of the USB packet size. + * pad(1~3 bytes) is added after each 802.11 payload. + * USB end pad(4 bytes) is added at each USB bulk out packet end. + * TX frame format is : + * | TXINFO | TXWI | 802.11 header | L2 pad | payload | pad | USB end pad | + * |<------------- tx_pkt_len ------------->| */ - length = roundup(entry->skb->len + 4, 4); - length += (4 * !(length % entry->queue->usb_maxpacket)); + rt2800_write_tx_data(entry, txdesc); + padding_len = roundup(entry->skb->len + 4, 4) - entry->skb->len; + memset(skb_put(entry->skb, padding_len), 0, padding_len); +} - return length; +/* + * TX data initialization + */ +static int rt2800usb_get_tx_data_len(struct queue_entry *entry) +{ + return entry->skb->len; } /* @@ -507,6 +561,7 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = { .get_tsf = rt2800_get_tsf, .rfkill_poll = rt2x00mac_rfkill_poll, .ampdu_action = rt2800_ampdu_action, + .flush = rt2x00mac_flush, }; static const struct rt2800_ops rt2800usb_rt2800_ops = { @@ -535,9 +590,9 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { .link_stats = rt2800_link_stats, .reset_tuner = rt2800_reset_tuner, .link_tuner = rt2800_link_tuner, - .watchdog = rt2x00usb_watchdog, + .watchdog = rt2800usb_watchdog, .write_tx_desc = rt2800usb_write_tx_desc, - .write_tx_data = rt2800_write_tx_data, + .write_tx_data = rt2800usb_write_tx_data, .write_beacon = rt2800_write_beacon, .get_tx_data_len = rt2800usb_get_tx_data_len, .kick_tx_queue = rt2x00usb_kick_tx_queue, @@ -553,21 +608,21 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { }; static const struct data_queue_desc rt2800usb_queue_rx = { - .entry_num = RX_ENTRIES, + .entry_num = 128, .data_size = AGGREGATION_SIZE, .desc_size = RXINFO_DESC_SIZE + RXWI_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), }; static const struct data_queue_desc rt2800usb_queue_tx = { - .entry_num = TX_ENTRIES, + .entry_num = 64, .data_size = AGGREGATION_SIZE, .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), }; static const struct data_queue_desc rt2800usb_queue_bcn = { - .entry_num = 8 * BEACON_ENTRIES, + .entry_num = 8, .data_size = MGMT_FRAME_SIZE, .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), @@ -599,11 +654,19 @@ static struct usb_device_id rt2800usb_device_table[] = { /* Abocom */ { USB_DEVICE(0x07b8, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07b8, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x07b8, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x07b8, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1482, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* AirTies */ + { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Allwin */ { USB_DEVICE(0x8516, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x8516, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x8516, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Amit */ { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Askey */ @@ -612,8 +675,13 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0b05, 0x1731), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0b05, 0x1732), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0b05, 0x1742), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) }, /* AzureWave */ { USB_DEVICE(0x13d3, 0x3247), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x13d3, 0x3307), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x13d3, 0x3321), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Belkin */ { USB_DEVICE(0x050d, 0x8053), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x050d, 0x805c), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -624,6 +692,7 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x14b2, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x14b2, 0x3c23), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x14b2, 0x3c25), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x14b2, 0x3c27), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -632,17 +701,36 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07aa, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) }, /* D-Link */ { USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x07d1, 0x3c16), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* Draytek */ + { USB_DEVICE(0x07fa, 0x7712), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Edimax */ + { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* Encore */ + { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) }, /* EnGenius */ { USB_DEVICE(0x1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Gigabyte */ { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Hawking */ { USB_DEVICE(0x0e66, 0x0001), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -651,6 +739,10 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0e66, 0x0013), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0e66, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0e66, 0x0018), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* I-O DATA */ + { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Linksys */ { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -658,17 +750,44 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0789, 0x0164), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0789, 0x0166), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Motorola */ { USB_DEVICE(0x100d, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) }, /* MSI */ + { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0db0, 0x3821), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0db0, 0x3822), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0db0, 0x3870), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0db0, 0x3871), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0db0, 0x821a), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0db0, 0x822a), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0db0, 0x822b), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0db0, 0x822c), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0db0, 0x870a), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0db0, 0x871a), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0db0, 0x871b), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0db0, 0x871c), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0db0, 0x899a), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* Para */ + { USB_DEVICE(0x20b8, 0x8888), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* Pegatron */ + { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Philips */ { USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Planex */ + { USB_DEVICE(0x2019, 0xab25), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x2019, 0xed06), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* Quanta */ + { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Ralink */ + { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x148f, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x148f, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x148f, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x148f, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Samsung */ { USB_DEVICE(0x04e8, 0x2018), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Siemens */ @@ -681,13 +800,22 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0df6, 0x0039), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0df6, 0x003b), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0df6, 0x003d), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0df6, 0x0047), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0df6, 0x0048), USB_DEVICE_DATA(&rt2800usb_ops) }, /* SMC */ { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x083a, 0x7512), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x083a, 0x7522), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x083a, 0x8522), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x083a, 0xa618), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x083a, 0xa701), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x083a, 0xa702), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x083a, 0xa703), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x083a, 0xb522), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Sparklan */ { USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -701,101 +829,16 @@ static struct usb_device_id rt2800usb_device_table[] = { /* Zinwell */ { USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Zyxel */ { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) }, -#ifdef CONFIG_RT2800USB_RT30XX - /* Abocom */ - { USB_DEVICE(0x07b8, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07b8, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* AirTies */ - { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Allwin */ - { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* ASUS */ - { USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* AzureWave */ - { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x13d3, 0x3307), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x13d3, 0x3321), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Conceptronic */ - { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Corega */ - { USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* D-Link */ - { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c16), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Draytek */ - { USB_DEVICE(0x07fa, 0x7712), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Edimax */ - { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Encore */ - { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* EnGenius */ - { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Gigabyte */ - { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* I-O DATA */ - { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Logitec */ - { USB_DEVICE(0x0789, 0x0166), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* MSI */ - { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x3821), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x3822), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x3870), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x3871), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x821a), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x822a), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x822b), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x822c), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x870a), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x871a), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x871b), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x871c), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0db0, 0x899a), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Para */ - { USB_DEVICE(0x20b8, 0x8888), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Pegatron */ - { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Planex */ - { USB_DEVICE(0x2019, 0xab25), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Quanta */ - { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) }, +#ifdef CONFIG_RT2800USB_RT33XX /* Ralink */ - { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x148f, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x148f, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x148f, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x148f, 0x8070), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Sitecom */ - { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x0047), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x0048), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* SMC */ - { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0xa701), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0xa702), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0xa703), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Zinwell */ - { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0df6, 0x0050), USB_DEVICE_DATA(&rt2800usb_ops) }, #endif #ifdef CONFIG_RT2800USB_RT35XX /* Allwin */ @@ -809,12 +852,9 @@ static struct usb_device_id rt2800usb_device_table[] = { /* I-O DATA */ { USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Ralink */ - { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x148f, 0x8070), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Sitecom */ { USB_DEVICE(0x0df6, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x0050), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Zinwell */ { USB_DEVICE(0x5a57, 0x0284), USB_DEVICE_DATA(&rt2800usb_ops) }, #endif diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h index 0722badccf8..671ea359261 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.h +++ b/drivers/net/wireless/rt2x00/rt2800usb.h @@ -40,8 +40,8 @@ /* * DMA descriptor defines. */ -#define TXINFO_DESC_SIZE ( 1 * sizeof(__le32) ) -#define RXINFO_DESC_SIZE ( 1 * sizeof(__le32) ) +#define TXINFO_DESC_SIZE (1 * sizeof(__le32)) +#define RXINFO_DESC_SIZE (1 * sizeof(__le32)) /* * TX Info structure diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 94fe589acfa..0a55eeff871 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -915,7 +915,7 @@ struct rt2x00_dev { * in those cases REGISTER_BUSY_COUNT attempts should be * taken with a REGISTER_BUSY_DELAY interval. */ -#define REGISTER_BUSY_COUNT 5 +#define REGISTER_BUSY_COUNT 100 #define REGISTER_BUSY_DELAY 100 /* @@ -1133,6 +1133,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params); void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw); +void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop); /* * Driver allocation handlers. diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 54ffb5aeb34..a238e908c85 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -133,7 +133,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, */ if (!(ant->flags & ANTENNA_RX_DIVERSITY)) config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx); - else if(config.rx == ANTENNA_SW_DIVERSITY) + else if (config.rx == ANTENNA_SW_DIVERSITY) config.rx = active->rx; if (!(ant->flags & ANTENNA_TX_DIVERSITY)) @@ -146,7 +146,8 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, * else the changes will be ignored by the device. */ if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF_LINK); + rt2x00dev->ops->lib->set_device_state(rt2x00dev, + STATE_RADIO_RX_OFF); /* * Write new antenna setup to device and reset the link tuner. @@ -160,7 +161,8 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, memcpy(active, &config, sizeof(config)); if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); + rt2x00dev->ops->lib->set_device_state(rt2x00dev, + STATE_RADIO_RX_ON); } void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index fcdb6b0dc40..64dfb1f6823 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c @@ -162,11 +162,11 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, struct timeval timestamp; u32 data_len; - do_gettimeofday(×tamp); - - if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)) + if (likely(!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags))) return; + do_gettimeofday(×tamp); + if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) { DEBUG(rt2x00dev, "txrx dump queue length exceeded.\n"); return; @@ -342,7 +342,7 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file, sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdma done\tdone\n"); queue_for_each(intf->rt2x00dev, queue) { - spin_lock_irqsave(&queue->lock, irqflags); + spin_lock_irqsave(&queue->index_lock, irqflags); temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid, queue->count, queue->limit, queue->length, @@ -350,7 +350,7 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file, queue->index[Q_INDEX_DMA_DONE], queue->index[Q_INDEX_DONE]); - spin_unlock_irqrestore(&queue->lock, irqflags); + spin_unlock_irqrestore(&queue->index_lock, irqflags); } size = strlen(data); diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 5ba79b935f0..c879f9a7037 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -68,7 +68,8 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) /* * Enable RX. */ - rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); + rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_ON); + rt2x00link_start_tuner(rt2x00dev); /* * Start watchdog monitoring. @@ -102,7 +103,8 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) /* * Disable RX. */ - rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); + rt2x00link_stop_tuner(rt2x00dev); + rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_OFF); /* * Disable radio. @@ -113,23 +115,6 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) rt2x00leds_led_radio(rt2x00dev, false); } -void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state) -{ - /* - * When we are disabling the RX, we should also stop the link tuner. - */ - if (state == STATE_RADIO_RX_OFF) - rt2x00link_stop_tuner(rt2x00dev); - - rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); - - /* - * When we are enabling the RX, we should also start the link tuner. - */ - if (state == STATE_RADIO_RX_ON) - rt2x00link_start_tuner(rt2x00dev); -} - static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { @@ -265,10 +250,9 @@ void rt2x00lib_txdone(struct queue_entry *entry, struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); - unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb); + unsigned int header_length, i; u8 rate_idx, rate_flags, retry_rates; u8 skbdesc_flags = skbdesc->flags; - unsigned int i; bool success; /* @@ -287,6 +271,11 @@ void rt2x00lib_txdone(struct queue_entry *entry, skbdesc->flags &= ~SKBDESC_DESC_IN_SKB; /* + * Determine the length of 802.11 header. + */ + header_length = ieee80211_get_hdrlen_from_skb(entry->skb); + + /* * Remove L2 padding which was added during */ if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags)) @@ -483,6 +472,10 @@ void rt2x00lib_rxdone(struct queue_entry *entry) unsigned int header_length; int rate_idx; + if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) || + !test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + goto submit_entry; + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) goto submit_entry; @@ -567,9 +560,13 @@ void rt2x00lib_rxdone(struct queue_entry *entry) entry->skb = skb; submit_entry: - rt2x00dev->ops->lib->clear_entry(entry); - rt2x00queue_index_inc(entry->queue, Q_INDEX); + entry->flags = 0; rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); + if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && + test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) { + rt2x00dev->ops->lib->clear_entry(entry); + rt2x00queue_index_inc(entry->queue, Q_INDEX); + } } EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); @@ -678,7 +675,7 @@ static void rt2x00lib_rate(struct ieee80211_rate *entry, { entry->flags = 0; entry->bitrate = rate->bitrate; - entry->hw_value =index; + entry->hw_value = index; entry->hw_value_short = index; if (rate->flags & DEV_RATE_SHORT_PREAMBLE) diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 619da23b7b5..2cf68f82674 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -57,7 +57,7 @@ static inline const struct rt2x00_rate *rt2x00_get_rate(const u16 hw_value) } #define RATE_MCS(__mode, __mcs) \ - ( (((__mode) & 0x00ff) << 8) | ((__mcs) & 0x00ff) ) + ((((__mode) & 0x00ff) << 8) | ((__mcs) & 0x00ff)) static inline int rt2x00_get_rate_mcs(const u16 mcs_value) { @@ -69,7 +69,6 @@ static inline int rt2x00_get_rate_mcs(const u16 mcs_value) */ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev); void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev); -void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state); /* * Initialization handlers. diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index b971d8798eb..bfda60eaf4e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c @@ -67,7 +67,7 @@ (__avg).avg_weight ? \ ((((__avg).avg_weight * ((AVG_SAMPLES) - 1)) + \ ((__val) * (AVG_FACTOR))) / \ - (AVG_SAMPLES) ) : \ + (AVG_SAMPLES)) : \ ((__val) * (AVG_FACTOR)); \ __new.avg = __new.avg_weight / (AVG_FACTOR); \ __new; \ diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index c3c206a97d5..829bf4be9bc 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -283,14 +283,8 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, * invalid behavior in the device. */ memcpy(&intf->mac, vif->addr, ETH_ALEN); - if (vif->type == NL80211_IFTYPE_AP) { - memcpy(&intf->bssid, vif->addr, ETH_ALEN); - rt2x00lib_config_intf(rt2x00dev, intf, vif->type, - intf->mac, intf->bssid); - } else { - rt2x00lib_config_intf(rt2x00dev, intf, vif->type, - intf->mac, NULL); - } + rt2x00lib_config_intf(rt2x00dev, intf, vif->type, + intf->mac, NULL); /* * Some filters depend on the current working mode. We can force @@ -358,7 +352,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed) * if for any reason the link tuner must be reset, this will be * handled by rt2x00lib_config(). */ - rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF_LINK); + rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_OFF); /* * When we've just turned on the radio, we want to reprogram @@ -376,7 +370,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed) rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant); /* Turn RX back on */ - rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); + rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_ON); return 0; } @@ -719,3 +713,41 @@ void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw) wiphy_rfkill_set_hw_state(hw->wiphy, !active); } EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll); + +void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop) +{ + struct rt2x00_dev *rt2x00dev = hw->priv; + struct data_queue *queue; + unsigned int i = 0; + + ieee80211_stop_queues(hw); + + /* + * Run over all queues to kick them, this will force + * any pending frames to be transmitted. + */ + tx_queue_for_each(rt2x00dev, queue) { + rt2x00dev->ops->lib->kick_tx_queue(queue); + } + + /** + * All queues have been kicked, now wait for each queue + * to become empty. With a bit of luck, we only have to wait + * for the first queue to become empty, because while waiting + * for the that queue, the other queues will have transmitted + * all their frames as well (since they were already kicked). + */ + tx_queue_for_each(rt2x00dev, queue) { + for (i = 0; i < 10; i++) { + if (rt2x00queue_empty(queue)) + break; + msleep(100); + } + + if (!rt2x00queue_empty(queue)) + WARNING(rt2x00dev, "Failed to flush queue %d", queue->qid); + } + + ieee80211_wake_queues(hw); +} +EXPORT_SYMBOL_GPL(rt2x00mac_flush); diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 2449d785cf8..868ca19b13e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -105,7 +105,7 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, */ addr = dma_alloc_coherent(rt2x00dev->dev, queue->limit * queue->desc_size, - &dma, GFP_KERNEL | GFP_DMA); + &dma, GFP_KERNEL); if (!addr) return -ENOMEM; diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index e360d287def..a3d79c7a21c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -204,8 +204,10 @@ void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length) if (!l2pad) return; - memmove(skb->data + l2pad, skb->data, header_length); - skb_pull(skb, l2pad); + memmove(skb->data + header_length, skb->data + header_length + l2pad, + skb->len - header_length - l2pad); + + skb_trim(skb, skb->len - l2pad); } static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, @@ -311,14 +313,6 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, memset(txdesc, 0, sizeof(*txdesc)); /* - * Initialize information from queue - */ - txdesc->qid = entry->queue->qid; - txdesc->cw_min = entry->queue->cw_min; - txdesc->cw_max = entry->queue->cw_max; - txdesc->aifs = entry->queue->aifs; - - /* * Header and frame information. */ txdesc->length = entry->skb->len; @@ -460,12 +454,9 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, rt2x00debug_dump_frame(queue->rt2x00dev, DUMP_FRAME_TX, entry->skb); } -static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, +static void rt2x00queue_kick_tx_queue(struct data_queue *queue, struct txentry_desc *txdesc) { - struct data_queue *queue = entry->queue; - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - /* * Check if we need to kick the queue, there are however a few rules * 1) Don't kick unless this is the last in frame in a burst. @@ -477,7 +468,7 @@ static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, */ if (rt2x00queue_threshold(queue) || !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) - rt2x00dev->ops->lib->kick_tx_queue(queue); + queue->rt2x00dev->ops->lib->kick_tx_queue(queue); } int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, @@ -567,7 +558,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, rt2x00queue_index_inc(queue, Q_INDEX); rt2x00queue_write_tx_descriptor(entry, &txdesc); - rt2x00queue_kick_tx_queue(entry, &txdesc); + rt2x00queue_kick_tx_queue(queue, &txdesc); return 0; } @@ -649,10 +640,10 @@ void rt2x00queue_for_each_entry(struct data_queue *queue, * it should not be kicked during this run, since it * is part of another TX operation. */ - spin_lock_irqsave(&queue->lock, irqflags); + spin_lock_irqsave(&queue->index_lock, irqflags); index_start = queue->index[start]; index_end = queue->index[end]; - spin_unlock_irqrestore(&queue->lock, irqflags); + spin_unlock_irqrestore(&queue->index_lock, irqflags); /* * Start from the TX done pointer, this guarentees that we will @@ -706,11 +697,11 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, return NULL; } - spin_lock_irqsave(&queue->lock, irqflags); + spin_lock_irqsave(&queue->index_lock, irqflags); entry = &queue->entries[queue->index[index]]; - spin_unlock_irqrestore(&queue->lock, irqflags); + spin_unlock_irqrestore(&queue->index_lock, irqflags); return entry; } @@ -726,7 +717,7 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) return; } - spin_lock_irqsave(&queue->lock, irqflags); + spin_lock_irqsave(&queue->index_lock, irqflags); queue->index[index]++; if (queue->index[index] >= queue->limit) @@ -741,7 +732,7 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) queue->count++; } - spin_unlock_irqrestore(&queue->lock, irqflags); + spin_unlock_irqrestore(&queue->index_lock, irqflags); } static void rt2x00queue_reset(struct data_queue *queue) @@ -749,7 +740,7 @@ static void rt2x00queue_reset(struct data_queue *queue) unsigned long irqflags; unsigned int i; - spin_lock_irqsave(&queue->lock, irqflags); + spin_lock_irqsave(&queue->index_lock, irqflags); queue->count = 0; queue->length = 0; @@ -759,7 +750,7 @@ static void rt2x00queue_reset(struct data_queue *queue) queue->last_action[i] = jiffies; } - spin_unlock_irqrestore(&queue->lock, irqflags); + spin_unlock_irqrestore(&queue->index_lock, irqflags); } void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev) @@ -809,8 +800,8 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, return -ENOMEM; #define QUEUE_ENTRY_PRIV_OFFSET(__base, __index, __limit, __esize, __psize) \ - ( ((char *)(__base)) + ((__limit) * (__esize)) + \ - ((__index) * (__psize)) ) + (((char *)(__base)) + ((__limit) * (__esize)) + \ + ((__index) * (__psize))) for (i = 0; i < queue->limit; i++) { entries[i].flags = 0; @@ -911,7 +902,7 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev) static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev, struct data_queue *queue, enum data_queue_qid qid) { - spin_lock_init(&queue->lock); + spin_lock_init(&queue->index_lock); queue->rt2x00dev = rt2x00dev; queue->qid = qid; diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index d81d85f3486..29b051ac640 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -43,22 +43,6 @@ #define AGGREGATION_SIZE 3840 /** - * DOC: Number of entries per queue - * - * Under normal load without fragmentation, 12 entries are sufficient - * without the queue being filled up to the maximum. When using fragmentation - * and the queue threshold code, we need to add some additional margins to - * make sure the queue will never (or only under extreme load) fill up - * completely. - * Since we don't use preallocated DMA, having a large number of queue entries - * will have minimal impact on the memory requirements for the queue. - */ -#define RX_ENTRIES 24 -#define TX_ENTRIES 24 -#define BEACON_ENTRIES 1 -#define ATIM_ENTRIES 8 - -/** * enum data_queue_qid: Queue identification * * @QID_AC_BE: AC BE queue @@ -296,7 +280,6 @@ enum txentry_desc_flags { * Summary of information for the frame descriptor before sending a TX frame. * * @flags: Descriptor flags (See &enum queue_entry_flags). - * @qid: Queue identification (See &enum data_queue_qid). * @length: Length of the entire frame. * @header_length: Length of 802.11 header. * @length_high: PLCP length high word. @@ -309,11 +292,8 @@ enum txentry_desc_flags { * @rate_mode: Rate mode (See @enum rate_modulation). * @mpdu_density: MDPU density. * @retry_limit: Max number of retries. - * @aifs: AIFS value. * @ifs: IFS value. * @txop: IFS value for 11n capable chips. - * @cw_min: cwmin value. - * @cw_max: cwmax value. * @cipher: Cipher type used for encryption. * @key_idx: Key index used for encryption. * @iv_offset: Position where IV should be inserted by hardware. @@ -322,8 +302,6 @@ enum txentry_desc_flags { struct txentry_desc { unsigned long flags; - enum data_queue_qid qid; - u16 length; u16 header_length; @@ -339,11 +317,8 @@ struct txentry_desc { u16 mpdu_density; short retry_limit; - short aifs; short ifs; short txop; - short cw_min; - short cw_max; enum cipher cipher; u16 key_idx; @@ -423,7 +398,7 @@ enum queue_index { * @entries: Base address of the &struct queue_entry which are * part of this queue. * @qid: The queue identification, see &enum data_queue_qid. - * @lock: Spinlock to protect index handling. Whenever @index, @index_done or + * @index_lock: Spinlock to protect index handling. Whenever @index, @index_done or * @index_crypt needs to be changed this lock should be grabbed to prevent * index corruption due to concurrency. * @count: Number of frames handled in the queue. @@ -447,7 +422,7 @@ struct data_queue { enum data_queue_qid qid; - spinlock_t lock; + spinlock_t index_lock; unsigned int count; unsigned short limit; unsigned short threshold; @@ -618,10 +593,10 @@ static inline int rt2x00queue_threshold(struct data_queue *queue) } /** - * rt2x00queue_timeout - Check if a timeout occured for STATUS reorts + * rt2x00queue_status_timeout - Check if a timeout occured for STATUS reports * @queue: Queue to check. */ -static inline int rt2x00queue_timeout(struct data_queue *queue) +static inline int rt2x00queue_status_timeout(struct data_queue *queue) { return time_after(queue->last_action[Q_INDEX_DMA_DONE], queue->last_action[Q_INDEX_DONE] + (HZ / 10)); diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h index cef94621cef..ed71be95136 100644 --- a/drivers/net/wireless/rt2x00/rt2x00reg.h +++ b/drivers/net/wireless/rt2x00/rt2x00reg.h @@ -85,8 +85,6 @@ enum dev_state { STATE_RADIO_OFF, STATE_RADIO_RX_ON, STATE_RADIO_RX_OFF, - STATE_RADIO_RX_ON_LINK, - STATE_RADIO_RX_OFF_LINK, STATE_RADIO_IRQ_ON, STATE_RADIO_IRQ_OFF, STATE_RADIO_IRQ_ON_ISR, diff --git a/drivers/net/wireless/rt2x00/rt2x00soc.c b/drivers/net/wireless/rt2x00/rt2x00soc.c index fc98063de71..2aa5c38022f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00soc.c +++ b/drivers/net/wireless/rt2x00/rt2x00soc.c @@ -40,6 +40,8 @@ static void rt2x00soc_free_reg(struct rt2x00_dev *rt2x00dev) kfree(rt2x00dev->eeprom); rt2x00dev->eeprom = NULL; + + iounmap(rt2x00dev->csr.base); } static int rt2x00soc_alloc_reg(struct rt2x00_dev *rt2x00dev) @@ -51,9 +53,9 @@ static int rt2x00soc_alloc_reg(struct rt2x00_dev *rt2x00dev) if (!res) return -ENODEV; - rt2x00dev->csr.base = (void __iomem *)KSEG1ADDR(res->start); + rt2x00dev->csr.base = ioremap(res->start, resource_size(res)); if (!rt2x00dev->csr.base) - goto exit; + return -ENOMEM; rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL); if (!rt2x00dev->eeprom) diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index b3317df7a7d..9ac14598e2a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -226,9 +226,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) * Schedule the delayed work for reading the TX status * from the device. */ - if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && - test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work); + ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work); } static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) @@ -323,21 +321,6 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) rt2x00dev->txdone_work.func(&rt2x00dev->txdone_work); /* - * Security measure: if the driver did override the - * txdone_work function, and the hardware did arrive - * in a state which causes it to malfunction, it is - * possible that the driver couldn't handle the txdone - * event correctly. So after giving the driver the - * chance to cleanup, we now force a cleanup of any - * leftovers. - */ - if (!rt2x00queue_empty(queue)) { - WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," - " status handling failed, invoke hard reset", queue->qid); - rt2x00usb_work_txdone(&rt2x00dev->txdone_work); - } - - /* * The queue has been reset, and mac80211 is allowed to use the * queue again. */ @@ -361,7 +344,7 @@ void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) if (!rt2x00queue_empty(queue)) { if (rt2x00queue_dma_timeout(queue)) rt2x00usb_watchdog_tx_dma(queue); - if (rt2x00queue_timeout(queue)) + if (rt2x00queue_status_timeout(queue)) rt2x00usb_watchdog_tx_status(queue); } } @@ -424,9 +407,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) * Schedule the delayed work for reading the RX status * from the device. */ - if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && - test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work); + ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work); } /* diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index af548c87f10..6b09b01f634 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1623,8 +1623,7 @@ static void rt61pci_toggle_rx(struct rt2x00_dev *rt2x00dev, rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, - (state == STATE_RADIO_RX_OFF) || - (state == STATE_RADIO_RX_OFF_LINK)); + (state == STATE_RADIO_RX_OFF)); rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); } @@ -1745,9 +1744,7 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt61pci_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: - case STATE_RADIO_RX_ON_LINK: case STATE_RADIO_RX_OFF: - case STATE_RADIO_RX_OFF_LINK: rt61pci_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: @@ -1789,10 +1786,10 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry, * Start writing the descriptor words. */ rt2x00_desc_read(txd, 1, &word); - rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid); - rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); - rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); - rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); + rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, entry->queue->qid); + rt2x00_set_field32(&word, TXD_W1_AIFSN, entry->queue->aifs); + rt2x00_set_field32(&word, TXD_W1_CWMIN, entry->queue->cw_min); + rt2x00_set_field32(&word, TXD_W1_CWMAX, entry->queue->cw_max); rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset); rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags)); @@ -1820,7 +1817,7 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry, rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); rt2x00_desc_write(txd, 5, word); - if (txdesc->qid != QID_BEACON) { + if (entry->queue->qid != QID_BEACON) { rt2x00_desc_read(txd, 6, &word); rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, skbdesc->skb_dma); @@ -1866,8 +1863,8 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry, * Register descriptor details in skb frame descriptor. */ skbdesc->desc = txd; - skbdesc->desc_len = - (txdesc->qid == QID_BEACON) ? TXINFO_SIZE : TXD_DESC_SIZE; + skbdesc->desc_len = (entry->queue->qid == QID_BEACON) ? TXINFO_SIZE : + TXD_DESC_SIZE; } /* @@ -2078,7 +2075,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) * that the TX_STA_FIFO stack has a size of 16. We stick to our * tx ring size for now. */ - for (i = 0; i < TX_ENTRIES; i++) { + for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { rt2x00pci_register_read(rt2x00dev, STA_CSR4, ®); if (!rt2x00_get_field32(reg, STA_CSR4_VALID)) break; @@ -2824,6 +2821,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { .conf_tx = rt61pci_conf_tx, .get_tsf = rt61pci_get_tsf, .rfkill_poll = rt2x00mac_rfkill_poll, + .flush = rt2x00mac_flush, }; static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { @@ -2857,21 +2855,21 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { }; static const struct data_queue_desc rt61pci_queue_rx = { - .entry_num = RX_ENTRIES, + .entry_num = 32, .data_size = DATA_FRAME_SIZE, .desc_size = RXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt61pci_queue_tx = { - .entry_num = TX_ENTRIES, + .entry_num = 32, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), }; static const struct data_queue_desc rt61pci_queue_bcn = { - .entry_num = 4 * BEACON_ENTRIES, + .entry_num = 4, .data_size = 0, /* No DMA required for beacons */ .desc_size = TXINFO_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci), diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index e2e728ab0b2..afc803b7959 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h @@ -412,7 +412,7 @@ struct hw_pairwise_ta_entry { * DROP_VERSION_ERROR: Drop version error frame. * DROP_MULTICAST: Drop multicast frames. * DROP_BORADCAST: Drop broadcast frames. - * ROP_ACK_CTS: Drop received ACK and CTS. + * DROP_ACK_CTS: Drop received ACK and CTS. */ #define TXRX_CSR0 0x3040 #define TXRX_CSR0_RX_ACK_TIMEOUT FIELD32(0x000001ff) diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 9be8089317e..6f04552f581 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -40,7 +40,7 @@ /* * Allow hardware encryption to be disabled. */ -static int modparam_nohwcrypt = 0; +static int modparam_nohwcrypt; module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); @@ -1331,8 +1331,7 @@ static void rt73usb_toggle_rx(struct rt2x00_dev *rt2x00dev, rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, ®); rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, - (state == STATE_RADIO_RX_OFF) || - (state == STATE_RADIO_RX_OFF_LINK)); + (state == STATE_RADIO_RX_OFF)); rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg); } @@ -1403,9 +1402,7 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, rt73usb_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: - case STATE_RADIO_RX_ON_LINK: case STATE_RADIO_RX_OFF: - case STATE_RADIO_RX_OFF_LINK: rt73usb_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: @@ -1472,10 +1469,10 @@ static void rt73usb_write_tx_desc(struct queue_entry *entry, rt2x00_desc_write(txd, 0, word); rt2x00_desc_read(txd, 1, &word); - rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid); - rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); - rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); - rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); + rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, entry->queue->qid); + rt2x00_set_field32(&word, TXD_W1_AIFSN, entry->queue->aifs); + rt2x00_set_field32(&word, TXD_W1_CWMIN, entry->queue->cw_min); + rt2x00_set_field32(&word, TXD_W1_CWMAX, entry->queue->cw_max); rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset); rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags)); @@ -2264,6 +2261,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = { .conf_tx = rt73usb_conf_tx, .get_tsf = rt73usb_get_tsf, .rfkill_poll = rt2x00mac_rfkill_poll, + .flush = rt2x00mac_flush, }; static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { @@ -2296,21 +2294,21 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { }; static const struct data_queue_desc rt73usb_queue_rx = { - .entry_num = RX_ENTRIES, + .entry_num = 32, .data_size = DATA_FRAME_SIZE, .desc_size = RXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), }; static const struct data_queue_desc rt73usb_queue_tx = { - .entry_num = TX_ENTRIES, + .entry_num = 32, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), }; static const struct data_queue_desc rt73usb_queue_bcn = { - .entry_num = 4 * BEACON_ENTRIES, + .entry_num = 4, .data_size = MGMT_FRAME_SIZE, .desc_size = TXINFO_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index 44d5b2bebd3..1315ce5c992 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h @@ -322,7 +322,7 @@ struct hw_pairwise_ta_entry { * DROP_VERSION_ERROR: Drop version error frame. * DROP_MULTICAST: Drop multicast frames. * DROP_BORADCAST: Drop broadcast frames. - * ROP_ACK_CTS: Drop received ACK and CTS. + * DROP_ACK_CTS: Drop received ACK and CTS. */ #define TXRX_CSR0 0x3040 #define TXRX_CSR0_RX_ACK_TIMEOUT FIELD32(0x000001ff) |