X-Git-Url: https://git.archive.openwrt.org/?p=openwrt.git;a=blobdiff_plain;f=target%2Flinux%2Far71xx%2Ffiles%2Fdrivers%2Fnet%2Fethernet%2Fatheros%2Fag71xx%2Fag71xx_ar7240.c;h=21140106cb2eecfd76f4c980527d270840633d37;hp=9faed2197aae6963713363c9047283c0be269260;hb=0b6484dce5ace7f5e0cc3f54fd9b18252affcf42;hpb=0fced5df74b7e714d112b7005cee83a7a561f496 diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c index 9faed2197a..21140106cb 100644 --- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c +++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c @@ -83,6 +83,7 @@ #define AR7240_MIB_AT_HALF_EN BIT(16) #define AR7240_MIB_BUSY BIT(17) #define AR7240_MIB_FUNC_S 24 +#define AR7240_MIB_FUNC_M BITM(3) #define AR7240_MIB_FUNC_NO_OP 0x0 #define AR7240_MIB_FUNC_FLUSH 0x1 #define AR7240_MIB_FUNC_CAPTURE 0x3 @@ -207,6 +208,20 @@ #define AR934X_REG_OPER_MODE1 0x08 #define AR934X_REG_OPER_MODE1_PHY4_MII_EN BIT(28) +#define AR934X_REG_FLOOD_MASK 0x2c +#define AR934X_FLOOD_MASK_MC_DP(_p) BIT(16 + (_p)) +#define AR934X_FLOOD_MASK_BC_DP(_p) BIT(25 + (_p)) + +#define AR934X_REG_QM_CTRL 0x3c +#define AR934X_QM_CTRL_ARP_EN BIT(15) + +#define AR934X_REG_AT_CTRL 0x5c +#define AR934X_AT_CTRL_AGE_TIME BITS(0, 15) +#define AR934X_AT_CTRL_AGE_EN BIT(17) +#define AR934X_AT_CTRL_LEARN_CHANGE BIT(18) + +#define AR934X_MIB_ENABLE BIT(30) + #define AR934X_REG_PORT_BASE(_port) (0x100 + (_port) * 0x100) #define AR934X_REG_PORT_VLAN1(_port) (AR934X_REG_PORT_BASE((_port)) + 0x08) @@ -506,8 +521,9 @@ static int ar7240sw_capture_stats(struct ar7240sw *as) write_lock(&as->stats_lock); /* Capture the hardware statistics for all ports */ - ar7240sw_reg_write(mii, AR7240_REG_MIB_FUNCTION0, - (AR7240_MIB_FUNC_CAPTURE << AR7240_MIB_FUNC_S)); + ar7240sw_reg_rmw(mii, AR7240_REG_MIB_FUNCTION0, + (AR7240_MIB_FUNC_M << AR7240_MIB_FUNC_S), + (AR7240_MIB_FUNC_CAPTURE << AR7240_MIB_FUNC_S)); /* Wait for the capturing to complete. */ ret = ar7240sw_reg_wait(mii, AR7240_REG_MIB_FUNCTION0, @@ -556,17 +572,36 @@ static void ar7240sw_setup(struct ar7240sw *as) /* Setup TAG priority mapping */ ar7240sw_reg_write(mii, AR7240_REG_TAG_PRIORITY, 0xfa50); - /* Enable ARP frame acknowledge, aging, MAC replacing */ - ar7240sw_reg_write(mii, AR7240_REG_AT_CTRL, - AR7240_AT_CTRL_RESERVED | - 0x2b /* 5 min age time */ | - AR7240_AT_CTRL_AGE_EN | - AR7240_AT_CTRL_ARP_EN | - AR7240_AT_CTRL_LEARN_CHANGE); + if (sw_is_ar934x(as)) { + /* Enable aging, MAC replacing */ + ar7240sw_reg_write(mii, AR934X_REG_AT_CTRL, + 0x2b /* 5 min age time */ | + AR934X_AT_CTRL_AGE_EN | + AR934X_AT_CTRL_LEARN_CHANGE); + /* Enable ARP frame acknowledge */ + ar7240sw_reg_set(mii, AR934X_REG_QM_CTRL, + AR934X_QM_CTRL_ARP_EN); + /* Enable Broadcast/Multicast frames transmitted to the CPU */ + ar7240sw_reg_set(mii, AR934X_REG_FLOOD_MASK, + AR934X_FLOOD_MASK_BC_DP(0) | + AR934X_FLOOD_MASK_MC_DP(0)); + + /* Enable MIB counters */ + ar7240sw_reg_set(mii, AR7240_REG_MIB_FUNCTION0, + AR934X_MIB_ENABLE); - /* Enable Broadcast frames transmitted to the CPU */ - ar7240sw_reg_set(mii, AR7240_REG_FLOOD_MASK, - AR7240_FLOOD_MASK_BROAD_TO_CPU); + } else { + /* Enable ARP frame acknowledge, aging, MAC replacing */ + ar7240sw_reg_write(mii, AR7240_REG_AT_CTRL, + AR7240_AT_CTRL_RESERVED | + 0x2b /* 5 min age time */ | + AR7240_AT_CTRL_AGE_EN | + AR7240_AT_CTRL_ARP_EN | + AR7240_AT_CTRL_LEARN_CHANGE); + /* Enable Broadcast frames transmitted to the CPU */ + ar7240sw_reg_set(mii, AR7240_REG_FLOOD_MASK, + AR7240_FLOOD_MASK_BROAD_TO_CPU); + } /* setup MTU */ ar7240sw_reg_rmw(mii, AR7240_REG_GLOBAL_CTRL, AR7240_GLOBAL_CTRL_MTU_M, @@ -1082,19 +1117,26 @@ static void link_function(struct work_struct *work) { struct ag71xx *ag = container_of(work, struct ag71xx, link_work.work); struct ar7240sw *as = ag->phy_priv; unsigned long flags; + u8 mask; int i; int status = 0; - for (i = 0; i < as->swdev.ports; i++) { - int link = ar7240sw_phy_read(ag->mii_bus, i, MII_BMSR); - if(link & BMSR_LSTATUS) { + mask = ~as->swdata->phy_poll_mask; + for (i = 0; i < AR7240_NUM_PHYS; i++) { + int link; + + if (!(mask & BIT(i))) + continue; + + link = ar7240sw_phy_read(ag->mii_bus, i, MII_BMSR); + if (link & BMSR_LSTATUS) { status = 1; break; } } spin_lock_irqsave(&ag->lock, flags); - if(status != ag->link) { + if (status != ag->link) { ag->link = status; ag71xx_link_adjust(ag); }