2024-05-06 21:20:36

by Muna Sinada

[permalink] [raw]
Subject: [PATCH 0/2] Allow VLAN unicast packets to take 8023 xmit path

Allow VLAN unicast packets to take the 8023 xmit path when
encapsulation offload is enabled. This allows AP VLAN unicast
packets to have encapsulation and encryption handled in hardware

Before doing so, relocate __ieee80211_subif_start_xmit() definition to
allow it to call ieee80211_8023_xmit()

Muna Sinada (2):
wifi: mac80211: relocate __ieee80211_subif_start_xmit() definition
wifi: mac80211: VLAN unicast packets take 8023 xmit path

net/mac80211/tx.c | 177 +++++++++++++++++++++++++---------------------
1 file changed, 95 insertions(+), 82 deletions(-)

--
2.34.1



2024-05-06 21:20:40

by Muna Sinada

[permalink] [raw]
Subject: [PATCH 1/2] wifi: mac80211: relocate __ieee80211_subif_start_xmit() definition

Move __ieee80211_subif_start_xmit() definition below
ieee80211_8023_xmit() due to subsequent patch adding
ieee80211_8023_xmit() function call in __ieee80211_subif_start_xmit().

Signed-off-by: Muna Sinada <[email protected]>
---
net/mac80211/tx.c | 164 +++++++++++++++++++++++-----------------------
1 file changed, 82 insertions(+), 82 deletions(-)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index cfd0a62d0152..c0e0b5f63714 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -4265,88 +4265,6 @@ void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac)
}
EXPORT_SYMBOL(ieee80211_txq_schedule_start);

-void __ieee80211_subif_start_xmit(struct sk_buff *skb,
- struct net_device *dev,
- u32 info_flags,
- u32 ctrl_flags,
- u64 *cookie)
-{
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- struct ieee80211_local *local = sdata->local;
- struct sta_info *sta;
- struct sk_buff *next;
- int len = skb->len;
-
- if (unlikely(!ieee80211_sdata_running(sdata) || skb->len < ETH_HLEN)) {
- kfree_skb(skb);
- return;
- }
-
- sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift);
-
- rcu_read_lock();
-
- if (ieee80211_vif_is_mesh(&sdata->vif) &&
- ieee80211_hw_check(&local->hw, SUPPORT_FAST_XMIT) &&
- ieee80211_mesh_xmit_fast(sdata, skb, ctrl_flags))
- goto out;
-
- if (ieee80211_lookup_ra_sta(sdata, skb, &sta))
- goto out_free;
-
- if (IS_ERR(sta))
- sta = NULL;
-
- skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb));
- ieee80211_aggr_check(sdata, sta, skb);
-
- if (sta) {
- struct ieee80211_fast_tx *fast_tx;
-
- fast_tx = rcu_dereference(sta->fast_tx);
-
- if (fast_tx &&
- ieee80211_xmit_fast(sdata, sta, fast_tx, skb))
- goto out;
- }
-
- /* the frame could be fragmented, software-encrypted, and other
- * things so we cannot really handle checksum or GSO offload.
- * fix it up in software before we handle anything else.
- */
- skb = ieee80211_tx_skb_fixup(skb, 0);
- if (!skb) {
- len = 0;
- goto out;
- }
-
- skb_list_walk_safe(skb, skb, next) {
- skb_mark_not_on_list(skb);
-
- if (skb->protocol == sdata->control_port_protocol)
- ctrl_flags |= IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP;
-
- skb = ieee80211_build_hdr(sdata, skb, info_flags,
- sta, ctrl_flags, cookie);
- if (IS_ERR(skb)) {
- kfree_skb_list(next);
- goto out;
- }
-
- dev_sw_netstats_tx_add(dev, 1, skb->len);
-
- ieee80211_xmit(sdata, sta, skb);
- }
- goto out;
- out_free:
- kfree_skb(skb);
- len = 0;
- out:
- if (len)
- ieee80211_tpt_led_trig_tx(local, len);
- rcu_read_unlock();
-}
-
static int ieee80211_change_da(struct sk_buff *skb, struct sta_info *sta)
{
struct ethhdr *eth;
@@ -4729,6 +4647,88 @@ netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb,
return NETDEV_TX_OK;
}

