linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next v2 0/9] add more features for mtk-star-emac
@ 2022-01-27  1:58 Biao Huang
  2022-01-27  1:58 ` [PATCH net-next v2 1/9] net: ethernet: mtk-star-emac: store bit_clk_div in compat structure Biao Huang
                   ` (8 more replies)
  0 siblings, 9 replies; 23+ messages in thread
From: Biao Huang @ 2022-01-27  1:58 UTC (permalink / raw)
  To: David Miller, Rob Herring, Bartosz Golaszewski, Fabien Parent
  Cc: Jakub Kicinski, Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Biao Huang, Yinghua Pan,
	srv_heupstream, Macpaul Lin

Changes in v2:
1. fix coding style as Bartosz's comments.
2. add reviewed-by as Bartosz's comments.

This series add more features for mtk-star-emac:
1. add reference clock pad selection for RMII;
2. add simple timing adjustment for RMII;
3. add support for MII;
4. add support for new IC MT8365;
5. separate tx/rx interrupt handling.

Biao Huang (8):
  net: ethernet: mtk-star-emac: modify IRQ trigger flags
  net: ethernet: mtk-star-emac: add support for MT8365 SoC
  dt-bindings: net: mtk-star-emac: add support for MT8365
  net: ethernet: mtk-star-emac: add clock pad selection for RMII
  net: ethernet: mtk-star-emac: add timing adjustment support
  dt-bindings: net: mtk-star-emac: add description for new  properties
  net: ethernet: mtk-star-emac: add support for MII interface
  net: ethernet: mtk-star-emac: separate tx/rx handling with two NAPIs

Fabien Parent (1):
  net: ethernet: mtk-star-emac: store bit_clk_div in compat structure

 .../bindings/net/mediatek,star-emac.yaml      |  17 +
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 477 ++++++++++++------
 2 files changed, 341 insertions(+), 153 deletions(-)

-- 
2.25.1



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

* [PATCH net-next v2 1/9] net: ethernet: mtk-star-emac: store bit_clk_div in compat structure
  2022-01-27  1:58 [PATCH net-next v2 0/9] add more features for mtk-star-emac Biao Huang
@ 2022-01-27  1:58 ` Biao Huang
  2022-01-27  2:23   ` Macpaul Lin
  2022-01-27  1:58 ` [PATCH net-next v2 2/9] net: ethernet: mtk-star-emac: modify IRQ trigger flags Biao Huang
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 23+ messages in thread
From: Biao Huang @ 2022-01-27  1:58 UTC (permalink / raw)
  To: David Miller, Rob Herring, Bartosz Golaszewski, Fabien Parent
  Cc: Jakub Kicinski, Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Biao Huang, Yinghua Pan,
	srv_heupstream, Macpaul Lin

From: Fabien Parent <fparent@baylibre.com>

Not all the SoC are using the same clock divider. Move the divider into
a compat structure specific to the SoCs.

Signed-off-by: Biao Huang <biao.huang@mediatek.com>
Signed-off-by: Fabien Parent <fparent@baylibre.com>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 23 +++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index 1d5dd2015453..7fd8ec0fc636 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/of_mdio.h>
 #include <linux/of_net.h>
 #include <linux/platform_device.h>
@@ -232,6 +233,10 @@ struct mtk_star_ring {
 	unsigned int tail;
 };
 
+struct mtk_star_compat {
+	unsigned char bit_clk_div;
+};
+
 struct mtk_star_priv {
 	struct net_device *ndev;
 
@@ -257,6 +262,8 @@ struct mtk_star_priv {
 	int duplex;
 	int pause;
 
+	const struct mtk_star_compat *compat_data;
+
 	/* Protects against concurrent descriptor access. */
 	spinlock_t lock;
 
@@ -899,7 +906,7 @@ static void mtk_star_init_config(struct mtk_star_priv *priv)
 	regmap_write(priv->regs, MTK_STAR_REG_SYS_CONF, val);
 	regmap_update_bits(priv->regs, MTK_STAR_REG_MAC_CLK_CONF,
 			   MTK_STAR_MSK_MAC_CLK_CONF,
-			   MTK_STAR_BIT_CLK_DIV_10);
+			   priv->compat_data->bit_clk_div);
 }
 
 static void mtk_star_set_mode_rmii(struct mtk_star_priv *priv)
@@ -1461,6 +1468,7 @@ static int mtk_star_probe(struct platform_device *pdev)
 
 	priv = netdev_priv(ndev);
 	priv->ndev = ndev;
+	priv->compat_data = of_device_get_match_data(&pdev->dev);
 	SET_NETDEV_DEV(ndev, dev);
 	platform_set_drvdata(pdev, ndev);
 
@@ -1556,10 +1564,17 @@ static int mtk_star_probe(struct platform_device *pdev)
 	return devm_register_netdev(dev, ndev);
 }
 
+static const struct mtk_star_compat mtk_star_mt8516_compat = {
+	.bit_clk_div = MTK_STAR_BIT_CLK_DIV_10,
+};
+
 static const struct of_device_id mtk_star_of_match[] = {
-	{ .compatible = "mediatek,mt8516-eth", },
-	{ .compatible = "mediatek,mt8518-eth", },
-	{ .compatible = "mediatek,mt8175-eth", },
+	{ .compatible = "mediatek,mt8516-eth",
+	  .data = &mtk_star_mt8516_compat },
+	{ .compatible = "mediatek,mt8518-eth",
+	  .data = &mtk_star_mt8516_compat },
+	{ .compatible = "mediatek,mt8175-eth",
+	  .data = &mtk_star_mt8516_compat },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, mtk_star_of_match);
-- 
2.25.1


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

* [PATCH net-next v2 2/9] net: ethernet: mtk-star-emac: modify IRQ trigger flags
  2022-01-27  1:58 [PATCH net-next v2 0/9] add more features for mtk-star-emac Biao Huang
  2022-01-27  1:58 ` [PATCH net-next v2 1/9] net: ethernet: mtk-star-emac: store bit_clk_div in compat structure Biao Huang
@ 2022-01-27  1:58 ` Biao Huang
  2022-01-27  1:58 ` [PATCH net-next v2 3/9] net: ethernet: mtk-star-emac: add support for MT8365 SoC Biao Huang
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 23+ messages in thread
From: Biao Huang @ 2022-01-27  1:58 UTC (permalink / raw)
  To: David Miller, Rob Herring, Bartosz Golaszewski, Fabien Parent
  Cc: Jakub Kicinski, Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Biao Huang, Yinghua Pan,
	srv_heupstream, Macpaul Lin

If the flags in request_irq() is IRQF_TRIGGER_NONE, the trigger method
is determined by "interrupt" property in dts.
So, modify the flag from IRQF_TRIGGER_FALLING to IRQF_TRIGGER_NONE.

Signed-off-by: Biao Huang <biao.huang@mediatek.com>
Signed-off-by: Yinghua Pan <ot_yinghua.pan@mediatek.com>
Reviewed-by: Bartosz Golaszewski <brgl@bgdev.pl>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index 7fd8ec0fc636..a8fbbbcd185b 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -959,7 +959,7 @@ static int mtk_star_enable(struct net_device *ndev)
 
 	/* Request the interrupt */
 	ret = request_irq(ndev->irq, mtk_star_handle_irq,
-			  IRQF_TRIGGER_FALLING, ndev->name, ndev);
+			  IRQF_TRIGGER_NONE, ndev->name, ndev);
 	if (ret)
 		goto err_free_skbs;
 
-- 
2.25.1


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

* [PATCH net-next v2 3/9] net: ethernet: mtk-star-emac: add support for MT8365 SoC
  2022-01-27  1:58 [PATCH net-next v2 0/9] add more features for mtk-star-emac Biao Huang
  2022-01-27  1:58 ` [PATCH net-next v2 1/9] net: ethernet: mtk-star-emac: store bit_clk_div in compat structure Biao Huang
  2022-01-27  1:58 ` [PATCH net-next v2 2/9] net: ethernet: mtk-star-emac: modify IRQ trigger flags Biao Huang
@ 2022-01-27  1:58 ` Biao Huang
  2022-01-27  2:22   ` Macpaul Lin
  2022-01-27  1:58 ` [PATCH net-next v2 4/9] dt-bindings: net: mtk-star-emac: add support for MT8365 Biao Huang
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 23+ messages in thread
From: Biao Huang @ 2022-01-27  1:58 UTC (permalink / raw)
  To: David Miller, Rob Herring, Bartosz Golaszewski, Fabien Parent
  Cc: Jakub Kicinski, Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Biao Huang, Yinghua Pan,
	srv_heupstream, Macpaul Lin

Add Ethernet driver support for MT8365 SoC.

Signed-off-by: Biao Huang <biao.huang@mediatek.com>
Signed-off-by: Yinghua Pan <ot_yinghua.pan@mediatek.com>
Signed-off-by: Fabien Parent <fparent@baylibre.com>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 75 ++++++++++++++++---
 1 file changed, 64 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index a8fbbbcd185b..a3884beaa3fe 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -151,6 +151,7 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
 #define MTK_STAR_REG_MAC_CLK_CONF		0x00ac
 #define MTK_STAR_MSK_MAC_CLK_CONF		GENMASK(7, 0)
 #define MTK_STAR_BIT_CLK_DIV_10			0x0a
+#define MTK_STAR_BIT_CLK_DIV_50			0x32
 
 /* Counter registers. */
 #define MTK_STAR_REG_C_RXOKPKT			0x0100
@@ -183,9 +184,11 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
 #define MTK_STAR_REG_C_RX_TWIST			0x0218
 
 /* Ethernet CFG Control */
-#define MTK_PERICFG_REG_NIC_CFG_CON		0x03c4
-#define MTK_PERICFG_MSK_NIC_CFG_CON_CFG_MII	GENMASK(3, 0)
-#define MTK_PERICFG_BIT_NIC_CFG_CON_RMII	BIT(0)
+#define MTK_PERICFG_REG_NIC_CFG0_CON		0x03c4
+#define MTK_PERICFG_REG_NIC_CFG1_CON		0x03c8
+#define MTK_PERICFG_REG_NIC_CFG_CON_V2		0x0c10
+#define MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF	GENMASK(3, 0)
+#define MTK_PERICFG_BIT_NIC_CFG_CON_RMII	1
 
 /* Represents the actual structure of descriptors used by the MAC. We can
  * reuse the same structure for both TX and RX - the layout is the same, only
@@ -234,6 +237,7 @@ struct mtk_star_ring {
 };
 
 struct mtk_star_compat {
+	int (*set_interface_mode)(struct net_device *ndev);
 	unsigned char bit_clk_div;
 };
 
@@ -909,13 +913,6 @@ static void mtk_star_init_config(struct mtk_star_priv *priv)
 			   priv->compat_data->bit_clk_div);
 }
 
-static void mtk_star_set_mode_rmii(struct mtk_star_priv *priv)
-{
-	regmap_update_bits(priv->pericfg, MTK_PERICFG_REG_NIC_CFG_CON,
-			   MTK_PERICFG_MSK_NIC_CFG_CON_CFG_MII,
-			   MTK_PERICFG_BIT_NIC_CFG_CON_RMII);
-}
-
 static int mtk_star_enable(struct net_device *ndev)
 {
 	struct mtk_star_priv *priv = netdev_priv(ndev);
@@ -1531,7 +1528,13 @@ static int mtk_star_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	mtk_star_set_mode_rmii(priv);
+	if (priv->compat_data->set_interface_mode) {
+		ret = priv->compat_data->set_interface_mode(ndev);
+		if (ret) {
+			dev_err(dev, "Failed to set phy interface, err = %d\n", ret);
+			return -EINVAL;
+		}
+	}
 
 	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
 	if (ret) {
@@ -1564,10 +1567,58 @@ static int mtk_star_probe(struct platform_device *pdev)
 	return devm_register_netdev(dev, ndev);
 }
 
+static int mt8516_set_interface_mode(struct net_device *ndev)
+{
+	struct mtk_star_priv *priv = netdev_priv(ndev);
+	struct device *dev = mtk_star_get_dev(priv);
+	unsigned int intf_val;
+
+	switch (priv->phy_intf) {
+	case PHY_INTERFACE_MODE_RMII:
+		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
+		break;
+	default:
+		dev_err(dev, "This interface not supported\n");
+		return -EINVAL;
+	}
+
+	return regmap_update_bits(priv->pericfg,
+				  MTK_PERICFG_REG_NIC_CFG0_CON,
+				  MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF,
+				  intf_val);
+}
+
+static int mt8365_set_interface_mode(struct net_device *ndev)
+{
+	struct mtk_star_priv *priv = netdev_priv(ndev);
+	struct device *dev = mtk_star_get_dev(priv);
+	unsigned int intf_val;
+
+	switch (priv->phy_intf) {
+	case PHY_INTERFACE_MODE_RMII:
+		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
+		break;
+	default:
+		dev_err(dev, "This interface not supported\n");
+		return -EINVAL;
+	}
+
+	return regmap_update_bits(priv->pericfg,
+				  MTK_PERICFG_REG_NIC_CFG_CON_V2,
+				  MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF,
+				  intf_val);
+}
+
 static const struct mtk_star_compat mtk_star_mt8516_compat = {
+	.set_interface_mode = mt8516_set_interface_mode,
 	.bit_clk_div = MTK_STAR_BIT_CLK_DIV_10,
 };
 
+static const struct mtk_star_compat mtk_star_mt8365_compat = {
+	.set_interface_mode = mt8365_set_interface_mode,
+	.bit_clk_div = MTK_STAR_BIT_CLK_DIV_50,
+};
+
 static const struct of_device_id mtk_star_of_match[] = {
 	{ .compatible = "mediatek,mt8516-eth",
 	  .data = &mtk_star_mt8516_compat },
@@ -1575,6 +1626,8 @@ static const struct of_device_id mtk_star_of_match[] = {
 	  .data = &mtk_star_mt8516_compat },
 	{ .compatible = "mediatek,mt8175-eth",
 	  .data = &mtk_star_mt8516_compat },
+	{ .compatible = "mediatek,mt8365-eth",
+	  .data = &mtk_star_mt8365_compat },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, mtk_star_of_match);
-- 
2.25.1


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

* [PATCH net-next v2 4/9] dt-bindings: net: mtk-star-emac: add support for MT8365
  2022-01-27  1:58 [PATCH net-next v2 0/9] add more features for mtk-star-emac Biao Huang
                   ` (2 preceding siblings ...)
  2022-01-27  1:58 ` [PATCH net-next v2 3/9] net: ethernet: mtk-star-emac: add support for MT8365 SoC Biao Huang
@ 2022-01-27  1:58 ` Biao Huang
  2022-02-09  3:35   ` Rob Herring
  2022-01-27  1:58 ` [PATCH net-next v2 5/9] net: ethernet: mtk-star-emac: add clock pad selection for RMII Biao Huang
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 23+ messages in thread
From: Biao Huang @ 2022-01-27  1:58 UTC (permalink / raw)
  To: David Miller, Rob Herring, Bartosz Golaszewski, Fabien Parent
  Cc: Jakub Kicinski, Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Biao Huang, Yinghua Pan,
	srv_heupstream, Macpaul Lin

