diff options
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 59 |
1 files changed, 44 insertions, 15 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index ca7fa7f0613d..27c990bf2320 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/bitmap.h> | 19 | #include <linux/bitmap.h> |
20 | #include <linux/rcupdate.h> | 20 | #include <linux/rcupdate.h> |
21 | #include <linux/export.h> | 21 | #include <linux/export.h> |
22 | #include <linux/time.h> | ||
22 | #include <net/net_namespace.h> | 23 | #include <net/net_namespace.h> |
23 | #include <net/ieee80211_radiotap.h> | 24 | #include <net/ieee80211_radiotap.h> |
24 | #include <net/cfg80211.h> | 25 | #include <net/cfg80211.h> |
@@ -489,6 +490,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
489 | info->control.jiffies = jiffies; | 490 | info->control.jiffies = jiffies; |
490 | info->control.vif = &tx->sdata->vif; | 491 | info->control.vif = &tx->sdata->vif; |
491 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 492 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
493 | info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS; | ||
492 | skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb); | 494 | skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb); |
493 | 495 | ||
494 | if (!timer_pending(&local->sta_cleanup)) | 496 | if (!timer_pending(&local->sta_cleanup)) |
@@ -560,7 +562,8 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
560 | 562 | ||
561 | if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) | 563 | if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) |
562 | tx->key = NULL; | 564 | tx->key = NULL; |
563 | else if (tx->sta && (key = rcu_dereference(tx->sta->ptk))) | 565 | else if (tx->sta && |
566 | (key = rcu_dereference(tx->sta->ptk[tx->sta->ptk_idx]))) | ||
564 | tx->key = key; | 567 | tx->key = key; |
565 | else if (ieee80211_is_mgmt(hdr->frame_control) && | 568 | else if (ieee80211_is_mgmt(hdr->frame_control) && |
566 | is_multicast_ether_addr(hdr->addr1) && | 569 | is_multicast_ether_addr(hdr->addr1) && |
@@ -843,15 +846,16 @@ static int ieee80211_fragment(struct ieee80211_tx_data *tx, | |||
843 | rem -= fraglen; | 846 | rem -= fraglen; |
844 | tmp = dev_alloc_skb(local->tx_headroom + | 847 | tmp = dev_alloc_skb(local->tx_headroom + |
845 | frag_threshold + | 848 | frag_threshold + |
846 | IEEE80211_ENCRYPT_HEADROOM + | 849 | tx->sdata->encrypt_headroom + |
847 | IEEE80211_ENCRYPT_TAILROOM); | 850 | IEEE80211_ENCRYPT_TAILROOM); |
848 | if (!tmp) | 851 | if (!tmp) |
849 | return -ENOMEM; | 852 | return -ENOMEM; |
850 | 853 | ||
851 | __skb_queue_tail(&tx->skbs, tmp); | 854 | __skb_queue_tail(&tx->skbs, tmp); |
852 | 855 | ||
853 | skb_reserve(tmp, local->tx_headroom + | 856 | skb_reserve(tmp, |
854 | IEEE80211_ENCRYPT_HEADROOM); | 857 | local->tx_headroom + tx->sdata->encrypt_headroom); |
858 | |||
855 | /* copy control information */ | 859 | /* copy control information */ |
856 | memcpy(tmp->cb, skb->cb, sizeof(tmp->cb)); | 860 | memcpy(tmp->cb, skb->cb, sizeof(tmp->cb)); |
857 | 861 | ||
@@ -1073,6 +1077,7 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx, | |||
1073 | queued = true; | 1077 | queued = true; |
1074 | info->control.vif = &tx->sdata->vif; | 1078 | info->control.vif = &tx->sdata->vif; |
1075 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 1079 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
1080 | info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS; | ||
1076 | __skb_queue_tail(&tid_tx->pending, skb); | 1081 | __skb_queue_tail(&tid_tx->pending, skb); |
1077 | if (skb_queue_len(&tid_tx->pending) > STA_MAX_TX_BUFFER) | 1082 | if (skb_queue_len(&tid_tx->pending) > STA_MAX_TX_BUFFER) |
1078 | purge_skb = __skb_dequeue(&tid_tx->pending); | 1083 | purge_skb = __skb_dequeue(&tid_tx->pending); |
@@ -1488,7 +1493,7 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, | |||
1488 | 1493 | ||
1489 | headroom = local->tx_headroom; | 1494 | headroom = local->tx_headroom; |
1490 | if (may_encrypt) | 1495 | if (may_encrypt) |
1491 | headroom += IEEE80211_ENCRYPT_HEADROOM; | 1496 | headroom += sdata->encrypt_headroom; |
1492 | headroom -= skb_headroom(skb); | 1497 | headroom -= skb_headroom(skb); |
1493 | headroom = max_t(int, 0, headroom); | 1498 | headroom = max_t(int, 0, headroom); |
1494 | 1499 | ||
@@ -1727,8 +1732,7 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
1727 | * radar detection by itself. We can do that later by adding a | 1732 | * radar detection by itself. We can do that later by adding a |
1728 | * monitor flag interfaces used for AP support. | 1733 | * monitor flag interfaces used for AP support. |
1729 | */ | 1734 | */ |
1730 | if ((chan->flags & (IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_RADAR | | 1735 | if ((chan->flags & (IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_RADAR))) |
1731 | IEEE80211_CHAN_PASSIVE_SCAN))) | ||
1732 | goto fail_rcu; | 1736 | goto fail_rcu; |
1733 | 1737 | ||
1734 | ieee80211_xmit(sdata, skb, chan->band); | 1738 | ieee80211_xmit(sdata, skb, chan->band); |
@@ -1743,6 +1747,26 @@ fail: | |||
1743 | return NETDEV_TX_OK; /* meaning, we dealt with the skb */ | 1747 | return NETDEV_TX_OK; /* meaning, we dealt with the skb */ |
1744 | } | 1748 | } |
1745 | 1749 | ||
1750 | /* | ||
1751 | * Measure Tx frame arrival time for Tx latency statistics calculation | ||
1752 | * A single Tx frame latency should be measured from when it is entering the | ||
1753 | * Kernel until we receive Tx complete confirmation indication and the skb is | ||
1754 | * freed. | ||
1755 | */ | ||
1756 | static void ieee80211_tx_latency_start_msrmnt(struct ieee80211_local *local, | ||
1757 | struct sk_buff *skb) | ||
1758 | { | ||
1759 | struct timespec skb_arv; | ||
1760 | struct ieee80211_tx_latency_bin_ranges *tx_latency; | ||
1761 | |||
1762 | tx_latency = rcu_dereference(local->tx_latency); | ||
1763 | if (!tx_latency) | ||
1764 | return; | ||
1765 | |||
1766 | ktime_get_ts(&skb_arv); | ||
1767 | skb->tstamp = ktime_set(skb_arv.tv_sec, skb_arv.tv_nsec); | ||
1768 | } | ||
1769 | |||
1746 | /** | 1770 | /** |
1747 | * ieee80211_subif_start_xmit - netif start_xmit function for Ethernet-type | 1771 | * ieee80211_subif_start_xmit - netif start_xmit function for Ethernet-type |
1748 | * subinterfaces (wlan#, WDS, and VLAN interfaces) | 1772 | * subinterfaces (wlan#, WDS, and VLAN interfaces) |
@@ -1793,6 +1817,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1793 | 1817 | ||
1794 | rcu_read_lock(); | 1818 | rcu_read_lock(); |
1795 | 1819 | ||
1820 | /* Measure frame arrival for Tx latency statistics calculation */ | ||
1821 | ieee80211_tx_latency_start_msrmnt(local, skb); | ||
1822 | |||
1796 | switch (sdata->vif.type) { | 1823 | switch (sdata->vif.type) { |
1797 | case NL80211_IFTYPE_AP_VLAN: | 1824 | case NL80211_IFTYPE_AP_VLAN: |
1798 | sta = rcu_dereference(sdata->u.vlan.sta); | 1825 | sta = rcu_dereference(sdata->u.vlan.sta); |
@@ -2112,7 +2139,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
2112 | */ | 2139 | */ |
2113 | 2140 | ||
2114 | if (head_need > 0 || skb_cloned(skb)) { | 2141 | if (head_need > 0 || skb_cloned(skb)) { |
2115 | head_need += IEEE80211_ENCRYPT_HEADROOM; | 2142 | head_need += sdata->encrypt_headroom; |
2116 | head_need += local->tx_headroom; | 2143 | head_need += local->tx_headroom; |
2117 | head_need = max_t(int, 0, head_need); | 2144 | head_need = max_t(int, 0, head_need); |
2118 | if (ieee80211_skb_resize(sdata, skb, head_need, true)) { | 2145 | if (ieee80211_skb_resize(sdata, skb, head_need, true)) { |
@@ -2139,7 +2166,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
2139 | if (ieee80211_is_data_qos(fc)) { | 2166 | if (ieee80211_is_data_qos(fc)) { |
2140 | __le16 *qos_control; | 2167 | __le16 *qos_control; |
2141 | 2168 | ||
2142 | qos_control = (__le16*) skb_push(skb, 2); | 2169 | qos_control = (__le16 *) skb_push(skb, 2); |
2143 | memcpy(skb_push(skb, hdrlen - 2), &hdr, hdrlen - 2); | 2170 | memcpy(skb_push(skb, hdrlen - 2), &hdr, hdrlen - 2); |
2144 | /* | 2171 | /* |
2145 | * Maybe we could actually set some fields here, for now just | 2172 | * Maybe we could actually set some fields here, for now just |
@@ -2301,7 +2328,7 @@ static void __ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata, | |||
2301 | if (atomic_read(&ps->num_sta_ps) > 0) | 2328 | if (atomic_read(&ps->num_sta_ps) > 0) |
2302 | /* in the hope that this is faster than | 2329 | /* in the hope that this is faster than |
2303 | * checking byte-for-byte */ | 2330 | * checking byte-for-byte */ |
2304 | have_bits = !bitmap_empty((unsigned long*)ps->tim, | 2331 | have_bits = !bitmap_empty((unsigned long *)ps->tim, |
2305 | IEEE80211_MAX_AID+1); | 2332 | IEEE80211_MAX_AID+1); |
2306 | 2333 | ||
2307 | if (ps->dtim_count == 0) | 2334 | if (ps->dtim_count == 0) |
@@ -2527,7 +2554,8 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2527 | */ | 2554 | */ |
2528 | skb = dev_alloc_skb(local->tx_headroom + | 2555 | skb = dev_alloc_skb(local->tx_headroom + |
2529 | beacon->head_len + | 2556 | beacon->head_len + |
2530 | beacon->tail_len + 256); | 2557 | beacon->tail_len + 256 + |
2558 | local->hw.extra_beacon_tailroom); | ||
2531 | if (!skb) | 2559 | if (!skb) |
2532 | goto out; | 2560 | goto out; |
2533 | 2561 | ||
@@ -2559,7 +2587,8 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2559 | ieee80211_update_csa(sdata, presp); | 2587 | ieee80211_update_csa(sdata, presp); |
2560 | 2588 | ||
2561 | 2589 | ||
2562 | skb = dev_alloc_skb(local->tx_headroom + presp->head_len); | 2590 | skb = dev_alloc_skb(local->tx_headroom + presp->head_len + |
2591 | local->hw.extra_beacon_tailroom); | ||
2563 | if (!skb) | 2592 | if (!skb) |
2564 | goto out; | 2593 | goto out; |
2565 | skb_reserve(skb, local->tx_headroom); | 2594 | skb_reserve(skb, local->tx_headroom); |
@@ -2580,13 +2609,13 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2580 | ieee80211_update_csa(sdata, bcn); | 2609 | ieee80211_update_csa(sdata, bcn); |
2581 | 2610 | ||
2582 | if (ifmsh->sync_ops) | 2611 | if (ifmsh->sync_ops) |
2583 | ifmsh->sync_ops->adjust_tbtt( | 2612 | ifmsh->sync_ops->adjust_tbtt(sdata, bcn); |
2584 | sdata); | ||
2585 | 2613 | ||
2586 | skb = dev_alloc_skb(local->tx_headroom + | 2614 | skb = dev_alloc_skb(local->tx_headroom + |
2587 | bcn->head_len + | 2615 | bcn->head_len + |
2588 | 256 + /* TIM IE */ | 2616 | 256 + /* TIM IE */ |
2589 | bcn->tail_len); | 2617 | bcn->tail_len + |
2618 | local->hw.extra_beacon_tailroom); | ||
2590 | if (!skb) | 2619 | if (!skb) |
2591 | goto out; | 2620 | goto out; |
2592 | skb_reserve(skb, local->tx_headroom); | 2621 | skb_reserve(skb, local->tx_headroom); |