All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping
@ 2016-05-09 10:03 John Crispin
  2016-05-09 10:03 ` [PATCH V2 01/22] net-next: mediatek: use mdiobus_free() in favour of kfree() John Crispin
                   ` (18 more replies)
  0 siblings, 19 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:03 UTC (permalink / raw)
  To: davem; +Cc: nbd, netdev, linux-mediatek, John Crispin

This series introduces a number of fixes that we stumbled across while
doing more performance testing and code level reviewing. Additionally
it improves the PHY setup code adding support for fixed phys, asymmetric
flow control and gigabit feature advertisement. Next the series adds a
support for IRQ grouping, allowing use to separate the IRQs onto more than
one core using irq affinity. The last two patches wrap up the series by
updating my email address.

John Crispin (22):
  net-next: mediatek: use mdiobus_free() in favour of kfree()
  net-next: mediatek: fix gigabit and flow control advertisement
  net-next: mediatek: add fixed-phy support
  net-next: mediatek: properly handle RGMII modes
  net-next: mediatek: fix DQL support
  net-next: mediatek: add missing return code check
  net-next: mediatek: fix missing free of scratch memory
  net-next: mediatek: invalid buffer lookup in mtk_tx_map()
  net-next: mediatek: dropped rx packets are not being counted properly
  net-next: mediatek: add next data pointer coherency protection
  net-next: mediatek: disable all interrupts during probe
  net-next: mediatek: fix threshold value
  net-next: mediatek: increase watchdog_timeo
  net-next: mediatek: fix off by one in the TX ring allocation
  net-next: mediatek: only wake the queue if it is stopped
  net-next: mediatek: remove superfluous queue wake up call
  net-next: mediatek: remove superfluous register reads
  net-next: mediatek: don't use intermediate variables to store IRQ
    masks
  net-next: mediatek: add IRQ locking
  net-next: mediatek: add support for IRQ grouping
  net-next: mediatek: change my email address
  MAINTAINERS: change my email address

 MAINTAINERS                                 |    2 +-
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |  293 +++++++++++++++++----------
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |   19 +-
 3 files changed, 209 insertions(+), 105 deletions(-)

