blob: 1214ccb27b5ff4cbf94889a3dbda63bd72e0c4ba [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From: Felix Fietkau <nbd@nbd.name>
2Date: Wed, 16 Dec 2020 21:34:03 +0100
3Subject: [PATCH] mac80211: add rx decapsulation offload support
4
5This allows drivers to pass 802.3 frames to mac80211, with some restrictions:
6
7- the skb must be passed with a valid sta
8- fast-rx needs to be active for the sta
9- monitor mode needs to be disabled
10
11mac80211 will tell the driver when it is safe to enable rx decap offload for
12a particular station.
13
14In order to implement support, a driver must:
15
16- call ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD)
17- implement ops->sta_set_decap_offload
18- mark 802.3 frames with RX_FLAG_8023
19
20If it doesn't want to enable offload for some vif types, it can mask out
21IEEE80211_OFFLOAD_DECAP_ENABLED in vif->offload_flags from within the
22.add_interface or .update_vif_offload driver ops
23
24Signed-off-by: Felix Fietkau <nbd@nbd.name>
25---
26
27--- a/include/net/mac80211.h
28+++ b/include/net/mac80211.h
29@@ -1297,6 +1297,8 @@ ieee80211_tx_info_clear_status(struct ie
30 * the "0-length PSDU" field included there. The value for it is
31 * in &struct ieee80211_rx_status. Note that if this value isn't
32 * known the frame shouldn't be reported.
33+ * @RX_FLAG_8023: the frame has an 802.3 header (decap offload performed by
34+ * hardware or driver)
35 */
36 enum mac80211_rx_flags {
37 RX_FLAG_MMIC_ERROR = BIT(0),
38@@ -1329,6 +1331,7 @@ enum mac80211_rx_flags {
39 RX_FLAG_RADIOTAP_HE_MU = BIT(27),
40 RX_FLAG_RADIOTAP_LSIG = BIT(28),
41 RX_FLAG_NO_PSDU = BIT(29),
42+ RX_FLAG_8023 = BIT(30),
43 };
44
45 /**
46@@ -1650,11 +1653,15 @@ enum ieee80211_vif_flags {
47 * The driver supports sending frames passed as 802.3 frames by mac80211.
48 * It must also support sending 802.11 packets for the same interface.
49 * @IEEE80211_OFFLOAD_ENCAP_4ADDR: support 4-address mode encapsulation offload
50+ * @IEEE80211_OFFLOAD_DECAP_ENABLED: rx encapsulation offload is enabled
51+ * The driver supports passing received 802.11 frames as 802.3 frames to
52+ * mac80211.
53 */
54
55 enum ieee80211_offload_flags {
56 IEEE80211_OFFLOAD_ENCAP_ENABLED = BIT(0),
57 IEEE80211_OFFLOAD_ENCAP_4ADDR = BIT(1),
58+ IEEE80211_OFFLOAD_DECAP_ENABLED = BIT(2),
59 };
60
61 /**
62@@ -2390,6 +2397,9 @@ struct ieee80211_txq {
63 * @IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD: Hardware supports tx encapsulation
64 * offload
65 *
66+ * @IEEE80211_HW_SUPPORTS_RX_DECAP_OFFLOAD: Hardware supports rx decapsulation
67+ * offload
68+ *
69 * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
70 */
71 enum ieee80211_hw_flags {
72@@ -2443,6 +2453,7 @@ enum ieee80211_hw_flags {
73 IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID,
74 IEEE80211_HW_AMPDU_KEYBORDER_SUPPORT,
75 IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD,
76+ IEEE80211_HW_SUPPORTS_RX_DECAP_OFFLOAD,
77
78 /* keep last, obviously */
79 NUM_IEEE80211_HW_FLAGS
80@@ -4196,6 +4207,9 @@ struct ieee80211_ops {
81 struct ieee80211_vif *vif);
82 void (*sta_set_4addr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
83 struct ieee80211_sta *sta, bool enabled);
84+ void (*sta_set_decap_offload)(struct ieee80211_hw *hw,
85+ struct ieee80211_vif *vif,
86+ struct ieee80211_sta *sta, bool enabled);
87 };
88
89 /**
90--- a/net/mac80211/debugfs.c
91+++ b/net/mac80211/debugfs.c
92@@ -405,6 +405,7 @@ static const char *hw_flag_names[] = {
93 FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID),
94 FLAG(AMPDU_KEYBORDER_SUPPORT),
95 FLAG(SUPPORTS_TX_ENCAP_OFFLOAD),
96+ FLAG(SUPPORTS_RX_DECAP_OFFLOAD),
97 #undef FLAG
98 };
99
100--- a/net/mac80211/debugfs_sta.c
101+++ b/net/mac80211/debugfs_sta.c
102@@ -79,6 +79,7 @@ static const char * const sta_flag_names
103 FLAG(MPSP_RECIPIENT),
104 FLAG(PS_DELIVER),
105 FLAG(USES_ENCRYPTION),
106+ FLAG(DECAP_OFFLOAD),
107 #undef FLAG
108 };
109
110--- a/net/mac80211/driver-ops.h
111+++ b/net/mac80211/driver-ops.h
112@@ -1416,4 +1416,20 @@ static inline void drv_sta_set_4addr(str
113 trace_drv_return_void(local);
114 }
115
116+static inline void drv_sta_set_decap_offload(struct ieee80211_local *local,
117+ struct ieee80211_sub_if_data *sdata,
118+ struct ieee80211_sta *sta,
119+ bool enabled)
120+{
121+ sdata = get_bss_sdata(sdata);
122+ if (!check_sdata_in_driver(sdata))
123+ return;
124+
125+ trace_drv_sta_set_decap_offload(local, sdata, sta, enabled);
126+ if (local->ops->sta_set_decap_offload)
127+ local->ops->sta_set_decap_offload(&local->hw, &sdata->vif, sta,
128+ enabled);
129+ trace_drv_return_void(local);
130+}
131+
132 #endif /* __MAC80211_DRIVER_OPS */
133--- a/net/mac80211/iface.c
134+++ b/net/mac80211/iface.c
135@@ -856,7 +856,7 @@ static const struct net_device_ops ieee8
136
137 };
138
139-static bool ieee80211_iftype_supports_encap_offload(enum nl80211_iftype iftype)
140+static bool ieee80211_iftype_supports_hdr_offload(enum nl80211_iftype iftype)
141 {
142 switch (iftype) {
143 /* P2P GO and client are mapped to AP/STATION types */
144@@ -876,7 +876,7 @@ static bool ieee80211_set_sdata_offload_
145 flags = sdata->vif.offload_flags;
146
147 if (ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) &&
148- ieee80211_iftype_supports_encap_offload(sdata->vif.type)) {
149+ ieee80211_iftype_supports_hdr_offload(sdata->vif.type)) {
150 flags |= IEEE80211_OFFLOAD_ENCAP_ENABLED;
151
152 if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_FRAG) &&
153@@ -889,10 +889,21 @@ static bool ieee80211_set_sdata_offload_
154 flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
155 }
156
157+ if (ieee80211_hw_check(&local->hw, SUPPORTS_RX_DECAP_OFFLOAD) &&
158+ ieee80211_iftype_supports_hdr_offload(sdata->vif.type)) {
159+ flags |= IEEE80211_OFFLOAD_DECAP_ENABLED;
160+
161+ if (local->monitors)
162+ flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED;
163+ } else {
164+ flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED;
165+ }
166+
167 if (sdata->vif.offload_flags == flags)
168 return false;
169
170 sdata->vif.offload_flags = flags;
171+ ieee80211_check_fast_rx_iface(sdata);
172 return true;
173 }
174
175@@ -910,7 +921,7 @@ static void ieee80211_set_vif_encap_ops(
176 }
177
178 if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) ||
179- !ieee80211_iftype_supports_encap_offload(bss->vif.type))
180+ !ieee80211_iftype_supports_hdr_offload(bss->vif.type))
181 return;
182
183 enabled = bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED;
184--- a/net/mac80211/rx.c
185+++ b/net/mac80211/rx.c
186@@ -4199,7 +4199,9 @@ void ieee80211_check_fast_rx(struct sta_
187 .vif_type = sdata->vif.type,
188 .control_port_protocol = sdata->control_port_protocol,
189 }, *old, *new = NULL;
190+ bool set_offload = false;
191 bool assign = false;
192+ bool offload;
193
194 /* use sparse to check that we don't return without updating */
195 __acquire(check_fast_rx);
196@@ -4312,6 +4314,17 @@ void ieee80211_check_fast_rx(struct sta_
197 if (assign)
198 new = kmemdup(&fastrx, sizeof(fastrx), GFP_KERNEL);
199
200+ offload = assign &&
201+ (sdata->vif.offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED);
202+
203+ if (offload)
204+ set_offload = !test_and_set_sta_flag(sta, WLAN_STA_DECAP_OFFLOAD);
205+ else
206+ set_offload = test_and_clear_sta_flag(sta, WLAN_STA_DECAP_OFFLOAD);
207+
208+ if (set_offload)
209+ drv_sta_set_decap_offload(local, sdata, &sta->sta, assign);
210+
211 spin_lock_bh(&sta->lock);
212 old = rcu_dereference_protected(sta->fast_rx, true);
213 rcu_assign_pointer(sta->fast_rx, new);
214@@ -4358,6 +4371,108 @@ void ieee80211_check_fast_rx_iface(struc
215 mutex_unlock(&local->sta_mtx);
216 }
217
218+static void ieee80211_rx_8023(struct ieee80211_rx_data *rx,
219+ struct ieee80211_fast_rx *fast_rx,
220+ int orig_len)
221+{
222+ struct ieee80211_sta_rx_stats *stats;
223+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
224+ struct sta_info *sta = rx->sta;
225+ struct sk_buff *skb = rx->skb;
226+ void *sa = skb->data + ETH_ALEN;
227+ void *da = skb->data;
228+
229+ stats = &sta->rx_stats;
230+ if (fast_rx->uses_rss)
231+ stats = this_cpu_ptr(sta->pcpu_rx_stats);
232+
233+ /* statistics part of ieee80211_rx_h_sta_process() */
234+ if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
235+ stats->last_signal = status->signal;
236+ if (!fast_rx->uses_rss)
237+ ewma_signal_add(&sta->rx_stats_avg.signal,
238+ -status->signal);
239+ }
240+
241+ if (status->chains) {
242+ int i;
243+
244+ stats->chains = status->chains;
245+ for (i = 0; i < ARRAY_SIZE(status->chain_signal); i++) {
246+ int signal = status->chain_signal[i];
247+
248+ if (!(status->chains & BIT(i)))
249+ continue;
250+
251+ stats->chain_signal_last[i] = signal;
252+ if (!fast_rx->uses_rss)
253+ ewma_signal_add(&sta->rx_stats_avg.chain_signal[i],
254+ -signal);
255+ }
256+ }
257+ /* end of statistics */
258+
259+ stats->last_rx = jiffies;
260+ stats->last_rate = sta_stats_encode_rate(status);
261+
262+ stats->fragments++;
263+ stats->packets++;
264+
265+ skb->dev = fast_rx->dev;
266+
267+ ieee80211_rx_stats(fast_rx->dev, skb->len);
268+
269+ /* The seqno index has the same property as needed
270+ * for the rx_msdu field, i.e. it is IEEE80211_NUM_TIDS
271+ * for non-QoS-data frames. Here we know it's a data
272+ * frame, so count MSDUs.
273+ */
274+ u64_stats_update_begin(&stats->syncp);
275+ stats->msdu[rx->seqno_idx]++;
276+ stats->bytes += orig_len;
277+ u64_stats_update_end(&stats->syncp);
278+
279+ if (fast_rx->internal_forward) {
280+ struct sk_buff *xmit_skb = NULL;
281+ if (is_multicast_ether_addr(da)) {
282+ xmit_skb = skb_copy(skb, GFP_ATOMIC);
283+ } else if (!ether_addr_equal(da, sa) &&
284+ sta_info_get(rx->sdata, da)) {
285+ xmit_skb = skb;
286+ skb = NULL;
287+ }
288+
289+ if (xmit_skb) {
290+ /*
291+ * Send to wireless media and increase priority by 256
292+ * to keep the received priority instead of
293+ * reclassifying the frame (see cfg80211_classify8021d).
294+ */
295+ xmit_skb->priority += 256;
296+ xmit_skb->protocol = htons(ETH_P_802_3);
297+ skb_reset_network_header(xmit_skb);
298+ skb_reset_mac_header(xmit_skb);
299+ dev_queue_xmit(xmit_skb);
300+ }
301+
302+ if (!skb)
303+ return;
304+ }
305+
306+ /* deliver to local stack */
307+ skb->protocol = eth_type_trans(skb, fast_rx->dev);
308+ memset(skb->cb, 0, sizeof(skb->cb));
309+ if (rx->list)
310+#if LINUX_VERSION_IS_GEQ(4,19,0)
311+ list_add_tail(&skb->list, rx->list);
312+#else
313+ __skb_queue_tail(rx->list, skb);
314+#endif
315+ else
316+ netif_receive_skb(skb);
317+
318+}
319+
320 static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
321 struct ieee80211_fast_rx *fast_rx)
322 {
323@@ -4378,9 +4493,6 @@ static bool ieee80211_invoke_fast_rx(str
324 } addrs __aligned(2);
325 struct ieee80211_sta_rx_stats *stats = &sta->rx_stats;
326
327- if (fast_rx->uses_rss)
328- stats = this_cpu_ptr(sta->pcpu_rx_stats);
329-
330 /* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write
331 * to a common data structure; drivers can implement that per queue
332 * but we don't have that information in mac80211
333@@ -4454,32 +4566,6 @@ static bool ieee80211_invoke_fast_rx(str
334 pskb_trim(skb, skb->len - fast_rx->icv_len))
335 goto drop;
336
337- /* statistics part of ieee80211_rx_h_sta_process() */
338- if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
339- stats->last_signal = status->signal;
340- if (!fast_rx->uses_rss)
341- ewma_signal_add(&sta->rx_stats_avg.signal,
342- -status->signal);
343- }
344-
345- if (status->chains) {
346- int i;
347-
348- stats->chains = status->chains;
349- for (i = 0; i < ARRAY_SIZE(status->chain_signal); i++) {
350- int signal = status->chain_signal[i];
351-
352- if (!(status->chains & BIT(i)))
353- continue;
354-
355- stats->chain_signal_last[i] = signal;
356- if (!fast_rx->uses_rss)
357- ewma_signal_add(&sta->rx_stats_avg.chain_signal[i],
358- -signal);
359- }
360- }
361- /* end of statistics */
362-
363 if (rx->key && !ieee80211_has_protected(hdr->frame_control))
364 goto drop;
365
366@@ -4491,12 +4577,6 @@ static bool ieee80211_invoke_fast_rx(str
367 return true;
368 }
369
370- stats->last_rx = jiffies;
371- stats->last_rate = sta_stats_encode_rate(status);
372-
373- stats->fragments++;
374- stats->packets++;
375-
376 /* do the header conversion - first grab the addresses */
377 ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs);
378 ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs);
379@@ -4505,62 +4585,14 @@ static bool ieee80211_invoke_fast_rx(str
380 /* push the addresses in front */
381 memcpy(skb_push(skb, sizeof(addrs)), &addrs, sizeof(addrs));
382
383- skb->dev = fast_rx->dev;
384-
385- ieee80211_rx_stats(fast_rx->dev, skb->len);
386-
387- /* The seqno index has the same property as needed
388- * for the rx_msdu field, i.e. it is IEEE80211_NUM_TIDS
389- * for non-QoS-data frames. Here we know it's a data
390- * frame, so count MSDUs.
391- */
392- u64_stats_update_begin(&stats->syncp);
393- stats->msdu[rx->seqno_idx]++;
394- stats->bytes += orig_len;
395- u64_stats_update_end(&stats->syncp);
396-
397- if (fast_rx->internal_forward) {
398- struct sk_buff *xmit_skb = NULL;
399- if (is_multicast_ether_addr(addrs.da)) {
400- xmit_skb = skb_copy(skb, GFP_ATOMIC);
401- } else if (!ether_addr_equal(addrs.da, addrs.sa) &&
402- sta_info_get(rx->sdata, addrs.da)) {
403- xmit_skb = skb;
404- skb = NULL;
405- }
406-
407- if (xmit_skb) {
408- /*
409- * Send to wireless media and increase priority by 256
410- * to keep the received priority instead of
411- * reclassifying the frame (see cfg80211_classify8021d).
412- */
413- xmit_skb->priority += 256;
414- xmit_skb->protocol = htons(ETH_P_802_3);
415- skb_reset_network_header(xmit_skb);
416- skb_reset_mac_header(xmit_skb);
417- dev_queue_xmit(xmit_skb);
418- }
419-
420- if (!skb)
421- return true;
422- }
423-
424- /* deliver to local stack */
425- skb->protocol = eth_type_trans(skb, fast_rx->dev);
426- memset(skb->cb, 0, sizeof(skb->cb));
427- if (rx->list)
428-#if LINUX_VERSION_IS_GEQ(4,19,0)
429- list_add_tail(&skb->list, rx->list);
430-#else
431- __skb_queue_tail(rx->list, skb);
432-#endif
433- else
434- netif_receive_skb(skb);
435+ ieee80211_rx_8023(rx, fast_rx, orig_len);
436
437 return true;
438 drop:
439 dev_kfree_skb(skb);
440+ if (fast_rx->uses_rss)
441+ stats = this_cpu_ptr(sta->pcpu_rx_stats);
442+
443 stats->dropped++;
444 return true;
445 }
446@@ -4614,6 +4646,47 @@ static bool ieee80211_prepare_and_rx_han
447 return true;
448 }
449
450+static void __ieee80211_rx_handle_8023(struct ieee80211_hw *hw,
451+ struct ieee80211_sta *pubsta,
452+ struct sk_buff *skb,
453+#if LINUX_VERSION_IS_GEQ(4,19,0)
454+ struct list_head *list)
455+#else
456+ struct sk_buff_head *list)
457+#endif
458+{
459+ struct ieee80211_local *local = hw_to_local(hw);
460+ struct ieee80211_fast_rx *fast_rx;
461+ struct ieee80211_rx_data rx;
462+
463+ memset(&rx, 0, sizeof(rx));
464+ rx.skb = skb;
465+ rx.local = local;
466+ rx.list = list;
467+
468+ I802_DEBUG_INC(local->dot11ReceivedFragmentCount);
469+
470+ /* drop frame if too short for header */
471+ if (skb->len < sizeof(struct ethhdr))
472+ goto drop;
473+
474+ if (!pubsta)
475+ goto drop;
476+
477+ rx.sta = container_of(pubsta, struct sta_info, sta);
478+ rx.sdata = rx.sta->sdata;
479+
480+ fast_rx = rcu_dereference(rx.sta->fast_rx);
481+ if (!fast_rx)
482+ goto drop;
483+
484+ ieee80211_rx_8023(&rx, fast_rx, skb->len);
485+ return;
486+
487+drop:
488+ dev_kfree_skb(skb);
489+}
490+
491 /*
492 * This is the actual Rx frames handler. as it belongs to Rx path it must
493 * be called with rcu_read_lock protection.
494@@ -4851,15 +4924,20 @@ void ieee80211_rx_list(struct ieee80211_
495 * if it was previously present.
496 * Also, frames with less than 16 bytes are dropped.
497 */
498- skb = ieee80211_rx_monitor(local, skb, rate);
499- if (!skb)
500- return;
501+ if (!(status->flag & RX_FLAG_8023)) {
502+ skb = ieee80211_rx_monitor(local, skb, rate);
503+ if (!skb)
504+ return;
505+ }
506
507 ieee80211_tpt_led_trig_rx(local,
508 ((struct ieee80211_hdr *)skb->data)->frame_control,
509 skb->len);
510
511- __ieee80211_rx_handle_packet(hw, pubsta, skb, list);
512+ if (status->flag & RX_FLAG_8023)
513+ __ieee80211_rx_handle_8023(hw, pubsta, skb, list);
514+ else
515+ __ieee80211_rx_handle_packet(hw, pubsta, skb, list);
516
517 return;
518 drop:
519--- a/net/mac80211/sta_info.h
520+++ b/net/mac80211/sta_info.h
521@@ -71,6 +71,7 @@
522 * until pending frames are delivered
523 * @WLAN_STA_USES_ENCRYPTION: This station was configured for encryption,
524 * so drop all packets without a key later.
525+ * @WLAN_STA_DECAP_OFFLOAD: This station uses rx decap offload
526 *
527 * @NUM_WLAN_STA_FLAGS: number of defined flags
528 */
529@@ -102,6 +103,7 @@ enum ieee80211_sta_info_flags {
530 WLAN_STA_MPSP_RECIPIENT,
531 WLAN_STA_PS_DELIVER,
532 WLAN_STA_USES_ENCRYPTION,
533+ WLAN_STA_DECAP_OFFLOAD,
534
535 NUM_WLAN_STA_FLAGS,
536 };
537--- a/net/mac80211/trace.h
538+++ b/net/mac80211/trace.h
539@@ -2761,7 +2761,7 @@ DEFINE_EVENT(local_sdata_addr_evt, drv_u
540 TP_ARGS(local, sdata)
541 );
542
543-TRACE_EVENT(drv_sta_set_4addr,
544+DECLARE_EVENT_CLASS(sta_flag_evt,
545 TP_PROTO(struct ieee80211_local *local,
546 struct ieee80211_sub_if_data *sdata,
547 struct ieee80211_sta *sta, bool enabled),
548@@ -2788,6 +2788,22 @@ TRACE_EVENT(drv_sta_set_4addr,
549 )
550 );
551
552+DEFINE_EVENT(sta_flag_evt, drv_sta_set_4addr,
553+ TP_PROTO(struct ieee80211_local *local,
554+ struct ieee80211_sub_if_data *sdata,
555+ struct ieee80211_sta *sta, bool enabled),
556+
557+ TP_ARGS(local, sdata, sta, enabled)
558+);
559+
560+DEFINE_EVENT(sta_flag_evt, drv_sta_set_decap_offload,
561+ TP_PROTO(struct ieee80211_local *local,
562+ struct ieee80211_sub_if_data *sdata,
563+ struct ieee80211_sta *sta, bool enabled),
564+
565+ TP_ARGS(local, sdata, sta, enabled)
566+);
567+
568 #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
569
570 #undef TRACE_INCLUDE_PATH