aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/DocBook/mac80211.tmpl1
-rw-r--r--drivers/net/wireless/adm8211.c13
-rw-r--r--drivers/net/wireless/ath/ar9170/ar9170.h8
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c13
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h1
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c44
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c25
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c7
-rw-r--r--drivers/net/wireless/ath/regd.c5
-rw-r--r--drivers/net/wireless/b43/b43.h1
-rw-r--r--drivers/net/wireless/b43/dma.c17
-rw-r--r--drivers/net/wireless/b43/dma.h5
-rw-r--r--drivers/net/wireless/b43/main.c38
-rw-r--r--drivers/net/wireless/b43/phy_n.c302
-rw-r--r--drivers/net/wireless/b43/phy_n.h4
-rw-r--r--drivers/net/wireless/b43/pio.c17
-rw-r--r--drivers/net/wireless/b43/pio.h5
-rw-r--r--drivers/net/wireless/b43legacy/dma.c20
-rw-r--r--drivers/net/wireless/b43legacy/dma.h10
-rw-r--r--drivers/net/wireless/b43legacy/main.c26
-rw-r--r--drivers/net/wireless/b43legacy/pio.c13
-rw-r--r--drivers/net/wireless/b43legacy/pio.h11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c21
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c25
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c37
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c49
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c1
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c5
-rw-r--r--drivers/net/wireless/libertas/dev.h1
-rw-r--r--drivers/net/wireless/libertas/if_spi.c1
-rw-r--r--drivers/net/wireless/libertas/main.c31
-rw-r--r--drivers/net/wireless/libertas_tf/main.c3
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c44
-rw-r--r--drivers/net/wireless/mwl8k.c35
-rw-r--r--drivers/net/wireless/p54/main.c11
-rw-r--r--drivers/net/wireless/p54/p54.h8
-rw-r--r--drivers/net/wireless/p54/txrx.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c16
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_main.c3
-rw-r--r--drivers/ssb/driver_mipscore.c5
-rw-r--r--drivers/ssb/main.c3
-rw-r--r--include/net/cfg80211.h83
-rw-r--r--include/net/ieee80211_radiotap.h4
-rw-r--r--include/net/mac80211.h49
-rw-r--r--net/mac80211/agg-tx.c8
-rw-r--r--net/mac80211/cfg.c25
-rw-r--r--net/mac80211/debugfs.c33
-rw-r--r--net/mac80211/driver-ops.h42
-rw-r--r--net/mac80211/driver-trace.h73
-rw-r--r--net/mac80211/ibss.c24
-rw-r--r--net/mac80211/ieee80211_i.h19
-rw-r--r--net/mac80211/mesh_plink.c17
-rw-r--r--net/mac80211/mlme.c60
-rw-r--r--net/mac80211/pm.c10
-rw-r--r--net/mac80211/rate.c2
-rw-r--r--net/mac80211/rate.h7
-rw-r--r--net/mac80211/rx.c12
-rw-r--r--net/mac80211/scan.c27
-rw-r--r--net/mac80211/sta_info.c731
-rw-r--r--net/mac80211/sta_info.h36
-rw-r--r--net/mac80211/status.c17
-rw-r--r--net/mac80211/tx.c11
-rw-r--r--net/mac80211/util.c24
-rw-r--r--net/wireless/radiotap.c305
79 files changed, 1458 insertions, 1088 deletions
diff --git a/Documentation/DocBook/mac80211.tmpl b/Documentation/DocBook/mac80211.tmpl
index 971d1c0c83e..affb15a344a 100644
--- a/Documentation/DocBook/mac80211.tmpl
+++ b/Documentation/DocBook/mac80211.tmpl
@@ -234,7 +234,6 @@ usage should require reading the full document.
234 <title>Multiple queues and QoS support</title> 234 <title>Multiple queues and QoS support</title>
235 <para>TBD</para> 235 <para>TBD</para>
236!Finclude/net/mac80211.h ieee80211_tx_queue_params 236!Finclude/net/mac80211.h ieee80211_tx_queue_params
237!Finclude/net/mac80211.h ieee80211_tx_queue_stats
238 </chapter> 237 </chapter>
239 238
240 <chapter id="AP"> 239 <chapter id="AP">
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index e6ca3eb4c0d..547912e6843 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -302,18 +302,6 @@ static int adm8211_get_stats(struct ieee80211_hw *dev,
302 return 0; 302 return 0;
303} 303}
304 304
305static int adm8211_get_tx_stats(struct ieee80211_hw *dev,
306 struct ieee80211_tx_queue_stats *stats)
307{
308 struct adm8211_priv *priv = dev->priv;
309
310 stats[0].len = priv->cur_tx - priv->dirty_tx;
311 stats[0].limit = priv->tx_ring_size - 2;
312 stats[0].count = priv->dirty_tx;
313
314 return 0;
315}
316
317static void adm8211_interrupt_tci(struct ieee80211_hw *dev) 305static void adm8211_interrupt_tci(struct ieee80211_hw *dev)
318{ 306{
319 struct adm8211_priv *priv = dev->priv; 307 struct adm8211_priv *priv = dev->priv;
@@ -1773,7 +1761,6 @@ static const struct ieee80211_ops adm8211_ops = {
1773 .prepare_multicast = adm8211_prepare_multicast, 1761 .prepare_multicast = adm8211_prepare_multicast,
1774 .configure_filter = adm8211_configure_filter, 1762 .configure_filter = adm8211_configure_filter,
1775 .get_stats = adm8211_get_stats, 1763 .get_stats = adm8211_get_stats,
1776 .get_tx_stats = adm8211_get_tx_stats,
1777 .get_tsf = adm8211_get_tsft 1764 .get_tsf = adm8211_get_tsft
1778}; 1765};
1779 1766
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h
index b99a8c2053d..8c8ce67971e 100644
--- a/drivers/net/wireless/ath/ar9170/ar9170.h
+++ b/drivers/net/wireless/ath/ar9170/ar9170.h
@@ -144,6 +144,12 @@ struct ar9170_sta_tid {
144 bool active; 144 bool active;
145}; 145};
146 146
147struct ar9170_tx_queue_stats {
148 unsigned int len;
149 unsigned int limit;
150 unsigned int count;
151};
152
147#define AR9170_QUEUE_TIMEOUT 64 153#define AR9170_QUEUE_TIMEOUT 64
148#define AR9170_TX_TIMEOUT 8 154#define AR9170_TX_TIMEOUT 8
149#define AR9170_BA_TIMEOUT 4 155#define AR9170_BA_TIMEOUT 4
@@ -211,7 +217,7 @@ struct ar9170 {
211 217
212 /* qos queue settings */ 218 /* qos queue settings */
213 spinlock_t tx_stats_lock; 219 spinlock_t tx_stats_lock;
214 struct ieee80211_tx_queue_stats tx_stats[5]; 220 struct ar9170_tx_queue_stats tx_stats[5];
215 struct ieee80211_tx_queue_params edcf[5]; 221 struct ieee80211_tx_queue_params edcf[5];
216 222
217 spinlock_t cmdlock; 223 spinlock_t cmdlock;
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index 4d27f7f67c7..91797cb6e0e 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -2396,18 +2396,6 @@ static int ar9170_get_stats(struct ieee80211_hw *hw,
2396 return 0; 2396 return 0;
2397} 2397}
2398 2398
2399static int ar9170_get_tx_stats(struct ieee80211_hw *hw,
2400 struct ieee80211_tx_queue_stats *tx_stats)
2401{
2402 struct ar9170 *ar = hw->priv;
2403
2404 spin_lock_bh(&ar->tx_stats_lock);
2405 memcpy(tx_stats, ar->tx_stats, sizeof(tx_stats[0]) * hw->queues);
2406 spin_unlock_bh(&ar->tx_stats_lock);
2407
2408 return 0;
2409}
2410
2411static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, 2399static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
2412 const struct ieee80211_tx_queue_params *param) 2400 const struct ieee80211_tx_queue_params *param)
2413{ 2401{
@@ -2509,7 +2497,6 @@ static const struct ieee80211_ops ar9170_ops = {
2509 .set_key = ar9170_set_key, 2497 .set_key = ar9170_set_key,
2510 .sta_notify = ar9170_sta_notify, 2498 .sta_notify = ar9170_sta_notify,
2511 .get_stats = ar9170_get_stats, 2499 .get_stats = ar9170_get_stats,
2512 .get_tx_stats = ar9170_get_tx_stats,
2513 .ampdu_action = ar9170_ampdu_action, 2500 .ampdu_action = ar9170_ampdu_action,
2514}; 2501};
2515 2502
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index ad4d446f026..ac67f02e26d 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -541,7 +541,6 @@ struct ath5k_txq_info {
541/* 541/*
542 * Transmit packet types. 542 * Transmit packet types.
543 * used on tx control descriptor 543 * used on tx control descriptor
544 * TODO: Use them inside base.c corectly
545 */ 544 */
546enum ath5k_pkt_type { 545enum ath5k_pkt_type {
547 AR5K_PKT_TYPE_NORMAL = 0, 546 AR5K_PKT_TYPE_NORMAL = 0,
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index edb6c90e376..8dce0077b02 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -241,8 +241,6 @@ static int ath5k_set_key(struct ieee80211_hw *hw,
241 struct ieee80211_key_conf *key); 241 struct ieee80211_key_conf *key);
242static int ath5k_get_stats(struct ieee80211_hw *hw, 242static int ath5k_get_stats(struct ieee80211_hw *hw,
243 struct ieee80211_low_level_stats *stats); 243 struct ieee80211_low_level_stats *stats);
244static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
245 struct ieee80211_tx_queue_stats *stats);
246static u64 ath5k_get_tsf(struct ieee80211_hw *hw); 244static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
247static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf); 245static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf);
248static void ath5k_reset_tsf(struct ieee80211_hw *hw); 246static void ath5k_reset_tsf(struct ieee80211_hw *hw);
@@ -269,7 +267,6 @@ static const struct ieee80211_ops ath5k_hw_ops = {
269 .set_key = ath5k_set_key, 267 .set_key = ath5k_set_key,
270 .get_stats = ath5k_get_stats, 268 .get_stats = ath5k_get_stats,
271 .conf_tx = NULL, 269 .conf_tx = NULL,
272 .get_tx_stats = ath5k_get_tx_stats,
273 .get_tsf = ath5k_get_tsf, 270 .get_tsf = ath5k_get_tsf,
274 .set_tsf = ath5k_set_tsf, 271 .set_tsf = ath5k_set_tsf,
275 .reset_tsf = ath5k_reset_tsf, 272 .reset_tsf = ath5k_reset_tsf,
@@ -1249,6 +1246,29 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
1249 return 0; 1246 return 0;
1250} 1247}
1251 1248
1249static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb)
1250{
1251 struct ieee80211_hdr *hdr;
1252 enum ath5k_pkt_type htype;
1253 __le16 fc;
1254
1255 hdr = (struct ieee80211_hdr *)skb->data;
1256 fc = hdr->frame_control;
1257
1258 if (ieee80211_is_beacon(fc))
1259 htype = AR5K_PKT_TYPE_BEACON;
1260 else if (ieee80211_is_probe_resp(fc))
1261 htype = AR5K_PKT_TYPE_PROBE_RESP;
1262 else if (ieee80211_is_atim(fc))
1263 htype = AR5K_PKT_TYPE_ATIM;
1264 else if (ieee80211_is_pspoll(fc))
1265 htype = AR5K_PKT_TYPE_PSPOLL;
1266 else
1267 htype = AR5K_PKT_TYPE_NORMAL;
1268
1269 return htype;
1270}
1271
1252static int 1272static int
1253ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, 1273ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1254 struct ath5k_txq *txq) 1274 struct ath5k_txq *txq)
@@ -1303,7 +1323,8 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1303 sc->vif, pktlen, info)); 1323 sc->vif, pktlen, info));
1304 } 1324 }
1305 ret = ah->ah_setup_tx_desc(ah, ds, pktlen, 1325 ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
1306 ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, 1326 ieee80211_get_hdrlen_from_skb(skb),
1327 get_hw_packet_type(skb),
1307 (sc->power_level * 2), 1328 (sc->power_level * 2),
1308 hw_rate, 1329 hw_rate,
1309 info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags, 1330 info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags,
@@ -1332,7 +1353,6 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1332 1353
1333 spin_lock_bh(&txq->lock); 1354 spin_lock_bh(&txq->lock);
1334 list_add_tail(&bf->list, &txq->q); 1355 list_add_tail(&bf->list, &txq->q);
1335 sc->tx_stats[txq->qnum].len++;
1336 if (txq->link == NULL) /* is this first packet? */ 1356 if (txq->link == NULL) /* is this first packet? */
1337 ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr); 1357 ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr);
1338 else /* no, so only link it */ 1358 else /* no, so only link it */
@@ -1581,7 +1601,6 @@ ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1581 ath5k_txbuf_free(sc, bf); 1601 ath5k_txbuf_free(sc, bf);
1582 1602
1583 spin_lock_bh(&sc->txbuflock); 1603 spin_lock_bh(&sc->txbuflock);
1584 sc->tx_stats[txq->qnum].len--;
1585 list_move_tail(&bf->list, &sc->txbuf); 1604 list_move_tail(&bf->list, &sc->txbuf);
1586 sc->txbuf_len++; 1605 sc->txbuf_len++;
1587 spin_unlock_bh(&sc->txbuflock); 1606 spin_unlock_bh(&sc->txbuflock);
@@ -2011,10 +2030,8 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
2011 } 2030 }
2012 2031
2013 ieee80211_tx_status(sc->hw, skb); 2032 ieee80211_tx_status(sc->hw, skb);
2014 sc->tx_stats[txq->qnum].count++;
2015 2033
2016 spin_lock(&sc->txbuflock); 2034 spin_lock(&sc->txbuflock);
2017 sc->tx_stats[txq->qnum].len--;
2018 list_move_tail(&bf->list, &sc->txbuf); 2035 list_move_tail(&bf->list, &sc->txbuf);
2019 sc->txbuf_len++; 2036 sc->txbuf_len++;
2020 spin_unlock(&sc->txbuflock); 2037 spin_unlock(&sc->txbuflock);
@@ -3116,17 +3133,6 @@ ath5k_get_stats(struct ieee80211_hw *hw,
3116 return 0; 3133 return 0;
3117} 3134}
3118 3135
3119static int
3120ath5k_get_tx_stats(struct ieee80211_hw *hw,
3121 struct ieee80211_tx_queue_stats *stats)
3122{
3123 struct ath5k_softc *sc = hw->priv;
3124
3125 memcpy(stats, &sc->tx_stats, sizeof(sc->tx_stats));
3126
3127 return 0;
3128}
3129
3130static u64 3136static u64
3131ath5k_get_tsf(struct ieee80211_hw *hw) 3137ath5k_get_tsf(struct ieee80211_hw *hw)
3132{ 3138{
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 952b3a21bbc..7e1a88a5abd 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -117,7 +117,6 @@ struct ath5k_softc {
117 struct pci_dev *pdev; /* for dma mapping */ 117 struct pci_dev *pdev; /* for dma mapping */
118 void __iomem *iobase; /* address of the device */ 118 void __iomem *iobase; /* address of the device */
119 struct mutex lock; /* dev-level lock */ 119 struct mutex lock; /* dev-level lock */
120 struct ieee80211_tx_queue_stats tx_stats[AR5K_NUM_TX_QUEUES];
121 struct ieee80211_low_level_stats ll_stats; 120 struct ieee80211_low_level_stats ll_stats;
122 struct ieee80211_hw *hw; /* IEEE 802.11 common */ 121 struct ieee80211_hw *hw; /* IEEE 802.11 common */
123 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; 122 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 0ea340fd071..83c7ea4c007 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -267,6 +267,7 @@ void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
267 u16 tid, u16 *ssn); 267 u16 tid, u16 *ssn);
268void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); 268void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
269void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); 269void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
270void ath9k_enable_ps(struct ath_softc *sc);
270 271
271/********/ 272/********/
272/* VIFs */ 273/* VIFs */
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 422454fe4ff..d088ebfe63a 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -577,6 +577,13 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
577 u64 tsf; 577 u64 tsf;
578 int num_beacons, offset, dtim_dec_count, cfp_dec_count; 578 int num_beacons, offset, dtim_dec_count, cfp_dec_count;
579 579
580 /* No need to configure beacon if we are not associated */
581 if (!common->curaid) {
582 ath_print(common, ATH_DBG_BEACON,
583 "STA is not yet associated..skipping beacon config\n");
584 return;
585 }
586
580 memset(&bs, 0, sizeof(bs)); 587 memset(&bs, 0, sizeof(bs));
581 intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; 588 intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
582 589
@@ -739,7 +746,6 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
739 enum nl80211_iftype iftype; 746 enum nl80211_iftype iftype;
740 747
741 /* Setup the beacon configuration parameters */ 748 /* Setup the beacon configuration parameters */
742
743 if (vif) { 749 if (vif) {
744 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; 750 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
745 751
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index f15fee76a4e..f00f5c744f4 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1217,6 +1217,17 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
1217 /* As defined by IEEE 802.11-2007 17.3.8.6 */ 1217 /* As defined by IEEE 802.11-2007 17.3.8.6 */
1218 slottime = ah->slottime + 3 * ah->coverage_class; 1218 slottime = ah->slottime + 3 * ah->coverage_class;
1219 acktimeout = slottime + sifstime; 1219 acktimeout = slottime + sifstime;
1220
1221 /*
1222 * Workaround for early ACK timeouts, add an offset to match the
1223 * initval's 64us ack timeout value.
1224 * This was initially only meant to work around an issue with delayed
1225 * BA frames in some implementations, but it has been found to fix ACK
1226 * timeout issues in other cases as well.
1227 */
1228 if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ)
1229 acktimeout += 64 - sifstime - ah->slottime;
1230
1220 ath9k_hw_setslottime(ah, slottime); 1231 ath9k_hw_setslottime(ah, slottime);
1221 ath9k_hw_set_ack_timeout(ah, acktimeout); 1232 ath9k_hw_set_ack_timeout(ah, acktimeout);
1222 ath9k_hw_set_cts_timeout(ah, acktimeout); 1233 ath9k_hw_set_cts_timeout(ah, acktimeout);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 4b5e5484868..623c2f88498 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -622,7 +622,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
622 IEEE80211_HW_SIGNAL_DBM | 622 IEEE80211_HW_SIGNAL_DBM |
623 IEEE80211_HW_SUPPORTS_PS | 623 IEEE80211_HW_SUPPORTS_PS |
624 IEEE80211_HW_PS_NULLFUNC_STACK | 624 IEEE80211_HW_PS_NULLFUNC_STACK |
625 IEEE80211_HW_SPECTRUM_MGMT; 625 IEEE80211_HW_SPECTRUM_MGMT |
626 IEEE80211_HW_REPORTS_TX_ACK_STATUS;
626 627
627 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) 628 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
628 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; 629 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 6796d5cdc29..9c8f925c209 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -809,6 +809,7 @@ static void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf
809 809
810 clear_bit(key->hw_key_idx + 64, common->keymap); 810 clear_bit(key->hw_key_idx + 64, common->keymap);
811 if (common->splitmic) { 811 if (common->splitmic) {
812 ath9k_hw_keyreset(ah, key->hw_key_idx + 32);
812 clear_bit(key->hw_key_idx + 32, common->keymap); 813 clear_bit(key->hw_key_idx + 32, common->keymap);
813 clear_bit(key->hw_key_idx + 64 + 32, common->keymap); 814 clear_bit(key->hw_key_idx + 64 + 32, common->keymap);
814 } 815 }
@@ -1492,6 +1493,19 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
1492 mutex_unlock(&sc->mutex); 1493 mutex_unlock(&sc->mutex);
1493} 1494}
1494 1495
1496void ath9k_enable_ps(struct ath_softc *sc)
1497{
1498 sc->ps_enabled = true;
1499 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
1500 if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
1501 sc->imask |= ATH9K_INT_TIM_TIMER;
1502 ath9k_hw_set_interrupts(sc->sc_ah,
1503 sc->imask);
1504 }
1505 }
1506 ath9k_hw_setrxabort(sc->sc_ah, 1);
1507}
1508
1495static int ath9k_config(struct ieee80211_hw *hw, u32 changed) 1509static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1496{ 1510{
1497 struct ath_wiphy *aphy = hw->priv; 1511 struct ath_wiphy *aphy = hw->priv;
@@ -1546,22 +1560,13 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1546 if (changed & IEEE80211_CONF_CHANGE_PS) { 1560 if (changed & IEEE80211_CONF_CHANGE_PS) {
1547 if (conf->flags & IEEE80211_CONF_PS) { 1561 if (conf->flags & IEEE80211_CONF_PS) {
1548 sc->ps_flags |= PS_ENABLED; 1562 sc->ps_flags |= PS_ENABLED;
1549 if (!(ah->caps.hw_caps &
1550 ATH9K_HW_CAP_AUTOSLEEP)) {
1551 if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
1552 sc->imask |= ATH9K_INT_TIM_TIMER;
1553 ath9k_hw_set_interrupts(sc->sc_ah,
1554 sc->imask);
1555 }
1556 }
1557 /* 1563 /*
1558 * At this point we know hardware has received an ACK 1564 * At this point we know hardware has received an ACK
1559 * of a previously sent null data frame. 1565 * of a previously sent null data frame.
1560 */ 1566 */
1561 if ((sc->ps_flags & PS_NULLFUNC_COMPLETED)) { 1567 if ((sc->ps_flags & PS_NULLFUNC_COMPLETED)) {
1562 sc->ps_flags &= ~PS_NULLFUNC_COMPLETED; 1568 sc->ps_flags &= ~PS_NULLFUNC_COMPLETED;
1563 sc->ps_enabled = true; 1569 ath9k_enable_ps(sc);
1564 ath9k_hw_setrxabort(sc->sc_ah, 1);
1565 } 1570 }
1566 } else { 1571 } else {
1567 sc->ps_enabled = false; 1572 sc->ps_enabled = false;
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 3c790a4f38f..f5cbbcb9a4a 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -2048,10 +2048,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2048 */ 2048 */
2049 if (bf->bf_isnullfunc && 2049 if (bf->bf_isnullfunc &&
2050 (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) { 2050 (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) {
2051 if ((sc->ps_flags & PS_ENABLED)) { 2051 if ((sc->ps_flags & PS_ENABLED))
2052 sc->ps_enabled = true; 2052 ath9k_enable_ps(sc);
2053 ath9k_hw_setrxabort(sc->sc_ah, 1); 2053 else
2054 } else
2055 sc->ps_flags |= PS_NULLFUNC_COMPLETED; 2054 sc->ps_flags |= PS_NULLFUNC_COMPLETED;
2056 } 2055 }
2057 2056
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index 039ac490465..04abd1f556b 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -110,8 +110,9 @@ static const struct ieee80211_regdomain ath_world_regdom_67_68_6A = {
110 110
111static inline bool is_wwr_sku(u16 regd) 111static inline bool is_wwr_sku(u16 regd)
112{ 112{
113 return ((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) || 113 return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) &&
114 (regd == WORLD); 114 (((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) ||
115 (regd == WORLD));
115} 116}
116 117
117static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg) 118static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 54d6085a887..6a6ab0f630e 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -115,6 +115,7 @@
115#define B43_MMIO_TSF_2 0x636 /* core rev < 3 only */ 115#define B43_MMIO_TSF_2 0x636 /* core rev < 3 only */
116#define B43_MMIO_TSF_3 0x638 /* core rev < 3 only */ 116#define B43_MMIO_TSF_3 0x638 /* core rev < 3 only */
117#define B43_MMIO_RNG 0x65A 117#define B43_MMIO_RNG 0x65A
118#define B43_MMIO_IFSSLOT 0x684 /* Interframe slot time */
118#define B43_MMIO_IFSCTL 0x688 /* Interframe space control */ 119#define B43_MMIO_IFSCTL 0x688 /* Interframe space control */
119#define B43_MMIO_IFSCTL_USE_EDCF 0x0004 120#define B43_MMIO_IFSCTL_USE_EDCF 0x0004
120#define B43_MMIO_POWERUP_DELAY 0x6A8 121#define B43_MMIO_POWERUP_DELAY 0x6A8
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 615af22c49f..be7abf8916a 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -1369,7 +1369,6 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
1369 b43err(dev->wl, "DMA tx mapping failure\n"); 1369 b43err(dev->wl, "DMA tx mapping failure\n");
1370 goto out; 1370 goto out;
1371 } 1371 }
1372 ring->nr_tx_packets++;
1373 if ((free_slots(ring) < TX_SLOTS_PER_FRAME) || 1372 if ((free_slots(ring) < TX_SLOTS_PER_FRAME) ||
1374 should_inject_overflow(ring)) { 1373 should_inject_overflow(ring)) {
1375 /* This TX ring is full. */ 1374 /* This TX ring is full. */
@@ -1500,22 +1499,6 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
1500 } 1499 }
1501} 1500}
1502 1501
1503void b43_dma_get_tx_stats(struct b43_wldev *dev,
1504 struct ieee80211_tx_queue_stats *stats)
1505{
1506 const int nr_queues = dev->wl->hw->queues;
1507 struct b43_dmaring *ring;
1508 int i;
1509
1510 for (i = 0; i < nr_queues; i++) {
1511 ring = select_ring_by_priority(dev, i);
1512
1513 stats[i].len = ring->used_slots / TX_SLOTS_PER_FRAME;
1514 stats[i].limit = ring->nr_slots / TX_SLOTS_PER_FRAME;
1515 stats[i].count = ring->nr_tx_packets;
1516 }
1517}
1518
1519static void dma_rx(struct b43_dmaring *ring, int *slot) 1502static void dma_rx(struct b43_dmaring *ring, int *slot)
1520{ 1503{
1521 const struct b43_dma_ops *ops = ring->ops; 1504 const struct b43_dma_ops *ops = ring->ops;
diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h
index f7ab37c4cdb..dc91944d602 100644
--- a/drivers/net/wireless/b43/dma.h
+++ b/drivers/net/wireless/b43/dma.h
@@ -228,8 +228,6 @@ struct b43_dmaring {
228 int used_slots; 228 int used_slots;
229 /* Currently used slot in the ring. */ 229 /* Currently used slot in the ring. */
230 int current_slot; 230 int current_slot;
231 /* Total number of packets sent. Statistics only. */
232 unsigned int nr_tx_packets;
233 /* Frameoffset in octets. */ 231 /* Frameoffset in octets. */
234 u32 frameoffset; 232 u32 frameoffset;
235 /* Descriptor buffer size. */ 233 /* Descriptor buffer size. */
@@ -278,9 +276,6 @@ void b43_dma_free(struct b43_wldev *dev);
278void b43_dma_tx_suspend(struct b43_wldev *dev); 276void b43_dma_tx_suspend(struct b43_wldev *dev);
279void b43_dma_tx_resume(struct b43_wldev *dev); 277void b43_dma_tx_resume(struct b43_wldev *dev);
280 278
281void b43_dma_get_tx_stats(struct b43_wldev *dev,
282 struct ieee80211_tx_queue_stats *stats);
283
284int b43_dma_tx(struct b43_wldev *dev, 279int b43_dma_tx(struct b43_wldev *dev,
285 struct sk_buff *skb); 280 struct sk_buff *skb);
286void b43_dma_handle_txstatus(struct b43_wldev *dev, 281void b43_dma_handle_txstatus(struct b43_wldev *dev,
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 316a913860d..aa33d741e5e 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -637,10 +637,17 @@ static void b43_upload_card_macaddress(struct b43_wldev *dev)
637static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time) 637static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time)
638{ 638{
639 /* slot_time is in usec. */ 639 /* slot_time is in usec. */
640 if (dev->phy.type != B43_PHYTYPE_G) 640 /* This test used to exit for all but a G PHY. */
641 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
641 return; 642 return;
642 b43_write16(dev, 0x684, 510 + slot_time); 643 b43_write16(dev, B43_MMIO_IFSSLOT, 510 + slot_time);
643 b43_shm_write16(dev, B43_SHM_SHARED, 0x0010, slot_time); 644 /* Shared memory location 0x0010 is the slot time and should be
645 * set to slot_time; however, this register is initially 0 and changing
646 * the value adversely affects the transmit rate for BCM4311
647 * devices. Until this behavior is unterstood, delete this step
648 *
649 * b43_shm_write16(dev, B43_SHM_SHARED, 0x0010, slot_time);
650 */
644} 651}
645 652
646static void b43_short_slot_timing_enable(struct b43_wldev *dev) 653static void b43_short_slot_timing_enable(struct b43_wldev *dev)
@@ -3349,27 +3356,6 @@ out_unlock:
3349 return err; 3356 return err;
3350} 3357}
3351 3358
3352static int b43_op_get_tx_stats(struct ieee80211_hw *hw,
3353 struct ieee80211_tx_queue_stats *stats)
3354{
3355 struct b43_wl *wl = hw_to_b43_wl(hw);
3356 struct b43_wldev *dev;
3357 int err = -ENODEV;
3358
3359 mutex_lock(&wl->mutex);
3360 dev = wl->current_dev;
3361 if (dev && b43_status(dev) >= B43_STAT_STARTED) {
3362 if (b43_using_pio_transfers(dev))
3363 b43_pio_get_tx_stats(dev, stats);
3364 else
3365 b43_dma_get_tx_stats(dev, stats);
3366 err = 0;
3367 }
3368 mutex_unlock(&wl->mutex);
3369
3370 return err;
3371}
3372
3373static int b43_op_get_stats(struct ieee80211_hw *hw, 3359static int b43_op_get_stats(struct ieee80211_hw *hw,
3374 struct ieee80211_low_level_stats *stats) 3360 struct ieee80211_low_level_stats *stats)
3375{ 3361{
@@ -3980,6 +3966,7 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
3980 } 3966 }
3981 3967
3982 /* We are ready to run. */ 3968 /* We are ready to run. */
3969 ieee80211_wake_queues(dev->wl->hw);
3983 b43_set_status(dev, B43_STAT_STARTED); 3970 b43_set_status(dev, B43_STAT_STARTED);
3984 3971
3985 /* Start data flow (TX/RX). */ 3972 /* Start data flow (TX/RX). */
@@ -4389,8 +4376,6 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4389 4376
4390 ieee80211_wake_queues(dev->wl->hw); 4377 ieee80211_wake_queues(dev->wl->hw);
4391 4378
4392 ieee80211_wake_queues(dev->wl->hw);
4393
4394 b43_set_status(dev, B43_STAT_INITIALIZED); 4379 b43_set_status(dev, B43_STAT_INITIALIZED);
4395 4380
4396out: 4381out:
@@ -4596,7 +4581,6 @@ static const struct ieee80211_ops b43_hw_ops = {
4596 .set_key = b43_op_set_key, 4581 .set_key = b43_op_set_key,
4597 .update_tkip_key = b43_op_update_tkip_key, 4582 .update_tkip_key = b43_op_update_tkip_key,
4598 .get_stats = b43_op_get_stats, 4583 .get_stats = b43_op_get_stats,
4599 .get_tx_stats = b43_op_get_tx_stats,
4600 .get_tsf = b43_op_get_tsf, 4584 .get_tsf = b43_op_get_tsf,
4601 .set_tsf = b43_op_set_tsf, 4585 .set_tsf = b43_op_set_tsf,
4602 .start = b43_op_start, 4586 .start = b43_op_start,
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 6392da25efe..795bb1e3345 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -68,6 +68,10 @@ static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
68 u8 *events, u8 *delays, u8 length); 68 u8 *events, u8 *delays, u8 length);
69static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, 69static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
70 enum b43_nphy_rf_sequence seq); 70 enum b43_nphy_rf_sequence seq);
71static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
72 u16 value, u8 core, bool off);
73static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
74 u16 value, u8 core);
71 75
72void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) 76void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
73{//TODO 77{//TODO
@@ -498,8 +502,8 @@ static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core)
498 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0007); 502 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0007);
499 } 503 }
500 504
501 /* TODO: Call N PHY RF Ctrl Intc Override with 2, 0, 3 as arguments */ 505 b43_nphy_rf_control_intc_override(dev, 2, 0, 3);
502 /* TODO: Call N PHY RF Intc Override with 8, 0, 3, 0 as arguments */ 506 b43_nphy_rf_control_override(dev, 8, 0, 3, false);
503 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX); 507 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
504 508
505 if (core == 0) { 509 if (core == 0) {
@@ -509,9 +513,8 @@ static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core)
509 rxval = 4; 513 rxval = 4;
510 txval = 2; 514 txval = 2;
511 } 515 }
512 516 b43_nphy_rf_control_intc_override(dev, 1, rxval, (core + 1));
513 /* TODO: Call N PHY RF Ctrl Intc Override with 1, rxval, (core + 1) */ 517 b43_nphy_rf_control_intc_override(dev, 1, txval, (2 - core));
514 /* TODO: Call N PHY RF Ctrl Intc Override with 1, txval, (2 - core) */
515} 518}
516 519
517/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */ 520/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */
@@ -714,6 +717,67 @@ static void b43_nphy_stop_playback(struct b43_wldev *dev)
714 b43_nphy_stay_in_carrier_search(dev, 0); 717 b43_nphy_stay_in_carrier_search(dev, 0);
715} 718}
716 719
720/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SpurWar */
721static void b43_nphy_spur_workaround(struct b43_wldev *dev)
722{
723 struct b43_phy_n *nphy = dev->phy.n;
724
725 unsigned int channel;
726 int tone[2] = { 57, 58 };
727 u32 noise[2] = { 0x3FF, 0x3FF };
728
729 B43_WARN_ON(dev->phy.rev < 3);
730
731 if (nphy->hang_avoid)
732 b43_nphy_stay_in_carrier_search(dev, 1);
733
734 /* FIXME: channel = radio_chanspec */
735
736 if (nphy->gband_spurwar_en) {
737 /* TODO: N PHY Adjust Analog Pfbw (7) */
738 if (channel == 11 && dev->phy.is_40mhz)
739 ; /* TODO: N PHY Adjust Min Noise Var(2, tone, noise)*/
740 else
741 ; /* TODO: N PHY Adjust Min Noise Var(0, NULL, NULL)*/
742 /* TODO: N PHY Adjust CRS Min Power (0x1E) */
743 }
744
745 if (nphy->aband_spurwar_en) {
746 if (channel == 54) {
747 tone[0] = 0x20;
748 noise[0] = 0x25F;
749 } else if (channel == 38 || channel == 102 || channel == 118) {
750 if (0 /* FIXME */) {
751 tone[0] = 0x20;
752 noise[0] = 0x21F;
753 } else {
754 tone[0] = 0;
755 noise[0] = 0;
756 }
757 } else if (channel == 134) {
758 tone[0] = 0x20;
759 noise[0] = 0x21F;
760 } else if (channel == 151) {
761 tone[0] = 0x10;
762 noise[0] = 0x23F;
763 } else if (channel == 153 || channel == 161) {
764 tone[0] = 0x30;
765 noise[0] = 0x23F;
766 } else {
767 tone[0] = 0;
768 noise[0] = 0;
769 }
770
771 if (!tone[0] && !noise[0])
772 ; /* TODO: N PHY Adjust Min Noise Var(1, tone, noise)*/
773 else
774 ; /* TODO: N PHY Adjust Min Noise Var(0, NULL, NULL)*/
775 }
776
777 if (nphy->hang_avoid)
778 b43_nphy_stay_in_carrier_search(dev, 0);
779}
780
717/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */ 781/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
718static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev) 782static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev)
719{ 783{
@@ -953,6 +1017,33 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
953 b43_nphy_stay_in_carrier_search(dev, 0); 1017 b43_nphy_stay_in_carrier_search(dev, 0);
954} 1018}
955 1019
1020/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/LoadSampleTable */
1021static int b43_nphy_load_samples(struct b43_wldev *dev,
1022 struct b43_c32 *samples, u16 len) {
1023 struct b43_phy_n *nphy = dev->phy.n;
1024 u16 i;
1025 u32 *data;
1026
1027 data = kzalloc(len * sizeof(u32), GFP_KERNEL);
1028 if (!data) {
1029 b43err(dev->wl, "allocation for samples loading failed\n");
1030 return -ENOMEM;
1031 }
1032 if (nphy->hang_avoid)
1033 b43_nphy_stay_in_carrier_search(dev, 1);
1034
1035 for (i = 0; i < len; i++) {
1036 data[i] = (samples[i].i & 0x3FF << 10);
1037 data[i] |= samples[i].q & 0x3FF;
1038 }
1039 b43_ntab_write_bulk(dev, B43_NTAB32(17, 0), len, data);
1040
1041 kfree(data);
1042 if (nphy->hang_avoid)
1043 b43_nphy_stay_in_carrier_search(dev, 0);
1044 return 0;
1045}
1046
956/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GenLoadSamples */ 1047/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GenLoadSamples */
957static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max, 1048static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
958 bool test) 1049 bool test)
@@ -978,6 +1069,10 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
978 } 1069 }
979 1070
980 samples = kzalloc(len * sizeof(struct b43_c32), GFP_KERNEL); 1071 samples = kzalloc(len * sizeof(struct b43_c32), GFP_KERNEL);
1072 if (!samples) {
1073 b43err(dev->wl, "allocation for samples generation failed\n");
1074 return 0;
1075 }
981 rot = (((freq * 36) / bw) << 16) / 100; 1076 rot = (((freq * 36) / bw) << 16) / 100;
982 angle = 0; 1077 angle = 0;
983 1078
@@ -988,9 +1083,9 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
988 samples[i].i = CORDIC_CONVERT(samples[i].i * max); 1083 samples[i].i = CORDIC_CONVERT(samples[i].i * max);
989 } 1084 }
990 1085
991 /* TODO: Call N PHY Load Sample Table with buffer, len as arguments */ 1086 i = b43_nphy_load_samples(dev, samples, len);
992 kfree(samples); 1087 kfree(samples);
993 return len; 1088 return (i < 0) ? 0 : len;
994} 1089}
995 1090
996/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */ 1091/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */
@@ -1264,6 +1359,104 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
1264 } 1359 }
1265} 1360}
1266 1361
1362/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlIntcOverride */
1363static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
1364 u16 value, u8 core)
1365{
1366 u8 i, j;
1367 u16 reg, tmp, val;
1368
1369 B43_WARN_ON(dev->phy.rev < 3);
1370 B43_WARN_ON(field > 4);
1371
1372 for (i = 0; i < 2; i++) {
1373 if ((core == 1 && i == 1) || (core == 2 && !i))
1374 continue;
1375
1376 reg = (i == 0) ?
1377 B43_NPHY_RFCTL_INTC1 : B43_NPHY_RFCTL_INTC2;
1378 b43_phy_mask(dev, reg, 0xFBFF);
1379
1380 switch (field) {
1381 case 0:
1382 b43_phy_write(dev, reg, 0);
1383 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
1384 break;
1385 case 1:
1386 if (!i) {
1387 b43_phy_maskset(dev, B43_NPHY_RFCTL_INTC1,
1388 0xFC3F, (value << 6));
1389 b43_phy_maskset(dev, B43_NPHY_TXF_40CO_B1S1,
1390 0xFFFE, 1);
1391 b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
1392 B43_NPHY_RFCTL_CMD_START);
1393 for (j = 0; j < 100; j++) {
1394 if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_START) {
1395 j = 0;
1396 break;
1397 }
1398 udelay(10);
1399 }
1400 if (j)
1401 b43err(dev->wl,
1402 "intc override timeout\n");
1403 b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1,
1404 0xFFFE);
1405 } else {
1406 b43_phy_maskset(dev, B43_NPHY_RFCTL_INTC2,
1407 0xFC3F, (value << 6));
1408 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER,
1409 0xFFFE, 1);
1410 b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
1411 B43_NPHY_RFCTL_CMD_RXTX);
1412 for (j = 0; j < 100; j++) {
1413 if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_RXTX) {
1414 j = 0;
1415 break;
1416 }
1417 udelay(10);
1418 }
1419 if (j)
1420 b43err(dev->wl,
1421 "intc override timeout\n");
1422 b43_phy_mask(dev, B43_NPHY_RFCTL_OVER,
1423 0xFFFE);
1424 }
1425 break;
1426 case 2:
1427 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
1428 tmp = 0x0020;
1429 val = value << 5;
1430 } else {
1431 tmp = 0x0010;
1432 val = value << 4;
1433 }
1434 b43_phy_maskset(dev, reg, ~tmp, val);
1435 break;
1436 case 3:
1437 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
1438 tmp = 0x0001;
1439 val = value;
1440 } else {
1441 tmp = 0x0004;
1442 val = value << 2;
1443 }
1444 b43_phy_maskset(dev, reg, ~tmp, val);
1445 break;
1446 case 4:
1447 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
1448 tmp = 0x0002;
1449 val = value << 1;
1450 } else {
1451 tmp = 0x0008;
1452 val = value << 3;
1453 }
1454 b43_phy_maskset(dev, reg, ~tmp, val);
1455 break;
1456 }
1457 }
1458}
1459
1267static void b43_nphy_bphy_init(struct b43_wldev *dev) 1460static void b43_nphy_bphy_init(struct b43_wldev *dev)
1268{ 1461{
1269 unsigned int i; 1462 unsigned int i;
@@ -2161,9 +2354,9 @@ static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev)
2161 regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); 2354 regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
2162 regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); 2355 regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
2163 2356
2164 /* TODO: Call N PHY RF Ctrl Intc Override with 2, 1, 3 */ 2357 b43_nphy_rf_control_intc_override(dev, 2, 1, 3);
2165 /* TODO: Call N PHY RF Ctrl Intc Override with 1, 2, 1 */ 2358 b43_nphy_rf_control_intc_override(dev, 1, 2, 1);
2166 /* TODO: Call N PHY RF Ctrl Intc Override with 1, 8, 2 */ 2359 b43_nphy_rf_control_intc_override(dev, 1, 8, 2);
2167 2360
2168 regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0); 2361 regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0);
2169 regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1); 2362 regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1);
@@ -2194,6 +2387,55 @@ static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev)
2194 } 2387 }
2195} 2388}
2196 2389
2390/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SaveCal */
2391static void b43_nphy_save_cal(struct b43_wldev *dev)
2392{
2393 struct b43_phy_n *nphy = dev->phy.n;
2394
2395 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
2396 u16 *txcal_radio_regs = NULL;
2397 u8 *iqcal_chanspec;
2398 u16 *table = NULL;
2399
2400 if (nphy->hang_avoid)
2401 b43_nphy_stay_in_carrier_search(dev, 1);
2402
2403 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2404 rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_2G;
2405 txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_2G;
2406 iqcal_chanspec = &nphy->iqcal_chanspec_2G;
2407 table = nphy->cal_cache.txcal_coeffs_2G;
2408 } else {
2409 rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_5G;
2410 txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_5G;
2411 iqcal_chanspec = &nphy->iqcal_chanspec_5G;
2412 table = nphy->cal_cache.txcal_coeffs_5G;
2413 }
2414
2415 b43_nphy_rx_iq_coeffs(dev, false, rxcal_coeffs);
2416 /* TODO use some definitions */
2417 if (dev->phy.rev >= 3) {
2418 txcal_radio_regs[0] = b43_radio_read(dev, 0x2021);
2419 txcal_radio_regs[1] = b43_radio_read(dev, 0x2022);
2420 txcal_radio_regs[2] = b43_radio_read(dev, 0x3021);
2421 txcal_radio_regs[3] = b43_radio_read(dev, 0x3022);
2422 txcal_radio_regs[4] = b43_radio_read(dev, 0x2023);
2423 txcal_radio_regs[5] = b43_radio_read(dev, 0x2024);
2424 txcal_radio_regs[6] = b43_radio_read(dev, 0x3023);
2425 txcal_radio_regs[7] = b43_radio_read(dev, 0x3024);
2426 } else {
2427 txcal_radio_regs[0] = b43_radio_read(dev, 0x8B);
2428 txcal_radio_regs[1] = b43_radio_read(dev, 0xBA);
2429 txcal_radio_regs[2] = b43_radio_read(dev, 0x8D);
2430 txcal_radio_regs[3] = b43_radio_read(dev, 0xBC);
2431 }
2432 *iqcal_chanspec = nphy->radio_chanspec;
2433 b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 8, table);
2434
2435 if (nphy->hang_avoid)
2436 b43_nphy_stay_in_carrier_search(dev, 0);
2437}
2438
2197/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */ 2439/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */
2198static void b43_nphy_restore_cal(struct b43_wldev *dev) 2440static void b43_nphy_restore_cal(struct b43_wldev *dev)
2199{ 2441{
@@ -2486,6 +2728,39 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
2486 return error; 2728 return error;
2487} 2729}
2488 2730
2731/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ReapplyTxCalCoeffs */
2732static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev)
2733{
2734 struct b43_phy_n *nphy = dev->phy.n;
2735 u8 i;
2736 u16 buffer[7];
2737 bool equal = true;
2738
2739 if (!nphy->txiqlocal_coeffsvalid || 1 /* FIXME */)
2740 return;
2741
2742 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
2743 for (i = 0; i < 4; i++) {
2744 if (buffer[i] != nphy->txiqlocal_bestc[i]) {
2745 equal = false;
2746 break;
2747 }
2748 }
2749
2750 if (!equal) {
2751 b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 4,
2752 nphy->txiqlocal_bestc);
2753 for (i = 0; i < 4; i++)
2754 buffer[i] = 0;
2755 b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4,
2756 buffer);
2757 b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2,
2758 &nphy->txiqlocal_bestc[5]);
2759 b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2,
2760 &nphy->txiqlocal_bestc[5]);
2761 }
2762}
2763
2489/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalRxIqRev2 */ 2764/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalRxIqRev2 */
2490static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, 2765static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
2491 struct nphy_txgains target, u8 type, bool debug) 2766 struct nphy_txgains target, u8 type, bool debug)
@@ -2516,7 +2791,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
2516 b43_nphy_stay_in_carrier_search(dev, 1); 2791 b43_nphy_stay_in_carrier_search(dev, 1);
2517 2792
2518 if (dev->phy.rev < 2) 2793 if (dev->phy.rev < 2)
2519 ;/* TODO: Call N PHY Reapply TX Cal Coeffs */ 2794 b43_nphy_reapply_tx_cal_coeffs(dev);
2520 b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save); 2795 b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save);
2521 for (i = 0; i < 2; i++) { 2796 for (i = 0; i < 2; i++) {
2522 b43_nphy_iq_cal_gain_params(dev, i, target, &cal_params[i]); 2797 b43_nphy_iq_cal_gain_params(dev, i, target, &cal_params[i]);
@@ -2858,7 +3133,7 @@ int b43_phy_initn(struct b43_wldev *dev)
2858 3133
2859 if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false)) { 3134 if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false)) {
2860 if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0) 3135 if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0)
2861 ;/* Call N PHY Save Cal */ 3136 b43_nphy_save_cal(dev);
2862 else if (nphy->mphase_cal_phase_id == 0) 3137 else if (nphy->mphase_cal_phase_id == 0)
2863 ;/* N PHY Periodic Calibration with argument 3 */ 3138 ;/* N PHY Periodic Calibration with argument 3 */
2864 } else { 3139 } else {
@@ -2872,7 +3147,8 @@ int b43_phy_initn(struct b43_wldev *dev)
2872 if (phy->rev >= 3 && phy->rev <= 6) 3147 if (phy->rev >= 3 && phy->rev <= 6)
2873 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0014); 3148 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0014);
2874 b43_nphy_tx_lp_fbw(dev); 3149 b43_nphy_tx_lp_fbw(dev);
2875 /* TODO N PHY Spur Workaround */ 3150 if (phy->rev >= 3)
3151 b43_nphy_spur_workaround(dev);
2876 3152
2877 b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n"); 3153 b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n");
2878 return 0; 3154 return 0;
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h
index ae82f0fc209..403aad3f894 100644
--- a/drivers/net/wireless/b43/phy_n.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -975,6 +975,7 @@ struct b43_phy_n {
975 u16 papd_epsilon_offset[2]; 975 u16 papd_epsilon_offset[2];
976 s32 preamble_override; 976 s32 preamble_override;
977 u32 bb_mult_save; 977 u32 bb_mult_save;
978 u16 radio_chanspec;
978 979
979 bool gain_boost; 980 bool gain_boost;
980 bool elna_gain_config; 981 bool elna_gain_config;
@@ -1001,6 +1002,9 @@ struct b43_phy_n {
1001 u16 classifier_state; 1002 u16 classifier_state;
1002 u16 clip_state[2]; 1003 u16 clip_state[2];
1003 1004
1005 bool aband_spurwar_en;
1006 bool gband_spurwar_en;
1007
1004 bool ipa2g_on; 1008 bool ipa2g_on;
1005 u8 iqcal_chanspec_2G; 1009 u8 iqcal_chanspec_2G;
1006 u8 rssical_chanspec_2G; 1010 u8 rssical_chanspec_2G;
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index c01b8e02412..a6062c3e89a 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -559,7 +559,6 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
559 b43err(dev->wl, "PIO transmission failure\n"); 559 b43err(dev->wl, "PIO transmission failure\n");
560 goto out; 560 goto out;
561 } 561 }
562 q->nr_tx_packets++;
563 562
564 B43_WARN_ON(q->buffer_used > q->buffer_size); 563 B43_WARN_ON(q->buffer_used > q->buffer_size);
565 if (((q->buffer_size - q->buffer_used) < roundup(2 + 2 + 6, 4)) || 564 if (((q->buffer_size - q->buffer_used) < roundup(2 + 2 + 6, 4)) ||
@@ -605,22 +604,6 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev,
605 } 604 }
606} 605}
607 606
608void b43_pio_get_tx_stats(struct b43_wldev *dev,
609 struct ieee80211_tx_queue_stats *stats)
610{
611 const int nr_queues = dev->wl->hw->queues;
612 struct b43_pio_txqueue *q;
613 int i;
614
615 for (i = 0; i < nr_queues; i++) {
616 q = select_queue_by_priority(dev, i);
617
618 stats[i].len = B43_PIO_MAX_NR_TXPACKETS - q->free_packet_slots;
619 stats[i].limit = B43_PIO_MAX_NR_TXPACKETS;
620 stats[i].count = q->nr_tx_packets;
621 }
622}
623
624/* Returns whether we should fetch another frame. */ 607/* Returns whether we should fetch another frame. */
625static bool pio_rx_frame(struct b43_pio_rxqueue *q) 608static bool pio_rx_frame(struct b43_pio_rxqueue *q)
626{ 609{
diff --git a/drivers/net/wireless/b43/pio.h b/drivers/net/wireless/b43/pio.h
index 7b3c42f93a1..1e516147424 100644
--- a/drivers/net/wireless/b43/pio.h
+++ b/drivers/net/wireless/b43/pio.h
@@ -90,9 +90,6 @@ struct b43_pio_txqueue {
90 struct b43_pio_txpacket packets[B43_PIO_MAX_NR_TXPACKETS]; 90 struct b43_pio_txpacket packets[B43_PIO_MAX_NR_TXPACKETS];
91 struct list_head packets_list; 91 struct list_head packets_list;
92 92
93 /* Total number of transmitted packets. */
94 unsigned int nr_tx_packets;
95
96 /* Shortcut to the 802.11 core revision. This is to 93 /* Shortcut to the 802.11 core revision. This is to
97 * avoid horrible pointer dereferencing in the fastpaths. */ 94 * avoid horrible pointer dereferencing in the fastpaths. */
98 u8 rev; 95 u8 rev;
@@ -160,8 +157,6 @@ void b43_pio_free(struct b43_wldev *dev);
160int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb); 157int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb);
161void b43_pio_handle_txstatus(struct b43_wldev *dev, 158void b43_pio_handle_txstatus(struct b43_wldev *dev,
162 const struct b43_txstatus *status); 159 const struct b43_txstatus *status);
163void b43_pio_get_tx_stats(struct b43_wldev *dev,
164 struct ieee80211_tx_queue_stats *stats);
165void b43_pio_rx(struct b43_pio_rxqueue *q); 160void b43_pio_rx(struct b43_pio_rxqueue *q);
166 161
167void b43_pio_tx_suspend(struct b43_wldev *dev); 162void b43_pio_tx_suspend(struct b43_wldev *dev);
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
index 0a86bdf5315..8b9387c6ff3 100644
--- a/drivers/net/wireless/b43legacy/dma.c
+++ b/drivers/net/wireless/b43legacy/dma.c
@@ -1411,7 +1411,6 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
1411 b43legacyerr(dev->wl, "DMA tx mapping failure\n"); 1411 b43legacyerr(dev->wl, "DMA tx mapping failure\n");
1412 goto out_unlock; 1412 goto out_unlock;
1413 } 1413 }
1414 ring->nr_tx_packets++;
1415 if ((free_slots(ring) < SLOTS_PER_PACKET) || 1414 if ((free_slots(ring) < SLOTS_PER_PACKET) ||
1416 should_inject_overflow(ring)) { 1415 should_inject_overflow(ring)) {
1417 /* This TX ring is full. */ 1416 /* This TX ring is full. */
@@ -1527,25 +1526,6 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
1527 spin_unlock(&ring->lock); 1526 spin_unlock(&ring->lock);
1528} 1527}
1529 1528
1530void b43legacy_dma_get_tx_stats(struct b43legacy_wldev *dev,
1531 struct ieee80211_tx_queue_stats *stats)
1532{
1533 const int nr_queues = dev->wl->hw->queues;
1534 struct b43legacy_dmaring *ring;
1535 unsigned long flags;
1536 int i;
1537
1538 for (i = 0; i < nr_queues; i++) {
1539 ring = priority_to_txring(dev, i);
1540
1541 spin_lock_irqsave(&ring->lock, flags);
1542 stats[i].len = ring->used_slots / SLOTS_PER_PACKET;
1543 stats[i].limit = ring->nr_slots / SLOTS_PER_PACKET;
1544 stats[i].count = ring->nr_tx_packets;
1545 spin_unlock_irqrestore(&ring->lock, flags);
1546 }
1547}
1548
1549static void dma_rx(struct b43legacy_dmaring *ring, 1529static void dma_rx(struct b43legacy_dmaring *ring,
1550 int *slot) 1530 int *slot)
1551{ 1531{
diff --git a/drivers/net/wireless/b43legacy/dma.h b/drivers/net/wireless/b43legacy/dma.h
index 2f186003c31..f9681041c2d 100644
--- a/drivers/net/wireless/b43legacy/dma.h
+++ b/drivers/net/wireless/b43legacy/dma.h
@@ -243,8 +243,6 @@ struct b43legacy_dmaring {
243 int used_slots; 243 int used_slots;
244 /* Currently used slot in the ring. */ 244 /* Currently used slot in the ring. */
245 int current_slot; 245 int current_slot;
246 /* Total number of packets sent. Statistics only. */
247 unsigned int nr_tx_packets;
248 /* Frameoffset in octets. */ 246 /* Frameoffset in octets. */
249 u32 frameoffset; 247 u32 frameoffset;
250 /* Descriptor buffer size. */ 248 /* Descriptor buffer size. */
@@ -292,9 +290,6 @@ void b43legacy_dma_free(struct b43legacy_wldev *dev);
292void b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev); 290void b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev);
293void b43legacy_dma_tx_resume(struct b43legacy_wldev *dev); 291void b43legacy_dma_tx_resume(struct b43legacy_wldev *dev);
294 292
295void b43legacy_dma_get_tx_stats(struct b43legacy_wldev *dev,
296 struct ieee80211_tx_queue_stats *stats);
297
298int b43legacy_dma_tx(struct b43legacy_wldev *dev, 293int b43legacy_dma_tx(struct b43legacy_wldev *dev,
299 struct sk_buff *skb); 294 struct sk_buff *skb);
300void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev, 295void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
@@ -315,11 +310,6 @@ void b43legacy_dma_free(struct b43legacy_wldev *dev)
315{ 310{
316} 311}
317static inline 312static inline
318void b43legacy_dma_get_tx_stats(struct b43legacy_wldev *dev,
319 struct ieee80211_tx_queue_stats *stats)
320{
321}
322static inline
323int b43legacy_dma_tx(struct b43legacy_wldev *dev, 313int b43legacy_dma_tx(struct b43legacy_wldev *dev,
324 struct sk_buff *skb) 314 struct sk_buff *skb)
325{ 315{
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 874a64a6c61..1d070be5a67 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -2446,29 +2446,6 @@ static int b43legacy_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
2446 return 0; 2446 return 0;
2447} 2447}
2448 2448
2449static int b43legacy_op_get_tx_stats(struct ieee80211_hw *hw,
2450 struct ieee80211_tx_queue_stats *stats)
2451{
2452 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
2453 struct b43legacy_wldev *dev = wl->current_dev;
2454 unsigned long flags;
2455 int err = -ENODEV;
2456
2457 if (!dev)
2458 goto out;
2459 spin_lock_irqsave(&wl->irq_lock, flags);
2460 if (likely(b43legacy_status(dev) >= B43legacy_STAT_STARTED)) {
2461 if (b43legacy_using_pio(dev))
2462 b43legacy_pio_get_tx_stats(dev, stats);
2463 else
2464 b43legacy_dma_get_tx_stats(dev, stats);
2465 err = 0;
2466 }
2467 spin_unlock_irqrestore(&wl->irq_lock, flags);
2468out:
2469 return err;
2470}
2471
2472static int b43legacy_op_get_stats(struct ieee80211_hw *hw, 2449static int b43legacy_op_get_stats(struct ieee80211_hw *hw,
2473 struct ieee80211_low_level_stats *stats) 2450 struct ieee80211_low_level_stats *stats)
2474{ 2451{
@@ -2923,6 +2900,7 @@ static int b43legacy_wireless_core_start(struct b43legacy_wldev *dev)
2923 goto out; 2900 goto out;
2924 } 2901 }
2925 /* We are ready to run. */ 2902 /* We are ready to run. */
2903 ieee80211_wake_queues(dev->wl->hw);
2926 b43legacy_set_status(dev, B43legacy_STAT_STARTED); 2904 b43legacy_set_status(dev, B43legacy_STAT_STARTED);
2927 2905
2928 /* Start data flow (TX/RX) */ 2906 /* Start data flow (TX/RX) */
@@ -3343,6 +3321,7 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev)
3343 b43legacy_security_init(dev); 3321 b43legacy_security_init(dev);
3344 b43legacy_rng_init(wl); 3322 b43legacy_rng_init(wl);
3345 3323
3324 ieee80211_wake_queues(dev->wl->hw);
3346 b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED); 3325 b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED);
3347 3326
3348 b43legacy_leds_init(dev); 3327 b43legacy_leds_init(dev);
@@ -3511,7 +3490,6 @@ static const struct ieee80211_ops b43legacy_hw_ops = {
3511 .bss_info_changed = b43legacy_op_bss_info_changed, 3490 .bss_info_changed = b43legacy_op_bss_info_changed,
3512 .configure_filter = b43legacy_op_configure_filter, 3491 .configure_filter = b43legacy_op_configure_filter,
3513 .get_stats = b43legacy_op_get_stats, 3492 .get_stats = b43legacy_op_get_stats,
3514 .get_tx_stats = b43legacy_op_get_tx_stats,
3515 .start = b43legacy_op_start, 3493 .start = b43legacy_op_start,
3516 .stop = b43legacy_op_stop, 3494 .stop = b43legacy_op_stop,
3517 .set_tim = b43legacy_op_beacon_set_tim, 3495 .set_tim = b43legacy_op_beacon_set_tim,
diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c
index 51866c9a276..017c0e9c37e 100644
--- a/drivers/net/wireless/b43legacy/pio.c
+++ b/drivers/net/wireless/b43legacy/pio.c
@@ -477,7 +477,6 @@ int b43legacy_pio_tx(struct b43legacy_wldev *dev,
477 477
478 list_move_tail(&packet->list, &queue->txqueue); 478 list_move_tail(&packet->list, &queue->txqueue);
479 queue->nr_txfree--; 479 queue->nr_txfree--;
480 queue->nr_tx_packets++;
481 B43legacy_WARN_ON(queue->nr_txfree >= B43legacy_PIO_MAXTXPACKETS); 480 B43legacy_WARN_ON(queue->nr_txfree >= B43legacy_PIO_MAXTXPACKETS);
482 481
483 tasklet_schedule(&queue->txtask); 482 tasklet_schedule(&queue->txtask);
@@ -546,18 +545,6 @@ void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev,
546 tasklet_schedule(&queue->txtask); 545 tasklet_schedule(&queue->txtask);
547} 546}
548 547
549void b43legacy_pio_get_tx_stats(struct b43legacy_wldev *dev,
550 struct ieee80211_tx_queue_stats *stats)
551{
552 struct b43legacy_pio *pio = &dev->pio;
553 struct b43legacy_pioqueue *queue;
554
555 queue = pio->queue1;
556 stats[0].len = B43legacy_PIO_MAXTXPACKETS - queue->nr_txfree;
557 stats[0].limit = B43legacy_PIO_MAXTXPACKETS;
558 stats[0].count = queue->nr_tx_packets;
559}
560
561static void pio_rx_error(struct b43legacy_pioqueue *queue, 548static void pio_rx_error(struct b43legacy_pioqueue *queue,
562 int clear_buffers, 549 int clear_buffers,
563 const char *error) 550 const char *error)
diff --git a/drivers/net/wireless/b43legacy/pio.h b/drivers/net/wireless/b43legacy/pio.h
index 464fec05a06..8e6773ea6e7 100644
--- a/drivers/net/wireless/b43legacy/pio.h
+++ b/drivers/net/wireless/b43legacy/pio.h
@@ -74,10 +74,6 @@ struct b43legacy_pioqueue {
74 * posted to the device. We are waiting for the txstatus. 74 * posted to the device. We are waiting for the txstatus.
75 */ 75 */
76 struct list_head txrunning; 76 struct list_head txrunning;
77 /* Total number or packets sent.
78 * (This counter can obviously wrap).
79 */
80 unsigned int nr_tx_packets;
81 struct tasklet_struct txtask; 77 struct tasklet_struct txtask;
82 struct b43legacy_pio_txpacket 78 struct b43legacy_pio_txpacket
83 tx_packets_cache[B43legacy_PIO_MAXTXPACKETS]; 79 tx_packets_cache[B43legacy_PIO_MAXTXPACKETS];
@@ -106,8 +102,6 @@ int b43legacy_pio_tx(struct b43legacy_wldev *dev,
106 struct sk_buff *skb); 102 struct sk_buff *skb);
107void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev, 103void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev,
108 const struct b43legacy_txstatus *status); 104 const struct b43legacy_txstatus *status);
109void b43legacy_pio_get_tx_stats(struct b43legacy_wldev *dev,
110 struct ieee80211_tx_queue_stats *stats);
111void b43legacy_pio_rx(struct b43legacy_pioqueue *queue); 105void b43legacy_pio_rx(struct b43legacy_pioqueue *queue);
112 106
113/* Suspend TX queue in hardware. */ 107/* Suspend TX queue in hardware. */
@@ -140,11 +134,6 @@ void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev,
140{ 134{
141} 135}
142static inline 136static inline
143void b43legacy_pio_get_tx_stats(struct b43legacy_wldev *dev,
144 struct ieee80211_tx_queue_stats *stats)
145{
146}
147static inline
148void b43legacy_pio_rx(struct b43legacy_pioqueue *queue) 137void b43legacy_pio_rx(struct b43legacy_pioqueue *queue)
149{ 138{
150} 139}
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 9d1820676f3..694ceef8859 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -247,6 +247,7 @@ struct iwl_cfg iwl1000_bgn_cfg = {
247 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 247 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
248 .support_ct_kill_exit = true, 248 .support_ct_kill_exit = true,
249 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 249 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
250 .chain_noise_scale = 1000,
250}; 251};
251 252
252struct iwl_cfg iwl1000_bg_cfg = { 253struct iwl_cfg iwl1000_bg_cfg = {
@@ -274,6 +275,7 @@ struct iwl_cfg iwl1000_bg_cfg = {
274 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 275 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
275 .support_ct_kill_exit = true, 276 .support_ct_kill_exit = true,
276 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 277 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
278 .chain_noise_scale = 1000,
277}; 279};
278 280
279MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); 281MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 6d598890134..f3d662c8cbc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -179,14 +179,24 @@ static void iwl5000_gain_computation(struct iwl_priv *priv,
179 data->delta_gain_code[i] = 0; 179 data->delta_gain_code[i] = 0;
180 continue; 180 continue;
181 } 181 }
182 delta_g = (1000 * ((s32)average_noise[default_chain] - 182
183 delta_g = (priv->cfg->chain_noise_scale *
184 ((s32)average_noise[default_chain] -
183 (s32)average_noise[i])) / 1500; 185 (s32)average_noise[i])) / 1500;
186
184 /* bound gain by 2 bits value max, 3rd bit is sign */ 187 /* bound gain by 2 bits value max, 3rd bit is sign */
185 data->delta_gain_code[i] = 188 data->delta_gain_code[i] =
186 min(abs(delta_g), (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE); 189 min(abs(delta_g), (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
187 190
188 if (delta_g < 0) 191 if (delta_g < 0)
189 /* set negative sign */ 192 /*
193 * set negative sign ...
194 * note to Intel developers: This is uCode API format,
195 * not the format of any internal device registers.
196 * Do not change this format for e.g. 6050 or similar
197 * devices. Change format only if more resolution
198 * (i.e. more than 2 bits magnitude) is needed.
199 */
190 data->delta_gain_code[i] |= (1 << 2); 200 data->delta_gain_code[i] |= (1 << 2);
191 } 201 }
192 202
@@ -1587,6 +1597,7 @@ struct iwl_cfg iwl5300_agn_cfg = {
1587 .use_rts_for_ht = true, /* use rts/cts protection */ 1597 .use_rts_for_ht = true, /* use rts/cts protection */
1588 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1598 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1589 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 1599 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1600 .chain_noise_scale = 1000,
1590}; 1601};
1591 1602
1592struct iwl_cfg iwl5100_bgn_cfg = { 1603struct iwl_cfg iwl5100_bgn_cfg = {
@@ -1612,6 +1623,7 @@ struct iwl_cfg iwl5100_bgn_cfg = {
1612 .use_rts_for_ht = true, /* use rts/cts protection */ 1623 .use_rts_for_ht = true, /* use rts/cts protection */
1613 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1624 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1614 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 1625 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1626 .chain_noise_scale = 1000,
1615}; 1627};
1616 1628
1617struct iwl_cfg iwl5100_abg_cfg = { 1629struct iwl_cfg iwl5100_abg_cfg = {
@@ -1635,6 +1647,7 @@ struct iwl_cfg iwl5100_abg_cfg = {
1635 .led_compensation = 51, 1647 .led_compensation = 51,
1636 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1648 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1637 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 1649 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1650 .chain_noise_scale = 1000,
1638}; 1651};
1639 1652
1640struct iwl_cfg iwl5100_agn_cfg = { 1653struct iwl_cfg iwl5100_agn_cfg = {
@@ -1660,6 +1673,7 @@ struct iwl_cfg iwl5100_agn_cfg = {
1660 .use_rts_for_ht = true, /* use rts/cts protection */ 1673 .use_rts_for_ht = true, /* use rts/cts protection */
1661 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1674 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1662 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 1675 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1676 .chain_noise_scale = 1000,
1663}; 1677};
1664 1678
1665struct iwl_cfg iwl5350_agn_cfg = { 1679struct iwl_cfg iwl5350_agn_cfg = {
@@ -1685,6 +1699,7 @@ struct iwl_cfg iwl5350_agn_cfg = {
1685 .use_rts_for_ht = true, /* use rts/cts protection */ 1699 .use_rts_for_ht = true, /* use rts/cts protection */
1686 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1700 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1687 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 1701 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1702 .chain_noise_scale = 1000,
1688}; 1703};
1689 1704
1690struct iwl_cfg iwl5150_agn_cfg = { 1705struct iwl_cfg iwl5150_agn_cfg = {
@@ -1710,6 +1725,7 @@ struct iwl_cfg iwl5150_agn_cfg = {
1710 .use_rts_for_ht = true, /* use rts/cts protection */ 1725 .use_rts_for_ht = true, /* use rts/cts protection */
1711 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1726 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1712 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 1727 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1728 .chain_noise_scale = 1000,
1713}; 1729};
1714 1730
1715struct iwl_cfg iwl5150_abg_cfg = { 1731struct iwl_cfg iwl5150_abg_cfg = {
@@ -1733,6 +1749,7 @@ struct iwl_cfg iwl5150_abg_cfg = {
1733 .led_compensation = 51, 1749 .led_compensation = 51,
1734 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1750 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1735 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 1751 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1752 .chain_noise_scale = 1000,
1736}; 1753};
1737 1754
1738MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); 1755MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index a9f8551e0e4..782e23a2698 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -277,21 +277,6 @@ static const struct iwl_ops iwl6000_ops = {
277 .led = &iwlagn_led_ops, 277 .led = &iwlagn_led_ops,
278}; 278};
279 279
280static struct iwl_hcmd_utils_ops iwl6050_hcmd_utils = {
281 .get_hcmd_size = iwl5000_get_hcmd_size,
282 .build_addsta_hcmd = iwl5000_build_addsta_hcmd,
283 .rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag,
284 .calc_rssi = iwl5000_calc_rssi,
285};
286
287static const struct iwl_ops iwl6050_ops = {
288 .ucode = &iwl5000_ucode,
289 .lib = &iwl6000_lib,
290 .hcmd = &iwl5000_hcmd,
291 .utils = &iwl6050_hcmd_utils,
292 .led = &iwlagn_led_ops,
293};
294
295/* 280/*
296 * "i": Internal configuration, use internal Power Amplifier 281 * "i": Internal configuration, use internal Power Amplifier
297 */ 282 */
@@ -324,6 +309,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
324 .adv_thermal_throttle = true, 309 .adv_thermal_throttle = true,
325 .support_ct_kill_exit = true, 310 .support_ct_kill_exit = true,
326 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 311 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
312 .chain_noise_scale = 1000,
327}; 313};
328 314
329struct iwl_cfg iwl6000i_2abg_cfg = { 315struct iwl_cfg iwl6000i_2abg_cfg = {
@@ -354,6 +340,7 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
354 .adv_thermal_throttle = true, 340 .adv_thermal_throttle = true,
355 .support_ct_kill_exit = true, 341 .support_ct_kill_exit = true,
356 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 342 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
343 .chain_noise_scale = 1000,
357}; 344};
358 345
359struct iwl_cfg iwl6000i_2bg_cfg = { 346struct iwl_cfg iwl6000i_2bg_cfg = {
@@ -384,6 +371,7 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
384 .adv_thermal_throttle = true, 371 .adv_thermal_throttle = true,
385 .support_ct_kill_exit = true, 372 .support_ct_kill_exit = true,
386 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 373 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
374 .chain_noise_scale = 1000,
387}; 375};
388 376
389struct iwl_cfg iwl6050_2agn_cfg = { 377struct iwl_cfg iwl6050_2agn_cfg = {
@@ -392,7 +380,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
392 .ucode_api_max = IWL6050_UCODE_API_MAX, 380 .ucode_api_max = IWL6050_UCODE_API_MAX,
393 .ucode_api_min = IWL6050_UCODE_API_MIN, 381 .ucode_api_min = IWL6050_UCODE_API_MIN,
394 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 382 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
395 .ops = &iwl6050_ops, 383 .ops = &iwl6000_ops,
396 .eeprom_size = OTP_LOW_IMAGE_SIZE, 384 .eeprom_size = OTP_LOW_IMAGE_SIZE,
397 .eeprom_ver = EEPROM_6050_EEPROM_VERSION, 385 .eeprom_ver = EEPROM_6050_EEPROM_VERSION,
398 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 386 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
@@ -415,6 +403,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
415 .adv_thermal_throttle = true, 403 .adv_thermal_throttle = true,
416 .support_ct_kill_exit = true, 404 .support_ct_kill_exit = true,
417 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 405 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
406 .chain_noise_scale = 1500,
418}; 407};
419 408
420struct iwl_cfg iwl6050_2abg_cfg = { 409struct iwl_cfg iwl6050_2abg_cfg = {
@@ -423,7 +412,7 @@ struct iwl_cfg iwl6050_2abg_cfg = {
423 .ucode_api_max = IWL6050_UCODE_API_MAX, 412 .ucode_api_max = IWL6050_UCODE_API_MAX,
424 .ucode_api_min = IWL6050_UCODE_API_MIN, 413 .ucode_api_min = IWL6050_UCODE_API_MIN,
425 .sku = IWL_SKU_A|IWL_SKU_G, 414 .sku = IWL_SKU_A|IWL_SKU_G,
426 .ops = &iwl6050_ops, 415 .ops = &iwl6000_ops,
427 .eeprom_size = OTP_LOW_IMAGE_SIZE, 416 .eeprom_size = OTP_LOW_IMAGE_SIZE,
428 .eeprom_ver = EEPROM_6050_EEPROM_VERSION, 417 .eeprom_ver = EEPROM_6050_EEPROM_VERSION,
429 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 418 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
@@ -445,6 +434,7 @@ struct iwl_cfg iwl6050_2abg_cfg = {
445 .adv_thermal_throttle = true, 434 .adv_thermal_throttle = true,
446 .support_ct_kill_exit = true, 435 .support_ct_kill_exit = true,
447 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 436 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
437 .chain_noise_scale = 1500,
448}; 438};
449 439
450struct iwl_cfg iwl6000_3agn_cfg = { 440struct iwl_cfg iwl6000_3agn_cfg = {
@@ -476,6 +466,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
476 .adv_thermal_throttle = true, 466 .adv_thermal_throttle = true,
477 .support_ct_kill_exit = true, 467 .support_ct_kill_exit = true,
478 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 468 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
469 .chain_noise_scale = 1000,
479}; 470};
480 471
481MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); 472MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index d0268280d67..1854c720b5e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2631,7 +2631,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv)
2631 */ 2631 */
2632 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 2632 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2633 2633
2634 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; 2634 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX + 1;
2635 /* we create the 802.11 header and a zero-length SSID element */ 2635 /* we create the 802.11 header and a zero-length SSID element */
2636 hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; 2636 hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
2637 2637
@@ -3440,7 +3440,6 @@ static struct ieee80211_ops iwl_hw_ops = {
3440 .set_key = iwl_mac_set_key, 3440 .set_key = iwl_mac_set_key,
3441 .update_tkip_key = iwl_mac_update_tkip_key, 3441 .update_tkip_key = iwl_mac_update_tkip_key,
3442 .get_stats = iwl_mac_get_stats, 3442 .get_stats = iwl_mac_get_stats,
3443 .get_tx_stats = iwl_mac_get_tx_stats,
3444 .conf_tx = iwl_mac_conf_tx, 3443 .conf_tx = iwl_mac_conf_tx,
3445 .reset_tsf = iwl_mac_reset_tsf, 3444 .reset_tsf = iwl_mac_reset_tsf,
3446 .bss_info_changed = iwl_bss_info_changed, 3445 .bss_info_changed = iwl_bss_info_changed,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 02bf17ecaf5..d390eef2efe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2787,6 +2787,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2787 if ((le16_to_cpu(priv->staging_rxon.channel) != ch)) 2787 if ((le16_to_cpu(priv->staging_rxon.channel) != ch))
2788 priv->staging_rxon.flags = 0; 2788 priv->staging_rxon.flags = 0;
2789 2789
2790 iwl_set_rxon_ht(priv, ht_conf);
2790 iwl_set_rxon_channel(priv, conf->channel); 2791 iwl_set_rxon_channel(priv, conf->channel);
2791 2792
2792 iwl_set_flags_for_band(priv, conf->channel->band); 2793 iwl_set_flags_for_band(priv, conf->channel->band);
@@ -2850,42 +2851,6 @@ out:
2850} 2851}
2851EXPORT_SYMBOL(iwl_mac_config); 2852EXPORT_SYMBOL(iwl_mac_config);
2852 2853
2853int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
2854 struct ieee80211_tx_queue_stats *stats)
2855{
2856 struct iwl_priv *priv = hw->priv;
2857 int i, avail;
2858 struct iwl_tx_queue *txq;
2859 struct iwl_queue *q;
2860 unsigned long flags;
2861
2862 IWL_DEBUG_MAC80211(priv, "enter\n");
2863
2864 if (!iwl_is_ready_rf(priv)) {
2865 IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
2866 return -EIO;
2867 }
2868
2869 spin_lock_irqsave(&priv->lock, flags);
2870
2871 for (i = 0; i < AC_NUM; i++) {
2872 txq = &priv->txq[i];
2873 q = &txq->q;
2874 avail = iwl_queue_space(q);
2875
2876 stats[i].len = q->n_window - avail;
2877 stats[i].limit = q->n_window - q->high_mark;
2878 stats[i].count = q->n_window;
2879
2880 }
2881 spin_unlock_irqrestore(&priv->lock, flags);
2882
2883 IWL_DEBUG_MAC80211(priv, "leave\n");
2884
2885 return 0;
2886}
2887EXPORT_SYMBOL(iwl_mac_get_tx_stats);
2888
2889void iwl_mac_reset_tsf(struct ieee80211_hw *hw) 2854void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2890{ 2855{
2891 struct iwl_priv *priv = hw->priv; 2856 struct iwl_priv *priv = hw->priv;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index ec1fe1d7cc9..8f0c564e68b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -293,6 +293,7 @@ struct iwl_cfg {
293 bool support_ct_kill_exit; 293 bool support_ct_kill_exit;
294 const bool support_wimax_coexist; 294 const bool support_wimax_coexist;
295 u8 plcp_delta_threshold; 295 u8 plcp_delta_threshold;
296 s32 chain_noise_scale;
296}; 297};
297 298
298/*************************** 299/***************************
@@ -341,8 +342,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
341 struct ieee80211_vif *vif); 342 struct ieee80211_vif *vif);
342int iwl_mac_config(struct ieee80211_hw *hw, u32 changed); 343int iwl_mac_config(struct ieee80211_hw *hw, u32 changed);
343void iwl_config_ap(struct iwl_priv *priv); 344void iwl_config_ap(struct iwl_priv *priv);
344int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
345 struct ieee80211_tx_queue_stats *stats);
346void iwl_mac_reset_tsf(struct ieee80211_hw *hw); 345void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
347int iwl_alloc_txq_mem(struct iwl_priv *priv); 346int iwl_alloc_txq_mem(struct iwl_priv *priv);
348void iwl_free_txq_mem(struct iwl_priv *priv); 347void iwl_free_txq_mem(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 08faafae849..f786a407638 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -651,9 +651,20 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
651 if (left < 0) 651 if (left < 0)
652 return 0; 652 return 0;
653 *pos++ = WLAN_EID_SSID; 653 *pos++ = WLAN_EID_SSID;
654 *pos++ = 0; 654 if (!priv->is_internal_short_scan &&
655 655 priv->scan_request->n_ssids) {
656 len += 2; 656 struct cfg80211_ssid *ssid =
657 priv->scan_request->ssids;
658
659 /* Broadcast if ssid_len is 0 */
660 *pos++ = ssid->ssid_len;
661 memcpy(pos, ssid->ssid, ssid->ssid_len);
662 pos += ssid->ssid_len;
663 len += 2 + ssid->ssid_len;
664 } else {
665 *pos++ = 0;
666 len += 2;
667 }
657 668
658 if (WARN_ON(left < ie_len)) 669 if (WARN_ON(left < ie_len))
659 return len; 670 return len;
@@ -782,20 +793,26 @@ static void iwl_bg_request_scan(struct work_struct *data)
782 if (priv->is_internal_short_scan) { 793 if (priv->is_internal_short_scan) {
783 IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); 794 IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
784 } else if (priv->scan_request->n_ssids) { 795 } else if (priv->scan_request->n_ssids) {
785 int i, p = 0;
786 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); 796 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
787 for (i = 0; i < priv->scan_request->n_ssids; i++) { 797 /*
788 /* always does wildcard anyway */ 798 * The first SSID to scan is stuffed into the probe request
789 if (!priv->scan_request->ssids[i].ssid_len) 799 * template and the remaining ones are handled through the
790 continue; 800 * direct_scan array.
791 scan->direct_scan[p].id = WLAN_EID_SSID; 801 */
792 scan->direct_scan[p].len = 802 if (priv->scan_request->n_ssids > 1) {
793 priv->scan_request->ssids[i].ssid_len; 803 int i, p = 0;
794 memcpy(scan->direct_scan[p].ssid, 804 for (i = 1; i < priv->scan_request->n_ssids; i++) {
795 priv->scan_request->ssids[i].ssid, 805 if (!priv->scan_request->ssids[i].ssid_len)
796 priv->scan_request->ssids[i].ssid_len); 806 continue;
797 n_probes++; 807 scan->direct_scan[p].id = WLAN_EID_SSID;
798 p++; 808 scan->direct_scan[p].len =
809 priv->scan_request->ssids[i].ssid_len;
810 memcpy(scan->direct_scan[p].ssid,
811 priv->scan_request->ssids[i].ssid,
812 priv->scan_request->ssids[i].ssid_len);
813 n_probes++;
814 p++;
815 }
799 } 816 }
800 is_active = true; 817 is_active = true;
801 } else 818 } else
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 119da54116d..eac2b9a9571 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -3835,7 +3835,6 @@ static struct ieee80211_ops iwl3945_hw_ops = {
3835 .config = iwl_mac_config, 3835 .config = iwl_mac_config,
3836 .configure_filter = iwl_configure_filter, 3836 .configure_filter = iwl_configure_filter,
3837 .set_key = iwl3945_mac_set_key, 3837 .set_key = iwl3945_mac_set_key,
3838 .get_tx_stats = iwl_mac_get_tx_stats,
3839 .conf_tx = iwl_mac_conf_tx, 3838 .conf_tx = iwl_mac_conf_tx,
3840 .reset_tsf = iwl_mac_reset_tsf, 3839 .reset_tsf = iwl_mac_reset_tsf,
3841 .bss_info_changed = iwl_bss_info_changed, 3840 .bss_info_changed = iwl_bss_info_changed,
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index 0334a58820e..e7470442f76 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -240,11 +240,6 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
240 /* Now we got response from FW, cancel the command timer */ 240 /* Now we got response from FW, cancel the command timer */
241 del_timer(&priv->command_timer); 241 del_timer(&priv->command_timer);
242 priv->cmd_timed_out = 0; 242 priv->cmd_timed_out = 0;
243 if (priv->nr_retries) {
244 lbs_pr_info("Received result %x to command %x after %d retries\n",
245 result, curcmd, priv->nr_retries);
246 priv->nr_retries = 0;
247 }
248 243
249 /* Store the response code to cur_cmd_retcode. */ 244 /* Store the response code to cur_cmd_retcode. */
250 priv->cur_cmd_retcode = result; 245 priv->cur_cmd_retcode = result;
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index c348aff8f30..6977ee82021 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -109,7 +109,6 @@ struct lbs_private {
109 struct list_head cmdpendingq; /* pending command buffers */ 109 struct list_head cmdpendingq; /* pending command buffers */
110 wait_queue_head_t cmd_pending; 110 wait_queue_head_t cmd_pending;
111 struct timer_list command_timer; 111 struct timer_list command_timer;
112 int nr_retries;
113 int cmd_timed_out; 112 int cmd_timed_out;
114 113
115 /* Command responses sent from the hardware to the driver */ 114 /* Command responses sent from the hardware to the driver */
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index bf4bfbae622..3ea03f259ee 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -23,6 +23,7 @@
23#include <linux/kthread.h> 23#include <linux/kthread.h>
24#include <linux/list.h> 24#include <linux/list.h>
25#include <linux/netdevice.h> 25#include <linux/netdevice.h>
26#include <linux/semaphore.h>
26#include <linux/spi/libertas_spi.h> 27#include <linux/spi/libertas_spi.h>
27#include <linux/spi/spi.h> 28#include <linux/spi/spi.h>
28 29
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 60bde1233a3..cd8ed7fdafa 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -536,31 +536,14 @@ static int lbs_thread(void *data)
536 if (priv->cmd_timed_out && priv->cur_cmd) { 536 if (priv->cmd_timed_out && priv->cur_cmd) {
537 struct cmd_ctrl_node *cmdnode = priv->cur_cmd; 537 struct cmd_ctrl_node *cmdnode = priv->cur_cmd;
538 538
539 if (++priv->nr_retries > 3) { 539 lbs_pr_info("Timeout submitting command 0x%04x\n",
540 lbs_pr_info("Excessive timeouts submitting " 540 le16_to_cpu(cmdnode->cmdbuf->command));
541 "command 0x%04x\n", 541 lbs_complete_command(priv, cmdnode, -ETIMEDOUT);
542 le16_to_cpu(cmdnode->cmdbuf->command)); 542 if (priv->reset_card)
543 lbs_complete_command(priv, cmdnode, -ETIMEDOUT); 543 priv->reset_card(priv);
544 priv->nr_retries = 0;
545 if (priv->reset_card)
546 priv->reset_card(priv);
547 } else {
548 priv->cur_cmd = NULL;
549 priv->dnld_sent = DNLD_RES_RECEIVED;
550 lbs_pr_info("requeueing command 0x%04x due "
551 "to timeout (#%d)\n",
552 le16_to_cpu(cmdnode->cmdbuf->command),
553 priv->nr_retries);
554
555 /* Stick it back at the _top_ of the pending queue
556 for immediate resubmission */
557 list_add(&cmdnode->list, &priv->cmdpendingq);
558 }
559 } 544 }
560 priv->cmd_timed_out = 0; 545 priv->cmd_timed_out = 0;
561 546
562
563
564 if (!priv->fw_ready) 547 if (!priv->fw_ready)
565 continue; 548 continue;
566 549
@@ -732,7 +715,7 @@ done:
732 * This function handles the timeout of command sending. 715 * This function handles the timeout of command sending.
733 * It will re-send the same command again. 716 * It will re-send the same command again.
734 */ 717 */
735static void command_timer_fn(unsigned long data) 718static void lbs_cmd_timeout_handler(unsigned long data)
736{ 719{
737 struct lbs_private *priv = (struct lbs_private *)data; 720 struct lbs_private *priv = (struct lbs_private *)data;
738 unsigned long flags; 721 unsigned long flags;
@@ -851,7 +834,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
851 834
852 mutex_init(&priv->lock); 835 mutex_init(&priv->lock);
853 836
854 setup_timer(&priv->command_timer, command_timer_fn, 837 setup_timer(&priv->command_timer, lbs_cmd_timeout_handler,
855 (unsigned long)priv); 838 (unsigned long)priv);
856 setup_timer(&priv->auto_deepsleep_timer, auto_deepsleep_timer_fn, 839 setup_timer(&priv->auto_deepsleep_timer, auto_deepsleep_timer_fn,
857 (unsigned long)priv); 840 (unsigned long)priv);
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c
index ba3eb0101d5..6ab30033c26 100644
--- a/drivers/net/wireless/libertas_tf/main.c
+++ b/drivers/net/wireless/libertas_tf/main.c
@@ -555,6 +555,9 @@ struct lbtf_private *lbtf_add_card(void *card, struct device *dmdev)
555 priv->band.n_channels = ARRAY_SIZE(lbtf_channels); 555 priv->band.n_channels = ARRAY_SIZE(lbtf_channels);
556 priv->band.channels = priv->channels; 556 priv->band.channels = priv->channels;
557 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; 557 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
558 hw->wiphy->interface_modes =
559 BIT(NL80211_IFTYPE_STATION) |
560 BIT(NL80211_IFTYPE_ADHOC);
558 skb_queue_head_init(&priv->bc_ps_buf); 561 skb_queue_head_init(&priv->bc_ps_buf);
559 562
560 SET_IEEE80211_DEV(hw, dmdev); 563 SET_IEEE80211_DEV(hw, dmdev);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 0dbda8dfbd9..00ffe6dd435 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -32,6 +32,10 @@ static int radios = 2;
32module_param(radios, int, 0444); 32module_param(radios, int, 0444);
33MODULE_PARM_DESC(radios, "Number of simulated radios"); 33MODULE_PARM_DESC(radios, "Number of simulated radios");
34 34
35static bool fake_hw_scan;
36module_param(fake_hw_scan, bool, 0444);
37MODULE_PARM_DESC(fake_hw_scan, "Install fake (no-op) hw-scan handler");
38
35/** 39/**
36 * enum hwsim_regtest - the type of regulatory tests we offer 40 * enum hwsim_regtest - the type of regulatory tests we offer
37 * 41 *
@@ -908,8 +912,43 @@ static void mac80211_hwsim_flush(struct ieee80211_hw *hw, bool drop)
908 */ 912 */
909} 913}
910 914
915struct hw_scan_done {
916 struct delayed_work w;
917 struct ieee80211_hw *hw;
918};
911 919
912static const struct ieee80211_ops mac80211_hwsim_ops = 920static void hw_scan_done(struct work_struct *work)
921{
922 struct hw_scan_done *hsd =
923 container_of(work, struct hw_scan_done, w.work);
924
925 ieee80211_scan_completed(hsd->hw, false);
926 kfree(hsd);
927}
928
929static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw,
930 struct cfg80211_scan_request *req)
931{
932 struct hw_scan_done *hsd = kzalloc(sizeof(*hsd), GFP_KERNEL);
933 int i;
934
935 if (!hsd)
936 return -ENOMEM;
937
938 hsd->hw = hw;
939 INIT_DELAYED_WORK(&hsd->w, hw_scan_done);
940
941 printk(KERN_DEBUG "hwsim scan request\n");
942 for (i = 0; i < req->n_channels; i++)
943 printk(KERN_DEBUG "hwsim scan freq %d\n",
944 req->channels[i]->center_freq);
945
946 ieee80211_queue_delayed_work(hw, &hsd->w, 2 * HZ);
947
948 return 0;
949}
950
951static struct ieee80211_ops mac80211_hwsim_ops =
913{ 952{
914 .tx = mac80211_hwsim_tx, 953 .tx = mac80211_hwsim_tx,
915 .start = mac80211_hwsim_start, 954 .start = mac80211_hwsim_start,
@@ -1119,6 +1158,9 @@ static int __init init_mac80211_hwsim(void)
1119 if (radios < 1 || radios > 100) 1158 if (radios < 1 || radios > 100)
1120 return -EINVAL; 1159 return -EINVAL;
1121 1160
1161 if (fake_hw_scan)
1162 mac80211_hwsim_ops.hw_scan = mac80211_hwsim_hw_scan;
1163
1122 spin_lock_init(&hwsim_radio_lock); 1164 spin_lock_init(&hwsim_radio_lock);
1123 INIT_LIST_HEAD(&hwsim_radios); 1165 INIT_LIST_HEAD(&hwsim_radios);
1124 1166
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index f0f08f3919c..0cfdb9db66f 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -119,7 +119,7 @@ struct mwl8k_tx_queue {
119 /* sw appends here */ 119 /* sw appends here */
120 int tail; 120 int tail;
121 121
122 struct ieee80211_tx_queue_stats stats; 122 unsigned int len;
123 struct mwl8k_tx_desc *txd; 123 struct mwl8k_tx_desc *txd;
124 dma_addr_t txd_dma; 124 dma_addr_t txd_dma;
125 struct sk_buff **skb; 125 struct sk_buff **skb;
@@ -1136,8 +1136,7 @@ static int mwl8k_txq_init(struct ieee80211_hw *hw, int index)
1136 int size; 1136 int size;
1137 int i; 1137 int i;
1138 1138
1139 memset(&txq->stats, 0, sizeof(struct ieee80211_tx_queue_stats)); 1139 txq->len = 0;
1140 txq->stats.limit = MWL8K_TX_DESCS;
1141 txq->head = 0; 1140 txq->head = 0;
1142 txq->tail = 0; 1141 txq->tail = 0;
1143 1142
@@ -1213,7 +1212,7 @@ static void mwl8k_dump_tx_rings(struct ieee80211_hw *hw)
1213 printk(KERN_ERR "%s: txq[%d] len=%d head=%d tail=%d " 1212 printk(KERN_ERR "%s: txq[%d] len=%d head=%d tail=%d "
1214 "fw_owned=%d drv_owned=%d unused=%d\n", 1213 "fw_owned=%d drv_owned=%d unused=%d\n",
1215 wiphy_name(hw->wiphy), i, 1214 wiphy_name(hw->wiphy), i,
1216 txq->stats.len, txq->head, txq->tail, 1215 txq->len, txq->head, txq->tail,
1217 fw_owned, drv_owned, unused); 1216 fw_owned, drv_owned, unused);
1218 } 1217 }
1219} 1218}
@@ -1299,7 +1298,7 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1299 int processed; 1298 int processed;
1300 1299
1301 processed = 0; 1300 processed = 0;
1302 while (txq->stats.len > 0 && limit--) { 1301 while (txq->len > 0 && limit--) {
1303 int tx; 1302 int tx;
1304 struct mwl8k_tx_desc *tx_desc; 1303 struct mwl8k_tx_desc *tx_desc;
1305 unsigned long addr; 1304 unsigned long addr;
@@ -1321,8 +1320,8 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1321 } 1320 }
1322 1321
1323 txq->head = (tx + 1) % MWL8K_TX_DESCS; 1322 txq->head = (tx + 1) % MWL8K_TX_DESCS;
1324 BUG_ON(txq->stats.len == 0); 1323 BUG_ON(txq->len == 0);
1325 txq->stats.len--; 1324 txq->len--;
1326 priv->pending_tx_pkts--; 1325 priv->pending_tx_pkts--;
1327 1326
1328 addr = le32_to_cpu(tx_desc->pkt_phys_addr); 1327 addr = le32_to_cpu(tx_desc->pkt_phys_addr);
@@ -1454,8 +1453,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1454 wmb(); 1453 wmb();
1455 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus); 1454 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus);
1456 1455
1457 txq->stats.count++; 1456 txq->len++;
1458 txq->stats.len++;
1459 priv->pending_tx_pkts++; 1457 priv->pending_tx_pkts++;
1460 1458
1461 txq->tail++; 1459 txq->tail++;
@@ -3818,24 +3816,6 @@ static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
3818 return rc; 3816 return rc;
3819} 3817}
3820 3818
3821static int mwl8k_get_tx_stats(struct ieee80211_hw *hw,
3822 struct ieee80211_tx_queue_stats *stats)
3823{
3824 struct mwl8k_priv *priv = hw->priv;
3825 struct mwl8k_tx_queue *txq;
3826 int index;
3827
3828 spin_lock_bh(&priv->tx_lock);
3829 for (index = 0; index < MWL8K_TX_QUEUES; index++) {
3830 txq = priv->txq + index;
3831 memcpy(&stats[index], &txq->stats,
3832 sizeof(struct ieee80211_tx_queue_stats));
3833 }
3834 spin_unlock_bh(&priv->tx_lock);
3835
3836 return 0;
3837}
3838
3839static int mwl8k_get_stats(struct ieee80211_hw *hw, 3819static int mwl8k_get_stats(struct ieee80211_hw *hw,
3840 struct ieee80211_low_level_stats *stats) 3820 struct ieee80211_low_level_stats *stats)
3841{ 3821{
@@ -3871,7 +3851,6 @@ static const struct ieee80211_ops mwl8k_ops = {
3871 .set_rts_threshold = mwl8k_set_rts_threshold, 3851 .set_rts_threshold = mwl8k_set_rts_threshold,
3872 .sta_notify = mwl8k_sta_notify, 3852 .sta_notify = mwl8k_sta_notify,
3873 .conf_tx = mwl8k_conf_tx, 3853 .conf_tx = mwl8k_conf_tx,
3874 .get_tx_stats = mwl8k_get_tx_stats,
3875 .get_stats = mwl8k_get_stats, 3854 .get_stats = mwl8k_get_stats,
3876 .ampdu_action = mwl8k_ampdu_action, 3855 .ampdu_action = mwl8k_ampdu_action,
3877}; 3856};
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index 26428e4c9c6..3fe6366e567 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -358,16 +358,6 @@ static int p54_get_stats(struct ieee80211_hw *dev,
358 return 0; 358 return 0;
359} 359}
360 360
361static int p54_get_tx_stats(struct ieee80211_hw *dev,
362 struct ieee80211_tx_queue_stats *stats)
363{
364 struct p54_common *priv = dev->priv;
365
366 memcpy(stats, &priv->tx_stats[P54_QUEUE_DATA],
367 sizeof(stats[0]) * dev->queues);
368 return 0;
369}
370
371static void p54_bss_info_changed(struct ieee80211_hw *dev, 361static void p54_bss_info_changed(struct ieee80211_hw *dev,
372 struct ieee80211_vif *vif, 362 struct ieee80211_vif *vif,
373 struct ieee80211_bss_conf *info, 363 struct ieee80211_bss_conf *info,
@@ -522,7 +512,6 @@ static const struct ieee80211_ops p54_ops = {
522 .configure_filter = p54_configure_filter, 512 .configure_filter = p54_configure_filter,
523 .conf_tx = p54_conf_tx, 513 .conf_tx = p54_conf_tx,
524 .get_stats = p54_get_stats, 514 .get_stats = p54_get_stats,
525 .get_tx_stats = p54_get_tx_stats
526}; 515};
527 516
528struct ieee80211_hw *p54_init_common(size_t priv_data_len) 517struct ieee80211_hw *p54_init_common(size_t priv_data_len)
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index 1afc39410e8..43a3b2ead81 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -157,6 +157,12 @@ struct p54_led_dev {
157 157
158#endif /* CONFIG_P54_LEDS */ 158#endif /* CONFIG_P54_LEDS */
159 159
160struct p54_tx_queue_stats {
161 unsigned int len;
162 unsigned int limit;
163 unsigned int count;
164};
165
160struct p54_common { 166struct p54_common {
161 struct ieee80211_hw *hw; 167 struct ieee80211_hw *hw;
162 struct ieee80211_vif *vif; 168 struct ieee80211_vif *vif;
@@ -183,7 +189,7 @@ struct p54_common {
183 /* (e)DCF / QOS state */ 189 /* (e)DCF / QOS state */
184 bool use_short_slot; 190 bool use_short_slot;
185 spinlock_t tx_stats_lock; 191 spinlock_t tx_stats_lock;
186 struct ieee80211_tx_queue_stats tx_stats[8]; 192 struct p54_tx_queue_stats tx_stats[8];
187 struct p54_edcf_queue_param qos_params[8]; 193 struct p54_edcf_queue_param qos_params[8];
188 194
189 /* Radio data */ 195 /* Radio data */
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index b6dda2b27fb..0e8f69461ff 100644
--- a/drivers/net/wireless/p54/txrx.c
+++ b/drivers/net/wireless/p54/txrx.c
@@ -183,7 +183,7 @@ static int p54_tx_qos_accounting_alloc(struct p54_common *priv,
183 struct sk_buff *skb, 183 struct sk_buff *skb,
184 const u16 p54_queue) 184 const u16 p54_queue)
185{ 185{
186 struct ieee80211_tx_queue_stats *queue; 186 struct p54_tx_queue_stats *queue;
187 unsigned long flags; 187 unsigned long flags;
188 188
189 if (WARN_ON(p54_queue > P54_QUEUE_NUM)) 189 if (WARN_ON(p54_queue > P54_QUEUE_NUM))
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index aa579eb8723..108982762d4 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1561,7 +1561,6 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
1561 .get_stats = rt2x00mac_get_stats, 1561 .get_stats = rt2x00mac_get_stats,
1562 .bss_info_changed = rt2x00mac_bss_info_changed, 1562 .bss_info_changed = rt2x00mac_bss_info_changed,
1563 .conf_tx = rt2400pci_conf_tx, 1563 .conf_tx = rt2400pci_conf_tx,
1564 .get_tx_stats = rt2x00mac_get_tx_stats,
1565 .get_tsf = rt2400pci_get_tsf, 1564 .get_tsf = rt2400pci_get_tsf,
1566 .tx_last_beacon = rt2400pci_tx_last_beacon, 1565 .tx_last_beacon = rt2400pci_tx_last_beacon,
1567 .rfkill_poll = rt2x00mac_rfkill_poll, 1566 .rfkill_poll = rt2x00mac_rfkill_poll,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 77ee1df7933..f6440bb0e5f 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1859,7 +1859,6 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
1859 .get_stats = rt2x00mac_get_stats, 1859 .get_stats = rt2x00mac_get_stats,
1860 .bss_info_changed = rt2x00mac_bss_info_changed, 1860 .bss_info_changed = rt2x00mac_bss_info_changed,
1861 .conf_tx = rt2x00mac_conf_tx, 1861 .conf_tx = rt2x00mac_conf_tx,
1862 .get_tx_stats = rt2x00mac_get_tx_stats,
1863 .get_tsf = rt2500pci_get_tsf, 1862 .get_tsf = rt2500pci_get_tsf,
1864 .tx_last_beacon = rt2500pci_tx_last_beacon, 1863 .tx_last_beacon = rt2500pci_tx_last_beacon,
1865 .rfkill_poll = rt2x00mac_rfkill_poll, 1864 .rfkill_poll = rt2x00mac_rfkill_poll,
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 9e6f865c57f..81ca4ec068d 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1761,7 +1761,6 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
1761 .get_stats = rt2x00mac_get_stats, 1761 .get_stats = rt2x00mac_get_stats,
1762 .bss_info_changed = rt2x00mac_bss_info_changed, 1762 .bss_info_changed = rt2x00mac_bss_info_changed,
1763 .conf_tx = rt2x00mac_conf_tx, 1763 .conf_tx = rt2x00mac_conf_tx,
1764 .get_tx_stats = rt2x00mac_get_tx_stats,
1765 .rfkill_poll = rt2x00mac_rfkill_poll, 1764 .rfkill_poll = rt2x00mac_rfkill_poll,
1766}; 1765};
1767 1766
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 529a37364eb..a45e027f2d1 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2297,7 +2297,6 @@ const struct ieee80211_ops rt2800_mac80211_ops = {
2297 .set_rts_threshold = rt2800_set_rts_threshold, 2297 .set_rts_threshold = rt2800_set_rts_threshold,
2298 .bss_info_changed = rt2x00mac_bss_info_changed, 2298 .bss_info_changed = rt2x00mac_bss_info_changed,
2299 .conf_tx = rt2800_conf_tx, 2299 .conf_tx = rt2800_conf_tx,
2300 .get_tx_stats = rt2x00mac_get_tx_stats,
2301 .get_tsf = rt2800_get_tsf, 2300 .get_tsf = rt2800_get_tsf,
2302 .rfkill_poll = rt2x00mac_rfkill_poll, 2301 .rfkill_poll = rt2x00mac_rfkill_poll,
2303}; 2302};
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 096da85a66f..43b70c6e4e9 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -1044,8 +1044,6 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
1044#endif /* CONFIG_RT2X00_LIB_CRYPTO */ 1044#endif /* CONFIG_RT2X00_LIB_CRYPTO */
1045int rt2x00mac_get_stats(struct ieee80211_hw *hw, 1045int rt2x00mac_get_stats(struct ieee80211_hw *hw,
1046 struct ieee80211_low_level_stats *stats); 1046 struct ieee80211_low_level_stats *stats);
1047int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw,
1048 struct ieee80211_tx_queue_stats *stats);
1049void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, 1047void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
1050 struct ieee80211_vif *vif, 1048 struct ieee80211_vif *vif,
1051 struct ieee80211_bss_conf *bss_conf, 1049 struct ieee80211_bss_conf *bss_conf,
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 00f1f939f1b..abbd857ec75 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -555,22 +555,6 @@ int rt2x00mac_get_stats(struct ieee80211_hw *hw,
555} 555}
556EXPORT_SYMBOL_GPL(rt2x00mac_get_stats); 556EXPORT_SYMBOL_GPL(rt2x00mac_get_stats);
557 557
558int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw,
559 struct ieee80211_tx_queue_stats *stats)
560{
561 struct rt2x00_dev *rt2x00dev = hw->priv;
562 unsigned int i;
563
564 for (i = 0; i < rt2x00dev->ops->tx_queues; i++) {
565 stats[i].len = rt2x00dev->tx[i].length;
566 stats[i].limit = rt2x00dev->tx[i].limit;
567 stats[i].count = rt2x00dev->tx[i].count;
568 }
569
570 return 0;
571}
572EXPORT_SYMBOL_GPL(rt2x00mac_get_tx_stats);
573
574void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, 558void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
575 struct ieee80211_vif *vif, 559 struct ieee80211_vif *vif,
576 struct ieee80211_bss_conf *bss_conf, 560 struct ieee80211_bss_conf *bss_conf,
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 1f97a797bc4..74de53e68b4 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2730,7 +2730,6 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
2730 .get_stats = rt2x00mac_get_stats, 2730 .get_stats = rt2x00mac_get_stats,
2731 .bss_info_changed = rt2x00mac_bss_info_changed, 2731 .bss_info_changed = rt2x00mac_bss_info_changed,
2732 .conf_tx = rt61pci_conf_tx, 2732 .conf_tx = rt61pci_conf_tx,
2733 .get_tx_stats = rt2x00mac_get_tx_stats,
2734 .get_tsf = rt61pci_get_tsf, 2733 .get_tsf = rt61pci_get_tsf,
2735 .rfkill_poll = rt2x00mac_rfkill_poll, 2734 .rfkill_poll = rt2x00mac_rfkill_poll,
2736}; 2735};
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index a0269129439..3781eb7b4aa 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2245,7 +2245,6 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
2245 .get_stats = rt2x00mac_get_stats, 2245 .get_stats = rt2x00mac_get_stats,
2246 .bss_info_changed = rt2x00mac_bss_info_changed, 2246 .bss_info_changed = rt2x00mac_bss_info_changed,
2247 .conf_tx = rt73usb_conf_tx, 2247 .conf_tx = rt73usb_conf_tx,
2248 .get_tx_stats = rt2x00mac_get_tx_stats,
2249 .get_tsf = rt73usb_get_tsf, 2248 .get_tsf = rt73usb_get_tsf,
2250 .rfkill_poll = rt2x00mac_rfkill_poll, 2249 .rfkill_poll = rt2x00mac_rfkill_poll,
2251}; 2250};
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index a717dde4822..24ae6a360ac 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -1144,9 +1144,10 @@ static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
1144 if (ret < 0) 1144 if (ret < 0)
1145 goto out; 1145 goto out;
1146 1146
1147 /* mac80211 uses units of 32 usec */
1147 ret = wl1251_acx_ac_cfg(wl, wl1251_tx_get_queue(queue), 1148 ret = wl1251_acx_ac_cfg(wl, wl1251_tx_get_queue(queue),
1148 params->cw_min, params->cw_max, 1149 params->cw_min, params->cw_max,
1149 params->aifs, params->txop); 1150 params->aifs, params->txop * 32);
1150 if (ret < 0) 1151 if (ret < 0)
1151 goto out_sleep; 1152 goto out_sleep;
1152 1153
diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c
index 3c6feed46f6..97efce184a8 100644
--- a/drivers/ssb/driver_mipscore.c
+++ b/drivers/ssb/driver_mipscore.c
@@ -270,7 +270,6 @@ void ssb_mipscore_init(struct ssb_mipscore *mcore)
270 set_irq(dev, irq++); 270 set_irq(dev, irq++);
271 } 271 }
272 break; 272 break;
273 /* fallthrough */
274 case SSB_DEV_PCI: 273 case SSB_DEV_PCI:
275 case SSB_DEV_ETHERNET: 274 case SSB_DEV_ETHERNET:
276 case SSB_DEV_ETHERNET_GBIT: 275 case SSB_DEV_ETHERNET_GBIT:
@@ -281,6 +280,10 @@ void ssb_mipscore_init(struct ssb_mipscore *mcore)
281 set_irq(dev, irq++); 280 set_irq(dev, irq++);
282 break; 281 break;
283 } 282 }
283 /* fallthrough */
284 case SSB_DEV_EXTIF:
285 set_irq(dev, 0);
286 break;
284 } 287 }
285 } 288 }
286 ssb_dprintk(KERN_INFO PFX "after irq reconfiguration\n"); 289 ssb_dprintk(KERN_INFO PFX "after irq reconfiguration\n");
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 5681ebed9c6..03dfd27c4bf 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -494,8 +494,7 @@ static int ssb_devices_register(struct ssb_bus *bus)
494#endif 494#endif
495 break; 495 break;
496 case SSB_BUSTYPE_SDIO: 496 case SSB_BUSTYPE_SDIO:
497#ifdef CONFIG_SSB_SDIO 497#ifdef CONFIG_SSB_SDIOHOST
498 sdev->irq = bus->host_sdio->dev.irq;
499 dev->parent = &bus->host_sdio->dev; 498 dev->parent = &bus->host_sdio->dev;
500#endif 499#endif
501 break; 500 break;
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index a3f0a7ed31a..5b3569b2a74 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1561,37 +1561,82 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
1561 * Documentation in Documentation/networking/radiotap-headers.txt 1561 * Documentation in Documentation/networking/radiotap-headers.txt
1562 */ 1562 */
1563 1563
1564struct radiotap_align_size {
1565 uint8_t align:4, size:4;
1566};
1567
1568struct ieee80211_radiotap_namespace {
1569 const struct radiotap_align_size *align_size;
1570 int n_bits;
1571 uint32_t oui;
1572 uint8_t subns;
1573};
1574
1575struct ieee80211_radiotap_vendor_namespaces {
1576 const struct ieee80211_radiotap_namespace *ns;
1577 int n_ns;
1578};
1579
1564/** 1580/**
1565 * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args 1581 * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args
1566 * @rtheader: pointer to the radiotap header we are walking through 1582 * @this_arg_index: index of current arg, valid after each successful call
1567 * @max_length: length of radiotap header in cpu byte ordering 1583 * to ieee80211_radiotap_iterator_next()
1568 * @this_arg_index: IEEE80211_RADIOTAP_... index of current arg 1584 * @this_arg: pointer to current radiotap arg; it is valid after each
1569 * @this_arg: pointer to current radiotap arg 1585 * call to ieee80211_radiotap_iterator_next() but also after
1570 * @arg_index: internal next argument index 1586 * ieee80211_radiotap_iterator_init() where it will point to
1571 * @arg: internal next argument pointer 1587 * the beginning of the actual data portion
1572 * @next_bitmap: internal pointer to next present u32 1588 * @this_arg_size: length of the current arg, for convenience
1573 * @bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present 1589 * @current_namespace: pointer to the current namespace definition
1590 * (or internally %NULL if the current namespace is unknown)
1591 * @is_radiotap_ns: indicates whether the current namespace is the default
1592 * radiotap namespace or not
1593 *
1594 * @overrides: override standard radiotap fields
1595 * @n_overrides: number of overrides
1596 *
1597 * @_rtheader: pointer to the radiotap header we are walking through
1598 * @_max_length: length of radiotap header in cpu byte ordering
1599 * @_arg_index: next argument index
1600 * @_arg: next argument pointer
1601 * @_next_bitmap: internal pointer to next present u32
1602 * @_bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present
1603 * @_vns: vendor namespace definitions
1604 * @_next_ns_data: beginning of the next namespace's data
1605 * @_reset_on_ext: internal; reset the arg index to 0 when going to the
1606 * next bitmap word
1607 *
1608 * Describes the radiotap parser state. Fields prefixed with an underscore
1609 * must not be used by users of the parser, only by the parser internally.
1574 */ 1610 */
1575 1611
1576struct ieee80211_radiotap_iterator { 1612struct ieee80211_radiotap_iterator {
1577 struct ieee80211_radiotap_header *rtheader; 1613 struct ieee80211_radiotap_header *_rtheader;
1578 int max_length; 1614 const struct ieee80211_radiotap_vendor_namespaces *_vns;
1615 const struct ieee80211_radiotap_namespace *current_namespace;
1616
1617 unsigned char *_arg, *_next_ns_data;
1618 uint32_t *_next_bitmap;
1619
1620 unsigned char *this_arg;
1579 int this_arg_index; 1621 int this_arg_index;
1580 u8 *this_arg; 1622 int this_arg_size;
1581 1623
1582 int arg_index; 1624 int is_radiotap_ns;
1583 u8 *arg; 1625
1584 __le32 *next_bitmap; 1626 int _max_length;
1585 u32 bitmap_shifter; 1627 int _arg_index;
1628 uint32_t _bitmap_shifter;
1629 int _reset_on_ext;
1586}; 1630};
1587 1631
1588extern int ieee80211_radiotap_iterator_init( 1632extern int ieee80211_radiotap_iterator_init(
1589 struct ieee80211_radiotap_iterator *iterator, 1633 struct ieee80211_radiotap_iterator *iterator,
1590 struct ieee80211_radiotap_header *radiotap_header, 1634 struct ieee80211_radiotap_header *radiotap_header,
1591 int max_length); 1635 int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns);
1592 1636
1593extern int ieee80211_radiotap_iterator_next( 1637extern int ieee80211_radiotap_iterator_next(
1594 struct ieee80211_radiotap_iterator *iterator); 1638 struct ieee80211_radiotap_iterator *iterator);
1639
1595 1640
1596extern const unsigned char rfc1042_header[6]; 1641extern const unsigned char rfc1042_header[6];
1597extern const unsigned char bridge_tunnel_header[6]; 1642extern const unsigned char bridge_tunnel_header[6];
diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h
index 9d3d86aaccb..af49f8ab7f8 100644
--- a/include/net/ieee80211_radiotap.h
+++ b/include/net/ieee80211_radiotap.h
@@ -198,6 +198,10 @@ enum ieee80211_radiotap_type {
198 IEEE80211_RADIOTAP_TX_FLAGS = 15, 198 IEEE80211_RADIOTAP_TX_FLAGS = 15,
199 IEEE80211_RADIOTAP_RTS_RETRIES = 16, 199 IEEE80211_RADIOTAP_RTS_RETRIES = 16,
200 IEEE80211_RADIOTAP_DATA_RETRIES = 17, 200 IEEE80211_RADIOTAP_DATA_RETRIES = 17,
201
202 /* valid in every it_present bitmap, even vendor namespaces */
203 IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29,
204 IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30,
201 IEEE80211_RADIOTAP_EXT = 31 205 IEEE80211_RADIOTAP_EXT = 31
202}; 206};
203 207
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 74ccf30fdf8..314e9817316 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -117,19 +117,6 @@ struct ieee80211_tx_queue_params {
117 bool uapsd; 117 bool uapsd;
118}; 118};
119 119
120/**
121 * struct ieee80211_tx_queue_stats - transmit queue statistics
122 *
123 * @len: number of packets in queue
124 * @limit: queue length limit
125 * @count: number of frames sent
126 */
127struct ieee80211_tx_queue_stats {
128 unsigned int len;
129 unsigned int limit;
130 unsigned int count;
131};
132
133struct ieee80211_low_level_stats { 120struct ieee80211_low_level_stats {
134 unsigned int dot11ACKFailureCount; 121 unsigned int dot11ACKFailureCount;
135 unsigned int dot11RTSFailureCount; 122 unsigned int dot11RTSFailureCount;
@@ -814,7 +801,7 @@ enum set_key_cmd {
814 * mac80211, any ieee80211_sta pointer you get access to must 801 * mac80211, any ieee80211_sta pointer you get access to must
815 * either be protected by rcu_read_lock() explicitly or implicitly, 802 * either be protected by rcu_read_lock() explicitly or implicitly,
816 * or you must take good care to not use such a pointer after a 803 * or you must take good care to not use such a pointer after a
817 * call to your sta_notify callback that removed it. 804 * call to your sta_remove callback that removed it.
818 * 805 *
819 * @addr: MAC address 806 * @addr: MAC address
820 * @aid: AID we assigned to the station if we're an AP 807 * @aid: AID we assigned to the station if we're an AP
@@ -840,8 +827,8 @@ struct ieee80211_sta {
840 * indicates addition and removal of a station to station table, 827 * indicates addition and removal of a station to station table,
841 * or if a associated station made a power state transition. 828 * or if a associated station made a power state transition.
842 * 829 *
843 * @STA_NOTIFY_ADD: a station was added to the station table 830 * @STA_NOTIFY_ADD: (DEPRECATED) a station was added to the station table
844 * @STA_NOTIFY_REMOVE: a station being removed from the station table 831 * @STA_NOTIFY_REMOVE: (DEPRECATED) a station being removed from the station table
845 * @STA_NOTIFY_SLEEP: a station is now sleeping 832 * @STA_NOTIFY_SLEEP: a station is now sleeping
846 * @STA_NOTIFY_AWAKE: a sleeping station woke up 833 * @STA_NOTIFY_AWAKE: a sleeping station woke up
847 */ 834 */
@@ -958,6 +945,11 @@ enum ieee80211_tkip_key_type {
958 * Hardware supports Unscheduled Automatic Power Save Delivery 945 * Hardware supports Unscheduled Automatic Power Save Delivery
959 * (U-APSD) in managed mode. The mode is configured with 946 * (U-APSD) in managed mode. The mode is configured with
960 * conf_tx() operation. 947 * conf_tx() operation.
948 *
949 * @IEEE80211_HW_REPORTS_TX_ACK_STATUS:
950 * Hardware can provide ack status reports of Tx frames to
951 * the stack.
952 *
961 */ 953 */
962enum ieee80211_hw_flags { 954enum ieee80211_hw_flags {
963 IEEE80211_HW_HAS_RATE_CONTROL = 1<<0, 955 IEEE80211_HW_HAS_RATE_CONTROL = 1<<0,
@@ -978,6 +970,7 @@ enum ieee80211_hw_flags {
978 IEEE80211_HW_SUPPORTS_STATIC_SMPS = 1<<15, 970 IEEE80211_HW_SUPPORTS_STATIC_SMPS = 1<<15,
979 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS = 1<<16, 971 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS = 1<<16,
980 IEEE80211_HW_SUPPORTS_UAPSD = 1<<17, 972 IEEE80211_HW_SUPPORTS_UAPSD = 1<<17,
973 IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18,
981}; 974};
982 975
983/** 976/**
@@ -1534,22 +1527,20 @@ enum ieee80211_ampdu_mlme_action {
1534 * @set_rts_threshold: Configuration of RTS threshold (if device needs it) 1527 * @set_rts_threshold: Configuration of RTS threshold (if device needs it)
1535 * The callback can sleep. 1528 * The callback can sleep.
1536 * 1529 *
1537 * @sta_notify: Notifies low level driver about addition, removal or power 1530 * @sta_add: Notifies low level driver about addition of an associated station,
1538 * state transition of an associated station, AP, IBSS/WDS/mesh peer etc. 1531 * AP, IBSS/WDS/mesh peer etc. This callback can sleep.
1539 * Must be atomic. 1532 *
1533 * @sta_remove: Notifies low level driver about removal of an associated
1534 * station, AP, IBSS/WDS/mesh peer etc. This callback can sleep.
1535 *
1536 * @sta_notify: Notifies low level driver about power state transition of an
1537 * associated station, AP, IBSS/WDS/mesh peer etc. Must be atomic.
1540 * 1538 *
1541 * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max), 1539 * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
1542 * bursting) for a hardware TX queue. 1540 * bursting) for a hardware TX queue.
1543 * Returns a negative error code on failure. 1541 * Returns a negative error code on failure.
1544 * The callback can sleep. 1542 * The callback can sleep.
1545 * 1543 *
1546 * @get_tx_stats: Get statistics of the current TX queue status. This is used
1547 * to get number of currently queued packets (queue length), maximum queue
1548 * size (limit), and total number of packets sent using each TX queue
1549 * (count). The 'stats' pointer points to an array that has hw->queues
1550 * items.
1551 * The callback must be atomic.
1552 *
1553 * @get_tsf: Get the current TSF timer value from firmware/hardware. Currently, 1544 * @get_tsf: Get the current TSF timer value from firmware/hardware. Currently,
1554 * this is only used for IBSS mode BSSID merging and debugging. Is not a 1545 * this is only used for IBSS mode BSSID merging and debugging. Is not a
1555 * required function. 1546 * required function.
@@ -1635,12 +1626,14 @@ struct ieee80211_ops {
1635 void (*get_tkip_seq)(struct ieee80211_hw *hw, u8 hw_key_idx, 1626 void (*get_tkip_seq)(struct ieee80211_hw *hw, u8 hw_key_idx,
1636 u32 *iv32, u16 *iv16); 1627 u32 *iv32, u16 *iv16);
1637 int (*set_rts_threshold)(struct ieee80211_hw *hw, u32 value); 1628 int (*set_rts_threshold)(struct ieee80211_hw *hw, u32 value);
1629 int (*sta_add)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1630 struct ieee80211_sta *sta);
1631 int (*sta_remove)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1632 struct ieee80211_sta *sta);
1638 void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1633 void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1639 enum sta_notify_cmd, struct ieee80211_sta *sta); 1634 enum sta_notify_cmd, struct ieee80211_sta *sta);
1640 int (*conf_tx)(struct ieee80211_hw *hw, u16 queue, 1635 int (*conf_tx)(struct ieee80211_hw *hw, u16 queue,
1641 const struct ieee80211_tx_queue_params *params); 1636 const struct ieee80211_tx_queue_params *params);
1642 int (*get_tx_stats)(struct ieee80211_hw *hw,
1643 struct ieee80211_tx_queue_stats *stats);
1644 u64 (*get_tsf)(struct ieee80211_hw *hw); 1637 u64 (*get_tsf)(struct ieee80211_hw *hw);
1645 void (*set_tsf)(struct ieee80211_hw *hw, u64 tsf); 1638 void (*set_tsf)(struct ieee80211_hw *hw, u64 tsf);
1646 void (*reset_tsf)(struct ieee80211_hw *hw); 1639 void (*reset_tsf)(struct ieee80211_hw *hw);
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 718fbcff84d..5538e1b4a69 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -237,6 +237,14 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
237 sdata->vif.type != NL80211_IFTYPE_AP) 237 sdata->vif.type != NL80211_IFTYPE_AP)
238 return -EINVAL; 238 return -EINVAL;
239 239
240 if (test_sta_flags(sta, WLAN_STA_DISASSOC)) {
241#ifdef CONFIG_MAC80211_HT_DEBUG
242 printk(KERN_DEBUG "Disassociation is in progress. "
243 "Denying BA session request\n");
244#endif
245 return -EINVAL;
246 }
247
240 if (test_sta_flags(sta, WLAN_STA_SUSPEND)) { 248 if (test_sta_flags(sta, WLAN_STA_SUSPEND)) {
241#ifdef CONFIG_MAC80211_HT_DEBUG 249#ifdef CONFIG_MAC80211_HT_DEBUG
242 printk(KERN_DEBUG "Suspend in progress. " 250 printk(KERN_DEBUG "Suspend in progress. "
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index facf233843e..e1731b7c252 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -515,6 +515,8 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
515 if (old) 515 if (old)
516 memcpy(new->tail, old->tail, new_tail_len); 516 memcpy(new->tail, old->tail, new_tail_len);
517 517
518 sdata->vif.bss_conf.dtim_period = new->dtim_period;
519
518 rcu_assign_pointer(sdata->u.ap.beacon, new); 520 rcu_assign_pointer(sdata->u.ap.beacon, new);
519 521
520 synchronize_rcu(); 522 synchronize_rcu();
@@ -747,9 +749,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
747 layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN || 749 layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
748 sdata->vif.type == NL80211_IFTYPE_AP; 750 sdata->vif.type == NL80211_IFTYPE_AP;
749 751
750 rcu_read_lock(); 752 err = sta_info_insert_rcu(sta);
751
752 err = sta_info_insert(sta);
753 if (err) { 753 if (err) {
754 rcu_read_unlock(); 754 rcu_read_unlock();
755 return err; 755 return err;
@@ -768,26 +768,13 @@ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
768{ 768{
769 struct ieee80211_local *local = wiphy_priv(wiphy); 769 struct ieee80211_local *local = wiphy_priv(wiphy);
770 struct ieee80211_sub_if_data *sdata; 770 struct ieee80211_sub_if_data *sdata;
771 struct sta_info *sta;
772 771
773 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 772 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
774 773
775 if (mac) { 774 if (mac)
776 rcu_read_lock(); 775 return sta_info_destroy_addr_bss(sdata, mac);
777
778 sta = sta_info_get_bss(sdata, mac);
779 if (!sta) {
780 rcu_read_unlock();
781 return -ENOENT;
782 }
783
784 sta_info_unlink(&sta);
785 rcu_read_unlock();
786
787 sta_info_destroy(sta);
788 } else
789 sta_info_flush(local, sdata);
790 776
777 sta_info_flush(local, sdata);
791 return 0; 778 return 0;
792} 779}
793 780
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index b3bc32b62a5..637929b65cc 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -250,6 +250,38 @@ static const struct file_operations uapsd_max_sp_len_ops = {
250 .open = mac80211_open_file_generic 250 .open = mac80211_open_file_generic
251}; 251};
252 252
253static ssize_t channel_type_read(struct file *file, char __user *user_buf,
254 size_t count, loff_t *ppos)
255{
256 struct ieee80211_local *local = file->private_data;
257 const char *buf;
258
259 switch (local->hw.conf.channel_type) {
260 case NL80211_CHAN_NO_HT:
261 buf = "no ht\n";
262 break;
263 case NL80211_CHAN_HT20:
264 buf = "ht20\n";
265 break;
266 case NL80211_CHAN_HT40MINUS:
267 buf = "ht40-\n";
268 break;
269 case NL80211_CHAN_HT40PLUS:
270 buf = "ht40+\n";
271 break;
272 default:
273 buf = "???";
274 break;
275 }
276
277 return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
278}
279
280static const struct file_operations channel_type_ops = {
281 .read = channel_type_read,
282 .open = mac80211_open_file_generic
283};
284
253static ssize_t queues_read(struct file *file, char __user *user_buf, 285static ssize_t queues_read(struct file *file, char __user *user_buf,
254 size_t count, loff_t *ppos) 286 size_t count, loff_t *ppos)
255{ 287{
@@ -408,6 +440,7 @@ void debugfs_hw_add(struct ieee80211_local *local)
408 DEBUGFS_ADD(noack); 440 DEBUGFS_ADD(noack);
409 DEBUGFS_ADD(uapsd_queues); 441 DEBUGFS_ADD(uapsd_queues);
410 DEBUGFS_ADD(uapsd_max_sp_len); 442 DEBUGFS_ADD(uapsd_max_sp_len);
443 DEBUGFS_ADD(channel_type);
411 444
412 statsd = debugfs_create_dir("statistics", phyd); 445 statsd = debugfs_create_dir("statistics", phyd);
413 446
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 6c31f38ac7f..c3d844093a2 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -243,6 +243,40 @@ static inline void drv_sta_notify(struct ieee80211_local *local,
243 trace_drv_sta_notify(local, sdata, cmd, sta); 243 trace_drv_sta_notify(local, sdata, cmd, sta);
244} 244}
245 245
246static inline int drv_sta_add(struct ieee80211_local *local,
247 struct ieee80211_sub_if_data *sdata,
248 struct ieee80211_sta *sta)
249{
250 int ret = 0;
251
252 might_sleep();
253
254 if (local->ops->sta_add)
255 ret = local->ops->sta_add(&local->hw, &sdata->vif, sta);
256 else if (local->ops->sta_notify)
257 local->ops->sta_notify(&local->hw, &sdata->vif,
258 STA_NOTIFY_ADD, sta);
259
260 trace_drv_sta_add(local, sdata, sta, ret);
261
262 return ret;
263}
264
265static inline void drv_sta_remove(struct ieee80211_local *local,
266 struct ieee80211_sub_if_data *sdata,
267 struct ieee80211_sta *sta)
268{
269 might_sleep();
270
271 if (local->ops->sta_remove)
272 local->ops->sta_remove(&local->hw, &sdata->vif, sta);
273 else if (local->ops->sta_notify)
274 local->ops->sta_notify(&local->hw, &sdata->vif,
275 STA_NOTIFY_REMOVE, sta);
276
277 trace_drv_sta_remove(local, sdata, sta);
278}
279
246static inline int drv_conf_tx(struct ieee80211_local *local, u16 queue, 280static inline int drv_conf_tx(struct ieee80211_local *local, u16 queue,
247 const struct ieee80211_tx_queue_params *params) 281 const struct ieee80211_tx_queue_params *params)
248{ 282{
@@ -256,14 +290,6 @@ static inline int drv_conf_tx(struct ieee80211_local *local, u16 queue,
256 return ret; 290 return ret;
257} 291}
258 292
259static inline int drv_get_tx_stats(struct ieee80211_local *local,
260 struct ieee80211_tx_queue_stats *stats)
261{
262 int ret = local->ops->get_tx_stats(&local->hw, stats);
263 trace_drv_get_tx_stats(local, stats, ret);
264 return ret;
265}
266
267static inline u64 drv_get_tsf(struct ieee80211_local *local) 293static inline u64 drv_get_tsf(struct ieee80211_local *local)
268{ 294{
269 u64 ret = -1ULL; 295 u64 ret = -1ULL;
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 502424b2538..41baf730a5c 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -545,59 +545,88 @@ TRACE_EVENT(drv_sta_notify,
545 ) 545 )
546); 546);
547 547
548TRACE_EVENT(drv_conf_tx, 548TRACE_EVENT(drv_sta_add,
549 TP_PROTO(struct ieee80211_local *local, u16 queue, 549 TP_PROTO(struct ieee80211_local *local,
550 const struct ieee80211_tx_queue_params *params, 550 struct ieee80211_sub_if_data *sdata,
551 int ret), 551 struct ieee80211_sta *sta, int ret),
552 552
553 TP_ARGS(local, queue, params, ret), 553 TP_ARGS(local, sdata, sta, ret),
554 554
555 TP_STRUCT__entry( 555 TP_STRUCT__entry(
556 LOCAL_ENTRY 556 LOCAL_ENTRY
557 __field(u16, queue) 557 VIF_ENTRY
558 __field(u16, txop) 558 STA_ENTRY
559 __field(u16, cw_min)
560 __field(u16, cw_max)
561 __field(u8, aifs)
562 __field(int, ret) 559 __field(int, ret)
563 ), 560 ),
564 561
565 TP_fast_assign( 562 TP_fast_assign(
566 LOCAL_ASSIGN; 563 LOCAL_ASSIGN;
567 __entry->queue = queue; 564 VIF_ASSIGN;
565 STA_ASSIGN;
568 __entry->ret = ret; 566 __entry->ret = ret;
569 __entry->txop = params->txop;
570 __entry->cw_max = params->cw_max;
571 __entry->cw_min = params->cw_min;
572 __entry->aifs = params->aifs;
573 ), 567 ),
574 568
575 TP_printk( 569 TP_printk(
576 LOCAL_PR_FMT " queue:%d ret:%d", 570 LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " ret:%d",
577 LOCAL_PR_ARG, __entry->queue, __entry->ret 571 LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->ret
578 ) 572 )
579); 573);
580 574
581TRACE_EVENT(drv_get_tx_stats, 575TRACE_EVENT(drv_sta_remove,
582 TP_PROTO(struct ieee80211_local *local, 576 TP_PROTO(struct ieee80211_local *local,
583 struct ieee80211_tx_queue_stats *stats, 577 struct ieee80211_sub_if_data *sdata,
578 struct ieee80211_sta *sta),
579
580 TP_ARGS(local, sdata, sta),
581
582 TP_STRUCT__entry(
583 LOCAL_ENTRY
584 VIF_ENTRY
585 STA_ENTRY
586 ),
587
588 TP_fast_assign(
589 LOCAL_ASSIGN;
590 VIF_ASSIGN;
591 STA_ASSIGN;
592 ),
593
594 TP_printk(
595 LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT,
596 LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG
597 )
598);
599
600TRACE_EVENT(drv_conf_tx,
601 TP_PROTO(struct ieee80211_local *local, u16 queue,
602 const struct ieee80211_tx_queue_params *params,
584 int ret), 603 int ret),
585 604
586 TP_ARGS(local, stats, ret), 605 TP_ARGS(local, queue, params, ret),
587 606
588 TP_STRUCT__entry( 607 TP_STRUCT__entry(
589 LOCAL_ENTRY 608 LOCAL_ENTRY
609 __field(u16, queue)
610 __field(u16, txop)
611 __field(u16, cw_min)
612 __field(u16, cw_max)
613 __field(u8, aifs)
590 __field(int, ret) 614 __field(int, ret)
591 ), 615 ),
592 616
593 TP_fast_assign( 617 TP_fast_assign(
594 LOCAL_ASSIGN; 618 LOCAL_ASSIGN;
619 __entry->queue = queue;
595 __entry->ret = ret; 620 __entry->ret = ret;
621 __entry->txop = params->txop;
622 __entry->cw_max = params->cw_max;
623 __entry->cw_min = params->cw_min;
624 __entry->aifs = params->aifs;
596 ), 625 ),
597 626
598 TP_printk( 627 TP_printk(
599 LOCAL_PR_FMT " ret:%d", 628 LOCAL_PR_FMT " queue:%d ret:%d",
600 LOCAL_PR_ARG, __entry->ret 629 LOCAL_PR_ARG, __entry->queue, __entry->ret
601 ) 630 )
602); 631);
603 632
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index f95750b423e..f3e94248674 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -275,10 +275,12 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
275 (unsigned long long) supp_rates, 275 (unsigned long long) supp_rates,
276 (unsigned long long) sta->sta.supp_rates[band]); 276 (unsigned long long) sta->sta.supp_rates[band]);
277#endif 277#endif
278 } else 278 rcu_read_unlock();
279 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates); 279 } else {
280 280 rcu_read_unlock();
281 rcu_read_unlock(); 281 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
282 supp_rates, GFP_KERNEL);
283 }
282 } 284 }
283 285
284 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems, 286 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
@@ -368,7 +370,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
368 sdata->name, mgmt->bssid); 370 sdata->name, mgmt->bssid);
369#endif 371#endif
370 ieee80211_sta_join_ibss(sdata, bss); 372 ieee80211_sta_join_ibss(sdata, bss);
371 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates); 373 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
374 supp_rates, GFP_KERNEL);
372 } 375 }
373 376
374 put_bss: 377 put_bss:
@@ -381,7 +384,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
381 * must be callable in atomic context. 384 * must be callable in atomic context.
382 */ 385 */
383struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, 386struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
384 u8 *bssid,u8 *addr, u32 supp_rates) 387 u8 *bssid,u8 *addr, u32 supp_rates,
388 gfp_t gfp)
385{ 389{
386 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 390 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
387 struct ieee80211_local *local = sdata->local; 391 struct ieee80211_local *local = sdata->local;
@@ -410,7 +414,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
410 wiphy_name(local->hw.wiphy), addr, sdata->name); 414 wiphy_name(local->hw.wiphy), addr, sdata->name);
411#endif 415#endif
412 416
413 sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); 417 sta = sta_info_alloc(sdata, addr, gfp);
414 if (!sta) 418 if (!sta)
415 return NULL; 419 return NULL;
416 420
@@ -422,9 +426,9 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
422 426
423 rate_control_rate_init(sta); 427 rate_control_rate_init(sta);
424 428
429 /* If it fails, maybe we raced another insertion? */
425 if (sta_info_insert(sta)) 430 if (sta_info_insert(sta))
426 return NULL; 431 return sta_info_get(sdata, addr);
427
428 return sta; 432 return sta;
429} 433}
430 434
@@ -652,7 +656,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
652 } 656 }
653 if (pos[1] != 0 && 657 if (pos[1] != 0 &&
654 (pos[1] != ifibss->ssid_len || 658 (pos[1] != ifibss->ssid_len ||
655 !memcmp(pos + 2, ifibss->ssid, ifibss->ssid_len))) { 659 memcmp(pos + 2, ifibss->ssid, ifibss->ssid_len))) {
656 /* Ignore ProbeReq for foreign SSID */ 660 /* Ignore ProbeReq for foreign SSID */
657 return; 661 return;
658 } 662 }
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 3067fbd69d6..9dd98b674cb 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -316,6 +316,7 @@ enum ieee80211_sta_flags {
316 IEEE80211_STA_CSA_RECEIVED = BIT(5), 316 IEEE80211_STA_CSA_RECEIVED = BIT(5),
317 IEEE80211_STA_MFP_ENABLED = BIT(6), 317 IEEE80211_STA_MFP_ENABLED = BIT(6),
318 IEEE80211_STA_UAPSD_ENABLED = BIT(7), 318 IEEE80211_STA_UAPSD_ENABLED = BIT(7),
319 IEEE80211_STA_NULLFUNC_ACKED = BIT(8),
319}; 320};
320 321
321struct ieee80211_if_managed { 322struct ieee80211_if_managed {
@@ -688,15 +689,18 @@ struct ieee80211_local {
688 689
689 /* Station data */ 690 /* Station data */
690 /* 691 /*
691 * The lock only protects the list, hash, timer and counter 692 * The mutex only protects the list and counter,
692 * against manipulation, reads are done in RCU. Additionally, 693 * reads are done in RCU.
693 * the lock protects each BSS's TIM bitmap. 694 * Additionally, the lock protects the hash table,
695 * the pending list and each BSS's TIM bitmap.
694 */ 696 */
697 struct mutex sta_mtx;
695 spinlock_t sta_lock; 698 spinlock_t sta_lock;
696 unsigned long num_sta; 699 unsigned long num_sta;
697 struct list_head sta_list; 700 struct list_head sta_list, sta_pending_list;
698 struct sta_info *sta_hash[STA_HASH_SIZE]; 701 struct sta_info *sta_hash[STA_HASH_SIZE];
699 struct timer_list sta_cleanup; 702 struct timer_list sta_cleanup;
703 struct work_struct sta_finish_work;
700 int sta_generation; 704 int sta_generation;
701 705
702 struct sk_buff_head pending[IEEE80211_MAX_QUEUES]; 706 struct sk_buff_head pending[IEEE80211_MAX_QUEUES];
@@ -770,10 +774,6 @@ struct ieee80211_local {
770 assoc_led_name[32], radio_led_name[32]; 774 assoc_led_name[32], radio_led_name[32];
771#endif 775#endif
772 776
773#ifdef CONFIG_MAC80211_DEBUGFS
774 struct work_struct sta_debugfs_add;
775#endif
776
777#ifdef CONFIG_MAC80211_DEBUG_COUNTERS 777#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
778 /* TX/RX handler statistics */ 778 /* TX/RX handler statistics */
779 unsigned int tx_handlers_drop; 779 unsigned int tx_handlers_drop;
@@ -985,7 +985,8 @@ void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata);
985ieee80211_rx_result 985ieee80211_rx_result
986ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); 986ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
987struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, 987struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
988 u8 *bssid, u8 *addr, u32 supp_rates); 988 u8 *bssid, u8 *addr, u32 supp_rates,
989 gfp_t gfp);
989int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, 990int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
990 struct cfg80211_ibss_params *params); 991 struct cfg80211_ibss_params *params);
991int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata); 992int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 7985e515089..bc4e20e57ff 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -102,7 +102,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
102 if (local->num_sta >= MESH_MAX_PLINKS) 102 if (local->num_sta >= MESH_MAX_PLINKS)
103 return NULL; 103 return NULL;
104 104
105 sta = sta_info_alloc(sdata, hw_addr, GFP_ATOMIC); 105 sta = sta_info_alloc(sdata, hw_addr, GFP_KERNEL);
106 if (!sta) 106 if (!sta)
107 return NULL; 107 return NULL;
108 108
@@ -236,12 +236,12 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data
236 236
237 sta = sta_info_get(sdata, hw_addr); 237 sta = sta_info_get(sdata, hw_addr);
238 if (!sta) { 238 if (!sta) {
239 rcu_read_unlock();
240
239 sta = mesh_plink_alloc(sdata, hw_addr, rates); 241 sta = mesh_plink_alloc(sdata, hw_addr, rates);
240 if (!sta) { 242 if (!sta)
241 rcu_read_unlock();
242 return; 243 return;
243 } 244 if (sta_info_insert_rcu(sta)) {
244 if (sta_info_insert(sta)) {
245 rcu_read_unlock(); 245 rcu_read_unlock();
246 return; 246 return;
247 } 247 }
@@ -485,9 +485,11 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
485 } else if (!sta) { 485 } else if (!sta) {
486 /* ftype == PLINK_OPEN */ 486 /* ftype == PLINK_OPEN */
487 u32 rates; 487 u32 rates;
488
489 rcu_read_unlock();
490
488 if (!mesh_plink_free_count(sdata)) { 491 if (!mesh_plink_free_count(sdata)) {
489 mpl_dbg("Mesh plink error: no more free plinks\n"); 492 mpl_dbg("Mesh plink error: no more free plinks\n");
490 rcu_read_unlock();
491 return; 493 return;
492 } 494 }
493 495
@@ -495,10 +497,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
495 sta = mesh_plink_alloc(sdata, mgmt->sa, rates); 497 sta = mesh_plink_alloc(sdata, mgmt->sa, rates);
496 if (!sta) { 498 if (!sta) {
497 mpl_dbg("Mesh plink error: plink table full\n"); 499 mpl_dbg("Mesh plink error: plink table full\n");
498 rcu_read_unlock();
499 return; 500 return;
500 } 501 }
501 if (sta_info_insert(sta)) { 502 if (sta_info_insert_rcu(sta)) {
502 rcu_read_unlock(); 503 rcu_read_unlock();
503 return; 504 return;
504 } 505 }
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 86c6ad1b058..bfc4a507001 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -27,10 +27,6 @@
27#include "rate.h" 27#include "rate.h"
28#include "led.h" 28#include "led.h"
29 29
30#define IEEE80211_AUTH_TIMEOUT (HZ / 5)
31#define IEEE80211_AUTH_MAX_TRIES 3
32#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
33#define IEEE80211_ASSOC_MAX_TRIES 3
34#define IEEE80211_MAX_PROBE_TRIES 5 30#define IEEE80211_MAX_PROBE_TRIES 5
35 31
36/* 32/*
@@ -438,8 +434,11 @@ static void ieee80211_enable_ps(struct ieee80211_local *local,
438 } else { 434 } else {
439 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) 435 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
440 ieee80211_send_nullfunc(local, sdata, 1); 436 ieee80211_send_nullfunc(local, sdata, 1);
441 conf->flags |= IEEE80211_CONF_PS; 437
442 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 438 if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) {
439 conf->flags |= IEEE80211_CONF_PS;
440 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
441 }
443 } 442 }
444} 443}
445 444
@@ -545,6 +544,7 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
545 container_of(work, struct ieee80211_local, 544 container_of(work, struct ieee80211_local,
546 dynamic_ps_enable_work); 545 dynamic_ps_enable_work);
547 struct ieee80211_sub_if_data *sdata = local->ps_sdata; 546 struct ieee80211_sub_if_data *sdata = local->ps_sdata;
547 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
548 548
549 /* can only happen when PS was just disabled anyway */ 549 /* can only happen when PS was just disabled anyway */
550 if (!sdata) 550 if (!sdata)
@@ -553,11 +553,16 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
553 if (local->hw.conf.flags & IEEE80211_CONF_PS) 553 if (local->hw.conf.flags & IEEE80211_CONF_PS)
554 return; 554 return;
555 555
556 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) 556 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
557 (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)))
557 ieee80211_send_nullfunc(local, sdata, 1); 558 ieee80211_send_nullfunc(local, sdata, 1);
558 559
559 local->hw.conf.flags |= IEEE80211_CONF_PS; 560 if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) ||
560 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 561 (ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) {
562 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
563 local->hw.conf.flags |= IEEE80211_CONF_PS;
564 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
565 }
561} 566}
562 567
563void ieee80211_dynamic_ps_timer(unsigned long data) 568void ieee80211_dynamic_ps_timer(unsigned long data)
@@ -792,8 +797,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata)
792 797
793 rcu_read_lock(); 798 rcu_read_lock();
794 sta = sta_info_get(sdata, bssid); 799 sta = sta_info_get(sdata, bssid);
795 if (sta) 800 if (sta) {
801 set_sta_flags(sta, WLAN_STA_DISASSOC);
796 ieee80211_sta_tear_down_BA_sessions(sta); 802 ieee80211_sta_tear_down_BA_sessions(sta);
803 }
797 rcu_read_unlock(); 804 rcu_read_unlock();
798 805
799 changed |= ieee80211_reset_erp_info(sdata); 806 changed |= ieee80211_reset_erp_info(sdata);
@@ -826,19 +833,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata)
826 changed |= BSS_CHANGED_BSSID; 833 changed |= BSS_CHANGED_BSSID;
827 ieee80211_bss_info_change_notify(sdata, changed); 834 ieee80211_bss_info_change_notify(sdata, changed);
828 835
829 rcu_read_lock(); 836 sta_info_destroy_addr(sdata, bssid);
830
831 sta = sta_info_get(sdata, bssid);
832 if (!sta) {
833 rcu_read_unlock();
834 return;
835 }
836
837 sta_info_unlink(&sta);
838
839 rcu_read_unlock();
840
841 sta_info_destroy(sta);
842} 837}
843 838
844void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 839void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
@@ -1844,7 +1839,11 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
1844 wk->probe_auth.algorithm = auth_alg; 1839 wk->probe_auth.algorithm = auth_alg;
1845 wk->probe_auth.privacy = req->bss->capability & WLAN_CAPABILITY_PRIVACY; 1840 wk->probe_auth.privacy = req->bss->capability & WLAN_CAPABILITY_PRIVACY;
1846 1841
1847 wk->type = IEEE80211_WORK_DIRECT_PROBE; 1842 /* if we already have a probe, don't probe again */
1843 if (req->bss->proberesp_ies)
1844 wk->type = IEEE80211_WORK_AUTH;
1845 else
1846 wk->type = IEEE80211_WORK_DIRECT_PROBE;
1848 wk->chan = req->bss->channel; 1847 wk->chan = req->bss->channel;
1849 wk->sdata = sdata; 1848 wk->sdata = sdata;
1850 wk->done = ieee80211_probe_auth_done; 1849 wk->done = ieee80211_probe_auth_done;
@@ -1904,6 +1903,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
1904 return -ENOMEM; 1903 return -ENOMEM;
1905 1904
1906 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; 1905 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
1906 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
1907 1907
1908 for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) 1908 for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
1909 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || 1909 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
@@ -2007,12 +2007,18 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2007 2007
2008 mutex_lock(&local->work_mtx); 2008 mutex_lock(&local->work_mtx);
2009 list_for_each_entry(wk, &local->work_list, list) { 2009 list_for_each_entry(wk, &local->work_list, list) {
2010 if (wk->type != IEEE80211_WORK_DIRECT_PROBE) 2010 if (wk->sdata != sdata)
2011 continue;
2012
2013 if (wk->type != IEEE80211_WORK_DIRECT_PROBE &&
2014 wk->type != IEEE80211_WORK_AUTH)
2011 continue; 2015 continue;
2016
2012 if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN)) 2017 if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN))
2013 continue; 2018 continue;
2014 not_auth_yet = true; 2019
2015 list_del(&wk->list); 2020 not_auth_yet = wk->type == IEEE80211_WORK_DIRECT_PROBE;
2021 list_del_rcu(&wk->list);
2016 free_work(wk); 2022 free_work(wk);
2017 break; 2023 break;
2018 } 2024 }
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 47f818959ad..0e64484e861 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -11,7 +11,6 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
11 struct ieee80211_local *local = hw_to_local(hw); 11 struct ieee80211_local *local = hw_to_local(hw);
12 struct ieee80211_sub_if_data *sdata; 12 struct ieee80211_sub_if_data *sdata;
13 struct sta_info *sta; 13 struct sta_info *sta;
14 unsigned long flags;
15 14
16 ieee80211_scan_cancel(local); 15 ieee80211_scan_cancel(local);
17 16
@@ -55,22 +54,21 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
55 rcu_read_unlock(); 54 rcu_read_unlock();
56 55
57 /* remove STAs */ 56 /* remove STAs */
58 spin_lock_irqsave(&local->sta_lock, flags); 57 mutex_lock(&local->sta_mtx);
59 list_for_each_entry(sta, &local->sta_list, list) { 58 list_for_each_entry(sta, &local->sta_list, list) {
60 if (local->ops->sta_notify) { 59 if (sta->uploaded) {
61 sdata = sta->sdata; 60 sdata = sta->sdata;
62 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 61 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
63 sdata = container_of(sdata->bss, 62 sdata = container_of(sdata->bss,
64 struct ieee80211_sub_if_data, 63 struct ieee80211_sub_if_data,
65 u.ap); 64 u.ap);
66 65
67 drv_sta_notify(local, sdata, STA_NOTIFY_REMOVE, 66 drv_sta_remove(local, sdata, &sta->sta);
68 &sta->sta);
69 } 67 }
70 68
71 mesh_plink_quiesce(sta); 69 mesh_plink_quiesce(sta);
72 } 70 }
73 spin_unlock_irqrestore(&local->sta_lock, flags); 71 mutex_unlock(&local->sta_mtx);
74 72
75 /* remove all interfaces */ 73 /* remove all interfaces */
76 list_for_each_entry(sdata, &local->interfaces, list) { 74 list_for_each_entry(sdata, &local->interfaces, list) {
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index c74b7c85403..99ab24cc978 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -145,7 +145,7 @@ static const struct file_operations rcname_ops = {
145}; 145};
146#endif 146#endif
147 147
148struct rate_control_ref *rate_control_alloc(const char *name, 148static struct rate_control_ref *rate_control_alloc(const char *name,
149 struct ieee80211_local *local) 149 struct ieee80211_local *local)
150{ 150{
151 struct dentry *debugfsdir = NULL; 151 struct dentry *debugfsdir = NULL;
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index 998cf7a935b..b6108bca96d 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -26,10 +26,6 @@ struct rate_control_ref {
26 struct kref kref; 26 struct kref kref;
27}; 27};
28 28
29/* Get a reference to the rate control algorithm. If `name' is NULL, get the
30 * first available algorithm. */
31struct rate_control_ref *rate_control_alloc(const char *name,
32 struct ieee80211_local *local);
33void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, 29void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
34 struct sta_info *sta, 30 struct sta_info *sta,
35 struct ieee80211_tx_rate_control *txrc); 31 struct ieee80211_tx_rate_control *txrc);
@@ -116,7 +112,8 @@ static inline void rate_control_remove_sta_debugfs(struct sta_info *sta)
116#endif 112#endif
117} 113}
118 114
119/* functions for rate control related to a device */ 115/* Get a reference to the rate control algorithm. If `name' is NULL, get the
116 * first available algorithm. */
120int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, 117int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
121 const char *name); 118 const char *name);
122void rate_control_deinitialize(struct ieee80211_local *local); 119void rate_control_deinitialize(struct ieee80211_local *local);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 5709307fcb9..c9755f3d986 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1719,6 +1719,7 @@ static ieee80211_rx_result debug_noinline
1719ieee80211_rx_h_data(struct ieee80211_rx_data *rx) 1719ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
1720{ 1720{
1721 struct ieee80211_sub_if_data *sdata = rx->sdata; 1721 struct ieee80211_sub_if_data *sdata = rx->sdata;
1722 struct ieee80211_local *local = rx->local;
1722 struct net_device *dev = sdata->dev; 1723 struct net_device *dev = sdata->dev;
1723 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 1724 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
1724 __le16 fc = hdr->frame_control; 1725 __le16 fc = hdr->frame_control;
@@ -1750,6 +1751,13 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
1750 dev->stats.rx_packets++; 1751 dev->stats.rx_packets++;
1751 dev->stats.rx_bytes += rx->skb->len; 1752 dev->stats.rx_bytes += rx->skb->len;
1752 1753
1754 if (ieee80211_is_data(hdr->frame_control) &&
1755 !is_multicast_ether_addr(hdr->addr1) &&
1756 local->hw.conf.dynamic_ps_timeout > 0 && local->ps_sdata) {
1757 mod_timer(&local->dynamic_ps_timer, jiffies +
1758 msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
1759 }
1760
1753 ieee80211_deliver_skb(rx); 1761 ieee80211_deliver_skb(rx);
1754 1762
1755 return RX_QUEUED; 1763 return RX_QUEUED;
@@ -2244,8 +2252,8 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
2244 rate_idx = 0; /* TODO: HT rates */ 2252 rate_idx = 0; /* TODO: HT rates */
2245 else 2253 else
2246 rate_idx = status->rate_idx; 2254 rate_idx = status->rate_idx;
2247 rx->sta = ieee80211_ibss_add_sta(sdata, bssid, hdr->addr2, 2255 rx->sta = ieee80211_ibss_add_sta(sdata, bssid,
2248 BIT(rate_idx)); 2256 hdr->addr2, BIT(rate_idx), GFP_ATOMIC);
2249 } 2257 }
2250 break; 2258 break;
2251 case NL80211_IFTYPE_MESH_POINT: 2259 case NL80211_IFTYPE_MESH_POINT:
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index bc061f62967..b822dce9786 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -345,6 +345,13 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
345 if (local->scan_req) 345 if (local->scan_req)
346 return -EBUSY; 346 return -EBUSY;
347 347
348 if (!list_empty(&local->work_list)) {
349 /* wait for the work to finish/time out */
350 local->scan_req = req;
351 local->scan_sdata = sdata;
352 return 0;
353 }
354
348 if (local->ops->hw_scan) { 355 if (local->ops->hw_scan) {
349 u8 *ies; 356 u8 *ies;
350 357
@@ -364,29 +371,33 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
364 local->hw_scan_req->ie = ies; 371 local->hw_scan_req->ie = ies;
365 372
366 local->hw_scan_band = 0; 373 local->hw_scan_band = 0;
374
375 /*
376 * After allocating local->hw_scan_req, we must
377 * go through until ieee80211_prep_hw_scan(), so
378 * anything that might be changed here and leave
379 * this function early must not go after this
380 * allocation.
381 */
367 } 382 }
368 383
369 local->scan_req = req; 384 local->scan_req = req;
370 local->scan_sdata = sdata; 385 local->scan_sdata = sdata;
371 386
372 if (!list_empty(&local->work_list)) {
373 /* wait for the work to finish/time out */
374 return 0;
375 }
376
377 if (local->ops->hw_scan) 387 if (local->ops->hw_scan)
378 __set_bit(SCAN_HW_SCANNING, &local->scanning); 388 __set_bit(SCAN_HW_SCANNING, &local->scanning);
379 else 389 else
380 __set_bit(SCAN_SW_SCANNING, &local->scanning); 390 __set_bit(SCAN_SW_SCANNING, &local->scanning);
391
381 /* 392 /*
382 * Kicking off the scan need not be protected, 393 * Kicking off the scan need not be protected,
383 * only the scan variable stuff, since now 394 * only the scan variable stuff, since now
384 * local->scan_req is assigned and other callers 395 * local->scan_req is assigned and other callers
385 * will abort their scan attempts. 396 * will abort their scan attempts.
386 * 397 *
387 * This avoids getting a scan_mtx -> iflist_mtx 398 * This avoids too many locking dependencies
388 * dependency, so that the scan completed calls 399 * so that the scan completed calls have more
389 * have more locking freedom. 400 * locking freedom.
390 */ 401 */
391 402
392 ieee80211_recalc_idle(local); 403 ieee80211_recalc_idle(local);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index f735826f055..211c475f73c 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -32,49 +32,33 @@
32 * for faster lookup and a list for iteration. They are managed using 32 * for faster lookup and a list for iteration. They are managed using
33 * RCU, i.e. access to the list and hash table is protected by RCU. 33 * RCU, i.e. access to the list and hash table is protected by RCU.
34 * 34 *
35 * Upon allocating a STA info structure with sta_info_alloc(), the caller owns 35 * Upon allocating a STA info structure with sta_info_alloc(), the caller
36 * that structure. It must then either destroy it using sta_info_destroy() 36 * owns that structure. It must then insert it into the hash table using
37 * (which is pretty useless) or insert it into the hash table using 37 * either sta_info_insert() or sta_info_insert_rcu(); only in the latter
38 * sta_info_insert() which demotes the reference from ownership to a regular 38 * case (which acquires an rcu read section but must not be called from
39 * RCU-protected reference; if the function is called without protection by an 39 * within one) will the pointer still be valid after the call. Note that
40 * RCU critical section the reference is instantly invalidated. Note that the 40 * the caller may not do much with the STA info before inserting it, in
41 * caller may not do much with the STA info before inserting it, in particular, 41 * particular, it may not start any mesh peer link management or add
42 * it may not start any mesh peer link management or add encryption keys. 42 * encryption keys.
43 * 43 *
44 * When the insertion fails (sta_info_insert()) returns non-zero), the 44 * When the insertion fails (sta_info_insert()) returns non-zero), the
45 * structure will have been freed by sta_info_insert()! 45 * structure will have been freed by sta_info_insert()!
46 * 46 *
47 * sta entries are added by mac80211 when you establish a link with a 47 * Station entries are added by mac80211 when you establish a link with a
48 * peer. This means different things for the different type of interfaces 48 * peer. This means different things for the different type of interfaces
49 * we support. For a regular station this mean we add the AP sta when we 49 * we support. For a regular station this mean we add the AP sta when we
50 * receive an assocation response from the AP. For IBSS this occurs when 50 * receive an assocation response from the AP. For IBSS this occurs when
51 * we receive a probe response or a beacon from target IBSS network. For 51 * get to know about a peer on the same IBSS. For WDS we add the sta for
52 * WDS we add the sta for the peer imediately upon device open. When using 52 * the peer imediately upon device open. When using AP mode we add stations
53 * AP mode we add stations for each respective station upon request from 53 * for each respective station upon request from userspace through nl80211.
54 * userspace through nl80211.
55 * 54 *
56 * Because there are debugfs entries for each station, and adding those 55 * In order to remove a STA info structure, various sta_info_destroy_*()
57 * must be able to sleep, it is also possible to "pin" a station entry, 56 * calls are available.
58 * that means it can be removed from the hash table but not be freed.
59 * See the comment in __sta_info_unlink() for more information, this is
60 * an internal capability only.
61 * 57 *
62 * In order to remove a STA info structure, the caller needs to first 58 * There is no concept of ownership on a STA entry, each structure is
63 * unlink it (sta_info_unlink()) from the list and hash tables and 59 * owned by the global hash table/list until it is removed. All users of
64 * then destroy it; sta_info_destroy() will wait for an RCU grace period 60 * the structure need to be RCU protected so that the structure won't be
65 * to elapse before actually freeing it. Due to the pinning and the 61 * freed before they are done using it.
66 * possibility of multiple callers trying to remove the same STA info at
67 * the same time, sta_info_unlink() can clear the STA info pointer it is
68 * passed to indicate that the STA info is owned by somebody else now.
69 *
70 * If sta_info_unlink() did not clear the pointer then the caller owns
71 * the STA info structure now and is responsible of destroying it with
72 * a call to sta_info_destroy().
73 *
74 * In all other cases, there is no concept of ownership on a STA entry,
75 * each structure is owned by the global hash table/list until it is
76 * removed. All users of the structure need to be RCU protected so that
77 * the structure won't be freed before they are done using it.
78 */ 62 */
79 63
80/* Caller must hold local->sta_lock */ 64/* Caller must hold local->sta_lock */
@@ -185,101 +169,6 @@ static void __sta_info_free(struct ieee80211_local *local,
185 kfree(sta); 169 kfree(sta);
186} 170}
187 171
188void sta_info_destroy(struct sta_info *sta)
189{
190 struct ieee80211_local *local;
191 struct sk_buff *skb;
192 int i;
193
194 might_sleep();
195
196 if (!sta)
197 return;
198
199 local = sta->local;
200
201 cancel_work_sync(&sta->drv_unblock_wk);
202
203 rate_control_remove_sta_debugfs(sta);
204 ieee80211_sta_debugfs_remove(sta);
205
206#ifdef CONFIG_MAC80211_MESH
207 if (ieee80211_vif_is_mesh(&sta->sdata->vif))
208 mesh_plink_deactivate(sta);
209#endif
210
211 /*
212 * We have only unlinked the key, and actually destroying it
213 * may mean it is removed from hardware which requires that
214 * the key->sta pointer is still valid, so flush the key todo
215 * list here.
216 *
217 * ieee80211_key_todo() will synchronize_rcu() so after this
218 * nothing can reference this sta struct any more.
219 */
220 ieee80211_key_todo();
221
222#ifdef CONFIG_MAC80211_MESH
223 if (ieee80211_vif_is_mesh(&sta->sdata->vif))
224 del_timer_sync(&sta->plink_timer);
225#endif
226
227 while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) {
228 local->total_ps_buffered--;
229 dev_kfree_skb_any(skb);
230 }
231
232 while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL)
233 dev_kfree_skb_any(skb);
234
235 for (i = 0; i < STA_TID_NUM; i++) {
236 struct tid_ampdu_rx *tid_rx;
237 struct tid_ampdu_tx *tid_tx;
238
239 spin_lock_bh(&sta->lock);
240 tid_rx = sta->ampdu_mlme.tid_rx[i];
241 /* Make sure timer won't free the tid_rx struct, see below */
242 if (tid_rx)
243 tid_rx->shutdown = true;
244
245 spin_unlock_bh(&sta->lock);
246
247 /*
248 * Outside spinlock - shutdown is true now so that the timer
249 * won't free tid_rx, we have to do that now. Can't let the
250 * timer do it because we have to sync the timer outside the
251 * lock that it takes itself.
252 */
253 if (tid_rx) {
254 del_timer_sync(&tid_rx->session_timer);
255 kfree(tid_rx);
256 }
257
258 /*
259 * No need to do such complications for TX agg sessions, the
260 * path leading to freeing the tid_tx struct goes via a call
261 * from the driver, and thus needs to look up the sta struct
262 * again, which cannot be found when we get here. Hence, we
263 * just need to delete the timer and free the aggregation
264 * info; we won't be telling the peer about it then but that
265 * doesn't matter if we're not talking to it again anyway.
266 */
267 tid_tx = sta->ampdu_mlme.tid_tx[i];
268 if (tid_tx) {
269 del_timer_sync(&tid_tx->addba_resp_timer);
270 /*
271 * STA removed while aggregation session being
272 * started? Bit odd, but purge frames anyway.
273 */
274 skb_queue_purge(&tid_tx->pending);
275 kfree(tid_tx);
276 }
277 }
278
279 __sta_info_free(local, sta);
280}
281
282
283/* Caller must hold local->sta_lock */ 172/* Caller must hold local->sta_lock */
284static void sta_info_hash_add(struct ieee80211_local *local, 173static void sta_info_hash_add(struct ieee80211_local *local,
285 struct sta_info *sta) 174 struct sta_info *sta)
@@ -376,7 +265,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
376 return sta; 265 return sta;
377} 266}
378 267
379int sta_info_insert(struct sta_info *sta) 268static int sta_info_finish_insert(struct sta_info *sta, bool async)
380{ 269{
381 struct ieee80211_local *local = sta->local; 270 struct ieee80211_local *local = sta->local;
382 struct ieee80211_sub_if_data *sdata = sta->sdata; 271 struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -384,6 +273,91 @@ int sta_info_insert(struct sta_info *sta)
384 unsigned long flags; 273 unsigned long flags;
385 int err = 0; 274 int err = 0;
386 275
276 WARN_ON(!mutex_is_locked(&local->sta_mtx));
277
278 /* notify driver */
279 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
280 sdata = container_of(sdata->bss,
281 struct ieee80211_sub_if_data,
282 u.ap);
283 err = drv_sta_add(local, sdata, &sta->sta);
284 if (err) {
285 if (!async)
286 return err;
287 printk(KERN_DEBUG "%s: failed to add IBSS STA %pM to driver (%d)"
288 " - keeping it anyway.\n",
289 sdata->name, sta->sta.addr, err);
290 } else {
291 sta->uploaded = true;
292#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
293 if (async)
294 printk(KERN_DEBUG "%s: Finished adding IBSS STA %pM\n",
295 wiphy_name(local->hw.wiphy), sta->sta.addr);
296#endif
297 }
298
299 sdata = sta->sdata;
300
301 if (!async) {
302 local->num_sta++;
303 local->sta_generation++;
304 smp_mb();
305
306 /* make the station visible */
307 spin_lock_irqsave(&local->sta_lock, flags);
308 sta_info_hash_add(local, sta);
309 spin_unlock_irqrestore(&local->sta_lock, flags);
310 }
311
312 list_add(&sta->list, &local->sta_list);
313
314 ieee80211_sta_debugfs_add(sta);
315 rate_control_add_sta_debugfs(sta);
316
317 sinfo.filled = 0;
318 sinfo.generation = local->sta_generation;
319 cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
320
321
322 return 0;
323}
324
325static void sta_info_finish_pending(struct ieee80211_local *local)
326{
327 struct sta_info *sta;
328 unsigned long flags;
329
330 spin_lock_irqsave(&local->sta_lock, flags);
331 while (!list_empty(&local->sta_pending_list)) {
332 sta = list_first_entry(&local->sta_pending_list,
333 struct sta_info, list);
334 list_del(&sta->list);
335 spin_unlock_irqrestore(&local->sta_lock, flags);
336
337 sta_info_finish_insert(sta, true);
338
339 spin_lock_irqsave(&local->sta_lock, flags);
340 }
341 spin_unlock_irqrestore(&local->sta_lock, flags);
342}
343
344static void sta_info_finish_work(struct work_struct *work)
345{
346 struct ieee80211_local *local =
347 container_of(work, struct ieee80211_local, sta_finish_work);
348
349 mutex_lock(&local->sta_mtx);
350 sta_info_finish_pending(local);
351 mutex_unlock(&local->sta_mtx);
352}
353
354int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU)
355{
356 struct ieee80211_local *local = sta->local;
357 struct ieee80211_sub_if_data *sdata = sta->sdata;
358 unsigned long flags;
359 int err = 0;
360
387 /* 361 /*
388 * Can't be a WARN_ON because it can be triggered through a race: 362 * Can't be a WARN_ON because it can be triggered through a race:
389 * something inserts a STA (on one CPU) without holding the RTNL 363 * something inserts a STA (on one CPU) without holding the RTNL
@@ -391,36 +365,87 @@ int sta_info_insert(struct sta_info *sta)
391 */ 365 */
392 if (unlikely(!ieee80211_sdata_running(sdata))) { 366 if (unlikely(!ieee80211_sdata_running(sdata))) {
393 err = -ENETDOWN; 367 err = -ENETDOWN;
368 rcu_read_lock();
394 goto out_free; 369 goto out_free;
395 } 370 }
396 371
397 if (WARN_ON(compare_ether_addr(sta->sta.addr, sdata->vif.addr) == 0 || 372 if (WARN_ON(compare_ether_addr(sta->sta.addr, sdata->vif.addr) == 0 ||
398 is_multicast_ether_addr(sta->sta.addr))) { 373 is_multicast_ether_addr(sta->sta.addr))) {
399 err = -EINVAL; 374 err = -EINVAL;
375 rcu_read_lock();
400 goto out_free; 376 goto out_free;
401 } 377 }
402 378
379 /*
380 * In ad-hoc mode, we sometimes need to insert stations
381 * from tasklet context from the RX path. To avoid races,
382 * always do so in that case -- see the comment below.
383 */
384 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
385 spin_lock_irqsave(&local->sta_lock, flags);
386 /* check if STA exists already */
387 if (sta_info_get_bss(sdata, sta->sta.addr)) {
388 spin_unlock_irqrestore(&local->sta_lock, flags);
389 rcu_read_lock();
390 err = -EEXIST;
391 goto out_free;
392 }
393
394 local->num_sta++;
395 local->sta_generation++;
396 smp_mb();
397 sta_info_hash_add(local, sta);
398
399 list_add_tail(&sta->list, &local->sta_pending_list);
400
401 rcu_read_lock();
402 spin_unlock_irqrestore(&local->sta_lock, flags);
403
404#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
405 printk(KERN_DEBUG "%s: Added IBSS STA %pM\n",
406 wiphy_name(local->hw.wiphy), sta->sta.addr);
407#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
408
409 ieee80211_queue_work(&local->hw, &local->sta_finish_work);
410
411 return 0;
412 }
413
414 /*
415 * On first glance, this will look racy, because the code
416 * below this point, which inserts a station with sleeping,
417 * unlocks the sta_lock between checking existence in the
418 * hash table and inserting into it.
419 *
420 * However, it is not racy against itself because it keeps
421 * the mutex locked. It still seems to race against the
422 * above code that atomically inserts the station... That,
423 * however, is not true because the above code can only
424 * be invoked for IBSS interfaces, and the below code will
425 * not be -- and the two do not race against each other as
426 * the hash table also keys off the interface.
427 */
428
429 might_sleep();
430
431 mutex_lock(&local->sta_mtx);
432
403 spin_lock_irqsave(&local->sta_lock, flags); 433 spin_lock_irqsave(&local->sta_lock, flags);
404 /* check if STA exists already */ 434 /* check if STA exists already */
405 if (sta_info_get(sdata, sta->sta.addr)) { 435 if (sta_info_get_bss(sdata, sta->sta.addr)) {
406 spin_unlock_irqrestore(&local->sta_lock, flags); 436 spin_unlock_irqrestore(&local->sta_lock, flags);
437 rcu_read_lock();
407 err = -EEXIST; 438 err = -EEXIST;
408 goto out_free; 439 goto out_free;
409 } 440 }
410 list_add(&sta->list, &local->sta_list);
411 local->sta_generation++;
412 local->num_sta++;
413 sta_info_hash_add(local, sta);
414 441
415 /* notify driver */ 442 spin_unlock_irqrestore(&local->sta_lock, flags);
416 if (local->ops->sta_notify) {
417 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
418 sdata = container_of(sdata->bss,
419 struct ieee80211_sub_if_data,
420 u.ap);
421 443
422 drv_sta_notify(local, sdata, STA_NOTIFY_ADD, &sta->sta); 444 err = sta_info_finish_insert(sta, false);
423 sdata = sta->sdata; 445 if (err) {
446 mutex_unlock(&local->sta_mtx);
447 rcu_read_lock();
448 goto out_free;
424 } 449 }
425 450
426#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 451#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -428,22 +453,9 @@ int sta_info_insert(struct sta_info *sta)
428 wiphy_name(local->hw.wiphy), sta->sta.addr); 453 wiphy_name(local->hw.wiphy), sta->sta.addr);
429#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 454#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
430 455
431 spin_unlock_irqrestore(&local->sta_lock, flags); 456 /* move reference to rcu-protected */
432 457 rcu_read_lock();
433 sinfo.filled = 0; 458 mutex_unlock(&local->sta_mtx);
434 sinfo.generation = local->sta_generation;
435 cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_ATOMIC);
436
437#ifdef CONFIG_MAC80211_DEBUGFS
438 /*
439 * Debugfs entry adding might sleep, so schedule process
440 * context task for adding entry for STAs that do not yet
441 * have one.
442 * NOTE: due to auto-freeing semantics this may only be done
443 * if the insertion is successful!
444 */
445 schedule_work(&local->sta_debugfs_add);
446#endif
447 459
448 if (ieee80211_vif_is_mesh(&sdata->vif)) 460 if (ieee80211_vif_is_mesh(&sdata->vif))
449 mesh_accept_plinks_update(sdata); 461 mesh_accept_plinks_update(sdata);
@@ -455,6 +467,15 @@ int sta_info_insert(struct sta_info *sta)
455 return err; 467 return err;
456} 468}
457 469
470int sta_info_insert(struct sta_info *sta)
471{
472 int err = sta_info_insert_rcu(sta);
473
474 rcu_read_unlock();
475
476 return err;
477}
478
458static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) 479static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid)
459{ 480{
460 /* 481 /*
@@ -523,108 +544,6 @@ void sta_info_clear_tim_bit(struct sta_info *sta)
523 spin_unlock_irqrestore(&sta->local->sta_lock, flags); 544 spin_unlock_irqrestore(&sta->local->sta_lock, flags);
524} 545}
525 546
526static void __sta_info_unlink(struct sta_info **sta)
527{
528 struct ieee80211_local *local = (*sta)->local;
529 struct ieee80211_sub_if_data *sdata = (*sta)->sdata;
530 /*
531 * pull caller's reference if we're already gone.
532 */
533 if (sta_info_hash_del(local, *sta)) {
534 *sta = NULL;
535 return;
536 }
537
538 if ((*sta)->key) {
539 ieee80211_key_free((*sta)->key);
540 WARN_ON((*sta)->key);
541 }
542
543 list_del(&(*sta)->list);
544 (*sta)->dead = true;
545
546 if (test_and_clear_sta_flags(*sta,
547 WLAN_STA_PS_STA | WLAN_STA_PS_DRIVER)) {
548 BUG_ON(!sdata->bss);
549
550 atomic_dec(&sdata->bss->num_sta_ps);
551 __sta_info_clear_tim_bit(sdata->bss, *sta);
552 }
553
554 local->num_sta--;
555 local->sta_generation++;
556
557 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
558 rcu_assign_pointer(sdata->u.vlan.sta, NULL);
559
560 if (local->ops->sta_notify) {
561 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
562 sdata = container_of(sdata->bss,
563 struct ieee80211_sub_if_data,
564 u.ap);
565
566 drv_sta_notify(local, sdata, STA_NOTIFY_REMOVE,
567 &(*sta)->sta);
568 sdata = (*sta)->sdata;
569 }
570
571 if (ieee80211_vif_is_mesh(&sdata->vif)) {
572 mesh_accept_plinks_update(sdata);
573#ifdef CONFIG_MAC80211_MESH
574 del_timer(&(*sta)->plink_timer);
575#endif
576 }
577
578#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
579 printk(KERN_DEBUG "%s: Removed STA %pM\n",
580 wiphy_name(local->hw.wiphy), (*sta)->sta.addr);
581#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
582
583 /*
584 * Finally, pull caller's reference if the STA is pinned by the
585 * task that is adding the debugfs entries. In that case, we
586 * leave the STA "to be freed".
587 *
588 * The rules are not trivial, but not too complex either:
589 * (1) pin_status is only modified under the sta_lock
590 * (2) STAs may only be pinned under the RTNL so that
591 * sta_info_flush() is guaranteed to actually destroy
592 * all STAs that are active for a given interface, this
593 * is required for correctness because otherwise we
594 * could notify a driver that an interface is going
595 * away and only after that (!) notify it about a STA
596 * on that interface going away.
597 * (3) sta_info_debugfs_add_work() will set the status
598 * to PINNED when it found an item that needs a new
599 * debugfs directory created. In that case, that item
600 * must not be freed although all *RCU* users are done
601 * with it. Hence, we tell the caller of _unlink()
602 * that the item is already gone (as can happen when
603 * two tasks try to unlink/destroy at the same time)
604 * (4) We set the pin_status to DESTROY here when we
605 * find such an item.
606 * (5) sta_info_debugfs_add_work() will reset the pin_status
607 * from PINNED to NORMAL when it is done with the item,
608 * but will check for DESTROY before resetting it in
609 * which case it will free the item.
610 */
611 if ((*sta)->pin_status == STA_INFO_PIN_STAT_PINNED) {
612 (*sta)->pin_status = STA_INFO_PIN_STAT_DESTROY;
613 *sta = NULL;
614 return;
615 }
616}
617
618void sta_info_unlink(struct sta_info **sta)
619{
620 struct ieee80211_local *local = (*sta)->local;
621 unsigned long flags;
622
623 spin_lock_irqsave(&local->sta_lock, flags);
624 __sta_info_unlink(sta);
625 spin_unlock_irqrestore(&local->sta_lock, flags);
626}
627
628static int sta_info_buffer_expired(struct sta_info *sta, 547static int sta_info_buffer_expired(struct sta_info *sta,
629 struct sk_buff *skb) 548 struct sk_buff *skb)
630{ 549{
@@ -681,109 +600,209 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
681 } 600 }
682} 601}
683 602
684 603static int __must_check __sta_info_destroy(struct sta_info *sta)
685static void sta_info_cleanup(unsigned long data)
686{ 604{
687 struct ieee80211_local *local = (struct ieee80211_local *) data; 605 struct ieee80211_local *local;
688 struct sta_info *sta; 606 struct ieee80211_sub_if_data *sdata;
607 struct sk_buff *skb;
608 unsigned long flags;
609 int ret, i;
689 610
690 rcu_read_lock(); 611 might_sleep();
691 list_for_each_entry_rcu(sta, &local->sta_list, list)
692 sta_info_cleanup_expire_buffered(local, sta);
693 rcu_read_unlock();
694 612
695 if (local->quiescing) 613 if (!sta)
696 return; 614 return -ENOENT;
697 615
698 local->sta_cleanup.expires = 616 local = sta->local;
699 round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); 617 sdata = sta->sdata;
700 add_timer(&local->sta_cleanup);
701}
702 618
703#ifdef CONFIG_MAC80211_DEBUGFS 619 spin_lock_irqsave(&local->sta_lock, flags);
704/* 620 ret = sta_info_hash_del(local, sta);
705 * See comment in __sta_info_unlink, 621 /* this might still be the pending list ... which is fine */
706 * caller must hold local->sta_lock. 622 if (!ret)
707 */ 623 list_del(&sta->list);
708static void __sta_info_pin(struct sta_info *sta) 624 spin_unlock_irqrestore(&local->sta_lock, flags);
709{ 625 if (ret)
710 WARN_ON(sta->pin_status != STA_INFO_PIN_STAT_NORMAL); 626 return ret;
711 sta->pin_status = STA_INFO_PIN_STAT_PINNED; 627
628 if (sta->key) {
629 ieee80211_key_free(sta->key);
630 /*
631 * We have only unlinked the key, and actually destroying it
632 * may mean it is removed from hardware which requires that
633 * the key->sta pointer is still valid, so flush the key todo
634 * list here.
635 *
636 * ieee80211_key_todo() will synchronize_rcu() so after this
637 * nothing can reference this sta struct any more.
638 */
639 ieee80211_key_todo();
640
641 WARN_ON(sta->key);
642 }
643
644 sta->dead = true;
645
646 if (test_and_clear_sta_flags(sta,
647 WLAN_STA_PS_STA | WLAN_STA_PS_DRIVER)) {
648 BUG_ON(!sdata->bss);
649
650 atomic_dec(&sdata->bss->num_sta_ps);
651 __sta_info_clear_tim_bit(sdata->bss, sta);
652 }
653
654 local->num_sta--;
655 local->sta_generation++;
656
657 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
658 rcu_assign_pointer(sdata->u.vlan.sta, NULL);
659
660 if (sta->uploaded) {
661 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
662 sdata = container_of(sdata->bss,
663 struct ieee80211_sub_if_data,
664 u.ap);
665 drv_sta_remove(local, sdata, &sta->sta);
666 sdata = sta->sdata;
667 }
668
669#ifdef CONFIG_MAC80211_MESH
670 if (ieee80211_vif_is_mesh(&sdata->vif)) {
671 mesh_accept_plinks_update(sdata);
672 del_timer(&sta->plink_timer);
673 }
674#endif
675
676#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
677 printk(KERN_DEBUG "%s: Removed STA %pM\n",
678 wiphy_name(local->hw.wiphy), sta->sta.addr);
679#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
680 cancel_work_sync(&sta->drv_unblock_wk);
681
682 rate_control_remove_sta_debugfs(sta);
683 ieee80211_sta_debugfs_remove(sta);
684
685#ifdef CONFIG_MAC80211_MESH
686 if (ieee80211_vif_is_mesh(&sta->sdata->vif)) {
687 mesh_plink_deactivate(sta);
688 del_timer_sync(&sta->plink_timer);
689 }
690#endif
691
692 while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) {
693 local->total_ps_buffered--;
694 dev_kfree_skb_any(skb);
695 }
696
697 while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL)
698 dev_kfree_skb_any(skb);
699
700 for (i = 0; i < STA_TID_NUM; i++) {
701 struct tid_ampdu_rx *tid_rx;
702 struct tid_ampdu_tx *tid_tx;
703
704 spin_lock_bh(&sta->lock);
705 tid_rx = sta->ampdu_mlme.tid_rx[i];
706 /* Make sure timer won't free the tid_rx struct, see below */
707 if (tid_rx)
708 tid_rx->shutdown = true;
709
710 spin_unlock_bh(&sta->lock);
711
712 /*
713 * Outside spinlock - shutdown is true now so that the timer
714 * won't free tid_rx, we have to do that now. Can't let the
715 * timer do it because we have to sync the timer outside the
716 * lock that it takes itself.
717 */
718 if (tid_rx) {
719 del_timer_sync(&tid_rx->session_timer);
720 kfree(tid_rx);
721 }
722
723 /*
724 * No need to do such complications for TX agg sessions, the
725 * path leading to freeing the tid_tx struct goes via a call
726 * from the driver, and thus needs to look up the sta struct
727 * again, which cannot be found when we get here. Hence, we
728 * just need to delete the timer and free the aggregation
729 * info; we won't be telling the peer about it then but that
730 * doesn't matter if we're not talking to it again anyway.
731 */
732 tid_tx = sta->ampdu_mlme.tid_tx[i];
733 if (tid_tx) {
734 del_timer_sync(&tid_tx->addba_resp_timer);
735 /*
736 * STA removed while aggregation session being
737 * started? Bit odd, but purge frames anyway.
738 */
739 skb_queue_purge(&tid_tx->pending);
740 kfree(tid_tx);
741 }
742 }
743
744 __sta_info_free(local, sta);
745
746 return 0;
712} 747}
713 748
714/* 749int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata, const u8 *addr)
715 * See comment in __sta_info_unlink, returns sta if it
716 * needs to be destroyed.
717 */
718static struct sta_info *__sta_info_unpin(struct sta_info *sta)
719{ 750{
720 struct sta_info *ret = NULL; 751 struct sta_info *sta;
721 unsigned long flags; 752 int ret;
722 753
723 spin_lock_irqsave(&sta->local->sta_lock, flags); 754 mutex_lock(&sdata->local->sta_mtx);
724 WARN_ON(sta->pin_status != STA_INFO_PIN_STAT_DESTROY && 755 sta = sta_info_get(sdata, addr);
725 sta->pin_status != STA_INFO_PIN_STAT_PINNED); 756 ret = __sta_info_destroy(sta);
726 if (sta->pin_status == STA_INFO_PIN_STAT_DESTROY) 757 mutex_unlock(&sdata->local->sta_mtx);
727 ret = sta;
728 sta->pin_status = STA_INFO_PIN_STAT_NORMAL;
729 spin_unlock_irqrestore(&sta->local->sta_lock, flags);
730 758
731 return ret; 759 return ret;
732} 760}
733 761
734static void sta_info_debugfs_add_work(struct work_struct *work) 762int sta_info_destroy_addr_bss(struct ieee80211_sub_if_data *sdata,
763 const u8 *addr)
735{ 764{
736 struct ieee80211_local *local = 765 struct sta_info *sta;
737 container_of(work, struct ieee80211_local, sta_debugfs_add); 766 int ret;
738 struct sta_info *sta, *tmp;
739 unsigned long flags;
740 767
741 /* We need to keep the RTNL across the whole pinned status. */ 768 mutex_lock(&sdata->local->sta_mtx);
742 rtnl_lock(); 769 sta = sta_info_get_bss(sdata, addr);
743 while (1) { 770 ret = __sta_info_destroy(sta);
744 sta = NULL; 771 mutex_unlock(&sdata->local->sta_mtx);
745 772
746 spin_lock_irqsave(&local->sta_lock, flags); 773 return ret;
747 list_for_each_entry(tmp, &local->sta_list, list) { 774}
748 /*
749 * debugfs.add_has_run will be set by
750 * ieee80211_sta_debugfs_add regardless
751 * of what else it does.
752 */
753 if (!tmp->debugfs.add_has_run) {
754 sta = tmp;
755 __sta_info_pin(sta);
756 break;
757 }
758 }
759 spin_unlock_irqrestore(&local->sta_lock, flags);
760 775
761 if (!sta) 776static void sta_info_cleanup(unsigned long data)
762 break; 777{
778 struct ieee80211_local *local = (struct ieee80211_local *) data;
779 struct sta_info *sta;
780
781 rcu_read_lock();
782 list_for_each_entry_rcu(sta, &local->sta_list, list)
783 sta_info_cleanup_expire_buffered(local, sta);
784 rcu_read_unlock();
763 785
764 ieee80211_sta_debugfs_add(sta); 786 if (local->quiescing)
765 rate_control_add_sta_debugfs(sta); 787 return;
766 788
767 sta = __sta_info_unpin(sta); 789 local->sta_cleanup.expires =
768 sta_info_destroy(sta); 790 round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL);
769 } 791 add_timer(&local->sta_cleanup);
770 rtnl_unlock();
771} 792}
772#endif
773 793
774void sta_info_init(struct ieee80211_local *local) 794void sta_info_init(struct ieee80211_local *local)
775{ 795{
776 spin_lock_init(&local->sta_lock); 796 spin_lock_init(&local->sta_lock);
797 mutex_init(&local->sta_mtx);
777 INIT_LIST_HEAD(&local->sta_list); 798 INIT_LIST_HEAD(&local->sta_list);
799 INIT_LIST_HEAD(&local->sta_pending_list);
800 INIT_WORK(&local->sta_finish_work, sta_info_finish_work);
778 801
779 setup_timer(&local->sta_cleanup, sta_info_cleanup, 802 setup_timer(&local->sta_cleanup, sta_info_cleanup,
780 (unsigned long)local); 803 (unsigned long)local);
781 local->sta_cleanup.expires = 804 local->sta_cleanup.expires =
782 round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); 805 round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL);
783
784#ifdef CONFIG_MAC80211_DEBUGFS
785 INIT_WORK(&local->sta_debugfs_add, sta_info_debugfs_add_work);
786#endif
787} 806}
788 807
789int sta_info_start(struct ieee80211_local *local) 808int sta_info_start(struct ieee80211_local *local)
@@ -795,16 +814,6 @@ int sta_info_start(struct ieee80211_local *local)
795void sta_info_stop(struct ieee80211_local *local) 814void sta_info_stop(struct ieee80211_local *local)
796{ 815{
797 del_timer(&local->sta_cleanup); 816 del_timer(&local->sta_cleanup);
798#ifdef CONFIG_MAC80211_DEBUGFS
799 /*
800 * Make sure the debugfs adding work isn't pending after this
801 * because we're about to be destroyed. It doesn't matter
802 * whether it ran or not since we're going to flush all STAs
803 * anyway.
804 */
805 cancel_work_sync(&local->sta_debugfs_add);
806#endif
807
808 sta_info_flush(local, NULL); 817 sta_info_flush(local, NULL);
809} 818}
810 819
@@ -820,26 +829,19 @@ int sta_info_flush(struct ieee80211_local *local,
820 struct ieee80211_sub_if_data *sdata) 829 struct ieee80211_sub_if_data *sdata)
821{ 830{
822 struct sta_info *sta, *tmp; 831 struct sta_info *sta, *tmp;
823 LIST_HEAD(tmp_list);
824 int ret = 0; 832 int ret = 0;
825 unsigned long flags;
826 833
827 might_sleep(); 834 might_sleep();
828 835
829 spin_lock_irqsave(&local->sta_lock, flags); 836 mutex_lock(&local->sta_mtx);
837
838 sta_info_finish_pending(local);
839
830 list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { 840 list_for_each_entry_safe(sta, tmp, &local->sta_list, list) {
831 if (!sdata || sdata == sta->sdata) { 841 if (!sdata || sdata == sta->sdata)
832 __sta_info_unlink(&sta); 842 WARN_ON(__sta_info_destroy(sta));
833 if (sta) {
834 list_add_tail(&sta->list, &tmp_list);
835 ret++;
836 }
837 }
838 } 843 }
839 spin_unlock_irqrestore(&local->sta_lock, flags); 844 mutex_unlock(&local->sta_mtx);
840
841 list_for_each_entry_safe(sta, tmp, &tmp_list, list)
842 sta_info_destroy(sta);
843 845
844 return ret; 846 return ret;
845} 847}
@@ -849,24 +851,17 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
849{ 851{
850 struct ieee80211_local *local = sdata->local; 852 struct ieee80211_local *local = sdata->local;
851 struct sta_info *sta, *tmp; 853 struct sta_info *sta, *tmp;
852 LIST_HEAD(tmp_list);
853 unsigned long flags;
854 854
855 spin_lock_irqsave(&local->sta_lock, flags); 855 mutex_lock(&local->sta_mtx);
856 list_for_each_entry_safe(sta, tmp, &local->sta_list, list) 856 list_for_each_entry_safe(sta, tmp, &local->sta_list, list)
857 if (time_after(jiffies, sta->last_rx + exp_time)) { 857 if (time_after(jiffies, sta->last_rx + exp_time)) {
858#ifdef CONFIG_MAC80211_IBSS_DEBUG 858#ifdef CONFIG_MAC80211_IBSS_DEBUG
859 printk(KERN_DEBUG "%s: expiring inactive STA %pM\n", 859 printk(KERN_DEBUG "%s: expiring inactive STA %pM\n",
860 sdata->name, sta->sta.addr); 860 sdata->name, sta->sta.addr);
861#endif 861#endif
862 __sta_info_unlink(&sta); 862 WARN_ON(__sta_info_destroy(sta));
863 if (sta)
864 list_add(&sta->list, &tmp_list);
865 } 863 }
866 spin_unlock_irqrestore(&local->sta_lock, flags); 864 mutex_unlock(&local->sta_mtx);
867
868 list_for_each_entry_safe(sta, tmp, &tmp_list, list)
869 sta_info_destroy(sta);
870} 865}
871 866
872struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, 867struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw,
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 6f79bba5706..822d8452293 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -42,6 +42,9 @@
42 * be in the queues 42 * be in the queues
43 * @WLAN_STA_PSPOLL: Station sent PS-poll while driver was keeping 43 * @WLAN_STA_PSPOLL: Station sent PS-poll while driver was keeping
44 * station in power-save mode, reply when the driver unblocks. 44 * station in power-save mode, reply when the driver unblocks.
45 * @WLAN_STA_DISASSOC: Disassociation in progress.
46 * This is used to reject TX BA session requests when disassociation
47 * is in progress.
45 */ 48 */
46enum ieee80211_sta_info_flags { 49enum ieee80211_sta_info_flags {
47 WLAN_STA_AUTH = 1<<0, 50 WLAN_STA_AUTH = 1<<0,
@@ -57,6 +60,7 @@ enum ieee80211_sta_info_flags {
57 WLAN_STA_SUSPEND = 1<<11, 60 WLAN_STA_SUSPEND = 1<<11,
58 WLAN_STA_PS_DRIVER = 1<<12, 61 WLAN_STA_PS_DRIVER = 1<<12,
59 WLAN_STA_PSPOLL = 1<<13, 62 WLAN_STA_PSPOLL = 1<<13,
63 WLAN_STA_DISASSOC = 1<<14,
60}; 64};
61 65
62#define STA_TID_NUM 16 66#define STA_TID_NUM 16
@@ -162,11 +166,6 @@ struct sta_ampdu_mlme {
162}; 166};
163 167
164 168
165/* see __sta_info_unlink */
166#define STA_INFO_PIN_STAT_NORMAL 0
167#define STA_INFO_PIN_STAT_PINNED 1
168#define STA_INFO_PIN_STAT_DESTROY 2
169
170/** 169/**
171 * struct sta_info - STA information 170 * struct sta_info - STA information
172 * 171 *
@@ -187,7 +186,6 @@ struct sta_ampdu_mlme {
187 * @flaglock: spinlock for flags accesses 186 * @flaglock: spinlock for flags accesses
188 * @drv_unblock_wk: used for driver PS unblocking 187 * @drv_unblock_wk: used for driver PS unblocking
189 * @listen_interval: listen interval of this station, when we're acting as AP 188 * @listen_interval: listen interval of this station, when we're acting as AP
190 * @pin_status: used internally for pinning a STA struct into memory
191 * @flags: STA flags, see &enum ieee80211_sta_info_flags 189 * @flags: STA flags, see &enum ieee80211_sta_info_flags
192 * @ps_tx_buf: buffer of frames to transmit to this station 190 * @ps_tx_buf: buffer of frames to transmit to this station
193 * when it leaves power saving state 191 * when it leaves power saving state
@@ -226,6 +224,7 @@ struct sta_ampdu_mlme {
226 * @debugfs: debug filesystem info 224 * @debugfs: debug filesystem info
227 * @sta: station information we share with the driver 225 * @sta: station information we share with the driver
228 * @dead: set to true when sta is unlinked 226 * @dead: set to true when sta is unlinked
227 * @uploaded: set to true when sta is uploaded to the driver
229 */ 228 */
230struct sta_info { 229struct sta_info {
231 /* General information, mostly static */ 230 /* General information, mostly static */
@@ -245,11 +244,7 @@ struct sta_info {
245 244
246 bool dead; 245 bool dead;
247 246
248 /* 247 bool uploaded;
249 * for use by the internal lifetime management,
250 * see __sta_info_unlink
251 */
252 u8 pin_status;
253 248
254 /* 249 /*
255 * frequently updated, locked with own spinlock (flaglock), 250 * frequently updated, locked with own spinlock (flaglock),
@@ -449,18 +444,19 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
449 * Insert STA info into hash table/list, returns zero or a 444 * Insert STA info into hash table/list, returns zero or a
450 * -EEXIST if (if the same MAC address is already present). 445 * -EEXIST if (if the same MAC address is already present).
451 * 446 *
452 * Calling this without RCU protection makes the caller 447 * Calling the non-rcu version makes the caller relinquish,
453 * relinquish its reference to @sta. 448 * the _rcu version calls read_lock_rcu() and must be called
449 * without it held.
454 */ 450 */
455int sta_info_insert(struct sta_info *sta); 451int sta_info_insert(struct sta_info *sta);
456/* 452int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU);
457 * Unlink a STA info from the hash table/list. 453int sta_info_insert_atomic(struct sta_info *sta);
458 * This can NULL the STA pointer if somebody else 454
459 * has already unlinked it. 455int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata,
460 */ 456 const u8 *addr);
461void sta_info_unlink(struct sta_info **sta); 457int sta_info_destroy_addr_bss(struct ieee80211_sub_if_data *sdata,
458 const u8 *addr);
462 459
463void sta_info_destroy(struct sta_info *sta);
464void sta_info_set_tim_bit(struct sta_info *sta); 460void sta_info_set_tim_bit(struct sta_info *sta);
465void sta_info_clear_tim_bit(struct sta_info *sta); 461void sta_info_clear_tim_bit(struct sta_info *sta);
466 462
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index e57ad6b1d7e..ded98730c11 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -188,6 +188,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
188 rcu_read_lock(); 188 rcu_read_lock();
189 189
190 sband = local->hw.wiphy->bands[info->band]; 190 sband = local->hw.wiphy->bands[info->band];
191 fc = hdr->frame_control;
191 192
192 for_each_sta_info(local, hdr->addr1, sta, tmp) { 193 for_each_sta_info(local, hdr->addr1, sta, tmp) {
193 /* skip wrong virtual interface */ 194 /* skip wrong virtual interface */
@@ -205,8 +206,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
205 return; 206 return;
206 } 207 }
207 208
208 fc = hdr->frame_control;
209
210 if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && 209 if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) &&
211 (ieee80211_is_data_qos(fc))) { 210 (ieee80211_is_data_qos(fc))) {
212 u16 tid, ssn; 211 u16 tid, ssn;
@@ -275,6 +274,20 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
275 local->dot11FailedCount++; 274 local->dot11FailedCount++;
276 } 275 }
277 276
277 if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc) &&
278 (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) &&
279 !(info->flags & IEEE80211_TX_CTL_INJECTED) &&
280 local->ps_sdata && !(local->scanning)) {
281 if (info->flags & IEEE80211_TX_STAT_ACK) {
282 local->ps_sdata->u.mgd.flags |=
283 IEEE80211_STA_NULLFUNC_ACKED;
284 ieee80211_queue_work(&local->hw,
285 &local->dynamic_ps_enable_work);
286 } else
287 mod_timer(&local->dynamic_ps_timer, jiffies +
288 msecs_to_jiffies(10));
289 }
290
278 /* this was a transmitted frame, but now we want to reuse it */ 291 /* this was a transmitted frame, but now we want to reuse it */
279 skb_orphan(skb); 292 skb_orphan(skb);
280 293
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 85e382aa894..cbe53ed4fb0 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -571,7 +571,7 @@ ieee80211_tx_h_sta(struct ieee80211_tx_data *tx)
571{ 571{
572 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); 572 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
573 573
574 if (tx->sta) 574 if (tx->sta && tx->sta->uploaded)
575 info->control.sta = &tx->sta->sta; 575 info->control.sta = &tx->sta->sta;
576 576
577 return TX_CONTINUE; 577 return TX_CONTINUE;
@@ -1010,7 +1010,8 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
1010 (struct ieee80211_radiotap_header *) skb->data; 1010 (struct ieee80211_radiotap_header *) skb->data;
1011 struct ieee80211_supported_band *sband; 1011 struct ieee80211_supported_band *sband;
1012 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1012 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1013 int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); 1013 int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len,
1014 NULL);
1014 1015
1015 sband = tx->local->hw.wiphy->bands[tx->channel->band]; 1016 sband = tx->local->hw.wiphy->bands[tx->channel->band];
1016 1017
@@ -1046,7 +1047,7 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
1046 * because it will be recomputed and added 1047 * because it will be recomputed and added
1047 * on transmission 1048 * on transmission
1048 */ 1049 */
1049 if (skb->len < (iterator.max_length + FCS_LEN)) 1050 if (skb->len < (iterator._max_length + FCS_LEN))
1050 return false; 1051 return false;
1051 1052
1052 skb_trim(skb, skb->len - FCS_LEN); 1053 skb_trim(skb, skb->len - FCS_LEN);
@@ -1073,10 +1074,10 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
1073 1074
1074 /* 1075 /*
1075 * remove the radiotap header 1076 * remove the radiotap header
1076 * iterator->max_length was sanity-checked against 1077 * iterator->_max_length was sanity-checked against
1077 * skb->len by iterator init 1078 * skb->len by iterator init
1078 */ 1079 */
1079 skb_pull(skb, iterator.max_length); 1080 skb_pull(skb, iterator._max_length);
1080 1081
1081 return true; 1082 return true;
1082} 1083}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index ca170b417da..c453226f06b 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1082,7 +1082,6 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1082 struct ieee80211_hw *hw = &local->hw; 1082 struct ieee80211_hw *hw = &local->hw;
1083 struct ieee80211_sub_if_data *sdata; 1083 struct ieee80211_sub_if_data *sdata;
1084 struct sta_info *sta; 1084 struct sta_info *sta;
1085 unsigned long flags;
1086 int res; 1085 int res;
1087 1086
1088 if (local->suspended) 1087 if (local->suspended)
@@ -1116,20 +1115,19 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1116 } 1115 }
1117 1116
1118 /* add STAs back */ 1117 /* add STAs back */
1119 if (local->ops->sta_notify) { 1118 mutex_lock(&local->sta_mtx);
1120 spin_lock_irqsave(&local->sta_lock, flags); 1119 list_for_each_entry(sta, &local->sta_list, list) {
1121 list_for_each_entry(sta, &local->sta_list, list) { 1120 if (sta->uploaded) {
1122 sdata = sta->sdata; 1121 sdata = sta->sdata;
1123 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 1122 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1124 sdata = container_of(sdata->bss, 1123 sdata = container_of(sdata->bss,
1125 struct ieee80211_sub_if_data, 1124 struct ieee80211_sub_if_data,
1126 u.ap); 1125 u.ap);
1127 1126
1128 drv_sta_notify(local, sdata, STA_NOTIFY_ADD, 1127 WARN_ON(drv_sta_add(local, sdata, &sta->sta));
1129 &sta->sta);
1130 } 1128 }
1131 spin_unlock_irqrestore(&local->sta_lock, flags);
1132 } 1129 }
1130 mutex_unlock(&local->sta_mtx);
1133 1131
1134 /* Clear Suspend state so that ADDBA requests can be processed */ 1132 /* Clear Suspend state so that ADDBA requests can be processed */
1135 1133
@@ -1180,6 +1178,14 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1180 } 1178 }
1181 } 1179 }
1182 1180
1181 rcu_read_lock();
1182 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
1183 list_for_each_entry_rcu(sta, &local->sta_list, list) {
1184 ieee80211_sta_tear_down_BA_sessions(sta);
1185 }
1186 }
1187 rcu_read_unlock();
1188
1183 /* add back keys */ 1189 /* add back keys */
1184 list_for_each_entry(sdata, &local->interfaces, list) 1190 list_for_each_entry(sdata, &local->interfaces, list)
1185 if (ieee80211_sdata_running(sdata)) 1191 if (ieee80211_sdata_running(sdata))
@@ -1219,10 +1225,10 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1219 1225
1220 add_timer(&local->sta_cleanup); 1226 add_timer(&local->sta_cleanup);
1221 1227
1222 spin_lock_irqsave(&local->sta_lock, flags); 1228 mutex_lock(&local->sta_mtx);
1223 list_for_each_entry(sta, &local->sta_list, list) 1229 list_for_each_entry(sta, &local->sta_list, list)
1224 mesh_plink_restart(sta); 1230 mesh_plink_restart(sta);
1225 spin_unlock_irqrestore(&local->sta_lock, flags); 1231 mutex_unlock(&local->sta_mtx);
1226#else 1232#else
1227 WARN_ON(1); 1233 WARN_ON(1);
1228#endif 1234#endif
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c
index f591871a7b4..1332c445d1c 100644
--- a/net/wireless/radiotap.c
+++ b/net/wireless/radiotap.c
@@ -2,6 +2,16 @@
2 * Radiotap parser 2 * Radiotap parser
3 * 3 *
4 * Copyright 2007 Andy Green <andy@warmcat.com> 4 * Copyright 2007 Andy Green <andy@warmcat.com>
5 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Alternatively, this software may be distributed under the terms of BSD
12 * license.
13 *
14 * See COPYING for more details.
5 */ 15 */
6 16
7#include <net/cfg80211.h> 17#include <net/cfg80211.h>
@@ -10,6 +20,35 @@
10 20
11/* function prototypes and related defs are in include/net/cfg80211.h */ 21/* function prototypes and related defs are in include/net/cfg80211.h */
12 22
23static const struct radiotap_align_size rtap_namespace_sizes[] = {
24 [IEEE80211_RADIOTAP_TSFT] = { .align = 8, .size = 8, },
25 [IEEE80211_RADIOTAP_FLAGS] = { .align = 1, .size = 1, },
26 [IEEE80211_RADIOTAP_RATE] = { .align = 1, .size = 1, },
27 [IEEE80211_RADIOTAP_CHANNEL] = { .align = 2, .size = 4, },
28 [IEEE80211_RADIOTAP_FHSS] = { .align = 2, .size = 2, },
29 [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = { .align = 1, .size = 1, },
30 [IEEE80211_RADIOTAP_DBM_ANTNOISE] = { .align = 1, .size = 1, },
31 [IEEE80211_RADIOTAP_LOCK_QUALITY] = { .align = 2, .size = 2, },
32 [IEEE80211_RADIOTAP_TX_ATTENUATION] = { .align = 2, .size = 2, },
33 [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = { .align = 2, .size = 2, },
34 [IEEE80211_RADIOTAP_DBM_TX_POWER] = { .align = 1, .size = 1, },
35 [IEEE80211_RADIOTAP_ANTENNA] = { .align = 1, .size = 1, },
36 [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = { .align = 1, .size = 1, },
37 [IEEE80211_RADIOTAP_DB_ANTNOISE] = { .align = 1, .size = 1, },
38 [IEEE80211_RADIOTAP_RX_FLAGS] = { .align = 2, .size = 2, },
39 [IEEE80211_RADIOTAP_TX_FLAGS] = { .align = 2, .size = 2, },
40 [IEEE80211_RADIOTAP_RTS_RETRIES] = { .align = 1, .size = 1, },
41 [IEEE80211_RADIOTAP_DATA_RETRIES] = { .align = 1, .size = 1, },
42 /*
43 * add more here as they are defined in radiotap.h
44 */
45};
46
47static const struct ieee80211_radiotap_namespace radiotap_ns = {
48 .n_bits = sizeof(rtap_namespace_sizes) / sizeof(rtap_namespace_sizes[0]),
49 .align_size = rtap_namespace_sizes,
50};
51
13/** 52/**
14 * ieee80211_radiotap_iterator_init - radiotap parser iterator initialization 53 * ieee80211_radiotap_iterator_init - radiotap parser iterator initialization
15 * @iterator: radiotap_iterator to initialize 54 * @iterator: radiotap_iterator to initialize
@@ -50,9 +89,9 @@
50 */ 89 */
51 90
52int ieee80211_radiotap_iterator_init( 91int ieee80211_radiotap_iterator_init(
53 struct ieee80211_radiotap_iterator *iterator, 92 struct ieee80211_radiotap_iterator *iterator,
54 struct ieee80211_radiotap_header *radiotap_header, 93 struct ieee80211_radiotap_header *radiotap_header,
55 int max_length) 94 int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns)
56{ 95{
57 /* Linux only supports version 0 radiotap format */ 96 /* Linux only supports version 0 radiotap format */
58 if (radiotap_header->it_version) 97 if (radiotap_header->it_version)
@@ -62,19 +101,24 @@ int ieee80211_radiotap_iterator_init(
62 if (max_length < get_unaligned_le16(&radiotap_header->it_len)) 101 if (max_length < get_unaligned_le16(&radiotap_header->it_len))
63 return -EINVAL; 102 return -EINVAL;
64 103
65 iterator->rtheader = radiotap_header; 104 iterator->_rtheader = radiotap_header;
66 iterator->max_length = get_unaligned_le16(&radiotap_header->it_len); 105 iterator->_max_length = get_unaligned_le16(&radiotap_header->it_len);
67 iterator->arg_index = 0; 106 iterator->_arg_index = 0;
68 iterator->bitmap_shifter = get_unaligned_le32(&radiotap_header->it_present); 107 iterator->_bitmap_shifter = get_unaligned_le32(&radiotap_header->it_present);
69 iterator->arg = (u8 *)radiotap_header + sizeof(*radiotap_header); 108 iterator->_arg = (uint8_t *)radiotap_header + sizeof(*radiotap_header);
70 iterator->this_arg = NULL; 109 iterator->_reset_on_ext = 0;
110 iterator->_next_bitmap = &radiotap_header->it_present;
111 iterator->_next_bitmap++;
112 iterator->_vns = vns;
113 iterator->current_namespace = &radiotap_ns;
114 iterator->is_radiotap_ns = 1;
71 115
72 /* find payload start allowing for extended bitmap(s) */ 116 /* find payload start allowing for extended bitmap(s) */
73 117
74 if (unlikely(iterator->bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT))) { 118 if (iterator->_bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT)) {
75 while (get_unaligned_le32(iterator->arg) & 119 while (get_unaligned_le32(iterator->_arg) &
76 (1 << IEEE80211_RADIOTAP_EXT)) { 120 (1 << IEEE80211_RADIOTAP_EXT)) {
77 iterator->arg += sizeof(u32); 121 iterator->_arg += sizeof(uint32_t);
78 122
79 /* 123 /*
80 * check for insanity where the present bitmaps 124 * check for insanity where the present bitmaps
@@ -82,12 +126,13 @@ int ieee80211_radiotap_iterator_init(
82 * stated radiotap header length 126 * stated radiotap header length
83 */ 127 */
84 128
85 if (((ulong)iterator->arg - 129 if ((unsigned long)iterator->_arg -
86 (ulong)iterator->rtheader) > iterator->max_length) 130 (unsigned long)iterator->_rtheader >
131 (unsigned long)iterator->_max_length)
87 return -EINVAL; 132 return -EINVAL;
88 } 133 }
89 134
90 iterator->arg += sizeof(u32); 135 iterator->_arg += sizeof(uint32_t);
91 136
92 /* 137 /*
93 * no need to check again for blowing past stated radiotap 138 * no need to check again for blowing past stated radiotap
@@ -96,12 +141,36 @@ int ieee80211_radiotap_iterator_init(
96 */ 141 */
97 } 142 }
98 143
144 iterator->this_arg = iterator->_arg;
145
99 /* we are all initialized happily */ 146 /* we are all initialized happily */
100 147
101 return 0; 148 return 0;
102} 149}
103EXPORT_SYMBOL(ieee80211_radiotap_iterator_init); 150EXPORT_SYMBOL(ieee80211_radiotap_iterator_init);
104 151
152static void find_ns(struct ieee80211_radiotap_iterator *iterator,
153 uint32_t oui, uint8_t subns)
154{
155 int i;
156
157 iterator->current_namespace = NULL;
158
159 if (!iterator->_vns)
160 return;
161
162 for (i = 0; i < iterator->_vns->n_ns; i++) {
163 if (iterator->_vns->ns[i].oui != oui)
164 continue;
165 if (iterator->_vns->ns[i].subns != subns)
166 continue;
167
168 iterator->current_namespace = &iterator->_vns->ns[i];
169 break;
170 }
171}
172
173
105 174
106/** 175/**
107 * ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg 176 * ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg
@@ -127,99 +196,80 @@ EXPORT_SYMBOL(ieee80211_radiotap_iterator_init);
127 */ 196 */
128 197
129int ieee80211_radiotap_iterator_next( 198int ieee80211_radiotap_iterator_next(
130 struct ieee80211_radiotap_iterator *iterator) 199 struct ieee80211_radiotap_iterator *iterator)
131{ 200{
132 201 while (1) {
133 /*
134 * small length lookup table for all radiotap types we heard of
135 * starting from b0 in the bitmap, so we can walk the payload
136 * area of the radiotap header
137 *
138 * There is a requirement to pad args, so that args
139 * of a given length must begin at a boundary of that length
140 * -- but note that compound args are allowed (eg, 2 x u16
141 * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not
142 * a reliable indicator of alignment requirement.
143 *
144 * upper nybble: content alignment for arg
145 * lower nybble: content length for arg
146 */
147
148 static const u8 rt_sizes[] = {
149 [IEEE80211_RADIOTAP_TSFT] = 0x88,
150 [IEEE80211_RADIOTAP_FLAGS] = 0x11,
151 [IEEE80211_RADIOTAP_RATE] = 0x11,
152 [IEEE80211_RADIOTAP_CHANNEL] = 0x24,
153 [IEEE80211_RADIOTAP_FHSS] = 0x22,
154 [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 0x11,
155 [IEEE80211_RADIOTAP_DBM_ANTNOISE] = 0x11,
156 [IEEE80211_RADIOTAP_LOCK_QUALITY] = 0x22,
157 [IEEE80211_RADIOTAP_TX_ATTENUATION] = 0x22,
158 [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 0x22,
159 [IEEE80211_RADIOTAP_DBM_TX_POWER] = 0x11,
160 [IEEE80211_RADIOTAP_ANTENNA] = 0x11,
161 [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 0x11,
162 [IEEE80211_RADIOTAP_DB_ANTNOISE] = 0x11,
163 [IEEE80211_RADIOTAP_RX_FLAGS] = 0x22,
164 [IEEE80211_RADIOTAP_TX_FLAGS] = 0x22,
165 [IEEE80211_RADIOTAP_RTS_RETRIES] = 0x11,
166 [IEEE80211_RADIOTAP_DATA_RETRIES] = 0x11,
167 /*
168 * add more here as they are defined in
169 * include/net/ieee80211_radiotap.h
170 */
171 };
172
173 /*
174 * for every radiotap entry we can at
175 * least skip (by knowing the length)...
176 */
177
178 while (iterator->arg_index < sizeof(rt_sizes)) {
179 int hit = 0; 202 int hit = 0;
180 int pad; 203 int pad, align, size, subns, vnslen;
204 uint32_t oui;
181 205
182 if (!(iterator->bitmap_shifter & 1)) 206 /* if no more EXT bits, that's it */
207 if ((iterator->_arg_index % 32) == IEEE80211_RADIOTAP_EXT &&
208 !(iterator->_bitmap_shifter & 1))
209 return -ENOENT;
210
211 if (!(iterator->_bitmap_shifter & 1))
183 goto next_entry; /* arg not present */ 212 goto next_entry; /* arg not present */
184 213
214 /* get alignment/size of data */
215 switch (iterator->_arg_index % 32) {
216 case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
217 case IEEE80211_RADIOTAP_EXT:
218 align = 1;
219 size = 0;
220 break;
221 case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
222 align = 2;
223 size = 6;
224 break;
225 default:
226 if (!iterator->current_namespace ||
227 iterator->_arg_index >= iterator->current_namespace->n_bits) {
228 if (iterator->current_namespace == &radiotap_ns)
229 return -ENOENT;
230 align = 0;
231 } else {
232 align = iterator->current_namespace->align_size[iterator->_arg_index].align;
233 size = iterator->current_namespace->align_size[iterator->_arg_index].size;
234 }
235 if (!align) {
236 /* skip all subsequent data */
237 iterator->_arg = iterator->_next_ns_data;
238 /* give up on this namespace */
239 iterator->current_namespace = NULL;
240 goto next_entry;
241 }
242 break;
243 }
244
185 /* 245 /*
186 * arg is present, account for alignment padding 246 * arg is present, account for alignment padding
187 * 8-bit args can be at any alignment
188 * 16-bit args must start on 16-bit boundary
189 * 32-bit args must start on 32-bit boundary
190 * 64-bit args must start on 64-bit boundary
191 * 247 *
192 * note that total arg size can differ from alignment of 248 * Note that these alignments are relative to the start
193 * elements inside arg, so we use upper nybble of length 249 * of the radiotap header. There is no guarantee
194 * table to base alignment on
195 *
196 * also note: these alignments are ** relative to the
197 * start of the radiotap header **. There is no guarantee
198 * that the radiotap header itself is aligned on any 250 * that the radiotap header itself is aligned on any
199 * kind of boundary. 251 * kind of boundary.
200 * 252 *
201 * the above is why get_unaligned() is used to dereference 253 * The above is why get_unaligned() is used to dereference
202 * multibyte elements from the radiotap area 254 * multibyte elements from the radiotap area.
203 */ 255 */
204 256
205 pad = (((ulong)iterator->arg) - 257 pad = ((unsigned long)iterator->_arg -
206 ((ulong)iterator->rtheader)) & 258 (unsigned long)iterator->_rtheader) & (align - 1);
207 ((rt_sizes[iterator->arg_index] >> 4) - 1);
208 259
209 if (pad) 260 if (pad)
210 iterator->arg += 261 iterator->_arg += align - pad;
211 (rt_sizes[iterator->arg_index] >> 4) - pad;
212 262
213 /* 263 /*
214 * this is what we will return to user, but we need to 264 * this is what we will return to user, but we need to
215 * move on first so next call has something fresh to test 265 * move on first so next call has something fresh to test
216 */ 266 */
217 iterator->this_arg_index = iterator->arg_index; 267 iterator->this_arg_index = iterator->_arg_index;
218 iterator->this_arg = iterator->arg; 268 iterator->this_arg = iterator->_arg;
219 hit = 1; 269 iterator->this_arg_size = size;
220 270
221 /* internally move on the size of this arg */ 271 /* internally move on the size of this arg */
222 iterator->arg += rt_sizes[iterator->arg_index] & 0x0f; 272 iterator->_arg += size;
223 273
224 /* 274 /*
225 * check for insanity where we are given a bitmap that 275 * check for insanity where we are given a bitmap that
@@ -228,32 +278,73 @@ int ieee80211_radiotap_iterator_next(
228 * max_length on the last arg, never exceeding it. 278 * max_length on the last arg, never exceeding it.
229 */ 279 */
230 280
231 if (((ulong)iterator->arg - (ulong)iterator->rtheader) > 281 if ((unsigned long)iterator->_arg -
232 iterator->max_length) 282 (unsigned long)iterator->_rtheader >
283 (unsigned long)iterator->_max_length)
233 return -EINVAL; 284 return -EINVAL;
234 285
235 next_entry: 286 /* these special ones are valid in each bitmap word */
236 iterator->arg_index++; 287 switch (iterator->_arg_index % 32) {
237 if (unlikely((iterator->arg_index & 31) == 0)) { 288 case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
238 /* completed current u32 bitmap */ 289 iterator->_bitmap_shifter >>= 1;
239 if (iterator->bitmap_shifter & 1) { 290 iterator->_arg_index++;
240 /* b31 was set, there is more */ 291
241 /* move to next u32 bitmap */ 292 iterator->_reset_on_ext = 1;
242 iterator->bitmap_shifter = 293
243 get_unaligned_le32(iterator->next_bitmap); 294 vnslen = get_unaligned_le16(iterator->this_arg + 4);
244 iterator->next_bitmap++; 295 iterator->_next_ns_data = iterator->_arg + vnslen;
245 } else 296 oui = (*iterator->this_arg << 16) |
246 /* no more bitmaps: end */ 297 (*(iterator->this_arg + 1) << 8) |
247 iterator->arg_index = sizeof(rt_sizes); 298 *(iterator->this_arg + 2);
248 } else /* just try the next bit */ 299 subns = *(iterator->this_arg + 3);
249 iterator->bitmap_shifter >>= 1; 300
301 find_ns(iterator, oui, subns);
302
303 iterator->is_radiotap_ns = 0;
304 /* allow parsers to show this information */
305 iterator->this_arg_index =
306 IEEE80211_RADIOTAP_VENDOR_NAMESPACE;
307 iterator->this_arg_size += vnslen;
308 if ((unsigned long)iterator->this_arg +
309 iterator->this_arg_size -
310 (unsigned long)iterator->_rtheader >
311 (unsigned long)(unsigned long)iterator->_max_length)
312 return -EINVAL;
313 hit = 1;
314 break;
315 case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
316 iterator->_bitmap_shifter >>= 1;
317 iterator->_arg_index++;
318
319 iterator->_reset_on_ext = 1;
320 iterator->current_namespace = &radiotap_ns;
321 iterator->is_radiotap_ns = 1;
322 break;
323 case IEEE80211_RADIOTAP_EXT:
324 /*
325 * bit 31 was set, there is more
326 * -- move to next u32 bitmap
327 */
328 iterator->_bitmap_shifter =
329 get_unaligned_le32(iterator->_next_bitmap);
330 iterator->_next_bitmap++;
331 if (iterator->_reset_on_ext)
332 iterator->_arg_index = 0;
333 else
334 iterator->_arg_index++;
335 iterator->_reset_on_ext = 0;
336 break;
337 default:
338 /* we've got a hit! */
339 hit = 1;
340 next_entry:
341 iterator->_bitmap_shifter >>= 1;
342 iterator->_arg_index++;
343 }
250 344
251 /* if we found a valid arg earlier, return it now */ 345 /* if we found a valid arg earlier, return it now */
252 if (hit) 346 if (hit)
253 return 0; 347 return 0;
254 } 348 }
255
256 /* we don't know how to handle any more args, we're done */
257 return -ENOENT;
258} 349}
259EXPORT_SYMBOL(ieee80211_radiotap_iterator_next); 350EXPORT_SYMBOL(ieee80211_radiotap_iterator_next);