MII related infrastructure changes.
* Add a new method to set the MII mode - GMII, RGMII, RMII, MII. + arge0 supports all four (two for non-Gige interfaces.) + arge1 only supports two (one for non-gige interfaces.) * Set the MII clock speed when changing the MAC PLL speed. + Needed for AR91xx and AR71xx; not needed for AR724x. Tested: * AR71xx only, I'll do AR913x testing tonight and fix whichever issues creep up. TODO: * Implement the missing AR7242 arge0 PLL configuration, but don't adjust the MII speed accordingly. * .. the AR7240/AR7241 don't require this, so make sure it's not set accidentally. Bugs (not fixed here): * Statically configured arge speeds are still broken - investigate why that is on the AP96 board. Autonegotiate is working fine, but there still seems to be an occasionally heavy packet loss issue. Obtained from: Linux/Atheros/OpenWRT
This commit is contained in:
parent
784bcea8a9
commit
da88453012
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <mips/atheros/ar71xx_cpudef.h>
|
||||
#include <mips/atheros/ar71xx_setup.h>
|
||||
#include <mips/atheros/ar71xx_chip.h>
|
||||
#include <mips/atheros/ar724x_chip.h>
|
||||
|
||||
#include <mips/sentry5/s5reg.h>
|
||||
@ -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,
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user