03d115071ec71f8ed39f48d03b84e25ab0db51f9
[openwrt/staging/aparcar.git] /
1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Fri, 22 Mar 2019 18:06:03 +0100
3 Subject: [PATCH] mac80211: when using iTXQ, select the queue in
4 ieee80211_subif_start_xmit
5
6 When using iTXQ, the network stack does not need the real queue number, since
7 mac80211 is using its internal queues anyway. In that case we can defer
8 selecting the queue and remove a redundant station lookup in the tx path to save
9 some CPU cycles.
10
11 Signed-off-by: Felix Fietkau <nbd@nbd.name>
12 ---
13
14 --- a/net/mac80211/tx.c
15 +++ b/net/mac80211/tx.c
16 @@ -3753,6 +3753,7 @@ void __ieee80211_subif_start_xmit(struct
17 u32 info_flags)
18 {
19 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
20 + struct ieee80211_local *local = sdata->local;
21 struct sta_info *sta;
22 struct sk_buff *next;
23
24 @@ -3766,7 +3767,15 @@ void __ieee80211_subif_start_xmit(struct
25 if (ieee80211_lookup_ra_sta(sdata, skb, &sta))
26 goto out_free;
27
28 - if (!IS_ERR_OR_NULL(sta)) {
29 + if (IS_ERR(sta))
30 + sta = NULL;
31 +
32 + if (local->ops->wake_tx_queue) {
33 + u16 queue = __ieee80211_select_queue(sdata, sta, skb);
34 + skb_set_queue_mapping(skb, queue);
35 + }
36 +
37 + if (sta) {
38 struct ieee80211_fast_tx *fast_tx;
39
40 /* We need a bit of data queued to build aggregates properly, so
41 --- a/net/mac80211/wme.c
42 +++ b/net/mac80211/wme.c
43 @@ -141,6 +141,42 @@ u16 ieee80211_select_queue_80211(struct
44 return ieee80211_downgrade_queue(sdata, NULL, skb);
45 }
46
47 +u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
48 + struct sta_info *sta, struct sk_buff *skb)
49 +{
50 + struct mac80211_qos_map *qos_map;
51 + bool qos;
52 +
53 + /* all mesh/ocb stations are required to support WME */
54 + if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
55 + sdata->vif.type == NL80211_IFTYPE_OCB)
56 + qos = true;
57 + else if (sta)
58 + qos = sta->sta.wme;
59 + else
60 + qos = false;
61 +
62 + if (!qos) {
63 + skb->priority = 0; /* required for correct WPA/11i MIC */
64 + return IEEE80211_AC_BE;
65 + }
66 +
67 + if (skb->protocol == sdata->control_port_protocol) {
68 + skb->priority = 7;
69 + goto downgrade;
70 + }
71 +
72 + /* use the data classifier to determine what 802.1d tag the
73 + * data frame has */
74 + qos_map = rcu_dereference(sdata->qos_map);
75 + skb->priority = cfg80211_classify8021d(skb, qos_map ?
76 + &qos_map->qos_map : NULL);
77 +
78 + downgrade:
79 + return ieee80211_downgrade_queue(sdata, sta, skb);
80 +}
81 +
82 +
83 /* Indicate which queue to use. */
84 u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
85 struct sk_buff *skb)
86 @@ -148,10 +184,12 @@ u16 ieee80211_select_queue(struct ieee80
87 struct ieee80211_local *local = sdata->local;
88 struct sta_info *sta = NULL;
89 const u8 *ra = NULL;
90 - bool qos = false;
91 - struct mac80211_qos_map *qos_map;
92 u16 ret;
93
94 + /* when using iTXQ, we can do this later */
95 + if (local->ops->wake_tx_queue)
96 + return 0;
97 +
98 if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) {
99 skb->priority = 0; /* required for correct WPA/11i MIC */
100 return 0;
101 @@ -161,10 +199,8 @@ u16 ieee80211_select_queue(struct ieee80
102 switch (sdata->vif.type) {
103 case NL80211_IFTYPE_AP_VLAN:
104 sta = rcu_dereference(sdata->u.vlan.sta);
105 - if (sta) {
106 - qos = sta->sta.wme;
107 + if (sta)
108 break;
109 - }
110 /* fall through */
111 case NL80211_IFTYPE_AP:
112 ra = skb->data;
113 @@ -172,56 +208,26 @@ u16 ieee80211_select_queue(struct ieee80
114 case NL80211_IFTYPE_WDS:
115 ra = sdata->u.wds.remote_addr;
116 break;
117 -#ifdef CPTCFG_MAC80211_MESH
118 - case NL80211_IFTYPE_MESH_POINT:
119 - qos = true;
120 - break;
121 -#endif
122 case NL80211_IFTYPE_STATION:
123 /* might be a TDLS station */
124 sta = sta_info_get(sdata, skb->data);
125 if (sta)
126 - qos = sta->sta.wme;
127 + break;
128
129 ra = sdata->u.mgd.bssid;
130 break;
131 case NL80211_IFTYPE_ADHOC:
132 ra = skb->data;
133 break;
134 - case NL80211_IFTYPE_OCB:
135 - /* all stations are required to support WME */
136 - qos = true;
137 - break;
138 default:
139 break;
140 }
141
142 - if (!sta && ra && !is_multicast_ether_addr(ra)) {
143 + if (!sta && ra && !is_multicast_ether_addr(ra))
144 sta = sta_info_get(sdata, ra);
145 - if (sta)
146 - qos = sta->sta.wme;
147 - }
148
149 - if (!qos) {
150 - skb->priority = 0; /* required for correct WPA/11i MIC */
151 - ret = IEEE80211_AC_BE;
152 - goto out;
153 - }
154 -
155 - if (skb->protocol == sdata->control_port_protocol) {
156 - skb->priority = 7;
157 - goto downgrade;
158 - }
159 -
160 - /* use the data classifier to determine what 802.1d tag the
161 - * data frame has */
162 - qos_map = rcu_dereference(sdata->qos_map);
163 - skb->priority = cfg80211_classify8021d(skb, qos_map ?
164 - &qos_map->qos_map : NULL);
165 + ret = __ieee80211_select_queue(sdata, sta, skb);
166
167 - downgrade:
168 - ret = ieee80211_downgrade_queue(sdata, sta, skb);
169 - out:
170 rcu_read_unlock();
171 return ret;
172 }
173 --- a/net/mac80211/wme.h
174 +++ b/net/mac80211/wme.h
175 @@ -16,6 +16,8 @@
176 u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,
177 struct sk_buff *skb,
178 struct ieee80211_hdr *hdr);
179 +u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
180 + struct sta_info *sta, struct sk_buff *skb);
181 u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
182 struct sk_buff *skb);
183 void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata,