]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blobdiff - drivers/net/ethernet/mediatek/mtk_eth_soc.c
net: ethernet: mtk_eth_soc: fix build_skb cleanup
[mirror_ubuntu-jammy-kernel.git] / drivers / net / ethernet / mediatek / mtk_eth_soc.c
index 01d3ee4b58292cfcfc210bccf6e3ba52bc5e0063..07daa5de8bec14f4a0ec4421175d0587ab4544f3 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/interrupt.h>
 #include <linux/pinctrl/devinfo.h>
 #include <linux/phylink.h>
+#include <net/dsa.h>
 
 #include "mtk_eth_soc.h"
 
@@ -1264,13 +1265,12 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
                        break;
 
                /* find out which mac the packet come from. values start at 1 */
-               if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) {
+               if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) ||
+                   (trxd.rxd4 & RX_DMA_SPECIAL_TAG))
                        mac = 0;
-               } else {
-                       mac = (trxd.rxd4 >> RX_DMA_FPORT_SHIFT) &
-                               RX_DMA_FPORT_MASK;
-                       mac--;
-               }
+               else
+                       mac = ((trxd.rxd4 >> RX_DMA_FPORT_SHIFT) &
+                              RX_DMA_FPORT_MASK) - 1;
 
                if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
                             !eth->netdev[mac]))
@@ -1298,17 +1298,18 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
                        goto release_desc;
                }
 
+               dma_unmap_single(eth->dev, trxd.rxd1,
+                                ring->buf_size, DMA_FROM_DEVICE);
+
                /* receive data */
                skb = build_skb(data, ring->frag_size);
                if (unlikely(!skb)) {
-                       skb_free_frag(new_data);
+                       skb_free_frag(data);
                        netdev->stats.rx_dropped++;
-                       goto release_desc;
+                       goto skip_rx;
                }
                skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN);
 
-               dma_unmap_single(eth->dev, trxd.rxd1,
-                                ring->buf_size, DMA_FROM_DEVICE);
                pktlen = RX_DMA_GET_PLEN0(trxd.rxd2);
                skb->dev = netdev;
                skb_put(skb, pktlen);
@@ -1319,12 +1320,13 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
                skb->protocol = eth_type_trans(skb, netdev);
 
                if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX &&
-                   RX_DMA_VID(trxd.rxd3))
+                   (trxd.rxd2 & RX_DMA_VTAG))
                        __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
                                               RX_DMA_VID(trxd.rxd3));
                skb_record_rx_queue(skb, 0);
                napi_gro_receive(napi, skb);
 
+skip_rx:
                ring->data[idx] = new_data;
                rxd->rxd1 = (unsigned int)dma_addr;
 
@@ -2233,6 +2235,9 @@ static void mtk_gdm_config(struct mtk_eth *eth, u32 config)
 
                val |= config;
 
+               if (!i && eth->netdev[0] && netdev_uses_dsa(eth->netdev[0]))
+                       val |= MTK_GDMA_SPECIAL_TAG;
+
                mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
        }
        /* Reset and enable PSE */
@@ -2255,12 +2260,17 @@ static int mtk_open(struct net_device *dev)
 
        /* we run 2 netdevs on the same dma ring so we only bring it up once */
        if (!refcount_read(&eth->dma_refcnt)) {
-               int err = mtk_start_dma(eth);
+               u32 gdm_config = MTK_GDMA_TO_PDMA;
+               int err;
 
+               err = mtk_start_dma(eth);
                if (err)
                        return err;
 
-               mtk_gdm_config(eth, MTK_GDMA_TO_PDMA);
+               if (eth->soc->offload_version && mtk_ppe_start(&eth->ppe) == 0)
+                       gdm_config = MTK_GDMA_TO_PPE;
+
+               mtk_gdm_config(eth, gdm_config);
 
                napi_enable(&eth->tx_napi);
                napi_enable(&eth->rx_napi);
@@ -2327,6 +2337,9 @@ static int mtk_stop(struct net_device *dev)
 
        mtk_dma_free(eth);
 
+       if (eth->soc->offload_version)
+               mtk_ppe_stop(&eth->ppe);
+
        return 0;
 }
 
@@ -2473,14 +2486,11 @@ static int __init mtk_init(struct net_device *dev)
 {
        struct mtk_mac *mac = netdev_priv(dev);
        struct mtk_eth *eth = mac->hw;
-       const char *mac_addr;
-
-       mac_addr = of_get_mac_address(mac->of_node);
-       if (!IS_ERR(mac_addr))
-               ether_addr_copy(dev->dev_addr, mac_addr);
+       int ret;
 
-       /* If the mac address is invalid, use random mac address  */
-       if (!is_valid_ether_addr(dev->dev_addr)) {
+       ret = of_get_mac_address(mac->of_node, dev->dev_addr);
+       if (ret) {
+               /* If the mac address is invalid, use random mac address */
                eth_hw_addr_random(dev);
                dev_err(eth->dev, "generated random MAC address %pM\n",
                        dev->dev_addr);
@@ -2832,6 +2842,7 @@ static const struct net_device_ops mtk_netdev_ops = {
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = mtk_poll_controller,
 #endif
+       .ndo_setup_tc           = mtk_eth_setup_tc,
 };
 
 static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
@@ -3088,6 +3099,17 @@ static int mtk_probe(struct platform_device *pdev)
                        goto err_free_dev;
        }
 
+       if (eth->soc->offload_version) {
+               err = mtk_ppe_init(&eth->ppe, eth->dev,
+                                  eth->base + MTK_ETH_PPE_BASE, 2);
+               if (err)
+                       goto err_free_dev;
+
+               err = mtk_eth_offload_init(eth);
+               if (err)
+                       goto err_free_dev;
+       }
+
        for (i = 0; i < MTK_MAX_DEVS; i++) {
                if (!eth->netdev[i])
                        continue;
@@ -3162,6 +3184,7 @@ static const struct mtk_soc_data mt7621_data = {
        .hw_features = MTK_HW_FEATURES,
        .required_clks = MT7621_CLKS_BITMAP,
        .required_pctl = false,
+       .offload_version = 2,
 };
 
 static const struct mtk_soc_data mt7622_data = {
@@ -3170,6 +3193,7 @@ static const struct mtk_soc_data mt7622_data = {
        .hw_features = MTK_HW_FEATURES,
        .required_clks = MT7622_CLKS_BITMAP,
        .required_pctl = false,
+       .offload_version = 2,
 };
 
 static const struct mtk_soc_data mt7623_data = {
@@ -3177,6 +3201,7 @@ static const struct mtk_soc_data mt7623_data = {
        .hw_features = MTK_HW_FEATURES,
        .required_clks = MT7623_CLKS_BITMAP,
        .required_pctl = true,
+       .offload_version = 2,
 };
 
 static const struct mtk_soc_data mt7629_data = {