mac80211: notify the driver when a sta uses 4-address mode
authorFelix Fietkau <nbd@nbd.name>
Tue, 8 Sep 2020 12:37:01 +0000 (14:37 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 18 Sep 2020 10:16:16 +0000 (12:16 +0200)
This is needed for encapsulation offload of 4-address mode packets

Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://lore.kernel.org/r/20200908123702.88454-14-nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/mac80211.h
net/mac80211/cfg.c
net/mac80211/driver-ops.h
net/mac80211/mlme.c
net/mac80211/trace.h

index 3a9ab3c..07c4dd7 100644 (file)
@@ -3842,6 +3842,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,
@@ -4155,6 +4157,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);
 };
 
 /**
index b4e39e3..022caf1 100644 (file)
@@ -1696,6 +1696,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 &&
index e3dfb93..bcdfd19 100644 (file)
@@ -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 */
index ac87030..8e0f79c 100644 (file)
@@ -3548,6 +3548,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);
 
        /*
index 50a0a83..8972390 100644 (file)
@@ -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