summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMadalin Bucur <madalin.bucur@freescale.com>2013-07-19 17:01:59 (GMT)
committerFleming Andrew-AFLEMING <AFLEMING@freescale.com>2013-07-30 21:11:12 (GMT)
commit8a8f723b345b6fd7934ea960d69570c2e70f867a (patch)
tree0f8fafe8ebd712ba2aa79e2a37391d116f1ad038
parent086d3b61366bd341cd2532142111fed2e6f2161f (diff)
downloadlinux-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>
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth.c121
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth.h3
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c110
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_common.h9
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_macless.c4
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_proxy.c2
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c2
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_shared.c4
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;