diff options
Diffstat (limited to 'drivers/net/ethernet/marvell/mvpp2.c')
-rw-r--r-- | drivers/net/ethernet/marvell/mvpp2.c | 52 |
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 */ |
3416 | static void mvpp2_bm_bufs_free(struct mvpp2 *priv, struct mvpp2_bm_pool *bm_pool) | 3416 | static 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 | } |