Bjørn Mork <bj...@mork.no> writes:

> The WiFi extender I am having trouble with (ZyXEL WAP6805 - similar to
> the WAP6806) has an RGMII connected Quantenna 5Ghz module.  My
> assumption is that this module is connected to the RGMII pads on the
> MT7621 and that I need support for the second GMAC to get it running.
> The Quantenna module loads its firmware using TFTP in the OEM firmware.
>
> I note that forum user Thirsty has had some success using the mainline
> MT7623 driver to enable both GMACs:
> https://forum.lede-project.org/t/er-x-sfp-sfp-eth5-port-has-link-state-led-lit-but-swconfig-says-link-port-5-link-down/4608/70
>
> but this currently implies DSA, so it's not exactly plug-and-play with
> OpenWrt.  I haven't tried it myself yet.

My progress is slow... Just keeping this thread alive ;-)

Encouraged by the possible switch (pun intended) to DSA for the next
release, I decided to try out Thirsty's solution.  And it worked fine,
with a slight device-specific tweak (details below).

So I thought I could go a little further and try to reduce the diff as
much as possible.  The attached patch is what I ended up with.  Like
John said: pretty easy. Almost no diff at all.

How to use: Remove the conflicting out-of-tree mtk_eth_soc driver from
the ramips target, copy all mtk_eth_soc patches from the mediatek target
to the ramips target, and then apply the attached patch. And use the
following kernel config changes (are all these necessary? not verified):

  KCONFIG:= \
        CONFIG_NET_MEDIATEK_GSW_MT7621=n \
        CONFIG_NET_MEDIATEK_MDIO=n \
        CONFIG_NET_MEDIATEK_MDIO_MT7620=n \
        CONFIG_NET_MEDIATEK_MT7621=n \
        CONFIG_NET_DSA=y \
        CONFIG_NET_DSA_MT7530=y \
        CONFIG_NET_DSA_TAG_MTK=y \
        CONFIG_MDIO_BUS=y \
        CONFIG_MDIO_DEVICE=y \
        CONFIG_MDIO_I2C=y \
        CONFIG_MFD_SYSCON=y \
        CONFIG_REGMAP_MMIO=y

With a minor diff to the mt7621.dtsi for the syscon support. note that
the ethernet reg size adjustment is somewhat optional. You'll only get
access warnings from the mt7623_trgmii_* functions in the mt7530 driver
without it.  That code should probably be disabled instead: 

diff --git a/target/linux/ramips/dts/mt7621.dtsi 
b/target/linux/ramips/dts/mt7621.dtsi
index 31d930d2251b..389c7064cc9a 100644
--- a/target/linux/ramips/dts/mt7621.dtsi
+++ b/target/linux/ramips/dts/mt7621.dtsi
@@ -60,7 +60,7 @@
                #size-cells = <1>;
 
                sysc: sysc@0 {
-                       compatible = "mtk,mt7621-sysc";
+                       compatible = "mtk,mt7621-sysc", "syscon";
                        reg = <0x0 0x100>;
                };
 
