diff options
| -rw-r--r-- | drivers/net/netxen/netxen_nic.h | 11 | ||||
| -rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 2 | ||||
| -rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 11 | ||||
| -rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 32 |
4 files changed, 35 insertions, 21 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index ab11c2b3f0fe..970cedeb5f37 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
| @@ -169,6 +169,7 @@ | |||
| 169 | #define MAX_NUM_CARDS 4 | 169 | #define MAX_NUM_CARDS 4 |
| 170 | 170 | ||
| 171 | #define MAX_BUFFERS_PER_CMD 32 | 171 | #define MAX_BUFFERS_PER_CMD 32 |
| 172 | #define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + 4) | ||
| 172 | 173 | ||
| 173 | /* | 174 | /* |
| 174 | * Following are the states of the Phantom. Phantom will set them and | 175 | * Following are the states of the Phantom. Phantom will set them and |
| @@ -1436,7 +1437,7 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p); | |||
| 1436 | struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev); | 1437 | struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev); |
| 1437 | 1438 | ||
| 1438 | void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, | 1439 | void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, |
| 1439 | struct nx_host_tx_ring *tx_ring, uint32_t crb_producer); | 1440 | struct nx_host_tx_ring *tx_ring); |
| 1440 | 1441 | ||
| 1441 | /* | 1442 | /* |
| 1442 | * NetXen Board information | 1443 | * NetXen Board information |
| @@ -1538,6 +1539,14 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter) | |||
| 1538 | } | 1539 | } |
| 1539 | 1540 | ||
| 1540 | 1541 | ||
| 1542 | static inline u32 netxen_tx_avail(struct nx_host_tx_ring *tx_ring) | ||
| 1543 | { | ||
| 1544 | smp_mb(); | ||
| 1545 | return find_diff_among(tx_ring->producer, | ||
| 1546 | tx_ring->sw_consumer, tx_ring->num_desc); | ||
| 1547 | |||
| 1548 | } | ||
| 1549 | |||
| 1541 | int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac); | 1550 | int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac); |
| 1542 | int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac); | 1551 | int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac); |
| 1543 | extern void netxen_change_ringparam(struct netxen_adapter *adapter); | 1552 | extern void netxen_change_ringparam(struct netxen_adapter *adapter); |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 9702509ce3c5..ce3b89d2cbb6 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
| @@ -488,7 +488,7 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, | |||
| 488 | 488 | ||
| 489 | tx_ring->producer = producer; | 489 | tx_ring->producer = producer; |
| 490 | 490 | ||
| 491 | netxen_nic_update_cmd_producer(adapter, tx_ring, producer); | 491 | netxen_nic_update_cmd_producer(adapter, tx_ring); |
| 492 | 492 | ||
| 493 | netif_tx_unlock_bh(adapter->netdev); | 493 | netif_tx_unlock_bh(adapter->netdev); |
| 494 | 494 | ||
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 6f77ad58e3b3..bdb143d2b5c7 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
| @@ -1292,7 +1292,6 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) | |||
| 1292 | return 1; | 1292 | return 1; |
| 1293 | 1293 | ||
| 1294 | sw_consumer = tx_ring->sw_consumer; | 1294 | sw_consumer = tx_ring->sw_consumer; |
| 1295 | barrier(); /* hw_consumer can change underneath */ | ||
| 1296 | hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); | 1295 | hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); |
| 1297 | 1296 | ||
| 1298 | while (sw_consumer != hw_consumer) { | 1297 | while (sw_consumer != hw_consumer) { |
| @@ -1319,14 +1318,15 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) | |||
| 1319 | break; | 1318 | break; |
| 1320 | } | 1319 | } |
| 1321 | 1320 | ||
| 1322 | tx_ring->sw_consumer = sw_consumer; | ||
| 1323 | |||
| 1324 | if (count && netif_running(netdev)) { | 1321 | if (count && netif_running(netdev)) { |
| 1322 | tx_ring->sw_consumer = sw_consumer; | ||
| 1323 | |||
| 1325 | smp_mb(); | 1324 | smp_mb(); |
| 1325 | |||
| 1326 | if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) { | 1326 | if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) { |
| 1327 | netif_tx_lock(netdev); | 1327 | netif_tx_lock(netdev); |
| 1328 | netif_wake_queue(netdev); | 1328 | if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) |
| 1329 | smp_mb(); | 1329 | netif_wake_queue(netdev); |
| 1330 | netif_tx_unlock(netdev); | 1330 | netif_tx_unlock(netdev); |
| 1331 | } | 1331 | } |
| 1332 | } | 1332 | } |
| @@ -1343,7 +1343,6 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) | |||
| 1343 | * There is still a possible race condition and the host could miss an | 1343 | * There is still a possible race condition and the host could miss an |
| 1344 | * interrupt. The card has to take care of this. | 1344 | * interrupt. The card has to take care of this. |
| 1345 | */ | 1345 | */ |
| 1346 | barrier(); /* hw_consumer can change underneath */ | ||
| 1347 | hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); | 1346 | hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); |
| 1348 | done = (sw_consumer == hw_consumer); | 1347 | done = (sw_consumer == hw_consumer); |
| 1349 | spin_unlock(&adapter->tx_clean_lock); | 1348 | spin_unlock(&adapter->tx_clean_lock); |
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 | ||
