aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath9k/core.h47
-rw-r--r--drivers/net/wireless/ath9k/main.c4
-rw-r--r--drivers/net/wireless/ath9k/rc.c82
-rw-r--r--drivers/net/wireless/ath9k/rc.h2
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,
540void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta); 540void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta);
541void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta); 541void 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 */
559struct 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);
579void ath_get_beaconconfig(struct ath_softc *sc, 602void 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 */
598struct 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/* 1449static 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 */
1457static 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
1542void 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 */
1566static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, 1547static 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
1690static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 1671static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
@@ -1699,16 +1680,9 @@ static void ath_rate_free(void *priv)
1699 1680
1700static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) 1681static 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
280struct ath_rate_softc *ath_rate_attach(struct ath_softc *sch); 279struct ath_rate_softc *ath_rate_attach(struct ath_softc *sch);
281void ath_rate_detach(struct ath_rate_softc *asc); 280void ath_rate_detach(struct ath_rate_softc *asc);
282void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv);
283u8 ath_rate_findrateix(struct ath_softc *sc, u8 dot11_rate); 281u8 ath_rate_findrateix(struct ath_softc *sc, u8 dot11_rate);
284int ath_rate_control_register(void); 282int ath_rate_control_register(void);
285void ath_rate_control_unregister(void); 283void ath_rate_control_unregister(void);