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: Pat Erley <pat-lkml@erley.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Родитель
d8cd7effc2
Коммит
9cb5412b07
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
* 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,
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
/* 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,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче