From: Felix Fietkau Date: Mon, 20 Mar 2023 17:51:06 +0000 (+0100) Subject: mediatek: add kernel code for supporting offloading wlan->eth and wlan->wlan flows X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=d0a06965e8ab0a92a4813fddbb8e045407897310;p=openwrt%2Fstaging%2Flinusw.git mediatek: add kernel code for supporting offloading wlan->eth and wlan->wlan flows Will be enabled by an upcoming mt76 update Signed-off-by: Felix Fietkau --- diff --git a/package/kernel/mac80211/patches/subsys/327-wifi-mac80211-add-support-for-letting-drivers-regist.patch b/package/kernel/mac80211/patches/subsys/327-wifi-mac80211-add-support-for-letting-drivers-regist.patch new file mode 100644 index 0000000000..f1807bdc8a --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/327-wifi-mac80211-add-support-for-letting-drivers-regist.patch @@ -0,0 +1,149 @@ +From: Felix Fietkau +Date: Mon, 20 Mar 2023 14:28:08 +0100 +Subject: [PATCH] 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 +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -4196,6 +4196,10 @@ struct ieee80211_prep_tx_info { + * Note that a sta can also be inserted or removed with valid links, + * i.e. passed to @sta_add/@sta_state with sta->valid_links not zero. + * In fact, cannot change from having valid_links and not having them. ++ * @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, +@@ -4551,6 +4555,11 @@ struct ieee80211_ops { + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + u16 old_links, u16 new_links); ++ int (*net_setup_tc)(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct net_device *dev, ++ enum tc_setup_type type, ++ void *type_data); + }; + + /** +--- a/net/mac80211/driver-ops.h ++++ b/net/mac80211/driver-ops.h +@@ -1470,6 +1470,23 @@ static inline int drv_net_fill_forward_p + 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, +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1935,7 +1935,8 @@ void ieee80211_color_change_finalize_wor + /* 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) +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -813,6 +813,21 @@ ieee80211_get_stats64(struct net_device + 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; ++ struct ieee80211_local *local; ++ ++ sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++ local = sdata->local; ++ ++ if (!local->ops->net_setup_tc) ++ return -EOPNOTSUPP; ++ ++ 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 +836,7 @@ static const struct net_device_ops ieee8 + .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 +945,7 @@ static const struct net_device_ops ieee8 + .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) +--- a/net/mac80211/trace.h ++++ b/net/mac80211/trace.h +@@ -2478,6 +2478,31 @@ DEFINE_EVENT(sta_event, drv_net_fill_for + 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, diff --git a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch index 80ffb493b8..d7ee33bebc 100644 --- a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch +++ b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch @@ -18,7 +18,7 @@ --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -1645,6 +1645,7 @@ enum ieee80211_smps_mode { +@@ -1671,6 +1671,7 @@ enum ieee80211_smps_mode { * * @power_level: requested transmit power (in dBm), backward compatibility * value only that is set to the minimum of all interfaces @@ -26,7 +26,7 @@ * * @chandef: the channel definition to tune to * @radar_enabled: whether radar detection is enabled -@@ -1665,6 +1666,7 @@ enum ieee80211_smps_mode { +@@ -1691,6 +1692,7 @@ enum ieee80211_smps_mode { struct ieee80211_conf { u32 flags; int power_level, dynamic_ps_timeout; @@ -57,7 +57,7 @@ __NL80211_ATTR_AFTER_LAST, --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2998,6 +2998,19 @@ static int ieee80211_get_tx_power(struct +@@ -3028,6 +3028,19 @@ static int ieee80211_get_tx_power(struct return 0; } @@ -77,7 +77,7 @@ static void ieee80211_rfkill_poll(struct wiphy *wiphy) { struct ieee80211_local *local = wiphy_priv(wiphy); -@@ -4881,6 +4894,7 @@ const struct cfg80211_ops mac80211_confi +@@ -4911,6 +4924,7 @@ const struct cfg80211_ops mac80211_confi .set_wiphy_params = ieee80211_set_wiphy_params, .set_tx_power = ieee80211_set_tx_power, .get_tx_power = ieee80211_get_tx_power, diff --git a/target/linux/generic/hack-5.10/100-update-mtk_wed_h.patch b/target/linux/generic/hack-5.10/100-update-mtk_wed_h.patch index 151f2e8054..5f05179a36 100644 --- a/target/linux/generic/hack-5.10/100-update-mtk_wed_h.patch +++ b/target/linux/generic/hack-5.10/100-update-mtk_wed_h.patch @@ -1,10 +1,11 @@ --- a/include/linux/soc/mediatek/mtk_wed.h +++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -5,21 +5,76 @@ +@@ -5,21 +5,77 @@ #include #include #include +#include ++#include #define MTK_WED_TX_QUEUES 2 +#define MTK_WED_RX_QUEUES 2 @@ -77,7 +78,7 @@ struct mtk_wed_device { #ifdef CONFIG_NET_MEDIATEK_SOC_WED const struct mtk_wed_ops *ops; -@@ -28,30 +83,76 @@ struct mtk_wed_device { +@@ -28,30 +84,76 @@ struct mtk_wed_device { bool init_done, running; int wdma_idx; int irq; @@ -156,7 +157,7 @@ } wlan; #endif }; -@@ -59,10 +160,16 @@ struct mtk_wed_device { +@@ -59,10 +161,16 @@ struct mtk_wed_device { struct mtk_wed_ops { int (*attach)(struct mtk_wed_device *dev); int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring, @@ -174,7 +175,16 @@ void (*stop)(struct mtk_wed_device *dev); void (*start)(struct mtk_wed_device *dev, u32 irq_mask); -@@ -97,12 +204,22 @@ mtk_wed_device_attach(struct mtk_wed_dev +@@ -73,6 +181,8 @@ struct mtk_wed_ops { + + u32 (*irq_get)(struct mtk_wed_device *dev, u32 mask); + void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask); ++ int (*setup_tc)(struct mtk_wed_device *wed, struct net_device *dev, ++ enum tc_setup_type type, void *type_data); + }; + + extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops; +@@ -97,12 +207,22 @@ mtk_wed_device_attach(struct mtk_wed_dev return ret; } @@ -199,7 +209,7 @@ #define mtk_wed_device_txfree_ring_setup(_dev, _regs) \ (_dev)->ops->txfree_ring_setup(_dev, _regs) #define mtk_wed_device_reg_read(_dev, _reg) \ -@@ -113,6 +230,14 @@ mtk_wed_device_attach(struct mtk_wed_dev +@@ -113,6 +233,16 @@ mtk_wed_device_attach(struct mtk_wed_dev (_dev)->ops->irq_get(_dev, _mask) #define mtk_wed_device_irq_set_mask(_dev, _mask) \ (_dev)->ops->irq_set_mask(_dev, _mask) @@ -211,10 +221,12 @@ + (_dev)->ops->msg_update(_dev, _id, _msg, _len) +#define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev) +#define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev) ++#define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) \ ++ (_dev)->ops->setup_tc(_dev, _netdev, _type, _type_data) #else static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) { -@@ -120,12 +245,17 @@ static inline bool mtk_wed_device_active +@@ -120,12 +250,18 @@ static inline bool mtk_wed_device_active } #define mtk_wed_device_detach(_dev) do {} while (0) #define mtk_wed_device_start(_dev, _mask) do {} while (0) @@ -230,6 +242,7 @@ +#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV +#define mtk_wed_device_stop(_dev) do {} while (0) +#define mtk_wed_device_dma_reset(_dev) do {} while (0) ++#define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) -EOPNOTSUPP #endif #endif diff --git a/target/linux/generic/pending-5.15/736-01-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch b/target/linux/generic/pending-5.15/736-01-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch new file mode 100644 index 0000000000..0496752f78 --- /dev/null +++ b/target/linux/generic/pending-5.15/736-01-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch @@ -0,0 +1,266 @@ +From: Felix Fietkau +Date: Mon, 20 Mar 2023 11:44:30 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: add code for offloading flows + from wlan devices + +WED version 2 (on MT7986 and later) can offload flows originating from wireless +devices. In order to make that work, ndo_setup_tc needs to be implemented on +the netdevs. This adds the required code to offload flows coming in from WED, +while keeping track of the incoming wed index used for selecting the correct +PPE device. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1319,6 +1319,9 @@ int mtk_gmac_rgmii_path_setup(struct mtk + int mtk_eth_offload_init(struct mtk_eth *eth); + int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type, + void *type_data); ++int mtk_flow_offload_cmd(struct mtk_eth *eth, struct flow_cls_offload *cls, ++ int ppe_index); ++void mtk_flow_offload_cleanup(struct mtk_eth *eth, struct list_head *list); + void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev); + + +--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +@@ -235,7 +235,8 @@ out: + } + + static int +-mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f) ++mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f, ++ int ppe_index) + { + struct flow_rule *rule = flow_cls_offload_flow_rule(f); + struct flow_action_entry *act; +@@ -452,6 +453,7 @@ mtk_flow_offload_replace(struct mtk_eth + entry->cookie = f->cookie; + memcpy(&entry->data, &foe, sizeof(entry->data)); + entry->wed_index = wed_index; ++ entry->ppe_index = ppe_index; + + err = mtk_foe_entry_commit(eth->ppe[entry->ppe_index], entry); + if (err < 0) +@@ -520,25 +522,15 @@ mtk_flow_offload_stats(struct mtk_eth *e + + static DEFINE_MUTEX(mtk_flow_offload_mutex); + +-static int +-mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) ++int mtk_flow_offload_cmd(struct mtk_eth *eth, struct flow_cls_offload *cls, ++ int ppe_index) + { +- struct flow_cls_offload *cls = type_data; +- struct net_device *dev = cb_priv; +- struct mtk_mac *mac = netdev_priv(dev); +- struct mtk_eth *eth = mac->hw; + int err; + +- if (!tc_can_offload(dev)) +- return -EOPNOTSUPP; +- +- if (type != TC_SETUP_CLSFLOWER) +- return -EOPNOTSUPP; +- + mutex_lock(&mtk_flow_offload_mutex); + switch (cls->command) { + case FLOW_CLS_REPLACE: +- err = mtk_flow_offload_replace(eth, cls); ++ err = mtk_flow_offload_replace(eth, cls, ppe_index); + break; + case FLOW_CLS_DESTROY: + err = mtk_flow_offload_destroy(eth, cls); +@@ -556,6 +548,23 @@ mtk_eth_setup_tc_block_cb(enum tc_setup_ + } + + static int ++mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) ++{ ++ struct flow_cls_offload *cls = type_data; ++ struct net_device *dev = cb_priv; ++ struct mtk_mac *mac = netdev_priv(dev); ++ struct mtk_eth *eth = mac->hw; ++ ++ if (!tc_can_offload(dev)) ++ return -EOPNOTSUPP; ++ ++ if (type != TC_SETUP_CLSFLOWER) ++ return -EOPNOTSUPP; ++ ++ return mtk_flow_offload_cmd(eth, cls, 0); ++} ++ ++static int + mtk_eth_setup_tc_block(struct net_device *dev, struct flow_block_offload *f) + { + struct mtk_mac *mac = netdev_priv(dev); +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -13,6 +13,8 @@ + #include + #include + #include ++#include ++#include + #include "mtk_eth_soc.h" + #include "mtk_wed_regs.h" + #include "mtk_wed.h" +@@ -41,6 +43,11 @@ + static struct mtk_wed_hw *hw_list[2]; + static DEFINE_MUTEX(hw_lock); + ++struct mtk_wed_flow_block_priv { ++ struct mtk_wed_hw *hw; ++ struct net_device *dev; ++}; ++ + static void + wed_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val) + { +@@ -1752,6 +1759,99 @@ out: + mutex_unlock(&hw_lock); + } + ++static int ++mtk_wed_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) ++{ ++ struct mtk_wed_flow_block_priv *priv = cb_priv; ++ struct flow_cls_offload *cls = type_data; ++ struct mtk_wed_hw *hw = priv->hw; ++ ++ if (!tc_can_offload(priv->dev)) ++ return -EOPNOTSUPP; ++ ++ if (type != TC_SETUP_CLSFLOWER) ++ return -EOPNOTSUPP; ++ ++ return mtk_flow_offload_cmd(hw->eth, cls, hw->index); ++} ++ ++static int ++mtk_wed_setup_tc_block(struct mtk_wed_hw *hw, struct net_device *dev, ++ struct flow_block_offload *f) ++{ ++ struct mtk_wed_flow_block_priv *priv; ++ static LIST_HEAD(block_cb_list); ++ struct flow_block_cb *block_cb; ++ struct mtk_eth *eth = hw->eth; ++ flow_setup_cb_t *cb; ++ ++ if (!eth->soc->offload_version) ++ return -EOPNOTSUPP; ++ ++ if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) ++ return -EOPNOTSUPP; ++ ++ cb = mtk_wed_setup_tc_block_cb; ++ f->driver_block_list = &block_cb_list; ++ ++ switch (f->command) { ++ case FLOW_BLOCK_BIND: ++ block_cb = flow_block_cb_lookup(f->block, cb, dev); ++ if (block_cb) { ++ flow_block_cb_incref(block_cb); ++ return 0; ++ } ++ ++ priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ priv->hw = hw; ++ priv->dev = dev; ++ block_cb = flow_block_cb_alloc(cb, dev, priv, NULL); ++ if (IS_ERR(block_cb)) { ++ kfree(priv); ++ return PTR_ERR(block_cb); ++ } ++ ++ flow_block_cb_incref(block_cb); ++ flow_block_cb_add(block_cb, f); ++ list_add_tail(&block_cb->driver_list, &block_cb_list); ++ return 0; ++ case FLOW_BLOCK_UNBIND: ++ block_cb = flow_block_cb_lookup(f->block, cb, dev); ++ if (!block_cb) ++ return -ENOENT; ++ ++ if (!flow_block_cb_decref(block_cb)) { ++ flow_block_cb_remove(block_cb, f); ++ list_del(&block_cb->driver_list); ++ kfree(block_cb->cb_priv); ++ } ++ return 0; ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++ ++static int ++mtk_wed_setup_tc(struct mtk_wed_device *wed, struct net_device *dev, ++ enum tc_setup_type type, void *type_data) ++{ ++ struct mtk_wed_hw *hw = wed->hw; ++ ++ if (hw->version < 2) ++ return -EOPNOTSUPP; ++ ++ switch (type) { ++ case TC_SETUP_BLOCK: ++ case TC_SETUP_FT: ++ return mtk_wed_setup_tc_block(hw, dev, type_data); ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++ + void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, + void __iomem *wdma, phys_addr_t wdma_phy, + int index) +@@ -1771,6 +1871,7 @@ void mtk_wed_add_hw(struct device_node * + .irq_set_mask = mtk_wed_irq_set_mask, + .detach = mtk_wed_detach, + .ppe_check = mtk_wed_ppe_check, ++ .setup_tc = mtk_wed_setup_tc, + }; + struct device_node *eth_np = eth->dev->of_node; + struct platform_device *pdev; +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + + #define MTK_WED_TX_QUEUES 2 + #define MTK_WED_RX_QUEUES 2 +@@ -180,6 +181,8 @@ struct mtk_wed_ops { + + u32 (*irq_get)(struct mtk_wed_device *dev, u32 mask); + void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask); ++ int (*setup_tc)(struct mtk_wed_device *wed, struct net_device *dev, ++ enum tc_setup_type type, void *type_data); + }; + + extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops; +@@ -238,6 +241,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic + (_dev)->ops->msg_update(_dev, _id, _msg, _len) + #define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev) + #define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev) ++#define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) \ ++ (_dev)->ops->setup_tc(_dev, _netdev, _type, _type_data) + #else + static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) + { +@@ -256,6 +261,7 @@ static inline bool mtk_wed_device_active + #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV + #define mtk_wed_device_stop(_dev) do {} while (0) + #define mtk_wed_device_dma_reset(_dev) do {} while (0) ++#define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) -EOPNOTSUPP + #endif + + #endif diff --git a/target/linux/generic/pending-5.15/736-02-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch b/target/linux/generic/pending-5.15/736-02-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch new file mode 100644 index 0000000000..6e17e4dc52 --- /dev/null +++ b/target/linux/generic/pending-5.15/736-02-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch @@ -0,0 +1,37 @@ +From: Felix Fietkau +Date: Mon, 20 Mar 2023 15:37:55 +0100 +Subject: [PATCH] net: ethernet: mediatek: mtk_ppe: prefer newly added l2 + flows over existing ones + +When a device is roaming between interfaces and a new flow entry is created, +we should assume that its output device is more up to date than whatever +entry existed already. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -639,10 +639,20 @@ void mtk_foe_entry_clear(struct mtk_ppe + static int + mtk_foe_entry_commit_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) + { ++ struct mtk_flow_entry *prev; ++ + entry->type = MTK_FLOW_TYPE_L2; + +- return rhashtable_insert_fast(&ppe->l2_flows, &entry->l2_node, +- mtk_flow_l2_ht_params); ++ prev = rhashtable_lookup_get_insert_fast(&ppe->l2_flows, &entry->l2_node, ++ mtk_flow_l2_ht_params); ++ if (likely(!prev)) ++ return 0; ++ ++ if (IS_ERR(prev)) ++ return PTR_ERR(prev); ++ ++ return rhashtable_replace_fast(&ppe->l2_flows, &prev->l2_node, ++ &entry->l2_node, mtk_flow_l2_ht_params); + } + + int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) diff --git a/target/linux/mediatek/patches-5.15/944-net-ethernet-mtk_wed-move-dlm-a-dedicated-dts-node.patch b/target/linux/mediatek/patches-5.15/944-net-ethernet-mtk_wed-move-dlm-a-dedicated-dts-node.patch index fb3940f544..a455005504 100644 --- a/target/linux/mediatek/patches-5.15/944-net-ethernet-mtk_wed-move-dlm-a-dedicated-dts-node.patch +++ b/target/linux/mediatek/patches-5.15/944-net-ethernet-mtk_wed-move-dlm-a-dedicated-dts-node.patch @@ -22,7 +22,7 @@ Signed-off-by: Lorenzo Bianconi --- a/drivers/net/ethernet/mediatek/mtk_wed.c +++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -806,6 +806,24 @@ mtk_wed_rro_alloc(struct mtk_wed_device +@@ -813,6 +813,24 @@ mtk_wed_rro_alloc(struct mtk_wed_device struct device_node *np; int index; @@ -47,7 +47,7 @@ Signed-off-by: Lorenzo Bianconi index = of_property_match_string(dev->hw->node, "memory-region-names", "wo-dlm"); if (index < 0) -@@ -822,6 +840,7 @@ mtk_wed_rro_alloc(struct mtk_wed_device +@@ -829,6 +847,7 @@ mtk_wed_rro_alloc(struct mtk_wed_device return -ENODEV; dev->rro.miod_phys = rmem->base;