diff options
| author | John W. Linville <linville@tuxdriver.com> | 2014-02-27 15:05:51 -0500 |
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2014-02-27 15:05:51 -0500 |
| commit | 8e2a89c5151d4645b9649ab9a9498f3445d48868 (patch) | |
| tree | cc532feafb67c7a608f5c2b718c548b2c898e1b0 | |
| parent | 724b9e1d75ab3401aaa081bd4efb440c1b3509db (diff) | |
| parent | b7b146c9c9a0248cc57da71244f672ebc54bbef1 (diff) | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h | 4 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 8 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/recv.c | 70 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 13 | ||||
| -rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 14 | ||||
| -rw-r--r-- | drivers/net/wireless/hostap/hostap_ap.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/sta.c | 1 | ||||
| -rw-r--r-- | drivers/net/wireless/libertas/cfg.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/mwifiex/pcie.c | 34 | ||||
| -rw-r--r-- | drivers/net/wireless/mwifiex/usb.c | 4 | ||||
| -rw-r--r-- | drivers/net/wireless/mwifiex/wmm.c | 3 | ||||
| -rw-r--r-- | net/mac80211/ieee80211_i.h | 10 | ||||
| -rw-r--r-- | net/mac80211/mlme.c | 1 | ||||
| -rw-r--r-- | net/mac80211/rx.c | 7 | ||||
| -rw-r--r-- | net/mac80211/sta_info.c | 66 | ||||
| -rw-r--r-- | net/mac80211/sta_info.h | 7 | ||||
| -rw-r--r-- | net/mac80211/tx.c | 15 | ||||
| -rw-r--r-- | net/mac80211/util.c | 48 | ||||
| -rw-r--r-- | net/mac80211/wme.c | 5 | ||||
| -rw-r--r-- | net/nfc/nci/core.c | 2 | ||||
| -rw-r--r-- | net/wireless/reg.c | 2 |
21 files changed, 178 insertions, 140 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index 1cc13569b17b..1b6b4d0cfa97 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h | |||
| @@ -57,7 +57,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { | |||
| 57 | {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32365a5e}, | 57 | {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32365a5e}, |
| 58 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 58 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
| 59 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, | 59 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, |
| 60 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, | 60 | {0x00009e20, 0x000003a5, 0x000003a5, 0x000003a5, 0x000003a5}, |
| 61 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, | 61 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, |
| 62 | {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, | 62 | {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, |
| 63 | {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27}, | 63 | {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27}, |
| @@ -96,7 +96,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { | |||
| 96 | {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000}, | 96 | {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000}, |
| 97 | {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 97 | {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
| 98 | {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, | 98 | {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, |
| 99 | {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, | 99 | {0x0000ae20, 0x000001a6, 0x000001a6, 0x000001aa, 0x000001aa}, |
| 100 | {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, | 100 | {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, |
| 101 | }; | 101 | }; |
| 102 | 102 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 11eab9f01fd8..303ce27964c1 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
| @@ -1534,7 +1534,7 @@ EXPORT_SYMBOL(ath9k_hw_check_nav); | |||
| 1534 | bool ath9k_hw_check_alive(struct ath_hw *ah) | 1534 | bool ath9k_hw_check_alive(struct ath_hw *ah) |
| 1535 | { | 1535 | { |
| 1536 | int count = 50; | 1536 | int count = 50; |
| 1537 | u32 reg; | 1537 | u32 reg, last_val; |
| 1538 | 1538 | ||
| 1539 | if (AR_SREV_9300(ah)) | 1539 | if (AR_SREV_9300(ah)) |
| 1540 | return !ath9k_hw_detect_mac_hang(ah); | 1540 | return !ath9k_hw_detect_mac_hang(ah); |
| @@ -1542,9 +1542,13 @@ bool ath9k_hw_check_alive(struct ath_hw *ah) | |||
| 1542 | if (AR_SREV_9285_12_OR_LATER(ah)) | 1542 | if (AR_SREV_9285_12_OR_LATER(ah)) |
| 1543 | return true; | 1543 | return true; |
| 1544 | 1544 | ||
| 1545 | last_val = REG_READ(ah, AR_OBS_BUS_1); | ||
| 1545 | do { | 1546 | do { |
| 1546 | reg = REG_READ(ah, AR_OBS_BUS_1); | 1547 | reg = REG_READ(ah, AR_OBS_BUS_1); |
| 1548 | if (reg != last_val) | ||
| 1549 | return true; | ||
| 1547 | 1550 | ||
| 1551 | last_val = reg; | ||
| 1548 | if ((reg & 0x7E7FFFEF) == 0x00702400) | 1552 | if ((reg & 0x7E7FFFEF) == 0x00702400) |
| 1549 | continue; | 1553 | continue; |
| 1550 | 1554 | ||
| @@ -1556,6 +1560,8 @@ bool ath9k_hw_check_alive(struct ath_hw *ah) | |||
| 1556 | default: | 1560 | default: |
| 1557 | return true; | 1561 | return true; |
| 1558 | } | 1562 | } |
| 1563 | |||
| 1564 | udelay(1); | ||
| 1559 | } while (count-- > 0); | 1565 | } while (count-- > 0); |
| 1560 | 1566 | ||
| 1561 | return false; | 1567 | return false; |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index a0ebdd000fc2..82e340d3ec60 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
| @@ -732,11 +732,18 @@ static struct ath_rxbuf *ath_get_next_rx_buf(struct ath_softc *sc, | |||
| 732 | return NULL; | 732 | return NULL; |
| 733 | 733 | ||
| 734 | /* | 734 | /* |
| 735 | * mark descriptor as zero-length and set the 'more' | 735 | * Re-check previous descriptor, in case it has been filled |
| 736 | * flag to ensure that both buffers get discarded | 736 | * in the mean time. |
| 737 | */ | 737 | */ |
| 738 | rs->rs_datalen = 0; | 738 | ret = ath9k_hw_rxprocdesc(ah, ds, rs); |
| 739 | rs->rs_more = true; | 739 | if (ret == -EINPROGRESS) { |
| 740 | /* | ||
| 741 | * mark descriptor as zero-length and set the 'more' | ||
| 742 | * flag to ensure that both buffers get discarded | ||
| 743 | */ | ||
| 744 | rs->rs_datalen = 0; | ||
| 745 | rs->rs_more = true; | ||
| 746 | } | ||
| 740 | } | 747 | } |
| 741 | 748 | ||
| 742 | list_del(&bf->list); | 749 | list_del(&bf->list); |
| @@ -985,32 +992,32 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
| 985 | struct ath_common *common = ath9k_hw_common(ah); | 992 | struct ath_common *common = ath9k_hw_common(ah); |
| 986 | struct ieee80211_hdr *hdr; | 993 | struct ieee80211_hdr *hdr; |
| 987 | bool discard_current = sc->rx.discard_next; | 994 | bool discard_current = sc->rx.discard_next; |
| 988 | int ret = 0; | ||
| 989 | 995 | ||
| 990 | /* | 996 | /* |
| 991 | * Discard corrupt descriptors which are marked in | 997 | * Discard corrupt descriptors which are marked in |
| 992 | * ath_get_next_rx_buf(). | 998 | * ath_get_next_rx_buf(). |
| 993 | */ | 999 | */ |
| 994 | sc->rx.discard_next = rx_stats->rs_more; | ||
| 995 | if (discard_current) | 1000 | if (discard_current) |
| 996 | return -EINVAL; | 1001 | goto corrupt; |
| 1002 | |||
| 1003 | sc->rx.discard_next = false; | ||
| 997 | 1004 | ||
| 998 | /* | 1005 | /* |
| 999 | * Discard zero-length packets. | 1006 | * Discard zero-length packets. |
| 1000 | */ | 1007 | */ |
| 1001 | if (!rx_stats->rs_datalen) { | 1008 | if (!rx_stats->rs_datalen) { |
| 1002 | RX_STAT_INC(rx_len_err); | 1009 | RX_STAT_INC(rx_len_err); |
| 1003 | return -EINVAL; | 1010 | goto corrupt; |
| 1004 | } | 1011 | } |
| 1005 | 1012 | ||
| 1006 | /* | 1013 | /* |
| 1007 | * rs_status follows rs_datalen so if rs_datalen is too large | 1014 | * rs_status follows rs_datalen so if rs_datalen is too large |
| 1008 | * we can take a hint that hardware corrupted it, so ignore | 1015 | * we can take a hint that hardware corrupted it, so ignore |
| 1009 | * those frames. | 1016 | * those frames. |
| 1010 | */ | 1017 | */ |
| 1011 | if (rx_stats->rs_datalen > (common->rx_bufsize - ah->caps.rx_status_len)) { | 1018 | if (rx_stats->rs_datalen > (common->rx_bufsize - ah->caps.rx_status_len)) { |
| 1012 | RX_STAT_INC(rx_len_err); | 1019 | RX_STAT_INC(rx_len_err); |
| 1013 | return -EINVAL; | 1020 | goto corrupt; |
| 1014 | } | 1021 | } |
| 1015 | 1022 | ||
| 1016 | /* Only use status info from the last fragment */ | 1023 | /* Only use status info from the last fragment */ |
| @@ -1024,10 +1031,8 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
| 1024 | * This is different from the other corrupt descriptor | 1031 | * This is different from the other corrupt descriptor |
| 1025 | * condition handled above. | 1032 | * condition handled above. |
| 1026 | */ | 1033 | */ |
| 1027 | if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC) { | 1034 | if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC) |
| 1028 | ret = -EINVAL; | 1035 | goto corrupt; |
| 1029 | goto exit; | ||
| 1030 | } | ||
| 1031 | 1036 | ||
| 1032 | hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len); | 1037 | hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len); |
| 1033 | 1038 | ||
| @@ -1043,18 +1048,15 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
| 1043 | if (ath_process_fft(sc, hdr, rx_stats, rx_status->mactime)) | 1048 | if (ath_process_fft(sc, hdr, rx_stats, rx_status->mactime)) |
| 1044 | RX_STAT_INC(rx_spectral); | 1049 | RX_STAT_INC(rx_spectral); |
| 1045 | 1050 | ||
| 1046 | ret = -EINVAL; | 1051 | return -EINVAL; |
| 1047 | goto exit; | ||
| 1048 | } | 1052 | } |
| 1049 | 1053 | ||
| 1050 | /* | 1054 | /* |
| 1051 | * everything but the rate is checked here, the rate check is done | 1055 | * everything but the rate is checked here, the rate check is done |
| 1052 | * separately to avoid doing two lookups for a rate for each frame. | 1056 | * separately to avoid doing two lookups for a rate for each frame. |
| 1053 | */ | 1057 | */ |
| 1054 | if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) { | 1058 | if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) |
| 1055 | ret = -EINVAL; | 1059 | return -EINVAL; |
| 1056 | goto exit; | ||
| 1057 | } | ||
| 1058 | 1060 | ||
| 1059 | if (ath_is_mybeacon(common, hdr)) { | 1061 | if (ath_is_mybeacon(common, hdr)) { |
| 1060 | RX_STAT_INC(rx_beacons); | 1062 | RX_STAT_INC(rx_beacons); |
| @@ -1064,15 +1066,11 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
| 1064 | /* | 1066 | /* |
| 1065 | * This shouldn't happen, but have a safety check anyway. | 1067 | * This shouldn't happen, but have a safety check anyway. |
| 1066 | */ | 1068 | */ |
| 1067 | if (WARN_ON(!ah->curchan)) { | 1069 | if (WARN_ON(!ah->curchan)) |
| 1068 | ret = -EINVAL; | 1070 | return -EINVAL; |
| 1069 | goto exit; | ||
| 1070 | } | ||
| 1071 | 1071 | ||
| 1072 | if (ath9k_process_rate(common, hw, rx_stats, rx_status)) { | 1072 | if (ath9k_process_rate(common, hw, rx_stats, rx_status)) |
| 1073 | ret =-EINVAL; | 1073 | return -EINVAL; |
| 1074 | goto exit; | ||
| 1075 | } | ||
| 1076 | 1074 | ||
| 1077 | ath9k_process_rssi(common, hw, rx_stats, rx_status); | 1075 | ath9k_process_rssi(common, hw, rx_stats, rx_status); |
| 1078 | 1076 | ||
| @@ -1087,9 +1085,11 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
| 1087 | sc->rx.num_pkts++; | 1085 | sc->rx.num_pkts++; |
| 1088 | #endif | 1086 | #endif |
| 1089 | 1087 | ||
| 1090 | exit: | 1088 | return 0; |
| 1091 | sc->rx.discard_next = false; | 1089 | |
| 1092 | return ret; | 1090 | corrupt: |
| 1091 | sc->rx.discard_next = rx_stats->rs_more; | ||
| 1092 | return -EINVAL; | ||
| 1093 | } | 1093 | } |
| 1094 | 1094 | ||
| 1095 | static void ath9k_rx_skb_postprocess(struct ath_common *common, | 1095 | static void ath9k_rx_skb_postprocess(struct ath_common *common, |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 0a75e2f68c9d..f042a18c8495 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -1444,14 +1444,16 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, | |||
| 1444 | for (tidno = 0, tid = &an->tid[tidno]; | 1444 | for (tidno = 0, tid = &an->tid[tidno]; |
| 1445 | tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { | 1445 | tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { |
| 1446 | 1446 | ||
| 1447 | if (!tid->sched) | ||
| 1448 | continue; | ||
| 1449 | |||
| 1450 | ac = tid->ac; | 1447 | ac = tid->ac; |
| 1451 | txq = ac->txq; | 1448 | txq = ac->txq; |
| 1452 | 1449 | ||
| 1453 | ath_txq_lock(sc, txq); | 1450 | ath_txq_lock(sc, txq); |
| 1454 | 1451 | ||
| 1452 | if (!tid->sched) { | ||
| 1453 | ath_txq_unlock(sc, txq); | ||
| 1454 | continue; | ||
| 1455 | } | ||
| 1456 | |||
| 1455 | buffered = ath_tid_has_buffered(tid); | 1457 | buffered = ath_tid_has_buffered(tid); |
| 1456 | 1458 | ||
| 1457 | tid->sched = false; | 1459 | tid->sched = false; |
| @@ -2184,14 +2186,15 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
| 2184 | txq->stopped = true; | 2186 | txq->stopped = true; |
| 2185 | } | 2187 | } |
| 2186 | 2188 | ||
| 2189 | if (txctl->an) | ||
| 2190 | tid = ath_get_skb_tid(sc, txctl->an, skb); | ||
| 2191 | |||
| 2187 | if (info->flags & IEEE80211_TX_CTL_PS_RESPONSE) { | 2192 | if (info->flags & IEEE80211_TX_CTL_PS_RESPONSE) { |
| 2188 | ath_txq_unlock(sc, txq); | 2193 | ath_txq_unlock(sc, txq); |
| 2189 | txq = sc->tx.uapsdq; | 2194 | txq = sc->tx.uapsdq; |
| 2190 | ath_txq_lock(sc, txq); | 2195 | ath_txq_lock(sc, txq); |
| 2191 | } else if (txctl->an && | 2196 | } else if (txctl->an && |
| 2192 | ieee80211_is_data_present(hdr->frame_control)) { | 2197 | ieee80211_is_data_present(hdr->frame_control)) { |
| 2193 | tid = ath_get_skb_tid(sc, txctl->an, skb); | ||
| 2194 | |||
| 2195 | WARN_ON(tid->ac->txq != txctl->txq); | 2198 | WARN_ON(tid->ac->txq != txctl->txq); |
| 2196 | 2199 | ||
| 2197 | if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) | 2200 | if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 3e991897d7ca..119ee6eaf1c3 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
| @@ -457,7 +457,6 @@ struct brcmf_sdio { | |||
| 457 | 457 | ||
| 458 | u8 tx_hdrlen; /* sdio bus header length for tx packet */ | 458 | u8 tx_hdrlen; /* sdio bus header length for tx packet */ |
| 459 | bool txglom; /* host tx glomming enable flag */ | 459 | bool txglom; /* host tx glomming enable flag */ |
| 460 | struct sk_buff *txglom_sgpad; /* scatter-gather padding buffer */ | ||
| 461 | u16 head_align; /* buffer pointer alignment */ | 460 | u16 head_align; /* buffer pointer alignment */ |
| 462 | u16 sgentry_align; /* scatter-gather buffer alignment */ | 461 | u16 sgentry_align; /* scatter-gather buffer alignment */ |
| 463 | }; | 462 | }; |
| @@ -1944,9 +1943,8 @@ static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio *bus, | |||
| 1944 | if (lastfrm && chain_pad) | 1943 | if (lastfrm && chain_pad) |
| 1945 | tail_pad += blksize - chain_pad; | 1944 | tail_pad += blksize - chain_pad; |
| 1946 | if (skb_tailroom(pkt) < tail_pad && pkt->len > blksize) { | 1945 | if (skb_tailroom(pkt) < tail_pad && pkt->len > blksize) { |
| 1947 | pkt_pad = bus->txglom_sgpad; | 1946 | pkt_pad = brcmu_pkt_buf_get_skb(tail_pad + tail_chop + |
| 1948 | if (pkt_pad == NULL) | 1947 | bus->head_align); |
| 1949 | brcmu_pkt_buf_get_skb(tail_pad + tail_chop); | ||
| 1950 | if (pkt_pad == NULL) | 1948 | if (pkt_pad == NULL) |
| 1951 | return -ENOMEM; | 1949 | return -ENOMEM; |
| 1952 | ret = brcmf_sdio_txpkt_hdalign(bus, pkt_pad); | 1950 | ret = brcmf_sdio_txpkt_hdalign(bus, pkt_pad); |
| @@ -1957,6 +1955,7 @@ static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio *bus, | |||
| 1957 | tail_chop); | 1955 | tail_chop); |
| 1958 | *(u32 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop; | 1956 | *(u32 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop; |
| 1959 | skb_trim(pkt, pkt->len - tail_chop); | 1957 | skb_trim(pkt, pkt->len - tail_chop); |
| 1958 | skb_trim(pkt_pad, tail_pad + tail_chop); | ||
| 1960 | __skb_queue_after(pktq, pkt, pkt_pad); | 1959 | __skb_queue_after(pktq, pkt, pkt_pad); |
| 1961 | } else { | 1960 | } else { |
| 1962 | ntail = pkt->data_len + tail_pad - | 1961 | ntail = pkt->data_len + tail_pad - |
| @@ -2011,7 +2010,7 @@ brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq, | |||
| 2011 | return ret; | 2010 | return ret; |
| 2012 | head_pad = (u16)ret; | 2011 | head_pad = (u16)ret; |
| 2013 | if (head_pad) | 2012 | if (head_pad) |
| 2014 | memset(pkt_next->data, 0, head_pad + bus->tx_hdrlen); | 2013 | memset(pkt_next->data + bus->tx_hdrlen, 0, head_pad); |
| 2015 | 2014 | ||
| 2016 | total_len += pkt_next->len; | 2015 | total_len += pkt_next->len; |
| 2017 | 2016 | ||
| @@ -3486,10 +3485,6 @@ static int brcmf_sdio_bus_preinit(struct device *dev) | |||
| 3486 | bus->txglom = false; | 3485 | bus->txglom = false; |
| 3487 | value = 1; | 3486 | value = 1; |
| 3488 | pad_size = bus->sdiodev->func[2]->cur_blksize << 1; | 3487 | pad_size = bus->sdiodev->func[2]->cur_blksize << 1; |
| 3489 | bus->txglom_sgpad = brcmu_pkt_buf_get_skb(pad_size); | ||
| 3490 | if (!bus->txglom_sgpad) | ||
| 3491 | brcmf_err("allocating txglom padding skb failed, reduced performance\n"); | ||
| 3492 | |||
| 3493 | err = brcmf_iovar_data_set(bus->sdiodev->dev, "bus:rxglom", | 3488 | err = brcmf_iovar_data_set(bus->sdiodev->dev, "bus:rxglom", |
| 3494 | &value, sizeof(u32)); | 3489 | &value, sizeof(u32)); |
| 3495 | if (err < 0) { | 3490 | if (err < 0) { |
| @@ -4053,7 +4048,6 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus) | |||
| 4053 | brcmf_sdio_chip_detach(&bus->ci); | 4048 | brcmf_sdio_chip_detach(&bus->ci); |
| 4054 | } | 4049 | } |
| 4055 | 4050 | ||
| 4056 | brcmu_pkt_buf_free_skb(bus->txglom_sgpad); | ||
| 4057 | kfree(bus->rxbuf); | 4051 | kfree(bus->rxbuf); |
| 4058 | kfree(bus->hdrbuf); | 4052 | kfree(bus->hdrbuf); |
| 4059 | kfree(bus); | 4053 | kfree(bus); |
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index d36e252d2ccb..596525528f50 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c | |||
| @@ -147,7 +147,7 @@ static void ap_free_sta(struct ap_data *ap, struct sta_info *sta) | |||
| 147 | 147 | ||
| 148 | if (!sta->ap && sta->u.sta.challenge) | 148 | if (!sta->ap && sta->u.sta.challenge) |
| 149 | kfree(sta->u.sta.challenge); | 149 | kfree(sta->u.sta.challenge); |
| 150 | del_timer(&sta->timer); | 150 | del_timer_sync(&sta->timer); |
| 151 | #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ | 151 | #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ |
| 152 | 152 | ||
| 153 | kfree(sta); | 153 | kfree(sta); |
diff --git a/drivers/net/wireless/iwlwifi/dvm/sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c index c0d070c5df5e..9cdd91cdf661 100644 --- a/drivers/net/wireless/iwlwifi/dvm/sta.c +++ b/drivers/net/wireless/iwlwifi/dvm/sta.c | |||
| @@ -590,6 +590,7 @@ void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id, | |||
| 590 | sizeof(priv->tid_data[sta_id][tid])); | 590 | sizeof(priv->tid_data[sta_id][tid])); |
| 591 | 591 | ||
| 592 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; | 592 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; |
| 593 | priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; | ||
| 593 | 594 | ||
| 594 | priv->num_stations--; | 595 | priv->num_stations--; |
| 595 | 596 | ||
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 32f75007a825..cb6d189bc3e6 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
| @@ -621,7 +621,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | |||
| 621 | id = *pos++; | 621 | id = *pos++; |
| 622 | elen = *pos++; | 622 | elen = *pos++; |
| 623 | left -= 2; | 623 | left -= 2; |
| 624 | if (elen > left || elen == 0) { | 624 | if (elen > left) { |
| 625 | lbs_deb_scan("scan response: invalid IE fmt\n"); | 625 | lbs_deb_scan("scan response: invalid IE fmt\n"); |
| 626 | goto done; | 626 | goto done; |
| 627 | } | 627 | } |
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 03688aa14e8a..7fe7b53fb17a 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c | |||
| @@ -1211,6 +1211,12 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) | |||
| 1211 | rd_index = card->rxbd_rdptr & reg->rx_mask; | 1211 | rd_index = card->rxbd_rdptr & reg->rx_mask; |
| 1212 | skb_data = card->rx_buf_list[rd_index]; | 1212 | skb_data = card->rx_buf_list[rd_index]; |
| 1213 | 1213 | ||
| 1214 | /* If skb allocation was failed earlier for Rx packet, | ||
| 1215 | * rx_buf_list[rd_index] would have been left with a NULL. | ||
| 1216 | */ | ||
| 1217 | if (!skb_data) | ||
| 1218 | return -ENOMEM; | ||
| 1219 | |||
| 1214 | MWIFIEX_SKB_PACB(skb_data, &buf_pa); | 1220 | MWIFIEX_SKB_PACB(skb_data, &buf_pa); |
| 1215 | pci_unmap_single(card->dev, buf_pa, MWIFIEX_RX_DATA_BUF_SIZE, | 1221 | pci_unmap_single(card->dev, buf_pa, MWIFIEX_RX_DATA_BUF_SIZE, |
| 1216 | PCI_DMA_FROMDEVICE); | 1222 | PCI_DMA_FROMDEVICE); |
| @@ -1525,6 +1531,14 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) | |||
| 1525 | if (adapter->ps_state == PS_STATE_SLEEP_CFM) { | 1531 | if (adapter->ps_state == PS_STATE_SLEEP_CFM) { |
| 1526 | mwifiex_process_sleep_confirm_resp(adapter, skb->data, | 1532 | mwifiex_process_sleep_confirm_resp(adapter, skb->data, |
| 1527 | skb->len); | 1533 | skb->len); |
| 1534 | mwifiex_pcie_enable_host_int(adapter); | ||
| 1535 | if (mwifiex_write_reg(adapter, | ||
| 1536 | PCIE_CPU_INT_EVENT, | ||
| 1537 | CPU_INTR_SLEEP_CFM_DONE)) { | ||
| 1538 | dev_warn(adapter->dev, | ||
| 1539 | "Write register failed\n"); | ||
| 1540 | return -1; | ||
| 1541 | } | ||
| 1528 | while (reg->sleep_cookie && (count++ < 10) && | 1542 | while (reg->sleep_cookie && (count++ < 10) && |
| 1529 | mwifiex_pcie_ok_to_access_hw(adapter)) | 1543 | mwifiex_pcie_ok_to_access_hw(adapter)) |
| 1530 | usleep_range(50, 60); | 1544 | usleep_range(50, 60); |
| @@ -1993,23 +2007,9 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) | |||
| 1993 | adapter->int_status |= pcie_ireg; | 2007 | adapter->int_status |= pcie_ireg; |
| 1994 | spin_unlock_irqrestore(&adapter->int_lock, flags); | 2008 | spin_unlock_irqrestore(&adapter->int_lock, flags); |
| 1995 | 2009 | ||
| 1996 | if (pcie_ireg & HOST_INTR_CMD_DONE) { | 2010 | if (!adapter->pps_uapsd_mode && |
| 1997 | if ((adapter->ps_state == PS_STATE_SLEEP_CFM) || | 2011 | adapter->ps_state == PS_STATE_SLEEP && |
| 1998 | (adapter->ps_state == PS_STATE_SLEEP)) { | 2012 | mwifiex_pcie_ok_to_access_hw(adapter)) { |
| 1999 | mwifiex_pcie_enable_host_int(adapter); | ||
| 2000 | if (mwifiex_write_reg(adapter, | ||
| 2001 | PCIE_CPU_INT_EVENT, | ||
| 2002 | CPU_INTR_SLEEP_CFM_DONE) | ||
| 2003 | ) { | ||
| 2004 | dev_warn(adapter->dev, | ||
| 2005 | "Write register failed\n"); | ||
| 2006 | return; | ||
| 2007 | |||
| 2008 | } | ||
| 2009 | } | ||
| 2010 | } else if (!adapter->pps_uapsd_mode && | ||
| 2011 | adapter->ps_state == PS_STATE_SLEEP && | ||
| 2012 | mwifiex_pcie_ok_to_access_hw(adapter)) { | ||
| 2013 | /* Potentially for PCIe we could get other | 2013 | /* Potentially for PCIe we could get other |
| 2014 | * interrupts like shared. Don't change power | 2014 | * interrupts like shared. Don't change power |
| 2015 | * state until cookie is set */ | 2015 | * state until cookie is set */ |
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c index e8ebbd4bc3cd..cb6b70a1b34d 100644 --- a/drivers/net/wireless/mwifiex/usb.c +++ b/drivers/net/wireless/mwifiex/usb.c | |||
| @@ -22,8 +22,6 @@ | |||
| 22 | 22 | ||
| 23 | #define USB_VERSION "1.0" | 23 | #define USB_VERSION "1.0" |
| 24 | 24 | ||
| 25 | static const char usbdriver_name[] = "usb8xxx"; | ||
| 26 | |||
| 27 | static struct mwifiex_if_ops usb_ops; | 25 | static struct mwifiex_if_ops usb_ops; |
| 28 | static struct semaphore add_remove_card_sem; | 26 | static struct semaphore add_remove_card_sem; |
| 29 | static struct usb_card_rec *usb_card; | 27 | static struct usb_card_rec *usb_card; |
| @@ -567,7 +565,7 @@ static void mwifiex_usb_disconnect(struct usb_interface *intf) | |||
| 567 | } | 565 | } |
| 568 | 566 | ||
| 569 | static struct usb_driver mwifiex_usb_driver = { | 567 | static struct usb_driver mwifiex_usb_driver = { |
| 570 | .name = usbdriver_name, | 568 | .name = "mwifiex_usb", |
| 571 | .probe = mwifiex_usb_probe, | 569 | .probe = mwifiex_usb_probe, |
| 572 | .disconnect = mwifiex_usb_disconnect, | 570 | .disconnect = mwifiex_usb_disconnect, |
| 573 | .id_table = mwifiex_usb_table, | 571 | .id_table = mwifiex_usb_table, |
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 13eaeed03898..981cf6e7c73b 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c | |||
| @@ -559,7 +559,8 @@ mwifiex_clean_txrx(struct mwifiex_private *priv) | |||
| 559 | mwifiex_wmm_delete_all_ralist(priv); | 559 | mwifiex_wmm_delete_all_ralist(priv); |
| 560 | memcpy(tos_to_tid, ac_to_tid, sizeof(tos_to_tid)); | 560 | memcpy(tos_to_tid, ac_to_tid, sizeof(tos_to_tid)); |
| 561 | 561 | ||
| 562 | if (priv->adapter->if_ops.clean_pcie_ring) | 562 | if (priv->adapter->if_ops.clean_pcie_ring && |
| 563 | !priv->adapter->surprise_removed) | ||
| 563 | priv->adapter->if_ops.clean_pcie_ring(priv->adapter); | 564 | priv->adapter->if_ops.clean_pcie_ring(priv->adapter); |
| 564 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); | 565 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); |
| 565 | } | 566 | } |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3701930c6649..5e44e3179e02 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -1692,14 +1692,8 @@ void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, | |||
| 1692 | void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue); | 1692 | void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue); |
| 1693 | void ieee80211_add_pending_skb(struct ieee80211_local *local, | 1693 | void ieee80211_add_pending_skb(struct ieee80211_local *local, |
| 1694 | struct sk_buff *skb); | 1694 | struct sk_buff *skb); |
| 1695 | void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, | 1695 | void ieee80211_add_pending_skbs(struct ieee80211_local *local, |
| 1696 | struct sk_buff_head *skbs, | 1696 | struct sk_buff_head *skbs); |
| 1697 | void (*fn)(void *data), void *data); | ||
| 1698 | static inline void ieee80211_add_pending_skbs(struct ieee80211_local *local, | ||
| 1699 | struct sk_buff_head *skbs) | ||
| 1700 | { | ||
| 1701 | ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL); | ||
| 1702 | } | ||
| 1703 | void ieee80211_flush_queues(struct ieee80211_local *local, | 1697 | void ieee80211_flush_queues(struct ieee80211_local *local, |
| 1704 | struct ieee80211_sub_if_data *sdata); | 1698 | struct ieee80211_sub_if_data *sdata); |
| 1705 | 1699 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index fc1d82465b3c..57d5482b10fa 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -3753,6 +3753,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
| 3753 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | 3753 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); |
| 3754 | if (WARN_ON(!chanctx_conf)) { | 3754 | if (WARN_ON(!chanctx_conf)) { |
| 3755 | rcu_read_unlock(); | 3755 | rcu_read_unlock(); |
| 3756 | sta_info_free(local, new_sta); | ||
| 3756 | return -EINVAL; | 3757 | return -EINVAL; |
| 3757 | } | 3758 | } |
| 3758 | rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def); | 3759 | rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def); |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index c24ca0d0f469..3e57f96c9666 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -1128,6 +1128,13 @@ static void sta_ps_end(struct sta_info *sta) | |||
| 1128 | sta->sta.addr, sta->sta.aid); | 1128 | sta->sta.addr, sta->sta.aid); |
| 1129 | 1129 | ||
| 1130 | if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { | 1130 | if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { |
| 1131 | /* | ||
| 1132 | * Clear the flag only if the other one is still set | ||
| 1133 | * so that the TX path won't start TX'ing new frames | ||
| 1134 | * directly ... In the case that the driver flag isn't | ||
| 1135 | * set ieee80211_sta_ps_deliver_wakeup() will clear it. | ||
| 1136 | */ | ||
| 1137 | clear_sta_flag(sta, WLAN_STA_PS_STA); | ||
| 1131 | ps_dbg(sta->sdata, "STA %pM aid %d driver-ps-blocked\n", | 1138 | ps_dbg(sta->sdata, "STA %pM aid %d driver-ps-blocked\n", |
| 1132 | sta->sta.addr, sta->sta.aid); | 1139 | sta->sta.addr, sta->sta.aid); |
| 1133 | return; | 1140 | return; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index decd30c1e290..a023b432143b 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
| @@ -91,7 +91,7 @@ static int sta_info_hash_del(struct ieee80211_local *local, | |||
| 91 | return -ENOENT; | 91 | return -ENOENT; |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | static void cleanup_single_sta(struct sta_info *sta) | 94 | static void __cleanup_single_sta(struct sta_info *sta) |
| 95 | { | 95 | { |
| 96 | int ac, i; | 96 | int ac, i; |
| 97 | struct tid_ampdu_tx *tid_tx; | 97 | struct tid_ampdu_tx *tid_tx; |
| @@ -99,7 +99,8 @@ static void cleanup_single_sta(struct sta_info *sta) | |||
| 99 | struct ieee80211_local *local = sdata->local; | 99 | struct ieee80211_local *local = sdata->local; |
| 100 | struct ps_data *ps; | 100 | struct ps_data *ps; |
| 101 | 101 | ||
| 102 | if (test_sta_flag(sta, WLAN_STA_PS_STA)) { | 102 | if (test_sta_flag(sta, WLAN_STA_PS_STA) || |
| 103 | test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { | ||
| 103 | if (sta->sdata->vif.type == NL80211_IFTYPE_AP || | 104 | if (sta->sdata->vif.type == NL80211_IFTYPE_AP || |
| 104 | sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 105 | sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
| 105 | ps = &sdata->bss->ps; | 106 | ps = &sdata->bss->ps; |
| @@ -109,6 +110,7 @@ static void cleanup_single_sta(struct sta_info *sta) | |||
| 109 | return; | 110 | return; |
| 110 | 111 | ||
| 111 | clear_sta_flag(sta, WLAN_STA_PS_STA); | 112 | clear_sta_flag(sta, WLAN_STA_PS_STA); |
| 113 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); | ||
| 112 | 114 | ||
| 113 | atomic_dec(&ps->num_sta_ps); | 115 | atomic_dec(&ps->num_sta_ps); |
| 114 | sta_info_recalc_tim(sta); | 116 | sta_info_recalc_tim(sta); |
| @@ -139,7 +141,14 @@ static void cleanup_single_sta(struct sta_info *sta) | |||
| 139 | ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending); | 141 | ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending); |
| 140 | kfree(tid_tx); | 142 | kfree(tid_tx); |
| 141 | } | 143 | } |
| 144 | } | ||
| 142 | 145 | ||
| 146 | static void cleanup_single_sta(struct sta_info *sta) | ||
| 147 | { | ||
| 148 | struct ieee80211_sub_if_data *sdata = sta->sdata; | ||
| 149 | struct ieee80211_local *local = sdata->local; | ||
| 150 | |||
| 151 | __cleanup_single_sta(sta); | ||
| 143 | sta_info_free(local, sta); | 152 | sta_info_free(local, sta); |
| 144 | } | 153 | } |
| 145 | 154 | ||
| @@ -330,6 +339,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
| 330 | rcu_read_unlock(); | 339 | rcu_read_unlock(); |
| 331 | 340 | ||
| 332 | spin_lock_init(&sta->lock); | 341 | spin_lock_init(&sta->lock); |
| 342 | spin_lock_init(&sta->ps_lock); | ||
| 333 | INIT_WORK(&sta->drv_unblock_wk, sta_unblock); | 343 | INIT_WORK(&sta->drv_unblock_wk, sta_unblock); |
| 334 | INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); | 344 | INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); |
| 335 | mutex_init(&sta->ampdu_mlme.mtx); | 345 | mutex_init(&sta->ampdu_mlme.mtx); |
| @@ -487,21 +497,26 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) | |||
| 487 | goto out_err; | 497 | goto out_err; |
| 488 | } | 498 | } |
| 489 | 499 | ||
| 490 | /* notify driver */ | ||
| 491 | err = sta_info_insert_drv_state(local, sdata, sta); | ||
| 492 | if (err) | ||
| 493 | goto out_err; | ||
| 494 | |||
| 495 | local->num_sta++; | 500 | local->num_sta++; |
| 496 | local->sta_generation++; | 501 | local->sta_generation++; |
| 497 | smp_mb(); | 502 | smp_mb(); |
| 498 | 503 | ||
| 504 | /* simplify things and don't accept BA sessions yet */ | ||
| 505 | set_sta_flag(sta, WLAN_STA_BLOCK_BA); | ||
| 506 | |||
| 499 | /* make the station visible */ | 507 | /* make the station visible */ |
| 500 | sta_info_hash_add(local, sta); | 508 | sta_info_hash_add(local, sta); |
| 501 | 509 | ||
| 502 | list_add_rcu(&sta->list, &local->sta_list); | 510 | list_add_rcu(&sta->list, &local->sta_list); |
| 503 | 511 | ||
| 512 | /* notify driver */ | ||
| 513 | err = sta_info_insert_drv_state(local, sdata, sta); | ||
| 514 | if (err) | ||
| 515 | goto out_remove; | ||
| 516 | |||
| 504 | set_sta_flag(sta, WLAN_STA_INSERTED); | 517 | set_sta_flag(sta, WLAN_STA_INSERTED); |
| 518 | /* accept BA sessions now */ | ||
| 519 | clear_sta_flag(sta, WLAN_STA_BLOCK_BA); | ||
| 505 | 520 | ||
| 506 | ieee80211_recalc_min_chandef(sdata); | 521 | ieee80211_recalc_min_chandef(sdata); |
| 507 | ieee80211_sta_debugfs_add(sta); | 522 | ieee80211_sta_debugfs_add(sta); |
| @@ -522,6 +537,12 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) | |||
| 522 | mesh_accept_plinks_update(sdata); | 537 | mesh_accept_plinks_update(sdata); |
| 523 | 538 | ||
| 524 | return 0; | 539 | return 0; |
| 540 | out_remove: | ||
| 541 | sta_info_hash_del(local, sta); | ||
| 542 | list_del_rcu(&sta->list); | ||
| 543 | local->num_sta--; | ||
| 544 | synchronize_net(); | ||
| 545 | __cleanup_single_sta(sta); | ||
| 525 | out_err: | 546 | out_err: |
| 526 | mutex_unlock(&local->sta_mtx); | 547 | mutex_unlock(&local->sta_mtx); |
| 527 | rcu_read_lock(); | 548 | rcu_read_lock(); |
| @@ -1071,10 +1092,14 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, | |||
| 1071 | } | 1092 | } |
| 1072 | EXPORT_SYMBOL(ieee80211_find_sta); | 1093 | EXPORT_SYMBOL(ieee80211_find_sta); |
| 1073 | 1094 | ||
| 1074 | static void clear_sta_ps_flags(void *_sta) | 1095 | /* powersave support code */ |
| 1096 | void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | ||
| 1075 | { | 1097 | { |
| 1076 | struct sta_info *sta = _sta; | ||
| 1077 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 1098 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
| 1099 | struct ieee80211_local *local = sdata->local; | ||
| 1100 | struct sk_buff_head pending; | ||
| 1101 | int filtered = 0, buffered = 0, ac; | ||
| 1102 | unsigned long flags; | ||
| 1078 | struct ps_data *ps; | 1103 | struct ps_data *ps; |
| 1079 | 1104 | ||
| 1080 | if (sdata->vif.type == NL80211_IFTYPE_AP || | 1105 | if (sdata->vif.type == NL80211_IFTYPE_AP || |
| @@ -1085,20 +1110,6 @@ static void clear_sta_ps_flags(void *_sta) | |||
| 1085 | else | 1110 | else |
| 1086 | return; | 1111 | return; |
| 1087 | 1112 | ||
| 1088 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); | ||
| 1089 | if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA)) | ||
| 1090 | atomic_dec(&ps->num_sta_ps); | ||
| 1091 | } | ||
| 1092 | |||
| 1093 | /* powersave support code */ | ||
| 1094 | void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | ||
| 1095 | { | ||
| 1096 | struct ieee80211_sub_if_data *sdata = sta->sdata; | ||
| 1097 | struct ieee80211_local *local = sdata->local; | ||
| 1098 | struct sk_buff_head pending; | ||
| 1099 | int filtered = 0, buffered = 0, ac; | ||
| 1100 | unsigned long flags; | ||
| 1101 | |||
| 1102 | clear_sta_flag(sta, WLAN_STA_SP); | 1113 | clear_sta_flag(sta, WLAN_STA_SP); |
| 1103 | 1114 | ||
| 1104 | BUILD_BUG_ON(BITS_TO_LONGS(IEEE80211_NUM_TIDS) > 1); | 1115 | BUILD_BUG_ON(BITS_TO_LONGS(IEEE80211_NUM_TIDS) > 1); |
| @@ -1109,6 +1120,8 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
| 1109 | 1120 | ||
| 1110 | skb_queue_head_init(&pending); | 1121 | skb_queue_head_init(&pending); |
| 1111 | 1122 | ||
| 1123 | /* sync with ieee80211_tx_h_unicast_ps_buf */ | ||
| 1124 | spin_lock(&sta->ps_lock); | ||
| 1112 | /* Send all buffered frames to the station */ | 1125 | /* Send all buffered frames to the station */ |
| 1113 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | 1126 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { |
| 1114 | int count = skb_queue_len(&pending), tmp; | 1127 | int count = skb_queue_len(&pending), tmp; |
| @@ -1127,7 +1140,12 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
| 1127 | buffered += tmp - count; | 1140 | buffered += tmp - count; |
| 1128 | } | 1141 | } |
| 1129 | 1142 | ||
| 1130 | ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta); | 1143 | ieee80211_add_pending_skbs(local, &pending); |
| 1144 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); | ||
| 1145 | clear_sta_flag(sta, WLAN_STA_PS_STA); | ||
| 1146 | spin_unlock(&sta->ps_lock); | ||
| 1147 | |||
| 1148 | atomic_dec(&ps->num_sta_ps); | ||
| 1131 | 1149 | ||
| 1132 | /* This station just woke up and isn't aware of our SMPS state */ | 1150 | /* This station just woke up and isn't aware of our SMPS state */ |
| 1133 | if (!ieee80211_smps_is_restrictive(sta->known_smps_mode, | 1151 | if (!ieee80211_smps_is_restrictive(sta->known_smps_mode, |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index d77ff7090630..d3a6d8208f2f 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
| @@ -267,6 +267,7 @@ struct ieee80211_tx_latency_stat { | |||
| 267 | * @drv_unblock_wk: used for driver PS unblocking | 267 | * @drv_unblock_wk: used for driver PS unblocking |
| 268 | * @listen_interval: listen interval of this station, when we're acting as AP | 268 | * @listen_interval: listen interval of this station, when we're acting as AP |
| 269 | * @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly | 269 | * @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly |
| 270 | * @ps_lock: used for powersave (when mac80211 is the AP) related locking | ||
| 270 | * @ps_tx_buf: buffers (per AC) of frames to transmit to this station | 271 | * @ps_tx_buf: buffers (per AC) of frames to transmit to this station |
| 271 | * when it leaves power saving state or polls | 272 | * when it leaves power saving state or polls |
| 272 | * @tx_filtered: buffers (per AC) of frames we already tried to | 273 | * @tx_filtered: buffers (per AC) of frames we already tried to |
| @@ -356,10 +357,8 @@ struct sta_info { | |||
| 356 | /* use the accessors defined below */ | 357 | /* use the accessors defined below */ |
| 357 | unsigned long _flags; | 358 | unsigned long _flags; |
| 358 | 359 | ||
| 359 | /* | 360 | /* STA powersave lock and frame queues */ |
| 360 | * STA powersave frame queues, no more than the internal | 361 | spinlock_t ps_lock; |
| 361 | * locking required. | ||
| 362 | */ | ||
| 363 | struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS]; | 362 | struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS]; |
| 364 | struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS]; | 363 | struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS]; |
| 365 | unsigned long driver_buffered_tids; | 364 | unsigned long driver_buffered_tids; |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 97a02d3f7d87..4080c615636f 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -478,6 +478,20 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
| 478 | sta->sta.addr, sta->sta.aid, ac); | 478 | sta->sta.addr, sta->sta.aid, ac); |
| 479 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) | 479 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) |
| 480 | purge_old_ps_buffers(tx->local); | 480 | purge_old_ps_buffers(tx->local); |
| 481 | |||
| 482 | /* sync with ieee80211_sta_ps_deliver_wakeup */ | ||
| 483 | spin_lock(&sta->ps_lock); | ||
| 484 | /* | ||
| 485 | * STA woke up the meantime and all the frames on ps_tx_buf have | ||
| 486 | * been queued to pending queue. No reordering can happen, go | ||
| 487 | * ahead and Tx the packet. | ||
| 488 | */ | ||
| 489 | if (!test_sta_flag(sta, WLAN_STA_PS_STA) && | ||
| 490 | !test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { | ||
| 491 | spin_unlock(&sta->ps_lock); | ||
| 492 | return TX_CONTINUE; | ||
| 493 | } | ||
| 494 | |||
| 481 | if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) { | 495 | if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) { |
| 482 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]); | 496 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]); |
| 483 | ps_dbg(tx->sdata, | 497 | ps_dbg(tx->sdata, |
| @@ -492,6 +506,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
| 492 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 506 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
| 493 | info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS; | 507 | info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS; |
| 494 | skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb); | 508 | skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb); |
| 509 | spin_unlock(&sta->ps_lock); | ||
| 495 | 510 | ||
| 496 | if (!timer_pending(&local->sta_cleanup)) | 511 | if (!timer_pending(&local->sta_cleanup)) |
| 497 | mod_timer(&local->sta_cleanup, | 512 | mod_timer(&local->sta_cleanup, |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 676dc0967f37..b8700d417a9c 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -435,9 +435,8 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local, | |||
| 435 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | 435 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); |
| 436 | } | 436 | } |
| 437 | 437 | ||
| 438 | void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, | 438 | void ieee80211_add_pending_skbs(struct ieee80211_local *local, |
| 439 | struct sk_buff_head *skbs, | 439 | struct sk_buff_head *skbs) |
| 440 | void (*fn)(void *data), void *data) | ||
| 441 | { | 440 | { |
| 442 | struct ieee80211_hw *hw = &local->hw; | 441 | struct ieee80211_hw *hw = &local->hw; |
| 443 | struct sk_buff *skb; | 442 | struct sk_buff *skb; |
| @@ -461,9 +460,6 @@ void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, | |||
| 461 | __skb_queue_tail(&local->pending[queue], skb); | 460 | __skb_queue_tail(&local->pending[queue], skb); |
| 462 | } | 461 | } |
| 463 | 462 | ||
| 464 | if (fn) | ||
| 465 | fn(data); | ||
| 466 | |||
| 467 | for (i = 0; i < hw->queues; i++) | 463 | for (i = 0; i < hw->queues; i++) |
| 468 | __ieee80211_wake_queue(hw, i, | 464 | __ieee80211_wake_queue(hw, i, |
| 469 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD); | 465 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD); |
| @@ -1741,6 +1737,26 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
| 1741 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); | 1737 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); |
| 1742 | 1738 | ||
| 1743 | /* | 1739 | /* |
| 1740 | * Reconfigure sched scan if it was interrupted by FW restart or | ||
| 1741 | * suspend. | ||
| 1742 | */ | ||
| 1743 | mutex_lock(&local->mtx); | ||
| 1744 | sched_scan_sdata = rcu_dereference_protected(local->sched_scan_sdata, | ||
| 1745 | lockdep_is_held(&local->mtx)); | ||
| 1746 | if (sched_scan_sdata && local->sched_scan_req) | ||
| 1747 | /* | ||
| 1748 | * Sched scan stopped, but we don't want to report it. Instead, | ||
| 1749 | * we're trying to reschedule. | ||
| 1750 | */ | ||
| 1751 | if (__ieee80211_request_sched_scan_start(sched_scan_sdata, | ||
| 1752 | local->sched_scan_req)) | ||
| 1753 | sched_scan_stopped = true; | ||
| 1754 | mutex_unlock(&local->mtx); | ||
| 1755 | |||
| 1756 | if (sched_scan_stopped) | ||
| 1757 | cfg80211_sched_scan_stopped(local->hw.wiphy); | ||
| 1758 | |||
| 1759 | /* | ||
| 1744 | * If this is for hw restart things are still running. | 1760 | * If this is for hw restart things are still running. |
| 1745 | * We may want to change that later, however. | 1761 | * We may want to change that later, however. |
| 1746 | */ | 1762 | */ |
| @@ -1768,26 +1784,6 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
| 1768 | WARN_ON(1); | 1784 | WARN_ON(1); |
| 1769 | #endif | 1785 | #endif |
| 1770 | 1786 | ||
| 1771 | /* | ||
| 1772 | * Reconfigure sched scan if it was interrupted by FW restart or | ||
| 1773 | * suspend. | ||
| 1774 | */ | ||
| 1775 | mutex_lock(&local->mtx); | ||
| 1776 | sched_scan_sdata = rcu_dereference_protected(local->sched_scan_sdata, | ||
| 1777 | lockdep_is_held(&local->mtx)); | ||
| 1778 | if (sched_scan_sdata && local->sched_scan_req) | ||
| 1779 | /* | ||
| 1780 | * Sched scan stopped, but we don't want to report it. Instead, | ||
| 1781 | * we're trying to reschedule. | ||
| 1782 | */ | ||
| 1783 | if (__ieee80211_request_sched_scan_start(sched_scan_sdata, | ||
| 1784 | local->sched_scan_req)) | ||
| 1785 | sched_scan_stopped = true; | ||
| 1786 | mutex_unlock(&local->mtx); | ||
| 1787 | |||
| 1788 | if (sched_scan_stopped) | ||
| 1789 | cfg80211_sched_scan_stopped(local->hw.wiphy); | ||
| 1790 | |||
| 1791 | return 0; | 1787 | return 0; |
| 1792 | } | 1788 | } |
| 1793 | 1789 | ||
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 21211c60ca98..d51422c778de 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
| @@ -154,6 +154,11 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, | |||
| 154 | return IEEE80211_AC_BE; | 154 | return IEEE80211_AC_BE; |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | if (skb->protocol == sdata->control_port_protocol) { | ||
| 158 | skb->priority = 7; | ||
| 159 | return ieee80211_downgrade_queue(sdata, skb); | ||
| 160 | } | ||
| 161 | |||
| 157 | /* use the data classifier to determine what 802.1d tag the | 162 | /* use the data classifier to determine what 802.1d tag the |
| 158 | * data frame has */ | 163 | * data frame has */ |
| 159 | rcu_read_lock(); | 164 | rcu_read_lock(); |
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index 46bda010bf11..56db888b1cd5 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c | |||
| @@ -301,7 +301,7 @@ static int nci_open_device(struct nci_dev *ndev) | |||
| 301 | rc = __nci_request(ndev, nci_reset_req, 0, | 301 | rc = __nci_request(ndev, nci_reset_req, 0, |
| 302 | msecs_to_jiffies(NCI_RESET_TIMEOUT)); | 302 | msecs_to_jiffies(NCI_RESET_TIMEOUT)); |
| 303 | 303 | ||
| 304 | if (ndev->ops->setup(ndev)) | 304 | if (ndev->ops->setup) |
| 305 | ndev->ops->setup(ndev); | 305 | ndev->ops->setup(ndev); |
| 306 | 306 | ||
| 307 | if (!rc) { | 307 | if (!rc) { |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 9b897fca7487..4c50c21d6f52 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
| @@ -1700,7 +1700,7 @@ static void reg_process_hint(struct regulatory_request *reg_request) | |||
| 1700 | return; | 1700 | return; |
| 1701 | case NL80211_REGDOM_SET_BY_USER: | 1701 | case NL80211_REGDOM_SET_BY_USER: |
| 1702 | treatment = reg_process_hint_user(reg_request); | 1702 | treatment = reg_process_hint_user(reg_request); |
| 1703 | if (treatment == REG_REQ_OK || | 1703 | if (treatment == REG_REQ_IGNORE || |
| 1704 | treatment == REG_REQ_ALREADY_SET) | 1704 | treatment == REG_REQ_ALREADY_SET) |
| 1705 | return; | 1705 | return; |
| 1706 | schedule_delayed_work(®_timeout, msecs_to_jiffies(3142)); | 1706 | schedule_delayed_work(®_timeout, msecs_to_jiffies(3142)); |
