ba848583ce3b1ceb26a30ab9ef6932481555f903
[librecmc/librecmc.git] /
1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Mon, 20 Mar 2023 14:28:08 +0100
3 Subject: [PATCH] wifi: mac80211: add support for letting drivers register tc
4  offload support
5
6 On newer MediaTek SoCs (e.g. MT7986), WLAN->WLAN or WLAN->Ethernet flows can
7 be offloaded by the SoC. In order to support that, the .ndo_setup_tc op is
8 needed.
9
10 Signed-off-by: Felix Fietkau <nbd@nbd.name>
11 ---
12
13 --- a/include/net/mac80211.h
14 +++ b/include/net/mac80211.h
15 @@ -4201,6 +4201,10 @@ struct ieee80211_prep_tx_info {
16   *     Note that a sta can also be inserted or removed with valid links,
17   *     i.e. passed to @sta_add/@sta_state with sta->valid_links not zero.
18   *     In fact, cannot change from having valid_links and not having them.
19 + * @net_setup_tc: Called from .ndo_setup_tc in order to prepare hardware
20 + *     flow offloading for flows originating from the vif.
21 + *     Note that the driver must not assume that the vif driver_data is valid
22 + *     at this point, since the callback can be called during netdev teardown.
23   */
24  struct ieee80211_ops {
25         void (*tx)(struct ieee80211_hw *hw,
26 @@ -4556,6 +4560,11 @@ struct ieee80211_ops {
27                                 struct ieee80211_vif *vif,
28                                 struct ieee80211_sta *sta,
29                                 u16 old_links, u16 new_links);
30 +       int (*net_setup_tc)(struct ieee80211_hw *hw,
31 +                           struct ieee80211_vif *vif,
32 +                           struct net_device *dev,
33 +                           enum tc_setup_type type,
34 +                           void *type_data);
35  };
36  
37  /**
38 --- a/net/mac80211/driver-ops.h
39 +++ b/net/mac80211/driver-ops.h
40 @@ -1470,6 +1470,23 @@ static inline int drv_net_fill_forward_p
41         return ret;
42  }
43  
44 +static inline int drv_net_setup_tc(struct ieee80211_local *local,
45 +                                  struct ieee80211_sub_if_data *sdata,
46 +                                  struct net_device *dev,
47 +                                  enum tc_setup_type type, void *type_data)
48 +{
49 +       int ret = -EOPNOTSUPP;
50 +
51 +       sdata = get_bss_sdata(sdata);
52 +       trace_drv_net_setup_tc(local, sdata, type);
53 +       if (local->ops->net_setup_tc)
54 +               ret = local->ops->net_setup_tc(&local->hw, &sdata->vif, dev,
55 +                                              type, type_data);
56 +       trace_drv_return_int(local, ret);
57 +
58 +       return ret;
59 +}
60 +
61  int drv_change_vif_links(struct ieee80211_local *local,
62                          struct ieee80211_sub_if_data *sdata,
63                          u16 old_links, u16 new_links,
64 --- a/net/mac80211/ieee80211_i.h
65 +++ b/net/mac80211/ieee80211_i.h
66 @@ -1944,7 +1944,8 @@ void ieee80211_color_collision_detection
67  /* interface handling */
68  #define MAC80211_SUPPORTED_FEATURES_TX (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
69                                          NETIF_F_HW_CSUM | NETIF_F_SG | \
70 -                                        NETIF_F_HIGHDMA | NETIF_F_GSO_SOFTWARE)
71 +                                        NETIF_F_HIGHDMA | NETIF_F_GSO_SOFTWARE | \
72 +                                        NETIF_F_HW_TC)
73  #define MAC80211_SUPPORTED_FEATURES_RX (NETIF_F_RXCSUM)
74  #define MAC80211_SUPPORTED_FEATURES    (MAC80211_SUPPORTED_FEATURES_TX | \
75                                          MAC80211_SUPPORTED_FEATURES_RX)
76 --- a/net/mac80211/iface.c
77 +++ b/net/mac80211/iface.c
78 @@ -813,6 +813,21 @@ ieee80211_get_stats64(struct net_device
79         dev_fetch_sw_netstats(stats, dev->tstats);
80  }
81  
82 +static int ieee80211_netdev_setup_tc(struct net_device *dev,
83 +                                    enum tc_setup_type type, void *type_data)
84 +{
85 +       struct ieee80211_sub_if_data *sdata;
86 +       struct ieee80211_local *local;
87 +
88 +       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
89 +       local = sdata->local;
90 +
91 +       if (!local->ops->net_setup_tc)
92 +               return -EOPNOTSUPP;
93 +
94 +       return drv_net_setup_tc(local, sdata, dev, type, type_data);
95 +}
96 +
97  static const struct net_device_ops ieee80211_dataif_ops = {
98         .ndo_open               = ieee80211_open,
99         .ndo_stop               = ieee80211_stop,
100 @@ -821,6 +836,7 @@ static const struct net_device_ops ieee8
101         .ndo_set_rx_mode        = ieee80211_set_multicast_list,
102         .ndo_set_mac_address    = ieee80211_change_mac,
103         .ndo_get_stats64        = ieee80211_get_stats64,
104 +       .ndo_setup_tc           = ieee80211_netdev_setup_tc,
105  };
106  
107  #if LINUX_VERSION_IS_GEQ(5,2,0)
108 @@ -945,6 +961,7 @@ static const struct net_device_ops ieee8
109  #if LINUX_VERSION_IS_GEQ(5,13,0)
110         .ndo_fill_forward_path  = ieee80211_netdev_fill_forward_path,
111  #endif
112 +       .ndo_setup_tc           = ieee80211_netdev_setup_tc,
113  };
114  
115  static bool ieee80211_iftype_supports_hdr_offload(enum nl80211_iftype iftype)
116 --- a/net/mac80211/trace.h
117 +++ b/net/mac80211/trace.h
118 @@ -2478,6 +2478,31 @@ DEFINE_EVENT(sta_event, drv_net_fill_for
119         TP_ARGS(local, sdata, sta)
120  );
121  
122 +TRACE_EVENT(drv_net_setup_tc,
123 +       TP_PROTO(struct ieee80211_local *local,
124 +                struct ieee80211_sub_if_data *sdata,
125 +                u8 type),
126 +
127 +       TP_ARGS(local, sdata, type),
128 +
129 +       TP_STRUCT__entry(
130 +               LOCAL_ENTRY
131 +               VIF_ENTRY
132 +               __field(u8, type)
133 +       ),
134 +
135 +       TP_fast_assign(
136 +               LOCAL_ASSIGN;
137 +               VIF_ASSIGN;
138 +               __entry->type = type;
139 +       ),
140 +
141 +       TP_printk(
142 +               LOCAL_PR_FMT VIF_PR_FMT " type:%d\n",
143 +               LOCAL_PR_ARG, VIF_PR_ARG, __entry->type
144 +       )
145 +);
146 +
147  TRACE_EVENT(drv_change_vif_links,
148         TP_PROTO(struct ieee80211_local *local,
149                  struct ieee80211_sub_if_data *sdata,