aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath9k/main.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-10-14 10:58:37 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-10-31 19:00:16 -0400
commitae5eb02641233a4e9d1b92d22090f1b1afa14466 (patch)
tree117b7cb5efa3ff1cf714218098fc6db3820ed4e0 /drivers/net/wireless/ath9k/main.c
parentbda3933a8aceedd03e0dd410844bd310033ca756 (diff)
mac80211: rewrite HT handling
The HT handling has the following deficiencies, which I've (partially) fixed: * it always uses the AP info even if there is no AP, hence has no chance of working as an AP * it pretends to be HW config, but really is per-BSS * channel sanity checking is left to the drivers * it generally lets the driver control too much HT enabling is still wrong with this patch if you have more than one virtual STA mode interface, but that never happens currently. Once WDS, IBSS or AP/VLAN gets HT capabilities, it will also be wrong, see the comment in ieee80211_enable_ht(). Additionally, this fixes a number of bugs: * mac80211: ieee80211_set_disassoc doesn't notify the driver any more since the refactoring * iwl-agn-rs: always uses the HT capabilities from the wrong stuff mac80211 gives it rather than the actual peer STA * ath9k: a number of bugs resulting from the broken HT API I'm not entirely happy with putting the HT capabilities into struct ieee80211_sta as restricted to our own HT TX capabilities, but I see no cleaner solution for now. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath9k/main.c')
-rw-r--r--drivers/net/wireless/ath9k/main.c41
1 files changed, 20 insertions, 21 deletions
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 41cd114c438c..7555c3413384 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -330,25 +330,15 @@ static void ath9k_ht_conf(struct ath_softc *sc,
330{ 330{
331 struct ath_ht_info *ht_info = &sc->sc_ht_info; 331 struct ath_ht_info *ht_info = &sc->sc_ht_info;
332 332
333 if (bss_conf->assoc_ht) { 333 if (sc->hw->conf.ht.enabled) {
334 ht_info->ext_chan_offset = 334 ht_info->ext_chan_offset = bss_conf->ht.secondary_channel_offset;
335 bss_conf->ht_bss_conf->bss_cap & 335
336 IEEE80211_HT_PARAM_CHA_SEC_OFFSET; 336 if (bss_conf->ht.width_40_ok)
337
338 if (!(bss_conf->ht_cap->cap &
339 IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
340 (bss_conf->ht_bss_conf->bss_cap &
341 IEEE80211_HT_PARAM_CHAN_WIDTH_ANY))
342 ht_info->tx_chan_width = ATH9K_HT_MACMODE_2040; 337 ht_info->tx_chan_width = ATH9K_HT_MACMODE_2040;
343 else 338 else
344 ht_info->tx_chan_width = ATH9K_HT_MACMODE_20; 339 ht_info->tx_chan_width = ATH9K_HT_MACMODE_20;
345 340
346 ath9k_hw_set11nmac2040(sc->sc_ah, ht_info->tx_chan_width); 341 ath9k_hw_set11nmac2040(sc->sc_ah, ht_info->tx_chan_width);
347 ht_info->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
348 bss_conf->ht_cap->ampdu_factor);
349 ht_info->mpdudensity =
350 parse_mpdudensity(bss_conf->ht_cap->ampdu_density);
351
352 } 342 }
353} 343}
354 344
@@ -390,7 +380,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
390 sc->sc_halstats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER; 380 sc->sc_halstats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
391 381
392 /* Update chainmask */ 382 /* Update chainmask */
393 ath_update_chainmask(sc, bss_conf->assoc_ht); 383 ath_update_chainmask(sc, hw->conf.ht.enabled);
394 384
395 DPRINTF(sc, ATH_DBG_CONFIG, 385 DPRINTF(sc, ATH_DBG_CONFIG,
396 "%s: bssid %pM aid 0x%x\n", 386 "%s: bssid %pM aid 0x%x\n",
@@ -408,7 +398,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
408 return; 398 return;
409 } 399 }
410 400
411 if (hw->conf.ht_cap.ht_supported) 401 if (hw->conf.ht.enabled)
412 sc->sc_ah->ah_channels[pos].chanmode = 402 sc->sc_ah->ah_channels[pos].chanmode =
413 ath_get_extchanmode(sc, curchan); 403 ath_get_extchanmode(sc, curchan);
414 else 404 else
@@ -531,7 +521,6 @@ int _ath_rx_indicate(struct ath_softc *sc,
531 521
532 if (an) { 522 if (an) {
533 ath_rx_input(sc, an, 523 ath_rx_input(sc, an,
534 hw->conf.ht_cap.ht_supported,
535 skb, status, &st); 524 skb, status, &st);
536 } 525 }
537 if (!an || (st != ATH_RX_CONSUMED)) 526 if (!an || (st != ATH_RX_CONSUMED))
@@ -1241,6 +1230,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1241 __func__, 1230 __func__,
1242 curchan->center_freq); 1231 curchan->center_freq);
1243 1232
1233 /* Update chainmask */
1234 ath_update_chainmask(sc, conf->ht.enabled);
1235
1244 pos = ath_get_channel(sc, curchan); 1236 pos = ath_get_channel(sc, curchan);
1245 if (pos == -1) { 1237 if (pos == -1) {
1246 DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid channel\n", __func__); 1238 DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid channel\n", __func__);
@@ -1251,7 +1243,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1251 (curchan->band == IEEE80211_BAND_2GHZ) ? 1243 (curchan->band == IEEE80211_BAND_2GHZ) ?
1252 CHANNEL_G : CHANNEL_A; 1244 CHANNEL_G : CHANNEL_A;
1253 1245
1254 if (sc->sc_curaid && hw->conf.ht_cap.ht_supported) 1246 if (sc->sc_curaid && hw->conf.ht.enabled)
1255 sc->sc_ah->ah_channels[pos].chanmode = 1247 sc->sc_ah->ah_channels[pos].chanmode =
1256 ath_get_extchanmode(sc, curchan); 1248 ath_get_extchanmode(sc, curchan);
1257 1249
@@ -1434,6 +1426,14 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw,
1434 } else { 1426 } else {
1435 ath_node_get(sc, sta->addr); 1427 ath_node_get(sc, sta->addr);
1436 } 1428 }
1429
1430 /* XXX: Is this right? Can the capabilities change? */
1431 an = ath_node_find(sc, sta->addr);
1432 an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
1433 sta->ht_cap.ampdu_factor);
1434 an->mpdudensity =
1435 parse_mpdudensity(sta->ht_cap.ampdu_density);
1436
1437 spin_unlock_irqrestore(&sc->node_lock, flags); 1437 spin_unlock_irqrestore(&sc->node_lock, flags);
1438 break; 1438 break;
1439 case STA_NOTIFY_REMOVE: 1439 case STA_NOTIFY_REMOVE:
@@ -1552,9 +1552,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1552 } 1552 }
1553 1553
1554 if (changed & BSS_CHANGED_HT) { 1554 if (changed & BSS_CHANGED_HT) {
1555 DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed HT %d\n", 1555 DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed HT\n",
1556 __func__, 1556 __func__);
1557 bss_conf->assoc_ht);
1558 ath9k_ht_conf(sc, bss_conf); 1557 ath9k_ht_conf(sc, bss_conf);
1559 } 1558 }
1560 1559