| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764 |
- --- a/net/mac80211/agg-rx.c
- +++ b/net/mac80211/agg-rx.c
- @@ -204,6 +204,8 @@ static void ieee80211_send_addba_resp(st
- memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
- else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
- memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
- + else if (sdata->vif.type == NL80211_IFTYPE_WDS)
- + memcpy(mgmt->bssid, da, ETH_ALEN);
-
- mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_ACTION);
- --- a/net/mac80211/agg-tx.c
- +++ b/net/mac80211/agg-tx.c
- @@ -81,7 +81,8 @@ static void ieee80211_send_addba_request
- memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
- if (sdata->vif.type == NL80211_IFTYPE_AP ||
- sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
- - sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
- + sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
- + sdata->vif.type == NL80211_IFTYPE_WDS)
- memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
- else if (sdata->vif.type == NL80211_IFTYPE_STATION)
- memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
- @@ -527,6 +528,7 @@ int ieee80211_start_tx_ba_session(struct
- sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
- sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
- sdata->vif.type != NL80211_IFTYPE_AP &&
- + sdata->vif.type != NL80211_IFTYPE_WDS &&
- sdata->vif.type != NL80211_IFTYPE_ADHOC)
- return -EINVAL;
-
- --- a/net/mac80211/debugfs_sta.c
- +++ b/net/mac80211/debugfs_sta.c
- @@ -66,11 +66,11 @@ static ssize_t sta_flags_read(struct fil
- test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : ""
-
- int res = scnprintf(buf, sizeof(buf),
- - "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
- + "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
- TEST(AUTH), TEST(ASSOC), TEST(PS_STA),
- TEST(PS_DRIVER), TEST(AUTHORIZED),
- TEST(SHORT_PREAMBLE),
- - TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT),
- + TEST(WME), TEST(CLEAR_PS_FILT),
- TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL),
- TEST(UAPSD), TEST(SP), TEST(TDLS_PEER),
- TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT),
- --- a/net/mac80211/iface.c
- +++ b/net/mac80211/iface.c
- @@ -463,7 +463,6 @@ int ieee80211_do_open(struct wireless_de
- struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
- struct net_device *dev = wdev->netdev;
- struct ieee80211_local *local = sdata->local;
- - struct sta_info *sta;
- u32 changed = 0;
- int res;
- u32 hw_reconf_flags = 0;
- @@ -629,30 +628,8 @@ int ieee80211_do_open(struct wireless_de
-
- set_bit(SDATA_STATE_RUNNING, &sdata->state);
-
- - if (sdata->vif.type == NL80211_IFTYPE_WDS) {
- - /* Create STA entry for the WDS peer */
- - sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
- - GFP_KERNEL);
- - if (!sta) {
- - res = -ENOMEM;
- - goto err_del_interface;
- - }
- -
- - sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
- - sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
- - sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
- -
- - res = sta_info_insert(sta);
- - if (res) {
- - /* STA has been freed */
- - goto err_del_interface;
- - }
- -
- - rate_control_rate_init(sta);
- - netif_carrier_on(dev);
- - } else if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) {
- + if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE)
- rcu_assign_pointer(local->p2p_sdata, sdata);
- - }
-
- /*
- * set_multicast_list will be invoked by the networking core
- @@ -1116,6 +1093,74 @@ static void ieee80211_if_setup(struct ne
- dev->destructor = free_netdev;
- }
-
- +static void ieee80211_wds_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
- + struct sk_buff *skb)
- +{
- + struct ieee80211_local *local = sdata->local;
- + struct ieee80211_rx_status *rx_status;
- + struct ieee802_11_elems elems;
- + struct ieee80211_mgmt *mgmt;
- + struct sta_info *sta;
- + size_t baselen;
- + u32 rates = 0;
- + u16 stype;
- + bool new = false;
- + enum ieee80211_band band;
- + struct ieee80211_supported_band *sband;
- +
- + rx_status = IEEE80211_SKB_RXCB(skb);
- + band = rx_status->band;
- + sband = local->hw.wiphy->bands[band];
- + mgmt = (struct ieee80211_mgmt *) skb->data;
- + stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
- +
- + if (stype != IEEE80211_STYPE_BEACON)
- + return;
- +
- + baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
- + if (baselen > skb->len)
- + return;
- +
- + ieee802_11_parse_elems(mgmt->u.probe_resp.variable,
- + skb->len - baselen, false, &elems);
- +
- + rates = ieee80211_sta_get_rates(local, &elems, band, NULL);
- +
- + rcu_read_lock();
- +
- + sta = sta_info_get(sdata, sdata->u.wds.remote_addr);
- +
- + if (!sta) {
- + rcu_read_unlock();
- + sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
- + GFP_KERNEL);
- + if (!sta)
- + return;
- +
- + new = true;
- + }
- +
- + sta->last_rx = jiffies;
- + sta->sta.supp_rates[band] = rates;
- +
- + if (elems.ht_cap_elem)
- + ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
- + elems.ht_cap_elem, sta);
- +
- + if (elems.wmm_param)
- + set_sta_flag(sta, WLAN_STA_WME);
- +
- + if (new) {
- + sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
- + sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
- + sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
- + rate_control_rate_init(sta);
- + sta_info_insert_rcu(sta);
- + }
- +
- + rcu_read_unlock();
- +}
- +
- static void ieee80211_iface_work(struct work_struct *work)
- {
- struct ieee80211_sub_if_data *sdata =
- @@ -1220,6 +1265,9 @@ static void ieee80211_iface_work(struct
- break;
- ieee80211_mesh_rx_queued_mgmt(sdata, skb);
- break;
- + case NL80211_IFTYPE_WDS:
- + ieee80211_wds_rx_queued_mgmt(sdata, skb);
- + break;
- default:
- WARN(1, "frame for unexpected interface type");
- break;
- --- a/net/mac80211/rc80211_minstrel_ht.c
- +++ b/net/mac80211/rc80211_minstrel_ht.c
- @@ -804,10 +804,18 @@ minstrel_ht_get_rate(void *priv, struct
-
- sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES];
- info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
- + rate->count = 1;
- +
- + if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) {
- + int idx = sample_idx % ARRAY_SIZE(mp->cck_rates);
- + rate->idx = mp->cck_rates[idx];
- + rate->flags = 0;
- + return;
- + }
- +
- rate->idx = sample_idx % MCS_GROUP_RATES +
- (sample_group->streams - 1) * MCS_GROUP_RATES;
- rate->flags = IEEE80211_TX_RC_MCS | sample_group->flags;
- - rate->count = 1;
- }
-
- static void
- --- a/net/mac80211/rx.c
- +++ b/net/mac80211/rx.c
- @@ -2369,6 +2369,7 @@ ieee80211_rx_h_action(struct ieee80211_r
- sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
- sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
- sdata->vif.type != NL80211_IFTYPE_AP &&
- + sdata->vif.type != NL80211_IFTYPE_WDS &&
- sdata->vif.type != NL80211_IFTYPE_ADHOC)
- break;
-
- @@ -2720,14 +2721,15 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
-
- if (!ieee80211_vif_is_mesh(&sdata->vif) &&
- sdata->vif.type != NL80211_IFTYPE_ADHOC &&
- - sdata->vif.type != NL80211_IFTYPE_STATION)
- + sdata->vif.type != NL80211_IFTYPE_STATION &&
- + sdata->vif.type != NL80211_IFTYPE_WDS)
- return RX_DROP_MONITOR;
-
- switch (stype) {
- case cpu_to_le16(IEEE80211_STYPE_AUTH):
- case cpu_to_le16(IEEE80211_STYPE_BEACON):
- case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
- - /* process for all: mesh, mlme, ibss */
- + /* process for all: mesh, mlme, ibss, wds */
- break;
- case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
- case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
- @@ -3059,10 +3061,16 @@ static int prepare_for_handlers(struct i
- }
- break;
- case NL80211_IFTYPE_WDS:
- - if (bssid || !ieee80211_is_data(hdr->frame_control))
- - return 0;
- if (!ether_addr_equal(sdata->u.wds.remote_addr, hdr->addr2))
- return 0;
- +
- + if (ieee80211_is_data(hdr->frame_control) ||
- + ieee80211_is_action(hdr->frame_control)) {
- + if (compare_ether_addr(sdata->vif.addr, hdr->addr1))
- + return 0;
- + } else if (!ieee80211_is_beacon(hdr->frame_control))
- + return 0;
- +
- break;
- case NL80211_IFTYPE_P2P_DEVICE:
- if (!ieee80211_is_public_action(hdr, skb->len) &&
- --- a/net/mac80211/sta_info.h
- +++ b/net/mac80211/sta_info.h
- @@ -32,7 +32,6 @@
- * @WLAN_STA_SHORT_PREAMBLE: Station is capable of receiving short-preamble
- * frames.
- * @WLAN_STA_WME: Station is a QoS-STA.
- - * @WLAN_STA_WDS: Station is one of our WDS peers.
- * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
- * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
- * frame to this station is transmitted.
- @@ -66,7 +65,6 @@ enum ieee80211_sta_info_flags {
- WLAN_STA_AUTHORIZED,
- WLAN_STA_SHORT_PREAMBLE,
- WLAN_STA_WME,
- - WLAN_STA_WDS,
- WLAN_STA_CLEAR_PS_FILT,
- WLAN_STA_MFP,
- WLAN_STA_BLOCK_BA,
- --- a/drivers/net/wireless/ath/ath9k/xmit.c
- +++ b/drivers/net/wireless/ath/ath9k/xmit.c
- @@ -146,6 +146,28 @@ static void ath_set_rates(struct ieee802
- ARRAY_SIZE(bf->rates));
- }
-
- +static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
- + struct sk_buff *skb)
- +{
- + int q;
- +
- + q = skb_get_queue_mapping(skb);
- + if (txq == sc->tx.uapsdq)
- + txq = sc->tx.txq_map[q];
- +
- + if (txq != sc->tx.txq_map[q])
- + return;
- +
- + if (WARN_ON(--txq->pending_frames < 0))
- + txq->pending_frames = 0;
- +
- + if (txq->stopped &&
- + txq->pending_frames < sc->tx.txq_max_pending[q]) {
- + ieee80211_wake_queue(sc->hw, q);
- + txq->stopped = false;
- + }
- +}
- +
- static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
- {
- struct ath_txq *txq = tid->ac->txq;
- @@ -167,6 +189,7 @@ static void ath_tx_flush_tid(struct ath_
- if (!bf) {
- bf = ath_tx_setup_buffer(sc, txq, tid, skb);
- if (!bf) {
- + ath_txq_skb_done(sc, txq, skb);
- ieee80211_free_txskb(sc->hw, skb);
- continue;
- }
- @@ -811,6 +834,7 @@ ath_tx_get_tid_subframe(struct ath_softc
-
- if (!bf) {
- __skb_unlink(skb, &tid->buf_q);
- + ath_txq_skb_done(sc, txq, skb);
- ieee80211_free_txskb(sc->hw, skb);
- continue;
- }
- @@ -1824,6 +1848,7 @@ static void ath_tx_send_ampdu(struct ath
-
- bf = ath_tx_setup_buffer(sc, txq, tid, skb);
- if (!bf) {
- + ath_txq_skb_done(sc, txq, skb);
- ieee80211_free_txskb(sc->hw, skb);
- return;
- }
- @@ -2090,6 +2115,7 @@ int ath_tx_start(struct ieee80211_hw *hw
-
- bf = ath_tx_setup_buffer(sc, txq, tid, skb);
- if (!bf) {
- + ath_txq_skb_done(sc, txq, skb);
- if (txctl->paprd)
- dev_kfree_skb_any(skb);
- else
- @@ -2189,7 +2215,7 @@ static void ath_tx_complete(struct ath_s
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
- - int q, padpos, padsize;
- + int padpos, padsize;
- unsigned long flags;
-
- ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb);
- @@ -2225,21 +2251,7 @@ static void ath_tx_complete(struct ath_s
- spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
-
- __skb_queue_tail(&txq->complete_q, skb);
- -
- - q = skb_get_queue_mapping(skb);
- - if (txq == sc->tx.uapsdq)
- - txq = sc->tx.txq_map[q];
- -
- - if (txq == sc->tx.txq_map[q]) {
- - if (WARN_ON(--txq->pending_frames < 0))
- - txq->pending_frames = 0;
- -
- - if (txq->stopped &&
- - txq->pending_frames < sc->tx.txq_max_pending[q]) {
- - ieee80211_wake_queue(sc->hw, q);
- - txq->stopped = false;
- - }
- - }
- + ath_txq_skb_done(sc, txq, skb);
- }
-
- static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
- --- a/drivers/net/wireless/ath/ath9k/main.c
- +++ b/drivers/net/wireless/ath/ath9k/main.c
- @@ -2094,7 +2094,7 @@ static void ath9k_wow_add_pattern(struct
- {
- struct ath_hw *ah = sc->sc_ah;
- struct ath9k_wow_pattern *wow_pattern = NULL;
- - struct cfg80211_wowlan_trig_pkt_pattern *patterns = wowlan->patterns;
- + struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
- int mask_len;
- s8 i = 0;
-
- --- a/drivers/net/wireless/mwifiex/cfg80211.c
- +++ b/drivers/net/wireless/mwifiex/cfg80211.c
- @@ -2298,8 +2298,7 @@ EXPORT_SYMBOL_GPL(mwifiex_del_virtual_in
-
- #ifdef CONFIG_PM
- static bool
- -mwifiex_is_pattern_supported(struct cfg80211_wowlan_trig_pkt_pattern *pat,
- - s8 *byte_seq)
- +mwifiex_is_pattern_supported(struct cfg80211_pkt_pattern *pat, s8 *byte_seq)
- {
- int j, k, valid_byte_cnt = 0;
- bool dont_care_byte = false;
- --- a/drivers/net/wireless/ti/wlcore/main.c
- +++ b/drivers/net/wireless/ti/wlcore/main.c
- @@ -1315,7 +1315,7 @@ static struct sk_buff *wl12xx_alloc_dumm
-
- #ifdef CONFIG_PM
- static int
- -wl1271_validate_wowlan_pattern(struct cfg80211_wowlan_trig_pkt_pattern *p)
- +wl1271_validate_wowlan_pattern(struct cfg80211_pkt_pattern *p)
- {
- int num_fields = 0, in_field = 0, fields_size = 0;
- int i, pattern_len = 0;
- @@ -1458,9 +1458,9 @@ void wl1271_rx_filter_flatten_fields(str
- * Allocates an RX filter returned through f
- * which needs to be freed using rx_filter_free()
- */
- -static int wl1271_convert_wowlan_pattern_to_rx_filter(
- - struct cfg80211_wowlan_trig_pkt_pattern *p,
- - struct wl12xx_rx_filter **f)
- +static int
- +wl1271_convert_wowlan_pattern_to_rx_filter(struct cfg80211_pkt_pattern *p,
- + struct wl12xx_rx_filter **f)
- {
- int i, j, ret = 0;
- struct wl12xx_rx_filter *filter;
- @@ -1562,7 +1562,7 @@ static int wl1271_configure_wowlan(struc
-
- /* Translate WoWLAN patterns into filters */
- for (i = 0; i < wow->n_patterns; i++) {
- - struct cfg80211_wowlan_trig_pkt_pattern *p;
- + struct cfg80211_pkt_pattern *p;
- struct wl12xx_rx_filter *filter = NULL;
-
- p = &wow->patterns[i];
- --- a/include/net/cfg80211.h
- +++ b/include/net/cfg80211.h
- @@ -1698,7 +1698,7 @@ struct cfg80211_pmksa {
- };
-
- /**
- - * struct cfg80211_wowlan_trig_pkt_pattern - packet pattern
- + * struct cfg80211_pkt_pattern - packet pattern
- * @mask: bitmask where to match pattern and where to ignore bytes,
- * one bit per byte, in same format as nl80211
- * @pattern: bytes to match where bitmask is 1
- @@ -1708,7 +1708,7 @@ struct cfg80211_pmksa {
- * Internal note: @mask and @pattern are allocated in one chunk of
- * memory, free @mask only!
- */
- -struct cfg80211_wowlan_trig_pkt_pattern {
- +struct cfg80211_pkt_pattern {
- u8 *mask, *pattern;
- int pattern_len;
- int pkt_offset;
- @@ -1770,7 +1770,7 @@ struct cfg80211_wowlan {
- bool any, disconnect, magic_pkt, gtk_rekey_failure,
- eap_identity_req, four_way_handshake,
- rfkill_release;
- - struct cfg80211_wowlan_trig_pkt_pattern *patterns;
- + struct cfg80211_pkt_pattern *patterns;
- struct cfg80211_wowlan_tcp *tcp;
- int n_patterns;
- };
- --- a/include/uapi/linux/nl80211.h
- +++ b/include/uapi/linux/nl80211.h
- @@ -3060,11 +3060,11 @@ enum nl80211_tx_power_setting {
- };
-
- /**
- - * enum nl80211_wowlan_packet_pattern_attr - WoWLAN packet pattern attribute
- - * @__NL80211_WOWLAN_PKTPAT_INVALID: invalid number for nested attribute
- - * @NL80211_WOWLAN_PKTPAT_PATTERN: the pattern, values where the mask has
- + * enum nl80211_packet_pattern_attr - packet pattern attribute
- + * @__NL80211_PKTPAT_INVALID: invalid number for nested attribute
- + * @NL80211_PKTPAT_PATTERN: the pattern, values where the mask has
- * a zero bit are ignored
- - * @NL80211_WOWLAN_PKTPAT_MASK: pattern mask, must be long enough to have
- + * @NL80211_PKTPAT_MASK: pattern mask, must be long enough to have
- * a bit for each byte in the pattern. The lowest-order bit corresponds
- * to the first byte of the pattern, but the bytes of the pattern are
- * in a little-endian-like format, i.e. the 9th byte of the pattern
- @@ -3075,23 +3075,23 @@ enum nl80211_tx_power_setting {
- * Note that the pattern matching is done as though frames were not
- * 802.11 frames but 802.3 frames, i.e. the frame is fully unpacked
- * first (including SNAP header unpacking) and then matched.
- - * @NL80211_WOWLAN_PKTPAT_OFFSET: packet offset, pattern is matched after
- + * @NL80211_PKTPAT_OFFSET: packet offset, pattern is matched after
- * these fixed number of bytes of received packet
- - * @NUM_NL80211_WOWLAN_PKTPAT: number of attributes
- - * @MAX_NL80211_WOWLAN_PKTPAT: max attribute number
- + * @NUM_NL80211_PKTPAT: number of attributes
- + * @MAX_NL80211_PKTPAT: max attribute number
- */
- -enum nl80211_wowlan_packet_pattern_attr {
- - __NL80211_WOWLAN_PKTPAT_INVALID,
- - NL80211_WOWLAN_PKTPAT_MASK,
- - NL80211_WOWLAN_PKTPAT_PATTERN,
- - NL80211_WOWLAN_PKTPAT_OFFSET,
- +enum nl80211_packet_pattern_attr {
- + __NL80211_PKTPAT_INVALID,
- + NL80211_PKTPAT_MASK,
- + NL80211_PKTPAT_PATTERN,
- + NL80211_PKTPAT_OFFSET,
-
- - NUM_NL80211_WOWLAN_PKTPAT,
- - MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1,
- + NUM_NL80211_PKTPAT,
- + MAX_NL80211_PKTPAT = NUM_NL80211_PKTPAT - 1,
- };
-
- /**
- - * struct nl80211_wowlan_pattern_support - pattern support information
- + * struct nl80211_pattern_support - packet pattern support information
- * @max_patterns: maximum number of patterns supported
- * @min_pattern_len: minimum length of each pattern
- * @max_pattern_len: maximum length of each pattern
- @@ -3101,13 +3101,22 @@ enum nl80211_wowlan_packet_pattern_attr
- * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED in the
- * capability information given by the kernel to userspace.
- */
- -struct nl80211_wowlan_pattern_support {
- +struct nl80211_pattern_support {
- __u32 max_patterns;
- __u32 min_pattern_len;
- __u32 max_pattern_len;
- __u32 max_pkt_offset;
- } __attribute__((packed));
-
- +/* only for backward compatibility */
- +#define __NL80211_WOWLAN_PKTPAT_INVALID __NL80211_PKTPAT_INVALID
- +#define NL80211_WOWLAN_PKTPAT_MASK NL80211_PKTPAT_MASK
- +#define NL80211_WOWLAN_PKTPAT_PATTERN NL80211_PKTPAT_PATTERN
- +#define NL80211_WOWLAN_PKTPAT_OFFSET NL80211_PKTPAT_OFFSET
- +#define NUM_NL80211_WOWLAN_PKTPAT NUM_NL80211_PKTPAT
- +#define MAX_NL80211_WOWLAN_PKTPAT MAX_NL80211_PKTPAT
- +#define nl80211_wowlan_pattern_support nl80211_pattern_support
- +
- /**
- * enum nl80211_wowlan_triggers - WoWLAN trigger definitions
- * @__NL80211_WOWLAN_TRIG_INVALID: invalid number for nested attributes
- @@ -3127,7 +3136,7 @@ struct nl80211_wowlan_pattern_support {
- * pattern matching is done after the packet is converted to the MSDU.
- *
- * In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute
- - * carrying a &struct nl80211_wowlan_pattern_support.
- + * carrying a &struct nl80211_pattern_support.
- *
- * When reporting wakeup. it is a u32 attribute containing the 0-based
- * index of the pattern that caused the wakeup, in the patterns passed
- @@ -3284,7 +3293,7 @@ struct nl80211_wowlan_tcp_data_token_fea
- * @NL80211_WOWLAN_TCP_WAKE_PAYLOAD: wake packet payload, for advertising a
- * u32 attribute holding the maximum length
- * @NL80211_WOWLAN_TCP_WAKE_MASK: Wake packet payload mask, not used for
- - * feature advertising. The mask works like @NL80211_WOWLAN_PKTPAT_MASK
- + * feature advertising. The mask works like @NL80211_PKTPAT_MASK
- * but on the TCP payload only.
- * @NUM_NL80211_WOWLAN_TCP: number of TCP attributes
- * @MAX_NL80211_WOWLAN_TCP: highest attribute number
- --- a/net/mac80211/mesh_ps.c
- +++ b/net/mac80211/mesh_ps.c
- @@ -229,6 +229,10 @@ void ieee80211_mps_sta_status_update(str
- enum nl80211_mesh_power_mode pm;
- bool do_buffer;
-
- + /* For non-assoc STA, prevent buffering or frame transmission */
- + if (sta->sta_state < IEEE80211_STA_ASSOC)
- + return;
- +
- /*
- * use peer-specific power mode if peering is established and the
- * peer's power mode is known
- --- a/net/wireless/nl80211.c
- +++ b/net/wireless/nl80211.c
- @@ -974,7 +974,7 @@ static int nl80211_send_wowlan(struct sk
- return -ENOBUFS;
-
- if (dev->wiphy.wowlan->n_patterns) {
- - struct nl80211_wowlan_pattern_support pat = {
- + struct nl80211_pattern_support pat = {
- .max_patterns = dev->wiphy.wowlan->n_patterns,
- .min_pattern_len = dev->wiphy.wowlan->pattern_min_len,
- .max_pattern_len = dev->wiphy.wowlan->pattern_max_len,
- @@ -1568,8 +1568,10 @@ static int nl80211_dump_wiphy(struct sk_
- rtnl_lock();
- if (!state) {
- state = kzalloc(sizeof(*state), GFP_KERNEL);
- - if (!state)
- + if (!state) {
- + rtnl_unlock();
- return -ENOMEM;
- + }
- state->filter_wiphy = -1;
- ret = nl80211_dump_wiphy_parse(skb, cb, state);
- if (ret) {
- @@ -6615,12 +6617,14 @@ EXPORT_SYMBOL(cfg80211_testmode_alloc_ev
-
- void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp)
- {
- + struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
- void *hdr = ((void **)skb->cb)[1];
- struct nlattr *data = ((void **)skb->cb)[2];
-
- nla_nest_end(skb, data);
- genlmsg_end(skb, hdr);
- - genlmsg_multicast(skb, 0, nl80211_testmode_mcgrp.id, gfp);
- + genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), skb, 0,
- + nl80211_testmode_mcgrp.id, gfp);
- }
- EXPORT_SYMBOL(cfg80211_testmode_event);
- #endif
- @@ -7593,12 +7597,11 @@ static int nl80211_send_wowlan_patterns(
- if (!nl_pat)
- return -ENOBUFS;
- pat_len = wowlan->patterns[i].pattern_len;
- - if (nla_put(msg, NL80211_WOWLAN_PKTPAT_MASK,
- - DIV_ROUND_UP(pat_len, 8),
- + if (nla_put(msg, NL80211_PKTPAT_MASK, DIV_ROUND_UP(pat_len, 8),
- wowlan->patterns[i].mask) ||
- - nla_put(msg, NL80211_WOWLAN_PKTPAT_PATTERN,
- - pat_len, wowlan->patterns[i].pattern) ||
- - nla_put_u32(msg, NL80211_WOWLAN_PKTPAT_OFFSET,
- + nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
- + wowlan->patterns[i].pattern) ||
- + nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
- wowlan->patterns[i].pkt_offset))
- return -ENOBUFS;
- nla_nest_end(msg, nl_pat);
- @@ -7939,7 +7942,7 @@ static int nl80211_set_wowlan(struct sk_
- struct nlattr *pat;
- int n_patterns = 0;
- int rem, pat_len, mask_len, pkt_offset;
- - struct nlattr *pat_tb[NUM_NL80211_WOWLAN_PKTPAT];
- + struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
-
- nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
- rem)
- @@ -7958,26 +7961,25 @@ static int nl80211_set_wowlan(struct sk_
-
- nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
- rem) {
- - nla_parse(pat_tb, MAX_NL80211_WOWLAN_PKTPAT,
- - nla_data(pat), nla_len(pat), NULL);
- + nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
- + nla_len(pat), NULL);
- err = -EINVAL;
- - if (!pat_tb[NL80211_WOWLAN_PKTPAT_MASK] ||
- - !pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN])
- + if (!pat_tb[NL80211_PKTPAT_MASK] ||
- + !pat_tb[NL80211_PKTPAT_PATTERN])
- goto error;
- - pat_len = nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]);
- + pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
- mask_len = DIV_ROUND_UP(pat_len, 8);
- - if (nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]) !=
- - mask_len)
- + if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
- goto error;
- if (pat_len > wowlan->pattern_max_len ||
- pat_len < wowlan->pattern_min_len)
- goto error;
-
- - if (!pat_tb[NL80211_WOWLAN_PKTPAT_OFFSET])
- + if (!pat_tb[NL80211_PKTPAT_OFFSET])
- pkt_offset = 0;
- else
- pkt_offset = nla_get_u32(
- - pat_tb[NL80211_WOWLAN_PKTPAT_OFFSET]);
- + pat_tb[NL80211_PKTPAT_OFFSET]);
- if (pkt_offset > wowlan->max_pkt_offset)
- goto error;
- new_triggers.patterns[i].pkt_offset = pkt_offset;
- @@ -7991,11 +7993,11 @@ static int nl80211_set_wowlan(struct sk_
- new_triggers.patterns[i].pattern =
- new_triggers.patterns[i].mask + mask_len;
- memcpy(new_triggers.patterns[i].mask,
- - nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]),
- + nla_data(pat_tb[NL80211_PKTPAT_MASK]),
- mask_len);
- new_triggers.patterns[i].pattern_len = pat_len;
- memcpy(new_triggers.patterns[i].pattern,
- - nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]),
- + nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
- pat_len);
- i++;
- }
- @@ -10066,7 +10068,8 @@ void cfg80211_mgmt_tx_status(struct wire
-
- genlmsg_end(msg, hdr);
-
- - genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp);
- + genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
- + nl80211_mlme_mcgrp.id, gfp);
- return;
-
- nla_put_failure:
- --- a/net/wireless/reg.c
- +++ b/net/wireless/reg.c
- @@ -2279,7 +2279,9 @@ void wiphy_regulatory_deregister(struct
- static void reg_timeout_work(struct work_struct *work)
- {
- REG_DBG_PRINT("Timeout while waiting for CRDA to reply, restoring regulatory settings\n");
- + rtnl_lock();
- restore_regulatory_settings(true);
- + rtnl_unlock();
- }
-
- int __init regulatory_init(void)
- --- a/net/wireless/sme.c
- +++ b/net/wireless/sme.c
- @@ -34,8 +34,10 @@ struct cfg80211_conn {
- CFG80211_CONN_SCAN_AGAIN,
- CFG80211_CONN_AUTHENTICATE_NEXT,
- CFG80211_CONN_AUTHENTICATING,
- + CFG80211_CONN_AUTH_FAILED,
- CFG80211_CONN_ASSOCIATE_NEXT,
- CFG80211_CONN_ASSOCIATING,
- + CFG80211_CONN_ASSOC_FAILED,
- CFG80211_CONN_DEAUTH,
- CFG80211_CONN_CONNECTED,
- } state;
- @@ -164,6 +166,8 @@ static int cfg80211_conn_do_work(struct
- NULL, 0,
- params->key, params->key_len,
- params->key_idx, NULL, 0);
- + case CFG80211_CONN_AUTH_FAILED:
- + return -ENOTCONN;
- case CFG80211_CONN_ASSOCIATE_NEXT:
- BUG_ON(!rdev->ops->assoc);
- wdev->conn->state = CFG80211_CONN_ASSOCIATING;
- @@ -188,10 +192,17 @@ static int cfg80211_conn_do_work(struct
- WLAN_REASON_DEAUTH_LEAVING,
- false);
- return err;
- + case CFG80211_CONN_ASSOC_FAILED:
- + cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
- + NULL, 0,
- + WLAN_REASON_DEAUTH_LEAVING, false);
- + return -ENOTCONN;
- case CFG80211_CONN_DEAUTH:
- cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
- NULL, 0,
- WLAN_REASON_DEAUTH_LEAVING, false);
- + /* free directly, disconnected event already sent */
- + cfg80211_sme_free(wdev);
- return 0;
- default:
- return 0;
- @@ -371,7 +382,7 @@ bool cfg80211_sme_rx_assoc_resp(struct w
- return true;
- }
-
- - wdev->conn->state = CFG80211_CONN_DEAUTH;
- + wdev->conn->state = CFG80211_CONN_ASSOC_FAILED;
- schedule_work(&rdev->conn_work);
- return false;
- }
- @@ -383,7 +394,13 @@ void cfg80211_sme_deauth(struct wireless
-
- void cfg80211_sme_auth_timeout(struct wireless_dev *wdev)
- {
- - cfg80211_sme_free(wdev);
- + struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
- +
- + if (!wdev->conn)
- + return;
- +
- + wdev->conn->state = CFG80211_CONN_AUTH_FAILED;
- + schedule_work(&rdev->conn_work);
- }
-
- void cfg80211_sme_disassoc(struct wireless_dev *wdev)
- @@ -399,7 +416,13 @@ void cfg80211_sme_disassoc(struct wirele
-
- void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev)
- {
- - cfg80211_sme_disassoc(wdev);
- + struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
- +
- + if (!wdev->conn)
- + return;
- +
- + wdev->conn->state = CFG80211_CONN_ASSOC_FAILED;
- + schedule_work(&rdev->conn_work);
- }
-
- static int cfg80211_sme_connect(struct wireless_dev *wdev,
|