This adds a function to update a CGR with new parameters. qman_create_cgr
can almost be used for this (with flags=0), but it's not suitable because
it also registers the callback function. The _safe variant was modeled off
of qman_cgr_delete_safe. However, we handle multiple arguments and a return
value.
Signed-off-by: Sean Anderson <sean.ander...@seco.com>
Acked-by: Camelia Groza <camelia.gr...@nxp.com>
---

Changes in v4:
- qman_cgr_create -> qman_create_cgr

Changes in v2:
- New

 drivers/soc/fsl/qbman/qman.c | 47 ++++++++++++++++++++++++++++++++++++
 include/soc/fsl/qman.h       |  9 +++++++
 2 files changed, 56 insertions(+)

diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index eb6600aab09b..68b825ea10f1 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -2568,6 +2568,53 @@ void qman_delete_cgr_safe(struct qman_cgr *cgr)
 }
 EXPORT_SYMBOL(qman_delete_cgr_safe);
 
+static int qman_update_cgr(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts)
+{
+       int ret;
+       unsigned long irqflags;
+       struct qman_portal *p = qman_cgr_get_affine_portal(cgr);
+
+       if (!p)
+               return -EINVAL;
+
+       spin_lock_irqsave(&p->cgr_lock, irqflags);
+       ret = qm_modify_cgr(cgr, 0, opts);
+       spin_unlock_irqrestore(&p->cgr_lock, irqflags);
+       put_affine_portal();
+       return ret;
+}
+
+struct update_cgr_params {
+       struct qman_cgr *cgr;
+       struct qm_mcc_initcgr *opts;
+       int ret;
+};
+
+static void qman_update_cgr_smp_call(void *p)
+{
+       struct update_cgr_params *params = p;
+
+       params->ret = qman_update_cgr(params->cgr, params->opts);
+}
+
+int qman_update_cgr_safe(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts)
+{
+       struct update_cgr_params params = {
+               .cgr = cgr,
+               .opts = opts,
+       };
+
+       preempt_disable();
+       if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id())
+               smp_call_function_single(qman_cgr_cpus[cgr->cgrid],
+                                        qman_update_cgr_smp_call, &params, 
true);
+       else
+               params.ret = qman_update_cgr(cgr, opts);
+       preempt_enable();
+       return params.ret;
+}
+EXPORT_SYMBOL(qman_update_cgr_safe);
+
 /* Cleanup FQs */
 
 static int _qm_mr_consume_and_match_verb(struct qm_portal *p, int v)
diff --git a/include/soc/fsl/qman.h b/include/soc/fsl/qman.h
index 59eeba31c192..0d3d6beb7fdb 100644
--- a/include/soc/fsl/qman.h
+++ b/include/soc/fsl/qman.h
@@ -1171,6 +1171,15 @@ int qman_delete_cgr(struct qman_cgr *cgr);
  */
 void qman_delete_cgr_safe(struct qman_cgr *cgr);
 
+/**
+ * qman_update_cgr_safe - Modifies a congestion group object from any CPU
+ * @cgr: the 'cgr' object to modify
+ * @opts: state of the CGR settings
+ *
+ * This will select the proper CPU and modify the CGR settings.
+ */
+int qman_update_cgr_safe(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts);
+
 /**
  * qman_query_cgr_congested - Queries CGR's congestion status
  * @cgr: the 'cgr' object to query
-- 
2.35.1.1320.gc452695387.dirty

Reply via email to