net: stmmac: Report taprio offload status
[linux-2.6-microblaze.git] / drivers / net / ethernet / stmicro / stmmac / stmmac_tc.c
index 07aa3a3..cce0071 100644 (file)
@@ -937,8 +937,8 @@ static void tc_taprio_map_maxsdu_txq(struct stmmac_priv *priv,
        }
 }
 
-static int tc_setup_taprio(struct stmmac_priv *priv,
-                          struct tc_taprio_qopt_offload *qopt)
+static int tc_taprio_configure(struct stmmac_priv *priv,
+                              struct tc_taprio_qopt_offload *qopt)
 {
        u32 size, wid = priv->dma_cap.estwid, dep = priv->dma_cap.estdep;
        struct plat_stmmacenet_data *plat = priv->plat;
@@ -990,8 +990,6 @@ static int tc_setup_taprio(struct stmmac_priv *priv,
 
        if (qopt->cmd == TAPRIO_CMD_DESTROY)
                goto disable;
-       else if (qopt->cmd != TAPRIO_CMD_REPLACE)
-               return -EOPNOTSUPP;
 
        if (qopt->num_entries >= dep)
                return -EINVAL;
@@ -1102,6 +1100,11 @@ disable:
                priv->plat->est->enable = false;
                stmmac_est_configure(priv, priv, priv->plat->est,
                                     priv->plat->clk_ptp_rate);
+               /* Reset taprio status */
+               for (i = 0; i < priv->plat->tx_queues_to_use; i++) {
+                       priv->xstats.max_sdu_txq_drop[i] = 0;
+                       priv->xstats.mtl_est_txq_hlbf[i] = 0;
+               }
                mutex_unlock(&priv->plat->est->lock);
        }
 
@@ -1119,6 +1122,57 @@ disable:
        return ret;
 }
 
+static void tc_taprio_stats(struct stmmac_priv *priv,
+                           struct tc_taprio_qopt_offload *qopt)
+{
+       u64 window_drops = 0;
+       int i = 0;
+
+       for (i = 0; i < priv->plat->tx_queues_to_use; i++)
+               window_drops += priv->xstats.max_sdu_txq_drop[i] +
+                               priv->xstats.mtl_est_txq_hlbf[i];
+       qopt->stats.window_drops = window_drops;
+
+       /* Transmission overrun doesn't happen for stmmac, hence always 0 */
+       qopt->stats.tx_overruns = 0;
+}
+
+static void tc_taprio_queue_stats(struct stmmac_priv *priv,
+                                 struct tc_taprio_qopt_offload *qopt)
+{
+       struct tc_taprio_qopt_queue_stats *q_stats = &qopt->queue_stats;
+       int queue = qopt->queue_stats.queue;
+
+       q_stats->stats.window_drops = priv->xstats.max_sdu_txq_drop[queue] +
+                                     priv->xstats.mtl_est_txq_hlbf[queue];
+
+       /* Transmission overrun doesn't happen for stmmac, hence always 0 */
+       q_stats->stats.tx_overruns = 0;
+}
+
+static int tc_setup_taprio(struct stmmac_priv *priv,
+                          struct tc_taprio_qopt_offload *qopt)
+{
+       int err = 0;
+
+       switch (qopt->cmd) {
+       case TAPRIO_CMD_REPLACE:
+       case TAPRIO_CMD_DESTROY:
+               err = tc_taprio_configure(priv, qopt);
+               break;
+       case TAPRIO_CMD_STATS:
+               tc_taprio_stats(priv, qopt);
+               break;
+       case TAPRIO_CMD_QUEUE_STATS:
+               tc_taprio_queue_stats(priv, qopt);
+               break;
+       default:
+               err = -EOPNOTSUPP;
+       }
+
+       return err;
+}
+
 static int tc_setup_etf(struct stmmac_priv *priv,
                        struct tc_etf_qopt_offload *qopt)
 {