Add mesh point functionality to ath9k
authorPat Erley <pat-lkml@erley.org>
Sat, 21 Mar 2009 02:59:59 +0000 (22:59 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Sat, 28 Mar 2009 00:13:06 +0000 (20:13 -0400)
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>
drivers/net/wireless/ath9k/beacon.c
drivers/net/wireless/ath9k/hw.c
drivers/net/wireless/ath9k/main.c
drivers/net/wireless/ath9k/rc.c

index e5b007196ca1160bc0002171523368a0074d9ec7..ec995730632ddeacb4f9e2a0b4eb7337abcad2f9 100644 (file)
@@ -70,7 +70,8 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
        ds = bf->bf_desc;
        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)) {
                ds->ds_link = bf->bf_daddr; /* self-linked */
                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);
                        break;
                case NL80211_IFTYPE_ADHOC:
+               case NL80211_IFTYPE_MESH_POINT:
                        ath_beacon_config_adhoc(sc, &conf, avp, vif);
                        break;
                case NL80211_IFTYPE_STATION:
index 15e4d422cad4f9910f29de42dd7552ad5cf57446..b15eaf8417ff0d50a1ec3e86d8d0d3c6e1065218 100644 (file)
@@ -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);
                break;
        case NL80211_IFTYPE_ADHOC:
+       case NL80211_IFTYPE_MESH_POINT:
                REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
                          | AR_STA_ID1_KSRCH_MODE);
                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;
                break;
        case NL80211_IFTYPE_ADHOC:
+       case NL80211_IFTYPE_MESH_POINT:
                REG_SET_BIT(ah, AR_TXCFG,
                            AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
                REG_WRITE(ah, AR_NEXT_NDP_TIMER,
index 4c29cef66a61263fb4611ff63c888edd1c61319e..c13e4e536341ef6eff5dff947ce389844c03c91d 100644 (file)
@@ -1599,7 +1599,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
        hw->wiphy->interface_modes =
                BIT(NL80211_IFTYPE_AP) |
                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->strict_regulatory = true;
@@ -2207,18 +2208,13 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
                ic_opmode = NL80211_IFTYPE_STATION;
                break;
        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_MESH_POINT:
                if (sc->nbcnvifs >= ATH_BCBUF) {
                        ret = -ENOBUFS;
                        goto out;
                }
-               ic_opmode = NL80211_IFTYPE_AP;
+               ic_opmode = conf->type;
                break;
        default:
                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.
         */
        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))
                        sc->imask |= ATH9K_INT_MIB;
                sc->imask |= ATH9K_INT_TSFOOR;
@@ -2301,8 +2298,9 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
        del_timer_sync(&sc->ani.timer);
 
        /* Reclaim beacon resources */
-       if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
-           sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) {
+       if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
+           (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
+           (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
                ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
                ath_beacon_return(sc, avp);
        }
@@ -2435,6 +2433,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
                switch (vif->type) {
                case NL80211_IFTYPE_STATION:
                case NL80211_IFTYPE_ADHOC:
+               case NL80211_IFTYPE_MESH_POINT:
                        /* Set BSSID */
                        memcpy(sc->curbssid, 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) ||
-           (vif->type == NL80211_IFTYPE_AP)) {
+           (vif->type == NL80211_IFTYPE_AP) ||
+           (vif->type == NL80211_IFTYPE_MESH_POINT)) {
                if ((conf->changed & IEEE80211_IFCC_BEACON) ||
                    (conf->changed & IEEE80211_IFCC_BEACON_ENABLED &&
                     conf->enable_beacon)) {
index 6c2fd395bc38b1ece2db8e36122225d5cd5c6c82..824ccbb8b7b83249791cde9b962720efb7953e4c 100644 (file)
@@ -1619,6 +1619,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
        /* Choose rate table first */
 
        if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) ||
+           (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) ||
            (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
                rate_table = ath_choose_rate_table(sc, sband->band,
                                                   sta->ht_cap.ht_supported,