diff options
author | Madalin Bucur <madalin.bucur@freescale.com> | 2013-07-19 17:01:59 (GMT) |
---|---|---|
committer | Fleming Andrew-AFLEMING <AFLEMING@freescale.com> | 2013-07-30 21:11:12 (GMT) |
commit | 8a8f723b345b6fd7934ea960d69570c2e70f867a (patch) | |
tree | 0f8fafe8ebd712ba2aa79e2a37391d116f1ad038 /drivers/net | |
parent | 086d3b61366bd341cd2532142111fed2e6f2161f (diff) | |
download | linux-fsl-qoriq-8a8f723b345b6fd7934ea960d69570c2e70f867a.tar.xz |
dpaa_eth: bpool probing code separation
First changes in the series that will separate bpool initialization
for private and other drivers.
Signed-off-by: Madalin Bucur <madalin.bucur@freescale.com>
Change-Id: I96ff087f37c0dd7117d9aabc3cf3554bf2c35684
Reviewed-on: http://git.am.freescale.net:8181/3560
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Radulescu Ruxandra Ioana-B05472 <ruxandra.radulescu@freescale.com>
Reviewed-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
Diffstat (limited to 'drivers/net')
8 files changed, 168 insertions, 87 deletions
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c index 1c6bc39..6339de6 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c @@ -614,6 +614,117 @@ static int dpa_private_netdev_init(struct device_node *dpa_node, return dpa_netdev_init(dpa_node, net_dev, mac_addr, tx_timeout); } +static struct dpa_bp * __cold +dpa_priv_bp_probe(struct device *dev) +{ + struct dpa_bp *dpa_bp; + + dpa_bp = devm_kzalloc(dev, sizeof(*dpa_bp), GFP_KERNEL); + if (unlikely(dpa_bp == NULL)) { + dev_err(dev, "devm_kzalloc() failed\n"); + return ERR_PTR(-ENOMEM); + } + + dpa_bp->target_count = CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT; + dpa_bp->requires_draining = true; + + return dpa_bp; +} + +static int +dpa_priv_bp_alloc(struct dpa_bp *dpa_bp) +{ + int err; + struct bman_pool_params bp_params; + struct platform_device *pdev; + + BUG_ON(dpa_bp->size == 0); + BUG_ON(dpa_bp->config_count == 0); + + bp_params.flags = BMAN_POOL_FLAG_DEPLETION; + bp_params.cb = dpa_bp_depletion; + bp_params.cb_ctx = dpa_bp; + + if (default_pool) { + atomic_inc(&default_pool->refs); + return 0; + } + + /* If the pool is already specified, we only create one per bpid */ + if (dpa_bpid2pool_use(dpa_bp->bpid)) + return 0; + + if (dpa_bp->bpid == 0) + bp_params.flags |= BMAN_POOL_FLAG_DYNAMIC_BPID; + else + bp_params.bpid = dpa_bp->bpid; + + dpa_bp->pool = bman_new_pool(&bp_params); + if (unlikely(dpa_bp->pool == NULL)) { + pr_err("bman_new_pool() failed\n"); + return -ENODEV; + } + + dpa_bp->bpid = bman_get_params(dpa_bp->pool)->bpid; + + pdev = platform_device_register_simple("dpaa_eth_bpool", + dpa_bp->bpid, NULL, 0); + if (IS_ERR(pdev)) { + err = PTR_ERR(pdev); + goto pdev_register_failed; + } + + err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(40)); + if (err) + goto pdev_mask_failed; + + dpa_bp->dev = &pdev->dev; + + if (!default_pool) + default_pool = dpa_bp; + + dpa_bpid2pool_map(dpa_bp->bpid, dpa_bp); + + return 0; + +pdev_mask_failed: + platform_device_unregister(pdev); +pdev_register_failed: + bman_free_pool(dpa_bp->pool); + + return err; +} + +static int dpa_priv_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp, + size_t count) +{ + struct dpa_priv_s *priv = netdev_priv(net_dev); + int i; + + priv->shared = 0; + + if (netif_msg_probe(priv)) + dev_dbg(net_dev->dev.parent, + "Using private BM buffer pools\n"); + + priv->dpa_bp = dpa_bp; + priv->bp_count = count; + + for (i = 0; i < count; i++) { + int err; + err = dpa_priv_bp_alloc(&dpa_bp[i]); + if (err < 0) { + dpa_bp_free(priv, dpa_bp); + priv->dpa_bp = NULL; + return err; + } + + priv->dpa_bp = default_pool; + } + + return 0; +} + static const struct of_device_id dpa_match[]; static int @@ -624,7 +735,7 @@ dpaa_eth_priv_probe(struct platform_device *_of_dev) struct device_node *dpa_node; struct dpa_bp *dpa_bp; struct dpa_fq *dpa_fq, *tmp; - size_t count; + size_t count = 1; struct net_device *net_dev = NULL; struct dpa_priv_s *priv = NULL; struct dpa_percpu_priv_s *percpu_priv; @@ -640,8 +751,10 @@ dpaa_eth_priv_probe(struct platform_device *_of_dev) if (!of_device_is_available(dpa_node)) return -ENODEV; - /* Get the buffer pools assigned to this interface */ - dpa_bp = dpa_bp_probe(_of_dev, &count, default_pool); + /* Get the buffer pools assigned to this interface; + * run only once the default pool probing code + */ + dpa_bp = (default_pool) ? default_pool : dpa_priv_bp_probe(dev); if (IS_ERR(dpa_bp)) return PTR_ERR(dpa_bp); @@ -703,7 +816,7 @@ dpaa_eth_priv_probe(struct platform_device *_of_dev) /* bp init */ - err = dpa_bp_create(net_dev, dpa_bp, count, &default_pool); + err = dpa_priv_bp_create(net_dev, dpa_bp, count); if (err < 0) goto bp_create_failed; diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpa/dpaa_eth.h index d1304c1..43f325f 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.h +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.h @@ -361,7 +361,8 @@ struct dpa_bp { * the buffers */ void *vaddr; - int kernel_pool; + /* 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; diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c index 96b8290..5349476 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c @@ -687,8 +687,7 @@ static int dpa_bp_cmp(const void *dpa_bp0, const void *dpa_bp1) } struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */ -dpa_bp_probe(struct platform_device *_of_dev, size_t *count, - struct dpa_bp *default_pool) +dpa_bp_probe(struct platform_device *_of_dev, size_t *count) { int i, lenp, na, ns; struct device *dev; @@ -697,22 +696,12 @@ dpa_bp_probe(struct platform_device *_of_dev, size_t *count, const uint32_t *bpid; const uint32_t *bpool_cfg; struct dpa_bp *dpa_bp; - int has_kernel_pool = 0; - int has_shared_pool = 0; dev = &_of_dev->dev; /* The default is one, if there's no property */ *count = 1; - /* There are three types of buffer pool configuration: - * 1) No bp assignment - * 2) A static assignment to an empty configuration - * 3) A static assignment to one or more configured pools - * - * We don't support using multiple unconfigured pools. - */ - /* Get the buffer pools to be used */ phandle_prop = of_get_property(dev->of_node, "fsl,bman-buffer-pools", &lenp); @@ -720,10 +709,9 @@ dpa_bp_probe(struct platform_device *_of_dev, size_t *count, if (phandle_prop) *count = lenp / sizeof(phandle); else { - if (default_pool) - return default_pool; - - has_kernel_pool = 1; + dev_err(dev, + "missing fsl,bman-buffer-pools device tree entry\n"); + return ERR_PTR(-EINVAL); } dpa_bp = devm_kzalloc(dev, *count * sizeof(*dpa_bp), GFP_KERNEL); @@ -780,24 +768,16 @@ dpa_bp_probe(struct platform_device *_of_dev, size_t *count, "fsl,bpool-ethernet-seeds", &lenp); dpa_bp[i].seed_pool = !!seed_pool; - has_shared_pool = 1; } else { - has_kernel_pool = 1; + dev_err(dev, + "Missing/invalid fsl,bpool-ethernet-cfg device tree entry for node %s\n", + dev_node->full_name); + dpa_bp = ERR_PTR(-EINVAL); + goto _return_of_node_put; } - - if (i > 0) - has_shared_pool = 1; } - if (has_kernel_pool && has_shared_pool) { - dev_err(dev, "Invalid buffer pool configuration for node %s\n", - dev_node->full_name); - dpa_bp = ERR_PTR(-EINVAL); - goto _return_of_node_put; - } else if (has_kernel_pool) { - dpa_bp->target_count = CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT; - dpa_bp->kernel_pool = 1; - } + dpa_bp->requires_draining = false; sort(dpa_bp, *count, sizeof(*dpa_bp), dpa_bp_cmp, NULL); @@ -810,7 +790,7 @@ _return_of_node_put: return dpa_bp; } -static void dpa_bp_depletion(struct bman_portal *portal, +void dpa_bp_depletion(struct bman_portal *portal, struct bman_pool *pool, void *cb_ctx, int depleted) { if (net_ratelimit()) @@ -865,7 +845,7 @@ static int dpa_make_shared_port_pool(struct dpa_bp *bp) } static int __must_check /* __attribute__((nonnull)) */ -dpa_bp_alloc(struct dpa_bp *dpa_bp, struct dpa_bp **default_pool) +dpa_bp_alloc(struct dpa_bp *dpa_bp) { int err; struct bman_pool_params bp_params; @@ -878,19 +858,9 @@ dpa_bp_alloc(struct dpa_bp *dpa_bp, struct dpa_bp **default_pool) bp_params.cb = dpa_bp_depletion; bp_params.cb_ctx = dpa_bp; - /* We support two options. Either a global shared pool, or - * a specified pool. If the pool is specified, we only - * create one per bpid - */ - if (dpa_bp->kernel_pool && default_pool && *default_pool) { - atomic_inc(&(*default_pool)->refs); - return 0; - } - - if (dpa_bp_array[dpa_bp->bpid]) { - atomic_inc(&dpa_bp_array[dpa_bp->bpid]->refs); + /* If the pool is already specified, we only create one per bpid */ + if (dpa_bpid2pool_use(dpa_bp->bpid)) return 0; - } if (dpa_bp->bpid == 0) bp_params.flags |= BMAN_POOL_FLAG_DYNAMIC_BPID; @@ -918,18 +888,11 @@ dpa_bp_alloc(struct dpa_bp *dpa_bp, struct dpa_bp **default_pool) dpa_bp->dev = &pdev->dev; - if (dpa_bp->kernel_pool) { - if (default_pool && !*default_pool) - *default_pool = dpa_bp; - } else { - err = dpa_make_shared_port_pool(dpa_bp); - if (err) - goto make_shared_pool_failed; - } - - dpa_bp_array[dpa_bp->bpid] = dpa_bp; + err = dpa_make_shared_port_pool(dpa_bp); + if (err) + goto make_shared_pool_failed; - atomic_set(&dpa_bp->refs, 1); + dpa_bpid2pool_map(dpa_bp->bpid, dpa_bp); return 0; @@ -943,38 +906,24 @@ pdev_register_failed: } int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp, - size_t count, struct dpa_bp **default_pool) + size_t count) { struct dpa_priv_s *priv = netdev_priv(net_dev); int i; - if (dpa_bp->kernel_pool) { - priv->shared = 0; - - if (netif_msg_probe(priv)) - dev_info(net_dev->dev.parent, - "Using private BM buffer pools\n"); - } else { - priv->shared = 1; - } + priv->shared = 1; priv->dpa_bp = dpa_bp; priv->bp_count = count; for (i = 0; i < count; i++) { int err; - err = dpa_bp_alloc(&dpa_bp[i], default_pool); + err = dpa_bp_alloc(&dpa_bp[i]); if (err < 0) { dpa_bp_free(priv, dpa_bp); priv->dpa_bp = NULL; return err; } - - /* For now, just point to the default pool. - * We can add support for more pools, later - */ - if (dpa_bp->kernel_pool) - priv->dpa_bp = (default_pool) ? *default_pool : NULL; } return 0; @@ -988,7 +937,7 @@ _dpa_bp_free(struct dpa_bp *dpa_bp) if (!atomic_dec_and_test(&bp->refs)) return; - if (bp->kernel_pool) { + if (bp->requires_draining) { int num; do { @@ -1026,6 +975,21 @@ struct dpa_bp *dpa_bpid2pool(int bpid) return dpa_bp_array[bpid]; } +void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp) +{ + dpa_bp_array[bpid] = dpa_bp; + atomic_set(&dpa_bp->refs, 1); +} + +bool dpa_bpid2pool_use(int bpid) +{ + if (dpa_bpid2pool(bpid)) { + atomic_inc(&dpa_bp_array[bpid]->refs); + return true; + } + + return false; +} #ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb) diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.h b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.h index 2d156a7..c97501b 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.h +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.h @@ -86,13 +86,16 @@ void dpa_set_rx_mode(struct net_device *net_dev); void dpa_set_buffers_layout(struct mac_device *mac_dev, struct dpa_buffer_layout_s *layout); struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */ -dpa_bp_probe(struct platform_device *_of_dev, size_t *count, - struct dpa_bp *default_pool); +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, struct dpa_bp **default_pool); + size_t count); void __cold __attribute__((nonnull)) dpa_bp_free(struct dpa_priv_s *priv, struct dpa_bp *dpa_bp); +void dpa_bp_depletion(struct bman_portal *portal, + struct bman_pool *pool, void *cb_ctx, int depleted); struct dpa_bp *dpa_bpid2pool(int bpid); +void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp); +bool dpa_bpid2pool_use(int bpid); #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 604efda..4e0c35b 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_macless.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_macless.c @@ -245,7 +245,7 @@ static int dpaa_eth_macless_probe(struct platform_device *_of_dev) return -ENODEV; /* Get the buffer pools assigned to this interface */ - dpa_bp = dpa_bp_probe(_of_dev, &count, NULL); + dpa_bp = dpa_bp_probe(_of_dev, &count); if (IS_ERR(dpa_bp)) return PTR_ERR(dpa_bp); @@ -280,7 +280,7 @@ static int dpaa_eth_macless_probe(struct platform_device *_of_dev) /* bp init */ - err = dpa_bp_create(net_dev, dpa_bp, count, NULL); + err = dpa_bp_create(net_dev, dpa_bp, count); if (err < 0) goto bp_create_failed; diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_proxy.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_proxy.c index e881bd8..22a941a 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_proxy.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_proxy.c @@ -93,7 +93,7 @@ static int dpaa_eth_proxy_probe(struct platform_device *_of_dev) return -ENODEV; /* Get the buffer pools assigned to this interface */ - dpa_bp = dpa_bp_probe(_of_dev, &count, NULL); + dpa_bp = dpa_bp_probe(_of_dev, &count); if (IS_ERR(dpa_bp)) return PTR_ERR(dpa_bp); diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c index d5b52e1..4e4f2ac 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c @@ -138,7 +138,7 @@ void dpa_make_private_pool(struct dpa_bp *dpa_bp) dpa_bp->percpu_count = alloc_percpu(*dpa_bp->percpu_count); - /* Give each CPU an allotment of "page_count" buffers */ + /* Give each CPU an allotment of "config_count" buffers */ for_each_online_cpu(i) { int j; diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_shared.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_shared.c index 2f228b4..ea584ff 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_shared.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_shared.c @@ -574,7 +574,7 @@ dpaa_eth_shared_probe(struct platform_device *_of_dev) return -ENODEV; /* Get the buffer pools assigned to this interface */ - dpa_bp = dpa_bp_probe(_of_dev, &count, NULL); + dpa_bp = dpa_bp_probe(_of_dev, &count); if (IS_ERR(dpa_bp)) return PTR_ERR(dpa_bp); @@ -627,7 +627,7 @@ dpaa_eth_shared_probe(struct platform_device *_of_dev) /* bp init */ - err = dpa_bp_create(net_dev, dpa_bp, count, NULL); + err = dpa_bp_create(net_dev, dpa_bp, count); if (err < 0) goto bp_create_failed; |