diff options
author | David S. Miller <davem@davemloft.net> | 2010-10-04 01:09:32 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-04 01:09:32 -0400 |
commit | 72829071269b19381173a13ea1b2ca2f4f9d4cec (patch) | |
tree | a5445625189ba1be6bb8a38a0854452fbfef136f /net | |
parent | 10651db75a94c54a34bbf85fbee334d1114da3fb (diff) | |
parent | 41f4a6f71fe33faa7971c173c263fb431fe987fe (diff) |
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/debugfs.c | 1 | ||||
-rw-r--r-- | net/mac80211/debugfs_netdev.c | 3 | ||||
-rw-r--r-- | net/mac80211/debugfs_sta.c | 2 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 43 | ||||
-rw-r--r-- | net/mac80211/main.c | 3 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 16 | ||||
-rw-r--r-- | net/mac80211/rx.c | 291 | ||||
-rw-r--r-- | net/mac80211/scan.c | 3 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 15 | ||||
-rw-r--r-- | net/mac80211/status.c | 1 | ||||
-rw-r--r-- | net/mac80211/util.c | 47 | ||||
-rw-r--r-- | net/mac80211/wpa.c | 2 | ||||
-rw-r--r-- | net/wireless/ibss.c | 19 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 20 |
14 files changed, 272 insertions, 194 deletions
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index e81ef4e8cb32..ebd5b69f562e 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -368,7 +368,6 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
368 | if (!phyd) | 368 | if (!phyd) |
369 | return; | 369 | return; |
370 | 370 | ||
371 | local->debugfs.stations = debugfs_create_dir("stations", phyd); | ||
372 | local->debugfs.keys = debugfs_create_dir("keys", phyd); | 371 | local->debugfs.keys = debugfs_create_dir("keys", phyd); |
373 | 372 | ||
374 | DEBUGFS_ADD(frequency); | 373 | DEBUGFS_ADD(frequency); |
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 20b2998fa0ed..3e12430591b7 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -409,6 +409,9 @@ void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata) | |||
409 | sprintf(buf, "netdev:%s", sdata->name); | 409 | sprintf(buf, "netdev:%s", sdata->name); |
410 | sdata->debugfs.dir = debugfs_create_dir(buf, | 410 | sdata->debugfs.dir = debugfs_create_dir(buf, |
411 | sdata->local->hw.wiphy->debugfsdir); | 411 | sdata->local->hw.wiphy->debugfsdir); |
412 | if (sdata->debugfs.dir) | ||
413 | sdata->debugfs.subdir_stations = debugfs_create_dir("stations", | ||
414 | sdata->debugfs.dir); | ||
412 | add_files(sdata); | 415 | add_files(sdata); |
413 | } | 416 | } |
414 | 417 | ||
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 76839d4dfaac..6b7ff9fb4604 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -300,7 +300,7 @@ STA_OPS(ht_capa); | |||
300 | 300 | ||
301 | void ieee80211_sta_debugfs_add(struct sta_info *sta) | 301 | void ieee80211_sta_debugfs_add(struct sta_info *sta) |
302 | { | 302 | { |
303 | struct dentry *stations_dir = sta->local->debugfs.stations; | 303 | struct dentry *stations_dir = sta->sdata->debugfs.subdir_stations; |
304 | u8 mac[3*ETH_ALEN]; | 304 | u8 mac[3*ETH_ALEN]; |
305 | 305 | ||
306 | sta->debugfs.add_has_run = true; | 306 | sta->debugfs.add_has_run = true; |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 9346a6b0f400..945fbf29719d 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -159,13 +159,37 @@ typedef unsigned __bitwise__ ieee80211_rx_result; | |||
159 | #define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u) | 159 | #define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u) |
160 | #define RX_QUEUED ((__force ieee80211_rx_result) 3u) | 160 | #define RX_QUEUED ((__force ieee80211_rx_result) 3u) |
161 | 161 | ||
162 | #define IEEE80211_RX_IN_SCAN BIT(0) | 162 | /** |
163 | /* frame is destined to interface currently processed (incl. multicast frames) */ | 163 | * enum ieee80211_packet_rx_flags - packet RX flags |
164 | #define IEEE80211_RX_RA_MATCH BIT(1) | 164 | * @IEEE80211_RX_RA_MATCH: frame is destined to interface currently processed |
165 | #define IEEE80211_RX_AMSDU BIT(2) | 165 | * (incl. multicast frames) |
166 | #define IEEE80211_RX_FRAGMENTED BIT(3) | 166 | * @IEEE80211_RX_IN_SCAN: received while scanning |
167 | #define IEEE80211_MALFORMED_ACTION_FRM BIT(4) | 167 | * @IEEE80211_RX_FRAGMENTED: fragmented frame |
168 | /* only add flags here that do not change with subframes of an aMPDU */ | 168 | * @IEEE80211_RX_AMSDU: a-MSDU packet |
169 | * @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed | ||
170 | * | ||
171 | * These are per-frame flags that are attached to a frame in the | ||
172 | * @rx_flags field of &struct ieee80211_rx_status. | ||
173 | */ | ||
174 | enum ieee80211_packet_rx_flags { | ||
175 | IEEE80211_RX_IN_SCAN = BIT(0), | ||
176 | IEEE80211_RX_RA_MATCH = BIT(1), | ||
177 | IEEE80211_RX_FRAGMENTED = BIT(2), | ||
178 | IEEE80211_RX_AMSDU = BIT(3), | ||
179 | IEEE80211_RX_MALFORMED_ACTION_FRM = BIT(4), | ||
180 | }; | ||
181 | |||
182 | /** | ||
183 | * enum ieee80211_rx_flags - RX data flags | ||
184 | * | ||
185 | * @IEEE80211_RX_CMNTR: received on cooked monitor already | ||
186 | * | ||
187 | * These flags are used across handling multiple interfaces | ||
188 | * for a single frame. | ||
189 | */ | ||
190 | enum ieee80211_rx_flags { | ||
191 | IEEE80211_RX_CMNTR = BIT(0), | ||
192 | }; | ||
169 | 193 | ||
170 | struct ieee80211_rx_data { | 194 | struct ieee80211_rx_data { |
171 | struct sk_buff *skb; | 195 | struct sk_buff *skb; |
@@ -564,6 +588,7 @@ struct ieee80211_sub_if_data { | |||
564 | #ifdef CONFIG_MAC80211_DEBUGFS | 588 | #ifdef CONFIG_MAC80211_DEBUGFS |
565 | struct { | 589 | struct { |
566 | struct dentry *dir; | 590 | struct dentry *dir; |
591 | struct dentry *subdir_stations; | ||
567 | struct dentry *default_key; | 592 | struct dentry *default_key; |
568 | struct dentry *default_mgmt_key; | 593 | struct dentry *default_mgmt_key; |
569 | } debugfs; | 594 | } debugfs; |
@@ -899,7 +924,6 @@ struct ieee80211_local { | |||
899 | #ifdef CONFIG_MAC80211_DEBUGFS | 924 | #ifdef CONFIG_MAC80211_DEBUGFS |
900 | struct local_debugfsdentries { | 925 | struct local_debugfsdentries { |
901 | struct dentry *rcdir; | 926 | struct dentry *rcdir; |
902 | struct dentry *stations; | ||
903 | struct dentry *keys; | 927 | struct dentry *keys; |
904 | } debugfs; | 928 | } debugfs; |
905 | #endif | 929 | #endif |
@@ -1256,7 +1280,8 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | |||
1256 | const u8 *key, u8 key_len, u8 key_idx); | 1280 | const u8 *key, u8 key_len, u8 key_idx); |
1257 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | 1281 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, |
1258 | const u8 *ie, size_t ie_len, | 1282 | const u8 *ie, size_t ie_len, |
1259 | enum ieee80211_band band); | 1283 | enum ieee80211_band band, u32 rate_mask, |
1284 | u8 channel); | ||
1260 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | 1285 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, |
1261 | const u8 *ssid, size_t ssid_len, | 1286 | const u8 *ssid, size_t ssid_len, |
1262 | const u8 *ie, size_t ie_len); | 1287 | const u8 *ie, size_t ie_len); |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index fda97bb0018b..db341a99c7c7 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -110,7 +110,8 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
110 | chan = scan_chan; | 110 | chan = scan_chan; |
111 | channel_type = NL80211_CHAN_NO_HT; | 111 | channel_type = NL80211_CHAN_NO_HT; |
112 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; | 112 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; |
113 | } else if (local->tmp_channel) { | 113 | } else if (local->tmp_channel && |
114 | local->oper_channel != local->tmp_channel) { | ||
114 | chan = scan_chan = local->tmp_channel; | 115 | chan = scan_chan = local->tmp_channel; |
115 | channel_type = local->tmp_channel_type; | 116 | channel_type = local->tmp_channel_type; |
116 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; | 117 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 8b733cf6f3ea..77913a15f537 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -880,14 +880,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
880 | sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | | 880 | sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | |
881 | IEEE80211_STA_BEACON_POLL); | 881 | IEEE80211_STA_BEACON_POLL); |
882 | 882 | ||
883 | /* | ||
884 | * Always handle WMM once after association regardless | ||
885 | * of the first value the AP uses. Setting -1 here has | ||
886 | * that effect because the AP values is an unsigned | ||
887 | * 4-bit value. | ||
888 | */ | ||
889 | sdata->u.mgd.wmm_last_param_set = -1; | ||
890 | |||
891 | ieee80211_led_assoc(local, 1); | 883 | ieee80211_led_assoc(local, 1); |
892 | 884 | ||
893 | if (local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) | 885 | if (local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) |
@@ -1367,6 +1359,14 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, | |||
1367 | return false; | 1359 | return false; |
1368 | } | 1360 | } |
1369 | 1361 | ||
1362 | /* | ||
1363 | * Always handle WMM once after association regardless | ||
1364 | * of the first value the AP uses. Setting -1 here has | ||
1365 | * that effect because the AP values is an unsigned | ||
1366 | * 4-bit value. | ||
1367 | */ | ||
1368 | ifmgd->wmm_last_param_set = -1; | ||
1369 | |||
1370 | if (elems.wmm_param) | 1370 | if (elems.wmm_param) |
1371 | ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, | 1371 | ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, |
1372 | elems.wmm_param_len); | 1372 | elems.wmm_param_len); |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index c0368152b721..0b0e83ebe3d5 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -315,6 +315,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
315 | static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) | 315 | static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) |
316 | { | 316 | { |
317 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 317 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
318 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
318 | int tid; | 319 | int tid; |
319 | 320 | ||
320 | /* does the frame have a qos control field? */ | 321 | /* does the frame have a qos control field? */ |
@@ -323,9 +324,7 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) | |||
323 | /* frame has qos control */ | 324 | /* frame has qos control */ |
324 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; | 325 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; |
325 | if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) | 326 | if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) |
326 | rx->flags |= IEEE80211_RX_AMSDU; | 327 | status->rx_flags |= IEEE80211_RX_AMSDU; |
327 | else | ||
328 | rx->flags &= ~IEEE80211_RX_AMSDU; | ||
329 | } else { | 328 | } else { |
330 | /* | 329 | /* |
331 | * IEEE 802.11-2007, 7.1.3.4.1 ("Sequence Number field"): | 330 | * IEEE 802.11-2007, 7.1.3.4.1 ("Sequence Number field"): |
@@ -387,26 +386,25 @@ static ieee80211_rx_result debug_noinline | |||
387 | ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) | 386 | ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) |
388 | { | 387 | { |
389 | struct ieee80211_local *local = rx->local; | 388 | struct ieee80211_local *local = rx->local; |
389 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
390 | struct sk_buff *skb = rx->skb; | 390 | struct sk_buff *skb = rx->skb; |
391 | 391 | ||
392 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning))) | 392 | if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN))) |
393 | return RX_CONTINUE; | ||
394 | |||
395 | if (test_bit(SCAN_HW_SCANNING, &local->scanning)) | ||
393 | return ieee80211_scan_rx(rx->sdata, skb); | 396 | return ieee80211_scan_rx(rx->sdata, skb); |
394 | 397 | ||
395 | if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning) && | 398 | if (test_bit(SCAN_SW_SCANNING, &local->scanning)) { |
396 | (rx->flags & IEEE80211_RX_IN_SCAN))) { | ||
397 | /* drop all the other packets during a software scan anyway */ | 399 | /* drop all the other packets during a software scan anyway */ |
398 | if (ieee80211_scan_rx(rx->sdata, skb) != RX_QUEUED) | 400 | if (ieee80211_scan_rx(rx->sdata, skb) != RX_QUEUED) |
399 | dev_kfree_skb(skb); | 401 | dev_kfree_skb(skb); |
400 | return RX_QUEUED; | 402 | return RX_QUEUED; |
401 | } | 403 | } |
402 | 404 | ||
403 | if (unlikely(rx->flags & IEEE80211_RX_IN_SCAN)) { | 405 | /* scanning finished during invoking of handlers */ |
404 | /* scanning finished during invoking of handlers */ | 406 | I802_DEBUG_INC(local->rx_handlers_drop_passive_scan); |
405 | I802_DEBUG_INC(local->rx_handlers_drop_passive_scan); | 407 | return RX_DROP_UNUSABLE; |
406 | return RX_DROP_UNUSABLE; | ||
407 | } | ||
408 | |||
409 | return RX_CONTINUE; | ||
410 | } | 408 | } |
411 | 409 | ||
412 | 410 | ||
@@ -785,13 +783,14 @@ static ieee80211_rx_result debug_noinline | |||
785 | ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | 783 | ieee80211_rx_h_check(struct ieee80211_rx_data *rx) |
786 | { | 784 | { |
787 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 785 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
786 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
788 | 787 | ||
789 | /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ | 788 | /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ |
790 | if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { | 789 | if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { |
791 | if (unlikely(ieee80211_has_retry(hdr->frame_control) && | 790 | if (unlikely(ieee80211_has_retry(hdr->frame_control) && |
792 | rx->sta->last_seq_ctrl[rx->queue] == | 791 | rx->sta->last_seq_ctrl[rx->queue] == |
793 | hdr->seq_ctrl)) { | 792 | hdr->seq_ctrl)) { |
794 | if (rx->flags & IEEE80211_RX_RA_MATCH) { | 793 | if (status->rx_flags & IEEE80211_RX_RA_MATCH) { |
795 | rx->local->dot11FrameDuplicateCount++; | 794 | rx->local->dot11FrameDuplicateCount++; |
796 | rx->sta->num_duplicates++; | 795 | rx->sta->num_duplicates++; |
797 | } | 796 | } |
@@ -824,7 +823,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
824 | if ((!ieee80211_has_fromds(hdr->frame_control) && | 823 | if ((!ieee80211_has_fromds(hdr->frame_control) && |
825 | !ieee80211_has_tods(hdr->frame_control) && | 824 | !ieee80211_has_tods(hdr->frame_control) && |
826 | ieee80211_is_data(hdr->frame_control)) || | 825 | ieee80211_is_data(hdr->frame_control)) || |
827 | !(rx->flags & IEEE80211_RX_RA_MATCH)) { | 826 | !(status->rx_flags & IEEE80211_RX_RA_MATCH)) { |
828 | /* Drop IBSS frames and frames for other hosts | 827 | /* Drop IBSS frames and frames for other hosts |
829 | * silently. */ | 828 | * silently. */ |
830 | return RX_DROP_MONITOR; | 829 | return RX_DROP_MONITOR; |
@@ -881,7 +880,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
881 | * No point in finding a key and decrypting if the frame is neither | 880 | * No point in finding a key and decrypting if the frame is neither |
882 | * addressed to us nor a multicast frame. | 881 | * addressed to us nor a multicast frame. |
883 | */ | 882 | */ |
884 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 883 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) |
885 | return RX_CONTINUE; | 884 | return RX_CONTINUE; |
886 | 885 | ||
887 | /* start without a key */ | 886 | /* start without a key */ |
@@ -1114,7 +1113,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
1114 | sta->last_rx = jiffies; | 1113 | sta->last_rx = jiffies; |
1115 | } | 1114 | } |
1116 | 1115 | ||
1117 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 1116 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) |
1118 | return RX_CONTINUE; | 1117 | return RX_CONTINUE; |
1119 | 1118 | ||
1120 | if (rx->sdata->vif.type == NL80211_IFTYPE_STATION) | 1119 | if (rx->sdata->vif.type == NL80211_IFTYPE_STATION) |
@@ -1271,6 +1270,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1271 | unsigned int frag, seq; | 1270 | unsigned int frag, seq; |
1272 | struct ieee80211_fragment_entry *entry; | 1271 | struct ieee80211_fragment_entry *entry; |
1273 | struct sk_buff *skb; | 1272 | struct sk_buff *skb; |
1273 | struct ieee80211_rx_status *status; | ||
1274 | 1274 | ||
1275 | hdr = (struct ieee80211_hdr *)rx->skb->data; | 1275 | hdr = (struct ieee80211_hdr *)rx->skb->data; |
1276 | fc = hdr->frame_control; | 1276 | fc = hdr->frame_control; |
@@ -1370,7 +1370,8 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1370 | } | 1370 | } |
1371 | 1371 | ||
1372 | /* Complete frame has been reassembled - process it now */ | 1372 | /* Complete frame has been reassembled - process it now */ |
1373 | rx->flags |= IEEE80211_RX_FRAGMENTED; | 1373 | status = IEEE80211_SKB_RXCB(rx->skb); |
1374 | status->rx_flags |= IEEE80211_RX_FRAGMENTED; | ||
1374 | 1375 | ||
1375 | out: | 1376 | out: |
1376 | if (rx->sta) | 1377 | if (rx->sta) |
@@ -1387,9 +1388,10 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
1387 | { | 1388 | { |
1388 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 1389 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1389 | __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control; | 1390 | __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control; |
1391 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
1390 | 1392 | ||
1391 | if (likely(!rx->sta || !ieee80211_is_pspoll(fc) || | 1393 | if (likely(!rx->sta || !ieee80211_is_pspoll(fc) || |
1392 | !(rx->flags & IEEE80211_RX_RA_MATCH))) | 1394 | !(status->rx_flags & IEEE80211_RX_RA_MATCH))) |
1393 | return RX_CONTINUE; | 1395 | return RX_CONTINUE; |
1394 | 1396 | ||
1395 | if ((sdata->vif.type != NL80211_IFTYPE_AP) && | 1397 | if ((sdata->vif.type != NL80211_IFTYPE_AP) && |
@@ -1550,6 +1552,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1550 | struct sk_buff *skb, *xmit_skb; | 1552 | struct sk_buff *skb, *xmit_skb; |
1551 | struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; | 1553 | struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; |
1552 | struct sta_info *dsta; | 1554 | struct sta_info *dsta; |
1555 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
1553 | 1556 | ||
1554 | skb = rx->skb; | 1557 | skb = rx->skb; |
1555 | xmit_skb = NULL; | 1558 | xmit_skb = NULL; |
@@ -1557,7 +1560,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1557 | if ((sdata->vif.type == NL80211_IFTYPE_AP || | 1560 | if ((sdata->vif.type == NL80211_IFTYPE_AP || |
1558 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && | 1561 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && |
1559 | !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && | 1562 | !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && |
1560 | (rx->flags & IEEE80211_RX_RA_MATCH) && | 1563 | (status->rx_flags & IEEE80211_RX_RA_MATCH) && |
1561 | (sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) { | 1564 | (sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) { |
1562 | if (is_multicast_ether_addr(ehdr->h_dest)) { | 1565 | if (is_multicast_ether_addr(ehdr->h_dest)) { |
1563 | /* | 1566 | /* |
@@ -1634,6 +1637,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | |||
1634 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1637 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1635 | __le16 fc = hdr->frame_control; | 1638 | __le16 fc = hdr->frame_control; |
1636 | struct sk_buff_head frame_list; | 1639 | struct sk_buff_head frame_list; |
1640 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
1637 | 1641 | ||
1638 | if (unlikely(!ieee80211_is_data(fc))) | 1642 | if (unlikely(!ieee80211_is_data(fc))) |
1639 | return RX_CONTINUE; | 1643 | return RX_CONTINUE; |
@@ -1641,7 +1645,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | |||
1641 | if (unlikely(!ieee80211_is_data_present(fc))) | 1645 | if (unlikely(!ieee80211_is_data_present(fc))) |
1642 | return RX_DROP_MONITOR; | 1646 | return RX_DROP_MONITOR; |
1643 | 1647 | ||
1644 | if (!(rx->flags & IEEE80211_RX_AMSDU)) | 1648 | if (!(status->rx_flags & IEEE80211_RX_AMSDU)) |
1645 | return RX_CONTINUE; | 1649 | return RX_CONTINUE; |
1646 | 1650 | ||
1647 | if (ieee80211_has_a4(hdr->frame_control) && | 1651 | if (ieee80211_has_a4(hdr->frame_control) && |
@@ -1692,6 +1696,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1692 | struct sk_buff *skb = rx->skb, *fwd_skb; | 1696 | struct sk_buff *skb = rx->skb, *fwd_skb; |
1693 | struct ieee80211_local *local = rx->local; | 1697 | struct ieee80211_local *local = rx->local; |
1694 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 1698 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1699 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
1695 | 1700 | ||
1696 | hdr = (struct ieee80211_hdr *) skb->data; | 1701 | hdr = (struct ieee80211_hdr *) skb->data; |
1697 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 1702 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
@@ -1737,7 +1742,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1737 | 1742 | ||
1738 | mesh_hdr->ttl--; | 1743 | mesh_hdr->ttl--; |
1739 | 1744 | ||
1740 | if (rx->flags & IEEE80211_RX_RA_MATCH) { | 1745 | if (status->rx_flags & IEEE80211_RX_RA_MATCH) { |
1741 | if (!mesh_hdr->ttl) | 1746 | if (!mesh_hdr->ttl) |
1742 | IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.mesh, | 1747 | IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.mesh, |
1743 | dropped_frames_ttl); | 1748 | dropped_frames_ttl); |
@@ -1947,6 +1952,7 @@ static ieee80211_rx_result debug_noinline | |||
1947 | ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) | 1952 | ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) |
1948 | { | 1953 | { |
1949 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; | 1954 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; |
1955 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
1950 | 1956 | ||
1951 | /* | 1957 | /* |
1952 | * From here on, look only at management frames. | 1958 | * From here on, look only at management frames. |
@@ -1959,7 +1965,7 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) | |||
1959 | if (!ieee80211_is_mgmt(mgmt->frame_control)) | 1965 | if (!ieee80211_is_mgmt(mgmt->frame_control)) |
1960 | return RX_DROP_MONITOR; | 1966 | return RX_DROP_MONITOR; |
1961 | 1967 | ||
1962 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 1968 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) |
1963 | return RX_DROP_MONITOR; | 1969 | return RX_DROP_MONITOR; |
1964 | 1970 | ||
1965 | if (ieee80211_drop_unencrypted_mgmt(rx)) | 1971 | if (ieee80211_drop_unencrypted_mgmt(rx)) |
@@ -1974,6 +1980,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
1974 | struct ieee80211_local *local = rx->local; | 1980 | struct ieee80211_local *local = rx->local; |
1975 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 1981 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1976 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; | 1982 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; |
1983 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
1977 | int len = rx->skb->len; | 1984 | int len = rx->skb->len; |
1978 | 1985 | ||
1979 | if (!ieee80211_is_action(mgmt->frame_control)) | 1986 | if (!ieee80211_is_action(mgmt->frame_control)) |
@@ -1986,7 +1993,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
1986 | if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) | 1993 | if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) |
1987 | return RX_DROP_UNUSABLE; | 1994 | return RX_DROP_UNUSABLE; |
1988 | 1995 | ||
1989 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 1996 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) |
1990 | return RX_DROP_UNUSABLE; | 1997 | return RX_DROP_UNUSABLE; |
1991 | 1998 | ||
1992 | switch (mgmt->u.action.category) { | 1999 | switch (mgmt->u.action.category) { |
@@ -2082,7 +2089,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2082 | return RX_CONTINUE; | 2089 | return RX_CONTINUE; |
2083 | 2090 | ||
2084 | invalid: | 2091 | invalid: |
2085 | rx->flags |= IEEE80211_MALFORMED_ACTION_FRM; | 2092 | status->rx_flags |= IEEE80211_RX_MALFORMED_ACTION_FRM; |
2086 | /* will return in the next handlers */ | 2093 | /* will return in the next handlers */ |
2087 | return RX_CONTINUE; | 2094 | return RX_CONTINUE; |
2088 | 2095 | ||
@@ -2104,10 +2111,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2104 | static ieee80211_rx_result debug_noinline | 2111 | static ieee80211_rx_result debug_noinline |
2105 | ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) | 2112 | ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) |
2106 | { | 2113 | { |
2107 | struct ieee80211_rx_status *status; | 2114 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); |
2108 | 2115 | ||
2109 | /* skip known-bad action frames and return them in the next handler */ | 2116 | /* skip known-bad action frames and return them in the next handler */ |
2110 | if (rx->flags & IEEE80211_MALFORMED_ACTION_FRM) | 2117 | if (status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM) |
2111 | return RX_CONTINUE; | 2118 | return RX_CONTINUE; |
2112 | 2119 | ||
2113 | /* | 2120 | /* |
@@ -2116,7 +2123,6 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) | |||
2116 | * so userspace can register for those to know whether ones | 2123 | * so userspace can register for those to know whether ones |
2117 | * it transmitted were processed or returned. | 2124 | * it transmitted were processed or returned. |
2118 | */ | 2125 | */ |
2119 | status = IEEE80211_SKB_RXCB(rx->skb); | ||
2120 | 2126 | ||
2121 | if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, | 2127 | if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, |
2122 | rx->skb->data, rx->skb->len, | 2128 | rx->skb->data, rx->skb->len, |
@@ -2138,6 +2144,7 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) | |||
2138 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; | 2144 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; |
2139 | struct sk_buff *nskb; | 2145 | struct sk_buff *nskb; |
2140 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 2146 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
2147 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
2141 | 2148 | ||
2142 | if (!ieee80211_is_action(mgmt->frame_control)) | 2149 | if (!ieee80211_is_action(mgmt->frame_control)) |
2143 | return RX_CONTINUE; | 2150 | return RX_CONTINUE; |
@@ -2152,7 +2159,7 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) | |||
2152 | * registration mechanisms, but older ones still use cooked | 2159 | * registration mechanisms, but older ones still use cooked |
2153 | * monitor interfaces so push all frames there. | 2160 | * monitor interfaces so push all frames there. |
2154 | */ | 2161 | */ |
2155 | if (!(rx->flags & IEEE80211_MALFORMED_ACTION_FRM) && | 2162 | if (!(status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM) && |
2156 | (sdata->vif.type == NL80211_IFTYPE_AP || | 2163 | (sdata->vif.type == NL80211_IFTYPE_AP || |
2157 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) | 2164 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) |
2158 | return RX_DROP_MONITOR; | 2165 | return RX_DROP_MONITOR; |
@@ -2286,8 +2293,13 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | |||
2286 | struct net_device *prev_dev = NULL; | 2293 | struct net_device *prev_dev = NULL; |
2287 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 2294 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
2288 | 2295 | ||
2289 | if (status->flag & RX_FLAG_INTERNAL_CMTR) | 2296 | /* |
2297 | * If cooked monitor has been processed already, then | ||
2298 | * don't do it again. If not, set the flag. | ||
2299 | */ | ||
2300 | if (rx->flags & IEEE80211_RX_CMNTR) | ||
2290 | goto out_free_skb; | 2301 | goto out_free_skb; |
2302 | rx->flags |= IEEE80211_RX_CMNTR; | ||
2291 | 2303 | ||
2292 | if (skb_headroom(skb) < sizeof(*rthdr) && | 2304 | if (skb_headroom(skb) < sizeof(*rthdr) && |
2293 | pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) | 2305 | pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) |
@@ -2343,12 +2355,8 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | |||
2343 | if (prev_dev) { | 2355 | if (prev_dev) { |
2344 | skb->dev = prev_dev; | 2356 | skb->dev = prev_dev; |
2345 | netif_receive_skb(skb); | 2357 | netif_receive_skb(skb); |
2346 | skb = NULL; | 2358 | return; |
2347 | } else | 2359 | } |
2348 | goto out_free_skb; | ||
2349 | |||
2350 | status->flag |= RX_FLAG_INTERNAL_CMTR; | ||
2351 | return; | ||
2352 | 2360 | ||
2353 | out_free_skb: | 2361 | out_free_skb: |
2354 | dev_kfree_skb(skb); | 2362 | dev_kfree_skb(skb); |
@@ -2409,6 +2417,7 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx, | |||
2409 | * same TID from the same station | 2417 | * same TID from the same station |
2410 | */ | 2418 | */ |
2411 | rx->skb = skb; | 2419 | rx->skb = skb; |
2420 | rx->flags = 0; | ||
2412 | 2421 | ||
2413 | CALL_RXH(ieee80211_rx_h_decrypt) | 2422 | CALL_RXH(ieee80211_rx_h_decrypt) |
2414 | CALL_RXH(ieee80211_rx_h_check_more_data) | 2423 | CALL_RXH(ieee80211_rx_h_check_more_data) |
@@ -2443,18 +2452,13 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx, | |||
2443 | } | 2452 | } |
2444 | } | 2453 | } |
2445 | 2454 | ||
2446 | static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, | 2455 | static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx) |
2447 | struct ieee80211_rx_data *rx, | ||
2448 | struct sk_buff *skb) | ||
2449 | { | 2456 | { |
2450 | struct sk_buff_head reorder_release; | 2457 | struct sk_buff_head reorder_release; |
2451 | ieee80211_rx_result res = RX_DROP_MONITOR; | 2458 | ieee80211_rx_result res = RX_DROP_MONITOR; |
2452 | 2459 | ||
2453 | __skb_queue_head_init(&reorder_release); | 2460 | __skb_queue_head_init(&reorder_release); |
2454 | 2461 | ||
2455 | rx->skb = skb; | ||
2456 | rx->sdata = sdata; | ||
2457 | |||
2458 | #define CALL_RXH(rxh) \ | 2462 | #define CALL_RXH(rxh) \ |
2459 | do { \ | 2463 | do { \ |
2460 | res = rxh(rx); \ | 2464 | res = rxh(rx); \ |
@@ -2484,7 +2488,12 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, | |||
2484 | void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) | 2488 | void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) |
2485 | { | 2489 | { |
2486 | struct sk_buff_head frames; | 2490 | struct sk_buff_head frames; |
2487 | struct ieee80211_rx_data rx = { }; | 2491 | struct ieee80211_rx_data rx = { |
2492 | .sta = sta, | ||
2493 | .sdata = sta->sdata, | ||
2494 | .local = sta->local, | ||
2495 | .queue = tid, | ||
2496 | }; | ||
2488 | struct tid_ampdu_rx *tid_agg_rx; | 2497 | struct tid_ampdu_rx *tid_agg_rx; |
2489 | 2498 | ||
2490 | tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); | 2499 | tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); |
@@ -2493,17 +2502,6 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) | |||
2493 | 2502 | ||
2494 | __skb_queue_head_init(&frames); | 2503 | __skb_queue_head_init(&frames); |
2495 | 2504 | ||
2496 | /* construct rx struct */ | ||
2497 | rx.sta = sta; | ||
2498 | rx.sdata = sta->sdata; | ||
2499 | rx.local = sta->local; | ||
2500 | rx.queue = tid; | ||
2501 | rx.flags |= IEEE80211_RX_RA_MATCH; | ||
2502 | |||
2503 | if (unlikely(test_bit(SCAN_HW_SCANNING, &sta->local->scanning) || | ||
2504 | test_bit(SCAN_OFF_CHANNEL, &sta->local->scanning))) | ||
2505 | rx.flags |= IEEE80211_RX_IN_SCAN; | ||
2506 | |||
2507 | spin_lock(&tid_agg_rx->reorder_lock); | 2505 | spin_lock(&tid_agg_rx->reorder_lock); |
2508 | ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx, &frames); | 2506 | ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx, &frames); |
2509 | spin_unlock(&tid_agg_rx->reorder_lock); | 2507 | spin_unlock(&tid_agg_rx->reorder_lock); |
@@ -2513,10 +2511,10 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) | |||
2513 | 2511 | ||
2514 | /* main receive path */ | 2512 | /* main receive path */ |
2515 | 2513 | ||
2516 | static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | 2514 | static int prepare_for_handlers(struct ieee80211_rx_data *rx, |
2517 | struct ieee80211_rx_data *rx, | ||
2518 | struct ieee80211_hdr *hdr) | 2515 | struct ieee80211_hdr *hdr) |
2519 | { | 2516 | { |
2517 | struct ieee80211_sub_if_data *sdata = rx->sdata; | ||
2520 | struct sk_buff *skb = rx->skb; | 2518 | struct sk_buff *skb = rx->skb; |
2521 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 2519 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
2522 | u8 *bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type); | 2520 | u8 *bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type); |
@@ -2530,7 +2528,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
2530 | compare_ether_addr(sdata->vif.addr, hdr->addr1) != 0) { | 2528 | compare_ether_addr(sdata->vif.addr, hdr->addr1) != 0) { |
2531 | if (!(sdata->dev->flags & IFF_PROMISC)) | 2529 | if (!(sdata->dev->flags & IFF_PROMISC)) |
2532 | return 0; | 2530 | return 0; |
2533 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2531 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
2534 | } | 2532 | } |
2535 | break; | 2533 | break; |
2536 | case NL80211_IFTYPE_ADHOC: | 2534 | case NL80211_IFTYPE_ADHOC: |
@@ -2540,15 +2538,15 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
2540 | return 1; | 2538 | return 1; |
2541 | } | 2539 | } |
2542 | else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { | 2540 | else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { |
2543 | if (!(rx->flags & IEEE80211_RX_IN_SCAN)) | 2541 | if (!(status->rx_flags & IEEE80211_RX_IN_SCAN)) |
2544 | return 0; | 2542 | return 0; |
2545 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2543 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
2546 | } else if (!multicast && | 2544 | } else if (!multicast && |
2547 | compare_ether_addr(sdata->vif.addr, | 2545 | compare_ether_addr(sdata->vif.addr, |
2548 | hdr->addr1) != 0) { | 2546 | hdr->addr1) != 0) { |
2549 | if (!(sdata->dev->flags & IFF_PROMISC)) | 2547 | if (!(sdata->dev->flags & IFF_PROMISC)) |
2550 | return 0; | 2548 | return 0; |
2551 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2549 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
2552 | } else if (!rx->sta) { | 2550 | } else if (!rx->sta) { |
2553 | int rate_idx; | 2551 | int rate_idx; |
2554 | if (status->flag & RX_FLAG_HT) | 2552 | if (status->flag & RX_FLAG_HT) |
@@ -2566,7 +2564,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
2566 | if (!(sdata->dev->flags & IFF_PROMISC)) | 2564 | if (!(sdata->dev->flags & IFF_PROMISC)) |
2567 | return 0; | 2565 | return 0; |
2568 | 2566 | ||
2569 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2567 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
2570 | } | 2568 | } |
2571 | break; | 2569 | break; |
2572 | case NL80211_IFTYPE_AP_VLAN: | 2570 | case NL80211_IFTYPE_AP_VLAN: |
@@ -2577,9 +2575,9 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
2577 | return 0; | 2575 | return 0; |
2578 | } else if (!ieee80211_bssid_match(bssid, | 2576 | } else if (!ieee80211_bssid_match(bssid, |
2579 | sdata->vif.addr)) { | 2577 | sdata->vif.addr)) { |
2580 | if (!(rx->flags & IEEE80211_RX_IN_SCAN)) | 2578 | if (!(status->rx_flags & IEEE80211_RX_IN_SCAN)) |
2581 | return 0; | 2579 | return 0; |
2582 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2580 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
2583 | } | 2581 | } |
2584 | break; | 2582 | break; |
2585 | case NL80211_IFTYPE_WDS: | 2583 | case NL80211_IFTYPE_WDS: |
@@ -2598,6 +2596,51 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
2598 | } | 2596 | } |
2599 | 2597 | ||
2600 | /* | 2598 | /* |
2599 | * This function returns whether or not the SKB | ||
2600 | * was destined for RX processing or not, which, | ||
2601 | * if consume is true, is equivalent to whether | ||
2602 | * or not the skb was consumed. | ||
2603 | */ | ||
2604 | static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, | ||
2605 | struct sk_buff *skb, bool consume) | ||
2606 | { | ||
2607 | struct ieee80211_local *local = rx->local; | ||
2608 | struct ieee80211_sub_if_data *sdata = rx->sdata; | ||
2609 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
2610 | struct ieee80211_hdr *hdr = (void *)skb->data; | ||
2611 | int prepares; | ||
2612 | |||
2613 | rx->skb = skb; | ||
2614 | status->rx_flags |= IEEE80211_RX_RA_MATCH; | ||
2615 | prepares = prepare_for_handlers(rx, hdr); | ||
2616 | |||
2617 | if (!prepares) | ||
2618 | return false; | ||
2619 | |||
2620 | if (status->flag & RX_FLAG_MMIC_ERROR) { | ||
2621 | if (status->rx_flags & IEEE80211_RX_RA_MATCH) | ||
2622 | ieee80211_rx_michael_mic_report(hdr, rx); | ||
2623 | return false; | ||
2624 | } | ||
2625 | |||
2626 | if (!consume) { | ||
2627 | skb = skb_copy(skb, GFP_ATOMIC); | ||
2628 | if (!skb) { | ||
2629 | if (net_ratelimit()) | ||
2630 | wiphy_debug(local->hw.wiphy, | ||
2631 | "failed to copy multicast frame for %s\n", | ||
2632 | sdata->name); | ||
2633 | return true; | ||
2634 | } | ||
2635 | |||
2636 | rx->skb = skb; | ||
2637 | } | ||
2638 | |||
2639 | ieee80211_invoke_rx_handlers(rx); | ||
2640 | return true; | ||
2641 | } | ||
2642 | |||
2643 | /* | ||
2601 | * This is the actual Rx frames handler. as it blongs to Rx path it must | 2644 | * This is the actual Rx frames handler. as it blongs to Rx path it must |
2602 | * be called with rcu_read_lock protection. | 2645 | * be called with rcu_read_lock protection. |
2603 | */ | 2646 | */ |
@@ -2610,11 +2653,8 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2610 | struct ieee80211_hdr *hdr; | 2653 | struct ieee80211_hdr *hdr; |
2611 | __le16 fc; | 2654 | __le16 fc; |
2612 | struct ieee80211_rx_data rx; | 2655 | struct ieee80211_rx_data rx; |
2613 | int prepares; | 2656 | struct ieee80211_sub_if_data *prev; |
2614 | struct ieee80211_sub_if_data *prev = NULL; | 2657 | struct sta_info *sta, *tmp, *prev_sta; |
2615 | struct sk_buff *skb_new; | ||
2616 | struct sta_info *sta, *tmp; | ||
2617 | bool found_sta = false; | ||
2618 | int err = 0; | 2658 | int err = 0; |
2619 | 2659 | ||
2620 | fc = ((struct ieee80211_hdr *)skb->data)->frame_control; | 2660 | fc = ((struct ieee80211_hdr *)skb->data)->frame_control; |
@@ -2627,7 +2667,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2627 | 2667 | ||
2628 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || | 2668 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || |
2629 | test_bit(SCAN_OFF_CHANNEL, &local->scanning))) | 2669 | test_bit(SCAN_OFF_CHANNEL, &local->scanning))) |
2630 | rx.flags |= IEEE80211_RX_IN_SCAN; | 2670 | status->rx_flags |= IEEE80211_RX_IN_SCAN; |
2631 | 2671 | ||
2632 | if (ieee80211_is_mgmt(fc)) | 2672 | if (ieee80211_is_mgmt(fc)) |
2633 | err = skb_linearize(skb); | 2673 | err = skb_linearize(skb); |
@@ -2644,90 +2684,67 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2644 | ieee80211_verify_alignment(&rx); | 2684 | ieee80211_verify_alignment(&rx); |
2645 | 2685 | ||
2646 | if (ieee80211_is_data(fc)) { | 2686 | if (ieee80211_is_data(fc)) { |
2687 | prev_sta = NULL; | ||
2688 | |||
2647 | for_each_sta_info(local, hdr->addr2, sta, tmp) { | 2689 | for_each_sta_info(local, hdr->addr2, sta, tmp) { |
2648 | rx.sta = sta; | 2690 | if (!prev_sta) { |
2649 | found_sta = true; | 2691 | prev_sta = sta; |
2650 | rx.sdata = sta->sdata; | ||
2651 | |||
2652 | rx.flags |= IEEE80211_RX_RA_MATCH; | ||
2653 | prepares = prepare_for_handlers(rx.sdata, &rx, hdr); | ||
2654 | if (prepares) { | ||
2655 | if (status->flag & RX_FLAG_MMIC_ERROR) { | ||
2656 | if (rx.flags & IEEE80211_RX_RA_MATCH) | ||
2657 | ieee80211_rx_michael_mic_report(hdr, &rx); | ||
2658 | } else | ||
2659 | prev = rx.sdata; | ||
2660 | } | ||
2661 | } | ||
2662 | } | ||
2663 | if (!found_sta) { | ||
2664 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | ||
2665 | if (!ieee80211_sdata_running(sdata)) | ||
2666 | continue; | 2692 | continue; |
2693 | } | ||
2667 | 2694 | ||
2668 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR || | 2695 | rx.sta = prev_sta; |
2669 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 2696 | rx.sdata = prev_sta->sdata; |
2670 | continue; | 2697 | ieee80211_prepare_and_rx_handle(&rx, skb, false); |
2671 | 2698 | ||
2672 | /* | 2699 | prev_sta = sta; |
2673 | * frame is destined for this interface, but if it's | 2700 | } |
2674 | * not also for the previous one we handle that after | ||
2675 | * the loop to avoid copying the SKB once too much | ||
2676 | */ | ||
2677 | 2701 | ||
2678 | if (!prev) { | 2702 | if (prev_sta) { |
2679 | prev = sdata; | 2703 | rx.sta = prev_sta; |
2680 | continue; | 2704 | rx.sdata = prev_sta->sdata; |
2681 | } | ||
2682 | 2705 | ||
2683 | rx.sta = sta_info_get_bss(prev, hdr->addr2); | 2706 | if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) |
2707 | return; | ||
2708 | } | ||
2709 | } | ||
2684 | 2710 | ||
2685 | rx.flags |= IEEE80211_RX_RA_MATCH; | 2711 | prev = NULL; |
2686 | prepares = prepare_for_handlers(prev, &rx, hdr); | ||
2687 | 2712 | ||
2688 | if (!prepares) | 2713 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
2689 | goto next; | 2714 | if (!ieee80211_sdata_running(sdata)) |
2715 | continue; | ||
2690 | 2716 | ||
2691 | if (status->flag & RX_FLAG_MMIC_ERROR) { | 2717 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR || |
2692 | rx.sdata = prev; | 2718 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
2693 | if (rx.flags & IEEE80211_RX_RA_MATCH) | 2719 | continue; |
2694 | ieee80211_rx_michael_mic_report(hdr, | ||
2695 | &rx); | ||
2696 | goto next; | ||
2697 | } | ||
2698 | 2720 | ||
2699 | /* | 2721 | /* |
2700 | * frame was destined for the previous interface | 2722 | * frame is destined for this interface, but if it's |
2701 | * so invoke RX handlers for it | 2723 | * not also for the previous one we handle that after |
2702 | */ | 2724 | * the loop to avoid copying the SKB once too much |
2725 | */ | ||
2703 | 2726 | ||
2704 | skb_new = skb_copy(skb, GFP_ATOMIC); | 2727 | if (!prev) { |
2705 | if (!skb_new) { | ||
2706 | if (net_ratelimit()) | ||
2707 | wiphy_debug(local->hw.wiphy, | ||
2708 | "failed to copy multicast frame for %s\n", | ||
2709 | prev->name); | ||
2710 | goto next; | ||
2711 | } | ||
2712 | ieee80211_invoke_rx_handlers(prev, &rx, skb_new); | ||
2713 | next: | ||
2714 | prev = sdata; | 2728 | prev = sdata; |
2729 | continue; | ||
2715 | } | 2730 | } |
2716 | 2731 | ||
2717 | if (prev) { | 2732 | rx.sta = sta_info_get_bss(prev, hdr->addr2); |
2718 | rx.sta = sta_info_get_bss(prev, hdr->addr2); | 2733 | rx.sdata = prev; |
2734 | ieee80211_prepare_and_rx_handle(&rx, skb, false); | ||
2719 | 2735 | ||
2720 | rx.flags |= IEEE80211_RX_RA_MATCH; | 2736 | prev = sdata; |
2721 | prepares = prepare_for_handlers(prev, &rx, hdr); | 2737 | } |
2722 | 2738 | ||
2723 | if (!prepares) | 2739 | if (prev) { |
2724 | prev = NULL; | 2740 | rx.sta = sta_info_get_bss(prev, hdr->addr2); |
2725 | } | 2741 | rx.sdata = prev; |
2742 | |||
2743 | if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) | ||
2744 | return; | ||
2726 | } | 2745 | } |
2727 | if (prev) | 2746 | |
2728 | ieee80211_invoke_rx_handlers(prev, &rx, skb); | 2747 | dev_kfree_skb(skb); |
2729 | else | ||
2730 | dev_kfree_skb(skb); | ||
2731 | } | 2748 | } |
2732 | 2749 | ||
2733 | /* | 2750 | /* |
@@ -2801,6 +2818,8 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2801 | } | 2818 | } |
2802 | } | 2819 | } |
2803 | 2820 | ||
2821 | status->rx_flags = 0; | ||
2822 | |||
2804 | /* | 2823 | /* |
2805 | * key references and virtual interfaces are protected using RCU | 2824 | * key references and virtual interfaces are protected using RCU |
2806 | * and this requires that we are in a read-side RCU section during | 2825 | * and this requires that we are in a read-side RCU section during |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index d60389ba9b95..5171a9581631 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -242,7 +242,8 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) | |||
242 | local->hw_scan_req->n_channels = n_chans; | 242 | local->hw_scan_req->n_channels = n_chans; |
243 | 243 | ||
244 | ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, | 244 | ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, |
245 | req->ie, req->ie_len, band); | 245 | req->ie, req->ie_len, band, (u32) -1, |
246 | 0); | ||
246 | local->hw_scan_req->ie_len = ielen; | 247 | local->hw_scan_req->ie_len = ielen; |
247 | 248 | ||
248 | return true; | 249 | return true; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 44e10a9de0a7..ca2cba9cea87 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -838,13 +838,20 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, | |||
838 | mutex_unlock(&local->sta_mtx); | 838 | mutex_unlock(&local->sta_mtx); |
839 | } | 839 | } |
840 | 840 | ||
841 | struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, | 841 | struct ieee80211_sta *ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw, |
842 | const u8 *addr) | 842 | const u8 *addr, |
843 | const u8 *localaddr) | ||
843 | { | 844 | { |
844 | struct sta_info *sta, *nxt; | 845 | struct sta_info *sta, *nxt; |
845 | 846 | ||
846 | /* Just return a random station ... first in list ... */ | 847 | /* |
848 | * Just return a random station if localaddr is NULL | ||
849 | * ... first in list. | ||
850 | */ | ||
847 | for_each_sta_info(hw_to_local(hw), addr, sta, nxt) { | 851 | for_each_sta_info(hw_to_local(hw), addr, sta, nxt) { |
852 | if (localaddr && | ||
853 | compare_ether_addr(sta->sdata->vif.addr, localaddr) != 0) | ||
854 | continue; | ||
848 | if (!sta->uploaded) | 855 | if (!sta->uploaded) |
849 | return NULL; | 856 | return NULL; |
850 | return &sta->sta; | 857 | return &sta->sta; |
@@ -852,7 +859,7 @@ struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, | |||
852 | 859 | ||
853 | return NULL; | 860 | return NULL; |
854 | } | 861 | } |
855 | EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw); | 862 | EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_ifaddr); |
856 | 863 | ||
857 | struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, | 864 | struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, |
858 | const u8 *addr) | 865 | const u8 *addr) |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 571b32bfc54c..dd85006c4fe8 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -58,6 +58,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
58 | info->control.vif = &sta->sdata->vif; | 58 | info->control.vif = &sta->sdata->vif; |
59 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING | | 59 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING | |
60 | IEEE80211_TX_INTFL_RETRANSMISSION; | 60 | IEEE80211_TX_INTFL_RETRANSMISSION; |
61 | info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS; | ||
61 | 62 | ||
62 | sta->tx_filtered_count++; | 63 | sta->tx_filtered_count++; |
63 | 64 | ||
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 737f4267c335..aba025d748e9 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -895,26 +895,34 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | |||
895 | 895 | ||
896 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | 896 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, |
897 | const u8 *ie, size_t ie_len, | 897 | const u8 *ie, size_t ie_len, |
898 | enum ieee80211_band band) | 898 | enum ieee80211_band band, u32 rate_mask, |
899 | u8 channel) | ||
899 | { | 900 | { |
900 | struct ieee80211_supported_band *sband; | 901 | struct ieee80211_supported_band *sband; |
901 | u8 *pos; | 902 | u8 *pos; |
902 | size_t offset = 0, noffset; | 903 | size_t offset = 0, noffset; |
903 | int supp_rates_len, i; | 904 | int supp_rates_len, i; |
905 | u8 rates[32]; | ||
906 | int num_rates; | ||
907 | int ext_rates_len; | ||
904 | 908 | ||
905 | sband = local->hw.wiphy->bands[band]; | 909 | sband = local->hw.wiphy->bands[band]; |
906 | 910 | ||
907 | pos = buffer; | 911 | pos = buffer; |
908 | 912 | ||
909 | supp_rates_len = min_t(int, sband->n_bitrates, 8); | 913 | num_rates = 0; |
914 | for (i = 0; i < sband->n_bitrates; i++) { | ||
915 | if ((BIT(i) & rate_mask) == 0) | ||
916 | continue; /* skip rate */ | ||
917 | rates[num_rates++] = (u8) (sband->bitrates[i].bitrate / 5); | ||
918 | } | ||
919 | |||
920 | supp_rates_len = min_t(int, num_rates, 8); | ||
910 | 921 | ||
911 | *pos++ = WLAN_EID_SUPP_RATES; | 922 | *pos++ = WLAN_EID_SUPP_RATES; |
912 | *pos++ = supp_rates_len; | 923 | *pos++ = supp_rates_len; |
913 | 924 | memcpy(pos, rates, supp_rates_len); | |
914 | for (i = 0; i < supp_rates_len; i++) { | 925 | pos += supp_rates_len; |
915 | int rate = sband->bitrates[i].bitrate; | ||
916 | *pos++ = (u8) (rate / 5); | ||
917 | } | ||
918 | 926 | ||
919 | /* insert "request information" if in custom IEs */ | 927 | /* insert "request information" if in custom IEs */ |
920 | if (ie && ie_len) { | 928 | if (ie && ie_len) { |
@@ -932,14 +940,18 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | |||
932 | offset = noffset; | 940 | offset = noffset; |
933 | } | 941 | } |
934 | 942 | ||
935 | if (sband->n_bitrates > i) { | 943 | ext_rates_len = num_rates - supp_rates_len; |
944 | if (ext_rates_len > 0) { | ||
936 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | 945 | *pos++ = WLAN_EID_EXT_SUPP_RATES; |
937 | *pos++ = sband->n_bitrates - i; | 946 | *pos++ = ext_rates_len; |
947 | memcpy(pos, rates + supp_rates_len, ext_rates_len); | ||
948 | pos += ext_rates_len; | ||
949 | } | ||
938 | 950 | ||
939 | for (; i < sband->n_bitrates; i++) { | 951 | if (channel && sband->band == IEEE80211_BAND_2GHZ) { |
940 | int rate = sband->bitrates[i].bitrate; | 952 | *pos++ = WLAN_EID_DS_PARAMS; |
941 | *pos++ = (u8) (rate / 5); | 953 | *pos++ = 1; |
942 | } | 954 | *pos++ = channel; |
943 | } | 955 | } |
944 | 956 | ||
945 | /* insert custom IEs that go before HT */ | 957 | /* insert custom IEs that go before HT */ |
@@ -1008,6 +1020,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | |||
1008 | struct ieee80211_mgmt *mgmt; | 1020 | struct ieee80211_mgmt *mgmt; |
1009 | size_t buf_len; | 1021 | size_t buf_len; |
1010 | u8 *buf; | 1022 | u8 *buf; |
1023 | u8 chan; | ||
1011 | 1024 | ||
1012 | /* FIXME: come up with a proper value */ | 1025 | /* FIXME: come up with a proper value */ |
1013 | buf = kmalloc(200 + ie_len, GFP_KERNEL); | 1026 | buf = kmalloc(200 + ie_len, GFP_KERNEL); |
@@ -1017,8 +1030,14 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | |||
1017 | return; | 1030 | return; |
1018 | } | 1031 | } |
1019 | 1032 | ||
1033 | chan = ieee80211_frequency_to_channel( | ||
1034 | local->hw.conf.channel->center_freq); | ||
1035 | |||
1020 | buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, | 1036 | buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, |
1021 | local->hw.conf.channel->band); | 1037 | local->hw.conf.channel->band, |
1038 | sdata->rc_rateidx_mask | ||
1039 | [local->hw.conf.channel->band], | ||
1040 | chan); | ||
1022 | 1041 | ||
1023 | skb = ieee80211_probereq_get(&local->hw, &sdata->vif, | 1042 | skb = ieee80211_probereq_get(&local->hw, &sdata->vif, |
1024 | ssid, ssid_len, | 1043 | ssid, ssid_len, |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 43882b36da55..bee230d8fd11 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -117,7 +117,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
117 | key = &rx->key->conf.key[key_offset]; | 117 | key = &rx->key->conf.key[key_offset]; |
118 | michael_mic(key, hdr, data, data_len, mic); | 118 | michael_mic(key, hdr, data, data_len, mic); |
119 | if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { | 119 | if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { |
120 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 120 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) |
121 | return RX_DROP_UNUSABLE; | 121 | return RX_DROP_UNUSABLE; |
122 | 122 | ||
123 | mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, | 123 | mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, |
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 27a8ce9343c3..8cb6e08373b9 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
@@ -88,6 +88,25 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | |||
88 | if (wdev->ssid_len) | 88 | if (wdev->ssid_len) |
89 | return -EALREADY; | 89 | return -EALREADY; |
90 | 90 | ||
91 | if (!params->basic_rates) { | ||
92 | /* | ||
93 | * If no rates were explicitly configured, | ||
94 | * use the mandatory rate set for 11b or | ||
95 | * 11a for maximum compatibility. | ||
96 | */ | ||
97 | struct ieee80211_supported_band *sband = | ||
98 | rdev->wiphy.bands[params->channel->band]; | ||
99 | int j; | ||
100 | u32 flag = params->channel->band == IEEE80211_BAND_5GHZ ? | ||
101 | IEEE80211_RATE_MANDATORY_A : | ||
102 | IEEE80211_RATE_MANDATORY_B; | ||
103 | |||
104 | for (j = 0; j < sband->n_bitrates; j++) { | ||
105 | if (sband->bitrates[j].flags & flag) | ||
106 | params->basic_rates |= BIT(j); | ||
107 | } | ||
108 | } | ||
109 | |||
91 | if (WARN_ON(wdev->connect_keys)) | 110 | if (WARN_ON(wdev->connect_keys)) |
92 | kfree(wdev->connect_keys); | 111 | kfree(wdev->connect_keys); |
93 | wdev->connect_keys = connkeys; | 112 | wdev->connect_keys = connkeys; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index f15b1af2c768..9c84825803ce 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -4119,23 +4119,6 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) | |||
4119 | goto out; | 4119 | goto out; |
4120 | } | 4120 | } |
4121 | } | 4121 | } |
4122 | } else { | ||
4123 | /* | ||
4124 | * If no rates were explicitly configured, | ||
4125 | * use the mandatory rate set for 11b or | ||
4126 | * 11a for maximum compatibility. | ||
4127 | */ | ||
4128 | struct ieee80211_supported_band *sband = | ||
4129 | wiphy->bands[ibss.channel->band]; | ||
4130 | int j; | ||
4131 | u32 flag = ibss.channel->band == IEEE80211_BAND_5GHZ ? | ||
4132 | IEEE80211_RATE_MANDATORY_A : | ||
4133 | IEEE80211_RATE_MANDATORY_B; | ||
4134 | |||
4135 | for (j = 0; j < sband->n_bitrates; j++) { | ||
4136 | if (sband->bitrates[j].flags & flag) | ||
4137 | ibss.basic_rates |= BIT(j); | ||
4138 | } | ||
4139 | } | 4122 | } |
4140 | 4123 | ||
4141 | err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); | 4124 | err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); |
@@ -4990,7 +4973,7 @@ static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info) | |||
4990 | 4973 | ||
4991 | err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); | 4974 | err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); |
4992 | if (err) | 4975 | if (err) |
4993 | goto unlock_rdev; | 4976 | goto unlock_rtnl; |
4994 | 4977 | ||
4995 | wdev = dev->ieee80211_ptr; | 4978 | wdev = dev->ieee80211_ptr; |
4996 | 4979 | ||
@@ -5014,6 +4997,7 @@ static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info) | |||
5014 | unlock_rdev: | 4997 | unlock_rdev: |
5015 | cfg80211_unlock_rdev(rdev); | 4998 | cfg80211_unlock_rdev(rdev); |
5016 | dev_put(dev); | 4999 | dev_put(dev); |
5000 | unlock_rtnl: | ||
5017 | rtnl_unlock(); | 5001 | rtnl_unlock(); |
5018 | 5002 | ||
5019 | out: | 5003 | out: |