-- 
1.7.10.4

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH V2 01/22] net-next: mediatek: use mdiobus_free() in favour of kfree()
  2016-05-09 10:03 [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping John Crispin
@ 2016-05-09 10:03 ` John Crispin
  2016-05-09 12:07   ` Andrew Lunn
  2016-05-09 10:03 ` [PATCH V2 02/22] net-next: mediatek: fix gigabit and flow control advertisement John Crispin
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:03 UTC (permalink / raw)
  To: davem; +Cc: nbd, netdev, linux-mediatek, John Crispin

The driver currently uses kfree() to clear the mii_bus. This is not the
correct way to clear the memory and mdiobus_free() should be used instead.
This patch fixes the two instances where this happens in the driver.

Reported-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index c984462..28f169f 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -280,7 +280,7 @@ static int mtk_mdio_init(struct mtk_eth *eth)
 	return 0;
 
 err_free_bus:
-	kfree(eth->mii_bus);
+	mdiobus_free(eth->mii_bus);
 
 err_put_node:
 	of_node_put(mii_np);
@@ -295,7 +295,7 @@ static void mtk_mdio_cleanup(struct mtk_eth *eth)
 
 	mdiobus_unregister(eth->mii_bus);
 	of_node_put(eth->mii_bus->dev.of_node);
-	kfree(eth->mii_bus);
+	mdiobus_free(eth->mii_bus);
 }
 
 static inline void mtk_irq_disable(struct mtk_eth *eth, u32 mask)
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 02/22] net-next: mediatek: fix gigabit and flow control advertisement
  2016-05-09 10:03 [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping John Crispin
  2016-05-09 10:03 ` [PATCH V2 01/22] net-next: mediatek: use mdiobus_free() in favour of kfree() John Crispin
@ 2016-05-09 10:03 ` John Crispin
  2016-05-09 10:03 ` [PATCH V2 03/22] net-next: mediatek: add fixed-phy support John Crispin
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:03 UTC (permalink / raw)
  To: davem; +Cc: nbd, netdev, linux-mediatek, John Crispin

The current code will not setup the PHYs advertisement features correctly.
Fix this and properly advertise Gigabit features and properly handle
asymmetric pause frames.

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |   16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 28f169f..a76aec20 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -133,6 +133,8 @@ static int mtk_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg)
 static void mtk_phy_link_adjust(struct net_device *dev)
 {
 	struct mtk_mac *mac = netdev_priv(dev);
+	u16 lcl_adv, rmt_adv = 0;
+	u8 flowctrl;
 	u32 mcr = MAC_MCR_MAX_RX_1536 | MAC_MCR_IPG_CFG |
 		  MAC_MCR_FORCE_MODE | MAC_MCR_TX_EN |
 		  MAC_MCR_RX_EN | MAC_MCR_BACKOFF_EN |
@@ -154,7 +156,16 @@ static void mtk_phy_link_adjust(struct net_device *dev)
 		mcr |= MAC_MCR_FORCE_DPX;
 
 	if (mac->phy_dev->pause)
-		mcr |= MAC_MCR_FORCE_RX_FC | MAC_MCR_FORCE_TX_FC;
+		rmt_adv = LPA_PAUSE_CAP;
+	if (mac->phy_dev->asym_pause)
+		rmt_adv |= LPA_PAUSE_ASYM;
+
+	lcl_adv = mii_advertise_flowctrl(FLOW_CTRL_RX | FLOW_CTRL_TX);
+	flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
+	if (flowctrl & FLOW_CTRL_TX)
+		mcr |= MAC_MCR_FORCE_TX_FC;
+	if (flowctrl & FLOW_CTRL_RX)
+		mcr |= MAC_MCR_FORCE_RX_FC;
 
 	mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
 
@@ -236,7 +247,8 @@ static int mtk_phy_connect(struct mtk_mac *mac)
 	mac->phy_dev->autoneg = AUTONEG_ENABLE;
 	mac->phy_dev->speed = 0;
 	mac->phy_dev->duplex = 0;
-	mac->phy_dev->supported &= PHY_BASIC_FEATURES;
+	mac->phy_dev->supported &= PHY_GBIT_FEATURES | SUPPORTED_Pause |
+				   ~SUPPORTED_Asym_Pause;
 	mac->phy_dev->advertising = mac->phy_dev->supported |
 				    ADVERTISED_Autoneg;
 	phy_start_aneg(mac->phy_dev);
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 03/22] net-next: mediatek: add fixed-phy support
  2016-05-09 10:03 [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping John Crispin
  2016-05-09 10:03 ` [PATCH V2 01/22] net-next: mediatek: use mdiobus_free() in favour of kfree() John Crispin
  2016-05-09 10:03 ` [PATCH V2 02/22] net-next: mediatek: fix gigabit and flow control advertisement John Crispin
@ 2016-05-09 10:03 ` John Crispin
  2016-05-09 10:03 ` [PATCH V2 04/22] net-next: mediatek: properly handle RGMII modes John Crispin
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:03 UTC (permalink / raw)
  To: davem; +Cc: nbd, netdev, linux-mediatek, John Crispin

The MT7623 SoC has a builtin gigabit switch. If we want to use it, GMAC1
needs to be configured using a fixed link speed and flow control settings.
The easiest way to do this is to used the fixed-phy driver, allowing us to
reuse the existing mdio polling code to setup the MAC.

Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index a76aec20..4d59bda 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -219,6 +219,9 @@ static int mtk_phy_connect(struct mtk_mac *mac)
 	u32 val, ge_mode;
 
 	np = of_parse_phandle(mac->of_node, "phy-handle", 0);
+	if (!np && of_phy_is_fixed_link(mac->of_node))
+		if (!of_phy_register_fixed_link(mac->of_node))
+			np = of_node_get(mac->of_node);
 	if (!np)
 		return -ENODEV;
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 04/22] net-next: mediatek: properly handle RGMII modes
  2016-05-09 10:03 [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping John Crispin
                   ` (2 preceding siblings ...)
  2016-05-09 10:03 ` [PATCH V2 03/22] net-next: mediatek: add fixed-phy support John Crispin
@ 2016-05-09 10:03 ` John Crispin
  2016-05-09 12:09   ` Andrew Lunn
  2016-05-09 10:03 ` [PATCH V2 05/22] net-next: mediatek: fix DQL support John Crispin
                   ` (14 subsequent siblings)
  18 siblings, 1 reply; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:03 UTC (permalink / raw)
  To: davem; +Cc: nbd, netdev, linux-mediatek, John Crispin

If an external Gigabit PHY is connected to either of the MACs we need to
be able to tell the PHY to use a delay. Not doing so will result in heavy
packet loss and/or data corruption when using PHYs such as the IC+ IP1001.
We tell the PHY which MII delay mode to use via the devictree.

The ethernet driver needs to be adapted to handle all 3 rgmii-*id modes
in the same way as normal rgmii when setting up the MAC.

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 4d59bda..c5ddb4d 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -226,6 +226,9 @@ static int mtk_phy_connect(struct mtk_mac *mac)
 		return -ENODEV;
 
 	switch (of_get_phy_mode(np)) {
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_ID:
 	case PHY_INTERFACE_MODE_RGMII:
 		ge_mode = 0;
 		break;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 05/22] net-next: mediatek: fix DQL support
  2016-05-09 10:03 [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping John Crispin
                   ` (3 preceding siblings ...)
  2016-05-09 10:03 ` [PATCH V2 04/22] net-next: mediatek: properly handle RGMII modes John Crispin
@ 2016-05-09 10:03 ` John Crispin
  2016-05-09 10:03 ` [PATCH V2 06/22] net-next: mediatek: add missing return code check John Crispin
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:03 UTC (permalink / raw)
  To: davem; +Cc: nbd, netdev, linux-mediatek, John Crispin

The MTK ethernet core has 2 MACs both sitting on the same DMA ring. The
current code will assign the TX traffic of each MAC to its own DQL. This
results in the amount of data, that DQL says is in the queue incorrect. As
the data from multiple devices is infact enqueued. This makes any decision
based on these value non deterministic. Fix this by tracking all TX
traffic, regardless of the MAC it belongs to in the DQL of all devices
using the DMA.

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |   33 ++++++++++++++++-----------
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index c5ddb4d..4a01ba7 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -643,7 +643,16 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
 	WRITE_ONCE(itxd->txd3, (TX_DMA_SWC | TX_DMA_PLEN0(skb_headlen(skb)) |
 				(!nr_frags * TX_DMA_LS0)));
 
-	netdev_sent_queue(dev, skb->len);
+	/* 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);
+	}
+
 	skb_tx_timestamp(skb);
 
 	ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2);
@@ -871,21 +880,18 @@ static int mtk_poll_tx(struct mtk_eth *eth, int budget, bool *tx_again)
 	struct mtk_tx_dma *desc;
 	struct sk_buff *skb;
 	struct mtk_tx_buf *tx_buf;
-	int total = 0, done[MTK_MAX_DEVS];
-	unsigned int bytes[MTK_MAX_DEVS];
+	int total = 0, done = 0;
+	unsigned int bytes = 0;
 	u32 cpu, dma;
 	static int condition;
 	int 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) && budget) {
+	while ((cpu != dma) && done < budget) {
 		u32 next_cpu = desc->txd2;
 		int mac;
 
@@ -905,9 +911,8 @@ static int mtk_poll_tx(struct mtk_eth *eth, int budget, bool *tx_again)
 		}
 
 		if (skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC) {
-			bytes[mac] += skb->len;
-			done[mac]++;
-			budget--;
+			bytes += skb->len;
+			done++;
 		}
 		mtk_tx_unmap(eth->dev, tx_buf);
 
@@ -920,11 +925,13 @@ static int mtk_poll_tx(struct mtk_eth *eth, int budget, bool *tx_again)
 
 	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] || !done[i])
+		if (!eth->netdev[i])
 			continue;
-		netdev_completed_queue(eth->netdev[i], done[i], bytes[i]);
-		total += done[i];
+		netdev_completed_queue(eth->netdev[i], done, bytes);
 	}
 
 	/* read hw index again make sure no new tx packet */
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 06/22] net-next: mediatek: add missing return code check
  2016-05-09 10:03 [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping John Crispin
                   ` (4 preceding siblings ...)
  2016-05-09 10:03 ` [PATCH V2 05/22] net-next: mediatek: fix DQL support John Crispin
@ 2016-05-09 10:03 ` John Crispin
  2016-05-09 10:03 ` [PATCH V2 07/22] net-next: mediatek: fix missing free of scratch memory John Crispin
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:03 UTC (permalink / raw)
  To: davem; +Cc: nbd, netdev, linux-mediatek, John Crispin

The code fails to check if the scratch memory was properly allocated. Add
this check and return with an error if the allocation failed.

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 4a01ba7..d16ec59 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -485,6 +485,9 @@ static int mtk_init_fq_dma(struct mtk_eth *eth)
 
 	eth->scratch_head = kcalloc(cnt, MTK_QDMA_PAGE_SIZE,
 				    GFP_KERNEL);
+	if (unlikely(!eth->scratch_head))
+		return -ENOMEM;
+
 	dma_addr = dma_map_single(eth->dev,
 				  eth->scratch_head, cnt * MTK_QDMA_PAGE_SIZE,
 				  DMA_FROM_DEVICE);
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 07/22] net-next: mediatek: fix missing free of scratch memory
  2016-05-09 10:03 [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping John Crispin
                   ` (5 preceding siblings ...)
  2016-05-09 10:03 ` [PATCH V2 06/22] net-next: mediatek: add missing return code check John Crispin
@ 2016-05-09 10:03 ` John Crispin
  2016-05-09 10:04 ` [PATCH V2 08/22] net-next: mediatek: invalid buffer lookup in mtk_tx_map() John Crispin
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:03 UTC (permalink / raw)
  To: davem; +Cc: nbd, netdev, linux-mediatek, John Crispin

Scratch memory gets allocated in mtk_init_fq_dma() but the corresponding
code to free it is missing inside mtk_dma_free() causing a memory leak.
With this patch applied, we can run ifconfig/up/down several thousand
times without any problems.

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |   18 +++++++++++++-----
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |    2 ++
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index d16ec59..49a3b7c 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -471,14 +471,14 @@ static inline void mtk_rx_get_desc(struct mtk_rx_dma *rxd,
 /* the qdma core needs scratch memory to be setup */
 static int mtk_init_fq_dma(struct mtk_eth *eth)
 {
-	dma_addr_t phy_ring_head, phy_ring_tail;
+	dma_addr_t phy_ring_tail;
 	int cnt = MTK_DMA_SIZE;
 	dma_addr_t dma_addr;
 	int i;
 
 	eth->scratch_ring = dma_alloc_coherent(eth->dev,
 					       cnt * sizeof(struct mtk_tx_dma),
-					       &phy_ring_head,
+					       &eth->phy_scratch_ring,
 					       GFP_ATOMIC | __GFP_ZERO);
 	if (unlikely(!eth->scratch_ring))
 		return -ENOMEM;
@@ -495,19 +495,19 @@ static int mtk_init_fq_dma(struct mtk_eth *eth)
 		return -ENOMEM;
 
 	memset(eth->scratch_ring, 0x0, sizeof(struct mtk_tx_dma) * cnt);
-	phy_ring_tail = phy_ring_head +
+	phy_ring_tail = eth->phy_scratch_ring +
 			(sizeof(struct mtk_tx_dma) * (cnt - 1));
 
 	for (i = 0; i < cnt; i++) {
 		eth->scratch_ring[i].txd1 =
 					(dma_addr + (i * MTK_QDMA_PAGE_SIZE));
 		if (i < cnt - 1)
-			eth->scratch_ring[i].txd2 = (phy_ring_head +
+			eth->scratch_ring[i].txd2 = (eth->phy_scratch_ring +
 				((i + 1) * sizeof(struct mtk_tx_dma)));
 		eth->scratch_ring[i].txd3 = TX_DMA_SDL(MTK_QDMA_PAGE_SIZE);
 	}
 
-	mtk_w32(eth, phy_ring_head, MTK_QDMA_FQ_HEAD);
+	mtk_w32(eth, eth->phy_scratch_ring, MTK_QDMA_FQ_HEAD);
 	mtk_w32(eth, phy_ring_tail, MTK_QDMA_FQ_TAIL);
 	mtk_w32(eth, (cnt << 16) | cnt, MTK_QDMA_FQ_CNT);
 	mtk_w32(eth, MTK_QDMA_PAGE_SIZE << 16, MTK_QDMA_FQ_BLEN);
@@ -1207,6 +1207,14 @@ static void mtk_dma_free(struct mtk_eth *eth)
 	for (i = 0; i < MTK_MAC_COUNT; i++)
 		if (eth->netdev[i])
 			netdev_reset_queue(eth->netdev[i]);
+	if (eth->scratch_ring) {
+		dma_free_coherent(eth->dev,
+				  MTK_DMA_SIZE * sizeof(struct mtk_tx_dma),
+				  eth->scratch_ring,
+				  eth->phy_scratch_ring);
+		eth->scratch_ring = NULL;
+		eth->phy_scratch_ring = 0;
+	}
 	mtk_tx_clean(eth);
 	mtk_rx_clean(eth);
 	kfree(eth->scratch_head);
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index eed626d..57f7e8a 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -357,6 +357,7 @@ struct mtk_rx_ring {
  * @rx_ring:		Pointer to the memore holding info about the RX ring
  * @rx_napi:		The NAPI struct
  * @scratch_ring:	Newer SoCs need memory for a second HW managed TX ring
+ * @phy_scratch_ring:	physical address of scratch_ring
  * @scratch_head:	The scratch memory that scratch_ring points to.
  * @clk_ethif:		The ethif clock
  * @clk_esw:		The switch clock
@@ -384,6 +385,7 @@ struct mtk_eth {
 	struct mtk_rx_ring		rx_ring;
 	struct napi_struct		rx_napi;
 	struct mtk_tx_dma		*scratch_ring;
+	dma_addr_t			phy_scratch_ring;
 	void				*scratch_head;
 	struct clk			*clk_ethif;
 	struct clk			*clk_esw;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 08/22] net-next: mediatek: invalid buffer lookup in mtk_tx_map()
  2016-05-09 10:03 [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping John Crispin
                   ` (6 preceding siblings ...)
  2016-05-09 10:03 ` [PATCH V2 07/22] net-next: mediatek: fix missing free of scratch memory John Crispin
@ 2016-05-09 10:04 ` John Crispin
  2016-05-09 10:04 ` [PATCH V2 09/22] net-next: mediatek: dropped rx packets are not being counted properly John Crispin
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:04 UTC (permalink / raw)
  To: davem; +Cc: nbd, netdev, linux-mediatek, John Crispin

The lookup of the tx_buffer in the error path inside mtk_tx_map() uses the
wrong descriptor pointer. This looks like a copy & paste error. Change the
code to use the correct pointer.

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 49a3b7c..e61e73b 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -673,7 +673,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
 
 err_dma:
 	do {
-		tx_buf = mtk_desc_to_tx_buf(ring, txd);
+		tx_buf = mtk_desc_to_tx_buf(ring, itxd);
 
 		/* unmap dma */
 		mtk_tx_unmap(&dev->dev, tx_buf);
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 09/22] net-next: mediatek: dropped rx packets are not being counted properly
  2016-05-09 10:03 [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping John Crispin
                   ` (7 preceding siblings ...)
  2016-05-09 10:04 ` [PATCH V2 08/22] net-next: mediatek: invalid buffer lookup in mtk_tx_map() John Crispin
@ 2016-05-09 10:04 ` John Crispin
  2016-05-09 10:04 ` [PATCH V2 10/22] net-next: mediatek: add next data pointer coherency protection John Crispin
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:04 UTC (permalink / raw)
  To: davem; +Cc: nbd, netdev, linux-mediatek, John Crispin

There are 2 places inside mtk_poll_rx where rx_dropped is not being
incremented properly. Fix this by adding the missing code to increment
the counter.

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index e61e73b..75488d1 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -828,6 +828,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
 					  DMA_FROM_DEVICE);
 		if (unlikely(dma_mapping_error(&netdev->dev, dma_addr))) {
 			skb_free_frag(new_data);
+			netdev->stats.rx_dropped++;
 			goto release_desc;
 		}
 
@@ -835,6 +836,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
 		skb = build_skb(data, ring->frag_size);
 		if (unlikely(!skb)) {
 			put_page(virt_to_head_page(new_data));
+			netdev->stats.rx_dropped++;
 			goto release_desc;
 		}
 		skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN);
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 10/22] net-next: mediatek: add next data pointer coherency protection
  2016-05-09 10:03 [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping John Crispin
                   ` (8 preceding siblings ...)
  2016-05-09 10:04 ` [PATCH V2 09/22] net-next: mediatek: dropped rx packets are not being counted properly John Crispin
@ 2016-05-09 10:04 ` John Crispin
  2016-05-09 10:04 ` [PATCH V2 11/22] net-next: mediatek: disable all interrupts during probe John Crispin
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:04 UTC (permalink / raw)
  To: davem; +Cc: nbd, netdev, linux-mediatek, John Crispin

The QDMA engine can fail to update the register pointing to the next TX
descriptor if this bit does not get set in the QDMA configuration register.
Not setting this bit can result in invalid values inside the TX rings
registers which will causes TX stalls.

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |    2 +-
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |    1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 75488d1..3ab7ab9 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1279,7 +1279,7 @@ static int mtk_start_dma(struct mtk_eth *eth)
 	mtk_w32(eth,
 		MTK_TX_WB_DDONE | MTK_RX_DMA_EN | MTK_TX_DMA_EN |
 		MTK_RX_2B_OFFSET | MTK_DMA_SIZE_16DWORDS |
-		MTK_RX_BT_32DWORDS,
+		MTK_RX_BT_32DWORDS | MTK_NDP_CO_PRO,
 		MTK_QDMA_GLO_CFG);
 
 	return 0;
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 57f7e8a..a5eb7c6 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -91,6 +91,7 @@
 #define MTK_QDMA_GLO_CFG	0x1A04
 #define MTK_RX_2B_OFFSET	BIT(31)
 #define MTK_RX_BT_32DWORDS	(3 << 11)
+#define MTK_NDP_CO_PRO		BIT(10)
 #define MTK_TX_WB_DDONE		BIT(6)
 #define MTK_DMA_SIZE_16DWORDS	(2 << 4)
 #define MTK_RX_DMA_BUSY		BIT(3)
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 11/22] net-next: mediatek: disable all interrupts during probe
  2016-05-09 10:03 [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping John Crispin
                   ` (9 preceding siblings ...)
  2016-05-09 10:04 ` [PATCH V2 10/22] net-next: mediatek: add next data pointer coherency protection John Crispin
@ 2016-05-09 10:04 ` John Crispin
  2016-05-09 10:04 ` [PATCH V2 13/22] net-next: mediatek: increase watchdog_timeo John Crispin
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:04 UTC (permalink / raw)
  To: davem; +Cc: nbd, netdev, linux-mediatek, John Crispin

The current code only disables those IRQs that we will later use. To
ensure that we have a predefined state, we really want to disable all IRQs.
Change the code to disable all IRQs to achieve this.

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 3ab7ab9..b8d8ad2 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1393,7 +1393,7 @@ static int __init mtk_hw_init(struct mtk_eth *eth)
 
 	/* disable delay and normal interrupt */
 	mtk_w32(eth, 0, MTK_QDMA_DELAY_INT);
-	mtk_irq_disable(eth, MTK_TX_DONE_INT | MTK_RX_DONE_INT);
+	mtk_irq_disable(eth, ~0);
 	mtk_w32(eth, RST_GL_PSE, MTK_RST_GL);
 	mtk_w32(eth, 0, MTK_RST_GL);
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 12/22] net-next: mediatek: fix threshold value
       [not found] ` <1462788254-40572-1-git-send-email-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
@ 2016-05-09 10:04   ` John Crispin
  2016-05-09 10:04   ` [PATCH V2 14/22] net-next: mediatek: fix off by one in the TX ring allocation John Crispin
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:04 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, John Crispin,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, nbd-Vt+b4OUoWG0

The logic to calculate the threshold value for stopping the TX queue is
bad. Currently it will always use 1/2 of the rings size, which is way too
much. Set the threshold to MAX_SKB_FRAGS. This makes sure that the queue
is stopped when there is not enough room to accept an additional segment. 

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index b8d8ad2..984788a 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1030,8 +1030,7 @@ static int mtk_tx_alloc(struct mtk_eth *eth)
 	atomic_set(&ring->free_count, MTK_DMA_SIZE - 2);
 	ring->next_free = &ring->dma[0];
 	ring->last_free = &ring->dma[MTK_DMA_SIZE - 2];
-	ring->thresh = max((unsigned long)MTK_DMA_SIZE >> 2,
-			      MAX_SKB_FRAGS);
+	ring->thresh = MAX_SKB_FRAGS;
 
 	/* make sure that all changes to the dma ring are flushed before we
 	 * continue
-- 
1.7.10.4


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 13/22] net-next: mediatek: increase watchdog_timeo
  2016-05-09 10:03 [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping John Crispin
                   ` (10 preceding siblings ...)
  2016-05-09 10:04 ` [PATCH V2 11/22] net-next: mediatek: disable all interrupts during probe John Crispin
@ 2016-05-09 10:04 ` John Crispin
  2016-05-09 10:04 ` [PATCH V2 15/22] net-next: mediatek: only wake the queue if it is stopped John Crispin
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:04 UTC (permalink / raw)
  To: davem; +Cc: nbd, netdev, linux-mediatek, John Crispin

During stress testing, after reducing the threshold value, we have seen
TX timeouts that were caused by the watchdog_timeo value being too low.
Increase the value to 5 * HZ which is a value commonly used by many other
drivers.

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 984788a..3ece159 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1706,7 +1706,7 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
 	mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
 
 	SET_NETDEV_DEV(eth->netdev[id], eth->dev);
-	eth->netdev[id]->watchdog_timeo = HZ;
+	eth->netdev[id]->watchdog_timeo = 5 * HZ;
 	eth->netdev[id]->netdev_ops = &mtk_netdev_ops;
 	eth->netdev[id]->base_addr = (unsigned long)eth->base;
 	eth->netdev[id]->vlan_features = MTK_HW_FEATURES &
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 14/22] net-next: mediatek: fix off by one in the TX ring allocation
       [not found] ` <1462788254-40572-1-git-send-email-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
  2016-05-09 10:04   ` [PATCH V2 12/22] net-next: mediatek: fix threshold value John Crispin
@ 2016-05-09 10:04   ` John Crispin
  2016-05-09 10:04   ` [PATCH V2 16/22] net-next: mediatek: remove superfluous queue wake up call John Crispin
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:04 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, John Crispin,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, nbd-Vt+b4OUoWG0

The TX ring setup has an off by one error causing it to not utilise all
descriptors. This has the side effect that we need to reset the next
pointer at runtime to make it work. Fix the off by one and remove the
code fixing the ring at runtime.

Signed-off-by: John Crispin <john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 3ece159..9f4b533 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -921,7 +921,6 @@ static int mtk_poll_tx(struct mtk_eth *eth, int budget, bool *tx_again)
 		}
 		mtk_tx_unmap(eth->dev, tx_buf);
 
-		ring->last_free->txd2 = next_cpu;
 		ring->last_free = desc;
 		atomic_inc(&ring->free_count);
 
@@ -1029,7 +1028,7 @@ static int mtk_tx_alloc(struct mtk_eth *eth)
 
 	atomic_set(&ring->free_count, MTK_DMA_SIZE - 2);
 	ring->next_free = &ring->dma[0];
-	ring->last_free = &ring->dma[MTK_DMA_SIZE - 2];
+	ring->last_free = &ring->dma[MTK_DMA_SIZE - 1];
 	ring->thresh = MAX_SKB_FRAGS;
 
 	/* make sure that all changes to the dma ring are flushed before we
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 15/22] net-next: mediatek: only wake the queue if it is stopped
  2016-05-09 10:03 [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping John Crispin
                   ` (11 preceding siblings ...)
  2016-05-09 10:04 ` [PATCH V2 13/22] net-next: mediatek: increase watchdog_timeo John Crispin
@ 2016-05-09 10:04 ` John Crispin
  2016-05-09 10:04 ` [PATCH V2 17/22] net-next: mediatek: remove superfluous register reads John Crispin
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:04 UTC (permalink / raw)
  To: davem; +Cc: nbd, netdev, linux-mediatek, John Crispin

The current code unconditionally wakes up the queue at the end of each
tx_poll action. Change the code to only wake up the queues if any of
them have actually been stopped before.

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |   17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 9f4b533..7f42178 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -703,6 +703,20 @@ static inline int mtk_cal_txd_req(struct sk_buff *skb)
 	return nfrags;
 }
 
+static int mtk_queue_stopped(struct mtk_eth *eth)
+{
+	int i;
+
+	for (i = 0; i < MTK_MAC_COUNT; i++) {
+		if (!eth->netdev[i])
+			continue;
+		if (netif_queue_stopped(eth->netdev[i]))
+			return 1;
+	}
+
+	return 0;
+}
+
 static void mtk_wake_queue(struct mtk_eth *eth)
 {
 	int i;
@@ -947,7 +961,8 @@ static int mtk_poll_tx(struct mtk_eth *eth, int budget, bool *tx_again)
 	if (!total)
 		return 0;
 
-	if (atomic_read(&ring->free_count) > ring->thresh)
+	if (mtk_queue_stopped(eth) &&
+	    (atomic_read(&ring->free_count) > ring->thresh))
 		mtk_wake_queue(eth);
 
 	return total;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 16/22] net-next: mediatek: remove superfluous queue wake up call
       [not found] ` <1462788254-40572-1-git-send-email-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
  2016-05-09 10:04   ` [PATCH V2 12/22] net-next: mediatek: fix threshold value John Crispin
  2016-05-09 10:04   ` [PATCH V2 14/22] net-next: mediatek: fix off by one in the TX ring allocation John Crispin
@ 2016-05-09 10:04   ` John Crispin
  2016-05-09 10:04   ` [PATCH V2 18/22] net-next: mediatek: don't use intermediate variables to store IRQ masks John Crispin
  2016-05-09 10:04   ` [PATCH V2 20/22] net-next: mediatek: add support for IRQ grouping John Crispin
  4 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:04 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, John Crispin,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, nbd-Vt+b4OUoWG0

The code checks if the queue should be stopped because we are below the
threshold of free descriptors only to check if it should be started again.
If we do end up in a state where we are at the threshold limit, it makes
more sense to just stop the queue and wait for the next IRQ to trigger the
TX housekeeping again. There is no rush in enqueuing the next packet, it
needs to wait for all the others in the queue to be dispatched first
anyway.

Signed-off-by: John Crispin <john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |    7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 7f42178..74375a1 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -782,12 +782,9 @@ static int mtk_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (mtk_tx_map(skb, dev, tx_num, ring, gso) < 0)
 		goto drop;
 
-	if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) {
+	if (unlikely(atomic_read(&ring->free_count) <= ring->thresh))
 		mtk_stop_queue(eth);
-		if (unlikely(atomic_read(&ring->free_count) >
-			     ring->thresh))
-			mtk_wake_queue(eth);
-	}
+
 	spin_unlock_irqrestore(&eth->page_lock, flags);
 
 	return NETDEV_TX_OK;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 17/22] net-next: mediatek: remove superfluous register reads
  2016-05-09 10:03 [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping John Crispin
                   ` (12 preceding siblings ...)
  2016-05-09 10:04 ` [PATCH V2 15/22] net-next: mediatek: only wake the queue if it is stopped John Crispin
@ 2016-05-09 10:04 ` John Crispin
       [not found] ` <1462788254-40572-1-git-send-email-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:04 UTC (permalink / raw)
  To: davem; +Cc: nbd, netdev, linux-mediatek, John Crispin

The driver was originally written for MIPS based SoC. These required the
IRQ mask register to be read after writing it to ensure that the content
was actually applied. As this version only works on ARM based SoC, we can
safely remove the 2 reads as they ware not required.

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |    4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 74375a1..464a8ec 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -322,8 +322,6 @@ static inline void mtk_irq_disable(struct mtk_eth *eth, u32 mask)
 
 	val = mtk_r32(eth, MTK_QDMA_INT_MASK);
 	mtk_w32(eth, val & ~mask, MTK_QDMA_INT_MASK);
-	/* flush write */
-	mtk_r32(eth, MTK_QDMA_INT_MASK);
 }
 
 static inline void mtk_irq_enable(struct mtk_eth *eth, u32 mask)
@@ -332,8 +330,6 @@ static inline void mtk_irq_enable(struct mtk_eth *eth, u32 mask)
 
 	val = mtk_r32(eth, MTK_QDMA_INT_MASK);
 	mtk_w32(eth, val | mask, MTK_QDMA_INT_MASK);
-	/* flush write */
-	mtk_r32(eth, MTK_QDMA_INT_MASK);
 }
 
 static int mtk_set_mac_address(struct net_device *dev, void *p)
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 18/22] net-next: mediatek: don't use intermediate variables to store IRQ masks
       [not found] ` <1462788254-40572-1-git-send-email-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
                     ` (2 preceding siblings ...)
  2016-05-09 10:04   ` [PATCH V2 16/22] net-next: mediatek: remove superfluous queue wake up call John Crispin
@ 2016-05-09 10:04   ` John Crispin
  2016-05-09 10:04   ` [PATCH V2 20/22] net-next: mediatek: add support for IRQ grouping John Crispin
  4 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:04 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, John Crispin,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, nbd-Vt+b4OUoWG0

The code currently uses variables to store and never modify the bit masks
of interrupts. This is legacy code from an early version of the driver
that supported MIPS based SoCs where the IRQ bits depended on the actual
SoC. As the bits are the same for all ARM based SoC using this driver we
can remove the intermediate variables.

Signed-off-by: John Crispin <john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |   22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 464a8ec..5c20fbf 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -793,7 +793,7 @@ drop:
 }
 
 static int mtk_poll_rx(struct napi_struct *napi, int budget,
-		       struct mtk_eth *eth, u32 rx_intr)
+		       struct mtk_eth *eth)
 {
 	struct mtk_rx_ring *ring = &eth->rx_ring;
 	int idx = ring->calc_idx;
@@ -881,7 +881,7 @@ release_desc:
 	}
 
 	if (done < budget)
-		mtk_w32(eth, rx_intr, MTK_QMTK_INT_STATUS);
+		mtk_w32(eth, MTK_RX_DONE_INT, MTK_QMTK_INT_STATUS);
 
 	return done;
 }
@@ -964,28 +964,26 @@ static int mtk_poll_tx(struct mtk_eth *eth, int budget, bool *tx_again)
 static int mtk_poll(struct napi_struct *napi, int budget)
 {
 	struct mtk_eth *eth = container_of(napi, struct mtk_eth, rx_napi);
-	u32 status, status2, mask, tx_intr, rx_intr, status_intr;
+	u32 status, status2, mask;
 	int tx_done, rx_done;
 	bool tx_again = false;
 
 	status = mtk_r32(eth, MTK_QMTK_INT_STATUS);
 	status2 = mtk_r32(eth, MTK_INT_STATUS2);
-	tx_intr = MTK_TX_DONE_INT;
-	rx_intr = MTK_RX_DONE_INT;
-	status_intr = (MTK_GDM1_AF | MTK_GDM2_AF);
 	tx_done = 0;
 	rx_done = 0;
 	tx_again = 0;
 
-	if (status & tx_intr)
+	if (status & MTK_TX_DONE_INT)
 		tx_done = mtk_poll_tx(eth, budget, &tx_again);
 
-	if (status & rx_intr)
-		rx_done = mtk_poll_rx(napi, budget, eth, rx_intr);
+	if (status & MTK_RX_DONE_INT)
+		rx_done = mtk_poll_rx(napi, budget, eth);
 
-	if (unlikely(status2 & status_intr)) {
+	if (unlikely(status2 & (MTK_GDM1_AF | MTK_GDM2_AF))) {
 		mtk_stats_update(eth);
-		mtk_w32(eth, status_intr, MTK_INT_STATUS2);
+		mtk_w32(eth, (MTK_GDM1_AF | MTK_GDM2_AF),
+			MTK_INT_STATUS2);
 	}
 
 	if (unlikely(netif_msg_intr(eth))) {
@@ -1003,7 +1001,7 @@ static int mtk_poll(struct napi_struct *napi, int budget)
 		return budget;
 
 	napi_complete(napi);
-	mtk_irq_enable(eth, tx_intr | rx_intr);
+	mtk_irq_enable(eth, MTK_RX_DONE_INT | MTK_RX_DONE_INT);
 
 	return rx_done;
 }
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 19/22] net-next: mediatek: add IRQ locking
  2016-05-09 10:03 [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping John Crispin
                   ` (14 preceding siblings ...)
       [not found] ` <1462788254-40572-1-git-send-email-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
@ 2016-05-09 10:04 ` John Crispin
  2016-05-09 10:04 ` [PATCH V2 21/22] net-next: mediatek: change my email address John Crispin
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:04 UTC (permalink / raw)
  To: davem; +Cc: nbd, netdev, linux-mediatek, John Crispin

The code that enables and disables IRQs is missing proper locking. After
adding the IRQ separation patch and routing the putting the RX and TX IRQs
on different cores we experienced IRQ stalls. Fix this by adding proper
locking. We use a dedicated lock to reduce the latency if the IRQ code.
Otherwise it might wait for bottom code to finish before reenabling or
disabling IRQs.

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |    7 +++++++
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |    1 +
 2 files changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 5c20fbf..a738221 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -318,18 +318,24 @@ static void mtk_mdio_cleanup(struct mtk_eth *eth)
 
 static inline void mtk_irq_disable(struct mtk_eth *eth, u32 mask)
 {
+	unsigned long flags;
 	u32 val;
 
+	spin_lock_irqsave(&eth->irq_lock, flags);
 	val = mtk_r32(eth, MTK_QDMA_INT_MASK);
 	mtk_w32(eth, val & ~mask, MTK_QDMA_INT_MASK);
+	spin_unlock_irqrestore(&eth->irq_lock, flags);
 }
 
 static inline void mtk_irq_enable(struct mtk_eth *eth, u32 mask)
 {
+	unsigned long flags;
 	u32 val;
 
+	spin_lock_irqsave(&eth->irq_lock, flags);
 	val = mtk_r32(eth, MTK_QDMA_INT_MASK);
 	mtk_w32(eth, val | mask, MTK_QDMA_INT_MASK);
+	spin_unlock_irqrestore(&eth->irq_lock, flags);
 }
 
 static int mtk_set_mac_address(struct net_device *dev, void *p)
@@ -1757,6 +1763,7 @@ static int mtk_probe(struct platform_device *pdev)
 		return PTR_ERR(eth->base);
 
 	spin_lock_init(&eth->page_lock);
+	spin_lock_init(&eth->irq_lock);
 
 	eth->ethsys = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
 						      "mediatek,ethsys");
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index a5eb7c6..3159d2a 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -373,6 +373,7 @@ struct mtk_eth {
 	void __iomem			*base;
 	struct reset_control		*rstc;
 	spinlock_t			page_lock;
+	spinlock_t			irq_lock;
 	struct net_device		dummy_dev;
 	struct net_device		*netdev[MTK_MAX_DEVS];
 	struct mtk_mac			*mac[MTK_MAX_DEVS];
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 20/22] net-next: mediatek: add support for IRQ grouping
       [not found] ` <1462788254-40572-1-git-send-email-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
                     ` (3 preceding siblings ...)
  2016-05-09 10:04   ` [PATCH V2 18/22] net-next: mediatek: don't use intermediate variables to store IRQ masks John Crispin
@ 2016-05-09 10:04   ` John Crispin
  4 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:04 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, John Crispin,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, nbd-Vt+b4OUoWG0

The ethernet core has 3 IRQs. using the IRQ grouping registers we are able
to separate TX and RX IRQs, which allows us to service them on separate
cores. This patch splits the irq handler into 2 separate functions, one for
TX and another for RX. The TX housekeeping is split out into its own NAPI
handler.

Signed-off-by: John Crispin <john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |  156 +++++++++++++++++----------
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |   15 ++-
 2 files changed, 111 insertions(+), 60 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index a738221..74cb234 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -892,14 +892,13 @@ release_desc:
 	return done;
 }
 
-static int mtk_poll_tx(struct mtk_eth *eth, int budget, bool *tx_again)
+static int mtk_poll_tx(struct mtk_eth *eth, int budget)
 {
 	struct mtk_tx_ring *ring = &eth->tx_ring;
 	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 bytes = 0, done = 0;
 	u32 cpu, dma;
 	static int condition;
 	int i;
@@ -951,63 +950,82 @@ static int mtk_poll_tx(struct mtk_eth *eth, int budget, bool *tx_again)
 		netdev_completed_queue(eth->netdev[i], done, bytes);
 	}
 
-	/* read hw index again make sure no new tx packet */
-	if (cpu != dma || cpu != mtk_r32(eth, MTK_QTX_DRX_PTR))
-		*tx_again = true;
-	else
-		mtk_w32(eth, MTK_TX_DONE_INT, MTK_QMTK_INT_STATUS);
-
-	if (!total)
-		return 0;
-
 	if (mtk_queue_stopped(eth) &&
 	    (atomic_read(&ring->free_count) > ring->thresh))
 		mtk_wake_queue(eth);
 
-	return total;
+	return done;
 }
 
-static int mtk_poll(struct napi_struct *napi, int budget)
+static void mtk_handle_status_irq(struct mtk_eth *eth)
 {
-	struct mtk_eth *eth = container_of(napi, struct mtk_eth, rx_napi);
-	u32 status, status2, mask;
-	int tx_done, rx_done;
-	bool tx_again = false;
-
-	status = mtk_r32(eth, MTK_QMTK_INT_STATUS);
-	status2 = mtk_r32(eth, MTK_INT_STATUS2);
-	tx_done = 0;
-	rx_done = 0;
-	tx_again = 0;
-
-	if (status & MTK_TX_DONE_INT)
-		tx_done = mtk_poll_tx(eth, budget, &tx_again);
-
-	if (status & MTK_RX_DONE_INT)
-		rx_done = mtk_poll_rx(napi, budget, eth);
+	u32 status2 = mtk_r32(eth, MTK_INT_STATUS2);
 
 	if (unlikely(status2 & (MTK_GDM1_AF | MTK_GDM2_AF))) {
 		mtk_stats_update(eth);
 		mtk_w32(eth, (MTK_GDM1_AF | MTK_GDM2_AF),
 			MTK_INT_STATUS2);
 	}
+}
+
+static int mtk_napi_tx(struct napi_struct *napi, int budget)
+{
+	struct mtk_eth *eth = container_of(napi, struct mtk_eth, tx_napi);
+	u32 status, mask;
+	int tx_done = 0;
+
+	mtk_handle_status_irq(eth);
+	mtk_w32(eth, MTK_TX_DONE_INT, MTK_QMTK_INT_STATUS);
+	tx_done = mtk_poll_tx(eth, budget);
+
+	if (unlikely(netif_msg_intr(eth))) {
+		status = mtk_r32(eth, MTK_QMTK_INT_STATUS);
+		mask = mtk_r32(eth, MTK_QDMA_INT_MASK);
+		dev_info(eth->dev,
+			 "done tx %d, intr 0x%08x/0x%x\n",
+			 tx_done, status, mask);
+	}
+
+	if (tx_done == budget)
+		return budget;
+
+	status = mtk_r32(eth, MTK_QMTK_INT_STATUS);
+	if (status & MTK_TX_DONE_INT)
+		return budget;
+
+	napi_complete(napi);
+	mtk_irq_enable(eth, MTK_TX_DONE_INT);
+
+	return tx_done;
+}
+
+static int mtk_napi_rx(struct napi_struct *napi, int budget)
+{
+	struct mtk_eth *eth = container_of(napi, struct mtk_eth, rx_napi);
+	u32 status, mask;
+	int rx_done = 0;
+
+	mtk_handle_status_irq(eth);
+	mtk_w32(eth, MTK_RX_DONE_INT, MTK_QMTK_INT_STATUS);
+	rx_done = mtk_poll_rx(napi, budget, eth);
 
 	if (unlikely(netif_msg_intr(eth))) {
+		status = mtk_r32(eth, MTK_QMTK_INT_STATUS);
 		mask = mtk_r32(eth, MTK_QDMA_INT_MASK);
-		netdev_info(eth->netdev[0],
-			    "done tx %d, rx %d, intr 0x%08x/0x%x\n",
-			    tx_done, rx_done, status, mask);
+		dev_info(eth->dev,
+			 "done rx %d, intr 0x%08x/0x%x\n",
+			 rx_done, status, mask);
 	}
 
-	if (tx_again || rx_done == budget)
+	if (rx_done == budget)
 		return budget;
 
 	status = mtk_r32(eth, MTK_QMTK_INT_STATUS);
-	if (status & (tx_intr | rx_intr))
+	if (status & MTK_RX_DONE_INT)
 		return budget;
 
 	napi_complete(napi);
-	mtk_irq_enable(eth, MTK_RX_DONE_INT | MTK_RX_DONE_INT);
+	mtk_irq_enable(eth, MTK_RX_DONE_INT);
 
 	return rx_done;
 }
@@ -1243,22 +1261,26 @@ static void mtk_tx_timeout(struct net_device *dev)
 	schedule_work(&eth->pending_work);
 }
 