Add binding document for Ethernet on MT8365.

Signed-off-by: Biao Huang <biao.huang@mediatek.com>
Reviewed-by: Bartosz Golaszewski <brgl@bgdev.pl>
---
 Documentation/devicetree/bindings/net/mediatek,star-emac.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml b/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
index e6a5ff208253..87a8b25b03a6 100644
--- a/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
+++ b/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
@@ -23,6 +23,7 @@ properties:
       - mediatek,mt8516-eth
       - mediatek,mt8518-eth
       - mediatek,mt8175-eth
+      - mediatek,mt8365-eth
 
   reg:
     maxItems: 1
-- 
2.25.1


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

* [PATCH net-next v2 5/9] net: ethernet: mtk-star-emac: add clock pad selection for RMII
  2022-01-27  1:58 [PATCH net-next v2 0/9] add more features for mtk-star-emac Biao Huang
                   ` (3 preceding siblings ...)
  2022-01-27  1:58 ` [PATCH net-next v2 4/9] dt-bindings: net: mtk-star-emac: add support for MT8365 Biao Huang
@ 2022-01-27  1:58 ` Biao Huang
  2022-01-27  2:26   ` Macpaul Lin
  2022-01-27  1:58 ` [PATCH net-next v2 6/9] net: ethernet: mtk-star-emac: add timing adjustment support Biao Huang
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 23+ messages in thread
From: Biao Huang @ 2022-01-27  1:58 UTC (permalink / raw)
  To: David Miller, Rob Herring, Bartosz Golaszewski, Fabien Parent
  Cc: Jakub Kicinski, Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Biao Huang, Yinghua Pan,
	srv_heupstream, Macpaul Lin

This patch add a new dts property named "mediatek,rmii-rxc" parsing
in driver, which will configure MAC to select which pin the RMII reference
clock is connected to, TXC or RXC.

TXC pad is the default reference clock pin. If user wants to use RXC pad
instead, add "mediatek,rmii-rxc" to corresponding device node.

Signed-off-by: Biao Huang <biao.huang@mediatek.com>
Signed-off-by: Yinghua Pan <ot_yinghua.pan@mediatek.com>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index a3884beaa3fe..d69f75661e75 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -189,6 +189,8 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
 #define MTK_PERICFG_REG_NIC_CFG_CON_V2		0x0c10
 #define MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF	GENMASK(3, 0)
 #define MTK_PERICFG_BIT_NIC_CFG_CON_RMII	1
+#define MTK_PERICFG_BIT_NIC_CFG_CON_CLK		BIT(0)
+#define MTK_PERICFG_BIT_NIC_CFG_CON_CLK_V2	BIT(8)
 
 /* Represents the actual structure of descriptors used by the MAC. We can
  * reuse the same structure for both TX and RX - the layout is the same, only
@@ -265,6 +267,7 @@ struct mtk_star_priv {
 	int speed;
 	int duplex;
 	int pause;
+	bool rmii_rxc;
 
 	const struct mtk_star_compat *compat_data;
 
@@ -1528,6 +1531,8 @@ static int mtk_star_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	priv->rmii_rxc = of_property_read_bool(of_node, "mediatek,rmii-rxc");
+
 	if (priv->compat_data->set_interface_mode) {
 		ret = priv->compat_data->set_interface_mode(ndev);
 		if (ret) {
@@ -1571,17 +1576,25 @@ static int mt8516_set_interface_mode(struct net_device *ndev)
 {
 	struct mtk_star_priv *priv = netdev_priv(ndev);
 	struct device *dev = mtk_star_get_dev(priv);
-	unsigned int intf_val;
+	unsigned int intf_val, ret, rmii_rxc;
 
 	switch (priv->phy_intf) {
 	case PHY_INTERFACE_MODE_RMII:
 		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
+		rmii_rxc = priv->rmii_rxc ? 0 : MTK_PERICFG_BIT_NIC_CFG_CON_CLK;
 		break;
 	default:
 		dev_err(dev, "This interface not supported\n");
 		return -EINVAL;
 	}
 
+	ret = regmap_update_bits(priv->pericfg,
+				 MTK_PERICFG_REG_NIC_CFG1_CON,
+				 MTK_PERICFG_BIT_NIC_CFG_CON_CLK,
+				 rmii_rxc);
+	if (ret)
+		return ret;
+
 	return regmap_update_bits(priv->pericfg,
 				  MTK_PERICFG_REG_NIC_CFG0_CON,
 				  MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF,
@@ -1597,6 +1610,7 @@ static int mt8365_set_interface_mode(struct net_device *ndev)
 	switch (priv->phy_intf) {
 	case PHY_INTERFACE_MODE_RMII:
 		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
+		intf_val |= priv->rmii_rxc ? 0 : MTK_PERICFG_BIT_NIC_CFG_CON_CLK_V2;
 		break;
 	default:
 		dev_err(dev, "This interface not supported\n");
@@ -1605,7 +1619,8 @@ static int mt8365_set_interface_mode(struct net_device *ndev)
 
 	return regmap_update_bits(priv->pericfg,
 				  MTK_PERICFG_REG_NIC_CFG_CON_V2,
-				  MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF,
+				  MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF |
+				  MTK_PERICFG_BIT_NIC_CFG_CON_CLK_V2,
 				  intf_val);
 }
 
-- 
2.25.1


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

* [PATCH net-next v2 6/9] net: ethernet: mtk-star-emac: add timing adjustment support
  2022-01-27  1:58 [PATCH net-next v2 0/9] add more features for mtk-star-emac Biao Huang
                   ` (4 preceding siblings ...)
  2022-01-27  1:58 ` [PATCH net-next v2 5/9] net: ethernet: mtk-star-emac: add clock pad selection for RMII Biao Huang
@ 2022-01-27  1:58 ` Biao Huang
  2022-01-27  2:20   ` Macpaul Lin
  2022-01-27  1:58 ` [PATCH net-next v2 7/9] dt-bindings: net: mtk-star-emac: add description for new properties Biao Huang
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 23+ messages in thread
From: Biao Huang @ 2022-01-27  1:58 UTC (permalink / raw)
  To: David Miller, Rob Herring, Bartosz Golaszewski, Fabien Parent
  Cc: Jakub Kicinski, Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Biao Huang, Yinghua Pan,
	srv_heupstream, Macpaul Lin

Add simple clock inversion for timing adjustment in driver.
Add property "mediatek,txc-inverse" or "mediatek,rxc-inverse" to
device node when necessary.

Signed-off-by: Biao Huang <biao.huang@mediatek.com>
Signed-off-by: Yinghua Pan <ot_yinghua.pan@mediatek.com>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 34 +++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index d69f75661e75..d5e974e0db6d 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -131,6 +131,11 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
 #define MTK_STAR_REG_INT_MASK			0x0054
 #define MTK_STAR_BIT_INT_MASK_FNRC		BIT(6)
 
+/* Delay-Macro Register */
+#define MTK_STAR_REG_TEST0			0x0058
+#define MTK_STAR_BIT_INV_RX_CLK			BIT(30)
+#define MTK_STAR_BIT_INV_TX_CLK			BIT(31)
+
 /* Misc. Config Register */
 #define MTK_STAR_REG_TEST1			0x005c
 #define MTK_STAR_BIT_TEST1_RST_HASH_MBIST	BIT(31)
@@ -268,6 +273,8 @@ struct mtk_star_priv {
 	int duplex;
 	int pause;
 	bool rmii_rxc;
+	bool rx_inv;
+	bool tx_inv;
 
 	const struct mtk_star_compat *compat_data;
 
@@ -1450,6 +1457,25 @@ static void mtk_star_clk_disable_unprepare(void *data)
 	clk_bulk_disable_unprepare(MTK_STAR_NCLKS, priv->clks);
 }
 
+static int mtk_star_set_timing(struct mtk_star_priv *priv)
+{
+	struct device *dev = mtk_star_get_dev(priv);
+	unsigned int delay_val = 0;
+
+	switch (priv->phy_intf) {
+	case PHY_INTERFACE_MODE_RMII:
+		delay_val |= FIELD_PREP(MTK_STAR_BIT_INV_RX_CLK, priv->rx_inv);
+		delay_val |= FIELD_PREP(MTK_STAR_BIT_INV_TX_CLK, priv->tx_inv);
+		break;
+	default:
+		dev_err(dev, "This interface not supported\n");
+		return -EINVAL;
+	}
+
+	regmap_write(priv->regs, MTK_STAR_REG_TEST0, delay_val);
+
+	return 0;
+}
 static int mtk_star_probe(struct platform_device *pdev)
 {
 	struct device_node *of_node;
@@ -1532,6 +1558,8 @@ static int mtk_star_probe(struct platform_device *pdev)
 	}
 
 	priv->rmii_rxc = of_property_read_bool(of_node, "mediatek,rmii-rxc");
+	priv->rx_inv = of_property_read_bool(of_node, "mediatek,rxc-inverse");
+	priv->tx_inv = of_property_read_bool(of_node, "mediatek,txc-inverse");
 
 	if (priv->compat_data->set_interface_mode) {
 		ret = priv->compat_data->set_interface_mode(ndev);
@@ -1541,6 +1569,12 @@ static int mtk_star_probe(struct platform_device *pdev)
 		}
 	}
 
