diff options
author | Madalin Bucur <madalin.bucur@freescale.com> | 2013-07-30 12:01:07 (GMT) |
---|---|---|
committer | Fleming Andrew-AFLEMING <AFLEMING@freescale.com> | 2013-07-31 21:49:59 (GMT) |
commit | 5548c02ece5c03a42aa2571848c61060401c2826 (patch) | |
tree | 904224d2ecbf9d3fee905d1650084e5e2306c327 /drivers/net | |
parent | a3a292cd90c05ead376bdaa460629e7da5ee8552 (diff) | |
download | linux-fsl-qoriq-5548c02ece5c03a42aa2571848c61060401c2826.tar.xz |
dpaa_eth: add drain and seed callbacks for dpa_bp
Add callbacks for seeding and draining the bpools.
Signed-off-by: Madalin Bucur <madalin.bucur@freescale.com>
Change-Id: Ib6e2e0c6d6b8ea9187c0d90b5ab4af4c54f344a4
Reviewed-on: http://git.am.freescale.net:8181/3657
Reviewed-by: Hamciuc Bogdan-BHAMCIU1 <bogdan.hamciuc@freescale.com>
Reviewed-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
Tested-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
Diffstat (limited to 'drivers/net')
6 files changed, 63 insertions, 53 deletions
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c index e9d3575..845d392 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c @@ -647,7 +647,7 @@ dpa_priv_bp_probe(struct device *dev) dpa_bp->percpu_count = alloc_percpu(*dpa_bp->percpu_count); dpa_bp->target_count = CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT; - dpa_bp->requires_draining = true; + dpa_bp->drain_cb = dpa_bp_drain; return dpa_bp; } diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpa/dpaa_eth.h index d19991b..987c3b9 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.h +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.h @@ -361,11 +361,13 @@ struct dpa_bp { * the buffers */ void *vaddr; - /* some bpools need to be emptied before freeing */ - bool requires_draining; /* current number of buffers in the bpool alloted to this CPU */ int *percpu_count; atomic_t refs; + /* some bpools need to be seeded before use by this cb */ + int (*seed_cb)(struct dpa_bp *); + /* some bpools need to be emptied before freeing by this cb */ + void (*drain_cb)(struct dpa_bp *); }; struct dpa_rx_errors { diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c index bd78b58..c635695 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c @@ -744,8 +744,6 @@ dpa_bp_probe(struct platform_device *_of_dev, size_t *count) } } - dpa_bp->requires_draining = false; - sort(dpa_bp, *count, sizeof(*dpa_bp), dpa_bp_cmp, NULL); return dpa_bp; @@ -757,29 +755,7 @@ _return_of_node_put: return dpa_bp; } -static void dpaa_eth_seed_pool(struct dpa_bp *bp) -{ - int count = bp->target_count; - size_t addr = bp->paddr; - - while (count) { - struct bm_buffer bufs[8]; - int num_bufs = 0; - - do { - BUG_ON(addr > 0xffffffffffffull); - bufs[num_bufs].bpid = bp->bpid; - bm_buffer_set64(&bufs[num_bufs++], addr); - addr += bp->size; - - } while (--count && (num_bufs < 8)); - - while (bman_release(bp->pool, bufs, num_bufs, 0)) - cpu_relax(); - } -} - -static int dpa_make_shared_port_pool(struct dpa_bp *bp) +int dpa_bp_shared_port_seed(struct dpa_bp *bp) { /* In MAC-less and Shared-MAC scenarios the physical * address of the buffer pool in device tree is set @@ -789,6 +765,7 @@ static int dpa_make_shared_port_pool(struct dpa_bp *bp) if (!bp->paddr) return 0; + /* allocate memory region for buffers */ devm_request_mem_region(bp->dev, bp->paddr, bp->size * bp->config_count, KBUILD_MODNAME); bp->vaddr = devm_ioremap_prot(bp->dev, bp->paddr, @@ -798,8 +775,27 @@ static int dpa_make_shared_port_pool(struct dpa_bp *bp) return -EIO; } - if (bp->seed_pool) - dpaa_eth_seed_pool(bp); + /* seed pool with buffers from that memory region */ + if (bp->seed_pool) { + int count = bp->target_count; + size_t addr = bp->paddr; + + while (count) { + struct bm_buffer bufs[8]; + int num_bufs = 0; + + do { + BUG_ON(addr > 0xffffffffffffull); + bufs[num_bufs].bpid = bp->bpid; + bm_buffer_set64(&bufs[num_bufs++], addr); + addr += bp->size; + + } while (--count && (num_bufs < 8)); + + while (bman_release(bp->pool, bufs, num_bufs, 0)) + cpu_relax(); + } + } return 0; } @@ -846,15 +842,17 @@ dpa_bp_alloc(struct dpa_bp *dpa_bp) dpa_bp->dev = &pdev->dev; - err = dpa_make_shared_port_pool(dpa_bp); - if (err) - goto make_shared_pool_failed; + if (dpa_bp->seed_cb) { + err = dpa_bp->seed_cb(dpa_bp); + if (err) + goto pool_seed_failed; + } dpa_bpid2pool_map(dpa_bp->bpid, dpa_bp); return 0; -make_shared_pool_failed: +pool_seed_failed: pdev_mask_failed: platform_device_unregister(pdev); pdev_register_failed: @@ -885,33 +883,37 @@ int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp, return 0; } -static void __cold __attribute__((nonnull)) -_dpa_bp_free(struct dpa_bp *dpa_bp) +void dpa_bp_drain(struct dpa_bp *bp) { - struct dpa_bp *bp = dpa_bpid2pool(dpa_bp->bpid); + int num; - if (!atomic_dec_and_test(&bp->refs)) - return; + do { + struct bm_buffer bmb[8]; + int i; - if (bp->requires_draining) { - int num; + num = bman_acquire(bp->pool, bmb, 8, 0); - do { - struct bm_buffer bmb[8]; - int i; + for (i = 0; i < num; i++) { + dma_addr_t addr = bm_buf_addr(&bmb[i]); - num = bman_acquire(bp->pool, bmb, 8, 0); + dma_unmap_single(bp->dev, addr, bp->size, + DMA_BIDIRECTIONAL); + + _dpa_bp_free_buf(phys_to_virt(addr)); + } + } while (num == 8); +} - for (i = 0; i < num; i++) { - dma_addr_t addr = bm_buf_addr(&bmb[i]); +static void __cold __attribute__((nonnull)) +_dpa_bp_free(struct dpa_bp *dpa_bp) +{ + struct dpa_bp *bp = dpa_bpid2pool(dpa_bp->bpid); - dma_unmap_single(bp->dev, addr, bp->size, - DMA_BIDIRECTIONAL); + if (!atomic_dec_and_test(&bp->refs)) + return; - _dpa_bp_free_buf(phys_to_virt(addr)); - } - } while (num == 8); - } + if (bp->drain_cb) + bp->drain_cb(bp); dpa_bp_array[bp->bpid] = 0; bman_free_pool(bp->pool); diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.h b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.h index 9c9fe3b..524fe40 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.h +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.h @@ -88,11 +88,13 @@ struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */ dpa_bp_probe(struct platform_device *_of_dev, size_t *count); int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp, size_t count); +int dpa_bp_shared_port_seed(struct dpa_bp *bp); void __cold __attribute__((nonnull)) dpa_bp_free(struct dpa_priv_s *priv, struct dpa_bp *dpa_bp); struct dpa_bp *dpa_bpid2pool(int bpid); void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp); bool dpa_bpid2pool_use(int bpid); +void dpa_bp_drain(struct dpa_bp *bp); #ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb); #endif diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_macless.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_macless.c index 7f09ade..3dc845e 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_macless.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_macless.c @@ -249,6 +249,8 @@ static int dpaa_eth_macless_probe(struct platform_device *_of_dev) if (IS_ERR(dpa_bp)) return PTR_ERR(dpa_bp); + dpa_bp->seed_cb = dpa_bp_shared_port_seed; + /* Allocate this early, so we can store relevant information in * the private area (needed by 1588 code in dpa_mac_probe) */ diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_shared.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_shared.c index 0cf48dc..c0b9cf2 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_shared.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_shared.c @@ -578,6 +578,8 @@ dpaa_eth_shared_probe(struct platform_device *_of_dev) if (IS_ERR(dpa_bp)) return PTR_ERR(dpa_bp); + dpa_bp->seed_cb = dpa_bp_shared_port_seed; + /* Allocate this early, so we can store relevant information in * the private area (needed by 1588 code in dpa_mac_probe) */ |