diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2400pci.c | 31 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500pci.c | 37 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 31 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800.h | 13 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800lib.c | 305 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800lib.h | 9 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800pci.c | 114 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800usb.c | 105 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 15 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00debug.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 71 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.h | 48 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.c | 199 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.h | 12 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 57 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 35 |
17 files changed, 611 insertions, 488 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 8e3fbdf48889..103c71164f10 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -1007,12 +1007,11 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1007 | /* | 1007 | /* |
1008 | * TX descriptor initialization | 1008 | * TX descriptor initialization |
1009 | */ | 1009 | */ |
1010 | static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1010 | static void rt2400pci_write_tx_desc(struct queue_entry *entry, |
1011 | struct sk_buff *skb, | ||
1012 | struct txentry_desc *txdesc) | 1011 | struct txentry_desc *txdesc) |
1013 | { | 1012 | { |
1014 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 1013 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1015 | struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; | 1014 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
1016 | __le32 *txd = entry_priv->desc; | 1015 | __le32 *txd = entry_priv->desc; |
1017 | u32 word; | 1016 | u32 word; |
1018 | 1017 | ||
@@ -1096,7 +1095,7 @@ static void rt2400pci_write_beacon(struct queue_entry *entry, | |||
1096 | /* | 1095 | /* |
1097 | * Write the TX descriptor for the beacon. | 1096 | * Write the TX descriptor for the beacon. |
1098 | */ | 1097 | */ |
1099 | rt2400pci_write_tx_desc(rt2x00dev, entry->skb, txdesc); | 1098 | rt2400pci_write_tx_desc(entry, txdesc); |
1100 | 1099 | ||
1101 | /* | 1100 | /* |
1102 | * Dump beacon to userspace through debugfs. | 1101 | * Dump beacon to userspace through debugfs. |
@@ -1112,24 +1111,24 @@ static void rt2400pci_write_beacon(struct queue_entry *entry, | |||
1112 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 1111 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); |
1113 | } | 1112 | } |
1114 | 1113 | ||
1115 | static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1114 | static void rt2400pci_kick_tx_queue(struct data_queue *queue) |
1116 | const enum data_queue_qid queue) | ||
1117 | { | 1115 | { |
1116 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
1118 | u32 reg; | 1117 | u32 reg; |
1119 | 1118 | ||
1120 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | 1119 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); |
1121 | rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue == QID_AC_BE)); | 1120 | rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE)); |
1122 | rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue == QID_AC_BK)); | 1121 | rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK)); |
1123 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue == QID_ATIM)); | 1122 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM)); |
1124 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 1123 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); |
1125 | } | 1124 | } |
1126 | 1125 | ||
1127 | static void rt2400pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, | 1126 | static void rt2400pci_kill_tx_queue(struct data_queue *queue) |
1128 | const enum data_queue_qid qid) | ||
1129 | { | 1127 | { |
1128 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
1130 | u32 reg; | 1129 | u32 reg; |
1131 | 1130 | ||
1132 | if (qid == QID_BEACON) { | 1131 | if (queue->qid == QID_BEACON) { |
1133 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | 1132 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); |
1134 | } else { | 1133 | } else { |
1135 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | 1134 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); |
@@ -1488,8 +1487,10 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1488 | spec->channels_info = info; | 1487 | spec->channels_info = info; |
1489 | 1488 | ||
1490 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); | 1489 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); |
1491 | for (i = 0; i < 14; i++) | 1490 | for (i = 0; i < 14; i++) { |
1492 | info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); | 1491 | info[i].max_power = TXPOWER_FROM_DEV(MAX_TXPOWER); |
1492 | info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); | ||
1493 | } | ||
1493 | 1494 | ||
1494 | return 0; | 1495 | return 0; |
1495 | } | 1496 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 1d174e42f11e..ab0507110e42 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -1161,12 +1161,11 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1161 | /* | 1161 | /* |
1162 | * TX descriptor initialization | 1162 | * TX descriptor initialization |
1163 | */ | 1163 | */ |
1164 | static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1164 | static void rt2500pci_write_tx_desc(struct queue_entry *entry, |
1165 | struct sk_buff *skb, | ||
1166 | struct txentry_desc *txdesc) | 1165 | struct txentry_desc *txdesc) |
1167 | { | 1166 | { |
1168 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 1167 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1169 | struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; | 1168 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
1170 | __le32 *txd = entry_priv->desc; | 1169 | __le32 *txd = entry_priv->desc; |
1171 | u32 word; | 1170 | u32 word; |
1172 | 1171 | ||
@@ -1249,7 +1248,7 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, | |||
1249 | /* | 1248 | /* |
1250 | * Write the TX descriptor for the beacon. | 1249 | * Write the TX descriptor for the beacon. |
1251 | */ | 1250 | */ |
1252 | rt2500pci_write_tx_desc(rt2x00dev, entry->skb, txdesc); | 1251 | rt2500pci_write_tx_desc(entry, txdesc); |
1253 | 1252 | ||
1254 | /* | 1253 | /* |
1255 | * Dump beacon to userspace through debugfs. | 1254 | * Dump beacon to userspace through debugfs. |
@@ -1265,24 +1264,24 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, | |||
1265 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 1264 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); |
1266 | } | 1265 | } |
1267 | 1266 | ||
1268 | static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1267 | static void rt2500pci_kick_tx_queue(struct data_queue *queue) |
1269 | const enum data_queue_qid queue) | ||
1270 | { | 1268 | { |
1269 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
1271 | u32 reg; | 1270 | u32 reg; |
1272 | 1271 | ||
1273 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | 1272 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); |
1274 | rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue == QID_AC_BE)); | 1273 | rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE)); |
1275 | rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue == QID_AC_BK)); | 1274 | rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK)); |
1276 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue == QID_ATIM)); | 1275 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM)); |
1277 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 1276 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); |
1278 | } | 1277 | } |
1279 | 1278 | ||
1280 | static void rt2500pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, | 1279 | static void rt2500pci_kill_tx_queue(struct data_queue *queue) |
1281 | const enum data_queue_qid qid) | ||
1282 | { | 1280 | { |
1281 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
1283 | u32 reg; | 1282 | u32 reg; |
1284 | 1283 | ||
1285 | if (qid == QID_BEACON) { | 1284 | if (queue->qid == QID_BEACON) { |
1286 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | 1285 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); |
1287 | } else { | 1286 | } else { |
1288 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | 1287 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); |
@@ -1802,12 +1801,16 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1802 | spec->channels_info = info; | 1801 | spec->channels_info = info; |
1803 | 1802 | ||
1804 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); | 1803 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); |
1805 | for (i = 0; i < 14; i++) | 1804 | for (i = 0; i < 14; i++) { |
1806 | info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); | 1805 | info[i].max_power = MAX_TXPOWER; |
1806 | info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); | ||
1807 | } | ||
1807 | 1808 | ||
1808 | if (spec->num_channels > 14) { | 1809 | if (spec->num_channels > 14) { |
1809 | for (i = 14; i < spec->num_channels; i++) | 1810 | for (i = 14; i < spec->num_channels; i++) { |
1810 | info[i].tx_power1 = DEFAULT_TXPOWER; | 1811 | info[i].max_power = MAX_TXPOWER; |
1812 | info[i].default_power1 = DEFAULT_TXPOWER; | ||
1813 | } | ||
1811 | } | 1814 | } |
1812 | 1815 | ||
1813 | return 0; | 1816 | return 0; |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index baadf03a800e..db64df4267d8 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1041,12 +1041,11 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1041 | /* | 1041 | /* |
1042 | * TX descriptor initialization | 1042 | * TX descriptor initialization |
1043 | */ | 1043 | */ |
1044 | static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1044 | static void rt2500usb_write_tx_desc(struct queue_entry *entry, |
1045 | struct sk_buff *skb, | ||
1046 | struct txentry_desc *txdesc) | 1045 | struct txentry_desc *txdesc) |
1047 | { | 1046 | { |
1048 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 1047 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1049 | __le32 *txd = (__le32 *) skb->data; | 1048 | __le32 *txd = (__le32 *) entry->skb->data; |
1050 | u32 word; | 1049 | u32 word; |
1051 | 1050 | ||
1052 | /* | 1051 | /* |
@@ -1129,7 +1128,7 @@ static void rt2500usb_write_beacon(struct queue_entry *entry, | |||
1129 | /* | 1128 | /* |
1130 | * Write the TX descriptor for the beacon. | 1129 | * Write the TX descriptor for the beacon. |
1131 | */ | 1130 | */ |
1132 | rt2500usb_write_tx_desc(rt2x00dev, entry->skb, txdesc); | 1131 | rt2500usb_write_tx_desc(entry, txdesc); |
1133 | 1132 | ||
1134 | /* | 1133 | /* |
1135 | * Dump beacon to userspace through debugfs. | 1134 | * Dump beacon to userspace through debugfs. |
@@ -1197,6 +1196,14 @@ static int rt2500usb_get_tx_data_len(struct queue_entry *entry) | |||
1197 | return length; | 1196 | return length; |
1198 | } | 1197 | } |
1199 | 1198 | ||
1199 | static void rt2500usb_kill_tx_queue(struct data_queue *queue) | ||
1200 | { | ||
1201 | if (queue->qid == QID_BEACON) | ||
1202 | rt2500usb_register_write(queue->rt2x00dev, TXRX_CSR19, 0); | ||
1203 | |||
1204 | rt2x00usb_kill_tx_queue(queue); | ||
1205 | } | ||
1206 | |||
1200 | /* | 1207 | /* |
1201 | * RX control handlers | 1208 | * RX control handlers |
1202 | */ | 1209 | */ |
@@ -1707,12 +1714,16 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1707 | spec->channels_info = info; | 1714 | spec->channels_info = info; |
1708 | 1715 | ||
1709 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); | 1716 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); |
1710 | for (i = 0; i < 14; i++) | 1717 | for (i = 0; i < 14; i++) { |
1711 | info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); | 1718 | info[i].max_power = MAX_TXPOWER; |
1719 | info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); | ||
1720 | } | ||
1712 | 1721 | ||
1713 | if (spec->num_channels > 14) { | 1722 | if (spec->num_channels > 14) { |
1714 | for (i = 14; i < spec->num_channels; i++) | 1723 | for (i = 14; i < spec->num_channels; i++) { |
1715 | info[i].tx_power1 = DEFAULT_TXPOWER; | 1724 | info[i].max_power = MAX_TXPOWER; |
1725 | info[i].default_power1 = DEFAULT_TXPOWER; | ||
1726 | } | ||
1716 | } | 1727 | } |
1717 | 1728 | ||
1718 | return 0; | 1729 | return 0; |
@@ -1791,7 +1802,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { | |||
1791 | .write_beacon = rt2500usb_write_beacon, | 1802 | .write_beacon = rt2500usb_write_beacon, |
1792 | .get_tx_data_len = rt2500usb_get_tx_data_len, | 1803 | .get_tx_data_len = rt2500usb_get_tx_data_len, |
1793 | .kick_tx_queue = rt2x00usb_kick_tx_queue, | 1804 | .kick_tx_queue = rt2x00usb_kick_tx_queue, |
1794 | .kill_tx_queue = rt2x00usb_kill_tx_queue, | 1805 | .kill_tx_queue = rt2500usb_kill_tx_queue, |
1795 | .fill_rxdone = rt2500usb_fill_rxdone, | 1806 | .fill_rxdone = rt2500usb_fill_rxdone, |
1796 | .config_shared_key = rt2500usb_config_key, | 1807 | .config_shared_key = rt2500usb_config_key, |
1797 | .config_pairwise_key = rt2500usb_config_key, | 1808 | .config_pairwise_key = rt2500usb_config_key, |
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index cf1f16bfcd5e..70a5cb86405b 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h | |||
@@ -1859,6 +1859,13 @@ struct mac_iveiv_entry { | |||
1859 | #define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00) | 1859 | #define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00) |
1860 | 1860 | ||
1861 | /* | 1861 | /* |
1862 | * EEPROM Maximum TX power values | ||
1863 | */ | ||
1864 | #define EEPROM_MAX_TX_POWER 0x0027 | ||
1865 | #define EEPROM_MAX_TX_POWER_24GHZ FIELD16(0x00ff) | ||
1866 | #define EEPROM_MAX_TX_POWER_5GHZ FIELD16(0xff00) | ||
1867 | |||
1868 | /* | ||
1862 | * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power. | 1869 | * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power. |
1863 | * This is delta in 40MHZ. | 1870 | * This is delta in 40MHZ. |
1864 | * VALUE: Tx Power dalta value (MAX=4) | 1871 | * VALUE: Tx Power dalta value (MAX=4) |
@@ -1946,6 +1953,8 @@ struct mac_iveiv_entry { | |||
1946 | * TX_OP: 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs | 1953 | * TX_OP: 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs |
1947 | * BW: Channel bandwidth 20MHz or 40 MHz | 1954 | * BW: Channel bandwidth 20MHz or 40 MHz |
1948 | * STBC: 1: STBC support MCS =0-7, 2,3 : RESERVED | 1955 | * STBC: 1: STBC support MCS =0-7, 2,3 : RESERVED |
1956 | * AMPDU: 1: this frame is eligible for AMPDU aggregation, the hw will | ||
1957 | * aggregate consecutive frames with the same RA and QoS TID. | ||
1949 | */ | 1958 | */ |
1950 | #define TXWI_W0_FRAG FIELD32(0x00000001) | 1959 | #define TXWI_W0_FRAG FIELD32(0x00000001) |
1951 | #define TXWI_W0_MIMO_PS FIELD32(0x00000002) | 1960 | #define TXWI_W0_MIMO_PS FIELD32(0x00000002) |
@@ -1969,7 +1978,9 @@ struct mac_iveiv_entry { | |||
1969 | * WIRELESS_CLI_ID: Client ID for WCID table access | 1978 | * WIRELESS_CLI_ID: Client ID for WCID table access |
1970 | * MPDU_TOTAL_BYTE_COUNT: Length of 802.11 frame | 1979 | * MPDU_TOTAL_BYTE_COUNT: Length of 802.11 frame |
1971 | * PACKETID: Will be latched into the TX_STA_FIFO register once the according | 1980 | * PACKETID: Will be latched into the TX_STA_FIFO register once the according |
1972 | * frame was processed. 0: Don't report tx status for this frame. | 1981 | * frame was processed. If multiple frames are aggregated together |
1982 | * (AMPDU==1) the reported tx status will always contain the packet | ||
1983 | * id of the first frame. 0: Don't report tx status for this frame. | ||
1973 | */ | 1984 | */ |
1974 | #define TXWI_W1_ACK FIELD32(0x00000001) | 1985 | #define TXWI_W1_ACK FIELD32(0x00000001) |
1975 | #define TXWI_W1_NSEQ FIELD32(0x00000002) | 1986 | #define TXWI_W1_NSEQ FIELD32(0x00000002) |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 6a0cb2d924d8..27a6e225083c 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -255,6 +255,23 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, | |||
255 | } | 255 | } |
256 | EXPORT_SYMBOL_GPL(rt2800_mcu_request); | 256 | EXPORT_SYMBOL_GPL(rt2800_mcu_request); |
257 | 257 | ||
258 | int rt2800_wait_csr_ready(struct rt2x00_dev *rt2x00dev) | ||
259 | { | ||
260 | unsigned int i = 0; | ||
261 | u32 reg; | ||
262 | |||
263 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
264 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | ||
265 | if (reg && reg != ~0) | ||
266 | return 0; | ||
267 | msleep(1); | ||
268 | } | ||
269 | |||
270 | ERROR(rt2x00dev, "Unstable hardware.\n"); | ||
271 | return -EBUSY; | ||
272 | } | ||
273 | EXPORT_SYMBOL_GPL(rt2800_wait_csr_ready); | ||
274 | |||
258 | int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev) | 275 | int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev) |
259 | { | 276 | { |
260 | unsigned int i; | 277 | unsigned int i; |
@@ -368,19 +385,16 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
368 | u32 reg; | 385 | u32 reg; |
369 | 386 | ||
370 | /* | 387 | /* |
371 | * Wait for stable hardware. | 388 | * If driver doesn't wake up firmware here, |
389 | * rt2800_load_firmware will hang forever when interface is up again. | ||
372 | */ | 390 | */ |
373 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 391 | rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0x00000000); |
374 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | ||
375 | if (reg && reg != ~0) | ||
376 | break; | ||
377 | msleep(1); | ||
378 | } | ||
379 | 392 | ||
380 | if (i == REGISTER_BUSY_COUNT) { | 393 | /* |
381 | ERROR(rt2x00dev, "Unstable hardware.\n"); | 394 | * Wait for stable hardware. |
395 | */ | ||
396 | if (rt2800_wait_csr_ready(rt2x00dev)) | ||
382 | return -EBUSY; | 397 | return -EBUSY; |
383 | } | ||
384 | 398 | ||
385 | if (rt2x00_is_pci(rt2x00dev)) | 399 | if (rt2x00_is_pci(rt2x00dev)) |
386 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); | 400 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); |
@@ -469,7 +483,7 @@ void rt2800_write_tx_data(struct queue_entry *entry, | |||
469 | txdesc->key_idx : 0xff); | 483 | txdesc->key_idx : 0xff); |
470 | rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, | 484 | rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, |
471 | txdesc->length); | 485 | txdesc->length); |
472 | rt2x00_set_field32(&word, TXWI_W1_PACKETID, txdesc->queue + 1); | 486 | rt2x00_set_field32(&word, TXWI_W1_PACKETID, txdesc->qid + 1); |
473 | rt2x00_desc_write(txwi, 1, word); | 487 | rt2x00_desc_write(txwi, 1, word); |
474 | 488 | ||
475 | /* | 489 | /* |
@@ -573,6 +587,49 @@ void rt2800_process_rxwi(struct queue_entry *entry, | |||
573 | } | 587 | } |
574 | EXPORT_SYMBOL_GPL(rt2800_process_rxwi); | 588 | EXPORT_SYMBOL_GPL(rt2800_process_rxwi); |
575 | 589 | ||
590 | static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg) | ||
591 | { | ||
592 | __le32 *txwi; | ||
593 | u32 word; | ||
594 | int wcid, ack, pid; | ||
595 | int tx_wcid, tx_ack, tx_pid; | ||
596 | |||
597 | wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); | ||
598 | ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); | ||
599 | pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); | ||
600 | |||
601 | /* | ||
602 | * This frames has returned with an IO error, | ||
603 | * so the status report is not intended for this | ||
604 | * frame. | ||
605 | */ | ||
606 | if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) { | ||
607 | rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); | ||
608 | return false; | ||
609 | } | ||
610 | |||
611 | /* | ||
612 | * Validate if this TX status report is intended for | ||
613 | * this entry by comparing the WCID/ACK/PID fields. | ||
614 | */ | ||
615 | txwi = rt2800_drv_get_txwi(entry); | ||
616 | |||
617 | rt2x00_desc_read(txwi, 1, &word); | ||
618 | tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); | ||
619 | tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); | ||
620 | tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); | ||
621 | |||
622 | if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) { | ||
623 | WARNING(entry->queue->rt2x00dev, | ||
624 | "TX status report missed for queue %d entry %d\n", | ||
625 | entry->queue->qid, entry->entry_idx); | ||
626 | rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); | ||
627 | return false; | ||
628 | } | ||
629 | |||
630 | return true; | ||
631 | } | ||
632 | |||
576 | void rt2800_txdone(struct rt2x00_dev *rt2x00dev) | 633 | void rt2800_txdone(struct rt2x00_dev *rt2x00dev) |
577 | { | 634 | { |
578 | struct data_queue *queue; | 635 | struct data_queue *queue; |
@@ -581,8 +638,8 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) | |||
581 | struct txdone_entry_desc txdesc; | 638 | struct txdone_entry_desc txdesc; |
582 | u32 word; | 639 | u32 word; |
583 | u32 reg; | 640 | u32 reg; |
584 | int wcid, ack, pid, tx_wcid, tx_ack, tx_pid; | ||
585 | u16 mcs, real_mcs; | 641 | u16 mcs, real_mcs; |
642 | u8 pid; | ||
586 | int i; | 643 | int i; |
587 | 644 | ||
588 | /* | 645 | /* |
@@ -599,18 +656,15 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) | |||
599 | if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) | 656 | if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) |
600 | break; | 657 | break; |
601 | 658 | ||
602 | wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); | ||
603 | ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); | ||
604 | pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); | ||
605 | |||
606 | /* | 659 | /* |
607 | * Skip this entry when it contains an invalid | 660 | * Skip this entry when it contains an invalid |
608 | * queue identication number. | 661 | * queue identication number. |
609 | */ | 662 | */ |
610 | if (pid <= 0 || pid > QID_RX) | 663 | pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE) - 1; |
664 | if (pid >= QID_RX) | ||
611 | continue; | 665 | continue; |
612 | 666 | ||
613 | queue = rt2x00queue_get_queue(rt2x00dev, pid - 1); | 667 | queue = rt2x00queue_get_queue(rt2x00dev, pid); |
614 | if (unlikely(!queue)) | 668 | if (unlikely(!queue)) |
615 | continue; | 669 | continue; |
616 | 670 | ||
@@ -619,38 +673,24 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) | |||
619 | * order. We first check that the queue is not empty. | 673 | * order. We first check that the queue is not empty. |
620 | */ | 674 | */ |
621 | entry = NULL; | 675 | entry = NULL; |
676 | txwi = NULL; | ||
622 | while (!rt2x00queue_empty(queue)) { | 677 | while (!rt2x00queue_empty(queue)) { |
623 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | 678 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
624 | if (!test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) | 679 | if (rt2800_txdone_entry_check(entry, reg)) |
625 | break; | 680 | break; |
626 | |||
627 | rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); | ||
628 | } | 681 | } |
629 | 682 | ||
630 | if (!entry || rt2x00queue_empty(queue)) | 683 | if (!entry || rt2x00queue_empty(queue)) |
631 | break; | 684 | break; |
632 | 685 | ||
633 | /* | ||
634 | * Check if we got a match by looking at WCID/ACK/PID | ||
635 | * fields | ||
636 | */ | ||
637 | txwi = rt2800_drv_get_txwi(entry); | ||
638 | |||
639 | rt2x00_desc_read(txwi, 1, &word); | ||
640 | tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); | ||
641 | tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); | ||
642 | tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); | ||
643 | |||
644 | if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) | ||
645 | WARNING(rt2x00dev, "invalid TX_STA_FIFO content"); | ||
646 | 686 | ||
647 | /* | 687 | /* |
648 | * Obtain the status about this packet. | 688 | * Obtain the status about this packet. |
649 | */ | 689 | */ |
650 | txdesc.flags = 0; | 690 | txdesc.flags = 0; |
691 | txwi = rt2800_drv_get_txwi(entry); | ||
651 | rt2x00_desc_read(txwi, 0, &word); | 692 | rt2x00_desc_read(txwi, 0, &word); |
652 | mcs = rt2x00_get_field32(word, TXWI_W0_MCS); | 693 | mcs = rt2x00_get_field32(word, TXWI_W0_MCS); |
653 | mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); | ||
654 | real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); | 694 | real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); |
655 | 695 | ||
656 | /* | 696 | /* |
@@ -1095,19 +1135,23 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, | |||
1095 | } | 1135 | } |
1096 | 1136 | ||
1097 | if (flags & CONFIG_UPDATE_MAC) { | 1137 | if (flags & CONFIG_UPDATE_MAC) { |
1098 | reg = le32_to_cpu(conf->mac[1]); | 1138 | if (!is_zero_ether_addr((const u8 *)conf->mac)) { |
1099 | rt2x00_set_field32(®, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff); | 1139 | reg = le32_to_cpu(conf->mac[1]); |
1100 | conf->mac[1] = cpu_to_le32(reg); | 1140 | rt2x00_set_field32(®, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff); |
1141 | conf->mac[1] = cpu_to_le32(reg); | ||
1142 | } | ||
1101 | 1143 | ||
1102 | rt2800_register_multiwrite(rt2x00dev, MAC_ADDR_DW0, | 1144 | rt2800_register_multiwrite(rt2x00dev, MAC_ADDR_DW0, |
1103 | conf->mac, sizeof(conf->mac)); | 1145 | conf->mac, sizeof(conf->mac)); |
1104 | } | 1146 | } |
1105 | 1147 | ||
1106 | if (flags & CONFIG_UPDATE_BSSID) { | 1148 | if (flags & CONFIG_UPDATE_BSSID) { |
1107 | reg = le32_to_cpu(conf->bssid[1]); | 1149 | if (!is_zero_ether_addr((const u8 *)conf->bssid)) { |
1108 | rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 3); | 1150 | reg = le32_to_cpu(conf->bssid[1]); |
1109 | rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 7); | 1151 | rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 3); |
1110 | conf->bssid[1] = cpu_to_le32(reg); | 1152 | rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 7); |
1153 | conf->bssid[1] = cpu_to_le32(reg); | ||
1154 | } | ||
1111 | 1155 | ||
1112 | rt2800_register_multiwrite(rt2x00dev, MAC_BSSID_DW0, | 1156 | rt2800_register_multiwrite(rt2x00dev, MAC_BSSID_DW0, |
1113 | conf->bssid, sizeof(conf->bssid)); | 1157 | conf->bssid, sizeof(conf->bssid)); |
@@ -1240,27 +1284,23 @@ static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev, | |||
1240 | * double meaning, and we should set a 7DBm boost flag. | 1284 | * double meaning, and we should set a 7DBm boost flag. |
1241 | */ | 1285 | */ |
1242 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST, | 1286 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST, |
1243 | (info->tx_power1 >= 0)); | 1287 | (info->default_power1 >= 0)); |
1244 | 1288 | ||
1245 | if (info->tx_power1 < 0) | 1289 | if (info->default_power1 < 0) |
1246 | info->tx_power1 += 7; | 1290 | info->default_power1 += 7; |
1247 | 1291 | ||
1248 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A, | 1292 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A, info->default_power1); |
1249 | TXPOWER_A_TO_DEV(info->tx_power1)); | ||
1250 | 1293 | ||
1251 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST, | 1294 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST, |
1252 | (info->tx_power2 >= 0)); | 1295 | (info->default_power2 >= 0)); |
1253 | 1296 | ||
1254 | if (info->tx_power2 < 0) | 1297 | if (info->default_power2 < 0) |
1255 | info->tx_power2 += 7; | 1298 | info->default_power2 += 7; |
1256 | 1299 | ||
1257 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A, | 1300 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A, info->default_power2); |
1258 | TXPOWER_A_TO_DEV(info->tx_power2)); | ||
1259 | } else { | 1301 | } else { |
1260 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G, | 1302 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G, info->default_power1); |
1261 | TXPOWER_G_TO_DEV(info->tx_power1)); | 1303 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G, info->default_power2); |
1262 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G, | ||
1263 | TXPOWER_G_TO_DEV(info->tx_power2)); | ||
1264 | } | 1304 | } |
1265 | 1305 | ||
1266 | rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf)); | 1306 | rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf)); |
@@ -1300,13 +1340,11 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, | |||
1300 | rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); | 1340 | rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); |
1301 | 1341 | ||
1302 | rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr); | 1342 | rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr); |
1303 | rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, | 1343 | rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, info->default_power1); |
1304 | TXPOWER_G_TO_DEV(info->tx_power1)); | ||
1305 | rt2800_rfcsr_write(rt2x00dev, 12, rfcsr); | 1344 | rt2800_rfcsr_write(rt2x00dev, 12, rfcsr); |
1306 | 1345 | ||
1307 | rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr); | 1346 | rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr); |
1308 | rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, | 1347 | rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, info->default_power2); |
1309 | TXPOWER_G_TO_DEV(info->tx_power2)); | ||
1310 | rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); | 1348 | rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); |
1311 | 1349 | ||
1312 | rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); | 1350 | rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); |
@@ -1330,10 +1368,19 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
1330 | unsigned int tx_pin; | 1368 | unsigned int tx_pin; |
1331 | u8 bbp; | 1369 | u8 bbp; |
1332 | 1370 | ||
1371 | if (rf->channel <= 14) { | ||
1372 | info->default_power1 = TXPOWER_G_TO_DEV(info->default_power1); | ||
1373 | info->default_power2 = TXPOWER_G_TO_DEV(info->default_power2); | ||
1374 | } else { | ||
1375 | info->default_power1 = TXPOWER_A_TO_DEV(info->default_power1); | ||
1376 | info->default_power2 = TXPOWER_A_TO_DEV(info->default_power2); | ||
1377 | } | ||
1378 | |||
1333 | if (rt2x00_rf(rt2x00dev, RF2020) || | 1379 | if (rt2x00_rf(rt2x00dev, RF2020) || |
1334 | rt2x00_rf(rt2x00dev, RF3020) || | 1380 | rt2x00_rf(rt2x00dev, RF3020) || |
1335 | rt2x00_rf(rt2x00dev, RF3021) || | 1381 | rt2x00_rf(rt2x00dev, RF3021) || |
1336 | rt2x00_rf(rt2x00dev, RF3022)) | 1382 | rt2x00_rf(rt2x00dev, RF3022) || |
1383 | rt2x00_rf(rt2x00dev, RF3052)) | ||
1337 | rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); | 1384 | rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); |
1338 | else | 1385 | else |
1339 | rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); | 1386 | rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); |
@@ -1656,7 +1703,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner); | |||
1656 | /* | 1703 | /* |
1657 | * Initialization functions. | 1704 | * Initialization functions. |
1658 | */ | 1705 | */ |
1659 | int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | 1706 | static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) |
1660 | { | 1707 | { |
1661 | u32 reg; | 1708 | u32 reg; |
1662 | u16 eeprom; | 1709 | u16 eeprom; |
@@ -2026,7 +2073,6 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
2026 | 2073 | ||
2027 | return 0; | 2074 | return 0; |
2028 | } | 2075 | } |
2029 | EXPORT_SYMBOL_GPL(rt2800_init_registers); | ||
2030 | 2076 | ||
2031 | static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev) | 2077 | static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev) |
2032 | { | 2078 | { |
@@ -2069,7 +2115,7 @@ static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) | |||
2069 | return -EACCES; | 2115 | return -EACCES; |
2070 | } | 2116 | } |
2071 | 2117 | ||
2072 | int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | 2118 | static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) |
2073 | { | 2119 | { |
2074 | unsigned int i; | 2120 | unsigned int i; |
2075 | u16 eeprom; | 2121 | u16 eeprom; |
@@ -2164,7 +2210,6 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
2164 | 2210 | ||
2165 | return 0; | 2211 | return 0; |
2166 | } | 2212 | } |
2167 | EXPORT_SYMBOL_GPL(rt2800_init_bbp); | ||
2168 | 2213 | ||
2169 | static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, | 2214 | static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, |
2170 | bool bw40, u8 rfcsr24, u8 filter_target) | 2215 | bool bw40, u8 rfcsr24, u8 filter_target) |
@@ -2226,7 +2271,7 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, | |||
2226 | return rfcsr24; | 2271 | return rfcsr24; |
2227 | } | 2272 | } |
2228 | 2273 | ||
2229 | int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | 2274 | static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) |
2230 | { | 2275 | { |
2231 | u8 rfcsr; | 2276 | u8 rfcsr; |
2232 | u8 bbp; | 2277 | u8 bbp; |
@@ -2480,7 +2525,100 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
2480 | 2525 | ||
2481 | return 0; | 2526 | return 0; |
2482 | } | 2527 | } |
2483 | EXPORT_SYMBOL_GPL(rt2800_init_rfcsr); | 2528 | |
2529 | int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev) | ||
2530 | { | ||
2531 | u32 reg; | ||
2532 | u16 word; | ||
2533 | |||
2534 | /* | ||
2535 | * Initialize all registers. | ||
2536 | */ | ||
2537 | if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || | ||
2538 | rt2800_init_registers(rt2x00dev) || | ||
2539 | rt2800_init_bbp(rt2x00dev) || | ||
2540 | rt2800_init_rfcsr(rt2x00dev))) | ||
2541 | return -EIO; | ||
2542 | |||
2543 | /* | ||
2544 | * Send signal to firmware during boot time. | ||
2545 | */ | ||
2546 | rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); | ||
2547 | |||
2548 | if (rt2x00_is_usb(rt2x00dev) && | ||
2549 | (rt2x00_rt(rt2x00dev, RT3070) || | ||
2550 | rt2x00_rt(rt2x00dev, RT3071) || | ||
2551 | rt2x00_rt(rt2x00dev, RT3572))) { | ||
2552 | udelay(200); | ||
2553 | rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0); | ||
2554 | udelay(10); | ||
2555 | } | ||
2556 | |||
2557 | /* | ||
2558 | * Enable RX. | ||
2559 | */ | ||
2560 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
2561 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); | ||
2562 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); | ||
2563 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
2564 | |||
2565 | udelay(50); | ||
2566 | |||
2567 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); | ||
2568 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1); | ||
2569 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1); | ||
2570 | rt2x00_set_field32(®, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 2); | ||
2571 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); | ||
2572 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); | ||
2573 | |||
2574 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
2575 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); | ||
2576 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); | ||
2577 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
2578 | |||
2579 | /* | ||
2580 | * Initialize LED control | ||
2581 | */ | ||
2582 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word); | ||
2583 | rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff, | ||
2584 | word & 0xff, (word >> 8) & 0xff); | ||
2585 | |||
2586 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word); | ||
2587 | rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff, | ||
2588 | word & 0xff, (word >> 8) & 0xff); | ||
2589 | |||
2590 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word); | ||
2591 | rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff, | ||
2592 | word & 0xff, (word >> 8) & 0xff); | ||
2593 | |||
2594 | return 0; | ||
2595 | } | ||
2596 | EXPORT_SYMBOL_GPL(rt2800_enable_radio); | ||
2597 | |||
2598 | void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev) | ||
2599 | { | ||
2600 | u32 reg; | ||
2601 | |||
2602 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); | ||
2603 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); | ||
2604 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0); | ||
2605 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); | ||
2606 | rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0); | ||
2607 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); | ||
2608 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); | ||
2609 | |||
2610 | /* Wait for DMA, ignore error */ | ||
2611 | rt2800_wait_wpdma_ready(rt2x00dev); | ||
2612 | |||
2613 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
2614 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 0); | ||
2615 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); | ||
2616 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
2617 | |||
2618 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0); | ||
2619 | rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); | ||
2620 | } | ||
2621 | EXPORT_SYMBOL_GPL(rt2800_disable_radio); | ||
2484 | 2622 | ||
2485 | int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev) | 2623 | int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev) |
2486 | { | 2624 | { |
@@ -2636,6 +2774,13 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2636 | default_lna_gain); | 2774 | default_lna_gain); |
2637 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); | 2775 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); |
2638 | 2776 | ||
2777 | rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &word); | ||
2778 | if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_24GHZ) == 0xff) | ||
2779 | rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_24GHZ, MAX_G_TXPOWER); | ||
2780 | if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_5GHZ) == 0xff) | ||
2781 | rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_5GHZ, MAX_A_TXPOWER); | ||
2782 | rt2x00_eeprom_write(rt2x00dev, EEPROM_MAX_TX_POWER, word); | ||
2783 | |||
2639 | return 0; | 2784 | return 0; |
2640 | } | 2785 | } |
2641 | EXPORT_SYMBOL_GPL(rt2800_validate_eeprom); | 2786 | EXPORT_SYMBOL_GPL(rt2800_validate_eeprom); |
@@ -2875,9 +3020,10 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2875 | { | 3020 | { |
2876 | struct hw_mode_spec *spec = &rt2x00dev->spec; | 3021 | struct hw_mode_spec *spec = &rt2x00dev->spec; |
2877 | struct channel_info *info; | 3022 | struct channel_info *info; |
2878 | char *tx_power1; | 3023 | char *default_power1; |
2879 | char *tx_power2; | 3024 | char *default_power2; |
2880 | unsigned int i; | 3025 | unsigned int i; |
3026 | unsigned short max_power; | ||
2881 | u16 eeprom; | 3027 | u16 eeprom; |
2882 | 3028 | ||
2883 | /* | 3029 | /* |
@@ -2991,21 +3137,26 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2991 | 3137 | ||
2992 | spec->channels_info = info; | 3138 | spec->channels_info = info; |
2993 | 3139 | ||
2994 | tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); | 3140 | rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &eeprom); |
2995 | tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); | 3141 | max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_24GHZ); |
3142 | default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); | ||
3143 | default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); | ||
2996 | 3144 | ||
2997 | for (i = 0; i < 14; i++) { | 3145 | for (i = 0; i < 14; i++) { |
2998 | info[i].tx_power1 = TXPOWER_G_FROM_DEV(tx_power1[i]); | 3146 | info[i].max_power = max_power; |
2999 | info[i].tx_power2 = TXPOWER_G_FROM_DEV(tx_power2[i]); | 3147 | info[i].default_power1 = TXPOWER_G_FROM_DEV(default_power1[i]); |
3148 | info[i].default_power2 = TXPOWER_G_FROM_DEV(default_power2[i]); | ||
3000 | } | 3149 | } |
3001 | 3150 | ||
3002 | if (spec->num_channels > 14) { | 3151 | if (spec->num_channels > 14) { |
3003 | tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); | 3152 | max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_5GHZ); |
3004 | tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); | 3153 | default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); |
3154 | default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); | ||
3005 | 3155 | ||
3006 | for (i = 14; i < spec->num_channels; i++) { | 3156 | for (i = 14; i < spec->num_channels; i++) { |
3007 | info[i].tx_power1 = TXPOWER_A_FROM_DEV(tx_power1[i]); | 3157 | info[i].max_power = max_power; |
3008 | info[i].tx_power2 = TXPOWER_A_FROM_DEV(tx_power2[i]); | 3158 | info[i].default_power1 = TXPOWER_A_FROM_DEV(default_power1[i]); |
3159 | info[i].default_power2 = TXPOWER_A_FROM_DEV(default_power2[i]); | ||
3009 | } | 3160 | } |
3010 | } | 3161 | } |
3011 | 3162 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index 3b572c63382d..986229c06c19 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h | |||
@@ -140,6 +140,9 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, | |||
140 | const u8 command, const u8 token, | 140 | const u8 command, const u8 token, |
141 | const u8 arg0, const u8 arg1); | 141 | const u8 arg0, const u8 arg1); |
142 | 142 | ||
143 | int rt2800_wait_csr_ready(struct rt2x00_dev *rt2x00dev); | ||
144 | int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev); | ||
145 | |||
143 | int rt2800_check_firmware(struct rt2x00_dev *rt2x00dev, | 146 | int rt2800_check_firmware(struct rt2x00_dev *rt2x00dev, |
144 | const u8 *data, const size_t len); | 147 | const u8 *data, const size_t len); |
145 | int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, | 148 | int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, |
@@ -176,10 +179,8 @@ void rt2800_reset_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual); | |||
176 | void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual, | 179 | void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual, |
177 | const u32 count); | 180 | const u32 count); |
178 | 181 | ||
179 | int rt2800_init_registers(struct rt2x00_dev *rt2x00dev); | 182 | int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev); |
180 | int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev); | 183 | void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev); |
181 | int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev); | ||
182 | int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev); | ||
183 | 184 | ||
184 | int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev); | 185 | int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev); |
185 | void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev); | 186 | void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 4390f2b74b2e..2bcb1507e3ac 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -196,8 +196,6 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev, | |||
196 | { | 196 | { |
197 | u32 reg; | 197 | u32 reg; |
198 | 198 | ||
199 | rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0x00000000); | ||
200 | |||
201 | /* | 199 | /* |
202 | * enable Host program ram write selection | 200 | * enable Host program ram write selection |
203 | */ | 201 | */ |
@@ -399,78 +397,18 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
399 | 397 | ||
400 | static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) | 398 | static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) |
401 | { | 399 | { |
402 | u32 reg; | ||
403 | u16 word; | ||
404 | |||
405 | /* | ||
406 | * Initialize all registers. | ||
407 | */ | ||
408 | if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || | 400 | if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || |
409 | rt2800pci_init_queues(rt2x00dev) || | 401 | rt2800pci_init_queues(rt2x00dev))) |
410 | rt2800_init_registers(rt2x00dev) || | ||
411 | rt2800_wait_wpdma_ready(rt2x00dev) || | ||
412 | rt2800_init_bbp(rt2x00dev) || | ||
413 | rt2800_init_rfcsr(rt2x00dev))) | ||
414 | return -EIO; | 402 | return -EIO; |
415 | 403 | ||
416 | /* | 404 | return rt2800_enable_radio(rt2x00dev); |
417 | * Send signal to firmware during boot time. | ||
418 | */ | ||
419 | rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); | ||
420 | |||
421 | /* | ||
422 | * Enable RX. | ||
423 | */ | ||
424 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
425 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); | ||
426 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); | ||
427 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
428 | |||
429 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); | ||
430 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1); | ||
431 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1); | ||
432 | rt2x00_set_field32(®, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 2); | ||
433 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); | ||
434 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); | ||
435 | |||
436 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
437 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); | ||
438 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); | ||
439 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
440 | |||
441 | /* | ||
442 | * Initialize LED control | ||
443 | */ | ||
444 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word); | ||
445 | rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff, | ||
446 | word & 0xff, (word >> 8) & 0xff); | ||
447 | |||
448 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word); | ||
449 | rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff, | ||
450 | word & 0xff, (word >> 8) & 0xff); | ||
451 | |||
452 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word); | ||
453 | rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff, | ||
454 | word & 0xff, (word >> 8) & 0xff); | ||
455 | |||
456 | return 0; | ||
457 | } | 405 | } |
458 | 406 | ||
459 | static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev) | 407 | static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev) |
460 | { | 408 | { |
461 | u32 reg; | 409 | u32 reg; |
462 | 410 | ||
463 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); | 411 | rt2800_disable_radio(rt2x00dev); |
464 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); | ||
465 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0); | ||
466 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); | ||
467 | rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0); | ||
468 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); | ||
469 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); | ||
470 | |||
471 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0); | ||
472 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0); | ||
473 | rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); | ||
474 | 412 | ||
475 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001280); | 413 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001280); |
476 | 414 | ||
@@ -486,9 +424,6 @@ static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
486 | 424 | ||
487 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); | 425 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); |
488 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); | 426 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); |
489 | |||
490 | /* Wait for DMA, ignore error */ | ||
491 | rt2800_wait_wpdma_ready(rt2x00dev); | ||
492 | } | 427 | } |
493 | 428 | ||
494 | static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev, | 429 | static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev, |
@@ -571,12 +506,11 @@ static __le32 *rt2800pci_get_txwi(struct queue_entry *entry) | |||
571 | return (__le32 *) entry->skb->data; | 506 | return (__le32 *) entry->skb->data; |
572 | } | 507 | } |
573 | 508 | ||
574 | static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 509 | static void rt2800pci_write_tx_desc(struct queue_entry *entry, |
575 | struct sk_buff *skb, | ||
576 | struct txentry_desc *txdesc) | 510 | struct txentry_desc *txdesc) |
577 | { | 511 | { |
578 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 512 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
579 | struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; | 513 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
580 | __le32 *txd = entry_priv->desc; | 514 | __le32 *txd = entry_priv->desc; |
581 | u32 word; | 515 | u32 word; |
582 | 516 | ||
@@ -596,7 +530,7 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
596 | rt2x00_desc_write(txd, 0, word); | 530 | rt2x00_desc_write(txd, 0, word); |
597 | 531 | ||
598 | rt2x00_desc_read(txd, 1, &word); | 532 | rt2x00_desc_read(txd, 1, &word); |
599 | rt2x00_set_field32(&word, TXD_W1_SD_LEN1, skb->len); | 533 | rt2x00_set_field32(&word, TXD_W1_SD_LEN1, entry->skb->len); |
600 | rt2x00_set_field32(&word, TXD_W1_LAST_SEC1, | 534 | rt2x00_set_field32(&word, TXD_W1_LAST_SEC1, |
601 | !test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); | 535 | !test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
602 | rt2x00_set_field32(&word, TXD_W1_BURST, | 536 | rt2x00_set_field32(&word, TXD_W1_BURST, |
@@ -627,41 +561,35 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
627 | /* | 561 | /* |
628 | * TX data initialization | 562 | * TX data initialization |
629 | */ | 563 | */ |
630 | static void rt2800pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 564 | static void rt2800pci_kick_tx_queue(struct data_queue *queue) |
631 | const enum data_queue_qid queue_idx) | ||
632 | { | 565 | { |
633 | struct data_queue *queue; | 566 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; |
634 | unsigned int idx, qidx = 0; | 567 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); |
635 | 568 | unsigned int qidx = 0; | |
636 | if (queue_idx > QID_HCCA && queue_idx != QID_MGMT) | ||
637 | return; | ||
638 | |||
639 | queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); | ||
640 | idx = queue->index[Q_INDEX]; | ||
641 | 569 | ||
642 | if (queue_idx == QID_MGMT) | 570 | if (queue->qid == QID_MGMT) |
643 | qidx = 5; | 571 | qidx = 5; |
644 | else | 572 | else |
645 | qidx = queue_idx; | 573 | qidx = queue->qid; |
646 | 574 | ||
647 | rt2800_register_write(rt2x00dev, TX_CTX_IDX(qidx), idx); | 575 | rt2800_register_write(rt2x00dev, TX_CTX_IDX(qidx), entry->entry_idx); |
648 | } | 576 | } |
649 | 577 | ||
650 | static void rt2800pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, | 578 | static void rt2800pci_kill_tx_queue(struct data_queue *queue) |
651 | const enum data_queue_qid qid) | ||
652 | { | 579 | { |
580 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
653 | u32 reg; | 581 | u32 reg; |
654 | 582 | ||
655 | if (qid == QID_BEACON) { | 583 | if (queue->qid == QID_BEACON) { |
656 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, 0); | 584 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, 0); |
657 | return; | 585 | return; |
658 | } | 586 | } |
659 | 587 | ||
660 | rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, ®); | 588 | rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, ®); |
661 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, (qid == QID_AC_BE)); | 589 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, (queue->qid == QID_AC_BE)); |
662 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, (qid == QID_AC_BK)); | 590 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, (queue->qid == QID_AC_BK)); |
663 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, (qid == QID_AC_VI)); | 591 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, (queue->qid == QID_AC_VI)); |
664 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX3, (qid == QID_AC_VO)); | 592 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX3, (queue->qid == QID_AC_VO)); |
665 | rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg); | 593 | rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg); |
666 | } | 594 | } |
667 | 595 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 9ad28be294eb..3dff56ec195a 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -101,19 +101,6 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev, | |||
101 | msleep(10); | 101 | msleep(10); |
102 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); | 102 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); |
103 | 103 | ||
104 | /* | ||
105 | * Send signal to firmware during boot time. | ||
106 | */ | ||
107 | rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); | ||
108 | |||
109 | if (rt2x00_rt(rt2x00dev, RT3070) || | ||
110 | rt2x00_rt(rt2x00dev, RT3071) || | ||
111 | rt2x00_rt(rt2x00dev, RT3572)) { | ||
112 | udelay(200); | ||
113 | rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0); | ||
114 | udelay(10); | ||
115 | } | ||
116 | |||
117 | return 0; | 104 | return 0; |
118 | } | 105 | } |
119 | 106 | ||
@@ -135,26 +122,18 @@ static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev, | |||
135 | static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) | 122 | static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) |
136 | { | 123 | { |
137 | u32 reg; | 124 | u32 reg; |
138 | int i; | ||
139 | 125 | ||
140 | /* | 126 | /* |
141 | * Wait until BBP and RF are ready. | 127 | * Wait until BBP and RF are ready. |
142 | */ | 128 | */ |
143 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 129 | if (rt2800_wait_csr_ready(rt2x00dev)) |
144 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | ||
145 | if (reg && reg != ~0) | ||
146 | break; | ||
147 | msleep(1); | ||
148 | } | ||
149 | |||
150 | if (i == REGISTER_BUSY_COUNT) { | ||
151 | ERROR(rt2x00dev, "Unstable hardware.\n"); | ||
152 | return -EBUSY; | 130 | return -EBUSY; |
153 | } | ||
154 | 131 | ||
155 | rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); | 132 | rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); |
156 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); | 133 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); |
157 | 134 | ||
135 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); | ||
136 | |||
158 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | 137 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); |
159 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); | 138 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); |
160 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); | 139 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); |
@@ -173,30 +152,10 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
173 | static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) | 152 | static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) |
174 | { | 153 | { |
175 | u32 reg; | 154 | u32 reg; |
176 | u16 word; | ||
177 | 155 | ||
178 | /* | 156 | if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev))) |
179 | * Initialize all registers. | ||
180 | */ | ||
181 | if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || | ||
182 | rt2800_init_registers(rt2x00dev) || | ||
183 | rt2800_init_bbp(rt2x00dev) || | ||
184 | rt2800_init_rfcsr(rt2x00dev))) | ||
185 | return -EIO; | 157 | return -EIO; |
186 | 158 | ||
187 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
188 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); | ||
189 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
190 | |||
191 | udelay(50); | ||
192 | |||
193 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); | ||
194 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); | ||
195 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1); | ||
196 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1); | ||
197 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); | ||
198 | |||
199 | |||
200 | rt2800_register_read(rt2x00dev, USB_DMA_CFG, ®); | 159 | rt2800_register_read(rt2x00dev, USB_DMA_CFG, ®); |
201 | rt2x00_set_field32(®, USB_DMA_CFG_PHY_CLEAR, 0); | 160 | rt2x00_set_field32(®, USB_DMA_CFG_PHY_CLEAR, 0); |
202 | rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_AGG_EN, 0); | 161 | rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_AGG_EN, 0); |
@@ -211,45 +170,12 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
211 | rt2x00_set_field32(®, USB_DMA_CFG_TX_BULK_EN, 1); | 170 | rt2x00_set_field32(®, USB_DMA_CFG_TX_BULK_EN, 1); |
212 | rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg); | 171 | rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg); |
213 | 172 | ||
214 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | 173 | return rt2800_enable_radio(rt2x00dev); |
215 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); | ||
216 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); | ||
217 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
218 | |||
219 | /* | ||
220 | * Initialize LED control | ||
221 | */ | ||
222 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word); | ||
223 | rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff, | ||
224 | word & 0xff, (word >> 8) & 0xff); | ||
225 | |||
226 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word); | ||
227 | rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff, | ||
228 | word & 0xff, (word >> 8) & 0xff); | ||
229 | |||
230 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word); | ||
231 | rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff, | ||
232 | word & 0xff, (word >> 8) & 0xff); | ||
233 | |||
234 | return 0; | ||
235 | } | 174 | } |
236 | 175 | ||
237 | static void rt2800usb_disable_radio(struct rt2x00_dev *rt2x00dev) | 176 | static void rt2800usb_disable_radio(struct rt2x00_dev *rt2x00dev) |
238 | { | 177 | { |
239 | u32 reg; | 178 | rt2800_disable_radio(rt2x00dev); |
240 | |||
241 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); | ||
242 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); | ||
243 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); | ||
244 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); | ||
245 | |||
246 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0); | ||
247 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0); | ||
248 | rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); | ||
249 | |||
250 | /* Wait for DMA, ignore error */ | ||
251 | rt2800_wait_wpdma_ready(rt2x00dev); | ||
252 | |||
253 | rt2x00usb_disable_radio(rt2x00dev); | 179 | rt2x00usb_disable_radio(rt2x00dev); |
254 | } | 180 | } |
255 | 181 | ||
@@ -329,12 +255,11 @@ static __le32 *rt2800usb_get_txwi(struct queue_entry *entry) | |||
329 | return (__le32 *) (entry->skb->data + TXINFO_DESC_SIZE); | 255 | return (__le32 *) (entry->skb->data + TXINFO_DESC_SIZE); |
330 | } | 256 | } |
331 | 257 | ||
332 | static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 258 | static void rt2800usb_write_tx_desc(struct queue_entry *entry, |
333 | struct sk_buff *skb, | ||
334 | struct txentry_desc *txdesc) | 259 | struct txentry_desc *txdesc) |
335 | { | 260 | { |
336 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 261 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
337 | __le32 *txi = (__le32 *) skb->data; | 262 | __le32 *txi = (__le32 *) entry->skb->data; |
338 | u32 word; | 263 | u32 word; |
339 | 264 | ||
340 | /* | 265 | /* |
@@ -342,7 +267,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
342 | */ | 267 | */ |
343 | rt2x00_desc_read(txi, 0, &word); | 268 | rt2x00_desc_read(txi, 0, &word); |
344 | rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, | 269 | rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, |
345 | skb->len - TXINFO_DESC_SIZE); | 270 | entry->skb->len - TXINFO_DESC_SIZE); |
346 | rt2x00_set_field32(&word, TXINFO_W0_WIV, | 271 | rt2x00_set_field32(&word, TXINFO_W0_WIV, |
347 | !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); | 272 | !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); |
348 | rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); | 273 | rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); |
@@ -410,6 +335,14 @@ static void rt2800usb_work_txdone(struct work_struct *work) | |||
410 | } | 335 | } |
411 | } | 336 | } |
412 | 337 | ||
338 | static void rt2800usb_kill_tx_queue(struct data_queue *queue) | ||
339 | { | ||
340 | if (queue->qid == QID_BEACON) | ||
341 | rt2x00usb_register_write(queue->rt2x00dev, BCN_TIME_CFG, 0); | ||
342 | |||
343 | rt2x00usb_kill_tx_queue(queue); | ||
344 | } | ||
345 | |||
413 | /* | 346 | /* |
414 | * RX control handlers | 347 | * RX control handlers |
415 | */ | 348 | */ |
@@ -608,7 +541,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { | |||
608 | .write_beacon = rt2800_write_beacon, | 541 | .write_beacon = rt2800_write_beacon, |
609 | .get_tx_data_len = rt2800usb_get_tx_data_len, | 542 | .get_tx_data_len = rt2800usb_get_tx_data_len, |
610 | .kick_tx_queue = rt2x00usb_kick_tx_queue, | 543 | .kick_tx_queue = rt2x00usb_kick_tx_queue, |
611 | .kill_tx_queue = rt2x00usb_kill_tx_queue, | 544 | .kill_tx_queue = rt2800usb_kill_tx_queue, |
612 | .fill_rxdone = rt2800usb_fill_rxdone, | 545 | .fill_rxdone = rt2800usb_fill_rxdone, |
613 | .config_shared_key = rt2800_config_shared_key, | 546 | .config_shared_key = rt2800_config_shared_key, |
614 | .config_pairwise_key = rt2800_config_pairwise_key, | 547 | .config_pairwise_key = rt2800_config_pairwise_key, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 8c65244a847a..0ae942cb66df 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -213,8 +213,9 @@ struct channel_info { | |||
213 | unsigned int flags; | 213 | unsigned int flags; |
214 | #define GEOGRAPHY_ALLOWED 0x00000001 | 214 | #define GEOGRAPHY_ALLOWED 0x00000001 |
215 | 215 | ||
216 | short tx_power1; | 216 | short max_power; |
217 | short tx_power2; | 217 | short default_power1; |
218 | short default_power2; | ||
218 | }; | 219 | }; |
219 | 220 | ||
220 | /* | 221 | /* |
@@ -559,18 +560,15 @@ struct rt2x00lib_ops { | |||
559 | /* | 560 | /* |
560 | * TX control handlers | 561 | * TX control handlers |
561 | */ | 562 | */ |
562 | void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, | 563 | void (*write_tx_desc) (struct queue_entry *entry, |
563 | struct sk_buff *skb, | ||
564 | struct txentry_desc *txdesc); | 564 | struct txentry_desc *txdesc); |
565 | void (*write_tx_data) (struct queue_entry *entry, | 565 | void (*write_tx_data) (struct queue_entry *entry, |
566 | struct txentry_desc *txdesc); | 566 | struct txentry_desc *txdesc); |
567 | void (*write_beacon) (struct queue_entry *entry, | 567 | void (*write_beacon) (struct queue_entry *entry, |
568 | struct txentry_desc *txdesc); | 568 | struct txentry_desc *txdesc); |
569 | int (*get_tx_data_len) (struct queue_entry *entry); | 569 | int (*get_tx_data_len) (struct queue_entry *entry); |
570 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, | 570 | void (*kick_tx_queue) (struct data_queue *queue); |
571 | const enum data_queue_qid queue); | 571 | void (*kill_tx_queue) (struct data_queue *queue); |
572 | void (*kill_tx_queue) (struct rt2x00_dev *rt2x00dev, | ||
573 | const enum data_queue_qid queue); | ||
574 | 572 | ||
575 | /* | 573 | /* |
576 | * RX control handlers | 574 | * RX control handlers |
@@ -1072,6 +1070,7 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | |||
1072 | */ | 1070 | */ |
1073 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); | 1071 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); |
1074 | void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev); | 1072 | void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev); |
1073 | void rt2x00lib_dmadone(struct queue_entry *entry); | ||
1075 | void rt2x00lib_txdone(struct queue_entry *entry, | 1074 | void rt2x00lib_txdone(struct queue_entry *entry, |
1076 | struct txdone_entry_desc *txdesc); | 1075 | struct txdone_entry_desc *txdesc); |
1077 | void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status); | 1076 | void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index 2d018ceffc54..b8cf45c4e9f5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c | |||
@@ -338,7 +338,7 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file, | |||
338 | return -ENOMEM; | 338 | return -ENOMEM; |
339 | 339 | ||
340 | temp = data + | 340 | temp = data + |
341 | sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdone\tcrypto\n"); | 341 | sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdma done\tdone\n"); |
342 | 342 | ||
343 | queue_for_each(intf->rt2x00dev, queue) { | 343 | queue_for_each(intf->rt2x00dev, queue) { |
344 | spin_lock_irqsave(&queue->lock, irqflags); | 344 | spin_lock_irqsave(&queue->lock, irqflags); |
@@ -346,8 +346,8 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file, | |||
346 | temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid, | 346 | temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid, |
347 | queue->count, queue->limit, queue->length, | 347 | queue->count, queue->limit, queue->length, |
348 | queue->index[Q_INDEX], | 348 | queue->index[Q_INDEX], |
349 | queue->index[Q_INDEX_DONE], | 349 | queue->index[Q_INDEX_DMA_DONE], |
350 | queue->index[Q_INDEX_CRYPTO]); | 350 | queue->index[Q_INDEX_DONE]); |
351 | 351 | ||
352 | spin_unlock_irqrestore(&queue->lock, irqflags); | 352 | spin_unlock_irqrestore(&queue->lock, irqflags); |
353 | } | 353 | } |
@@ -481,6 +481,9 @@ static ssize_t rt2x00debug_write_##__name(struct file *file, \ | |||
481 | if (index >= debug->__name.word_count) \ | 481 | if (index >= debug->__name.word_count) \ |
482 | return -EINVAL; \ | 482 | return -EINVAL; \ |
483 | \ | 483 | \ |
484 | if (length > sizeof(line)) \ | ||
485 | return -EINVAL; \ | ||
486 | \ | ||
484 | if (copy_from_user(line, buf, length)) \ | 487 | if (copy_from_user(line, buf, length)) \ |
485 | return -EFAULT; \ | 488 | return -EFAULT; \ |
486 | \ | 489 | \ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index e692608bee8b..053fdd3bd720 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -251,6 +251,12 @@ void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev) | |||
251 | } | 251 | } |
252 | EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); | 252 | EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); |
253 | 253 | ||
254 | void rt2x00lib_dmadone(struct queue_entry *entry) | ||
255 | { | ||
256 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE); | ||
257 | } | ||
258 | EXPORT_SYMBOL_GPL(rt2x00lib_dmadone); | ||
259 | |||
254 | void rt2x00lib_txdone(struct queue_entry *entry, | 260 | void rt2x00lib_txdone(struct queue_entry *entry, |
255 | struct txdone_entry_desc *txdesc) | 261 | struct txdone_entry_desc *txdesc) |
256 | { | 262 | { |
@@ -711,7 +717,7 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, | |||
711 | for (i = 0; i < spec->num_channels; i++) { | 717 | for (i = 0; i < spec->num_channels; i++) { |
712 | rt2x00lib_channel(&channels[i], | 718 | rt2x00lib_channel(&channels[i], |
713 | spec->channels[i].channel, | 719 | spec->channels[i].channel, |
714 | spec->channels_info[i].tx_power1, i); | 720 | spec->channels_info[i].max_power, i); |
715 | } | 721 | } |
716 | 722 | ||
717 | /* | 723 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 480d33a3ce42..eede99939db9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -312,7 +312,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
312 | /* | 312 | /* |
313 | * Initialize information from queue | 313 | * Initialize information from queue |
314 | */ | 314 | */ |
315 | txdesc->queue = entry->queue->qid; | 315 | txdesc->qid = entry->queue->qid; |
316 | txdesc->cw_min = entry->queue->cw_min; | 316 | txdesc->cw_min = entry->queue->cw_min; |
317 | txdesc->cw_max = entry->queue->cw_max; | 317 | txdesc->cw_max = entry->queue->cw_max; |
318 | txdesc->aifs = entry->queue->aifs; | 318 | txdesc->aifs = entry->queue->aifs; |
@@ -449,15 +449,14 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | |||
449 | struct txentry_desc *txdesc) | 449 | struct txentry_desc *txdesc) |
450 | { | 450 | { |
451 | struct data_queue *queue = entry->queue; | 451 | struct data_queue *queue = entry->queue; |
452 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
453 | 452 | ||
454 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc); | 453 | queue->rt2x00dev->ops->lib->write_tx_desc(entry, txdesc); |
455 | 454 | ||
456 | /* | 455 | /* |
457 | * All processing on the frame has been completed, this means | 456 | * All processing on the frame has been completed, this means |
458 | * it is now ready to be dumped to userspace through debugfs. | 457 | * it is now ready to be dumped to userspace through debugfs. |
459 | */ | 458 | */ |
460 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb); | 459 | rt2x00debug_dump_frame(queue->rt2x00dev, DUMP_FRAME_TX, entry->skb); |
461 | } | 460 | } |
462 | 461 | ||
463 | static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, | 462 | static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, |
@@ -477,7 +476,7 @@ static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, | |||
477 | */ | 476 | */ |
478 | if (rt2x00queue_threshold(queue) || | 477 | if (rt2x00queue_threshold(queue) || |
479 | !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) | 478 | !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) |
480 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid); | 479 | rt2x00dev->ops->lib->kick_tx_queue(queue); |
481 | } | 480 | } |
482 | 481 | ||
483 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | 482 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, |
@@ -591,7 +590,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, | |||
591 | intf->beacon->skb = NULL; | 590 | intf->beacon->skb = NULL; |
592 | 591 | ||
593 | if (!enable_beacon) { | 592 | if (!enable_beacon) { |
594 | rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_BEACON); | 593 | rt2x00dev->ops->lib->kill_tx_queue(intf->beacon->queue); |
595 | mutex_unlock(&intf->beacon_skb_mutex); | 594 | mutex_unlock(&intf->beacon_skb_mutex); |
596 | return 0; | 595 | return 0; |
597 | } | 596 | } |
@@ -626,6 +625,51 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, | |||
626 | return 0; | 625 | return 0; |
627 | } | 626 | } |
628 | 627 | ||
628 | void rt2x00queue_for_each_entry(struct data_queue *queue, | ||
629 | enum queue_index start, | ||
630 | enum queue_index end, | ||
631 | void (*fn)(struct queue_entry *entry)) | ||
632 | { | ||
633 | unsigned long irqflags; | ||
634 | unsigned int index_start; | ||
635 | unsigned int index_end; | ||
636 | unsigned int i; | ||
637 | |||
638 | if (unlikely(start >= Q_INDEX_MAX || end >= Q_INDEX_MAX)) { | ||
639 | ERROR(queue->rt2x00dev, | ||
640 | "Entry requested from invalid index range (%d - %d)\n", | ||
641 | start, end); | ||
642 | return; | ||
643 | } | ||
644 | |||
645 | /* | ||
646 | * Only protect the range we are going to loop over, | ||
647 | * if during our loop a extra entry is set to pending | ||
648 | * it should not be kicked during this run, since it | ||
649 | * is part of another TX operation. | ||
650 | */ | ||
651 | spin_lock_irqsave(&queue->lock, irqflags); | ||
652 | index_start = queue->index[start]; | ||
653 | index_end = queue->index[end]; | ||
654 | spin_unlock_irqrestore(&queue->lock, irqflags); | ||
655 | |||
656 | /* | ||
657 | * Start from the TX done pointer, this guarentees that we will | ||
658 | * send out all frames in the correct order. | ||
659 | */ | ||
660 | if (index_start < index_end) { | ||
661 | for (i = index_start; i < index_end; i++) | ||
662 | fn(&queue->entries[i]); | ||
663 | } else { | ||
664 | for (i = index_start; i < queue->limit; i++) | ||
665 | fn(&queue->entries[i]); | ||
666 | |||
667 | for (i = 0; i < index_end; i++) | ||
668 | fn(&queue->entries[i]); | ||
669 | } | ||
670 | } | ||
671 | EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry); | ||
672 | |||
629 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, | 673 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, |
630 | const enum data_queue_qid queue) | 674 | const enum data_queue_qid queue) |
631 | { | 675 | { |
@@ -687,13 +731,13 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) | |||
687 | if (queue->index[index] >= queue->limit) | 731 | if (queue->index[index] >= queue->limit) |
688 | queue->index[index] = 0; | 732 | queue->index[index] = 0; |
689 | 733 | ||
734 | queue->last_action[index] = jiffies; | ||
735 | |||
690 | if (index == Q_INDEX) { | 736 | if (index == Q_INDEX) { |
691 | queue->length++; | 737 | queue->length++; |
692 | queue->last_index = jiffies; | ||
693 | } else if (index == Q_INDEX_DONE) { | 738 | } else if (index == Q_INDEX_DONE) { |
694 | queue->length--; | 739 | queue->length--; |
695 | queue->count++; | 740 | queue->count++; |
696 | queue->last_index_done = jiffies; | ||
697 | } | 741 | } |
698 | 742 | ||
699 | spin_unlock_irqrestore(&queue->lock, irqflags); | 743 | spin_unlock_irqrestore(&queue->lock, irqflags); |
@@ -702,14 +746,17 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) | |||
702 | static void rt2x00queue_reset(struct data_queue *queue) | 746 | static void rt2x00queue_reset(struct data_queue *queue) |
703 | { | 747 | { |
704 | unsigned long irqflags; | 748 | unsigned long irqflags; |
749 | unsigned int i; | ||
705 | 750 | ||
706 | spin_lock_irqsave(&queue->lock, irqflags); | 751 | spin_lock_irqsave(&queue->lock, irqflags); |
707 | 752 | ||
708 | queue->count = 0; | 753 | queue->count = 0; |
709 | queue->length = 0; | 754 | queue->length = 0; |
710 | queue->last_index = jiffies; | 755 | |
711 | queue->last_index_done = jiffies; | 756 | for (i = 0; i < Q_INDEX_MAX; i++) { |
712 | memset(queue->index, 0, sizeof(queue->index)); | 757 | queue->index[i] = 0; |
758 | queue->last_action[i] = jiffies; | ||
759 | } | ||
713 | 760 | ||
714 | spin_unlock_irqrestore(&queue->lock, irqflags); | 761 | spin_unlock_irqrestore(&queue->lock, irqflags); |
715 | } | 762 | } |
@@ -719,7 +766,7 @@ void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev) | |||
719 | struct data_queue *queue; | 766 | struct data_queue *queue; |
720 | 767 | ||
721 | txall_queue_for_each(rt2x00dev, queue) | 768 | txall_queue_for_each(rt2x00dev, queue) |
722 | rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, queue->qid); | 769 | rt2x00dev->ops->lib->kill_tx_queue(queue); |
723 | } | 770 | } |
724 | 771 | ||
725 | void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev) | 772 | void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 2d3bf843735f..d81d85f34866 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -296,7 +296,7 @@ enum txentry_desc_flags { | |||
296 | * Summary of information for the frame descriptor before sending a TX frame. | 296 | * Summary of information for the frame descriptor before sending a TX frame. |
297 | * | 297 | * |
298 | * @flags: Descriptor flags (See &enum queue_entry_flags). | 298 | * @flags: Descriptor flags (See &enum queue_entry_flags). |
299 | * @queue: Queue identification (See &enum data_queue_qid). | 299 | * @qid: Queue identification (See &enum data_queue_qid). |
300 | * @length: Length of the entire frame. | 300 | * @length: Length of the entire frame. |
301 | * @header_length: Length of 802.11 header. | 301 | * @header_length: Length of 802.11 header. |
302 | * @length_high: PLCP length high word. | 302 | * @length_high: PLCP length high word. |
@@ -322,7 +322,7 @@ enum txentry_desc_flags { | |||
322 | struct txentry_desc { | 322 | struct txentry_desc { |
323 | unsigned long flags; | 323 | unsigned long flags; |
324 | 324 | ||
325 | enum data_queue_qid queue; | 325 | enum data_queue_qid qid; |
326 | 326 | ||
327 | u16 length; | 327 | u16 length; |
328 | u16 header_length; | 328 | u16 header_length; |
@@ -360,9 +360,6 @@ struct txentry_desc { | |||
360 | * @ENTRY_OWNER_DEVICE_DATA: This entry is owned by the device for data | 360 | * @ENTRY_OWNER_DEVICE_DATA: This entry is owned by the device for data |
361 | * transfer (either TX or RX depending on the queue). The entry should | 361 | * transfer (either TX or RX depending on the queue). The entry should |
362 | * only be touched after the device has signaled it is done with it. | 362 | * only be touched after the device has signaled it is done with it. |
363 | * @ENTRY_OWNER_DEVICE_CRYPTO: This entry is owned by the device for data | ||
364 | * encryption or decryption. The entry should only be touched after | ||
365 | * the device has signaled it is done with it. | ||
366 | * @ENTRY_DATA_PENDING: This entry contains a valid frame and is waiting | 363 | * @ENTRY_DATA_PENDING: This entry contains a valid frame and is waiting |
367 | * for the signal to start sending. | 364 | * for the signal to start sending. |
368 | * @ENTRY_DATA_IO_FAILED: Hardware indicated that an IO error occured | 365 | * @ENTRY_DATA_IO_FAILED: Hardware indicated that an IO error occured |
@@ -372,7 +369,6 @@ struct txentry_desc { | |||
372 | enum queue_entry_flags { | 369 | enum queue_entry_flags { |
373 | ENTRY_BCN_ASSIGNED, | 370 | ENTRY_BCN_ASSIGNED, |
374 | ENTRY_OWNER_DEVICE_DATA, | 371 | ENTRY_OWNER_DEVICE_DATA, |
375 | ENTRY_OWNER_DEVICE_CRYPTO, | ||
376 | ENTRY_DATA_PENDING, | 372 | ENTRY_DATA_PENDING, |
377 | ENTRY_DATA_IO_FAILED | 373 | ENTRY_DATA_IO_FAILED |
378 | }; | 374 | }; |
@@ -405,18 +401,18 @@ struct queue_entry { | |||
405 | * | 401 | * |
406 | * @Q_INDEX: Index pointer to the current entry in the queue, if this entry is | 402 | * @Q_INDEX: Index pointer to the current entry in the queue, if this entry is |
407 | * owned by the hardware then the queue is considered to be full. | 403 | * owned by the hardware then the queue is considered to be full. |
404 | * @Q_INDEX_DMA_DONE: Index pointer for the next entry which will have been | ||
405 | * transfered to the hardware. | ||
408 | * @Q_INDEX_DONE: Index pointer to the next entry which will be completed by | 406 | * @Q_INDEX_DONE: Index pointer to the next entry which will be completed by |
409 | * the hardware and for which we need to run the txdone handler. If this | 407 | * the hardware and for which we need to run the txdone handler. If this |
410 | * entry is not owned by the hardware the queue is considered to be empty. | 408 | * entry is not owned by the hardware the queue is considered to be empty. |
411 | * @Q_INDEX_CRYPTO: Index pointer to the next entry which encryption/decription | ||
412 | * will be completed by the hardware next. | ||
413 | * @Q_INDEX_MAX: Keep last, used in &struct data_queue to determine the size | 409 | * @Q_INDEX_MAX: Keep last, used in &struct data_queue to determine the size |
414 | * of the index array. | 410 | * of the index array. |
415 | */ | 411 | */ |
416 | enum queue_index { | 412 | enum queue_index { |
417 | Q_INDEX, | 413 | Q_INDEX, |
414 | Q_INDEX_DMA_DONE, | ||
418 | Q_INDEX_DONE, | 415 | Q_INDEX_DONE, |
419 | Q_INDEX_CRYPTO, | ||
420 | Q_INDEX_MAX, | 416 | Q_INDEX_MAX, |
421 | }; | 417 | }; |
422 | 418 | ||
@@ -452,13 +448,12 @@ struct data_queue { | |||
452 | enum data_queue_qid qid; | 448 | enum data_queue_qid qid; |
453 | 449 | ||
454 | spinlock_t lock; | 450 | spinlock_t lock; |
455 | unsigned long last_index; | ||
456 | unsigned long last_index_done; | ||
457 | unsigned int count; | 451 | unsigned int count; |
458 | unsigned short limit; | 452 | unsigned short limit; |
459 | unsigned short threshold; | 453 | unsigned short threshold; |
460 | unsigned short length; | 454 | unsigned short length; |
461 | unsigned short index[Q_INDEX_MAX]; | 455 | unsigned short index[Q_INDEX_MAX]; |
456 | unsigned long last_action[Q_INDEX_MAX]; | ||
462 | 457 | ||
463 | unsigned short txop; | 458 | unsigned short txop; |
464 | unsigned short aifs; | 459 | unsigned short aifs; |
@@ -571,6 +566,22 @@ struct data_queue_desc { | |||
571 | queue_loop(__entry, (__dev)->tx, queue_end(__dev)) | 566 | queue_loop(__entry, (__dev)->tx, queue_end(__dev)) |
572 | 567 | ||
573 | /** | 568 | /** |
569 | * rt2x00queue_for_each_entry - Loop through all entries in the queue | ||
570 | * @queue: Pointer to @data_queue | ||
571 | * @start: &enum queue_index Pointer to start index | ||
572 | * @end: &enum queue_index Pointer to end index | ||
573 | * @fn: The function to call for each &struct queue_entry | ||
574 | * | ||
575 | * This will walk through all entries in the queue, in chronological | ||
576 | * order. This means it will start at the current @start pointer | ||
577 | * and will walk through the queue until it reaches the @end pointer. | ||
578 | */ | ||
579 | void rt2x00queue_for_each_entry(struct data_queue *queue, | ||
580 | enum queue_index start, | ||
581 | enum queue_index end, | ||
582 | void (*fn)(struct queue_entry *entry)); | ||
583 | |||
584 | /** | ||
574 | * rt2x00queue_empty - Check if the queue is empty. | 585 | * rt2x00queue_empty - Check if the queue is empty. |
575 | * @queue: Queue to check if empty. | 586 | * @queue: Queue to check if empty. |
576 | */ | 587 | */ |
@@ -607,12 +618,23 @@ static inline int rt2x00queue_threshold(struct data_queue *queue) | |||
607 | } | 618 | } |
608 | 619 | ||
609 | /** | 620 | /** |
610 | * rt2x00queue_timeout - Check if a timeout occured for this queue | 621 | * rt2x00queue_timeout - Check if a timeout occured for STATUS reorts |
611 | * @queue: Queue to check. | 622 | * @queue: Queue to check. |
612 | */ | 623 | */ |
613 | static inline int rt2x00queue_timeout(struct data_queue *queue) | 624 | static inline int rt2x00queue_timeout(struct data_queue *queue) |
614 | { | 625 | { |
615 | return time_after(queue->last_index, queue->last_index_done + (HZ / 10)); | 626 | return time_after(queue->last_action[Q_INDEX_DMA_DONE], |
627 | queue->last_action[Q_INDEX_DONE] + (HZ / 10)); | ||
628 | } | ||
629 | |||
630 | /** | ||
631 | * rt2x00queue_timeout - Check if a timeout occured for DMA transfers | ||
632 | * @queue: Queue to check. | ||
633 | */ | ||
634 | static inline int rt2x00queue_dma_timeout(struct data_queue *queue) | ||
635 | { | ||
636 | return time_after(queue->last_action[Q_INDEX], | ||
637 | queue->last_action[Q_INDEX_DMA_DONE] + (HZ / 10)); | ||
616 | } | 638 | } |
617 | 639 | ||
618 | /** | 640 | /** |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index f76014f732ce..4c5ae3d45625 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -208,11 +208,15 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) | |||
208 | struct queue_entry *entry = (struct queue_entry *)urb->context; | 208 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
209 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 209 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
210 | 210 | ||
211 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) || | 211 | if (!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
212 | !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) | ||
213 | return; | 212 | return; |
214 | 213 | ||
215 | /* | 214 | /* |
215 | * Report the frame as DMA done | ||
216 | */ | ||
217 | rt2x00lib_dmadone(entry); | ||
218 | |||
219 | /* | ||
216 | * Check if the frame was correctly uploaded | 220 | * Check if the frame was correctly uploaded |
217 | */ | 221 | */ |
218 | if (urb->status) | 222 | if (urb->status) |
@@ -222,112 +226,84 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) | |||
222 | * Schedule the delayed work for reading the TX status | 226 | * Schedule the delayed work for reading the TX status |
223 | * from the device. | 227 | * from the device. |
224 | */ | 228 | */ |
225 | ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work); | 229 | if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && |
230 | test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
231 | ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work); | ||
226 | } | 232 | } |
227 | 233 | ||
228 | static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry) | 234 | static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) |
229 | { | 235 | { |
230 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 236 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
231 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); | 237 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); |
232 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; | 238 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; |
233 | u32 length; | 239 | u32 length; |
234 | 240 | ||
235 | if (test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) { | 241 | if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) |
236 | /* | 242 | return; |
237 | * USB devices cannot blindly pass the skb->len as the | ||
238 | * length of the data to usb_fill_bulk_urb. Pass the skb | ||
239 | * to the driver to determine what the length should be. | ||
240 | */ | ||
241 | length = rt2x00dev->ops->lib->get_tx_data_len(entry); | ||
242 | |||
243 | usb_fill_bulk_urb(entry_priv->urb, usb_dev, | ||
244 | usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint), | ||
245 | entry->skb->data, length, | ||
246 | rt2x00usb_interrupt_txdone, entry); | ||
247 | |||
248 | usb_submit_urb(entry_priv->urb, GFP_ATOMIC); | ||
249 | } | ||
250 | } | ||
251 | |||
252 | void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | ||
253 | const enum data_queue_qid qid) | ||
254 | { | ||
255 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid); | ||
256 | unsigned long irqflags; | ||
257 | unsigned int index; | ||
258 | unsigned int index_done; | ||
259 | unsigned int i; | ||
260 | 243 | ||
261 | /* | 244 | /* |
262 | * Only protect the range we are going to loop over, | 245 | * USB devices cannot blindly pass the skb->len as the |
263 | * if during our loop a extra entry is set to pending | 246 | * length of the data to usb_fill_bulk_urb. Pass the skb |
264 | * it should not be kicked during this run, since it | 247 | * to the driver to determine what the length should be. |
265 | * is part of another TX operation. | ||
266 | */ | 248 | */ |
267 | spin_lock_irqsave(&queue->lock, irqflags); | 249 | length = rt2x00dev->ops->lib->get_tx_data_len(entry); |
268 | index = queue->index[Q_INDEX]; | ||
269 | index_done = queue->index[Q_INDEX_DONE]; | ||
270 | spin_unlock_irqrestore(&queue->lock, irqflags); | ||
271 | 250 | ||
272 | /* | 251 | usb_fill_bulk_urb(entry_priv->urb, usb_dev, |
273 | * Start from the TX done pointer, this guarentees that we will | 252 | usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint), |
274 | * send out all frames in the correct order. | 253 | entry->skb->data, length, |
275 | */ | 254 | rt2x00usb_interrupt_txdone, entry); |
276 | if (index_done < index) { | ||
277 | for (i = index_done; i < index; i++) | ||
278 | rt2x00usb_kick_tx_entry(&queue->entries[i]); | ||
279 | } else { | ||
280 | for (i = index_done; i < queue->limit; i++) | ||
281 | rt2x00usb_kick_tx_entry(&queue->entries[i]); | ||
282 | 255 | ||
283 | for (i = 0; i < index; i++) | 256 | usb_submit_urb(entry_priv->urb, GFP_ATOMIC); |
284 | rt2x00usb_kick_tx_entry(&queue->entries[i]); | 257 | } |
285 | } | 258 | |
259 | void rt2x00usb_kick_tx_queue(struct data_queue *queue) | ||
260 | { | ||
261 | rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, | ||
262 | rt2x00usb_kick_tx_entry); | ||
286 | } | 263 | } |
287 | EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue); | 264 | EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue); |
288 | 265 | ||
289 | void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev, | 266 | static void rt2x00usb_kill_tx_entry(struct queue_entry *entry) |
290 | const enum data_queue_qid qid) | ||
291 | { | 267 | { |
292 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid); | 268 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
293 | struct queue_entry_priv_usb *entry_priv; | 269 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; |
294 | struct queue_entry_priv_usb_bcn *bcn_priv; | 270 | struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data; |
295 | unsigned int i; | 271 | |
296 | bool kill_guard; | 272 | if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
273 | return; | ||
274 | |||
275 | usb_kill_urb(entry_priv->urb); | ||
297 | 276 | ||
298 | /* | 277 | /* |
299 | * When killing the beacon queue, we must also kill | 278 | * Kill guardian urb (if required by driver). |
300 | * the beacon guard byte. | ||
301 | */ | 279 | */ |
302 | kill_guard = | 280 | if ((entry->queue->qid == QID_BEACON) && |
303 | (qid == QID_BEACON) && | 281 | (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))) |
304 | (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)); | 282 | usb_kill_urb(bcn_priv->guardian_urb); |
305 | 283 | ||
306 | /* | 284 | /* |
307 | * Cancel all entries. | 285 | * We need a short delay here to wait for |
286 | * the URB to be canceled | ||
308 | */ | 287 | */ |
309 | for (i = 0; i < queue->limit; i++) { | 288 | do { |
310 | entry_priv = queue->entries[i].priv_data; | 289 | udelay(100); |
311 | usb_kill_urb(entry_priv->urb); | 290 | } while (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)); |
291 | } | ||
312 | 292 | ||
313 | /* | 293 | void rt2x00usb_kill_tx_queue(struct data_queue *queue) |
314 | * Kill guardian urb (if required by driver). | 294 | { |
315 | */ | 295 | rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, |
316 | if (kill_guard) { | 296 | rt2x00usb_kill_tx_entry); |
317 | bcn_priv = queue->entries[i].priv_data; | ||
318 | usb_kill_urb(bcn_priv->guardian_urb); | ||
319 | } | ||
320 | } | ||
321 | } | 297 | } |
322 | EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue); | 298 | EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue); |
323 | 299 | ||
324 | static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue) | 300 | static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) |
325 | { | 301 | { |
326 | struct queue_entry *entry; | 302 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; |
327 | struct queue_entry_priv_usb *entry_priv; | ||
328 | unsigned short threshold = queue->threshold; | 303 | unsigned short threshold = queue->threshold; |
329 | 304 | ||
330 | WARNING(queue->rt2x00dev, "TX queue %d timed out, invoke reset", queue->qid); | 305 | WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," |
306 | " invoke forced forced reset", queue->qid); | ||
331 | 307 | ||
332 | /* | 308 | /* |
333 | * Temporarily disable the TX queue, this will force mac80211 | 309 | * Temporarily disable the TX queue, this will force mac80211 |
@@ -337,28 +313,33 @@ static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue) | |||
337 | * queue from being enabled during the txdone handler. | 313 | * queue from being enabled during the txdone handler. |
338 | */ | 314 | */ |
339 | queue->threshold = queue->limit; | 315 | queue->threshold = queue->limit; |
340 | ieee80211_stop_queue(queue->rt2x00dev->hw, queue->qid); | 316 | ieee80211_stop_queue(rt2x00dev->hw, queue->qid); |
341 | 317 | ||
342 | /* | 318 | /* |
343 | * Reset all currently uploaded TX frames. | 319 | * Kill all entries in the queue, afterwards we need to |
320 | * wait a bit for all URBs to be cancelled. | ||
344 | */ | 321 | */ |
345 | while (!rt2x00queue_empty(queue)) { | 322 | rt2x00usb_kill_tx_queue(queue); |
346 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | ||
347 | entry_priv = entry->priv_data; | ||
348 | usb_kill_urb(entry_priv->urb); | ||
349 | 323 | ||
350 | /* | 324 | /* |
351 | * We need a short delay here to wait for | 325 | * In case that a driver has overriden the txdone_work |
352 | * the URB to be canceled | 326 | * function, we invoke the TX done through there. |
353 | */ | 327 | */ |
354 | do { | 328 | rt2x00dev->txdone_work.func(&rt2x00dev->txdone_work); |
355 | udelay(100); | ||
356 | } while (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)); | ||
357 | 329 | ||
358 | /* | 330 | /* |
359 | * Invoke the TX done handler | 331 | * Security measure: if the driver did override the |
360 | */ | 332 | * txdone_work function, and the hardware did arrive |
361 | rt2x00usb_work_txdone_entry(entry); | 333 | * in a state which causes it to malfunction, it is |
334 | * possible that the driver couldn't handle the txdone | ||
335 | * event correctly. So after giving the driver the | ||
336 | * chance to cleanup, we now force a cleanup of any | ||
337 | * leftovers. | ||
338 | */ | ||
339 | if (!rt2x00queue_empty(queue)) { | ||
340 | WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," | ||
341 | " status handling failed, invoke hard reset", queue->qid); | ||
342 | rt2x00usb_work_txdone(&rt2x00dev->txdone_work); | ||
362 | } | 343 | } |
363 | 344 | ||
364 | /* | 345 | /* |
@@ -366,7 +347,15 @@ static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue) | |||
366 | * queue again. | 347 | * queue again. |
367 | */ | 348 | */ |
368 | queue->threshold = threshold; | 349 | queue->threshold = threshold; |
369 | ieee80211_wake_queue(queue->rt2x00dev->hw, queue->qid); | 350 | ieee80211_wake_queue(rt2x00dev->hw, queue->qid); |
351 | } | ||
352 | |||
353 | static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) | ||
354 | { | ||
355 | WARNING(queue->rt2x00dev, "TX queue %d status timed out," | ||
356 | " invoke forced tx handler", queue->qid); | ||
357 | |||
358 | ieee80211_queue_work(queue->rt2x00dev->hw, &queue->rt2x00dev->txdone_work); | ||
370 | } | 359 | } |
371 | 360 | ||
372 | void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) | 361 | void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) |
@@ -374,8 +363,10 @@ void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) | |||
374 | struct data_queue *queue; | 363 | struct data_queue *queue; |
375 | 364 | ||
376 | tx_queue_for_each(rt2x00dev, queue) { | 365 | tx_queue_for_each(rt2x00dev, queue) { |
366 | if (rt2x00queue_dma_timeout(queue)) | ||
367 | rt2x00usb_watchdog_tx_dma(queue); | ||
377 | if (rt2x00queue_timeout(queue)) | 368 | if (rt2x00queue_timeout(queue)) |
378 | rt2x00usb_watchdog_reset_tx(queue); | 369 | rt2x00usb_watchdog_tx_status(queue); |
379 | } | 370 | } |
380 | } | 371 | } |
381 | EXPORT_SYMBOL_GPL(rt2x00usb_watchdog); | 372 | EXPORT_SYMBOL_GPL(rt2x00usb_watchdog); |
@@ -416,11 +407,15 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) | |||
416 | struct queue_entry *entry = (struct queue_entry *)urb->context; | 407 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
417 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 408 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
418 | 409 | ||
419 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) || | 410 | if (!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
420 | !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) | ||
421 | return; | 411 | return; |
422 | 412 | ||
423 | /* | 413 | /* |
414 | * Report the frame as DMA done | ||
415 | */ | ||
416 | rt2x00lib_dmadone(entry); | ||
417 | |||
418 | /* | ||
424 | * Check if the received data is simply too small | 419 | * Check if the received data is simply too small |
425 | * to be actually valid, or if the urb is signaling | 420 | * to be actually valid, or if the urb is signaling |
426 | * a problem. | 421 | * a problem. |
@@ -432,7 +427,9 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) | |||
432 | * Schedule the delayed work for reading the RX status | 427 | * Schedule the delayed work for reading the RX status |
433 | * from the device. | 428 | * from the device. |
434 | */ | 429 | */ |
435 | ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work); | 430 | if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && |
431 | test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
432 | ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work); | ||
436 | } | 433 | } |
437 | 434 | ||
438 | /* | 435 | /* |
@@ -447,7 +444,7 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
447 | * The USB version of kill_tx_queue also works | 444 | * The USB version of kill_tx_queue also works |
448 | * on the RX queue. | 445 | * on the RX queue. |
449 | */ | 446 | */ |
450 | rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_RX); | 447 | rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev->rx); |
451 | } | 448 | } |
452 | EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); | 449 | EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); |
453 | 450 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index d3d3ddc40875..c2d997f67b3e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h | |||
@@ -379,25 +379,21 @@ struct queue_entry_priv_usb_bcn { | |||
379 | 379 | ||
380 | /** | 380 | /** |
381 | * rt2x00usb_kick_tx_queue - Kick data queue | 381 | * rt2x00usb_kick_tx_queue - Kick data queue |
382 | * @rt2x00dev: Pointer to &struct rt2x00_dev | 382 | * @queue: Data queue to kick |
383 | * @qid: Data queue to kick | ||
384 | * | 383 | * |
385 | * This will walk through all entries of the queue and push all pending | 384 | * This will walk through all entries of the queue and push all pending |
386 | * frames to the hardware as a single burst. | 385 | * frames to the hardware as a single burst. |
387 | */ | 386 | */ |
388 | void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 387 | void rt2x00usb_kick_tx_queue(struct data_queue *queue); |
389 | const enum data_queue_qid qid); | ||
390 | 388 | ||
391 | /** | 389 | /** |
392 | * rt2x00usb_kill_tx_queue - Kill data queue | 390 | * rt2x00usb_kill_tx_queue - Kill data queue |
393 | * @rt2x00dev: Pointer to &struct rt2x00_dev | 391 | * @queue: Data queue to kill |
394 | * @qid: Data queue to kill | ||
395 | * | 392 | * |
396 | * This will walk through all entries of the queue and kill all | 393 | * This will walk through all entries of the queue and kill all |
397 | * previously kicked frames before they can be send. | 394 | * previously kicked frames before they can be send. |
398 | */ | 395 | */ |
399 | void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev, | 396 | void rt2x00usb_kill_tx_queue(struct data_queue *queue); |
400 | const enum data_queue_qid qid); | ||
401 | 397 | ||
402 | /** | 398 | /** |
403 | * rt2x00usb_watchdog - Watchdog for USB communication | 399 | * rt2x00usb_watchdog - Watchdog for USB communication |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 3f8d10b76fee..3a7759929190 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1766,12 +1766,11 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1766 | /* | 1766 | /* |
1767 | * TX descriptor initialization | 1767 | * TX descriptor initialization |
1768 | */ | 1768 | */ |
1769 | static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1769 | static void rt61pci_write_tx_desc(struct queue_entry *entry, |
1770 | struct sk_buff *skb, | ||
1771 | struct txentry_desc *txdesc) | 1770 | struct txentry_desc *txdesc) |
1772 | { | 1771 | { |
1773 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 1772 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1774 | struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; | 1773 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
1775 | __le32 *txd = entry_priv->desc; | 1774 | __le32 *txd = entry_priv->desc; |
1776 | u32 word; | 1775 | u32 word; |
1777 | 1776 | ||
@@ -1779,7 +1778,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1779 | * Start writing the descriptor words. | 1778 | * Start writing the descriptor words. |
1780 | */ | 1779 | */ |
1781 | rt2x00_desc_read(txd, 1, &word); | 1780 | rt2x00_desc_read(txd, 1, &word); |
1782 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue); | 1781 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid); |
1783 | rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); | 1782 | rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); |
1784 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); | 1783 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1785 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); | 1784 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
@@ -1802,15 +1801,15 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1802 | } | 1801 | } |
1803 | 1802 | ||
1804 | rt2x00_desc_read(txd, 5, &word); | 1803 | rt2x00_desc_read(txd, 5, &word); |
1805 | rt2x00_set_field32(&word, TXD_W5_PID_TYPE, skbdesc->entry->queue->qid); | 1804 | rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->queue->qid); |
1806 | rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, | 1805 | rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, |
1807 | skbdesc->entry->entry_idx); | 1806 | skbdesc->entry->entry_idx); |
1808 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, | 1807 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, |
1809 | TXPOWER_TO_DEV(rt2x00dev->tx_power)); | 1808 | TXPOWER_TO_DEV(entry->queue->rt2x00dev->tx_power)); |
1810 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); | 1809 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); |
1811 | rt2x00_desc_write(txd, 5, word); | 1810 | rt2x00_desc_write(txd, 5, word); |
1812 | 1811 | ||
1813 | if (txdesc->queue != QID_BEACON) { | 1812 | if (txdesc->qid != QID_BEACON) { |
1814 | rt2x00_desc_read(txd, 6, &word); | 1813 | rt2x00_desc_read(txd, 6, &word); |
1815 | rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, | 1814 | rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, |
1816 | skbdesc->skb_dma); | 1815 | skbdesc->skb_dma); |
@@ -1857,7 +1856,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1857 | */ | 1856 | */ |
1858 | skbdesc->desc = txd; | 1857 | skbdesc->desc = txd; |
1859 | skbdesc->desc_len = | 1858 | skbdesc->desc_len = |
1860 | (txdesc->queue == QID_BEACON) ? TXINFO_SIZE : TXD_DESC_SIZE; | 1859 | (txdesc->qid == QID_BEACON) ? TXINFO_SIZE : TXD_DESC_SIZE; |
1861 | } | 1860 | } |
1862 | 1861 | ||
1863 | /* | 1862 | /* |
@@ -1882,7 +1881,7 @@ static void rt61pci_write_beacon(struct queue_entry *entry, | |||
1882 | /* | 1881 | /* |
1883 | * Write the TX descriptor for the beacon. | 1882 | * Write the TX descriptor for the beacon. |
1884 | */ | 1883 | */ |
1885 | rt61pci_write_tx_desc(rt2x00dev, entry->skb, txdesc); | 1884 | rt61pci_write_tx_desc(entry, txdesc); |
1886 | 1885 | ||
1887 | /* | 1886 | /* |
1888 | * Dump beacon to userspace through debugfs. | 1887 | * Dump beacon to userspace through debugfs. |
@@ -1918,34 +1917,34 @@ static void rt61pci_write_beacon(struct queue_entry *entry, | |||
1918 | entry->skb = NULL; | 1917 | entry->skb = NULL; |
1919 | } | 1918 | } |
1920 | 1919 | ||
1921 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1920 | static void rt61pci_kick_tx_queue(struct data_queue *queue) |
1922 | const enum data_queue_qid queue) | ||
1923 | { | 1921 | { |
1922 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
1924 | u32 reg; | 1923 | u32 reg; |
1925 | 1924 | ||
1926 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); | 1925 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); |
1927 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, (queue == QID_AC_BE)); | 1926 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, (queue->qid == QID_AC_BE)); |
1928 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, (queue == QID_AC_BK)); | 1927 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, (queue->qid == QID_AC_BK)); |
1929 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, (queue == QID_AC_VI)); | 1928 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, (queue->qid == QID_AC_VI)); |
1930 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, (queue == QID_AC_VO)); | 1929 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, (queue->qid == QID_AC_VO)); |
1931 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1930 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
1932 | } | 1931 | } |
1933 | 1932 | ||
1934 | static void rt61pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, | 1933 | static void rt61pci_kill_tx_queue(struct data_queue *queue) |
1935 | const enum data_queue_qid qid) | ||
1936 | { | 1934 | { |
1935 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
1937 | u32 reg; | 1936 | u32 reg; |
1938 | 1937 | ||
1939 | if (qid == QID_BEACON) { | 1938 | if (queue->qid == QID_BEACON) { |
1940 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); | 1939 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); |
1941 | return; | 1940 | return; |
1942 | } | 1941 | } |
1943 | 1942 | ||
1944 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); | 1943 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); |
1945 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, (qid == QID_AC_BE)); | 1944 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, (queue->qid == QID_AC_BE)); |
1946 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, (qid == QID_AC_BK)); | 1945 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, (queue->qid == QID_AC_BK)); |
1947 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, (qid == QID_AC_VI)); | 1946 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, (queue->qid == QID_AC_VI)); |
1948 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, (qid == QID_AC_VO)); | 1947 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, (queue->qid == QID_AC_VO)); |
1949 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1948 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
1950 | } | 1949 | } |
1951 | 1950 | ||
@@ -2657,13 +2656,17 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2657 | spec->channels_info = info; | 2656 | spec->channels_info = info; |
2658 | 2657 | ||
2659 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START); | 2658 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START); |
2660 | for (i = 0; i < 14; i++) | 2659 | for (i = 0; i < 14; i++) { |
2661 | info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); | 2660 | info[i].max_power = MAX_TXPOWER; |
2661 | info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); | ||
2662 | } | ||
2662 | 2663 | ||
2663 | if (spec->num_channels > 14) { | 2664 | if (spec->num_channels > 14) { |
2664 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); | 2665 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); |
2665 | for (i = 14; i < spec->num_channels; i++) | 2666 | for (i = 14; i < spec->num_channels; i++) { |
2666 | info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); | 2667 | info[i].max_power = MAX_TXPOWER; |
2668 | info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); | ||
2669 | } | ||
2667 | } | 2670 | } |
2668 | 2671 | ||
2669 | return 0; | 2672 | return 0; |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 8ca19f70aea7..87fb2201537b 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -1426,12 +1426,11 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1426 | /* | 1426 | /* |
1427 | * TX descriptor initialization | 1427 | * TX descriptor initialization |
1428 | */ | 1428 | */ |
1429 | static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1429 | static void rt73usb_write_tx_desc(struct queue_entry *entry, |
1430 | struct sk_buff *skb, | ||
1431 | struct txentry_desc *txdesc) | 1430 | struct txentry_desc *txdesc) |
1432 | { | 1431 | { |
1433 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 1432 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1434 | __le32 *txd = (__le32 *) skb->data; | 1433 | __le32 *txd = (__le32 *) entry->skb->data; |
1435 | u32 word; | 1434 | u32 word; |
1436 | 1435 | ||
1437 | /* | 1436 | /* |
@@ -1464,7 +1463,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1464 | rt2x00_desc_write(txd, 0, word); | 1463 | rt2x00_desc_write(txd, 0, word); |
1465 | 1464 | ||
1466 | rt2x00_desc_read(txd, 1, &word); | 1465 | rt2x00_desc_read(txd, 1, &word); |
1467 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue); | 1466 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid); |
1468 | rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); | 1467 | rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); |
1469 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); | 1468 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1470 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); | 1469 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
@@ -1487,7 +1486,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1487 | 1486 | ||
1488 | rt2x00_desc_read(txd, 5, &word); | 1487 | rt2x00_desc_read(txd, 5, &word); |
1489 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, | 1488 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, |
1490 | TXPOWER_TO_DEV(rt2x00dev->tx_power)); | 1489 | TXPOWER_TO_DEV(entry->queue->rt2x00dev->tx_power)); |
1491 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); | 1490 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); |
1492 | rt2x00_desc_write(txd, 5, word); | 1491 | rt2x00_desc_write(txd, 5, word); |
1493 | 1492 | ||
@@ -1526,7 +1525,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry, | |||
1526 | /* | 1525 | /* |
1527 | * Write the TX descriptor for the beacon. | 1526 | * Write the TX descriptor for the beacon. |
1528 | */ | 1527 | */ |
1529 | rt73usb_write_tx_desc(rt2x00dev, entry->skb, txdesc); | 1528 | rt73usb_write_tx_desc(entry, txdesc); |
1530 | 1529 | ||
1531 | /* | 1530 | /* |
1532 | * Dump beacon to userspace through debugfs. | 1531 | * Dump beacon to userspace through debugfs. |
@@ -1574,6 +1573,14 @@ static int rt73usb_get_tx_data_len(struct queue_entry *entry) | |||
1574 | return length; | 1573 | return length; |
1575 | } | 1574 | } |
1576 | 1575 | ||
1576 | static void rt73usb_kill_tx_queue(struct data_queue *queue) | ||
1577 | { | ||
1578 | if (queue->qid == QID_BEACON) | ||
1579 | rt2x00usb_register_write(queue->rt2x00dev, TXRX_CSR9, 0); | ||
1580 | |||
1581 | rt2x00usb_kill_tx_queue(queue); | ||
1582 | } | ||
1583 | |||
1577 | /* | 1584 | /* |
1578 | * RX control handlers | 1585 | * RX control handlers |
1579 | */ | 1586 | */ |
@@ -2091,13 +2098,17 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2091 | spec->channels_info = info; | 2098 | spec->channels_info = info; |
2092 | 2099 | ||
2093 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START); | 2100 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START); |
2094 | for (i = 0; i < 14; i++) | 2101 | for (i = 0; i < 14; i++) { |
2095 | info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); | 2102 | info[i].max_power = MAX_TXPOWER; |
2103 | info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); | ||
2104 | } | ||
2096 | 2105 | ||
2097 | if (spec->num_channels > 14) { | 2106 | if (spec->num_channels > 14) { |
2098 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); | 2107 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); |
2099 | for (i = 14; i < spec->num_channels; i++) | 2108 | for (i = 14; i < spec->num_channels; i++) { |
2100 | info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); | 2109 | info[i].max_power = MAX_TXPOWER; |
2110 | info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); | ||
2111 | } | ||
2101 | } | 2112 | } |
2102 | 2113 | ||
2103 | return 0; | 2114 | return 0; |
@@ -2259,7 +2270,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | |||
2259 | .write_beacon = rt73usb_write_beacon, | 2270 | .write_beacon = rt73usb_write_beacon, |
2260 | .get_tx_data_len = rt73usb_get_tx_data_len, | 2271 | .get_tx_data_len = rt73usb_get_tx_data_len, |
2261 | .kick_tx_queue = rt2x00usb_kick_tx_queue, | 2272 | .kick_tx_queue = rt2x00usb_kick_tx_queue, |
2262 | .kill_tx_queue = rt2x00usb_kill_tx_queue, | 2273 | .kill_tx_queue = rt73usb_kill_tx_queue, |
2263 | .fill_rxdone = rt73usb_fill_rxdone, | 2274 | .fill_rxdone = rt73usb_fill_rxdone, |
2264 | .config_shared_key = rt73usb_config_shared_key, | 2275 | .config_shared_key = rt73usb_config_shared_key, |
2265 | .config_pairwise_key = rt73usb_config_pairwise_key, | 2276 | .config_pairwise_key = rt73usb_config_pairwise_key, |