diff options
Diffstat (limited to 'drivers/net/netxen/netxen_nic_main.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 32 |
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 | ||
108 | void | 108 | void |
109 | netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, | 109 | netxen_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 | ||
115 | static uint32_t crb_cmd_consumer[4] = { | 120 | static uint32_t crb_cmd_consumer[4] = { |
@@ -119,9 +124,9 @@ static uint32_t crb_cmd_consumer[4] = { | |||
119 | 124 | ||
120 | static inline void | 125 | static inline void |
121 | netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter, | 126 | netxen_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 | ||
127 | static uint32_t msi_tgt_status[8] = { | 132 | static 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 | ||