|
|
@@ -1808,6 +1808,51 @@ static int cpsw_set_cbs(struct net_device *ndev,
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static void cpsw_cbs_resume(struct cpsw_slave *slave, struct cpsw_priv *priv)
|
|
|
+{
|
|
|
+ int fifo, bw;
|
|
|
+
|
|
|
+ for (fifo = CPSW_FIFO_SHAPERS_NUM; fifo > 0; fifo--) {
|
|
|
+ bw = priv->fifo_bw[fifo];
|
|
|
+ if (!bw)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ cpsw_set_fifo_rlimit(priv, fifo, bw);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void cpsw_mqprio_resume(struct cpsw_slave *slave, struct cpsw_priv *priv)
|
|
|
+{
|
|
|
+ struct cpsw_common *cpsw = priv->cpsw;
|
|
|
+ u32 tx_prio_map = 0;
|
|
|
+ int i, tc, fifo;
|
|
|
+ u32 tx_prio_rg;
|
|
|
+
|
|
|
+ if (!priv->mqprio_hw)
|
|
|
+ return;
|
|
|
+
|
|
|
+ for (i = 0; i < 8; i++) {
|
|
|
+ tc = netdev_get_prio_tc_map(priv->ndev, i);
|
|
|
+ fifo = CPSW_FIFO_SHAPERS_NUM - tc;
|
|
|
+ tx_prio_map |= fifo << (4 * i);
|
|
|
+ }
|
|
|
+
|
|
|
+ tx_prio_rg = cpsw->version == CPSW_VERSION_1 ?
|
|
|
+ CPSW1_TX_PRI_MAP : CPSW2_TX_PRI_MAP;
|
|
|
+
|
|
|
+ slave_write(slave, tx_prio_map, tx_prio_rg);
|
|
|
+}
|
|
|
+
|
|
|
+/* restore resources after port reset */
|
|
|
+static void cpsw_restore(struct cpsw_priv *priv)
|
|
|
+{
|
|
|
+ /* restore MQPRIO offload */
|
|
|
+ for_each_slave(priv, cpsw_mqprio_resume, priv);
|
|
|
+
|
|
|
+ /* restore CBS offload */
|
|
|
+ for_each_slave(priv, cpsw_cbs_resume, priv);
|
|
|
+}
|
|
|
+
|
|
|
static int cpsw_ndo_open(struct net_device *ndev)
|
|
|
{
|
|
|
struct cpsw_priv *priv = netdev_priv(ndev);
|
|
|
@@ -1887,6 +1932,8 @@ static int cpsw_ndo_open(struct net_device *ndev)
|
|
|
|
|
|
}
|
|
|
|
|
|
+ cpsw_restore(priv);
|
|
|
+
|
|
|
/* Enable Interrupt pacing if configured */
|
|
|
if (cpsw->coal_intvl != 0) {
|
|
|
struct ethtool_coalesce coal;
|