diff --git a/sys/mips/atheros/ar71xx_chip.c b/sys/mips/atheros/ar71xx_chip.c index 18181aef169f..f83f70317dd4 100644 --- a/sys/mips/atheros/ar71xx_chip.c +++ b/sys/mips/atheros/ar71xx_chip.c @@ -176,6 +176,50 @@ ar71xx_chip_set_mii_speed(uint32_t unit, uint32_t speed) ATH_WRITE_REG(reg, val); } +void +ar71xx_chip_set_mii_if(uint32_t unit, uint32_t mii_mode) +{ + uint32_t val, reg, mii_if; + + switch (unit) { + case 0: + reg = AR71XX_MII0_CTRL; + if (mii_mode == AR71XX_MII_MODE_GMII) + mii_if = MII0_CTRL_IF_GMII; + else if (mii_mode == AR71XX_MII_MODE_MII) + mii_if = MII0_CTRL_IF_MII; + else if (mii_mode == AR71XX_MII_MODE_RGMII) + mii_if = MII0_CTRL_IF_RGMII; + else if (mii_mode == AR71XX_MII_MODE_RMII) + mii_if = MII0_CTRL_IF_RMII; + else + printf("%s: invalid MII mode (%d) for unit %d\n", + __func__, mii_mode, unit); + return; + break; + case 1: + reg = AR71XX_MII1_CTRL; + if (mii_mode == AR71XX_MII_MODE_RGMII) + mii_if = MII1_CTRL_IF_RGMII; + if (mii_mode == AR71XX_MII_MODE_RMII) + mii_if = MII1_CTRL_IF_RMII; + else + printf("%s: invalid MII mode (%d) for unit %d\n", + __func__, mii_mode, unit); + return; + break; + default: + printf("%s: invalid MII unit set for arge unit: %d\n", + __func__, unit); + return; + } + + val = ATH_READ_REG(reg); + val &= ~(MII_CTRL_IF_MASK << MII_CTRL_IF_SHIFT); + val |= (mii_if & MII_CTRL_IF_MASK) << MII_CTRL_IF_SHIFT; + ATH_WRITE_REG(reg, val); +} + /* Speed is either 10, 100 or 1000 */ static void ar71xx_chip_set_pll_ge(int unit, int speed) @@ -197,6 +241,7 @@ ar71xx_chip_set_pll_ge(int unit, int speed) __func__, unit, speed); return; } + switch (unit) { case 0: ar71xx_write_pll(AR71XX_PLL_SEC_CONFIG, @@ -213,6 +258,12 @@ ar71xx_chip_set_pll_ge(int unit, int speed) __func__, unit); return; } + + /* + * AR71xx and AR913x require this; AR724x doesn't require + * an MII clock change at all. + */ + ar71xx_chip_set_mii_speed(unit, speed); } static void @@ -278,6 +329,7 @@ struct ar71xx_cpu_def ar71xx_chip_def = { &ar71xx_chip_device_stopped, &ar71xx_chip_set_pll_ge, &ar71xx_chip_set_mii_speed, + &ar71xx_chip_set_mii_if, &ar71xx_chip_ddr_flush_ge, &ar71xx_chip_get_eth_pll, &ar71xx_chip_ddr_flush_ip2, diff --git a/sys/mips/atheros/ar71xx_chip.h b/sys/mips/atheros/ar71xx_chip.h index 4869f3110f6e..a9b4804299d1 100644 --- a/sys/mips/atheros/ar71xx_chip.h +++ b/sys/mips/atheros/ar71xx_chip.h @@ -31,5 +31,6 @@ extern struct ar71xx_cpu_def ar71xx_chip_def; extern void ar71xx_chip_set_mii_speed(uint32_t unit, uint32_t speed); +extern void ar71xx_chip_set_mii_if(uint32_t unit, uint32_t mii_if); #endif diff --git a/sys/mips/atheros/ar71xx_cpudef.h b/sys/mips/atheros/ar71xx_cpudef.h index ce472f51a2e4..1fe2e096ce63 100644 --- a/sys/mips/atheros/ar71xx_cpudef.h +++ b/sys/mips/atheros/ar71xx_cpudef.h @@ -37,6 +37,7 @@ struct ar71xx_cpu_def { int (* ar71xx_chip_device_stopped) (uint32_t); void (* ar71xx_chip_set_pll_ge) (int, int); void (* ar71xx_chip_set_mii_speed) (uint32_t, uint32_t); + void (* ar71xx_chip_set_mii_if) (uint32_t, ar71xx_mii_mode); void (* ar71xx_chip_ddr_flush_ge) (int); uint32_t (* ar71xx_chip_get_eth_pll) (unsigned int, int); @@ -90,6 +91,11 @@ static inline void ar71xx_device_set_mii_speed(int unit, int speed) ar71xx_cpu_ops->ar71xx_chip_set_mii_speed(unit, speed); } +static inline void ar71xx_device_set_mii_if(int unit, ar71xx_mii_mode mii_cfg) +{ + ar71xx_cpu_ops->ar71xx_chip_set_mii_if(unit, mii_cfg); +} + static inline void ar71xx_device_flush_ddr_ge(int unit) { ar71xx_cpu_ops->ar71xx_chip_ddr_flush_ge(unit); diff --git a/sys/mips/atheros/ar724x_chip.c b/sys/mips/atheros/ar724x_chip.c index d56a26c73da7..d15529765d1b 100644 --- a/sys/mips/atheros/ar724x_chip.c +++ b/sys/mips/atheros/ar724x_chip.c @@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -130,6 +131,13 @@ ar724x_chip_set_mii_speed(uint32_t unit, uint32_t speed) return; } +/* + * XXX TODO: set the PLL for arge0 only on AR7242. + * The PLL/clock requirements are different. + * + * Otherwise, it's a NULL function for AR7240, AR7241 and + * AR7242 arge1. + */ static void ar724x_chip_set_pll_ge(int unit, int speed) { @@ -229,6 +237,7 @@ struct ar71xx_cpu_def ar724x_chip_def = { &ar724x_chip_device_stopped, &ar724x_chip_set_pll_ge, &ar724x_chip_set_mii_speed, + &ar71xx_chip_set_mii_if, &ar724x_chip_ddr_flush_ge, &ar724x_chip_get_eth_pll, &ar724x_chip_ddr_flush_ip2, diff --git a/sys/mips/atheros/ar91xx_chip.c b/sys/mips/atheros/ar91xx_chip.c index c88518f1cb22..d2fec2f326da 100644 --- a/sys/mips/atheros/ar91xx_chip.c +++ b/sys/mips/atheros/ar91xx_chip.c @@ -147,6 +147,7 @@ ar91xx_chip_set_pll_ge(int unit, int speed) __func__, unit); return; } + ar71xx_chip_set_mii_speed(unit, speed); } static void @@ -211,6 +212,7 @@ struct ar71xx_cpu_def ar91xx_chip_def = { &ar91xx_chip_device_stopped, &ar91xx_chip_set_pll_ge, &ar71xx_chip_set_mii_speed, + &ar71xx_chip_set_mii_if, &ar91xx_chip_ddr_flush_ge, &ar91xx_chip_get_eth_pll, &ar91xx_chip_ddr_flush_ip2,