diff options
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 68 |
1 files changed, 46 insertions, 22 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c54db966926..e1733dcb58a 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -351,8 +351,8 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) | |||
351 | 351 | ||
352 | local->total_ps_buffered = total; | 352 | local->total_ps_buffered = total; |
353 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 353 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
354 | printk(KERN_DEBUG "%s: PS buffers full - purged %d frames\n", | 354 | wiphy_debug(local->hw.wiphy, "PS buffers full - purged %d frames\n", |
355 | wiphy_name(local->hw.wiphy), purged); | 355 | purged); |
356 | #endif | 356 | #endif |
357 | } | 357 | } |
358 | 358 | ||
@@ -509,6 +509,18 @@ ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) | |||
509 | } | 509 | } |
510 | 510 | ||
511 | static ieee80211_tx_result debug_noinline | 511 | static ieee80211_tx_result debug_noinline |
512 | ieee80211_tx_h_check_control_port_protocol(struct ieee80211_tx_data *tx) | ||
513 | { | ||
514 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
515 | |||
516 | if (unlikely(tx->sdata->control_port_protocol == tx->skb->protocol && | ||
517 | tx->sdata->control_port_no_encrypt)) | ||
518 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | ||
519 | |||
520 | return TX_CONTINUE; | ||
521 | } | ||
522 | |||
523 | static ieee80211_tx_result debug_noinline | ||
512 | ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | 524 | ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) |
513 | { | 525 | { |
514 | struct ieee80211_key *key = NULL; | 526 | struct ieee80211_key *key = NULL; |
@@ -527,7 +539,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
527 | else if ((key = rcu_dereference(tx->sdata->default_key))) | 539 | else if ((key = rcu_dereference(tx->sdata->default_key))) |
528 | tx->key = key; | 540 | tx->key = key; |
529 | else if (tx->sdata->drop_unencrypted && | 541 | else if (tx->sdata->drop_unencrypted && |
530 | (tx->skb->protocol != cpu_to_be16(ETH_P_PAE)) && | 542 | (tx->skb->protocol != tx->sdata->control_port_protocol) && |
531 | !(info->flags & IEEE80211_TX_CTL_INJECTED) && | 543 | !(info->flags & IEEE80211_TX_CTL_INJECTED) && |
532 | (!ieee80211_is_robust_mgmt_frame(hdr) || | 544 | (!ieee80211_is_robust_mgmt_frame(hdr) || |
533 | (ieee80211_is_action(hdr->frame_control) && | 545 | (ieee80211_is_action(hdr->frame_control) && |
@@ -543,15 +555,16 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
543 | tx->key->tx_rx_count++; | 555 | tx->key->tx_rx_count++; |
544 | /* TODO: add threshold stuff again */ | 556 | /* TODO: add threshold stuff again */ |
545 | 557 | ||
546 | switch (tx->key->conf.alg) { | 558 | switch (tx->key->conf.cipher) { |
547 | case ALG_WEP: | 559 | case WLAN_CIPHER_SUITE_WEP40: |
560 | case WLAN_CIPHER_SUITE_WEP104: | ||
548 | if (ieee80211_is_auth(hdr->frame_control)) | 561 | if (ieee80211_is_auth(hdr->frame_control)) |
549 | break; | 562 | break; |
550 | case ALG_TKIP: | 563 | case WLAN_CIPHER_SUITE_TKIP: |
551 | if (!ieee80211_is_data_present(hdr->frame_control)) | 564 | if (!ieee80211_is_data_present(hdr->frame_control)) |
552 | tx->key = NULL; | 565 | tx->key = NULL; |
553 | break; | 566 | break; |
554 | case ALG_CCMP: | 567 | case WLAN_CIPHER_SUITE_CCMP: |
555 | if (!ieee80211_is_data_present(hdr->frame_control) && | 568 | if (!ieee80211_is_data_present(hdr->frame_control) && |
556 | !ieee80211_use_mfp(hdr->frame_control, tx->sta, | 569 | !ieee80211_use_mfp(hdr->frame_control, tx->sta, |
557 | tx->skb)) | 570 | tx->skb)) |
@@ -561,7 +574,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
561 | IEEE80211_KEY_FLAG_SW_MGMT) && | 574 | IEEE80211_KEY_FLAG_SW_MGMT) && |
562 | ieee80211_is_mgmt(hdr->frame_control); | 575 | ieee80211_is_mgmt(hdr->frame_control); |
563 | break; | 576 | break; |
564 | case ALG_AES_CMAC: | 577 | case WLAN_CIPHER_SUITE_AES_CMAC: |
565 | if (!ieee80211_is_mgmt(hdr->frame_control)) | 578 | if (!ieee80211_is_mgmt(hdr->frame_control)) |
566 | tx->key = NULL; | 579 | tx->key = NULL; |
567 | break; | 580 | break; |
@@ -946,22 +959,31 @@ ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) | |||
946 | static ieee80211_tx_result debug_noinline | 959 | static ieee80211_tx_result debug_noinline |
947 | ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) | 960 | ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) |
948 | { | 961 | { |
962 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
963 | |||
949 | if (!tx->key) | 964 | if (!tx->key) |
950 | return TX_CONTINUE; | 965 | return TX_CONTINUE; |
951 | 966 | ||
952 | switch (tx->key->conf.alg) { | 967 | switch (tx->key->conf.cipher) { |
953 | case ALG_WEP: | 968 | case WLAN_CIPHER_SUITE_WEP40: |
969 | case WLAN_CIPHER_SUITE_WEP104: | ||
954 | return ieee80211_crypto_wep_encrypt(tx); | 970 | return ieee80211_crypto_wep_encrypt(tx); |
955 | case ALG_TKIP: | 971 | case WLAN_CIPHER_SUITE_TKIP: |
956 | return ieee80211_crypto_tkip_encrypt(tx); | 972 | return ieee80211_crypto_tkip_encrypt(tx); |
957 | case ALG_CCMP: | 973 | case WLAN_CIPHER_SUITE_CCMP: |
958 | return ieee80211_crypto_ccmp_encrypt(tx); | 974 | return ieee80211_crypto_ccmp_encrypt(tx); |
959 | case ALG_AES_CMAC: | 975 | case WLAN_CIPHER_SUITE_AES_CMAC: |
960 | return ieee80211_crypto_aes_cmac_encrypt(tx); | 976 | return ieee80211_crypto_aes_cmac_encrypt(tx); |
977 | default: | ||
978 | /* handle hw-only algorithm */ | ||
979 | if (info->control.hw_key) { | ||
980 | ieee80211_tx_set_protected(tx); | ||
981 | return TX_CONTINUE; | ||
982 | } | ||
983 | break; | ||
984 | |||
961 | } | 985 | } |
962 | 986 | ||
963 | /* not reached */ | ||
964 | WARN_ON(1); | ||
965 | return TX_DROP; | 987 | return TX_DROP; |
966 | } | 988 | } |
967 | 989 | ||
@@ -1339,6 +1361,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | |||
1339 | CALL_TXH(ieee80211_tx_h_dynamic_ps); | 1361 | CALL_TXH(ieee80211_tx_h_dynamic_ps); |
1340 | CALL_TXH(ieee80211_tx_h_check_assoc); | 1362 | CALL_TXH(ieee80211_tx_h_check_assoc); |
1341 | CALL_TXH(ieee80211_tx_h_ps_buf); | 1363 | CALL_TXH(ieee80211_tx_h_ps_buf); |
1364 | CALL_TXH(ieee80211_tx_h_check_control_port_protocol); | ||
1342 | CALL_TXH(ieee80211_tx_h_select_key); | 1365 | CALL_TXH(ieee80211_tx_h_select_key); |
1343 | if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) | 1366 | if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) |
1344 | CALL_TXH(ieee80211_tx_h_rate_ctrl); | 1367 | CALL_TXH(ieee80211_tx_h_rate_ctrl); |
@@ -1511,8 +1534,8 @@ static int ieee80211_skb_resize(struct ieee80211_local *local, | |||
1511 | I802_DEBUG_INC(local->tx_expand_skb_head); | 1534 | I802_DEBUG_INC(local->tx_expand_skb_head); |
1512 | 1535 | ||
1513 | if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) { | 1536 | if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) { |
1514 | printk(KERN_DEBUG "%s: failed to reallocate TX buffer\n", | 1537 | wiphy_debug(local->hw.wiphy, |
1515 | wiphy_name(local->hw.wiphy)); | 1538 | "failed to reallocate TX buffer\n"); |
1516 | return -ENOMEM; | 1539 | return -ENOMEM; |
1517 | } | 1540 | } |
1518 | 1541 | ||
@@ -1586,6 +1609,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1586 | return; | 1609 | return; |
1587 | } | 1610 | } |
1588 | 1611 | ||
1612 | hdr = (struct ieee80211_hdr *) skb->data; | ||
1589 | info->control.vif = &sdata->vif; | 1613 | info->control.vif = &sdata->vif; |
1590 | 1614 | ||
1591 | if (ieee80211_vif_is_mesh(&sdata->vif) && | 1615 | if (ieee80211_vif_is_mesh(&sdata->vif) && |
@@ -1699,7 +1723,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1699 | u16 ethertype, hdrlen, meshhdrlen = 0; | 1723 | u16 ethertype, hdrlen, meshhdrlen = 0; |
1700 | __le16 fc; | 1724 | __le16 fc; |
1701 | struct ieee80211_hdr hdr; | 1725 | struct ieee80211_hdr hdr; |
1702 | struct ieee80211s_hdr mesh_hdr; | 1726 | struct ieee80211s_hdr mesh_hdr __maybe_unused; |
1703 | const u8 *encaps_data; | 1727 | const u8 *encaps_data; |
1704 | int encaps_len, skip_header_bytes; | 1728 | int encaps_len, skip_header_bytes; |
1705 | int nh_pos, h_pos; | 1729 | int nh_pos, h_pos; |
@@ -1816,7 +1840,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1816 | #endif | 1840 | #endif |
1817 | case NL80211_IFTYPE_STATION: | 1841 | case NL80211_IFTYPE_STATION: |
1818 | memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); | 1842 | memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); |
1819 | if (sdata->u.mgd.use_4addr && ethertype != ETH_P_PAE) { | 1843 | if (sdata->u.mgd.use_4addr && |
1844 | cpu_to_be16(ethertype) != sdata->control_port_protocol) { | ||
1820 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); | 1845 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
1821 | /* RA TA DA SA */ | 1846 | /* RA TA DA SA */ |
1822 | memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN); | 1847 | memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN); |
@@ -1869,7 +1894,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1869 | if (!ieee80211_vif_is_mesh(&sdata->vif) && | 1894 | if (!ieee80211_vif_is_mesh(&sdata->vif) && |
1870 | unlikely(!is_multicast_ether_addr(hdr.addr1) && | 1895 | unlikely(!is_multicast_ether_addr(hdr.addr1) && |
1871 | !(sta_flags & WLAN_STA_AUTHORIZED) && | 1896 | !(sta_flags & WLAN_STA_AUTHORIZED) && |
1872 | !(ethertype == ETH_P_PAE && | 1897 | !(cpu_to_be16(ethertype) == sdata->control_port_protocol && |
1873 | compare_ether_addr(sdata->vif.addr, | 1898 | compare_ether_addr(sdata->vif.addr, |
1874 | skb->data + ETH_ALEN) == 0))) { | 1899 | skb->data + ETH_ALEN) == 0))) { |
1875 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 1900 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
@@ -2068,8 +2093,7 @@ void ieee80211_tx_pending(unsigned long data) | |||
2068 | 2093 | ||
2069 | if (skb_queue_empty(&local->pending[i])) | 2094 | if (skb_queue_empty(&local->pending[i])) |
2070 | list_for_each_entry_rcu(sdata, &local->interfaces, list) | 2095 | list_for_each_entry_rcu(sdata, &local->interfaces, list) |
2071 | netif_tx_wake_queue( | 2096 | netif_wake_subqueue(sdata->dev, i); |
2072 | netdev_get_tx_queue(sdata->dev, i)); | ||
2073 | } | 2097 | } |
2074 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | 2098 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); |
2075 | 2099 | ||