aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-01-05 16:06:25 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-01-05 16:06:25 -0500
commitc96e96354a6c9456cdf1f150eca504e2ea35301e (patch)
tree751bec601fb8152116b8e31e0f1f83d687a37d6f /drivers/net/wireless/rt2x00
parentdbbe68bb12b34f3e450da7a73c20e6fa1f85d63a (diff)
parent33af88138b859f515b365a074e0a014d7cdbf846 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: net/bluetooth/Makefile
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c18
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c16
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h25
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c25
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00ht.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c35
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c2
8 files changed, 39 insertions, 92 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index baa1468a56a..aa97971a38a 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -688,14 +688,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
688 u32 status; 688 u32 status;
689 u8 qid; 689 u8 qid;
690 690
691 while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) { 691 while (kfifo_get(&rt2x00dev->txstatus_fifo, &status)) {
692 /* Now remove the tx status from the FIFO */
693 if (kfifo_out(&rt2x00dev->txstatus_fifo, &status,
694 sizeof(status)) != sizeof(status)) {
695 WARN_ON(1);
696 break;
697 }
698
699 qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE); 692 qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE);
700 if (qid >= QID_RX) { 693 if (qid >= QID_RX) {
701 /* 694 /*
@@ -803,14 +796,7 @@ static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev)
803 if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) 796 if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID))
804 break; 797 break;
805 798
806 if (kfifo_is_full(&rt2x00dev->txstatus_fifo)) { 799 if (!kfifo_put(&rt2x00dev->txstatus_fifo, &status)) {
807 WARNING(rt2x00dev, "TX status FIFO overrun,"
808 " drop tx status report.\n");
809 break;
810 }
811
812 if (kfifo_in(&rt2x00dev->txstatus_fifo, &status,
813 sizeof(status)) != sizeof(status)) {
814 WARNING(rt2x00dev, "TX status FIFO overrun," 800 WARNING(rt2x00dev, "TX status FIFO overrun,"
815 "drop tx status report.\n"); 801 "drop tx status report.\n");
816 break; 802 break;
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 3e0205ddf7b..b97a4a54ff4 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -369,7 +369,10 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry,
369static void rt2800usb_write_tx_data(struct queue_entry *entry, 369static void rt2800usb_write_tx_data(struct queue_entry *entry,
370 struct txentry_desc *txdesc) 370 struct txentry_desc *txdesc)
371{ 371{
372 u8 padding_len; 372 unsigned int len;
373 int err;
374
375 rt2800_write_tx_data(entry, txdesc);
373 376
374 /* 377 /*
375 * pad(1~3 bytes) is added after each 802.11 payload. 378 * pad(1~3 bytes) is added after each 802.11 payload.
@@ -378,9 +381,14 @@ static void rt2800usb_write_tx_data(struct queue_entry *entry,
378 * | TXINFO | TXWI | 802.11 header | L2 pad | payload | pad | USB end pad | 381 * | TXINFO | TXWI | 802.11 header | L2 pad | payload | pad | USB end pad |
379 * |<------------- tx_pkt_len ------------->| 382 * |<------------- tx_pkt_len ------------->|
380 */ 383 */
381 rt2800_write_tx_data(entry, txdesc); 384 len = roundup(entry->skb->len, 4) + 4;
382 padding_len = roundup(entry->skb->len + 4, 4) - entry->skb->len; 385 err = skb_padto(entry->skb, len);
383 memset(skb_put(entry->skb, padding_len), 0, padding_len); 386 if (unlikely(err)) {
387 WARNING(entry->queue->rt2x00dev, "TX SKB padding error, out of memory\n");
388 return;
389 }
390
391 entry->skb->len = len;
384} 392}
385 393
386/* 394/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index c254d5a62c7..84aaf393da4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -347,6 +347,10 @@ struct link {
347 struct delayed_work watchdog_work; 347 struct delayed_work watchdog_work;
348}; 348};
349 349
350enum rt2x00_delayed_flags {
351 DELAYED_UPDATE_BEACON,
352};
353
350/* 354/*
351 * Interface structure 355 * Interface structure
352 * Per interface configuration details, this structure 356 * Per interface configuration details, this structure
@@ -354,22 +358,6 @@ struct link {
354 */ 358 */
355struct rt2x00_intf { 359struct rt2x00_intf {
356 /* 360 /*
357 * All fields within the rt2x00_intf structure
358 * must be protected with a spinlock.
359 */
360 spinlock_t lock;
361
362 /*
363 * MAC of the device.
364 */
365 u8 mac[ETH_ALEN];
366
367 /*
368 * BBSID of the AP to associate with.
369 */
370 u8 bssid[ETH_ALEN];
371
372 /*
373 * beacon->skb must be protected with the mutex. 361 * beacon->skb must be protected with the mutex.
374 */ 362 */
375 struct mutex beacon_skb_mutex; 363 struct mutex beacon_skb_mutex;
@@ -384,8 +372,7 @@ struct rt2x00_intf {
384 /* 372 /*
385 * Actions that needed rescheduling. 373 * Actions that needed rescheduling.
386 */ 374 */
387 unsigned int delayed_flags; 375 unsigned long delayed_flags;
388#define DELAYED_UPDATE_BEACON 0x00000001
389 376
390 /* 377 /*
391 * Software sequence counter, this is only required 378 * Software sequence counter, this is only required
@@ -908,7 +895,7 @@ struct rt2x00_dev {
908 /* 895 /*
909 * FIFO for storing tx status reports between isr and tasklet. 896 * FIFO for storing tx status reports between isr and tasklet.
910 */ 897 */
911 struct kfifo txstatus_fifo; 898 DECLARE_KFIFO_PTR(txstatus_fifo, u32);
912 899
913 /* 900 /*
914 * Tasklet for processing tx status reports (rt2800pci). 901 * Tasklet for processing tx status reports (rt2800pci).
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 70ca9379833..e7f67d5eda5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -62,13 +62,13 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,
62 * This will prevent the device being confused when it wants 62 * This will prevent the device being confused when it wants
63 * to ACK frames or consideres itself associated. 63 * to ACK frames or consideres itself associated.
64 */ 64 */
65 memset(&conf.mac, 0, sizeof(conf.mac)); 65 memset(conf.mac, 0, sizeof(conf.mac));
66 if (mac) 66 if (mac)
67 memcpy(&conf.mac, mac, ETH_ALEN); 67 memcpy(conf.mac, mac, ETH_ALEN);
68 68
69 memset(&conf.bssid, 0, sizeof(conf.bssid)); 69 memset(conf.bssid, 0, sizeof(conf.bssid));
70 if (bssid) 70 if (bssid)
71 memcpy(&conf.bssid, bssid, ETH_ALEN); 71 memcpy(conf.bssid, bssid, ETH_ALEN);
72 72
73 flags |= CONFIG_UPDATE_TYPE; 73 flags |= CONFIG_UPDATE_TYPE;
74 if (mac || (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count)) 74 if (mac || (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count))
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index fa74acdd271..9597a03242c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -110,19 +110,6 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
110{ 110{
111 struct rt2x00_dev *rt2x00dev = data; 111 struct rt2x00_dev *rt2x00dev = data;
112 struct rt2x00_intf *intf = vif_to_intf(vif); 112 struct rt2x00_intf *intf = vif_to_intf(vif);
113 int delayed_flags;
114
115 /*
116 * Copy all data we need during this action under the protection
117 * of a spinlock. Otherwise race conditions might occur which results
118 * into an invalid configuration.
119 */
120 spin_lock(&intf->lock);
121
122 delayed_flags = intf->delayed_flags;
123 intf->delayed_flags = 0;
124
125 spin_unlock(&intf->lock);
126 113
127 /* 114 /*
128 * It is possible the radio was disabled while the work had been 115 * It is possible the radio was disabled while the work had been
@@ -133,7 +120,7 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
133 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) 120 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
134 return; 121 return;
135 122
136 if (delayed_flags & DELAYED_UPDATE_BEACON) 123 if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags))
137 rt2x00queue_update_beacon(rt2x00dev, vif, true); 124 rt2x00queue_update_beacon(rt2x00dev, vif, true);
138} 125}
139 126
@@ -813,8 +800,7 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
813 /* 800 /*
814 * Allocate tx status FIFO for driver use. 801 * Allocate tx status FIFO for driver use.
815 */ 802 */
816 if (test_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags) && 803 if (test_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags)) {
817 rt2x00dev->ops->lib->txstatus_tasklet) {
818 /* 804 /*
819 * Allocate txstatus fifo and tasklet, we use a size of 512 805 * Allocate txstatus fifo and tasklet, we use a size of 512
820 * for the kfifo which is big enough to store 512/4=128 tx 806 * for the kfifo which is big enough to store 512/4=128 tx
@@ -828,9 +814,10 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
828 return status; 814 return status;
829 815
830 /* tasklet for processing the tx status reports. */ 816 /* tasklet for processing the tx status reports. */
831 tasklet_init(&rt2x00dev->txstatus_tasklet, 817 if (rt2x00dev->ops->lib->txstatus_tasklet)
832 rt2x00dev->ops->lib->txstatus_tasklet, 818 tasklet_init(&rt2x00dev->txstatus_tasklet,
833 (unsigned long)rt2x00dev); 819 rt2x00dev->ops->lib->txstatus_tasklet,
820 (unsigned long)rt2x00dev);
834 821
835 } 822 }
836 823
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c
index c637bcaec5f..b7ad46ecaa1 100644
--- a/drivers/net/wireless/rt2x00/rt2x00ht.c
+++ b/drivers/net/wireless/rt2x00/rt2x00ht.c
@@ -40,8 +40,6 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
40 if (tx_info->control.sta) 40 if (tx_info->control.sta)
41 txdesc->mpdu_density = 41 txdesc->mpdu_density =
42 tx_info->control.sta->ht_cap.ampdu_density; 42 tx_info->control.sta->ht_cap.ampdu_density;
43 else
44 txdesc->mpdu_density = 0;
45 43
46 txdesc->ba_size = 7; /* FIXME: What value is needed? */ 44 txdesc->ba_size = 7; /* FIXME: What value is needed? */
47 45
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 4cac7ad60f4..658542d2efe 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -268,7 +268,6 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
268 else 268 else
269 rt2x00dev->intf_sta_count++; 269 rt2x00dev->intf_sta_count++;
270 270
271 spin_lock_init(&intf->lock);
272 spin_lock_init(&intf->seqlock); 271 spin_lock_init(&intf->seqlock);
273 mutex_init(&intf->beacon_skb_mutex); 272 mutex_init(&intf->beacon_skb_mutex);
274 intf->beacon = entry; 273 intf->beacon = entry;
@@ -282,9 +281,8 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
282 * STA interfaces at this time, since this can cause 281 * STA interfaces at this time, since this can cause
283 * invalid behavior in the device. 282 * invalid behavior in the device.
284 */ 283 */
285 memcpy(&intf->mac, vif->addr, ETH_ALEN);
286 rt2x00lib_config_intf(rt2x00dev, intf, vif->type, 284 rt2x00lib_config_intf(rt2x00dev, intf, vif->type,
287 intf->mac, NULL); 285 vif->addr, NULL);
288 286
289 /* 287 /*
290 * Some filters depend on the current working mode. We can force 288 * Some filters depend on the current working mode. We can force
@@ -445,9 +443,7 @@ static void rt2x00mac_set_tim_iter(void *data, u8 *mac,
445 vif->type != NL80211_IFTYPE_WDS) 443 vif->type != NL80211_IFTYPE_WDS)
446 return; 444 return;
447 445
448 spin_lock(&intf->lock); 446 set_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags);
449 intf->delayed_flags |= DELAYED_UPDATE_BEACON;
450 spin_unlock(&intf->lock);
451} 447}
452 448
453int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, 449int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
@@ -472,17 +468,17 @@ EXPORT_SYMBOL_GPL(rt2x00mac_set_tim);
472static void memcpy_tkip(struct rt2x00lib_crypto *crypto, u8 *key, u8 key_len) 468static void memcpy_tkip(struct rt2x00lib_crypto *crypto, u8 *key, u8 key_len)
473{ 469{
474 if (key_len > NL80211_TKIP_DATA_OFFSET_ENCR_KEY) 470 if (key_len > NL80211_TKIP_DATA_OFFSET_ENCR_KEY)
475 memcpy(&crypto->key, 471 memcpy(crypto->key,
476 &key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY], 472 &key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY],
477 sizeof(crypto->key)); 473 sizeof(crypto->key));
478 474
479 if (key_len > NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY) 475 if (key_len > NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
480 memcpy(&crypto->tx_mic, 476 memcpy(crypto->tx_mic,
481 &key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY], 477 &key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
482 sizeof(crypto->tx_mic)); 478 sizeof(crypto->tx_mic));
483 479
484 if (key_len > NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY) 480 if (key_len > NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY)
485 memcpy(&crypto->rx_mic, 481 memcpy(crypto->rx_mic,
486 &key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY], 482 &key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
487 sizeof(crypto->rx_mic)); 483 sizeof(crypto->rx_mic));
488} 484}
@@ -492,7 +488,6 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
492 struct ieee80211_key_conf *key) 488 struct ieee80211_key_conf *key)
493{ 489{
494 struct rt2x00_dev *rt2x00dev = hw->priv; 490 struct rt2x00_dev *rt2x00dev = hw->priv;
495 struct rt2x00_intf *intf = vif_to_intf(vif);
496 int (*set_key) (struct rt2x00_dev *rt2x00dev, 491 int (*set_key) (struct rt2x00_dev *rt2x00dev,
497 struct rt2x00lib_crypto *crypto, 492 struct rt2x00lib_crypto *crypto,
498 struct ieee80211_key_conf *key); 493 struct ieee80211_key_conf *key);
@@ -516,7 +511,7 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
516 if (rt2x00dev->intf_sta_count) 511 if (rt2x00dev->intf_sta_count)
517 crypto.bssidx = 0; 512 crypto.bssidx = 0;
518 else 513 else
519 crypto.bssidx = intf->mac[5] & (rt2x00dev->ops->max_ap_intf - 1); 514 crypto.bssidx = vif->addr[5] & (rt2x00dev->ops->max_ap_intf - 1);
520 515
521 crypto.cipher = rt2x00crypto_key_to_cipher(key); 516 crypto.cipher = rt2x00crypto_key_to_cipher(key);
522 if (crypto.cipher == CIPHER_NONE) 517 if (crypto.cipher == CIPHER_NONE)
@@ -534,7 +529,7 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
534 if (crypto.cipher == CIPHER_TKIP) 529 if (crypto.cipher == CIPHER_TKIP)
535 memcpy_tkip(&crypto, &key->key[0], key->keylen); 530 memcpy_tkip(&crypto, &key->key[0], key->keylen);
536 else 531 else
537 memcpy(&crypto.key, &key->key[0], key->keylen); 532 memcpy(crypto.key, &key->key[0], key->keylen);
538 /* 533 /*
539 * Each BSS has a maximum of 4 shared keys. 534 * Each BSS has a maximum of 4 shared keys.
540 * Shared key index values: 535 * Shared key index values:
@@ -614,22 +609,8 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
614 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) 609 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
615 return; 610 return;
616 611
617 spin_lock(&intf->lock);
618
619 /*
620 * conf->bssid can be NULL if coming from the internal
621 * beacon update routine.
622 */
623 if (changes & BSS_CHANGED_BSSID)
624 memcpy(&intf->bssid, bss_conf->bssid, ETH_ALEN);
625
626 spin_unlock(&intf->lock);
627
628 /* 612 /*
629 * Call rt2x00_config_intf() outside of the spinlock context since 613 * Update the BSSID.
630 * the call will sleep for USB drivers. By using the ieee80211_if_conf
631 * values as arguments we make keep access to rt2x00_intf thread safe
632 * even without the lock.
633 */ 614 */
634 if (changes & BSS_CHANGED_BSSID) 615 if (changes & BSS_CHANGED_BSSID)
635 rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL, 616 rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL,
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 28e6ff1a669..73631c6fbb3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -286,7 +286,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
286 rt2x00dev->irq = pci_dev->irq; 286 rt2x00dev->irq = pci_dev->irq;
287 rt2x00dev->name = pci_name(pci_dev); 287 rt2x00dev->name = pci_name(pci_dev);
288 288
289 if (pci_dev->is_pcie) 289 if (pci_is_pcie(pci_dev))
290 rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE); 290 rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE);
291 else 291 else
292 rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI); 292 rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI);