aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen/netxen_nic_main.c
diff options
context:
space:
mode:
authorDhananjay Phadke <dhananjay@netxen.com>2009-06-17 13:27:25 -0400
committerDavid S. Miller <davem@davemloft.net>2009-06-18 03:46:14 -0400
commitcb2107be43d2fc5eadec58b92b54bf32c00bfff3 (patch)
treedd04fda143a4a7d71b32b79b508a0566450c22c6 /drivers/net/netxen/netxen_nic_main.c
parentd173346040af497af22818dfc48cff369e67cf50 (diff)
netxen: fix tx ring accounting
This forces every update of tx ring producer to check for availability of space for next full TSO command. Earlier firmware control commands didn't care to pause tx queue. Stop the tx queue if there's not enough space to transmit one full LSO command left on the tx ring after current transmit. This avoids returning NETDEV_TX_BUSY after checking distance between producer and consumer on every cpu. Restart the tx queue only if we have cleaned up enough tx descriptors. Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/netxen/netxen_nic_main.c')
-rw-r--r--drivers/net/netxen/netxen_nic_main.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 98737ef72936..71daa3d5f114 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -107,9 +107,14 @@ static uint32_t crb_cmd_producer[4] = {
107 107
108void 108void
109netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, 109netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
110 struct nx_host_tx_ring *tx_ring, u32 producer) 110 struct nx_host_tx_ring *tx_ring)
111{ 111{
112 NXWR32(adapter, tx_ring->crb_cmd_producer, producer); 112 NXWR32(adapter, tx_ring->crb_cmd_producer, tx_ring->producer);
113
114 if (netxen_tx_avail(tx_ring) <= TX_STOP_THRESH) {
115 netif_stop_queue(adapter->netdev);
116 smp_mb();
117 }
113} 118}
114 119
115static uint32_t crb_cmd_consumer[4] = { 120static uint32_t crb_cmd_consumer[4] = {
@@ -119,9 +124,9 @@ static uint32_t crb_cmd_consumer[4] = {
119 124
120static inline void 125static inline void
121netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter, 126netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter,
122 struct nx_host_tx_ring *tx_ring, u32 consumer) 127 struct nx_host_tx_ring *tx_ring)
123{ 128{
124 NXWR32(adapter, tx_ring->crb_cmd_consumer, consumer); 129 NXWR32(adapter, tx_ring->crb_cmd_consumer, tx_ring->sw_consumer);
125} 130}
126 131
127static uint32_t msi_tgt_status[8] = { 132static uint32_t msi_tgt_status[8] = {
@@ -900,8 +905,11 @@ netxen_nic_attach(struct netxen_adapter *adapter)
900 tx_ring->crb_cmd_producer = crb_cmd_producer[adapter->portnum]; 905 tx_ring->crb_cmd_producer = crb_cmd_producer[adapter->portnum];
901 tx_ring->crb_cmd_consumer = crb_cmd_consumer[adapter->portnum]; 906 tx_ring->crb_cmd_consumer = crb_cmd_consumer[adapter->portnum];
902 907
903 netxen_nic_update_cmd_producer(adapter, tx_ring, 0); 908 tx_ring->producer = 0;
904 netxen_nic_update_cmd_consumer(adapter, tx_ring, 0); 909 tx_ring->sw_consumer = 0;
910
911 netxen_nic_update_cmd_producer(adapter, tx_ring);
912 netxen_nic_update_cmd_consumer(adapter, tx_ring);
905 } 913 }
906 914
907 for (ring = 0; ring < adapter->max_rds_rings; ring++) { 915 for (ring = 0; ring < adapter->max_rds_rings; ring++) {
@@ -1362,7 +1370,7 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
1362 dma_addr_t temp_dma; 1370 dma_addr_t temp_dma;
1363 int i, k; 1371 int i, k;
1364 1372
1365 u32 producer, consumer; 1373 u32 producer;
1366 int frag_count, no_of_desc; 1374 int frag_count, no_of_desc;
1367 u32 num_txd = tx_ring->num_desc; 1375 u32 num_txd = tx_ring->num_desc;
1368 bool is_tso = false; 1376 bool is_tso = false;
@@ -1372,15 +1380,13 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
1372 /* 4 fragments per cmd des */ 1380 /* 4 fragments per cmd des */
1373 no_of_desc = (frag_count + 3) >> 2; 1381 no_of_desc = (frag_count + 3) >> 2;
1374 1382
1375 producer = tx_ring->producer; 1383 if (unlikely(no_of_desc + 2) > netxen_tx_avail(tx_ring)) {
1376 smp_mb();
1377 consumer = tx_ring->sw_consumer;
1378 if ((no_of_desc+2) >= find_diff_among(producer, consumer, num_txd)) {
1379 netif_stop_queue(netdev); 1384 netif_stop_queue(netdev);
1380 smp_mb();
1381 return NETDEV_TX_BUSY; 1385 return NETDEV_TX_BUSY;
1382 } 1386 }
1383 1387
1388 producer = tx_ring->producer;
1389
1384 hwdesc = &tx_ring->desc_head[producer]; 1390 hwdesc = &tx_ring->desc_head[producer];
1385 netxen_clear_cmddesc((u64 *)hwdesc); 1391 netxen_clear_cmddesc((u64 *)hwdesc);
1386 pbuf = &tx_ring->cmd_buf_arr[producer]; 1392 pbuf = &tx_ring->cmd_buf_arr[producer];
@@ -1493,7 +1499,7 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
1493 tx_ring->producer = producer; 1499 tx_ring->producer = producer;
1494 adapter->stats.txbytes += skb->len; 1500 adapter->stats.txbytes += skb->len;
1495 1501
1496 netxen_nic_update_cmd_producer(adapter, tx_ring, producer); 1502 netxen_nic_update_cmd_producer(adapter, tx_ring);
1497 1503
1498 adapter->stats.xmitcalled++; 1504 adapter->stats.xmitcalled++;
1499 1505