diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/ath9k/core.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/main.c | 41 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/rc.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/recv.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/xmit.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 23 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 39 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-sta.c | 33 |
10 files changed, 100 insertions, 88 deletions
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index cb3e61e57c4d..59d835b72cd8 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h | |||
@@ -380,7 +380,6 @@ void ath_rx_cleanup(struct ath_softc *sc); | |||
380 | int ath_rx_tasklet(struct ath_softc *sc, int flush); | 380 | int ath_rx_tasklet(struct ath_softc *sc, int flush); |
381 | int ath_rx_input(struct ath_softc *sc, | 381 | int ath_rx_input(struct ath_softc *sc, |
382 | struct ath_node *node, | 382 | struct ath_node *node, |
383 | int is_ampdu, | ||
384 | struct sk_buff *skb, | 383 | struct sk_buff *skb, |
385 | struct ath_recv_status *rx_status, | 384 | struct ath_recv_status *rx_status, |
386 | enum ATH_RX_TYPE *status); | 385 | enum ATH_RX_TYPE *status); |
@@ -650,6 +649,9 @@ struct ath_node { | |||
650 | u8 an_smmode; /* SM Power save mode */ | 649 | u8 an_smmode; /* SM Power save mode */ |
651 | u8 an_flags; | 650 | u8 an_flags; |
652 | u8 an_addr[ETH_ALEN]; | 651 | u8 an_addr[ETH_ALEN]; |
652 | |||
653 | u16 maxampdu; | ||
654 | u8 mpdudensity; | ||
653 | }; | 655 | }; |
654 | 656 | ||
655 | void ath_tx_resume_tid(struct ath_softc *sc, | 657 | void ath_tx_resume_tid(struct ath_softc *sc, |
@@ -919,8 +921,6 @@ enum RATE_TYPE { | |||
919 | 921 | ||
920 | struct ath_ht_info { | 922 | struct ath_ht_info { |
921 | enum ath9k_ht_macmode tx_chan_width; | 923 | enum ath9k_ht_macmode tx_chan_width; |
922 | u16 maxampdu; | ||
923 | u8 mpdudensity; | ||
924 | u8 ext_chan_offset; | 924 | u8 ext_chan_offset; |
925 | }; | 925 | }; |
926 | 926 | ||
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 | ||
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index ee2dbce42b4d..9b2526030965 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c | |||
@@ -1838,7 +1838,7 @@ void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv) | |||
1838 | struct ath_softc *sc = hw->priv; | 1838 | struct ath_softc *sc = hw->priv; |
1839 | u32 capflag = 0; | 1839 | u32 capflag = 0; |
1840 | 1840 | ||
1841 | if (hw->conf.ht_cap.ht_supported) { | 1841 | if (hw->conf.ht.enabled) { |
1842 | capflag |= ATH_RC_HT_FLAG | ATH_RC_DS_FLAG; | 1842 | capflag |= ATH_RC_HT_FLAG | ATH_RC_DS_FLAG; |
1843 | if (sc->sc_ht_info.tx_chan_width == ATH9K_HT_MACMODE_2040) | 1843 | if (sc->sc_ht_info.tx_chan_width == ATH9K_HT_MACMODE_2040) |
1844 | capflag |= ATH_RC_CW40_FLAG; | 1844 | capflag |= ATH_RC_CW40_FLAG; |
@@ -1979,7 +1979,7 @@ static void ath_get_rate(void *priv, struct ieee80211_supported_band *sband, | |||
1979 | 1979 | ||
1980 | /* Check if aggregation has to be enabled for this tid */ | 1980 | /* Check if aggregation has to be enabled for this tid */ |
1981 | 1981 | ||
1982 | if (hw->conf.ht_cap.ht_supported) { | 1982 | if (hw->conf.ht.enabled) { |
1983 | if (ieee80211_is_data_qos(fc)) { | 1983 | if (ieee80211_is_data_qos(fc)) { |
1984 | qc = ieee80211_get_qos_ctl(hdr); | 1984 | qc = ieee80211_get_qos_ctl(hdr); |
1985 | tid = qc[0] & 0xf; | 1985 | tid = qc[0] & 0xf; |
@@ -2026,9 +2026,9 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
2026 | DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__); | 2026 | DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__); |
2027 | 2027 | ||
2028 | ath_setup_rates(sc, sband, sta, ath_rc_priv); | 2028 | ath_setup_rates(sc, sband, sta, ath_rc_priv); |
2029 | if (sc->hw->conf.flags & IEEE80211_CONF_SUPPORT_HT_MODE) { | 2029 | if (sc->hw->conf.ht.enabled) { |
2030 | for (i = 0; i < 77; i++) { | 2030 | for (i = 0; i < 77; i++) { |
2031 | if (sc->hw->conf.ht_cap.mcs.rx_mask[i/8] & (1<<(i%8))) | 2031 | if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8))) |
2032 | ath_rc_priv->neg_ht_rates.rs_rates[j++] = i; | 2032 | ath_rc_priv->neg_ht_rates.rs_rates[j++] = i; |
2033 | if (j == ATH_RATE_MAX) | 2033 | if (j == ATH_RATE_MAX) |
2034 | break; | 2034 | break; |
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 010fcdfec3f6..828322840a86 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c | |||
@@ -720,12 +720,11 @@ void ath_flushrecv(struct ath_softc *sc) | |||
720 | 720 | ||
721 | int ath_rx_input(struct ath_softc *sc, | 721 | int ath_rx_input(struct ath_softc *sc, |
722 | struct ath_node *an, | 722 | struct ath_node *an, |
723 | int is_ampdu, | ||
724 | struct sk_buff *skb, | 723 | struct sk_buff *skb, |
725 | struct ath_recv_status *rx_status, | 724 | struct ath_recv_status *rx_status, |
726 | enum ATH_RX_TYPE *status) | 725 | enum ATH_RX_TYPE *status) |
727 | { | 726 | { |
728 | if (is_ampdu && (sc->sc_flags & SC_OP_RXAGGR)) { | 727 | if (sc->sc_flags & SC_OP_RXAGGR) { |
729 | *status = ATH_RX_CONSUMED; | 728 | *status = ATH_RX_CONSUMED; |
730 | return ath_ampdu_input(sc, an, skb, rx_status); | 729 | return ath_ampdu_input(sc, an, skb, rx_status); |
731 | } else { | 730 | } else { |
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 3770fbe84fce..ba818cc2fb5c 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c | |||
@@ -300,7 +300,8 @@ static int ath_tx_prepare(struct ath_softc *sc, | |||
300 | if (ieee80211_is_data(fc) && !txctl->use_minrate) { | 300 | if (ieee80211_is_data(fc) && !txctl->use_minrate) { |
301 | 301 | ||
302 | /* Enable HT only for DATA frames and not for EAPOL */ | 302 | /* Enable HT only for DATA frames and not for EAPOL */ |
303 | txctl->ht = (hw->conf.ht_cap.ht_supported && | 303 | /* XXX why AMPDU only?? */ |
304 | txctl->ht = (hw->conf.ht.enabled && | ||
304 | (tx_info->flags & IEEE80211_TX_CTL_AMPDU)); | 305 | (tx_info->flags & IEEE80211_TX_CTL_AMPDU)); |
305 | 306 | ||
306 | if (is_multicast_ether_addr(hdr->addr1)) { | 307 | if (is_multicast_ether_addr(hdr->addr1)) { |
@@ -1450,7 +1451,8 @@ static int ath_tx_send_ampdu(struct ath_softc *sc, | |||
1450 | */ | 1451 | */ |
1451 | 1452 | ||
1452 | static u32 ath_lookup_rate(struct ath_softc *sc, | 1453 | static u32 ath_lookup_rate(struct ath_softc *sc, |
1453 | struct ath_buf *bf) | 1454 | struct ath_buf *bf, |
1455 | struct ath_atx_tid *tid) | ||
1454 | { | 1456 | { |
1455 | const struct ath9k_rate_table *rt = sc->sc_currates; | 1457 | const struct ath9k_rate_table *rt = sc->sc_currates; |
1456 | struct sk_buff *skb; | 1458 | struct sk_buff *skb; |
@@ -1504,7 +1506,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, | |||
1504 | * The IE, however can hold upto 65536, which shows up here | 1506 | * The IE, however can hold upto 65536, which shows up here |
1505 | * as zero. Ignore 65536 since we are constrained by hw. | 1507 | * as zero. Ignore 65536 since we are constrained by hw. |
1506 | */ | 1508 | */ |
1507 | maxampdu = sc->sc_ht_info.maxampdu; | 1509 | maxampdu = tid->an->maxampdu; |
1508 | if (maxampdu) | 1510 | if (maxampdu) |
1509 | aggr_limit = min(aggr_limit, maxampdu); | 1511 | aggr_limit = min(aggr_limit, maxampdu); |
1510 | 1512 | ||
@@ -1518,6 +1520,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, | |||
1518 | */ | 1520 | */ |
1519 | 1521 | ||
1520 | static int ath_compute_num_delims(struct ath_softc *sc, | 1522 | static int ath_compute_num_delims(struct ath_softc *sc, |
1523 | struct ath_atx_tid *tid, | ||
1521 | struct ath_buf *bf, | 1524 | struct ath_buf *bf, |
1522 | u16 frmlen) | 1525 | u16 frmlen) |
1523 | { | 1526 | { |
@@ -1545,7 +1548,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, | |||
1545 | * required minimum length for subframe. Take into account | 1548 | * required minimum length for subframe. Take into account |
1546 | * whether high rate is 20 or 40Mhz and half or full GI. | 1549 | * whether high rate is 20 or 40Mhz and half or full GI. |
1547 | */ | 1550 | */ |
1548 | mpdudensity = sc->sc_ht_info.mpdudensity; | 1551 | mpdudensity = tid->an->mpdudensity; |
1549 | 1552 | ||
1550 | /* | 1553 | /* |
1551 | * If there is no mpdu density restriction, no further calculation | 1554 | * If there is no mpdu density restriction, no further calculation |
@@ -1619,7 +1622,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | |||
1619 | } | 1622 | } |
1620 | 1623 | ||
1621 | if (!rl) { | 1624 | if (!rl) { |
1622 | aggr_limit = ath_lookup_rate(sc, bf); | 1625 | aggr_limit = ath_lookup_rate(sc, bf, tid); |
1623 | rl = 1; | 1626 | rl = 1; |
1624 | /* | 1627 | /* |
1625 | * Is rate dual stream | 1628 | * Is rate dual stream |
@@ -1657,7 +1660,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | |||
1657 | * Get the delimiters needed to meet the MPDU | 1660 | * Get the delimiters needed to meet the MPDU |
1658 | * density for this node. | 1661 | * density for this node. |
1659 | */ | 1662 | */ |
1660 | ndelim = ath_compute_num_delims(sc, bf_first, bf->bf_frmlen); | 1663 | ndelim = ath_compute_num_delims(sc, tid, bf_first, bf->bf_frmlen); |
1661 | 1664 | ||
1662 | bpad = PADBYTES(al_delta) + (ndelim << 2); | 1665 | bpad = PADBYTES(al_delta) + (ndelim << 2); |
1663 | 1666 | ||
@@ -2629,7 +2632,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) | |||
2629 | struct ath_atx_ac *ac; | 2632 | struct ath_atx_ac *ac; |
2630 | int tidno, acno; | 2633 | int tidno, acno; |
2631 | 2634 | ||
2632 | sc->sc_ht_info.maxampdu = ATH_AMPDU_LIMIT_DEFAULT; | 2635 | an->maxampdu = ATH_AMPDU_LIMIT_DEFAULT; |
2633 | 2636 | ||
2634 | /* | 2637 | /* |
2635 | * Init per tid tx state | 2638 | * Init per tid tx state |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index cd1bff590491..e10e0ca09ce9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -1133,8 +1133,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, | |||
1133 | s32 rate; | 1133 | s32 rate; |
1134 | s8 is_green = lq_sta->is_green; | 1134 | s8 is_green = lq_sta->is_green; |
1135 | 1135 | ||
1136 | if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) || | 1136 | if (!conf->ht.enabled || !sta->ht_cap.ht_supported) |
1137 | !sta->ht_cap.ht_supported) | ||
1138 | return -1; | 1137 | return -1; |
1139 | 1138 | ||
1140 | if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2) | 1139 | if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2) |
@@ -1201,8 +1200,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv, | |||
1201 | u8 is_green = lq_sta->is_green; | 1200 | u8 is_green = lq_sta->is_green; |
1202 | s32 rate; | 1201 | s32 rate; |
1203 | 1202 | ||
1204 | if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) || | 1203 | if (!conf->ht.enabled || !sta->ht_cap.ht_supported) |
1205 | !sta->ht_cap.ht_supported) | ||
1206 | return -1; | 1204 | return -1; |
1207 | 1205 | ||
1208 | IWL_DEBUG_RATE("LQ: try to switch to SISO\n"); | 1206 | IWL_DEBUG_RATE("LQ: try to switch to SISO\n"); |
@@ -2001,9 +1999,8 @@ lq_update: | |||
2001 | * stay with best antenna legacy modulation for a while | 1999 | * stay with best antenna legacy modulation for a while |
2002 | * before next round of mode comparisons. */ | 2000 | * before next round of mode comparisons. */ |
2003 | tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); | 2001 | tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); |
2004 | if (is_legacy(tbl1->lq_type) && | 2002 | if (is_legacy(tbl1->lq_type) && !conf->ht.enabled && |
2005 | (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) && | 2003 | lq_sta->action_counter >= 1) { |
2006 | (lq_sta->action_counter >= 1)) { | ||
2007 | lq_sta->action_counter = 0; | 2004 | lq_sta->action_counter = 0; |
2008 | IWL_DEBUG_RATE("LQ: STAY in legacy table\n"); | 2005 | IWL_DEBUG_RATE("LQ: STAY in legacy table\n"); |
2009 | rs_set_stay_in_table(priv, 1, lq_sta); | 2006 | rs_set_stay_in_table(priv, 1, lq_sta); |
@@ -2238,19 +2235,19 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, | |||
2238 | * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), | 2235 | * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), |
2239 | * supp_rates[] does not; shift to convert format, force 9 MBits off. | 2236 | * supp_rates[] does not; shift to convert format, force 9 MBits off. |
2240 | */ | 2237 | */ |
2241 | lq_sta->active_siso_rate = conf->ht_cap.mcs.rx_mask[0] << 1; | 2238 | lq_sta->active_siso_rate = sta->ht_cap.mcs.rx_mask[0] << 1; |
2242 | lq_sta->active_siso_rate |= conf->ht_cap.mcs.rx_mask[0] & 0x1; | 2239 | lq_sta->active_siso_rate |= sta->ht_cap.mcs.rx_mask[0] & 0x1; |
2243 | lq_sta->active_siso_rate &= ~((u16)0x2); | 2240 | lq_sta->active_siso_rate &= ~((u16)0x2); |
2244 | lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE; | 2241 | lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE; |
2245 | 2242 | ||
2246 | /* Same here */ | 2243 | /* Same here */ |
2247 | lq_sta->active_mimo2_rate = conf->ht_cap.mcs.rx_mask[1] << 1; | 2244 | lq_sta->active_mimo2_rate = sta->ht_cap.mcs.rx_mask[1] << 1; |
2248 | lq_sta->active_mimo2_rate |= conf->ht_cap.mcs.rx_mask[1] & 0x1; | 2245 | lq_sta->active_mimo2_rate |= sta->ht_cap.mcs.rx_mask[1] & 0x1; |
2249 | lq_sta->active_mimo2_rate &= ~((u16)0x2); | 2246 | lq_sta->active_mimo2_rate &= ~((u16)0x2); |
2250 | lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; | 2247 | lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; |
2251 | 2248 | ||
2252 | lq_sta->active_mimo3_rate = conf->ht_cap.mcs.rx_mask[2] << 1; | 2249 | lq_sta->active_mimo3_rate = sta->ht_cap.mcs.rx_mask[2] << 1; |
2253 | lq_sta->active_mimo3_rate |= conf->ht_cap.mcs.rx_mask[2] & 0x1; | 2250 | lq_sta->active_mimo3_rate |= sta->ht_cap.mcs.rx_mask[2] & 0x1; |
2254 | lq_sta->active_mimo3_rate &= ~((u16)0x2); | 2251 | lq_sta->active_mimo3_rate &= ~((u16)0x2); |
2255 | lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE; | 2252 | lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE; |
2256 | 2253 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 79a24410dd0a..7c3eb3d8f7e7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -552,17 +552,30 @@ static int iwl4965_send_beacon_cmd(struct iwl_priv *priv) | |||
552 | static void iwl4965_ht_conf(struct iwl_priv *priv, | 552 | static void iwl4965_ht_conf(struct iwl_priv *priv, |
553 | struct ieee80211_bss_conf *bss_conf) | 553 | struct ieee80211_bss_conf *bss_conf) |
554 | { | 554 | { |
555 | struct ieee80211_sta_ht_cap *ht_conf = bss_conf->ht_cap; | 555 | struct ieee80211_sta_ht_cap *ht_conf; |
556 | struct ieee80211_ht_bss_info *ht_bss_conf = bss_conf->ht_bss_conf; | ||
557 | struct iwl_ht_info *iwl_conf = &priv->current_ht_config; | 556 | struct iwl_ht_info *iwl_conf = &priv->current_ht_config; |
557 | struct ieee80211_sta *sta; | ||
558 | 558 | ||
559 | IWL_DEBUG_MAC80211("enter: \n"); | 559 | IWL_DEBUG_MAC80211("enter: \n"); |
560 | 560 | ||
561 | iwl_conf->is_ht = bss_conf->assoc_ht; | ||
562 | |||
563 | if (!iwl_conf->is_ht) | 561 | if (!iwl_conf->is_ht) |
564 | return; | 562 | return; |
565 | 563 | ||
564 | |||
565 | /* | ||
566 | * It is totally wrong to base global information on something | ||
567 | * that is valid only when associated, alas, this driver works | ||
568 | * that way and I don't know how to fix it. | ||
569 | */ | ||
570 | |||
571 | rcu_read_lock(); | ||
572 | sta = ieee80211_find_sta(priv->hw, priv->bssid); | ||
573 | if (!sta) { | ||
574 | rcu_read_unlock(); | ||
575 | return; | ||
576 | } | ||
577 | ht_conf = &sta->ht_cap; | ||
578 | |||
566 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20) | 579 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20) |
567 | iwl_conf->sgf |= HT_SHORT_GI_20MHZ; | 580 | iwl_conf->sgf |= HT_SHORT_GI_20MHZ; |
568 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40) | 581 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40) |
@@ -574,8 +587,8 @@ static void iwl4965_ht_conf(struct iwl_priv *priv, | |||
574 | 587 | ||
575 | iwl_conf->supported_chan_width = | 588 | iwl_conf->supported_chan_width = |
576 | !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40); | 589 | !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40); |
577 | iwl_conf->extension_chan_offset = | 590 | |
578 | ht_bss_conf->bss_cap & IEEE80211_HT_PARAM_CHA_SEC_OFFSET; | 591 | iwl_conf->extension_chan_offset = bss_conf->ht.secondary_channel_offset; |
579 | /* If no above or below channel supplied disable FAT channel */ | 592 | /* If no above or below channel supplied disable FAT channel */ |
580 | if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE && | 593 | if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE && |
581 | iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW) { | 594 | iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW) { |
@@ -587,15 +600,14 @@ static void iwl4965_ht_conf(struct iwl_priv *priv, | |||
587 | 600 | ||
588 | memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16); | 601 | memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16); |
589 | 602 | ||
590 | iwl_conf->control_channel = ht_bss_conf->primary_channel; | 603 | iwl_conf->tx_chan_width = bss_conf->ht.width_40_ok; |
591 | iwl_conf->tx_chan_width = | ||
592 | !!(ht_bss_conf->bss_cap & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY); | ||
593 | iwl_conf->ht_protection = | 604 | iwl_conf->ht_protection = |
594 | ht_bss_conf->bss_op_mode & IEEE80211_HT_OP_MODE_PROTECTION; | 605 | bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; |
595 | iwl_conf->non_GF_STA_present = | 606 | iwl_conf->non_GF_STA_present = |
596 | !!(ht_bss_conf->bss_op_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); | 607 | !!(bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); |
608 | |||
609 | rcu_read_unlock(); | ||
597 | 610 | ||
598 | IWL_DEBUG_MAC80211("control channel %d\n", iwl_conf->control_channel); | ||
599 | IWL_DEBUG_MAC80211("leave\n"); | 611 | IWL_DEBUG_MAC80211("leave\n"); |
600 | } | 612 | } |
601 | 613 | ||
@@ -2746,6 +2758,8 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
2746 | mutex_lock(&priv->mutex); | 2758 | mutex_lock(&priv->mutex); |
2747 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value); | 2759 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value); |
2748 | 2760 | ||
2761 | priv->current_ht_config.is_ht = conf->ht.enabled; | ||
2762 | |||
2749 | if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) { | 2763 | if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) { |
2750 | IWL_DEBUG_MAC80211("leave - RF-KILL - waiting for uCode\n"); | 2764 | IWL_DEBUG_MAC80211("leave - RF-KILL - waiting for uCode\n"); |
2751 | goto out; | 2765 | goto out; |
@@ -3104,7 +3118,6 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw, | |||
3104 | } | 3118 | } |
3105 | 3119 | ||
3106 | if (changes & BSS_CHANGED_HT) { | 3120 | if (changes & BSS_CHANGED_HT) { |
3107 | IWL_DEBUG_MAC80211("HT %d\n", bss_conf->assoc_ht); | ||
3108 | iwl4965_ht_conf(priv, bss_conf); | 3121 | iwl4965_ht_conf(priv, bss_conf); |
3109 | iwl_set_rxon_chain(priv); | 3122 | iwl_set_rxon_chain(priv); |
3110 | } | 3123 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 4678da447ff6..10f5a0a233fe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -637,8 +637,8 @@ u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, | |||
637 | } | 637 | } |
638 | 638 | ||
639 | return iwl_is_channel_extension(priv, priv->band, | 639 | return iwl_is_channel_extension(priv, priv->band, |
640 | iwl_ht_conf->control_channel, | 640 | le16_to_cpu(priv->staging_rxon.channel), |
641 | iwl_ht_conf->extension_chan_offset); | 641 | iwl_ht_conf->extension_chan_offset); |
642 | } | 642 | } |
643 | EXPORT_SYMBOL(iwl_is_fat_tx_allowed); | 643 | EXPORT_SYMBOL(iwl_is_fat_tx_allowed); |
644 | 644 | ||
@@ -663,13 +663,6 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) | |||
663 | rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK | | 663 | rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK | |
664 | RXON_FLG_CHANNEL_MODE_PURE_40_MSK); | 664 | RXON_FLG_CHANNEL_MODE_PURE_40_MSK); |
665 | 665 | ||
666 | if (le16_to_cpu(rxon->channel) != ht_info->control_channel) { | ||
667 | IWL_DEBUG_ASSOC("control diff than current %d %d\n", | ||
668 | le16_to_cpu(rxon->channel), | ||
669 | ht_info->control_channel); | ||
670 | return; | ||
671 | } | ||
672 | |||
673 | /* Note: control channel is opposite of extension channel */ | 666 | /* Note: control channel is opposite of extension channel */ |
674 | switch (ht_info->extension_chan_offset) { | 667 | switch (ht_info->extension_chan_offset) { |
675 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | 668 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
@@ -692,14 +685,12 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) | |||
692 | 685 | ||
693 | IWL_DEBUG_ASSOC("supported HT rate 0x%X 0x%X 0x%X " | 686 | IWL_DEBUG_ASSOC("supported HT rate 0x%X 0x%X 0x%X " |
694 | "rxon flags 0x%X operation mode :0x%X " | 687 | "rxon flags 0x%X operation mode :0x%X " |
695 | "extension channel offset 0x%x " | 688 | "extension channel offset 0x%x\n", |
696 | "control chan %d\n", | ||
697 | ht_info->mcs.rx_mask[0], | 689 | ht_info->mcs.rx_mask[0], |
698 | ht_info->mcs.rx_mask[1], | 690 | ht_info->mcs.rx_mask[1], |
699 | ht_info->mcs.rx_mask[2], | 691 | ht_info->mcs.rx_mask[2], |
700 | le32_to_cpu(rxon->flags), ht_info->ht_protection, | 692 | le32_to_cpu(rxon->flags), ht_info->ht_protection, |
701 | ht_info->extension_chan_offset, | 693 | ht_info->extension_chan_offset); |
702 | ht_info->control_channel); | ||
703 | return; | 694 | return; |
704 | } | 695 | } |
705 | EXPORT_SYMBOL(iwl_set_rxon_ht); | 696 | EXPORT_SYMBOL(iwl_set_rxon_ht); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 572250ee9d58..2e9514933970 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -413,7 +413,6 @@ struct iwl_ht_info { | |||
413 | u8 mpdu_density; | 413 | u8 mpdu_density; |
414 | struct ieee80211_mcs_info mcs; | 414 | struct ieee80211_mcs_info mcs; |
415 | /* BSS related data */ | 415 | /* BSS related data */ |
416 | u8 control_channel; | ||
417 | u8 extension_chan_offset; | 416 | u8 extension_chan_offset; |
418 | u8 tx_chan_width; | 417 | u8 tx_chan_width; |
419 | u8 ht_protection; | 418 | u8 ht_protection; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index b9b8554433a6..218483d096cc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -890,20 +890,31 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap) | |||
890 | */ | 890 | */ |
891 | int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) | 891 | int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) |
892 | { | 892 | { |
893 | struct ieee80211_sta *sta; | ||
894 | struct ieee80211_sta_ht_cap ht_config; | ||
895 | struct ieee80211_sta_ht_cap *cur_ht_config = NULL; | ||
893 | u8 sta_id; | 896 | u8 sta_id; |
894 | 897 | ||
895 | /* Add station to device's station table */ | 898 | /* Add station to device's station table */ |
896 | struct ieee80211_conf *conf = &priv->hw->conf; | 899 | |
897 | struct ieee80211_sta_ht_cap *cur_ht_config = &conf->ht_cap; | 900 | /* |
898 | 901 | * XXX: This check is definitely not correct, if we're an AP | |
899 | if ((is_ap) && | 902 | * it'll always be false which is not what we want, but |
900 | (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) && | 903 | * it doesn't look like iwlagn is prepared to be an HT |
901 | (priv->iw_mode == NL80211_IFTYPE_STATION)) | 904 | * AP anyway. |
902 | sta_id = iwl_add_station_flags(priv, addr, is_ap, | 905 | */ |
903 | 0, cur_ht_config); | 906 | if (priv->current_ht_config.is_ht) { |
904 | else | 907 | rcu_read_lock(); |
905 | sta_id = iwl_add_station_flags(priv, addr, is_ap, | 908 | sta = ieee80211_find_sta(priv->hw, addr); |
906 | 0, NULL); | 909 | if (sta) { |
910 | memcpy(&ht_config, &sta->ht_cap, sizeof(ht_config)); | ||
911 | cur_ht_config = &ht_config; | ||
912 | } | ||
913 | rcu_read_unlock(); | ||
914 | } | ||
915 | |||
916 | sta_id = iwl_add_station_flags(priv, addr, is_ap, | ||
917 | 0, cur_ht_config); | ||
907 | 918 | ||
908 | /* Set up default rate scaling table in device's station table */ | 919 | /* Set up default rate scaling table in device's station table */ |
909 | iwl_sta_init_lq(priv, addr, is_ap); | 920 | iwl_sta_init_lq(priv, addr, is_ap); |