diff options
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/dfs_pri_detector.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/b43/phy_n.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | 264 | ||||
-rw-r--r-- | drivers/ssb/driver_chipcommon_pmu.c | 29 | ||||
-rw-r--r-- | include/linux/ssb/ssb_driver_chipcommon.h | 2 | ||||
-rw-r--r-- | net/mac80211/iface.c | 27 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 24 |
11 files changed, 211 insertions, 157 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h index 28fd99203f64..bdee2ed67219 100644 --- a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h | |||
@@ -519,7 +519,7 @@ static const u32 ar9580_1p0_mac_core[][2] = { | |||
519 | {0x00008258, 0x00000000}, | 519 | {0x00008258, 0x00000000}, |
520 | {0x0000825c, 0x40000000}, | 520 | {0x0000825c, 0x40000000}, |
521 | {0x00008260, 0x00080922}, | 521 | {0x00008260, 0x00080922}, |
522 | {0x00008264, 0x9bc00010}, | 522 | {0x00008264, 0x9d400010}, |
523 | {0x00008268, 0xffffffff}, | 523 | {0x00008268, 0xffffffff}, |
524 | {0x0000826c, 0x0000ffff}, | 524 | {0x0000826c, 0x0000ffff}, |
525 | {0x00008270, 0x00000000}, | 525 | {0x00008270, 0x00000000}, |
diff --git a/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c b/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c index 467b60014b7b..73fe8d6db566 100644 --- a/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c +++ b/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c | |||
@@ -143,14 +143,14 @@ channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq) | |||
143 | u32 sz, i; | 143 | u32 sz, i; |
144 | struct channel_detector *cd; | 144 | struct channel_detector *cd; |
145 | 145 | ||
146 | cd = kmalloc(sizeof(*cd), GFP_KERNEL); | 146 | cd = kmalloc(sizeof(*cd), GFP_ATOMIC); |
147 | if (cd == NULL) | 147 | if (cd == NULL) |
148 | goto fail; | 148 | goto fail; |
149 | 149 | ||
150 | INIT_LIST_HEAD(&cd->head); | 150 | INIT_LIST_HEAD(&cd->head); |
151 | cd->freq = freq; | 151 | cd->freq = freq; |
152 | sz = sizeof(cd->detectors) * dpd->num_radar_types; | 152 | sz = sizeof(cd->detectors) * dpd->num_radar_types; |
153 | cd->detectors = kzalloc(sz, GFP_KERNEL); | 153 | cd->detectors = kzalloc(sz, GFP_ATOMIC); |
154 | if (cd->detectors == NULL) | 154 | if (cd->detectors == NULL) |
155 | goto fail; | 155 | goto fail; |
156 | 156 | ||
diff --git a/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c b/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c index 91b8dceeadb1..5e48c5515b8c 100644 --- a/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c +++ b/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c | |||
@@ -218,7 +218,7 @@ static bool pulse_queue_enqueue(struct pri_detector *pde, u64 ts) | |||
218 | { | 218 | { |
219 | struct pulse_elem *p = pool_get_pulse_elem(); | 219 | struct pulse_elem *p = pool_get_pulse_elem(); |
220 | if (p == NULL) { | 220 | if (p == NULL) { |
221 | p = kmalloc(sizeof(*p), GFP_KERNEL); | 221 | p = kmalloc(sizeof(*p), GFP_ATOMIC); |
222 | if (p == NULL) { | 222 | if (p == NULL) { |
223 | DFS_POOL_STAT_INC(pulse_alloc_error); | 223 | DFS_POOL_STAT_INC(pulse_alloc_error); |
224 | return false; | 224 | return false; |
@@ -299,7 +299,7 @@ static bool pseq_handler_create_sequences(struct pri_detector *pde, | |||
299 | ps.deadline_ts = ps.first_ts + ps.dur; | 299 | ps.deadline_ts = ps.first_ts + ps.dur; |
300 | new_ps = pool_get_pseq_elem(); | 300 | new_ps = pool_get_pseq_elem(); |
301 | if (new_ps == NULL) { | 301 | if (new_ps == NULL) { |
302 | new_ps = kmalloc(sizeof(*new_ps), GFP_KERNEL); | 302 | new_ps = kmalloc(sizeof(*new_ps), GFP_ATOMIC); |
303 | if (new_ps == NULL) { | 303 | if (new_ps == NULL) { |
304 | DFS_POOL_STAT_INC(pseq_alloc_error); | 304 | DFS_POOL_STAT_INC(pseq_alloc_error); |
305 | return false; | 305 | return false; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 716058b67557..a47f5e05fc04 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -796,7 +796,7 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv) | |||
796 | * required version. | 796 | * required version. |
797 | */ | 797 | */ |
798 | if (priv->fw_version_major != MAJOR_VERSION_REQ || | 798 | if (priv->fw_version_major != MAJOR_VERSION_REQ || |
799 | priv->fw_version_minor != MINOR_VERSION_REQ) { | 799 | priv->fw_version_minor < MINOR_VERSION_REQ) { |
800 | dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n", | 800 | dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n", |
801 | MAJOR_VERSION_REQ, MINOR_VERSION_REQ); | 801 | MAJOR_VERSION_REQ, MINOR_VERSION_REQ); |
802 | return -EINVAL; | 802 | return -EINVAL; |
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index e8486c1e091a..b70f220bc4b3 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c | |||
@@ -5165,7 +5165,8 @@ static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid) | |||
5165 | #endif | 5165 | #endif |
5166 | #ifdef CONFIG_B43_SSB | 5166 | #ifdef CONFIG_B43_SSB |
5167 | case B43_BUS_SSB: | 5167 | case B43_BUS_SSB: |
5168 | /* FIXME */ | 5168 | ssb_pmu_spuravoid_pllupdate(&dev->dev->sdev->bus->chipco, |
5169 | avoid); | ||
5169 | break; | 5170 | break; |
5170 | #endif | 5171 | #endif |
5171 | } | 5172 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index ec46ffff5409..78da3eff75e8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -4128,10 +4128,6 @@ static const struct ieee80211_iface_limit brcmf_iface_limits[] = { | |||
4128 | }, | 4128 | }, |
4129 | { | 4129 | { |
4130 | .max = 1, | 4130 | .max = 1, |
4131 | .types = BIT(NL80211_IFTYPE_P2P_DEVICE) | ||
4132 | }, | ||
4133 | { | ||
4134 | .max = 1, | ||
4135 | .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | | 4131 | .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | |
4136 | BIT(NL80211_IFTYPE_P2P_GO) | 4132 | BIT(NL80211_IFTYPE_P2P_GO) |
4137 | }, | 4133 | }, |
@@ -4187,8 +4183,7 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev) | |||
4187 | BIT(NL80211_IFTYPE_ADHOC) | | 4183 | BIT(NL80211_IFTYPE_ADHOC) | |
4188 | BIT(NL80211_IFTYPE_AP) | | 4184 | BIT(NL80211_IFTYPE_AP) | |
4189 | BIT(NL80211_IFTYPE_P2P_CLIENT) | | 4185 | BIT(NL80211_IFTYPE_P2P_CLIENT) | |
4190 | BIT(NL80211_IFTYPE_P2P_GO) | | 4186 | BIT(NL80211_IFTYPE_P2P_GO); |
4191 | BIT(NL80211_IFTYPE_P2P_DEVICE); | ||
4192 | wiphy->iface_combinations = brcmf_iface_combos; | 4187 | wiphy->iface_combinations = brcmf_iface_combos; |
4193 | wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); | 4188 | wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); |
4194 | wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; | 4189 | wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index c6451c61407a..e2340b231aa1 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
@@ -274,6 +274,130 @@ static void brcms_set_basic_rate(struct brcm_rateset *rs, u16 rate, bool is_br) | |||
274 | } | 274 | } |
275 | } | 275 | } |
276 | 276 | ||
277 | /** | ||
278 | * This function frees the WL per-device resources. | ||
279 | * | ||
280 | * This function frees resources owned by the WL device pointed to | ||
281 | * by the wl parameter. | ||
282 | * | ||
283 | * precondition: can both be called locked and unlocked | ||
284 | * | ||
285 | */ | ||
286 | static void brcms_free(struct brcms_info *wl) | ||
287 | { | ||
288 | struct brcms_timer *t, *next; | ||
289 | |||
290 | /* free ucode data */ | ||
291 | if (wl->fw.fw_cnt) | ||
292 | brcms_ucode_data_free(&wl->ucode); | ||
293 | if (wl->irq) | ||
294 | free_irq(wl->irq, wl); | ||
295 | |||
296 | /* kill dpc */ | ||
297 | tasklet_kill(&wl->tasklet); | ||
298 | |||
299 | if (wl->pub) { | ||
300 | brcms_debugfs_detach(wl->pub); | ||
301 | brcms_c_module_unregister(wl->pub, "linux", wl); | ||
302 | } | ||
303 | |||
304 | /* free common resources */ | ||
305 | if (wl->wlc) { | ||
306 | brcms_c_detach(wl->wlc); | ||
307 | wl->wlc = NULL; | ||
308 | wl->pub = NULL; | ||
309 | } | ||
310 | |||
311 | /* virtual interface deletion is deferred so we cannot spinwait */ | ||
312 | |||
313 | /* wait for all pending callbacks to complete */ | ||
314 | while (atomic_read(&wl->callbacks) > 0) | ||
315 | schedule(); | ||
316 | |||
317 | /* free timers */ | ||
318 | for (t = wl->timers; t; t = next) { | ||
319 | next = t->next; | ||
320 | #ifdef DEBUG | ||
321 | kfree(t->name); | ||
322 | #endif | ||
323 | kfree(t); | ||
324 | } | ||
325 | } | ||
326 | |||
327 | /* | ||
328 | * called from both kernel as from this kernel module (error flow on attach) | ||
329 | * precondition: perimeter lock is not acquired. | ||
330 | */ | ||
331 | static void brcms_remove(struct bcma_device *pdev) | ||
332 | { | ||
333 | struct ieee80211_hw *hw = bcma_get_drvdata(pdev); | ||
334 | struct brcms_info *wl = hw->priv; | ||
335 | |||
336 | if (wl->wlc) { | ||
337 | wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); | ||
338 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); | ||
339 | ieee80211_unregister_hw(hw); | ||
340 | } | ||
341 | |||
342 | brcms_free(wl); | ||
343 | |||
344 | bcma_set_drvdata(pdev, NULL); | ||
345 | ieee80211_free_hw(hw); | ||
346 | } | ||
347 | |||
348 | /* | ||
349 | * Precondition: Since this function is called in brcms_pci_probe() context, | ||
350 | * no locking is required. | ||
351 | */ | ||
352 | static void brcms_release_fw(struct brcms_info *wl) | ||
353 | { | ||
354 | int i; | ||
355 | for (i = 0; i < MAX_FW_IMAGES; i++) { | ||
356 | release_firmware(wl->fw.fw_bin[i]); | ||
357 | release_firmware(wl->fw.fw_hdr[i]); | ||
358 | } | ||
359 | } | ||
360 | |||
361 | /* | ||
362 | * Precondition: Since this function is called in brcms_pci_probe() context, | ||
363 | * no locking is required. | ||
364 | */ | ||
365 | static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev) | ||
366 | { | ||
367 | int status; | ||
368 | struct device *device = &pdev->dev; | ||
369 | char fw_name[100]; | ||
370 | int i; | ||
371 | |||
372 | memset(&wl->fw, 0, sizeof(struct brcms_firmware)); | ||
373 | for (i = 0; i < MAX_FW_IMAGES; i++) { | ||
374 | if (brcms_firmwares[i] == NULL) | ||
375 | break; | ||
376 | sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i], | ||
377 | UCODE_LOADER_API_VER); | ||
378 | status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); | ||
379 | if (status) { | ||
380 | wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", | ||
381 | KBUILD_MODNAME, fw_name); | ||
382 | return status; | ||
383 | } | ||
384 | sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i], | ||
385 | UCODE_LOADER_API_VER); | ||
386 | status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); | ||
387 | if (status) { | ||
388 | wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", | ||
389 | KBUILD_MODNAME, fw_name); | ||
390 | return status; | ||
391 | } | ||
392 | wl->fw.hdr_num_entries[i] = | ||
393 | wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr)); | ||
394 | } | ||
395 | wl->fw.fw_cnt = i; | ||
396 | status = brcms_ucode_data_init(wl, &wl->ucode); | ||
397 | brcms_release_fw(wl); | ||
398 | return status; | ||
399 | } | ||
400 | |||
277 | static void brcms_ops_tx(struct ieee80211_hw *hw, | 401 | static void brcms_ops_tx(struct ieee80211_hw *hw, |
278 | struct ieee80211_tx_control *control, | 402 | struct ieee80211_tx_control *control, |
279 | struct sk_buff *skb) | 403 | struct sk_buff *skb) |
@@ -306,6 +430,14 @@ static int brcms_ops_start(struct ieee80211_hw *hw) | |||
306 | if (!blocked) | 430 | if (!blocked) |
307 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); | 431 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); |
308 | 432 | ||
433 | if (!wl->ucode.bcm43xx_bomminor) { | ||
434 | err = brcms_request_fw(wl, wl->wlc->hw->d11core); | ||
435 | if (err) { | ||
436 | brcms_remove(wl->wlc->hw->d11core); | ||
437 | return -ENOENT; | ||
438 | } | ||
439 | } | ||
440 | |||
309 | spin_lock_bh(&wl->lock); | 441 | spin_lock_bh(&wl->lock); |
310 | /* avoid acknowledging frames before a non-monitor device is added */ | 442 | /* avoid acknowledging frames before a non-monitor device is added */ |
311 | wl->mute_tx = true; | 443 | wl->mute_tx = true; |
@@ -793,128 +925,6 @@ void brcms_dpc(unsigned long data) | |||
793 | wake_up(&wl->tx_flush_wq); | 925 | wake_up(&wl->tx_flush_wq); |
794 | } | 926 | } |
795 | 927 | ||
796 | /* | ||
797 | * Precondition: Since this function is called in brcms_pci_probe() context, | ||
798 | * no locking is required. | ||
799 | */ | ||
800 | static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev) | ||
801 | { | ||
802 | int status; | ||
803 | struct device *device = &pdev->dev; | ||
804 | char fw_name[100]; | ||
805 | int i; | ||
806 | |||
807 | memset(&wl->fw, 0, sizeof(struct brcms_firmware)); | ||
808 | for (i = 0; i < MAX_FW_IMAGES; i++) { | ||
809 | if (brcms_firmwares[i] == NULL) | ||
810 | break; | ||
811 | sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i], | ||
812 | UCODE_LOADER_API_VER); | ||
813 | status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); | ||
814 | if (status) { | ||
815 | wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", | ||
816 | KBUILD_MODNAME, fw_name); | ||
817 | return status; | ||
818 | } | ||
819 | sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i], | ||
820 | UCODE_LOADER_API_VER); | ||
821 | status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); | ||
822 | if (status) { | ||
823 | wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", | ||
824 | KBUILD_MODNAME, fw_name); | ||
825 | return status; | ||
826 | } | ||
827 | wl->fw.hdr_num_entries[i] = | ||
828 | wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr)); | ||
829 | } | ||
830 | wl->fw.fw_cnt = i; | ||
831 | return brcms_ucode_data_init(wl, &wl->ucode); | ||
832 | } | ||
833 | |||
834 | /* | ||
835 | * Precondition: Since this function is called in brcms_pci_probe() context, | ||
836 | * no locking is required. | ||
837 | */ | ||
838 | static void brcms_release_fw(struct brcms_info *wl) | ||
839 | { | ||
840 | int i; | ||
841 | for (i = 0; i < MAX_FW_IMAGES; i++) { | ||
842 | release_firmware(wl->fw.fw_bin[i]); | ||
843 | release_firmware(wl->fw.fw_hdr[i]); | ||
844 | } | ||
845 | } | ||
846 | |||
847 | /** | ||
848 | * This function frees the WL per-device resources. | ||
849 | * | ||
850 | * This function frees resources owned by the WL device pointed to | ||
851 | * by the wl parameter. | ||
852 | * | ||
853 | * precondition: can both be called locked and unlocked | ||
854 | * | ||
855 | */ | ||
856 | static void brcms_free(struct brcms_info *wl) | ||
857 | { | ||
858 | struct brcms_timer *t, *next; | ||
859 | |||
860 | /* free ucode data */ | ||
861 | if (wl->fw.fw_cnt) | ||
862 | brcms_ucode_data_free(&wl->ucode); | ||
863 | if (wl->irq) | ||
864 | free_irq(wl->irq, wl); | ||
865 | |||
866 | /* kill dpc */ | ||
867 | tasklet_kill(&wl->tasklet); | ||
868 | |||
869 | if (wl->pub) { | ||
870 | brcms_debugfs_detach(wl->pub); | ||
871 | brcms_c_module_unregister(wl->pub, "linux", wl); | ||
872 | } | ||
873 | |||
874 | /* free common resources */ | ||
875 | if (wl->wlc) { | ||
876 | brcms_c_detach(wl->wlc); | ||
877 | wl->wlc = NULL; | ||
878 | wl->pub = NULL; | ||
879 | } | ||
880 | |||
881 | /* virtual interface deletion is deferred so we cannot spinwait */ | ||
882 | |||
883 | /* wait for all pending callbacks to complete */ | ||
884 | while (atomic_read(&wl->callbacks) > 0) | ||
885 | schedule(); | ||
886 | |||
887 | /* free timers */ | ||
888 | for (t = wl->timers; t; t = next) { | ||
889 | next = t->next; | ||
890 | #ifdef DEBUG | ||
891 | kfree(t->name); | ||
892 | #endif | ||
893 | kfree(t); | ||
894 | } | ||
895 | } | ||
896 | |||
897 | /* | ||
898 | * called from both kernel as from this kernel module (error flow on attach) | ||
899 | * precondition: perimeter lock is not acquired. | ||
900 | */ | ||
901 | static void brcms_remove(struct bcma_device *pdev) | ||
902 | { | ||
903 | struct ieee80211_hw *hw = bcma_get_drvdata(pdev); | ||
904 | struct brcms_info *wl = hw->priv; | ||
905 | |||
906 | if (wl->wlc) { | ||
907 | wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); | ||
908 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); | ||
909 | ieee80211_unregister_hw(hw); | ||
910 | } | ||
911 | |||
912 | brcms_free(wl); | ||
913 | |||
914 | bcma_set_drvdata(pdev, NULL); | ||
915 | ieee80211_free_hw(hw); | ||
916 | } | ||
917 | |||
918 | static irqreturn_t brcms_isr(int irq, void *dev_id) | 928 | static irqreturn_t brcms_isr(int irq, void *dev_id) |
919 | { | 929 | { |
920 | struct brcms_info *wl; | 930 | struct brcms_info *wl; |
@@ -1047,18 +1057,8 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev) | |||
1047 | spin_lock_init(&wl->lock); | 1057 | spin_lock_init(&wl->lock); |
1048 | spin_lock_init(&wl->isr_lock); | 1058 | spin_lock_init(&wl->isr_lock); |
1049 | 1059 | ||
1050 | /* prepare ucode */ | ||
1051 | if (brcms_request_fw(wl, pdev) < 0) { | ||
1052 | wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in " | ||
1053 | "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm"); | ||
1054 | brcms_release_fw(wl); | ||
1055 | brcms_remove(pdev); | ||
1056 | return NULL; | ||
1057 | } | ||
1058 | |||
1059 | /* common load-time initialization */ | 1060 | /* common load-time initialization */ |
1060 | wl->wlc = brcms_c_attach((void *)wl, pdev, unit, false, &err); | 1061 | wl->wlc = brcms_c_attach((void *)wl, pdev, unit, false, &err); |
1061 | brcms_release_fw(wl); | ||
1062 | if (!wl->wlc) { | 1062 | if (!wl->wlc) { |
1063 | wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n", | 1063 | wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n", |
1064 | KBUILD_MODNAME, err); | 1064 | KBUILD_MODNAME, err); |
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c index 4c0f6d883dd3..7b0bce936762 100644 --- a/drivers/ssb/driver_chipcommon_pmu.c +++ b/drivers/ssb/driver_chipcommon_pmu.c | |||
@@ -675,3 +675,32 @@ u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc) | |||
675 | return 0; | 675 | return 0; |
676 | } | 676 | } |
677 | } | 677 | } |
678 | |||
679 | void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid) | ||
680 | { | ||
681 | u32 pmu_ctl = 0; | ||
682 | |||
683 | switch (cc->dev->bus->chip_id) { | ||
684 | case 0x4322: | ||
685 | ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL0, 0x11100070); | ||
686 | ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL1, 0x1014140a); | ||
687 | ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL5, 0x88888854); | ||
688 | if (spuravoid == 1) | ||
689 | ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05201828); | ||
690 | else | ||
691 | ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05001828); | ||
692 | pmu_ctl = SSB_CHIPCO_PMU_CTL_PLL_UPD; | ||
693 | break; | ||
694 | case 43222: | ||
695 | /* TODO: BCM43222 requires updating PLLs too */ | ||
696 | return; | ||
697 | default: | ||
698 | ssb_printk(KERN_ERR PFX | ||
699 | "Unknown spuravoidance settings for chip 0x%04X, not changing PLL\n", | ||
700 | cc->dev->bus->chip_id); | ||
701 | return; | ||
702 | } | ||
703 | |||
704 | chipco_set32(cc, SSB_CHIPCO_PMU_CTL, pmu_ctl); | ||
705 | } | ||
706 | EXPORT_SYMBOL_GPL(ssb_pmu_spuravoid_pllupdate); | ||
diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h index 9e492be5244b..6fcfe99bd999 100644 --- a/include/linux/ssb/ssb_driver_chipcommon.h +++ b/include/linux/ssb/ssb_driver_chipcommon.h | |||
@@ -219,6 +219,7 @@ | |||
219 | #define SSB_CHIPCO_PMU_CTL 0x0600 /* PMU control */ | 219 | #define SSB_CHIPCO_PMU_CTL 0x0600 /* PMU control */ |
220 | #define SSB_CHIPCO_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */ | 220 | #define SSB_CHIPCO_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */ |
221 | #define SSB_CHIPCO_PMU_CTL_ILP_DIV_SHIFT 16 | 221 | #define SSB_CHIPCO_PMU_CTL_ILP_DIV_SHIFT 16 |
222 | #define SSB_CHIPCO_PMU_CTL_PLL_UPD 0x00000400 | ||
222 | #define SSB_CHIPCO_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */ | 223 | #define SSB_CHIPCO_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */ |
223 | #define SSB_CHIPCO_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */ | 224 | #define SSB_CHIPCO_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */ |
224 | #define SSB_CHIPCO_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */ | 225 | #define SSB_CHIPCO_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */ |
@@ -667,5 +668,6 @@ enum ssb_pmu_ldo_volt_id { | |||
667 | void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc, | 668 | void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc, |
668 | enum ssb_pmu_ldo_volt_id id, u32 voltage); | 669 | enum ssb_pmu_ldo_volt_id id, u32 voltage); |
669 | void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on); | 670 | void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on); |
671 | void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid); | ||
670 | 672 | ||
671 | #endif /* LINUX_SSB_CHIPCO_H_ */ | 673 | #endif /* LINUX_SSB_CHIPCO_H_ */ |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 58150f877ec3..9ed49ad0380f 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -78,7 +78,7 @@ void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) | |||
78 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER); | 78 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER); |
79 | } | 79 | } |
80 | 80 | ||
81 | u32 ieee80211_idle_off(struct ieee80211_local *local) | 81 | static u32 __ieee80211_idle_off(struct ieee80211_local *local) |
82 | { | 82 | { |
83 | if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) | 83 | if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) |
84 | return 0; | 84 | return 0; |
@@ -87,7 +87,7 @@ u32 ieee80211_idle_off(struct ieee80211_local *local) | |||
87 | return IEEE80211_CONF_CHANGE_IDLE; | 87 | return IEEE80211_CONF_CHANGE_IDLE; |
88 | } | 88 | } |
89 | 89 | ||
90 | static u32 ieee80211_idle_on(struct ieee80211_local *local) | 90 | static u32 __ieee80211_idle_on(struct ieee80211_local *local) |
91 | { | 91 | { |
92 | if (local->hw.conf.flags & IEEE80211_CONF_IDLE) | 92 | if (local->hw.conf.flags & IEEE80211_CONF_IDLE) |
93 | return 0; | 93 | return 0; |
@@ -98,16 +98,18 @@ static u32 ieee80211_idle_on(struct ieee80211_local *local) | |||
98 | return IEEE80211_CONF_CHANGE_IDLE; | 98 | return IEEE80211_CONF_CHANGE_IDLE; |
99 | } | 99 | } |
100 | 100 | ||
101 | void ieee80211_recalc_idle(struct ieee80211_local *local) | 101 | static u32 __ieee80211_recalc_idle(struct ieee80211_local *local, |
102 | bool force_active) | ||
102 | { | 103 | { |
103 | bool working = false, scanning, active; | 104 | bool working = false, scanning, active; |
104 | unsigned int led_trig_start = 0, led_trig_stop = 0; | 105 | unsigned int led_trig_start = 0, led_trig_stop = 0; |
105 | struct ieee80211_roc_work *roc; | 106 | struct ieee80211_roc_work *roc; |
106 | u32 change; | ||
107 | 107 | ||
108 | lockdep_assert_held(&local->mtx); | 108 | lockdep_assert_held(&local->mtx); |
109 | 109 | ||
110 | active = !list_empty(&local->chanctx_list) || local->monitors; | 110 | active = force_active || |
111 | !list_empty(&local->chanctx_list) || | ||
112 | local->monitors; | ||
111 | 113 | ||
112 | if (!local->ops->remain_on_channel) { | 114 | if (!local->ops->remain_on_channel) { |
113 | list_for_each_entry(roc, &local->roc_list, list) { | 115 | list_for_each_entry(roc, &local->roc_list, list) { |
@@ -132,9 +134,18 @@ void ieee80211_recalc_idle(struct ieee80211_local *local) | |||
132 | ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); | 134 | ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); |
133 | 135 | ||
134 | if (working || scanning || active) | 136 | if (working || scanning || active) |
135 | change = ieee80211_idle_off(local); | 137 | return __ieee80211_idle_off(local); |
136 | else | 138 | return __ieee80211_idle_on(local); |
137 | change = ieee80211_idle_on(local); | 139 | } |
140 | |||
141 | u32 ieee80211_idle_off(struct ieee80211_local *local) | ||
142 | { | ||
143 | return __ieee80211_recalc_idle(local, true); | ||
144 | } | ||
145 | |||
146 | void ieee80211_recalc_idle(struct ieee80211_local *local) | ||
147 | { | ||
148 | u32 change = __ieee80211_recalc_idle(local, false); | ||
138 | if (change) | 149 | if (change) |
139 | ieee80211_hw_config(local, change); | 150 | ieee80211_hw_config(local, change); |
140 | } | 151 | } |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 82cc30318a86..346ad4cfb013 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -3964,8 +3964,16 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
3964 | /* prep auth_data so we don't go into idle on disassoc */ | 3964 | /* prep auth_data so we don't go into idle on disassoc */ |
3965 | ifmgd->auth_data = auth_data; | 3965 | ifmgd->auth_data = auth_data; |
3966 | 3966 | ||
3967 | if (ifmgd->associated) | 3967 | if (ifmgd->associated) { |
3968 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | 3968 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; |
3969 | |||
3970 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, | ||
3971 | WLAN_REASON_UNSPECIFIED, | ||
3972 | false, frame_buf); | ||
3973 | |||
3974 | __cfg80211_send_deauth(sdata->dev, frame_buf, | ||
3975 | sizeof(frame_buf)); | ||
3976 | } | ||
3969 | 3977 | ||
3970 | sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); | 3978 | sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); |
3971 | 3979 | ||
@@ -4025,8 +4033,16 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4025 | 4033 | ||
4026 | mutex_lock(&ifmgd->mtx); | 4034 | mutex_lock(&ifmgd->mtx); |
4027 | 4035 | ||
4028 | if (ifmgd->associated) | 4036 | if (ifmgd->associated) { |
4029 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | 4037 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; |
4038 | |||
4039 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, | ||
4040 | WLAN_REASON_UNSPECIFIED, | ||
4041 | false, frame_buf); | ||
4042 | |||
4043 | __cfg80211_send_deauth(sdata->dev, frame_buf, | ||
4044 | sizeof(frame_buf)); | ||
4045 | } | ||
4030 | 4046 | ||
4031 | if (ifmgd->auth_data && !ifmgd->auth_data->done) { | 4047 | if (ifmgd->auth_data && !ifmgd->auth_data->done) { |
4032 | err = -EBUSY; | 4048 | err = -EBUSY; |