Commit ec094144cdd54a36e65a69161e9705959c09cb23
Exists in
master
and in
20 other branches
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
Conflicts: drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
Showing 11 changed files Side-by-side Diff
- drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
- drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c
- drivers/net/wireless/ath/ath9k/dfs_pri_detector.c
- drivers/net/wireless/ath/ath9k/htc_drv_init.c
- drivers/net/wireless/b43/phy_n.c
- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
- drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
- drivers/ssb/driver_chipcommon_pmu.c
- include/linux/ssb/ssb_driver_chipcommon.h
- net/mac80211/iface.c
- net/mac80211/mlme.c
drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c
... | ... | @@ -145,14 +145,14 @@ |
145 | 145 | struct channel_detector *cd; |
146 | 146 | struct ath_common *common = ath9k_hw_common(dpd->ah); |
147 | 147 | |
148 | - cd = kmalloc(sizeof(*cd), GFP_KERNEL); | |
148 | + cd = kmalloc(sizeof(*cd), GFP_ATOMIC); | |
149 | 149 | if (cd == NULL) |
150 | 150 | goto fail; |
151 | 151 | |
152 | 152 | INIT_LIST_HEAD(&cd->head); |
153 | 153 | cd->freq = freq; |
154 | 154 | sz = sizeof(cd->detectors) * dpd->num_radar_types; |
155 | - cd->detectors = kzalloc(sz, GFP_KERNEL); | |
155 | + cd->detectors = kzalloc(sz, GFP_ATOMIC); | |
156 | 156 | if (cd->detectors == NULL) |
157 | 157 | goto fail; |
158 | 158 |
drivers/net/wireless/ath/ath9k/dfs_pri_detector.c
... | ... | @@ -196,7 +196,7 @@ |
196 | 196 | { |
197 | 197 | struct pulse_elem *p = pool_get_pulse_elem(); |
198 | 198 | if (p == NULL) { |
199 | - p = kmalloc(sizeof(*p), GFP_KERNEL); | |
199 | + p = kmalloc(sizeof(*p), GFP_ATOMIC); | |
200 | 200 | if (p == NULL) { |
201 | 201 | DFS_POOL_STAT_INC(pulse_alloc_error); |
202 | 202 | return false; |
... | ... | @@ -277,7 +277,7 @@ |
277 | 277 | ps.deadline_ts = ps.first_ts + ps.dur; |
278 | 278 | new_ps = pool_get_pseq_elem(); |
279 | 279 | if (new_ps == NULL) { |
280 | - new_ps = kmalloc(sizeof(*new_ps), GFP_KERNEL); | |
280 | + new_ps = kmalloc(sizeof(*new_ps), GFP_ATOMIC); | |
281 | 281 | if (new_ps == NULL) { |
282 | 282 | DFS_POOL_STAT_INC(pseq_alloc_error); |
283 | 283 | return false; |
drivers/net/wireless/ath/ath9k/htc_drv_init.c
... | ... | @@ -796,7 +796,7 @@ |
796 | 796 | * required version. |
797 | 797 | */ |
798 | 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 | 800 | dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n", |
801 | 801 | MAJOR_VERSION_REQ, MINOR_VERSION_REQ); |
802 | 802 | return -EINVAL; |
drivers/net/wireless/b43/phy_n.c
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
... | ... | @@ -4088,10 +4088,6 @@ |
4088 | 4088 | }, |
4089 | 4089 | { |
4090 | 4090 | .max = 1, |
4091 | - .types = BIT(NL80211_IFTYPE_P2P_DEVICE) | |
4092 | - }, | |
4093 | - { | |
4094 | - .max = 1, | |
4095 | 4091 | .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | |
4096 | 4092 | BIT(NL80211_IFTYPE_P2P_GO) |
4097 | 4093 | }, |
... | ... | @@ -4152,8 +4148,7 @@ |
4152 | 4148 | BIT(NL80211_IFTYPE_ADHOC) | |
4153 | 4149 | BIT(NL80211_IFTYPE_AP) | |
4154 | 4150 | BIT(NL80211_IFTYPE_P2P_CLIENT) | |
4155 | - BIT(NL80211_IFTYPE_P2P_GO) | | |
4156 | - BIT(NL80211_IFTYPE_P2P_DEVICE); | |
4151 | + BIT(NL80211_IFTYPE_P2P_GO); | |
4157 | 4152 | wiphy->iface_combinations = brcmf_iface_combos; |
4158 | 4153 | wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); |
4159 | 4154 | wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; |
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
... | ... | @@ -276,6 +276,130 @@ |
276 | 276 | } |
277 | 277 | } |
278 | 278 | |
279 | +/** | |
280 | + * This function frees the WL per-device resources. | |
281 | + * | |
282 | + * This function frees resources owned by the WL device pointed to | |
283 | + * by the wl parameter. | |
284 | + * | |
285 | + * precondition: can both be called locked and unlocked | |
286 | + * | |
287 | + */ | |
288 | +static void brcms_free(struct brcms_info *wl) | |
289 | +{ | |
290 | + struct brcms_timer *t, *next; | |
291 | + | |
292 | + /* free ucode data */ | |
293 | + if (wl->fw.fw_cnt) | |
294 | + brcms_ucode_data_free(&wl->ucode); | |
295 | + if (wl->irq) | |
296 | + free_irq(wl->irq, wl); | |
297 | + | |
298 | + /* kill dpc */ | |
299 | + tasklet_kill(&wl->tasklet); | |
300 | + | |
301 | + if (wl->pub) { | |
302 | + brcms_debugfs_detach(wl->pub); | |
303 | + brcms_c_module_unregister(wl->pub, "linux", wl); | |
304 | + } | |
305 | + | |
306 | + /* free common resources */ | |
307 | + if (wl->wlc) { | |
308 | + brcms_c_detach(wl->wlc); | |
309 | + wl->wlc = NULL; | |
310 | + wl->pub = NULL; | |
311 | + } | |
312 | + | |
313 | + /* virtual interface deletion is deferred so we cannot spinwait */ | |
314 | + | |
315 | + /* wait for all pending callbacks to complete */ | |
316 | + while (atomic_read(&wl->callbacks) > 0) | |
317 | + schedule(); | |
318 | + | |
319 | + /* free timers */ | |
320 | + for (t = wl->timers; t; t = next) { | |
321 | + next = t->next; | |
322 | +#ifdef DEBUG | |
323 | + kfree(t->name); | |
324 | +#endif | |
325 | + kfree(t); | |
326 | + } | |
327 | +} | |
328 | + | |
329 | +/* | |
330 | +* called from both kernel as from this kernel module (error flow on attach) | |
331 | +* precondition: perimeter lock is not acquired. | |
332 | +*/ | |
333 | +static void brcms_remove(struct bcma_device *pdev) | |
334 | +{ | |
335 | + struct ieee80211_hw *hw = bcma_get_drvdata(pdev); | |
336 | + struct brcms_info *wl = hw->priv; | |
337 | + | |
338 | + if (wl->wlc) { | |
339 | + wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); | |
340 | + wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); | |
341 | + ieee80211_unregister_hw(hw); | |
342 | + } | |
343 | + | |
344 | + brcms_free(wl); | |
345 | + | |
346 | + bcma_set_drvdata(pdev, NULL); | |
347 | + ieee80211_free_hw(hw); | |
348 | +} | |
349 | + | |
350 | +/* | |
351 | + * Precondition: Since this function is called in brcms_pci_probe() context, | |
352 | + * no locking is required. | |
353 | + */ | |
354 | +static void brcms_release_fw(struct brcms_info *wl) | |
355 | +{ | |
356 | + int i; | |
357 | + for (i = 0; i < MAX_FW_IMAGES; i++) { | |
358 | + release_firmware(wl->fw.fw_bin[i]); | |
359 | + release_firmware(wl->fw.fw_hdr[i]); | |
360 | + } | |
361 | +} | |
362 | + | |
363 | +/* | |
364 | + * Precondition: Since this function is called in brcms_pci_probe() context, | |
365 | + * no locking is required. | |
366 | + */ | |
367 | +static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev) | |
368 | +{ | |
369 | + int status; | |
370 | + struct device *device = &pdev->dev; | |
371 | + char fw_name[100]; | |
372 | + int i; | |
373 | + | |
374 | + memset(&wl->fw, 0, sizeof(struct brcms_firmware)); | |
375 | + for (i = 0; i < MAX_FW_IMAGES; i++) { | |
376 | + if (brcms_firmwares[i] == NULL) | |
377 | + break; | |
378 | + sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i], | |
379 | + UCODE_LOADER_API_VER); | |
380 | + status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); | |
381 | + if (status) { | |
382 | + wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", | |
383 | + KBUILD_MODNAME, fw_name); | |
384 | + return status; | |
385 | + } | |
386 | + sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i], | |
387 | + UCODE_LOADER_API_VER); | |
388 | + status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); | |
389 | + if (status) { | |
390 | + wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", | |
391 | + KBUILD_MODNAME, fw_name); | |
392 | + return status; | |
393 | + } | |
394 | + wl->fw.hdr_num_entries[i] = | |
395 | + wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr)); | |
396 | + } | |
397 | + wl->fw.fw_cnt = i; | |
398 | + status = brcms_ucode_data_init(wl, &wl->ucode); | |
399 | + brcms_release_fw(wl); | |
400 | + return status; | |
401 | +} | |
402 | + | |
279 | 403 | static void brcms_ops_tx(struct ieee80211_hw *hw, |
280 | 404 | struct ieee80211_tx_control *control, |
281 | 405 | struct sk_buff *skb) |
... | ... | @@ -308,6 +432,14 @@ |
308 | 432 | if (!blocked) |
309 | 433 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); |
310 | 434 | |
435 | + if (!wl->ucode.bcm43xx_bomminor) { | |
436 | + err = brcms_request_fw(wl, wl->wlc->hw->d11core); | |
437 | + if (err) { | |
438 | + brcms_remove(wl->wlc->hw->d11core); | |
439 | + return -ENOENT; | |
440 | + } | |
441 | + } | |
442 | + | |
311 | 443 | spin_lock_bh(&wl->lock); |
312 | 444 | /* avoid acknowledging frames before a non-monitor device is added */ |
313 | 445 | wl->mute_tx = true; |
... | ... | @@ -856,129 +988,6 @@ |
856 | 988 | wake_up(&wl->tx_flush_wq); |
857 | 989 | } |
858 | 990 | |
859 | -/* | |
860 | - * Precondition: Since this function is called in brcms_pci_probe() context, | |
861 | - * no locking is required. | |
862 | - */ | |
863 | -static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev) | |
864 | -{ | |
865 | - int status; | |
866 | - struct device *device = &pdev->dev; | |
867 | - char fw_name[100]; | |
868 | - int i; | |
869 | - | |
870 | - memset(&wl->fw, 0, sizeof(struct brcms_firmware)); | |
871 | - for (i = 0; i < MAX_FW_IMAGES; i++) { | |
872 | - if (brcms_firmwares[i] == NULL) | |
873 | - break; | |
874 | - sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i], | |
875 | - UCODE_LOADER_API_VER); | |
876 | - status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); | |
877 | - if (status) { | |
878 | - wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", | |
879 | - KBUILD_MODNAME, fw_name); | |
880 | - return status; | |
881 | - } | |
882 | - sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i], | |
883 | - UCODE_LOADER_API_VER); | |
884 | - status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); | |
885 | - if (status) { | |
886 | - wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", | |
887 | - KBUILD_MODNAME, fw_name); | |
888 | - return status; | |
889 | - } | |
890 | - wl->fw.hdr_num_entries[i] = | |
891 | - wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr)); | |
892 | - } | |
893 | - wl->fw.fw_cnt = i; | |
894 | - return brcms_ucode_data_init(wl, &wl->ucode); | |
895 | -} | |
896 | - | |
897 | -/* | |
898 | - * Precondition: Since this function is called in brcms_pci_probe() context, | |
899 | - * no locking is required. | |
900 | - */ | |
901 | -static void brcms_release_fw(struct brcms_info *wl) | |
902 | -{ | |
903 | - int i; | |
904 | - for (i = 0; i < MAX_FW_IMAGES; i++) { | |
905 | - release_firmware(wl->fw.fw_bin[i]); | |
906 | - release_firmware(wl->fw.fw_hdr[i]); | |
907 | - } | |
908 | -} | |
909 | - | |
910 | -/** | |
911 | - * This function frees the WL per-device resources. | |
912 | - * | |
913 | - * This function frees resources owned by the WL device pointed to | |
914 | - * by the wl parameter. | |
915 | - * | |
916 | - * precondition: can both be called locked and unlocked | |
917 | - * | |
918 | - */ | |
919 | -static void brcms_free(struct brcms_info *wl) | |
920 | -{ | |
921 | - struct brcms_timer *t, *next; | |
922 | - | |
923 | - /* free ucode data */ | |
924 | - if (wl->fw.fw_cnt) | |
925 | - brcms_ucode_data_free(&wl->ucode); | |
926 | - if (wl->irq) | |
927 | - free_irq(wl->irq, wl); | |
928 | - | |
929 | - /* kill dpc */ | |
930 | - tasklet_kill(&wl->tasklet); | |
931 | - | |
932 | - if (wl->pub) { | |
933 | - brcms_debugfs_detach(wl->pub); | |
934 | - brcms_c_module_unregister(wl->pub, "linux", wl); | |
935 | - } | |
936 | - | |
937 | - /* free common resources */ | |
938 | - if (wl->wlc) { | |
939 | - brcms_c_detach(wl->wlc); | |
940 | - wl->wlc = NULL; | |
941 | - wl->pub = NULL; | |
942 | - } | |
943 | - | |
944 | - /* virtual interface deletion is deferred so we cannot spinwait */ | |
945 | - | |
946 | - /* wait for all pending callbacks to complete */ | |
947 | - while (atomic_read(&wl->callbacks) > 0) | |
948 | - schedule(); | |
949 | - | |
950 | - /* free timers */ | |
951 | - for (t = wl->timers; t; t = next) { | |
952 | - next = t->next; | |
953 | -#ifdef DEBUG | |
954 | - kfree(t->name); | |
955 | -#endif | |
956 | - kfree(t); | |
957 | - } | |
958 | -} | |
959 | - | |
960 | -/* | |
961 | -* called from both kernel as from this kernel module (error flow on attach) | |
962 | -* precondition: perimeter lock is not acquired. | |
963 | -*/ | |
964 | -static void brcms_remove(struct bcma_device *pdev) | |
965 | -{ | |
966 | - struct ieee80211_hw *hw = bcma_get_drvdata(pdev); | |
967 | - struct brcms_info *wl = hw->priv; | |
968 | - | |
969 | - if (wl->wlc) { | |
970 | - brcms_led_unregister(wl); | |
971 | - wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); | |
972 | - wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); | |
973 | - ieee80211_unregister_hw(hw); | |
974 | - } | |
975 | - | |
976 | - brcms_free(wl); | |
977 | - | |
978 | - bcma_set_drvdata(pdev, NULL); | |
979 | - ieee80211_free_hw(hw); | |
980 | -} | |
981 | - | |
982 | 991 | static irqreturn_t brcms_isr(int irq, void *dev_id) |
983 | 992 | { |
984 | 993 | struct brcms_info *wl; |
985 | 994 | |
... | ... | @@ -1120,18 +1129,8 @@ |
1120 | 1129 | spin_lock_init(&wl->lock); |
1121 | 1130 | spin_lock_init(&wl->isr_lock); |
1122 | 1131 | |
1123 | - /* prepare ucode */ | |
1124 | - if (brcms_request_fw(wl, pdev) < 0) { | |
1125 | - wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in " | |
1126 | - "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm"); | |
1127 | - brcms_release_fw(wl); | |
1128 | - brcms_remove(pdev); | |
1129 | - return NULL; | |
1130 | - } | |
1131 | - | |
1132 | 1132 | /* common load-time initialization */ |
1133 | 1133 | wl->wlc = brcms_c_attach((void *)wl, pdev, unit, false, &err); |
1134 | - brcms_release_fw(wl); | |
1135 | 1134 | if (!wl->wlc) { |
1136 | 1135 | wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n", |
1137 | 1136 | KBUILD_MODNAME, err); |
drivers/ssb/driver_chipcommon_pmu.c
... | ... | @@ -670,4 +670,33 @@ |
670 | 670 | return 0; |
671 | 671 | } |
672 | 672 | } |
673 | + | |
674 | +void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid) | |
675 | +{ | |
676 | + u32 pmu_ctl = 0; | |
677 | + | |
678 | + switch (cc->dev->bus->chip_id) { | |
679 | + case 0x4322: | |
680 | + ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL0, 0x11100070); | |
681 | + ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL1, 0x1014140a); | |
682 | + ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL5, 0x88888854); | |
683 | + if (spuravoid == 1) | |
684 | + ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05201828); | |
685 | + else | |
686 | + ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05001828); | |
687 | + pmu_ctl = SSB_CHIPCO_PMU_CTL_PLL_UPD; | |
688 | + break; | |
689 | + case 43222: | |
690 | + /* TODO: BCM43222 requires updating PLLs too */ | |
691 | + return; | |
692 | + default: | |
693 | + ssb_printk(KERN_ERR PFX | |
694 | + "Unknown spuravoidance settings for chip 0x%04X, not changing PLL\n", | |
695 | + cc->dev->bus->chip_id); | |
696 | + return; | |
697 | + } | |
698 | + | |
699 | + chipco_set32(cc, SSB_CHIPCO_PMU_CTL, pmu_ctl); | |
700 | +} | |
701 | +EXPORT_SYMBOL_GPL(ssb_pmu_spuravoid_pllupdate); |
include/linux/ssb/ssb_driver_chipcommon.h
... | ... | @@ -219,6 +219,7 @@ |
219 | 219 | #define SSB_CHIPCO_PMU_CTL 0x0600 /* PMU control */ |
220 | 220 | #define SSB_CHIPCO_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */ |
221 | 221 | #define SSB_CHIPCO_PMU_CTL_ILP_DIV_SHIFT 16 |
222 | +#define SSB_CHIPCO_PMU_CTL_PLL_UPD 0x00000400 | |
222 | 223 | #define SSB_CHIPCO_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */ |
223 | 224 | #define SSB_CHIPCO_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */ |
224 | 225 | #define SSB_CHIPCO_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */ |
... | ... | @@ -667,6 +668,7 @@ |
667 | 668 | void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc, |
668 | 669 | enum ssb_pmu_ldo_volt_id id, u32 voltage); |
669 | 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 | 673 | #endif /* LINUX_SSB_CHIPCO_H_ */ |
net/mac80211/iface.c
... | ... | @@ -78,7 +78,7 @@ |
78 | 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 | 83 | if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) |
84 | 84 | return 0; |
... | ... | @@ -87,7 +87,7 @@ |
87 | 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 | 92 | if (local->hw.conf.flags & IEEE80211_CONF_IDLE) |
93 | 93 | return 0; |
94 | 94 | |
95 | 95 | |
... | ... | @@ -98,16 +98,18 @@ |
98 | 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 | 104 | bool working = false, scanning, active; |
104 | 105 | unsigned int led_trig_start = 0, led_trig_stop = 0; |
105 | 106 | struct ieee80211_roc_work *roc; |
106 | - u32 change; | |
107 | 107 | |
108 | 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 | 114 | if (!local->ops->remain_on_channel) { |
113 | 115 | list_for_each_entry(roc, &local->roc_list, list) { |
... | ... | @@ -132,9 +134,18 @@ |
132 | 134 | ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); |
133 | 135 | |
134 | 136 | if (working || scanning || active) |
135 | - change = ieee80211_idle_off(local); | |
136 | - else | |
137 | - change = ieee80211_idle_on(local); | |
137 | + return __ieee80211_idle_off(local); | |
138 | + return __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 | 149 | if (change) |
139 | 150 | ieee80211_hw_config(local, change); |
140 | 151 | } |
net/mac80211/mlme.c
... | ... | @@ -4022,9 +4022,17 @@ |
4022 | 4022 | /* prep auth_data so we don't go into idle on disassoc */ |
4023 | 4023 | ifmgd->auth_data = auth_data; |
4024 | 4024 | |
4025 | - if (ifmgd->associated) | |
4026 | - ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | |
4025 | + if (ifmgd->associated) { | |
4026 | + u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; | |
4027 | 4027 | |
4028 | + ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, | |
4029 | + WLAN_REASON_UNSPECIFIED, | |
4030 | + false, frame_buf); | |
4031 | + | |
4032 | + __cfg80211_send_deauth(sdata->dev, frame_buf, | |
4033 | + sizeof(frame_buf)); | |
4034 | + } | |
4035 | + | |
4028 | 4036 | sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); |
4029 | 4037 | |
4030 | 4038 | err = ieee80211_prep_connection(sdata, req->bss, false); |
... | ... | @@ -4083,8 +4091,16 @@ |
4083 | 4091 | |
4084 | 4092 | mutex_lock(&ifmgd->mtx); |
4085 | 4093 | |
4086 | - if (ifmgd->associated) | |
4087 | - ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | |
4094 | + if (ifmgd->associated) { | |
4095 | + u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; | |
4096 | + | |
4097 | + ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, | |
4098 | + WLAN_REASON_UNSPECIFIED, | |
4099 | + false, frame_buf); | |
4100 | + | |
4101 | + __cfg80211_send_deauth(sdata->dev, frame_buf, | |
4102 | + sizeof(frame_buf)); | |
4103 | + } | |
4088 | 4104 | |
4089 | 4105 | if (ifmgd->auth_data && !ifmgd->auth_data->done) { |
4090 | 4106 | err = -EBUSY; |