aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r--net/mac80211/main.c81
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
304u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) 296u32 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 */
384static 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
421no_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
430static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, 372static 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);