diff options
Diffstat (limited to 'drivers/net/sfc/tx.c')
-rw-r--r-- | drivers/net/sfc/tx.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index 03194f7c0954..bdb92b4af683 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c | |||
@@ -240,8 +240,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) | |||
240 | * of read_count. */ | 240 | * of read_count. */ |
241 | smp_mb(); | 241 | smp_mb(); |
242 | tx_queue->old_read_count = | 242 | tx_queue->old_read_count = |
243 | *(volatile unsigned *) | 243 | ACCESS_ONCE(tx_queue->read_count); |
244 | &tx_queue->read_count; | ||
245 | fill_level = (tx_queue->insert_count | 244 | fill_level = (tx_queue->insert_count |
246 | - tx_queue->old_read_count); | 245 | - tx_queue->old_read_count); |
247 | q_space = efx->txq_entries - 1 - fill_level; | 246 | q_space = efx->txq_entries - 1 - fill_level; |
@@ -429,6 +428,16 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) | |||
429 | __netif_tx_unlock(queue); | 428 | __netif_tx_unlock(queue); |
430 | } | 429 | } |
431 | } | 430 | } |
431 | |||
432 | /* Check whether the hardware queue is now empty */ | ||
433 | if ((int)(tx_queue->read_count - tx_queue->old_write_count) >= 0) { | ||
434 | tx_queue->old_write_count = ACCESS_ONCE(tx_queue->write_count); | ||
435 | if (tx_queue->read_count == tx_queue->old_write_count) { | ||
436 | smp_mb(); | ||
437 | tx_queue->empty_read_count = | ||
438 | tx_queue->read_count | EFX_EMPTY_COUNT_VALID; | ||
439 | } | ||
440 | } | ||
432 | } | 441 | } |
433 | 442 | ||
434 | int efx_probe_tx_queue(struct efx_tx_queue *tx_queue) | 443 | int efx_probe_tx_queue(struct efx_tx_queue *tx_queue) |
@@ -474,8 +483,10 @@ void efx_init_tx_queue(struct efx_tx_queue *tx_queue) | |||
474 | 483 | ||
475 | tx_queue->insert_count = 0; | 484 | tx_queue->insert_count = 0; |
476 | tx_queue->write_count = 0; | 485 | tx_queue->write_count = 0; |
486 | tx_queue->old_write_count = 0; | ||
477 | tx_queue->read_count = 0; | 487 | tx_queue->read_count = 0; |
478 | tx_queue->old_read_count = 0; | 488 | tx_queue->old_read_count = 0; |
489 | tx_queue->empty_read_count = 0 | EFX_EMPTY_COUNT_VALID; | ||
479 | BUG_ON(tx_queue->stopped); | 490 | BUG_ON(tx_queue->stopped); |
480 | 491 | ||
481 | /* Set up TX descriptor ring */ | 492 | /* Set up TX descriptor ring */ |
@@ -764,7 +775,7 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue, | |||
764 | * stopped from the access of read_count. */ | 775 | * stopped from the access of read_count. */ |
765 | smp_mb(); | 776 | smp_mb(); |
766 | tx_queue->old_read_count = | 777 | tx_queue->old_read_count = |
767 | *(volatile unsigned *)&tx_queue->read_count; | 778 | ACCESS_ONCE(tx_queue->read_count); |
768 | fill_level = (tx_queue->insert_count | 779 | fill_level = (tx_queue->insert_count |
769 | - tx_queue->old_read_count); | 780 | - tx_queue->old_read_count); |
770 | q_space = efx->txq_entries - 1 - fill_level; | 781 | q_space = efx->txq_entries - 1 - fill_level; |