aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/main.c
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/net/wireless/ath/ath9k/main.c
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/net/wireless/ath/ath9k/main.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c70
1 files changed, 61 insertions, 9 deletions
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;