@@ -384,11 +384,11 @@
        };
 
        ethernet: ethernet@1e100000 {
-               compatible = "mediatek,mt7621-eth";
-               reg = <0x1e100000 0x10000>;
+               compatible = "mediatek,mt7621-eth", "syscon";
+               reg = <0x1e100000 0x20000>;
 
                #address-cells = <1>;
-               #size-cells = <1>;
+               #size-cells = <0>;
 
                resets = <&rstctrl 6 &rstctrl 23>;
                reset-names = "fe", "eth";
@@ -397,6 +397,7 @@
                interrupts = <GIC_SHARED 3 IRQ_TYPE_LEVEL_HIGH>;
 
                mediatek,switch = <&gsw>;
+               mediatek,ethsys = <&sysc>;
 
                mdio-bus {
                        #address-cells = <1>;





In my target device DTS I've used this

&ethernet {
        gmac0: mac@0 {
                compatible = "mediatek,eth-mac";
                reg = <0>;
                phy-mode = "rgmii";
                mtd-mac-address = <&factory 0xe000>;
                fixed-link {
                        speed = <1000>;
                        full-duplex;
                        pause;
                };
        };
        gmac1: mac@1 {
                compatible = "mediatek,eth-mac";
                reg = <1>;
                phy-mode = "rgmii";
                mtd-mac-address = <&factory 0xe000>;
                mtd-mac-address-increment = <1>;
                fixed-link {
                        speed = <1000>;
                        full-duplex;
                        pause;
                };
        };
};

&phy1f {
        compatible = "mediatek,mt7530";
        #address-cells = <1>;
        #size-cells = <0>;

        ports {
                #address-cells = <1>;
                #size-cells = <0>;

                port@0 {
                        reg = <0>;
                        label = "lan0";
                };
                port@1 {
                        reg = <1>;
                        label = "lan1";
                };
                port@2 {
                        reg = <2>;
                        label = "lan2";
                };
                port@3 {
                        reg = <3>;
                        label = "lan3";
                };
                cpu_port0: port@6 {
                        reg = <6>;
                        label = "cpu";
                        ethernet = <&gmac0>;
                };
        };
};



That's everything necessary for the mainline mtk_etc_soc and mt7530
drivers with MT7621, with both GMACs enabled!

There are still a couple of rough corners though:

- I've completely ignored clocks.  Thirsty created a clock driver, but
  looking at mtk_eth_soc, this seemed optional to me.  So I dropped it
  for simplicity and simply did '#define MT7621_CLKS_BITMAP     (0)'

- I've also ignored regulators.  The mt7530 drivers needs a couple, but
  the automatic dummy does the job.

- Not too sure about the shared interrupt thingy.  I tried reusing the
  interrupt handlers, and it ends up in a tight ksoftirq loop (aka
  lockup) if there is simultaneous traffic over the two gmacs.  This
  "fixes" the problem, but something doesn't seem quite right:

--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1775,8 +1775,8 @@ static irqreturn_t mtk_handle_irq_rx(int
 
        if (likely(napi_schedule_prep(&eth->rx_napi))) {
                __napi_schedule(&eth->rx_napi);
-               mtk_rx_irq_disable(eth, MTK_RX_DONE_INT);
        }
+       mtk_rx_irq_disable(eth, MTK_RX_DONE_INT);
 
        return IRQ_HANDLED;
 }
@@ -1787,8 +1787,8 @@ static irqreturn_t mtk_handle_irq_tx(int
 
        if (likely(napi_schedule_prep(&eth->tx_napi))) {
                __napi_schedule(&eth->tx_napi);
-               mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
        }
+       mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
 
        return IRQ_HANDLED;
 }


It does halfway make sense, given that returning IRQ_HANDLED without
actually doing anything seems like a bad idea.  But that code is there
in the mainline driver.  Why doesn't it lock up from time to time?  Or
does it?



The required device specific tweak mentioned above is related to an
undocumented(?) FE or switch register at 0x1e110008.  By default this
register reads

 root@OpenWrt:/# io -4 0x1e110008
 1e110008:  000c000c

and nothing is received on the eth1 interface.  But the FCS error
counter increases.  Writing another magic value makes the FCS errors go
away and packets are received normally:

 root@OpenWrt:/# io -4 -w 0x1e110008 0x9000c

I've experimented somewhat with different values and found that 0x8000c
also works.  So it seems clearing bit 18 is the important part.  For
those who wonder where I got this magic: It comes almost directly from
an OEM firmware script (/sbin/internet.sh), having:

 # Support QTN 5G
 if [ "$CONFIG_QTN_5G" = "y" ]; then
    reg s 0xbe110000
    reg w 8 0x9000c
    mii_mgr -s -p 0 -r 0 -v 0x3900
    mii_mgr -s -p 1 -r 0 -v 0x3900
    mii_mgr -s -p 2 -r 0 -v 0x3900
    mii_mgr -s -p 3 -r 0 -v 0x3900
         #switch reg w 2004 20ff0400
         #switch reg w 2104 20ff0400
         #switch reg w 2204 20ff0400
         #switch reg w 2304 20ff0400
    ifconfig eth3 up
    brctl addif br0 eth3
    ifconfig br0:9 1.1.1.1 netmask 255.255.255.0 broadcast 1.1.1.255
    cp /usr/etc/protocols /etc/
    cp /usr/etc/rmt_ip.conf /etc/
    rmt_qcsmngr -m 0 &
 fi


My best guess is that this is somehow related to RMGII delays, based on
the FCS effect.  In which case it should probably be related to
rgmii-id, rgmii-txid, or rgmii-rxid somewhere.  But guessing where is
difficult not knowing the exact meaning of those bits.  So I've not
implemented anything here yet, except a local device fix to ease my own
testing.

Still have a long way to go before I have the Quantenna module up and
running without a kick in the butt.  But the good news is that the
Quantenna PCIe work done by ILOVEPIE at
https://github.com/ILOVEPIE/qts1kpcie_wifi_driver.git
seems to apply to RMGII connected Quantenna modules too. Even the module
firmware!  So there is a good chance we can reuse tools, plugins and
firmware packages for all Quantenna modules regardless of connection, if
we ever finish the support.  But there is quite a lot of polishing left...



Anyway, the main point here was the mtk_eth_soc and mt7530 mainline
driver part.  Hope this info is useful to someone.



root@OpenWrt:/# ifconfig -a
br-lan    Link encap:Ethernet  HWaddr 60:31:97:66:16:10  
          inet addr:192.168.1.1  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::6231:97ff:fe66:1610/64 Scope:Link
          inet6 addr: fd5f:9350:2bf2::1/60 Scope:Global
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:47 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:2414 (2.3 KiB)  TX bytes:8170 (7.9 KiB)

eth0      Link encap:Ethernet  HWaddr 60:31:97:66:16:10  
          inet6 addr: fe80::6231:97ff:fe66:1610/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:405 errors:0 dropped:0 overruns:0 frame:0
          TX packets:61 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:96287 (94.0 KiB)  TX bytes:11043 (10.7 KiB)
          Interrupt:15 

eth1      Link encap:Ethernet  HWaddr 60:31:97:66:16:11  
          inet addr:1.1.1.1  Bcast:255.255.255.248  Mask:255.255.255.248
          inet6 addr: fe80::6231:97ff:fe66:1611/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6457 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6544 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:396616 (387.3 KiB)  TX bytes:9515000 (9.0 MiB)
          Interrupt:15 

lan0      Link encap:Ethernet  HWaddr 60:31:97:66:16:10  
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:405 errors:0 dropped:399 overruns:0 frame:0
          TX packets:47 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:88997 (86.9 KiB)  TX bytes:8170 (7.9 KiB)

lan1      Link encap:Ethernet  HWaddr 60:31:97:66:16:10  
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lan2      Link encap:Ethernet  HWaddr 60:31:97:66:16:10  
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lan3      Link encap:Ethernet  HWaddr 60:31:97:66:16:10  
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:2073 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2073 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:134060 (130.9 KiB)  TX bytes:134060 (130.9 KiB)

wlan0     Link encap:Ethernet  HWaddr 02:10:18:FF:5B:F8  
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

root@OpenWrt:/# ls -la /sys/class/net/*/device/driver
lrwxrwxrwx    1 root     root             0 Aug 17 11:24 
/sys/class/net/eth0/device/driver -> ../../../bus/platform/drivers/mtk_soc_eth
lrwxrwxrwx    1 root     root             0 Aug 17 11:24 
/sys/class/net/eth1/device/driver -> ../../../bus/platform/drivers/mtk_soc_eth
lrwxrwxrwx    1 root     root             0 Aug 17 11:25 
/sys/class/net/lan0/device/driver -> 
../../../../../../bus/mdio_bus/drivers/mt7530
lrwxrwxrwx    1 root     root             0 Aug 17 11:25 
/sys/class/net/lan1/device/driver -> 
../../../../../../bus/mdio_bus/drivers/mt7530
lrwxrwxrwx    1 root     root             0 Aug 17 11:25 
/sys/class/net/lan2/device/driver -> 
../../../../../../bus/mdio_bus/drivers/mt7530
lrwxrwxrwx    1 root     root             0 Aug 17 11:25 
/sys/class/net/lan3/device/driver -> 
../../../../../../bus/mdio_bus/drivers/mt7530
lrwxrwxrwx    1 root     root             0 Aug 17 11:25 
/sys/class/net/wlan0/device/driver -> ../../../../bus/pci/drivers/mt7603e

root@OpenWrt:/# brctl show
bridge name     bridge id               STP enabled     interfaces
br-lan          7fff.603197661610       no              lan0
                                                        lan1
                                                        lan2
                                                        lan3

root@OpenWrt:/# ip route get 192.168.1.33
192.168.1.33 dev br-lan  src 192.168.1.1 


root@OpenWrt:/# ping 192.168.1.33
PING 192.168.1.33 (192.168.1.33): 56 data bytes
64 bytes from 192.168.1.33: seq=0 ttl=64 time=1.010 ms
^C
--- 192.168.1.33 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 1.010/1.010/1.010 ms

root@OpenWrt:/# qcsapi_sockrpc --host 1.1.1.2 get_info eth1
Build name:            v37.3.1.25
Build revision:        30503
Build type:            GPL
Build timestamp:       1429609059
Platform ID:           450
Hardware ID:           QV840
Hardware revision:     bbic4_rev_a2
Band:                  5GHz
Kernel version:        2.6.35
Calibration version:   disabled
DC/IQ cal version:     V8.1
Power cal version:     V8.1
MuC firmware:          qtn_driver.qtn_ruby.0.bin
DSP firmware:          rdsp_driver.0.bin
AuC firmware:          auc_driver.0.bin
MAC address 0:         00:26:86:32:b9:03
MAC address 1:         00:00:00:00:00:00
U-Boot version:        v37.3.0.22

Bjørn

--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1792,6 +1792,19 @@ static irqreturn_t mtk_handle_irq_tx(int
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t mtk_handle_irq(int irq, void *_eth)
+{
+	struct mtk_eth *eth = _eth;
+
+	if (mtk_r32(eth, MTK_PDMA_INT_STATUS) & MTK_RX_DONE_INT)
+		mtk_handle_irq_rx(irq, _eth);
+
+	if (mtk_r32(eth, MTK_QMTK_INT_STATUS) & MTK_TX_DONE_INT)
+		mtk_handle_irq_tx(irq, _eth);
+
+	return IRQ_HANDLED;
+}
+
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void mtk_poll_controller(struct net_device *dev)
 {
@@ -2184,11 +2197,13 @@ static int mtk_free_dev(struct mtk_eth *
 
 static int mtk_unreg_dev(struct mtk_eth *eth)
 {
+	struct mtk_mac *mac;
 	int i;
 
 	for (i = 0; i < MTK_MAC_COUNT; i++) {
 		if (!eth->netdev[i])
 			continue;
+		mac = netdev_priv(eth->netdev[i]);
 		unregister_netdev(eth->netdev[i]);
 	}
 
@@ -2579,8 +2594,12 @@ static int mtk_probe(struct platform_dev
 		}
 	}
 
-	for (i = 0; i < 3; i++) {
-		eth->irq[i] = platform_get_irq(pdev, i);
+	for (i = 0; i < 3; i++)
+	{
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT) && i > 0)
+			eth->irq[i] = eth->irq[0];
+		else
+			eth->irq[i] = platform_get_irq(pdev, i);
 		if (eth->irq[i] < 0) {
 			dev_err(&pdev->dev, "no IRQ%d resource found\n", i);
 			return -ENXIO;
@@ -2627,13 +2646,18 @@ static int mtk_probe(struct platform_dev
 			goto err_deinit_hw;
 	}
 
-	err = devm_request_irq(eth->dev, eth->irq[1], mtk_handle_irq_tx, 0,
-			       dev_name(eth->dev), eth);
-	if (err)
-		goto err_free_dev;
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) {
+		err = devm_request_irq(eth->dev, eth->irq[0], mtk_handle_irq, 0,
+				       dev_name(eth->dev), eth);
+	} else {
+		err = devm_request_irq(eth->dev, eth->irq[1], mtk_handle_irq_tx, 0,
+				       dev_name(eth->dev), eth);
+		if (err)
+			goto err_free_dev;
 
-	err = devm_request_irq(eth->dev, eth->irq[2], mtk_handle_irq_rx, 0,
-			       dev_name(eth->dev), eth);
+		err = devm_request_irq(eth->dev, eth->irq[2], mtk_handle_irq_rx, 0,
+				       dev_name(eth->dev), eth);
+	}
 	if (err)
 		goto err_free_dev;
 
@@ -2706,6 +2730,12 @@ static const struct mtk_soc_data mt2701_
 	.required_pctl = true,
 };
 
+static const struct mtk_soc_data mt7621_data = {
+	.caps = MTK_SHARED_INT,
+	.required_clks = MT7621_CLKS_BITMAP,
+	.required_pctl = false,
+};
+
 static const struct mtk_soc_data mt7622_data = {
 	.caps = MTK_DUAL_GMAC_SHARED_SGMII | MTK_GMAC1_ESW,
 	.required_clks = MT7622_CLKS_BITMAP,
@@ -2720,6 +2750,7 @@ static const struct mtk_soc_data mt7623_
 
 const struct of_device_id of_mtk_match[] = {
 	{ .compatible = "mediatek,mt2701-eth", .data = &mt2701_data},
+	{ .compatible = "mediatek,mt7621-eth", .data = &mt7621_data},
 	{ .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
 	{ .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
 	{},
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -364,6 +364,7 @@
 #define ETHSYS_CHIPID4_7	0x4
 #define MT7623_ETH		7623
 #define MT7622_ETH		7622
+#define MT7621_ETH		7621
 
 /* ethernet subsystem config register */
 #define ETHSYS_SYSCFG0		0x14
@@ -489,6 +490,8 @@ enum mtk_clks_map {
 				 BIT(MTK_CLK_SGMII_CDR_FB) | \
 				 BIT(MTK_CLK_SGMII_CK) | \
 				 BIT(MTK_CLK_ETH2PLL))
+#define MT7621_CLKS_BITMAP	(0)
+
 enum mtk_dev_state {
 	MTK_HW_INIT,
 	MTK_RESETTING
@@ -567,6 +570,8 @@ struct mtk_rx_ring {
 #define MTK_GMAC2_SGMII			(BIT(10) | MTK_SGMII)
 #define MTK_DUAL_GMAC_SHARED_SGMII	(BIT(11) | MTK_GMAC1_SGMII | \
 					 MTK_GMAC2_SGMII)
+#define MTK_SHARED_INT			BIT(12)
+
 #define MTK_HAS_CAPS(caps, _x)		(((caps) & (_x)) == (_x))
 
 /* struct mtk_eth_data -	This is the structure holding all differences
--- a/drivers/net/ethernet/mediatek/Kconfig
+++ b/drivers/net/ethernet/mediatek/Kconfig
@@ -1,6 +1,6 @@
 config NET_VENDOR_MEDIATEK
 	bool "MediaTek ethernet driver"
-	depends on ARCH_MEDIATEK
+	depends on ARCH_MEDIATEK || SOC_MT7621
 	---help---
 	  If you have a Mediatek SoC with ethernet, say Y.
 
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to