diff options
Diffstat (limited to 'net')
43 files changed, 1008 insertions, 766 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index a6f74b2b9571..a2cbe61f6e65 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
@@ -390,6 +390,10 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
390 | if (dev->br_port != NULL) | 390 | if (dev->br_port != NULL) |
391 | return -EBUSY; | 391 | return -EBUSY; |
392 | 392 | ||
393 | /* No bridging devices that dislike that (e.g. wireless) */ | ||
394 | if (dev->priv_flags & IFF_DONT_BRIDGE) | ||
395 | return -EOPNOTSUPP; | ||
396 | |||
393 | p = new_nbp(br, dev); | 397 | p = new_nbp(br, dev); |
394 | if (IS_ERR(p)) | 398 | if (IS_ERR(p)) |
395 | return PTR_ERR(p); | 399 | return PTR_ERR(p); |
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 9f3cf7129324..298cfcc1bf8d 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile | |||
@@ -2,7 +2,7 @@ obj-$(CONFIG_MAC80211) += mac80211.o | |||
2 | 2 | ||
3 | # mac80211 objects | 3 | # mac80211 objects |
4 | mac80211-y := \ | 4 | mac80211-y := \ |
5 | main.o \ | 5 | main.o status.o \ |
6 | sta_info.o \ | 6 | sta_info.o \ |
7 | wep.o \ | 7 | wep.o \ |
8 | wpa.o \ | 8 | wpa.o \ |
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index bc064d7933ff..7ed5fe664732 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -41,7 +41,8 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | |||
41 | sta->sta.addr, tid); | 41 | sta->sta.addr, tid); |
42 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 42 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
43 | 43 | ||
44 | if (drv_ampdu_action(local, IEEE80211_AMPDU_RX_STOP, | 44 | if (drv_ampdu_action(local, &sta->sdata->vif, |
45 | IEEE80211_AMPDU_RX_STOP, | ||
45 | &sta->sta, tid, NULL)) | 46 | &sta->sta, tid, NULL)) |
46 | printk(KERN_DEBUG "HW problem - can not stop rx " | 47 | printk(KERN_DEBUG "HW problem - can not stop rx " |
47 | "aggregation for tid %d\n", tid); | 48 | "aggregation for tid %d\n", tid); |
@@ -170,7 +171,7 @@ static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *d | |||
170 | mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout); | 171 | mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout); |
171 | mgmt->u.action.u.addba_resp.status = cpu_to_le16(status); | 172 | mgmt->u.action.u.addba_resp.status = cpu_to_le16(status); |
172 | 173 | ||
173 | ieee80211_tx_skb(sdata, skb, 1); | 174 | ieee80211_tx_skb(sdata, skb); |
174 | } | 175 | } |
175 | 176 | ||
176 | void ieee80211_process_addba_request(struct ieee80211_local *local, | 177 | void ieee80211_process_addba_request(struct ieee80211_local *local, |
@@ -284,7 +285,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
284 | goto end; | 285 | goto end; |
285 | } | 286 | } |
286 | 287 | ||
287 | ret = drv_ampdu_action(local, IEEE80211_AMPDU_RX_START, | 288 | ret = drv_ampdu_action(local, &sta->sdata->vif, |
289 | IEEE80211_AMPDU_RX_START, | ||
288 | &sta->sta, tid, &start_seq_num); | 290 | &sta->sta, tid, &start_seq_num); |
289 | #ifdef CONFIG_MAC80211_HT_DEBUG | 291 | #ifdef CONFIG_MAC80211_HT_DEBUG |
290 | printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret); | 292 | printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret); |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index b09948ceec4a..b50b2bc3b8c5 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -91,7 +91,7 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, | |||
91 | mgmt->u.action.u.addba_req.start_seq_num = | 91 | mgmt->u.action.u.addba_req.start_seq_num = |
92 | cpu_to_le16(start_seq_num << 4); | 92 | cpu_to_le16(start_seq_num << 4); |
93 | 93 | ||
94 | ieee80211_tx_skb(sdata, skb, 1); | 94 | ieee80211_tx_skb(sdata, skb); |
95 | } | 95 | } |
96 | 96 | ||
97 | void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn) | 97 | void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn) |
@@ -120,7 +120,8 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1 | |||
120 | bar->control = cpu_to_le16(bar_control); | 120 | bar->control = cpu_to_le16(bar_control); |
121 | bar->start_seq_num = cpu_to_le16(ssn); | 121 | bar->start_seq_num = cpu_to_le16(ssn); |
122 | 122 | ||
123 | ieee80211_tx_skb(sdata, skb, 0); | 123 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
124 | ieee80211_tx_skb(sdata, skb); | ||
124 | } | 125 | } |
125 | 126 | ||
126 | static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | 127 | static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, |
@@ -138,7 +139,8 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
138 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | | 139 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | |
139 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); | 140 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); |
140 | 141 | ||
141 | ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_STOP, | 142 | ret = drv_ampdu_action(local, &sta->sdata->vif, |
143 | IEEE80211_AMPDU_TX_STOP, | ||
142 | &sta->sta, tid, NULL); | 144 | &sta->sta, tid, NULL); |
143 | 145 | ||
144 | /* HW shall not deny going back to legacy */ | 146 | /* HW shall not deny going back to legacy */ |
@@ -196,11 +198,11 @@ static inline int ieee80211_ac_from_tid(int tid) | |||
196 | return ieee802_1d_to_ac[tid & 7]; | 198 | return ieee802_1d_to_ac[tid & 7]; |
197 | } | 199 | } |
198 | 200 | ||
199 | int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | 201 | int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid) |
200 | { | 202 | { |
201 | struct ieee80211_local *local = hw_to_local(hw); | 203 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); |
202 | struct sta_info *sta; | 204 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
203 | struct ieee80211_sub_if_data *sdata; | 205 | struct ieee80211_local *local = sdata->local; |
204 | u8 *state; | 206 | u8 *state; |
205 | int ret = 0; | 207 | int ret = 0; |
206 | u16 start_seq_num; | 208 | u16 start_seq_num; |
@@ -208,52 +210,37 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
208 | if (WARN_ON(!local->ops->ampdu_action)) | 210 | if (WARN_ON(!local->ops->ampdu_action)) |
209 | return -EINVAL; | 211 | return -EINVAL; |
210 | 212 | ||
211 | if ((tid >= STA_TID_NUM) || !(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) | 213 | if ((tid >= STA_TID_NUM) || |
214 | !(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) | ||
212 | return -EINVAL; | 215 | return -EINVAL; |
213 | 216 | ||
214 | #ifdef CONFIG_MAC80211_HT_DEBUG | 217 | #ifdef CONFIG_MAC80211_HT_DEBUG |
215 | printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n", | 218 | printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n", |
216 | ra, tid); | 219 | pubsta->addr, tid); |
217 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 220 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
218 | 221 | ||
219 | rcu_read_lock(); | ||
220 | |||
221 | sta = sta_info_get(local, ra); | ||
222 | if (!sta) { | ||
223 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
224 | printk(KERN_DEBUG "Could not find the station\n"); | ||
225 | #endif | ||
226 | ret = -ENOENT; | ||
227 | goto unlock; | ||
228 | } | ||
229 | |||
230 | /* | 222 | /* |
231 | * The aggregation code is not prepared to handle | 223 | * The aggregation code is not prepared to handle |
232 | * anything but STA/AP due to the BSSID handling. | 224 | * anything but STA/AP due to the BSSID handling. |
233 | * IBSS could work in the code but isn't supported | 225 | * IBSS could work in the code but isn't supported |
234 | * by drivers or the standard. | 226 | * by drivers or the standard. |
235 | */ | 227 | */ |
236 | if (sta->sdata->vif.type != NL80211_IFTYPE_STATION && | 228 | if (sdata->vif.type != NL80211_IFTYPE_STATION && |
237 | sta->sdata->vif.type != NL80211_IFTYPE_AP_VLAN && | 229 | sdata->vif.type != NL80211_IFTYPE_AP_VLAN && |
238 | sta->sdata->vif.type != NL80211_IFTYPE_AP) { | 230 | sdata->vif.type != NL80211_IFTYPE_AP) |
239 | ret = -EINVAL; | 231 | return -EINVAL; |
240 | goto unlock; | ||
241 | } | ||
242 | 232 | ||
243 | if (test_sta_flags(sta, WLAN_STA_SUSPEND)) { | 233 | if (test_sta_flags(sta, WLAN_STA_SUSPEND)) { |
244 | #ifdef CONFIG_MAC80211_HT_DEBUG | 234 | #ifdef CONFIG_MAC80211_HT_DEBUG |
245 | printk(KERN_DEBUG "Suspend in progress. " | 235 | printk(KERN_DEBUG "Suspend in progress. " |
246 | "Denying BA session request\n"); | 236 | "Denying BA session request\n"); |
247 | #endif | 237 | #endif |
248 | ret = -EINVAL; | 238 | return -EINVAL; |
249 | goto unlock; | ||
250 | } | 239 | } |
251 | 240 | ||
252 | spin_lock_bh(&sta->lock); | 241 | spin_lock_bh(&sta->lock); |
253 | spin_lock(&local->ampdu_lock); | 242 | spin_lock(&local->ampdu_lock); |
254 | 243 | ||
255 | sdata = sta->sdata; | ||
256 | |||
257 | /* we have tried too many times, receiver does not want A-MPDU */ | 244 | /* we have tried too many times, receiver does not want A-MPDU */ |
258 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { | 245 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { |
259 | ret = -EBUSY; | 246 | ret = -EBUSY; |
@@ -310,8 +297,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
310 | 297 | ||
311 | start_seq_num = sta->tid_seq[tid]; | 298 | start_seq_num = sta->tid_seq[tid]; |
312 | 299 | ||
313 | ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_START, | 300 | ret = drv_ampdu_action(local, &sdata->vif, |
314 | &sta->sta, tid, &start_seq_num); | 301 | IEEE80211_AMPDU_TX_START, |
302 | pubsta, tid, &start_seq_num); | ||
315 | 303 | ||
316 | if (ret) { | 304 | if (ret) { |
317 | #ifdef CONFIG_MAC80211_HT_DEBUG | 305 | #ifdef CONFIG_MAC80211_HT_DEBUG |
@@ -336,7 +324,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
336 | sta->ampdu_mlme.dialog_token_allocator; | 324 | sta->ampdu_mlme.dialog_token_allocator; |
337 | sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; | 325 | sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; |
338 | 326 | ||
339 | ieee80211_send_addba_request(sta->sdata, ra, tid, | 327 | ieee80211_send_addba_request(sdata, pubsta->addr, tid, |
340 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, | 328 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, |
341 | sta->ampdu_mlme.tid_tx[tid]->ssn, | 329 | sta->ampdu_mlme.tid_tx[tid]->ssn, |
342 | 0x40, 5000); | 330 | 0x40, 5000); |
@@ -348,7 +336,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
348 | #ifdef CONFIG_MAC80211_HT_DEBUG | 336 | #ifdef CONFIG_MAC80211_HT_DEBUG |
349 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); | 337 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); |
350 | #endif | 338 | #endif |
351 | goto unlock; | 339 | return 0; |
352 | 340 | ||
353 | err_free: | 341 | err_free: |
354 | kfree(sta->ampdu_mlme.tid_tx[tid]); | 342 | kfree(sta->ampdu_mlme.tid_tx[tid]); |
@@ -360,8 +348,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
360 | err_unlock_sta: | 348 | err_unlock_sta: |
361 | spin_unlock(&local->ampdu_lock); | 349 | spin_unlock(&local->ampdu_lock); |
362 | spin_unlock_bh(&sta->lock); | 350 | spin_unlock_bh(&sta->lock); |
363 | unlock: | ||
364 | rcu_read_unlock(); | ||
365 | return ret; | 351 | return ret; |
366 | } | 352 | } |
367 | EXPORT_SYMBOL(ieee80211_start_tx_ba_session); | 353 | EXPORT_SYMBOL(ieee80211_start_tx_ba_session); |
@@ -428,13 +414,15 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local, | |||
428 | ieee80211_agg_splice_finish(local, sta, tid); | 414 | ieee80211_agg_splice_finish(local, sta, tid); |
429 | spin_unlock(&local->ampdu_lock); | 415 | spin_unlock(&local->ampdu_lock); |
430 | 416 | ||
431 | drv_ampdu_action(local, IEEE80211_AMPDU_TX_OPERATIONAL, | 417 | drv_ampdu_action(local, &sta->sdata->vif, |
418 | IEEE80211_AMPDU_TX_OPERATIONAL, | ||
432 | &sta->sta, tid, NULL); | 419 | &sta->sta, tid, NULL); |
433 | } | 420 | } |
434 | 421 | ||
435 | void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | 422 | void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) |
436 | { | 423 | { |
437 | struct ieee80211_local *local = hw_to_local(hw); | 424 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
425 | struct ieee80211_local *local = sdata->local; | ||
438 | struct sta_info *sta; | 426 | struct sta_info *sta; |
439 | u8 *state; | 427 | u8 *state; |
440 | 428 | ||
@@ -483,10 +471,11 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
483 | } | 471 | } |
484 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); | 472 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); |
485 | 473 | ||
486 | void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | 474 | void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, |
487 | const u8 *ra, u16 tid) | 475 | const u8 *ra, u16 tid) |
488 | { | 476 | { |
489 | struct ieee80211_local *local = hw_to_local(hw); | 477 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
478 | struct ieee80211_local *local = sdata->local; | ||
490 | struct ieee80211_ra_tid *ra_tid; | 479 | struct ieee80211_ra_tid *ra_tid; |
491 | struct sk_buff *skb = dev_alloc_skb(0); | 480 | struct sk_buff *skb = dev_alloc_skb(0); |
492 | 481 | ||
@@ -501,6 +490,7 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | |||
501 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 490 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
502 | memcpy(&ra_tid->ra, ra, ETH_ALEN); | 491 | memcpy(&ra_tid->ra, ra, ETH_ALEN); |
503 | ra_tid->tid = tid; | 492 | ra_tid->tid = tid; |
493 | ra_tid->vif = vif; | ||
504 | 494 | ||
505 | skb->pkt_type = IEEE80211_ADDBA_MSG; | 495 | skb->pkt_type = IEEE80211_ADDBA_MSG; |
506 | skb_queue_tail(&local->skb_queue, skb); | 496 | skb_queue_tail(&local->skb_queue, skb); |
@@ -535,13 +525,12 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
535 | return ret; | 525 | return ret; |
536 | } | 526 | } |
537 | 527 | ||
538 | int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | 528 | int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, |
539 | u8 *ra, u16 tid, | ||
540 | enum ieee80211_back_parties initiator) | 529 | enum ieee80211_back_parties initiator) |
541 | { | 530 | { |
542 | struct ieee80211_local *local = hw_to_local(hw); | 531 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); |
543 | struct sta_info *sta; | 532 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
544 | int ret = 0; | 533 | struct ieee80211_local *local = sdata->local; |
545 | 534 | ||
546 | if (WARN_ON(!local->ops->ampdu_action)) | 535 | if (WARN_ON(!local->ops->ampdu_action)) |
547 | return -EINVAL; | 536 | return -EINVAL; |
@@ -549,22 +538,14 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
549 | if (tid >= STA_TID_NUM) | 538 | if (tid >= STA_TID_NUM) |
550 | return -EINVAL; | 539 | return -EINVAL; |
551 | 540 | ||
552 | rcu_read_lock(); | 541 | return __ieee80211_stop_tx_ba_session(sta, tid, initiator); |
553 | sta = sta_info_get(local, ra); | ||
554 | if (!sta) { | ||
555 | rcu_read_unlock(); | ||
556 | return -ENOENT; | ||
557 | } | ||
558 | |||
559 | ret = __ieee80211_stop_tx_ba_session(sta, tid, initiator); | ||
560 | rcu_read_unlock(); | ||
561 | return ret; | ||
562 | } | 542 | } |
563 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); | 543 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); |
564 | 544 | ||
565 | void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | 545 | void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) |
566 | { | 546 | { |
567 | struct ieee80211_local *local = hw_to_local(hw); | 547 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
548 | struct ieee80211_local *local = sdata->local; | ||
568 | struct sta_info *sta; | 549 | struct sta_info *sta; |
569 | u8 *state; | 550 | u8 *state; |
570 | 551 | ||
@@ -627,10 +608,11 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
627 | } | 608 | } |
628 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); | 609 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); |
629 | 610 | ||
630 | void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | 611 | void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, |
631 | const u8 *ra, u16 tid) | 612 | const u8 *ra, u16 tid) |
632 | { | 613 | { |
633 | struct ieee80211_local *local = hw_to_local(hw); | 614 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
615 | struct ieee80211_local *local = sdata->local; | ||
634 | struct ieee80211_ra_tid *ra_tid; | 616 | struct ieee80211_ra_tid *ra_tid; |
635 | struct sk_buff *skb = dev_alloc_skb(0); | 617 | struct sk_buff *skb = dev_alloc_skb(0); |
636 | 618 | ||
@@ -645,6 +627,7 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | |||
645 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 627 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
646 | memcpy(&ra_tid->ra, ra, ETH_ALEN); | 628 | memcpy(&ra_tid->ra, ra, ETH_ALEN); |
647 | ra_tid->tid = tid; | 629 | ra_tid->tid = tid; |
630 | ra_tid->vif = vif; | ||
648 | 631 | ||
649 | skb->pkt_type = IEEE80211_DELBA_MSG; | 632 | skb->pkt_type = IEEE80211_DELBA_MSG; |
650 | skb_queue_tail(&local->skb_queue, skb); | 633 | skb_queue_tail(&local->skb_queue, skb); |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 7f18c8fa1880..93ee1fd5c08d 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -42,15 +42,6 @@ static bool nl80211_params_check(enum nl80211_iftype type, | |||
42 | if (!nl80211_type_check(type)) | 42 | if (!nl80211_type_check(type)) |
43 | return false; | 43 | return false; |
44 | 44 | ||
45 | if (params->use_4addr > 0) { | ||
46 | switch(type) { | ||
47 | case NL80211_IFTYPE_AP_VLAN: | ||
48 | case NL80211_IFTYPE_STATION: | ||
49 | break; | ||
50 | default: | ||
51 | return false; | ||
52 | } | ||
53 | } | ||
54 | return true; | 45 | return true; |
55 | } | 46 | } |
56 | 47 | ||
@@ -107,12 +98,16 @@ static int ieee80211_change_iface(struct wiphy *wiphy, | |||
107 | params->mesh_id_len, | 98 | params->mesh_id_len, |
108 | params->mesh_id); | 99 | params->mesh_id); |
109 | 100 | ||
110 | if (params->use_4addr >= 0) | ||
111 | sdata->use_4addr = !!params->use_4addr; | ||
112 | |||
113 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags) | 101 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags) |
114 | return 0; | 102 | return 0; |
115 | 103 | ||
104 | if (type == NL80211_IFTYPE_AP_VLAN && | ||
105 | params && params->use_4addr == 0) | ||
106 | rcu_assign_pointer(sdata->u.vlan.sta, NULL); | ||
107 | else if (type == NL80211_IFTYPE_STATION && | ||
108 | params && params->use_4addr >= 0) | ||
109 | sdata->u.mgd.use_4addr = params->use_4addr; | ||
110 | |||
116 | sdata->u.mntr_flags = *flags; | 111 | sdata->u.mntr_flags = *flags; |
117 | return 0; | 112 | return 0; |
118 | } | 113 | } |
@@ -398,13 +393,13 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
398 | static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, | 393 | static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, |
399 | int idx, u8 *mac, struct station_info *sinfo) | 394 | int idx, u8 *mac, struct station_info *sinfo) |
400 | { | 395 | { |
401 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 396 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
402 | struct sta_info *sta; | 397 | struct sta_info *sta; |
403 | int ret = -ENOENT; | 398 | int ret = -ENOENT; |
404 | 399 | ||
405 | rcu_read_lock(); | 400 | rcu_read_lock(); |
406 | 401 | ||
407 | sta = sta_info_get_by_idx(local, idx, dev); | 402 | sta = sta_info_get_by_idx(sdata, idx); |
408 | if (sta) { | 403 | if (sta) { |
409 | ret = 0; | 404 | ret = 0; |
410 | memcpy(mac, sta->sta.addr, ETH_ALEN); | 405 | memcpy(mac, sta->sta.addr, ETH_ALEN); |
@@ -827,9 +822,11 @@ static int ieee80211_change_station(struct wiphy *wiphy, | |||
827 | return -EINVAL; | 822 | return -EINVAL; |
828 | } | 823 | } |
829 | 824 | ||
830 | if (vlansdata->use_4addr) { | 825 | if (params->vlan->ieee80211_ptr->use_4addr) { |
831 | if (vlansdata->u.vlan.sta) | 826 | if (vlansdata->u.vlan.sta) { |
827 | rcu_read_unlock(); | ||
832 | return -EBUSY; | 828 | return -EBUSY; |
829 | } | ||
833 | 830 | ||
834 | rcu_assign_pointer(vlansdata->u.vlan.sta, sta); | 831 | rcu_assign_pointer(vlansdata->u.vlan.sta, sta); |
835 | } | 832 | } |
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 82c807723b6f..e4b54093d41b 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -52,7 +52,7 @@ DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d", | |||
52 | DEBUGFS_READONLY_FILE(wep_iv, 20, "%#08x", | 52 | DEBUGFS_READONLY_FILE(wep_iv, 20, "%#08x", |
53 | local->wep_iv & 0xffffff); | 53 | local->wep_iv & 0xffffff); |
54 | DEBUGFS_READONLY_FILE(rate_ctrl_alg, 100, "%s", | 54 | DEBUGFS_READONLY_FILE(rate_ctrl_alg, 100, "%s", |
55 | local->rate_ctrl ? local->rate_ctrl->ops->name : "<unset>"); | 55 | local->rate_ctrl ? local->rate_ctrl->ops->name : "hw/driver"); |
56 | 56 | ||
57 | static ssize_t tsf_read(struct file *file, char __user *user_buf, | 57 | static ssize_t tsf_read(struct file *file, char __user *user_buf, |
58 | size_t count, loff_t *ppos) | 58 | size_t count, loff_t *ppos) |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index f043c29070d7..3f41608c8081 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -157,6 +157,34 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, | |||
157 | } | 157 | } |
158 | STA_OPS(agg_status); | 158 | STA_OPS(agg_status); |
159 | 159 | ||
160 | static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf, | ||
161 | size_t count, loff_t *ppos) | ||
162 | { | ||
163 | char buf[200], *p = buf; | ||
164 | int i; | ||
165 | struct sta_info *sta = file->private_data; | ||
166 | struct ieee80211_sta_ht_cap *htc = &sta->sta.ht_cap; | ||
167 | |||
168 | p += scnprintf(p, sizeof(buf) + buf - p, "ht %ssupported\n", | ||
169 | htc->ht_supported ? "" : "not "); | ||
170 | if (htc->ht_supported) { | ||
171 | p += scnprintf(p, sizeof(buf)+buf-p, "cap: %#.2x\n", htc->cap); | ||
172 | p += scnprintf(p, sizeof(buf)+buf-p, "ampdu factor/density: %d/%d\n", | ||
173 | htc->ampdu_factor, htc->ampdu_density); | ||
174 | p += scnprintf(p, sizeof(buf)+buf-p, "MCS mask:"); | ||
175 | for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) | ||
176 | p += scnprintf(p, sizeof(buf)+buf-p, " %.2x", | ||
177 | htc->mcs.rx_mask[i]); | ||
178 | p += scnprintf(p, sizeof(buf)+buf-p, "\nMCS rx highest: %d\n", | ||
179 | le16_to_cpu(htc->mcs.rx_highest)); | ||
180 | p += scnprintf(p, sizeof(buf)+buf-p, "MCS tx params: %x\n", | ||
181 | htc->mcs.tx_params); | ||
182 | } | ||
183 | |||
184 | return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); | ||
185 | } | ||
186 | STA_OPS(ht_capa); | ||
187 | |||
160 | #define DEBUGFS_ADD(name) \ | 188 | #define DEBUGFS_ADD(name) \ |
161 | debugfs_create_file(#name, 0400, \ | 189 | debugfs_create_file(#name, 0400, \ |
162 | sta->debugfs.dir, sta, &sta_ ##name## _ops); | 190 | sta->debugfs.dir, sta, &sta_ ##name## _ops); |
@@ -207,6 +235,7 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta) | |||
207 | DEBUGFS_ADD(last_signal); | 235 | DEBUGFS_ADD(last_signal); |
208 | DEBUGFS_ADD(last_noise); | 236 | DEBUGFS_ADD(last_noise); |
209 | DEBUGFS_ADD(wep_weak_iv_count); | 237 | DEBUGFS_ADD(wep_weak_iv_count); |
238 | DEBUGFS_ADD(ht_capa); | ||
210 | } | 239 | } |
211 | 240 | ||
212 | void ieee80211_sta_debugfs_remove(struct sta_info *sta) | 241 | void ieee80211_sta_debugfs_remove(struct sta_info *sta) |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 020a94a31106..921dd9c9ff62 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -239,15 +239,16 @@ static inline int drv_tx_last_beacon(struct ieee80211_local *local) | |||
239 | } | 239 | } |
240 | 240 | ||
241 | static inline int drv_ampdu_action(struct ieee80211_local *local, | 241 | static inline int drv_ampdu_action(struct ieee80211_local *local, |
242 | struct ieee80211_vif *vif, | ||
242 | enum ieee80211_ampdu_mlme_action action, | 243 | enum ieee80211_ampdu_mlme_action action, |
243 | struct ieee80211_sta *sta, u16 tid, | 244 | struct ieee80211_sta *sta, u16 tid, |
244 | u16 *ssn) | 245 | u16 *ssn) |
245 | { | 246 | { |
246 | int ret = -EOPNOTSUPP; | 247 | int ret = -EOPNOTSUPP; |
247 | if (local->ops->ampdu_action) | 248 | if (local->ops->ampdu_action) |
248 | ret = local->ops->ampdu_action(&local->hw, action, | 249 | ret = local->ops->ampdu_action(&local->hw, vif, action, |
249 | sta, tid, ssn); | 250 | sta, tid, ssn); |
250 | trace_drv_ampdu_action(local, action, sta, tid, ssn, ret); | 251 | trace_drv_ampdu_action(local, vif, action, sta, tid, ssn, ret); |
251 | return ret; | 252 | return ret; |
252 | } | 253 | } |
253 | 254 | ||
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 37b9051afcf3..b8fef1d11369 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h | |||
@@ -634,11 +634,12 @@ TRACE_EVENT(drv_tx_last_beacon, | |||
634 | 634 | ||
635 | TRACE_EVENT(drv_ampdu_action, | 635 | TRACE_EVENT(drv_ampdu_action, |
636 | TP_PROTO(struct ieee80211_local *local, | 636 | TP_PROTO(struct ieee80211_local *local, |
637 | struct ieee80211_vif *vif, | ||
637 | enum ieee80211_ampdu_mlme_action action, | 638 | enum ieee80211_ampdu_mlme_action action, |
638 | struct ieee80211_sta *sta, u16 tid, | 639 | struct ieee80211_sta *sta, u16 tid, |
639 | u16 *ssn, int ret), | 640 | u16 *ssn, int ret), |
640 | 641 | ||
641 | TP_ARGS(local, action, sta, tid, ssn, ret), | 642 | TP_ARGS(local, vif, action, sta, tid, ssn, ret), |
642 | 643 | ||
643 | TP_STRUCT__entry( | 644 | TP_STRUCT__entry( |
644 | LOCAL_ENTRY | 645 | LOCAL_ENTRY |
@@ -647,10 +648,12 @@ TRACE_EVENT(drv_ampdu_action, | |||
647 | __field(u16, tid) | 648 | __field(u16, tid) |
648 | __field(u16, ssn) | 649 | __field(u16, ssn) |
649 | __field(int, ret) | 650 | __field(int, ret) |
651 | VIF_ENTRY | ||
650 | ), | 652 | ), |
651 | 653 | ||
652 | TP_fast_assign( | 654 | TP_fast_assign( |
653 | LOCAL_ASSIGN; | 655 | LOCAL_ASSIGN; |
656 | VIF_ASSIGN; | ||
654 | STA_ASSIGN; | 657 | STA_ASSIGN; |
655 | __entry->ret = ret; | 658 | __entry->ret = ret; |
656 | __entry->action = action; | 659 | __entry->action = action; |
@@ -659,8 +662,8 @@ TRACE_EVENT(drv_ampdu_action, | |||
659 | ), | 662 | ), |
660 | 663 | ||
661 | TP_printk( | 664 | TP_printk( |
662 | LOCAL_PR_FMT STA_PR_FMT " action:%d tid:%d ret:%d", | 665 | LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " action:%d tid:%d ret:%d", |
663 | LOCAL_PR_ARG, STA_PR_ARG, __entry->action, __entry->tid, __entry->ret | 666 | LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->action, __entry->tid, __entry->ret |
664 | ) | 667 | ) |
665 | ); | 668 | ); |
666 | #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ | 669 | #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 48ef1a282b91..15c9d4f94cee 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -134,14 +134,13 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, | |||
134 | mgmt->u.action.u.delba.params = cpu_to_le16(params); | 134 | mgmt->u.action.u.delba.params = cpu_to_le16(params); |
135 | mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code); | 135 | mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code); |
136 | 136 | ||
137 | ieee80211_tx_skb(sdata, skb, 1); | 137 | ieee80211_tx_skb(sdata, skb); |
138 | } | 138 | } |
139 | 139 | ||
140 | void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | 140 | void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, |
141 | struct sta_info *sta, | 141 | struct sta_info *sta, |
142 | struct ieee80211_mgmt *mgmt, size_t len) | 142 | struct ieee80211_mgmt *mgmt, size_t len) |
143 | { | 143 | { |
144 | struct ieee80211_local *local = sdata->local; | ||
145 | u16 tid, params; | 144 | u16 tid, params; |
146 | u16 initiator; | 145 | u16 initiator; |
147 | 146 | ||
@@ -164,7 +163,7 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | |||
164 | sta->ampdu_mlme.tid_state_tx[tid] = | 163 | sta->ampdu_mlme.tid_state_tx[tid] = |
165 | HT_AGG_STATE_OPERATIONAL; | 164 | HT_AGG_STATE_OPERATIONAL; |
166 | spin_unlock_bh(&sta->lock); | 165 | spin_unlock_bh(&sta->lock); |
167 | ieee80211_stop_tx_ba_session(&local->hw, sta->sta.addr, tid, | 166 | ieee80211_stop_tx_ba_session(&sta->sta, tid, |
168 | WLAN_BACK_RECIPIENT); | 167 | WLAN_BACK_RECIPIENT); |
169 | } | 168 | } |
170 | } | 169 | } |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index fbffce90edbc..10d13856f86c 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -659,7 +659,8 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
659 | printk(KERN_DEBUG "%s: Sending ProbeResp to %pM\n", | 659 | printk(KERN_DEBUG "%s: Sending ProbeResp to %pM\n", |
660 | sdata->dev->name, resp->da); | 660 | sdata->dev->name, resp->da); |
661 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 661 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
662 | ieee80211_tx_skb(sdata, skb, 0); | 662 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
663 | ieee80211_tx_skb(sdata, skb); | ||
663 | } | 664 | } |
664 | 665 | ||
665 | static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | 666 | static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index b63b99fb2fd3..04093e84ebd7 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
25 | #include <linux/etherdevice.h> | 25 | #include <linux/etherdevice.h> |
26 | #include <net/ieee80211_radiotap.h> | ||
26 | #include <net/cfg80211.h> | 27 | #include <net/cfg80211.h> |
27 | #include <net/mac80211.h> | 28 | #include <net/mac80211.h> |
28 | #include "key.h" | 29 | #include "key.h" |
@@ -167,13 +168,10 @@ typedef unsigned __bitwise__ ieee80211_rx_result; | |||
167 | 168 | ||
168 | struct ieee80211_rx_data { | 169 | struct ieee80211_rx_data { |
169 | struct sk_buff *skb; | 170 | struct sk_buff *skb; |
170 | struct net_device *dev; | ||
171 | struct ieee80211_local *local; | 171 | struct ieee80211_local *local; |
172 | struct ieee80211_sub_if_data *sdata; | 172 | struct ieee80211_sub_if_data *sdata; |
173 | struct sta_info *sta; | 173 | struct sta_info *sta; |
174 | struct ieee80211_key *key; | 174 | struct ieee80211_key *key; |
175 | struct ieee80211_rx_status *status; | ||
176 | struct ieee80211_rate *rate; | ||
177 | 175 | ||
178 | unsigned int flags; | 176 | unsigned int flags; |
179 | int queue; | 177 | int queue; |
@@ -314,6 +312,8 @@ struct ieee80211_if_managed { | |||
314 | } mfp; /* management frame protection */ | 312 | } mfp; /* management frame protection */ |
315 | 313 | ||
316 | int wmm_last_param_set; | 314 | int wmm_last_param_set; |
315 | |||
316 | u8 use_4addr; | ||
317 | }; | 317 | }; |
318 | 318 | ||
319 | enum ieee80211_ibss_request { | 319 | enum ieee80211_ibss_request { |
@@ -461,8 +461,6 @@ struct ieee80211_sub_if_data { | |||
461 | int force_unicast_rateidx; /* forced TX rateidx for unicast frames */ | 461 | int force_unicast_rateidx; /* forced TX rateidx for unicast frames */ |
462 | int max_ratectrl_rateidx; /* max TX rateidx for rate control */ | 462 | int max_ratectrl_rateidx; /* max TX rateidx for rate control */ |
463 | 463 | ||
464 | bool use_4addr; /* use 4-address frames */ | ||
465 | |||
466 | union { | 464 | union { |
467 | struct ieee80211_if_ap ap; | 465 | struct ieee80211_if_ap ap; |
468 | struct ieee80211_if_wds wds; | 466 | struct ieee80211_if_wds wds; |
@@ -581,7 +579,6 @@ struct ieee80211_local { | |||
581 | /* number of interfaces with corresponding FIF_ flags */ | 579 | /* number of interfaces with corresponding FIF_ flags */ |
582 | int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll; | 580 | int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll; |
583 | unsigned int filter_flags; /* FIF_* */ | 581 | unsigned int filter_flags; /* FIF_* */ |
584 | struct iw_statistics wstats; | ||
585 | 582 | ||
586 | /* protects the aggregated multicast list and filter calls */ | 583 | /* protects the aggregated multicast list and filter calls */ |
587 | spinlock_t filter_lock; | 584 | spinlock_t filter_lock; |
@@ -771,8 +768,9 @@ IEEE80211_DEV_TO_SUB_IF(struct net_device *dev) | |||
771 | return netdev_priv(dev); | 768 | return netdev_priv(dev); |
772 | } | 769 | } |
773 | 770 | ||
774 | /* this struct represents 802.11n's RA/TID combination */ | 771 | /* this struct represents 802.11n's RA/TID combination along with our vif */ |
775 | struct ieee80211_ra_tid { | 772 | struct ieee80211_ra_tid { |
773 | struct ieee80211_vif *vif; | ||
776 | u8 ra[ETH_ALEN]; | 774 | u8 ra[ETH_ALEN]; |
777 | u16 tid; | 775 | u16 tid; |
778 | }; | 776 | }; |
@@ -799,7 +797,7 @@ struct ieee802_11_elems { | |||
799 | u8 *wmm_param; | 797 | u8 *wmm_param; |
800 | struct ieee80211_ht_cap *ht_cap_elem; | 798 | struct ieee80211_ht_cap *ht_cap_elem; |
801 | struct ieee80211_ht_info *ht_info_elem; | 799 | struct ieee80211_ht_info *ht_info_elem; |
802 | u8 *mesh_config; | 800 | struct ieee80211_meshconf_ie *mesh_config; |
803 | u8 *mesh_id; | 801 | u8 *mesh_id; |
804 | u8 *peer_link; | 802 | u8 *peer_link; |
805 | u8 *preq; | 803 | u8 *preq; |
@@ -827,7 +825,6 @@ struct ieee802_11_elems { | |||
827 | u8 ext_supp_rates_len; | 825 | u8 ext_supp_rates_len; |
828 | u8 wmm_info_len; | 826 | u8 wmm_info_len; |
829 | u8 wmm_param_len; | 827 | u8 wmm_param_len; |
830 | u8 mesh_config_len; | ||
831 | u8 mesh_id_len; | 828 | u8 mesh_id_len; |
832 | u8 peer_link_len; | 829 | u8 peer_link_len; |
833 | u8 preq_len; | 830 | u8 preq_len; |
@@ -950,6 +947,18 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
950 | netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | 947 | netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, |
951 | struct net_device *dev); | 948 | struct net_device *dev); |
952 | 949 | ||
950 | /* | ||
951 | * radiotap header for status frames | ||
952 | */ | ||
953 | struct ieee80211_tx_status_rtap_hdr { | ||
954 | struct ieee80211_radiotap_header hdr; | ||
955 | u8 rate; | ||
956 | u8 padding_for_rate; | ||
957 | __le16 tx_flags; | ||
958 | u8 data_retries; | ||
959 | } __attribute__ ((packed)); | ||
960 | |||
961 | |||
953 | /* HT */ | 962 | /* HT */ |
954 | void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, | 963 | void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, |
955 | struct ieee80211_ht_cap *ht_cap_ie, | 964 | struct ieee80211_ht_cap *ht_cap_ie, |
@@ -1017,8 +1026,7 @@ void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int ke | |||
1017 | struct ieee80211_hdr *hdr, const u8 *tsc, | 1026 | struct ieee80211_hdr *hdr, const u8 *tsc, |
1018 | gfp_t gfp); | 1027 | gfp_t gfp); |
1019 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata); | 1028 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata); |
1020 | void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, | 1029 | void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); |
1021 | int encrypt); | ||
1022 | void ieee802_11_parse_elems(u8 *start, size_t len, | 1030 | void ieee802_11_parse_elems(u8 *start, size_t len, |
1023 | struct ieee802_11_elems *elems); | 1031 | struct ieee802_11_elems *elems); |
1024 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | 1032 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 1f02b0610e82..1bf12a26b45e 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -752,7 +752,8 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
752 | ieee80211_mandatory_rates(sdata->local, | 752 | ieee80211_mandatory_rates(sdata->local, |
753 | sdata->local->hw.conf.channel->band); | 753 | sdata->local->hw.conf.channel->band); |
754 | sdata->drop_unencrypted = 0; | 754 | sdata->drop_unencrypted = 0; |
755 | sdata->use_4addr = 0; | 755 | if (type == NL80211_IFTYPE_STATION) |
756 | sdata->u.mgd.use_4addr = false; | ||
756 | 757 | ||
757 | return 0; | 758 | return 0; |
758 | } | 759 | } |
@@ -810,6 +811,12 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
810 | /* setup type-dependent data */ | 811 | /* setup type-dependent data */ |
811 | ieee80211_setup_sdata(sdata, type); | 812 | ieee80211_setup_sdata(sdata, type); |
812 | 813 | ||
814 | if (params) { | ||
815 | ndev->ieee80211_ptr->use_4addr = params->use_4addr; | ||
816 | if (type == NL80211_IFTYPE_STATION) | ||
817 | sdata->u.mgd.use_4addr = params->use_4addr; | ||
818 | } | ||
819 | |||
813 | ret = register_netdevice(ndev); | 820 | ret = register_netdevice(ndev); |
814 | if (ret) | 821 | if (ret) |
815 | goto fail; | 822 | goto fail; |
@@ -820,9 +827,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
820 | params->mesh_id_len, | 827 | params->mesh_id_len, |
821 | params->mesh_id); | 828 | params->mesh_id); |
822 | 829 | ||
823 | if (params && params->use_4addr >= 0) | ||
824 | sdata->use_4addr = !!params->use_4addr; | ||
825 | |||
826 | mutex_lock(&local->iflist_mtx); | 830 | mutex_lock(&local->iflist_mtx); |
827 | list_add_tail_rcu(&sdata->list, &local->interfaces); | 831 | list_add_tail_rcu(&sdata->list, &local->interfaces); |
828 | mutex_unlock(&local->iflist_mtx); | 832 | mutex_unlock(&local->iflist_mtx); |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index beb8718d905e..dd8ec8d5e8b2 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -9,7 +9,6 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <net/mac80211.h> | 11 | #include <net/mac80211.h> |
12 | #include <net/ieee80211_radiotap.h> | ||
13 | #include <linux/module.h> | 12 | #include <linux/module.h> |
14 | #include <linux/init.h> | 13 | #include <linux/init.h> |
15 | #include <linux/netdevice.h> | 14 | #include <linux/netdevice.h> |
@@ -30,26 +29,11 @@ | |||
30 | #include "rate.h" | 29 | #include "rate.h" |
31 | #include "mesh.h" | 30 | #include "mesh.h" |
32 | #include "wep.h" | 31 | #include "wep.h" |
33 | #include "wme.h" | ||
34 | #include "aes_ccm.h" | ||
35 | #include "led.h" | 32 | #include "led.h" |
36 | #include "cfg.h" | 33 | #include "cfg.h" |
37 | #include "debugfs.h" | 34 | #include "debugfs.h" |
38 | #include "debugfs_netdev.h" | 35 | #include "debugfs_netdev.h" |
39 | 36 | ||
40 | /* | ||
41 | * For seeing transmitted packets on monitor interfaces | ||
42 | * we have a radiotap header too. | ||
43 | */ | ||
44 | struct ieee80211_tx_status_rtap_hdr { | ||
45 | struct ieee80211_radiotap_header hdr; | ||
46 | u8 rate; | ||
47 | u8 padding_for_rate; | ||
48 | __le16 tx_flags; | ||
49 | u8 data_retries; | ||
50 | } __attribute__ ((packed)); | ||
51 | |||
52 | |||
53 | void ieee80211_configure_filter(struct ieee80211_local *local) | 37 | void ieee80211_configure_filter(struct ieee80211_local *local) |
54 | { | 38 | { |
55 | u64 mc; | 39 | u64 mc; |
@@ -253,28 +237,6 @@ u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) | |||
253 | BSS_CHANGED_ERP_SLOT; | 237 | BSS_CHANGED_ERP_SLOT; |
254 | } | 238 | } |
255 | 239 | ||
256 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, | ||
257 | struct sk_buff *skb) | ||
258 | { | ||
259 | struct ieee80211_local *local = hw_to_local(hw); | ||
260 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
261 | int tmp; | ||
262 | |||
263 | skb->pkt_type = IEEE80211_TX_STATUS_MSG; | ||
264 | skb_queue_tail(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS ? | ||
265 | &local->skb_queue : &local->skb_queue_unreliable, skb); | ||
266 | tmp = skb_queue_len(&local->skb_queue) + | ||
267 | skb_queue_len(&local->skb_queue_unreliable); | ||
268 | while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT && | ||
269 | (skb = skb_dequeue(&local->skb_queue_unreliable))) { | ||
270 | dev_kfree_skb_irq(skb); | ||
271 | tmp--; | ||
272 | I802_DEBUG_INC(local->tx_status_drop); | ||
273 | } | ||
274 | tasklet_schedule(&local->tasklet); | ||
275 | } | ||
276 | EXPORT_SYMBOL(ieee80211_tx_status_irqsafe); | ||
277 | |||
278 | static void ieee80211_tasklet_handler(unsigned long data) | 240 | static void ieee80211_tasklet_handler(unsigned long data) |
279 | { | 241 | { |
280 | struct ieee80211_local *local = (struct ieee80211_local *) data; | 242 | struct ieee80211_local *local = (struct ieee80211_local *) data; |
@@ -296,14 +258,14 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
296 | break; | 258 | break; |
297 | case IEEE80211_DELBA_MSG: | 259 | case IEEE80211_DELBA_MSG: |
298 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 260 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
299 | ieee80211_stop_tx_ba_cb(local_to_hw(local), | 261 | ieee80211_stop_tx_ba_cb(ra_tid->vif, ra_tid->ra, |
300 | ra_tid->ra, ra_tid->tid); | 262 | ra_tid->tid); |
301 | dev_kfree_skb(skb); | 263 | dev_kfree_skb(skb); |
302 | break; | 264 | break; |
303 | case IEEE80211_ADDBA_MSG: | 265 | case IEEE80211_ADDBA_MSG: |
304 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 266 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
305 | ieee80211_start_tx_ba_cb(local_to_hw(local), | 267 | ieee80211_start_tx_ba_cb(ra_tid->vif, ra_tid->ra, |
306 | ra_tid->ra, ra_tid->tid); | 268 | ra_tid->tid); |
307 | dev_kfree_skb(skb); | 269 | dev_kfree_skb(skb); |
308 | break ; | 270 | break ; |
309 | default: | 271 | default: |
@@ -315,299 +277,6 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
315 | } | 277 | } |
316 | } | 278 | } |
317 | 279 | ||
318 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | ||
319 | struct sta_info *sta, | ||
320 | struct sk_buff *skb) | ||
321 | { | ||
322 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
323 | |||
324 | /* | ||
325 | * XXX: This is temporary! | ||
326 | * | ||
327 | * The problem here is that when we get here, the driver will | ||
328 | * quite likely have pretty much overwritten info->control by | ||
329 | * using info->driver_data or info->rate_driver_data. Thus, | ||
330 | * when passing out the frame to the driver again, we would be | ||
331 | * passing completely bogus data since the driver would then | ||
332 | * expect a properly filled info->control. In mac80211 itself | ||
333 | * the same problem occurs, since we need info->control.vif | ||
334 | * internally. | ||
335 | * | ||
336 | * To fix this, we should send the frame through TX processing | ||
337 | * again. However, it's not that simple, since the frame will | ||
338 | * have been software-encrypted (if applicable) already, and | ||
339 | * encrypting it again doesn't do much good. So to properly do | ||
340 | * that, we not only have to skip the actual 'raw' encryption | ||
341 | * (key selection etc. still has to be done!) but also the | ||
342 | * sequence number assignment since that impacts the crypto | ||
343 | * encapsulation, of course. | ||
344 | * | ||
345 | * Hence, for now, fix the bug by just dropping the frame. | ||
346 | */ | ||
347 | goto drop; | ||
348 | |||
349 | sta->tx_filtered_count++; | ||
350 | |||
351 | /* | ||
352 | * Clear the TX filter mask for this STA when sending the next | ||
353 | * packet. If the STA went to power save mode, this will happen | ||
354 | * when it wakes up for the next time. | ||
355 | */ | ||
356 | set_sta_flags(sta, WLAN_STA_CLEAR_PS_FILT); | ||
357 | |||
358 | /* | ||
359 | * This code races in the following way: | ||
360 | * | ||
361 | * (1) STA sends frame indicating it will go to sleep and does so | ||
362 | * (2) hardware/firmware adds STA to filter list, passes frame up | ||
363 | * (3) hardware/firmware processes TX fifo and suppresses a frame | ||
364 | * (4) we get TX status before having processed the frame and | ||
365 | * knowing that the STA has gone to sleep. | ||
366 | * | ||
367 | * This is actually quite unlikely even when both those events are | ||
368 | * processed from interrupts coming in quickly after one another or | ||
369 | * even at the same time because we queue both TX status events and | ||
370 | * RX frames to be processed by a tasklet and process them in the | ||
371 | * same order that they were received or TX status last. Hence, there | ||
372 | * is no race as long as the frame RX is processed before the next TX | ||
373 | * status, which drivers can ensure, see below. | ||
374 | * | ||
375 | * Note that this can only happen if the hardware or firmware can | ||
376 | * actually add STAs to the filter list, if this is done by the | ||
377 | * driver in response to set_tim() (which will only reduce the race | ||
378 | * this whole filtering tries to solve, not completely solve it) | ||
379 | * this situation cannot happen. | ||
380 | * | ||
381 | * To completely solve this race drivers need to make sure that they | ||
382 | * (a) don't mix the irq-safe/not irq-safe TX status/RX processing | ||
383 | * functions and | ||
384 | * (b) always process RX events before TX status events if ordering | ||
385 | * can be unknown, for example with different interrupt status | ||
386 | * bits. | ||
387 | */ | ||
388 | if (test_sta_flags(sta, WLAN_STA_PS_STA) && | ||
389 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { | ||
390 | skb_queue_tail(&sta->tx_filtered, skb); | ||
391 | return; | ||
392 | } | ||
393 | |||
394 | if (!test_sta_flags(sta, WLAN_STA_PS_STA) && | ||
395 | !(info->flags & IEEE80211_TX_INTFL_RETRIED)) { | ||
396 | /* Software retry the packet once */ | ||
397 | info->flags |= IEEE80211_TX_INTFL_RETRIED; | ||
398 | ieee80211_add_pending_skb(local, skb); | ||
399 | return; | ||
400 | } | ||
401 | |||
402 | drop: | ||
403 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
404 | if (net_ratelimit()) | ||
405 | printk(KERN_DEBUG "%s: dropped TX filtered frame, " | ||
406 | "queue_len=%d PS=%d @%lu\n", | ||
407 | wiphy_name(local->hw.wiphy), | ||
408 | skb_queue_len(&sta->tx_filtered), | ||
409 | !!test_sta_flags(sta, WLAN_STA_PS_STA), jiffies); | ||
410 | #endif | ||
411 | dev_kfree_skb(skb); | ||
412 | } | ||
413 | |||
414 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
415 | { | ||
416 | struct sk_buff *skb2; | ||
417 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
418 | struct ieee80211_local *local = hw_to_local(hw); | ||
419 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
420 | u16 frag, type; | ||
421 | __le16 fc; | ||
422 | struct ieee80211_supported_band *sband; | ||
423 | struct ieee80211_tx_status_rtap_hdr *rthdr; | ||
424 | struct ieee80211_sub_if_data *sdata; | ||
425 | struct net_device *prev_dev = NULL; | ||
426 | struct sta_info *sta; | ||
427 | int retry_count = -1, i; | ||
428 | |||
429 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | ||
430 | /* the HW cannot have attempted that rate */ | ||
431 | if (i >= hw->max_rates) { | ||
432 | info->status.rates[i].idx = -1; | ||
433 | info->status.rates[i].count = 0; | ||
434 | } | ||
435 | |||
436 | retry_count += info->status.rates[i].count; | ||
437 | } | ||
438 | if (retry_count < 0) | ||
439 | retry_count = 0; | ||
440 | |||
441 | rcu_read_lock(); | ||
442 | |||
443 | sband = local->hw.wiphy->bands[info->band]; | ||
444 | |||
445 | sta = sta_info_get(local, hdr->addr1); | ||
446 | |||
447 | if (sta) { | ||
448 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && | ||
449 | test_sta_flags(sta, WLAN_STA_PS_STA)) { | ||
450 | /* | ||
451 | * The STA is in power save mode, so assume | ||
452 | * that this TX packet failed because of that. | ||
453 | */ | ||
454 | ieee80211_handle_filtered_frame(local, sta, skb); | ||
455 | rcu_read_unlock(); | ||
456 | return; | ||
457 | } | ||
458 | |||
459 | fc = hdr->frame_control; | ||
460 | |||
461 | if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && | ||
462 | (ieee80211_is_data_qos(fc))) { | ||
463 | u16 tid, ssn; | ||
464 | u8 *qc; | ||
465 | |||
466 | qc = ieee80211_get_qos_ctl(hdr); | ||
467 | tid = qc[0] & 0xf; | ||
468 | ssn = ((le16_to_cpu(hdr->seq_ctrl) + 0x10) | ||
469 | & IEEE80211_SCTL_SEQ); | ||
470 | ieee80211_send_bar(sta->sdata, hdr->addr1, | ||
471 | tid, ssn); | ||
472 | } | ||
473 | |||
474 | if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) { | ||
475 | ieee80211_handle_filtered_frame(local, sta, skb); | ||
476 | rcu_read_unlock(); | ||
477 | return; | ||
478 | } else { | ||
479 | if (!(info->flags & IEEE80211_TX_STAT_ACK)) | ||
480 | sta->tx_retry_failed++; | ||
481 | sta->tx_retry_count += retry_count; | ||
482 | } | ||
483 | |||
484 | rate_control_tx_status(local, sband, sta, skb); | ||
485 | if (ieee80211_vif_is_mesh(&sta->sdata->vif)) | ||
486 | ieee80211s_update_metric(local, sta, skb); | ||
487 | } | ||
488 | |||
489 | rcu_read_unlock(); | ||
490 | |||
491 | ieee80211_led_tx(local, 0); | ||
492 | |||
493 | /* SNMP counters | ||
494 | * Fragments are passed to low-level drivers as separate skbs, so these | ||
495 | * are actually fragments, not frames. Update frame counters only for | ||
496 | * the first fragment of the frame. */ | ||
497 | |||
498 | frag = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; | ||
499 | type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE; | ||
500 | |||
501 | if (info->flags & IEEE80211_TX_STAT_ACK) { | ||
502 | if (frag == 0) { | ||
503 | local->dot11TransmittedFrameCount++; | ||
504 | if (is_multicast_ether_addr(hdr->addr1)) | ||
505 | local->dot11MulticastTransmittedFrameCount++; | ||
506 | if (retry_count > 0) | ||
507 | local->dot11RetryCount++; | ||
508 | if (retry_count > 1) | ||
509 | local->dot11MultipleRetryCount++; | ||
510 | } | ||
511 | |||
512 | /* This counter shall be incremented for an acknowledged MPDU | ||
513 | * with an individual address in the address 1 field or an MPDU | ||
514 | * with a multicast address in the address 1 field of type Data | ||
515 | * or Management. */ | ||
516 | if (!is_multicast_ether_addr(hdr->addr1) || | ||
517 | type == IEEE80211_FTYPE_DATA || | ||
518 | type == IEEE80211_FTYPE_MGMT) | ||
519 | local->dot11TransmittedFragmentCount++; | ||
520 | } else { | ||
521 | if (frag == 0) | ||
522 | local->dot11FailedCount++; | ||
523 | } | ||
524 | |||
525 | /* this was a transmitted frame, but now we want to reuse it */ | ||
526 | skb_orphan(skb); | ||
527 | |||
528 | /* | ||
529 | * This is a bit racy but we can avoid a lot of work | ||
530 | * with this test... | ||
531 | */ | ||
532 | if (!local->monitors && !local->cooked_mntrs) { | ||
533 | dev_kfree_skb(skb); | ||
534 | return; | ||
535 | } | ||
536 | |||
537 | /* send frame to monitor interfaces now */ | ||
538 | |||
539 | if (skb_headroom(skb) < sizeof(*rthdr)) { | ||
540 | printk(KERN_ERR "ieee80211_tx_status: headroom too small\n"); | ||
541 | dev_kfree_skb(skb); | ||
542 | return; | ||
543 | } | ||
544 | |||
545 | rthdr = (struct ieee80211_tx_status_rtap_hdr *) | ||
546 | skb_push(skb, sizeof(*rthdr)); | ||
547 | |||
548 | memset(rthdr, 0, sizeof(*rthdr)); | ||
549 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); | ||
550 | rthdr->hdr.it_present = | ||
551 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | | ||
552 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES) | | ||
553 | (1 << IEEE80211_RADIOTAP_RATE)); | ||
554 | |||
555 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && | ||
556 | !is_multicast_ether_addr(hdr->addr1)) | ||
557 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); | ||
558 | |||
559 | /* | ||
560 | * XXX: Once radiotap gets the bitmap reset thing the vendor | ||
561 | * extensions proposal contains, we can actually report | ||
562 | * the whole set of tries we did. | ||
563 | */ | ||
564 | if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || | ||
565 | (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) | ||
566 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); | ||
567 | else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) | ||
568 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); | ||
569 | if (info->status.rates[0].idx >= 0 && | ||
570 | !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) | ||
571 | rthdr->rate = sband->bitrates[ | ||
572 | info->status.rates[0].idx].bitrate / 5; | ||
573 | |||
574 | /* for now report the total retry_count */ | ||
575 | rthdr->data_retries = retry_count; | ||
576 | |||
577 | /* XXX: is this sufficient for BPF? */ | ||
578 | skb_set_mac_header(skb, 0); | ||
579 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
580 | skb->pkt_type = PACKET_OTHERHOST; | ||
581 | skb->protocol = htons(ETH_P_802_2); | ||
582 | memset(skb->cb, 0, sizeof(skb->cb)); | ||
583 | |||
584 | rcu_read_lock(); | ||
585 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | ||
586 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR) { | ||
587 | if (!netif_running(sdata->dev)) | ||
588 | continue; | ||
589 | |||
590 | if (prev_dev) { | ||
591 | skb2 = skb_clone(skb, GFP_ATOMIC); | ||
592 | if (skb2) { | ||
593 | skb2->dev = prev_dev; | ||
594 | netif_rx(skb2); | ||
595 | } | ||
596 | } | ||
597 | |||
598 | prev_dev = sdata->dev; | ||
599 | } | ||
600 | } | ||
601 | if (prev_dev) { | ||
602 | skb->dev = prev_dev; | ||
603 | netif_rx(skb); | ||
604 | skb = NULL; | ||
605 | } | ||
606 | rcu_read_unlock(); | ||
607 | dev_kfree_skb(skb); | ||
608 | } | ||
609 | EXPORT_SYMBOL(ieee80211_tx_status); | ||
610 | |||
611 | static void ieee80211_restart_work(struct work_struct *work) | 280 | static void ieee80211_restart_work(struct work_struct *work) |
612 | { | 281 | { |
613 | struct ieee80211_local *local = | 282 | struct ieee80211_local *local = |
@@ -659,7 +328,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
659 | if (!wiphy) | 328 | if (!wiphy) |
660 | return NULL; | 329 | return NULL; |
661 | 330 | ||
662 | wiphy->netnsok = true; | 331 | wiphy->flags |= WIPHY_FLAG_NETNS_OK | |
332 | WIPHY_FLAG_4ADDR_AP | | ||
333 | WIPHY_FLAG_4ADDR_STATION; | ||
663 | wiphy->privid = mac80211_wiphy_privid; | 334 | wiphy->privid = mac80211_wiphy_privid; |
664 | 335 | ||
665 | /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */ | 336 | /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */ |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index bbd56b087899..51adb1115215 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -16,12 +16,6 @@ | |||
16 | #define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ) | 16 | #define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ) |
17 | #define IEEE80211_MESH_RANN_INTERVAL (1 * HZ) | 17 | #define IEEE80211_MESH_RANN_INTERVAL (1 * HZ) |
18 | 18 | ||
19 | #define MESHCONF_PP_OFFSET 0 /* Path Selection Protocol */ | ||
20 | #define MESHCONF_PM_OFFSET 1 /* Path Selection Metric */ | ||
21 | #define MESHCONF_CC_OFFSET 2 /* Congestion Control Mode */ | ||
22 | #define MESHCONF_SP_OFFSET 3 /* Synchronization Protocol */ | ||
23 | #define MESHCONF_AUTH_OFFSET 4 /* Authentication Protocol */ | ||
24 | #define MESHCONF_CAPAB_OFFSET 6 | ||
25 | #define MESHCONF_CAPAB_ACCEPT_PLINKS 0x01 | 19 | #define MESHCONF_CAPAB_ACCEPT_PLINKS 0x01 |
26 | #define MESHCONF_CAPAB_FORWARDING 0x08 | 20 | #define MESHCONF_CAPAB_FORWARDING 0x08 |
27 | 21 | ||
@@ -87,12 +81,11 @@ bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_dat | |||
87 | */ | 81 | */ |
88 | if (ifmsh->mesh_id_len == ie->mesh_id_len && | 82 | if (ifmsh->mesh_id_len == ie->mesh_id_len && |
89 | memcmp(ifmsh->mesh_id, ie->mesh_id, ie->mesh_id_len) == 0 && | 83 | memcmp(ifmsh->mesh_id, ie->mesh_id, ie->mesh_id_len) == 0 && |
90 | (ifmsh->mesh_pp_id == *(ie->mesh_config + MESHCONF_PP_OFFSET))&& | 84 | (ifmsh->mesh_pp_id == ie->mesh_config->meshconf_psel) && |
91 | (ifmsh->mesh_pm_id == *(ie->mesh_config + MESHCONF_PM_OFFSET))&& | 85 | (ifmsh->mesh_pm_id == ie->mesh_config->meshconf_pmetric) && |
92 | (ifmsh->mesh_cc_id == *(ie->mesh_config + MESHCONF_CC_OFFSET))&& | 86 | (ifmsh->mesh_cc_id == ie->mesh_config->meshconf_congest) && |
93 | (ifmsh->mesh_sp_id == *(ie->mesh_config + MESHCONF_SP_OFFSET))&& | 87 | (ifmsh->mesh_sp_id == ie->mesh_config->meshconf_synch) && |
94 | (ifmsh->mesh_auth_id == *(ie->mesh_config + | 88 | (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth)) |
95 | MESHCONF_AUTH_OFFSET))) | ||
96 | return true; | 89 | return true; |
97 | 90 | ||
98 | return false; | 91 | return false; |
@@ -105,7 +98,7 @@ bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_dat | |||
105 | */ | 98 | */ |
106 | bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie) | 99 | bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie) |
107 | { | 100 | { |
108 | return (*(ie->mesh_config + MESHCONF_CAPAB_OFFSET) & | 101 | return (ie->mesh_config->meshconf_cap & |
109 | MESHCONF_CAPAB_ACCEPT_PLINKS) != 0; | 102 | MESHCONF_CAPAB_ACCEPT_PLINKS) != 0; |
110 | } | 103 | } |
111 | 104 | ||
@@ -262,9 +255,9 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) | |||
262 | if (sdata->u.mesh.mesh_id_len) | 255 | if (sdata->u.mesh.mesh_id_len) |
263 | memcpy(pos, sdata->u.mesh.mesh_id, sdata->u.mesh.mesh_id_len); | 256 | memcpy(pos, sdata->u.mesh.mesh_id, sdata->u.mesh.mesh_id_len); |
264 | 257 | ||
265 | pos = skb_put(skb, 2 + IEEE80211_MESH_CONFIG_LEN); | 258 | pos = skb_put(skb, 2 + sizeof(struct ieee80211_meshconf_ie)); |
266 | *pos++ = WLAN_EID_MESH_CONFIG; | 259 | *pos++ = WLAN_EID_MESH_CONFIG; |
267 | *pos++ = IEEE80211_MESH_CONFIG_LEN; | 260 | *pos++ = sizeof(struct ieee80211_meshconf_ie); |
268 | 261 | ||
269 | /* Active path selection protocol ID */ | 262 | /* Active path selection protocol ID */ |
270 | *pos++ = sdata->u.mesh.mesh_pp_id; | 263 | *pos++ = sdata->u.mesh.mesh_pp_id; |
@@ -394,8 +387,9 @@ void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh) | |||
394 | * | 387 | * |
395 | * Return the length of the 802.11 (does not include a mesh control header) | 388 | * Return the length of the 802.11 (does not include a mesh control header) |
396 | */ | 389 | */ |
397 | int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, char | 390 | int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, |
398 | *meshda, char *meshsa) { | 391 | const u8 *meshda, const u8 *meshsa) |
392 | { | ||
399 | if (is_multicast_ether_addr(meshda)) { | 393 | if (is_multicast_ether_addr(meshda)) { |
400 | *fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); | 394 | *fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); |
401 | /* DA TA SA */ | 395 | /* DA TA SA */ |
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index bd0e1cbb9a1e..31e102541869 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
@@ -220,7 +220,7 @@ struct mesh_rmc { | |||
220 | /* Public interfaces */ | 220 | /* Public interfaces */ |
221 | /* Various */ | 221 | /* Various */ |
222 | int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, | 222 | int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, |
223 | char *da, char *sa); | 223 | const u8 *da, const u8 *sa); |
224 | int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, | 224 | int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, |
225 | struct ieee80211_sub_if_data *sdata, char *addr4, | 225 | struct ieee80211_sub_if_data *sdata, char *addr4, |
226 | char *addr5, char *addr6); | 226 | char *addr5, char *addr6); |
@@ -284,7 +284,7 @@ u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, | |||
284 | struct mesh_table *tbl); | 284 | struct mesh_table *tbl); |
285 | /* Mesh paths */ | 285 | /* Mesh paths */ |
286 | int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, __le16 target_rcode, | 286 | int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, __le16 target_rcode, |
287 | u8 *ra, struct ieee80211_sub_if_data *sdata); | 287 | const u8 *ra, struct ieee80211_sub_if_data *sdata); |
288 | void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta); | 288 | void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta); |
289 | void mesh_path_flush_pending(struct mesh_path *mpath); | 289 | void mesh_path_flush_pending(struct mesh_path *mpath); |
290 | void mesh_path_tx_pending(struct mesh_path *mpath); | 290 | void mesh_path_tx_pending(struct mesh_path *mpath); |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 5c67e7b8790f..9aecf0207afc 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -101,10 +101,12 @@ enum mpath_frame_type { | |||
101 | MPATH_RANN | 101 | MPATH_RANN |
102 | }; | 102 | }; |
103 | 103 | ||
104 | static const u8 broadcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | ||
105 | |||
104 | static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, | 106 | static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, |
105 | u8 *orig_addr, __le32 orig_sn, u8 target_flags, u8 *target, | 107 | u8 *orig_addr, __le32 orig_sn, u8 target_flags, u8 *target, |
106 | __le32 target_sn, u8 *da, u8 hop_count, u8 ttl,__le32 lifetime, | 108 | __le32 target_sn, const u8 *da, u8 hop_count, u8 ttl, |
107 | __le32 metric, __le32 preq_id, | 109 | __le32 lifetime, __le32 metric, __le32 preq_id, |
108 | struct ieee80211_sub_if_data *sdata) | 110 | struct ieee80211_sub_if_data *sdata) |
109 | { | 111 | { |
110 | struct ieee80211_local *local = sdata->local; | 112 | struct ieee80211_local *local = sdata->local; |
@@ -185,7 +187,7 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, | |||
185 | memcpy(pos, &target_sn, 4); | 187 | memcpy(pos, &target_sn, 4); |
186 | } | 188 | } |
187 | 189 | ||
188 | ieee80211_tx_skb(sdata, skb, 1); | 190 | ieee80211_tx_skb(sdata, skb); |
189 | return 0; | 191 | return 0; |
190 | } | 192 | } |
191 | 193 | ||
@@ -198,8 +200,8 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, | |||
198 | * @ra: node this frame is addressed to | 200 | * @ra: node this frame is addressed to |
199 | */ | 201 | */ |
200 | int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, | 202 | int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, |
201 | __le16 target_rcode, u8 *ra, | 203 | __le16 target_rcode, const u8 *ra, |
202 | struct ieee80211_sub_if_data *sdata) | 204 | struct ieee80211_sub_if_data *sdata) |
203 | { | 205 | { |
204 | struct ieee80211_local *local = sdata->local; | 206 | struct ieee80211_local *local = sdata->local; |
205 | struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); | 207 | struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); |
@@ -248,7 +250,7 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, | |||
248 | pos += 4; | 250 | pos += 4; |
249 | memcpy(pos, &target_rcode, 2); | 251 | memcpy(pos, &target_rcode, 2); |
250 | 252 | ||
251 | ieee80211_tx_skb(sdata, skb, 1); | 253 | ieee80211_tx_skb(sdata, skb); |
252 | return 0; | 254 | return 0; |
253 | } | 255 | } |
254 | 256 | ||
@@ -548,7 +550,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, | |||
548 | hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1; | 550 | hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1; |
549 | mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, | 551 | mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, |
550 | cpu_to_le32(orig_sn), target_flags, target_addr, | 552 | cpu_to_le32(orig_sn), target_flags, target_addr, |
551 | cpu_to_le32(target_sn), sdata->dev->broadcast, | 553 | cpu_to_le32(target_sn), broadcast_addr, |
552 | hopcount, ttl, cpu_to_le32(lifetime), | 554 | hopcount, ttl, cpu_to_le32(lifetime), |
553 | cpu_to_le32(metric), cpu_to_le32(preq_id), | 555 | cpu_to_le32(metric), cpu_to_le32(preq_id), |
554 | sdata); | 556 | sdata); |
@@ -660,7 +662,7 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata, | |||
660 | spin_unlock_bh(&mpath->state_lock); | 662 | spin_unlock_bh(&mpath->state_lock); |
661 | mesh_path_error_tx(ttl, target_addr, cpu_to_le32(target_sn), | 663 | mesh_path_error_tx(ttl, target_addr, cpu_to_le32(target_sn), |
662 | cpu_to_le16(target_rcode), | 664 | cpu_to_le16(target_rcode), |
663 | sdata->dev->broadcast, sdata); | 665 | broadcast_addr, sdata); |
664 | } else | 666 | } else |
665 | spin_unlock_bh(&mpath->state_lock); | 667 | spin_unlock_bh(&mpath->state_lock); |
666 | } | 668 | } |
@@ -709,7 +711,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, | |||
709 | if (mpath->sn < orig_sn) { | 711 | if (mpath->sn < orig_sn) { |
710 | mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, | 712 | mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, |
711 | cpu_to_le32(orig_sn), | 713 | cpu_to_le32(orig_sn), |
712 | 0, NULL, 0, sdata->dev->broadcast, | 714 | 0, NULL, 0, broadcast_addr, |
713 | hopcount, ttl, 0, | 715 | hopcount, ttl, 0, |
714 | cpu_to_le32(metric + mpath->metric), | 716 | cpu_to_le32(metric + mpath->metric), |
715 | 0, sdata); | 717 | 0, sdata); |
@@ -890,7 +892,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata) | |||
890 | spin_unlock_bh(&mpath->state_lock); | 892 | spin_unlock_bh(&mpath->state_lock); |
891 | mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->dev->dev_addr, | 893 | mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->dev->dev_addr, |
892 | cpu_to_le32(ifmsh->sn), target_flags, mpath->dst, | 894 | cpu_to_le32(ifmsh->sn), target_flags, mpath->dst, |
893 | cpu_to_le32(mpath->sn), sdata->dev->broadcast, 0, | 895 | cpu_to_le32(mpath->sn), broadcast_addr, 0, |
894 | ttl, cpu_to_le32(lifetime), 0, | 896 | ttl, cpu_to_le32(lifetime), 0, |
895 | cpu_to_le32(ifmsh->preq_id++), sdata); | 897 | cpu_to_le32(ifmsh->preq_id++), sdata); |
896 | mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout); | 898 | mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout); |
@@ -1011,6 +1013,6 @@ mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata) | |||
1011 | 1013 | ||
1012 | mesh_path_sel_frame_tx(MPATH_RANN, 0, sdata->dev->dev_addr, | 1014 | mesh_path_sel_frame_tx(MPATH_RANN, 0, sdata->dev->dev_addr, |
1013 | cpu_to_le32(++ifmsh->sn), | 1015 | cpu_to_le32(++ifmsh->sn), |
1014 | 0, NULL, 0, sdata->dev->broadcast, | 1016 | 0, NULL, 0, broadcast_addr, |
1015 | 0, MESH_TTL, 0, 0, 0, sdata); | 1017 | 0, MESH_TTL, 0, 0, 0, sdata); |
1016 | } | 1018 | } |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 5399e7a9ec6e..a8da23905c70 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
@@ -449,6 +449,7 @@ err_path_alloc: | |||
449 | */ | 449 | */ |
450 | void mesh_plink_broken(struct sta_info *sta) | 450 | void mesh_plink_broken(struct sta_info *sta) |
451 | { | 451 | { |
452 | static const u8 bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | ||
452 | struct mesh_path *mpath; | 453 | struct mesh_path *mpath; |
453 | struct mpath_node *node; | 454 | struct mpath_node *node; |
454 | struct hlist_node *p; | 455 | struct hlist_node *p; |
@@ -467,8 +468,8 @@ void mesh_plink_broken(struct sta_info *sta) | |||
467 | spin_unlock_bh(&mpath->state_lock); | 468 | spin_unlock_bh(&mpath->state_lock); |
468 | mesh_path_error_tx(MESH_TTL, mpath->dst, | 469 | mesh_path_error_tx(MESH_TTL, mpath->dst, |
469 | cpu_to_le32(mpath->sn), | 470 | cpu_to_le32(mpath->sn), |
470 | PERR_RCODE_DEST_UNREACH, | 471 | cpu_to_le16(PERR_RCODE_DEST_UNREACH), |
471 | sdata->dev->broadcast, sdata); | 472 | bcast, sdata); |
472 | } else | 473 | } else |
473 | spin_unlock_bh(&mpath->state_lock); | 474 | spin_unlock_bh(&mpath->state_lock); |
474 | } | 475 | } |
@@ -613,7 +614,7 @@ void mesh_path_discard_frame(struct sk_buff *skb, | |||
613 | if (mpath) | 614 | if (mpath) |
614 | sn = ++mpath->sn; | 615 | sn = ++mpath->sn; |
615 | mesh_path_error_tx(MESH_TTL, skb->data, cpu_to_le32(sn), | 616 | mesh_path_error_tx(MESH_TTL, skb->data, cpu_to_le32(sn), |
616 | PERR_RCODE_NO_ROUTE, ra, sdata); | 617 | cpu_to_le16(PERR_RCODE_NO_ROUTE), ra, sdata); |
617 | } | 618 | } |
618 | 619 | ||
619 | kfree_skb(skb); | 620 | kfree_skb(skb); |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index f21329afdae3..0f7c6e6a4248 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -222,7 +222,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, | |||
222 | memcpy(pos, &reason, 2); | 222 | memcpy(pos, &reason, 2); |
223 | } | 223 | } |
224 | 224 | ||
225 | ieee80211_tx_skb(sdata, skb, 1); | 225 | ieee80211_tx_skb(sdata, skb); |
226 | return 0; | 226 | return 0; |
227 | } | 227 | } |
228 | 228 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 2af306f67d78..6dc7b5ad9a41 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -426,7 +426,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
426 | memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); | 426 | memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); |
427 | } | 427 | } |
428 | 428 | ||
429 | ieee80211_tx_skb(sdata, skb, 0); | 429 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
430 | ieee80211_tx_skb(sdata, skb); | ||
430 | } | 431 | } |
431 | 432 | ||
432 | 433 | ||
@@ -467,7 +468,9 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, | |||
467 | __cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len); | 468 | __cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len); |
468 | else | 469 | else |
469 | cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len); | 470 | cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len); |
470 | ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED); | 471 | if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED)) |
472 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | ||
473 | ieee80211_tx_skb(sdata, skb); | ||
471 | } | 474 | } |
472 | 475 | ||
473 | void ieee80211_send_pspoll(struct ieee80211_local *local, | 476 | void ieee80211_send_pspoll(struct ieee80211_local *local, |
@@ -498,7 +501,8 @@ void ieee80211_send_pspoll(struct ieee80211_local *local, | |||
498 | memcpy(pspoll->bssid, ifmgd->bssid, ETH_ALEN); | 501 | memcpy(pspoll->bssid, ifmgd->bssid, ETH_ALEN); |
499 | memcpy(pspoll->ta, sdata->dev->dev_addr, ETH_ALEN); | 502 | memcpy(pspoll->ta, sdata->dev->dev_addr, ETH_ALEN); |
500 | 503 | ||
501 | ieee80211_tx_skb(sdata, skb, 0); | 504 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
505 | ieee80211_tx_skb(sdata, skb); | ||
502 | } | 506 | } |
503 | 507 | ||
504 | void ieee80211_send_nullfunc(struct ieee80211_local *local, | 508 | void ieee80211_send_nullfunc(struct ieee80211_local *local, |
@@ -531,7 +535,8 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local, | |||
531 | memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN); | 535 | memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN); |
532 | memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN); | 536 | memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN); |
533 | 537 | ||
534 | ieee80211_tx_skb(sdata, skb, 0); | 538 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
539 | ieee80211_tx_skb(sdata, skb); | ||
535 | } | 540 | } |
536 | 541 | ||
537 | /* spectrum management related things */ | 542 | /* spectrum management related things */ |
@@ -2503,6 +2508,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2503 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2508 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2504 | struct ieee80211_mgd_work *wk; | 2509 | struct ieee80211_mgd_work *wk; |
2505 | const u8 *bssid = NULL; | 2510 | const u8 *bssid = NULL; |
2511 | bool not_auth_yet = false; | ||
2506 | 2512 | ||
2507 | mutex_lock(&ifmgd->mtx); | 2513 | mutex_lock(&ifmgd->mtx); |
2508 | 2514 | ||
@@ -2512,6 +2518,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2512 | } else list_for_each_entry(wk, &ifmgd->work_list, list) { | 2518 | } else list_for_each_entry(wk, &ifmgd->work_list, list) { |
2513 | if (&wk->bss->cbss == req->bss) { | 2519 | if (&wk->bss->cbss == req->bss) { |
2514 | bssid = req->bss->bssid; | 2520 | bssid = req->bss->bssid; |
2521 | if (wk->state == IEEE80211_MGD_STATE_PROBE) | ||
2522 | not_auth_yet = true; | ||
2515 | list_del(&wk->list); | 2523 | list_del(&wk->list); |
2516 | kfree(wk); | 2524 | kfree(wk); |
2517 | break; | 2525 | break; |
@@ -2519,6 +2527,20 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2519 | } | 2527 | } |
2520 | 2528 | ||
2521 | /* | 2529 | /* |
2530 | * If somebody requests authentication and we haven't | ||
2531 | * sent out an auth frame yet there's no need to send | ||
2532 | * out a deauth frame either. If the state was PROBE, | ||
2533 | * then this is the case. If it's AUTH we have sent a | ||
2534 | * frame, and if it's IDLE we have completed the auth | ||
2535 | * process already. | ||
2536 | */ | ||
2537 | if (not_auth_yet) { | ||
2538 | mutex_unlock(&ifmgd->mtx); | ||
2539 | __cfg80211_auth_canceled(sdata->dev, bssid); | ||
2540 | return 0; | ||
2541 | } | ||
2542 | |||
2543 | /* | ||
2522 | * cfg80211 should catch this ... but it's racy since | 2544 | * cfg80211 should catch this ... but it's racy since |
2523 | * we can receive a deauth frame, process it, hand it | 2545 | * we can receive a deauth frame, process it, hand it |
2524 | * to cfg80211 while that's in a locked section already | 2546 | * to cfg80211 while that's in a locked section already |
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index ccda7454fb17..b9007f80cb92 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
@@ -284,9 +284,16 @@ int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, | |||
284 | struct rate_control_ref *ref, *old; | 284 | struct rate_control_ref *ref, *old; |
285 | 285 | ||
286 | ASSERT_RTNL(); | 286 | ASSERT_RTNL(); |
287 | |||
287 | if (local->open_count) | 288 | if (local->open_count) |
288 | return -EBUSY; | 289 | return -EBUSY; |
289 | 290 | ||
291 | if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) { | ||
292 | if (WARN_ON(!local->ops->set_rts_threshold)) | ||
293 | return -EINVAL; | ||
294 | return 0; | ||
295 | } | ||
296 | |||
290 | ref = rate_control_alloc(name, local); | 297 | ref = rate_control_alloc(name, local); |
291 | if (!ref) { | 298 | if (!ref) { |
292 | printk(KERN_WARNING "%s: Failed to select rate control " | 299 | printk(KERN_WARNING "%s: Failed to select rate control " |
@@ -305,7 +312,6 @@ int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, | |||
305 | "algorithm '%s'\n", wiphy_name(local->hw.wiphy), | 312 | "algorithm '%s'\n", wiphy_name(local->hw.wiphy), |
306 | ref->ops->name); | 313 | ref->ops->name); |
307 | 314 | ||
308 | |||
309 | return 0; | 315 | return 0; |
310 | } | 316 | } |
311 | 317 | ||
@@ -314,6 +320,10 @@ void rate_control_deinitialize(struct ieee80211_local *local) | |||
314 | struct rate_control_ref *ref; | 320 | struct rate_control_ref *ref; |
315 | 321 | ||
316 | ref = local->rate_ctrl; | 322 | ref = local->rate_ctrl; |
323 | |||
324 | if (!ref) | ||
325 | return; | ||
326 | |||
317 | local->rate_ctrl = NULL; | 327 | local->rate_ctrl = NULL; |
318 | rate_control_put(ref); | 328 | rate_control_put(ref); |
319 | } | 329 | } |
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h index 2ab5ad9e71ce..cb9bd1f65e27 100644 --- a/net/mac80211/rate.h +++ b/net/mac80211/rate.h | |||
@@ -59,6 +59,9 @@ static inline void rate_control_rate_init(struct sta_info *sta) | |||
59 | void *priv_sta = sta->rate_ctrl_priv; | 59 | void *priv_sta = sta->rate_ctrl_priv; |
60 | struct ieee80211_supported_band *sband; | 60 | struct ieee80211_supported_band *sband; |
61 | 61 | ||
62 | if (!ref) | ||
63 | return; | ||
64 | |||
62 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 65 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
63 | 66 | ||
64 | ref->ops->rate_init(ref->priv, sband, ista, priv_sta); | 67 | ref->ops->rate_init(ref->priv, sband, ista, priv_sta); |
@@ -72,7 +75,7 @@ static inline void rate_control_rate_update(struct ieee80211_local *local, | |||
72 | struct ieee80211_sta *ista = &sta->sta; | 75 | struct ieee80211_sta *ista = &sta->sta; |
73 | void *priv_sta = sta->rate_ctrl_priv; | 76 | void *priv_sta = sta->rate_ctrl_priv; |
74 | 77 | ||
75 | if (ref->ops->rate_update) | 78 | if (ref && ref->ops->rate_update) |
76 | ref->ops->rate_update(ref->priv, sband, ista, | 79 | ref->ops->rate_update(ref->priv, sband, ista, |
77 | priv_sta, changed); | 80 | priv_sta, changed); |
78 | } | 81 | } |
@@ -97,7 +100,7 @@ static inline void rate_control_add_sta_debugfs(struct sta_info *sta) | |||
97 | { | 100 | { |
98 | #ifdef CONFIG_MAC80211_DEBUGFS | 101 | #ifdef CONFIG_MAC80211_DEBUGFS |
99 | struct rate_control_ref *ref = sta->rate_ctrl; | 102 | struct rate_control_ref *ref = sta->rate_ctrl; |
100 | if (sta->debugfs.dir && ref->ops->add_sta_debugfs) | 103 | if (ref && sta->debugfs.dir && ref->ops->add_sta_debugfs) |
101 | ref->ops->add_sta_debugfs(ref->priv, sta->rate_ctrl_priv, | 104 | ref->ops->add_sta_debugfs(ref->priv, sta->rate_ctrl_priv, |
102 | sta->debugfs.dir); | 105 | sta->debugfs.dir); |
103 | #endif | 106 | #endif |
@@ -107,7 +110,7 @@ static inline void rate_control_remove_sta_debugfs(struct sta_info *sta) | |||
107 | { | 110 | { |
108 | #ifdef CONFIG_MAC80211_DEBUGFS | 111 | #ifdef CONFIG_MAC80211_DEBUGFS |
109 | struct rate_control_ref *ref = sta->rate_ctrl; | 112 | struct rate_control_ref *ref = sta->rate_ctrl; |
110 | if (ref->ops->remove_sta_debugfs) | 113 | if (ref && ref->ops->remove_sta_debugfs) |
111 | ref->ops->remove_sta_debugfs(ref->priv, sta->rate_ctrl_priv); | 114 | ref->ops->remove_sta_debugfs(ref->priv, sta->rate_ctrl_priv); |
112 | #endif | 115 | #endif |
113 | } | 116 | } |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 6bce97ee2534..96f13ad05d3c 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -27,11 +27,10 @@ | |||
27 | #include "tkip.h" | 27 | #include "tkip.h" |
28 | #include "wme.h" | 28 | #include "wme.h" |
29 | 29 | ||
30 | static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | 30 | static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, |
31 | struct tid_ampdu_rx *tid_agg_rx, | 31 | struct tid_ampdu_rx *tid_agg_rx, |
32 | struct sk_buff *skb, | 32 | u16 head_seq_num); |
33 | u16 mpdu_seq_num, | 33 | |
34 | int bar_req); | ||
35 | /* | 34 | /* |
36 | * monitor mode reception | 35 | * monitor mode reception |
37 | * | 36 | * |
@@ -164,6 +163,9 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
164 | if (status->band == IEEE80211_BAND_5GHZ) | 163 | if (status->band == IEEE80211_BAND_5GHZ) |
165 | put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ, | 164 | put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ, |
166 | pos); | 165 | pos); |
166 | else if (status->flag & RX_FLAG_HT) | ||
167 | put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ, | ||
168 | pos); | ||
167 | else if (rate->flags & IEEE80211_RATE_ERP_G) | 169 | else if (rate->flags & IEEE80211_RATE_ERP_G) |
168 | put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ, | 170 | put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ, |
169 | pos); | 171 | pos); |
@@ -478,7 +480,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) | |||
478 | { | 480 | { |
479 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 481 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
480 | unsigned int hdrlen = ieee80211_hdrlen(hdr->frame_control); | 482 | unsigned int hdrlen = ieee80211_hdrlen(hdr->frame_control); |
481 | char *dev_addr = rx->dev->dev_addr; | 483 | char *dev_addr = rx->sdata->dev->dev_addr; |
482 | 484 | ||
483 | if (ieee80211_is_data(hdr->frame_control)) { | 485 | if (ieee80211_is_data(hdr->frame_control)) { |
484 | if (is_multicast_ether_addr(hdr->addr1)) { | 486 | if (is_multicast_ether_addr(hdr->addr1)) { |
@@ -592,7 +594,9 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
592 | static ieee80211_rx_result debug_noinline | 594 | static ieee80211_rx_result debug_noinline |
593 | ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | 595 | ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) |
594 | { | 596 | { |
595 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 597 | struct sk_buff *skb = rx->skb; |
598 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
599 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
596 | int keyidx; | 600 | int keyidx; |
597 | int hdrlen; | 601 | int hdrlen; |
598 | ieee80211_rx_result result = RX_DROP_UNUSABLE; | 602 | ieee80211_rx_result result = RX_DROP_UNUSABLE; |
@@ -646,8 +650,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
646 | return RX_CONTINUE; | 650 | return RX_CONTINUE; |
647 | } else if (mmie_keyidx >= 0) { | 651 | } else if (mmie_keyidx >= 0) { |
648 | /* Broadcast/multicast robust management frame / BIP */ | 652 | /* Broadcast/multicast robust management frame / BIP */ |
649 | if ((rx->status->flag & RX_FLAG_DECRYPTED) && | 653 | if ((status->flag & RX_FLAG_DECRYPTED) && |
650 | (rx->status->flag & RX_FLAG_IV_STRIPPED)) | 654 | (status->flag & RX_FLAG_IV_STRIPPED)) |
651 | return RX_CONTINUE; | 655 | return RX_CONTINUE; |
652 | 656 | ||
653 | if (mmie_keyidx < NUM_DEFAULT_KEYS || | 657 | if (mmie_keyidx < NUM_DEFAULT_KEYS || |
@@ -679,8 +683,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
679 | * we somehow allow the driver to tell us which key | 683 | * we somehow allow the driver to tell us which key |
680 | * the hardware used if this flag is set? | 684 | * the hardware used if this flag is set? |
681 | */ | 685 | */ |
682 | if ((rx->status->flag & RX_FLAG_DECRYPTED) && | 686 | if ((status->flag & RX_FLAG_DECRYPTED) && |
683 | (rx->status->flag & RX_FLAG_IV_STRIPPED)) | 687 | (status->flag & RX_FLAG_IV_STRIPPED)) |
684 | return RX_CONTINUE; | 688 | return RX_CONTINUE; |
685 | 689 | ||
686 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 690 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
@@ -716,8 +720,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
716 | /* Check for weak IVs if possible */ | 720 | /* Check for weak IVs if possible */ |
717 | if (rx->sta && rx->key->conf.alg == ALG_WEP && | 721 | if (rx->sta && rx->key->conf.alg == ALG_WEP && |
718 | ieee80211_is_data(hdr->frame_control) && | 722 | ieee80211_is_data(hdr->frame_control) && |
719 | (!(rx->status->flag & RX_FLAG_IV_STRIPPED) || | 723 | (!(status->flag & RX_FLAG_IV_STRIPPED) || |
720 | !(rx->status->flag & RX_FLAG_DECRYPTED)) && | 724 | !(status->flag & RX_FLAG_DECRYPTED)) && |
721 | ieee80211_wep_is_weak_iv(rx->skb, rx->key)) | 725 | ieee80211_wep_is_weak_iv(rx->skb, rx->key)) |
722 | rx->sta->wep_weak_iv_count++; | 726 | rx->sta->wep_weak_iv_count++; |
723 | 727 | ||
@@ -737,7 +741,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
737 | } | 741 | } |
738 | 742 | ||
739 | /* either the frame has been decrypted or will be dropped */ | 743 | /* either the frame has been decrypted or will be dropped */ |
740 | rx->status->flag |= RX_FLAG_DECRYPTED; | 744 | status->flag |= RX_FLAG_DECRYPTED; |
741 | 745 | ||
742 | return result; | 746 | return result; |
743 | } | 747 | } |
@@ -817,7 +821,9 @@ static ieee80211_rx_result debug_noinline | |||
817 | ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | 821 | ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) |
818 | { | 822 | { |
819 | struct sta_info *sta = rx->sta; | 823 | struct sta_info *sta = rx->sta; |
820 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 824 | struct sk_buff *skb = rx->skb; |
825 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
826 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
821 | 827 | ||
822 | if (!sta) | 828 | if (!sta) |
823 | return RX_CONTINUE; | 829 | return RX_CONTINUE; |
@@ -848,8 +854,8 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
848 | 854 | ||
849 | sta->rx_fragments++; | 855 | sta->rx_fragments++; |
850 | sta->rx_bytes += rx->skb->len; | 856 | sta->rx_bytes += rx->skb->len; |
851 | sta->last_signal = rx->status->signal; | 857 | sta->last_signal = status->signal; |
852 | sta->last_noise = rx->status->noise; | 858 | sta->last_noise = status->noise; |
853 | 859 | ||
854 | /* | 860 | /* |
855 | * Change STA power saving mode only at the end of a frame | 861 | * Change STA power saving mode only at the end of a frame |
@@ -1141,11 +1147,14 @@ ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) | |||
1141 | static int | 1147 | static int |
1142 | ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc) | 1148 | ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc) |
1143 | { | 1149 | { |
1150 | struct sk_buff *skb = rx->skb; | ||
1151 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
1152 | |||
1144 | /* | 1153 | /* |
1145 | * Pass through unencrypted frames if the hardware has | 1154 | * Pass through unencrypted frames if the hardware has |
1146 | * decrypted them already. | 1155 | * decrypted them already. |
1147 | */ | 1156 | */ |
1148 | if (rx->status->flag & RX_FLAG_DECRYPTED) | 1157 | if (status->flag & RX_FLAG_DECRYPTED) |
1149 | return 0; | 1158 | return 0; |
1150 | 1159 | ||
1151 | /* Drop unencrypted frames if key is set. */ | 1160 | /* Drop unencrypted frames if key is set. */ |
@@ -1179,14 +1188,17 @@ ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc) | |||
1179 | static int | 1188 | static int |
1180 | __ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | 1189 | __ieee80211_data_to_8023(struct ieee80211_rx_data *rx) |
1181 | { | 1190 | { |
1182 | struct net_device *dev = rx->dev; | 1191 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1183 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1192 | struct net_device *dev = sdata->dev; |
1184 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 1193 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
1185 | 1194 | ||
1186 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->use_4addr && | 1195 | if (ieee80211_has_a4(hdr->frame_control) && |
1187 | ieee80211_has_a4(hdr->frame_control)) | 1196 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->u.vlan.sta) |
1188 | return -1; | 1197 | return -1; |
1189 | if (sdata->use_4addr && is_multicast_ether_addr(hdr->addr1)) | 1198 | |
1199 | if (is_multicast_ether_addr(hdr->addr1) && | ||
1200 | ((sdata->vif.type == NL80211_IFTYPE_AP_VLAN && sdata->u.vlan.sta) || | ||
1201 | (sdata->vif.type == NL80211_IFTYPE_STATION && sdata->u.mgd.use_4addr))) | ||
1190 | return -1; | 1202 | return -1; |
1191 | 1203 | ||
1192 | return ieee80211_data_to_8023(rx->skb, dev->dev_addr, sdata->vif.type); | 1204 | return ieee80211_data_to_8023(rx->skb, dev->dev_addr, sdata->vif.type); |
@@ -1206,7 +1218,7 @@ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc) | |||
1206 | * of whether the frame was encrypted or not. | 1218 | * of whether the frame was encrypted or not. |
1207 | */ | 1219 | */ |
1208 | if (ehdr->h_proto == htons(ETH_P_PAE) && | 1220 | if (ehdr->h_proto == htons(ETH_P_PAE) && |
1209 | (compare_ether_addr(ehdr->h_dest, rx->dev->dev_addr) == 0 || | 1221 | (compare_ether_addr(ehdr->h_dest, rx->sdata->dev->dev_addr) == 0 || |
1210 | compare_ether_addr(ehdr->h_dest, pae_group_addr) == 0)) | 1222 | compare_ether_addr(ehdr->h_dest, pae_group_addr) == 0)) |
1211 | return true; | 1223 | return true; |
1212 | 1224 | ||
@@ -1223,10 +1235,10 @@ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc) | |||
1223 | static void | 1235 | static void |
1224 | ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | 1236 | ieee80211_deliver_skb(struct ieee80211_rx_data *rx) |
1225 | { | 1237 | { |
1226 | struct net_device *dev = rx->dev; | 1238 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1239 | struct net_device *dev = sdata->dev; | ||
1227 | struct ieee80211_local *local = rx->local; | 1240 | struct ieee80211_local *local = rx->local; |
1228 | struct sk_buff *skb, *xmit_skb; | 1241 | struct sk_buff *skb, *xmit_skb; |
1229 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
1230 | struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; | 1242 | struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; |
1231 | struct sta_info *dsta; | 1243 | struct sta_info *dsta; |
1232 | 1244 | ||
@@ -1236,7 +1248,8 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1236 | if ((sdata->vif.type == NL80211_IFTYPE_AP || | 1248 | if ((sdata->vif.type == NL80211_IFTYPE_AP || |
1237 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && | 1249 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && |
1238 | !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && | 1250 | !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && |
1239 | (rx->flags & IEEE80211_RX_RA_MATCH) && !rx->sdata->use_4addr) { | 1251 | (rx->flags & IEEE80211_RX_RA_MATCH) && |
1252 | (sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) { | ||
1240 | if (is_multicast_ether_addr(ehdr->h_dest)) { | 1253 | if (is_multicast_ether_addr(ehdr->h_dest)) { |
1241 | /* | 1254 | /* |
1242 | * send multicast frames both to higher layers in | 1255 | * send multicast frames both to higher layers in |
@@ -1307,7 +1320,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1307 | static ieee80211_rx_result debug_noinline | 1320 | static ieee80211_rx_result debug_noinline |
1308 | ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | 1321 | ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) |
1309 | { | 1322 | { |
1310 | struct net_device *dev = rx->dev; | 1323 | struct net_device *dev = rx->sdata->dev; |
1311 | struct ieee80211_local *local = rx->local; | 1324 | struct ieee80211_local *local = rx->local; |
1312 | u16 ethertype; | 1325 | u16 ethertype; |
1313 | u8 *payload; | 1326 | u8 *payload; |
@@ -1432,12 +1445,11 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1432 | unsigned int hdrlen; | 1445 | unsigned int hdrlen; |
1433 | struct sk_buff *skb = rx->skb, *fwd_skb; | 1446 | struct sk_buff *skb = rx->skb, *fwd_skb; |
1434 | struct ieee80211_local *local = rx->local; | 1447 | struct ieee80211_local *local = rx->local; |
1435 | struct ieee80211_sub_if_data *sdata; | 1448 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1436 | 1449 | ||
1437 | hdr = (struct ieee80211_hdr *) skb->data; | 1450 | hdr = (struct ieee80211_hdr *) skb->data; |
1438 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 1451 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
1439 | mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); | 1452 | mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); |
1440 | sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); | ||
1441 | 1453 | ||
1442 | if (!ieee80211_is_data(hdr->frame_control)) | 1454 | if (!ieee80211_is_data(hdr->frame_control)) |
1443 | return RX_CONTINUE; | 1455 | return RX_CONTINUE; |
@@ -1475,7 +1487,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1475 | 1487 | ||
1476 | /* Frame has reached destination. Don't forward */ | 1488 | /* Frame has reached destination. Don't forward */ |
1477 | if (!is_multicast_ether_addr(hdr->addr1) && | 1489 | if (!is_multicast_ether_addr(hdr->addr1) && |
1478 | compare_ether_addr(rx->dev->dev_addr, hdr->addr3) == 0) | 1490 | compare_ether_addr(sdata->dev->dev_addr, hdr->addr3) == 0) |
1479 | return RX_CONTINUE; | 1491 | return RX_CONTINUE; |
1480 | 1492 | ||
1481 | mesh_hdr->ttl--; | 1493 | mesh_hdr->ttl--; |
@@ -1492,10 +1504,10 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1492 | 1504 | ||
1493 | if (!fwd_skb && net_ratelimit()) | 1505 | if (!fwd_skb && net_ratelimit()) |
1494 | printk(KERN_DEBUG "%s: failed to clone mesh frame\n", | 1506 | printk(KERN_DEBUG "%s: failed to clone mesh frame\n", |
1495 | rx->dev->name); | 1507 | sdata->dev->name); |
1496 | 1508 | ||
1497 | fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; | 1509 | fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; |
1498 | memcpy(fwd_hdr->addr2, rx->dev->dev_addr, ETH_ALEN); | 1510 | memcpy(fwd_hdr->addr2, sdata->dev->dev_addr, ETH_ALEN); |
1499 | info = IEEE80211_SKB_CB(fwd_skb); | 1511 | info = IEEE80211_SKB_CB(fwd_skb); |
1500 | memset(info, 0, sizeof(*info)); | 1512 | memset(info, 0, sizeof(*info)); |
1501 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 1513 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
@@ -1529,7 +1541,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1529 | } | 1541 | } |
1530 | 1542 | ||
1531 | if (is_multicast_ether_addr(hdr->addr1) || | 1543 | if (is_multicast_ether_addr(hdr->addr1) || |
1532 | rx->dev->flags & IFF_PROMISC) | 1544 | sdata->dev->flags & IFF_PROMISC) |
1533 | return RX_CONTINUE; | 1545 | return RX_CONTINUE; |
1534 | else | 1546 | else |
1535 | return RX_DROP_MONITOR; | 1547 | return RX_DROP_MONITOR; |
@@ -1539,9 +1551,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1539 | static ieee80211_rx_result debug_noinline | 1551 | static ieee80211_rx_result debug_noinline |
1540 | ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | 1552 | ieee80211_rx_h_data(struct ieee80211_rx_data *rx) |
1541 | { | 1553 | { |
1542 | struct net_device *dev = rx->dev; | 1554 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1555 | struct net_device *dev = sdata->dev; | ||
1543 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 1556 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
1544 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
1545 | __le16 fc = hdr->frame_control; | 1557 | __le16 fc = hdr->frame_control; |
1546 | int err; | 1558 | int err; |
1547 | 1559 | ||
@@ -1592,11 +1604,11 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | |||
1592 | 1604 | ||
1593 | if (ieee80211_is_back_req(bar->frame_control)) { | 1605 | if (ieee80211_is_back_req(bar->frame_control)) { |
1594 | if (!rx->sta) | 1606 | if (!rx->sta) |
1595 | return RX_CONTINUE; | 1607 | return RX_DROP_MONITOR; |
1596 | tid = le16_to_cpu(bar->control) >> 12; | 1608 | tid = le16_to_cpu(bar->control) >> 12; |
1597 | if (rx->sta->ampdu_mlme.tid_state_rx[tid] | 1609 | if (rx->sta->ampdu_mlme.tid_state_rx[tid] |
1598 | != HT_AGG_STATE_OPERATIONAL) | 1610 | != HT_AGG_STATE_OPERATIONAL) |
1599 | return RX_CONTINUE; | 1611 | return RX_DROP_MONITOR; |
1600 | tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid]; | 1612 | tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid]; |
1601 | 1613 | ||
1602 | start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4; | 1614 | start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4; |
@@ -1606,13 +1618,10 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | |||
1606 | mod_timer(&tid_agg_rx->session_timer, | 1618 | mod_timer(&tid_agg_rx->session_timer, |
1607 | TU_TO_EXP_TIME(tid_agg_rx->timeout)); | 1619 | TU_TO_EXP_TIME(tid_agg_rx->timeout)); |
1608 | 1620 | ||
1609 | /* manage reordering buffer according to requested */ | 1621 | /* release stored frames up to start of BAR */ |
1610 | /* sequence number */ | 1622 | ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num); |
1611 | rcu_read_lock(); | 1623 | kfree_skb(skb); |
1612 | ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, NULL, | 1624 | return RX_QUEUED; |
1613 | start_seq_num, 1); | ||
1614 | rcu_read_unlock(); | ||
1615 | return RX_DROP_UNUSABLE; | ||
1616 | } | 1625 | } |
1617 | 1626 | ||
1618 | return RX_CONTINUE; | 1627 | return RX_CONTINUE; |
@@ -1661,14 +1670,14 @@ static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata, | |||
1661 | mgmt->u.action.u.sa_query.trans_id, | 1670 | mgmt->u.action.u.sa_query.trans_id, |
1662 | WLAN_SA_QUERY_TR_ID_LEN); | 1671 | WLAN_SA_QUERY_TR_ID_LEN); |
1663 | 1672 | ||
1664 | ieee80211_tx_skb(sdata, skb, 1); | 1673 | ieee80211_tx_skb(sdata, skb); |
1665 | } | 1674 | } |
1666 | 1675 | ||
1667 | static ieee80211_rx_result debug_noinline | 1676 | static ieee80211_rx_result debug_noinline |
1668 | ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | 1677 | ieee80211_rx_h_action(struct ieee80211_rx_data *rx) |
1669 | { | 1678 | { |
1670 | struct ieee80211_local *local = rx->local; | 1679 | struct ieee80211_local *local = rx->local; |
1671 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); | 1680 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1672 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; | 1681 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; |
1673 | int len = rx->skb->len; | 1682 | int len = rx->skb->len; |
1674 | 1683 | ||
@@ -1780,7 +1789,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
1780 | static ieee80211_rx_result debug_noinline | 1789 | static ieee80211_rx_result debug_noinline |
1781 | ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) | 1790 | ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) |
1782 | { | 1791 | { |
1783 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); | 1792 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1784 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; | 1793 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; |
1785 | 1794 | ||
1786 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 1795 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) |
@@ -1818,11 +1827,11 @@ static void ieee80211_rx_michael_mic_report(struct ieee80211_hdr *hdr, | |||
1818 | * Some hardware seem to generate incorrect Michael MIC | 1827 | * Some hardware seem to generate incorrect Michael MIC |
1819 | * reports; ignore them to avoid triggering countermeasures. | 1828 | * reports; ignore them to avoid triggering countermeasures. |
1820 | */ | 1829 | */ |
1821 | goto ignore; | 1830 | return; |
1822 | } | 1831 | } |
1823 | 1832 | ||
1824 | if (!ieee80211_has_protected(hdr->frame_control)) | 1833 | if (!ieee80211_has_protected(hdr->frame_control)) |
1825 | goto ignore; | 1834 | return; |
1826 | 1835 | ||
1827 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP && keyidx) { | 1836 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP && keyidx) { |
1828 | /* | 1837 | /* |
@@ -1831,35 +1840,33 @@ static void ieee80211_rx_michael_mic_report(struct ieee80211_hdr *hdr, | |||
1831 | * group keys and only the AP is sending real multicast | 1840 | * group keys and only the AP is sending real multicast |
1832 | * frames in the BSS. | 1841 | * frames in the BSS. |
1833 | */ | 1842 | */ |
1834 | goto ignore; | 1843 | return; |
1835 | } | 1844 | } |
1836 | 1845 | ||
1837 | if (!ieee80211_is_data(hdr->frame_control) && | 1846 | if (!ieee80211_is_data(hdr->frame_control) && |
1838 | !ieee80211_is_auth(hdr->frame_control)) | 1847 | !ieee80211_is_auth(hdr->frame_control)) |
1839 | goto ignore; | 1848 | return; |
1840 | 1849 | ||
1841 | mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr, NULL, | 1850 | mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr, NULL, |
1842 | GFP_ATOMIC); | 1851 | GFP_ATOMIC); |
1843 | ignore: | ||
1844 | dev_kfree_skb(rx->skb); | ||
1845 | rx->skb = NULL; | ||
1846 | } | 1852 | } |
1847 | 1853 | ||
1848 | /* TODO: use IEEE80211_RX_FRAGMENTED */ | 1854 | /* TODO: use IEEE80211_RX_FRAGMENTED */ |
1849 | static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx) | 1855 | static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, |
1856 | struct ieee80211_rate *rate) | ||
1850 | { | 1857 | { |
1851 | struct ieee80211_sub_if_data *sdata; | 1858 | struct ieee80211_sub_if_data *sdata; |
1852 | struct ieee80211_local *local = rx->local; | 1859 | struct ieee80211_local *local = rx->local; |
1853 | struct ieee80211_rtap_hdr { | 1860 | struct ieee80211_rtap_hdr { |
1854 | struct ieee80211_radiotap_header hdr; | 1861 | struct ieee80211_radiotap_header hdr; |
1855 | u8 flags; | 1862 | u8 flags; |
1856 | u8 rate; | 1863 | u8 rate_or_pad; |
1857 | __le16 chan_freq; | 1864 | __le16 chan_freq; |
1858 | __le16 chan_flags; | 1865 | __le16 chan_flags; |
1859 | } __attribute__ ((packed)) *rthdr; | 1866 | } __attribute__ ((packed)) *rthdr; |
1860 | struct sk_buff *skb = rx->skb, *skb2; | 1867 | struct sk_buff *skb = rx->skb, *skb2; |
1861 | struct net_device *prev_dev = NULL; | 1868 | struct net_device *prev_dev = NULL; |
1862 | struct ieee80211_rx_status *status = rx->status; | 1869 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
1863 | 1870 | ||
1864 | if (rx->flags & IEEE80211_RX_CMNTR_REPORTED) | 1871 | if (rx->flags & IEEE80211_RX_CMNTR_REPORTED) |
1865 | goto out_free_skb; | 1872 | goto out_free_skb; |
@@ -1873,10 +1880,13 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx) | |||
1873 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); | 1880 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); |
1874 | rthdr->hdr.it_present = | 1881 | rthdr->hdr.it_present = |
1875 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | 1882 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | |
1876 | (1 << IEEE80211_RADIOTAP_RATE) | | ||
1877 | (1 << IEEE80211_RADIOTAP_CHANNEL)); | 1883 | (1 << IEEE80211_RADIOTAP_CHANNEL)); |
1878 | 1884 | ||
1879 | rthdr->rate = rx->rate->bitrate / 5; | 1885 | if (rate) { |
1886 | rthdr->rate_or_pad = rate->bitrate / 5; | ||
1887 | rthdr->hdr.it_present |= | ||
1888 | cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE); | ||
1889 | } | ||
1880 | rthdr->chan_freq = cpu_to_le16(status->freq); | 1890 | rthdr->chan_freq = cpu_to_le16(status->freq); |
1881 | 1891 | ||
1882 | if (status->band == IEEE80211_BAND_5GHZ) | 1892 | if (status->band == IEEE80211_BAND_5GHZ) |
@@ -1929,13 +1939,13 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx) | |||
1929 | 1939 | ||
1930 | static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, | 1940 | static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, |
1931 | struct ieee80211_rx_data *rx, | 1941 | struct ieee80211_rx_data *rx, |
1932 | struct sk_buff *skb) | 1942 | struct sk_buff *skb, |
1943 | struct ieee80211_rate *rate) | ||
1933 | { | 1944 | { |
1934 | ieee80211_rx_result res = RX_DROP_MONITOR; | 1945 | ieee80211_rx_result res = RX_DROP_MONITOR; |
1935 | 1946 | ||
1936 | rx->skb = skb; | 1947 | rx->skb = skb; |
1937 | rx->sdata = sdata; | 1948 | rx->sdata = sdata; |
1938 | rx->dev = sdata->dev; | ||
1939 | 1949 | ||
1940 | #define CALL_RXH(rxh) \ | 1950 | #define CALL_RXH(rxh) \ |
1941 | do { \ | 1951 | do { \ |
@@ -1974,7 +1984,7 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, | |||
1974 | rx->sta->rx_dropped++; | 1984 | rx->sta->rx_dropped++; |
1975 | /* fall through */ | 1985 | /* fall through */ |
1976 | case RX_CONTINUE: | 1986 | case RX_CONTINUE: |
1977 | ieee80211_rx_cooked_monitor(rx); | 1987 | ieee80211_rx_cooked_monitor(rx, rate); |
1978 | break; | 1988 | break; |
1979 | case RX_DROP_UNUSABLE: | 1989 | case RX_DROP_UNUSABLE: |
1980 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); | 1990 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); |
@@ -1994,12 +2004,14 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
1994 | struct ieee80211_rx_data *rx, | 2004 | struct ieee80211_rx_data *rx, |
1995 | struct ieee80211_hdr *hdr) | 2005 | struct ieee80211_hdr *hdr) |
1996 | { | 2006 | { |
1997 | u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len, sdata->vif.type); | 2007 | struct sk_buff *skb = rx->skb; |
2008 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
2009 | u8 *bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type); | ||
1998 | int multicast = is_multicast_ether_addr(hdr->addr1); | 2010 | int multicast = is_multicast_ether_addr(hdr->addr1); |
1999 | 2011 | ||
2000 | switch (sdata->vif.type) { | 2012 | switch (sdata->vif.type) { |
2001 | case NL80211_IFTYPE_STATION: | 2013 | case NL80211_IFTYPE_STATION: |
2002 | if (!bssid && !sdata->use_4addr) | 2014 | if (!bssid && !sdata->u.mgd.use_4addr) |
2003 | return 0; | 2015 | return 0; |
2004 | if (!multicast && | 2016 | if (!multicast && |
2005 | compare_ether_addr(sdata->dev->dev_addr, hdr->addr1) != 0) { | 2017 | compare_ether_addr(sdata->dev->dev_addr, hdr->addr1) != 0) { |
@@ -2026,10 +2038,10 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
2026 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2038 | rx->flags &= ~IEEE80211_RX_RA_MATCH; |
2027 | } else if (!rx->sta) { | 2039 | } else if (!rx->sta) { |
2028 | int rate_idx; | 2040 | int rate_idx; |
2029 | if (rx->status->flag & RX_FLAG_HT) | 2041 | if (status->flag & RX_FLAG_HT) |
2030 | rate_idx = 0; /* TODO: HT rates */ | 2042 | rate_idx = 0; /* TODO: HT rates */ |
2031 | else | 2043 | else |
2032 | rate_idx = rx->status->rate_idx; | 2044 | rate_idx = status->rate_idx; |
2033 | rx->sta = ieee80211_ibss_add_sta(sdata, bssid, hdr->addr2, | 2045 | rx->sta = ieee80211_ibss_add_sta(sdata, bssid, hdr->addr2, |
2034 | BIT(rate_idx)); | 2046 | BIT(rate_idx)); |
2035 | } | 2047 | } |
@@ -2064,8 +2076,6 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
2064 | return 0; | 2076 | return 0; |
2065 | break; | 2077 | break; |
2066 | case NL80211_IFTYPE_MONITOR: | 2078 | case NL80211_IFTYPE_MONITOR: |
2067 | /* take everything */ | ||
2068 | break; | ||
2069 | case NL80211_IFTYPE_UNSPECIFIED: | 2079 | case NL80211_IFTYPE_UNSPECIFIED: |
2070 | case __NL80211_IFTYPE_AFTER_LAST: | 2080 | case __NL80211_IFTYPE_AFTER_LAST: |
2071 | /* should never get here */ | 2081 | /* should never get here */ |
@@ -2098,23 +2108,9 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2098 | rx.skb = skb; | 2108 | rx.skb = skb; |
2099 | rx.local = local; | 2109 | rx.local = local; |
2100 | 2110 | ||
2101 | rx.status = status; | ||
2102 | rx.rate = rate; | ||
2103 | |||
2104 | if (ieee80211_is_data(hdr->frame_control) || ieee80211_is_mgmt(hdr->frame_control)) | 2111 | if (ieee80211_is_data(hdr->frame_control) || ieee80211_is_mgmt(hdr->frame_control)) |
2105 | local->dot11ReceivedFragmentCount++; | 2112 | local->dot11ReceivedFragmentCount++; |
2106 | 2113 | ||
2107 | rx.sta = sta_info_get(local, hdr->addr2); | ||
2108 | if (rx.sta) { | ||
2109 | rx.sdata = rx.sta->sdata; | ||
2110 | rx.dev = rx.sta->sdata->dev; | ||
2111 | } | ||
2112 | |||
2113 | if ((status->flag & RX_FLAG_MMIC_ERROR)) { | ||
2114 | ieee80211_rx_michael_mic_report(hdr, &rx); | ||
2115 | return; | ||
2116 | } | ||
2117 | |||
2118 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || | 2114 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || |
2119 | test_bit(SCAN_OFF_CHANNEL, &local->scanning))) | 2115 | test_bit(SCAN_OFF_CHANNEL, &local->scanning))) |
2120 | rx.flags |= IEEE80211_RX_IN_SCAN; | 2116 | rx.flags |= IEEE80211_RX_IN_SCAN; |
@@ -2122,13 +2118,20 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2122 | ieee80211_parse_qos(&rx); | 2118 | ieee80211_parse_qos(&rx); |
2123 | ieee80211_verify_alignment(&rx); | 2119 | ieee80211_verify_alignment(&rx); |
2124 | 2120 | ||
2125 | skb = rx.skb; | 2121 | rx.sta = sta_info_get(local, hdr->addr2); |
2122 | if (rx.sta) | ||
2123 | rx.sdata = rx.sta->sdata; | ||
2126 | 2124 | ||
2127 | if (rx.sdata && ieee80211_is_data(hdr->frame_control)) { | 2125 | if (rx.sdata && ieee80211_is_data(hdr->frame_control)) { |
2128 | rx.flags |= IEEE80211_RX_RA_MATCH; | 2126 | rx.flags |= IEEE80211_RX_RA_MATCH; |
2129 | prepares = prepare_for_handlers(rx.sdata, &rx, hdr); | 2127 | prepares = prepare_for_handlers(rx.sdata, &rx, hdr); |
2130 | if (prepares) | 2128 | if (prepares) { |
2131 | prev = rx.sdata; | 2129 | if (status->flag & RX_FLAG_MMIC_ERROR) { |
2130 | if (rx.flags & IEEE80211_RX_RA_MATCH) | ||
2131 | ieee80211_rx_michael_mic_report(hdr, &rx); | ||
2132 | } else | ||
2133 | prev = rx.sdata; | ||
2134 | } | ||
2132 | } else list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 2135 | } else list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
2133 | if (!netif_running(sdata->dev)) | 2136 | if (!netif_running(sdata->dev)) |
2134 | continue; | 2137 | continue; |
@@ -2143,6 +2146,13 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2143 | if (!prepares) | 2146 | if (!prepares) |
2144 | continue; | 2147 | continue; |
2145 | 2148 | ||
2149 | if (status->flag & RX_FLAG_MMIC_ERROR) { | ||
2150 | rx.sdata = sdata; | ||
2151 | if (rx.flags & IEEE80211_RX_RA_MATCH) | ||
2152 | ieee80211_rx_michael_mic_report(hdr, &rx); | ||
2153 | continue; | ||
2154 | } | ||
2155 | |||
2146 | /* | 2156 | /* |
2147 | * frame is destined for this interface, but if it's not | 2157 | * frame is destined for this interface, but if it's not |
2148 | * also for the previous one we handle that after the | 2158 | * also for the previous one we handle that after the |
@@ -2168,11 +2178,11 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2168 | prev->dev->name); | 2178 | prev->dev->name); |
2169 | continue; | 2179 | continue; |
2170 | } | 2180 | } |
2171 | ieee80211_invoke_rx_handlers(prev, &rx, skb_new); | 2181 | ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate); |
2172 | prev = sdata; | 2182 | prev = sdata; |
2173 | } | 2183 | } |
2174 | if (prev) | 2184 | if (prev) |
2175 | ieee80211_invoke_rx_handlers(prev, &rx, skb); | 2185 | ieee80211_invoke_rx_handlers(prev, &rx, skb, rate); |
2176 | else | 2186 | else |
2177 | dev_kfree_skb(skb); | 2187 | dev_kfree_skb(skb); |
2178 | } | 2188 | } |
@@ -2201,7 +2211,7 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, | |||
2201 | int index) | 2211 | int index) |
2202 | { | 2212 | { |
2203 | struct ieee80211_supported_band *sband; | 2213 | struct ieee80211_supported_band *sband; |
2204 | struct ieee80211_rate *rate; | 2214 | struct ieee80211_rate *rate = NULL; |
2205 | struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; | 2215 | struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; |
2206 | struct ieee80211_rx_status *status; | 2216 | struct ieee80211_rx_status *status; |
2207 | 2217 | ||
@@ -2212,9 +2222,7 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, | |||
2212 | 2222 | ||
2213 | /* release the reordered frames to stack */ | 2223 | /* release the reordered frames to stack */ |
2214 | sband = hw->wiphy->bands[status->band]; | 2224 | sband = hw->wiphy->bands[status->band]; |
2215 | if (status->flag & RX_FLAG_HT) | 2225 | if (!(status->flag & RX_FLAG_HT)) |
2216 | rate = sband->bitrates; /* TODO: HT rates */ | ||
2217 | else | ||
2218 | rate = &sband->bitrates[status->rate_idx]; | 2226 | rate = &sband->bitrates[status->rate_idx]; |
2219 | __ieee80211_rx_handle_packet(hw, skb, rate); | 2227 | __ieee80211_rx_handle_packet(hw, skb, rate); |
2220 | tid_agg_rx->stored_mpdu_num--; | 2228 | tid_agg_rx->stored_mpdu_num--; |
@@ -2224,6 +2232,18 @@ no_frame: | |||
2224 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); | 2232 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); |
2225 | } | 2233 | } |
2226 | 2234 | ||
2235 | static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, | ||
2236 | struct tid_ampdu_rx *tid_agg_rx, | ||
2237 | u16 head_seq_num) | ||
2238 | { | ||
2239 | int index; | ||
2240 | |||
2241 | while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) { | ||
2242 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % | ||
2243 | tid_agg_rx->buf_size; | ||
2244 | ieee80211_release_reorder_frame(hw, tid_agg_rx, index); | ||
2245 | } | ||
2246 | } | ||
2227 | 2247 | ||
2228 | /* | 2248 | /* |
2229 | * Timeout (in jiffies) for skb's that are waiting in the RX reorder buffer. If | 2249 | * Timeout (in jiffies) for skb's that are waiting in the RX reorder buffer. If |
@@ -2235,15 +2255,17 @@ no_frame: | |||
2235 | #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) | 2255 | #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) |
2236 | 2256 | ||
2237 | /* | 2257 | /* |
2238 | * As it function blongs to Rx path it must be called with | 2258 | * As this function belongs to the RX path it must be under |
2239 | * the proper rcu_read_lock protection for its flow. | 2259 | * rcu_read_lock protection. It returns false if the frame |
2260 | * can be processed immediately, true if it was consumed. | ||
2240 | */ | 2261 | */ |
2241 | static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | 2262 | static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, |
2242 | struct tid_ampdu_rx *tid_agg_rx, | 2263 | struct tid_ampdu_rx *tid_agg_rx, |
2243 | struct sk_buff *skb, | 2264 | struct sk_buff *skb) |
2244 | u16 mpdu_seq_num, | ||
2245 | int bar_req) | ||
2246 | { | 2265 | { |
2266 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
2267 | u16 sc = le16_to_cpu(hdr->seq_ctrl); | ||
2268 | u16 mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4; | ||
2247 | u16 head_seq_num, buf_size; | 2269 | u16 head_seq_num, buf_size; |
2248 | int index; | 2270 | int index; |
2249 | 2271 | ||
@@ -2253,47 +2275,37 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
2253 | /* frame with out of date sequence number */ | 2275 | /* frame with out of date sequence number */ |
2254 | if (seq_less(mpdu_seq_num, head_seq_num)) { | 2276 | if (seq_less(mpdu_seq_num, head_seq_num)) { |
2255 | dev_kfree_skb(skb); | 2277 | dev_kfree_skb(skb); |
2256 | return 1; | 2278 | return true; |
2257 | } | 2279 | } |
2258 | 2280 | ||
2259 | /* if frame sequence number exceeds our buffering window size or | 2281 | /* |
2260 | * block Ack Request arrived - release stored frames */ | 2282 | * If frame the sequence number exceeds our buffering window |
2261 | if ((!seq_less(mpdu_seq_num, head_seq_num + buf_size)) || (bar_req)) { | 2283 | * size release some previous frames to make room for this one. |
2262 | /* new head to the ordering buffer */ | 2284 | */ |
2263 | if (bar_req) | 2285 | if (!seq_less(mpdu_seq_num, head_seq_num + buf_size)) { |
2264 | head_seq_num = mpdu_seq_num; | 2286 | head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size)); |
2265 | else | ||
2266 | head_seq_num = | ||
2267 | seq_inc(seq_sub(mpdu_seq_num, buf_size)); | ||
2268 | /* release stored frames up to new head to stack */ | 2287 | /* release stored frames up to new head to stack */ |
2269 | while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) { | 2288 | ieee80211_release_reorder_frames(hw, tid_agg_rx, head_seq_num); |
2270 | index = seq_sub(tid_agg_rx->head_seq_num, | ||
2271 | tid_agg_rx->ssn) | ||
2272 | % tid_agg_rx->buf_size; | ||
2273 | ieee80211_release_reorder_frame(hw, tid_agg_rx, | ||
2274 | index); | ||
2275 | } | ||
2276 | if (bar_req) | ||
2277 | return 1; | ||
2278 | } | 2289 | } |
2279 | 2290 | ||
2280 | /* now the new frame is always in the range of the reordering */ | 2291 | /* Now the new frame is always in the range of the reordering buffer */ |
2281 | /* buffer window */ | 2292 | |
2282 | index = seq_sub(mpdu_seq_num, tid_agg_rx->ssn) | 2293 | index = seq_sub(mpdu_seq_num, tid_agg_rx->ssn) % tid_agg_rx->buf_size; |
2283 | % tid_agg_rx->buf_size; | 2294 | |
2284 | /* check if we already stored this frame */ | 2295 | /* check if we already stored this frame */ |
2285 | if (tid_agg_rx->reorder_buf[index]) { | 2296 | if (tid_agg_rx->reorder_buf[index]) { |
2286 | dev_kfree_skb(skb); | 2297 | dev_kfree_skb(skb); |
2287 | return 1; | 2298 | return true; |
2288 | } | 2299 | } |
2289 | 2300 | ||
2290 | /* if arrived mpdu is in the right order and nothing else stored */ | 2301 | /* |
2291 | /* release it immediately */ | 2302 | * If the current MPDU is in the right order and nothing else |
2303 | * is stored we can process it directly, no need to buffer it. | ||
2304 | */ | ||
2292 | if (mpdu_seq_num == tid_agg_rx->head_seq_num && | 2305 | if (mpdu_seq_num == tid_agg_rx->head_seq_num && |
2293 | tid_agg_rx->stored_mpdu_num == 0) { | 2306 | tid_agg_rx->stored_mpdu_num == 0) { |
2294 | tid_agg_rx->head_seq_num = | 2307 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); |
2295 | seq_inc(tid_agg_rx->head_seq_num); | 2308 | return false; |
2296 | return 0; | ||
2297 | } | 2309 | } |
2298 | 2310 | ||
2299 | /* put the frame in the reordering buffer */ | 2311 | /* put the frame in the reordering buffer */ |
@@ -2301,8 +2313,8 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
2301 | tid_agg_rx->reorder_time[index] = jiffies; | 2313 | tid_agg_rx->reorder_time[index] = jiffies; |
2302 | tid_agg_rx->stored_mpdu_num++; | 2314 | tid_agg_rx->stored_mpdu_num++; |
2303 | /* release the buffer until next missing frame */ | 2315 | /* release the buffer until next missing frame */ |
2304 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) | 2316 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % |
2305 | % tid_agg_rx->buf_size; | 2317 | tid_agg_rx->buf_size; |
2306 | if (!tid_agg_rx->reorder_buf[index] && | 2318 | if (!tid_agg_rx->reorder_buf[index] && |
2307 | tid_agg_rx->stored_mpdu_num > 1) { | 2319 | tid_agg_rx->stored_mpdu_num > 1) { |
2308 | /* | 2320 | /* |
@@ -2313,12 +2325,12 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
2313 | int skipped = 1; | 2325 | int skipped = 1; |
2314 | for (j = (index + 1) % tid_agg_rx->buf_size; j != index; | 2326 | for (j = (index + 1) % tid_agg_rx->buf_size; j != index; |
2315 | j = (j + 1) % tid_agg_rx->buf_size) { | 2327 | j = (j + 1) % tid_agg_rx->buf_size) { |
2316 | if (tid_agg_rx->reorder_buf[j] == NULL) { | 2328 | if (!tid_agg_rx->reorder_buf[j]) { |
2317 | skipped++; | 2329 | skipped++; |
2318 | continue; | 2330 | continue; |
2319 | } | 2331 | } |
2320 | if (!time_after(jiffies, tid_agg_rx->reorder_time[j] + | 2332 | if (!time_after(jiffies, tid_agg_rx->reorder_time[j] + |
2321 | HZ / 10)) | 2333 | HT_RX_REORDER_BUF_TIMEOUT)) |
2322 | break; | 2334 | break; |
2323 | 2335 | ||
2324 | #ifdef CONFIG_MAC80211_HT_DEBUG | 2336 | #ifdef CONFIG_MAC80211_HT_DEBUG |
@@ -2334,51 +2346,56 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
2334 | * Increment the head seq# also for the skipped slots. | 2346 | * Increment the head seq# also for the skipped slots. |
2335 | */ | 2347 | */ |
2336 | tid_agg_rx->head_seq_num = | 2348 | tid_agg_rx->head_seq_num = |
2337 | (tid_agg_rx->head_seq_num + skipped) & | 2349 | (tid_agg_rx->head_seq_num + skipped) & SEQ_MASK; |
2338 | SEQ_MASK; | ||
2339 | skipped = 0; | 2350 | skipped = 0; |
2340 | } | 2351 | } |
2341 | } else while (tid_agg_rx->reorder_buf[index]) { | 2352 | } else while (tid_agg_rx->reorder_buf[index]) { |
2342 | ieee80211_release_reorder_frame(hw, tid_agg_rx, index); | 2353 | ieee80211_release_reorder_frame(hw, tid_agg_rx, index); |
2343 | index = seq_sub(tid_agg_rx->head_seq_num, | 2354 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % |
2344 | tid_agg_rx->ssn) % tid_agg_rx->buf_size; | 2355 | tid_agg_rx->buf_size; |
2345 | } | 2356 | } |
2346 | return 1; | 2357 | |
2358 | return true; | ||
2347 | } | 2359 | } |
2348 | 2360 | ||
2349 | static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, | 2361 | /* |
2350 | struct sk_buff *skb) | 2362 | * Reorder MPDUs from A-MPDUs, keeping them on a buffer. Returns |
2363 | * true if the MPDU was buffered, false if it should be processed. | ||
2364 | */ | ||
2365 | static bool ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, | ||
2366 | struct sk_buff *skb) | ||
2351 | { | 2367 | { |
2352 | struct ieee80211_hw *hw = &local->hw; | 2368 | struct ieee80211_hw *hw = &local->hw; |
2353 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 2369 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
2354 | struct sta_info *sta; | 2370 | struct sta_info *sta; |
2355 | struct tid_ampdu_rx *tid_agg_rx; | 2371 | struct tid_ampdu_rx *tid_agg_rx; |
2356 | u16 sc; | 2372 | u16 sc; |
2357 | u16 mpdu_seq_num; | ||
2358 | u8 ret = 0; | ||
2359 | int tid; | 2373 | int tid; |
2360 | 2374 | ||
2375 | if (!ieee80211_is_data_qos(hdr->frame_control)) | ||
2376 | return false; | ||
2377 | |||
2378 | /* | ||
2379 | * filter the QoS data rx stream according to | ||
2380 | * STA/TID and check if this STA/TID is on aggregation | ||
2381 | */ | ||
2382 | |||
2361 | sta = sta_info_get(local, hdr->addr2); | 2383 | sta = sta_info_get(local, hdr->addr2); |
2362 | if (!sta) | 2384 | if (!sta) |
2363 | return ret; | 2385 | return false; |
2364 | |||
2365 | /* filter the QoS data rx stream according to | ||
2366 | * STA/TID and check if this STA/TID is on aggregation */ | ||
2367 | if (!ieee80211_is_data_qos(hdr->frame_control)) | ||
2368 | goto end_reorder; | ||
2369 | 2386 | ||
2370 | tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; | 2387 | tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; |
2371 | 2388 | ||
2372 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) | 2389 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) |
2373 | goto end_reorder; | 2390 | return false; |
2374 | 2391 | ||
2375 | tid_agg_rx = sta->ampdu_mlme.tid_rx[tid]; | 2392 | tid_agg_rx = sta->ampdu_mlme.tid_rx[tid]; |
2376 | 2393 | ||
2377 | /* qos null data frames are excluded */ | 2394 | /* qos null data frames are excluded */ |
2378 | if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) | 2395 | if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) |
2379 | goto end_reorder; | 2396 | return false; |
2380 | 2397 | ||
2381 | /* new un-ordered ampdu frame - process it */ | 2398 | /* new, potentially un-ordered, ampdu frame - process it */ |
2382 | 2399 | ||
2383 | /* reset session timer */ | 2400 | /* reset session timer */ |
2384 | if (tid_agg_rx->timeout) | 2401 | if (tid_agg_rx->timeout) |
@@ -2390,16 +2407,11 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, | |||
2390 | if (sc & IEEE80211_SCTL_FRAG) { | 2407 | if (sc & IEEE80211_SCTL_FRAG) { |
2391 | ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr, | 2408 | ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr, |
2392 | tid, 0, WLAN_REASON_QSTA_REQUIRE_SETUP); | 2409 | tid, 0, WLAN_REASON_QSTA_REQUIRE_SETUP); |
2393 | ret = 1; | 2410 | dev_kfree_skb(skb); |
2394 | goto end_reorder; | 2411 | return true; |
2395 | } | 2412 | } |
2396 | 2413 | ||
2397 | /* according to mpdu sequence number deal with reordering buffer */ | 2414 | return ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb); |
2398 | mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4; | ||
2399 | ret = ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, | ||
2400 | mpdu_seq_num, 0); | ||
2401 | end_reorder: | ||
2402 | return ret; | ||
2403 | } | 2415 | } |
2404 | 2416 | ||
2405 | /* | 2417 | /* |
@@ -2457,10 +2469,6 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2457 | status->rate_idx, | 2469 | status->rate_idx, |
2458 | status->rate_idx)) | 2470 | status->rate_idx)) |
2459 | goto drop; | 2471 | goto drop; |
2460 | /* HT rates are not in the table - use the highest legacy rate | ||
2461 | * for now since other parts of mac80211 may not yet be fully | ||
2462 | * MCS aware. */ | ||
2463 | rate = &sband->bitrates[sband->n_bitrates - 1]; | ||
2464 | } else { | 2472 | } else { |
2465 | if (WARN_ON(status->rate_idx < 0 || | 2473 | if (WARN_ON(status->rate_idx < 0 || |
2466 | status->rate_idx >= sband->n_bitrates)) | 2474 | status->rate_idx >= sband->n_bitrates)) |
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c index 68953033403d..aa743a895cf9 100644 --- a/net/mac80211/spectmgmt.c +++ b/net/mac80211/spectmgmt.c | |||
@@ -65,7 +65,7 @@ static void ieee80211_send_refuse_measurement_request(struct ieee80211_sub_if_da | |||
65 | IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED; | 65 | IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED; |
66 | msr_report->u.action.u.measurement.msr_elem.type = request_ie->type; | 66 | msr_report->u.action.u.measurement.msr_elem.type = request_ie->type; |
67 | 67 | ||
68 | ieee80211_tx_skb(sdata, skb, 1); | 68 | ieee80211_tx_skb(sdata, skb); |
69 | } | 69 | } |
70 | 70 | ||
71 | void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, | 71 | void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 396a94806de9..71f370dd24bc 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -116,14 +116,15 @@ struct sta_info *sta_info_get(struct ieee80211_local *local, const u8 *addr) | |||
116 | return sta; | 116 | return sta; |
117 | } | 117 | } |
118 | 118 | ||
119 | struct sta_info *sta_info_get_by_idx(struct ieee80211_local *local, int idx, | 119 | struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata, |
120 | struct net_device *dev) | 120 | int idx) |
121 | { | 121 | { |
122 | struct ieee80211_local *local = sdata->local; | ||
122 | struct sta_info *sta; | 123 | struct sta_info *sta; |
123 | int i = 0; | 124 | int i = 0; |
124 | 125 | ||
125 | list_for_each_entry_rcu(sta, &local->sta_list, list) { | 126 | list_for_each_entry_rcu(sta, &local->sta_list, list) { |
126 | if (dev && dev != sta->sdata->dev) | 127 | if (sdata != sta->sdata) |
127 | continue; | 128 | continue; |
128 | if (i < idx) { | 129 | if (i < idx) { |
129 | ++i; | 130 | ++i; |
@@ -147,8 +148,10 @@ struct sta_info *sta_info_get_by_idx(struct ieee80211_local *local, int idx, | |||
147 | static void __sta_info_free(struct ieee80211_local *local, | 148 | static void __sta_info_free(struct ieee80211_local *local, |
148 | struct sta_info *sta) | 149 | struct sta_info *sta) |
149 | { | 150 | { |
150 | rate_control_free_sta(sta); | 151 | if (sta->rate_ctrl) { |
151 | rate_control_put(sta->rate_ctrl); | 152 | rate_control_free_sta(sta); |
153 | rate_control_put(sta->rate_ctrl); | ||
154 | } | ||
152 | 155 | ||
153 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 156 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
154 | printk(KERN_DEBUG "%s: Destroyed STA %pM\n", | 157 | printk(KERN_DEBUG "%s: Destroyed STA %pM\n", |
@@ -276,6 +279,23 @@ static void sta_unblock(struct work_struct *wk) | |||
276 | ieee80211_sta_ps_deliver_poll_response(sta); | 279 | ieee80211_sta_ps_deliver_poll_response(sta); |
277 | } | 280 | } |
278 | 281 | ||
282 | static int sta_prepare_rate_control(struct ieee80211_local *local, | ||
283 | struct sta_info *sta, gfp_t gfp) | ||
284 | { | ||
285 | if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) | ||
286 | return 0; | ||
287 | |||
288 | sta->rate_ctrl = rate_control_get(local->rate_ctrl); | ||
289 | sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl, | ||
290 | &sta->sta, gfp); | ||
291 | if (!sta->rate_ctrl_priv) { | ||
292 | rate_control_put(sta->rate_ctrl); | ||
293 | return -ENOMEM; | ||
294 | } | ||
295 | |||
296 | return 0; | ||
297 | } | ||
298 | |||
279 | struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | 299 | struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, |
280 | u8 *addr, gfp_t gfp) | 300 | u8 *addr, gfp_t gfp) |
281 | { | 301 | { |
@@ -295,11 +315,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
295 | sta->local = local; | 315 | sta->local = local; |
296 | sta->sdata = sdata; | 316 | sta->sdata = sdata; |
297 | 317 | ||
298 | sta->rate_ctrl = rate_control_get(local->rate_ctrl); | 318 | if (sta_prepare_rate_control(local, sta, gfp)) { |
299 | sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl, | ||
300 | &sta->sta, gfp); | ||
301 | if (!sta->rate_ctrl_priv) { | ||
302 | rate_control_put(sta->rate_ctrl); | ||
303 | kfree(sta); | 319 | kfree(sta); |
304 | return NULL; | 320 | return NULL; |
305 | } | 321 | } |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 4673454176ed..b4810f6aa94f 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -185,6 +185,7 @@ struct sta_ampdu_mlme { | |||
185 | * @lock: used for locking all fields that require locking, see comments | 185 | * @lock: used for locking all fields that require locking, see comments |
186 | * in the header file. | 186 | * in the header file. |
187 | * @flaglock: spinlock for flags accesses | 187 | * @flaglock: spinlock for flags accesses |
188 | * @drv_unblock_wk: used for driver PS unblocking | ||
188 | * @listen_interval: listen interval of this station, when we're acting as AP | 189 | * @listen_interval: listen interval of this station, when we're acting as AP |
189 | * @pin_status: used internally for pinning a STA struct into memory | 190 | * @pin_status: used internally for pinning a STA struct into memory |
190 | * @flags: STA flags, see &enum ieee80211_sta_info_flags | 191 | * @flags: STA flags, see &enum ieee80211_sta_info_flags |
@@ -225,7 +226,6 @@ struct sta_ampdu_mlme { | |||
225 | * @debugfs: debug filesystem info | 226 | * @debugfs: debug filesystem info |
226 | * @sta: station information we share with the driver | 227 | * @sta: station information we share with the driver |
227 | * @dead: set to true when sta is unlinked | 228 | * @dead: set to true when sta is unlinked |
228 | * @drv_unblock_wk used for driver PS unblocking | ||
229 | */ | 229 | */ |
230 | struct sta_info { | 230 | struct sta_info { |
231 | /* General information, mostly static */ | 231 | /* General information, mostly static */ |
@@ -409,8 +409,8 @@ struct sta_info *sta_info_get(struct ieee80211_local *local, const u8 *addr); | |||
409 | /* | 409 | /* |
410 | * Get STA info by index, BROKEN! | 410 | * Get STA info by index, BROKEN! |
411 | */ | 411 | */ |
412 | struct sta_info *sta_info_get_by_idx(struct ieee80211_local *local, int idx, | 412 | struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata, |
413 | struct net_device *dev); | 413 | int idx); |
414 | /* | 414 | /* |
415 | * Create a new STA info, caller owns returned structure | 415 | * Create a new STA info, caller owns returned structure |
416 | * until sta_info_insert(). | 416 | * until sta_info_insert(). |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c new file mode 100644 index 000000000000..9f91fd8e6efb --- /dev/null +++ b/net/mac80211/status.c | |||
@@ -0,0 +1,337 @@ | |||
1 | /* | ||
2 | * Copyright 2002-2005, Instant802 Networks, Inc. | ||
3 | * Copyright 2005-2006, Devicescape Software, Inc. | ||
4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | ||
5 | * Copyright 2008-2009 Johannes Berg <johannes@sipsolutions.net> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <net/mac80211.h> | ||
13 | #include "ieee80211_i.h" | ||
14 | #include "rate.h" | ||
15 | #include "mesh.h" | ||
16 | #include "led.h" | ||
17 | |||
18 | |||
19 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, | ||
20 | struct sk_buff *skb) | ||
21 | { | ||
22 | struct ieee80211_local *local = hw_to_local(hw); | ||
23 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
24 | int tmp; | ||
25 | |||
26 | skb->pkt_type = IEEE80211_TX_STATUS_MSG; | ||
27 | skb_queue_tail(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS ? | ||
28 | &local->skb_queue : &local->skb_queue_unreliable, skb); | ||
29 | tmp = skb_queue_len(&local->skb_queue) + | ||
30 | skb_queue_len(&local->skb_queue_unreliable); | ||
31 | while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT && | ||
32 | (skb = skb_dequeue(&local->skb_queue_unreliable))) { | ||
33 | dev_kfree_skb_irq(skb); | ||
34 | tmp--; | ||
35 | I802_DEBUG_INC(local->tx_status_drop); | ||
36 | } | ||
37 | tasklet_schedule(&local->tasklet); | ||
38 | } | ||
39 | EXPORT_SYMBOL(ieee80211_tx_status_irqsafe); | ||
40 | |||
41 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | ||
42 | struct sta_info *sta, | ||
43 | struct sk_buff *skb) | ||
44 | { | ||
45 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
46 | |||
47 | /* | ||
48 | * XXX: This is temporary! | ||
49 | * | ||
50 | * The problem here is that when we get here, the driver will | ||
51 | * quite likely have pretty much overwritten info->control by | ||
52 | * using info->driver_data or info->rate_driver_data. Thus, | ||
53 | * when passing out the frame to the driver again, we would be | ||
54 | * passing completely bogus data since the driver would then | ||
55 | * expect a properly filled info->control. In mac80211 itself | ||
56 | * the same problem occurs, since we need info->control.vif | ||
57 | * internally. | ||
58 | * | ||
59 | * To fix this, we should send the frame through TX processing | ||
60 | * again. However, it's not that simple, since the frame will | ||
61 | * have been software-encrypted (if applicable) already, and | ||
62 | * encrypting it again doesn't do much good. So to properly do | ||
63 | * that, we not only have to skip the actual 'raw' encryption | ||
64 | * (key selection etc. still has to be done!) but also the | ||
65 | * sequence number assignment since that impacts the crypto | ||
66 | * encapsulation, of course. | ||
67 | * | ||
68 | * Hence, for now, fix the bug by just dropping the frame. | ||
69 | */ | ||
70 | goto drop; | ||
71 | |||
72 | sta->tx_filtered_count++; | ||
73 | |||
74 | /* | ||
75 | * Clear the TX filter mask for this STA when sending the next | ||
76 | * packet. If the STA went to power save mode, this will happen | ||
77 | * when it wakes up for the next time. | ||
78 | */ | ||
79 | set_sta_flags(sta, WLAN_STA_CLEAR_PS_FILT); | ||
80 | |||
81 | /* | ||
82 | * This code races in the following way: | ||
83 | * | ||
84 | * (1) STA sends frame indicating it will go to sleep and does so | ||
85 | * (2) hardware/firmware adds STA to filter list, passes frame up | ||
86 | * (3) hardware/firmware processes TX fifo and suppresses a frame | ||
87 | * (4) we get TX status before having processed the frame and | ||
88 | * knowing that the STA has gone to sleep. | ||
89 | * | ||
90 | * This is actually quite unlikely even when both those events are | ||
91 | * processed from interrupts coming in quickly after one another or | ||
92 | * even at the same time because we queue both TX status events and | ||
93 | * RX frames to be processed by a tasklet and process them in the | ||
94 | * same order that they were received or TX status last. Hence, there | ||
95 | * is no race as long as the frame RX is processed before the next TX | ||
96 | * status, which drivers can ensure, see below. | ||
97 | * | ||
98 | * Note that this can only happen if the hardware or firmware can | ||
99 | * actually add STAs to the filter list, if this is done by the | ||
100 | * driver in response to set_tim() (which will only reduce the race | ||
101 | * this whole filtering tries to solve, not completely solve it) | ||
102 | * this situation cannot happen. | ||
103 | * | ||
104 | * To completely solve this race drivers need to make sure that they | ||
105 | * (a) don't mix the irq-safe/not irq-safe TX status/RX processing | ||
106 | * functions and | ||
107 | * (b) always process RX events before TX status events if ordering | ||
108 | * can be unknown, for example with different interrupt status | ||
109 | * bits. | ||
110 | */ | ||
111 | if (test_sta_flags(sta, WLAN_STA_PS_STA) && | ||
112 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { | ||
113 | skb_queue_tail(&sta->tx_filtered, skb); | ||
114 | return; | ||
115 | } | ||
116 | |||
117 | if (!test_sta_flags(sta, WLAN_STA_PS_STA) && | ||
118 | !(info->flags & IEEE80211_TX_INTFL_RETRIED)) { | ||
119 | /* Software retry the packet once */ | ||
120 | info->flags |= IEEE80211_TX_INTFL_RETRIED; | ||
121 | ieee80211_add_pending_skb(local, skb); | ||
122 | return; | ||
123 | } | ||
124 | |||
125 | drop: | ||
126 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
127 | if (net_ratelimit()) | ||
128 | printk(KERN_DEBUG "%s: dropped TX filtered frame, " | ||
129 | "queue_len=%d PS=%d @%lu\n", | ||
130 | wiphy_name(local->hw.wiphy), | ||
131 | skb_queue_len(&sta->tx_filtered), | ||
132 | !!test_sta_flags(sta, WLAN_STA_PS_STA), jiffies); | ||
133 | #endif | ||
134 | dev_kfree_skb(skb); | ||
135 | } | ||
136 | |||
137 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
138 | { | ||
139 | struct sk_buff *skb2; | ||
140 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
141 | struct ieee80211_local *local = hw_to_local(hw); | ||
142 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
143 | u16 frag, type; | ||
144 | __le16 fc; | ||
145 | struct ieee80211_supported_band *sband; | ||
146 | struct ieee80211_tx_status_rtap_hdr *rthdr; | ||
147 | struct ieee80211_sub_if_data *sdata; | ||
148 | struct net_device *prev_dev = NULL; | ||
149 | struct sta_info *sta; | ||
150 | int retry_count = -1, i; | ||
151 | |||
152 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | ||
153 | /* the HW cannot have attempted that rate */ | ||
154 | if (i >= hw->max_rates) { | ||
155 | info->status.rates[i].idx = -1; | ||
156 | info->status.rates[i].count = 0; | ||
157 | } | ||
158 | |||
159 | retry_count += info->status.rates[i].count; | ||
160 | } | ||
161 | if (retry_count < 0) | ||
162 | retry_count = 0; | ||
163 | |||
164 | rcu_read_lock(); | ||
165 | |||
166 | sband = local->hw.wiphy->bands[info->band]; | ||
167 | |||
168 | sta = sta_info_get(local, hdr->addr1); | ||
169 | |||
170 | if (sta) { | ||
171 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && | ||
172 | test_sta_flags(sta, WLAN_STA_PS_STA)) { | ||
173 | /* | ||
174 | * The STA is in power save mode, so assume | ||
175 | * that this TX packet failed because of that. | ||
176 | */ | ||
177 | ieee80211_handle_filtered_frame(local, sta, skb); | ||
178 | rcu_read_unlock(); | ||
179 | return; | ||
180 | } | ||
181 | |||
182 | fc = hdr->frame_control; | ||
183 | |||
184 | if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && | ||
185 | (ieee80211_is_data_qos(fc))) { | ||
186 | u16 tid, ssn; | ||
187 | u8 *qc; | ||
188 | |||
189 | qc = ieee80211_get_qos_ctl(hdr); | ||
190 | tid = qc[0] & 0xf; | ||
191 | ssn = ((le16_to_cpu(hdr->seq_ctrl) + 0x10) | ||
192 | & IEEE80211_SCTL_SEQ); | ||
193 | ieee80211_send_bar(sta->sdata, hdr->addr1, | ||
194 | tid, ssn); | ||
195 | } | ||
196 | |||
197 | if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) { | ||
198 | ieee80211_handle_filtered_frame(local, sta, skb); | ||
199 | rcu_read_unlock(); | ||
200 | return; | ||
201 | } else { | ||
202 | if (!(info->flags & IEEE80211_TX_STAT_ACK)) | ||
203 | sta->tx_retry_failed++; | ||
204 | sta->tx_retry_count += retry_count; | ||
205 | } | ||
206 | |||
207 | rate_control_tx_status(local, sband, sta, skb); | ||
208 | if (ieee80211_vif_is_mesh(&sta->sdata->vif)) | ||
209 | ieee80211s_update_metric(local, sta, skb); | ||
210 | } | ||
211 | |||
212 | rcu_read_unlock(); | ||
213 | |||
214 | ieee80211_led_tx(local, 0); | ||
215 | |||
216 | /* SNMP counters | ||
217 | * Fragments are passed to low-level drivers as separate skbs, so these | ||
218 | * are actually fragments, not frames. Update frame counters only for | ||
219 | * the first fragment of the frame. */ | ||
220 | |||
221 | frag = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; | ||
222 | type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE; | ||
223 | |||
224 | if (info->flags & IEEE80211_TX_STAT_ACK) { | ||
225 | if (frag == 0) { | ||
226 | local->dot11TransmittedFrameCount++; | ||
227 | if (is_multicast_ether_addr(hdr->addr1)) | ||
228 | local->dot11MulticastTransmittedFrameCount++; | ||
229 | if (retry_count > 0) | ||
230 | local->dot11RetryCount++; | ||
231 | if (retry_count > 1) | ||
232 | local->dot11MultipleRetryCount++; | ||
233 | } | ||
234 | |||
235 | /* This counter shall be incremented for an acknowledged MPDU | ||
236 | * with an individual address in the address 1 field or an MPDU | ||
237 | * with a multicast address in the address 1 field of type Data | ||
238 | * or Management. */ | ||
239 | if (!is_multicast_ether_addr(hdr->addr1) || | ||
240 | type == IEEE80211_FTYPE_DATA || | ||
241 | type == IEEE80211_FTYPE_MGMT) | ||
242 | local->dot11TransmittedFragmentCount++; | ||
243 | } else { | ||
244 | if (frag == 0) | ||
245 | local->dot11FailedCount++; | ||
246 | } | ||
247 | |||
248 | /* this was a transmitted frame, but now we want to reuse it */ | ||
249 | skb_orphan(skb); | ||
250 | |||
251 | /* | ||
252 | * This is a bit racy but we can avoid a lot of work | ||
253 | * with this test... | ||
254 | */ | ||
255 | if (!local->monitors && !local->cooked_mntrs) { | ||
256 | dev_kfree_skb(skb); | ||
257 | return; | ||
258 | } | ||
259 | |||
260 | /* send frame to monitor interfaces now */ | ||
261 | |||
262 | if (skb_headroom(skb) < sizeof(*rthdr)) { | ||
263 | printk(KERN_ERR "ieee80211_tx_status: headroom too small\n"); | ||
264 | dev_kfree_skb(skb); | ||
265 | return; | ||
266 | } | ||
267 | |||
268 | rthdr = (struct ieee80211_tx_status_rtap_hdr *) | ||
269 | skb_push(skb, sizeof(*rthdr)); | ||
270 | |||
271 | memset(rthdr, 0, sizeof(*rthdr)); | ||
272 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); | ||
273 | rthdr->hdr.it_present = | ||
274 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | | ||
275 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES) | | ||
276 | (1 << IEEE80211_RADIOTAP_RATE)); | ||
277 | |||
278 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && | ||
279 | !is_multicast_ether_addr(hdr->addr1)) | ||
280 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); | ||
281 | |||
282 | /* | ||
283 | * XXX: Once radiotap gets the bitmap reset thing the vendor | ||
284 | * extensions proposal contains, we can actually report | ||
285 | * the whole set of tries we did. | ||
286 | */ | ||
287 | if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || | ||
288 | (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) | ||
289 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); | ||
290 | else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) | ||
291 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); | ||
292 | if (info->status.rates[0].idx >= 0 && | ||
293 | !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) | ||
294 | rthdr->rate = sband->bitrates[ | ||
295 | info->status.rates[0].idx].bitrate / 5; | ||
296 | |||
297 | /* for now report the total retry_count */ | ||
298 | rthdr->data_retries = retry_count; | ||
299 | |||
300 | /* XXX: is this sufficient for BPF? */ | ||
301 | skb_set_mac_header(skb, 0); | ||
302 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
303 | skb->pkt_type = PACKET_OTHERHOST; | ||
304 | skb->protocol = htons(ETH_P_802_2); | ||
305 | memset(skb->cb, 0, sizeof(skb->cb)); | ||
306 | |||
307 | rcu_read_lock(); | ||
308 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | ||
309 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR) { | ||
310 | if (!netif_running(sdata->dev)) | ||
311 | continue; | ||
312 | |||
313 | if ((sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) && | ||
314 | !(info->flags & IEEE80211_TX_CTL_INJECTED) && | ||
315 | (type == IEEE80211_FTYPE_DATA)) | ||
316 | continue; | ||
317 | |||
318 | if (prev_dev) { | ||
319 | skb2 = skb_clone(skb, GFP_ATOMIC); | ||
320 | if (skb2) { | ||
321 | skb2->dev = prev_dev; | ||
322 | netif_rx(skb2); | ||
323 | } | ||
324 | } | ||
325 | |||
326 | prev_dev = sdata->dev; | ||
327 | } | ||
328 | } | ||
329 | if (prev_dev) { | ||
330 | skb->dev = prev_dev; | ||
331 | netif_rx(skb); | ||
332 | skb = NULL; | ||
333 | } | ||
334 | rcu_read_unlock(); | ||
335 | dev_kfree_skb(skb); | ||
336 | } | ||
337 | EXPORT_SYMBOL(ieee80211_tx_status); | ||
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index 964b7faa7f17..4921d724b6c7 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c | |||
@@ -301,9 +301,9 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
301 | #endif | 301 | #endif |
302 | if (key->local->ops->update_tkip_key && | 302 | if (key->local->ops->update_tkip_key && |
303 | key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | 303 | key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { |
304 | u8 bcast[ETH_ALEN] = | 304 | static const u8 bcast[ETH_ALEN] = |
305 | {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | 305 | {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
306 | u8 *sta_addr = key->sta->sta.addr; | 306 | const u8 *sta_addr = key->sta->sta.addr; |
307 | 307 | ||
308 | if (is_multicast_ether_addr(ra)) | 308 | if (is_multicast_ether_addr(ra)) |
309 | sta_addr = bcast; | 309 | sta_addr = bcast; |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 3ad053f6de12..943def2b07df 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1051,7 +1051,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1051 | 1051 | ||
1052 | hdr = (struct ieee80211_hdr *) skb->data; | 1052 | hdr = (struct ieee80211_hdr *) skb->data; |
1053 | 1053 | ||
1054 | if ((sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && sdata->use_4addr) | 1054 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
1055 | tx->sta = rcu_dereference(sdata->u.vlan.sta); | 1055 | tx->sta = rcu_dereference(sdata->u.vlan.sta); |
1056 | if (!tx->sta) | 1056 | if (!tx->sta) |
1057 | tx->sta = sta_info_get(local, hdr->addr1); | 1057 | tx->sta = sta_info_get(local, hdr->addr1); |
@@ -1219,7 +1219,8 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | |||
1219 | CALL_TXH(ieee80211_tx_h_ps_buf); | 1219 | CALL_TXH(ieee80211_tx_h_ps_buf); |
1220 | CALL_TXH(ieee80211_tx_h_select_key); | 1220 | CALL_TXH(ieee80211_tx_h_select_key); |
1221 | CALL_TXH(ieee80211_tx_h_michael_mic_add); | 1221 | CALL_TXH(ieee80211_tx_h_michael_mic_add); |
1222 | CALL_TXH(ieee80211_tx_h_rate_ctrl); | 1222 | if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) |
1223 | CALL_TXH(ieee80211_tx_h_rate_ctrl); | ||
1223 | CALL_TXH(ieee80211_tx_h_misc); | 1224 | CALL_TXH(ieee80211_tx_h_misc); |
1224 | CALL_TXH(ieee80211_tx_h_sequence); | 1225 | CALL_TXH(ieee80211_tx_h_sequence); |
1225 | CALL_TXH(ieee80211_tx_h_fragment); | 1226 | CALL_TXH(ieee80211_tx_h_fragment); |
@@ -1430,8 +1431,6 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1430 | int headroom; | 1431 | int headroom; |
1431 | bool may_encrypt; | 1432 | bool may_encrypt; |
1432 | 1433 | ||
1433 | dev_hold(sdata->dev); | ||
1434 | |||
1435 | if (need_dynamic_ps(local)) { | 1434 | if (need_dynamic_ps(local)) { |
1436 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | 1435 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { |
1437 | ieee80211_stop_queues_by_reason(&local->hw, | 1436 | ieee80211_stop_queues_by_reason(&local->hw, |
@@ -1444,7 +1443,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1444 | msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); | 1443 | msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); |
1445 | } | 1444 | } |
1446 | 1445 | ||
1447 | info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | 1446 | rcu_read_lock(); |
1448 | 1447 | ||
1449 | if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) { | 1448 | if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) { |
1450 | int hdrlen; | 1449 | int hdrlen; |
@@ -1468,7 +1467,6 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1468 | * support we will need a different mechanism. | 1467 | * support we will need a different mechanism. |
1469 | */ | 1468 | */ |
1470 | 1469 | ||
1471 | rcu_read_lock(); | ||
1472 | list_for_each_entry_rcu(tmp_sdata, &local->interfaces, | 1470 | list_for_each_entry_rcu(tmp_sdata, &local->interfaces, |
1473 | list) { | 1471 | list) { |
1474 | if (!netif_running(tmp_sdata->dev)) | 1472 | if (!netif_running(tmp_sdata->dev)) |
@@ -1477,13 +1475,10 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1477 | continue; | 1475 | continue; |
1478 | if (compare_ether_addr(tmp_sdata->dev->dev_addr, | 1476 | if (compare_ether_addr(tmp_sdata->dev->dev_addr, |
1479 | hdr->addr2) == 0) { | 1477 | hdr->addr2) == 0) { |
1480 | dev_hold(tmp_sdata->dev); | ||
1481 | dev_put(sdata->dev); | ||
1482 | sdata = tmp_sdata; | 1478 | sdata = tmp_sdata; |
1483 | break; | 1479 | break; |
1484 | } | 1480 | } |
1485 | } | 1481 | } |
1486 | rcu_read_unlock(); | ||
1487 | } | 1482 | } |
1488 | } | 1483 | } |
1489 | 1484 | ||
@@ -1497,7 +1492,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1497 | 1492 | ||
1498 | if (ieee80211_skb_resize(local, skb, headroom, may_encrypt)) { | 1493 | if (ieee80211_skb_resize(local, skb, headroom, may_encrypt)) { |
1499 | dev_kfree_skb(skb); | 1494 | dev_kfree_skb(skb); |
1500 | dev_put(sdata->dev); | 1495 | rcu_read_unlock(); |
1501 | return; | 1496 | return; |
1502 | } | 1497 | } |
1503 | 1498 | ||
@@ -1508,13 +1503,13 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1508 | !is_multicast_ether_addr(hdr->addr1)) | 1503 | !is_multicast_ether_addr(hdr->addr1)) |
1509 | if (mesh_nexthop_lookup(skb, sdata)) { | 1504 | if (mesh_nexthop_lookup(skb, sdata)) { |
1510 | /* skb queued: don't free */ | 1505 | /* skb queued: don't free */ |
1511 | dev_put(sdata->dev); | 1506 | rcu_read_unlock(); |
1512 | return; | 1507 | return; |
1513 | } | 1508 | } |
1514 | 1509 | ||
1515 | ieee80211_select_queue(local, skb); | 1510 | ieee80211_select_queue(local, skb); |
1516 | ieee80211_tx(sdata, skb, false); | 1511 | ieee80211_tx(sdata, skb, false); |
1517 | dev_put(sdata->dev); | 1512 | rcu_read_unlock(); |
1518 | } | 1513 | } |
1519 | 1514 | ||
1520 | netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, | 1515 | netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, |
@@ -1578,6 +1573,8 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
1578 | 1573 | ||
1579 | memset(info, 0, sizeof(*info)); | 1574 | memset(info, 0, sizeof(*info)); |
1580 | 1575 | ||
1576 | info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
1577 | |||
1581 | /* pass the radiotap header up to xmit */ | 1578 | /* pass the radiotap header up to xmit */ |
1582 | ieee80211_xmit(IEEE80211_DEV_TO_SUB_IF(dev), skb); | 1579 | ieee80211_xmit(IEEE80211_DEV_TO_SUB_IF(dev), skb); |
1583 | return NETDEV_TX_OK; | 1580 | return NETDEV_TX_OK; |
@@ -1635,8 +1632,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1635 | switch (sdata->vif.type) { | 1632 | switch (sdata->vif.type) { |
1636 | case NL80211_IFTYPE_AP_VLAN: | 1633 | case NL80211_IFTYPE_AP_VLAN: |
1637 | rcu_read_lock(); | 1634 | rcu_read_lock(); |
1638 | if (sdata->use_4addr) | 1635 | sta = rcu_dereference(sdata->u.vlan.sta); |
1639 | sta = rcu_dereference(sdata->u.vlan.sta); | ||
1640 | if (sta) { | 1636 | if (sta) { |
1641 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); | 1637 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
1642 | /* RA TA DA SA */ | 1638 | /* RA TA DA SA */ |
@@ -1687,21 +1683,25 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1687 | /* packet from other interface */ | 1683 | /* packet from other interface */ |
1688 | struct mesh_path *mppath; | 1684 | struct mesh_path *mppath; |
1689 | int is_mesh_mcast = 1; | 1685 | int is_mesh_mcast = 1; |
1690 | char *mesh_da; | 1686 | const u8 *mesh_da; |
1691 | 1687 | ||
1692 | rcu_read_lock(); | 1688 | rcu_read_lock(); |
1693 | if (is_multicast_ether_addr(skb->data)) | 1689 | if (is_multicast_ether_addr(skb->data)) |
1694 | /* DA TA mSA AE:SA */ | 1690 | /* DA TA mSA AE:SA */ |
1695 | mesh_da = skb->data; | 1691 | mesh_da = skb->data; |
1696 | else { | 1692 | else { |
1693 | static const u8 bcast[ETH_ALEN] = | ||
1694 | { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | ||
1695 | |||
1697 | mppath = mpp_path_lookup(skb->data, sdata); | 1696 | mppath = mpp_path_lookup(skb->data, sdata); |
1698 | if (mppath) { | 1697 | if (mppath) { |
1699 | /* RA TA mDA mSA AE:DA SA */ | 1698 | /* RA TA mDA mSA AE:DA SA */ |
1700 | mesh_da = mppath->mpp; | 1699 | mesh_da = mppath->mpp; |
1701 | is_mesh_mcast = 0; | 1700 | is_mesh_mcast = 0; |
1702 | } else | 1701 | } else { |
1703 | /* DA TA mSA AE:SA */ | 1702 | /* DA TA mSA AE:SA */ |
1704 | mesh_da = dev->broadcast; | 1703 | mesh_da = bcast; |
1704 | } | ||
1705 | } | 1705 | } |
1706 | hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, | 1706 | hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, |
1707 | mesh_da, dev->dev_addr); | 1707 | mesh_da, dev->dev_addr); |
@@ -1726,7 +1726,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1726 | #endif | 1726 | #endif |
1727 | case NL80211_IFTYPE_STATION: | 1727 | case NL80211_IFTYPE_STATION: |
1728 | memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); | 1728 | memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); |
1729 | if (sdata->use_4addr && ethertype != ETH_P_PAE) { | 1729 | if (sdata->u.mgd.use_4addr && ethertype != ETH_P_PAE) { |
1730 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); | 1730 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
1731 | /* RA TA DA SA */ | 1731 | /* RA TA DA SA */ |
1732 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); | 1732 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); |
@@ -1964,12 +1964,10 @@ void ieee80211_tx_pending(unsigned long data) | |||
1964 | } | 1964 | } |
1965 | 1965 | ||
1966 | sdata = vif_to_sdata(info->control.vif); | 1966 | sdata = vif_to_sdata(info->control.vif); |
1967 | dev_hold(sdata->dev); | ||
1968 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, | 1967 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, |
1969 | flags); | 1968 | flags); |
1970 | 1969 | ||
1971 | txok = ieee80211_tx_pending_skb(local, skb); | 1970 | txok = ieee80211_tx_pending_skb(local, skb); |
1972 | dev_put(sdata->dev); | ||
1973 | if (!txok) | 1971 | if (!txok) |
1974 | __skb_queue_head(&local->pending[i], skb); | 1972 | __skb_queue_head(&local->pending[i], skb); |
1975 | spin_lock_irqsave(&local->queue_stop_reason_lock, | 1973 | spin_lock_irqsave(&local->queue_stop_reason_lock, |
@@ -2282,17 +2280,12 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
2282 | } | 2280 | } |
2283 | EXPORT_SYMBOL(ieee80211_get_buffered_bc); | 2281 | EXPORT_SYMBOL(ieee80211_get_buffered_bc); |
2284 | 2282 | ||
2285 | void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, | 2283 | void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) |
2286 | int encrypt) | ||
2287 | { | 2284 | { |
2288 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
2289 | skb_set_mac_header(skb, 0); | 2285 | skb_set_mac_header(skb, 0); |
2290 | skb_set_network_header(skb, 0); | 2286 | skb_set_network_header(skb, 0); |
2291 | skb_set_transport_header(skb, 0); | 2287 | skb_set_transport_header(skb, 0); |
2292 | 2288 | ||
2293 | if (!encrypt) | ||
2294 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | ||
2295 | |||
2296 | /* | 2289 | /* |
2297 | * The other path calling ieee80211_xmit is from the tasklet, | 2290 | * The other path calling ieee80211_xmit is from the tasklet, |
2298 | * and while we can handle concurrent transmissions locking | 2291 | * and while we can handle concurrent transmissions locking |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index da86e1592f8c..2fb0432ac830 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -666,8 +666,8 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
666 | elems->mesh_id_len = elen; | 666 | elems->mesh_id_len = elen; |
667 | break; | 667 | break; |
668 | case WLAN_EID_MESH_CONFIG: | 668 | case WLAN_EID_MESH_CONFIG: |
669 | elems->mesh_config = pos; | 669 | if (elen >= sizeof(struct ieee80211_meshconf_ie)) |
670 | elems->mesh_config_len = elen; | 670 | elems->mesh_config = (void *)pos; |
671 | break; | 671 | break; |
672 | case WLAN_EID_PEER_LINK: | 672 | case WLAN_EID_PEER_LINK: |
673 | elems->peer_link = pos; | 673 | elems->peer_link = pos; |
@@ -872,7 +872,8 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | |||
872 | WARN_ON(err); | 872 | WARN_ON(err); |
873 | } | 873 | } |
874 | 874 | ||
875 | ieee80211_tx_skb(sdata, skb, 0); | 875 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
876 | ieee80211_tx_skb(sdata, skb); | ||
876 | } | 877 | } |
877 | 878 | ||
878 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | 879 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, |
@@ -974,7 +975,8 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | |||
974 | skb_put(skb, ieee80211_build_preq_ies(local, pos, ie, ie_len, | 975 | skb_put(skb, ieee80211_build_preq_ies(local, pos, ie, ie_len, |
975 | local->hw.conf.channel->band)); | 976 | local->hw.conf.channel->band)); |
976 | 977 | ||
977 | ieee80211_tx_skb(sdata, skb, 0); | 978 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
979 | ieee80211_tx_skb(sdata, skb); | ||
978 | } | 980 | } |
979 | 981 | ||
980 | u32 ieee80211_sta_get_rates(struct ieee80211_local *local, | 982 | u32 ieee80211_sta_get_rates(struct ieee80211_local *local, |
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index 8a980f136941..247123fe1a7a 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c | |||
@@ -281,16 +281,18 @@ bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) | |||
281 | ieee80211_rx_result | 281 | ieee80211_rx_result |
282 | ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) | 282 | ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) |
283 | { | 283 | { |
284 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 284 | struct sk_buff *skb = rx->skb; |
285 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
286 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
285 | 287 | ||
286 | if (!ieee80211_is_data(hdr->frame_control) && | 288 | if (!ieee80211_is_data(hdr->frame_control) && |
287 | !ieee80211_is_auth(hdr->frame_control)) | 289 | !ieee80211_is_auth(hdr->frame_control)) |
288 | return RX_CONTINUE; | 290 | return RX_CONTINUE; |
289 | 291 | ||
290 | if (!(rx->status->flag & RX_FLAG_DECRYPTED)) { | 292 | if (!(status->flag & RX_FLAG_DECRYPTED)) { |
291 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) | 293 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) |
292 | return RX_DROP_UNUSABLE; | 294 | return RX_DROP_UNUSABLE; |
293 | } else if (!(rx->status->flag & RX_FLAG_IV_STRIPPED)) { | 295 | } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) { |
294 | ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); | 296 | ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); |
295 | /* remove ICV */ | 297 | /* remove ICV */ |
296 | skb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN); | 298 | skb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN); |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 70778694877b..5332014cb229 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -85,16 +85,16 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
85 | u8 *data, *key = NULL, key_offset; | 85 | u8 *data, *key = NULL, key_offset; |
86 | size_t data_len; | 86 | size_t data_len; |
87 | unsigned int hdrlen; | 87 | unsigned int hdrlen; |
88 | struct ieee80211_hdr *hdr; | ||
89 | u8 mic[MICHAEL_MIC_LEN]; | 88 | u8 mic[MICHAEL_MIC_LEN]; |
90 | struct sk_buff *skb = rx->skb; | 89 | struct sk_buff *skb = rx->skb; |
90 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
91 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
91 | int authenticator = 1, wpa_test = 0; | 92 | int authenticator = 1, wpa_test = 0; |
92 | 93 | ||
93 | /* No way to verify the MIC if the hardware stripped it */ | 94 | /* No way to verify the MIC if the hardware stripped it */ |
94 | if (rx->status->flag & RX_FLAG_MMIC_STRIPPED) | 95 | if (status->flag & RX_FLAG_MMIC_STRIPPED) |
95 | return RX_CONTINUE; | 96 | return RX_CONTINUE; |
96 | 97 | ||
97 | hdr = (struct ieee80211_hdr *)skb->data; | ||
98 | if (!rx->key || rx->key->conf.alg != ALG_TKIP || | 98 | if (!rx->key || rx->key->conf.alg != ALG_TKIP || |
99 | !ieee80211_has_protected(hdr->frame_control) || | 99 | !ieee80211_has_protected(hdr->frame_control) || |
100 | !ieee80211_is_data_present(hdr->frame_control)) | 100 | !ieee80211_is_data_present(hdr->frame_control)) |
@@ -216,6 +216,7 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
216 | int hdrlen, res, hwaccel = 0, wpa_test = 0; | 216 | int hdrlen, res, hwaccel = 0, wpa_test = 0; |
217 | struct ieee80211_key *key = rx->key; | 217 | struct ieee80211_key *key = rx->key; |
218 | struct sk_buff *skb = rx->skb; | 218 | struct sk_buff *skb = rx->skb; |
219 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
219 | 220 | ||
220 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 221 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
221 | 222 | ||
@@ -225,8 +226,8 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
225 | if (!rx->sta || skb->len - hdrlen < 12) | 226 | if (!rx->sta || skb->len - hdrlen < 12) |
226 | return RX_DROP_UNUSABLE; | 227 | return RX_DROP_UNUSABLE; |
227 | 228 | ||
228 | if (rx->status->flag & RX_FLAG_DECRYPTED) { | 229 | if (status->flag & RX_FLAG_DECRYPTED) { |
229 | if (rx->status->flag & RX_FLAG_IV_STRIPPED) { | 230 | if (status->flag & RX_FLAG_IV_STRIPPED) { |
230 | /* | 231 | /* |
231 | * Hardware took care of all processing, including | 232 | * Hardware took care of all processing, including |
232 | * replay protection, and stripped the ICV/IV so | 233 | * replay protection, and stripped the ICV/IV so |
@@ -442,6 +443,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
442 | int hdrlen; | 443 | int hdrlen; |
443 | struct ieee80211_key *key = rx->key; | 444 | struct ieee80211_key *key = rx->key; |
444 | struct sk_buff *skb = rx->skb; | 445 | struct sk_buff *skb = rx->skb; |
446 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
445 | u8 pn[CCMP_PN_LEN]; | 447 | u8 pn[CCMP_PN_LEN]; |
446 | int data_len; | 448 | int data_len; |
447 | 449 | ||
@@ -455,8 +457,8 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
455 | if (!rx->sta || data_len < 0) | 457 | if (!rx->sta || data_len < 0) |
456 | return RX_DROP_UNUSABLE; | 458 | return RX_DROP_UNUSABLE; |
457 | 459 | ||
458 | if ((rx->status->flag & RX_FLAG_DECRYPTED) && | 460 | if ((status->flag & RX_FLAG_DECRYPTED) && |
459 | (rx->status->flag & RX_FLAG_IV_STRIPPED)) | 461 | (status->flag & RX_FLAG_IV_STRIPPED)) |
460 | return RX_CONTINUE; | 462 | return RX_CONTINUE; |
461 | 463 | ||
462 | ccmp_hdr2pn(pn, skb->data + hdrlen); | 464 | ccmp_hdr2pn(pn, skb->data + hdrlen); |
@@ -466,7 +468,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
466 | return RX_DROP_UNUSABLE; | 468 | return RX_DROP_UNUSABLE; |
467 | } | 469 | } |
468 | 470 | ||
469 | if (!(rx->status->flag & RX_FLAG_DECRYPTED)) { | 471 | if (!(status->flag & RX_FLAG_DECRYPTED)) { |
470 | /* hardware didn't decrypt/verify MIC */ | 472 | /* hardware didn't decrypt/verify MIC */ |
471 | ccmp_special_blocks(skb, pn, key->u.ccmp.rx_crypto_buf, 1); | 473 | ccmp_special_blocks(skb, pn, key->u.ccmp.rx_crypto_buf, 1); |
472 | 474 | ||
@@ -563,6 +565,7 @@ ieee80211_rx_result | |||
563 | ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) | 565 | ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) |
564 | { | 566 | { |
565 | struct sk_buff *skb = rx->skb; | 567 | struct sk_buff *skb = rx->skb; |
568 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
566 | struct ieee80211_key *key = rx->key; | 569 | struct ieee80211_key *key = rx->key; |
567 | struct ieee80211_mmie *mmie; | 570 | struct ieee80211_mmie *mmie; |
568 | u8 aad[20], mic[8], ipn[6]; | 571 | u8 aad[20], mic[8], ipn[6]; |
@@ -571,8 +574,8 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) | |||
571 | if (!ieee80211_is_mgmt(hdr->frame_control)) | 574 | if (!ieee80211_is_mgmt(hdr->frame_control)) |
572 | return RX_CONTINUE; | 575 | return RX_CONTINUE; |
573 | 576 | ||
574 | if ((rx->status->flag & RX_FLAG_DECRYPTED) && | 577 | if ((status->flag & RX_FLAG_DECRYPTED) && |
575 | (rx->status->flag & RX_FLAG_IV_STRIPPED)) | 578 | (status->flag & RX_FLAG_IV_STRIPPED)) |
576 | return RX_CONTINUE; | 579 | return RX_CONTINUE; |
577 | 580 | ||
578 | if (skb->len < 24 + sizeof(*mmie)) | 581 | if (skb->len < 24 + sizeof(*mmie)) |
@@ -591,7 +594,7 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) | |||
591 | return RX_DROP_UNUSABLE; | 594 | return RX_DROP_UNUSABLE; |
592 | } | 595 | } |
593 | 596 | ||
594 | if (!(rx->status->flag & RX_FLAG_DECRYPTED)) { | 597 | if (!(status->flag & RX_FLAG_DECRYPTED)) { |
595 | /* hardware didn't decrypt/verify MIC */ | 598 | /* hardware didn't decrypt/verify MIC */ |
596 | bip_aad(skb, aad); | 599 | bip_aad(skb, aad); |
597 | ieee80211_aes_cmac(key->u.aes_cmac.tfm, | 600 | ieee80211_aes_cmac(key->u.aes_cmac.tfm, |
diff --git a/net/rfkill/core.c b/net/rfkill/core.c index ba2efb960c60..09f4e161799b 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c | |||
@@ -592,11 +592,13 @@ static const char *rfkill_get_type_str(enum rfkill_type type) | |||
592 | return "wwan"; | 592 | return "wwan"; |
593 | case RFKILL_TYPE_GPS: | 593 | case RFKILL_TYPE_GPS: |
594 | return "gps"; | 594 | return "gps"; |
595 | case RFKILL_TYPE_FM: | ||
596 | return "fm"; | ||
595 | default: | 597 | default: |
596 | BUG(); | 598 | BUG(); |
597 | } | 599 | } |
598 | 600 | ||
599 | BUILD_BUG_ON(NUM_RFKILL_TYPES != RFKILL_TYPE_GPS + 1); | 601 | BUILD_BUG_ON(NUM_RFKILL_TYPES != RFKILL_TYPE_FM + 1); |
600 | } | 602 | } |
601 | 603 | ||
602 | static ssize_t rfkill_type_show(struct device *dev, | 604 | static ssize_t rfkill_type_show(struct device *dev, |
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig index 614bdcec1c80..90e93a5701aa 100644 --- a/net/wireless/Kconfig +++ b/net/wireless/Kconfig | |||
@@ -74,12 +74,6 @@ config CFG80211_REG_DEBUG | |||
74 | 74 | ||
75 | If unsure, say N. | 75 | If unsure, say N. |
76 | 76 | ||
77 | config CFG80211_DEFAULT_PS_VALUE | ||
78 | int | ||
79 | default 1 if CFG80211_DEFAULT_PS | ||
80 | default 0 | ||
81 | depends on CFG80211 | ||
82 | |||
83 | config CFG80211_DEFAULT_PS | 77 | config CFG80211_DEFAULT_PS |
84 | bool "enable powersave by default" | 78 | bool "enable powersave by default" |
85 | depends on CFG80211 | 79 | depends on CFG80211 |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 45bd63ad2eb2..fe6f402a22af 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -231,7 +231,7 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev, | |||
231 | struct wireless_dev *wdev; | 231 | struct wireless_dev *wdev; |
232 | int err = 0; | 232 | int err = 0; |
233 | 233 | ||
234 | if (!rdev->wiphy.netnsok) | 234 | if (!(rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK)) |
235 | return -EOPNOTSUPP; | 235 | return -EOPNOTSUPP; |
236 | 236 | ||
237 | list_for_each_entry(wdev, &rdev->netdev_list, list) { | 237 | list_for_each_entry(wdev, &rdev->netdev_list, list) { |
@@ -368,7 +368,9 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) | |||
368 | rdev->wiphy.dev.class = &ieee80211_class; | 368 | rdev->wiphy.dev.class = &ieee80211_class; |
369 | rdev->wiphy.dev.platform_data = rdev; | 369 | rdev->wiphy.dev.platform_data = rdev; |
370 | 370 | ||
371 | rdev->wiphy.ps_default = CONFIG_CFG80211_DEFAULT_PS_VALUE; | 371 | #ifdef CONFIG_CFG80211_DEFAULT_PS |
372 | rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
373 | #endif | ||
372 | 374 | ||
373 | wiphy_net_set(&rdev->wiphy, &init_net); | 375 | wiphy_net_set(&rdev->wiphy, &init_net); |
374 | 376 | ||
@@ -483,7 +485,7 @@ int wiphy_register(struct wiphy *wiphy) | |||
483 | if (IS_ERR(rdev->wiphy.debugfsdir)) | 485 | if (IS_ERR(rdev->wiphy.debugfsdir)) |
484 | rdev->wiphy.debugfsdir = NULL; | 486 | rdev->wiphy.debugfsdir = NULL; |
485 | 487 | ||
486 | if (wiphy->custom_regulatory) { | 488 | if (wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) { |
487 | struct regulatory_request request; | 489 | struct regulatory_request request; |
488 | 490 | ||
489 | request.wiphy_idx = get_wiphy_idx(wiphy); | 491 | request.wiphy_idx = get_wiphy_idx(wiphy); |
@@ -681,7 +683,10 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, | |||
681 | wdev->wext.default_key = -1; | 683 | wdev->wext.default_key = -1; |
682 | wdev->wext.default_mgmt_key = -1; | 684 | wdev->wext.default_mgmt_key = -1; |
683 | wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; | 685 | wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; |
684 | wdev->wext.ps = wdev->wiphy->ps_default; | 686 | if (wdev->wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT) |
687 | wdev->wext.ps = true; | ||
688 | else | ||
689 | wdev->wext.ps = false; | ||
685 | wdev->wext.ps_timeout = 100; | 690 | wdev->wext.ps_timeout = 100; |
686 | if (rdev->ops->set_power_mgmt) | 691 | if (rdev->ops->set_power_mgmt) |
687 | if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, | 692 | if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, |
@@ -693,6 +698,10 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, | |||
693 | #endif | 698 | #endif |
694 | if (!dev->ethtool_ops) | 699 | if (!dev->ethtool_ops) |
695 | dev->ethtool_ops = &cfg80211_ethtool_ops; | 700 | dev->ethtool_ops = &cfg80211_ethtool_ops; |
701 | |||
702 | if ((wdev->iftype == NL80211_IFTYPE_STATION || | ||
703 | wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr) | ||
704 | dev->priv_flags |= IFF_DONT_BRIDGE; | ||
696 | break; | 705 | break; |
697 | case NETDEV_GOING_DOWN: | 706 | case NETDEV_GOING_DOWN: |
698 | switch (wdev->iftype) { | 707 | switch (wdev->iftype) { |
diff --git a/net/wireless/core.h b/net/wireless/core.h index 5aeebb9085f8..a9db9e6255bb 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -273,6 +273,8 @@ int cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | |||
273 | struct cfg80211_ibss_params *params, | 273 | struct cfg80211_ibss_params *params, |
274 | struct cfg80211_cached_keys *connkeys); | 274 | struct cfg80211_cached_keys *connkeys); |
275 | void cfg80211_clear_ibss(struct net_device *dev, bool nowext); | 275 | void cfg80211_clear_ibss(struct net_device *dev, bool nowext); |
276 | int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, | ||
277 | struct net_device *dev, bool nowext); | ||
276 | int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, | 278 | int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, |
277 | struct net_device *dev, bool nowext); | 279 | struct net_device *dev, bool nowext); |
278 | void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid); | 280 | void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid); |
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 39b6d92e2828..34dfc93fa713 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
@@ -169,8 +169,8 @@ void cfg80211_clear_ibss(struct net_device *dev, bool nowext) | |||
169 | wdev_unlock(wdev); | 169 | wdev_unlock(wdev); |
170 | } | 170 | } |
171 | 171 | ||
172 | static int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, | 172 | int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, |
173 | struct net_device *dev, bool nowext) | 173 | struct net_device *dev, bool nowext) |
174 | { | 174 | { |
175 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 175 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
176 | int err; | 176 | int err; |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 2610b746effa..1001db4912f7 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -243,21 +243,12 @@ void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len) | |||
243 | } | 243 | } |
244 | EXPORT_SYMBOL(cfg80211_send_disassoc); | 244 | EXPORT_SYMBOL(cfg80211_send_disassoc); |
245 | 245 | ||
246 | void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr) | 246 | static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr) |
247 | { | 247 | { |
248 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
249 | struct wiphy *wiphy = wdev->wiphy; | ||
250 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | ||
251 | int i; | 248 | int i; |
252 | bool done = false; | 249 | bool done = false; |
253 | 250 | ||
254 | wdev_lock(wdev); | 251 | ASSERT_WDEV_LOCK(wdev); |
255 | |||
256 | nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL); | ||
257 | if (wdev->sme_state == CFG80211_SME_CONNECTING) | ||
258 | __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, | ||
259 | WLAN_STATUS_UNSPECIFIED_FAILURE, | ||
260 | false, NULL); | ||
261 | 252 | ||
262 | for (i = 0; addr && i < MAX_AUTH_BSSES; i++) { | 253 | for (i = 0; addr && i < MAX_AUTH_BSSES; i++) { |
263 | if (wdev->authtry_bsses[i] && | 254 | if (wdev->authtry_bsses[i] && |
@@ -272,6 +263,29 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr) | |||
272 | } | 263 | } |
273 | 264 | ||
274 | WARN_ON(!done); | 265 | WARN_ON(!done); |
266 | } | ||
267 | |||
268 | void __cfg80211_auth_canceled(struct net_device *dev, const u8 *addr) | ||
269 | { | ||
270 | __cfg80211_auth_remove(dev->ieee80211_ptr, addr); | ||
271 | } | ||
272 | EXPORT_SYMBOL(__cfg80211_auth_canceled); | ||
273 | |||
274 | void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr) | ||
275 | { | ||
276 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
277 | struct wiphy *wiphy = wdev->wiphy; | ||
278 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | ||
279 | |||
280 | wdev_lock(wdev); | ||
281 | |||
282 | nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL); | ||
283 | if (wdev->sme_state == CFG80211_SME_CONNECTING) | ||
284 | __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, | ||
285 | WLAN_STATUS_UNSPECIFIED_FAILURE, | ||
286 | false, NULL); | ||
287 | |||
288 | __cfg80211_auth_remove(wdev, addr); | ||
275 | 289 | ||
276 | wdev_unlock(wdev); | 290 | wdev_unlock(wdev); |
277 | } | 291 | } |
@@ -446,12 +460,23 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | |||
446 | struct cfg80211_assoc_request req; | 460 | struct cfg80211_assoc_request req; |
447 | struct cfg80211_internal_bss *bss; | 461 | struct cfg80211_internal_bss *bss; |
448 | int i, err, slot = -1; | 462 | int i, err, slot = -1; |
463 | bool was_connected = false; | ||
449 | 464 | ||
450 | ASSERT_WDEV_LOCK(wdev); | 465 | ASSERT_WDEV_LOCK(wdev); |
451 | 466 | ||
452 | memset(&req, 0, sizeof(req)); | 467 | memset(&req, 0, sizeof(req)); |
453 | 468 | ||
454 | if (wdev->current_bss) | 469 | if (wdev->current_bss && prev_bssid && |
470 | memcmp(wdev->current_bss->pub.bssid, prev_bssid, ETH_ALEN) == 0) { | ||
471 | /* | ||
472 | * Trying to reassociate: Allow this to proceed and let the old | ||
473 | * association to be dropped when the new one is completed. | ||
474 | */ | ||
475 | if (wdev->sme_state == CFG80211_SME_CONNECTED) { | ||
476 | was_connected = true; | ||
477 | wdev->sme_state = CFG80211_SME_CONNECTING; | ||
478 | } | ||
479 | } else if (wdev->current_bss) | ||
455 | return -EALREADY; | 480 | return -EALREADY; |
456 | 481 | ||
457 | req.ie = ie; | 482 | req.ie = ie; |
@@ -461,8 +486,11 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | |||
461 | req.prev_bssid = prev_bssid; | 486 | req.prev_bssid = prev_bssid; |
462 | req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, | 487 | req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, |
463 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); | 488 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); |
464 | if (!req.bss) | 489 | if (!req.bss) { |
490 | if (was_connected) | ||
491 | wdev->sme_state = CFG80211_SME_CONNECTED; | ||
465 | return -ENOENT; | 492 | return -ENOENT; |
493 | } | ||
466 | 494 | ||
467 | bss = bss_from_pub(req.bss); | 495 | bss = bss_from_pub(req.bss); |
468 | 496 | ||
@@ -480,6 +508,8 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | |||
480 | 508 | ||
481 | err = rdev->ops->assoc(&rdev->wiphy, dev, &req); | 509 | err = rdev->ops->assoc(&rdev->wiphy, dev, &req); |
482 | out: | 510 | out: |
511 | if (err && was_connected) | ||
512 | wdev->sme_state = CFG80211_SME_CONNECTED; | ||
483 | /* still a reference in wdev->auth_bsses[slot] */ | 513 | /* still a reference in wdev->auth_bsses[slot] */ |
484 | cfg80211_put_bss(req.bss); | 514 | cfg80211_put_bss(req.bss); |
485 | return err; | 515 | return err; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 37264d56bace..149539ade15e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -561,7 +561,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
561 | CMD(deauth, DEAUTHENTICATE); | 561 | CMD(deauth, DEAUTHENTICATE); |
562 | CMD(disassoc, DISASSOCIATE); | 562 | CMD(disassoc, DISASSOCIATE); |
563 | CMD(join_ibss, JOIN_IBSS); | 563 | CMD(join_ibss, JOIN_IBSS); |
564 | if (dev->wiphy.netnsok) { | 564 | if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) { |
565 | i++; | 565 | i++; |
566 | NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS); | 566 | NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS); |
567 | } | 567 | } |
@@ -968,6 +968,32 @@ static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags) | |||
968 | return 0; | 968 | return 0; |
969 | } | 969 | } |
970 | 970 | ||
971 | static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev, | ||
972 | struct net_device *netdev, u8 use_4addr, | ||
973 | enum nl80211_iftype iftype) | ||
974 | { | ||
975 | if (!use_4addr) { | ||
976 | if (netdev && netdev->br_port) | ||
977 | return -EBUSY; | ||
978 | return 0; | ||
979 | } | ||
980 | |||
981 | switch (iftype) { | ||
982 | case NL80211_IFTYPE_AP_VLAN: | ||
983 | if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP) | ||
984 | return 0; | ||
985 | break; | ||
986 | case NL80211_IFTYPE_STATION: | ||
987 | if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_STATION) | ||
988 | return 0; | ||
989 | break; | ||
990 | default: | ||
991 | break; | ||
992 | } | ||
993 | |||
994 | return -EOPNOTSUPP; | ||
995 | } | ||
996 | |||
971 | static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) | 997 | static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) |
972 | { | 998 | { |
973 | struct cfg80211_registered_device *rdev; | 999 | struct cfg80211_registered_device *rdev; |
@@ -1011,6 +1037,9 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) | |||
1011 | if (info->attrs[NL80211_ATTR_4ADDR]) { | 1037 | if (info->attrs[NL80211_ATTR_4ADDR]) { |
1012 | params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]); | 1038 | params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]); |
1013 | change = true; | 1039 | change = true; |
1040 | err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype); | ||
1041 | if (err) | ||
1042 | goto unlock; | ||
1014 | } else { | 1043 | } else { |
1015 | params.use_4addr = -1; | 1044 | params.use_4addr = -1; |
1016 | } | 1045 | } |
@@ -1034,6 +1063,9 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) | |||
1034 | else | 1063 | else |
1035 | err = 0; | 1064 | err = 0; |
1036 | 1065 | ||
1066 | if (!err && params.use_4addr != -1) | ||
1067 | dev->ieee80211_ptr->use_4addr = params.use_4addr; | ||
1068 | |||
1037 | unlock: | 1069 | unlock: |
1038 | dev_put(dev); | 1070 | dev_put(dev); |
1039 | cfg80211_unlock_rdev(rdev); | 1071 | cfg80211_unlock_rdev(rdev); |
@@ -1081,8 +1113,12 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
1081 | params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); | 1113 | params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); |
1082 | } | 1114 | } |
1083 | 1115 | ||
1084 | if (info->attrs[NL80211_ATTR_4ADDR]) | 1116 | if (info->attrs[NL80211_ATTR_4ADDR]) { |
1085 | params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]); | 1117 | params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]); |
1118 | err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type); | ||
1119 | if (err) | ||
1120 | goto unlock; | ||
1121 | } | ||
1086 | 1122 | ||
1087 | err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? | 1123 | err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? |
1088 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, | 1124 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index f256dfffbf46..1f33017737fd 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -1008,7 +1008,7 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band, | |||
1008 | 1008 | ||
1009 | if (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER && | 1009 | if (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER && |
1010 | request_wiphy && request_wiphy == wiphy && | 1010 | request_wiphy && request_wiphy == wiphy && |
1011 | request_wiphy->strict_regulatory) { | 1011 | request_wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) { |
1012 | /* | 1012 | /* |
1013 | * This gaurantees the driver's requested regulatory domain | 1013 | * This gaurantees the driver's requested regulatory domain |
1014 | * will always be used as a base for further regulatory | 1014 | * will always be used as a base for further regulatory |
@@ -1051,13 +1051,13 @@ static bool ignore_reg_update(struct wiphy *wiphy, | |||
1051 | if (!last_request) | 1051 | if (!last_request) |
1052 | return true; | 1052 | return true; |
1053 | if (initiator == NL80211_REGDOM_SET_BY_CORE && | 1053 | if (initiator == NL80211_REGDOM_SET_BY_CORE && |
1054 | wiphy->custom_regulatory) | 1054 | wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) |
1055 | return true; | 1055 | return true; |
1056 | /* | 1056 | /* |
1057 | * wiphy->regd will be set once the device has its own | 1057 | * wiphy->regd will be set once the device has its own |
1058 | * desired regulatory domain set | 1058 | * desired regulatory domain set |
1059 | */ | 1059 | */ |
1060 | if (wiphy->strict_regulatory && !wiphy->regd && | 1060 | if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY && !wiphy->regd && |
1061 | !is_world_regdom(last_request->alpha2)) | 1061 | !is_world_regdom(last_request->alpha2)) |
1062 | return true; | 1062 | return true; |
1063 | return false; | 1063 | return false; |
@@ -1093,7 +1093,7 @@ static void handle_reg_beacon(struct wiphy *wiphy, | |||
1093 | 1093 | ||
1094 | chan->beacon_found = true; | 1094 | chan->beacon_found = true; |
1095 | 1095 | ||
1096 | if (wiphy->disable_beacon_hints) | 1096 | if (wiphy->flags & WIPHY_FLAG_DISABLE_BEACON_HINTS) |
1097 | return; | 1097 | return; |
1098 | 1098 | ||
1099 | chan_before.center_freq = chan->center_freq; | 1099 | chan_before.center_freq = chan->center_freq; |
@@ -1164,7 +1164,7 @@ static bool reg_is_world_roaming(struct wiphy *wiphy) | |||
1164 | return true; | 1164 | return true; |
1165 | if (last_request && | 1165 | if (last_request && |
1166 | last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && | 1166 | last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && |
1167 | wiphy->custom_regulatory) | 1167 | wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) |
1168 | return true; | 1168 | return true; |
1169 | return false; | 1169 | return false; |
1170 | } | 1170 | } |
@@ -1591,7 +1591,8 @@ static void reg_process_hint(struct regulatory_request *reg_request) | |||
1591 | 1591 | ||
1592 | r = __regulatory_hint(wiphy, reg_request); | 1592 | r = __regulatory_hint(wiphy, reg_request); |
1593 | /* This is required so that the orig_* parameters are saved */ | 1593 | /* This is required so that the orig_* parameters are saved */ |
1594 | if (r == -EALREADY && wiphy && wiphy->strict_regulatory) | 1594 | if (r == -EALREADY && wiphy && |
1595 | wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) | ||
1595 | wiphy_update_regulatory(wiphy, reg_request->initiator); | 1596 | wiphy_update_regulatory(wiphy, reg_request->initiator); |
1596 | out: | 1597 | out: |
1597 | mutex_unlock(®_mutex); | 1598 | mutex_unlock(®_mutex); |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index e2d344ff6745..227d57b8dc41 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -217,7 +217,7 @@ static bool is_mesh(struct cfg80211_bss *a, | |||
217 | a->len_information_elements); | 217 | a->len_information_elements); |
218 | if (!ie) | 218 | if (!ie) |
219 | return false; | 219 | return false; |
220 | if (ie[1] != IEEE80211_MESH_CONFIG_LEN) | 220 | if (ie[1] != sizeof(struct ieee80211_meshconf_ie)) |
221 | return false; | 221 | return false; |
222 | 222 | ||
223 | /* | 223 | /* |
@@ -225,7 +225,8 @@ static bool is_mesh(struct cfg80211_bss *a, | |||
225 | * comparing since that may differ between stations taking | 225 | * comparing since that may differ between stations taking |
226 | * part in the same mesh. | 226 | * part in the same mesh. |
227 | */ | 227 | */ |
228 | return memcmp(ie + 2, meshcfg, IEEE80211_MESH_CONFIG_LEN - 2) == 0; | 228 | return memcmp(ie + 2, meshcfg, |
229 | sizeof(struct ieee80211_meshconf_ie) - 2) == 0; | ||
229 | } | 230 | } |
230 | 231 | ||
231 | static int cmp_bss(struct cfg80211_bss *a, | 232 | static int cmp_bss(struct cfg80211_bss *a, |
@@ -399,7 +400,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, | |||
399 | res->pub.information_elements, | 400 | res->pub.information_elements, |
400 | res->pub.len_information_elements); | 401 | res->pub.len_information_elements); |
401 | if (!meshid || !meshcfg || | 402 | if (!meshid || !meshcfg || |
402 | meshcfg[1] != IEEE80211_MESH_CONFIG_LEN) { | 403 | meshcfg[1] != sizeof(struct ieee80211_meshconf_ie)) { |
403 | /* bogus mesh */ | 404 | /* bogus mesh */ |
404 | kref_put(&res->ref, bss_release); | 405 | kref_put(&res->ref, bss_release); |
405 | return NULL; | 406 | return NULL; |
@@ -865,7 +866,7 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info, | |||
865 | break; | 866 | break; |
866 | case WLAN_EID_MESH_CONFIG: | 867 | case WLAN_EID_MESH_CONFIG: |
867 | ismesh = true; | 868 | ismesh = true; |
868 | if (ie[1] != IEEE80211_MESH_CONFIG_LEN) | 869 | if (ie[1] != sizeof(struct ieee80211_meshconf_ie)) |
869 | break; | 870 | break; |
870 | buf = kmalloc(50, GFP_ATOMIC); | 871 | buf = kmalloc(50, GFP_ATOMIC); |
871 | if (!buf) | 872 | if (!buf) |
@@ -873,35 +874,40 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info, | |||
873 | cfg = ie + 2; | 874 | cfg = ie + 2; |
874 | memset(&iwe, 0, sizeof(iwe)); | 875 | memset(&iwe, 0, sizeof(iwe)); |
875 | iwe.cmd = IWEVCUSTOM; | 876 | iwe.cmd = IWEVCUSTOM; |
876 | sprintf(buf, "Mesh network (version %d)", cfg[0]); | 877 | sprintf(buf, "Mesh Network Path Selection Protocol ID: " |
878 | "0x%02X", cfg[0]); | ||
877 | iwe.u.data.length = strlen(buf); | 879 | iwe.u.data.length = strlen(buf); |
878 | current_ev = iwe_stream_add_point(info, current_ev, | 880 | current_ev = iwe_stream_add_point(info, current_ev, |
879 | end_buf, | 881 | end_buf, |
880 | &iwe, buf); | 882 | &iwe, buf); |
881 | sprintf(buf, "Path Selection Protocol ID: " | 883 | sprintf(buf, "Path Selection Metric ID: 0x%02X", |
882 | "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3], | 884 | cfg[1]); |
883 | cfg[4]); | ||
884 | iwe.u.data.length = strlen(buf); | 885 | iwe.u.data.length = strlen(buf); |
885 | current_ev = iwe_stream_add_point(info, current_ev, | 886 | current_ev = iwe_stream_add_point(info, current_ev, |
886 | end_buf, | 887 | end_buf, |
887 | &iwe, buf); | 888 | &iwe, buf); |
888 | sprintf(buf, "Path Selection Metric ID: " | 889 | sprintf(buf, "Congestion Control Mode ID: 0x%02X", |
889 | "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7], | 890 | cfg[2]); |
890 | cfg[8]); | ||
891 | iwe.u.data.length = strlen(buf); | 891 | iwe.u.data.length = strlen(buf); |
892 | current_ev = iwe_stream_add_point(info, current_ev, | 892 | current_ev = iwe_stream_add_point(info, current_ev, |
893 | end_buf, | 893 | end_buf, |
894 | &iwe, buf); | 894 | &iwe, buf); |
895 | sprintf(buf, "Congestion Control Mode ID: " | 895 | sprintf(buf, "Synchronization ID: 0x%02X", cfg[3]); |
896 | "0x%02X%02X%02X%02X", cfg[9], cfg[10], | ||
897 | cfg[11], cfg[12]); | ||
898 | iwe.u.data.length = strlen(buf); | 896 | iwe.u.data.length = strlen(buf); |
899 | current_ev = iwe_stream_add_point(info, current_ev, | 897 | current_ev = iwe_stream_add_point(info, current_ev, |
900 | end_buf, | 898 | end_buf, |
901 | &iwe, buf); | 899 | &iwe, buf); |
902 | sprintf(buf, "Channel Precedence: " | 900 | sprintf(buf, "Authentication ID: 0x%02X", cfg[4]); |
903 | "0x%02X%02X%02X%02X", cfg[13], cfg[14], | 901 | iwe.u.data.length = strlen(buf); |
904 | cfg[15], cfg[16]); | 902 | current_ev = iwe_stream_add_point(info, current_ev, |
903 | end_buf, | ||
904 | &iwe, buf); | ||
905 | sprintf(buf, "Formation Info: 0x%02X", cfg[5]); | ||
906 | iwe.u.data.length = strlen(buf); | ||
907 | current_ev = iwe_stream_add_point(info, current_ev, | ||
908 | end_buf, | ||
909 | &iwe, buf); | ||
910 | sprintf(buf, "Capabilities: 0x%02X", cfg[6]); | ||
905 | iwe.u.data.length = strlen(buf); | 911 | iwe.u.data.length = strlen(buf); |
906 | current_ev = iwe_stream_add_point(info, current_ev, | 912 | current_ev = iwe_stream_add_point(info, current_ev, |
907 | end_buf, | 913 | end_buf, |
diff --git a/net/wireless/util.c b/net/wireless/util.c index 5aa39f7cf9b9..59361fdcb5d0 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -658,7 +658,14 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, | |||
658 | !(rdev->wiphy.interface_modes & (1 << ntype))) | 658 | !(rdev->wiphy.interface_modes & (1 << ntype))) |
659 | return -EOPNOTSUPP; | 659 | return -EOPNOTSUPP; |
660 | 660 | ||
661 | /* if it's part of a bridge, reject changing type to station/ibss */ | ||
662 | if (dev->br_port && (ntype == NL80211_IFTYPE_ADHOC || | ||
663 | ntype == NL80211_IFTYPE_STATION)) | ||
664 | return -EBUSY; | ||
665 | |||
661 | if (ntype != otype) { | 666 | if (ntype != otype) { |
667 | dev->ieee80211_ptr->use_4addr = false; | ||
668 | |||
662 | switch (otype) { | 669 | switch (otype) { |
663 | case NL80211_IFTYPE_ADHOC: | 670 | case NL80211_IFTYPE_ADHOC: |
664 | cfg80211_leave_ibss(rdev, dev, false); | 671 | cfg80211_leave_ibss(rdev, dev, false); |
@@ -682,5 +689,34 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, | |||
682 | 689 | ||
683 | WARN_ON(!err && dev->ieee80211_ptr->iftype != ntype); | 690 | WARN_ON(!err && dev->ieee80211_ptr->iftype != ntype); |
684 | 691 | ||
692 | if (!err && params && params->use_4addr != -1) | ||
693 | dev->ieee80211_ptr->use_4addr = params->use_4addr; | ||
694 | |||
695 | if (!err) { | ||
696 | dev->priv_flags &= ~IFF_DONT_BRIDGE; | ||
697 | switch (ntype) { | ||
698 | case NL80211_IFTYPE_STATION: | ||
699 | if (dev->ieee80211_ptr->use_4addr) | ||
700 | break; | ||
701 | /* fall through */ | ||
702 | case NL80211_IFTYPE_ADHOC: | ||
703 | dev->priv_flags |= IFF_DONT_BRIDGE; | ||
704 | break; | ||
705 | case NL80211_IFTYPE_AP: | ||
706 | case NL80211_IFTYPE_AP_VLAN: | ||
707 | case NL80211_IFTYPE_WDS: | ||
708 | case NL80211_IFTYPE_MESH_POINT: | ||
709 | /* bridging OK */ | ||
710 | break; | ||
711 | case NL80211_IFTYPE_MONITOR: | ||
712 | /* monitor can't bridge anyway */ | ||
713 | break; | ||
714 | case NL80211_IFTYPE_UNSPECIFIED: | ||
715 | case __NL80211_IFTYPE_AFTER_LAST: | ||
716 | /* not happening */ | ||
717 | break; | ||
718 | } | ||
719 | } | ||
720 | |||
685 | return err; | 721 | return err; |
686 | } | 722 | } |
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 41abcbdc5fb9..29091ac9f989 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -437,6 +437,7 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, | |||
437 | { | 437 | { |
438 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 438 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
439 | int err, i; | 439 | int err, i; |
440 | bool rejoin = false; | ||
440 | 441 | ||
441 | if (!wdev->wext.keys) { | 442 | if (!wdev->wext.keys) { |
442 | wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys), | 443 | wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys), |
@@ -466,8 +467,24 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, | |||
466 | 467 | ||
467 | if (remove) { | 468 | if (remove) { |
468 | err = 0; | 469 | err = 0; |
469 | if (wdev->current_bss) | 470 | if (wdev->current_bss) { |
471 | /* | ||
472 | * If removing the current TX key, we will need to | ||
473 | * join a new IBSS without the privacy bit clear. | ||
474 | */ | ||
475 | if (idx == wdev->wext.default_key && | ||
476 | wdev->iftype == NL80211_IFTYPE_ADHOC) { | ||
477 | __cfg80211_leave_ibss(rdev, wdev->netdev, true); | ||
478 | rejoin = true; | ||
479 | } | ||
470 | err = rdev->ops->del_key(&rdev->wiphy, dev, idx, addr); | 480 | err = rdev->ops->del_key(&rdev->wiphy, dev, idx, addr); |
481 | } | ||
482 | /* | ||
483 | * Applications using wireless extensions expect to be | ||
484 | * able to delete keys that don't exist, so allow that. | ||
485 | */ | ||
486 | if (err == -ENOENT) | ||
487 | err = 0; | ||
471 | if (!err) { | 488 | if (!err) { |
472 | if (!addr) { | 489 | if (!addr) { |
473 | wdev->wext.keys->params[idx].key_len = 0; | 490 | wdev->wext.keys->params[idx].key_len = 0; |
@@ -478,12 +495,9 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, | |||
478 | else if (idx == wdev->wext.default_mgmt_key) | 495 | else if (idx == wdev->wext.default_mgmt_key) |
479 | wdev->wext.default_mgmt_key = -1; | 496 | wdev->wext.default_mgmt_key = -1; |
480 | } | 497 | } |
481 | /* | 498 | |
482 | * Applications using wireless extensions expect to be | 499 | if (!err && rejoin) |
483 | * able to delete keys that don't exist, so allow that. | 500 | err = cfg80211_ibss_wext_join(rdev, wdev); |
484 | */ | ||
485 | if (err == -ENOENT) | ||
486 | return 0; | ||
487 | 501 | ||
488 | return err; | 502 | return err; |
489 | } | 503 | } |
@@ -511,11 +525,25 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, | |||
511 | if ((params->cipher == WLAN_CIPHER_SUITE_WEP40 || | 525 | if ((params->cipher == WLAN_CIPHER_SUITE_WEP40 || |
512 | params->cipher == WLAN_CIPHER_SUITE_WEP104) && | 526 | params->cipher == WLAN_CIPHER_SUITE_WEP104) && |
513 | (tx_key || (!addr && wdev->wext.default_key == -1))) { | 527 | (tx_key || (!addr && wdev->wext.default_key == -1))) { |
514 | if (wdev->current_bss) | 528 | if (wdev->current_bss) { |
529 | /* | ||
530 | * If we are getting a new TX key from not having | ||
531 | * had one before we need to join a new IBSS with | ||
532 | * the privacy bit set. | ||
533 | */ | ||
534 | if (wdev->iftype == NL80211_IFTYPE_ADHOC && | ||
535 | wdev->wext.default_key == -1) { | ||
536 | __cfg80211_leave_ibss(rdev, wdev->netdev, true); | ||
537 | rejoin = true; | ||
538 | } | ||
515 | err = rdev->ops->set_default_key(&rdev->wiphy, | 539 | err = rdev->ops->set_default_key(&rdev->wiphy, |
516 | dev, idx); | 540 | dev, idx); |
517 | if (!err) | 541 | } |
542 | if (!err) { | ||
518 | wdev->wext.default_key = idx; | 543 | wdev->wext.default_key = idx; |
544 | if (rejoin) | ||
545 | err = cfg80211_ibss_wext_join(rdev, wdev); | ||
546 | } | ||
519 | return err; | 547 | return err; |
520 | } | 548 | } |
521 | 549 | ||
@@ -539,10 +567,13 @@ static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev, | |||
539 | { | 567 | { |
540 | int err; | 568 | int err; |
541 | 569 | ||
570 | /* devlist mutex needed for possible IBSS re-join */ | ||
571 | mutex_lock(&rdev->devlist_mtx); | ||
542 | wdev_lock(dev->ieee80211_ptr); | 572 | wdev_lock(dev->ieee80211_ptr); |
543 | err = __cfg80211_set_encryption(rdev, dev, addr, remove, | 573 | err = __cfg80211_set_encryption(rdev, dev, addr, remove, |
544 | tx_key, idx, params); | 574 | tx_key, idx, params); |
545 | wdev_unlock(dev->ieee80211_ptr); | 575 | wdev_unlock(dev->ieee80211_ptr); |
576 | mutex_unlock(&rdev->devlist_mtx); | ||
546 | 577 | ||
547 | return err; | 578 | return err; |
548 | } | 579 | } |