summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorBogdan Hamciuc <bogdan.hamciuc@freescale.com>2013-12-04 17:34:35 (GMT)
committerMadalin-Cristian Bucur <madalin.bucur@freescale.com>2014-01-06 15:44:18 (GMT)
commit2533f4623c2cc615ae19fadd3cf9db5e587aadbf (patch)
tree2325c90ec2dedacbb7b46a35bd0f5b5378265839 /drivers
parent15d2b372325a024fc529662d2809f0962b654f19 (diff)
downloadlinux-fsl-qoriq-2533f4623c2cc615ae19fadd3cf9db5e587aadbf.tar.xz
dpaa_eth: Put Rx FQs in a new CGR
To avoid situations where we feed a high-speed ingress port with buffers allocated from lowmem only to have those frames piling up in the ingress queues and eventually depleting our memory, add a per-port CGR where every ingress FQ is placed. This CGR won't deliver congestion notifications to the FMan port, but instead will act as an aggregated counter for all the Rx FQs of the net device, tail-dropping excess traffic instead of enqueueing it in indefinitely long FQs. To avoid artificially dropping ingress frames, set the CGR's threshold to a very high value, which we'll fine-tune over test sessions. Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com> Reviewed-on: http://git.am.freescale.net:8181/7092 Reviewed-by: Cristian Bercaru <cristian.bercaru@freescale.com> Reviewed-by: Thomas Trefny <Tom.Trefny@freescale.com> Reviewed-by: Madalin-Cristian Bucur <madalin.bucur@freescale.com> Reviewed-by: Ruxandra Ioana Radulescu <ruxandra.radulescu@freescale.com> Tested-by: Richard Schmitt <B43082@freescale.com> Change-Id: If0eb43b83b6a91347288b6b5002563762f84943f Reviewed-on: http://git.am.freescale.net:8181/7354 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Jose Rivera <German.Rivera@freescale.com> Reviewed-on: http://git.am.freescale.net:8181/7687 Tested-by: Madalin-Cristian Bucur <madalin.bucur@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth.c50
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth.h2
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c16
3 files changed, 68 insertions, 0 deletions
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
index 4bcc302..c22dbf6 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
@@ -681,6 +681,51 @@ dpa_priv_bp_probe(struct device *dev)
return dpa_bp;
}
+/* Place all ingress FQs (Rx Default, Rx Error, PCD FQs) in a dedicated CGR.
+ * We won't be sending congestion notifications to FMan; for now, we just use
+ * this CGR to generate enqueue rejections to FMan in order to drop the frames
+ * before they reach our ingress queues and eat up memory.
+ */
+#define DPA_INGRESS_CS_THRESHOLD 0x10000000
+static int dpaa_eth_priv_ingress_cgr_init(struct dpa_priv_s *priv)
+{
+ struct qm_mcc_initcgr initcgr;
+ u32 cs_th;
+ int err;
+
+ err = qman_alloc_cgrid(&priv->ingress_cgr.cgrid);
+ if (err < 0) {
+ pr_err("Error %d allocating CGR ID\n", err);
+ goto out_error;
+ }
+
+ /* Enable CS TD, but disable Congestion State Change Notifications. */
+ initcgr.we_mask = QM_CGR_WE_CS_THRES;
+ initcgr.cgr.cscn_en = QM_CGR_EN;
+ cs_th = DPA_INGRESS_CS_THRESHOLD;
+ qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1);
+
+ initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
+ initcgr.cgr.cstd_en = QM_CGR_EN;
+
+ /* This is actually a hack, because this CGR will be associated with
+ * our affine SWP. However, we'll place our ingress FQs in it.
+ */
+ err = qman_create_cgr(&priv->ingress_cgr, QMAN_CGR_FLAG_USE_INIT,
+ &initcgr);
+ if (err < 0) {
+ pr_err("Error %d creating ingress CGR with ID %d\n", err,
+ priv->ingress_cgr.cgrid);
+ qman_release_cgrid(priv->ingress_cgr.cgrid);
+ goto out_error;
+ }
+ pr_debug("Created ingress CGR %d for netdev with hwaddr %pM\n",
+ priv->ingress_cgr.cgrid, priv->mac_dev->addr);
+
+out_error:
+ return err;
+}
+
static int dpa_priv_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
size_t count)
{
@@ -836,6 +881,11 @@ dpaa_eth_priv_probe(struct platform_device *_of_dev)
dev_err(dev, "Error initializing CGR\n");
goto cgr_init_failed;
}
+ err = dpaa_eth_priv_ingress_cgr_init(priv);
+ if (err < 0) {
+ dev_err(dev, "Error initializing ingress CGR\n");
+ goto cgr_init_failed;
+ }
/* Add the FQs to the interface, and make them active */
list_for_each_entry_safe(dpa_fq, tmp, &priv->dpa_fq_list, list) {
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpa/dpaa_eth.h
index 9d50347..88aa4d8 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.h
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.h
@@ -395,6 +395,8 @@ struct dpa_priv_s {
*/
u32 cgr_congested_count;
} cgr_data;
+ /* Use a per-port CGR for ingress traffic. */
+ struct qman_cgr ingress_cgr;
#ifdef CONFIG_FSL_DPAA_TS
bool ts_tx_en; /* Tx timestamping enabled */
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c
index d2adcbf..3e6e8d4 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c
@@ -1302,6 +1302,22 @@ int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable)
}
#endif
+ /* Put all ingress queues in our "ingress CGR". */
+ if (dpa_fq->fq_type == FQ_TYPE_RX_DEFAULT ||
+ dpa_fq->fq_type == FQ_TYPE_RX_ERROR ||
+ dpa_fq->fq_type == FQ_TYPE_RX_PCD) {
+ initfq.we_mask |= QM_INITFQ_WE_CGID;
+ initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE;
+ initfq.fqd.cgid = priv->ingress_cgr.cgrid;
+ /* Set a fixed overhead accounting, just like for the
+ * egress CGR.
+ */
+ initfq.we_mask |= QM_INITFQ_WE_OAC;
+ initfq.fqd.oac_init.oac = QM_OAC_CG;
+ initfq.fqd.oac_init.oal = min(sizeof(struct sk_buff) +
+ priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL);
+ }
+
/* Initialization common to all ingress queues */
if (dpa_fq->flags & QMAN_FQ_FLAG_NO_ENQUEUE) {
initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;