From: Ioana Radulescu <ruxandra.radule...@nxp.com>

Depending on when MC connects the DPNI to a MAC, Tx FQIDs may
not be available during probe time.

Read the FQIDs each time the link goes up to avoid using invalid
values. In case an error occurs or an invalid value is retrieved,
fall back to QDID-based enqueueing.

Fixes: 1fa0f68c9255 ("dpaa2-eth: Use FQ-based DPIO enqueue API")
Signed-off-by: Ioana Radulescu <ruxandra.radule...@nxp.com>
Signed-off-by: Ioana Ciornei <ioana.cior...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 42 ++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 5acd734a216b..5bd24c160256 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -1235,6 +1235,8 @@ static void dpaa2_eth_set_rx_taildrop(struct 
dpaa2_eth_priv *priv, bool enable)
        priv->rx_td_enabled = enable;
 }
 
+static void update_tx_fqids(struct dpaa2_eth_priv *priv);
+
 static int link_state_update(struct dpaa2_eth_priv *priv)
 {
        struct dpni_link_state state = {0};
@@ -1261,6 +1263,7 @@ static int link_state_update(struct dpaa2_eth_priv *priv)
                goto out;
 
        if (state.up) {
+               update_tx_fqids(priv);
                netif_carrier_on(priv->net_dev);
                netif_tx_start_all_queues(priv->net_dev);
        } else {
@@ -2533,6 +2536,45 @@ static int set_pause(struct dpaa2_eth_priv *priv)
        return 0;
 }
 
+static void update_tx_fqids(struct dpaa2_eth_priv *priv)
+{
+       struct dpaa2_eth_fq *fq;
+       struct dpni_queue queue;
+       struct dpni_queue_id qid = {0};
+       int i, j, err;
+
+       /* We only use Tx FQIDs for FQID-based enqueue, so check
+        * if DPNI version supports it before updating FQIDs
+        */
+       if (dpaa2_eth_cmp_dpni_ver(priv, DPNI_ENQUEUE_FQID_VER_MAJOR,
+                                  DPNI_ENQUEUE_FQID_VER_MINOR) < 0)
+               return;
+
+       for (i = 0; i < priv->num_fqs; i++) {
+               fq = &priv->fq[i];
+               if (fq->type != DPAA2_TX_CONF_FQ)
+                       continue;
+               for (j = 0; j < dpaa2_eth_tc_count(priv); j++) {
+                       err = dpni_get_queue(priv->mc_io, 0, priv->mc_token,
+                                            DPNI_QUEUE_TX, j, fq->flowid,
+                                            &queue, &qid);
+                       if (err)
+                               goto out_err;
+
+                       fq->tx_fqid[j] = qid.fqid;
+                       if (fq->tx_fqid[j] == 0)
+                               goto out_err;
+               }
+       }
+
+       return;
+
+out_err:
+       netdev_info(priv->net_dev,
+                   "Error reading Tx FQID, fallback to QDID-based enqueue");
+       priv->enqueue = dpaa2_eth_enqueue_qd;
+}
+
 /* Configure the DPNI object this interface is associated with */
 static int setup_dpni(struct fsl_mc_device *ls_dev)
 {
-- 
1.9.1

Reply via email to