diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2009-01-27 18:32:33 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-02-09 15:03:34 -0500 |
commit | a2c9b652a12a550d3d8509e9bae43bac396c5076 (patch) | |
tree | 8e871e038bc73465c6eca67f8563e9562d079d56 /drivers/net/wireless/rt2x00 | |
parent | 382fe0f2da78db7833c6a7278e33e694e6e2a6f3 (diff) |
rt2x00: Add kill_tx_queue callback function
provide rt2x00lib the possibility to kill a particular TX queue.
This can be useful when disabling the radio, but more importantly
will allow beaconing to be disabled when mac80211 requests this
(during scanning for example)
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2400pci.c | 30 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500pci.c | 30 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00lib.h | 13 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 19 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.c | 62 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.h | 11 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 37 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 1 |
12 files changed, 145 insertions, 72 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 4a2c0b971ca8..b0848259b455 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -934,21 +934,10 @@ static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
934 | 934 | ||
935 | static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev) | 935 | static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev) |
936 | { | 936 | { |
937 | u32 reg; | ||
938 | |||
939 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); | ||
940 | |||
941 | /* | 937 | /* |
942 | * Disable synchronisation. | 938 | * Disable power |
943 | */ | 939 | */ |
944 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | 940 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); |
945 | |||
946 | /* | ||
947 | * Cancel RX and TX. | ||
948 | */ | ||
949 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | ||
950 | rt2x00_set_field32(®, TXCSR0_ABORT, 1); | ||
951 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | ||
952 | } | 941 | } |
953 | 942 | ||
954 | static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev, | 943 | static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev, |
@@ -1145,6 +1134,20 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1145 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 1134 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); |
1146 | } | 1135 | } |
1147 | 1136 | ||
1137 | static void rt2400pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, | ||
1138 | const enum data_queue_qid qid) | ||
1139 | { | ||
1140 | u32 reg; | ||
1141 | |||
1142 | if (qid == QID_BEACON) { | ||
1143 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | ||
1144 | } else { | ||
1145 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | ||
1146 | rt2x00_set_field32(®, TXCSR0_ABORT, 1); | ||
1147 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | ||
1148 | } | ||
1149 | } | ||
1150 | |||
1148 | /* | 1151 | /* |
1149 | * RX control handlers | 1152 | * RX control handlers |
1150 | */ | 1153 | */ |
@@ -1606,6 +1609,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { | |||
1606 | .write_tx_data = rt2x00pci_write_tx_data, | 1609 | .write_tx_data = rt2x00pci_write_tx_data, |
1607 | .write_beacon = rt2400pci_write_beacon, | 1610 | .write_beacon = rt2400pci_write_beacon, |
1608 | .kick_tx_queue = rt2400pci_kick_tx_queue, | 1611 | .kick_tx_queue = rt2400pci_kick_tx_queue, |
1612 | .kill_tx_queue = rt2400pci_kill_tx_queue, | ||
1609 | .fill_rxdone = rt2400pci_fill_rxdone, | 1613 | .fill_rxdone = rt2400pci_fill_rxdone, |
1610 | .config_filter = rt2400pci_config_filter, | 1614 | .config_filter = rt2400pci_config_filter, |
1611 | .config_intf = rt2400pci_config_intf, | 1615 | .config_intf = rt2400pci_config_intf, |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index b9104e28bc2e..eb82860c54f9 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -1093,21 +1093,10 @@ static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1093 | 1093 | ||
1094 | static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev) | 1094 | static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev) |
1095 | { | 1095 | { |
1096 | u32 reg; | ||
1097 | |||
1098 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); | ||
1099 | |||
1100 | /* | 1096 | /* |
1101 | * Disable synchronisation. | 1097 | * Disable power |
1102 | */ | 1098 | */ |
1103 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | 1099 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); |
1104 | |||
1105 | /* | ||
1106 | * Cancel RX and TX. | ||
1107 | */ | ||
1108 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | ||
1109 | rt2x00_set_field32(®, TXCSR0_ABORT, 1); | ||
1110 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | ||
1111 | } | 1100 | } |
1112 | 1101 | ||
1113 | static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev, | 1102 | static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev, |
@@ -1303,6 +1292,20 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1303 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 1292 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); |
1304 | } | 1293 | } |
1305 | 1294 | ||
1295 | static void rt2500pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, | ||
1296 | const enum data_queue_qid qid) | ||
1297 | { | ||
1298 | u32 reg; | ||
1299 | |||
1300 | if (qid == QID_BEACON) { | ||
1301 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | ||
1302 | } else { | ||
1303 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | ||
1304 | rt2x00_set_field32(®, TXCSR0_ABORT, 1); | ||
1305 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | ||
1306 | } | ||
1307 | } | ||
1308 | |||
1306 | /* | 1309 | /* |
1307 | * RX control handlers | 1310 | * RX control handlers |
1308 | */ | 1311 | */ |
@@ -1905,6 +1908,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { | |||
1905 | .write_tx_data = rt2x00pci_write_tx_data, | 1908 | .write_tx_data = rt2x00pci_write_tx_data, |
1906 | .write_beacon = rt2500pci_write_beacon, | 1909 | .write_beacon = rt2500pci_write_beacon, |
1907 | .kick_tx_queue = rt2500pci_kick_tx_queue, | 1910 | .kick_tx_queue = rt2500pci_kick_tx_queue, |
1911 | .kill_tx_queue = rt2500pci_kill_tx_queue, | ||
1908 | .fill_rxdone = rt2500pci_fill_rxdone, | 1912 | .fill_rxdone = rt2500pci_fill_rxdone, |
1909 | .config_filter = rt2500pci_config_filter, | 1913 | .config_filter = rt2500pci_config_filter, |
1910 | .config_intf = rt2500pci_config_intf, | 1914 | .config_intf = rt2500pci_config_intf, |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index c526e737fcad..270691ac2361 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1935,6 +1935,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { | |||
1935 | .write_beacon = rt2500usb_write_beacon, | 1935 | .write_beacon = rt2500usb_write_beacon, |
1936 | .get_tx_data_len = rt2500usb_get_tx_data_len, | 1936 | .get_tx_data_len = rt2500usb_get_tx_data_len, |
1937 | .kick_tx_queue = rt2500usb_kick_tx_queue, | 1937 | .kick_tx_queue = rt2500usb_kick_tx_queue, |
1938 | .kill_tx_queue = rt2x00usb_kill_tx_queue, | ||
1938 | .fill_rxdone = rt2500usb_fill_rxdone, | 1939 | .fill_rxdone = rt2500usb_fill_rxdone, |
1939 | .config_shared_key = rt2500usb_config_key, | 1940 | .config_shared_key = rt2500usb_config_key, |
1940 | .config_pairwise_key = rt2500usb_config_key, | 1941 | .config_pairwise_key = rt2500usb_config_key, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index d0a825638188..94fb571667fe 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -508,6 +508,8 @@ struct rt2x00lib_ops { | |||
508 | int (*get_tx_data_len) (struct queue_entry *entry); | 508 | int (*get_tx_data_len) (struct queue_entry *entry); |
509 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, | 509 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, |
510 | const enum data_queue_qid queue); | 510 | const enum data_queue_qid queue); |
511 | void (*kill_tx_queue) (struct rt2x00_dev *rt2x00dev, | ||
512 | const enum data_queue_qid queue); | ||
511 | 513 | ||
512 | /* | 514 | /* |
513 | * RX control handlers | 515 | * RX control handlers |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index e681d239d43c..05f94e21b423 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -83,9 +83,10 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
83 | return; | 83 | return; |
84 | 84 | ||
85 | /* | 85 | /* |
86 | * Stop the TX queues. | 86 | * Stop the TX queues in mac80211. |
87 | */ | 87 | */ |
88 | ieee80211_stop_queues(rt2x00dev->hw); | 88 | ieee80211_stop_queues(rt2x00dev->hw); |
89 | rt2x00queue_stop_queues(rt2x00dev); | ||
89 | 90 | ||
90 | /* | 91 | /* |
91 | * Disable RX. | 92 | * Disable RX. |
@@ -157,7 +158,7 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, | |||
157 | return; | 158 | return; |
158 | 159 | ||
159 | if (delayed_flags & DELAYED_UPDATE_BEACON) | 160 | if (delayed_flags & DELAYED_UPDATE_BEACON) |
160 | rt2x00queue_update_beacon(rt2x00dev, vif); | 161 | rt2x00queue_update_beacon(rt2x00dev, vif, true); |
161 | 162 | ||
162 | if (delayed_flags & DELAYED_CONFIG_ERP) | 163 | if (delayed_flags & DELAYED_CONFIG_ERP) |
163 | rt2x00lib_config_erp(rt2x00dev, intf, &conf); | 164 | rt2x00lib_config_erp(rt2x00dev, intf, &conf); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 34efe4653549..a631613177d0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -123,9 +123,11 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb); | |||
123 | * rt2x00queue_update_beacon - Send new beacon from mac80211 to hardware | 123 | * rt2x00queue_update_beacon - Send new beacon from mac80211 to hardware |
124 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | 124 | * @rt2x00dev: Pointer to &struct rt2x00_dev. |
125 | * @vif: Interface for which the beacon should be updated. | 125 | * @vif: Interface for which the beacon should be updated. |
126 | * @enable_beacon: Enable beaconing | ||
126 | */ | 127 | */ |
127 | int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, | 128 | int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, |
128 | struct ieee80211_vif *vif); | 129 | struct ieee80211_vif *vif, |
130 | const bool enable_beacon); | ||
129 | 131 | ||
130 | /** | 132 | /** |
131 | * rt2x00queue_index_inc - Index incrementation function | 133 | * rt2x00queue_index_inc - Index incrementation function |
@@ -139,6 +141,15 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, | |||
139 | void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); | 141 | void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); |
140 | 142 | ||
141 | /** | 143 | /** |
144 | * rt2x00queue_stop_queues - Halt all data queues | ||
145 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
146 | * | ||
147 | * This function will loop through all available queues to stop | ||
148 | * any pending outgoing frames. | ||
149 | */ | ||
150 | void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev); | ||
151 | |||
152 | /** | ||
142 | * rt2x00queue_init_queues - Initialize all data queues | 153 | * rt2x00queue_init_queues - Initialize all data queues |
143 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | 154 | * @rt2x00dev: Pointer to &struct rt2x00_dev. |
144 | * | 155 | * |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 71de8a7144f9..c41a0b9e473d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -431,8 +431,10 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
431 | /* | 431 | /* |
432 | * Update the beacon. | 432 | * Update the beacon. |
433 | */ | 433 | */ |
434 | if (conf->changed & IEEE80211_IFCC_BEACON) | 434 | if (conf->changed & (IEEE80211_IFCC_BEACON | |
435 | status = rt2x00queue_update_beacon(rt2x00dev, vif); | 435 | IEEE80211_IFCC_BEACON_ENABLED)) |
436 | status = rt2x00queue_update_beacon(rt2x00dev, vif, | ||
437 | conf->enable_beacon); | ||
436 | 438 | ||
437 | return status; | 439 | return status; |
438 | } | 440 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index c86fb6471754..a5664bd8493e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -443,7 +443,8 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) | |||
443 | } | 443 | } |
444 | 444 | ||
445 | int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, | 445 | int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, |
446 | struct ieee80211_vif *vif) | 446 | struct ieee80211_vif *vif, |
447 | const bool enable_beacon) | ||
447 | { | 448 | { |
448 | struct rt2x00_intf *intf = vif_to_intf(vif); | 449 | struct rt2x00_intf *intf = vif_to_intf(vif); |
449 | struct skb_frame_desc *skbdesc; | 450 | struct skb_frame_desc *skbdesc; |
@@ -453,6 +454,11 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, | |||
453 | if (unlikely(!intf->beacon)) | 454 | if (unlikely(!intf->beacon)) |
454 | return -ENOBUFS; | 455 | return -ENOBUFS; |
455 | 456 | ||
457 | if (!enable_beacon) { | ||
458 | rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_BEACON); | ||
459 | return 0; | ||
460 | } | ||
461 | |||
456 | intf->beacon->skb = ieee80211_beacon_get(rt2x00dev->hw, vif); | 462 | intf->beacon->skb = ieee80211_beacon_get(rt2x00dev->hw, vif); |
457 | if (!intf->beacon->skb) | 463 | if (!intf->beacon->skb) |
458 | return -ENOMEM; | 464 | return -ENOMEM; |
@@ -501,6 +507,9 @@ struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, | |||
501 | { | 507 | { |
502 | int atim = test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | 508 | int atim = test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
503 | 509 | ||
510 | if (queue == QID_RX) | ||
511 | return rt2x00dev->rx; | ||
512 | |||
504 | if (queue < rt2x00dev->ops->tx_queues && rt2x00dev->tx) | 513 | if (queue < rt2x00dev->ops->tx_queues && rt2x00dev->tx) |
505 | return &rt2x00dev->tx[queue]; | 514 | return &rt2x00dev->tx[queue]; |
506 | 515 | ||
@@ -577,6 +586,14 @@ static void rt2x00queue_reset(struct data_queue *queue) | |||
577 | spin_unlock_irqrestore(&queue->lock, irqflags); | 586 | spin_unlock_irqrestore(&queue->lock, irqflags); |
578 | } | 587 | } |
579 | 588 | ||
589 | void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev) | ||
590 | { | ||
591 | struct data_queue *queue; | ||
592 | |||
593 | txall_queue_for_each(rt2x00dev, queue) | ||
594 | rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, queue->qid); | ||
595 | } | ||
596 | |||
580 | void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev) | 597 | void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev) |
581 | { | 598 | { |
582 | struct data_queue *queue; | 599 | struct data_queue *queue; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index c89d1520838c..7d50ca82375e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -296,6 +296,41 @@ void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
296 | } | 296 | } |
297 | EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue); | 297 | EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue); |
298 | 298 | ||
299 | void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev, | ||
300 | const enum data_queue_qid qid) | ||
301 | { | ||
302 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid); | ||
303 | struct queue_entry_priv_usb *entry_priv; | ||
304 | struct queue_entry_priv_usb_bcn *bcn_priv; | ||
305 | unsigned int i; | ||
306 | bool kill_guard; | ||
307 | |||
308 | /* | ||
309 | * When killing the beacon queue, we must also kill | ||
310 | * the beacon guard byte. | ||
311 | */ | ||
312 | kill_guard = | ||
313 | (qid == QID_BEACON) && | ||
314 | (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)); | ||
315 | |||
316 | /* | ||
317 | * Cancel all entries. | ||
318 | */ | ||
319 | for (i = 0; i < queue->limit; i++) { | ||
320 | entry_priv = queue->entries[i].priv_data; | ||
321 | usb_kill_urb(entry_priv->urb); | ||
322 | |||
323 | /* | ||
324 | * Kill guardian urb (if required by driver). | ||
325 | */ | ||
326 | if (kill_guard) { | ||
327 | bcn_priv = queue->entries[i].priv_data; | ||
328 | usb_kill_urb(bcn_priv->guardian_urb); | ||
329 | } | ||
330 | } | ||
331 | } | ||
332 | EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue); | ||
333 | |||
299 | /* | 334 | /* |
300 | * RX data handlers. | 335 | * RX data handlers. |
301 | */ | 336 | */ |
@@ -338,35 +373,14 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) | |||
338 | */ | 373 | */ |
339 | void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) | 374 | void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) |
340 | { | 375 | { |
341 | struct queue_entry_priv_usb *entry_priv; | ||
342 | struct queue_entry_priv_usb_bcn *bcn_priv; | ||
343 | struct data_queue *queue; | ||
344 | unsigned int i; | ||
345 | |||
346 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0, | 376 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0, |
347 | REGISTER_TIMEOUT); | 377 | REGISTER_TIMEOUT); |
348 | 378 | ||
349 | /* | 379 | /* |
350 | * Cancel all queues. | 380 | * The USB version of kill_tx_queue also works |
381 | * on the RX queue. | ||
351 | */ | 382 | */ |
352 | queue_for_each(rt2x00dev, queue) { | 383 | rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_RX); |
353 | for (i = 0; i < queue->limit; i++) { | ||
354 | entry_priv = queue->entries[i].priv_data; | ||
355 | usb_kill_urb(entry_priv->urb); | ||
356 | } | ||
357 | } | ||
358 | |||
359 | /* | ||
360 | * Kill guardian urb (if required by driver). | ||
361 | */ | ||
362 | if (!test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)) | ||
363 | return; | ||
364 | |||
365 | for (i = 0; i < rt2x00dev->bcn->limit; i++) { | ||
366 | bcn_priv = rt2x00dev->bcn->entries[i].priv_data; | ||
367 | if (bcn_priv->guardian_urb) | ||
368 | usb_kill_urb(bcn_priv->guardian_urb); | ||
369 | } | ||
370 | } | 384 | } |
371 | EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); | 385 | EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); |
372 | 386 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index fe4523887bdf..bd2d59c85f1b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h | |||
@@ -419,6 +419,17 @@ struct queue_entry_priv_usb_bcn { | |||
419 | void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 419 | void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
420 | const enum data_queue_qid qid); | 420 | const enum data_queue_qid qid); |
421 | 421 | ||
422 | /** | ||
423 | * rt2x00usb_kill_tx_queue - Kill data queue | ||
424 | * @rt2x00dev: Pointer to &struct rt2x00_dev | ||
425 | * @qid: Data queue to kill | ||
426 | * | ||
427 | * This will walk through all entries of the queue and kill all | ||
428 | * previously kicked frames before they can be send. | ||
429 | */ | ||
430 | void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev, | ||
431 | const enum data_queue_qid qid); | ||
432 | |||
422 | /* | 433 | /* |
423 | * Device initialization handlers. | 434 | * Device initialization handlers. |
424 | */ | 435 | */ |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index d81a8de9dc17..c7ad1b3d4765 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1696,24 +1696,10 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1696 | 1696 | ||
1697 | static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev) | 1697 | static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev) |
1698 | { | 1698 | { |
1699 | u32 reg; | ||
1700 | |||
1701 | rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818); | ||
1702 | |||
1703 | /* | ||
1704 | * Disable synchronisation. | ||
1705 | */ | ||
1706 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
1707 | |||
1708 | /* | 1699 | /* |
1709 | * Cancel RX and TX. | 1700 | * Disable power |
1710 | */ | 1701 | */ |
1711 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); | 1702 | rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818); |
1712 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, 1); | ||
1713 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, 1); | ||
1714 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); | ||
1715 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1); | ||
1716 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | ||
1717 | } | 1703 | } |
1718 | 1704 | ||
1719 | static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) | 1705 | static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) |
@@ -1936,6 +1922,24 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1936 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1922 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
1937 | } | 1923 | } |
1938 | 1924 | ||
1925 | static void rt61pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, | ||
1926 | const enum data_queue_qid qid) | ||
1927 | { | ||
1928 | u32 reg; | ||
1929 | |||
1930 | if (qid == QID_BEACON) { | ||
1931 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
1932 | return; | ||
1933 | } | ||
1934 | |||
1935 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); | ||
1936 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, (qid == QID_AC_BE)); | ||
1937 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, (qid == QID_AC_BK)); | ||
1938 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, (qid == QID_AC_VI)); | ||
1939 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, (qid == QID_AC_VO)); | ||
1940 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | ||
1941 | } | ||
1942 | |||
1939 | /* | 1943 | /* |
1940 | * RX control handlers | 1944 | * RX control handlers |
1941 | */ | 1945 | */ |
@@ -2761,6 +2765,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | |||
2761 | .write_tx_data = rt2x00pci_write_tx_data, | 2765 | .write_tx_data = rt2x00pci_write_tx_data, |
2762 | .write_beacon = rt61pci_write_beacon, | 2766 | .write_beacon = rt61pci_write_beacon, |
2763 | .kick_tx_queue = rt61pci_kick_tx_queue, | 2767 | .kick_tx_queue = rt61pci_kick_tx_queue, |
2768 | .kill_tx_queue = rt61pci_kill_tx_queue, | ||
2764 | .fill_rxdone = rt61pci_fill_rxdone, | 2769 | .fill_rxdone = rt61pci_fill_rxdone, |
2765 | .config_shared_key = rt61pci_config_shared_key, | 2770 | .config_shared_key = rt61pci_config_shared_key, |
2766 | .config_pairwise_key = rt61pci_config_pairwise_key, | 2771 | .config_pairwise_key = rt61pci_config_pairwise_key, |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index f854551be75d..24e97b341cf8 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -2293,6 +2293,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | |||
2293 | .write_beacon = rt73usb_write_beacon, | 2293 | .write_beacon = rt73usb_write_beacon, |
2294 | .get_tx_data_len = rt73usb_get_tx_data_len, | 2294 | .get_tx_data_len = rt73usb_get_tx_data_len, |
2295 | .kick_tx_queue = rt73usb_kick_tx_queue, | 2295 | .kick_tx_queue = rt73usb_kick_tx_queue, |
2296 | .kill_tx_queue = rt2x00usb_kill_tx_queue, | ||
2296 | .fill_rxdone = rt73usb_fill_rxdone, | 2297 | .fill_rxdone = rt73usb_fill_rxdone, |
2297 | .config_shared_key = rt73usb_config_shared_key, | 2298 | .config_shared_key = rt73usb_config_shared_key, |
2298 | .config_pairwise_key = rt73usb_config_pairwise_key, | 2299 | .config_pairwise_key = rt73usb_config_pairwise_key, |