aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2009-01-27 18:32:33 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-02-09 15:03:34 -0500
commita2c9b652a12a550d3d8509e9bae43bac396c5076 (patch)
tree8e871e038bc73465c6eca67f8563e9562d079d56 /drivers
parent382fe0f2da78db7833c6a7278e33e694e6e2a6f3 (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')
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c30
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c30
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h13
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c19
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c62
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h11
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c37
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c1
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
935static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev) 935static 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, &reg);
950 rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
951 rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
952} 941}
953 942
954static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev, 943static 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
1137static 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, &reg);
1146 rt2x00_set_field32(&reg, 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
1094static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev) 1094static 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, &reg);
1109 rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
1110 rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
1111} 1100}
1112 1101
1113static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev, 1102static 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
1295static 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, &reg);
1304 rt2x00_set_field32(&reg, 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 */
127int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, 128int 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,
139void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); 141void 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 */
150void 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
445int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, 445int 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
589void 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
580void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev) 597void 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}
297EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue); 297EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue);
298 298
299void 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}
332EXPORT_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 */
339void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) 374void 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}
371EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); 385EXPORT_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 {
419void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, 419void 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 */
430void 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
1697static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev) 1697static 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, &reg); 1702 rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818);
1712 rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC0, 1);
1713 rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC1, 1);
1714 rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC2, 1);
1715 rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC3, 1);
1716 rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
1717} 1703}
1718 1704
1719static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) 1705static 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
1925static 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, &reg);
1936 rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC0, (qid == QID_AC_BE));
1937 rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC1, (qid == QID_AC_BK));
1938 rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC2, (qid == QID_AC_VI));
1939 rt2x00_set_field32(&reg, 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,