net: mscc: ocelot: refactor policer work out of ocelot_setup_tc_cls_matchall
authorVladimir Oltean <vladimir.oltean@nxp.com>
Wed, 16 Mar 2022 20:41:39 +0000 (22:41 +0200)
committerJakub Kicinski <kuba@kernel.org>
Fri, 18 Mar 2022 00:42:46 +0000 (17:42 -0700)
In preparation for adding port mirroring support to the ocelot driver,
the dispatching function ocelot_setup_tc_cls_matchall() must be free of
action-specific code. Move port policer creation and deletion to
separate functions.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/mscc/ocelot_net.c

index 5767e38..a95e2fb 100644 (file)
@@ -216,14 +216,14 @@ int ocelot_setup_tc_cls_flower(struct ocelot_port_private *priv,
        }
 }
 
-static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv,
-                                       struct tc_cls_matchall_offload *f,
-                                       bool ingress)
+static int ocelot_setup_tc_cls_matchall_police(struct ocelot_port_private *priv,
+                                              struct tc_cls_matchall_offload *f,
+                                              bool ingress,
+                                              struct netlink_ext_ack *extack)
 {
-       struct netlink_ext_ack *extack = f->common.extack;
+       struct flow_action_entry *action = &f->rule->action.entries[0];
        struct ocelot *ocelot = priv->port.ocelot;
        struct ocelot_policer pol = { 0 };
-       struct flow_action_entry *action;
        int port = priv->chip_port;
        int err;
 
@@ -232,6 +232,58 @@ static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv,
                return -EOPNOTSUPP;
        }
 
+       if (priv->tc.police_id && priv->tc.police_id != f->cookie) {
+               NL_SET_ERR_MSG_MOD(extack,
+                                  "Only one policer per port is supported");
+               return -EEXIST;
+       }
+
+       err = ocelot_policer_validate(&f->rule->action, action, extack);
+       if (err)
+               return err;
+
+       pol.rate = (u32)div_u64(action->police.rate_bytes_ps, 1000) * 8;
+       pol.burst = action->police.burst;
+
+       err = ocelot_port_policer_add(ocelot, port, &pol);
+       if (err) {
+               NL_SET_ERR_MSG_MOD(extack, "Could not add policer");
+               return err;
+       }
+
+       priv->tc.police_id = f->cookie;
+       priv->tc.offload_cnt++;
+
+       return 0;
+}
+
+static int ocelot_del_tc_cls_matchall_police(struct ocelot_port_private *priv,
+                                            struct netlink_ext_ack *extack)
+{
+       struct ocelot *ocelot = priv->port.ocelot;
+       int port = priv->chip_port;
+       int err;
+
+       err = ocelot_port_policer_del(ocelot, port);
+       if (err) {
+               NL_SET_ERR_MSG_MOD(extack,
+                                  "Could not delete policer");
+               return err;
+       }
+
+       priv->tc.police_id = 0;
+       priv->tc.offload_cnt--;
+
+       return 0;
+}
+
+static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv,
+                                       struct tc_cls_matchall_offload *f,
+                                       bool ingress)
+{
+       struct netlink_ext_ack *extack = f->common.extack;
+       struct flow_action_entry *action;
+
        switch (f->command) {
        case TC_CLSMATCHALL_REPLACE:
                if (!flow_offload_has_one_action(&f->rule->action)) {
@@ -248,47 +300,27 @@ static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv,
 
                action = &f->rule->action.entries[0];
 
-               if (action->id != FLOW_ACTION_POLICE) {
+               switch (action->id) {
+               case FLOW_ACTION_POLICE:
+                       return ocelot_setup_tc_cls_matchall_police(priv, f,
+                                                                  ingress,
+                                                                  extack);
+                       break;
+               default:
                        NL_SET_ERR_MSG_MOD(extack, "Unsupported action");
                        return -EOPNOTSUPP;
                }
 
-               if (priv->tc.police_id && priv->tc.police_id != f->cookie) {
-                       NL_SET_ERR_MSG_MOD(extack,
-                                          "Only one policer per port is supported");
-                       return -EEXIST;
-               }
-
-               err = ocelot_policer_validate(&f->rule->action, action,
-                                             extack);
-               if (err)
-                       return err;
-
-               pol.rate = (u32)div_u64(action->police.rate_bytes_ps, 1000) * 8;
-               pol.burst = action->police.burst;
-
-               err = ocelot_port_policer_add(ocelot, port, &pol);
-               if (err) {
-                       NL_SET_ERR_MSG_MOD(extack, "Could not add policer");
-                       return err;
-               }
-
-               priv->tc.police_id = f->cookie;
-               priv->tc.offload_cnt++;
-               return 0;
+               break;
        case TC_CLSMATCHALL_DESTROY:
-               if (priv->tc.police_id != f->cookie)
+               action = &f->rule->action.entries[0];
+
+               if (f->cookie == priv->tc.police_id)
+                       return ocelot_del_tc_cls_matchall_police(priv, extack);
+               else
                        return -ENOENT;
 
-               err = ocelot_port_policer_del(ocelot, port);
-               if (err) {
-                       NL_SET_ERR_MSG_MOD(extack,
-                                          "Could not delete policer");
-                       return err;
-               }
-               priv->tc.police_id = 0;
-               priv->tc.offload_cnt--;
-               return 0;
+               break;
        case TC_CLSMATCHALL_STATS:
        default:
                return -EOPNOTSUPP;