aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRajkumar Manoharan <rmanoharan@atheros.com>2011-04-04 13:26:18 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-07 15:34:15 -0400
commit4f5ef75b155955bf92adc772c6660787151fc78c (patch)
tree8b274c152875ac445b1de352709f9bc371253b48 /drivers
parent66da424177db4f4f2fa7a462db5912655aad966f (diff)
ath9k: Handle BSSID/AID for multiple interfaces
As of now bssid/aid is overridden with recently changed vif's bss config. This may cause improper beacon updation due to bssid/aid mismatch. On station mode, select an associated sta vif as primary vif and configure that vif's bss into hw. Update the primary vif on interface change and bss info change. Signed-off-by: Rajkumar Manoharan <rmanoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c70
2 files changed, 63 insertions, 10 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index f3a753096d7d..a972396049e5 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -344,7 +344,7 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid
344 344
345struct ath_vif { 345struct ath_vif {
346 int av_bslot; 346 int av_bslot;
347 bool is_bslot_active; 347 bool is_bslot_active, primary_sta_vif;
348 __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ 348 __le64 tsf_adjust; /* TSF adjustment for staggered beacons */
349 struct ath_buf *av_bcbuf; 349 struct ath_buf *av_bcbuf;
350}; 350};
@@ -546,6 +546,7 @@ struct ath_ant_comb {
546#define SC_OP_BT_SCAN BIT(13) 546#define SC_OP_BT_SCAN BIT(13)
547#define SC_OP_ANI_RUN BIT(14) 547#define SC_OP_ANI_RUN BIT(14)
548#define SC_OP_ENABLE_APM BIT(15) 548#define SC_OP_ENABLE_APM BIT(15)
549#define SC_OP_PRIM_STA_VIF BIT(16)
549 550
550/* Powersave flags */ 551/* Powersave flags */
551#define PS_WAIT_FOR_BEACON BIT(0) 552#define PS_WAIT_FOR_BEACON BIT(0)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 6f300d7df88e..3181211ae248 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -841,10 +841,6 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
841 "Bss Info ASSOC %d, bssid: %pM\n", 841 "Bss Info ASSOC %d, bssid: %pM\n",
842 bss_conf->aid, common->curbssid); 842 bss_conf->aid, common->curbssid);
843 843
844 /* New association, store aid */
845 common->curaid = bss_conf->aid;
846 ath9k_hw_write_associd(ah);
847
848 /* 844 /*
849 * Request a re-configuration of Beacon related timers 845 * Request a re-configuration of Beacon related timers
850 * on the receipt of the first Beacon frame (i.e., 846 * on the receipt of the first Beacon frame (i.e.,
@@ -863,7 +859,6 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
863 ath_start_ani(common); 859 ath_start_ani(common);
864 } else { 860 } else {
865 ath_dbg(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n"); 861 ath_dbg(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
866 common->curaid = 0;
867 /* Stop ANI */ 862 /* Stop ANI */
868 sc->sc_flags &= ~SC_OP_ANI_RUN; 863 sc->sc_flags &= ~SC_OP_ANI_RUN;
869 del_timer_sync(&common->ani.timer); 864 del_timer_sync(&common->ani.timer);
@@ -1886,6 +1881,66 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
1886 1881
1887 return ret; 1882 return ret;
1888} 1883}
1884static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
1885{
1886 struct ath_softc *sc = data;
1887 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1888 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1889 struct ath_vif *avp = (void *)vif->drv_priv;
1890
1891 switch (sc->sc_ah->opmode) {
1892 case NL80211_IFTYPE_ADHOC:
1893 /* There can be only one vif available */
1894 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1895 common->curaid = bss_conf->aid;
1896 ath9k_hw_write_associd(sc->sc_ah);
1897 break;
1898 case NL80211_IFTYPE_STATION:
1899 /*
1900 * Skip iteration if primary station vif's bss info
1901 * was not changed
1902 */
1903 if (sc->sc_flags & SC_OP_PRIM_STA_VIF)
1904 break;
1905
1906 if (bss_conf->assoc) {
1907 sc->sc_flags |= SC_OP_PRIM_STA_VIF;
1908 avp->primary_sta_vif = true;
1909 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1910 common->curaid = bss_conf->aid;
1911 ath9k_hw_write_associd(sc->sc_ah);
1912 }
1913 break;
1914 default:
1915 break;
1916 }
1917}
1918
1919static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif)
1920{
1921 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1922 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1923 struct ath_vif *avp = (void *)vif->drv_priv;
1924
1925 /* Reconfigure bss info */
1926 if (avp->primary_sta_vif && !bss_conf->assoc) {
1927 sc->sc_flags &= ~SC_OP_PRIM_STA_VIF;
1928 avp->primary_sta_vif = false;
1929 memset(common->curbssid, 0, ETH_ALEN);
1930 common->curaid = 0;
1931 }
1932
1933 ieee80211_iterate_active_interfaces_atomic(
1934 sc->hw, ath9k_bss_iter, sc);
1935
1936 /*
1937 * None of station vifs are associated.
1938 * Clear bssid & aid
1939 */
1940 if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
1941 !(sc->sc_flags & SC_OP_PRIM_STA_VIF))
1942 ath9k_hw_write_associd(sc->sc_ah);
1943}
1889 1944
1890static void ath9k_bss_info_changed(struct ieee80211_hw *hw, 1945static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1891 struct ieee80211_vif *vif, 1946 struct ieee80211_vif *vif,
@@ -1903,10 +1958,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1903 mutex_lock(&sc->mutex); 1958 mutex_lock(&sc->mutex);
1904 1959
1905 if (changed & BSS_CHANGED_BSSID) { 1960 if (changed & BSS_CHANGED_BSSID) {
1906 /* Set BSSID */ 1961 ath9k_config_bss(sc, vif);
1907 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1908 common->curaid = 0;
1909 ath9k_hw_write_associd(ah);
1910 1962
1911 /* Set aggregation protection mode parameters */ 1963 /* Set aggregation protection mode parameters */
1912 sc->config.ath_aggr_prot = 0; 1964 sc->config.ath_aggr_prot = 0;