aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/marvell/mvpp2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/marvell/mvpp2.c')
-rw-r--r--drivers/net/ethernet/marvell/mvpp2.c52
1 files changed, 33 insertions, 19 deletions
diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index d9884fd15b45..a4beccf1fd46 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -3413,16 +3413,23 @@ static void mvpp2_bm_pool_bufsize_set(struct mvpp2 *priv,
3413} 3413}
3414 3414
3415/* Free all buffers from the pool */ 3415/* Free all buffers from the pool */
3416static void mvpp2_bm_bufs_free(struct mvpp2 *priv, struct mvpp2_bm_pool *bm_pool) 3416static void mvpp2_bm_bufs_free(struct device *dev, struct mvpp2 *priv,
3417 struct mvpp2_bm_pool *bm_pool)
3417{ 3418{
3418 int i; 3419 int i;
3419 3420
3420 for (i = 0; i < bm_pool->buf_num; i++) { 3421 for (i = 0; i < bm_pool->buf_num; i++) {
3422 dma_addr_t buf_phys_addr;
3421 u32 vaddr; 3423 u32 vaddr;
3422 3424
3423 /* Get buffer virtual address (indirect access) */ 3425 /* Get buffer virtual address (indirect access) */
3424 mvpp2_read(priv, MVPP2_BM_PHY_ALLOC_REG(bm_pool->id)); 3426 buf_phys_addr = mvpp2_read(priv,
3427 MVPP2_BM_PHY_ALLOC_REG(bm_pool->id));
3425 vaddr = mvpp2_read(priv, MVPP2_BM_VIRT_ALLOC_REG); 3428 vaddr = mvpp2_read(priv, MVPP2_BM_VIRT_ALLOC_REG);
3429
3430 dma_unmap_single(dev, buf_phys_addr,
3431 bm_pool->buf_size, DMA_FROM_DEVICE);
3432
3426 if (!vaddr) 3433 if (!vaddr)
3427 break; 3434 break;
3428 dev_kfree_skb_any((struct sk_buff *)vaddr); 3435 dev_kfree_skb_any((struct sk_buff *)vaddr);
@@ -3439,7 +3446,7 @@ static int mvpp2_bm_pool_destroy(struct platform_device *pdev,
3439{ 3446{
3440 u32 val; 3447 u32 val;
3441 3448
3442 mvpp2_bm_bufs_free(priv, bm_pool); 3449 mvpp2_bm_bufs_free(&pdev->dev, priv, bm_pool);
3443 if (bm_pool->buf_num) { 3450 if (bm_pool->buf_num) {
3444 WARN(1, "cannot free all buffers in pool %d\n", bm_pool->id); 3451 WARN(1, "cannot free all buffers in pool %d\n", bm_pool->id);
3445 return 0; 3452 return 0;
@@ -3692,7 +3699,8 @@ mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, enum mvpp2_bm_type type,
3692 MVPP2_BM_LONG_BUF_NUM : 3699 MVPP2_BM_LONG_BUF_NUM :
3693 MVPP2_BM_SHORT_BUF_NUM; 3700 MVPP2_BM_SHORT_BUF_NUM;
3694 else 3701 else
3695 mvpp2_bm_bufs_free(port->priv, new_pool); 3702 mvpp2_bm_bufs_free(port->dev->dev.parent,
3703 port->priv, new_pool);
3696 3704
3697 new_pool->pkt_size = pkt_size; 3705 new_pool->pkt_size = pkt_size;
3698 3706
@@ -3756,7 +3764,7 @@ static int mvpp2_bm_update_mtu(struct net_device *dev, int mtu)
3756 int pkt_size = MVPP2_RX_PKT_SIZE(mtu); 3764 int pkt_size = MVPP2_RX_PKT_SIZE(mtu);
3757 3765
3758 /* Update BM pool with new buffer size */ 3766 /* Update BM pool with new buffer size */
3759 mvpp2_bm_bufs_free(port->priv, port_pool); 3767 mvpp2_bm_bufs_free(dev->dev.parent, port->priv, port_pool);
3760 if (port_pool->buf_num) { 3768 if (port_pool->buf_num) {
3761 WARN(1, "cannot free all buffers in pool %d\n", port_pool->id); 3769 WARN(1, "cannot free all buffers in pool %d\n", port_pool->id);
3762 return -EIO; 3770 return -EIO;
@@ -4401,11 +4409,10 @@ static void mvpp2_txq_bufs_free(struct mvpp2_port *port,
4401 4409
4402 mvpp2_txq_inc_get(txq_pcpu); 4410 mvpp2_txq_inc_get(txq_pcpu);
4403 4411
4404 if (!skb)
4405 continue;
4406
4407 dma_unmap_single(port->dev->dev.parent, buf_phys_addr, 4412 dma_unmap_single(port->dev->dev.parent, buf_phys_addr,
4408 skb_headlen(skb), DMA_TO_DEVICE); 4413 skb_headlen(skb), DMA_TO_DEVICE);
4414 if (!skb)
4415 continue;
4409 dev_kfree_skb_any(skb); 4416 dev_kfree_skb_any(skb);
4410 } 4417 }
4411} 4418}
@@ -5092,7 +5099,8 @@ static int mvpp2_rx(struct mvpp2_port *port, int rx_todo,
5092 struct mvpp2_rx_queue *rxq) 5099 struct mvpp2_rx_queue *rxq)
5093{ 5100{
5094 struct net_device *dev = port->dev; 5101 struct net_device *dev = port->dev;
5095 int rx_received, rx_filled, i; 5102 int rx_received;
5103 int rx_done = 0;
5096 u32 rcvd_pkts = 0; 5104 u32 rcvd_pkts = 0;
5097 u32 rcvd_bytes = 0; 5105 u32 rcvd_bytes = 0;
5098 5106
@@ -5101,17 +5109,18 @@ static int mvpp2_rx(struct mvpp2_port *port, int rx_todo,
5101 if (rx_todo > rx_received) 5109 if (rx_todo > rx_received)
5102 rx_todo = rx_received; 5110 rx_todo = rx_received;
5103 5111
5104 rx_filled = 0; 5112 while (rx_done < rx_todo) {
5105 for (i = 0; i < rx_todo; i++) {
5106 struct mvpp2_rx_desc *rx_desc = mvpp2_rxq_next_desc_get(rxq); 5113 struct mvpp2_rx_desc *rx_desc = mvpp2_rxq_next_desc_get(rxq);
5107 struct mvpp2_bm_pool *bm_pool; 5114 struct mvpp2_bm_pool *bm_pool;
5108 struct sk_buff *skb; 5115 struct sk_buff *skb;
5116 dma_addr_t phys_addr;
5109 u32 bm, rx_status; 5117 u32 bm, rx_status;
5110 int pool, rx_bytes, err; 5118 int pool, rx_bytes, err;
5111 5119
5112 rx_filled++; 5120 rx_done++;
5113 rx_status = rx_desc->status; 5121 rx_status = rx_desc->status;
5114 rx_bytes = rx_desc->data_size - MVPP2_MH_SIZE; 5122 rx_bytes = rx_desc->data_size - MVPP2_MH_SIZE;
5123 phys_addr = rx_desc->buf_phys_addr;
5115 5124
5116 bm = mvpp2_bm_cookie_build(rx_desc); 5125 bm = mvpp2_bm_cookie_build(rx_desc);
5117 pool = mvpp2_bm_cookie_pool_get(bm); 5126 pool = mvpp2_bm_cookie_pool_get(bm);
@@ -5128,8 +5137,10 @@ static int mvpp2_rx(struct mvpp2_port *port, int rx_todo,
5128 * comprised by the RX descriptor. 5137 * comprised by the RX descriptor.
5129 */ 5138 */
5130 if (rx_status & MVPP2_RXD_ERR_SUMMARY) { 5139 if (rx_status & MVPP2_RXD_ERR_SUMMARY) {
5140 err_drop_frame:
5131 dev->stats.rx_errors++; 5141 dev->stats.rx_errors++;
5132 mvpp2_rx_error(port, rx_desc); 5142 mvpp2_rx_error(port, rx_desc);
5143 /* Return the buffer to the pool */
5133 mvpp2_pool_refill(port, bm, rx_desc->buf_phys_addr, 5144 mvpp2_pool_refill(port, bm, rx_desc->buf_phys_addr,
5134 rx_desc->buf_cookie); 5145 rx_desc->buf_cookie);
5135 continue; 5146 continue;
@@ -5137,6 +5148,15 @@ static int mvpp2_rx(struct mvpp2_port *port, int rx_todo,
5137 5148
5138 skb = (struct sk_buff *)rx_desc->buf_cookie; 5149 skb = (struct sk_buff *)rx_desc->buf_cookie;
5139 5150
5151 err = mvpp2_rx_refill(port, bm_pool, bm, 0);
5152 if (err) {
5153 netdev_err(port->dev, "failed to refill BM pools\n");
5154 goto err_drop_frame;
5155 }
5156
5157 dma_unmap_single(dev->dev.parent, phys_addr,
5158 bm_pool->buf_size, DMA_FROM_DEVICE);
5159
5140 rcvd_pkts++; 5160 rcvd_pkts++;
5141 rcvd_bytes += rx_bytes; 5161 rcvd_bytes += rx_bytes;
5142 atomic_inc(&bm_pool->in_use); 5162 atomic_inc(&bm_pool->in_use);
@@ -5147,12 +5167,6 @@ static int mvpp2_rx(struct mvpp2_port *port, int rx_todo,
5147 mvpp2_rx_csum(port, rx_status, skb); 5167 mvpp2_rx_csum(port, rx_status, skb);
5148 5168
5149 napi_gro_receive(&port->napi, skb); 5169 napi_gro_receive(&port->napi, skb);
5150
5151 err = mvpp2_rx_refill(port, bm_pool, bm, 0);
5152 if (err) {
5153 netdev_err(port->dev, "failed to refill BM pools\n");
5154 rx_filled--;
5155 }
5156 } 5170 }
5157 5171
5158 if (rcvd_pkts) { 5172 if (rcvd_pkts) {
@@ -5166,7 +5180,7 @@ static int mvpp2_rx(struct mvpp2_port *port, int rx_todo,
5166 5180
5167 /* Update Rx queue management counters */ 5181 /* Update Rx queue management counters */
5168 wmb(); 5182 wmb();
5169 mvpp2_rxq_status_update(port, rxq->id, rx_todo, rx_filled); 5183 mvpp2_rxq_status_update(port, rxq->id, rx_done, rx_done);
5170 5184
5171 return rx_todo; 5185 return rx_todo;
5172} 5186}