diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/main.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 94 |
1 files changed, 13 insertions, 81 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 6516a426f6ce..91c00486b2ac 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1197,8 +1197,6 @@ void ath_radio_disable(struct ath_softc *sc) | |||
1197 | ath9k_ps_restore(sc); | 1197 | ath9k_ps_restore(sc); |
1198 | } | 1198 | } |
1199 | 1199 | ||
1200 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
1201 | |||
1202 | /*******************/ | 1200 | /*******************/ |
1203 | /* Rfkill */ | 1201 | /* Rfkill */ |
1204 | /*******************/ | 1202 | /*******************/ |
@@ -1211,81 +1209,27 @@ static bool ath_is_rfkill_set(struct ath_softc *sc) | |||
1211 | ah->rfkill_polarity; | 1209 | ah->rfkill_polarity; |
1212 | } | 1210 | } |
1213 | 1211 | ||
1214 | /* s/w rfkill handlers */ | 1212 | static void ath9k_rfkill_poll_state(struct ieee80211_hw *hw) |
1215 | static int ath_rfkill_set_block(void *data, bool blocked) | ||
1216 | { | ||
1217 | struct ath_softc *sc = data; | ||
1218 | |||
1219 | if (blocked) | ||
1220 | ath_radio_disable(sc); | ||
1221 | else | ||
1222 | ath_radio_enable(sc); | ||
1223 | |||
1224 | return 0; | ||
1225 | } | ||
1226 | |||
1227 | static void ath_rfkill_poll_state(struct rfkill *rfkill, void *data) | ||
1228 | { | 1213 | { |
1229 | struct ath_softc *sc = data; | 1214 | struct ath_wiphy *aphy = hw->priv; |
1215 | struct ath_softc *sc = aphy->sc; | ||
1230 | bool blocked = !!ath_is_rfkill_set(sc); | 1216 | bool blocked = !!ath_is_rfkill_set(sc); |
1231 | 1217 | ||
1232 | if (rfkill_set_hw_state(rfkill, blocked)) | 1218 | wiphy_rfkill_set_hw_state(hw->wiphy, blocked); |
1219 | |||
1220 | if (blocked) | ||
1233 | ath_radio_disable(sc); | 1221 | ath_radio_disable(sc); |
1234 | else | 1222 | else |
1235 | ath_radio_enable(sc); | 1223 | ath_radio_enable(sc); |
1236 | } | 1224 | } |
1237 | 1225 | ||
1238 | /* Init s/w rfkill */ | 1226 | static void ath_start_rfkill_poll(struct ath_softc *sc) |
1239 | static int ath_init_sw_rfkill(struct ath_softc *sc) | ||
1240 | { | 1227 | { |
1241 | sc->rf_kill.ops.set_block = ath_rfkill_set_block; | 1228 | struct ath_hw *ah = sc->sc_ah; |
1242 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
1243 | sc->rf_kill.ops.poll = ath_rfkill_poll_state; | ||
1244 | |||
1245 | snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name), | ||
1246 | "ath9k-%s::rfkill", wiphy_name(sc->hw->wiphy)); | ||
1247 | |||
1248 | sc->rf_kill.rfkill = rfkill_alloc(sc->rf_kill.rfkill_name, | ||
1249 | wiphy_dev(sc->hw->wiphy), | ||
1250 | RFKILL_TYPE_WLAN, | ||
1251 | &sc->rf_kill.ops, sc); | ||
1252 | if (!sc->rf_kill.rfkill) { | ||
1253 | DPRINTF(sc, ATH_DBG_FATAL, "Failed to allocate rfkill\n"); | ||
1254 | return -ENOMEM; | ||
1255 | } | ||
1256 | |||
1257 | return 0; | ||
1258 | } | ||
1259 | |||
1260 | /* Deinitialize rfkill */ | ||
1261 | static void ath_deinit_rfkill(struct ath_softc *sc) | ||
1262 | { | ||
1263 | if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) { | ||
1264 | rfkill_unregister(sc->rf_kill.rfkill); | ||
1265 | rfkill_destroy(sc->rf_kill.rfkill); | ||
1266 | sc->sc_flags &= ~SC_OP_RFKILL_REGISTERED; | ||
1267 | } | ||
1268 | } | ||
1269 | |||
1270 | static int ath_start_rfkill_poll(struct ath_softc *sc) | ||
1271 | { | ||
1272 | if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) { | ||
1273 | if (rfkill_register(sc->rf_kill.rfkill)) { | ||
1274 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1275 | "Unable to register rfkill\n"); | ||
1276 | rfkill_destroy(sc->rf_kill.rfkill); | ||
1277 | |||
1278 | /* Deinitialize the device */ | ||
1279 | ath_cleanup(sc); | ||
1280 | return -EIO; | ||
1281 | } else { | ||
1282 | sc->sc_flags |= SC_OP_RFKILL_REGISTERED; | ||
1283 | } | ||
1284 | } | ||
1285 | 1229 | ||
1286 | return 0; | 1230 | if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) |
1231 | wiphy_rfkill_start_polling(sc->hw->wiphy); | ||
1287 | } | 1232 | } |
1288 | #endif /* CONFIG_RFKILL */ | ||
1289 | 1233 | ||
1290 | void ath_cleanup(struct ath_softc *sc) | 1234 | void ath_cleanup(struct ath_softc *sc) |
1291 | { | 1235 | { |
@@ -1305,9 +1249,6 @@ void ath_detach(struct ath_softc *sc) | |||
1305 | 1249 | ||
1306 | DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n"); | 1250 | DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n"); |
1307 | 1251 | ||
1308 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
1309 | ath_deinit_rfkill(sc); | ||
1310 | #endif | ||
1311 | ath_deinit_leds(sc); | 1252 | ath_deinit_leds(sc); |
1312 | cancel_work_sync(&sc->chan_work); | 1253 | cancel_work_sync(&sc->chan_work); |
1313 | cancel_delayed_work_sync(&sc->wiphy_work); | 1254 | cancel_delayed_work_sync(&sc->wiphy_work); |
@@ -1645,13 +1586,6 @@ int ath_attach(u16 devid, struct ath_softc *sc) | |||
1645 | if (error != 0) | 1586 | if (error != 0) |
1646 | goto error_attach; | 1587 | goto error_attach; |
1647 | 1588 | ||
1648 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
1649 | /* Initialize s/w rfkill */ | ||
1650 | error = ath_init_sw_rfkill(sc); | ||
1651 | if (error) | ||
1652 | goto error_attach; | ||
1653 | #endif | ||
1654 | |||
1655 | INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); | 1589 | INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); |
1656 | INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); | 1590 | INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); |
1657 | sc->wiphy_scheduler_int = msecs_to_jiffies(500); | 1591 | sc->wiphy_scheduler_int = msecs_to_jiffies(500); |
@@ -1667,6 +1601,7 @@ int ath_attach(u16 devid, struct ath_softc *sc) | |||
1667 | /* Initialize LED control */ | 1601 | /* Initialize LED control */ |
1668 | ath_init_leds(sc); | 1602 | ath_init_leds(sc); |
1669 | 1603 | ||
1604 | ath_start_rfkill_poll(sc); | ||
1670 | 1605 | ||
1671 | return 0; | 1606 | return 0; |
1672 | 1607 | ||
@@ -2035,10 +1970,6 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
2035 | 1970 | ||
2036 | ieee80211_wake_queues(hw); | 1971 | ieee80211_wake_queues(hw); |
2037 | 1972 | ||
2038 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
2039 | r = ath_start_rfkill_poll(sc); | ||
2040 | #endif | ||
2041 | |||
2042 | mutex_unlock: | 1973 | mutex_unlock: |
2043 | mutex_unlock(&sc->mutex); | 1974 | mutex_unlock(&sc->mutex); |
2044 | 1975 | ||
@@ -2176,7 +2107,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
2176 | } else | 2107 | } else |
2177 | sc->rx.rxlink = NULL; | 2108 | sc->rx.rxlink = NULL; |
2178 | 2109 | ||
2179 | rfkill_pause_polling(sc->rf_kill.rfkill); | 2110 | wiphy_rfkill_stop_polling(sc->hw->wiphy); |
2180 | 2111 | ||
2181 | /* disable HAL and put h/w to sleep */ | 2112 | /* disable HAL and put h/w to sleep */ |
2182 | ath9k_hw_disable(sc->sc_ah); | 2113 | ath9k_hw_disable(sc->sc_ah); |
@@ -2782,6 +2713,7 @@ struct ieee80211_ops ath9k_ops = { | |||
2782 | .ampdu_action = ath9k_ampdu_action, | 2713 | .ampdu_action = ath9k_ampdu_action, |
2783 | .sw_scan_start = ath9k_sw_scan_start, | 2714 | .sw_scan_start = ath9k_sw_scan_start, |
2784 | .sw_scan_complete = ath9k_sw_scan_complete, | 2715 | .sw_scan_complete = ath9k_sw_scan_complete, |
2716 | .rfkill_poll = ath9k_rfkill_poll_state, | ||
2785 | }; | 2717 | }; |
2786 | 2718 | ||
2787 | static struct { | 2719 | static struct { |