net: dsa: sja1105: move sja1105_compose_gating_subschedule at the top
authorVladimir Oltean <vladimir.oltean@nxp.com>
Wed, 24 Jun 2020 13:54:44 +0000 (16:54 +0300)
committerDavid S. Miller <davem@davemloft.net>
Thu, 25 Jun 2020 23:06:56 +0000 (16:06 -0700)
It turns out that sja1105_compose_gating_subschedule must also be called
from sja1105_vl_delete, to recalculate the overall tc-gate
configuration. Currently this is not possible without introducing a
forward declaration. So move the function at the top of the file, along
with its dependencies.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/sja1105/sja1105_vl.c

index 0056f9c..5ffa71f 100644 (file)
@@ -7,6 +7,166 @@
 
 #define SJA1105_SIZE_VL_STATUS                 8
 
+/* Insert into the global gate list, sorted by gate action time. */
+static int sja1105_insert_gate_entry(struct sja1105_gating_config *gating_cfg,
+                                    struct sja1105_rule *rule,
+                                    u8 gate_state, s64 entry_time,
+                                    struct netlink_ext_ack *extack)
+{
+       struct sja1105_gate_entry *e;
+       int rc;
+
+       e = kzalloc(sizeof(*e), GFP_KERNEL);
+       if (!e)
+               return -ENOMEM;
+
+       e->rule = rule;
+       e->gate_state = gate_state;
+       e->interval = entry_time;
+
+       if (list_empty(&gating_cfg->entries)) {
+               list_add(&e->list, &gating_cfg->entries);
+       } else {
+               struct sja1105_gate_entry *p;
+
+               list_for_each_entry(p, &gating_cfg->entries, list) {
+                       if (p->interval == e->interval) {
+                               NL_SET_ERR_MSG_MOD(extack,
+                                                  "Gate conflict");
+                               rc = -EBUSY;
+                               goto err;
+                       }
+
+                       if (e->interval < p->interval)
+                               break;
+               }
+               list_add(&e->list, p->list.prev);
+       }
+
+       gating_cfg->num_entries++;
+
+       return 0;
+err:
+       kfree(e);
+       return rc;
+}
+
+/* The gate entries contain absolute times in their e->interval field. Convert
+ * that to proper intervals (i.e. "0, 5, 10, 15" to "5, 5, 5, 5").
+ */
+static void
+sja1105_gating_cfg_time_to_interval(struct sja1105_gating_config *gating_cfg,
+                                   u64 cycle_time)
+{
+       struct sja1105_gate_entry *last_e;
+       struct sja1105_gate_entry *e;
+       struct list_head *prev;
+
+       list_for_each_entry(e, &gating_cfg->entries, list) {
+               struct sja1105_gate_entry *p;
+
+               prev = e->list.prev;
+
+               if (prev == &gating_cfg->entries)
+                       continue;
+
+               p = list_entry(prev, struct sja1105_gate_entry, list);
+               p->interval = e->interval - p->interval;
+       }
+       last_e = list_last_entry(&gating_cfg->entries,
+                                struct sja1105_gate_entry, list);
+       if (last_e->list.prev != &gating_cfg->entries)
+               last_e->interval = cycle_time - last_e->interval;
+}
+
+static void sja1105_free_gating_config(struct sja1105_gating_config *gating_cfg)
+{
+       struct sja1105_gate_entry *e, *n;
+
+       list_for_each_entry_safe(e, n, &gating_cfg->entries, list) {
+               list_del(&e->list);
+               kfree(e);
+       }
+}
+
+static int sja1105_compose_gating_subschedule(struct sja1105_private *priv,
+                                             struct netlink_ext_ack *extack)
+{
+       struct sja1105_gating_config *gating_cfg = &priv->tas_data.gating_cfg;
+       struct sja1105_rule *rule;
+       s64 max_cycle_time = 0;
+       s64 its_base_time = 0;
+       int i, rc = 0;
+
+       list_for_each_entry(rule, &priv->flow_block.rules, list) {
+               if (rule->type != SJA1105_RULE_VL)
+                       continue;
+               if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED)
+                       continue;
+
+               if (max_cycle_time < rule->vl.cycle_time) {
+                       max_cycle_time = rule->vl.cycle_time;
+                       its_base_time = rule->vl.base_time;
+               }
+       }
+
+       if (!max_cycle_time)
+               return 0;
+
+       dev_dbg(priv->ds->dev, "max_cycle_time %lld its_base_time %lld\n",
+               max_cycle_time, its_base_time);
+
+       sja1105_free_gating_config(gating_cfg);
+
+       gating_cfg->base_time = its_base_time;
+       gating_cfg->cycle_time = max_cycle_time;
+       gating_cfg->num_entries = 0;
+
+       list_for_each_entry(rule, &priv->flow_block.rules, list) {
+               s64 time;
+               s64 rbt;
+
+               if (rule->type != SJA1105_RULE_VL)
+                       continue;
+               if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED)
+                       continue;
+
+               /* Calculate the difference between this gating schedule's
+                * base time, and the base time of the gating schedule with the
+                * longest cycle time. We call it the relative base time (rbt).
+                */
+               rbt = future_base_time(rule->vl.base_time, rule->vl.cycle_time,
+                                      its_base_time);
+               rbt -= its_base_time;
+
+               time = rbt;
+
+               for (i = 0; i < rule->vl.num_entries; i++) {
+                       u8 gate_state = rule->vl.entries[i].gate_state;
+                       s64 entry_time = time;
+
+                       while (entry_time < max_cycle_time) {
+                               rc = sja1105_insert_gate_entry(gating_cfg, rule,
+                                                              gate_state,
+                                                              entry_time,
+                                                              extack);
+                               if (rc)
+                                       goto err;
+
+                               entry_time += rule->vl.cycle_time;
+                       }
+                       time += rule->vl.entries[i].interval;
+               }
+       }
+
+       sja1105_gating_cfg_time_to_interval(gating_cfg, max_cycle_time);
+
+       return 0;
+err:
+       sja1105_free_gating_config(gating_cfg);
+       return rc;
+}
+
 /* The switch flow classification core implements TTEthernet, which 'thinks' in
  * terms of Virtual Links (VL), a concept borrowed from ARINC 664 part 7.
  * However it also has one other operating mode (VLLUPFORMAT=0) where it acts
@@ -397,166 +557,6 @@ int sja1105_vl_delete(struct sja1105_private *priv, int port,
        return sja1105_static_config_reload(priv, SJA1105_VIRTUAL_LINKS);
 }
 
-/* Insert into the global gate list, sorted by gate action time. */
-static int sja1105_insert_gate_entry(struct sja1105_gating_config *gating_cfg,
-                                    struct sja1105_rule *rule,
-                                    u8 gate_state, s64 entry_time,
-                                    struct netlink_ext_ack *extack)
-{
-       struct sja1105_gate_entry *e;
-       int rc;
-
-       e = kzalloc(sizeof(*e), GFP_KERNEL);
-       if (!e)
-               return -ENOMEM;
-
-       e->rule = rule;
-       e->gate_state = gate_state;
-       e->interval = entry_time;
-
-       if (list_empty(&gating_cfg->entries)) {
-               list_add(&e->list, &gating_cfg->entries);
-       } else {
-               struct sja1105_gate_entry *p;
-
-               list_for_each_entry(p, &gating_cfg->entries, list) {
-                       if (p->interval == e->interval) {
-                               NL_SET_ERR_MSG_MOD(extack,
-                                                  "Gate conflict");
-                               rc = -EBUSY;
-                               goto err;
-                       }
-
-                       if (e->interval < p->interval)
-                               break;
-               }
-               list_add(&e->list, p->list.prev);
-       }
-
-       gating_cfg->num_entries++;
-
-       return 0;
-err:
-       kfree(e);
-       return rc;
-}
-
-/* The gate entries contain absolute times in their e->interval field. Convert
- * that to proper intervals (i.e. "0, 5, 10, 15" to "5, 5, 5, 5").
- */
-static void
-sja1105_gating_cfg_time_to_interval(struct sja1105_gating_config *gating_cfg,
-                                   u64 cycle_time)
-{
-       struct sja1105_gate_entry *last_e;
-       struct sja1105_gate_entry *e;
-       struct list_head *prev;
-
-       list_for_each_entry(e, &gating_cfg->entries, list) {
-               struct sja1105_gate_entry *p;
-
-               prev = e->list.prev;
-
-               if (prev == &gating_cfg->entries)
-                       continue;
-
-               p = list_entry(prev, struct sja1105_gate_entry, list);
-               p->interval = e->interval - p->interval;
-       }
-       last_e = list_last_entry(&gating_cfg->entries,
-                                struct sja1105_gate_entry, list);
-       if (last_e->list.prev != &gating_cfg->entries)
-               last_e->interval = cycle_time - last_e->interval;
-}
-
-static void sja1105_free_gating_config(struct sja1105_gating_config *gating_cfg)
-{
-       struct sja1105_gate_entry *e, *n;
-
-       list_for_each_entry_safe(e, n, &gating_cfg->entries, list) {
-               list_del(&e->list);
-               kfree(e);
-       }
-}
-
-static int sja1105_compose_gating_subschedule(struct sja1105_private *priv,
-                                             struct netlink_ext_ack *extack)
-{
-       struct sja1105_gating_config *gating_cfg = &priv->tas_data.gating_cfg;
-       struct sja1105_rule *rule;
-       s64 max_cycle_time = 0;
-       s64 its_base_time = 0;
-       int i, rc = 0;
-
-       list_for_each_entry(rule, &priv->flow_block.rules, list) {
-               if (rule->type != SJA1105_RULE_VL)
-                       continue;
-               if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED)
-                       continue;
-
-               if (max_cycle_time < rule->vl.cycle_time) {
-                       max_cycle_time = rule->vl.cycle_time;
-                       its_base_time = rule->vl.base_time;
-               }
-       }
-
-       if (!max_cycle_time)
-               return 0;
-
-       dev_dbg(priv->ds->dev, "max_cycle_time %lld its_base_time %lld\n",
-               max_cycle_time, its_base_time);
-
-       sja1105_free_gating_config(gating_cfg);
-
-       gating_cfg->base_time = its_base_time;
-       gating_cfg->cycle_time = max_cycle_time;
-       gating_cfg->num_entries = 0;
-
-       list_for_each_entry(rule, &priv->flow_block.rules, list) {
-               s64 time;
-               s64 rbt;
-
-               if (rule->type != SJA1105_RULE_VL)
-                       continue;
-               if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED)
-                       continue;
-
-               /* Calculate the difference between this gating schedule's
-                * base time, and the base time of the gating schedule with the
-                * longest cycle time. We call it the relative base time (rbt).
-                */
-               rbt = future_base_time(rule->vl.base_time, rule->vl.cycle_time,
-                                      its_base_time);
-               rbt -= its_base_time;
-
-               time = rbt;
-
-               for (i = 0; i < rule->vl.num_entries; i++) {
-                       u8 gate_state = rule->vl.entries[i].gate_state;
-                       s64 entry_time = time;
-
-                       while (entry_time < max_cycle_time) {
-                               rc = sja1105_insert_gate_entry(gating_cfg, rule,
-                                                              gate_state,
-                                                              entry_time,
-                                                              extack);
-                               if (rc)
-                                       goto err;
-
-                               entry_time += rule->vl.cycle_time;
-                       }
-                       time += rule->vl.entries[i].interval;
-               }
-       }
-
-       sja1105_gating_cfg_time_to_interval(gating_cfg, max_cycle_time);
-
-       return 0;
-err:
-       sja1105_free_gating_config(gating_cfg);
-       return rc;
-}
-
 int sja1105_vl_gate(struct sja1105_private *priv, int port,
                    struct netlink_ext_ack *extack, unsigned long cookie,
                    struct sja1105_key *key, u32 index, s32 prio,