diff --git a/sys/mips/atheros/ar71xxreg.h b/sys/mips/atheros/ar71xxreg.h index 3f6b50a97fb3..5677a4eff599 100644 --- a/sys/mips/atheros/ar71xxreg.h +++ b/sys/mips/atheros/ar71xxreg.h @@ -214,6 +214,10 @@ */ #define AR71XX_MAC0_BASE 0x19000000 #define AR71XX_MAC1_BASE 0x1A000000 +/* + * All 5 PHYs accessible only through MAC0 register space + */ +#define AR71XX_MII_BASE 0x19000000 #define AR71XX_MAC_CFG1 0x00 #define MAC_CFG1_SOFT_RESET (1 << 31) diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index 6263ef1601ff..6d77edca1a63 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -162,6 +162,11 @@ DRIVER_MODULE(miibus, arge, miibus_driver, miibus_devclass, 0, 0); */ extern uint32_t ar711_base_mac[ETHER_ADDR_LEN]; +static struct mtx miibus_mtx; + +MTX_SYSINIT(miibus_mtx, &miibus_mtx, "arge mii lock", MTX_SPIN); + + /* * Flushes all */ @@ -488,23 +493,27 @@ arge_miibus_readreg(device_t dev, int phy, int reg) if (phy != sc->arge_phy_num) return (0); - ARGE_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); - ARGE_WRITE(sc, AR71XX_MAC_MII_ADDR, addr); - ARGE_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_READ); + mtx_lock(&miibus_mtx); + ARGE_MII_WRITE(AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); + ARGE_MII_WRITE(AR71XX_MAC_MII_ADDR, addr); + ARGE_MII_WRITE(AR71XX_MAC_MII_CMD, MAC_MII_CMD_READ); i = ARGE_MII_TIMEOUT; - while ((ARGE_READ(sc, AR71XX_MAC_MII_INDICATOR) & + while ((ARGE_MII_READ(AR71XX_MAC_MII_INDICATOR) & MAC_MII_INDICATOR_BUSY) && (i--)) DELAY(5); if (i < 0) { + mtx_unlock(&miibus_mtx); dprintf("%s timedout\n", __func__); /* XXX: return ERRNO istead? */ return (-1); } - result = ARGE_READ(sc, AR71XX_MAC_MII_STATUS) & MAC_MII_STATUS_MASK; - ARGE_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); + result = ARGE_MII_READ(AR71XX_MAC_MII_STATUS) & MAC_MII_STATUS_MASK; + ARGE_MII_WRITE(AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); + mtx_unlock(&miibus_mtx); + dprintf("%s: phy=%d, reg=%02x, value[%08x]=%04x\n", __func__, phy, reg, addr, result); @@ -519,17 +528,24 @@ arge_miibus_writereg(device_t dev, int phy, int reg, int data) uint32_t addr = (phy << MAC_MII_PHY_ADDR_SHIFT) | (reg & MAC_MII_REG_MASK); + + if (phy != sc->arge_phy_num) + return (-1); + dprintf("%s: phy=%d, reg=%02x, value=%04x\n", __func__, phy, reg, data); - ARGE_WRITE(sc, AR71XX_MAC_MII_ADDR, addr); - ARGE_WRITE(sc, AR71XX_MAC_MII_CONTROL, data); + mtx_lock(&miibus_mtx); + ARGE_MII_WRITE(AR71XX_MAC_MII_ADDR, addr); + ARGE_MII_WRITE(AR71XX_MAC_MII_CONTROL, data); i = ARGE_MII_TIMEOUT; - while ((ARGE_READ(sc, AR71XX_MAC_MII_INDICATOR) & + while ((ARGE_MII_READ(AR71XX_MAC_MII_INDICATOR) & MAC_MII_INDICATOR_BUSY) && (i--)) DELAY(5); + mtx_unlock(&miibus_mtx); + if (i < 0) { dprintf("%s timedout\n", __func__); /* XXX: return ERRNO istead? */ diff --git a/sys/mips/atheros/if_argevar.h b/sys/mips/atheros/if_argevar.h index aec2cf46af34..40962ce58f11 100644 --- a/sys/mips/atheros/if_argevar.h +++ b/sys/mips/atheros/if_argevar.h @@ -64,6 +64,16 @@ #define ARGE_CLEAR_BITS(sc, reg, bits) \ ARGE_WRITE(sc, reg, ARGE_READ(sc, (reg)) & ~(bits)) +/* + * MII registers access macros + */ +#define ARGE_MII_READ(reg) \ + *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((AR71XX_MII_BASE + reg))) + +#define ARGE_MII_WRITE(reg, val) \ + *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((AR71XX_MII_BASE + reg))) = (val) + + #define ARGE_DESC_EMPTY (1 << 31) #define ARGE_DESC_MORE (1 << 24) #define ARGE_DESC_SIZE_MASK ((1 << 12) - 1)