diff options
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 81 |
1 files changed, 10 insertions, 71 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 6b7e92eaab47..092a017b237e 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -289,16 +289,8 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
289 | drv_bss_info_changed(local, &sdata->vif, | 289 | drv_bss_info_changed(local, &sdata->vif, |
290 | &sdata->vif.bss_conf, changed); | 290 | &sdata->vif.bss_conf, changed); |
291 | 291 | ||
292 | /* | 292 | /* DEPRECATED */ |
293 | * DEPRECATED | 293 | local->hw.conf.beacon_int = sdata->vif.bss_conf.beacon_int; |
294 | * | ||
295 | * ~changed is just there to not do this at resume time | ||
296 | */ | ||
297 | if (changed & BSS_CHANGED_BEACON_INT && ~changed) { | ||
298 | local->hw.conf.beacon_int = sdata->vif.bss_conf.beacon_int; | ||
299 | ieee80211_hw_config(local, | ||
300 | _IEEE80211_CONF_CHANGE_BEACON_INTERVAL); | ||
301 | } | ||
302 | } | 294 | } |
303 | 295 | ||
304 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) | 296 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) |
@@ -377,60 +369,12 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
377 | } | 369 | } |
378 | } | 370 | } |
379 | 371 | ||
380 | /* Remove added headers (e.g., QoS control), encryption header/MIC, etc. to | ||
381 | * make a prepared TX frame (one that has been given to hw) to look like brand | ||
382 | * new IEEE 802.11 frame that is ready to go through TX processing again. | ||
383 | */ | ||
384 | static void ieee80211_remove_tx_extra(struct ieee80211_local *local, | ||
385 | struct ieee80211_key *key, | ||
386 | struct sk_buff *skb) | ||
387 | { | ||
388 | unsigned int hdrlen, iv_len, mic_len; | ||
389 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
390 | |||
391 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | ||
392 | |||
393 | if (!key) | ||
394 | goto no_key; | ||
395 | |||
396 | switch (key->conf.alg) { | ||
397 | case ALG_WEP: | ||
398 | iv_len = WEP_IV_LEN; | ||
399 | mic_len = WEP_ICV_LEN; | ||
400 | break; | ||
401 | case ALG_TKIP: | ||
402 | iv_len = TKIP_IV_LEN; | ||
403 | mic_len = TKIP_ICV_LEN; | ||
404 | break; | ||
405 | case ALG_CCMP: | ||
406 | iv_len = CCMP_HDR_LEN; | ||
407 | mic_len = CCMP_MIC_LEN; | ||
408 | break; | ||
409 | default: | ||
410 | goto no_key; | ||
411 | } | ||
412 | |||
413 | if (skb->len >= hdrlen + mic_len && | ||
414 | !(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) | ||
415 | skb_trim(skb, skb->len - mic_len); | ||
416 | if (skb->len >= hdrlen + iv_len) { | ||
417 | memmove(skb->data + iv_len, skb->data, hdrlen); | ||
418 | hdr = (struct ieee80211_hdr *)skb_pull(skb, iv_len); | ||
419 | } | ||
420 | |||
421 | no_key: | ||
422 | if (ieee80211_is_data_qos(hdr->frame_control)) { | ||
423 | hdr->frame_control &= ~cpu_to_le16(IEEE80211_STYPE_QOS_DATA); | ||
424 | memmove(skb->data + IEEE80211_QOS_CTL_LEN, skb->data, | ||
425 | hdrlen - IEEE80211_QOS_CTL_LEN); | ||
426 | skb_pull(skb, IEEE80211_QOS_CTL_LEN); | ||
427 | } | ||
428 | } | ||
429 | |||
430 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | 372 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, |
431 | struct sta_info *sta, | 373 | struct sta_info *sta, |
432 | struct sk_buff *skb) | 374 | struct sk_buff *skb) |
433 | { | 375 | { |
376 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
377 | |||
434 | sta->tx_filtered_count++; | 378 | sta->tx_filtered_count++; |
435 | 379 | ||
436 | /* | 380 | /* |
@@ -472,16 +416,15 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
472 | */ | 416 | */ |
473 | if (test_sta_flags(sta, WLAN_STA_PS) && | 417 | if (test_sta_flags(sta, WLAN_STA_PS) && |
474 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { | 418 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { |
475 | ieee80211_remove_tx_extra(local, sta->key, skb); | ||
476 | skb_queue_tail(&sta->tx_filtered, skb); | 419 | skb_queue_tail(&sta->tx_filtered, skb); |
477 | return; | 420 | return; |
478 | } | 421 | } |
479 | 422 | ||
480 | if (!test_sta_flags(sta, WLAN_STA_PS) && !skb->requeue) { | 423 | if (!test_sta_flags(sta, WLAN_STA_PS) && |
424 | !(info->flags & IEEE80211_TX_INTFL_RETRIED)) { | ||
481 | /* Software retry the packet once */ | 425 | /* Software retry the packet once */ |
482 | skb->requeue = 1; | 426 | info->flags |= IEEE80211_TX_INTFL_RETRIED; |
483 | ieee80211_remove_tx_extra(local, sta->key, skb); | 427 | ieee80211_add_pending_skb(local, skb); |
484 | dev_queue_xmit(skb); | ||
485 | return; | 428 | return; |
486 | } | 429 | } |
487 | 430 | ||
@@ -735,9 +678,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
735 | * +-------------------------+ | 678 | * +-------------------------+ |
736 | * | 679 | * |
737 | */ | 680 | */ |
738 | priv_size = ((sizeof(struct ieee80211_local) + | 681 | priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len; |
739 | NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST) + | ||
740 | priv_data_len; | ||
741 | 682 | ||
742 | wiphy = wiphy_new(&mac80211_config_ops, priv_size); | 683 | wiphy = wiphy_new(&mac80211_config_ops, priv_size); |
743 | 684 | ||
@@ -754,9 +695,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
754 | 695 | ||
755 | local->hw.wiphy = wiphy; | 696 | local->hw.wiphy = wiphy; |
756 | 697 | ||
757 | local->hw.priv = (char *)local + | 698 | local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN); |
758 | ((sizeof(struct ieee80211_local) + | ||
759 | NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST); | ||
760 | 699 | ||
761 | BUG_ON(!ops->tx); | 700 | BUG_ON(!ops->tx); |
762 | BUG_ON(!ops->start); | 701 | BUG_ON(!ops->start); |