@ -971,6 +971,78 @@ ar8327_sw_get_eee(struct switch_dev *dev,
return 0 ;
}
static void
ar8327_wait_atu_ready ( struct ar8xxx_priv * priv , u16 r2 , u16 r1 )
{
int timeout = 20 ;
while ( mii_read32 ( priv , r2 , r1 ) & AR8327_ATU_FUNC_BUSY & & - - timeout )
udelay ( 10 ) ;
if ( ! timeout )
pr_err ( " ar8327: timeout waiting for atu to become ready \n " ) ;
}
static void ar8327_get_arl_entry ( struct ar8xxx_priv * priv ,
struct arl_entry * a , u32 * status , enum arl_op op )
{
struct mii_bus * bus = priv - > mii_bus ;
u16 r2 , page ;
u16 r1_data0 , r1_data1 , r1_data2 , r1_func ;
u32 t , val0 , val1 , val2 ;
int i ;
split_addr ( AR8327_REG_ATU_DATA0 , & r1_data0 , & r2 , & page ) ;
r2 | = 0x10 ;
r1_data1 = ( AR8327_REG_ATU_DATA1 > > 1 ) & 0x1e ;
r1_data2 = ( AR8327_REG_ATU_DATA2 > > 1 ) & 0x1e ;
r1_func = ( AR8327_REG_ATU_FUNC > > 1 ) & 0x1e ;
switch ( op ) {
case AR8XXX_ARL_INITIALIZE :
/* all ATU registers are on the same page
* therefore set page only once
*/
bus - > write ( bus , 0x18 , 0 , page ) ;
wait_for_page_switch ( ) ;
ar8327_wait_atu_ready ( priv , r2 , r1_func ) ;
mii_write32 ( priv , r2 , r1_data0 , 0 ) ;
mii_write32 ( priv , r2 , r1_data1 , 0 ) ;
mii_write32 ( priv , r2 , r1_data2 , 0 ) ;
break ;
case AR8XXX_ARL_GET_NEXT :
mii_write32 ( priv , r2 , r1_func ,
AR8327_ATU_FUNC_OP_GET_NEXT |
AR8327_ATU_FUNC_BUSY ) ;
ar8327_wait_atu_ready ( priv , r2 , r1_func ) ;
val0 = mii_read32 ( priv , r2 , r1_data0 ) ;
val1 = mii_read32 ( priv , r2 , r1_data1 ) ;
val2 = mii_read32 ( priv , r2 , r1_data2 ) ;
* status = val2 & AR8327_ATU_STATUS ;
if ( ! * status )
break ;
i = 0 ;
t = AR8327_ATU_PORT0 ;
while ( ! ( val1 & t ) & & + + i < AR8327_NUM_PORTS )
t < < = 1 ;
a - > port = i ;
a - > mac [ 0 ] = ( val0 & AR8327_ATU_ADDR0 ) > > AR8327_ATU_ADDR0_S ;
a - > mac [ 1 ] = ( val0 & AR8327_ATU_ADDR1 ) > > AR8327_ATU_ADDR1_S ;
a - > mac [ 2 ] = ( val0 & AR8327_ATU_ADDR2 ) > > AR8327_ATU_ADDR2_S ;
a - > mac [ 3 ] = ( val0 & AR8327_ATU_ADDR3 ) > > AR8327_ATU_ADDR3_S ;
a - > mac [ 4 ] = ( val1 & AR8327_ATU_ADDR4 ) > > AR8327_ATU_ADDR4_S ;
a - > mac [ 5 ] = ( val1 & AR8327_ATU_ADDR5 ) > > AR8327_ATU_ADDR5_S ;
break ;
}
}
static int
ar8327_sw_hw_apply ( struct switch_dev * dev )
{
@ -1041,6 +1113,13 @@ static const struct switch_attr ar8327_sw_attr_globals[] = {
. get = ar8xxx_sw_get_mirror_source_port ,
. max = AR8327_NUM_PORTS - 1
} ,
{
. type = SWITCH_TYPE_STRING ,
. name = " arl_table " ,
. description = " Get ARL table " ,
. set = NULL ,
. get = ar8xxx_sw_get_arl_table ,
} ,
} ;
static const struct switch_attr ar8327_sw_attr_port [ ] = {
@ -1114,6 +1193,7 @@ const struct ar8xxx_chip ar8327_chip = {
. vtu_load_vlan = ar8327_vtu_load_vlan ,
. phy_fixup = ar8327_phy_fixup ,
. set_mirror_regs = ar8327_set_mirror_regs ,
. get_arl_entry = ar8327_get_arl_entry ,
. sw_hw_apply = ar8327_sw_hw_apply ,
. num_mibs = ARRAY_SIZE ( ar8236_mibs ) ,
@ -1146,6 +1226,7 @@ const struct ar8xxx_chip ar8337_chip = {
. vtu_load_vlan = ar8327_vtu_load_vlan ,
. phy_fixup = ar8327_phy_fixup ,
. set_mirror_regs = ar8327_set_mirror_regs ,
. get_arl_entry = ar8327_get_arl_entry ,
. sw_hw_apply = ar8327_sw_hw_apply ,
. num_mibs = ARRAY_SIZE ( ar8236_mibs ) ,