aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c54
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c55
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c50
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h11
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c23
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00reg.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c64
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c2
11 files changed, 201 insertions, 70 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 25e9dcf65c4e..116244b72371 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -879,7 +879,8 @@ static void rt2400pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
879static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev, 879static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
880 enum dev_state state) 880 enum dev_state state)
881{ 881{
882 int mask = (state == STATE_RADIO_IRQ_OFF); 882 int mask = (state == STATE_RADIO_IRQ_OFF) ||
883 (state == STATE_RADIO_IRQ_OFF_ISR);
883 u32 reg; 884 u32 reg;
884 885
885 /* 886 /*
@@ -980,7 +981,9 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
980 rt2400pci_toggle_rx(rt2x00dev, state); 981 rt2400pci_toggle_rx(rt2x00dev, state);
981 break; 982 break;
982 case STATE_RADIO_IRQ_ON: 983 case STATE_RADIO_IRQ_ON:
984 case STATE_RADIO_IRQ_ON_ISR:
983 case STATE_RADIO_IRQ_OFF: 985 case STATE_RADIO_IRQ_OFF:
986 case STATE_RADIO_IRQ_OFF_ISR:
984 rt2400pci_toggle_irq(rt2x00dev, state); 987 rt2400pci_toggle_irq(rt2x00dev, state);
985 break; 988 break;
986 case STATE_DEEP_SLEEP: 989 case STATE_DEEP_SLEEP:
@@ -1235,23 +1238,10 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev,
1235 } 1238 }
1236} 1239}
1237 1240
1238static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) 1241static irqreturn_t rt2400pci_interrupt_thread(int irq, void *dev_instance)
1239{ 1242{
1240 struct rt2x00_dev *rt2x00dev = dev_instance; 1243 struct rt2x00_dev *rt2x00dev = dev_instance;
1241 u32 reg; 1244 u32 reg = rt2x00dev->irqvalue[0];
1242
1243 /*
1244 * Get the interrupt sources & saved to local variable.
1245 * Write register value back to clear pending interrupts.
1246 */
1247 rt2x00pci_register_read(rt2x00dev, CSR7, &reg);
1248 rt2x00pci_register_write(rt2x00dev, CSR7, reg);
1249
1250 if (!reg)
1251 return IRQ_NONE;
1252
1253 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
1254 return IRQ_HANDLED;
1255 1245
1256 /* 1246 /*
1257 * Handle interrupts, walk through all bits 1247 * Handle interrupts, walk through all bits
@@ -1289,9 +1279,40 @@ static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance)
1289 if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING)) 1279 if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING))
1290 rt2400pci_txdone(rt2x00dev, QID_AC_BK); 1280 rt2400pci_txdone(rt2x00dev, QID_AC_BK);
1291 1281
1282 /* Enable interrupts again. */
1283 rt2x00dev->ops->lib->set_device_state(rt2x00dev,
1284 STATE_RADIO_IRQ_ON_ISR);
1292 return IRQ_HANDLED; 1285 return IRQ_HANDLED;
1293} 1286}
1294 1287
1288static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance)
1289{
1290 struct rt2x00_dev *rt2x00dev = dev_instance;
1291 u32 reg;
1292
1293 /*
1294 * Get the interrupt sources & saved to local variable.
1295 * Write register value back to clear pending interrupts.
1296 */
1297 rt2x00pci_register_read(rt2x00dev, CSR7, &reg);
1298 rt2x00pci_register_write(rt2x00dev, CSR7, reg);
1299
1300 if (!reg)
1301 return IRQ_NONE;
1302
1303 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
1304 return IRQ_HANDLED;
1305
1306 /* Store irqvalues for use in the interrupt thread. */
1307 rt2x00dev->irqvalue[0] = reg;
1308
1309 /* Disable interrupts, will be enabled again in the interrupt thread. */
1310 rt2x00dev->ops->lib->set_device_state(rt2x00dev,
1311 STATE_RADIO_IRQ_OFF_ISR);
1312
1313 return IRQ_WAKE_THREAD;
1314}
1315
1295/* 1316/*
1296 * Device probe functions. 1317 * Device probe functions.
1297 */ 1318 */
@@ -1581,6 +1602,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
1581 1602
1582static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { 1603static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
1583 .irq_handler = rt2400pci_interrupt, 1604 .irq_handler = rt2400pci_interrupt,
1605 .irq_handler_thread = rt2400pci_interrupt_thread,
1584 .probe_hw = rt2400pci_probe_hw, 1606 .probe_hw = rt2400pci_probe_hw,
1585 .initialize = rt2x00pci_initialize, 1607 .initialize = rt2x00pci_initialize,
1586 .uninitialize = rt2x00pci_uninitialize, 1608 .uninitialize = rt2x00pci_uninitialize,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index faa804cf181a..5e80948d1a3e 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1033,7 +1033,8 @@ static void rt2500pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
1033static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev, 1033static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
1034 enum dev_state state) 1034 enum dev_state state)
1035{ 1035{
1036 int mask = (state == STATE_RADIO_IRQ_OFF); 1036 int mask = (state == STATE_RADIO_IRQ_OFF) ||
1037 (state == STATE_RADIO_IRQ_OFF_ISR);
1037 u32 reg; 1038 u32 reg;
1038 1039
1039 /* 1040 /*
@@ -1134,7 +1135,9 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev,
1134 rt2500pci_toggle_rx(rt2x00dev, state); 1135 rt2500pci_toggle_rx(rt2x00dev, state);
1135 break; 1136 break;
1136 case STATE_RADIO_IRQ_ON: 1137 case STATE_RADIO_IRQ_ON:
1138 case STATE_RADIO_IRQ_ON_ISR:
1137 case STATE_RADIO_IRQ_OFF: 1139 case STATE_RADIO_IRQ_OFF:
1140 case STATE_RADIO_IRQ_OFF_ISR:
1138 rt2500pci_toggle_irq(rt2x00dev, state); 1141 rt2500pci_toggle_irq(rt2x00dev, state);
1139 break; 1142 break;
1140 case STATE_DEEP_SLEEP: 1143 case STATE_DEEP_SLEEP:
@@ -1367,23 +1370,10 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev,
1367 } 1370 }
1368} 1371}
1369 1372
1370static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) 1373static irqreturn_t rt2500pci_interrupt_thread(int irq, void *dev_instance)
1371{ 1374{
1372 struct rt2x00_dev *rt2x00dev = dev_instance; 1375 struct rt2x00_dev *rt2x00dev = dev_instance;
1373 u32 reg; 1376 u32 reg = rt2x00dev->irqvalue[0];
1374
1375 /*
1376 * Get the interrupt sources & saved to local variable.
1377 * Write register value back to clear pending interrupts.
1378 */
1379 rt2x00pci_register_read(rt2x00dev, CSR7, &reg);
1380 rt2x00pci_register_write(rt2x00dev, CSR7, reg);
1381
1382 if (!reg)
1383 return IRQ_NONE;
1384
1385 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
1386 return IRQ_HANDLED;
1387 1377
1388 /* 1378 /*
1389 * Handle interrupts, walk through all bits 1379 * Handle interrupts, walk through all bits
@@ -1421,9 +1411,41 @@ static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance)
1421 if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING)) 1411 if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING))
1422 rt2500pci_txdone(rt2x00dev, QID_AC_BK); 1412 rt2500pci_txdone(rt2x00dev, QID_AC_BK);
1423 1413
1414 /* Enable interrupts again. */
1415 rt2x00dev->ops->lib->set_device_state(rt2x00dev,
1416 STATE_RADIO_IRQ_ON_ISR);
1417
1424 return IRQ_HANDLED; 1418 return IRQ_HANDLED;
1425} 1419}
1426 1420
1421static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance)
1422{
1423 struct rt2x00_dev *rt2x00dev = dev_instance;
1424 u32 reg;
1425
1426 /*
1427 * Get the interrupt sources & saved to local variable.
1428 * Write register value back to clear pending interrupts.
1429 */
1430 rt2x00pci_register_read(rt2x00dev, CSR7, &reg);
1431 rt2x00pci_register_write(rt2x00dev, CSR7, reg);
1432
1433 if (!reg)
1434 return IRQ_NONE;
1435
1436 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
1437 return IRQ_HANDLED;
1438
1439 /* Store irqvalues for use in the interrupt thread. */
1440 rt2x00dev->irqvalue[0] = reg;
1441
1442 /* Disable interrupts, will be enabled again in the interrupt thread. */
1443 rt2x00dev->ops->lib->set_device_state(rt2x00dev,
1444 STATE_RADIO_IRQ_OFF_ISR);
1445
1446 return IRQ_WAKE_THREAD;
1447}
1448
1427/* 1449/*
1428 * Device probe functions. 1450 * Device probe functions.
1429 */ 1451 */
@@ -1874,6 +1896,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
1874 1896
1875static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { 1897static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
1876 .irq_handler = rt2500pci_interrupt, 1898 .irq_handler = rt2500pci_interrupt,
1899 .irq_handler_thread = rt2500pci_interrupt_thread,
1877 .probe_hw = rt2500pci_probe_hw, 1900 .probe_hw = rt2500pci_probe_hw,
1878 .initialize = rt2x00pci_initialize, 1901 .initialize = rt2x00pci_initialize,
1879 .uninitialize = rt2x00pci_uninitialize, 1902 .uninitialize = rt2x00pci_uninitialize,
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 009323e6c20f..242d59558b79 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1004,7 +1004,9 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev,
1004 rt2500usb_toggle_rx(rt2x00dev, state); 1004 rt2500usb_toggle_rx(rt2x00dev, state);
1005 break; 1005 break;
1006 case STATE_RADIO_IRQ_ON: 1006 case STATE_RADIO_IRQ_ON:
1007 case STATE_RADIO_IRQ_ON_ISR:
1007 case STATE_RADIO_IRQ_OFF: 1008 case STATE_RADIO_IRQ_OFF:
1009 case STATE_RADIO_IRQ_OFF_ISR:
1008 /* No support, but no error either */ 1010 /* No support, but no error either */
1009 break; 1011 break;
1010 case STATE_DEEP_SLEEP: 1012 case STATE_DEEP_SLEEP:
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index a9eca99d416c..f21b77c61ad4 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -422,7 +422,8 @@ static void rt2800pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
422static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, 422static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
423 enum dev_state state) 423 enum dev_state state)
424{ 424{
425 int mask = (state == STATE_RADIO_IRQ_ON); 425 int mask = (state == STATE_RADIO_IRQ_ON) ||
426 (state == STATE_RADIO_IRQ_ON_ISR);
426 u32 reg; 427 u32 reg;
427 428
428 /* 429 /*
@@ -631,7 +632,9 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
631 rt2800pci_toggle_rx(rt2x00dev, state); 632 rt2800pci_toggle_rx(rt2x00dev, state);
632 break; 633 break;
633 case STATE_RADIO_IRQ_ON: 634 case STATE_RADIO_IRQ_ON:
635 case STATE_RADIO_IRQ_ON_ISR:
634 case STATE_RADIO_IRQ_OFF: 636 case STATE_RADIO_IRQ_OFF:
637 case STATE_RADIO_IRQ_OFF_ISR:
635 rt2800pci_toggle_irq(rt2x00dev, state); 638 rt2800pci_toggle_irq(rt2x00dev, state);
636 break; 639 break;
637 case STATE_DEEP_SLEEP: 640 case STATE_DEEP_SLEEP:
@@ -929,20 +932,10 @@ static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev)
929 rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); 932 rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);
930} 933}
931 934
932static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) 935static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance)
933{ 936{
934 struct rt2x00_dev *rt2x00dev = dev_instance; 937 struct rt2x00_dev *rt2x00dev = dev_instance;
935 u32 reg; 938 u32 reg = rt2x00dev->irqvalue[0];
936
937 /* Read status and ACK all interrupts */
938 rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
939 rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, reg);
940
941 if (!reg)
942 return IRQ_NONE;
943
944 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
945 return IRQ_HANDLED;
946 939
947 /* 940 /*
948 * 1 - Rx ring done interrupt. 941 * 1 - Rx ring done interrupt.
@@ -962,9 +955,39 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance)
962 if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP)) 955 if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP))
963 rt2800pci_wakeup(rt2x00dev); 956 rt2800pci_wakeup(rt2x00dev);
964 957
958 /* Enable interrupts again. */
959 rt2x00dev->ops->lib->set_device_state(rt2x00dev,
960 STATE_RADIO_IRQ_ON_ISR);
961
965 return IRQ_HANDLED; 962 return IRQ_HANDLED;
966} 963}
967 964
965static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance)
966{
967 struct rt2x00_dev *rt2x00dev = dev_instance;
968 u32 reg;
969
970 /* Read status and ACK all interrupts */
971 rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
972 rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, reg);
973
974 if (!reg)
975 return IRQ_NONE;
976
977 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
978 return IRQ_HANDLED;
979
980 /* Store irqvalue for use in the interrupt thread. */
981 rt2x00dev->irqvalue[0] = reg;
982
983 /* Disable interrupts, will be enabled again in the interrupt thread. */
984 rt2x00dev->ops->lib->set_device_state(rt2x00dev,
985 STATE_RADIO_IRQ_OFF_ISR);
986
987
988 return IRQ_WAKE_THREAD;
989}
990
968/* 991/*
969 * Device probe functions. 992 * Device probe functions.
970 */ 993 */
@@ -1049,6 +1072,7 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
1049 1072
1050static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { 1073static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
1051 .irq_handler = rt2800pci_interrupt, 1074 .irq_handler = rt2800pci_interrupt,
1075 .irq_handler_thread = rt2800pci_interrupt_thread,
1052 .probe_hw = rt2800pci_probe_hw, 1076 .probe_hw = rt2800pci_probe_hw,
1053 .get_firmware_name = rt2800pci_get_firmware_name, 1077 .get_firmware_name = rt2800pci_get_firmware_name,
1054 .check_firmware = rt2800pci_check_firmware, 1078 .check_firmware = rt2800pci_check_firmware,
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 5aa7563155cd..df78e28526bf 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -406,7 +406,9 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
406 rt2800usb_toggle_rx(rt2x00dev, state); 406 rt2800usb_toggle_rx(rt2x00dev, state);
407 break; 407 break;
408 case STATE_RADIO_IRQ_ON: 408 case STATE_RADIO_IRQ_ON:
409 case STATE_RADIO_IRQ_ON_ISR:
409 case STATE_RADIO_IRQ_OFF: 410 case STATE_RADIO_IRQ_OFF:
411 case STATE_RADIO_IRQ_OFF_ISR:
410 /* No support, but no error either */ 412 /* No support, but no error either */
411 break; 413 break;
412 case STATE_DEEP_SLEEP: 414 case STATE_DEEP_SLEEP:
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 97b6261fee4f..0fa21410676f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -515,6 +515,11 @@ struct rt2x00lib_ops {
515 irq_handler_t irq_handler; 515 irq_handler_t irq_handler;
516 516
517 /* 517 /*
518 * Threaded Interrupt handlers.
519 */
520 irq_handler_t irq_handler_thread;
521
522 /*
518 * Device init handlers. 523 * Device init handlers.
519 */ 524 */
520 int (*probe_hw) (struct rt2x00_dev *rt2x00dev); 525 int (*probe_hw) (struct rt2x00_dev *rt2x00dev);
@@ -871,6 +876,12 @@ struct rt2x00_dev {
871 const struct firmware *fw; 876 const struct firmware *fw;
872 877
873 /* 878 /*
879 * Interrupt values, stored between interrupt service routine
880 * and interrupt thread routine.
881 */
882 u32 irqvalue[2];
883
884 /*
874 * Driver specific data. 885 * Driver specific data.
875 */ 886 */
876 void *priv; 887 void *priv;
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 0906e14b347f..d3ebb4144562 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -340,9 +340,17 @@ void rt2x00lib_txdone(struct queue_entry *entry,
340 * send the status report back. 340 * send the status report back.
341 */ 341 */
342 if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) 342 if (!(skbdesc_flags & SKBDESC_NOT_MAC80211))
343 ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb); 343 /*
344 * Only PCI and SOC devices process the tx status in process
345 * context. Hence use ieee80211_tx_status for PCI and SOC
346 * devices and stick to ieee80211_tx_status_irqsafe for USB.
347 */
348 if (rt2x00_is_usb(rt2x00dev))
349 ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb);
350 else
351 ieee80211_tx_status(rt2x00dev->hw, entry->skb);
344 else 352 else
345 dev_kfree_skb_irq(entry->skb); 353 dev_kfree_skb_any(entry->skb);
346 354
347 /* 355 /*
348 * Make this entry available for reuse. 356 * Make this entry available for reuse.
@@ -489,7 +497,16 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
489 */ 497 */
490 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); 498 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb);
491 memcpy(IEEE80211_SKB_RXCB(entry->skb), rx_status, sizeof(*rx_status)); 499 memcpy(IEEE80211_SKB_RXCB(entry->skb), rx_status, sizeof(*rx_status));
492 ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb); 500
501 /*
502 * Currently only PCI and SOC devices handle rx interrupts in process
503 * context. Hence, use ieee80211_rx_irqsafe for USB and ieee80211_rx_ni
504 * for PCI and SOC devices.
505 */
506 if (rt2x00_is_usb(rt2x00dev))
507 ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb);
508 else
509 ieee80211_rx_ni(rt2x00dev->hw, entry->skb);
493 510
494 /* 511 /*
495 * Replace the skb with the freshly allocated one. 512 * Replace the skb with the freshly allocated one.
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index fc9da8358784..19b262e1ddbe 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -153,8 +153,10 @@ int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
153 /* 153 /*
154 * Register interrupt handler. 154 * Register interrupt handler.
155 */ 155 */
156 status = request_irq(rt2x00dev->irq, rt2x00dev->ops->lib->irq_handler, 156 status = request_threaded_irq(rt2x00dev->irq,
157 IRQF_SHARED, rt2x00dev->name, rt2x00dev); 157 rt2x00dev->ops->lib->irq_handler,
158 rt2x00dev->ops->lib->irq_handler_thread,
159 IRQF_SHARED, rt2x00dev->name, rt2x00dev);
158 if (status) { 160 if (status) {
159 ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n", 161 ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n",
160 rt2x00dev->irq, status); 162 rt2x00dev->irq, status);
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h
index b9fe94873ee0..055501c355a5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00reg.h
+++ b/drivers/net/wireless/rt2x00/rt2x00reg.h
@@ -88,6 +88,8 @@ enum dev_state {
88 STATE_RADIO_RX_OFF_LINK, 88 STATE_RADIO_RX_OFF_LINK,
89 STATE_RADIO_IRQ_ON, 89 STATE_RADIO_IRQ_ON,
90 STATE_RADIO_IRQ_OFF, 90 STATE_RADIO_IRQ_OFF,
91 STATE_RADIO_IRQ_ON_ISR,
92 STATE_RADIO_IRQ_OFF_ISR,
91}; 93};
92 94
93/* 95/*
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index fe7bce7c05de..049433fa760d 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1622,7 +1622,8 @@ static void rt61pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
1622static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, 1622static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
1623 enum dev_state state) 1623 enum dev_state state)
1624{ 1624{
1625 int mask = (state == STATE_RADIO_IRQ_OFF); 1625 int mask = (state == STATE_RADIO_IRQ_OFF) ||
1626 (state == STATE_RADIO_IRQ_OFF_ISR);
1626 u32 reg; 1627 u32 reg;
1627 1628
1628 /* 1629 /*
@@ -1739,7 +1740,9 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
1739 rt61pci_toggle_rx(rt2x00dev, state); 1740 rt61pci_toggle_rx(rt2x00dev, state);
1740 break; 1741 break;
1741 case STATE_RADIO_IRQ_ON: 1742 case STATE_RADIO_IRQ_ON:
1743 case STATE_RADIO_IRQ_ON_ISR:
1742 case STATE_RADIO_IRQ_OFF: 1744 case STATE_RADIO_IRQ_OFF:
1745 case STATE_RADIO_IRQ_OFF_ISR:
1743 rt61pci_toggle_irq(rt2x00dev, state); 1746 rt61pci_toggle_irq(rt2x00dev, state);
1744 break; 1747 break;
1745 case STATE_DEEP_SLEEP: 1748 case STATE_DEEP_SLEEP:
@@ -2147,27 +2150,11 @@ static void rt61pci_wakeup(struct rt2x00_dev *rt2x00dev)
2147 rt61pci_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); 2150 rt61pci_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);
2148} 2151}
2149 2152
2150static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) 2153static irqreturn_t rt61pci_interrupt_thread(int irq, void *dev_instance)
2151{ 2154{
2152 struct rt2x00_dev *rt2x00dev = dev_instance; 2155 struct rt2x00_dev *rt2x00dev = dev_instance;
2153 u32 reg_mcu; 2156 u32 reg = rt2x00dev->irqvalue[0];
2154 u32 reg; 2157 u32 reg_mcu = rt2x00dev->irqvalue[1];
2155
2156 /*
2157 * Get the interrupt sources & saved to local variable.
2158 * Write register value back to clear pending interrupts.
2159 */
2160 rt2x00pci_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, &reg_mcu);
2161 rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg_mcu);
2162
2163 rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
2164 rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg);
2165
2166 if (!reg && !reg_mcu)
2167 return IRQ_NONE;
2168
2169 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
2170 return IRQ_HANDLED;
2171 2158
2172 /* 2159 /*
2173 * Handle interrupts, walk through all bits 2160 * Handle interrupts, walk through all bits
@@ -2206,9 +2193,45 @@ static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance)
2206 if (rt2x00_get_field32(reg, INT_SOURCE_CSR_BEACON_DONE)) 2193 if (rt2x00_get_field32(reg, INT_SOURCE_CSR_BEACON_DONE))
2207 rt2x00lib_beacondone(rt2x00dev); 2194 rt2x00lib_beacondone(rt2x00dev);
2208 2195
2196 /* Enable interrupts again. */
2197 rt2x00dev->ops->lib->set_device_state(rt2x00dev,
2198 STATE_RADIO_IRQ_ON_ISR);
2209 return IRQ_HANDLED; 2199 return IRQ_HANDLED;
2210} 2200}
2211 2201
2202
2203static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance)
2204{
2205 struct rt2x00_dev *rt2x00dev = dev_instance;
2206 u32 reg_mcu;
2207 u32 reg;
2208
2209 /*
2210 * Get the interrupt sources & saved to local variable.
2211 * Write register value back to clear pending interrupts.
2212 */
2213 rt2x00pci_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, &reg_mcu);
2214 rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg_mcu);
2215
2216 rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
2217 rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg);
2218
2219 if (!reg && !reg_mcu)
2220 return IRQ_NONE;
2221
2222 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
2223 return IRQ_HANDLED;
2224
2225 /* Store irqvalues for use in the interrupt thread. */
2226 rt2x00dev->irqvalue[0] = reg;
2227 rt2x00dev->irqvalue[1] = reg_mcu;
2228
2229 /* Disable interrupts, will be enabled again in the interrupt thread. */
2230 rt2x00dev->ops->lib->set_device_state(rt2x00dev,
2231 STATE_RADIO_IRQ_OFF_ISR);
2232 return IRQ_WAKE_THREAD;
2233}
2234
2212/* 2235/*
2213 * Device probe functions. 2236 * Device probe functions.
2214 */ 2237 */
@@ -2795,6 +2818,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
2795 2818
2796static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { 2819static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
2797 .irq_handler = rt61pci_interrupt, 2820 .irq_handler = rt61pci_interrupt,
2821 .irq_handler_thread = rt61pci_interrupt_thread,
2798 .probe_hw = rt61pci_probe_hw, 2822 .probe_hw = rt61pci_probe_hw,
2799 .get_firmware_name = rt61pci_get_firmware_name, 2823 .get_firmware_name = rt61pci_get_firmware_name,
2800 .check_firmware = rt61pci_check_firmware, 2824 .check_firmware = rt61pci_check_firmware,
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index cad07b69c53e..aa9de18fd410 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1400,7 +1400,9 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
1400 rt73usb_toggle_rx(rt2x00dev, state); 1400 rt73usb_toggle_rx(rt2x00dev, state);
1401 break; 1401 break;
1402 case STATE_RADIO_IRQ_ON: 1402 case STATE_RADIO_IRQ_ON:
1403 case STATE_RADIO_IRQ_ON_ISR:
1403 case STATE_RADIO_IRQ_OFF: 1404 case STATE_RADIO_IRQ_OFF:
1405 case STATE_RADIO_IRQ_OFF_ISR:
1404 /* No support, but no error either */ 1406 /* No support, but no error either */
1405 break; 1407 break;
1406 case STATE_DEEP_SLEEP: 1408 case STATE_DEEP_SLEEP: