diff options
author | Marian Rotariu <marian.rotariu@freescale.com> | 2014-05-13 08:36:46 (GMT) |
---|---|---|
committer | Jose Rivera <German.Rivera@freescale.com> | 2014-05-14 14:02:36 (GMT) |
commit | 8d5cd1658cb0c97d5429124f9fb5caa88c460186 (patch) | |
tree | 4e2a8707c2c1a419d6f265571ac6f29035963b99 /drivers/net/ethernet/freescale | |
parent | b39bbe241c500b286f1b34f1ac2937d35175d178 (diff) | |
download | linux-fsl-qoriq-8d5cd1658cb0c97d5429124f9fb5caa88c460186.tar.xz |
onic: disable buffer deallocation
In some complex scenarios, VSP cannot be enabled on Tx O/H port. To support
these scenarios, a new attribute was added to onic dts node.
The user should guarantee that other hw modules will release the buffers into
onic draining pool, otherwise the system will leak memory.
Signed-off-by: Marian Rotariu <marian.rotariu@freescale.com>
Signed-off-by: Ioana Tibuleac <ioana.tibuleac@freescale.com>
Change-Id: Ieb6d1c9cc7d165ad71165a58bd2dbd7b46a70dbc
Reviewed-on: http://git.am.freescale.net:8181/12332
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Radu-Andrei Bulie <Radu.Bulie@freescale.com>
Reviewed-by: Jose Rivera <German.Rivera@freescale.com>
Diffstat (limited to 'drivers/net/ethernet/freescale')
-rw-r--r-- | drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.c | 31 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.h | 5 |
2 files changed, 32 insertions, 4 deletions
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.c index 534b283..b31f5f1 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.c @@ -1035,6 +1035,22 @@ int dpa_generic_tx_bp_probe(struct platform_device *_of_dev, return 0; } +int dpa_generic_buff_dealloc_probe(struct platform_device *_of_dev, + int *disable_buff_dealloc) +{ + struct device *dev = &_of_dev->dev; + const phandle *disable_handle = NULL; + int lenp = 0; + int err = 0; + + disable_handle = of_get_property(dev->of_node, + "fsl,disable_buff_dealloc", &lenp); + if (disable_handle != NULL) + *disable_buff_dealloc = 1; + + return err; +} + int dpa_generic_port_probe(struct platform_device *_of_dev, struct fm_port **rx_port, struct fm_port **tx_port) @@ -1167,7 +1183,7 @@ static void dpa_generic_fq_setup(struct dpa_generic_priv_s *priv, } } -static int dpa_generic_fq_init(struct dpa_fq *dpa_fq, bool td_enable) +static int dpa_generic_fq_init(struct dpa_fq *dpa_fq, int disable_buff_dealloc) { int _errno; struct device *dev; @@ -1199,7 +1215,7 @@ static int dpa_generic_fq_init(struct dpa_fq *dpa_fq, bool td_enable) initfq.fqd.dest.channel = dpa_fq->channel; initfq.fqd.dest.wq = dpa_fq->wq; - if (dpa_fq->fq_type == FQ_TYPE_TX) { + if (dpa_fq->fq_type == FQ_TYPE_TX && !disable_buff_dealloc) { initfq.we_mask |= QM_INITFQ_WE_CONTEXTA; /* ContextA: A2V=1 (contextA A2 field is valid) * ContextA A2: EBD=1 (deallocate buffers inside FMan) @@ -1268,7 +1284,7 @@ static int dpa_generic_fq_create(struct net_device *netdev, /* Add the FQs to the interface, and make them active */ list_for_each_entry_safe(fqs, tmp, &priv->dpa_fq_list, list) { - err = dpa_generic_fq_init(fqs, false); + err = dpa_generic_fq_init(fqs, priv->disable_buff_dealloc); if (err) return err; } @@ -1362,6 +1378,7 @@ static int dpa_generic_eth_probe(struct platform_device *_of_dev) struct fm_port *tx_port = NULL; struct dpa_percpu_priv_s *percpu_priv; int rx_bp_count = 0; + int disable_buff_dealloc = 0; struct dpa_bp *rx_bp = NULL, *draining_tx_bp = NULL; struct dpa_buffer_layout_s *rx_buf_layout = NULL, *tx_buf_layout = NULL; struct list_head *dpa_fq_list; @@ -1390,6 +1407,10 @@ static int dpa_generic_eth_probe(struct platform_device *_of_dev) if (IS_ERR(dpa_fq_list)) return PTR_ERR(dpa_fq_list); + err = dpa_generic_buff_dealloc_probe(_of_dev, &disable_buff_dealloc); + if (err < 0) + return err; + /* just one queue for now */ netdev = alloc_etherdev_mq(sizeof(*priv), 1); if (!netdev) { @@ -1410,6 +1431,8 @@ static int dpa_generic_eth_probe(struct platform_device *_of_dev) if (err < 0) goto bp_create_failed; + priv->disable_buff_dealloc = disable_buff_dealloc; + err = dpa_generic_fq_create(netdev, dpa_fq_list, rx_port); if (err < 0) goto fq_create_failed; @@ -1420,6 +1443,7 @@ static int dpa_generic_eth_probe(struct platform_device *_of_dev) priv->tx_port = tx_port; priv->mac_dev = NULL; + priv->percpu_priv = alloc_percpu(*priv->percpu_priv); if (priv->percpu_priv == NULL) { dev_err(dev, "alloc_percpu() failed\n"); @@ -1436,7 +1460,6 @@ static int dpa_generic_eth_probe(struct platform_device *_of_dev) if (err < 0) goto napi_add_failed; - err = dpa_generic_netdev_init(dpa_node, netdev); if (err < 0) goto netdev_init_failed; diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.h b/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.h index b3a19f1..3a4e28d 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.h +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.h @@ -54,6 +54,11 @@ struct dpa_generic_priv_s { uint16_t tx_headroom; uint16_t rx_headroom; + /* In some scenarios, when VSP are not enabled on the Tx O/H port, + * the buffers will be released by other hardware modules + */ + int disable_buff_dealloc; + struct qman_fq *egress_fqs[DPAA_ETH_TX_QUEUES]; struct fm_port *rx_port; |