|
|
|
@ -343,93 +343,6 @@ static unsigned char *ag71xx_speed_str(struct ag71xx *ag) |
|
|
|
|
return "?"; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ag71xx_link_adjust(struct ag71xx *ag) |
|
|
|
|
{ |
|
|
|
|
struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); |
|
|
|
|
u32 cfg2; |
|
|
|
|
u32 ifctl; |
|
|
|
|
u32 fifo5; |
|
|
|
|
u32 mii_speed; |
|
|
|
|
|
|
|
|
|
if (!ag->link) { |
|
|
|
|
netif_carrier_off(ag->dev); |
|
|
|
|
if (netif_msg_link(ag)) |
|
|
|
|
printk(KERN_INFO "%s: link down\n", ag->dev->name); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2); |
|
|
|
|
cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX); |
|
|
|
|
cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0; |
|
|
|
|
|
|
|
|
|
ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL); |
|
|
|
|
ifctl &= ~(MAC_IFCTL_SPEED); |
|
|
|
|
|
|
|
|
|
fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5); |
|
|
|
|
fifo5 &= ~FIFO_CFG5_BM; |
|
|
|
|
|
|
|
|
|
switch (ag->speed) { |
|
|
|
|
case SPEED_1000: |
|
|
|
|
mii_speed = MII_CTRL_SPEED_1000; |
|
|
|
|
cfg2 |= MAC_CFG2_IF_1000; |
|
|
|
|
fifo5 |= FIFO_CFG5_BM; |
|
|
|
|
break; |
|
|
|
|
case SPEED_100: |
|
|
|
|
mii_speed = MII_CTRL_SPEED_100; |
|
|
|
|
cfg2 |= MAC_CFG2_IF_10_100; |
|
|
|
|
ifctl |= MAC_IFCTL_SPEED; |
|
|
|
|
break; |
|
|
|
|
case SPEED_10: |
|
|
|
|
mii_speed = MII_CTRL_SPEED_10; |
|
|
|
|
cfg2 |= MAC_CFG2_IF_10_100; |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
BUG(); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (pdata->is_ar91xx) |
|
|
|
|
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x00780fff); |
|
|
|
|
else if (pdata->is_ar724x) |
|
|
|
|
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, pdata->fifo_cfg3); |
|
|
|
|
else |
|
|
|
|
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x008001ff); |
|
|
|
|
|
|
|
|
|
if (pdata->set_pll) |
|
|
|
|
pdata->set_pll(ag->speed); |
|
|
|
|
|
|
|
|
|
ag71xx_mii_ctrl_set_speed(ag, mii_speed); |
|
|
|
|
|
|
|
|
|
ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2); |
|
|
|
|
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5); |
|
|
|
|
ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl); |
|
|
|
|
|
|
|
|
|
netif_carrier_on(ag->dev); |
|
|
|
|
if (netif_msg_link(ag)) |
|
|
|
|
printk(KERN_INFO "%s: link up (%sMbps/%s duplex)\n", |
|
|
|
|
ag->dev->name, |
|
|
|
|
ag71xx_speed_str(ag), |
|
|
|
|
(DUPLEX_FULL == ag->duplex) ? "Full" : "Half"); |
|
|
|
|
|
|
|
|
|
DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n", |
|
|
|
|
ag->dev->name, |
|
|
|
|
ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), |
|
|
|
|
ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), |
|
|
|
|
ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); |
|
|
|
|
|
|
|
|
|
DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n", |
|
|
|
|
ag->dev->name, |
|
|
|
|
ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), |
|
|
|
|
ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), |
|
|
|
|
ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); |
|
|
|
|
|
|
|
|
|
DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x, mii_ctrl=%#x\n", |
|
|
|
|
ag->dev->name, |
|
|
|
|
ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), |
|
|
|
|
ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), |
|
|
|
|
ag71xx_mii_ctrl_rr(ag)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac) |
|
|
|
|
{ |
|
|
|
|
u32 t; |
|
|
|
@ -560,10 +473,98 @@ static void ag71xx_hw_start(struct ag71xx *ag) |
|
|
|
|
|
|
|
|
|
static void ag71xx_hw_stop(struct ag71xx *ag) |
|
|
|
|
{ |
|
|
|
|
/* disable all interrupts */ |
|
|
|
|
/* disable all interrupts and stop the rx engine */ |
|
|
|
|
ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, 0); |
|
|
|
|
ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ag71xx_dma_reset(ag); |
|
|
|
|
void ag71xx_link_adjust(struct ag71xx *ag) |
|
|
|
|
{ |
|
|
|
|
struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); |
|
|
|
|
u32 cfg2; |
|
|
|
|
u32 ifctl; |
|
|
|
|
u32 fifo5; |
|
|
|
|
u32 mii_speed; |
|
|
|
|
|
|
|
|
|
if (!ag->link) { |
|
|
|
|
ag71xx_hw_stop(ag); |
|
|
|
|
netif_carrier_off(ag->dev); |
|
|
|
|
if (netif_msg_link(ag)) |
|
|
|
|
printk(KERN_INFO "%s: link down\n", ag->dev->name); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2); |
|
|
|
|
cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX); |
|
|
|
|
cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0; |
|
|
|
|
|
|
|
|
|
ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL); |
|
|
|
|
ifctl &= ~(MAC_IFCTL_SPEED); |
|
|
|
|
|
|
|
|
|
fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5); |
|
|
|
|
fifo5 &= ~FIFO_CFG5_BM; |
|
|
|
|
|
|
|
|
|
switch (ag->speed) { |
|
|
|
|
case SPEED_1000: |
|
|
|
|
mii_speed = MII_CTRL_SPEED_1000; |
|
|
|
|
cfg2 |= MAC_CFG2_IF_1000; |
|
|
|
|
fifo5 |= FIFO_CFG5_BM; |
|
|
|
|
break; |
|
|
|
|
case SPEED_100: |
|
|
|
|
mii_speed = MII_CTRL_SPEED_100; |
|
|
|
|
cfg2 |= MAC_CFG2_IF_10_100; |
|
|
|
|
ifctl |= MAC_IFCTL_SPEED; |
|
|
|
|
break; |
|
|
|
|
case SPEED_10: |
|
|
|
|
mii_speed = MII_CTRL_SPEED_10; |
|
|
|
|
cfg2 |= MAC_CFG2_IF_10_100; |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
BUG(); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (pdata->is_ar91xx) |
|
|
|
|
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x00780fff); |
|
|
|
|
else if (pdata->is_ar724x) |
|
|
|
|
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, pdata->fifo_cfg3); |
|
|
|
|
else |
|
|
|
|
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x008001ff); |
|
|
|
|
|
|
|
|
|
if (pdata->set_pll) |
|
|
|
|
pdata->set_pll(ag->speed); |
|
|
|
|
|
|
|
|
|
ag71xx_mii_ctrl_set_speed(ag, mii_speed); |
|
|
|
|
|
|
|
|
|
ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2); |
|
|
|
|
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5); |
|
|
|
|
ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl); |
|
|
|
|
ag71xx_hw_start(ag); |
|
|
|
|
|
|
|
|
|
netif_carrier_on(ag->dev); |
|
|
|
|
if (netif_msg_link(ag)) |
|
|
|
|
printk(KERN_INFO "%s: link up (%sMbps/%s duplex)\n", |
|
|
|
|
ag->dev->name, |
|
|
|
|
ag71xx_speed_str(ag), |
|
|
|
|
(DUPLEX_FULL == ag->duplex) ? "Full" : "Half"); |
|
|
|
|
|
|
|
|
|
DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n", |
|
|
|
|
ag->dev->name, |
|
|
|
|
ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), |
|
|
|
|
ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), |
|
|
|
|
ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); |
|
|
|
|
|
|
|
|
|
DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n", |
|
|
|
|
ag->dev->name, |
|
|
|
|
ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), |
|
|
|
|
ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), |
|
|
|
|
ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); |
|
|
|
|
|
|
|
|
|
DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x, mii_ctrl=%#x\n", |
|
|
|
|
ag->dev->name, |
|
|
|
|
ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), |
|
|
|
|
ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), |
|
|
|
|
ag71xx_mii_ctrl_rr(ag)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int ag71xx_open(struct net_device *dev) |
|
|
|
@ -585,8 +586,6 @@ static int ag71xx_open(struct net_device *dev) |
|
|
|
|
|
|
|
|
|
ag71xx_hw_set_macaddr(ag, dev->dev_addr); |
|
|
|
|
|
|
|
|
|
ag71xx_hw_start(ag); |
|
|
|
|
|
|
|
|
|
netif_start_queue(dev); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
@ -609,6 +608,7 @@ static int ag71xx_stop(struct net_device *dev) |
|
|
|
|
netif_stop_queue(dev); |
|
|
|
|
|
|
|
|
|
ag71xx_hw_stop(ag); |
|
|
|
|
ag71xx_dma_reset(ag); |
|
|
|
|
|
|
|
|
|
napi_disable(&ag->napi); |
|
|
|
|
del_timer_sync(&ag->oom_timer); |
|
|
|
|