-static irqreturn_t mtk_handle_irq(int irq, void *_eth)
+static irqreturn_t mtk_handle_irq_rx(int irq, void *_eth)
 {
 	struct mtk_eth *eth = _eth;
-	u32 status;
 
-	status = mtk_r32(eth, MTK_QMTK_INT_STATUS);
-	if (unlikely(!status))
-		return IRQ_NONE;
+	if (likely(napi_schedule_prep(&eth->rx_napi))) {
+		__napi_schedule(&eth->rx_napi);
+		mtk_irq_disable(eth, MTK_RX_DONE_INT);
+	}
 
-	if (likely(status & (MTK_RX_DONE_INT | MTK_TX_DONE_INT))) {
-		if (likely(napi_schedule_prep(&eth->rx_napi)))
-			__napi_schedule(&eth->rx_napi);
-	} else {
-		mtk_w32(eth, status, MTK_QMTK_INT_STATUS);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t mtk_handle_irq_tx(int irq, void *_eth)
+{
+	struct mtk_eth *eth = _eth;
+
+	if (likely(napi_schedule_prep(&eth->tx_napi))) {
+		__napi_schedule(&eth->tx_napi);
+		mtk_irq_disable(eth, MTK_TX_DONE_INT);
 	}
-	mtk_irq_disable(eth, (MTK_RX_DONE_INT | MTK_TX_DONE_INT));
 
 	return IRQ_HANDLED;
 }
@@ -1271,7 +1293,7 @@ static void mtk_poll_controller(struct net_device *dev)
 	u32 int_mask = MTK_TX_DONE_INT | MTK_RX_DONE_INT;
 
 	mtk_irq_disable(eth, int_mask);
-	mtk_handle_irq(dev->irq, dev);
+	mtk_handle_irq(dev->irq[0], dev);
 	mtk_irq_enable(eth, int_mask);
 }
 #endif
@@ -1307,6 +1329,7 @@ static int mtk_open(struct net_device *dev)
 		if (err)
 			return err;
 
+		napi_enable(&eth->tx_napi);
 		napi_enable(&eth->rx_napi);
 		mtk_irq_enable(eth, MTK_TX_DONE_INT | MTK_RX_DONE_INT);
 	}
