wifi: mac80211: add support for letting drivers register tc offload support

On newer MediaTek SoCs (e.g. MT7986), WLAN->WLAN or WLAN->Ethernet flows can
be offloaded by the SoC. In order to support that, the .ndo_setup_tc op is
needed.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://lore.kernel.org/r/20230321091248.30947-1-nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Felix Fietkau 2023-03-21 10:12:48 +01:00 committed by Johannes Berg
parent 9457077df4
commit 61587f1556
5 changed files with 64 additions and 1 deletions

View File

@ -4227,6 +4227,10 @@ struct ieee80211_prep_tx_info {
* @set_hw_timestamp: Enable/disable HW timestamping of TM/FTM frames. This is
* not restored at HW reset by mac80211 so drivers need to take care of
* that.
* @net_setup_tc: Called from .ndo_setup_tc in order to prepare hardware
* flow offloading for flows originating from the vif.
* Note that the driver must not assume that the vif driver_data is valid
* at this point, since the callback can be called during netdev teardown.
*/
struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw,
@ -4593,6 +4597,11 @@ struct ieee80211_ops {
int (*set_hw_timestamp)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_set_hw_timestamp *hwts);
int (*net_setup_tc)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct net_device *dev,
enum tc_setup_type type,
void *type_data);
};
/**

View File

@ -1502,6 +1502,23 @@ static inline int drv_net_fill_forward_path(struct ieee80211_local *local,
return ret;
}
static inline int drv_net_setup_tc(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
struct net_device *dev,
enum tc_setup_type type, void *type_data)
{
int ret = -EOPNOTSUPP;
sdata = get_bss_sdata(sdata);
trace_drv_net_setup_tc(local, sdata, type);
if (local->ops->net_setup_tc)
ret = local->ops->net_setup_tc(&local->hw, &sdata->vif, dev,
type, type_data);
trace_drv_return_int(local, ret);
return ret;
}
int drv_change_vif_links(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
u16 old_links, u16 new_links,

View File

@ -1939,7 +1939,8 @@ void ieee80211_color_collision_detection_work(struct work_struct *work);
/* interface handling */
#define MAC80211_SUPPORTED_FEATURES_TX (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
NETIF_F_HW_CSUM | NETIF_F_SG | \
NETIF_F_HIGHDMA | NETIF_F_GSO_SOFTWARE)
NETIF_F_HIGHDMA | NETIF_F_GSO_SOFTWARE | \
NETIF_F_HW_TC)
#define MAC80211_SUPPORTED_FEATURES_RX (NETIF_F_RXCSUM)
#define MAC80211_SUPPORTED_FEATURES (MAC80211_SUPPORTED_FEATURES_TX | \
MAC80211_SUPPORTED_FEATURES_RX)

View File

@ -813,6 +813,15 @@ ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
dev_fetch_sw_netstats(stats, dev->tstats);
}
static int ieee80211_netdev_setup_tc(struct net_device *dev,
enum tc_setup_type type, void *type_data)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local;
return drv_net_setup_tc(local, sdata, dev, type, type_data);
}
static const struct net_device_ops ieee80211_dataif_ops = {
.ndo_open = ieee80211_open,
.ndo_stop = ieee80211_stop,
@ -821,6 +830,7 @@ static const struct net_device_ops ieee80211_dataif_ops = {
.ndo_set_rx_mode = ieee80211_set_multicast_list,
.ndo_set_mac_address = ieee80211_change_mac,
.ndo_get_stats64 = ieee80211_get_stats64,
.ndo_setup_tc = ieee80211_netdev_setup_tc,
};
static u16 ieee80211_monitor_select_queue(struct net_device *dev,
@ -929,6 +939,7 @@ static const struct net_device_ops ieee80211_dataif_8023_ops = {
.ndo_set_mac_address = ieee80211_change_mac,
.ndo_get_stats64 = ieee80211_get_stats64,
.ndo_fill_forward_path = ieee80211_netdev_fill_forward_path,
.ndo_setup_tc = ieee80211_netdev_setup_tc,
};
static bool ieee80211_iftype_supports_hdr_offload(enum nl80211_iftype iftype)

View File

@ -2478,6 +2478,31 @@ DEFINE_EVENT(sta_event, drv_net_fill_forward_path,
TP_ARGS(local, sdata, sta)
);
TRACE_EVENT(drv_net_setup_tc,
TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
u8 type),
TP_ARGS(local, sdata, type),
TP_STRUCT__entry(
LOCAL_ENTRY
VIF_ENTRY
__field(u8, type)
),
TP_fast_assign(
LOCAL_ASSIGN;
VIF_ASSIGN;
__entry->type = type;
),
TP_printk(
LOCAL_PR_FMT VIF_PR_FMT " type:%d\n",
LOCAL_PR_ARG, VIF_PR_ARG, __entry->type
)
);
TRACE_EVENT(drv_change_vif_links,
TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,