Ignore:
Timestamp:
2011-06-01T20:15:43+02:00 (5 years ago)
Author:
nbd
Message:

Revert "ar71xx: only enable the rx engine after the link is up..."

It messes up the DMA state when the link goes down

File:
1 edited

Legend:

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

    r27040 r27088  
    344344} 
    345345 
    346 static void ag71xx_dma_reset(struct ag71xx *ag) 
    347 { 
    348         u32 val; 
    349         int i; 
    350  
    351         ag71xx_dump_dma_regs(ag); 
    352  
    353         /* stop RX and TX */ 
    354         ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); 
    355         ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); 
    356  
    357         /* 
    358          * give the hardware some time to really stop all rx/tx activity 
    359          * clearing the descriptors too early causes random memory corruption 
    360          */ 
    361         mdelay(1); 
    362  
    363         /* clear descriptor addresses */ 
    364         ag71xx_wr(ag, AG71XX_REG_TX_DESC, 0); 
    365         ag71xx_wr(ag, AG71XX_REG_RX_DESC, 0); 
    366  
    367         /* clear pending RX/TX interrupts */ 
    368         for (i = 0; i < 256; i++) { 
    369                 ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); 
    370                 ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); 
    371         } 
    372  
    373         /* clear pending errors */ 
    374         ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF); 
    375         ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR); 
    376  
    377         val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); 
    378         if (val) 
    379                 printk(KERN_ALERT "%s: unable to clear DMA Rx status: %08x\n", 
    380                         ag->dev->name, val); 
    381  
    382         val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); 
    383  
    384         /* mask out reserved bits */ 
    385         val &= ~0xff000000; 
    386  
    387         if (val) 
    388                 printk(KERN_ALERT "%s: unable to clear DMA Tx status: %08x\n", 
    389                         ag->dev->name, val); 
    390  
    391         ag71xx_dump_dma_regs(ag); 
    392 } 
    393  
    394 static void ag71xx_hw_start(struct ag71xx *ag) 
    395 { 
    396         /* start RX engine */ 
    397         ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); 
    398  
    399         /* enable interrupts */ 
    400         ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, AG71XX_INT_INIT); 
    401 } 
    402  
    403 static void ag71xx_hw_stop(struct ag71xx *ag) 
    404 { 
    405         /* disable all interrupts */ 
    406         ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, 0); 
    407  
    408         ag71xx_dma_reset(ag); 
    409 } 
    410  
    411346void ag71xx_link_adjust(struct ag71xx *ag) 
    412347{ 
     
    418353 
    419354        if (!ag->link) { 
    420                 ag71xx_hw_stop(ag); 
    421355                netif_carrier_off(ag->dev); 
    422356                if (netif_msg_link(ag)) 
     
    471405        ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl); 
    472406 
    473         ag71xx_hw_start(ag); 
    474  
    475407        netif_carrier_on(ag->dev); 
    476408        if (netif_msg_link(ag)) 
     
    510442        t = (((u32) mac[1]) << 24) | (((u32) mac[0]) << 16); 
    511443        ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t); 
     444} 
     445 
     446static void ag71xx_dma_reset(struct ag71xx *ag) 
     447{ 
     448        u32 val; 
     449        int i; 
     450 
     451        ag71xx_dump_dma_regs(ag); 
     452 
     453        /* stop RX and TX */ 
     454        ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); 
     455        ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); 
     456 
     457        /* 
     458         * give the hardware some time to really stop all rx/tx activity 
     459         * clearing the descriptors too early causes random memory corruption 
     460         */ 
     461        mdelay(1); 
     462 
     463        /* clear descriptor addresses */ 
     464        ag71xx_wr(ag, AG71XX_REG_TX_DESC, 0); 
     465        ag71xx_wr(ag, AG71XX_REG_RX_DESC, 0); 
     466 
     467        /* clear pending RX/TX interrupts */ 
     468        for (i = 0; i < 256; i++) { 
     469                ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); 
     470                ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); 
     471        } 
     472 
     473        /* clear pending errors */ 
     474        ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF); 
     475        ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR); 
     476 
     477        val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); 
     478        if (val) 
     479                printk(KERN_ALERT "%s: unable to clear DMA Rx status: %08x\n", 
     480                        ag->dev->name, val); 
     481 
     482        val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); 
     483 
     484        /* mask out reserved bits */ 
     485        val &= ~0xff000000; 
     486 
     487        if (val) 
     488                printk(KERN_ALERT "%s: unable to clear DMA Tx status: %08x\n", 
     489                        ag->dev->name, val); 
     490 
     491        ag71xx_dump_dma_regs(ag); 
    512492} 
    513493 
     
    570550} 
    571551 
     552static void ag71xx_hw_start(struct ag71xx *ag) 
     553{ 
     554        /* start RX engine */ 
     555        ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); 
     556 
     557        /* enable interrupts */ 
     558        ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, AG71XX_INT_INIT); 
     559} 
     560 
     561static void ag71xx_hw_stop(struct ag71xx *ag) 
     562{ 
     563        /* disable all interrupts */ 
     564        ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, 0); 
     565 
     566        ag71xx_dma_reset(ag); 
     567} 
     568 
    572569static int ag71xx_open(struct net_device *dev) 
    573570{ 
     
    588585 
    589586        ag71xx_hw_set_macaddr(ag, dev->dev_addr); 
     587 
     588        ag71xx_hw_start(ag); 
    590589 
    591590        netif_start_queue(dev); 
Note: See TracChangeset for help on using the changeset viewer.