diff options
author | Pat Erley <pat-lkml@erley.org> | 2009-03-20 22:59:59 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-03-27 20:13:06 -0400 |
commit | 9cb5412b0760981d43ac3e612992c90cea690e72 (patch) | |
tree | 6ae9a5350899cf6106cd8510050f6ea1baa62f02 | |
parent | d8cd7effc20027c313d4086b123046ff9f9a5814 (diff) |
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>
-rw-r--r-- | drivers/net/wireless/ath9k/beacon.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/hw.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/main.c | 24 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/rc.c | 1 |
4 files changed, 18 insertions, 13 deletions
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index e5b007196ca1..ec995730632d 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c | |||
@@ -70,7 +70,8 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, | |||
70 | ds = bf->bf_desc; | 70 | ds = bf->bf_desc; |
71 | flags = ATH9K_TXDESC_NOACK; | 71 | flags = ATH9K_TXDESC_NOACK; |
72 | 72 | ||
73 | if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC && | 73 | if (((sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || |
74 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) && | ||
74 | (ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) { | 75 | (ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) { |
75 | ds->ds_link = bf->bf_daddr; /* self-linked */ | 76 | ds->ds_link = bf->bf_daddr; /* self-linked */ |
76 | flags |= ATH9K_TXDESC_VEOL; | 77 | flags |= ATH9K_TXDESC_VEOL; |
@@ -728,6 +729,7 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
728 | ath_beacon_config_ap(sc, &conf, avp); | 729 | ath_beacon_config_ap(sc, &conf, avp); |
729 | break; | 730 | break; |
730 | case NL80211_IFTYPE_ADHOC: | 731 | case NL80211_IFTYPE_ADHOC: |
732 | case NL80211_IFTYPE_MESH_POINT: | ||
731 | ath_beacon_config_adhoc(sc, &conf, avp, vif); | 733 | ath_beacon_config_adhoc(sc, &conf, avp, vif); |
732 | break; | 734 | break; |
733 | case NL80211_IFTYPE_STATION: | 735 | case NL80211_IFTYPE_STATION: |
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 15e4d422cad4..b15eaf8417ff 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c | |||
@@ -1448,6 +1448,7 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode) | |||
1448 | REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); | 1448 | REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); |
1449 | break; | 1449 | break; |
1450 | case NL80211_IFTYPE_ADHOC: | 1450 | case NL80211_IFTYPE_ADHOC: |
1451 | case NL80211_IFTYPE_MESH_POINT: | ||
1451 | REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC | 1452 | REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC |
1452 | | AR_STA_ID1_KSRCH_MODE); | 1453 | | AR_STA_ID1_KSRCH_MODE); |
1453 | REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); | 1454 | 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 | flags |= AR_TBTT_TIMER_EN; | 3150 | flags |= AR_TBTT_TIMER_EN; |
3150 | break; | 3151 | break; |
3151 | case NL80211_IFTYPE_ADHOC: | 3152 | case NL80211_IFTYPE_ADHOC: |
3153 | case NL80211_IFTYPE_MESH_POINT: | ||
3152 | REG_SET_BIT(ah, AR_TXCFG, | 3154 | REG_SET_BIT(ah, AR_TXCFG, |
3153 | AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY); | 3155 | AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY); |
3154 | REG_WRITE(ah, AR_NEXT_NDP_TIMER, | 3156 | REG_WRITE(ah, AR_NEXT_NDP_TIMER, |
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 4c29cef66a61..c13e4e536341 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c | |||
@@ -1599,7 +1599,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
1599 | hw->wiphy->interface_modes = | 1599 | hw->wiphy->interface_modes = |
1600 | BIT(NL80211_IFTYPE_AP) | | 1600 | BIT(NL80211_IFTYPE_AP) | |
1601 | BIT(NL80211_IFTYPE_STATION) | | 1601 | BIT(NL80211_IFTYPE_STATION) | |
1602 | BIT(NL80211_IFTYPE_ADHOC); | 1602 | BIT(NL80211_IFTYPE_ADHOC) | |
1603 | BIT(NL80211_IFTYPE_MESH_POINT); | ||
1603 | 1604 | ||
1604 | hw->wiphy->reg_notifier = ath9k_reg_notifier; | 1605 | hw->wiphy->reg_notifier = ath9k_reg_notifier; |
1605 | hw->wiphy->strict_regulatory = true; | 1606 | hw->wiphy->strict_regulatory = true; |
@@ -2207,18 +2208,13 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
2207 | ic_opmode = NL80211_IFTYPE_STATION; | 2208 | ic_opmode = NL80211_IFTYPE_STATION; |
2208 | break; | 2209 | break; |
2209 | case NL80211_IFTYPE_ADHOC: | 2210 | case NL80211_IFTYPE_ADHOC: |
2210 | if (sc->nbcnvifs >= ATH_BCBUF) { | ||
2211 | ret = -ENOBUFS; | ||
2212 | goto out; | ||
2213 | } | ||
2214 | ic_opmode = NL80211_IFTYPE_ADHOC; | ||
2215 | break; | ||
2216 | case NL80211_IFTYPE_AP: | 2211 | case NL80211_IFTYPE_AP: |
2212 | case NL80211_IFTYPE_MESH_POINT: | ||
2217 | if (sc->nbcnvifs >= ATH_BCBUF) { | 2213 | if (sc->nbcnvifs >= ATH_BCBUF) { |
2218 | ret = -ENOBUFS; | 2214 | ret = -ENOBUFS; |
2219 | goto out; | 2215 | goto out; |
2220 | } | 2216 | } |
2221 | ic_opmode = NL80211_IFTYPE_AP; | 2217 | ic_opmode = conf->type; |
2222 | break; | 2218 | break; |
2223 | default: | 2219 | default: |
2224 | DPRINTF(sc, ATH_DBG_FATAL, | 2220 | DPRINTF(sc, ATH_DBG_FATAL, |
@@ -2254,7 +2250,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
2254 | * Note we only do this (at the moment) for station mode. | 2250 | * Note we only do this (at the moment) for station mode. |
2255 | */ | 2251 | */ |
2256 | if ((conf->type == NL80211_IFTYPE_STATION) || | 2252 | if ((conf->type == NL80211_IFTYPE_STATION) || |
2257 | (conf->type == NL80211_IFTYPE_ADHOC)) { | 2253 | (conf->type == NL80211_IFTYPE_ADHOC) || |
2254 | (conf->type == NL80211_IFTYPE_MESH_POINT)) { | ||
2258 | if (ath9k_hw_phycounters(sc->sc_ah)) | 2255 | if (ath9k_hw_phycounters(sc->sc_ah)) |
2259 | sc->imask |= ATH9K_INT_MIB; | 2256 | sc->imask |= ATH9K_INT_MIB; |
2260 | sc->imask |= ATH9K_INT_TSFOOR; | 2257 | sc->imask |= ATH9K_INT_TSFOOR; |
@@ -2301,8 +2298,9 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
2301 | del_timer_sync(&sc->ani.timer); | 2298 | del_timer_sync(&sc->ani.timer); |
2302 | 2299 | ||
2303 | /* Reclaim beacon resources */ | 2300 | /* Reclaim beacon resources */ |
2304 | if (sc->sc_ah->opmode == NL80211_IFTYPE_AP || | 2301 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || |
2305 | sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) { | 2302 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || |
2303 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { | ||
2306 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 2304 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
2307 | ath_beacon_return(sc, avp); | 2305 | ath_beacon_return(sc, avp); |
2308 | } | 2306 | } |
@@ -2435,6 +2433,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, | |||
2435 | switch (vif->type) { | 2433 | switch (vif->type) { |
2436 | case NL80211_IFTYPE_STATION: | 2434 | case NL80211_IFTYPE_STATION: |
2437 | case NL80211_IFTYPE_ADHOC: | 2435 | case NL80211_IFTYPE_ADHOC: |
2436 | case NL80211_IFTYPE_MESH_POINT: | ||
2438 | /* Set BSSID */ | 2437 | /* Set BSSID */ |
2439 | memcpy(sc->curbssid, conf->bssid, ETH_ALEN); | 2438 | memcpy(sc->curbssid, conf->bssid, ETH_ALEN); |
2440 | memcpy(avp->bssid, conf->bssid, ETH_ALEN); | 2439 | memcpy(avp->bssid, conf->bssid, ETH_ALEN); |
@@ -2458,7 +2457,8 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, | |||
2458 | } | 2457 | } |
2459 | 2458 | ||
2460 | if ((vif->type == NL80211_IFTYPE_ADHOC) || | 2459 | if ((vif->type == NL80211_IFTYPE_ADHOC) || |
2461 | (vif->type == NL80211_IFTYPE_AP)) { | 2460 | (vif->type == NL80211_IFTYPE_AP) || |
2461 | (vif->type == NL80211_IFTYPE_MESH_POINT)) { | ||
2462 | if ((conf->changed & IEEE80211_IFCC_BEACON) || | 2462 | if ((conf->changed & IEEE80211_IFCC_BEACON) || |
2463 | (conf->changed & IEEE80211_IFCC_BEACON_ENABLED && | 2463 | (conf->changed & IEEE80211_IFCC_BEACON_ENABLED && |
2464 | conf->enable_beacon)) { | 2464 | conf->enable_beacon)) { |
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 6c2fd395bc38..824ccbb8b7b8 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c | |||
@@ -1619,6 +1619,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
1619 | /* Choose rate table first */ | 1619 | /* Choose rate table first */ |
1620 | 1620 | ||
1621 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) || | 1621 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) || |
1622 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) || | ||
1622 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) { | 1623 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) { |
1623 | rate_table = ath_choose_rate_table(sc, sband->band, | 1624 | rate_table = ath_choose_rate_table(sc, sband->band, |
1624 | sta->ht_cap.ht_supported, | 1625 | sta->ht_cap.ht_supported, |