aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen/netxen_nic_main.c
diff options
context:
space:
mode:
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