diff options
Diffstat (limited to 'target/linux/mediatek/patches-4.9/0059-eth-fixes.patch')
-rw-r--r-- | target/linux/mediatek/patches-4.9/0059-eth-fixes.patch | 511 |
1 files changed, 0 insertions, 511 deletions
diff --git a/target/linux/mediatek/patches-4.9/0059-eth-fixes.patch b/target/linux/mediatek/patches-4.9/0059-eth-fixes.patch deleted file mode 100644 index c155961862..0000000000 --- a/target/linux/mediatek/patches-4.9/0059-eth-fixes.patch +++ /dev/null @@ -1,511 +0,0 @@ ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -24,6 +24,7 @@ - #include <linux/tcp.h> - - #if defined(CONFIG_NET_MEDIATEK_HW_QOS) -+ - struct mtk_ioctl_reg { - unsigned int off; - unsigned int val; -@@ -32,6 +33,13 @@ struct mtk_ioctl_reg { - #define REG_HQOS_MAX 0x3FFF - #define RAETH_QDMA_REG_READ 0x89F8 - #define RAETH_QDMA_REG_WRITE 0x89F9 -+#define RAETH_QDMA_QUEUE_MAPPING 0x89FA -+ -+unsigned int M2Q_table[16] = {0}; -+unsigned int lan_wan_separate = 0; -+ -+EXPORT_SYMBOL_GPL(M2Q_table); -+ - #endif - - #if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE) -@@ -225,7 +233,7 @@ static void mtk_phy_link_adjust(struct n - if (flowctrl & FLOW_CTRL_RX) - mcr |= MAC_MCR_FORCE_RX_FC; - -- netif_dbg(mac->hw, link, dev, "rx pause %s, tx pause %s\n", -+ netif_info(mac->hw, link, dev, "rx pause %s, tx pause %s\n", - flowctrl & FLOW_CTRL_RX ? "enabled" : "disabled", - flowctrl & FLOW_CTRL_TX ? "enabled" : "disabled"); - } -@@ -508,9 +516,9 @@ static struct rtnl_link_stats64 * mtk_ge - unsigned int start; - - if (netif_running(dev) && netif_device_present(dev)) { -- if (spin_trylock_bh(&hw_stats->stats_lock)) { -+ if (spin_trylock(&hw_stats->stats_lock)) { - mtk_stats_update_mac(mac); -- spin_unlock_bh(&hw_stats->stats_lock); -+ spin_unlock(&hw_stats->stats_lock); - } - } - -@@ -690,6 +698,7 @@ static int mtk_tx_map(struct sk_buff *sk - txd3 |= skb->mark & 0x7; - if (mac->id) - txd3 += 8; -+ txd3 = 0; - #endif - - mapped_addr = dma_map_single(eth->dev, skb->data, -@@ -760,16 +769,7 @@ static int mtk_tx_map(struct sk_buff *sk - WRITE_ONCE(itxd->txd3, (TX_DMA_SWC | TX_DMA_PLEN0(skb_headlen(skb)) | - (!nr_frags * TX_DMA_LS0))); - -- /* we have a single DMA ring so BQL needs to be updated for all devices -- * sitting on this ring -- */ -- for (i = 0; i < MTK_MAC_COUNT; i++) { -- if (!eth->netdev[i]) -- continue; -- -- netdev_sent_queue(eth->netdev[i], skb->len); -- } -- -+ netdev_sent_queue(dev, skb->len); - skb_tx_timestamp(skb); - - ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2); -@@ -980,20 +980,9 @@ static int mtk_poll_rx(struct napi_struc - if (!(trxd.rxd2 & RX_DMA_DONE)) - break; - -- /* find out which mac the packet comes from. If the special tag is -- * we can assume that the traffic is coming from the builtin mt7530 -- * and the DSA driver has loaded. FPORT will be the physical switch -- * port in this case rather than the FE forward port id. */ -- if (!(trxd.rxd4 & RX_DMA_SP_TAG)) { -- /* values start at 1 */ -- mac = (trxd.rxd4 >> RX_DMA_FPORT_SHIFT) & -- RX_DMA_FPORT_MASK; -- mac--; -- } -- -- if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT || -- !eth->netdev[mac])) -- goto release_desc; -+ /* find out which mac the packet come from. values start at 1 */ -+ mac = (trxd.rxd4 >> 22) & 0x1; -+ mac = (mac + 1) % 2; - - netdev = eth->netdev[mac]; - -@@ -1017,6 +1006,9 @@ static int mtk_poll_rx(struct napi_struc - } - - /* receive data */ -+ if (mac < 0 || mac > 2) -+ mac = 0; -+ - skb = build_skb(data, ring->frag_size); - if (unlikely(!skb)) { - skb_free_frag(new_data); -@@ -1076,18 +1068,21 @@ static int mtk_poll_tx(struct mtk_eth *e - struct mtk_tx_dma *desc; - struct sk_buff *skb; - struct mtk_tx_buf *tx_buf; -- int total = 0, done = 0; -- unsigned int bytes = 0; -+ unsigned int done[MTK_MAX_DEVS]; -+ unsigned int bytes[MTK_MAX_DEVS]; - u32 cpu, dma; - static int condition; -- int i; -+ int total = 0, i; -+ -+ memset(done, 0, sizeof(done)); -+ memset(bytes, 0, sizeof(bytes)); - - cpu = mtk_r32(eth, MTK_QTX_CRX_PTR); - dma = mtk_r32(eth, MTK_QTX_DRX_PTR); - - desc = mtk_qdma_phys_to_virt(ring, cpu); - -- while ((cpu != dma) && done < budget) { -+ while ((cpu != dma) && budget) { - u32 next_cpu = desc->txd2; - int mac = 0; - -@@ -1106,8 +1101,9 @@ static int mtk_poll_tx(struct mtk_eth *e - } - - if (skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC) { -- bytes += skb->len; -- done++; -+ bytes[mac] += skb->len; -+ done[mac]++; -+ budget--; - } - mtk_tx_unmap(eth, tx_buf); - -@@ -1119,13 +1115,11 @@ static int mtk_poll_tx(struct mtk_eth *e - - mtk_w32(eth, cpu, MTK_QTX_CRX_PTR); - -- /* we have a single DMA ring so BQL needs to be updated for all devices -- * sitting on this ring -- */ - for (i = 0; i < MTK_MAC_COUNT; i++) { -- if (!eth->netdev[i]) -+ if (!eth->netdev[i] || !done[i]) - continue; -- netdev_completed_queue(eth->netdev[i], done, bytes); -+ netdev_completed_queue(eth->netdev[i], done[i], bytes[i]); -+ total += done[i]; - } - - if (mtk_queue_stopped(eth) && -@@ -1286,21 +1280,11 @@ static void mtk_tx_clean(struct mtk_eth - - static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag) - { -- struct mtk_rx_ring *ring; -+ struct mtk_rx_ring *ring = ð->rx_ring[ring_no]; - int rx_data_len, rx_dma_size; - int i; -- u32 offset = 0; -- -- if (rx_flag & MTK_RX_FLAGS_QDMA) { -- if (ring_no) -- return -EINVAL; -- ring = ð->rx_ring_qdma; -- offset = 0x1000; -- } else { -- ring = ð->rx_ring[ring_no]; -- } - -- if (rx_flag & MTK_RX_FLAGS_HWLRO) { -+ if (rx_flag == MTK_RX_FLAGS_HWLRO) { - rx_data_len = MTK_MAX_LRO_RX_LENGTH; - rx_dma_size = MTK_HW_LRO_DMA_SIZE; - } else { -@@ -1348,16 +1332,104 @@ static int mtk_rx_alloc(struct mtk_eth * - */ - wmb(); - -- mtk_w32(eth, ring->phys, MTK_PRX_BASE_PTR_CFG(ring_no) + offset); -- mtk_w32(eth, rx_dma_size, MTK_PRX_MAX_CNT_CFG(ring_no) + offset); -- mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg + offset); -- mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), MTK_PDMA_RST_IDX + offset); -+ mtk_w32(eth, ring->phys, MTK_PRX_BASE_PTR_CFG(ring_no)); -+ mtk_w32(eth, rx_dma_size, MTK_PRX_MAX_CNT_CFG(ring_no)); -+ mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg); -+ mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), MTK_PDMA_RST_IDX); - - return 0; - } - --static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring) -+static int mtk_rx_alloc_qdma(struct mtk_eth *eth, int rx_flag) - { -+ struct mtk_rx_ring *ring = ð->rx_ring_qdma; -+ int rx_data_len, rx_dma_size; -+ int i; -+ -+ rx_data_len = ETH_DATA_LEN; -+ rx_dma_size = MTK_DMA_SIZE; -+ -+ ring->frag_size = mtk_max_frag_size(rx_data_len); -+ ring->buf_size = mtk_max_buf_size(ring->frag_size); -+ ring->data = kcalloc(rx_dma_size, sizeof(*ring->data), -+ GFP_KERNEL); -+ if (!ring->data) -+ return -ENOMEM; -+ -+ for (i = 0; i < rx_dma_size; i++) { -+ ring->data[i] = netdev_alloc_frag(ring->frag_size); -+ if (!ring->data[i]) -+ return -ENOMEM; -+ } -+ -+ ring->dma = dma_alloc_coherent(eth->dev, -+ rx_dma_size * sizeof(*ring->dma), -+ &ring->phys, -+ GFP_ATOMIC | __GFP_ZERO); -+ if (!ring->dma) -+ return -ENOMEM; -+ -+ for (i = 0; i < rx_dma_size; i++) { -+ dma_addr_t dma_addr = dma_map_single(eth->dev, -+ ring->data[i] + NET_SKB_PAD, -+ ring->buf_size, -+ DMA_FROM_DEVICE); -+ if (unlikely(dma_mapping_error(eth->dev, dma_addr))) -+ return -ENOMEM; -+ ring->dma[i].rxd1 = (unsigned int)dma_addr; -+ -+ ring->dma[i].rxd2 = RX_DMA_PLEN0(ring->buf_size); -+ } -+ ring->dma_size = rx_dma_size; -+ ring->calc_idx_update = false; -+ ring->calc_idx = rx_dma_size - 1; -+ ring->crx_idx_reg = MTK_QRX_CRX_IDX_CFG(0); -+ /* make sure that all changes to the dma ring are flushed before we -+ * continue -+ */ -+ wmb(); -+ -+ mtk_w32(eth, ring->phys, MTK_QRX_BASE_PTR_CFG(0)); -+ mtk_w32(eth, rx_dma_size, MTK_QRX_MAX_CNT_CFG(0)); -+ mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg); -+ mtk_w32(eth, MTK_PST_DRX_IDX_CFG(0), MTK_QDMA_RST_IDX); -+ -+ return 0; -+} -+ -+static void mtk_rx_clean(struct mtk_eth *eth, int ring_no) -+{ -+ struct mtk_rx_ring *ring = ð->rx_ring[ring_no]; -+ int i; -+ -+ if (ring->data && ring->dma) { -+ for (i = 0; i < ring->dma_size; i++) { -+ if (!ring->data[i]) -+ continue; -+ if (!ring->dma[i].rxd1) -+ continue; -+ dma_unmap_single(eth->dev, -+ ring->dma[i].rxd1, -+ ring->buf_size, -+ DMA_FROM_DEVICE); -+ skb_free_frag(ring->data[i]); -+ } -+ kfree(ring->data); -+ ring->data = NULL; -+ } -+ -+ if (ring->dma) { -+ dma_free_coherent(eth->dev, -+ ring->dma_size * sizeof(*ring->dma), -+ ring->dma, -+ ring->phys); -+ ring->dma = NULL; -+ } -+} -+ -+static void mtk_rx_clean_qdma(struct mtk_eth *eth) -+{ -+ struct mtk_rx_ring *ring = ð->rx_ring_qdma; - int i; - - if (ring->data && ring->dma) { -@@ -1683,7 +1755,7 @@ static int mtk_dma_init(struct mtk_eth * - if (err) - return err; - -- err = mtk_rx_alloc(eth, 0, MTK_RX_FLAGS_QDMA); -+ err = mtk_rx_alloc_qdma(eth, MTK_RX_FLAGS_NORMAL); - if (err) - return err; - -@@ -1702,6 +1774,7 @@ static int mtk_dma_init(struct mtk_eth * - return err; - } - -+ - /* Enable random early drop and set drop threshold automatically */ - mtk_w32(eth, FC_THRES_DROP_MODE | FC_THRES_DROP_EN | FC_THRES_MIN, - MTK_QDMA_FC_THRES); -@@ -1726,13 +1799,13 @@ static void mtk_dma_free(struct mtk_eth - eth->phy_scratch_ring = 0; - } - mtk_tx_clean(eth); -- mtk_rx_clean(eth, ð->rx_ring[0]); -- mtk_rx_clean(eth, ð->rx_ring_qdma); -+ mtk_rx_clean(eth, 0); -+ mtk_rx_clean_qdma(eth); - - if (eth->hwlro) { - mtk_hwlro_rx_uninit(eth); - for (i = 1; i < MTK_MAX_RX_RING_NUM; i++) -- mtk_rx_clean(eth, ð->rx_ring[i]); -+ mtk_rx_clean(eth, i); - } - - kfree(eth->scratch_head); -@@ -1947,20 +2020,14 @@ static int mtk_hw_init(struct mtk_eth *e - val = mtk_r32(eth, MTK_CDMQ_IG_CTRL); - mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL); - -- /* Indicates CDM to parse the MTK special tag from CPU -- * which also is working out for untag packets. -- */ -- val = mtk_r32(eth, MTK_CDMQ_IG_CTRL); -- mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL); -- val = mtk_r32(eth, MTK_CDMP_IG_CTRL); -- mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL); -- - /* Enable RX VLan Offloading */ - if (MTK_HW_FEATURES & NETIF_F_HW_VLAN_CTAG_RX) - mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); - else - mtk_w32(eth, 0, MTK_CDMP_EG_CTRL); - -+ mtk_w32(eth, 0x81000001, MTK_CDMP_IG_CTRL); -+ - /* disable delay and normal interrupt */ - #ifdef MTK_IRQ_DLY - mtk_w32(eth, 0x84048404, MTK_PDMA_DELAY_INT); -@@ -1990,6 +2057,9 @@ static int mtk_hw_init(struct mtk_eth *e - /* Enable RX checksum */ - val |= MTK_GDMA_ICS_EN | MTK_GDMA_TCS_EN | MTK_GDMA_UCS_EN; - -+ if (!i) -+ val |= BIT(24); -+ - /* setup the mac dma */ - mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i)); - } -@@ -2069,7 +2139,18 @@ static int mtk_do_ioctl(struct net_devic - if (reg.off > REG_HQOS_MAX) - return -EINVAL; - mtk_w32(eth, reg.val, 0x1800 + reg.off); --// printk("write reg off:%x val:%x\n", reg.off, reg.val); -+ printk("write reg off:%x val:%x\n", reg.off, reg.val); -+ return 0; -+ -+ case RAETH_QDMA_QUEUE_MAPPING: -+ copy_from_user(®, ifr->ifr_data, sizeof(reg)); -+ if ((reg.off & 0x100) == 0x100) { -+ lan_wan_separate = 1; -+ reg.off &= 0xff; -+ } else { -+ lan_wan_separate = 0; -+ } -+ M2Q_table[reg.off] = reg.val; - return 0; - #endif - case SIOCGMIIPHY: -@@ -2288,9 +2369,9 @@ static void mtk_get_ethtool_stats(struct - return; - - if (netif_running(dev) && netif_device_present(dev)) { -- if (spin_trylock_bh(&hwstats->stats_lock)) { -+ if (spin_trylock(&hwstats->stats_lock)) { - mtk_stats_update_mac(mac); -- spin_unlock_bh(&hwstats->stats_lock); -+ spin_unlock(&hwstats->stats_lock); - } - } - -@@ -2443,7 +2524,7 @@ static int mtk_add_mac(struct mtk_eth *e - mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET; - - SET_NETDEV_DEV(eth->netdev[id], eth->dev); -- eth->netdev[id]->watchdog_timeo = 30 * HZ; -+ eth->netdev[id]->watchdog_timeo = 15 * HZ; - eth->netdev[id]->netdev_ops = &mtk_netdev_ops; - eth->netdev[id]->base_addr = (unsigned long)eth->base; - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -80,7 +80,6 @@ - - /* CDMP Ingress Control Register */ - #define MTK_CDMP_IG_CTRL 0x400 --#define MTK_CDMP_STAG_EN BIT(0) - - /* CDMP Exgress Control Register */ - #define MTK_CDMP_EG_CTRL 0x404 -@@ -91,12 +90,27 @@ - #define MTK_GDMA_TCS_EN BIT(21) - #define MTK_GDMA_UCS_EN BIT(20) - -+/* GDMA Ingress Control Register */ -+#define MTK_GDMA1_IG_CTRL(x) (0x500 + (x * 0x1000)) -+ - /* Unicast Filter MAC Address Register - Low */ - #define MTK_GDMA_MAC_ADRL(x) (0x508 + (x * 0x1000)) - - /* Unicast Filter MAC Address Register - High */ - #define MTK_GDMA_MAC_ADRH(x) (0x50C + (x * 0x1000)) - -+/* QDMA RX Base Pointer Register */ -+#define MTK_QRX_BASE_PTR0 0x1900 -+#define MTK_QRX_BASE_PTR_CFG(x) (MTK_QRX_BASE_PTR0 + (x * 0x10)) -+ -+/* QDMA RX Maximum Count Register */ -+#define MTK_QRX_MAX_CNT0 0x1904 -+#define MTK_QRX_MAX_CNT_CFG(x) (MTK_QRX_MAX_CNT0 + (x * 0x10)) -+ -+/* QDMA RX CPU Pointer Register */ -+#define MTK_QRX_CRX_IDX0 0x1908 -+#define MTK_QRX_CRX_IDX_CFG(x) (MTK_QRX_CRX_IDX0 + (x * 0x10)) -+ - /* PDMA RX Base Pointer Register */ - #define MTK_PRX_BASE_PTR0 0x900 - #define MTK_PRX_BASE_PTR_CFG(x) (MTK_PRX_BASE_PTR0 + (x * 0x10)) -@@ -240,7 +254,10 @@ - #define MTK_QDMA_INT_MASK 0x1A1C - - /* QDMA Interrupt Mask Register */ -+#define MTK_QDMA_HRED1 0x1A40 - #define MTK_QDMA_HRED2 0x1A44 -+#define MTK_QDMA_SRED1 0x1A48 -+#define MTK_QDMA_SRED2 0x1A4c - - /* QDMA TX Forward CPU Pointer Register */ - #define MTK_QTX_CTX_PTR 0x1B00 -@@ -275,6 +292,7 @@ - #define TX_DMA_TSO BIT(28) - #define TX_DMA_FPORT_SHIFT 25 - #define TX_DMA_FPORT_MASK 0x7 -+#define TX_DMA_VQID0 BIT(17) - #define TX_DMA_INS_VLAN BIT(16) - - /* QDMA descriptor txd3 */ -@@ -294,7 +312,6 @@ - - /* QDMA descriptor rxd4 */ - #define RX_DMA_L4_VALID BIT(24) --#define RX_DMA_SP_TAG BIT(22) - #define RX_DMA_FPORT_SHIFT 19 - #define RX_DMA_FPORT_MASK 0x7 - -@@ -310,6 +327,7 @@ - - /* Mac control registers */ - #define MTK_MAC_MCR(x) (0x10100 + (x * 0x100)) -+#define MTK_MAC_MSR(x) (0x10108 + (x * 0x100)) - #define MAC_MCR_MAX_RX_1536 BIT(24) - #define MAC_MCR_IPG_CFG (BIT(18) | BIT(16)) - #define MAC_MCR_FORCE_MODE BIT(15) -@@ -495,7 +513,6 @@ struct mtk_tx_ring { - enum mtk_rx_flags { - MTK_RX_FLAGS_NORMAL = 0, - MTK_RX_FLAGS_HWLRO, -- MTK_RX_FLAGS_QDMA, - }; - - /* struct mtk_rx_ring - This struct holds info describing a RX ring -@@ -539,9 +556,9 @@ struct mtk_rx_ring { - * @pctl: The register map pointing at the range used to setup - * GMAC port drive/slew values - * @dma_refcnt: track how many netdevs are using the DMA engine -- * @tx_ring: Pointer to the memory holding info about the TX ring -- * @rx_ring: Pointer to the memory holding info about the RX ring -- * @rx_ring_qdma: Pointer to the memory holding info about the QDMA RX ring -+ * @tx_ring: Pointer to the memore holding info about the TX ring -+ * @rx_ring: Pointer to the memore holding info about the RX ring -+ * @rx_ring_qdma: Pointer to the memore holding info about the RX ring (QDMA) - * @tx_napi: The TX NAPI struct - * @rx_napi: The RX NAPI struct - * @scratch_ring: Newer SoCs need memory for a second HW managed TX ring -@@ -563,6 +580,7 @@ struct mtk_eth { - struct net_device *netdev[MTK_MAX_DEVS]; - struct mtk_mac *mac[MTK_MAX_DEVS]; - int irq[3]; -+ cpumask_t affinity_mask[3]; - u32 msg_enable; - unsigned long sysclk; - struct regmap *ethsys; -@@ -615,4 +633,6 @@ void mtk_stats_update_mac(struct mtk_mac - void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg); - u32 mtk_r32(struct mtk_eth *eth, unsigned reg); - -+extern unsigned int M2Q_table[16]; -+ - #endif /* MTK_ETH_H */ |