diff options
Diffstat (limited to 'target/linux/ipq40xx/patches-6.1/702-net-ipqess-Add-out-of-band-DSA-tagging-support.patch')
-rw-r--r-- | target/linux/ipq40xx/patches-6.1/702-net-ipqess-Add-out-of-band-DSA-tagging-support.patch | 173 |
1 files changed, 0 insertions, 173 deletions
diff --git a/target/linux/ipq40xx/patches-6.1/702-net-ipqess-Add-out-of-band-DSA-tagging-support.patch b/target/linux/ipq40xx/patches-6.1/702-net-ipqess-Add-out-of-band-DSA-tagging-support.patch deleted file mode 100644 index ac0718ba2c..0000000000 --- a/target/linux/ipq40xx/patches-6.1/702-net-ipqess-Add-out-of-band-DSA-tagging-support.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 4975e2b3f1d37bba04f262784cef0d5b7e0a30a4 Mon Sep 17 00:00:00 2001 -From: Maxime Chevallier <maxime.chevallier@bootlin.com> -Date: Fri, 4 Nov 2022 18:41:50 +0100 -Subject: [PATCH] net: ipqess: Add out-of-band DSA tagging support - -On the IPQ4019, there's an 5 ports switch connected to the CPU through -the IPQESS Ethernet controller. The way the DSA tag is sent-out to that -switch is through the DMA descriptor, due to how tightly it is -integrated with the switch. - -We use the out-of-band tagging protocol by getting the source -port from the descriptor, push it into the skb extensions, and have the -tagger pull it to infer the destination netdev. The reverse process is -done on the TX side, where the driver pulls the tag from the skb and -builds the descriptor accordingly. - -Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com> ---- - drivers/net/ethernet/qualcomm/Kconfig | 1 + - drivers/net/ethernet/qualcomm/ipqess/ipqess.c | 64 ++++++++++++++++++- - drivers/net/ethernet/qualcomm/ipqess/ipqess.h | 4 ++ - 3 files changed, 68 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/qualcomm/Kconfig -+++ b/drivers/net/ethernet/qualcomm/Kconfig -@@ -64,6 +64,7 @@ config QCOM_IPQ4019_ESS_EDMA - tristate "Qualcomm Atheros IPQ4019 ESS EDMA support" - depends on (OF && ARCH_QCOM) || COMPILE_TEST - select PHYLINK -+ select NET_DSA_TAG_OOB - help - This driver supports the Qualcomm Atheros IPQ40xx built-in - ESS EDMA ethernet controller. ---- a/drivers/net/ethernet/qualcomm/ipqess/ipqess.c -+++ b/drivers/net/ethernet/qualcomm/ipqess/ipqess.c -@@ -9,6 +9,7 @@ - - #include <linux/bitfield.h> - #include <linux/clk.h> -+#include <linux/dsa/oob.h> - #include <linux/if_vlan.h> - #include <linux/interrupt.h> - #include <linux/module.h> -@@ -22,6 +23,7 @@ - #include <linux/skbuff.h> - #include <linux/vmalloc.h> - #include <net/checksum.h> -+#include <net/dsa.h> - #include <net/ip6_checksum.h> - - #include "ipqess.h" -@@ -327,6 +329,7 @@ static int ipqess_rx_poll(struct ipqess_ - tail &= IPQESS_RFD_CONS_IDX_MASK; - - while (done < budget) { -+ struct dsa_oob_tag_info *tag_info; - struct ipqess_rx_desc *rd; - struct sk_buff *skb; - -@@ -406,6 +409,12 @@ static int ipqess_rx_poll(struct ipqess_ - __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021AD), - le16_to_cpu(rd->rrd4)); - -+ if (likely(rx_ring->ess->dsa_ports)) { -+ tag_info = skb_ext_add(skb, SKB_EXT_DSA_OOB); -+ tag_info->port = FIELD_GET(IPQESS_RRD_PORT_ID_MASK, -+ le16_to_cpu(rd->rrd1)); -+ } -+ - napi_gro_receive(&rx_ring->napi_rx, skb); - - rx_ring->ess->stats.rx_packets++; -@@ -706,6 +715,23 @@ static void ipqess_rollback_tx(struct ip - tx_ring->head = start_index; - } - -+static void ipqess_process_dsa_tag_sh(struct ipqess *ess, struct sk_buff *skb, -+ u32 *word3) -+{ -+ struct dsa_oob_tag_info *tag_info; -+ -+ if (unlikely(!ess->dsa_ports)) -+ return; -+ -+ tag_info = skb_ext_find(skb, SKB_EXT_DSA_OOB); -+ if (!tag_info) -+ return; -+ -+ *word3 |= tag_info->port << IPQESS_TPD_PORT_BITMAP_SHIFT; -+ *word3 |= BIT(IPQESS_TPD_FROM_CPU_SHIFT); -+ *word3 |= 0x3e << IPQESS_TPD_PORT_BITMAP_SHIFT; -+} -+ - static int ipqess_tx_map_and_fill(struct ipqess_tx_ring *tx_ring, - struct sk_buff *skb) - { -@@ -716,6 +742,8 @@ static int ipqess_tx_map_and_fill(struct - u16 len; - int i; - -+ ipqess_process_dsa_tag_sh(tx_ring->ess, skb, &word3); -+ - if (skb_is_gso(skb)) { - if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) { - lso_word1 |= IPQESS_TPD_IPV4_EN; -@@ -917,6 +945,33 @@ static const struct net_device_ops ipqes - .ndo_tx_timeout = ipqess_tx_timeout, - }; - -+static int ipqess_netdevice_event(struct notifier_block *nb, -+ unsigned long event, void *ptr) -+{ -+ struct ipqess *ess = container_of(nb, struct ipqess, netdev_notifier); -+ struct net_device *dev = netdev_notifier_info_to_dev(ptr); -+ struct netdev_notifier_changeupper_info *info; -+ -+ if (dev != ess->netdev) -+ return NOTIFY_DONE; -+ -+ switch (event) { -+ case NETDEV_CHANGEUPPER: -+ info = ptr; -+ -+ if (!dsa_slave_dev_check(info->upper_dev)) -+ return NOTIFY_DONE; -+ -+ if (info->linking) -+ ess->dsa_ports++; -+ else -+ ess->dsa_ports--; -+ -+ return NOTIFY_DONE; -+ } -+ return NOTIFY_OK; -+} -+ - static void ipqess_hw_stop(struct ipqess *ess) - { - int i; -@@ -1184,12 +1239,19 @@ static int ipqess_axi_probe(struct platf - netif_napi_add(netdev, &ess->rx_ring[i].napi_rx, ipqess_rx_napi); - } - -- err = register_netdev(netdev); -+ ess->netdev_notifier.notifier_call = ipqess_netdevice_event; -+ err = register_netdevice_notifier(&ess->netdev_notifier); - if (err) - goto err_hw_stop; - -+ err = register_netdev(netdev); -+ if (err) -+ goto err_notifier_unregister; -+ - return 0; - -+err_notifier_unregister: -+ unregister_netdevice_notifier(&ess->netdev_notifier); - err_hw_stop: - ipqess_hw_stop(ess); - ---- a/drivers/net/ethernet/qualcomm/ipqess/ipqess.h -+++ b/drivers/net/ethernet/qualcomm/ipqess/ipqess.h -@@ -171,6 +171,10 @@ struct ipqess { - struct platform_device *pdev; - struct phylink *phylink; - struct phylink_config phylink_config; -+ -+ struct notifier_block netdev_notifier; -+ int dsa_ports; -+ - struct ipqess_tx_ring tx_ring[IPQESS_NETDEV_QUEUES]; - - struct ipqess_statistics ipqess_stats; |