<div dir="ltr"><div class="gmail_quote"><div dir="ltr">From: Joe Ayers <<a href="mailto:ae6xe@aredn.org" target="_blank">ae6xe@arrl.</a>net><br><div><br></div><div><font color="#303030">Fixes 19085 nanostation m5 loco xw loses interface</font></div><div><font color="#303030"><br></font></div><div><span style="color:rgb(48,48,48)">Signed-off-by: Joe Ayers        <<a href="mailto:ae6xe@aredn.org" target="_blank">ae6xe@a</a><a href="http://rrl.net">rrl.net</a>></span><br></div><div><span style="color:rgb(48,48,48)">Signed-off-by: Trevor Paskett <<a href="mailto:k7fpv@aredn.org" target="_blank">k7fpv@aredn.org</a>></span><span style="color:rgb(48,48,48)"><br></span></div><div><span style="color:rgb(48,48,48)">Signed-off-by: Darryl  Quinn    <<a href="mailto:k5dlq@aredn.org" target="_blank">k5dlq@aredn.org</a>></span><span style="color:rgb(48,48,48)"><br></span></div><div><span style="color:rgb(48,48,48)">Signed-off-by: Conrad Lara     <<a href="mailto:kg6jei@aredn.org" target="_blank">kg6jei@aredn.org</a>></span><span style="color:rgb(48,48,48)"><br></span></div><div>---</div><div><br></div><div>Test results:</div><div><div>[    0.000000] Linux version 4.4.14 (joe@AE6XE-PE) (gcc version 5.3.0 (OpenWrt GCC 5.3.0 49994) ) #1 Mon Nov 21 16:47:41 UTC 2016</div><div>[    0.000000] MyLoader: sysp=9f65a088, boardp=810d1261, parts=61618340</div><div>[    0.000000] bootconsole [early0] enabled</div><div>[    0.000000] CPU0 revision is: 0001974c (MIPS 74Kc)</div><div>[    0.000000] SoC: Atheros AR9342 rev 2</div><div>...</div><div>[    0.000000] Kernel command line:  board=UBNT-LOCO-XW mtdparts=spi0.0:256k(u-boot)ro<wbr>,64k(u-boot-env)ro,7552k(firmw<wbr>are),256k(cfg)ro,64k(EEPROM)ro console=ttyS0,115200 rootfstype=squashfs,jffs2 noinitrd</div><div>...</div><div>[    0.648684] libphy: ag71xx_mdio: probed</div><div>[    1.239012] ag71xx ag71xx.0: connected to PHY at ag71xx-mdio.0:01 [uid=004dd023, driver=Generic PHY]</div><div>[    1.249098] eth0: Atheros AG71xx at 0xb9000000, irq 4, mode:MII</div><div>...</div><div>[56312.947419] ag71xx_check_reset: expected: 004d, got: 0000</div><div>[56312.952909] ag71xx_gpio_reset triggered</div><div>[56312.961952] eth0: link down</div><div>[56312.965631] br-lan: port 1(eth0) entered disabled state</div><div>[56314.958602] eth0: link up (100Mbps/Full duplex)</div><div>[56314.963297] br-lan: port 1(eth0) entered forwarding state</div><div>[56314.968879] br-lan: port 1(eth0) entered forwarding state</div><div>[56316.967075] br-lan: port 1(eth0) entered forwarding state</div></div><div><br></div><div>741-MIPS-ath79-ag71xx-ar803x-l<wbr>ockup-fix.patch<br></div><div><br></div><div><div>--- a/drivers/net/ethernet/atheros<wbr>/ag71xx/ag71xx.h</div><div>+++ b/drivers/net/ethernet/atheros<wbr>/ag71xx/ag71xx.h</div><div>@@ -36,9 +36,10 @@</div><div> #include <asm/mach-ath79/ar71xx_regs.h></div><div> #include <asm/mach-ath79/ath79.h></div><div> #include <asm/mach-ath79/ag71xx_platfor<wbr>m.h></div><div>+#include <asm/addrspace.h></div><div> </div><div> #define AG71XX_DRV_NAME<span class="m_-8668292613678354981m_3930746537629411734gmail-Apple-tab-span" style="white-space:pre-wrap">          </span>"ag71xx"</div><div>-#define AG71XX_DRV_VERSION<span class="m_-8668292613678354981m_3930746537629411734gmail-Apple-tab-span" style="white-space:pre-wrap">  </span>"0.5.35"</div><div>+#define AG71XX_DRV_VERSION<span class="m_-8668292613678354981m_3930746537629411734gmail-Apple-tab-span" style="white-space:pre-wrap">  </span>"0.5.36"</div><div> </div><div> #define AG71XX_NAPI_WEIGHT<span class="m_-8668292613678354981m_3930746537629411734gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>64</div><div> #define AG71XX_OOM_REFILL<span class="m_-8668292613678354981m_3930746537629411734gmail-Apple-tab-span" style="white-space:pre-wrap">  </span>(1 + HZ/10)</div><div>@@ -370,6 +371,31 @@ ag71xx_ring_size_order(int size)</div><div> #define RX_STATUS_OF<span class="m_-8668292613678354981m_3930746537629411734gmail-Apple-tab-span" style="white-space:pre-wrap">          </span>BIT(2)<span class="m_-8668292613678354981m_3930746537629411734gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>/* Rx Overflow */</div><div> #define RX_STATUS_BE<span class="m_-8668292613678354981m_3930746537629411734gmail-Apple-tab-span" style="white-space:pre-wrap">                </span>BIT(3)<span class="m_-8668292613678354981m_3930746537629411734gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>/* Bus Error */</div><div> </div><div>+/* GPIO phy reset registers */</div><div>+#define AR934X_REG_GPIO_OE_ADDRESS      0x18040000</div><div>+#define AR934X_REG_GPIO_OUT             0x18040008</div><div>+#define AR934X_REG_GPIO_SET             0x1804000C</div><div>+#define AR934X_REG_GPIO_CLEAR           0x18040010</div><div>+#define AR934X_EXPECTED_ID1             0x4d</div><div>+#define AR934X_PHY_ID1                  2</div><div>+</div><div>+typedef unsigned int ath_reg_t;</div><div>+</div><div>+#define ath_reg_rd(_phys)       (*(volatile ath_reg_t *)KSEG1ADDR(_phys))</div><div>+</div><div>+#define ath_reg_wr_nf(_phys, _val) \</div><div>+        ((*(volatile ath_reg_t *)KSEG1ADDR(_phys)) = (_val))</div><div>+</div><div>+#define ath_reg_wr(_phys, _val) do {    \</div><div>+        ath_reg_wr_nf(_phys, _val);     \</div><div>+        ath_reg_rd(_phys);              \</div><div>+} while(0)</div><div>+</div><div>+#define ath_reg_rmw_set(_reg, _mask)    do {                    \</div><div>+        ath_reg_wr((_reg), (ath_reg_rd((_reg)) | (_mask)));     \</div><div>+        ath_reg_rd((_reg));                                     \</div><div>+} while(0)</div><div>+</div><div>+#define ath_reg_rmw_clear(_reg, _mask)    do {                  \</div><div>+        ath_reg_wr((_reg), (ath_reg_rd((_reg)) | (_mask)));     \</div><div>+        ath_reg_rd((_reg));                                     \</div><div>+} while(0)</div><div>+</div><div> static inline void ag71xx_check_reg_offset(struct ag71xx *ag, unsigned reg)</div><div> {</div><div> <span class="m_-8668292613678354981m_3930746537629411734gmail-Apple-tab-span" style="white-space:pre-wrap"> </span>switch (reg) {</div><div>@@ -490,4 +516,6 @@ u16 ar7240sw_phy_read(struct mii_bus *mi</div><div> int ar7240sw_phy_write(struct mii_bus *mii, unsigned phy_addr,</div><div> <span class="m_-8668292613678354981m_3930746537629411734gmail-Apple-tab-span" style="white-space:pre-wrap">             </span>       unsigned reg_addr, u16 reg_val);</div><div> </div><div>+void ag71xx_check_reset(struct ag71xx *ag, bool reset);</div><div>+</div><div> #endif /* _AG71XX_H */</div><div>--- a/drivers/net/ethernet/atheros<wbr>/ag71xx/ag71xx_main.c</div><div>+++ b/drivers/net/ethernet/atheros<wbr>/ag71xx/ag71xx_main.c</div><div>@@ -511,6 +511,86 @@ static void ag71xx_hw_init(struct ag71xx</div><div> <span class="m_-8668292613678354981m_3930746537629411734gmail-Apple-tab-span" style="white-space:pre-wrap">      </span>ag71xx_dma_reset(ag);</div><div> }</div><div> </div><div>+static void ag71xx_gpio_reset(struct ag71xx *ag) {</div><div>+    pr_info("ag71xx_gpio_reset triggered\n");</div><div>+</div><div>+    if ((ath_reg_rd(AR934X_REG_GPIO_O<wbr>UT) & BIT(0)) == 0) {</div><div>+        // Set GPIO0 to 1 (not in reset)</div><div>+        ath_reg_wr(AR934X_REG_GPIO_SE<wbr>T, BIT(0));</div><div>+    }</div><div>+</div><div>+    if (ath_reg_rd(AR934X_REG_GPIO_OE<wbr>_ADDRESS) & BIT(0)) {</div><div>+        // Set GPIO0 as output</div><div>+        ath_reg_rmw_clear(AR934X_REG_<wbr>GPIO_OE_ADDRESS, BIT(0));</div><div>+    }</div><div>+</div><div>+    ath_reg_wr(AR934X_REG_GPIO_CL<wbr>EAR, BIT(0));</div><div>+    mdelay(2);</div><div>+    ath_reg_wr(AR934X_REG_GPIO_SE<wbr>T, BIT(0));</div><div>+    mdelay(2);</div><div>+}</div><div>+</div><div>+void ag71xx_check_reset(struct ag71xx *ag, bool reset)</div><div>+{</div><div>+    int retries;</div><div>+    struct phy_device *phydev = ag->phy_dev;</div><div>+    struct net_device *dev = ag->dev;</div><div>+    uint16_t phy_id;</div><div>+    u32 rx_ds;</div><div>+    u32 mii_reg;</div><div>+</div><div>+    if (!soc_is_ar934x()) return;</div><div>+</div><div>+    phy_id = phy_read(phydev, AR934X_PHY_ID1);</div><div>+</div><div>+    if (!reset && phy_id == AR934X_EXPECTED_ID1) {</div><div>+        //No PHY hang detected</div><div>+        return;</div><div>+    }</div><div>+</div><div>+    pr_info("ag71xx_check_reset: expected: %04x, got: %04x\n", AR934X_EXPECTED_ID1, phy_id);</div><div>+</div><div>+    ag71xx_hw_stop(ag);</div><div>+    wmb();</div><div>+</div><div>+    mii_reg = ag71xx_rr(ag, AG71XX_REG_MII_CFG);</div><div>+    rx_ds = ag71xx_rr(ag, AG71XX_REG_RX_DESC);</div><div>+</div><div>+    ag71xx_gpio_reset(ag);</div><div>+</div><div>+    phy_id = phy_read(phydev, AR934X_PHY_ID1);</div><div>+</div><div>+    retries = 102; //To be sure last try > 10ms after reset</div><div>+</div><div>+    while (phy_id != AR934X_EXPECTED_ID1 && --retries) {</div><div>+        phy_id = phy_read(phydev, AR934X_PHY_ID1);</div><div>+        udelay(100);</div><div>+    }</div><div>+</div><div>+    phy_id = phy_read(phydev, AR934X_PHY_ID1);</div><div>+</div><div>+    if (phy_id != AR934X_EXPECTED_ID1) return;</div><div>+</div><div>+    ag71xx_dma_reset(ag);</div><div>+    ag71xx_hw_setup(ag);</div><div>+    ag71xx_tx_packets(ag, true);</div><div>+    ag->tx_ring.curr = 0;</div><div>+    ag->tx_ring.dirty = 0;</div><div>+    netdev_reset_queue(ag->dev);</div><div>+</div><div>+    /* setup max frame length */</div><div>+    ag71xx_wr(ag, AG71XX_REG_MAC_MFL,</div><div>+        ag71xx_max_frame_len(ag->dev-<wbr>>mtu));</div><div>+</div><div>+    ag71xx_wr(ag, AG71XX_REG_RX_DESC, rx_ds);</div><div>+    ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->tx_ring.descs_dma);</div><div>+    ag71xx_wr(ag, AG71XX_REG_MII_CFG, mii_reg);</div><div>+</div><div>+    ag71xx_hw_set_macaddr(ag, dev->dev_addr);</div><div>+</div><div>+    return;</div><div>+}</div><div>+</div><div> static void ag71xx_fast_reset(struct ag71xx *ag)</div><div> {</div><div> <span class="m_-8668292613678354981m_3930746537629411734gmail-Apple-tab-span" style="white-space:pre-wrap">      </span>struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);</div><div>@@ -570,6 +650,8 @@ __ag71xx_link_adjust(struct ag71xx *ag,</div><div> <span class="m_-8668292613678354981m_3930746537629411734gmail-Apple-tab-span" style="white-space:pre-wrap"> </span>u32 fifo5;</div><div> <span class="m_-8668292613678354981m_3930746537629411734gmail-Apple-tab-span" style="white-space:pre-wrap">   </span>u32 fifo3;</div><div> </div><div>+        ag71xx_check_reset(ag, false);</div><div>+</div><div> <span class="m_-8668292613678354981m_3930746537629411734gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>if (!ag->link && update) {</div><div> <span class="m_-8668292613678354981m_3930746537629411734gmail-Apple-tab-span" style="white-space:pre-wrap">                </span>ag71xx_hw_stop(ag);</div><div> <span class="m_-8668292613678354981m_3930746537629411734gmail-Apple-tab-span" style="white-space:pre-wrap">          </span>netif_carrier_off(ag->dev);</div></div><div><br></div></div>
<br></div><br></div>