@@ -1355,6 +1378,7 @@ static int mtk_stop(struct net_device *dev)
 		return 0;
 
 	mtk_irq_disable(eth, MTK_TX_DONE_INT | MTK_RX_DONE_INT);
+	napi_disable(&eth->tx_napi);
 	napi_disable(&eth->rx_napi);
 
 	mtk_stop_dma(eth, MTK_QDMA_GLO_CFG);
@@ -1392,7 +1416,11 @@ static int __init mtk_hw_init(struct mtk_eth *eth)
 	/* Enable RX VLan Offloading */
 	mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
 
-	err = devm_request_irq(eth->dev, eth->irq, mtk_handle_irq, 0,
+	err = devm_request_irq(eth->dev, eth->irq[1], mtk_handle_irq_tx, 0,
+			       dev_name(eth->dev), eth);
+	if (err)
+		return err;
+	err = devm_request_irq(eth->dev, eth->irq[2], mtk_handle_irq_rx, 0,
 			       dev_name(eth->dev), eth);
 	if (err)
 		return err;
@@ -1408,7 +1436,11 @@ static int __init mtk_hw_init(struct mtk_eth *eth)
 	mtk_w32(eth, 0, MTK_RST_GL);
 
 	/* FE int grouping */
-	mtk_w32(eth, 0, MTK_FE_INT_GRP);
+	mtk_w32(eth, MTK_TX_DONE_INT, MTK_PDMA_INT_GRP1);
+	mtk_w32(eth, MTK_RX_DONE_INT, MTK_PDMA_INT_GRP2);
+	mtk_w32(eth, MTK_TX_DONE_INT, MTK_QDMA_INT_GRP1);
+	mtk_w32(eth, MTK_RX_DONE_INT, MTK_QDMA_INT_GRP2);
+	mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
 
 	for (i = 0; i < 2; i++) {
 		u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
@@ -1456,7 +1488,9 @@ static void mtk_uninit(struct net_device *dev)
 	phy_disconnect(mac->phy_dev);
 	mtk_mdio_cleanup(eth);
 	mtk_irq_disable(eth, ~0);
-	free_irq(dev->irq, dev);
+	free_irq(eth->irq[0], dev);
+	free_irq(eth->irq[1], dev);
+	free_irq(eth->irq[2], dev);
 }
 
 static int mtk_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -1730,10 +1764,10 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
 		dev_err(eth->dev, "error bringing up device\n");
 		goto free_netdev;
 	}
