diff options
author | Sujith <Sujith.Manoharan@atheros.com> | 2009-02-03 21:40:07 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-02-11 11:44:21 -0500 |
commit | 141b38b6bc6db69348a9eaed87137451240bc55f (patch) | |
tree | 2b58a071e1426407a3e7364ce4e87038b196109a /drivers/net/wireless | |
parent | 367681f4ec9b226db201f181c4f47dd973f733a6 (diff) |
ath9k: Lock mac80211 callbacks with a mutex
Signed-off-by: Sujith <Sujith.Manoharan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/ath9k/main.c | 60 |
1 files changed, 46 insertions, 14 deletions
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 1c0f893e1c0a..9b040bacab10 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c | |||
@@ -1938,6 +1938,8 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1938 | DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with " | 1938 | DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with " |
1939 | "initial channel: %d MHz\n", curchan->center_freq); | 1939 | "initial channel: %d MHz\n", curchan->center_freq); |
1940 | 1940 | ||
1941 | mutex_lock(&sc->mutex); | ||
1942 | |||
1941 | /* setup initial channel */ | 1943 | /* setup initial channel */ |
1942 | 1944 | ||
1943 | pos = curchan->hw_value; | 1945 | pos = curchan->hw_value; |
@@ -1963,7 +1965,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1963 | "(freq %u MHz)\n", r, | 1965 | "(freq %u MHz)\n", r, |
1964 | curchan->center_freq); | 1966 | curchan->center_freq); |
1965 | spin_unlock_bh(&sc->sc_resetlock); | 1967 | spin_unlock_bh(&sc->sc_resetlock); |
1966 | return r; | 1968 | goto mutex_unlock; |
1967 | } | 1969 | } |
1968 | spin_unlock_bh(&sc->sc_resetlock); | 1970 | spin_unlock_bh(&sc->sc_resetlock); |
1969 | 1971 | ||
@@ -1983,7 +1985,8 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1983 | if (ath_startrecv(sc) != 0) { | 1985 | if (ath_startrecv(sc) != 0) { |
1984 | DPRINTF(sc, ATH_DBG_FATAL, | 1986 | DPRINTF(sc, ATH_DBG_FATAL, |
1985 | "Unable to start recv logic\n"); | 1987 | "Unable to start recv logic\n"); |
1986 | return -EIO; | 1988 | r = -EIO; |
1989 | goto mutex_unlock; | ||
1987 | } | 1990 | } |
1988 | 1991 | ||
1989 | /* Setup our intr mask. */ | 1992 | /* Setup our intr mask. */ |
@@ -2010,6 +2013,10 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
2010 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | 2013 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) |
2011 | r = ath_start_rfkill_poll(sc); | 2014 | r = ath_start_rfkill_poll(sc); |
2012 | #endif | 2015 | #endif |
2016 | |||
2017 | mutex_unlock: | ||
2018 | mutex_unlock(&sc->mutex); | ||
2019 | |||
2013 | return r; | 2020 | return r; |
2014 | } | 2021 | } |
2015 | 2022 | ||
@@ -2074,7 +2081,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
2074 | return; | 2081 | return; |
2075 | } | 2082 | } |
2076 | 2083 | ||
2077 | DPRINTF(sc, ATH_DBG_CONFIG, "Cleaning up\n"); | 2084 | mutex_lock(&sc->mutex); |
2078 | 2085 | ||
2079 | ieee80211_stop_queues(sc->hw); | 2086 | ieee80211_stop_queues(sc->hw); |
2080 | 2087 | ||
@@ -2099,6 +2106,8 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
2099 | 2106 | ||
2100 | sc->sc_flags |= SC_OP_INVALID; | 2107 | sc->sc_flags |= SC_OP_INVALID; |
2101 | 2108 | ||
2109 | mutex_unlock(&sc->mutex); | ||
2110 | |||
2102 | DPRINTF(sc, ATH_DBG_CONFIG, "Driver halt\n"); | 2111 | DPRINTF(sc, ATH_DBG_CONFIG, "Driver halt\n"); |
2103 | } | 2112 | } |
2104 | 2113 | ||
@@ -2114,6 +2123,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
2114 | if (sc->sc_nvaps) | 2123 | if (sc->sc_nvaps) |
2115 | return -ENOBUFS; | 2124 | return -ENOBUFS; |
2116 | 2125 | ||
2126 | mutex_lock(&sc->mutex); | ||
2127 | |||
2117 | switch (conf->type) { | 2128 | switch (conf->type) { |
2118 | case NL80211_IFTYPE_STATION: | 2129 | case NL80211_IFTYPE_STATION: |
2119 | ic_opmode = NL80211_IFTYPE_STATION; | 2130 | ic_opmode = NL80211_IFTYPE_STATION; |
@@ -2173,6 +2184,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
2173 | jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); | 2184 | jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); |
2174 | } | 2185 | } |
2175 | 2186 | ||
2187 | mutex_unlock(&sc->mutex); | ||
2188 | |||
2176 | return 0; | 2189 | return 0; |
2177 | } | 2190 | } |
2178 | 2191 | ||
@@ -2184,6 +2197,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
2184 | 2197 | ||
2185 | DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n"); | 2198 | DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n"); |
2186 | 2199 | ||
2200 | mutex_lock(&sc->mutex); | ||
2201 | |||
2187 | /* Stop ANI */ | 2202 | /* Stop ANI */ |
2188 | del_timer_sync(&sc->sc_ani.timer); | 2203 | del_timer_sync(&sc->sc_ani.timer); |
2189 | 2204 | ||
@@ -2198,6 +2213,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
2198 | 2213 | ||
2199 | sc->sc_vaps[0] = NULL; | 2214 | sc->sc_vaps[0] = NULL; |
2200 | sc->sc_nvaps--; | 2215 | sc->sc_nvaps--; |
2216 | |||
2217 | mutex_unlock(&sc->mutex); | ||
2201 | } | 2218 | } |
2202 | 2219 | ||
2203 | static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | 2220 | static int ath9k_config(struct ieee80211_hw *hw, u32 changed) |
@@ -2206,6 +2223,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2206 | struct ieee80211_conf *conf = &hw->conf; | 2223 | struct ieee80211_conf *conf = &hw->conf; |
2207 | 2224 | ||
2208 | mutex_lock(&sc->mutex); | 2225 | mutex_lock(&sc->mutex); |
2226 | |||
2209 | if (changed & IEEE80211_CONF_CHANGE_PS) { | 2227 | if (changed & IEEE80211_CONF_CHANGE_PS) { |
2210 | if (conf->flags & IEEE80211_CONF_PS) { | 2228 | if (conf->flags & IEEE80211_CONF_PS) { |
2211 | if ((sc->sc_imask & ATH9K_INT_TIM_TIMER) == 0) { | 2229 | if ((sc->sc_imask & ATH9K_INT_TIM_TIMER) == 0) { |
@@ -2250,6 +2268,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2250 | sc->sc_config.txpowlimit = 2 * conf->power_level; | 2268 | sc->sc_config.txpowlimit = 2 * conf->power_level; |
2251 | 2269 | ||
2252 | mutex_unlock(&sc->mutex); | 2270 | mutex_unlock(&sc->mutex); |
2271 | |||
2253 | return 0; | 2272 | return 0; |
2254 | } | 2273 | } |
2255 | 2274 | ||
@@ -2392,8 +2411,7 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw, | |||
2392 | } | 2411 | } |
2393 | } | 2412 | } |
2394 | 2413 | ||
2395 | static int ath9k_conf_tx(struct ieee80211_hw *hw, | 2414 | static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, |
2396 | u16 queue, | ||
2397 | const struct ieee80211_tx_queue_params *params) | 2415 | const struct ieee80211_tx_queue_params *params) |
2398 | { | 2416 | { |
2399 | struct ath_softc *sc = hw->priv; | 2417 | struct ath_softc *sc = hw->priv; |
@@ -2403,6 +2421,8 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, | |||
2403 | if (queue >= WME_NUM_AC) | 2421 | if (queue >= WME_NUM_AC) |
2404 | return 0; | 2422 | return 0; |
2405 | 2423 | ||
2424 | mutex_lock(&sc->mutex); | ||
2425 | |||
2406 | qi.tqi_aifs = params->aifs; | 2426 | qi.tqi_aifs = params->aifs; |
2407 | qi.tqi_cwmin = params->cw_min; | 2427 | qi.tqi_cwmin = params->cw_min; |
2408 | qi.tqi_cwmax = params->cw_max; | 2428 | qi.tqi_cwmax = params->cw_max; |
@@ -2419,6 +2439,8 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, | |||
2419 | if (ret) | 2439 | if (ret) |
2420 | DPRINTF(sc, ATH_DBG_FATAL, "TXQ Update failed\n"); | 2440 | DPRINTF(sc, ATH_DBG_FATAL, "TXQ Update failed\n"); |
2421 | 2441 | ||
2442 | mutex_unlock(&sc->mutex); | ||
2443 | |||
2422 | return ret; | 2444 | return ret; |
2423 | } | 2445 | } |
2424 | 2446 | ||
@@ -2431,6 +2453,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
2431 | struct ath_softc *sc = hw->priv; | 2453 | struct ath_softc *sc = hw->priv; |
2432 | int ret = 0; | 2454 | int ret = 0; |
2433 | 2455 | ||
2456 | mutex_lock(&sc->mutex); | ||
2434 | ath9k_ps_wakeup(sc); | 2457 | ath9k_ps_wakeup(sc); |
2435 | DPRINTF(sc, ATH_DBG_KEYCACHE, "Set HW Key\n"); | 2458 | DPRINTF(sc, ATH_DBG_KEYCACHE, "Set HW Key\n"); |
2436 | 2459 | ||
@@ -2456,6 +2479,8 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
2456 | } | 2479 | } |
2457 | 2480 | ||
2458 | ath9k_ps_restore(sc); | 2481 | ath9k_ps_restore(sc); |
2482 | mutex_unlock(&sc->mutex); | ||
2483 | |||
2459 | return ret; | 2484 | return ret; |
2460 | } | 2485 | } |
2461 | 2486 | ||
@@ -2466,6 +2491,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2466 | { | 2491 | { |
2467 | struct ath_softc *sc = hw->priv; | 2492 | struct ath_softc *sc = hw->priv; |
2468 | 2493 | ||
2494 | mutex_lock(&sc->mutex); | ||
2495 | |||
2469 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { | 2496 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { |
2470 | DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", | 2497 | DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", |
2471 | bss_conf->use_short_preamble); | 2498 | bss_conf->use_short_preamble); |
@@ -2490,15 +2517,18 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2490 | bss_conf->assoc); | 2517 | bss_conf->assoc); |
2491 | ath9k_bss_assoc_info(sc, vif, bss_conf); | 2518 | ath9k_bss_assoc_info(sc, vif, bss_conf); |
2492 | } | 2519 | } |
2520 | |||
2521 | mutex_unlock(&sc->mutex); | ||
2493 | } | 2522 | } |
2494 | 2523 | ||
2495 | static u64 ath9k_get_tsf(struct ieee80211_hw *hw) | 2524 | static u64 ath9k_get_tsf(struct ieee80211_hw *hw) |
2496 | { | 2525 | { |
2497 | u64 tsf; | 2526 | u64 tsf; |
2498 | struct ath_softc *sc = hw->priv; | 2527 | struct ath_softc *sc = hw->priv; |
2499 | struct ath_hal *ah = sc->sc_ah; | ||
2500 | 2528 | ||
2501 | tsf = ath9k_hw_gettsf64(ah); | 2529 | mutex_lock(&sc->mutex); |
2530 | tsf = ath9k_hw_gettsf64(sc->sc_ah); | ||
2531 | mutex_unlock(&sc->mutex); | ||
2502 | 2532 | ||
2503 | return tsf; | 2533 | return tsf; |
2504 | } | 2534 | } |
@@ -2506,23 +2536,25 @@ static u64 ath9k_get_tsf(struct ieee80211_hw *hw) | |||
2506 | static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf) | 2536 | static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf) |
2507 | { | 2537 | { |
2508 | struct ath_softc *sc = hw->priv; | 2538 | struct ath_softc *sc = hw->priv; |
2509 | struct ath_hal *ah = sc->sc_ah; | ||
2510 | 2539 | ||
2511 | ath9k_hw_settsf64(ah, tsf); | 2540 | mutex_lock(&sc->mutex); |
2541 | ath9k_hw_settsf64(sc->sc_ah, tsf); | ||
2542 | mutex_unlock(&sc->mutex); | ||
2512 | } | 2543 | } |
2513 | 2544 | ||
2514 | static void ath9k_reset_tsf(struct ieee80211_hw *hw) | 2545 | static void ath9k_reset_tsf(struct ieee80211_hw *hw) |
2515 | { | 2546 | { |
2516 | struct ath_softc *sc = hw->priv; | 2547 | struct ath_softc *sc = hw->priv; |
2517 | struct ath_hal *ah = sc->sc_ah; | ||
2518 | 2548 | ||
2519 | ath9k_hw_reset_tsf(ah); | 2549 | mutex_lock(&sc->mutex); |
2550 | ath9k_hw_reset_tsf(sc->sc_ah); | ||
2551 | mutex_unlock(&sc->mutex); | ||
2520 | } | 2552 | } |
2521 | 2553 | ||
2522 | static int ath9k_ampdu_action(struct ieee80211_hw *hw, | 2554 | static int ath9k_ampdu_action(struct ieee80211_hw *hw, |
2523 | enum ieee80211_ampdu_mlme_action action, | 2555 | enum ieee80211_ampdu_mlme_action action, |
2524 | struct ieee80211_sta *sta, | 2556 | struct ieee80211_sta *sta, |
2525 | u16 tid, u16 *ssn) | 2557 | u16 tid, u16 *ssn) |
2526 | { | 2558 | { |
2527 | struct ath_softc *sc = hw->priv; | 2559 | struct ath_softc *sc = hw->priv; |
2528 | int ret = 0; | 2560 | int ret = 0; |