+	ret = mtk_star_set_timing(priv);
+	if (ret) {
+		dev_err(dev, "Failed to set timing, err = %d\n", ret);
+		return -EINVAL;
+	}
+
 	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
 	if (ret) {
 		dev_err(dev, "unsupported DMA mask\n");
-- 
2.25.1


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

* [PATCH net-next v2 7/9] dt-bindings: net: mtk-star-emac: add description for new  properties
  2022-01-27  1:58 [PATCH net-next v2 0/9] add more features for mtk-star-emac Biao Huang
                   ` (5 preceding siblings ...)
  2022-01-27  1:58 ` [PATCH net-next v2 6/9] net: ethernet: mtk-star-emac: add timing adjustment support Biao Huang
@ 2022-01-27  1:58 ` Biao Huang
  2022-02-09  3:36   ` Rob Herring
  2022-01-27  1:58 ` [PATCH net-next v2 8/9] net: ethernet: mtk-star-emac: add support for MII interface Biao Huang
  2022-01-27  1:58 ` [PATCH net-next v2 9/9] net: ethernet: mtk-star-emac: separate tx/rx handling with two NAPIs Biao Huang
  8 siblings, 1 reply; 23+ messages in thread
From: Biao Huang @ 2022-01-27  1:58 UTC (permalink / raw)
  To: David Miller, Rob Herring, Bartosz Golaszewski, Fabien Parent
  Cc: Jakub Kicinski, Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Biao Huang, Yinghua Pan,
	srv_heupstream, Macpaul Lin

Add description for new properties which will be parsed in driver.

Signed-off-by: Biao Huang <biao.huang@mediatek.com>
---
 .../bindings/net/mediatek,star-emac.yaml         | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml b/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
index 87a8b25b03a6..41b1b1dd562c 100644
--- a/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
+++ b/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
@@ -48,6 +48,22 @@ properties:
       Phandle to the device containing the PERICFG register range. This is used
       to control the MII mode.
 
+  mediatek,rmii-rxc:
+    type: boolean
+    description:
+      If present, indicates that the RMII reference clock, which is from external
+      PHYs, is connected to RXC pin. Otherwise, is connected to TXC pin.
+
+  mediatek,rxc-inverse:
+    type: boolean
+    description:
+      If present, indicates that clock on RXC pad will be inversed.
+
+  mediatek,txc-inverse:
+    type: boolean
+    description:
+      If present, indicates that clock on TXC pad will be inversed.
+
   mdio:
     type: object
     description:
-- 
2.25.1


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

* [PATCH net-next v2 8/9] net: ethernet: mtk-star-emac: add support for MII interface
  2022-01-27  1:58 [PATCH net-next v2 0/9] add more features for mtk-star-emac Biao Huang
                   ` (6 preceding siblings ...)
  2022-01-27  1:58 ` [PATCH net-next v2 7/9] dt-bindings: net: mtk-star-emac: add description for new properties Biao Huang
@ 2022-01-27  1:58 ` Biao Huang
  2022-01-27  2:17   ` Macpaul Lin
  2022-01-27  1:58 ` [PATCH net-next v2 9/9] net: ethernet: mtk-star-emac: separate tx/rx handling with two NAPIs Biao Huang
  8 siblings, 1 reply; 23+ messages in thread
From: Biao Huang @ 2022-01-27  1:58 UTC (permalink / raw)
  To: David Miller, Rob Herring, Bartosz Golaszewski, Fabien Parent
  Cc: Jakub Kicinski, Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Biao Huang, Yinghua Pan,
	srv_heupstream, Macpaul Lin

Add support for MII interface.
If user wants to use MII, assign "MII" to "phy-mode" property in dts.

Signed-off-by: Biao Huang <biao.huang@mediatek.com>
Signed-off-by: Yinghua Pan <ot_yinghua.pan@mediatek.com>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index d5e974e0db6d..167a019fd8f5 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -193,6 +193,7 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
 #define MTK_PERICFG_REG_NIC_CFG1_CON		0x03c8
 #define MTK_PERICFG_REG_NIC_CFG_CON_V2		0x0c10
 #define MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF	GENMASK(3, 0)
+#define MTK_PERICFG_BIT_NIC_CFG_CON_MII		0
 #define MTK_PERICFG_BIT_NIC_CFG_CON_RMII	1
 #define MTK_PERICFG_BIT_NIC_CFG_CON_CLK		BIT(0)
 #define MTK_PERICFG_BIT_NIC_CFG_CON_CLK_V2	BIT(8)
@@ -1463,6 +1464,7 @@ static int mtk_star_set_timing(struct mtk_star_priv *priv)
 	unsigned int delay_val = 0;
 
 	switch (priv->phy_intf) {
+	case PHY_INTERFACE_MODE_MII:
 	case PHY_INTERFACE_MODE_RMII:
 		delay_val |= FIELD_PREP(MTK_STAR_BIT_INV_RX_CLK, priv->rx_inv);
 		delay_val |= FIELD_PREP(MTK_STAR_BIT_INV_TX_CLK, priv->tx_inv);
@@ -1545,7 +1547,8 @@ static int mtk_star_probe(struct platform_device *pdev)
 	ret = of_get_phy_mode(of_node, &priv->phy_intf);
 	if (ret) {
 		return ret;
-	} else if (priv->phy_intf != PHY_INTERFACE_MODE_RMII) {
+	} else if (priv->phy_intf != PHY_INTERFACE_MODE_RMII &&
+		   priv->phy_intf != PHY_INTERFACE_MODE_MII) {
 		dev_err(dev, "unsupported phy mode: %s\n",
 			phy_modes(priv->phy_intf));
 		return -EINVAL;
@@ -1610,9 +1613,12 @@ static int mt8516_set_interface_mode(struct net_device *ndev)
 {
 	struct mtk_star_priv *priv = netdev_priv(ndev);
 	struct device *dev = mtk_star_get_dev(priv);
-	unsigned int intf_val, ret, rmii_rxc;
+	unsigned int intf_val, ret, rmii_rxc = 0;
 
 	switch (priv->phy_intf) {
+	case PHY_INTERFACE_MODE_MII:
+		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_MII;
+		break;
 	case PHY_INTERFACE_MODE_RMII:
 		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
 		rmii_rxc = priv->rmii_rxc ? 0 : MTK_PERICFG_BIT_NIC_CFG_CON_CLK;
@@ -1642,6 +1648,9 @@ static int mt8365_set_interface_mode(struct net_device *ndev)
 	unsigned int intf_val;
 
 	switch (priv->phy_intf) {
+	case PHY_INTERFACE_MODE_MII:
+		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_MII;
+		break;
 	case PHY_INTERFACE_MODE_RMII:
 		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
 		intf_val |= priv->rmii_rxc ? 0 : MTK_PERICFG_BIT_NIC_CFG_CON_CLK_V2;
-- 
2.25.1


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

* [PATCH net-next v2 9/9] net: ethernet: mtk-star-emac: separate tx/rx handling with two NAPIs
  2022-01-27  1:58 [PATCH net-next v2 0/9] add more features for mtk-star-emac Biao Huang
                   ` (7 preceding siblings ...)
  2022-01-27  1:58 ` [PATCH net-next v2 8/9] net: ethernet: mtk-star-emac: add support for MII interface Biao Huang
@ 2022-01-27  1:58 ` Biao Huang
  2022-01-28  3:43   ` Jakub Kicinski
  8 siblings, 1 reply; 23+ messages in thread
From: Biao Huang @ 2022-01-27  1:58 UTC (permalink / raw)
  To: David Miller, Rob Herring, Bartosz Golaszewski, Fabien Parent
  Cc: Jakub Kicinski, Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Biao Huang, Yinghua Pan,
	srv_heupstream, Macpaul Lin

Current driver may lost tx interrupts under bidirectional test with iperf3,
which leads to some unexpected issues.

This patch let rx/tx interrupt enable/disable separately, and rx/tx are
handled in different NAPIs.

Signed-off-by: Biao Huang <biao.huang@mediatek.com>
Signed-off-by: Yinghua Pan <ot_yinghua.pan@mediatek.com>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 317 ++++++++++--------
 1 file changed, 181 insertions(+), 136 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index 167a019fd8f5..e5bcf851511a 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -229,7 +229,7 @@ struct mtk_star_ring_desc_data {
 	struct sk_buff *skb;
 };
 
-#define MTK_STAR_RING_NUM_DESCS			128
+#define MTK_STAR_RING_NUM_DESCS			512
 #define MTK_STAR_NUM_TX_DESCS			MTK_STAR_RING_NUM_DESCS
 #define MTK_STAR_NUM_RX_DESCS			MTK_STAR_RING_NUM_DESCS
 #define MTK_STAR_NUM_DESCS_TOTAL		(MTK_STAR_RING_NUM_DESCS * 2)
@@ -264,7 +264,8 @@ struct mtk_star_priv {
 	struct mtk_star_ring rx_ring;
 
 	struct mii_bus *mii;
-	struct napi_struct napi;
+	struct napi_struct tx_napi;
+	struct napi_struct rx_napi;
 
 	struct device_node *phy_node;
 	phy_interface_t phy_intf;
@@ -380,19 +381,16 @@ mtk_star_ring_push_head_tx(struct mtk_star_ring *ring,
 	mtk_star_ring_push_head(ring, desc_data, flags);
 }
 
-static unsigned int mtk_star_ring_num_used_descs(struct mtk_star_ring *ring)
+static unsigned int mtk_star_tx_ring_avail(struct mtk_star_ring *ring)
 {
-	return abs(ring->head - ring->tail);
-}
+	u32 avail;
 
-static bool mtk_star_ring_full(struct mtk_star_ring *ring)
-{
-	return mtk_star_ring_num_used_descs(ring) == MTK_STAR_RING_NUM_DESCS;
-}
+	if (ring->tail > ring->head)
+		avail = ring->tail - ring->head - 1;
+	else
+		avail = MTK_STAR_RING_NUM_DESCS - ring->head + ring->tail - 1;
 
-static bool mtk_star_ring_descs_available(struct mtk_star_ring *ring)
-{
-	return mtk_star_ring_num_used_descs(ring) > 0;
+	return avail;
 }
 
 static dma_addr_t mtk_star_dma_map_rx(struct mtk_star_priv *priv,
@@ -415,7 +413,7 @@ static void mtk_star_dma_unmap_rx(struct mtk_star_priv *priv,
 }
 
 static dma_addr_t mtk_star_dma_map_tx(struct mtk_star_priv *priv,
-				      struct sk_buff *skb)
+					     struct sk_buff *skb)
 {
 	struct device *dev = mtk_star_get_dev(priv);
 
@@ -437,6 +435,36 @@ static void mtk_star_nic_disable_pd(struct mtk_star_priv *priv)
 			  MTK_STAR_BIT_MAC_CFG_NIC_PD);
 }
 
+static void mtk_star_enable_dma_irq(struct mtk_star_priv *priv,
+				    bool rx, bool tx)
+{
+	u32 value;
+
+	regmap_read(priv->regs, MTK_STAR_REG_INT_MASK, &value);
+
+	if (tx)
+		value &= ~MTK_STAR_BIT_INT_STS_TNTC;
+	if (rx)
+		value &= ~MTK_STAR_BIT_INT_STS_FNRC;
+
+	regmap_write(priv->regs, MTK_STAR_REG_INT_MASK, value);
+}
+
+static void mtk_star_disable_dma_irq(struct mtk_star_priv *priv,
+				     bool rx, bool tx)
+{
+	u32 value;
+
+	regmap_read(priv->regs, MTK_STAR_REG_INT_MASK, &value);
+
+	if (tx)
+		value |= MTK_STAR_BIT_INT_STS_TNTC;
+	if (rx)
+		value |= MTK_STAR_BIT_INT_STS_FNRC;
+
+	regmap_write(priv->regs, MTK_STAR_REG_INT_MASK, value);
+}
+
 /* Unmask the three interrupts we care about, mask all others. */
 static void mtk_star_intr_enable(struct mtk_star_priv *priv)
 {
@@ -452,20 +480,11 @@ static void mtk_star_intr_disable(struct mtk_star_priv *priv)
 	regmap_write(priv->regs, MTK_STAR_REG_INT_MASK, ~0);
 }
 
-static unsigned int mtk_star_intr_read(struct mtk_star_priv *priv)
-{
-	unsigned int val;
-
-	regmap_read(priv->regs, MTK_STAR_REG_INT_STS, &val);
-
-	return val;
-}
-
 static unsigned int mtk_star_intr_ack_all(struct mtk_star_priv *priv)
 {
 	unsigned int val;
 
-	val = mtk_star_intr_read(priv);
+	regmap_read(priv->regs, MTK_STAR_REG_INT_STS, &val);
 	regmap_write(priv->regs, MTK_STAR_REG_INT_STS, val);
 
 	return val;
@@ -737,25 +756,46 @@ static void mtk_star_free_tx_skbs(struct mtk_star_priv *priv)
 	mtk_star_ring_free_skbs(priv, ring, mtk_star_dma_unmap_tx);
 }
 
-/* All processing for TX and RX happens in the napi poll callback.
- *
- * FIXME: The interrupt handling should be more fine-grained with each
- * interrupt enabled/disabled independently when needed. Unfortunatly this
- * turned out to impact the driver's stability and until we have something
- * working properly, we're disabling all interrupts during TX & RX processing
- * or when resetting the counter registers.
+/* mtk_star_handle_irq - Interrupt Handler.
+ * @irq: interrupt number.
+ * @data: pointer to a network interface device structure.
+ * Description : this is the driver interrupt service routine.
+ * it mainly handles:
+ *  1. tx complete interrupt for frame transmission.
+ *  2. rx complete interrupt for frame reception.
+ *  3. MAC Management Counter interrupt to avoid counter overflow.
  */
 static irqreturn_t mtk_star_handle_irq(int irq, void *data)
 {
-	struct mtk_star_priv *priv;
-	struct net_device *ndev;
+	struct net_device *ndev = data;
+	struct mtk_star_priv *priv = netdev_priv(ndev);
+	unsigned int intr_status = mtk_star_intr_ack_all(priv);
+	unsigned long flags = 0;
+
+	if (intr_status & MTK_STAR_BIT_INT_STS_FNRC) {
+		if (napi_schedule_prep(&priv->rx_napi)) {
+			spin_lock_irqsave(&priv->lock, flags);
+			/* mask Rx Complete interrupt */
+			mtk_star_disable_dma_irq(priv, true, false);
+			spin_unlock_irqrestore(&priv->lock, flags);
+			__napi_schedule_irqoff(&priv->rx_napi);
+		}
+	}
 
-	ndev = data;
-	priv = netdev_priv(ndev);
+	if (intr_status & MTK_STAR_BIT_INT_STS_TNTC) {
+		if (napi_schedule_prep(&priv->tx_napi)) {
+			spin_lock_irqsave(&priv->lock, flags);
+			/* mask Tx Complete interrupt */
+			mtk_star_disable_dma_irq(priv, false, true);
+			spin_unlock_irqrestore(&priv->lock, flags);
+			__napi_schedule_irqoff(&priv->tx_napi);
+		}
+	}
 
-	if (netif_running(ndev)) {
-		mtk_star_intr_disable(priv);
-		napi_schedule(&priv->napi);
+	/* interrupt is triggered once any counters reach 0x8000000 */
+	if (intr_status & MTK_STAR_REG_INT_STS_MIB_CNT_TH) {
+		mtk_star_update_stats(priv);
+		mtk_star_reset_counters(priv);
 	}
 
 	return IRQ_HANDLED;
@@ -971,7 +1011,8 @@ static int mtk_star_enable(struct net_device *ndev)
 	if (ret)
 		goto err_free_skbs;
 
-	napi_enable(&priv->napi);
+	napi_enable(&priv->tx_napi);
+	napi_enable(&priv->rx_napi);
 
 	mtk_star_intr_ack_all(priv);
 	mtk_star_intr_enable(priv);
@@ -1004,7 +1045,8 @@ static void mtk_star_disable(struct net_device *ndev)
 	struct mtk_star_priv *priv = netdev_priv(ndev);
 
 	netif_stop_queue(ndev);
-	napi_disable(&priv->napi);
+	napi_disable(&priv->tx_napi);
+	napi_disable(&priv->rx_napi);
 	mtk_star_intr_disable(priv);
 	mtk_star_dma_disable(priv);
 	mtk_star_intr_ack_all(priv);
@@ -1043,6 +1085,17 @@ static int mtk_star_netdev_start_xmit(struct sk_buff *skb,
 	struct mtk_star_ring *ring = &priv->tx_ring;
 	struct device *dev = mtk_star_get_dev(priv);
 	struct mtk_star_ring_desc_data desc_data;
+	int nfrags = skb_shinfo(skb)->nr_frags;
+
+	if (unlikely(mtk_star_tx_ring_avail(ring) < nfrags + 1)) {
+		if (!netif_queue_stopped(ndev)) {
+			netif_stop_queue(ndev);
+			/* This is a hard error, log it. */
+			netdev_err(priv->ndev, "%s: Tx Ring full when queue awake\n",
+				   __func__);
+		}
+		return NETDEV_TX_BUSY;
+	}
 
 	desc_data.dma_addr = mtk_star_dma_map_tx(priv, skb);
 	if (dma_mapping_error(dev, desc_data.dma_addr))
@@ -1050,18 +1103,10 @@ static int mtk_star_netdev_start_xmit(struct sk_buff *skb,
 
 	desc_data.skb = skb;
 	desc_data.len = skb->len;
-
-	spin_lock_bh(&priv->lock);
-
 	mtk_star_ring_push_head_tx(ring, &desc_data);
 
 	netdev_sent_queue(ndev, skb->len);
 
-	if (mtk_star_ring_full(ring))
-		netif_stop_queue(ndev);
-
-	spin_unlock_bh(&priv->lock);
-
 	mtk_star_dma_resume_tx(priv);
 
 	return NETDEV_TX_OK;
@@ -1092,23 +1137,31 @@ static int mtk_star_tx_complete_one(struct mtk_star_priv *priv)
 	return ret;
 }
 
-static void mtk_star_tx_complete_all(struct mtk_star_priv *priv)
+static int mtk_star_tx_poll(struct napi_struct *napi, int budget)
 {
-	struct mtk_star_ring *ring = &priv->tx_ring;
-	struct net_device *ndev = priv->ndev;
-	int ret, pkts_compl, bytes_compl;
+	int ret, pkts_compl = 0, bytes_compl = 0, count = 0;
+	struct mtk_star_priv *priv;
+	struct mtk_star_ring *ring;
+	struct net_device *ndev;
+	unsigned long flags = 0;
+	unsigned int entry;
 	bool wake = false;
 
-	spin_lock(&priv->lock);
+	priv = container_of(napi, struct mtk_star_priv, tx_napi);
+	ndev = priv->ndev;
 
-	for (pkts_compl = 0, bytes_compl = 0;;
+	__netif_tx_lock_bh(netdev_get_tx_queue(priv->ndev, 0));
+	ring = &priv->tx_ring;
+	entry = ring->tail;
+	for (pkts_compl = 0, bytes_compl = 0;
+	     (entry != ring->head) && (count < budget);
 	     pkts_compl++, bytes_compl += ret, wake = true) {
-		if (!mtk_star_ring_descs_available(ring))
-			break;
 
 		ret = mtk_star_tx_complete_one(priv);
 		if (ret < 0)
 			break;
+		count++;
+		entry = ring->tail;
 	}
 
 	netdev_completed_queue(ndev, pkts_compl, bytes_compl);
@@ -1116,7 +1169,16 @@ static void mtk_star_tx_complete_all(struct mtk_star_priv *priv)
 	if (wake && netif_queue_stopped(ndev))
 		netif_wake_queue(ndev);
 
-	spin_unlock(&priv->lock);
+	__netif_tx_unlock_bh(netdev_get_tx_queue(priv->ndev, 0));
+
+	count = min(count, budget);
+	if (count < budget && napi_complete_done(napi, count)) {
+		spin_lock_irqsave(&priv->lock, flags);
+		mtk_star_enable_dma_irq(priv, false, true);
+		spin_unlock_irqrestore(&priv->lock, flags);
+	}
+
+	return count;
 }
 
 static void mtk_star_netdev_get_stats64(struct net_device *ndev,
@@ -1196,7 +1258,7 @@ static const struct ethtool_ops mtk_star_ethtool_ops = {
 	.set_link_ksettings	= phy_ethtool_set_link_ksettings,
 };
 
-static int mtk_star_receive_packet(struct mtk_star_priv *priv)
+static int mtk_star_rx(struct mtk_star_priv *priv, int budget)
 {
 	struct mtk_star_ring *ring = &priv->rx_ring;
 	struct device *dev = mtk_star_get_dev(priv);
@@ -1204,107 +1266,86 @@ static int mtk_star_receive_packet(struct mtk_star_priv *priv)
 	struct net_device *ndev = priv->ndev;
 	struct sk_buff *curr_skb, *new_skb;
 	dma_addr_t new_dma_addr;
-	int ret;
+	int ret, count = 0;
 
-	spin_lock(&priv->lock);
-	ret = mtk_star_ring_pop_tail(ring, &desc_data);
-	spin_unlock(&priv->lock);
-	if (ret)
-		return -1;
+	while (count < budget) {
+		ret = mtk_star_ring_pop_tail(ring, &desc_data);
+		if (ret)
+			return -1;
 
-	curr_skb = desc_data.skb;
+		curr_skb = desc_data.skb;
 
-	if ((desc_data.flags & MTK_STAR_DESC_BIT_RX_CRCE) ||
-	    (desc_data.flags & MTK_STAR_DESC_BIT_RX_OSIZE)) {
-		/* Error packet -> drop and reuse skb. */
-		new_skb = curr_skb;
-		goto push_new_skb;
-	}
+		if ((desc_data.flags & MTK_STAR_DESC_BIT_RX_CRCE) ||
+		    (desc_data.flags & MTK_STAR_DESC_BIT_RX_OSIZE)) {
+			/* Error packet -> drop and reuse skb. */
+			new_skb = curr_skb;
+			goto push_new_skb;
+		}
 
-	/* Prepare new skb before receiving the current one. Reuse the current
-	 * skb if we fail at any point.
-	 */
-	new_skb = mtk_star_alloc_skb(ndev);
-	if (!new_skb) {
-		ndev->stats.rx_dropped++;
-		new_skb = curr_skb;
-		goto push_new_skb;
-	}
+		/* Prepare new skb before receiving the current one.
+		 * Reuse the current skb if we fail at any point.
+		 */
+		new_skb = mtk_star_alloc_skb(ndev);
+		if (!new_skb) {
+			ndev->stats.rx_dropped++;
+			new_skb = curr_skb;
+			goto push_new_skb;
+		}
 
-	new_dma_addr = mtk_star_dma_map_rx(priv, new_skb);
-	if (dma_mapping_error(dev, new_dma_addr)) {
-		ndev->stats.rx_dropped++;
-		dev_kfree_skb(new_skb);
-		new_skb = curr_skb;
-		netdev_err(ndev, "DMA mapping error of RX descriptor\n");
-		goto push_new_skb;
-	}
+		new_dma_addr = mtk_star_dma_map_rx(priv, new_skb);
+		if (dma_mapping_error(dev, new_dma_addr)) {
+			ndev->stats.rx_dropped++;
+			dev_kfree_skb(new_skb);
+			new_skb = curr_skb;
+			netdev_err(ndev, "DMA mapping error of RX descriptor\n");
+			goto push_new_skb;
+		}
 
-	/* We can't fail anymore at this point: it's safe to unmap the skb. */
-	mtk_star_dma_unmap_rx(priv, &desc_data);
+		/* We can't fail anymore at this point:
+		 * it's safe to unmap the skb.
+		 */
+		mtk_star_dma_unmap_rx(priv, &desc_data);
 
-	skb_put(desc_data.skb, desc_data.len);
-	desc_data.skb->ip_summed = CHECKSUM_NONE;
-	desc_data.skb->protocol = eth_type_trans(desc_data.skb, ndev);
-	desc_data.skb->dev = ndev;
-	netif_receive_skb(desc_data.skb);
+		skb_put(desc_data.skb, desc_data.len);
+		desc_data.skb->ip_summed = CHECKSUM_NONE;
+		desc_data.skb->protocol = eth_type_trans(desc_data.skb, ndev);
+		desc_data.skb->dev = ndev;
+		netif_receive_skb(desc_data.skb);
 
-	/* update dma_addr for new skb */
-	desc_data.dma_addr = new_dma_addr;
+		/* update dma_addr for new skb */
+		desc_data.dma_addr = new_dma_addr;
 
 push_new_skb:
-	desc_data.len = skb_tailroom(new_skb);
-	desc_data.skb = new_skb;
-
-	spin_lock(&priv->lock);
-	mtk_star_ring_push_head_rx(ring, &desc_data);
-	spin_unlock(&priv->lock);
-
-	return 0;
-}
 
-static int mtk_star_process_rx(struct mtk_star_priv *priv, int budget)
-{
-	int received, ret;
+		count++;
 
-	for (received = 0, ret = 0; received < budget && ret == 0; received++)
-		ret = mtk_star_receive_packet(priv);
+		desc_data.len = skb_tailroom(new_skb);
+		desc_data.skb = new_skb;
+		mtk_star_ring_push_head_rx(ring, &desc_data);
+	}
 
 	mtk_star_dma_resume_rx(priv);
 
-	return received;
+	return count;
 }
 
-static int mtk_star_poll(struct napi_struct *napi, int budget)
+static int mtk_star_rx_poll(struct napi_struct *napi, int budget)
 {
 	struct mtk_star_priv *priv;
-	unsigned int status;
-	int received = 0;
+	unsigned long flags = 0;
+	int work_done = 0;
 
-	priv = container_of(napi, struct mtk_star_priv, napi);
+	priv = container_of(napi, struct mtk_star_priv, rx_napi);
 
-	status = mtk_star_intr_read(priv);
-	mtk_star_intr_ack_all(priv);
-
-	if (status & MTK_STAR_BIT_INT_STS_TNTC)
-		/* Clean-up all TX descriptors. */
-		mtk_star_tx_complete_all(priv);
-
-	if (status & MTK_STAR_BIT_INT_STS_FNRC)
-		/* Receive up to $budget packets. */
-		received = mtk_star_process_rx(priv, budget);
-
-	if (unlikely(status & MTK_STAR_REG_INT_STS_MIB_CNT_TH)) {
-		mtk_star_update_stats(priv);
-		mtk_star_reset_counters(priv);
+	work_done = mtk_star_rx(priv, budget);
+	if (work_done < budget) {
+		napi_complete_done(napi, work_done);
+		spin_lock_irqsave(&priv->lock, flags);
+		mtk_star_enable_dma_irq(priv, true, false);
+		spin_unlock_irqrestore(&priv->lock, flags);
 	}
 
-	if (received < budget)
-		napi_complete_done(napi, received);
-
-	mtk_star_intr_enable(priv);
-
-	return received;
+	return work_done;
 }
 
 static void mtk_star_mdio_rwok_clear(struct mtk_star_priv *priv)
@@ -1478,6 +1519,7 @@ static int mtk_star_set_timing(struct mtk_star_priv *priv)
 
 	return 0;
 }
+
 static int mtk_star_probe(struct platform_device *pdev)
 {
 	struct device_node *of_node;
@@ -1604,7 +1646,10 @@ static int mtk_star_probe(struct platform_device *pdev)
 	ndev->netdev_ops = &mtk_star_netdev_ops;
 	ndev->ethtool_ops = &mtk_star_ethtool_ops;
 
-	netif_napi_add(ndev, &priv->napi, mtk_star_poll, MTK_STAR_NAPI_WEIGHT);
+	netif_napi_add(ndev, &priv->rx_napi,
+		       mtk_star_rx_poll, MTK_STAR_NAPI_WEIGHT);
+	netif_tx_napi_add(ndev, &priv->tx_napi,
+			  mtk_star_tx_poll, MTK_STAR_NAPI_WEIGHT);
 
 	return devm_register_netdev(dev, ndev);
 }
-- 
2.25.1


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

* Re: [PATCH net-next v2 8/9] net: ethernet: mtk-star-emac: add support for MII interface
  2022-01-27  1:58 ` [PATCH net-next v2 8/9] net: ethernet: mtk-star-emac: add support for MII interface Biao Huang
@ 2022-01-27  2:17   ` Macpaul Lin
  0 siblings, 0 replies; 23+ messages in thread
From: Macpaul Lin @ 2022-01-27  2:17 UTC (permalink / raw)
  To: Biao Huang, David Miller, Rob Herring, Bartosz Golaszewski,
	Fabien Parent
  Cc: Jakub Kicinski, Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Yinghua Pan, srv_heupstream

On 1/27/22 9:58 AM, Biao Huang wrote:
> Add support for MII interface.
> If user wants to use MII, assign "MII" to "phy-mode" property in dts.
> 
> Signed-off-by: Biao Huang <biao.huang@mediatek.com>
> Signed-off-by: Yinghua Pan <ot_yinghua.pan@mediatek.com>
> ---
>   drivers/net/ethernet/mediatek/mtk_star_emac.c | 13 +++++++++++--
>   1 file changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> index d5e974e0db6d..167a019fd8f5 100644
> --- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
> +++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> @@ -193,6 +193,7 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
>   #define MTK_PERICFG_REG_NIC_CFG1_CON		0x03c8
>   #define MTK_PERICFG_REG_NIC_CFG_CON_V2		0x0c10
>   #define MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF	GENMASK(3, 0)
> +#define MTK_PERICFG_BIT_NIC_CFG_CON_MII		0
>   #define MTK_PERICFG_BIT_NIC_CFG_CON_RMII	1
>   #define MTK_PERICFG_BIT_NIC_CFG_CON_CLK		BIT(0)
>   #define MTK_PERICFG_BIT_NIC_CFG_CON_CLK_V2	BIT(8)
> @@ -1463,6 +1464,7 @@ static int mtk_star_set_timing(struct mtk_star_priv *priv)
>   	unsigned int delay_val = 0;
>   
>   	switch (priv->phy_intf) {
> +	case PHY_INTERFACE_MODE_MII:
>   	case PHY_INTERFACE_MODE_RMII:
>   		delay_val |= FIELD_PREP(MTK_STAR_BIT_INV_RX_CLK, priv->rx_inv);
>   		delay_val |= FIELD_PREP(MTK_STAR_BIT_INV_TX_CLK, priv->tx_inv);
> @@ -1545,7 +1547,8 @@ static int mtk_star_probe(struct platform_device *pdev)
>   	ret = of_get_phy_mode(of_node, &priv->phy_intf);
>   	if (ret) {
>   		return ret;
> -	} else if (priv->phy_intf != PHY_INTERFACE_MODE_RMII) {
> +	} else if (priv->phy_intf != PHY_INTERFACE_MODE_RMII &&
> +		   priv->phy_intf != PHY_INTERFACE_MODE_MII) {
>   		dev_err(dev, "unsupported phy mode: %s\n",
>   			phy_modes(priv->phy_intf));
>   		return -EINVAL;
> @@ -1610,9 +1613,12 @@ static int mt8516_set_interface_mode(struct net_device *ndev)
>   {
>   	struct mtk_star_priv *priv = netdev_priv(ndev);
>   	struct device *dev = mtk_star_get_dev(priv);
> -	unsigned int intf_val, ret, rmii_rxc;
> +	unsigned int intf_val, ret, rmii_rxc = 0;
>   
>   	switch (priv->phy_intf) {
> +	case PHY_INTERFACE_MODE_MII:
> +		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_MII;
> +		break;
>   	case PHY_INTERFACE_MODE_RMII:
>   		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
>   		rmii_rxc = priv->rmii_rxc ? 0 : MTK_PERICFG_BIT_NIC_CFG_CON_CLK;
> @@ -1642,6 +1648,9 @@ static int mt8365_set_interface_mode(struct net_device *ndev)
>   	unsigned int intf_val;
>   
>   	switch (priv->phy_intf) {
> +	case PHY_INTERFACE_MODE_MII:
> +		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_MII;
> +		break;
>   	case PHY_INTERFACE_MODE_RMII:
>   		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
>   		intf_val |= priv->rmii_rxc ? 0 : MTK_PERICFG_BIT_NIC_CFG_CON_CLK_V2;
> 

Reviewed-by: Macpaul Lin <macpaul.lin@mediatek.com>

Regards,
Macpaul Lin

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

* Re: [PATCH net-next v2 6/9] net: ethernet: mtk-star-emac: add timing adjustment support
  2022-01-27  1:58 ` [PATCH net-next v2 6/9] net: ethernet: mtk-star-emac: add timing adjustment support Biao Huang
@ 2022-01-27  2:20   ` Macpaul Lin
  0 siblings, 0 replies; 23+ messages in thread
From: Macpaul Lin @ 2022-01-27  2:20 UTC (permalink / raw)
  To: Biao Huang, David Miller, Rob Herring, Bartosz Golaszewski,
	Fabien Parent
  Cc: Jakub Kicinski, Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Yinghua Pan, srv_heupstream


On 1/27/22 9:58 AM, Biao Huang wrote:
> Add simple clock inversion for timing adjustment in driver.
> Add property "mediatek,txc-inverse" or "mediatek,rxc-inverse" to
> device node when necessary.
> 
> Signed-off-by: Biao Huang <biao.huang@mediatek.com>
> Signed-off-by: Yinghua Pan <ot_yinghua.pan@mediatek.com>
> ---
>   drivers/net/ethernet/mediatek/mtk_star_emac.c | 34 +++++++++++++++++++
>   1 file changed, 34 insertions(+)
> 
> diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> index d69f75661e75..d5e974e0db6d 100644
> --- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
> +++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> @@ -131,6 +131,11 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
>   #define MTK_STAR_REG_INT_MASK			0x0054
>   #define MTK_STAR_BIT_INT_MASK_FNRC		BIT(6)
>   
> +/* Delay-Macro Register */
> +#define MTK_STAR_REG_TEST0			0x0058
> +#define MTK_STAR_BIT_INV_RX_CLK			BIT(30)
> +#define MTK_STAR_BIT_INV_TX_CLK			BIT(31)
> +
>   /* Misc. Config Register */
>   #define MTK_STAR_REG_TEST1			0x005c
>   #define MTK_STAR_BIT_TEST1_RST_HASH_MBIST	BIT(31)
> @@ -268,6 +273,8 @@ struct mtk_star_priv {
>   	int duplex;
>   	int pause;
>   	bool rmii_rxc;
> +	bool rx_inv;
> +	bool tx_inv;
>   
>   	const struct mtk_star_compat *compat_data;
>   
> @@ -1450,6 +1457,25 @@ static void mtk_star_clk_disable_unprepare(void *data)
>   	clk_bulk_disable_unprepare(MTK_STAR_NCLKS, priv->clks);
>   }
>   
> +static int mtk_star_set_timing(struct mtk_star_priv *priv)
> +{
> +	struct device *dev = mtk_star_get_dev(priv);
> +	unsigned int delay_val = 0;
> +
> +	switch (priv->phy_intf) {
> +	case PHY_INTERFACE_MODE_RMII:
> +		delay_val |= FIELD_PREP(MTK_STAR_BIT_INV_RX_CLK, priv->rx_inv);
> +		delay_val |= FIELD_PREP(MTK_STAR_BIT_INV_TX_CLK, priv->tx_inv);
> +		break;
> +	default:
> +		dev_err(dev, "This interface not supported\n");
> +		return -EINVAL;
> +	}
> +
> +	regmap_write(priv->regs, MTK_STAR_REG_TEST0, delay_val);
> +
> +	return 0;
> +}
>   static int mtk_star_probe(struct platform_device *pdev)
>   {
>   	struct device_node *of_node;
> @@ -1532,6 +1558,8 @@ static int mtk_star_probe(struct platform_device *pdev)
>   	}
>   
>   	priv->rmii_rxc = of_property_read_bool(of_node, "mediatek,rmii-rxc");
> +	priv->rx_inv = of_property_read_bool(of_node, "mediatek,rxc-inverse");
> +	priv->tx_inv = of_property_read_bool(of_node, "mediatek,txc-inverse");
>   
>   	if (priv->compat_data->set_interface_mode) {
>   		ret = priv->compat_data->set_interface_mode(ndev);
> @@ -1541,6 +1569,12 @@ static int mtk_star_probe(struct platform_device *pdev)
>   		}
>   	}
>   
> +	ret = mtk_star_set_timing(priv);
> +	if (ret) {
> +		dev_err(dev, "Failed to set timing, err = %d\n", ret);
> +		return -EINVAL;
> +	}
> +
>   	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
>   	if (ret) {
>   		dev_err(dev, "unsupported DMA mask\n");
> 

Reviewed-by: Macpaul Lin <macpaul.lin@mediatek.com>

Regards,
Macpaul Lin

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

* Re: [PATCH net-next v2 3/9] net: ethernet: mtk-star-emac: add support for MT8365 SoC
  2022-01-27  1:58 ` [PATCH net-next v2 3/9] net: ethernet: mtk-star-emac: add support for MT8365 SoC Biao Huang
@ 2022-01-27  2:22   ` Macpaul Lin
  0 siblings, 0 replies; 23+ messages in thread
From: Macpaul Lin @ 2022-01-27  2:22 UTC (permalink / raw)
  To: Biao Huang, David Miller, Rob Herring, Bartosz Golaszewski,
	Fabien Parent
  Cc: Jakub Kicinski, Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Yinghua Pan, srv_heupstream

On 1/27/22 9:58 AM, Biao Huang wrote:
> Add Ethernet driver support for MT8365 SoC.
> 
> Signed-off-by: Biao Huang <biao.huang@mediatek.com>
> Signed-off-by: Yinghua Pan <ot_yinghua.pan@mediatek.com>
> Signed-off-by: Fabien Parent <fparent@baylibre.com>
> ---
>   drivers/net/ethernet/mediatek/mtk_star_emac.c | 75 ++++++++++++++++---
>   1 file changed, 64 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> index a8fbbbcd185b..a3884beaa3fe 100644
> --- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
> +++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> @@ -151,6 +151,7 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
>   #define MTK_STAR_REG_MAC_CLK_CONF		0x00ac
>   #define MTK_STAR_MSK_MAC_CLK_CONF		GENMASK(7, 0)
>   #define MTK_STAR_BIT_CLK_DIV_10			0x0a
> +#define MTK_STAR_BIT_CLK_DIV_50			0x32
>   
>   /* Counter registers. */
>   #define MTK_STAR_REG_C_RXOKPKT			0x0100
> @@ -183,9 +184,11 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
>   #define MTK_STAR_REG_C_RX_TWIST			0x0218
>   
>   /* Ethernet CFG Control */
> -#define MTK_PERICFG_REG_NIC_CFG_CON		0x03c4
> -#define MTK_PERICFG_MSK_NIC_CFG_CON_CFG_MII	GENMASK(3, 0)
> -#define MTK_PERICFG_BIT_NIC_CFG_CON_RMII	BIT(0)
> +#define MTK_PERICFG_REG_NIC_CFG0_CON		0x03c4
> +#define MTK_PERICFG_REG_NIC_CFG1_CON		0x03c8
> +#define MTK_PERICFG_REG_NIC_CFG_CON_V2		0x0c10
> +#define MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF	GENMASK(3, 0)
> +#define MTK_PERICFG_BIT_NIC_CFG_CON_RMII	1
>   
>   /* Represents the actual structure of descriptors used by the MAC. We can
>    * reuse the same structure for both TX and RX - the layout is the same, only
> @@ -234,6 +237,7 @@ struct mtk_star_ring {
>   };
>   
>   struct mtk_star_compat {
> +	int (*set_interface_mode)(struct net_device *ndev);
>   	unsigned char bit_clk_div;
>   };
>   
> @@ -909,13 +913,6 @@ static void mtk_star_init_config(struct mtk_star_priv *priv)
>   			   priv->compat_data->bit_clk_div);
>   }
>   
> -static void mtk_star_set_mode_rmii(struct mtk_star_priv *priv)
> -{
> -	regmap_update_bits(priv->pericfg, MTK_PERICFG_REG_NIC_CFG_CON,
> -			   MTK_PERICFG_MSK_NIC_CFG_CON_CFG_MII,
> -			   MTK_PERICFG_BIT_NIC_CFG_CON_RMII);
> -}
> -
>   static int mtk_star_enable(struct net_device *ndev)
>   {
>   	struct mtk_star_priv *priv = netdev_priv(ndev);
> @@ -1531,7 +1528,13 @@ static int mtk_star_probe(struct platform_device *pdev)
>   		return -ENODEV;
>   	}
>   
> -	mtk_star_set_mode_rmii(priv);
> +	if (priv->compat_data->set_interface_mode) {
> +		ret = priv->compat_data->set_interface_mode(ndev);
> +		if (ret) {
> +			dev_err(dev, "Failed to set phy interface, err = %d\n", ret);
> +			return -EINVAL;
> +		}
> +	}
>   
>   	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
>   	if (ret) {
> @@ -1564,10 +1567,58 @@ static int mtk_star_probe(struct platform_device *pdev)
>   	return devm_register_netdev(dev, ndev);
>   }
>   
> +static int mt8516_set_interface_mode(struct net_device *ndev)
> +{
> +	struct mtk_star_priv *priv = netdev_priv(ndev);
> +	struct device *dev = mtk_star_get_dev(priv);
> +	unsigned int intf_val;
> +
> +	switch (priv->phy_intf) {
> +	case PHY_INTERFACE_MODE_RMII:
> +		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
> +		break;
> +	default:
> +		dev_err(dev, "This interface not supported\n");
> +		return -EINVAL;
> +	}
> +
> +	return regmap_update_bits(priv->pericfg,
> +				  MTK_PERICFG_REG_NIC_CFG0_CON,
> +				  MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF,
> +				  intf_val);
> +}
> +
> +static int mt8365_set_interface_mode(struct net_device *ndev)
> +{
> +	struct mtk_star_priv *priv = netdev_priv(ndev);
> +	struct device *dev = mtk_star_get_dev(priv);
> +	unsigned int intf_val;
> +
> +	switch (priv->phy_intf) {
> +	case PHY_INTERFACE_MODE_RMII:
> +		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
> +		break;
> +	default:
> +		dev_err(dev, "This interface not supported\n");
> +		return -EINVAL;
> +	}
> +
> +	return regmap_update_bits(priv->pericfg,
> +				  MTK_PERICFG_REG_NIC_CFG_CON_V2,
> +				  MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF,
> +				  intf_val);
> +}
> +
>   static const struct mtk_star_compat mtk_star_mt8516_compat = {
> +	.set_interface_mode = mt8516_set_interface_mode,
>   	.bit_clk_div = MTK_STAR_BIT_CLK_DIV_10,
>   };
>   
> +static const struct mtk_star_compat mtk_star_mt8365_compat = {
> +	.set_interface_mode = mt8365_set_interface_mode,
> +	.bit_clk_div = MTK_STAR_BIT_CLK_DIV_50,
> +};
> +
>   static const struct of_device_id mtk_star_of_match[] = {
>   	{ .compatible = "mediatek,mt8516-eth",
>   	  .data = &mtk_star_mt8516_compat },
> @@ -1575,6 +1626,8 @@ static const struct of_device_id mtk_star_of_match[] = {
>   	  .data = &mtk_star_mt8516_compat },
>   	{ .compatible = "mediatek,mt8175-eth",
>   	  .data = &mtk_star_mt8516_compat },
> +	{ .compatible = "mediatek,mt8365-eth",
> +	  .data = &mtk_star_mt8365_compat },
>   	{ }
>   };
>   MODULE_DEVICE_TABLE(of, mtk_star_of_match);
> 

Reviewed-by: Macpaul Lin <macpaul.lin@mediatek.com>

Regards,
Macpaul Lin

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

* Re: [PATCH net-next v2 1/9] net: ethernet: mtk-star-emac: store bit_clk_div in compat structure
  2022-01-27  1:58 ` [PATCH net-next v2 1/9] net: ethernet: mtk-star-emac: store bit_clk_div in compat structure Biao Huang
@ 2022-01-27  2:23   ` Macpaul Lin
  0 siblings, 0 replies; 23+ messages in thread
From: Macpaul Lin @ 2022-01-27  2:23 UTC (permalink / raw)
  To: Biao Huang, David Miller, Rob Herring, Bartosz Golaszewski,
	Fabien Parent
  Cc: Jakub Kicinski, Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Yinghua Pan, srv_heupstream

On 1/27/22 9:58 AM, Biao Huang wrote:
> From: Fabien Parent <fparent@baylibre.com>
> 
> Not all the SoC are using the same clock divider. Move the divider into
> a compat structure specific to the SoCs.
> 
> Signed-off-by: Biao Huang <biao.huang@mediatek.com>
> Signed-off-by: Fabien Parent <fparent@baylibre.com>
> ---
>   drivers/net/ethernet/mediatek/mtk_star_emac.c | 23 +++++++++++++++----
>   1 file changed, 19 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> index 1d5dd2015453..7fd8ec0fc636 100644
> --- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
> +++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> @@ -17,6 +17,7 @@
>   #include <linux/module.h>
>   #include <linux/netdevice.h>
>   #include <linux/of.h>
> +#include <linux/of_device.h>
>   #include <linux/of_mdio.h>
>   #include <linux/of_net.h>
>   #include <linux/platform_device.h>
> @@ -232,6 +233,10 @@ struct mtk_star_ring {
>   	unsigned int tail;
>   };
>   
> +struct mtk_star_compat {
> +	unsigned char bit_clk_div;
> +};
> +
>   struct mtk_star_priv {
>   	struct net_device *ndev;
>   
> @@ -257,6 +262,8 @@ struct mtk_star_priv {
>   	int duplex;
>   	int pause;
>   
> +	const struct mtk_star_compat *compat_data;
> +
>   	/* Protects against concurrent descriptor access. */
>   	spinlock_t lock;
>   
> @@ -899,7 +906,7 @@ static void mtk_star_init_config(struct mtk_star_priv *priv)
>   	regmap_write(priv->regs, MTK_STAR_REG_SYS_CONF, val);
>   	regmap_update_bits(priv->regs, MTK_STAR_REG_MAC_CLK_CONF,
>   			   MTK_STAR_MSK_MAC_CLK_CONF,
> -			   MTK_STAR_BIT_CLK_DIV_10);
> +			   priv->compat_data->bit_clk_div);
>   }
>   
>   static void mtk_star_set_mode_rmii(struct mtk_star_priv *priv)
> @@ -1461,6 +1468,7 @@ static int mtk_star_probe(struct platform_device *pdev)
>   
>   	priv = netdev_priv(ndev);
>   	priv->ndev = ndev;
> +	priv->compat_data = of_device_get_match_data(&pdev->dev);
>   	SET_NETDEV_DEV(ndev, dev);
>   	platform_set_drvdata(pdev, ndev);
>   
> @@ -1556,10 +1564,17 @@ static int mtk_star_probe(struct platform_device *pdev)
>   	return devm_register_netdev(dev, ndev);
>   }
>   
> +static const struct mtk_star_compat mtk_star_mt8516_compat = {
> +	.bit_clk_div = MTK_STAR_BIT_CLK_DIV_10,
> +};
> +
>   static const struct of_device_id mtk_star_of_match[] = {
> -	{ .compatible = "mediatek,mt8516-eth", },
> -	{ .compatible = "mediatek,mt8518-eth", },
> -	{ .compatible = "mediatek,mt8175-eth", },
> +	{ .compatible = "mediatek,mt8516-eth",
> +	  .data = &mtk_star_mt8516_compat },
> +	{ .compatible = "mediatek,mt8518-eth",
> +	  .data = &mtk_star_mt8516_compat },
> +	{ .compatible = "mediatek,mt8175-eth",
> +	  .data = &mtk_star_mt8516_compat },
>   	{ }
>   };
>   MODULE_DEVICE_TABLE(of, mtk_star_of_match);
> 

Reviewed-by: Macpaul Lin <macpaul.lin@mediatek.com>

Regards,
Macpaul Lin

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

* Re: [PATCH net-next v2 5/9] net: ethernet: mtk-star-emac: add clock pad selection for RMII
  2022-01-27  1:58 ` [PATCH net-next v2 5/9] net: ethernet: mtk-star-emac: add clock pad selection for RMII Biao Huang
@ 2022-01-27  2:26   ` Macpaul Lin
  0 siblings, 0 replies; 23+ messages in thread
From: Macpaul Lin @ 2022-01-27  2:26 UTC (permalink / raw)
  To: Biao Huang, David Miller, Rob Herring, Bartosz Golaszewski,
	Fabien Parent
  Cc: Jakub Kicinski, Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Yinghua Pan, srv_heupstream

On 1/27/22 9:58 AM, Biao Huang wrote:
> This patch add a new dts property named "mediatek,rmii-rxc" parsing
> in driver, which will configure MAC to select which pin the RMII reference
> clock is connected to, TXC or RXC.
> 
> TXC pad is the default reference clock pin. If user wants to use RXC pad
> instead, add "mediatek,rmii-rxc" to corresponding device node.
> 
> Signed-off-by: Biao Huang <biao.huang@mediatek.com>
> Signed-off-by: Yinghua Pan <ot_yinghua.pan@mediatek.com>
> ---
>   drivers/net/ethernet/mediatek/mtk_star_emac.c | 19 +++++++++++++++++--
>   1 file changed, 17 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> index a3884beaa3fe..d69f75661e75 100644
> --- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
> +++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> @@ -189,6 +189,8 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
>   #define MTK_PERICFG_REG_NIC_CFG_CON_V2		0x0c10
>   #define MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF	GENMASK(3, 0)
>   #define MTK_PERICFG_BIT_NIC_CFG_CON_RMII	1
> +#define MTK_PERICFG_BIT_NIC_CFG_CON_CLK		BIT(0)
> +#define MTK_PERICFG_BIT_NIC_CFG_CON_CLK_V2	BIT(8)
>   
>   /* Represents the actual structure of descriptors used by the MAC. We can
>    * reuse the same structure for both TX and RX - the layout is the same, only
> @@ -265,6 +267,7 @@ struct mtk_star_priv {
>   	int speed;
>   	int duplex;
>   	int pause;
> +	bool rmii_rxc;
>   
>   	const struct mtk_star_compat *compat_data;
>   
> @@ -1528,6 +1531,8 @@ static int mtk_star_probe(struct platform_device *pdev)
>   		return -ENODEV;
>   	}
>   
> +	priv->rmii_rxc = of_property_read_bool(of_node, "mediatek,rmii-rxc");
> +
>   	if (priv->compat_data->set_interface_mode) {
>   		ret = priv->compat_data->set_interface_mode(ndev);
>   		if (ret) {
> @@ -1571,17 +1576,25 @@ static int mt8516_set_interface_mode(struct net_device *ndev)
>   {
>   	struct mtk_star_priv *priv = netdev_priv(ndev);
>   	struct device *dev = mtk_star_get_dev(priv);
> -	unsigned int intf_val;
> +	unsigned int intf_val, ret, rmii_rxc;
>   
>   	switch (priv->phy_intf) {
>   	case PHY_INTERFACE_MODE_RMII:
>   		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
> +		rmii_rxc = priv->rmii_rxc ? 0 : MTK_PERICFG_BIT_NIC_CFG_CON_CLK;
>   		break;
>   	default:
>   		dev_err(dev, "This interface not supported\n");
>   		return -EINVAL;
>   	}
>   
> +	ret = regmap_update_bits(priv->pericfg,
> +				 MTK_PERICFG_REG_NIC_CFG1_CON,
> +				 MTK_PERICFG_BIT_NIC_CFG_CON_CLK,
> +				 rmii_rxc);
> +	if (ret)
> +		return ret;
> +
>   	return regmap_update_bits(priv->pericfg,
>   				  MTK_PERICFG_REG_NIC_CFG0_CON,
>   				  MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF,
> @@ -1597,6 +1610,7 @@ static int mt8365_set_interface_mode(struct net_device *ndev)
>   	switch (priv->phy_intf) {
>   	case PHY_INTERFACE_MODE_RMII:
>   		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
> +		intf_val |= priv->rmii_rxc ? 0 : MTK_PERICFG_BIT_NIC_CFG_CON_CLK_V2;
>   		break;
>   	default:
>   		dev_err(dev, "This interface not supported\n");
> @@ -1605,7 +1619,8 @@ static int mt8365_set_interface_mode(struct net_device *ndev)
>   
>   	return regmap_update_bits(priv->pericfg,
>   				  MTK_PERICFG_REG_NIC_CFG_CON_V2,
> -				  MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF,
> +				  MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF |
> +				  MTK_PERICFG_BIT_NIC_CFG_CON_CLK_V2,
>   				  intf_val);
>   }
>   
> 

Reviewed-by: Macpaul Lin <macpaul.lin@mediatek.com>

Regards,
Macpaul Lin

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

* Re: [PATCH net-next v2 9/9] net: ethernet: mtk-star-emac: separate tx/rx handling with two NAPIs
  2022-01-27  1:58 ` [PATCH net-next v2 9/9] net: ethernet: mtk-star-emac: separate tx/rx handling with two NAPIs Biao Huang
@ 2022-01-28  3:43   ` Jakub Kicinski
  2022-01-28  7:05     ` Biao Huang
  0 siblings, 1 reply; 23+ messages in thread
From: Jakub Kicinski @ 2022-01-28  3:43 UTC (permalink / raw)
  To: Biao Huang
  Cc: David Miller, Rob Herring, Bartosz Golaszewski, Fabien Parent,
	Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Yinghua Pan, srv_heupstream,
	Macpaul Lin

On Thu, 27 Jan 2022 09:58:57 +0800 Biao Huang wrote:
> Current driver may lost tx interrupts under bidirectional test with iperf3,
> which leads to some unexpected issues.
> 
> This patch let rx/tx interrupt enable/disable separately, and rx/tx are
> handled in different NAPIs.

> +/* mtk_star_handle_irq - Interrupt Handler.
> + * @irq: interrupt number.
> + * @data: pointer to a network interface device structure.

if you mean this to me a kdoc comment it needs to start with /**

> + * Description : this is the driver interrupt service routine.
> + * it mainly handles:
> + *  1. tx complete interrupt for frame transmission.
> + *  2. rx complete interrupt for frame reception.
> + *  3. MAC Management Counter interrupt to avoid counter overflow.
>   */
>  static irqreturn_t mtk_star_handle_irq(int irq, void *data)
>  {
> -	struct mtk_star_priv *priv;
> -	struct net_device *ndev;
> +	struct net_device *ndev = data;
> +	struct mtk_star_priv *priv = netdev_priv(ndev);
> +	unsigned int intr_status = mtk_star_intr_ack_all(priv);
> +	unsigned long flags = 0;
> +
> +	if (intr_status & MTK_STAR_BIT_INT_STS_FNRC) {
> +		if (napi_schedule_prep(&priv->rx_napi)) {
> +			spin_lock_irqsave(&priv->lock, flags);
> +			/* mask Rx Complete interrupt */
> +			mtk_star_disable_dma_irq(priv, true, false);
> +			spin_unlock_irqrestore(&priv->lock, flags);
> +			__napi_schedule_irqoff(&priv->rx_napi);
> +		}
> +	}
>  
> -	ndev = data;
> -	priv = netdev_priv(ndev);
> +	if (intr_status & MTK_STAR_BIT_INT_STS_TNTC) {
> +		if (napi_schedule_prep(&priv->tx_napi)) {
> +			spin_lock_irqsave(&priv->lock, flags);
> +			/* mask Tx Complete interrupt */
> +			mtk_star_disable_dma_irq(priv, false, true);
> +			spin_unlock_irqrestore(&priv->lock, flags);
> +			__napi_schedule_irqoff(&priv->tx_napi);
> +		}
> +	}

Seems a little wasteful to retake the same lock twice if two IRQ
sources fire at the same time.

> @@ -1043,6 +1085,17 @@ static int mtk_star_netdev_start_xmit(struct sk_buff *skb,
>  	struct mtk_star_ring *ring = &priv->tx_ring;
>  	struct device *dev = mtk_star_get_dev(priv);
>  	struct mtk_star_ring_desc_data desc_data;
> +	int nfrags = skb_shinfo(skb)->nr_frags;
> +
> +	if (unlikely(mtk_star_tx_ring_avail(ring) < nfrags + 1)) {
> +		if (!netif_queue_stopped(ndev)) {
> +			netif_stop_queue(ndev);
> +			/* This is a hard error, log it. */
> +			netdev_err(priv->ndev, "%s: Tx Ring full when queue awake\n",
> +				   __func__);

This needs to be rate limited. Also no point printing the function
name, unless the same message appears in multiple places.

> +		}
> +		return NETDEV_TX_BUSY;
> +	}
>  
>  	desc_data.dma_addr = mtk_star_dma_map_tx(priv, skb);
>  	if (dma_mapping_error(dev, desc_data.dma_addr))
> @@ -1050,18 +1103,10 @@ static int mtk_star_netdev_start_xmit(struct sk_buff *skb,
>  
>  	desc_data.skb = skb;
>  	desc_data.len = skb->len;
> -
> -	spin_lock_bh(&priv->lock);
> 
>  	mtk_star_ring_push_head_tx(ring, &desc_data);
>  
>  	netdev_sent_queue(ndev, skb->len);
>  
> -	if (mtk_star_ring_full(ring))
> -		netif_stop_queue(ndev);

Are you stopping the queue in advance somewhere else now? Did you only
test this with BQL enabled? Only place that stops the ring also prints
a loud warning now AFAICS..

> -static void mtk_star_tx_complete_all(struct mtk_star_priv *priv)
> +static int mtk_star_tx_poll(struct napi_struct *napi, int budget)
>  {
> -	struct mtk_star_ring *ring = &priv->tx_ring;
> -	struct net_device *ndev = priv->ndev;
> -	int ret, pkts_compl, bytes_compl;
> +	int ret, pkts_compl = 0, bytes_compl = 0, count = 0;
> +	struct mtk_star_priv *priv;
> +	struct mtk_star_ring *ring;
> +	struct net_device *ndev;
> +	unsigned long flags = 0;
> +	unsigned int entry;
>  	bool wake = false;
>  
> -	spin_lock(&priv->lock);
> +	priv = container_of(napi, struct mtk_star_priv, tx_napi);
> +	ndev = priv->ndev;
>  
> -	for (pkts_compl = 0, bytes_compl = 0;;
> +	__netif_tx_lock_bh(netdev_get_tx_queue(priv->ndev, 0));

Do you really need to lock out the Tx while cleaning?

Drivers usually manage to implement concurrent Tx and cleanup with just
a couple of memory barriers.

> +	ring = &priv->tx_ring;
> +	entry = ring->tail;
> +	for (pkts_compl = 0, bytes_compl = 0;
> +	     (entry != ring->head) && (count < budget);

budget is not really relevant for Tx, you can clean the whole ring.
netpoll will pass a budget of 0 to clean up rings.

>  	     pkts_compl++, bytes_compl += ret, wake = true) {
> -		if (!mtk_star_ring_descs_available(ring))
> -			break;
>  
>  		ret = mtk_star_tx_complete_one(priv);
>  		if (ret < 0)
>  			break;
> +		count++;
> +		entry = ring->tail;
>  	}
>  

> @@ -1196,7 +1258,7 @@ static const struct ethtool_ops mtk_star_ethtool_ops = {
>  	.set_link_ksettings	= phy_ethtool_set_link_ksettings,
>  };
>  
> -static int mtk_star_receive_packet(struct mtk_star_priv *priv)
> +static int mtk_star_rx(struct mtk_star_priv *priv, int budget)
>  {
>  	struct mtk_star_ring *ring = &priv->rx_ring;
>  	struct device *dev = mtk_star_get_dev(priv);
> @@ -1204,107 +1266,86 @@ static int mtk_star_receive_packet(struct mtk_star_priv *priv)
>  	struct net_device *ndev = priv->ndev;
>  	struct sk_buff *curr_skb, *new_skb;
>  	dma_addr_t new_dma_addr;
> -	int ret;
> +	int ret, count = 0;
>  
> -	spin_lock(&priv->lock);
> -	ret = mtk_star_ring_pop_tail(ring, &desc_data);
> -	spin_unlock(&priv->lock);
> -	if (ret)
> -		return -1;
> +	while (count < budget) {
> +		ret = mtk_star_ring_pop_tail(ring, &desc_data);
> +		if (ret)
> +			return -1;

> -static int mtk_star_process_rx(struct mtk_star_priv *priv, int budget)
> -{
> -	int received, ret;
> +		count++;
>  
> -	for (received = 0, ret = 0; received < budget && ret == 0; received++)
> -		ret = mtk_star_receive_packet(priv);
> +		desc_data.len = skb_tailroom(new_skb);
> +		desc_data.skb = new_skb;
> +		mtk_star_ring_push_head_rx(ring, &desc_data);
> +	}
>  
>  	mtk_star_dma_resume_rx(priv);

Again you can get a call with a budget of 0, not sure if it's okay to
resume DMA in that case..

> -	return received;
> +	return count;
>  }


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

* Re: [PATCH net-next v2 9/9] net: ethernet: mtk-star-emac: separate tx/rx handling with two NAPIs
  2022-01-28  3:43   ` Jakub Kicinski
@ 2022-01-28  7:05     ` Biao Huang
  2022-01-28 15:44       ` Jakub Kicinski
  0 siblings, 1 reply; 23+ messages in thread
From: Biao Huang @ 2022-01-28  7:05 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: David Miller, Rob Herring, Bartosz Golaszewski, Fabien Parent,
	Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Yinghua Pan, srv_heupstream,
	Macpaul Lin

Dear Jakub,
	Thanks for your comments!

On Thu, 2022-01-27 at 19:43 -0800, Jakub Kicinski wrote:
> On Thu, 27 Jan 2022 09:58:57 +0800 Biao Huang wrote:
> > Current driver may lost tx interrupts under bidirectional test with
> > iperf3,
> > which leads to some unexpected issues.
> > 
> > This patch let rx/tx interrupt enable/disable separately, and rx/tx
> > are
> > handled in different NAPIs.
> > +/* mtk_star_handle_irq - Interrupt Handler.
> > + * @irq: interrupt number.
> > + * @data: pointer to a network interface device structure.
> 
> if you mean this to me a kdoc comment it needs to start with /**
Yes, will fix in next send.
> 
> > + * Description : this is the driver interrupt service routine.
> > + * it mainly handles:
> > + *  1. tx complete interrupt for frame transmission.
> > + *  2. rx complete interrupt for frame reception.
> > + *  3. MAC Management Counter interrupt to avoid counter overflow.
> >   */
> >  static irqreturn_t mtk_star_handle_irq(int irq, void *data)
> >  {
> > -	struct mtk_star_priv *priv;
> > -	struct net_device *ndev;
> > +	struct net_device *ndev = data;
> > +	struct mtk_star_priv *priv = netdev_priv(ndev);
> > +	unsigned int intr_status = mtk_star_intr_ack_all(priv);
> > +	unsigned long flags = 0;
> > +
> > +	if (intr_status & MTK_STAR_BIT_INT_STS_FNRC) {
> > +		if (napi_schedule_prep(&priv->rx_napi)) {
> > +			spin_lock_irqsave(&priv->lock, flags);
> > +			/* mask Rx Complete interrupt */
> > +			mtk_star_disable_dma_irq(priv, true, false);
> > +			spin_unlock_irqrestore(&priv->lock, flags);
> > +			__napi_schedule_irqoff(&priv->rx_napi);
> > +		}
> > +	}
> >  
> > -	ndev = data;
> > -	priv = netdev_priv(ndev);
> > +	if (intr_status & MTK_STAR_BIT_INT_STS_TNTC) {
> > +		if (napi_schedule_prep(&priv->tx_napi)) {
> > +			spin_lock_irqsave(&priv->lock, flags);
> > +			/* mask Tx Complete interrupt */
> > +			mtk_star_disable_dma_irq(priv, false, true);
> > +			spin_unlock_irqrestore(&priv->lock, flags);
> > +			__napi_schedule_irqoff(&priv->tx_napi);
> > +		}
> > +	}
> 
> Seems a little wasteful to retake the same lock twice if two IRQ
> sources fire at the same time.
The TX/RX irq control bits are in the same register,
but they are triggered independently.
So it seems necessary to protect the register
access with a spin lock.
> 
> > @@ -1043,6 +1085,17 @@ static int mtk_star_netdev_start_xmit(struct
> > sk_buff *skb,
> >  	struct mtk_star_ring *ring = &priv->tx_ring;
> >  	struct device *dev = mtk_star_get_dev(priv);
> >  	struct mtk_star_ring_desc_data desc_data;
> > +	int nfrags = skb_shinfo(skb)->nr_frags;
> > +
> > +	if (unlikely(mtk_star_tx_ring_avail(ring) < nfrags + 1)) {
> > +		if (!netif_queue_stopped(ndev)) {
> > +			netif_stop_queue(ndev);
> > +			/* This is a hard error, log it. */
> > +			netdev_err(priv->ndev, "%s: Tx Ring full when
> > queue awake\n",
> > +				   __func__);
> 
> This needs to be rate limited. Also no point printing the function
> name, unless the same message appears in multiple places.
OK, will fix in next send.
> 
> > +		}
> > +		return NETDEV_TX_BUSY;
> > +	}
> >  
> >  	desc_data.dma_addr = mtk_star_dma_map_tx(priv, skb);
> >  	if (dma_mapping_error(dev, desc_data.dma_addr))
> > @@ -1050,18 +1103,10 @@ static int
> > mtk_star_netdev_start_xmit(struct sk_buff *skb,
> >  
> >  	desc_data.skb = skb;
> >  	desc_data.len = skb->len;
> > -
> > -	spin_lock_bh(&priv->lock);
> > 
> >  	mtk_star_ring_push_head_tx(ring, &desc_data);
> >  
> >  	netdev_sent_queue(ndev, skb->len);
> >  
> > -	if (mtk_star_ring_full(ring))
> > -		netif_stop_queue(ndev);
> 
> Are you stopping the queue in advance somewhere else now? Did you
> only
> test this with BQL enabled? Only place that stops the ring also
> prints
> a loud warning now AFAICS..
No.

We modify the ring full condition, and will not invoke netif_stop_queue
if queue is already stopped.
Test pass no matter whether BQL is enabled or disabled.

It's much safer to judge queue is full or not at the beginning of
start_xmit() to avoid invalid setting.
> 
> > -static void mtk_star_tx_complete_all(struct mtk_star_priv *priv)
> > +static int mtk_star_tx_poll(struct napi_struct *napi, int budget)
> >  {
> > -	struct mtk_star_ring *ring = &priv->tx_ring;
> > -	struct net_device *ndev = priv->ndev;
> > -	int ret, pkts_compl, bytes_compl;
> > +	int ret, pkts_compl = 0, bytes_compl = 0, count = 0;
> > +	struct mtk_star_priv *priv;
> > +	struct mtk_star_ring *ring;
> > +	struct net_device *ndev;
> > +	unsigned long flags = 0;
> > +	unsigned int entry;
> >  	bool wake = false;
> >  
> > -	spin_lock(&priv->lock);
> > +	priv = container_of(napi, struct mtk_star_priv, tx_napi);
> > +	ndev = priv->ndev;
> >  
> > -	for (pkts_compl = 0, bytes_compl = 0;;
> > +	__netif_tx_lock_bh(netdev_get_tx_queue(priv->ndev, 0));
> 
> Do you really need to lock out the Tx while cleaning?
> 
> Drivers usually manage to implement concurrent Tx and cleanup with
> just
> a couple of memory barriers.
We'll simplify the lock handling in next send,
the lock should protect tx descriptor ring, which is accessed by xmit()
and tx_complete().
> 
> > +	ring = &priv->tx_ring;
> > +	entry = ring->tail;
> > +	for (pkts_compl = 0, bytes_compl = 0;
> > +	     (entry != ring->head) && (count < budget);
> 
> budget is not really relevant for Tx, you can clean the whole ring.
> netpoll will pass a budget of 0 to clean up rings.
OK, will fix in next send.
> 
> >  	     pkts_compl++, bytes_compl += ret, wake = true) {
> > -		if (!mtk_star_ring_descs_available(ring))
> > -			break;
> >  
> >  		ret = mtk_star_tx_complete_one(priv);
> >  		if (ret < 0)
> >  			break;
> > +		count++;
> > +		entry = ring->tail;
> >  	}
> >  
> > @@ -1196,7 +1258,7 @@ static const struct ethtool_ops
> > mtk_star_ethtool_ops = {
> >  	.set_link_ksettings	= phy_ethtool_set_link_ksettings,
> >  };
> >  
> > -static int mtk_star_receive_packet(struct mtk_star_priv *priv)
> > +static int mtk_star_rx(struct mtk_star_priv *priv, int budget)
> >  {
> >  	struct mtk_star_ring *ring = &priv->rx_ring;
> >  	struct device *dev = mtk_star_get_dev(priv);
> > @@ -1204,107 +1266,86 @@ static int mtk_star_receive_packet(struct
> > mtk_star_priv *priv)
> >  	struct net_device *ndev = priv->ndev;
> >  	struct sk_buff *curr_skb, *new_skb;
> >  	dma_addr_t new_dma_addr;
> > -	int ret;
> > +	int ret, count = 0;
> >  
> > -	spin_lock(&priv->lock);
> > -	ret = mtk_star_ring_pop_tail(ring, &desc_data);
> > -	spin_unlock(&priv->lock);
> > -	if (ret)
> > -		return -1;
> > +	while (count < budget) {
> > +		ret = mtk_star_ring_pop_tail(ring, &desc_data);
> > +		if (ret)
> > +			return -1;
> > -static int mtk_star_process_rx(struct mtk_star_priv *priv, int
> > budget)
> > -{
> > -	int received, ret;
> > +		count++;
> >  
> > -	for (received = 0, ret = 0; received < budget && ret == 0;
> > received++)
> > -		ret = mtk_star_receive_packet(priv);
> > +		desc_data.len = skb_tailroom(new_skb);
> > +		desc_data.skb = new_skb;
> > +		mtk_star_ring_push_head_rx(ring, &desc_data);
> > +	}
> >  
> >  	mtk_star_dma_resume_rx(priv);
> 
> Again you can get a call with a budget of 0, not sure if it's okay to
> resume DMA in that case..
OK, we'll take it into consideration in next send.
> 
> > -	return received;
> > +	return count;
> >  }
> 
> 
Regards!
Biao


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

* Re: [PATCH net-next v2 9/9] net: ethernet: mtk-star-emac: separate tx/rx handling with two NAPIs
  2022-01-28  7:05     ` Biao Huang
@ 2022-01-28 15:44       ` Jakub Kicinski
  2022-03-14  7:01         ` Biao Huang
  0 siblings, 1 reply; 23+ messages in thread
From: Jakub Kicinski @ 2022-01-28 15:44 UTC (permalink / raw)
  To: Biao Huang
  Cc: David Miller, Rob Herring, Bartosz Golaszewski, Fabien Parent,
	Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Yinghua Pan, srv_heupstream,
	Macpaul Lin

On Fri, 28 Jan 2022 15:05:27 +0800 Biao Huang wrote:
> > > + * Description : this is the driver interrupt service routine.
> > > + * it mainly handles:
> > > + *  1. tx complete interrupt for frame transmission.
> > > + *  2. rx complete interrupt for frame reception.
> > > + *  3. MAC Management Counter interrupt to avoid counter overflow.
> > >   */
> > >  static irqreturn_t mtk_star_handle_irq(int irq, void *data)
> > >  {
> > > -	struct mtk_star_priv *priv;
> > > -	struct net_device *ndev;
> > > +	struct net_device *ndev = data;
> > > +	struct mtk_star_priv *priv = netdev_priv(ndev);
> > > +	unsigned int intr_status = mtk_star_intr_ack_all(priv);
> > > +	unsigned long flags = 0;
> > > +
> > > +	if (intr_status & MTK_STAR_BIT_INT_STS_FNRC) {
> > > +		if (napi_schedule_prep(&priv->rx_napi)) {
> > > +			spin_lock_irqsave(&priv->lock, flags);
> > > +			/* mask Rx Complete interrupt */
> > > +			mtk_star_disable_dma_irq(priv, true, false);
> > > +			spin_unlock_irqrestore(&priv->lock, flags);
> > > +			__napi_schedule_irqoff(&priv->rx_napi);
> > > +		}
> > > +	}
> > >  
> > > -	ndev = data;
> > > -	priv = netdev_priv(ndev);
> > > +	if (intr_status & MTK_STAR_BIT_INT_STS_TNTC) {
> > > +		if (napi_schedule_prep(&priv->tx_napi)) {
> > > +			spin_lock_irqsave(&priv->lock, flags);
> > > +			/* mask Tx Complete interrupt */
> > > +			mtk_star_disable_dma_irq(priv, false, true);
> > > +			spin_unlock_irqrestore(&priv->lock, flags);
> > > +			__napi_schedule_irqoff(&priv->tx_napi);
> > > +		}
> > > +	}  
> > 
> > Seems a little wasteful to retake the same lock twice if two IRQ
> > sources fire at the same time.  
> The TX/RX irq control bits are in the same register,
> but they are triggered independently.
> So it seems necessary to protect the register
> access with a spin lock.

This is what I meant:

rx = (status & RX) && napi_schedule_prep(rx_napi);
tx = (status & TX) && napi_schedule_prep(tx_napi);

if (rx || tx) {
	spin_lock()
	disable_irq(priv, rx, tx);	
	spin_unlock();
	if (rx)
		__napi_schedule_irqoff(rx_napi)
	if (tx)
		__napi_schedule_irqoff(tx_napi)
}

> > >  	desc_data.dma_addr = mtk_star_dma_map_tx(priv, skb);
> > >  	if (dma_mapping_error(dev, desc_data.dma_addr))
> > > @@ -1050,18 +1103,10 @@ static int
> > > mtk_star_netdev_start_xmit(struct sk_buff *skb,
> > >  
> > >  	desc_data.skb = skb;
> > >  	desc_data.len = skb->len;
> > > -
> > > -	spin_lock_bh(&priv->lock);
> > > 
> > >  	mtk_star_ring_push_head_tx(ring, &desc_data);
> > >  
> > >  	netdev_sent_queue(ndev, skb->len);
> > >  
> > > -	if (mtk_star_ring_full(ring))
> > > -		netif_stop_queue(ndev);  
> > 
> > Are you stopping the queue in advance somewhere else now? Did you
> > only
> > test this with BQL enabled? Only place that stops the ring also
> > prints
> > a loud warning now AFAICS..  
> No.
> 
> We modify the ring full condition, and will not invoke netif_stop_queue
> if queue is already stopped.

I don't understand what you're saying.

> Test pass no matter whether BQL is enabled or disabled.
> 
> It's much safer to judge queue is full or not at the beginning of
> start_xmit() to avoid invalid setting.

Drivers are expected to stop their queues at the end of xmit routine if
the ring can't accommodate another frame. It's more efficient to stop
the queues early than have to put skbs already dequeued from the qdisc
layer back into the qdiscs.

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

* Re: [PATCH net-next v2 4/9] dt-bindings: net: mtk-star-emac: add support for MT8365
  2022-01-27  1:58 ` [PATCH net-next v2 4/9] dt-bindings: net: mtk-star-emac: add support for MT8365 Biao Huang
@ 2022-02-09  3:35   ` Rob Herring
  0 siblings, 0 replies; 23+ messages in thread
From: Rob Herring @ 2022-02-09  3:35 UTC (permalink / raw)
  To: Biao Huang
  Cc: Mark Lee, linux-arm-kernel, Fabien Parent, Bartosz Golaszewski,
	Felix Fietkau, devicetree, Macpaul Lin, John Crispin,
	Jakub Kicinski, linux-mediatek, srv_heupstream, Matthias Brugger,
	netdev, Sean Wang, Rob Herring, linux-kernel, David Miller,
	Yinghua Pan

On Thu, 27 Jan 2022 09:58:52 +0800, Biao Huang wrote:
> Add binding document for Ethernet on MT8365.
> 
> Signed-off-by: Biao Huang <biao.huang@mediatek.com>
> Reviewed-by: Bartosz Golaszewski <brgl@bgdev.pl>
> ---
>  Documentation/devicetree/bindings/net/mediatek,star-emac.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH net-next v2 7/9] dt-bindings: net: mtk-star-emac: add description for new  properties
  2022-01-27  1:58 ` [PATCH net-next v2 7/9] dt-bindings: net: mtk-star-emac: add description for new properties Biao Huang
@ 2022-02-09  3:36   ` Rob Herring
  0 siblings, 0 replies; 23+ messages in thread
From: Rob Herring @ 2022-02-09  3:36 UTC (permalink / raw)
  To: Biao Huang
  Cc: srv_heupstream, linux-kernel, Bartosz Golaszewski,
	Matthias Brugger, netdev, Jakub Kicinski, Macpaul Lin,
	Yinghua Pan, David Miller, Felix Fietkau, John Crispin,
	Rob Herring, devicetree, Mark Lee, Sean Wang, linux-mediatek,
	Fabien Parent, linux-arm-kernel

On Thu, 27 Jan 2022 09:58:55 +0800, Biao Huang wrote:
> Add description for new properties which will be parsed in driver.
> 
> Signed-off-by: Biao Huang <biao.huang@mediatek.com>
> ---
>  .../bindings/net/mediatek,star-emac.yaml         | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH net-next v2 9/9] net: ethernet: mtk-star-emac: separate tx/rx handling with two NAPIs
  2022-01-28 15:44       ` Jakub Kicinski
@ 2022-03-14  7:01         ` Biao Huang
  2022-03-14 15:57           ` Jakub Kicinski
  0 siblings, 1 reply; 23+ messages in thread
From: Biao Huang @ 2022-03-14  7:01 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: David Miller, Rob Herring, Bartosz Golaszewski, Fabien Parent,
	Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Yinghua Pan, srv_heupstream,
	Macpaul Lin

Dear Jakub,
	Thanks for your comments~

On Fri, 2022-01-28 at 07:44 -0800, Jakub Kicinski wrote:
> On Fri, 28 Jan 2022 15:05:27 +0800 Biao Huang wrote:
> > > > + * Description : this is the driver interrupt service routine.
> > > > + * it mainly handles:
> > > > + *  1. tx complete interrupt for frame transmission.
> > > > + *  2. rx complete interrupt for frame reception.
> > > > + *  3. MAC Management Counter interrupt to avoid counter
> > > > overflow.
> > > >   */
> > > >  static irqreturn_t mtk_star_handle_irq(int irq, void *data)
> > > >  {
> > > > -	struct mtk_star_priv *priv;
> > > > -	struct net_device *ndev;
> > > > +	struct net_device *ndev = data;
> > > > +	struct mtk_star_priv *priv = netdev_priv(ndev);
> > > > +	unsigned int intr_status = mtk_star_intr_ack_all(priv);
> > > > +	unsigned long flags = 0;
> > > > +
> > > > +	if (intr_status & MTK_STAR_BIT_INT_STS_FNRC) {
> > > > +		if (napi_schedule_prep(&priv->rx_napi)) {
> > > > +			spin_lock_irqsave(&priv->lock, flags);
> > > > +			/* mask Rx Complete interrupt */
> > > > +			mtk_star_disable_dma_irq(priv, true,
> > > > false);
> > > > +			spin_unlock_irqrestore(&priv->lock,
> > > > flags);
> > > > +			__napi_schedule_irqoff(&priv->rx_napi);
> > > > +		}
> > > > +	}
> > > >  
> > > > -	ndev = data;
> > > > -	priv = netdev_priv(ndev);
> > > > +	if (intr_status & MTK_STAR_BIT_INT_STS_TNTC) {
> > > > +		if (napi_schedule_prep(&priv->tx_napi)) {
> > > > +			spin_lock_irqsave(&priv->lock, flags);
> > > > +			/* mask Tx Complete interrupt */
> > > > +			mtk_star_disable_dma_irq(priv, false,
> > > > true);
> > > > +			spin_unlock_irqrestore(&priv->lock,
> > > > flags);
> > > > +			__napi_schedule_irqoff(&priv->tx_napi);
> > > > +		}
> > > > +	}  
> > > 
> > > Seems a little wasteful to retake the same lock twice if two IRQ
> > > sources fire at the same time.  
> > 
> > The TX/RX irq control bits are in the same register,
> > but they are triggered independently.
> > So it seems necessary to protect the register
> > access with a spin lock.
> 
> This is what I meant:
> 
> rx = (status & RX) && napi_schedule_prep(rx_napi);
> tx = (status & TX) && napi_schedule_prep(tx_napi);
> 
> if (rx || tx) {
> 	spin_lock()
> 	disable_irq(priv, rx, tx);	
> 	spin_unlock();
> 	if (rx)
> 		__napi_schedule_irqoff(rx_napi)
> 	if (tx)
> 		__napi_schedule_irqoff(tx_napi)
> }
> 
OK, We'll adopt your suggestion, and corresponding modification will be
added in next send.
> > > >  	desc_data.dma_addr = mtk_star_dma_map_tx(priv, skb);
> > > >  	if (dma_mapping_error(dev, desc_data.dma_addr))
> > > > @@ -1050,18 +1103,10 @@ static int
> > > > mtk_star_netdev_start_xmit(struct sk_buff *skb,
> > > >  
> > > >  	desc_data.skb = skb;
> > > >  	desc_data.len = skb->len;
> > > > -
> > > > -	spin_lock_bh(&priv->lock);
> > > > 
> > > >  	mtk_star_ring_push_head_tx(ring, &desc_data);
> > > >  
> > > >  	netdev_sent_queue(ndev, skb->len);
> > > >  
> > > > -	if (mtk_star_ring_full(ring))
> > > > -		netif_stop_queue(ndev);  
> > > 
> > > Are you stopping the queue in advance somewhere else now? Did you
> > > only
> > > test this with BQL enabled? Only place that stops the ring also
> > > prints
> > > a loud warning now AFAICS..  
> > 
> > No.
> > 
> > We modify the ring full condition, and will not invoke
> > netif_stop_queue
> > if queue is already stopped.
> 
> I don't understand what you're saying.
> 
> > Test pass no matter whether BQL is enabled or disabled.
> > 
> > It's much safer to judge queue is full or not at the beginning of
> > start_xmit() to avoid invalid setting.
> 
> Drivers are expected to stop their queues at the end of xmit routine
> if
> the ring can't accommodate another frame. It's more efficient to stop
> the queues early than have to put skbs already dequeued from the
> qdisc
> layer back into the qdiscs.
Yes, if descriptors ring is full, it's meaningful to stop the queue 
at the end of xmit; 
But driver seems hard to know how many descriptors the next skb will
request, e.g. 3 descriptors are available for next round send, but the
next skb may need 4 descriptors, in this case, we still need judge
whether descriptors are enough for skb transmission, then decide stop
the queue or not, at the beginning of xmit routine.

Maybe we should judge ring is full or not at the beginning and the end
of xmit routine(seems a little redundancy).

Regards~


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

* Re: [PATCH net-next v2 9/9] net: ethernet: mtk-star-emac: separate tx/rx handling with two NAPIs
  2022-03-14  7:01         ` Biao Huang
@ 2022-03-14 15:57           ` Jakub Kicinski
  2022-03-15  0:59             ` Biao Huang
  0 siblings, 1 reply; 23+ messages in thread
From: Jakub Kicinski @ 2022-03-14 15:57 UTC (permalink / raw)
  To: Biao Huang
  Cc: David Miller, Rob Herring, Bartosz Golaszewski, Fabien Parent,
	Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Yinghua Pan, srv_heupstream,
	Macpaul Lin

On Mon, 14 Mar 2022 15:01:23 +0800 Biao Huang wrote:
> > Drivers are expected to stop their queues at the end of xmit routine
> > if
> > the ring can't accommodate another frame. It's more efficient to stop
> > the queues early than have to put skbs already dequeued from the
> > qdisc
> > layer back into the qdiscs.  
> Yes, if descriptors ring is full, it's meaningful to stop the queue 
> at the end of xmit; 
> But driver seems hard to know how many descriptors the next skb will
> request, e.g. 3 descriptors are available for next round send, but the
> next skb may need 4 descriptors, in this case, we still need judge
> whether descriptors are enough for skb transmission, then decide stop
> the queue or not, at the beginning of xmit routine.
> 
> Maybe we should judge ring is full or not at the beginning and the end
> of xmit routine(seems a little redundancy).

Assume the worst case scenario. You set the default ring size to 512,
skb can have at most MAX_SKB_FRAGS fragments (usually 17) so the max
number of descriptors should not be very high, hard to pre-compute,
or problematic compared to the total ring size.

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

* Re: [PATCH net-next v2 9/9] net: ethernet: mtk-star-emac: separate tx/rx handling with two NAPIs
  2022-03-14 15:57           ` Jakub Kicinski
@ 2022-03-15  0:59             ` Biao Huang
  0 siblings, 0 replies; 23+ messages in thread
From: Biao Huang @ 2022-03-15  0:59 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: David Miller, Rob Herring, Bartosz Golaszewski, Fabien Parent,
	Felix Fietkau, John Crispin, Sean Wang, Mark Lee,
	Matthias Brugger, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Yinghua Pan, srv_heupstream,
	Macpaul Lin

Dear Jakub,
	Thanks for your comments~

On Mon, 2022-03-14 at 08:57 -0700, Jakub Kicinski wrote:
> On Mon, 14 Mar 2022 15:01:23 +0800 Biao Huang wrote:
> > > Drivers are expected to stop their queues at the end of xmit
> > > routine
> > > if
> > > the ring can't accommodate another frame. It's more efficient to
> > > stop
> > > the queues early than have to put skbs already dequeued from the
> > > qdisc
> > > layer back into the qdiscs.  
> > 
> > Yes, if descriptors ring is full, it's meaningful to stop the
> > queue 
> > at the end of xmit; 
> > But driver seems hard to know how many descriptors the next skb
> > will
> > request, e.g. 3 descriptors are available for next round send, but
> > the
> > next skb may need 4 descriptors, in this case, we still need judge
> > whether descriptors are enough for skb transmission, then decide
> > stop
> > the queue or not, at the beginning of xmit routine.
> > 
> > Maybe we should judge ring is full or not at the beginning and the
> > end
> > of xmit routine(seems a little redundancy).
> 
> Assume the worst case scenario. You set the default ring size to 512,
> skb can have at most MAX_SKB_FRAGS fragments (usually 17) so the max
> number of descriptors should not be very high, hard to pre-compute,
> or problematic compared to the total ring size.
Yes, we'll check the available descriptor number at the end of xmit
routine, and ensure it will larger than (MAX_SKB_FRAGS + 1) in next
send. (refer to stmmac_main.c)

Regards!


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

end of thread, other threads:[~2022-03-15  0:59 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-27  1:58 [PATCH net-next v2 0/9] add more features for mtk-star-emac Biao Huang
2022-01-27  1:58 ` [PATCH net-next v2 1/9] net: ethernet: mtk-star-emac: store bit_clk_div in compat structure Biao Huang
2022-01-27  2:23   ` Macpaul Lin
2022-01-27  1:58 ` [PATCH net-next v2 2/9] net: ethernet: mtk-star-emac: modify IRQ trigger flags Biao Huang
2022-01-27  1:58 ` [PATCH net-next v2 3/9] net: ethernet: mtk-star-emac: add support for MT8365 SoC Biao Huang
2022-01-27  2:22   ` Macpaul Lin
2022-01-27  1:58 ` [PATCH net-next v2 4/9] dt-bindings: net: mtk-star-emac: add support for MT8365 Biao Huang
2022-02-09  3:35   ` Rob Herring
2022-01-27  1:58 ` [PATCH net-next v2 5/9] net: ethernet: mtk-star-emac: add clock pad selection for RMII Biao Huang
2022-01-27  2:26   ` Macpaul Lin
2022-01-27  1:58 ` [PATCH net-next v2 6/9] net: ethernet: mtk-star-emac: add timing adjustment support Biao Huang
2022-01-27  2:20   ` Macpaul Lin
2022-01-27  1:58 ` [PATCH net-next v2 7/9] dt-bindings: net: mtk-star-emac: add description for new properties Biao Huang
2022-02-09  3:36   ` Rob Herring
2022-01-27  1:58 ` [PATCH net-next v2 8/9] net: ethernet: mtk-star-emac: add support for MII interface Biao Huang
2022-01-27  2:17   ` Macpaul Lin
2022-01-27  1:58 ` [PATCH net-next v2 9/9] net: ethernet: mtk-star-emac: separate tx/rx handling with two NAPIs Biao Huang
2022-01-28  3:43   ` Jakub Kicinski
2022-01-28  7:05     ` Biao Huang
2022-01-28 15:44       ` Jakub Kicinski
2022-03-14  7:01         ` Biao Huang
2022-03-14 15:57           ` Jakub Kicinski
2022-03-15  0:59             ` Biao Huang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).