提交 9cb5412b 编写于 作者: P Pat Erley 提交者: John W. Linville

Add mesh point functionality to ath9k

This patch enables mesh point operation for ath9k.  Tested with b43,
ath9k, rt2500usb, and ath5k as peers.
Signed-off-by: NPat Erley <pat-lkml@erley.org>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 d8cd7eff
...@@ -70,7 +70,8 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, ...@@ -70,7 +70,8 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
ds = bf->bf_desc; ds = bf->bf_desc;
flags = ATH9K_TXDESC_NOACK; flags = ATH9K_TXDESC_NOACK;
if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC && if (((sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
(sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) &&
(ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) { (ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
ds->ds_link = bf->bf_daddr; /* self-linked */ ds->ds_link = bf->bf_daddr; /* self-linked */
flags |= ATH9K_TXDESC_VEOL; flags |= ATH9K_TXDESC_VEOL;
...@@ -728,6 +729,7 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) ...@@ -728,6 +729,7 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
ath_beacon_config_ap(sc, &conf, avp); ath_beacon_config_ap(sc, &conf, avp);
break; break;
case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_MESH_POINT:
ath_beacon_config_adhoc(sc, &conf, avp, vif); ath_beacon_config_adhoc(sc, &conf, avp, vif);
break; break;
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
......
...@@ -1448,6 +1448,7 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode) ...@@ -1448,6 +1448,7 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
break; break;
case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_MESH_POINT:
REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
| AR_STA_ID1_KSRCH_MODE); | AR_STA_ID1_KSRCH_MODE);
REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
...@@ -3149,6 +3150,7 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) ...@@ -3149,6 +3150,7 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
flags |= AR_TBTT_TIMER_EN; flags |= AR_TBTT_TIMER_EN;
break; break;
case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_MESH_POINT:
REG_SET_BIT(ah, AR_TXCFG, REG_SET_BIT(ah, AR_TXCFG,
AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY); AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
REG_WRITE(ah, AR_NEXT_NDP_TIMER, REG_WRITE(ah, AR_NEXT_NDP_TIMER,
......
...@@ -1599,7 +1599,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) ...@@ -1599,7 +1599,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
hw->wiphy->interface_modes = hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC); BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_MESH_POINT);
hw->wiphy->reg_notifier = ath9k_reg_notifier; hw->wiphy->reg_notifier = ath9k_reg_notifier;
hw->wiphy->strict_regulatory = true; hw->wiphy->strict_regulatory = true;
...@@ -2207,18 +2208,13 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, ...@@ -2207,18 +2208,13 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
ic_opmode = NL80211_IFTYPE_STATION; ic_opmode = NL80211_IFTYPE_STATION;
break; break;
case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_ADHOC:
if (sc->nbcnvifs >= ATH_BCBUF) {
ret = -ENOBUFS;
goto out;
}
ic_opmode = NL80211_IFTYPE_ADHOC;
break;
case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_MESH_POINT:
if (sc->nbcnvifs >= ATH_BCBUF) { if (sc->nbcnvifs >= ATH_BCBUF) {
ret = -ENOBUFS; ret = -ENOBUFS;
goto out; goto out;
} }
ic_opmode = NL80211_IFTYPE_AP; ic_opmode = conf->type;
break; break;
default: default:
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
...@@ -2254,7 +2250,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, ...@@ -2254,7 +2250,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
* Note we only do this (at the moment) for station mode. * Note we only do this (at the moment) for station mode.
*/ */
if ((conf->type == NL80211_IFTYPE_STATION) || if ((conf->type == NL80211_IFTYPE_STATION) ||
(conf->type == NL80211_IFTYPE_ADHOC)) { (conf->type == NL80211_IFTYPE_ADHOC) ||
(conf->type == NL80211_IFTYPE_MESH_POINT)) {
if (ath9k_hw_phycounters(sc->sc_ah)) if (ath9k_hw_phycounters(sc->sc_ah))
sc->imask |= ATH9K_INT_MIB; sc->imask |= ATH9K_INT_MIB;
sc->imask |= ATH9K_INT_TSFOOR; sc->imask |= ATH9K_INT_TSFOOR;
...@@ -2301,8 +2298,9 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, ...@@ -2301,8 +2298,9 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
del_timer_sync(&sc->ani.timer); del_timer_sync(&sc->ani.timer);
/* Reclaim beacon resources */ /* Reclaim beacon resources */
if (sc->sc_ah->opmode == NL80211_IFTYPE_AP || if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) { (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
(sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
ath_beacon_return(sc, avp); ath_beacon_return(sc, avp);
} }
...@@ -2435,6 +2433,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, ...@@ -2435,6 +2433,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
switch (vif->type) { switch (vif->type) {
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_MESH_POINT:
/* Set BSSID */ /* Set BSSID */
memcpy(sc->curbssid, conf->bssid, ETH_ALEN); memcpy(sc->curbssid, conf->bssid, ETH_ALEN);
memcpy(avp->bssid, conf->bssid, ETH_ALEN); memcpy(avp->bssid, conf->bssid, ETH_ALEN);
...@@ -2458,7 +2457,8 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, ...@@ -2458,7 +2457,8 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
} }
if ((vif->type == NL80211_IFTYPE_ADHOC) || if ((vif->type == NL80211_IFTYPE_ADHOC) ||
(vif->type == NL80211_IFTYPE_AP)) { (vif->type == NL80211_IFTYPE_AP) ||
(vif->type == NL80211_IFTYPE_MESH_POINT)) {
if ((conf->changed & IEEE80211_IFCC_BEACON) || if ((conf->changed & IEEE80211_IFCC_BEACON) ||
(conf->changed & IEEE80211_IFCC_BEACON_ENABLED && (conf->changed & IEEE80211_IFCC_BEACON_ENABLED &&
conf->enable_beacon)) { conf->enable_beacon)) {
......
...@@ -1619,6 +1619,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, ...@@ -1619,6 +1619,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
/* Choose rate table first */ /* Choose rate table first */
if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) || if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) ||
(sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) ||
(sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) { (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
rate_table = ath_choose_rate_table(sc, sband->band, rate_table = ath_choose_rate_table(sc, sband->band,
sta->ht_cap.ht_supported, sta->ht_cap.ht_supported,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册