diff options
Diffstat (limited to 'drivers/net/benet')
-rw-r--r-- | drivers/net/benet/be_main.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index babe53af7e86..243172bedfa6 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -1275,7 +1275,7 @@ static struct be_eth_tx_compl *be_tx_compl_get(struct be_queue_info *tx_cq) | |||
1275 | return txcp; | 1275 | return txcp; |
1276 | } | 1276 | } |
1277 | 1277 | ||
1278 | static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index) | 1278 | static u16 be_tx_compl_process(struct be_adapter *adapter, u16 last_index) |
1279 | { | 1279 | { |
1280 | struct be_queue_info *txq = &adapter->tx_obj.q; | 1280 | struct be_queue_info *txq = &adapter->tx_obj.q; |
1281 | struct be_eth_wrb *wrb; | 1281 | struct be_eth_wrb *wrb; |
@@ -1302,9 +1302,8 @@ static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index) | |||
1302 | queue_tail_inc(txq); | 1302 | queue_tail_inc(txq); |
1303 | } while (cur_index != last_index); | 1303 | } while (cur_index != last_index); |
1304 | 1304 | ||
1305 | atomic_sub(num_wrbs, &txq->used); | ||
1306 | |||
1307 | kfree_skb(sent_skb); | 1305 | kfree_skb(sent_skb); |
1306 | return num_wrbs; | ||
1308 | } | 1307 | } |
1309 | 1308 | ||
1310 | static inline struct be_eq_entry *event_get(struct be_eq_obj *eq_obj) | 1309 | static inline struct be_eq_entry *event_get(struct be_eq_obj *eq_obj) |
@@ -1387,7 +1386,7 @@ static void be_tx_compl_clean(struct be_adapter *adapter) | |||
1387 | struct be_queue_info *tx_cq = &adapter->tx_obj.cq; | 1386 | struct be_queue_info *tx_cq = &adapter->tx_obj.cq; |
1388 | struct be_queue_info *txq = &adapter->tx_obj.q; | 1387 | struct be_queue_info *txq = &adapter->tx_obj.q; |
1389 | struct be_eth_tx_compl *txcp; | 1388 | struct be_eth_tx_compl *txcp; |
1390 | u16 end_idx, cmpl = 0, timeo = 0; | 1389 | u16 end_idx, cmpl = 0, timeo = 0, num_wrbs = 0; |
1391 | struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list; | 1390 | struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list; |
1392 | struct sk_buff *sent_skb; | 1391 | struct sk_buff *sent_skb; |
1393 | bool dummy_wrb; | 1392 | bool dummy_wrb; |
@@ -1397,12 +1396,14 @@ static void be_tx_compl_clean(struct be_adapter *adapter) | |||
1397 | while ((txcp = be_tx_compl_get(tx_cq))) { | 1396 | while ((txcp = be_tx_compl_get(tx_cq))) { |
1398 | end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl, | 1397 | end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl, |
1399 | wrb_index, txcp); | 1398 | wrb_index, txcp); |
1400 | be_tx_compl_process(adapter, end_idx); | 1399 | num_wrbs += be_tx_compl_process(adapter, end_idx); |
1401 | cmpl++; | 1400 | cmpl++; |
1402 | } | 1401 | } |
1403 | if (cmpl) { | 1402 | if (cmpl) { |
1404 | be_cq_notify(adapter, tx_cq->id, false, cmpl); | 1403 | be_cq_notify(adapter, tx_cq->id, false, cmpl); |
1404 | atomic_sub(num_wrbs, &txq->used); | ||
1405 | cmpl = 0; | 1405 | cmpl = 0; |
1406 | num_wrbs = 0; | ||
1406 | } | 1407 | } |
1407 | 1408 | ||
1408 | if (atomic_read(&txq->used) == 0 || ++timeo > 200) | 1409 | if (atomic_read(&txq->used) == 0 || ++timeo > 200) |
@@ -1422,7 +1423,8 @@ static void be_tx_compl_clean(struct be_adapter *adapter) | |||
1422 | index_adv(&end_idx, | 1423 | index_adv(&end_idx, |
1423 | wrb_cnt_for_skb(adapter, sent_skb, &dummy_wrb) - 1, | 1424 | wrb_cnt_for_skb(adapter, sent_skb, &dummy_wrb) - 1, |
1424 | txq->len); | 1425 | txq->len); |
1425 | be_tx_compl_process(adapter, end_idx); | 1426 | num_wrbs = be_tx_compl_process(adapter, end_idx); |
1427 | atomic_sub(num_wrbs, &txq->used); | ||
1426 | } | 1428 | } |
1427 | } | 1429 | } |
1428 | 1430 | ||
@@ -1796,12 +1798,12 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget) | |||
1796 | struct be_queue_info *tx_cq = &adapter->tx_obj.cq; | 1798 | struct be_queue_info *tx_cq = &adapter->tx_obj.cq; |
1797 | struct be_eth_tx_compl *txcp; | 1799 | struct be_eth_tx_compl *txcp; |
1798 | int tx_compl = 0, mcc_compl, status = 0; | 1800 | int tx_compl = 0, mcc_compl, status = 0; |
1799 | u16 end_idx; | 1801 | u16 end_idx, num_wrbs = 0; |
1800 | 1802 | ||
1801 | while ((txcp = be_tx_compl_get(tx_cq))) { | 1803 | while ((txcp = be_tx_compl_get(tx_cq))) { |
1802 | end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl, | 1804 | end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl, |
1803 | wrb_index, txcp); | 1805 | wrb_index, txcp); |
1804 | be_tx_compl_process(adapter, end_idx); | 1806 | num_wrbs += be_tx_compl_process(adapter, end_idx); |
1805 | tx_compl++; | 1807 | tx_compl++; |
1806 | } | 1808 | } |
1807 | 1809 | ||
@@ -1817,6 +1819,8 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget) | |||
1817 | if (tx_compl) { | 1819 | if (tx_compl) { |
1818 | be_cq_notify(adapter, adapter->tx_obj.cq.id, true, tx_compl); | 1820 | be_cq_notify(adapter, adapter->tx_obj.cq.id, true, tx_compl); |
1819 | 1821 | ||
1822 | atomic_sub(num_wrbs, &txq->used); | ||
1823 | |||
1820 | /* As Tx wrbs have been freed up, wake up netdev queue if | 1824 | /* As Tx wrbs have been freed up, wake up netdev queue if |
1821 | * it was stopped due to lack of tx wrbs. | 1825 | * it was stopped due to lack of tx wrbs. |
1822 | */ | 1826 | */ |