+void __ieee80211_subif_start_xmit(struct sk_buff *skb,
+ struct net_device *dev,
+ u32 info_flags,
+ u32 ctrl_flags,
+ u64 *cookie)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_local *local = sdata->local;
+ struct sta_info *sta;
+ struct sk_buff *next;
+ int len = skb->len;
+
+ if (unlikely(!ieee80211_sdata_running(sdata) || skb->len < ETH_HLEN)) {
+ kfree_skb(skb);
+ return;
+ }
+
+ sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift);
+
+ rcu_read_lock();
+
+ if (ieee80211_vif_is_mesh(&sdata->vif) &&
+ ieee80211_hw_check(&local->hw, SUPPORT_FAST_XMIT) &&
+ ieee80211_mesh_xmit_fast(sdata, skb, ctrl_flags))
+ goto out;
+
+ if (ieee80211_lookup_ra_sta(sdata, skb, &sta))
+ goto out_free;
+
+ if (IS_ERR(sta))
+ sta = NULL;
+
+ skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb));
+ ieee80211_aggr_check(sdata, sta, skb);
+
+ if (sta) {
+ struct ieee80211_fast_tx *fast_tx;
+
+ fast_tx = rcu_dereference(sta->fast_tx);
+
+ if (fast_tx &&
+ ieee80211_xmit_fast(sdata, sta, fast_tx, skb))
+ goto out;
+ }
+
+ /* the frame could be fragmented, software-encrypted, and other
+ * things so we cannot really handle checksum or GSO offload.
+ * fix it up in software before we handle anything else.
+ */
+ skb = ieee80211_tx_skb_fixup(skb, 0);
+ if (!skb) {
+ len = 0;
+ goto out;
+ }
+
+ skb_list_walk_safe(skb, skb, next) {
+ skb_mark_not_on_list(skb);
+
+ if (skb->protocol == sdata->control_port_protocol)
+ ctrl_flags |= IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP;
+
+ skb = ieee80211_build_hdr(sdata, skb, info_flags,
+ sta, ctrl_flags, cookie);
+ if (IS_ERR(skb)) {
+ kfree_skb_list(next);
+ goto out;
+ }
+
+ dev_sw_netstats_tx_add(dev, 1, skb->len);
+
+ ieee80211_xmit(sdata, sta, skb);
+ }
+ goto out;
+ out_free:
+ kfree_skb(skb);
+ len = 0;
+ out:
+ if (len)
+ ieee80211_tpt_led_trig_tx(local, len);
+ rcu_read_unlock();
+}
+
struct sk_buff *
ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb, u32 info_flags)
--
2.34.1


2024-05-06 21:20:48

by Muna Sinada

[permalink] [raw]
Subject: [PATCH 2/2] wifi: mac80211: VLAN unicast packets take 8023 xmit path

Default behavior for multicast AP VLAN interface traffic is using
software encryption as per commit 18890d4b89d8 ("mac80211: Disable hw
crypto for GTKs on AP VLAN interfaces").

When encapsulation offload is enabled, non-VLAN AP unicast packets are
taking the 8023 xmit path. Similarly unicast packets in AP VLAN
interfaces should have the same behavior as the non-VLAN AP case.

Allow AP VLAN unicast packets to take the 8023 xmit path where
hardware will handle encapsulation and encryption. As a result, there
is less CPU overhead in the 8023 xmit path as we don't encapsulate in
software. Mcast/bcast will continue to use 80211 xmit path.

Co-developed-by: Gautham Kumar Senthilkumaran <[email protected]>
Signed-off-by: Gautham Kumar Senthilkumaran <[email protected]>
Signed-off-by: Muna Sinada <[email protected]>
---
net/mac80211/tx.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index c0e0b5f63714..d77172771a36 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -4654,7 +4654,9 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
u64 *cookie)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_sub_if_data *ap_sdata;
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_key *key;
struct sta_info *sta;
struct sk_buff *next;
int len = skb->len;
@@ -4679,6 +4681,17 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
if (IS_ERR(sta))
sta = NULL;

+ if (sta && sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
+ ap_sdata = container_of(sdata->bss,
+ struct ieee80211_sub_if_data, u.ap);
+ if (ap_sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED &&
+ !is_multicast_ether_addr(skb->data)) {
+ key = rcu_dereference(sta->ptk[sta->ptk_idx]);
+ ieee80211_8023_xmit(sdata, dev, sta, key, skb);
+ goto out;
+ }
+ }
+
skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb));
ieee80211_aggr_check(sdata, sta, skb);

--
2.34.1


2024-05-07 06:50:30

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 2/2] wifi: mac80211: VLAN unicast packets take 8023 xmit path

On Mon, 2024-05-06 at 14:20 -0700, Muna Sinada wrote:
>
> + if (sta && sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
> + ap_sdata = container_of(sdata->bss,
> + struct ieee80211_sub_if_data, u.ap);
> + if (ap_sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED &&
> + !is_multicast_ether_addr(skb->data)) {
> + key = rcu_dereference(sta->ptk[sta->ptk_idx]);

Why is that line there, and why is it necessary? Is it even correct?

I see you need a key pointer on the next line, but still... that doesn't
seem right.

johannes