aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorGertjan van Wingerde <gwingerde@kpnplanet.nl>2008-05-10 07:43:33 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-21 21:47:32 -0400
commit61448f88078e813bbaaa58eb775d650c85e7d407 (patch)
tree1a64fc0de784a3288369f9e554e7e2ec122ebc65 /drivers
parent61486e0f68d1f8966c09b734566a187d42d65c54 (diff)
rt2x00: Fix queue related oops in case of deselected mac80211 multi-queue feature.
With the integration of the mac80211 multiqueue patches it has become possible that the mac80211 layer modifies the number of TX queues that is stored inside the ieee80211_hw structure, especially when multi-queue is not selected. The rt2x00 drivers are not well suited to handle that situation, as they allocate the queue structures before mac80211 has modified the number of queues it is going to use, and also expect the number of allocated queues to match the hardware implementation. Hence, ensure that rt2x00 maintains by itself the number of queues that the hardware supports, and, at the same time, making is not dependent on the preservation of contents inside a mac80211 structure. Signed-off-by: Gertjan van Wingerde <gwingerde@kpnplanet.nl> 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.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.h5
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.h5
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.h5
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.h5
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.h5
15 files changed, 42 insertions, 11 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index fb02d118075b..b4310d798f94 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1373,7 +1373,6 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1373 rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 1373 rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1374 IEEE80211_HW_SIGNAL_DBM; 1374 IEEE80211_HW_SIGNAL_DBM;
1375 rt2x00dev->hw->extra_tx_headroom = 0; 1375 rt2x00dev->hw->extra_tx_headroom = 0;
1376 rt2x00dev->hw->queues = 2;
1377 1376
1378 SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); 1377 SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev);
1379 SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, 1378 SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
@@ -1620,6 +1619,7 @@ static const struct rt2x00_ops rt2400pci_ops = {
1620 .max_ap_intf = 1, 1619 .max_ap_intf = 1,
1621 .eeprom_size = EEPROM_SIZE, 1620 .eeprom_size = EEPROM_SIZE,
1622 .rf_size = RF_SIZE, 1621 .rf_size = RF_SIZE,
1622 .tx_queues = NUM_TX_QUEUES,
1623 .rx = &rt2400pci_queue_rx, 1623 .rx = &rt2400pci_queue_rx,
1624 .tx = &rt2400pci_queue_tx, 1624 .tx = &rt2400pci_queue_tx,
1625 .bcn = &rt2400pci_queue_bcn, 1625 .bcn = &rt2400pci_queue_bcn,
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h
index a5210f9a3360..e9aa326be9f6 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.h
+++ b/drivers/net/wireless/rt2x00/rt2400pci.h
@@ -52,6 +52,11 @@
52#define RF_SIZE 0x0010 52#define RF_SIZE 0x0010
53 53
54/* 54/*
55 * Number of TX queues.
56 */
57#define NUM_TX_QUEUES 2
58
59/*
55 * Control/Status Registers(CSR). 60 * Control/Status Registers(CSR).
56 * Some values are set in TU, whereas 1 TU == 1024 us. 61 * Some values are set in TU, whereas 1 TU == 1024 us.
57 */ 62 */
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 1724ce90f8b1..54aaa8375a2c 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1692,7 +1692,6 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1692 IEEE80211_HW_SIGNAL_DBM; 1692 IEEE80211_HW_SIGNAL_DBM;
1693 1693
1694 rt2x00dev->hw->extra_tx_headroom = 0; 1694 rt2x00dev->hw->extra_tx_headroom = 0;
1695 rt2x00dev->hw->queues = 2;
1696 1695
1697 SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); 1696 SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev);
1698 SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, 1697 SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
@@ -1933,6 +1932,7 @@ static const struct rt2x00_ops rt2500pci_ops = {
1933 .max_ap_intf = 1, 1932 .max_ap_intf = 1,
1934 .eeprom_size = EEPROM_SIZE, 1933 .eeprom_size = EEPROM_SIZE,
1935 .rf_size = RF_SIZE, 1934 .rf_size = RF_SIZE,
1935 .tx_queues = NUM_TX_QUEUES,
1936 .rx = &rt2500pci_queue_rx, 1936 .rx = &rt2500pci_queue_rx,
1937 .tx = &rt2500pci_queue_tx, 1937 .tx = &rt2500pci_queue_tx,
1938 .bcn = &rt2500pci_queue_bcn, 1938 .bcn = &rt2500pci_queue_bcn,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h
index 13899550465a..ea93b8f423a9 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/rt2x00/rt2500pci.h
@@ -63,6 +63,11 @@
63#define RF_SIZE 0x0014 63#define RF_SIZE 0x0014
64 64
65/* 65/*
66 * Number of TX queues.
67 */
68#define NUM_TX_QUEUES 2
69
70/*
66 * Control/Status Registers(CSR). 71 * Control/Status Registers(CSR).
67 * Some values are set in TU, whereas 1 TU == 1024 us. 72 * Some values are set in TU, whereas 1 TU == 1024 us.
68 */ 73 */
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 7df06ece1b45..661cf3d7212a 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1590,7 +1590,6 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1590 IEEE80211_HW_SIGNAL_DBM; 1590 IEEE80211_HW_SIGNAL_DBM;
1591 1591
1592 rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; 1592 rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
1593 rt2x00dev->hw->queues = 2;
1594 1593
1595 SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); 1594 SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev);
1596 SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, 1595 SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
@@ -1826,6 +1825,7 @@ static const struct rt2x00_ops rt2500usb_ops = {
1826 .max_ap_intf = 1, 1825 .max_ap_intf = 1,
1827 .eeprom_size = EEPROM_SIZE, 1826 .eeprom_size = EEPROM_SIZE,
1828 .rf_size = RF_SIZE, 1827 .rf_size = RF_SIZE,
1828 .tx_queues = NUM_TX_QUEUES,
1829 .rx = &rt2500usb_queue_rx, 1829 .rx = &rt2500usb_queue_rx,
1830 .tx = &rt2500usb_queue_tx, 1830 .tx = &rt2500usb_queue_tx,
1831 .bcn = &rt2500usb_queue_bcn, 1831 .bcn = &rt2500usb_queue_bcn,
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h
index a37a068d0c71..7d50098f0cc5 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.h
+++ b/drivers/net/wireless/rt2x00/rt2500usb.h
@@ -63,6 +63,11 @@
63#define RF_SIZE 0x0014 63#define RF_SIZE 0x0014
64 64
65/* 65/*
66 * Number of TX queues.
67 */
68#define NUM_TX_QUEUES 2
69
70/*
66 * Control/Status Registers(CSR). 71 * Control/Status Registers(CSR).
67 * Some values are set in TU, whereas 1 TU == 1024 us. 72 * Some values are set in TU, whereas 1 TU == 1024 us.
68 */ 73 */
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 65614841f748..6f7b34fac16c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -591,6 +591,7 @@ struct rt2x00_ops {
591 const unsigned int max_ap_intf; 591 const unsigned int max_ap_intf;
592 const unsigned int eeprom_size; 592 const unsigned int eeprom_size;
593 const unsigned int rf_size; 593 const unsigned int rf_size;
594 const unsigned int tx_queues;
594 const struct data_queue_desc *rx; 595 const struct data_queue_desc *rx;
595 const struct data_queue_desc *tx; 596 const struct data_queue_desc *tx;
596 const struct data_queue_desc *bcn; 597 const struct data_queue_desc *bcn;
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index e1368f709858..46c377873f16 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -975,6 +975,11 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
975 return status; 975 return status;
976 976
977 /* 977 /*
978 * Initialize HW fields.
979 */
980 rt2x00dev->hw->queues = rt2x00dev->ops->tx_queues;
981
982 /*
978 * Register HW. 983 * Register HW.
979 */ 984 */
980 status = ieee80211_register_hw(rt2x00dev->hw); 985 status = ieee80211_register_hw(rt2x00dev->hw);
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 767e0ffce04e..c5cedb29b87d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -456,7 +456,7 @@ int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw,
456 struct rt2x00_dev *rt2x00dev = hw->priv; 456 struct rt2x00_dev *rt2x00dev = hw->priv;
457 unsigned int i; 457 unsigned int i;
458 458
459 for (i = 0; i < hw->queues; i++) { 459 for (i = 0; i < rt2x00dev->ops->tx_queues; i++) {
460 stats[i].len = rt2x00dev->tx[i].length; 460 stats[i].len = rt2x00dev->tx[i].length;
461 stats[i].limit = rt2x00dev->tx[i].limit; 461 stats[i].limit = rt2x00dev->tx[i].limit;
462 stats[i].count = rt2x00dev->tx[i].count; 462 stats[i].count = rt2x00dev->tx[i].count;
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index e5b861f8416d..95f8dd3462f6 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -34,7 +34,7 @@ struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,
34{ 34{
35 int atim = test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); 35 int atim = test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
36 36
37 if (queue < rt2x00dev->hw->queues && rt2x00dev->tx) 37 if (queue < rt2x00dev->ops->tx_queues && rt2x00dev->tx)
38 return &rt2x00dev->tx[queue]; 38 return &rt2x00dev->tx[queue];
39 39
40 if (!rt2x00dev->bcn) 40 if (!rt2x00dev->bcn)
@@ -255,11 +255,11 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
255 /* 255 /*
256 * We need the following queues: 256 * We need the following queues:
257 * RX: 1 257 * RX: 1
258 * TX: hw->queues 258 * TX: ops->tx_queues
259 * Beacon: 1 259 * Beacon: 1
260 * Atim: 1 (if required) 260 * Atim: 1 (if required)
261 */ 261 */
262 rt2x00dev->data_queues = 2 + rt2x00dev->hw->queues + req_atim; 262 rt2x00dev->data_queues = 2 + rt2x00dev->ops->tx_queues + req_atim;
263 263
264 queue = kzalloc(rt2x00dev->data_queues * sizeof(*queue), GFP_KERNEL); 264 queue = kzalloc(rt2x00dev->data_queues * sizeof(*queue), GFP_KERNEL);
265 if (!queue) { 265 if (!queue) {
@@ -272,7 +272,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
272 */ 272 */
273 rt2x00dev->rx = queue; 273 rt2x00dev->rx = queue;
274 rt2x00dev->tx = &queue[1]; 274 rt2x00dev->tx = &queue[1];
275 rt2x00dev->bcn = &queue[1 + rt2x00dev->hw->queues]; 275 rt2x00dev->bcn = &queue[1 + rt2x00dev->ops->tx_queues];
276 276
277 /* 277 /*
278 * Initialize queue parameters. 278 * Initialize queue parameters.
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 3f7cfa9b7da5..4bde98ba3c60 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -397,7 +397,7 @@ struct data_queue_desc {
397 * the end of the TX queue array. 397 * the end of the TX queue array.
398 */ 398 */
399#define tx_queue_end(__dev) \ 399#define tx_queue_end(__dev) \
400 &(__dev)->tx[(__dev)->hw->queues] 400 &(__dev)->tx[(__dev)->ops->tx_queues]
401 401
402/** 402/**
403 * queue_loop - Loop through the queues within a specific range (HELPER MACRO). 403 * queue_loop - Loop through the queues within a specific range (HELPER MACRO).
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 5d690ee1befa..68d2216131b2 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2257,7 +2257,6 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2257 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 2257 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
2258 IEEE80211_HW_SIGNAL_DBM; 2258 IEEE80211_HW_SIGNAL_DBM;
2259 rt2x00dev->hw->extra_tx_headroom = 0; 2259 rt2x00dev->hw->extra_tx_headroom = 0;
2260 rt2x00dev->hw->queues = 4;
2261 2260
2262 SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); 2261 SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev);
2263 SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, 2262 SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
@@ -2489,6 +2488,7 @@ static const struct rt2x00_ops rt61pci_ops = {
2489 .max_ap_intf = 4, 2488 .max_ap_intf = 4,
2490 .eeprom_size = EEPROM_SIZE, 2489 .eeprom_size = EEPROM_SIZE,
2491 .rf_size = RF_SIZE, 2490 .rf_size = RF_SIZE,
2491 .tx_queues = NUM_TX_QUEUES,
2492 .rx = &rt61pci_queue_rx, 2492 .rx = &rt61pci_queue_rx,
2493 .tx = &rt61pci_queue_tx, 2493 .tx = &rt61pci_queue_tx,
2494 .bcn = &rt61pci_queue_bcn, 2494 .bcn = &rt61pci_queue_bcn,
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index 3511bba7ff65..c5a04b9329d2 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -54,6 +54,11 @@
54#define RF_SIZE 0x0014 54#define RF_SIZE 0x0014
55 55
56/* 56/*
57 * Number of TX queues.
58 */
59#define NUM_TX_QUEUES 4
60
61/*
57 * PCI registers. 62 * PCI registers.
58 */ 63 */
59 64
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index d98002cfe091..2191d8b94a89 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1831,7 +1831,6 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1831 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 1831 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1832 IEEE80211_HW_SIGNAL_DBM; 1832 IEEE80211_HW_SIGNAL_DBM;
1833 rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; 1833 rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
1834 rt2x00dev->hw->queues = 4;
1835 1834
1836 SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); 1835 SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev);
1837 SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, 1836 SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
@@ -2079,6 +2078,7 @@ static const struct rt2x00_ops rt73usb_ops = {
2079 .max_ap_intf = 4, 2078 .max_ap_intf = 4,
2080 .eeprom_size = EEPROM_SIZE, 2079 .eeprom_size = EEPROM_SIZE,
2081 .rf_size = RF_SIZE, 2080 .rf_size = RF_SIZE,
2081 .tx_queues = NUM_TX_QUEUES,
2082 .rx = &rt73usb_queue_rx, 2082 .rx = &rt73usb_queue_rx,
2083 .tx = &rt73usb_queue_tx, 2083 .tx = &rt73usb_queue_tx,
2084 .bcn = &rt73usb_queue_bcn, 2084 .bcn = &rt73usb_queue_bcn,
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index 06d687425fef..25cdcc9bf7c4 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -54,6 +54,11 @@
54#define RF_SIZE 0x0014 54#define RF_SIZE 0x0014
55 55
56/* 56/*
57 * Number of TX queues.
58 */
59#define NUM_TX_QUEUES 4
60
61/*
57 * USB registers. 62 * USB registers.
58 */ 63 */
59 64