[PATCH v3 11/13] mac80211: notify the driver when a sta uses 4-address mode

Felix Fietkau
2020-08-21T08:55:05Z

This is needed for encapsulation offload of 4-address mode packets

Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
include/net/mac80211.h | 4 ++++
net/mac80211/cfg.c | 1 +
net/mac80211/driver-ops.h | 14 ++++++++++++++
net/mac80211/mlme.c | 3 +++
net/mac80211/trace.h | 27 +++++++++++++++++++++++++++
5 files changed, 49 insertions(+)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index aaec7688e965..31bfe1b445e2 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3843,6 +3843,8 @@ enum ieee80211_reconfig_type {
* This callback may sleep.
* @update_vif_config: Update virtual interface offload flags
* This callback may sleep.
+ * @sta_set_4addr: Called to notify the driver when a station starts/stops using
+ * 4-address mode
*/
struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw,
@@ -4156,6 +4158,8 @@ struct ieee80211_ops {
struct ieee80211_sta *sta, u8 tids);
void (*update_vif_offload)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
+ void (*sta_set_4addr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, bool enabled);
};

/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index ea6f4d83f529..7b6c43e46a44 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1701,6 +1701,7 @@ static int ieee80211_change_station(struct wiphy *wiphy,

rcu_assign_pointer(vlansdata->u.vlan.sta, sta);
__ieee80211_check_fast_rx_iface(vlansdata);
+ drv_sta_set_4addr(local, sta->sdata, &sta->sta, true);
}

if (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index e3dfb9307fae..bcdfd19a596b 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1399,4 +1399,18 @@ static inline void drv_update_vif_offload(struct ieee80211_local *local,
trace_drv_return_void(local);
}

+static inline void drv_sta_set_4addr(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_sta *sta, bool enabled)
+{
+ sdata = get_bss_sdata(sdata);
+ if (!check_sdata_in_driver(sdata))
+ return;
+
+ trace_drv_sta_set_4addr(local, sdata, sta, enabled);
+ if (local->ops->sta_set_4addr)
+ local->ops->sta_set_4addr(&local->hw, &sdata->vif, sta, enabled);
+ trace_drv_return_void(local);
+}
+
#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index f241decf843d..50a9b9025725 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3523,6 +3523,9 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
goto out;
}

+ if (sdata->wdev.use_4addr)
+ drv_sta_set_4addr(local, sdata, &sta->sta, true);
+
mutex_unlock(&sdata->local->sta_mtx);

/*
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 50a0a83e96fc..89723907a094 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -2740,6 +2740,33 @@ DEFINE_EVENT(local_sdata_addr_evt, drv_update_vif_offload,
TP_ARGS(local, sdata)
);

+TRACE_EVENT(drv_sta_set_4addr,
+ TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_sta *sta, bool enabled),
+
+ TP_ARGS(local, sdata, sta, enabled),
+
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ VIF_ENTRY
+ STA_ENTRY
+ __field(bool, enabled)
+ ),
+
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ VIF_ASSIGN;
+ STA_ASSIGN;
+ __entry->enabled = enabled;
+ ),
+
+ TP_printk(
+ LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " enabled:%d",
+ LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->enabled
+ )
+);
+
#endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */

#undef TRACE_INCLUDE_PATH
--
2.28.0