net: dsa: b53: Report VLAN table occupancy via devlink
authorFlorian Fainelli <f.fainelli@gmail.com>
Wed, 9 Sep 2020 17:49:31 +0000 (10:49 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 9 Sep 2020 21:29:02 +0000 (14:29 -0700)
We already maintain an array of VLANs used by the switch so we can
simply iterate over it to report the occupancy via devlink.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/b53/b53_common.c
drivers/net/dsa/b53/b53_priv.h
drivers/net/dsa/bcm_sf2.c

index 26fcff85d881975c5a320fb1c0fe8743b451d343..6a5796c327215e4f54e39e6a03e77ac8443ae184 100644 (file)
@@ -977,6 +977,54 @@ int b53_get_sset_count(struct dsa_switch *ds, int port, int sset)
 }
 EXPORT_SYMBOL(b53_get_sset_count);
 
+enum b53_devlink_resource_id {
+       B53_DEVLINK_PARAM_ID_VLAN_TABLE,
+};
+
+static u64 b53_devlink_vlan_table_get(void *priv)
+{
+       struct b53_device *dev = priv;
+       struct b53_vlan *vl;
+       unsigned int i;
+       u64 count = 0;
+
+       for (i = 0; i < dev->num_vlans; i++) {
+               vl = &dev->vlans[i];
+               if (vl->members)
+                       count++;
+       }
+
+       return count;
+}
+
+int b53_setup_devlink_resources(struct dsa_switch *ds)
+{
+       struct devlink_resource_size_params size_params;
+       struct b53_device *dev = ds->priv;
+       int err;
+
+       devlink_resource_size_params_init(&size_params, dev->num_vlans,
+                                         dev->num_vlans,
+                                         1, DEVLINK_RESOURCE_UNIT_ENTRY);
+
+       err = dsa_devlink_resource_register(ds, "VLAN", dev->num_vlans,
+                                           B53_DEVLINK_PARAM_ID_VLAN_TABLE,
+                                           DEVLINK_RESOURCE_ID_PARENT_TOP,
+                                           &size_params);
+       if (err)
+               goto out;
+
+       dsa_devlink_resource_occ_get_register(ds,
+                                             B53_DEVLINK_PARAM_ID_VLAN_TABLE,
+                                             b53_devlink_vlan_table_get, dev);
+
+       return 0;
+out:
+       dsa_devlink_resources_unregister(ds);
+       return err;
+}
+EXPORT_SYMBOL(b53_setup_devlink_resources);
+
 static int b53_setup(struct dsa_switch *ds)
 {
        struct b53_device *dev = ds->priv;
@@ -992,8 +1040,10 @@ static int b53_setup(struct dsa_switch *ds)
        b53_reset_mib(dev);
 
        ret = b53_apply_config(dev);
-       if (ret)
+       if (ret) {
                dev_err(ds->dev, "failed to apply configuration\n");
+               return ret;
+       }
 
        /* Configure IMP/CPU port, disable all other ports. Enabled
         * ports will be configured with .port_enable
@@ -1012,7 +1062,12 @@ static int b53_setup(struct dsa_switch *ds)
         */
        ds->vlan_filtering_is_global = true;
 
-       return ret;
+       return b53_setup_devlink_resources(ds);
+}
+
+static void b53_teardown(struct dsa_switch *ds)
+{
+       dsa_devlink_resources_unregister(ds);
 }
 
 static void b53_force_link(struct b53_device *dev, int port, int link)
@@ -2141,6 +2196,7 @@ static int b53_get_max_mtu(struct dsa_switch *ds, int port)
 static const struct dsa_switch_ops b53_switch_ops = {
        .get_tag_protocol       = b53_get_tag_protocol,
        .setup                  = b53_setup,
+       .teardown               = b53_teardown,
        .get_strings            = b53_get_strings,
        .get_ethtool_stats      = b53_get_ethtool_stats,
        .get_sset_count         = b53_get_sset_count,
index e942c60e4365cfa414f2707b1f5a6d5b69fd7464..c55c0a9f1b478dd7e38eed5d6f41f47ab066dd39 100644 (file)
@@ -328,6 +328,7 @@ void b53_br_set_stp_state(struct dsa_switch *ds, int port, u8 state);
 void b53_br_fast_age(struct dsa_switch *ds, int port);
 int b53_br_egress_floods(struct dsa_switch *ds, int port,
                         bool unicast, bool multicast);
+int b53_setup_devlink_resources(struct dsa_switch *ds);
 void b53_port_event(struct dsa_switch *ds, int port);
 void b53_phylink_validate(struct dsa_switch *ds, int port,
                          unsigned long *supported,
index 3263e8a0ae67ca2b0c6c9596113f329ccff5d7d0..7238206031070fe6eae2df3cfb9190d6ecd14e0d 100644 (file)
@@ -936,7 +936,12 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
        b53_configure_vlan(ds);
        bcm_sf2_enable_acb(ds);
 
-       return 0;
+       return b53_setup_devlink_resources(ds);
+}
+
+static void bcm_sf2_sw_teardown(struct dsa_switch *ds)
+{
+       dsa_devlink_resources_unregister(ds);
 }
 
 /* The SWITCH_CORE register space is managed by b53 but operates on a page +
@@ -1073,6 +1078,7 @@ static int bcm_sf2_sw_get_sset_count(struct dsa_switch *ds, int port,
 static const struct dsa_switch_ops bcm_sf2_ops = {
        .get_tag_protocol       = b53_get_tag_protocol,
        .setup                  = bcm_sf2_sw_setup,
+       .teardown               = bcm_sf2_sw_teardown,
        .get_strings            = bcm_sf2_sw_get_strings,
        .get_ethtool_stats      = bcm_sf2_sw_get_ethtool_stats,
        .get_sset_count         = bcm_sf2_sw_get_sset_count,