Changeset 26856


Ignore:
Timestamp:
2011-05-08T18:32:53+02:00 (7 years ago)
Author:
juhosg
Message:

ar71xx: ag71xx: make switch register access atomic

Reading of the PHY registers occasionally returns with bogus values
under heavy load. This misleads the PHY driver and thus causes false
link/speed change notifications which leads to performance loss.

This is easily noticable during an iperf session:

...
[ 3] 52.0-53.0 sec 11.3 MBytes 94.4 Mbits/sec
[ 3] 53.0-54.0 sec 11.4 MBytes 95.4 Mbits/sec
eth1: link down
br-lan: port 2(eth1) entering forwarding state
eth1: link up (100Mbps/Full duplex)
br-lan: port 2(eth1) entering forwarding state
br-lan: port 2(eth1) entering forwarding state
[ 3] 54.0-55.0 sec 6.75 MBytes 56.6 Mbits/sec
[ 3] 55.0-56.0 sec 0.00 Bytes 0.00 bits/sec
[ 3] 56.0-57.0 sec 10.5 MBytes 88.1 Mbits/sec
...
[ 3] 169.0-170.0 sec 11.4 MBytes 95.4 Mbits/sec
[ 3] 170.0-171.0 sec 11.4 MBytes 95.4 Mbits/sec
eth1: link up (10Mbps/Half duplex)
[ 3] 171.0-172.0 sec 7.63 MBytes 64.0 Mbits/sec
[ 3] 172.0-173.0 sec 9.38 MBytes 78.6 Mbits/sec
eth1: link up (100Mbps/Full duplex)
[ 3] 173.0-174.0 sec 11.3 MBytes 94.4 Mbits/sec
[ 3] 174.0-175.0 sec 11.4 MBytes 95.4 Mbits/sec

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_ar7240.c

    r26855 r26856  
    234234static u32 __ar7240sw_reg_read(struct mii_bus *mii, u32 reg) 
    235235{ 
     236        unsigned long flags; 
    236237        u16 phy_addr; 
    237238        u16 phy_reg; 
     
    239240 
    240241        reg = (reg & 0xfffffffc) >> 2; 
    241  
    242         ag71xx_mdio_mii_write(mii->priv, 0x1f, 0x10, mk_high_addr(reg)); 
    243  
    244242        phy_addr = mk_phy_addr(reg); 
    245243        phy_reg = mk_phy_reg(reg); 
    246244 
     245        local_irq_save(flags); 
     246        ag71xx_mdio_mii_write(mii->priv, 0x1f, 0x10, mk_high_addr(reg)); 
    247247        lo = (u32) ag71xx_mdio_mii_read(mii->priv, phy_addr, phy_reg); 
    248248        hi = (u32) ag71xx_mdio_mii_read(mii->priv, phy_addr, phy_reg + 1); 
     249        local_irq_restore(flags); 
    249250 
    250251        return (hi << 16) | lo; 
     
    253254static void __ar7240sw_reg_write(struct mii_bus *mii, u32 reg, u32 val) 
    254255{ 
     256        unsigned long flags; 
    255257        u16 phy_addr; 
    256258        u16 phy_reg; 
    257259 
    258260        reg = (reg & 0xfffffffc) >> 2; 
    259  
    260         ag71xx_mdio_mii_write(mii->priv, 0x1f, 0x10, mk_high_addr(reg)); 
    261  
    262261        phy_addr = mk_phy_addr(reg); 
    263262        phy_reg = mk_phy_reg(reg); 
    264263 
     264        local_irq_save(flags); 
     265        ag71xx_mdio_mii_write(mii->priv, 0x1f, 0x10, mk_high_addr(reg)); 
    265266        ag71xx_mdio_mii_write(mii->priv, phy_addr, phy_reg + 1, (val >> 16)); 
    266267        ag71xx_mdio_mii_write(mii->priv, phy_addr, phy_reg, (val & 0xffff)); 
     268        local_irq_restore(flags); 
    267269} 
    268270 
Note: See TracChangeset for help on using the changeset viewer.