aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pasemi_mac.c
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2007-11-28 21:56:54 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:04:23 -0500
commit61cec3bddc79373a246e2f8eb13e5acdc106f46a (patch)
tree4c2780bc195ed6acce57073101b98813595206c8 /drivers/net/pasemi_mac.c
parent5c15332bed4c59fff6423f08ef6bd6894af38a99 (diff)
pasemi_mac: Fix TX cleaning
pasemi_mac: Fix TX cleaning This is a bit awkward. We don't have a timer-delayed interrupt on TX complete, but we have a count threshold. So set that reasonably high (32 packets), and schedule the NAPI poll when it goes off. Also bump a regular timer that will take care of rotting packets for the last 1..31 ones in case we don't trigger a TX interrupt (and there's no RX activity that would otherwise trigger the poll). The longer-term fix is to separate TX from RX NAPI and do two separate poll loops. Signed-off-by: Olof Johansson <olof@lixom.net> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/pasemi_mac.c')
-rw-r--r--drivers/net/pasemi_mac.c41
1 files changed, 33 insertions, 8 deletions
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index c6e24a8dcf72..683e8de0ac89 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -805,27 +805,43 @@ static irqreturn_t pasemi_mac_rx_intr(int irq, void *data)
805 return IRQ_HANDLED; 805 return IRQ_HANDLED;
806} 806}
807 807
808#define TX_CLEAN_INTERVAL HZ
809
810static void pasemi_mac_tx_timer(unsigned long data)
811{
812 struct pasemi_mac_txring *txring = (struct pasemi_mac_txring *)data;
813 struct pasemi_mac *mac = txring->mac;
814
815 pasemi_mac_clean_tx(txring);
816
817 mod_timer(&txring->clean_timer, jiffies + TX_CLEAN_INTERVAL);
818
819 pasemi_mac_restart_tx_intr(mac);
820}
821
808static irqreturn_t pasemi_mac_tx_intr(int irq, void *data) 822static irqreturn_t pasemi_mac_tx_intr(int irq, void *data)
809{ 823{
810 struct pasemi_mac_txring *txring = data; 824 struct pasemi_mac_txring *txring = data;
811 const struct pasemi_dmachan *chan = &txring->chan; 825 const struct pasemi_dmachan *chan = &txring->chan;
812 unsigned int reg, pcnt; 826 struct pasemi_mac *mac = txring->mac;
827 unsigned int reg;
813 828
814 if (!(*chan->status & PAS_STATUS_CAUSE_M)) 829 if (!(*chan->status & PAS_STATUS_CAUSE_M))
815 return IRQ_NONE; 830 return IRQ_NONE;
816 831
817 pasemi_mac_clean_tx(txring); 832 reg = 0;
818
819 pcnt = *chan->status & PAS_STATUS_PCNT_M;
820
821 reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC;
822 833
823 if (*chan->status & PAS_STATUS_SOFT) 834 if (*chan->status & PAS_STATUS_SOFT)
824 reg |= PAS_IOB_DMA_TXCH_RESET_SINTC; 835 reg |= PAS_IOB_DMA_TXCH_RESET_SINTC;
825 if (*chan->status & PAS_STATUS_ERROR) 836 if (*chan->status & PAS_STATUS_ERROR)
826 reg |= PAS_IOB_DMA_TXCH_RESET_DINTC; 837 reg |= PAS_IOB_DMA_TXCH_RESET_DINTC;
827 838
828 write_iob_reg(PAS_IOB_DMA_TXCH_RESET(chan->chno), reg); 839 mod_timer(&txring->clean_timer, jiffies + (TX_CLEAN_INTERVAL)*2);
840
841 netif_rx_schedule(mac->netdev, &mac->napi);
842
843 if (reg)
844 write_iob_reg(PAS_IOB_DMA_TXCH_RESET(chan->chno), reg);
829 845
830 return IRQ_HANDLED; 846 return IRQ_HANDLED;
831} 847}
@@ -973,7 +989,7 @@ static int pasemi_mac_open(struct net_device *dev)
973 PAS_IOB_DMA_RXCH_CFG_CNTTH(0)); 989 PAS_IOB_DMA_RXCH_CFG_CNTTH(0));
974 990
975 write_iob_reg(PAS_IOB_DMA_TXCH_CFG(mac->tx->chan.chno), 991 write_iob_reg(PAS_IOB_DMA_TXCH_CFG(mac->tx->chan.chno),
976 PAS_IOB_DMA_TXCH_CFG_CNTTH(128)); 992 PAS_IOB_DMA_TXCH_CFG_CNTTH(32));
977 993
978 write_mac_reg(mac, PAS_MAC_IPC_CHNL, 994 write_mac_reg(mac, PAS_MAC_IPC_CHNL,
979 PAS_MAC_IPC_CHNL_DCHNO(mac->rx->chan.chno) | 995 PAS_MAC_IPC_CHNL_DCHNO(mac->rx->chan.chno) |
@@ -1054,6 +1070,12 @@ static int pasemi_mac_open(struct net_device *dev)
1054 if (mac->phydev) 1070 if (mac->phydev)
1055 phy_start(mac->phydev); 1071 phy_start(mac->phydev);
1056 1072
1073 init_timer(&mac->tx->clean_timer);
1074 mac->tx->clean_timer.function = pasemi_mac_tx_timer;
1075 mac->tx->clean_timer.data = (unsigned long)mac->tx;
1076 mac->tx->clean_timer.expires = jiffies+HZ;
1077 add_timer(&mac->tx->clean_timer);
1078
1057 return 0; 1079 return 0;
1058 1080
1059out_rx_int: 1081out_rx_int:
@@ -1087,6 +1109,8 @@ static int pasemi_mac_close(struct net_device *dev)
1087 phy_disconnect(mac->phydev); 1109 phy_disconnect(mac->phydev);
1088 } 1110 }
1089 1111
1112 del_timer_sync(&mac->tx->clean_timer);
1113
1090 netif_stop_queue(dev); 1114 netif_stop_queue(dev);
1091 napi_disable(&mac->napi); 1115 napi_disable(&mac->napi);
1092 1116
@@ -1304,6 +1328,7 @@ static int pasemi_mac_poll(struct napi_struct *napi, int budget)
1304 netif_rx_complete(dev, napi); 1328 netif_rx_complete(dev, napi);
1305 1329
1306 pasemi_mac_restart_rx_intr(mac); 1330 pasemi_mac_restart_rx_intr(mac);
1331 pasemi_mac_restart_tx_intr(mac);
1307 } 1332 }
1308 return pkts; 1333 return pkts;
1309} 1334}