diff options
-rw-r--r-- | drivers/net/wireless/ath9k/core.h | 47 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/main.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/rc.c | 82 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/rc.h | 2 |
4 files changed, 50 insertions, 85 deletions
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 5500ef49d8bb..2ff33b80b485 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h | |||
@@ -540,6 +540,29 @@ void ath_newassoc(struct ath_softc *sc, | |||
540 | void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta); | 540 | void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta); |
541 | void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta); | 541 | void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta); |
542 | 542 | ||
543 | /********/ | ||
544 | /* VAPs */ | ||
545 | /********/ | ||
546 | |||
547 | /* | ||
548 | * Define the scheme that we select MAC address for multiple | ||
549 | * BSS on the same radio. The very first VAP will just use the MAC | ||
550 | * address from the EEPROM. For the next 3 VAPs, we set the | ||
551 | * U/L bit (bit 1) in MAC address, and use the next two bits as the | ||
552 | * index of the VAP. | ||
553 | */ | ||
554 | |||
555 | #define ATH_SET_VAP_BSSID_MASK(bssid_mask) \ | ||
556 | ((bssid_mask)[0] &= ~(((ATH_BCBUF-1)<<2)|0x02)) | ||
557 | |||
558 | /* driver-specific vap state */ | ||
559 | struct ath_vap { | ||
560 | int av_bslot; /* beacon slot index */ | ||
561 | enum ath9k_opmode av_opmode; /* VAP operational mode */ | ||
562 | struct ath_buf *av_bcbuf; /* beacon buffer */ | ||
563 | struct ath_tx_control av_btxctl; /* txctl information for beacon */ | ||
564 | }; | ||
565 | |||
543 | /*******************/ | 566 | /*******************/ |
544 | /* Beacon Handling */ | 567 | /* Beacon Handling */ |
545 | /*******************/ | 568 | /*******************/ |
@@ -579,30 +602,6 @@ void ath_beacon_sync(struct ath_softc *sc, int if_id); | |||
579 | void ath_get_beaconconfig(struct ath_softc *sc, | 602 | void ath_get_beaconconfig(struct ath_softc *sc, |
580 | int if_id, | 603 | int if_id, |
581 | struct ath_beacon_config *conf); | 604 | struct ath_beacon_config *conf); |
582 | /********/ | ||
583 | /* VAPs */ | ||
584 | /********/ | ||
585 | |||
586 | /* | ||
587 | * Define the scheme that we select MAC address for multiple | ||
588 | * BSS on the same radio. The very first VAP will just use the MAC | ||
589 | * address from the EEPROM. For the next 3 VAPs, we set the | ||
590 | * U/L bit (bit 1) in MAC address, and use the next two bits as the | ||
591 | * index of the VAP. | ||
592 | */ | ||
593 | |||
594 | #define ATH_SET_VAP_BSSID_MASK(bssid_mask) \ | ||
595 | ((bssid_mask)[0] &= ~(((ATH_BCBUF-1)<<2)|0x02)) | ||
596 | |||
597 | /* driver-specific vap state */ | ||
598 | struct ath_vap { | ||
599 | int av_bslot; /* beacon slot index */ | ||
600 | enum ath9k_opmode av_opmode; /* VAP operational mode */ | ||
601 | struct ath_buf *av_bcbuf; /* beacon buffer */ | ||
602 | struct ath_tx_control av_btxctl; /* txctl information for beacon */ | ||
603 | struct ath_rate_node *rc_node; | ||
604 | }; | ||
605 | |||
606 | /*********************/ | 605 | /*********************/ |
607 | /* Antenna diversity */ | 606 | /* Antenna diversity */ |
608 | /*********************/ | 607 | /*********************/ |
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index c9ac5e8acffa..7b843820fa66 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c | |||
@@ -316,10 +316,6 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, | |||
316 | DPRINTF(sc, ATH_DBG_FATAL, | 316 | DPRINTF(sc, ATH_DBG_FATAL, |
317 | "%s: Unable to set channel\n", | 317 | "%s: Unable to set channel\n", |
318 | __func__); | 318 | __func__); |
319 | |||
320 | /* Update ratectrl about the new state */ | ||
321 | ath_rc_node_update(hw, avp->rc_node); | ||
322 | |||
323 | /* Start ANI */ | 319 | /* Start ANI */ |
324 | mod_timer(&sc->sc_ani.timer, | 320 | mod_timer(&sc->sc_ani.timer, |
325 | jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); | 321 | jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); |
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 8a45b2502d23..0fa1b30bdcb6 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c | |||
@@ -1446,35 +1446,39 @@ static void ath_rate_tx_complete(struct ath_softc *sc, | |||
1446 | info_priv->tx.ts_longretry); | 1446 | info_priv->tx.ts_longretry); |
1447 | } | 1447 | } |
1448 | 1448 | ||
1449 | /* | 1449 | static void ath_rc_init(struct ath_softc *sc, |
1450 | * Update the SIB's rate control information | 1450 | struct ath_rate_node *ath_rc_priv, |
1451 | * | 1451 | struct ieee80211_supported_band *sband, |
1452 | * This should be called when the supported rates change | 1452 | struct ieee80211_sta *sta) |
1453 | * (e.g. SME operation, wireless mode change) | ||
1454 | * | ||
1455 | * It will determine which rates are valid for use. | ||
1456 | */ | ||
1457 | static void ath_rc_sib_update(struct ath_softc *sc, | ||
1458 | struct ath_rate_node *ath_rc_priv, | ||
1459 | u32 capflag, int keep_state, | ||
1460 | struct ath_rateset *negotiated_rates, | ||
1461 | struct ath_rateset *negotiated_htrates) | ||
1462 | { | 1453 | { |
1463 | struct ath_rate_table *rate_table = NULL; | 1454 | struct ath_rate_table *rate_table = NULL; |
1464 | struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc; | 1455 | struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc; |
1465 | struct ath_rateset *rateset = negotiated_rates; | 1456 | struct ath_rateset *rateset = &ath_rc_priv->neg_rates; |
1466 | u8 *ht_mcs = (u8 *)negotiated_htrates; | 1457 | u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates; |
1467 | u8 i, j, k, hi = 0, hthi = 0; | 1458 | u8 i, j, k, hi = 0, hthi = 0; |
1468 | 1459 | ||
1469 | rate_table = (struct ath_rate_table *) | 1460 | rate_table = (struct ath_rate_table *) |
1470 | asc->hw_rate_table[sc->sc_curmode]; | 1461 | asc->hw_rate_table[sc->sc_curmode]; |
1471 | 1462 | ||
1463 | if (sta->ht_cap.ht_supported) { | ||
1464 | if (sband->band == IEEE80211_BAND_2GHZ) | ||
1465 | rate_table = (struct ath_rate_table *) | ||
1466 | asc->hw_rate_table[ATH9K_MODE_11NG_HT20]; | ||
1467 | else | ||
1468 | rate_table = (struct ath_rate_table *) | ||
1469 | asc->hw_rate_table[ATH9K_MODE_11NA_HT20]; | ||
1470 | |||
1471 | ath_rc_priv->ht_cap = (WLAN_RC_HT_FLAG | WLAN_RC_DS_FLAG); | ||
1472 | if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) | ||
1473 | ath_rc_priv->ht_cap |= WLAN_RC_40_FLAG; | ||
1474 | } | ||
1475 | |||
1472 | /* Initial rate table size. Will change depending | 1476 | /* Initial rate table size. Will change depending |
1473 | * on the working rate set */ | 1477 | * on the working rate set */ |
1474 | ath_rc_priv->rate_table_size = MAX_TX_RATE_TBL; | 1478 | ath_rc_priv->rate_table_size = MAX_TX_RATE_TBL; |
1475 | 1479 | ||
1476 | /* Initialize thresholds according to the global rate table */ | 1480 | /* Initialize thresholds according to the global rate table */ |
1477 | for (i = 0 ; (i < ath_rc_priv->rate_table_size) && (!keep_state); i++) { | 1481 | for (i = 0 ; i < ath_rc_priv->rate_table_size; i++) { |
1478 | ath_rc_priv->state[i].rssi_thres = | 1482 | ath_rc_priv->state[i].rssi_thres = |
1479 | rate_table->info[i].rssi_ack_validmin; | 1483 | rate_table->info[i].rssi_ack_validmin; |
1480 | ath_rc_priv->state[i].per = 0; | 1484 | ath_rc_priv->state[i].per = 0; |
@@ -1488,24 +1492,24 @@ static void ath_rc_sib_update(struct ath_softc *sc, | |||
1488 | ath_rc_priv->valid_phy_rateidx[i][j] = 0; | 1492 | ath_rc_priv->valid_phy_rateidx[i][j] = 0; |
1489 | ath_rc_priv->valid_phy_ratecnt[i] = 0; | 1493 | ath_rc_priv->valid_phy_ratecnt[i] = 0; |
1490 | } | 1494 | } |
1491 | ath_rc_priv->rc_phy_mode = (capflag & WLAN_RC_40_FLAG); | 1495 | ath_rc_priv->rc_phy_mode = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG); |
1492 | 1496 | ||
1493 | /* Set stream capability */ | 1497 | /* Set stream capability */ |
1494 | ath_rc_priv->single_stream = (capflag & WLAN_RC_DS_FLAG) ? 0 : 1; | 1498 | ath_rc_priv->single_stream = (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? 0 : 1; |
1495 | 1499 | ||
1496 | if (!rateset->rs_nrates) { | 1500 | if (!rateset->rs_nrates) { |
1497 | /* No working rate, just initialize valid rates */ | 1501 | /* No working rate, just initialize valid rates */ |
1498 | hi = ath_rc_sib_init_validrates(ath_rc_priv, rate_table, | 1502 | hi = ath_rc_sib_init_validrates(ath_rc_priv, rate_table, |
1499 | capflag); | 1503 | ath_rc_priv->ht_cap); |
1500 | } else { | 1504 | } else { |
1501 | /* Use intersection of working rates and valid rates */ | 1505 | /* Use intersection of working rates and valid rates */ |
1502 | hi = ath_rc_sib_setvalid_rates(ath_rc_priv, rate_table, | 1506 | hi = ath_rc_sib_setvalid_rates(ath_rc_priv, rate_table, |
1503 | rateset, capflag); | 1507 | rateset, ath_rc_priv->ht_cap); |
1504 | if (capflag & WLAN_RC_HT_FLAG) { | 1508 | if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) { |
1505 | hthi = ath_rc_sib_setvalid_htrates(ath_rc_priv, | 1509 | hthi = ath_rc_sib_setvalid_htrates(ath_rc_priv, |
1506 | rate_table, | 1510 | rate_table, |
1507 | ht_mcs, | 1511 | ht_mcs, |
1508 | capflag); | 1512 | ath_rc_priv->ht_cap); |
1509 | } | 1513 | } |
1510 | hi = A_MAX(hi, hthi); | 1514 | hi = A_MAX(hi, hthi); |
1511 | } | 1515 | } |
@@ -1539,29 +1543,6 @@ static void ath_rc_sib_update(struct ath_softc *sc, | |||
1539 | ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4]; | 1543 | ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4]; |
1540 | } | 1544 | } |
1541 | 1545 | ||
1542 | void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv) | ||
1543 | { | ||
1544 | struct ath_softc *sc = hw->priv; | ||
1545 | u32 capflag = 0; | ||
1546 | |||
1547 | if (hw->conf.ht.enabled) { | ||
1548 | capflag |= ATH_RC_HT_FLAG | ATH_RC_DS_FLAG; | ||
1549 | if (sc->sc_ht_info.tx_chan_width == ATH9K_HT_MACMODE_2040) | ||
1550 | capflag |= ATH_RC_CW40_FLAG; | ||
1551 | } | ||
1552 | |||
1553 | rc_priv->ht_cap = | ||
1554 | ((capflag & ATH_RC_DS_FLAG) ? WLAN_RC_DS_FLAG : 0) | | ||
1555 | ((capflag & ATH_RC_SGI_FLAG) ? WLAN_RC_SGI_FLAG : 0) | | ||
1556 | ((capflag & ATH_RC_HT_FLAG) ? WLAN_RC_HT_FLAG : 0) | | ||
1557 | ((capflag & ATH_RC_CW40_FLAG) ? WLAN_RC_40_FLAG : 0); | ||
1558 | |||
1559 | |||
1560 | ath_rc_sib_update(sc, rc_priv, rc_priv->ht_cap, 0, | ||
1561 | &rc_priv->neg_rates, | ||
1562 | &rc_priv->neg_ht_rates); | ||
1563 | } | ||
1564 | |||
1565 | /* Rate Control callbacks */ | 1546 | /* Rate Control callbacks */ |
1566 | static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | 1547 | static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, |
1567 | struct ieee80211_sta *sta, void *priv_sta, | 1548 | struct ieee80211_sta *sta, void *priv_sta, |
@@ -1684,7 +1665,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
1684 | ath_rc_priv->neg_ht_rates.rs_nrates = j; | 1665 | ath_rc_priv->neg_ht_rates.rs_nrates = j; |
1685 | } | 1666 | } |
1686 | 1667 | ||
1687 | ath_rc_node_update(sc->hw, priv_sta); | 1668 | ath_rc_init(sc, priv_sta, sband, sta); |
1688 | } | 1669 | } |
1689 | 1670 | ||
1690 | static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) | 1671 | static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) |
@@ -1699,16 +1680,9 @@ static void ath_rate_free(void *priv) | |||
1699 | 1680 | ||
1700 | static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) | 1681 | static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) |
1701 | { | 1682 | { |
1702 | struct ieee80211_vif *vif; | ||
1703 | struct ath_softc *sc = priv; | 1683 | struct ath_softc *sc = priv; |
1704 | struct ath_vap *avp; | ||
1705 | struct ath_rate_node *rate_priv; | 1684 | struct ath_rate_node *rate_priv; |
1706 | 1685 | ||
1707 | vif = sc->sc_vaps[0]; | ||
1708 | ASSERT(vif); | ||
1709 | |||
1710 | avp = (void *)vif->drv_priv; | ||
1711 | |||
1712 | rate_priv = kzalloc(sizeof(struct ath_rate_node), gfp); | 1686 | rate_priv = kzalloc(sizeof(struct ath_rate_node), gfp); |
1713 | if (!rate_priv) { | 1687 | if (!rate_priv) { |
1714 | DPRINTF(sc, ATH_DBG_FATAL, | 1688 | DPRINTF(sc, ATH_DBG_FATAL, |
@@ -1717,9 +1691,7 @@ static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp | |||
1717 | return NULL; | 1691 | return NULL; |
1718 | } | 1692 | } |
1719 | 1693 | ||
1720 | rate_priv->avp = avp; | ||
1721 | rate_priv->asc = sc->sc_rc; | 1694 | rate_priv->asc = sc->sc_rc; |
1722 | avp->rc_node = rate_priv; | ||
1723 | rate_priv->rssi_down_time = jiffies_to_msecs(jiffies); | 1695 | rate_priv->rssi_down_time = jiffies_to_msecs(jiffies); |
1724 | 1696 | ||
1725 | return rate_priv; | 1697 | return rate_priv; |
diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h index 8d0650a510a2..07319c6c2e02 100644 --- a/drivers/net/wireless/ath9k/rc.h +++ b/drivers/net/wireless/ath9k/rc.h | |||
@@ -265,7 +265,6 @@ struct ath_rate_node { | |||
265 | struct ath_rateset neg_rates; | 265 | struct ath_rateset neg_rates; |
266 | struct ath_rateset neg_ht_rates; | 266 | struct ath_rateset neg_ht_rates; |
267 | struct ath_rate_softc *asc; | 267 | struct ath_rate_softc *asc; |
268 | struct ath_vap *avp; | ||
269 | }; | 268 | }; |
270 | 269 | ||
271 | /* Driver data of ieee80211_tx_info */ | 270 | /* Driver data of ieee80211_tx_info */ |
@@ -279,7 +278,6 @@ struct ath_tx_info_priv { | |||
279 | 278 | ||
280 | struct ath_rate_softc *ath_rate_attach(struct ath_softc *sch); | 279 | struct ath_rate_softc *ath_rate_attach(struct ath_softc *sch); |
281 | void ath_rate_detach(struct ath_rate_softc *asc); | 280 | void ath_rate_detach(struct ath_rate_softc *asc); |
282 | void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv); | ||
283 | u8 ath_rate_findrateix(struct ath_softc *sc, u8 dot11_rate); | 281 | u8 ath_rate_findrateix(struct ath_softc *sc, u8 dot11_rate); |
284 | int ath_rate_control_register(void); | 282 | int ath_rate_control_register(void); |
285 | void ath_rate_control_unregister(void); | 283 | void ath_rate_control_unregister(void); |