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:19 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-07 15:49:40 -0400
commit99e4d43ad5ff5778f92ee3bc40a29ac7cd8a28f4 (patch)
tree35f19c1d608a4abff349f68529f8e8ce817837cc /drivers/net/wireless/ath/ath9k/main.c
parent4f5ef75b155955bf92adc772c6660787151fc78c (diff)
ath9k: configure beacons based on hw opmode
Current ath9k code does not handle beacon timers on opmode specific. One such example is that a STA beacon config overwrites already configured AP vif's beacon timers during scan. On multi station vif case, configure beacon timers beased on primary vif selected. This also helps while moving back to single STA vif from multi STA vifs, where the power save is enabled and hw has to be reconfigured with proper beacon and bssid/aid. Otherwise connection poll will be triggered so frequently due to beacon loss. 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.c84
1 files changed, 26 insertions, 58 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 3181211ae248..ddd5413c8da8 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -299,7 +299,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
299 299
300 if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) { 300 if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) {
301 if (sc->sc_flags & SC_OP_BEACONS) 301 if (sc->sc_flags & SC_OP_BEACONS)
302 ath_beacon_config(sc, NULL); 302 ath_set_beacon(sc);
303 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); 303 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
304 ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2); 304 ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2);
305 ath_start_ani(common); 305 ath_start_ani(common);
@@ -828,43 +828,6 @@ chip_reset:
828#undef SCHED_INTR 828#undef SCHED_INTR
829} 829}
830 830
831static void ath9k_bss_assoc_info(struct ath_softc *sc,
832 struct ieee80211_hw *hw,
833 struct ieee80211_vif *vif,
834 struct ieee80211_bss_conf *bss_conf)
835{
836 struct ath_hw *ah = sc->sc_ah;
837 struct ath_common *common = ath9k_hw_common(ah);
838
839 if (bss_conf->assoc) {
840 ath_dbg(common, ATH_DBG_CONFIG,
841 "Bss Info ASSOC %d, bssid: %pM\n",
842 bss_conf->aid, common->curbssid);
843
844 /*
845 * Request a re-configuration of Beacon related timers
846 * on the receipt of the first Beacon frame (i.e.,
847 * after time sync with the AP).
848 */
849 sc->ps_flags |= PS_BEACON_SYNC;
850
851 /* Configure the beacon */
852 ath_beacon_config(sc, vif);
853
854 /* Reset rssi stats */
855 sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
856 sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
857
858 sc->sc_flags |= SC_OP_ANI_RUN;
859 ath_start_ani(common);
860 } else {
861 ath_dbg(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
862 /* Stop ANI */
863 sc->sc_flags &= ~SC_OP_ANI_RUN;
864 del_timer_sync(&common->ani.timer);
865 }
866}
867
868void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) 831void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
869{ 832{
870 struct ath_hw *ah = sc->sc_ah; 833 struct ath_hw *ah = sc->sc_ah;
@@ -894,7 +857,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
894 goto out; 857 goto out;
895 } 858 }
896 if (sc->sc_flags & SC_OP_BEACONS) 859 if (sc->sc_flags & SC_OP_BEACONS)
897 ath_beacon_config(sc, NULL); /* restart beacons */ 860 ath_set_beacon(sc); /* restart beacons */
898 861
899 /* Re-Enable interrupts */ 862 /* Re-Enable interrupts */
900 ath9k_hw_set_interrupts(ah, ah->imask); 863 ath9k_hw_set_interrupts(ah, ah->imask);
@@ -1001,7 +964,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
1001 sc->config.txpowlimit, &sc->curtxpow); 964 sc->config.txpowlimit, &sc->curtxpow);
1002 965
1003 if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL))) 966 if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL)))
1004 ath_beacon_config(sc, NULL); /* restart beacons */ 967 ath_set_beacon(sc); /* restart beacons */
1005 968
1006 ath9k_hw_set_interrupts(ah, ah->imask); 969 ath9k_hw_set_interrupts(ah, ah->imask);
1007 970
@@ -1408,9 +1371,6 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
1408 if ((iter_data.naps + iter_data.nadhocs) > 0) { 1371 if ((iter_data.naps + iter_data.nadhocs) > 0) {
1409 sc->sc_flags |= SC_OP_ANI_RUN; 1372 sc->sc_flags |= SC_OP_ANI_RUN;
1410 ath_start_ani(common); 1373 ath_start_ani(common);
1411 } else {
1412 sc->sc_flags &= ~SC_OP_ANI_RUN;
1413 del_timer_sync(&common->ani.timer);
1414 } 1374 }
1415} 1375}
1416 1376
@@ -1894,6 +1854,9 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
1894 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); 1854 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1895 common->curaid = bss_conf->aid; 1855 common->curaid = bss_conf->aid;
1896 ath9k_hw_write_associd(sc->sc_ah); 1856 ath9k_hw_write_associd(sc->sc_ah);
1857 /* configure beacon */
1858 if (bss_conf->enable_beacon)
1859 ath_beacon_config(sc, vif);
1897 break; 1860 break;
1898 case NL80211_IFTYPE_STATION: 1861 case NL80211_IFTYPE_STATION:
1899 /* 1862 /*
@@ -1909,6 +1872,16 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
1909 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); 1872 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1910 common->curaid = bss_conf->aid; 1873 common->curaid = bss_conf->aid;
1911 ath9k_hw_write_associd(sc->sc_ah); 1874 ath9k_hw_write_associd(sc->sc_ah);
1875 ath_dbg(common, ATH_DBG_CONFIG,
1876 "Bss Info ASSOC %d, bssid: %pM\n",
1877 bss_conf->aid, common->curbssid);
1878 ath_beacon_config(sc, vif);
1879 /* Reset rssi stats */
1880 sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
1881 sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
1882
1883 sc->sc_flags |= SC_OP_ANI_RUN;
1884 ath_start_ani(common);
1912 } 1885 }
1913 break; 1886 break;
1914 default: 1887 default:
@@ -1924,7 +1897,10 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif)
1924 1897
1925 /* Reconfigure bss info */ 1898 /* Reconfigure bss info */
1926 if (avp->primary_sta_vif && !bss_conf->assoc) { 1899 if (avp->primary_sta_vif && !bss_conf->assoc) {
1927 sc->sc_flags &= ~SC_OP_PRIM_STA_VIF; 1900 ath_dbg(common, ATH_DBG_CONFIG,
1901 "Bss Info DISASSOC %d, bssid %pM\n",
1902 common->curaid, common->curbssid);
1903 sc->sc_flags &= ~(SC_OP_PRIM_STA_VIF | SC_OP_BEACONS);
1928 avp->primary_sta_vif = false; 1904 avp->primary_sta_vif = false;
1929 memset(common->curbssid, 0, ETH_ALEN); 1905 memset(common->curbssid, 0, ETH_ALEN);
1930 common->curaid = 0; 1906 common->curaid = 0;
@@ -1938,8 +1914,12 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif)
1938 * Clear bssid & aid 1914 * Clear bssid & aid
1939 */ 1915 */
1940 if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && 1916 if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
1941 !(sc->sc_flags & SC_OP_PRIM_STA_VIF)) 1917 !(sc->sc_flags & SC_OP_PRIM_STA_VIF)) {
1942 ath9k_hw_write_associd(sc->sc_ah); 1918 ath9k_hw_write_associd(sc->sc_ah);
1919 /* Stop ANI */
1920 sc->sc_flags &= ~SC_OP_ANI_RUN;
1921 del_timer_sync(&common->ani.timer);
1922 }
1943} 1923}
1944 1924
1945static void ath9k_bss_info_changed(struct ieee80211_hw *hw, 1925static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
@@ -1948,7 +1928,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1948 u32 changed) 1928 u32 changed)
1949{ 1929{
1950 struct ath_softc *sc = hw->priv; 1930 struct ath_softc *sc = hw->priv;
1951 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
1952 struct ath_hw *ah = sc->sc_ah; 1931 struct ath_hw *ah = sc->sc_ah;
1953 struct ath_common *common = ath9k_hw_common(ah); 1932 struct ath_common *common = ath9k_hw_common(ah);
1954 struct ath_vif *avp = (void *)vif->drv_priv; 1933 struct ath_vif *avp = (void *)vif->drv_priv;
@@ -1965,9 +1944,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1965 1944
1966 ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n", 1945 ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n",
1967 common->curbssid, common->curaid); 1946 common->curbssid, common->curaid);
1968
1969 /* need to reconfigure the beacon */
1970 sc->sc_flags &= ~SC_OP_BEACONS ;
1971 } 1947 }
1972 1948
1973 /* Enable transmission of beacons (AP, IBSS, MESH) */ 1949 /* Enable transmission of beacons (AP, IBSS, MESH) */
@@ -2008,7 +1984,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
2008 } 1984 }
2009 1985
2010 if (changed & BSS_CHANGED_BEACON_INT) { 1986 if (changed & BSS_CHANGED_BEACON_INT) {
2011 cur_conf->beacon_interval = bss_conf->beacon_int;
2012 /* 1987 /*
2013 * In case of AP mode, the HW TSF has to be reset 1988 * In case of AP mode, the HW TSF has to be reset
2014 * when the beacon interval changes. 1989 * when the beacon interval changes.
@@ -2020,9 +1995,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
2020 if (!error) 1995 if (!error)
2021 ath_beacon_config(sc, vif); 1996 ath_beacon_config(sc, vif);
2022 ath9k_set_beaconing_status(sc, true); 1997 ath9k_set_beaconing_status(sc, true);
2023 } else { 1998 } else
2024 ath_beacon_config(sc, vif); 1999 ath_beacon_config(sc, vif);
2025 }
2026 } 2000 }
2027 2001
2028 if (changed & BSS_CHANGED_ERP_PREAMBLE) { 2002 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
@@ -2044,12 +2018,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
2044 sc->sc_flags &= ~SC_OP_PROTECT_ENABLE; 2018 sc->sc_flags &= ~SC_OP_PROTECT_ENABLE;
2045 } 2019 }
2046 2020
2047 if (changed & BSS_CHANGED_ASSOC) {
2048 ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
2049 bss_conf->assoc);
2050 ath9k_bss_assoc_info(sc, hw, vif, bss_conf);
2051 }
2052
2053 mutex_unlock(&sc->mutex); 2021 mutex_unlock(&sc->mutex);
2054} 2022}
2055 2023