summaryrefslogtreecommitdiff
path: root/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c')
-rw-r--r--drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c109
1 files changed, 90 insertions, 19 deletions
diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
index e4844ae..5523e58 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
@@ -2116,7 +2116,7 @@ static int setup_dpni(struct fsl_mc_device *ls_dev)
/* Enable flow control */
cfg.options = DPNI_LINK_OPT_AUTONEG | DPNI_LINK_OPT_PAUSE;
- priv->tx_pause_frames = 1;
+ priv->tx_pause_frames = true;
err = dpni_set_link_cfg(priv->mc_io, 0, priv->mc_token, &cfg);
if (err) {
@@ -2158,24 +2158,12 @@ static void free_dpni(struct dpaa2_eth_priv *priv)
kfree(priv->cscn_unaligned);
}
-int setup_fqs_taildrop(struct dpaa2_eth_priv *priv,
- bool enable)
+static int set_queue_taildrop(struct dpaa2_eth_priv *priv,
+ struct dpni_taildrop *td)
{
struct device *dev = priv->net_dev->dev.parent;
- struct dpni_taildrop td;
- int err = 0, i;
-
- td.enable = enable;
- td.threshold = DPAA2_ETH_TAILDROP_THRESH;
+ int err, i;
- if (enable) {
- priv->num_bufs = DPAA2_ETH_NUM_BUFS_TD;
- priv->refill_thresh = DPAA2_ETH_REFILL_THRESH_TD;
- } else {
- priv->num_bufs = DPAA2_ETH_NUM_BUFS_FC /
- priv->num_channels;
- priv->refill_thresh = priv->num_bufs - DPAA2_ETH_BUFS_PER_CMD;
- }
for (i = 0; i < priv->num_fqs; i++) {
if (priv->fq[i].type != DPAA2_RX_FQ)
@@ -2184,14 +2172,97 @@ int setup_fqs_taildrop(struct dpaa2_eth_priv *priv,
err = dpni_set_taildrop(priv->mc_io, 0, priv->mc_token,
DPNI_CP_QUEUE, DPNI_QUEUE_RX,
priv->fq[i].tc, priv->fq[i].flowid,
- &td);
+ td);
if (err) {
dev_err(dev, "dpni_set_taildrop() failed (%d)\n", err);
- break;
+ return err;
}
}
- return err;
+ return 0;
+}
+
+static int set_group_taildrop(struct dpaa2_eth_priv *priv,
+ struct dpni_taildrop *td)
+{
+ struct device *dev = priv->net_dev->dev.parent;
+ struct dpni_taildrop disable_td, *tc_td;
+ int i, err;
+
+ memset(&disable_td, 0, sizeof(struct dpni_taildrop));
+ for (i = 0; i < dpaa2_eth_tc_count(priv); i++) {
+ if (td->enable && dpaa2_eth_is_pfc_enabled(priv, i))
+ /* Do not set taildrop thresholds for PFC-enabled
+ * traffic classes. We will enable congestion
+ * notifications for them.
+ */
+ tc_td = &disable_td;
+ else
+ tc_td = td;
+
+ err = dpni_set_taildrop(priv->mc_io, 0, priv->mc_token,
+ DPNI_CP_GROUP, DPNI_QUEUE_RX,
+ i, 0, tc_td);
+ if (err) {
+ dev_err(dev, "dpni_set_taildrop() failed (%d)\n", err);
+ return err;
+ }
+ }
+ return 0;
+}
+
+/* Enable/disable Rx FQ taildrop
+ *
+ * Rx FQ taildrop is mutually exclusive with flow control and it only gets
+ * disabled when FC is active. Depending on FC status, we need to compute
+ * the maximum number of buffers in the pool differently, so use the
+ * opportunity to update max number of buffers as well.
+ */
+int set_rx_taildrop(struct dpaa2_eth_priv *priv)
+{
+ enum dpaa2_eth_td_cfg cfg = dpaa2_eth_get_td_type(priv);
+ struct dpni_taildrop td_queue, td_group;
+ int err = 0;
+
+ switch (cfg) {
+ case DPAA2_ETH_TD_NONE:
+ memset(&td_queue, 0, sizeof(struct dpni_taildrop));
+ memset(&td_group, 0, sizeof(struct dpni_taildrop));
+ priv->max_bufs_per_ch = DPAA2_ETH_NUM_BUFS_FC /
+ priv->num_channels;
+ break;
+ case DPAA2_ETH_TD_QUEUE:
+ memset(&td_group, 0, sizeof(struct dpni_taildrop));
+ td_queue.enable = 1;
+ td_queue.units = DPNI_CONGESTION_UNIT_BYTES;
+ td_queue.threshold = DPAA2_ETH_TAILDROP_THRESH /
+ dpaa2_eth_tc_count(priv);
+ priv->max_bufs_per_ch = DPAA2_ETH_NUM_BUFS_PER_CH;
+ break;
+ case DPAA2_ETH_TD_GROUP:
+ memset(&td_queue, 0, sizeof(struct dpni_taildrop));
+ td_group.enable = 1;
+ td_group.units = DPNI_CONGESTION_UNIT_FRAMES;
+ td_group.threshold = NAPI_POLL_WEIGHT *
+ dpaa2_eth_queue_count(priv);
+ priv->max_bufs_per_ch = NAPI_POLL_WEIGHT *
+ dpaa2_eth_tc_count(priv);
+ break;
+ default:
+ break;
+ }
+
+ err = set_queue_taildrop(priv, &td_queue);
+ if (err)
+ return err;
+
+ err = set_group_taildrop(priv, &td_group);
+ if (err)
+ return err;
+
+ priv->refill_thresh = DPAA2_ETH_REFILL_THRESH(priv);
+
+ return 0;
}
static int setup_rx_flow(struct dpaa2_eth_priv *priv,