-	eth->netdev[id]->irq = eth->irq;
+	eth->netdev[id]->irq = eth->irq[0];
 	netif_info(eth, probe, eth->netdev[id],
 		   "mediatek frame engine at 0x%08lx, irq %d\n",
-		   eth->netdev[id]->base_addr, eth->netdev[id]->irq);
+		   eth->netdev[id]->base_addr, eth->irq[0]);
 
 	return 0;
 
@@ -1750,6 +1784,7 @@ static int mtk_probe(struct platform_device *pdev)
 	struct mtk_soc_data *soc;
 	struct mtk_eth *eth;
 	int err;
+	int i;
 
 	match = of_match_device(of_mtk_match, &pdev->dev);
 	soc = (struct mtk_soc_data *)match->data;
@@ -1785,10 +1820,12 @@ static int mtk_probe(struct platform_device *pdev)
 		return PTR_ERR(eth->rstc);
 	}
 
-	eth->irq = platform_get_irq(pdev, 0);
-	if (eth->irq < 0) {
-		dev_err(&pdev->dev, "no IRQ resource found\n");
-		return -ENXIO;
+	for (i = 0; i < 3; i++) {
+		eth->irq[i] = platform_get_irq(pdev, i);
+		if (eth->irq[i] < 0) {
+			dev_err(&pdev->dev, "no IRQ%d resource found\n", i);
+			return -ENXIO;
+		}
 	}
 
 	eth->clk_ethif = devm_clk_get(&pdev->dev, "ethif");
@@ -1829,7 +1866,9 @@ static int mtk_probe(struct platform_device *pdev)
 	 * for NAPI to work
 	 */
 	init_dummy_netdev(&eth->dummy_dev);
-	netif_napi_add(&eth->dummy_dev, &eth->rx_napi, mtk_poll,
+	netif_napi_add(&eth->dummy_dev, &eth->tx_napi, mtk_napi_tx,
+		       MTK_NAPI_WEIGHT);
+	netif_napi_add(&eth->dummy_dev, &eth->rx_napi, mtk_napi_rx,
 		       MTK_NAPI_WEIGHT);
 
 	platform_set_drvdata(pdev, eth);
@@ -1850,6 +1889,7 @@ static int mtk_remove(struct platform_device *pdev)
 	clk_disable_unprepare(eth->clk_gp1);
 	clk_disable_unprepare(eth->clk_gp2);
 
+	netif_napi_del(&eth->tx_napi);
 	netif_napi_del(&eth->rx_napi);
 	mtk_cleanup(eth);
 	platform_set_drvdata(pdev, NULL);
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 3159d2a..f82e3ac 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -68,6 +68,10 @@
 /* Unicast Filter MAC Address Register - High */
 #define MTK_GDMA_MAC_ADRH(x)	(0x50C + (x * 0x1000))
 
+/* PDMA Interrupt grouping registers */
+#define MTK_PDMA_INT_GRP1	0xa50
+#define MTK_PDMA_INT_GRP2	0xa54
+
 /* QDMA TX Queue Configuration Registers */
 #define MTK_QTX_CFG(x)		(0x1800 + (x * 0x10))
 #define QDMA_RES_THRES		4
@@ -125,6 +129,11 @@
 #define MTK_TX_DONE_INT		(MTK_TX_DONE_INT0 | MTK_TX_DONE_INT1 | \
 				 MTK_TX_DONE_INT2 | MTK_TX_DONE_INT3)
 
+/* QDMA Interrupt grouping registers */
+#define MTK_QDMA_INT_GRP1	0x1a20
+#define MTK_QDMA_INT_GRP2	0x1a24
+#define MTK_RLS_DONE_INT	BIT(0)
+
 /* QDMA Interrupt Status Register */
 #define MTK_QDMA_INT_MASK	0x1A1C
 
@@ -356,7 +365,8 @@ struct mtk_rx_ring {
  * @dma_refcnt:		track how many netdevs are using the DMA engine
  * @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_napi:		The NAPI struct
+ * @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
  * @phy_scratch_ring:	physical address of scratch_ring
  * @scratch_head:	The scratch memory that scratch_ring points to.
@@ -377,7 +387,7 @@ struct mtk_eth {
 	struct net_device		dummy_dev;
 	struct net_device		*netdev[MTK_MAX_DEVS];
 	struct mtk_mac			*mac[MTK_MAX_DEVS];
-	int				irq;
+	int				irq[3];
 	u32				msg_enable;
 	unsigned long			sysclk;
 	struct regmap			*ethsys;
@@ -385,6 +395,7 @@ struct mtk_eth {
 	atomic_t			dma_refcnt;
 	struct mtk_tx_ring		tx_ring;
 	struct mtk_rx_ring		rx_ring;
+	struct napi_struct		tx_napi;
 	struct napi_struct		rx_napi;
 	struct mtk_tx_dma		*scratch_ring;
 	dma_addr_t			phy_scratch_ring;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 21/22] net-next: mediatek: change my email address
  2016-05-09 10:03 [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping John Crispin
                   ` (15 preceding siblings ...)
  2016-05-09 10:04 ` [PATCH V2 19/22] net-next: mediatek: add IRQ locking John Crispin
@ 2016-05-09 10:04 ` John Crispin
  2016-05-09 10:04 ` [PATCH V2 22/22] MAINTAINERS: " John Crispin
  2016-05-09 16:02 ` [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping David Miller
  18 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:04 UTC (permalink / raw)
  To: davem; +Cc: nbd, netdev, linux-mediatek, John Crispin

The old address is no longer valid. Use the my new one instead.

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 74cb234..32bf54e 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -7,7 +7,7 @@
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *   GNU General Public License for more details.
  *
- *   Copyright (C) 2009-2016 John Crispin <blogic@openwrt.org>
+ *   Copyright (C) 2009-2016 John Crispin <john@phrozen.org>
  *   Copyright (C) 2009-2016 Felix Fietkau <nbd@openwrt.org>
  *   Copyright (C) 2013-2016 Michael Lee <igvtee@gmail.com>
  */
@@ -1915,5 +1915,5 @@ static struct platform_driver mtk_driver = {
 module_platform_driver(mtk_driver);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
+MODULE_AUTHOR("John Crispin <john@phrozen.org>");
 MODULE_DESCRIPTION("Ethernet driver for MediaTek SoC");
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH V2 22/22] MAINTAINERS: change my email address
  2016-05-09 10:03 [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping John Crispin
                   ` (16 preceding siblings ...)
  2016-05-09 10:04 ` [PATCH V2 21/22] net-next: mediatek: change my email address John Crispin
@ 2016-05-09 10:04 ` John Crispin
  2016-05-09 16:02 ` [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping David Miller
  18 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 10:04 UTC (permalink / raw)
  To: davem; +Cc: nbd, netdev, linux-mediatek, John Crispin

The old address is no longer valid. Use the my new one instead.

Signed-off-by: John Crispin <john@phrozen.org>
---
 MAINTAINERS |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index e425912..68e6b1e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7125,7 +7125,7 @@ F:	include/uapi/linux/uvcvideo.h
 
 MEDIATEK ETHERNET DRIVER
 M:	Felix Fietkau <nbd@openwrt.org>
-M:	John Crispin <blogic@openwrt.org>
+M:	John Crispin <john@phrozen.org>
 L:	netdev@vger.kernel.org
 S:	Maintained
 F:	drivers/net/ethernet/mediatek/
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [PATCH V2 01/22] net-next: mediatek: use mdiobus_free() in favour of kfree()
  2016-05-09 10:03 ` [PATCH V2 01/22] net-next: mediatek: use mdiobus_free() in favour of kfree() John Crispin
@ 2016-05-09 12:07   ` Andrew Lunn
  0 siblings, 0 replies; 29+ messages in thread
From: Andrew Lunn @ 2016-05-09 12:07 UTC (permalink / raw)
  To: John Crispin; +Cc: davem, nbd, netdev, linux-mediatek

On Mon, May 09, 2016 at 12:03:53PM +0200, John Crispin wrote:
> The driver currently uses kfree() to clear the mii_bus. This is not the
> correct way to clear the memory and mdiobus_free() should be used instead.
> This patch fixes the two instances where this happens in the driver.
> 
> Reported-by: Andrew Lunn <andrew@lunn.ch>
> Signed-off-by: John Crispin <john@phrozen.org>

Thanks John

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

       Andrew

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH V2 04/22] net-next: mediatek: properly handle RGMII modes
  2016-05-09 10:03 ` [PATCH V2 04/22] net-next: mediatek: properly handle RGMII modes John Crispin
@ 2016-05-09 12:09   ` Andrew Lunn
  0 siblings, 0 replies; 29+ messages in thread
From: Andrew Lunn @ 2016-05-09 12:09 UTC (permalink / raw)
  To: John Crispin; +Cc: davem, nbd, netdev, linux-mediatek

On Mon, May 09, 2016 at 12:03:56PM +0200, John Crispin wrote:
> If an external Gigabit PHY is connected to either of the MACs we need to
> be able to tell the PHY to use a delay. Not doing so will result in heavy
> packet loss and/or data corruption when using PHYs such as the IC+ IP1001.
> We tell the PHY which MII delay mode to use via the devictree.
> 
> The ethernet driver needs to be adapted to handle all 3 rgmii-*id modes
> in the same way as normal rgmii when setting up the MAC.
> 
> Signed-off-by: John Crispin <john@phrozen.org>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

	     Andrew

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping
  2016-05-09 10:03 [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping John Crispin
                   ` (17 preceding siblings ...)
  2016-05-09 10:04 ` [PATCH V2 22/22] MAINTAINERS: " John Crispin
@ 2016-05-09 16:02 ` David Miller
  2016-05-09 16:25   ` John Crispin
  18 siblings, 1 reply; 29+ messages in thread
From: David Miller @ 2016-05-09 16:02 UTC (permalink / raw)
  To: john; +Cc: nbd, netdev, linux-mediatek

From: John Crispin <john@phrozen.org>
Date: Mon,  9 May 2016 12:03:52 +0200

> This series introduces a number of fixes that we stumbled across while
> doing more performance testing and code level reviewing. Additionally
> it improves the PHY setup code adding support for fixed phys, asymmetric
> flow control and gigabit feature advertisement. Next the series adds a
> support for IRQ grouping, allowing use to separate the IRQs onto more than
> one core using irq affinity. The last two patches wrap up the series by
> updating my email address.

This is too many patches to submit as a unit at one time.  Plus
this patch series contains lots of unrelated changes.

Split this up into logical units of related changes, and then submit
each smaller series one at a time, waiting each time for the current
series to be accepted before submitting the next one.

This is what I was trying to encourage you to do last time, I
hope what we expect is cleaerer now.

Thank you.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping
  2016-05-09 16:02 ` [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping David Miller
@ 2016-05-09 16:25   ` John Crispin
  2016-05-09 16:28     ` David Miller
  0 siblings, 1 reply; 29+ messages in thread
From: John Crispin @ 2016-05-09 16:25 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-mediatek, nbd



On 09/05/2016 18:02, David Miller wrote:
> From: John Crispin <john@phrozen.org>
> Date: Mon,  9 May 2016 12:03:52 +0200
> 
>> This series introduces a number of fixes that we stumbled across while
>> doing more performance testing and code level reviewing. Additionally
>> it improves the PHY setup code adding support for fixed phys, asymmetric
>> flow control and gigabit feature advertisement. Next the series adds a
>> support for IRQ grouping, allowing use to separate the IRQs onto more than
>> one core using irq affinity. The last two patches wrap up the series by
>> updating my email address.
> 
> This is too many patches to submit as a unit at one time.  Plus
> this patch series contains lots of unrelated changes.
> 
> Split this up into logical units of related changes, and then submit
> each smaller series one at a time, waiting each time for the current
> series to be accepted before submitting the next one.
> 
> This is what I was trying to encourage you to do last time, I
> hope what we expect is cleaerer now.
> 
> Thank you.

Hi,

before we do another few tries, I would send series split up as follows

1) fixes - ~12 patches
2) phy related stuff - 5 patches
3) irq grouping/fixes - 4 patches

or would you want me to split he ~12 fixes patches up aswell ?

	John

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping
  2016-05-09 16:25   ` John Crispin
@ 2016-05-09 16:28     ` David Miller
  2016-05-09 16:34       ` John Crispin
  0 siblings, 1 reply; 29+ messages in thread
From: David Miller @ 2016-05-09 16:28 UTC (permalink / raw)
  To: john; +Cc: netdev, linux-mediatek, nbd

From: John Crispin <john@phrozen.org>
Date: Mon, 9 May 2016 18:25:04 +0200

> before we do another few tries, I would send series split up as follows
> 
> 1) fixes - ~12 patches
> 2) phy related stuff - 5 patches
> 3) irq grouping/fixes - 4 patches

This looks fine.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping
  2016-05-09 16:28     ` David Miller
@ 2016-05-09 16:34       ` John Crispin
  0 siblings, 0 replies; 29+ messages in thread
From: John Crispin @ 2016-05-09 16:34 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-mediatek, nbd



On 09/05/2016 18:28, David Miller wrote:
> From: John Crispin <john@phrozen.org>
> Date: Mon, 9 May 2016 18:25:04 +0200
> 
>> before we do another few tries, I would send series split up as follows
>>
>> 1) fixes - ~12 patches
>> 2) phy related stuff - 5 patches
>> 3) irq grouping/fixes - 4 patches
> 
> This looks fine.
> 

I'll start with 2) as Andrew already did a review of those patches

sorry for the noise

	John

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2016-05-09 16:34 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-09 10:03 [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping John Crispin
2016-05-09 10:03 ` [PATCH V2 01/22] net-next: mediatek: use mdiobus_free() in favour of kfree() John Crispin
2016-05-09 12:07   ` Andrew Lunn
2016-05-09 10:03 ` [PATCH V2 02/22] net-next: mediatek: fix gigabit and flow control advertisement John Crispin
2016-05-09 10:03 ` [PATCH V2 03/22] net-next: mediatek: add fixed-phy support John Crispin
2016-05-09 10:03 ` [PATCH V2 04/22] net-next: mediatek: properly handle RGMII modes John Crispin
2016-05-09 12:09   ` Andrew Lunn
2016-05-09 10:03 ` [PATCH V2 05/22] net-next: mediatek: fix DQL support John Crispin
2016-05-09 10:03 ` [PATCH V2 06/22] net-next: mediatek: add missing return code check John Crispin
2016-05-09 10:03 ` [PATCH V2 07/22] net-next: mediatek: fix missing free of scratch memory John Crispin
2016-05-09 10:04 ` [PATCH V2 08/22] net-next: mediatek: invalid buffer lookup in mtk_tx_map() John Crispin
2016-05-09 10:04 ` [PATCH V2 09/22] net-next: mediatek: dropped rx packets are not being counted properly John Crispin
2016-05-09 10:04 ` [PATCH V2 10/22] net-next: mediatek: add next data pointer coherency protection John Crispin
2016-05-09 10:04 ` [PATCH V2 11/22] net-next: mediatek: disable all interrupts during probe John Crispin
2016-05-09 10:04 ` [PATCH V2 13/22] net-next: mediatek: increase watchdog_timeo John Crispin
2016-05-09 10:04 ` [PATCH V2 15/22] net-next: mediatek: only wake the queue if it is stopped John Crispin
2016-05-09 10:04 ` [PATCH V2 17/22] net-next: mediatek: remove superfluous register reads John Crispin
     [not found] ` <1462788254-40572-1-git-send-email-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
2016-05-09 10:04   ` [PATCH V2 12/22] net-next: mediatek: fix threshold value John Crispin
2016-05-09 10:04   ` [PATCH V2 14/22] net-next: mediatek: fix off by one in the TX ring allocation John Crispin
2016-05-09 10:04   ` [PATCH V2 16/22] net-next: mediatek: remove superfluous queue wake up call John Crispin
2016-05-09 10:04   ` [PATCH V2 18/22] net-next: mediatek: don't use intermediate variables to store IRQ masks John Crispin
2016-05-09 10:04   ` [PATCH V2 20/22] net-next: mediatek: add support for IRQ grouping John Crispin
2016-05-09 10:04 ` [PATCH V2 19/22] net-next: mediatek: add IRQ locking John Crispin
2016-05-09 10:04 ` [PATCH V2 21/22] net-next: mediatek: change my email address John Crispin
2016-05-09 10:04 ` [PATCH V2 22/22] MAINTAINERS: " John Crispin
2016-05-09 16:02 ` [PATCH V2 00/22] net-next: mediatek: various fixes and IRQ grouping David Miller
2016-05-09 16:25   ` John Crispin
2016-05-09 16:28     ` David Miller
2016-05-09 16:34       ` John Crispin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.