IP100A Fix Tx pause bug
Subsystems (2)
PATCH 2/6 IP100A Fix Tx pause bug
From: Jesse Huang <[email protected]>
Fix Tx pause bug
Change Logs:
Fix Tx pause bug
---
drivers/net/sundance.c | 49 +++++++++++++++++++++++++++--------------------- 1 files changed, 28 insertions(+), 21 deletions(-)
7e6bffe518096d89a9e7ee9b80f246b3ff442f2e
drivers/net/sundance.c +28 -21
@@ -262,8 +262,6 @@ enum alta_offsets { ASICCtrl =0x30 , EEData =0x34 , EECtrl =0x36 , - TxStartThresh =0x3c , - RxEarlyThresh =0x3e , FlashAddr =0x40 , FlashData =0x44 , TxStatus = 0x46,
@@ -1084,6 +1082,8 @@ reset_tx (struct net_device *dev) }/* free all tx skbuff */ for (i =0 ; i <TX_RING_SIZE ; i++) { + np->tx_ring[i].next_desc =0 ; + skb = np->tx_skbuff[i];if (skb) { pci_unmap_single(np->pci_dev,
@@ -1099,6 +1099,10 @@ reset_tx (struct net_device *dev) } np->cur_tx = np->dirty_tx =0 ; np->cur_task =0 ; + + np->last_tx=0 ; +iowrite8 (127 , ioaddr + TxDMAPollPeriod); +iowrite16 (StatsEnable | RxEnable | TxEnable, ioaddr + MACCtrl1);return 0 ; }
@@ -1156,29 +1160,29 @@ static irqreturn_t intr_handler(int irq, np->stats.tx_fifo_errors++;if (tx_status &0x02 ) np->stats.tx_window_errors++; -/* -** This reset has been verified on -** DFE-580TX boards ! [email protected]. -*/ -if (tx_status &0x10 ) {/* TxUnderrun */ -unsigned short txthreshold; - - txthreshold =ioread16 (ioaddr + TxStartThresh); -/* Restart Tx FIFO and transmitter */ -sundance_reset (dev, (NetworkReset|FIFOReset|TxReset) <<16 ); -iowrite16 (txthreshold, ioaddr + TxStartThresh); -/* No need to reset the Tx pointer here */ + +/* FIFO ERROR need to be reset tx */ +if (tx_status &0x10 ) {/* Reset the Tx. */ +spin_lock (&np->lock); +reset_tx (dev); +spin_unlock (&np->lock); + } +if (tx_status &0x1e ) { +/* need to make sure tx enabled */ +int i =10 ; +do { +iowrite16 (ioread16 (ioaddr + MACCtrl1) | TxEnable, ioaddr + MACCtrl1); +if (ioread16 (ioaddr + MACCtrl1) & TxEnabled) +break ; +mdelay (1 ); + }while (--i); } -/* Restart the Tx. */ -iowrite16 (TxEnable, ioaddr + MACCtrl1); } -/* Yup, this is a documentation bug. It cost me *hours*. */ +iowrite16 (0 , ioaddr + TxStatus); -if (tx_cnt <0 ) { -iowrite32 (5000 , ioaddr + DownCounter); -break ; - } tx_status =ioread16 (ioaddr + TxStatus); +if (tx_cnt <0 ) +break ; } hw_frame_id = (tx_status >>8 ) &0xff ; }else {
@@ -1244,6 +1248,9 @@ static irqreturn_t intr_handler(int irq,if (netif_msg_intr (np))printk (KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n" , dev->name,ioread16 (ioaddr + IntrStatus)); + +iowrite32 (5000 , ioaddr + DownCounter); +return IRQ_RETVAL (handled); }
Signature · 1 line
1.3.GIT
drivers/net/sundance.c reset_tx (struct net_device *dev) · line 1103
Quoted 6 lines · Jesse Huang
drivers/net/sundance.c +2
-0@@ -1099,6 +1099,10 @@ reset_tx (struct net_device *dev) } np->cur_tx = np->dirty_tx =0 ; np->cur_task =0 ; + + np->last_tx=0 ;
add whitespace, to make it look like all other assignments:
s/=/ = /
drivers/net/sundance.c reset_tx (struct net_device *dev) · line 1105
Quoted 2 lines
drivers/net/sundance.c +2
-0+iowrite8 (127 , ioaddr + TxDMAPollPeriod); +
what does the value 127 represent?
Quoted 53 lines
drivers/net/sundance.c +19
-19iowrite16 (StatsEnable | RxEnable | TxEnable, ioaddr + MACCtrl1);return 0 ; }@@ -1156,29 +1160,29 @@ static irqreturn_t intr_handler(int irq, np->stats.tx_fifo_errors++;if (tx_status &0x02 ) np->stats.tx_window_errors++; -/* -** This reset has been verified on -** DFE-580TX boards ! [email protected]. -*/ -if (tx_status &0x10 ) {/* TxUnderrun */ -unsigned short txthreshold; - - txthreshold =ioread16 (ioaddr + TxStartThresh); -/* Restart Tx FIFO and transmitter */ -sundance_reset (dev, (NetworkReset|FIFOReset|TxReset) <<16 ); -iowrite16 (txthreshold, ioaddr + TxStartThresh); -/* No need to reset the Tx pointer here */ + +/* FIFO ERROR need to be reset tx */ +if (tx_status &0x10 ) {/* Reset the Tx. */ +spin_lock (&np->lock); +reset_tx (dev); +spin_unlock (&np->lock); + } +if (tx_status &0x1e ) { +/* need to make sure tx enabled */ +int i =10 ; +do { +iowrite16 (ioread16 (ioaddr + MACCtrl1) | TxEnable, ioaddr + MACCtrl1); +if (ioread16 (ioaddr + MACCtrl1) & TxEnabled) +break ; +mdelay (1 ); + }while (--i); } -/* Restart the Tx. */ -iowrite16 (TxEnable, ioaddr + MACCtrl1); } -/* Yup, this is a documentation bug. It cost me *hours*. */ +iowrite16 (0 , ioaddr + TxStatus); -if (tx_cnt <0 ) { -iowrite32 (5000 , ioaddr + DownCounter); -break ; - } tx_status =ioread16 (ioaddr + TxStatus); +if (tx_cnt <0 ) +break ; } hw_frame_id = (tx_status >>8 ) &0xff ; }else {
drivers/net/sundance.c static irqreturn_t intr_handler(int irq, · line 1254
Quoted 7 lines
drivers/net/sundance.c +3
-0@@ -1244,6 +1248,9 @@ static irqreturn_t intr_handler(int irq,if (netif_msg_intr (np))printk (KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n" , dev->name,ioread16 (ioaddr + IntrStatus)); + +iowrite32 (5000 , ioaddr + DownCounter); +return IRQ_RETVAL (handled);
DownCounter should not be written unconditionally. Consider shared interrupts, where sundance performs no work, and handled==0.
Jeff
----- Original Message -----
From: "Jeff Garzik" <[email protected]>
To: "Jesse Huang" <[email protected]>
Cc: <[email protected]>; <[email protected]>; <[email protected]>
Sent: Friday, August 18, 2006 7:27 PM
Subject: Re: [PATCH 2/6] IP100A Fix Tx pause bug
(1)
Quoted 4 lines
Quoted 2 lines
+
iowrite8(127, ioaddr + TxDMAPollPeriod);
+what does the value 127 represent?
127 is polling period of Tx DMA to watch if there any packet need to send. The 127 means 127*320ns.
(2)
Quoted 2 lines
DownCounter should not be written unconditionally. Consider shared interrupts, where sundance performs no work, and handled==0.
DownCount is a the register that we can use for timer interrupt. When the value of DownCount from 1 count down to 0 , IP100A will issue an interrupt.