summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/nic/qos.c60
1 files changed, 55 insertions, 5 deletions
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/qos.c b/drivers/net/ethernet/marvell/octeontx2/nic/qos.c
index 69c0911e28e9..f160b1618efa 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/qos.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/qos.c
@@ -235,13 +235,63 @@ static int otx2_qos_txschq_set_parent_topology(struct otx2_nic *pfvf,
return rc;
}
+static int otx2_qos_reset_schq_topology(struct otx2_nic *pfvf, u16 lvl,
+ u16 schq)
+{
+ struct mbox *mbox = &pfvf->mbox;
+ struct nix_txschq_config *cfg;
+ int rc;
+
+ if (lvl < NIX_TXSCH_LVL_TL4 || lvl >= NIX_TXSCH_LVL_TL1)
+ return 0;
+
+ mutex_lock(&mbox->lock);
+
+ cfg = otx2_mbox_alloc_msg_nix_txschq_cfg(mbox);
+ if (!cfg) {
+ mutex_unlock(&mbox->lock);
+ return -ENOMEM;
+ }
+
+ cfg->lvl = lvl;
+ cfg->num_regs = 1;
+
+ if (lvl == NIX_TXSCH_LVL_TL4)
+ cfg->reg[0] = NIX_AF_TL4X_TOPOLOGY(schq);
+ else if (lvl == NIX_TXSCH_LVL_TL3)
+ cfg->reg[0] = NIX_AF_TL3X_TOPOLOGY(schq);
+ else if (lvl == NIX_TXSCH_LVL_TL2)
+ cfg->reg[0] = NIX_AF_TL2X_TOPOLOGY(schq);
+
+ cfg->regval[0] = 0;
+
+ rc = otx2_sync_mbox_msg(mbox);
+
+ mutex_unlock(&mbox->lock);
+
+ return rc;
+}
+
+static void otx2_qos_free_hw_schq(struct otx2_nic *pfvf, u16 lvl, u16 schq)
+{
+ int err;
+
+ err = otx2_qos_reset_schq_topology(pfvf, lvl, schq);
+ if (err)
+ netdev_warn(pfvf->netdev,
+ "QoS: failed to reset topology for schq %u at level %u: %d\n",
+ schq, lvl, err);
+
+ otx2_txschq_free_one(pfvf, lvl, schq);
+}
+
static void otx2_qos_free_hw_node_schq(struct otx2_nic *pfvf,
struct otx2_qos_node *parent)
{
struct otx2_qos_node *node;
list_for_each_entry_reverse(node, &parent->child_schq_list, list)
- otx2_txschq_free_one(pfvf, node->level, node->schq);
+ otx2_qos_free_hw_schq(pfvf, node->level, node->schq);
}
static void otx2_qos_free_hw_node(struct otx2_nic *pfvf,
@@ -252,7 +302,7 @@ static void otx2_qos_free_hw_node(struct otx2_nic *pfvf,
list_for_each_entry_safe(node, tmp, &parent->child_list, list) {
otx2_qos_free_hw_node(pfvf, node);
otx2_qos_free_hw_node_schq(pfvf, node);
- otx2_txschq_free_one(pfvf, node->level, node->schq);
+ otx2_qos_free_hw_schq(pfvf, node->level, node->schq);
}
}
@@ -266,7 +316,7 @@ static void otx2_qos_free_hw_cfg(struct otx2_nic *pfvf,
otx2_qos_free_hw_node_schq(pfvf, node);
/* free node hw mappings */
- otx2_txschq_free_one(pfvf, node->level, node->schq);
+ otx2_qos_free_hw_schq(pfvf, node->level, node->schq);
mutex_unlock(&pfvf->qos.qos_lock);
}
@@ -913,7 +963,7 @@ static void otx2_qos_free_cfg(struct otx2_nic *pfvf, struct otx2_qos_cfg *cfg)
for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
for (idx = 0; idx < cfg->schq[lvl]; idx++) {
schq = cfg->schq_list[lvl][idx];
- otx2_txschq_free_one(pfvf, lvl, schq);
+ otx2_qos_free_hw_schq(pfvf, lvl, schq);
}
}
@@ -921,7 +971,7 @@ static void otx2_qos_free_cfg(struct otx2_nic *pfvf, struct otx2_qos_cfg *cfg)
for (idx = 0; idx < cfg->schq_contig[lvl]; idx++) {
if (cfg->schq_index_used[lvl][idx]) {
schq = cfg->schq_contig_list[lvl][idx];
- otx2_txschq_free_one(pfvf, lvl, schq);
+ otx2_qos_free_hw_schq(pfvf, lvl, schq);
}
}
}