diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-11-04 14:45:14 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-11-04 14:45:14 -0500 |
commit | 01925efdf7e03b4b803b5c9f985163d687f7f017 (patch) | |
tree | 6c318f9bf002efac5ccd87e8edad35863d72bd17 | |
parent | a1b13b9ad3759dca24c6b721ee026c540a4e6564 (diff) | |
parent | 8ce9beac4661f576ea0d518b9f086bb52a171a37 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
Conflicts:
drivers/net/wireless/iwlwifi/pcie/drv.c
54 files changed, 415 insertions, 209 deletions
diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c index c9fd6943ce45..50329d1057ed 100644 --- a/drivers/bcma/driver_pci.c +++ b/drivers/bcma/driver_pci.c | |||
@@ -210,25 +210,6 @@ static void bcma_core_pci_config_fixup(struct bcma_drv_pci *pc) | |||
210 | } | 210 | } |
211 | } | 211 | } |
212 | 212 | ||
213 | static void bcma_core_pci_power_save(struct bcma_drv_pci *pc, bool up) | ||
214 | { | ||
215 | u16 data; | ||
216 | |||
217 | if (pc->core->id.rev >= 15 && pc->core->id.rev <= 20) { | ||
218 | data = up ? 0x74 : 0x7C; | ||
219 | bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1, | ||
220 | BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7F64); | ||
221 | bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1, | ||
222 | BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data); | ||
223 | } else if (pc->core->id.rev >= 21 && pc->core->id.rev <= 22) { | ||
224 | data = up ? 0x75 : 0x7D; | ||
225 | bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1, | ||
226 | BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7E65); | ||
227 | bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1, | ||
228 | BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data); | ||
229 | } | ||
230 | } | ||
231 | |||
232 | /************************************************** | 213 | /************************************************** |
233 | * Init. | 214 | * Init. |
234 | **************************************************/ | 215 | **************************************************/ |
@@ -255,6 +236,32 @@ void bcma_core_pci_init(struct bcma_drv_pci *pc) | |||
255 | bcma_core_pci_clientmode_init(pc); | 236 | bcma_core_pci_clientmode_init(pc); |
256 | } | 237 | } |
257 | 238 | ||
239 | void bcma_core_pci_power_save(struct bcma_bus *bus, bool up) | ||
240 | { | ||
241 | struct bcma_drv_pci *pc; | ||
242 | u16 data; | ||
243 | |||
244 | if (bus->hosttype != BCMA_HOSTTYPE_PCI) | ||
245 | return; | ||
246 | |||
247 | pc = &bus->drv_pci[0]; | ||
248 | |||
249 | if (pc->core->id.rev >= 15 && pc->core->id.rev <= 20) { | ||
250 | data = up ? 0x74 : 0x7C; | ||
251 | bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1, | ||
252 | BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7F64); | ||
253 | bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1, | ||
254 | BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data); | ||
255 | } else if (pc->core->id.rev >= 21 && pc->core->id.rev <= 22) { | ||
256 | data = up ? 0x75 : 0x7D; | ||
257 | bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1, | ||
258 | BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7E65); | ||
259 | bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1, | ||
260 | BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data); | ||
261 | } | ||
262 | } | ||
263 | EXPORT_SYMBOL_GPL(bcma_core_pci_power_save); | ||
264 | |||
258 | int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, | 265 | int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, |
259 | bool enable) | 266 | bool enable) |
260 | { | 267 | { |
@@ -310,8 +317,6 @@ void bcma_core_pci_up(struct bcma_bus *bus) | |||
310 | 317 | ||
311 | pc = &bus->drv_pci[0]; | 318 | pc = &bus->drv_pci[0]; |
312 | 319 | ||
313 | bcma_core_pci_power_save(pc, true); | ||
314 | |||
315 | bcma_core_pci_extend_L1timer(pc, true); | 320 | bcma_core_pci_extend_L1timer(pc, true); |
316 | } | 321 | } |
317 | EXPORT_SYMBOL_GPL(bcma_core_pci_up); | 322 | EXPORT_SYMBOL_GPL(bcma_core_pci_up); |
@@ -326,7 +331,5 @@ void bcma_core_pci_down(struct bcma_bus *bus) | |||
326 | pc = &bus->drv_pci[0]; | 331 | pc = &bus->drv_pci[0]; |
327 | 332 | ||
328 | bcma_core_pci_extend_L1timer(pc, false); | 333 | bcma_core_pci_extend_L1timer(pc, false); |
329 | |||
330 | bcma_core_pci_power_save(pc, false); | ||
331 | } | 334 | } |
332 | EXPORT_SYMBOL_GPL(bcma_core_pci_down); | 335 | EXPORT_SYMBOL_GPL(bcma_core_pci_down); |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 48161edec8de..69f58b073e85 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -1663,15 +1663,15 @@ ath5k_tx_frame_completed(struct ath5k_hw *ah, struct sk_buff *skb, | |||
1663 | ah->stats.tx_bytes_count += skb->len; | 1663 | ah->stats.tx_bytes_count += skb->len; |
1664 | info = IEEE80211_SKB_CB(skb); | 1664 | info = IEEE80211_SKB_CB(skb); |
1665 | 1665 | ||
1666 | size = min_t(int, sizeof(info->status.rates), sizeof(bf->rates)); | ||
1667 | memcpy(info->status.rates, bf->rates, size); | ||
1668 | |||
1666 | tries[0] = info->status.rates[0].count; | 1669 | tries[0] = info->status.rates[0].count; |
1667 | tries[1] = info->status.rates[1].count; | 1670 | tries[1] = info->status.rates[1].count; |
1668 | tries[2] = info->status.rates[2].count; | 1671 | tries[2] = info->status.rates[2].count; |
1669 | 1672 | ||
1670 | ieee80211_tx_info_clear_status(info); | 1673 | ieee80211_tx_info_clear_status(info); |
1671 | 1674 | ||
1672 | size = min_t(int, sizeof(info->status.rates), sizeof(bf->rates)); | ||
1673 | memcpy(info->status.rates, bf->rates, size); | ||
1674 | |||
1675 | for (i = 0; i < ts->ts_final_idx; i++) { | 1675 | for (i = 0; i < ts->ts_final_idx; i++) { |
1676 | struct ieee80211_tx_rate *r = | 1676 | struct ieee80211_tx_rate *r = |
1677 | &info->status.rates[i]; | 1677 | &info->status.rates[i]; |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 98964b02f139..74f452c7b166 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -208,6 +208,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) | |||
208 | struct ath_hw *ah = sc->sc_ah; | 208 | struct ath_hw *ah = sc->sc_ah; |
209 | struct ath_common *common = ath9k_hw_common(ah); | 209 | struct ath_common *common = ath9k_hw_common(ah); |
210 | unsigned long flags; | 210 | unsigned long flags; |
211 | int i; | ||
211 | 212 | ||
212 | if (ath_startrecv(sc) != 0) { | 213 | if (ath_startrecv(sc) != 0) { |
213 | ath_err(common, "Unable to restart recv logic\n"); | 214 | ath_err(common, "Unable to restart recv logic\n"); |
@@ -235,6 +236,15 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) | |||
235 | } | 236 | } |
236 | work: | 237 | work: |
237 | ath_restart_work(sc); | 238 | ath_restart_work(sc); |
239 | |||
240 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | ||
241 | if (!ATH_TXQ_SETUP(sc, i)) | ||
242 | continue; | ||
243 | |||
244 | spin_lock_bh(&sc->tx.txq[i].axq_lock); | ||
245 | ath_txq_schedule(sc, &sc->tx.txq[i]); | ||
246 | spin_unlock_bh(&sc->tx.txq[i].axq_lock); | ||
247 | } | ||
238 | } | 248 | } |
239 | 249 | ||
240 | ieee80211_wake_queues(sc->hw); | 250 | ieee80211_wake_queues(sc->hw); |
@@ -619,21 +629,10 @@ chip_reset: | |||
619 | 629 | ||
620 | static int ath_reset(struct ath_softc *sc) | 630 | static int ath_reset(struct ath_softc *sc) |
621 | { | 631 | { |
622 | int i, r; | 632 | int r; |
623 | 633 | ||
624 | ath9k_ps_wakeup(sc); | 634 | ath9k_ps_wakeup(sc); |
625 | |||
626 | r = ath_reset_internal(sc, NULL); | 635 | r = ath_reset_internal(sc, NULL); |
627 | |||
628 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | ||
629 | if (!ATH_TXQ_SETUP(sc, i)) | ||
630 | continue; | ||
631 | |||
632 | spin_lock_bh(&sc->tx.txq[i].axq_lock); | ||
633 | ath_txq_schedule(sc, &sc->tx.txq[i]); | ||
634 | spin_unlock_bh(&sc->tx.txq[i].axq_lock); | ||
635 | } | ||
636 | |||
637 | ath9k_ps_restore(sc); | 636 | ath9k_ps_restore(sc); |
638 | 637 | ||
639 | return r; | 638 | return r; |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index b1e74683b8dc..95ddca5495d4 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -1343,13 +1343,6 @@ static void ath9k_antenna_check(struct ath_softc *sc, | |||
1343 | return; | 1343 | return; |
1344 | 1344 | ||
1345 | /* | 1345 | /* |
1346 | * All MPDUs in an aggregate will use the same LNA | ||
1347 | * as the first MPDU. | ||
1348 | */ | ||
1349 | if (rs->rs_isaggr && !rs->rs_firstaggr) | ||
1350 | return; | ||
1351 | |||
1352 | /* | ||
1353 | * Change the default rx antenna if rx diversity | 1346 | * Change the default rx antenna if rx diversity |
1354 | * chooses the other antenna 3 times in a row. | 1347 | * chooses the other antenna 3 times in a row. |
1355 | */ | 1348 | */ |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index bea5caa11d4a..09cdbcd09739 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -399,6 +399,7 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf) | |||
399 | tbf->bf_buf_addr = bf->bf_buf_addr; | 399 | tbf->bf_buf_addr = bf->bf_buf_addr; |
400 | memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len); | 400 | memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len); |
401 | tbf->bf_state = bf->bf_state; | 401 | tbf->bf_state = bf->bf_state; |
402 | tbf->bf_state.stale = false; | ||
402 | 403 | ||
403 | return tbf; | 404 | return tbf; |
404 | } | 405 | } |
@@ -1390,11 +1391,15 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | |||
1390 | u16 tid, u16 *ssn) | 1391 | u16 tid, u16 *ssn) |
1391 | { | 1392 | { |
1392 | struct ath_atx_tid *txtid; | 1393 | struct ath_atx_tid *txtid; |
1394 | struct ath_txq *txq; | ||
1393 | struct ath_node *an; | 1395 | struct ath_node *an; |
1394 | u8 density; | 1396 | u8 density; |
1395 | 1397 | ||
1396 | an = (struct ath_node *)sta->drv_priv; | 1398 | an = (struct ath_node *)sta->drv_priv; |
1397 | txtid = ATH_AN_2_TID(an, tid); | 1399 | txtid = ATH_AN_2_TID(an, tid); |
1400 | txq = txtid->ac->txq; | ||
1401 | |||
1402 | ath_txq_lock(sc, txq); | ||
1398 | 1403 | ||
1399 | /* update ampdu factor/density, they may have changed. This may happen | 1404 | /* update ampdu factor/density, they may have changed. This may happen |
1400 | * in HT IBSS when a beacon with HT-info is received after the station | 1405 | * in HT IBSS when a beacon with HT-info is received after the station |
@@ -1418,6 +1423,8 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | |||
1418 | memset(txtid->tx_buf, 0, sizeof(txtid->tx_buf)); | 1423 | memset(txtid->tx_buf, 0, sizeof(txtid->tx_buf)); |
1419 | txtid->baw_head = txtid->baw_tail = 0; | 1424 | txtid->baw_head = txtid->baw_tail = 0; |
1420 | 1425 | ||
1426 | ath_txq_unlock_complete(sc, txq); | ||
1427 | |||
1421 | return 0; | 1428 | return 0; |
1422 | } | 1429 | } |
1423 | 1430 | ||
@@ -1556,8 +1563,10 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw, | |||
1556 | __skb_unlink(bf->bf_mpdu, tid_q); | 1563 | __skb_unlink(bf->bf_mpdu, tid_q); |
1557 | list_add_tail(&bf->list, &bf_q); | 1564 | list_add_tail(&bf->list, &bf_q); |
1558 | ath_set_rates(tid->an->vif, tid->an->sta, bf); | 1565 | ath_set_rates(tid->an->vif, tid->an->sta, bf); |
1559 | ath_tx_addto_baw(sc, tid, bf); | 1566 | if (bf_isampdu(bf)) { |
1560 | bf->bf_state.bf_type &= ~BUF_AGGR; | 1567 | ath_tx_addto_baw(sc, tid, bf); |
1568 | bf->bf_state.bf_type &= ~BUF_AGGR; | ||
1569 | } | ||
1561 | if (bf_tail) | 1570 | if (bf_tail) |
1562 | bf_tail->bf_next = bf; | 1571 | bf_tail->bf_next = bf; |
1563 | 1572 | ||
@@ -1944,7 +1953,9 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | |||
1944 | if (bf_is_ampdu_not_probing(bf)) | 1953 | if (bf_is_ampdu_not_probing(bf)) |
1945 | txq->axq_ampdu_depth++; | 1954 | txq->axq_ampdu_depth++; |
1946 | 1955 | ||
1947 | bf = bf->bf_lastbf->bf_next; | 1956 | bf_last = bf->bf_lastbf; |
1957 | bf = bf_last->bf_next; | ||
1958 | bf_last->bf_next = NULL; | ||
1948 | } | 1959 | } |
1949 | } | 1960 | } |
1950 | } | 1961 | } |
@@ -1952,15 +1963,18 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | |||
1952 | static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, | 1963 | static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, |
1953 | struct ath_atx_tid *tid, struct sk_buff *skb) | 1964 | struct ath_atx_tid *tid, struct sk_buff *skb) |
1954 | { | 1965 | { |
1966 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1955 | struct ath_frame_info *fi = get_frame_info(skb); | 1967 | struct ath_frame_info *fi = get_frame_info(skb); |
1956 | struct list_head bf_head; | 1968 | struct list_head bf_head; |
1957 | struct ath_buf *bf; | 1969 | struct ath_buf *bf = fi->bf; |
1958 | |||
1959 | bf = fi->bf; | ||
1960 | 1970 | ||
1961 | INIT_LIST_HEAD(&bf_head); | 1971 | INIT_LIST_HEAD(&bf_head); |
1962 | list_add_tail(&bf->list, &bf_head); | 1972 | list_add_tail(&bf->list, &bf_head); |
1963 | bf->bf_state.bf_type = 0; | 1973 | bf->bf_state.bf_type = 0; |
1974 | if (tid && (tx_info->flags & IEEE80211_TX_CTL_AMPDU)) { | ||
1975 | bf->bf_state.bf_type = BUF_AMPDU; | ||
1976 | ath_tx_addto_baw(sc, tid, bf); | ||
1977 | } | ||
1964 | 1978 | ||
1965 | bf->bf_next = NULL; | 1979 | bf->bf_next = NULL; |
1966 | bf->bf_lastbf = bf; | 1980 | bf->bf_lastbf = bf; |
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 7c970d3ae358..05ee7f10cc8f 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c | |||
@@ -164,7 +164,8 @@ static void b43_nphy_rf_ctl_override_rev7(struct b43_wldev *dev, u16 field, | |||
164 | } | 164 | } |
165 | en_addr = en_addrs[override][i]; | 165 | en_addr = en_addrs[override][i]; |
166 | 166 | ||
167 | val_addr = (i == 0) ? e->val_addr_core0 : e->val_addr_core1; | 167 | if (e) |
168 | val_addr = (i == 0) ? e->val_addr_core0 : e->val_addr_core1; | ||
168 | 169 | ||
169 | if (off) { | 170 | if (off) { |
170 | b43_phy_mask(dev, en_addr, ~en_mask); | 171 | b43_phy_mask(dev, en_addr, ~en_mask); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index c768ec2d473d..905704e335d7 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | |||
@@ -476,8 +476,6 @@ static struct sdio_driver brcmf_sdmmc_driver = { | |||
476 | 476 | ||
477 | static int brcmf_sdio_pd_probe(struct platform_device *pdev) | 477 | static int brcmf_sdio_pd_probe(struct platform_device *pdev) |
478 | { | 478 | { |
479 | int ret; | ||
480 | |||
481 | brcmf_dbg(SDIO, "Enter\n"); | 479 | brcmf_dbg(SDIO, "Enter\n"); |
482 | 480 | ||
483 | brcmfmac_sdio_pdata = dev_get_platdata(&pdev->dev); | 481 | brcmfmac_sdio_pdata = dev_get_platdata(&pdev->dev); |
@@ -485,11 +483,7 @@ static int brcmf_sdio_pd_probe(struct platform_device *pdev) | |||
485 | if (brcmfmac_sdio_pdata->power_on) | 483 | if (brcmfmac_sdio_pdata->power_on) |
486 | brcmfmac_sdio_pdata->power_on(); | 484 | brcmfmac_sdio_pdata->power_on(); |
487 | 485 | ||
488 | ret = sdio_register_driver(&brcmf_sdmmc_driver); | 486 | return 0; |
489 | if (ret) | ||
490 | brcmf_err("sdio_register_driver failed: %d\n", ret); | ||
491 | |||
492 | return ret; | ||
493 | } | 487 | } |
494 | 488 | ||
495 | static int brcmf_sdio_pd_remove(struct platform_device *pdev) | 489 | static int brcmf_sdio_pd_remove(struct platform_device *pdev) |
@@ -512,6 +506,15 @@ static struct platform_driver brcmf_sdio_pd = { | |||
512 | } | 506 | } |
513 | }; | 507 | }; |
514 | 508 | ||
509 | void brcmf_sdio_register(void) | ||
510 | { | ||
511 | int ret; | ||
512 | |||
513 | ret = sdio_register_driver(&brcmf_sdmmc_driver); | ||
514 | if (ret) | ||
515 | brcmf_err("sdio_register_driver failed: %d\n", ret); | ||
516 | } | ||
517 | |||
515 | void brcmf_sdio_exit(void) | 518 | void brcmf_sdio_exit(void) |
516 | { | 519 | { |
517 | brcmf_dbg(SDIO, "Enter\n"); | 520 | brcmf_dbg(SDIO, "Enter\n"); |
@@ -522,18 +525,13 @@ void brcmf_sdio_exit(void) | |||
522 | sdio_unregister_driver(&brcmf_sdmmc_driver); | 525 | sdio_unregister_driver(&brcmf_sdmmc_driver); |
523 | } | 526 | } |
524 | 527 | ||
525 | void brcmf_sdio_init(void) | 528 | void __init brcmf_sdio_init(void) |
526 | { | 529 | { |
527 | int ret; | 530 | int ret; |
528 | 531 | ||
529 | brcmf_dbg(SDIO, "Enter\n"); | 532 | brcmf_dbg(SDIO, "Enter\n"); |
530 | 533 | ||
531 | ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe); | 534 | ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe); |
532 | if (ret == -ENODEV) { | 535 | if (ret == -ENODEV) |
533 | brcmf_dbg(SDIO, "No platform data available, registering without.\n"); | 536 | brcmf_dbg(SDIO, "No platform data available.\n"); |
534 | ret = sdio_register_driver(&brcmf_sdmmc_driver); | ||
535 | } | ||
536 | |||
537 | if (ret) | ||
538 | brcmf_err("driver registration failed: %d\n", ret); | ||
539 | } | 537 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index 200ee9b485bf..7640d8a99e61 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | |||
@@ -156,10 +156,11 @@ extern int brcmf_bus_start(struct device *dev); | |||
156 | #ifdef CONFIG_BRCMFMAC_SDIO | 156 | #ifdef CONFIG_BRCMFMAC_SDIO |
157 | extern void brcmf_sdio_exit(void); | 157 | extern void brcmf_sdio_exit(void); |
158 | extern void brcmf_sdio_init(void); | 158 | extern void brcmf_sdio_init(void); |
159 | extern void brcmf_sdio_register(void); | ||
159 | #endif | 160 | #endif |
160 | #ifdef CONFIG_BRCMFMAC_USB | 161 | #ifdef CONFIG_BRCMFMAC_USB |
161 | extern void brcmf_usb_exit(void); | 162 | extern void brcmf_usb_exit(void); |
162 | extern void brcmf_usb_init(void); | 163 | extern void brcmf_usb_register(void); |
163 | #endif | 164 | #endif |
164 | 165 | ||
165 | #endif /* _BRCMF_BUS_H_ */ | 166 | #endif /* _BRCMF_BUS_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 42bf19a2eeee..64e9cff241b9 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | |||
@@ -1225,21 +1225,23 @@ u32 brcmf_get_chip_info(struct brcmf_if *ifp) | |||
1225 | return bus->chip << 4 | bus->chiprev; | 1225 | return bus->chip << 4 | bus->chiprev; |
1226 | } | 1226 | } |
1227 | 1227 | ||
1228 | static void brcmf_driver_init(struct work_struct *work) | 1228 | static void brcmf_driver_register(struct work_struct *work) |
1229 | { | 1229 | { |
1230 | brcmf_debugfs_init(); | ||
1231 | |||
1232 | #ifdef CONFIG_BRCMFMAC_SDIO | 1230 | #ifdef CONFIG_BRCMFMAC_SDIO |
1233 | brcmf_sdio_init(); | 1231 | brcmf_sdio_register(); |
1234 | #endif | 1232 | #endif |
1235 | #ifdef CONFIG_BRCMFMAC_USB | 1233 | #ifdef CONFIG_BRCMFMAC_USB |
1236 | brcmf_usb_init(); | 1234 | brcmf_usb_register(); |
1237 | #endif | 1235 | #endif |
1238 | } | 1236 | } |
1239 | static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init); | 1237 | static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register); |
1240 | 1238 | ||
1241 | static int __init brcmfmac_module_init(void) | 1239 | static int __init brcmfmac_module_init(void) |
1242 | { | 1240 | { |
1241 | brcmf_debugfs_init(); | ||
1242 | #ifdef CONFIG_BRCMFMAC_SDIO | ||
1243 | brcmf_sdio_init(); | ||
1244 | #endif | ||
1243 | if (!schedule_work(&brcmf_driver_work)) | 1245 | if (!schedule_work(&brcmf_driver_work)) |
1244 | return -EBUSY; | 1246 | return -EBUSY; |
1245 | 1247 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index bf6758d95600..422f44c63175 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c | |||
@@ -1536,7 +1536,7 @@ void brcmf_usb_exit(void) | |||
1536 | brcmf_release_fw(&fw_image_list); | 1536 | brcmf_release_fw(&fw_image_list); |
1537 | } | 1537 | } |
1538 | 1538 | ||
1539 | void brcmf_usb_init(void) | 1539 | void brcmf_usb_register(void) |
1540 | { | 1540 | { |
1541 | brcmf_dbg(USB, "Enter\n"); | 1541 | brcmf_dbg(USB, "Enter\n"); |
1542 | INIT_LIST_HEAD(&fw_image_list); | 1542 | INIT_LIST_HEAD(&fw_image_list); |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 3a6544710c8a..edc5d105ff98 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
@@ -457,6 +457,8 @@ static int brcms_ops_start(struct ieee80211_hw *hw) | |||
457 | if (err != 0) | 457 | if (err != 0) |
458 | brcms_err(wl->wlc->hw->d11core, "%s: brcms_up() returned %d\n", | 458 | brcms_err(wl->wlc->hw->d11core, "%s: brcms_up() returned %d\n", |
459 | __func__, err); | 459 | __func__, err); |
460 | |||
461 | bcma_core_pci_power_save(wl->wlc->hw->d11core->bus, true); | ||
460 | return err; | 462 | return err; |
461 | } | 463 | } |
462 | 464 | ||
@@ -479,6 +481,8 @@ static void brcms_ops_stop(struct ieee80211_hw *hw) | |||
479 | return; | 481 | return; |
480 | } | 482 | } |
481 | 483 | ||
484 | bcma_core_pci_power_save(wl->wlc->hw->d11core->bus, false); | ||
485 | |||
482 | /* put driver in down state */ | 486 | /* put driver in down state */ |
483 | spin_lock_bh(&wl->lock); | 487 | spin_lock_bh(&wl->lock); |
484 | brcms_down(wl); | 488 | brcms_down(wl); |
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c index e310752f0e33..40078f5f932e 100644 --- a/drivers/net/wireless/cw1200/cw1200_spi.c +++ b/drivers/net/wireless/cw1200/cw1200_spi.c | |||
@@ -42,7 +42,6 @@ struct hwbus_priv { | |||
42 | spinlock_t lock; /* Serialize all bus operations */ | 42 | spinlock_t lock; /* Serialize all bus operations */ |
43 | wait_queue_head_t wq; | 43 | wait_queue_head_t wq; |
44 | int claimed; | 44 | int claimed; |
45 | int irq_disabled; | ||
46 | }; | 45 | }; |
47 | 46 | ||
48 | #define SDIO_TO_SPI_ADDR(addr) ((addr & 0x1f)>>2) | 47 | #define SDIO_TO_SPI_ADDR(addr) ((addr & 0x1f)>>2) |
@@ -238,9 +237,9 @@ static irqreturn_t cw1200_spi_irq_handler(int irq, void *dev_id) | |||
238 | struct hwbus_priv *self = dev_id; | 237 | struct hwbus_priv *self = dev_id; |
239 | 238 | ||
240 | if (self->core) { | 239 | if (self->core) { |
241 | disable_irq_nosync(self->func->irq); | 240 | cw1200_spi_lock(self); |
242 | self->irq_disabled = 1; | ||
243 | cw1200_irq_handler(self->core); | 241 | cw1200_irq_handler(self->core); |
242 | cw1200_spi_unlock(self); | ||
244 | return IRQ_HANDLED; | 243 | return IRQ_HANDLED; |
245 | } else { | 244 | } else { |
246 | return IRQ_NONE; | 245 | return IRQ_NONE; |
@@ -253,9 +252,10 @@ static int cw1200_spi_irq_subscribe(struct hwbus_priv *self) | |||
253 | 252 | ||
254 | pr_debug("SW IRQ subscribe\n"); | 253 | pr_debug("SW IRQ subscribe\n"); |
255 | 254 | ||
256 | ret = request_any_context_irq(self->func->irq, cw1200_spi_irq_handler, | 255 | ret = request_threaded_irq(self->func->irq, NULL, |
257 | IRQF_TRIGGER_HIGH, | 256 | cw1200_spi_irq_handler, |
258 | "cw1200_wlan_irq", self); | 257 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, |
258 | "cw1200_wlan_irq", self); | ||
259 | if (WARN_ON(ret < 0)) | 259 | if (WARN_ON(ret < 0)) |
260 | goto exit; | 260 | goto exit; |
261 | 261 | ||
@@ -273,22 +273,13 @@ exit: | |||
273 | 273 | ||
274 | static int cw1200_spi_irq_unsubscribe(struct hwbus_priv *self) | 274 | static int cw1200_spi_irq_unsubscribe(struct hwbus_priv *self) |
275 | { | 275 | { |
276 | int ret = 0; | ||
277 | |||
276 | pr_debug("SW IRQ unsubscribe\n"); | 278 | pr_debug("SW IRQ unsubscribe\n"); |
277 | disable_irq_wake(self->func->irq); | 279 | disable_irq_wake(self->func->irq); |
278 | free_irq(self->func->irq, self); | 280 | free_irq(self->func->irq, self); |
279 | 281 | ||
280 | return 0; | 282 | return ret; |
281 | } | ||
282 | |||
283 | static int cw1200_spi_irq_enable(struct hwbus_priv *self, int enable) | ||
284 | { | ||
285 | /* Disables are handled by the interrupt handler */ | ||
286 | if (enable && self->irq_disabled) { | ||
287 | enable_irq(self->func->irq); | ||
288 | self->irq_disabled = 0; | ||
289 | } | ||
290 | |||
291 | return 0; | ||
292 | } | 283 | } |
293 | 284 | ||
294 | static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata) | 285 | static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata) |
@@ -368,7 +359,6 @@ static struct hwbus_ops cw1200_spi_hwbus_ops = { | |||
368 | .unlock = cw1200_spi_unlock, | 359 | .unlock = cw1200_spi_unlock, |
369 | .align_size = cw1200_spi_align_size, | 360 | .align_size = cw1200_spi_align_size, |
370 | .power_mgmt = cw1200_spi_pm, | 361 | .power_mgmt = cw1200_spi_pm, |
371 | .irq_enable = cw1200_spi_irq_enable, | ||
372 | }; | 362 | }; |
373 | 363 | ||
374 | /* Probe Function to be called by SPI stack when device is discovered */ | 364 | /* Probe Function to be called by SPI stack when device is discovered */ |
diff --git a/drivers/net/wireless/cw1200/fwio.c b/drivers/net/wireless/cw1200/fwio.c index 0b2061bbc68b..acdff0f7f952 100644 --- a/drivers/net/wireless/cw1200/fwio.c +++ b/drivers/net/wireless/cw1200/fwio.c | |||
@@ -485,7 +485,7 @@ int cw1200_load_firmware(struct cw1200_common *priv) | |||
485 | 485 | ||
486 | /* Enable interrupt signalling */ | 486 | /* Enable interrupt signalling */ |
487 | priv->hwbus_ops->lock(priv->hwbus_priv); | 487 | priv->hwbus_ops->lock(priv->hwbus_priv); |
488 | ret = __cw1200_irq_enable(priv, 2); | 488 | ret = __cw1200_irq_enable(priv, 1); |
489 | priv->hwbus_ops->unlock(priv->hwbus_priv); | 489 | priv->hwbus_ops->unlock(priv->hwbus_priv); |
490 | if (ret < 0) | 490 | if (ret < 0) |
491 | goto unsubscribe; | 491 | goto unsubscribe; |
diff --git a/drivers/net/wireless/cw1200/hwbus.h b/drivers/net/wireless/cw1200/hwbus.h index 51dfb3a90735..8b2fc831c3de 100644 --- a/drivers/net/wireless/cw1200/hwbus.h +++ b/drivers/net/wireless/cw1200/hwbus.h | |||
@@ -28,7 +28,6 @@ struct hwbus_ops { | |||
28 | void (*unlock)(struct hwbus_priv *self); | 28 | void (*unlock)(struct hwbus_priv *self); |
29 | size_t (*align_size)(struct hwbus_priv *self, size_t size); | 29 | size_t (*align_size)(struct hwbus_priv *self, size_t size); |
30 | int (*power_mgmt)(struct hwbus_priv *self, bool suspend); | 30 | int (*power_mgmt)(struct hwbus_priv *self, bool suspend); |
31 | int (*irq_enable)(struct hwbus_priv *self, int enable); | ||
32 | }; | 31 | }; |
33 | 32 | ||
34 | #endif /* CW1200_HWBUS_H */ | 33 | #endif /* CW1200_HWBUS_H */ |
diff --git a/drivers/net/wireless/cw1200/hwio.c b/drivers/net/wireless/cw1200/hwio.c index 41bd7615ccaa..ff230b7aeedd 100644 --- a/drivers/net/wireless/cw1200/hwio.c +++ b/drivers/net/wireless/cw1200/hwio.c | |||
@@ -273,21 +273,6 @@ int __cw1200_irq_enable(struct cw1200_common *priv, int enable) | |||
273 | u16 val16; | 273 | u16 val16; |
274 | int ret; | 274 | int ret; |
275 | 275 | ||
276 | /* We need to do this hack because the SPI layer can sleep on I/O | ||
277 | and the general path involves I/O to the device in interrupt | ||
278 | context. | ||
279 | |||
280 | However, the initial enable call needs to go to the hardware. | ||
281 | |||
282 | We don't worry about shutdown because we do a full reset which | ||
283 | clears the interrupt enabled bits. | ||
284 | */ | ||
285 | if (priv->hwbus_ops->irq_enable) { | ||
286 | ret = priv->hwbus_ops->irq_enable(priv->hwbus_priv, enable); | ||
287 | if (ret || enable < 2) | ||
288 | return ret; | ||
289 | } | ||
290 | |||
291 | if (HIF_8601_SILICON == priv->hw_type) { | 276 | if (HIF_8601_SILICON == priv->hw_type) { |
292 | ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32); | 277 | ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32); |
293 | if (ret < 0) { | 278 | if (ret < 0) { |
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index da442b81370a..1fef5240e6ad 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
@@ -433,27 +433,19 @@ int iwlagn_tx_skb(struct iwl_priv *priv, | |||
433 | /* Copy MAC header from skb into command buffer */ | 433 | /* Copy MAC header from skb into command buffer */ |
434 | memcpy(tx_cmd->hdr, hdr, hdr_len); | 434 | memcpy(tx_cmd->hdr, hdr, hdr_len); |
435 | 435 | ||
436 | txq_id = info->hw_queue; | ||
437 | |||
436 | if (is_agg) | 438 | if (is_agg) |
437 | txq_id = priv->tid_data[sta_id][tid].agg.txq_id; | 439 | txq_id = priv->tid_data[sta_id][tid].agg.txq_id; |
438 | else if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) { | 440 | else if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) { |
439 | /* | 441 | /* |
440 | * Send this frame after DTIM -- there's a special queue | ||
441 | * reserved for this for contexts that support AP mode. | ||
442 | */ | ||
443 | txq_id = ctx->mcast_queue; | ||
444 | |||
445 | /* | ||
446 | * The microcode will clear the more data | 442 | * The microcode will clear the more data |
447 | * bit in the last frame it transmits. | 443 | * bit in the last frame it transmits. |
448 | */ | 444 | */ |
449 | hdr->frame_control |= | 445 | hdr->frame_control |= |
450 | cpu_to_le16(IEEE80211_FCTL_MOREDATA); | 446 | cpu_to_le16(IEEE80211_FCTL_MOREDATA); |
451 | } else if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) | 447 | } |
452 | txq_id = IWL_AUX_QUEUE; | ||
453 | else | ||
454 | txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)]; | ||
455 | 448 | ||
456 | WARN_ON_ONCE(!is_agg && txq_id != info->hw_queue); | ||
457 | WARN_ON_ONCE(is_agg && | 449 | WARN_ON_ONCE(is_agg && |
458 | priv->queue_to_mac80211[txq_id] != info->hw_queue); | 450 | priv->queue_to_mac80211[txq_id] != info->hw_queue); |
459 | 451 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 30d45e2fc193..8ac305be68f4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -240,6 +240,12 @@ const struct iwl_cfg iwl6035_2agn_cfg = { | |||
240 | .ht_params = &iwl6000_ht_params, | 240 | .ht_params = &iwl6000_ht_params, |
241 | }; | 241 | }; |
242 | 242 | ||
243 | const struct iwl_cfg iwl6035_2agn_sff_cfg = { | ||
244 | .name = "Intel(R) Centrino(R) Ultimate-N 6235 AGN", | ||
245 | IWL_DEVICE_6035, | ||
246 | .ht_params = &iwl6000_ht_params, | ||
247 | }; | ||
248 | |||
243 | const struct iwl_cfg iwl1030_bgn_cfg = { | 249 | const struct iwl_cfg iwl1030_bgn_cfg = { |
244 | .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", | 250 | .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", |
245 | IWL_DEVICE_6030, | 251 | IWL_DEVICE_6030, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index 261e4a12fd8e..18f232e8e812 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h | |||
@@ -280,6 +280,7 @@ extern const struct iwl_cfg iwl2000_2bgn_cfg; | |||
280 | extern const struct iwl_cfg iwl2000_2bgn_d_cfg; | 280 | extern const struct iwl_cfg iwl2000_2bgn_d_cfg; |
281 | extern const struct iwl_cfg iwl2030_2bgn_cfg; | 281 | extern const struct iwl_cfg iwl2030_2bgn_cfg; |
282 | extern const struct iwl_cfg iwl6035_2agn_cfg; | 282 | extern const struct iwl_cfg iwl6035_2agn_cfg; |
283 | extern const struct iwl_cfg iwl6035_2agn_sff_cfg; | ||
283 | extern const struct iwl_cfg iwl105_bgn_cfg; | 284 | extern const struct iwl_cfg iwl105_bgn_cfg; |
284 | extern const struct iwl_cfg iwl105_bgn_d_cfg; | 285 | extern const struct iwl_cfg iwl105_bgn_d_cfg; |
285 | extern const struct iwl_cfg iwl135_bgn_cfg; | 286 | extern const struct iwl_cfg iwl135_bgn_cfg; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index dd57a36ecb10..c6bac7c90b00 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -601,8 +601,10 @@ static inline int iwl_trans_send_cmd(struct iwl_trans *trans, | |||
601 | { | 601 | { |
602 | int ret; | 602 | int ret; |
603 | 603 | ||
604 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, | 604 | if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) { |
605 | "%s bad state = %d", __func__, trans->state); | 605 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); |
606 | return -EIO; | ||
607 | } | ||
606 | 608 | ||
607 | if (!(cmd->flags & CMD_ASYNC)) | 609 | if (!(cmd->flags & CMD_ASYNC)) |
608 | lock_map_acquire_read(&trans->sync_cmd_lockdep_map); | 610 | lock_map_acquire_read(&trans->sync_cmd_lockdep_map); |
@@ -638,8 +640,8 @@ static inline void iwl_trans_free_tx_cmd(struct iwl_trans *trans, | |||
638 | static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, | 640 | static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, |
639 | struct iwl_device_cmd *dev_cmd, int queue) | 641 | struct iwl_device_cmd *dev_cmd, int queue) |
640 | { | 642 | { |
641 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, | 643 | if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) |
642 | "%s bad state = %d", __func__, trans->state); | 644 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); |
643 | 645 | ||
644 | return trans->ops->tx(trans, skb, dev_cmd, queue); | 646 | return trans->ops->tx(trans, skb, dev_cmd, queue); |
645 | } | 647 | } |
@@ -647,16 +649,16 @@ static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
647 | static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue, | 649 | static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue, |
648 | int ssn, struct sk_buff_head *skbs) | 650 | int ssn, struct sk_buff_head *skbs) |
649 | { | 651 | { |
650 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, | 652 | if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) |
651 | "%s bad state = %d", __func__, trans->state); | 653 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); |
652 | 654 | ||
653 | trans->ops->reclaim(trans, queue, ssn, skbs); | 655 | trans->ops->reclaim(trans, queue, ssn, skbs); |
654 | } | 656 | } |
655 | 657 | ||
656 | static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue) | 658 | static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue) |
657 | { | 659 | { |
658 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, | 660 | if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) |
659 | "%s bad state = %d", __func__, trans->state); | 661 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); |
660 | 662 | ||
661 | trans->ops->txq_disable(trans, queue); | 663 | trans->ops->txq_disable(trans, queue); |
662 | } | 664 | } |
@@ -667,8 +669,8 @@ static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue, | |||
667 | { | 669 | { |
668 | might_sleep(); | 670 | might_sleep(); |
669 | 671 | ||
670 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, | 672 | if (unlikely((trans->state != IWL_TRANS_FW_ALIVE))) |
671 | "%s bad state = %d", __func__, trans->state); | 673 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); |
672 | 674 | ||
673 | trans->ops->txq_enable(trans, queue, fifo, sta_id, tid, | 675 | trans->ops->txq_enable(trans, queue, fifo, sta_id, tid, |
674 | frame_limit, ssn); | 676 | frame_limit, ssn); |
@@ -683,8 +685,8 @@ static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, | |||
683 | 685 | ||
684 | static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) | 686 | static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) |
685 | { | 687 | { |
686 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, | 688 | if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) |
687 | "%s bad state = %d", __func__, trans->state); | 689 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); |
688 | 690 | ||
689 | return trans->ops->wait_tx_queue_empty(trans); | 691 | return trans->ops->wait_tx_queue_empty(trans); |
690 | } | 692 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index 80d5f88a9d32..550824aa84ea 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c | |||
@@ -273,7 +273,10 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, | |||
273 | if (!mvmvif->queue_params[ac].uapsd) | 273 | if (!mvmvif->queue_params[ac].uapsd) |
274 | continue; | 274 | continue; |
275 | 275 | ||
276 | cmd->flags |= cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK); | 276 | if (mvm->cur_ucode != IWL_UCODE_WOWLAN) |
277 | cmd->flags |= | ||
278 | cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK); | ||
279 | |||
277 | cmd->uapsd_ac_flags |= BIT(ac); | 280 | cmd->uapsd_ac_flags |= BIT(ac); |
278 | 281 | ||
279 | /* QNDP TID - the highest TID with no admission control */ | 282 | /* QNDP TID - the highest TID with no admission control */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 778dcd9320fe..dff7592e1ff8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
@@ -97,10 +97,10 @@ static inline __le32 iwl_mvm_scan_max_out_time(struct ieee80211_vif *vif) | |||
97 | 97 | ||
98 | static inline __le32 iwl_mvm_scan_suspend_time(struct ieee80211_vif *vif) | 98 | static inline __le32 iwl_mvm_scan_suspend_time(struct ieee80211_vif *vif) |
99 | { | 99 | { |
100 | if (vif->bss_conf.assoc) | 100 | if (!vif->bss_conf.assoc) |
101 | return cpu_to_le32(vif->bss_conf.beacon_int); | ||
102 | else | ||
103 | return 0; | 101 | return 0; |
102 | |||
103 | return cpu_to_le32(ieee80211_tu_to_usec(vif->bss_conf.beacon_int)); | ||
104 | } | 104 | } |
105 | 105 | ||
106 | static inline __le32 | 106 | static inline __le32 |
@@ -423,6 +423,11 @@ static bool iwl_mvm_scan_abort_notif(struct iwl_notif_wait_data *notif_wait, | |||
423 | return false; | 423 | return false; |
424 | } | 424 | } |
425 | 425 | ||
426 | /* | ||
427 | * If scan cannot be aborted, it means that we had a | ||
428 | * SCAN_COMPLETE_NOTIFICATION in the pipe and it called | ||
429 | * ieee80211_scan_completed already. | ||
430 | */ | ||
426 | IWL_DEBUG_SCAN(mvm, "Scan cannot be aborted, exit now: %d\n", | 431 | IWL_DEBUG_SCAN(mvm, "Scan cannot be aborted, exit now: %d\n", |
427 | *resp); | 432 | *resp); |
428 | return true; | 433 | return true; |
@@ -446,14 +451,19 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm) | |||
446 | SCAN_COMPLETE_NOTIFICATION }; | 451 | SCAN_COMPLETE_NOTIFICATION }; |
447 | int ret; | 452 | int ret; |
448 | 453 | ||
454 | if (mvm->scan_status == IWL_MVM_SCAN_NONE) | ||
455 | return; | ||
456 | |||
449 | iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort, | 457 | iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort, |
450 | scan_abort_notif, | 458 | scan_abort_notif, |
451 | ARRAY_SIZE(scan_abort_notif), | 459 | ARRAY_SIZE(scan_abort_notif), |
452 | iwl_mvm_scan_abort_notif, NULL); | 460 | iwl_mvm_scan_abort_notif, NULL); |
453 | 461 | ||
454 | ret = iwl_mvm_send_cmd_pdu(mvm, SCAN_ABORT_CMD, CMD_SYNC, 0, NULL); | 462 | ret = iwl_mvm_send_cmd_pdu(mvm, SCAN_ABORT_CMD, |
463 | CMD_SYNC | CMD_SEND_IN_RFKILL, 0, NULL); | ||
455 | if (ret) { | 464 | if (ret) { |
456 | IWL_ERR(mvm, "Couldn't send SCAN_ABORT_CMD: %d\n", ret); | 465 | IWL_ERR(mvm, "Couldn't send SCAN_ABORT_CMD: %d\n", ret); |
466 | /* mac80211's state will be cleaned in the fw_restart flow */ | ||
457 | goto out_remove_notif; | 467 | goto out_remove_notif; |
458 | } | 468 | } |
459 | 469 | ||
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index ddf15e1cffa2..941c0c88f982 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
@@ -139,13 +139,16 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
139 | 139 | ||
140 | /* 6x00 Series */ | 140 | /* 6x00 Series */ |
141 | {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)}, | 141 | {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)}, |
142 | {IWL_PCI_DEVICE(0x422B, 0x1108, iwl6000_3agn_cfg)}, | ||
142 | {IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)}, | 143 | {IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)}, |
144 | {IWL_PCI_DEVICE(0x422B, 0x1128, iwl6000_3agn_cfg)}, | ||
143 | {IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)}, | 145 | {IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)}, |
144 | {IWL_PCI_DEVICE(0x422C, 0x1306, iwl6000i_2abg_cfg)}, | 146 | {IWL_PCI_DEVICE(0x422C, 0x1306, iwl6000i_2abg_cfg)}, |
145 | {IWL_PCI_DEVICE(0x422C, 0x1307, iwl6000i_2bg_cfg)}, | 147 | {IWL_PCI_DEVICE(0x422C, 0x1307, iwl6000i_2bg_cfg)}, |
146 | {IWL_PCI_DEVICE(0x422C, 0x1321, iwl6000i_2agn_cfg)}, | 148 | {IWL_PCI_DEVICE(0x422C, 0x1321, iwl6000i_2agn_cfg)}, |
147 | {IWL_PCI_DEVICE(0x422C, 0x1326, iwl6000i_2abg_cfg)}, | 149 | {IWL_PCI_DEVICE(0x422C, 0x1326, iwl6000i_2abg_cfg)}, |
148 | {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)}, | 150 | {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)}, |
151 | {IWL_PCI_DEVICE(0x4238, 0x1118, iwl6000_3agn_cfg)}, | ||
149 | {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)}, | 152 | {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)}, |
150 | {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)}, | 153 | {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)}, |
151 | 154 | ||
@@ -153,12 +156,16 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
153 | {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_2agn_cfg)}, | 156 | {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_2agn_cfg)}, |
154 | {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_2abg_cfg)}, | 157 | {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_2abg_cfg)}, |
155 | {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_2bg_cfg)}, | 158 | {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_2bg_cfg)}, |
159 | {IWL_PCI_DEVICE(0x0082, 0x1308, iwl6005_2agn_cfg)}, | ||
156 | {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6005_2agn_cfg)}, | 160 | {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6005_2agn_cfg)}, |
157 | {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6005_2abg_cfg)}, | 161 | {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6005_2abg_cfg)}, |
162 | {IWL_PCI_DEVICE(0x0082, 0x1328, iwl6005_2agn_cfg)}, | ||
158 | {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)}, | 163 | {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)}, |
164 | {IWL_PCI_DEVICE(0x0085, 0x1318, iwl6005_2agn_cfg)}, | ||
159 | {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)}, | 165 | {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)}, |
160 | {IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_2agn_sff_cfg)}, | 166 | {IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_2agn_sff_cfg)}, |
161 | {IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_2agn_sff_cfg)}, | 167 | {IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_2agn_sff_cfg)}, |
168 | {IWL_PCI_DEVICE(0x0085, 0xC228, iwl6005_2agn_sff_cfg)}, | ||
162 | {IWL_PCI_DEVICE(0x0082, 0x4820, iwl6005_2agn_d_cfg)}, | 169 | {IWL_PCI_DEVICE(0x0082, 0x4820, iwl6005_2agn_d_cfg)}, |
163 | {IWL_PCI_DEVICE(0x0082, 0x1304, iwl6005_2agn_mow1_cfg)},/* low 5GHz active */ | 170 | {IWL_PCI_DEVICE(0x0082, 0x1304, iwl6005_2agn_mow1_cfg)},/* low 5GHz active */ |
164 | {IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_2agn_mow2_cfg)},/* high 5GHz active */ | 171 | {IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_2agn_mow2_cfg)},/* high 5GHz active */ |
@@ -240,8 +247,11 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
240 | 247 | ||
241 | /* 6x35 Series */ | 248 | /* 6x35 Series */ |
242 | {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, | 249 | {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, |
250 | {IWL_PCI_DEVICE(0x088E, 0x406A, iwl6035_2agn_sff_cfg)}, | ||
243 | {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, | 251 | {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, |
252 | {IWL_PCI_DEVICE(0x088F, 0x426A, iwl6035_2agn_sff_cfg)}, | ||
244 | {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, | 253 | {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, |
254 | {IWL_PCI_DEVICE(0x088E, 0x446A, iwl6035_2agn_sff_cfg)}, | ||
245 | {IWL_PCI_DEVICE(0x088E, 0x4860, iwl6035_2agn_cfg)}, | 255 | {IWL_PCI_DEVICE(0x088E, 0x4860, iwl6035_2agn_cfg)}, |
246 | {IWL_PCI_DEVICE(0x088F, 0x5260, iwl6035_2agn_cfg)}, | 256 | {IWL_PCI_DEVICE(0x088F, 0x5260, iwl6035_2agn_cfg)}, |
247 | 257 | ||
@@ -260,54 +270,86 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
260 | #if IS_ENABLED(CONFIG_IWLMVM) | 270 | #if IS_ENABLED(CONFIG_IWLMVM) |
261 | /* 7260 Series */ | 271 | /* 7260 Series */ |
262 | {IWL_PCI_DEVICE(0x08B1, 0x4070, iwl7260_2ac_cfg)}, | 272 | {IWL_PCI_DEVICE(0x08B1, 0x4070, iwl7260_2ac_cfg)}, |
273 | {IWL_PCI_DEVICE(0x08B1, 0x4072, iwl7260_2ac_cfg)}, | ||
263 | {IWL_PCI_DEVICE(0x08B1, 0x4170, iwl7260_2ac_cfg)}, | 274 | {IWL_PCI_DEVICE(0x08B1, 0x4170, iwl7260_2ac_cfg)}, |
264 | {IWL_PCI_DEVICE(0x08B1, 0x4060, iwl7260_2n_cfg)}, | 275 | {IWL_PCI_DEVICE(0x08B1, 0x4060, iwl7260_2n_cfg)}, |
276 | {IWL_PCI_DEVICE(0x08B1, 0x406A, iwl7260_2n_cfg)}, | ||
265 | {IWL_PCI_DEVICE(0x08B1, 0x4160, iwl7260_2n_cfg)}, | 277 | {IWL_PCI_DEVICE(0x08B1, 0x4160, iwl7260_2n_cfg)}, |
266 | {IWL_PCI_DEVICE(0x08B1, 0x4062, iwl7260_n_cfg)}, | 278 | {IWL_PCI_DEVICE(0x08B1, 0x4062, iwl7260_n_cfg)}, |
267 | {IWL_PCI_DEVICE(0x08B1, 0x4162, iwl7260_n_cfg)}, | 279 | {IWL_PCI_DEVICE(0x08B1, 0x4162, iwl7260_n_cfg)}, |
268 | {IWL_PCI_DEVICE(0x08B2, 0x4270, iwl7260_2ac_cfg)}, | 280 | {IWL_PCI_DEVICE(0x08B2, 0x4270, iwl7260_2ac_cfg)}, |
281 | {IWL_PCI_DEVICE(0x08B2, 0x4272, iwl7260_2ac_cfg)}, | ||
269 | {IWL_PCI_DEVICE(0x08B2, 0x4260, iwl7260_2n_cfg)}, | 282 | {IWL_PCI_DEVICE(0x08B2, 0x4260, iwl7260_2n_cfg)}, |
283 | {IWL_PCI_DEVICE(0x08B2, 0x426A, iwl7260_2n_cfg)}, | ||
270 | {IWL_PCI_DEVICE(0x08B2, 0x4262, iwl7260_n_cfg)}, | 284 | {IWL_PCI_DEVICE(0x08B2, 0x4262, iwl7260_n_cfg)}, |
271 | {IWL_PCI_DEVICE(0x08B1, 0x4470, iwl7260_2ac_cfg)}, | 285 | {IWL_PCI_DEVICE(0x08B1, 0x4470, iwl7260_2ac_cfg)}, |
286 | {IWL_PCI_DEVICE(0x08B1, 0x4472, iwl7260_2ac_cfg)}, | ||
272 | {IWL_PCI_DEVICE(0x08B1, 0x4460, iwl7260_2n_cfg)}, | 287 | {IWL_PCI_DEVICE(0x08B1, 0x4460, iwl7260_2n_cfg)}, |
288 | {IWL_PCI_DEVICE(0x08B1, 0x446A, iwl7260_2n_cfg)}, | ||
273 | {IWL_PCI_DEVICE(0x08B1, 0x4462, iwl7260_n_cfg)}, | 289 | {IWL_PCI_DEVICE(0x08B1, 0x4462, iwl7260_n_cfg)}, |
274 | {IWL_PCI_DEVICE(0x08B1, 0x4870, iwl7260_2ac_cfg)}, | 290 | {IWL_PCI_DEVICE(0x08B1, 0x4870, iwl7260_2ac_cfg)}, |
275 | {IWL_PCI_DEVICE(0x08B1, 0x486E, iwl7260_2ac_cfg)}, | 291 | {IWL_PCI_DEVICE(0x08B1, 0x486E, iwl7260_2ac_cfg)}, |
276 | {IWL_PCI_DEVICE(0x08B1, 0x4A70, iwl7260_2ac_cfg_high_temp)}, | 292 | {IWL_PCI_DEVICE(0x08B1, 0x4A70, iwl7260_2ac_cfg_high_temp)}, |
277 | {IWL_PCI_DEVICE(0x08B1, 0x4A6E, iwl7260_2ac_cfg_high_temp)}, | 293 | {IWL_PCI_DEVICE(0x08B1, 0x4A6E, iwl7260_2ac_cfg_high_temp)}, |
278 | {IWL_PCI_DEVICE(0x08B1, 0x4A6C, iwl7260_2ac_cfg_high_temp)}, | 294 | {IWL_PCI_DEVICE(0x08B1, 0x4A6C, iwl7260_2ac_cfg_high_temp)}, |
295 | {IWL_PCI_DEVICE(0x08B1, 0x4570, iwl7260_2ac_cfg)}, | ||
296 | {IWL_PCI_DEVICE(0x08B1, 0x4560, iwl7260_2n_cfg)}, | ||
297 | {IWL_PCI_DEVICE(0x08B2, 0x4370, iwl7260_2ac_cfg)}, | ||
298 | {IWL_PCI_DEVICE(0x08B2, 0x4360, iwl7260_2n_cfg)}, | ||
299 | {IWL_PCI_DEVICE(0x08B1, 0x5070, iwl7260_2ac_cfg)}, | ||
279 | {IWL_PCI_DEVICE(0x08B1, 0x4020, iwl7260_2n_cfg)}, | 300 | {IWL_PCI_DEVICE(0x08B1, 0x4020, iwl7260_2n_cfg)}, |
301 | {IWL_PCI_DEVICE(0x08B1, 0x402A, iwl7260_2n_cfg)}, | ||
280 | {IWL_PCI_DEVICE(0x08B2, 0x4220, iwl7260_2n_cfg)}, | 302 | {IWL_PCI_DEVICE(0x08B2, 0x4220, iwl7260_2n_cfg)}, |
281 | {IWL_PCI_DEVICE(0x08B1, 0x4420, iwl7260_2n_cfg)}, | 303 | {IWL_PCI_DEVICE(0x08B1, 0x4420, iwl7260_2n_cfg)}, |
282 | {IWL_PCI_DEVICE(0x08B1, 0xC070, iwl7260_2ac_cfg)}, | 304 | {IWL_PCI_DEVICE(0x08B1, 0xC070, iwl7260_2ac_cfg)}, |
305 | {IWL_PCI_DEVICE(0x08B1, 0xC072, iwl7260_2ac_cfg)}, | ||
283 | {IWL_PCI_DEVICE(0x08B1, 0xC170, iwl7260_2ac_cfg)}, | 306 | {IWL_PCI_DEVICE(0x08B1, 0xC170, iwl7260_2ac_cfg)}, |
284 | {IWL_PCI_DEVICE(0x08B1, 0xC060, iwl7260_2n_cfg)}, | 307 | {IWL_PCI_DEVICE(0x08B1, 0xC060, iwl7260_2n_cfg)}, |
308 | {IWL_PCI_DEVICE(0x08B1, 0xC06A, iwl7260_2n_cfg)}, | ||
285 | {IWL_PCI_DEVICE(0x08B1, 0xC160, iwl7260_2n_cfg)}, | 309 | {IWL_PCI_DEVICE(0x08B1, 0xC160, iwl7260_2n_cfg)}, |
286 | {IWL_PCI_DEVICE(0x08B1, 0xC062, iwl7260_n_cfg)}, | 310 | {IWL_PCI_DEVICE(0x08B1, 0xC062, iwl7260_n_cfg)}, |
287 | {IWL_PCI_DEVICE(0x08B1, 0xC162, iwl7260_n_cfg)}, | 311 | {IWL_PCI_DEVICE(0x08B1, 0xC162, iwl7260_n_cfg)}, |
312 | {IWL_PCI_DEVICE(0x08B1, 0xC770, iwl7260_2ac_cfg)}, | ||
313 | {IWL_PCI_DEVICE(0x08B1, 0xC760, iwl7260_2n_cfg)}, | ||
288 | {IWL_PCI_DEVICE(0x08B2, 0xC270, iwl7260_2ac_cfg)}, | 314 | {IWL_PCI_DEVICE(0x08B2, 0xC270, iwl7260_2ac_cfg)}, |
315 | {IWL_PCI_DEVICE(0x08B2, 0xC272, iwl7260_2ac_cfg)}, | ||
289 | {IWL_PCI_DEVICE(0x08B2, 0xC260, iwl7260_2n_cfg)}, | 316 | {IWL_PCI_DEVICE(0x08B2, 0xC260, iwl7260_2n_cfg)}, |
317 | {IWL_PCI_DEVICE(0x08B2, 0xC26A, iwl7260_n_cfg)}, | ||
290 | {IWL_PCI_DEVICE(0x08B2, 0xC262, iwl7260_n_cfg)}, | 318 | {IWL_PCI_DEVICE(0x08B2, 0xC262, iwl7260_n_cfg)}, |
291 | {IWL_PCI_DEVICE(0x08B1, 0xC470, iwl7260_2ac_cfg)}, | 319 | {IWL_PCI_DEVICE(0x08B1, 0xC470, iwl7260_2ac_cfg)}, |
320 | {IWL_PCI_DEVICE(0x08B1, 0xC472, iwl7260_2ac_cfg)}, | ||
292 | {IWL_PCI_DEVICE(0x08B1, 0xC460, iwl7260_2n_cfg)}, | 321 | {IWL_PCI_DEVICE(0x08B1, 0xC460, iwl7260_2n_cfg)}, |
293 | {IWL_PCI_DEVICE(0x08B1, 0xC462, iwl7260_n_cfg)}, | 322 | {IWL_PCI_DEVICE(0x08B1, 0xC462, iwl7260_n_cfg)}, |
323 | {IWL_PCI_DEVICE(0x08B1, 0xC570, iwl7260_2ac_cfg)}, | ||
324 | {IWL_PCI_DEVICE(0x08B1, 0xC560, iwl7260_2n_cfg)}, | ||
325 | {IWL_PCI_DEVICE(0x08B2, 0xC370, iwl7260_2ac_cfg)}, | ||
326 | {IWL_PCI_DEVICE(0x08B1, 0xC360, iwl7260_2n_cfg)}, | ||
294 | {IWL_PCI_DEVICE(0x08B1, 0xC020, iwl7260_2n_cfg)}, | 327 | {IWL_PCI_DEVICE(0x08B1, 0xC020, iwl7260_2n_cfg)}, |
328 | {IWL_PCI_DEVICE(0x08B1, 0xC02A, iwl7260_2n_cfg)}, | ||
295 | {IWL_PCI_DEVICE(0x08B2, 0xC220, iwl7260_2n_cfg)}, | 329 | {IWL_PCI_DEVICE(0x08B2, 0xC220, iwl7260_2n_cfg)}, |
296 | {IWL_PCI_DEVICE(0x08B1, 0xC420, iwl7260_2n_cfg)}, | 330 | {IWL_PCI_DEVICE(0x08B1, 0xC420, iwl7260_2n_cfg)}, |
297 | 331 | ||
298 | /* 3160 Series */ | 332 | /* 3160 Series */ |
299 | {IWL_PCI_DEVICE(0x08B3, 0x0070, iwl3160_2ac_cfg)}, | 333 | {IWL_PCI_DEVICE(0x08B3, 0x0070, iwl3160_2ac_cfg)}, |
334 | {IWL_PCI_DEVICE(0x08B3, 0x0072, iwl3160_2ac_cfg)}, | ||
300 | {IWL_PCI_DEVICE(0x08B3, 0x0170, iwl3160_2ac_cfg)}, | 335 | {IWL_PCI_DEVICE(0x08B3, 0x0170, iwl3160_2ac_cfg)}, |
336 | {IWL_PCI_DEVICE(0x08B3, 0x0172, iwl3160_2ac_cfg)}, | ||
301 | {IWL_PCI_DEVICE(0x08B3, 0x0060, iwl3160_2n_cfg)}, | 337 | {IWL_PCI_DEVICE(0x08B3, 0x0060, iwl3160_2n_cfg)}, |
302 | {IWL_PCI_DEVICE(0x08B3, 0x0062, iwl3160_n_cfg)}, | 338 | {IWL_PCI_DEVICE(0x08B3, 0x0062, iwl3160_n_cfg)}, |
303 | {IWL_PCI_DEVICE(0x08B4, 0x0270, iwl3160_2ac_cfg)}, | 339 | {IWL_PCI_DEVICE(0x08B4, 0x0270, iwl3160_2ac_cfg)}, |
340 | {IWL_PCI_DEVICE(0x08B4, 0x0272, iwl3160_2ac_cfg)}, | ||
304 | {IWL_PCI_DEVICE(0x08B3, 0x0470, iwl3160_2ac_cfg)}, | 341 | {IWL_PCI_DEVICE(0x08B3, 0x0470, iwl3160_2ac_cfg)}, |
342 | {IWL_PCI_DEVICE(0x08B3, 0x0472, iwl3160_2ac_cfg)}, | ||
343 | {IWL_PCI_DEVICE(0x08B4, 0x0370, iwl3160_2ac_cfg)}, | ||
305 | {IWL_PCI_DEVICE(0x08B3, 0x8070, iwl3160_2ac_cfg)}, | 344 | {IWL_PCI_DEVICE(0x08B3, 0x8070, iwl3160_2ac_cfg)}, |
345 | {IWL_PCI_DEVICE(0x08B3, 0x8072, iwl3160_2ac_cfg)}, | ||
306 | {IWL_PCI_DEVICE(0x08B3, 0x8170, iwl3160_2ac_cfg)}, | 346 | {IWL_PCI_DEVICE(0x08B3, 0x8170, iwl3160_2ac_cfg)}, |
347 | {IWL_PCI_DEVICE(0x08B3, 0x8172, iwl3160_2ac_cfg)}, | ||
307 | {IWL_PCI_DEVICE(0x08B3, 0x8060, iwl3160_2n_cfg)}, | 348 | {IWL_PCI_DEVICE(0x08B3, 0x8060, iwl3160_2n_cfg)}, |
308 | {IWL_PCI_DEVICE(0x08B3, 0x8062, iwl3160_n_cfg)}, | 349 | {IWL_PCI_DEVICE(0x08B3, 0x8062, iwl3160_n_cfg)}, |
309 | {IWL_PCI_DEVICE(0x08B4, 0x8270, iwl3160_2ac_cfg)}, | 350 | {IWL_PCI_DEVICE(0x08B4, 0x8270, iwl3160_2ac_cfg)}, |
310 | {IWL_PCI_DEVICE(0x08B3, 0x8470, iwl3160_2ac_cfg)}, | 351 | {IWL_PCI_DEVICE(0x08B3, 0x8470, iwl3160_2ac_cfg)}, |
352 | {IWL_PCI_DEVICE(0x08B3, 0x8570, iwl3160_2ac_cfg)}, | ||
311 | 353 | ||
312 | /* 7265 Series */ | 354 | /* 7265 Series */ |
313 | {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, | 355 | {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, |
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index b4168415538c..f644fcf861a8 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
@@ -1102,6 +1102,8 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | |||
1102 | * non-AGG queue. | 1102 | * non-AGG queue. |
1103 | */ | 1103 | */ |
1104 | iwl_clear_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); | 1104 | iwl_clear_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); |
1105 | |||
1106 | ssn = trans_pcie->txq[txq_id].q.read_ptr; | ||
1105 | } | 1107 | } |
1106 | 1108 | ||
1107 | /* Place first TFD at index corresponding to start sequence number. | 1109 | /* Place first TFD at index corresponding to start sequence number. |
@@ -1463,7 +1465,8 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, | |||
1463 | spin_unlock_bh(&txq->lock); | 1465 | spin_unlock_bh(&txq->lock); |
1464 | } | 1466 | } |
1465 | 1467 | ||
1466 | #define HOST_COMPLETE_TIMEOUT (2 * HZ) | 1468 | #define HOST_COMPLETE_TIMEOUT (2 * HZ) |
1469 | #define COMMAND_POKE_TIMEOUT (HZ / 10) | ||
1467 | 1470 | ||
1468 | static int iwl_pcie_send_hcmd_async(struct iwl_trans *trans, | 1471 | static int iwl_pcie_send_hcmd_async(struct iwl_trans *trans, |
1469 | struct iwl_host_cmd *cmd) | 1472 | struct iwl_host_cmd *cmd) |
@@ -1491,6 +1494,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, | |||
1491 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1494 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1492 | int cmd_idx; | 1495 | int cmd_idx; |
1493 | int ret; | 1496 | int ret; |
1497 | int timeout = HOST_COMPLETE_TIMEOUT; | ||
1494 | 1498 | ||
1495 | IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", | 1499 | IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", |
1496 | get_cmd_string(trans_pcie, cmd->id)); | 1500 | get_cmd_string(trans_pcie, cmd->id)); |
@@ -1515,10 +1519,29 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, | |||
1515 | return ret; | 1519 | return ret; |
1516 | } | 1520 | } |
1517 | 1521 | ||
1518 | ret = wait_event_timeout(trans_pcie->wait_command_queue, | 1522 | while (timeout > 0) { |
1519 | !test_bit(STATUS_HCMD_ACTIVE, | 1523 | unsigned long flags; |
1520 | &trans_pcie->status), | 1524 | |
1521 | HOST_COMPLETE_TIMEOUT); | 1525 | timeout -= COMMAND_POKE_TIMEOUT; |
1526 | ret = wait_event_timeout(trans_pcie->wait_command_queue, | ||
1527 | !test_bit(STATUS_HCMD_ACTIVE, | ||
1528 | &trans_pcie->status), | ||
1529 | COMMAND_POKE_TIMEOUT); | ||
1530 | if (ret) | ||
1531 | break; | ||
1532 | /* poke the device - it may have lost the command */ | ||
1533 | if (iwl_trans_grab_nic_access(trans, true, &flags)) { | ||
1534 | iwl_trans_release_nic_access(trans, &flags); | ||
1535 | IWL_DEBUG_INFO(trans, | ||
1536 | "Tried to wake NIC for command %s\n", | ||
1537 | get_cmd_string(trans_pcie, cmd->id)); | ||
1538 | } else { | ||
1539 | IWL_ERR(trans, "Failed to poke NIC for command %s\n", | ||
1540 | get_cmd_string(trans_pcie, cmd->id)); | ||
1541 | break; | ||
1542 | } | ||
1543 | } | ||
1544 | |||
1522 | if (!ret) { | 1545 | if (!ret) { |
1523 | if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { | 1546 | if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { |
1524 | struct iwl_txq *txq = | 1547 | struct iwl_txq *txq = |
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index 21c688264708..1214c587fd08 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c | |||
@@ -150,7 +150,7 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv, | |||
150 | */ | 150 | */ |
151 | int | 151 | int |
152 | mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, | 152 | mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, |
153 | struct mwifiex_ra_list_tbl *pra_list, int headroom, | 153 | struct mwifiex_ra_list_tbl *pra_list, |
154 | int ptrindex, unsigned long ra_list_flags) | 154 | int ptrindex, unsigned long ra_list_flags) |
155 | __releases(&priv->wmm.ra_list_spinlock) | 155 | __releases(&priv->wmm.ra_list_spinlock) |
156 | { | 156 | { |
@@ -160,6 +160,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, | |||
160 | int pad = 0, ret; | 160 | int pad = 0, ret; |
161 | struct mwifiex_tx_param tx_param; | 161 | struct mwifiex_tx_param tx_param; |
162 | struct txpd *ptx_pd = NULL; | 162 | struct txpd *ptx_pd = NULL; |
163 | int headroom = adapter->iface_type == MWIFIEX_USB ? 0 : INTF_HEADER_LEN; | ||
163 | 164 | ||
164 | skb_src = skb_peek(&pra_list->skb_head); | 165 | skb_src = skb_peek(&pra_list->skb_head); |
165 | if (!skb_src) { | 166 | if (!skb_src) { |
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.h b/drivers/net/wireless/mwifiex/11n_aggr.h index 900e1c62a0cc..892098d6a696 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.h +++ b/drivers/net/wireless/mwifiex/11n_aggr.h | |||
@@ -26,7 +26,7 @@ | |||
26 | int mwifiex_11n_deaggregate_pkt(struct mwifiex_private *priv, | 26 | int mwifiex_11n_deaggregate_pkt(struct mwifiex_private *priv, |
27 | struct sk_buff *skb); | 27 | struct sk_buff *skb); |
28 | int mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, | 28 | int mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, |
29 | struct mwifiex_ra_list_tbl *ptr, int headroom, | 29 | struct mwifiex_ra_list_tbl *ptr, |
30 | int ptr_index, unsigned long flags) | 30 | int ptr_index, unsigned long flags) |
31 | __releases(&priv->wmm.ra_list_spinlock); | 31 | __releases(&priv->wmm.ra_list_spinlock); |
32 | 32 | ||
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index fb3fa18390b8..e47f4e3012b8 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c | |||
@@ -1155,7 +1155,7 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, | |||
1155 | uint32_t conditions = le32_to_cpu(phs_cfg->params.hs_config.conditions); | 1155 | uint32_t conditions = le32_to_cpu(phs_cfg->params.hs_config.conditions); |
1156 | 1156 | ||
1157 | if (phs_cfg->action == cpu_to_le16(HS_ACTIVATE) && | 1157 | if (phs_cfg->action == cpu_to_le16(HS_ACTIVATE) && |
1158 | adapter->iface_type == MWIFIEX_SDIO) { | 1158 | adapter->iface_type != MWIFIEX_USB) { |
1159 | mwifiex_hs_activated_event(priv, true); | 1159 | mwifiex_hs_activated_event(priv, true); |
1160 | return 0; | 1160 | return 0; |
1161 | } else { | 1161 | } else { |
@@ -1167,8 +1167,7 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, | |||
1167 | } | 1167 | } |
1168 | if (conditions != HS_CFG_CANCEL) { | 1168 | if (conditions != HS_CFG_CANCEL) { |
1169 | adapter->is_hs_configured = true; | 1169 | adapter->is_hs_configured = true; |
1170 | if (adapter->iface_type == MWIFIEX_USB || | 1170 | if (adapter->iface_type == MWIFIEX_USB) |
1171 | adapter->iface_type == MWIFIEX_PCIE) | ||
1172 | mwifiex_hs_activated_event(priv, true); | 1171 | mwifiex_hs_activated_event(priv, true); |
1173 | } else { | 1172 | } else { |
1174 | adapter->is_hs_configured = false; | 1173 | adapter->is_hs_configured = false; |
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 717fbe2e0e5a..4e4686e6ac09 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c | |||
@@ -1422,13 +1422,19 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac) | |||
1422 | */ | 1422 | */ |
1423 | int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac) | 1423 | int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac) |
1424 | { | 1424 | { |
1425 | int ret = 0; | ||
1426 | |||
1425 | if (!priv->media_connected) | 1427 | if (!priv->media_connected) |
1426 | return 0; | 1428 | return 0; |
1427 | 1429 | ||
1428 | switch (priv->bss_mode) { | 1430 | switch (priv->bss_mode) { |
1429 | case NL80211_IFTYPE_STATION: | 1431 | case NL80211_IFTYPE_STATION: |
1430 | case NL80211_IFTYPE_P2P_CLIENT: | 1432 | case NL80211_IFTYPE_P2P_CLIENT: |
1431 | return mwifiex_deauthenticate_infra(priv, mac); | 1433 | ret = mwifiex_deauthenticate_infra(priv, mac); |
1434 | if (ret) | ||
1435 | cfg80211_disconnected(priv->netdev, 0, NULL, 0, | ||
1436 | GFP_KERNEL); | ||
1437 | break; | ||
1432 | case NL80211_IFTYPE_ADHOC: | 1438 | case NL80211_IFTYPE_ADHOC: |
1433 | return mwifiex_send_cmd_sync(priv, | 1439 | return mwifiex_send_cmd_sync(priv, |
1434 | HostCmd_CMD_802_11_AD_HOC_STOP, | 1440 | HostCmd_CMD_802_11_AD_HOC_STOP, |
@@ -1440,7 +1446,7 @@ int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac) | |||
1440 | break; | 1446 | break; |
1441 | } | 1447 | } |
1442 | 1448 | ||
1443 | return 0; | 1449 | return ret; |
1444 | } | 1450 | } |
1445 | EXPORT_SYMBOL_GPL(mwifiex_deauthenticate); | 1451 | EXPORT_SYMBOL_GPL(mwifiex_deauthenticate); |
1446 | 1452 | ||
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 408f307694aa..9d7c9d354d34 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
@@ -358,10 +358,12 @@ process_start: | |||
358 | } | 358 | } |
359 | } while (true); | 359 | } while (true); |
360 | 360 | ||
361 | if ((adapter->int_status) || IS_CARD_RX_RCVD(adapter)) | 361 | spin_lock_irqsave(&adapter->main_proc_lock, flags); |
362 | if ((adapter->int_status) || IS_CARD_RX_RCVD(adapter)) { | ||
363 | spin_unlock_irqrestore(&adapter->main_proc_lock, flags); | ||
362 | goto process_start; | 364 | goto process_start; |
365 | } | ||
363 | 366 | ||
364 | spin_lock_irqsave(&adapter->main_proc_lock, flags); | ||
365 | adapter->mwifiex_processing = false; | 367 | adapter->mwifiex_processing = false; |
366 | spin_unlock_irqrestore(&adapter->main_proc_lock, flags); | 368 | spin_unlock_irqrestore(&adapter->main_proc_lock, flags); |
367 | 369 | ||
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index 8b057524b252..8c351f71f72f 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c | |||
@@ -118,7 +118,8 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code) | |||
118 | dev_dbg(adapter->dev, | 118 | dev_dbg(adapter->dev, |
119 | "info: successfully disconnected from %pM: reason code %d\n", | 119 | "info: successfully disconnected from %pM: reason code %d\n", |
120 | priv->cfg_bssid, reason_code); | 120 | priv->cfg_bssid, reason_code); |
121 | if (priv->bss_mode == NL80211_IFTYPE_STATION) { | 121 | if (priv->bss_mode == NL80211_IFTYPE_STATION || |
122 | priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) { | ||
122 | cfg80211_disconnected(priv->netdev, reason_code, NULL, 0, | 123 | cfg80211_disconnected(priv->netdev, reason_code, NULL, 0, |
123 | GFP_KERNEL); | 124 | GFP_KERNEL); |
124 | } | 125 | } |
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c index 2472d4b7f00e..1c70b8d09227 100644 --- a/drivers/net/wireless/mwifiex/usb.c +++ b/drivers/net/wireless/mwifiex/usb.c | |||
@@ -447,9 +447,6 @@ static int mwifiex_usb_suspend(struct usb_interface *intf, pm_message_t message) | |||
447 | */ | 447 | */ |
448 | adapter->is_suspended = true; | 448 | adapter->is_suspended = true; |
449 | 449 | ||
450 | for (i = 0; i < adapter->priv_num; i++) | ||
451 | netif_carrier_off(adapter->priv[i]->netdev); | ||
452 | |||
453 | if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb) | 450 | if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb) |
454 | usb_kill_urb(card->rx_cmd.urb); | 451 | usb_kill_urb(card->rx_cmd.urb); |
455 | 452 | ||
@@ -509,10 +506,6 @@ static int mwifiex_usb_resume(struct usb_interface *intf) | |||
509 | MWIFIEX_RX_CMD_BUF_SIZE); | 506 | MWIFIEX_RX_CMD_BUF_SIZE); |
510 | } | 507 | } |
511 | 508 | ||
512 | for (i = 0; i < adapter->priv_num; i++) | ||
513 | if (adapter->priv[i]->media_connected) | ||
514 | netif_carrier_on(adapter->priv[i]->netdev); | ||
515 | |||
516 | /* Disable Host Sleep */ | 509 | /* Disable Host Sleep */ |
517 | if (adapter->hs_activated) | 510 | if (adapter->hs_activated) |
518 | mwifiex_cancel_hs(mwifiex_get_priv(adapter, | 511 | mwifiex_cancel_hs(mwifiex_get_priv(adapter, |
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 8f8fea015cb4..5dd0ccc70b86 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c | |||
@@ -1239,8 +1239,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) | |||
1239 | if (enable_tx_amsdu && mwifiex_is_amsdu_allowed(priv, tid) && | 1239 | if (enable_tx_amsdu && mwifiex_is_amsdu_allowed(priv, tid) && |
1240 | mwifiex_is_11n_aggragation_possible(priv, ptr, | 1240 | mwifiex_is_11n_aggragation_possible(priv, ptr, |
1241 | adapter->tx_buf_size)) | 1241 | adapter->tx_buf_size)) |
1242 | mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN, | 1242 | mwifiex_11n_aggregate_pkt(priv, ptr, ptr_index, flags); |
1243 | ptr_index, flags); | ||
1244 | /* ra_list_spinlock has been freed in | 1243 | /* ra_list_spinlock has been freed in |
1245 | mwifiex_11n_aggregate_pkt() */ | 1244 | mwifiex_11n_aggregate_pkt() */ |
1246 | else | 1245 | else |
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index b9deef66cf4b..e328d3058c41 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
@@ -83,6 +83,7 @@ static struct usb_device_id p54u_table[] = { | |||
83 | {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */ | 83 | {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */ |
84 | {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ | 84 | {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ |
85 | {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ | 85 | {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ |
86 | {USB_DEVICE(0x07aa, 0x0020)}, /* Corega WLUSB2GTST USB */ | ||
86 | {USB_DEVICE(0x0803, 0x4310)}, /* Zoom 4410a */ | 87 | {USB_DEVICE(0x0803, 0x4310)}, /* Zoom 4410a */ |
87 | {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ | 88 | {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ |
88 | {USB_DEVICE(0x083a, 0x4531)}, /* T-Com Sinus 154 data II */ | 89 | {USB_DEVICE(0x083a, 0x4531)}, /* T-Com Sinus 154 data II */ |
@@ -979,6 +980,7 @@ static int p54u_load_firmware(struct ieee80211_hw *dev, | |||
979 | if (err) { | 980 | if (err) { |
980 | dev_err(&priv->udev->dev, "(p54usb) cannot load firmware %s " | 981 | dev_err(&priv->udev->dev, "(p54usb) cannot load firmware %s " |
981 | "(%d)!\n", p54u_fwlist[i].fw, err); | 982 | "(%d)!\n", p54u_fwlist[i].fw, err); |
983 | usb_put_dev(udev); | ||
982 | } | 984 | } |
983 | 985 | ||
984 | return err; | 986 | return err; |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 3d53a09da5a1..38ed9a3e44c8 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -1261,7 +1261,7 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry, | |||
1261 | */ | 1261 | */ |
1262 | rxdesc->timestamp = ((u64)rx_high << 32) | rx_low; | 1262 | rxdesc->timestamp = ((u64)rx_high << 32) | rx_low; |
1263 | rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL) & ~0x08; | 1263 | rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL) & ~0x08; |
1264 | rxdesc->rssi = rt2x00_get_field32(word2, RXD_W3_RSSI) - | 1264 | rxdesc->rssi = rt2x00_get_field32(word3, RXD_W3_RSSI) - |
1265 | entry->queue->rt2x00dev->rssi_offset; | 1265 | entry->queue->rt2x00dev->rssi_offset; |
1266 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1266 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1267 | 1267 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 96677ce55da4..997df03a0c2e 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -148,6 +148,8 @@ static bool rt2800usb_txstatus_timeout(struct rt2x00_dev *rt2x00dev) | |||
148 | return false; | 148 | return false; |
149 | } | 149 | } |
150 | 150 | ||
151 | #define TXSTATUS_READ_INTERVAL 1000000 | ||
152 | |||
151 | static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, | 153 | static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, |
152 | int urb_status, u32 tx_status) | 154 | int urb_status, u32 tx_status) |
153 | { | 155 | { |
@@ -176,8 +178,9 @@ static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, | |||
176 | queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); | 178 | queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); |
177 | 179 | ||
178 | if (rt2800usb_txstatus_pending(rt2x00dev)) { | 180 | if (rt2800usb_txstatus_pending(rt2x00dev)) { |
179 | /* Read register after 250 us */ | 181 | /* Read register after 1 ms */ |
180 | hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 250000), | 182 | hrtimer_start(&rt2x00dev->txstatus_timer, |
183 | ktime_set(0, TXSTATUS_READ_INTERVAL), | ||
181 | HRTIMER_MODE_REL); | 184 | HRTIMER_MODE_REL); |
182 | return false; | 185 | return false; |
183 | } | 186 | } |
@@ -202,8 +205,9 @@ static void rt2800usb_async_read_tx_status(struct rt2x00_dev *rt2x00dev) | |||
202 | if (test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags)) | 205 | if (test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags)) |
203 | return; | 206 | return; |
204 | 207 | ||
205 | /* Read TX_STA_FIFO register after 500 us */ | 208 | /* Read TX_STA_FIFO register after 2 ms */ |
206 | hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 500000), | 209 | hrtimer_start(&rt2x00dev->txstatus_timer, |
210 | ktime_set(0, 2*TXSTATUS_READ_INTERVAL), | ||
207 | HRTIMER_MODE_REL); | 211 | HRTIMER_MODE_REL); |
208 | } | 212 | } |
209 | 213 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 51f17cfb93f9..7c157857f5ce 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -754,6 +754,9 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop) | |||
754 | struct rt2x00_dev *rt2x00dev = hw->priv; | 754 | struct rt2x00_dev *rt2x00dev = hw->priv; |
755 | struct data_queue *queue; | 755 | struct data_queue *queue; |
756 | 756 | ||
757 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) | ||
758 | return; | ||
759 | |||
757 | tx_queue_for_each(rt2x00dev, queue) | 760 | tx_queue_for_each(rt2x00dev, queue) |
758 | rt2x00queue_flush_queue(queue, drop); | 761 | rt2x00queue_flush_queue(queue, drop); |
759 | } | 762 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 6c5d667103c4..25da20e7e1f3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
@@ -105,13 +105,11 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops) | |||
105 | goto exit_release_regions; | 105 | goto exit_release_regions; |
106 | } | 106 | } |
107 | 107 | ||
108 | pci_enable_msi(pci_dev); | ||
109 | |||
110 | hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); | 108 | hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); |
111 | if (!hw) { | 109 | if (!hw) { |
112 | rt2x00_probe_err("Failed to allocate hardware\n"); | 110 | rt2x00_probe_err("Failed to allocate hardware\n"); |
113 | retval = -ENOMEM; | 111 | retval = -ENOMEM; |
114 | goto exit_disable_msi; | 112 | goto exit_release_regions; |
115 | } | 113 | } |
116 | 114 | ||
117 | pci_set_drvdata(pci_dev, hw); | 115 | pci_set_drvdata(pci_dev, hw); |
@@ -152,9 +150,6 @@ exit_free_reg: | |||
152 | exit_free_device: | 150 | exit_free_device: |
153 | ieee80211_free_hw(hw); | 151 | ieee80211_free_hw(hw); |
154 | 152 | ||
155 | exit_disable_msi: | ||
156 | pci_disable_msi(pci_dev); | ||
157 | |||
158 | exit_release_regions: | 153 | exit_release_regions: |
159 | pci_release_regions(pci_dev); | 154 | pci_release_regions(pci_dev); |
160 | 155 | ||
@@ -179,8 +174,6 @@ void rt2x00pci_remove(struct pci_dev *pci_dev) | |||
179 | rt2x00pci_free_reg(rt2x00dev); | 174 | rt2x00pci_free_reg(rt2x00dev); |
180 | ieee80211_free_hw(hw); | 175 | ieee80211_free_hw(hw); |
181 | 176 | ||
182 | pci_disable_msi(pci_dev); | ||
183 | |||
184 | /* | 177 | /* |
185 | * Free the PCI device data. | 178 | * Free the PCI device data. |
186 | */ | 179 | */ |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 04c7e57dbce2..25e50ffc44ec 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | |||
@@ -343,7 +343,8 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw, | |||
343 | (bool)GET_RX_DESC_PAGGR(pdesc)); | 343 | (bool)GET_RX_DESC_PAGGR(pdesc)); |
344 | rx_status->mactime = GET_RX_DESC_TSFL(pdesc); | 344 | rx_status->mactime = GET_RX_DESC_TSFL(pdesc); |
345 | if (phystatus) { | 345 | if (phystatus) { |
346 | p_drvinfo = (struct rx_fwinfo_92c *)(pdesc + RTL_RX_DESC_SIZE); | 346 | p_drvinfo = (struct rx_fwinfo_92c *)(skb->data + |
347 | stats->rx_bufshift); | ||
347 | rtl92c_translate_rx_signal_stuff(hw, skb, stats, pdesc, | 348 | rtl92c_translate_rx_signal_stuff(hw, skb, stats, pdesc, |
348 | p_drvinfo); | 349 | p_drvinfo); |
349 | } | 350 | } |
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 96763dcff5ae..d224dc3bb092 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h | |||
@@ -2055,7 +2055,7 @@ struct rtl_priv { | |||
2055 | that it points to the data allocated | 2055 | that it points to the data allocated |
2056 | beyond this structure like: | 2056 | beyond this structure like: |
2057 | rtl_pci_priv or rtl_usb_priv */ | 2057 | rtl_pci_priv or rtl_usb_priv */ |
2058 | u8 priv[0]; | 2058 | u8 priv[0] __aligned(sizeof(void *)); |
2059 | }; | 2059 | }; |
2060 | 2060 | ||
2061 | #define rtl_priv(hw) (((struct rtl_priv *)(hw)->priv)) | 2061 | #define rtl_priv(hw) (((struct rtl_priv *)(hw)->priv)) |
diff --git a/include/linux/bcma/bcma_driver_pci.h b/include/linux/bcma/bcma_driver_pci.h index d66033f418c9..0333e605ea0d 100644 --- a/include/linux/bcma/bcma_driver_pci.h +++ b/include/linux/bcma/bcma_driver_pci.h | |||
@@ -242,6 +242,7 @@ extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, | |||
242 | struct bcma_device *core, bool enable); | 242 | struct bcma_device *core, bool enable); |
243 | extern void bcma_core_pci_up(struct bcma_bus *bus); | 243 | extern void bcma_core_pci_up(struct bcma_bus *bus); |
244 | extern void bcma_core_pci_down(struct bcma_bus *bus); | 244 | extern void bcma_core_pci_down(struct bcma_bus *bus); |
245 | extern void bcma_core_pci_power_save(struct bcma_bus *bus, bool up); | ||
245 | 246 | ||
246 | extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev); | 247 | extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev); |
247 | extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev); | 248 | extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev); |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ac28af74a414..b0a651cc389f 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -3564,7 +3564,7 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, | |||
3564 | return -EINVAL; | 3564 | return -EINVAL; |
3565 | } | 3565 | } |
3566 | band = chanctx_conf->def.chan->band; | 3566 | band = chanctx_conf->def.chan->band; |
3567 | sta = sta_info_get(sdata, peer); | 3567 | sta = sta_info_get_bss(sdata, peer); |
3568 | if (sta) { | 3568 | if (sta) { |
3569 | qos = test_sta_flag(sta, WLAN_STA_WME); | 3569 | qos = test_sta_flag(sta, WLAN_STA_WME); |
3570 | } else { | 3570 | } else { |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3a87c8976a32..fe48b093d4dc 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -334,6 +334,7 @@ enum ieee80211_sta_flags { | |||
334 | IEEE80211_STA_DISABLE_VHT = BIT(11), | 334 | IEEE80211_STA_DISABLE_VHT = BIT(11), |
335 | IEEE80211_STA_DISABLE_80P80MHZ = BIT(12), | 335 | IEEE80211_STA_DISABLE_80P80MHZ = BIT(12), |
336 | IEEE80211_STA_DISABLE_160MHZ = BIT(13), | 336 | IEEE80211_STA_DISABLE_160MHZ = BIT(13), |
337 | IEEE80211_STA_DISABLE_WMM = BIT(14), | ||
337 | }; | 338 | }; |
338 | 339 | ||
339 | struct ieee80211_mgd_auth_data { | 340 | struct ieee80211_mgd_auth_data { |
@@ -893,6 +894,8 @@ struct tpt_led_trigger { | |||
893 | * that the scan completed. | 894 | * that the scan completed. |
894 | * @SCAN_ABORTED: Set for our scan work function when the driver reported | 895 | * @SCAN_ABORTED: Set for our scan work function when the driver reported |
895 | * a scan complete for an aborted scan. | 896 | * a scan complete for an aborted scan. |
897 | * @SCAN_HW_CANCELLED: Set for our scan work function when the scan is being | ||
898 | * cancelled. | ||
896 | */ | 899 | */ |
897 | enum { | 900 | enum { |
898 | SCAN_SW_SCANNING, | 901 | SCAN_SW_SCANNING, |
@@ -900,6 +903,7 @@ enum { | |||
900 | SCAN_ONCHANNEL_SCANNING, | 903 | SCAN_ONCHANNEL_SCANNING, |
901 | SCAN_COMPLETED, | 904 | SCAN_COMPLETED, |
902 | SCAN_ABORTED, | 905 | SCAN_ABORTED, |
906 | SCAN_HW_CANCELLED, | ||
903 | }; | 907 | }; |
904 | 908 | ||
905 | /** | 909 | /** |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 91cc8281e266..d7bdc4b97dde 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -2527,7 +2527,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2527 | */ | 2527 | */ |
2528 | ifmgd->wmm_last_param_set = -1; | 2528 | ifmgd->wmm_last_param_set = -1; |
2529 | 2529 | ||
2530 | if (elems.wmm_param) | 2530 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM) && elems.wmm_param) |
2531 | ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, | 2531 | ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, |
2532 | elems.wmm_param_len); | 2532 | elems.wmm_param_len); |
2533 | else | 2533 | else |
@@ -2955,7 +2955,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2955 | ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, | 2955 | ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, |
2956 | &elems, true); | 2956 | &elems, true); |
2957 | 2957 | ||
2958 | if (ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, | 2958 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM) && |
2959 | ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, | ||
2959 | elems.wmm_param_len)) | 2960 | elems.wmm_param_len)) |
2960 | changed |= BSS_CHANGED_QOS; | 2961 | changed |= BSS_CHANGED_QOS; |
2961 | 2962 | ||
@@ -3937,6 +3938,44 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
3937 | return err; | 3938 | return err; |
3938 | } | 3939 | } |
3939 | 3940 | ||
3941 | static bool ieee80211_usable_wmm_params(struct ieee80211_sub_if_data *sdata, | ||
3942 | const u8 *wmm_param, int len) | ||
3943 | { | ||
3944 | const u8 *pos; | ||
3945 | size_t left; | ||
3946 | |||
3947 | if (len < 8) | ||
3948 | return false; | ||
3949 | |||
3950 | if (wmm_param[5] != 1 /* version */) | ||
3951 | return false; | ||
3952 | |||
3953 | pos = wmm_param + 8; | ||
3954 | left = len - 8; | ||
3955 | |||
3956 | for (; left >= 4; left -= 4, pos += 4) { | ||
3957 | u8 aifsn = pos[0] & 0x0f; | ||
3958 | u8 ecwmin = pos[1] & 0x0f; | ||
3959 | u8 ecwmax = (pos[1] & 0xf0) >> 4; | ||
3960 | int aci = (pos[0] >> 5) & 0x03; | ||
3961 | |||
3962 | if (aifsn < 2) { | ||
3963 | sdata_info(sdata, | ||
3964 | "AP has invalid WMM params (AIFSN=%d for ACI %d), disabling WMM\n", | ||
3965 | aifsn, aci); | ||
3966 | return false; | ||
3967 | } | ||
3968 | if (ecwmin > ecwmax) { | ||
3969 | sdata_info(sdata, | ||
3970 | "AP has invalid WMM params (ECWmin/max=%d/%d for ACI %d), disabling WMM\n", | ||
3971 | ecwmin, ecwmax, aci); | ||
3972 | return false; | ||
3973 | } | ||
3974 | } | ||
3975 | |||
3976 | return true; | ||
3977 | } | ||
3978 | |||
3940 | int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | 3979 | int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, |
3941 | struct cfg80211_assoc_request *req) | 3980 | struct cfg80211_assoc_request *req) |
3942 | { | 3981 | { |
@@ -3994,9 +4033,45 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3994 | } | 4033 | } |
3995 | 4034 | ||
3996 | /* prepare assoc data */ | 4035 | /* prepare assoc data */ |
3997 | 4036 | ||
3998 | ifmgd->beacon_crc_valid = false; | 4037 | ifmgd->beacon_crc_valid = false; |
3999 | 4038 | ||
4039 | assoc_data->wmm = bss->wmm_used && | ||
4040 | (local->hw.queues >= IEEE80211_NUM_ACS); | ||
4041 | if (assoc_data->wmm) { | ||
4042 | /* try to check validity of WMM params IE */ | ||
4043 | const struct cfg80211_bss_ies *ies; | ||
4044 | const u8 *wp, *start, *end; | ||
4045 | |||
4046 | rcu_read_lock(); | ||
4047 | ies = rcu_dereference(req->bss->ies); | ||
4048 | start = ies->data; | ||
4049 | end = start + ies->len; | ||
4050 | |||
4051 | while (true) { | ||
4052 | wp = cfg80211_find_vendor_ie( | ||
4053 | WLAN_OUI_MICROSOFT, | ||
4054 | WLAN_OUI_TYPE_MICROSOFT_WMM, | ||
4055 | start, end - start); | ||
4056 | if (!wp) | ||
4057 | break; | ||
4058 | start = wp + wp[1] + 2; | ||
4059 | /* if this IE is too short, try the next */ | ||
4060 | if (wp[1] <= 4) | ||
4061 | continue; | ||
4062 | /* if this IE is WMM params, we found what we wanted */ | ||
4063 | if (wp[6] == 1) | ||
4064 | break; | ||
4065 | } | ||
4066 | |||
4067 | if (!wp || !ieee80211_usable_wmm_params(sdata, wp + 2, | ||
4068 | wp[1] - 2)) { | ||
4069 | assoc_data->wmm = false; | ||
4070 | ifmgd->flags |= IEEE80211_STA_DISABLE_WMM; | ||
4071 | } | ||
4072 | rcu_read_unlock(); | ||
4073 | } | ||
4074 | |||
4000 | /* | 4075 | /* |
4001 | * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode. | 4076 | * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode. |
4002 | * We still associate in non-HT mode (11a/b/g) if any one of these | 4077 | * We still associate in non-HT mode (11a/b/g) if any one of these |
@@ -4026,18 +4101,22 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4026 | /* Also disable HT if we don't support it or the AP doesn't use WMM */ | 4101 | /* Also disable HT if we don't support it or the AP doesn't use WMM */ |
4027 | sband = local->hw.wiphy->bands[req->bss->channel->band]; | 4102 | sband = local->hw.wiphy->bands[req->bss->channel->band]; |
4028 | if (!sband->ht_cap.ht_supported || | 4103 | if (!sband->ht_cap.ht_supported || |
4029 | local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) { | 4104 | local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used || |
4105 | ifmgd->flags & IEEE80211_STA_DISABLE_WMM) { | ||
4030 | ifmgd->flags |= IEEE80211_STA_DISABLE_HT; | 4106 | ifmgd->flags |= IEEE80211_STA_DISABLE_HT; |
4031 | if (!bss->wmm_used) | 4107 | if (!bss->wmm_used && |
4108 | !(ifmgd->flags & IEEE80211_STA_DISABLE_WMM)) | ||
4032 | netdev_info(sdata->dev, | 4109 | netdev_info(sdata->dev, |
4033 | "disabling HT as WMM/QoS is not supported by the AP\n"); | 4110 | "disabling HT as WMM/QoS is not supported by the AP\n"); |
4034 | } | 4111 | } |
4035 | 4112 | ||
4036 | /* disable VHT if we don't support it or the AP doesn't use WMM */ | 4113 | /* disable VHT if we don't support it or the AP doesn't use WMM */ |
4037 | if (!sband->vht_cap.vht_supported || | 4114 | if (!sband->vht_cap.vht_supported || |
4038 | local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) { | 4115 | local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used || |
4116 | ifmgd->flags & IEEE80211_STA_DISABLE_WMM) { | ||
4039 | ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; | 4117 | ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; |
4040 | if (!bss->wmm_used) | 4118 | if (!bss->wmm_used && |
4119 | !(ifmgd->flags & IEEE80211_STA_DISABLE_WMM)) | ||
4041 | netdev_info(sdata->dev, | 4120 | netdev_info(sdata->dev, |
4042 | "disabling VHT as WMM/QoS is not supported by the AP\n"); | 4121 | "disabling VHT as WMM/QoS is not supported by the AP\n"); |
4043 | } | 4122 | } |
@@ -4066,8 +4145,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4066 | sdata->smps_mode = ifmgd->req_smps; | 4145 | sdata->smps_mode = ifmgd->req_smps; |
4067 | 4146 | ||
4068 | assoc_data->capability = req->bss->capability; | 4147 | assoc_data->capability = req->bss->capability; |
4069 | assoc_data->wmm = bss->wmm_used && | ||
4070 | (local->hw.queues >= IEEE80211_NUM_ACS); | ||
4071 | assoc_data->supp_rates = bss->supp_rates; | 4148 | assoc_data->supp_rates = bss->supp_rates; |
4072 | assoc_data->supp_rates_len = bss->supp_rates_len; | 4149 | assoc_data->supp_rates_len = bss->supp_rates_len; |
4073 | 4150 | ||
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index acd1f71adc03..0c2a29484c07 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
@@ -394,6 +394,8 @@ void ieee80211_sw_roc_work(struct work_struct *work) | |||
394 | 394 | ||
395 | if (started) | 395 | if (started) |
396 | ieee80211_start_next_roc(local); | 396 | ieee80211_start_next_roc(local); |
397 | else if (list_empty(&local->roc_list)) | ||
398 | ieee80211_run_deferred_scan(local); | ||
397 | } | 399 | } |
398 | 400 | ||
399 | out_unlock: | 401 | out_unlock: |
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index e126605cec66..22b223f13c9f 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
@@ -235,7 +235,8 @@ static void rc_send_low_basicrate(s8 *idx, u32 basic_rates, | |||
235 | static void __rate_control_send_low(struct ieee80211_hw *hw, | 235 | static void __rate_control_send_low(struct ieee80211_hw *hw, |
236 | struct ieee80211_supported_band *sband, | 236 | struct ieee80211_supported_band *sband, |
237 | struct ieee80211_sta *sta, | 237 | struct ieee80211_sta *sta, |
238 | struct ieee80211_tx_info *info) | 238 | struct ieee80211_tx_info *info, |
239 | u32 rate_mask) | ||
239 | { | 240 | { |
240 | int i; | 241 | int i; |
241 | u32 rate_flags = | 242 | u32 rate_flags = |
@@ -247,6 +248,12 @@ static void __rate_control_send_low(struct ieee80211_hw *hw, | |||
247 | 248 | ||
248 | info->control.rates[0].idx = 0; | 249 | info->control.rates[0].idx = 0; |
249 | for (i = 0; i < sband->n_bitrates; i++) { | 250 | for (i = 0; i < sband->n_bitrates; i++) { |
251 | if (!(rate_mask & BIT(i))) | ||
252 | continue; | ||
253 | |||
254 | if ((rate_flags & sband->bitrates[i].flags) != rate_flags) | ||
255 | continue; | ||
256 | |||
250 | if (!rate_supported(sta, sband->band, i)) | 257 | if (!rate_supported(sta, sband->band, i)) |
251 | continue; | 258 | continue; |
252 | 259 | ||
@@ -274,7 +281,8 @@ bool rate_control_send_low(struct ieee80211_sta *pubsta, | |||
274 | bool use_basicrate = false; | 281 | bool use_basicrate = false; |
275 | 282 | ||
276 | if (!pubsta || !priv_sta || rc_no_data_or_no_ack_use_min(txrc)) { | 283 | if (!pubsta || !priv_sta || rc_no_data_or_no_ack_use_min(txrc)) { |
277 | __rate_control_send_low(txrc->hw, sband, pubsta, info); | 284 | __rate_control_send_low(txrc->hw, sband, pubsta, info, |
285 | txrc->rate_idx_mask); | ||
278 | 286 | ||
279 | if (!pubsta && txrc->bss) { | 287 | if (!pubsta && txrc->bss) { |
280 | mcast_rate = txrc->bss_conf->mcast_rate[sband->band]; | 288 | mcast_rate = txrc->bss_conf->mcast_rate[sband->band]; |
@@ -656,7 +664,8 @@ void ieee80211_get_tx_rates(struct ieee80211_vif *vif, | |||
656 | rate_control_apply_mask(sdata, sta, sband, info, dest, max_rates); | 664 | rate_control_apply_mask(sdata, sta, sband, info, dest, max_rates); |
657 | 665 | ||
658 | if (dest[0].idx < 0) | 666 | if (dest[0].idx < 0) |
659 | __rate_control_send_low(&sdata->local->hw, sband, sta, info); | 667 | __rate_control_send_low(&sdata->local->hw, sband, sta, info, |
668 | sdata->rc_rateidx_mask[info->band]); | ||
660 | 669 | ||
661 | if (sta) | 670 | if (sta) |
662 | rate_fixup_ratelist(vif, sband, info, dest, max_rates); | 671 | rate_fixup_ratelist(vif, sband, info, dest, max_rates); |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index f0247a43a75c..0011ac815097 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -3073,6 +3073,9 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
3073 | case NL80211_IFTYPE_ADHOC: | 3073 | case NL80211_IFTYPE_ADHOC: |
3074 | if (!bssid) | 3074 | if (!bssid) |
3075 | return 0; | 3075 | return 0; |
3076 | if (ether_addr_equal(sdata->vif.addr, hdr->addr2) || | ||
3077 | ether_addr_equal(sdata->u.ibss.bssid, hdr->addr2)) | ||
3078 | return 0; | ||
3076 | if (ieee80211_is_beacon(hdr->frame_control)) { | 3079 | if (ieee80211_is_beacon(hdr->frame_control)) { |
3077 | return 1; | 3080 | return 1; |
3078 | } else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { | 3081 | } else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index ecb57b0bf74a..5ad66a83ef7f 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -238,6 +238,9 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) | |||
238 | enum ieee80211_band band; | 238 | enum ieee80211_band band; |
239 | int i, ielen, n_chans; | 239 | int i, ielen, n_chans; |
240 | 240 | ||
241 | if (test_bit(SCAN_HW_CANCELLED, &local->scanning)) | ||
242 | return false; | ||
243 | |||
241 | do { | 244 | do { |
242 | if (local->hw_scan_band == IEEE80211_NUM_BANDS) | 245 | if (local->hw_scan_band == IEEE80211_NUM_BANDS) |
243 | return false; | 246 | return false; |
@@ -939,7 +942,23 @@ void ieee80211_scan_cancel(struct ieee80211_local *local) | |||
939 | if (!local->scan_req) | 942 | if (!local->scan_req) |
940 | goto out; | 943 | goto out; |
941 | 944 | ||
945 | /* | ||
946 | * We have a scan running and the driver already reported completion, | ||
947 | * but the worker hasn't run yet or is stuck on the mutex - mark it as | ||
948 | * cancelled. | ||
949 | */ | ||
950 | if (test_bit(SCAN_HW_SCANNING, &local->scanning) && | ||
951 | test_bit(SCAN_COMPLETED, &local->scanning)) { | ||
952 | set_bit(SCAN_HW_CANCELLED, &local->scanning); | ||
953 | goto out; | ||
954 | } | ||
955 | |||
942 | if (test_bit(SCAN_HW_SCANNING, &local->scanning)) { | 956 | if (test_bit(SCAN_HW_SCANNING, &local->scanning)) { |
957 | /* | ||
958 | * Make sure that __ieee80211_scan_completed doesn't trigger a | ||
959 | * scan on another band. | ||
960 | */ | ||
961 | set_bit(SCAN_HW_CANCELLED, &local->scanning); | ||
943 | if (local->ops->cancel_hw_scan) | 962 | if (local->ops->cancel_hw_scan) |
944 | drv_cancel_hw_scan(local, | 963 | drv_cancel_hw_scan(local, |
945 | rcu_dereference_protected(local->scan_sdata, | 964 | rcu_dereference_protected(local->scan_sdata, |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 368837fe3b80..78dc2e99027e 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -180,6 +180,9 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb) | |||
180 | struct ieee80211_local *local = sta->local; | 180 | struct ieee80211_local *local = sta->local; |
181 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 181 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
182 | 182 | ||
183 | if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) | ||
184 | sta->last_rx = jiffies; | ||
185 | |||
183 | if (ieee80211_is_data_qos(mgmt->frame_control)) { | 186 | if (ieee80211_is_data_qos(mgmt->frame_control)) { |
184 | struct ieee80211_hdr *hdr = (void *) skb->data; | 187 | struct ieee80211_hdr *hdr = (void *) skb->data; |
185 | u8 *qc = ieee80211_get_qos_ctl(hdr); | 188 | u8 *qc = ieee80211_get_qos_ctl(hdr); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 4fcbf634b548..9993fcb19ecd 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1120,7 +1120,8 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1120 | tx->sta = rcu_dereference(sdata->u.vlan.sta); | 1120 | tx->sta = rcu_dereference(sdata->u.vlan.sta); |
1121 | if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr) | 1121 | if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr) |
1122 | return TX_DROP; | 1122 | return TX_DROP; |
1123 | } else if (info->flags & IEEE80211_TX_CTL_INJECTED || | 1123 | } else if (info->flags & (IEEE80211_TX_CTL_INJECTED | |
1124 | IEEE80211_TX_INTFL_NL80211_FRAME_TX) || | ||
1124 | tx->sdata->control_port_protocol == tx->skb->protocol) { | 1125 | tx->sdata->control_port_protocol == tx->skb->protocol) { |
1125 | tx->sta = sta_info_get_bss(sdata, hdr->addr1); | 1126 | tx->sta = sta_info_get_bss(sdata, hdr->addr1); |
1126 | } | 1127 | } |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 550a6880625d..aefb9d5b9620 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -2101,7 +2101,7 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, | |||
2101 | { | 2101 | { |
2102 | struct ieee80211_local *local = sdata->local; | 2102 | struct ieee80211_local *local = sdata->local; |
2103 | struct ieee80211_supported_band *sband; | 2103 | struct ieee80211_supported_band *sband; |
2104 | int rate, skip, shift; | 2104 | int rate, shift; |
2105 | u8 i, exrates, *pos; | 2105 | u8 i, exrates, *pos; |
2106 | u32 basic_rates = sdata->vif.bss_conf.basic_rates; | 2106 | u32 basic_rates = sdata->vif.bss_conf.basic_rates; |
2107 | u32 rate_flags; | 2107 | u32 rate_flags; |
@@ -2129,14 +2129,11 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, | |||
2129 | pos = skb_put(skb, exrates + 2); | 2129 | pos = skb_put(skb, exrates + 2); |
2130 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | 2130 | *pos++ = WLAN_EID_EXT_SUPP_RATES; |
2131 | *pos++ = exrates; | 2131 | *pos++ = exrates; |
2132 | skip = 0; | ||
2133 | for (i = 8; i < sband->n_bitrates; i++) { | 2132 | for (i = 8; i < sband->n_bitrates; i++) { |
2134 | u8 basic = 0; | 2133 | u8 basic = 0; |
2135 | if ((rate_flags & sband->bitrates[i].flags) | 2134 | if ((rate_flags & sband->bitrates[i].flags) |
2136 | != rate_flags) | 2135 | != rate_flags) |
2137 | continue; | 2136 | continue; |
2138 | if (skip++ < 8) | ||
2139 | continue; | ||
2140 | if (need_basic && basic_rates & BIT(i)) | 2137 | if (need_basic && basic_rates & BIT(i)) |
2141 | basic = 0x80; | 2138 | basic = 0x80; |
2142 | rate = DIV_ROUND_UP(sband->bitrates[i].bitrate, | 2139 | rate = DIV_ROUND_UP(sband->bitrates[i].bitrate, |
@@ -2239,6 +2236,10 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local, | |||
2239 | } | 2236 | } |
2240 | 2237 | ||
2241 | rate = cfg80211_calculate_bitrate(&ri); | 2238 | rate = cfg80211_calculate_bitrate(&ri); |
2239 | if (WARN_ONCE(!rate, | ||
2240 | "Invalid bitrate: flags=0x%x, idx=%d, vht_nss=%d\n", | ||
2241 | status->flag, status->rate_idx, status->vht_nss)) | ||
2242 | return 0; | ||
2242 | 2243 | ||
2243 | /* rewind from end of MPDU */ | 2244 | /* rewind from end of MPDU */ |
2244 | if (status->flag & RX_FLAG_MACTIME_END) | 2245 | if (status->flag & RX_FLAG_MACTIME_END) |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 67153964aad2..aff959e5a1b3 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -566,18 +566,13 @@ int wiphy_register(struct wiphy *wiphy) | |||
566 | /* check and set up bitrates */ | 566 | /* check and set up bitrates */ |
567 | ieee80211_set_bitrate_flags(wiphy); | 567 | ieee80211_set_bitrate_flags(wiphy); |
568 | 568 | ||
569 | 569 | rtnl_lock(); | |
570 | res = device_add(&rdev->wiphy.dev); | 570 | res = device_add(&rdev->wiphy.dev); |
571 | if (res) | ||
572 | return res; | ||
573 | |||
574 | res = rfkill_register(rdev->rfkill); | ||
575 | if (res) { | 571 | if (res) { |
576 | device_del(&rdev->wiphy.dev); | 572 | rtnl_unlock(); |
577 | return res; | 573 | return res; |
578 | } | 574 | } |
579 | 575 | ||
580 | rtnl_lock(); | ||
581 | /* set up regulatory info */ | 576 | /* set up regulatory info */ |
582 | wiphy_regulatory_register(wiphy); | 577 | wiphy_regulatory_register(wiphy); |
583 | 578 | ||
@@ -606,6 +601,15 @@ int wiphy_register(struct wiphy *wiphy) | |||
606 | 601 | ||
607 | rdev->wiphy.registered = true; | 602 | rdev->wiphy.registered = true; |
608 | rtnl_unlock(); | 603 | rtnl_unlock(); |
604 | |||
605 | res = rfkill_register(rdev->rfkill); | ||
606 | if (res) { | ||
607 | rfkill_destroy(rdev->rfkill); | ||
608 | rdev->rfkill = NULL; | ||
609 | wiphy_unregister(&rdev->wiphy); | ||
610 | return res; | ||
611 | } | ||
612 | |||
609 | return 0; | 613 | return 0; |
610 | } | 614 | } |
611 | EXPORT_SYMBOL(wiphy_register); | 615 | EXPORT_SYMBOL(wiphy_register); |
@@ -640,7 +644,8 @@ void wiphy_unregister(struct wiphy *wiphy) | |||
640 | rtnl_unlock(); | 644 | rtnl_unlock(); |
641 | __count == 0; })); | 645 | __count == 0; })); |
642 | 646 | ||
643 | rfkill_unregister(rdev->rfkill); | 647 | if (rdev->rfkill) |
648 | rfkill_unregister(rdev->rfkill); | ||
644 | 649 | ||
645 | rtnl_lock(); | 650 | rtnl_lock(); |
646 | rdev->wiphy.registered = false; | 651 | rdev->wiphy.registered = false; |
@@ -953,8 +958,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | |||
953 | case NETDEV_PRE_UP: | 958 | case NETDEV_PRE_UP: |
954 | if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) | 959 | if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) |
955 | return notifier_from_errno(-EOPNOTSUPP); | 960 | return notifier_from_errno(-EOPNOTSUPP); |
956 | if (rfkill_blocked(rdev->rfkill)) | ||
957 | return notifier_from_errno(-ERFKILL); | ||
958 | ret = cfg80211_can_add_interface(rdev, wdev->iftype); | 961 | ret = cfg80211_can_add_interface(rdev, wdev->iftype); |
959 | if (ret) | 962 | if (ret) |
960 | return notifier_from_errno(ret); | 963 | return notifier_from_errno(ret); |
diff --git a/net/wireless/core.h b/net/wireless/core.h index b43efac4efca..eb0f7a3a25a9 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -402,6 +402,9 @@ static inline int | |||
402 | cfg80211_can_add_interface(struct cfg80211_registered_device *rdev, | 402 | cfg80211_can_add_interface(struct cfg80211_registered_device *rdev, |
403 | enum nl80211_iftype iftype) | 403 | enum nl80211_iftype iftype) |
404 | { | 404 | { |
405 | if (rfkill_blocked(rdev->rfkill)) | ||
406 | return -ERFKILL; | ||
407 | |||
405 | return cfg80211_can_change_interface(rdev, NULL, iftype); | 408 | return cfg80211_can_change_interface(rdev, NULL, iftype); |
406 | } | 409 | } |
407 | 410 | ||
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 39bff7d36768..403fe29c024d 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
@@ -263,6 +263,8 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, | |||
263 | if (chan->flags & IEEE80211_CHAN_DISABLED) | 263 | if (chan->flags & IEEE80211_CHAN_DISABLED) |
264 | continue; | 264 | continue; |
265 | wdev->wext.ibss.chandef.chan = chan; | 265 | wdev->wext.ibss.chandef.chan = chan; |
266 | wdev->wext.ibss.chandef.center_freq1 = | ||
267 | chan->center_freq; | ||
266 | break; | 268 | break; |
267 | } | 269 | } |
268 | 270 | ||
@@ -347,6 +349,7 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev, | |||
347 | if (chan) { | 349 | if (chan) { |
348 | wdev->wext.ibss.chandef.chan = chan; | 350 | wdev->wext.ibss.chandef.chan = chan; |
349 | wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT; | 351 | wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT; |
352 | wdev->wext.ibss.chandef.center_freq1 = freq; | ||
350 | wdev->wext.ibss.channel_fixed = true; | 353 | wdev->wext.ibss.channel_fixed = true; |
351 | } else { | 354 | } else { |
352 | /* cfg80211_ibss_wext_join will pick one if needed */ | 355 | /* cfg80211_ibss_wext_join will pick one if needed */ |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 2838206ddad3..cbbef88a8ebd 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -2421,7 +2421,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) | |||
2421 | change = true; | 2421 | change = true; |
2422 | } | 2422 | } |
2423 | 2423 | ||
2424 | if (flags && (*flags & NL80211_MNTR_FLAG_ACTIVE) && | 2424 | if (flags && (*flags & MONITOR_FLAG_ACTIVE) && |
2425 | !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR)) | 2425 | !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR)) |
2426 | return -EOPNOTSUPP; | 2426 | return -EOPNOTSUPP; |
2427 | 2427 | ||
@@ -2483,7 +2483,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
2483 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, | 2483 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, |
2484 | &flags); | 2484 | &flags); |
2485 | 2485 | ||
2486 | if (!err && (flags & NL80211_MNTR_FLAG_ACTIVE) && | 2486 | if (!err && (flags & MONITOR_FLAG_ACTIVE) && |
2487 | !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR)) | 2487 | !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR)) |
2488 | return -EOPNOTSUPP; | 2488 | return -EOPNOTSUPP; |
2489 | 2489 | ||
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c index 7d604c06c3dc..a271c27fac77 100644 --- a/net/wireless/radiotap.c +++ b/net/wireless/radiotap.c | |||
@@ -97,6 +97,10 @@ int ieee80211_radiotap_iterator_init( | |||
97 | struct ieee80211_radiotap_header *radiotap_header, | 97 | struct ieee80211_radiotap_header *radiotap_header, |
98 | int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns) | 98 | int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns) |
99 | { | 99 | { |
100 | /* check the radiotap header can actually be present */ | ||
101 | if (max_length < sizeof(struct ieee80211_radiotap_header)) | ||
102 | return -EINVAL; | ||
103 | |||
100 | /* Linux only supports version 0 radiotap format */ | 104 | /* Linux only supports version 0 radiotap format */ |
101 | if (radiotap_header->it_version) | 105 | if (radiotap_header->it_version) |
102 | return -EINVAL; | 106 | return -EINVAL; |
@@ -131,7 +135,8 @@ int ieee80211_radiotap_iterator_init( | |||
131 | */ | 135 | */ |
132 | 136 | ||
133 | if ((unsigned long)iterator->_arg - | 137 | if ((unsigned long)iterator->_arg - |
134 | (unsigned long)iterator->_rtheader > | 138 | (unsigned long)iterator->_rtheader + |
139 | sizeof(uint32_t) > | ||
135 | (unsigned long)iterator->_max_length) | 140 | (unsigned long)iterator->_max_length) |
136 | return -EINVAL; | 141 | return -EINVAL; |
137 | } | 142 | } |