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; |
