diff options
author | Marian Rotariu <marian.rotariu@freescale.com> | 2014-08-14 12:28:44 (GMT) |
---|---|---|
committer | Rich Schmitt <B43082@freescale.com> | 2014-09-05 17:32:33 (GMT) |
commit | 4d368f8399162885f5255f62f04a7d2959bec034 (patch) | |
tree | 3b91d726803a0899f6c3e6dd6adc79f9b6b295ca /drivers | |
parent | 455191e68d54c189ee6ec0821ff9b44f8ee0500d (diff) | |
download | linux-fsl-qoriq-4d368f8399162885f5255f62f04a7d2959bec034.tar.xz |
dpaa_eth: merge recycle and confirmation queues
In FMan v3, special transmission queues, called recycle queues, were created
because it was believed that the FCO flag from the FD is not enough to
differentiate between frames that are recyclable and those who are not. The
frame queue flags were used to signal the BMI to release the buffers back to
the default buffer pool.
The last findings and FMan improvements permit recycling activation only by
using FD fields. With this patch, the recycling frame queues are not needed
anymore.
This patch also removes the code dependency on the FMan version and improves
TCP traffic in forwarding scenarios due to single transmission queues, reducing
the out-of-order segments.
Signed-off-by: Marian Rotariu <marian.rotariu@freescale.com>
Change-Id: Idd4fea4ef7883563df67cf21dea9e87435b2dee8
Reviewed-on: http://git.am.freescale.net:8181/16872
Reviewed-by: Madalin-Cristian Bucur <madalin.bucur@freescale.com>
Tested-by: Madalin-Cristian Bucur <madalin.bucur@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/freescale/dpa/dpaa_eth.h | 36 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c | 68 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c | 14 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/dpa/dpaa_eth_sysfs.c | 5 |
4 files changed, 32 insertions, 91 deletions
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpa/dpaa_eth.h index ca5ad85..9187e84 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.h +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.h @@ -215,9 +215,6 @@ enum dpa_fq_type { FQ_TYPE_TX_CONFIRM, /* Tx default Conf FQ (actually an Rx FQ) */ FQ_TYPE_TX_CONF_MQ, /* Tx conf FQs (one for each Tx FQ) */ FQ_TYPE_TX_ERROR, /* Tx Error FQs (these are actually Rx FQs) */ -#ifdef CONFIG_FMAN_T4240 - FQ_TYPE_TX_RECYCLE, /* Tx FQs for recycleable frames only */ -#endif }; struct dpa_fq { @@ -336,9 +333,6 @@ struct dpa_priv_s { uint16_t channel; /* "fsl,qman-channel-id" */ struct list_head dpa_fq_list; -#ifdef CONFIG_FMAN_T4240 - struct qman_fq *recycle_fqs[DPAA_ETH_TX_QUEUES]; -#endif #ifdef CONFIG_FSL_DPAA_ETH_DEBUGFS struct dentry *debugfs_file; @@ -526,6 +520,19 @@ static inline void clear_fd(struct qm_fd *fd) fd->cmd = 0; } +static inline struct qman_fq *_dpa_get_tx_conf_queue( + const struct dpa_priv_s *priv, + struct qman_fq *tx_fq) +{ + int i; + + for (i = 0; i < DPAA_ETH_TX_QUEUES; i++) + if (priv->egress_fqs[i] == tx_fq) + return priv->conf_fqs[i]; + + return NULL; +} + static inline int __hot dpa_xmit(struct dpa_priv_s *priv, struct rtnl_link_stats64 *percpu_stats, int queue, struct qm_fd *fd) @@ -533,17 +540,11 @@ static inline int __hot dpa_xmit(struct dpa_priv_s *priv, int err, i; struct qman_fq *egress_fq; -#ifdef CONFIG_FMAN_T4240 - /* Choose egress fq based on whether we want - * to recycle the frame or not - */ - if (fd->cmd & FM_FD_CMD_FCO) - egress_fq = priv->recycle_fqs[queue]; - else - egress_fq = priv->egress_fqs[queue]; -#else egress_fq = priv->egress_fqs[queue]; -#endif + if (fd->bpid == 0xff) + fd->cmd |= qman_fq_fqid( + _dpa_get_tx_conf_queue(priv, egress_fq) + ); /* Trace this Tx fd */ trace_dpa_tx_fd(priv->net_dev, egress_fq, fd); @@ -587,9 +588,6 @@ static inline void _dpa_assign_wq(struct dpa_fq *fq) break; case FQ_TYPE_RX_DEFAULT: case FQ_TYPE_TX: -#ifdef CONFIG_FMAN_T4240 - case FQ_TYPE_TX_RECYCLE: -#endif case FQ_TYPE_RX_PCD: fq->wq = 3; break; diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c index 5a899b7..57b488a 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c @@ -69,12 +69,6 @@ static const struct fqid_cell tx_confirm_fqids[] = { {0, DPAA_ETH_TX_QUEUES} }; -#ifdef CONFIG_FMAN_T4240 -static const struct fqid_cell tx_recycle_fqids[] = { - {0, DPAA_ETH_TX_QUEUES} -}; -#endif - static const struct fqid_cell default_fqids[][3] = { [RX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_RX_QUEUES} }, [TX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_TX_QUEUES} } @@ -892,13 +886,6 @@ int dpa_fq_probe_mac(struct device *dev, struct list_head *list, if (!dpa_fq_alloc(dev, tx_confirm_fqids, list, FQ_TYPE_TX_CONF_MQ)) goto fq_alloc_failed; - -#ifdef CONFIG_FMAN_T4240 - /* per-core Tx queues for recyclable frames (FManv3 only) */ - if (!dpa_fq_alloc(dev, tx_recycle_fqids, list, - FQ_TYPE_TX_RECYCLE)) - goto fq_alloc_failed; -#endif } fqids = of_get_property(np, fsl_qman_frame_queues[ptype], &lenp); @@ -1105,9 +1092,6 @@ void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs, uint32_t pcd_fqid; const cpumask_t *affine_cpus = qman_affine_cpus(); int egress_cnt = 0, conf_cnt = 0; -#ifdef CONFIG_FMAN_T4240 - int recycle_cnt = 0; -#endif /* Prepare for PCD FQs init */ for_each_cpu(cpu, affine_cpus) @@ -1161,14 +1145,6 @@ void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs, BUG_ON(!priv->mac_dev); dpa_setup_ingress(priv, fq, &fq_cbs->tx_errq); break; -#ifdef CONFIG_FMAN_T4240 - case FQ_TYPE_TX_RECYCLE: - BUG_ON(!priv->mac_dev); - dpa_setup_egress(priv, fq, tx_port, - &fq_cbs->egress_ern); - priv->recycle_fqs[recycle_cnt++] = &fq->fq_base; - break; -#endif default: dev_warn(priv->net_dev->dev.parent, "Unknown FQ type detected!\n"); @@ -1192,18 +1168,6 @@ void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs, } } -static struct qman_fq *_dpa_get_tx_conf_queue(const struct dpa_priv_s *priv, - struct qman_fq *tx_fq) -{ - int i; - - for (i = 0; i < DPAA_ETH_TX_QUEUES; i++) - if (priv->egress_fqs[i] == tx_fq) - return priv->conf_fqs[i]; - - return NULL; -} - int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable) { int _errno; @@ -1286,34 +1250,16 @@ int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable) if (dpa_fq->fq_type == FQ_TYPE_TX) { confq = _dpa_get_tx_conf_queue(priv, &dpa_fq->fq_base); if (confq) { - initfq.we_mask |= QM_INITFQ_WE_CONTEXTA | - QM_INITFQ_WE_CONTEXTB; - /* CTXA[OVFQ] = 1 */ - initfq.fqd.context_a.hi = 0x80000000; - initfq.fqd.context_a.lo = 0x0; - initfq.fqd.context_b = qman_fq_fqid(confq); - } - } - -#ifdef CONFIG_FMAN_T4240 - /* Configure the Tx queues for recycled frames, such that the - * buffers are released by FMan and no confirmation is sent - */ - if (dpa_fq->fq_type == FQ_TYPE_TX_RECYCLE) { - initfq.we_mask |= QM_INITFQ_WE_CONTEXTA | - QM_INITFQ_WE_CONTEXTB; - /* ContextA: OVFQ=1 (use ContextB FQID for confirmation) - * OVOM=1 (use contextA2 bits instead of ICAD) - * A2V=1 (contextA A2 field is valid) - * B0V=1 (contextB field is valid) + initfq.we_mask |= QM_INITFQ_WE_CONTEXTA; + /* ContextA: OVOM=1 (use contextA2 bits instead of ICAD) + * A2V=1 (contextA A2 field is valid) + * A0V=1 (contextA A0 field is valid) * ContextA A2: EBD=1 (deallocate buffers inside FMan) - * ContextB: Confirmation FQID = 0 */ - initfq.fqd.context_a.hi = 0x96000000; - initfq.fqd.context_a.lo = 0x80000000; - initfq.fqd.context_b = 0; + initfq.fqd.context_a.hi = 0x1a000000; + initfq.fqd.context_a.lo = 0x80000000; + } } -#endif /* Put all *private* ingress queues in our "ingress CGR". */ if (priv->use_ingress_cgr && diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c index 2b49ab0..95eb17c 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c @@ -234,7 +234,6 @@ struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv, const enum dma_data_direction dma_dir = DMA_TO_DEVICE; int nr_frags; - DPA_BUG_ON(fd->cmd & FM_FD_CMD_FCO); dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, dma_dir); /* retrieve skb back pointer */ @@ -664,7 +663,6 @@ static int __hot skb_to_contig_fd(struct dpa_priv_s *priv, /* Buffer is recyclable; use the new start address * and set fd parameters and DMA mapping direction */ - fd->cmd |= FM_FD_CMD_FCO; fd->bpid = dpa_bp->bpid; DPA_BUG_ON(skb->data - buffer_start > DPA_MAX_FD_OFFSET); fd->offset = (uint16_t)(skb->data - buffer_start); @@ -679,6 +677,7 @@ static int __hot skb_to_contig_fd(struct dpa_priv_s *priv, * We are guaranteed to have at least tx_headroom bytes * available, so just use that for offset. */ + fd->bpid = 0xff; buffer_start = skb->data - priv->tx_headroom; fd->offset = priv->tx_headroom; dma_dir = DMA_TO_DEVICE; @@ -706,6 +705,7 @@ static int __hot skb_to_contig_fd(struct dpa_priv_s *priv, /* Fill in the rest of the FD fields */ fd->format = qm_fd_contig; fd->length20 = skb->len; + fd->cmd |= FM_FD_CMD_FCO; /* Map the entire buffer size that may be seen by FMan, but no more */ addr = dma_map_single(dpa_bp->dev, skbh, @@ -762,7 +762,7 @@ static int __hot skb_to_sg_fd(struct dpa_priv_s *priv, } sgt = (struct qm_sg_entry *)(sgt_buf + priv->tx_headroom); - sgt[0].bpid = dpa_bp->bpid; + sgt[0].bpid = 0xff; sgt[0].offset = 0; sgt[0].length = skb_headlen(skb); sgt[0].extension = 0; @@ -780,8 +780,7 @@ static int __hot skb_to_sg_fd(struct dpa_priv_s *priv, /* populate the rest of SGT entries */ for (i = 1; i <= nr_frags; i++) { frag = &skb_shinfo(skb)->frags[i - 1]; - sgt[i].bpid = dpa_bp->bpid; - + sgt[i].bpid = 0xff; sgt[i].offset = 0; sgt[i].length = frag->size; sgt[i].extension = 0; @@ -819,6 +818,9 @@ static int __hot skb_to_sg_fd(struct dpa_priv_s *priv, err = -EINVAL; goto sgt_map_failed; } + + fd->bpid = 0xff; + fd->cmd |= FM_FD_CMD_FCO; fd->addr_hi = upper_32_bits(addr); fd->addr_lo = lower_32_bits(addr); @@ -927,7 +929,7 @@ int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev) if (unlikely(err < 0)) goto skb_to_fd_failed; - if (fd.cmd & FM_FD_CMD_FCO) { + if (fd.bpid != 0xff) { skb_recycle(skb); /* skb_recycle() reserves NET_SKB_PAD as skb headroom, * but we need the skb to look as if returned by build_skb(). diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sysfs.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sysfs.c index bf01677..cd8b7d1 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sysfs.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sysfs.c @@ -102,11 +102,6 @@ static ssize_t dpaa_eth_show_fqids(struct device *dev, case FQ_TYPE_TX: str = "Tx"; break; -#ifdef CONFIG_FMAN_T4240 - case FQ_TYPE_TX_RECYCLE: - str = "Tx(recycling)"; - break; -#endif default: str = "Unknown"; } |