OSDN Git Service

net: dsa: felix: remove prevalidate_phy_mode interface
authorColin Foster <colin.foster@in-advantage.com>
Sat, 26 Feb 2022 22:36:50 +0000 (14:36 -0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 28 Feb 2022 11:53:10 +0000 (11:53 +0000)
All users of the felix driver were creating their own prevalidate_phy_mode
function. The same logic can be performed in a more general way by using a
simple array of bit fields.

Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
Suggested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/ocelot/felix.c
drivers/net/dsa/ocelot/felix.h
drivers/net/dsa/ocelot/felix_vsc9959.c
drivers/net/dsa/ocelot/seville_vsc9953.c

index 5fc740e..badb5b9 100644 (file)
@@ -938,11 +938,28 @@ static int felix_get_ts_info(struct dsa_switch *ds, int port,
        return ocelot_get_ts_info(ocelot, port, info);
 }
 
+static const u32 felix_phy_match_table[PHY_INTERFACE_MODE_MAX] = {
+       [PHY_INTERFACE_MODE_INTERNAL] = OCELOT_PORT_MODE_INTERNAL,
+       [PHY_INTERFACE_MODE_SGMII] = OCELOT_PORT_MODE_SGMII,
+       [PHY_INTERFACE_MODE_QSGMII] = OCELOT_PORT_MODE_QSGMII,
+       [PHY_INTERFACE_MODE_USXGMII] = OCELOT_PORT_MODE_USXGMII,
+       [PHY_INTERFACE_MODE_2500BASEX] = OCELOT_PORT_MODE_2500BASEX,
+};
+
+static int felix_validate_phy_mode(struct felix *felix, int port,
+                                  phy_interface_t phy_mode)
+{
+       u32 modes = felix->info->port_modes[port];
+
+       if (felix_phy_match_table[phy_mode] & modes)
+               return 0;
+       return -EOPNOTSUPP;
+}
+
 static int felix_parse_ports_node(struct felix *felix,
                                  struct device_node *ports_node,
                                  phy_interface_t *port_phy_modes)
 {
-       struct ocelot *ocelot = &felix->ocelot;
        struct device *dev = felix->ocelot.dev;
        struct device_node *child;
 
@@ -969,7 +986,7 @@ static int felix_parse_ports_node(struct felix *felix,
                        return -ENODEV;
                }
 
-               err = felix->info->prevalidate_phy_mode(ocelot, port, phy_mode);
+               err = felix_validate_phy_mode(felix, port, phy_mode);
                if (err < 0) {
                        dev_err(dev, "Unsupported PHY mode %s on port %d\n",
                                phy_modes(phy_mode), port);
index 9395ac1..f083b06 100644 (file)
@@ -7,6 +7,12 @@
 #define ocelot_to_felix(o)             container_of((o), struct felix, ocelot)
 #define FELIX_MAC_QUIRKS               OCELOT_QUIRK_PCS_PERFORMS_RATE_ADAPTATION
 
+#define OCELOT_PORT_MODE_INTERNAL      BIT(0)
+#define OCELOT_PORT_MODE_SGMII         BIT(1)
+#define OCELOT_PORT_MODE_QSGMII                BIT(2)
+#define OCELOT_PORT_MODE_2500BASEX     BIT(3)
+#define OCELOT_PORT_MODE_USXGMII       BIT(4)
+
 /* Platform-specific information */
 struct felix_info {
        const struct resource           *target_io_res;
@@ -15,6 +21,7 @@ struct felix_info {
        const struct reg_field          *regfields;
        const u32 *const                *map;
        const struct ocelot_ops         *ops;
+       const u32                       *port_modes;
        int                             num_mact_rows;
        const struct ocelot_stat_layout *stats_layout;
        unsigned int                    num_stats;
@@ -44,8 +51,6 @@ struct felix_info {
        void    (*phylink_validate)(struct ocelot *ocelot, int port,
                                    unsigned long *supported,
                                    struct phylink_link_state *state);
-       int     (*prevalidate_phy_mode)(struct ocelot *ocelot, int port,
-                                       phy_interface_t phy_mode);
        int     (*port_setup_tc)(struct dsa_switch *ds, int port,
                                 enum tc_setup_type type, void *type_data);
        void    (*port_sched_speed_set)(struct ocelot *ocelot, int port,
index 434c7e4..ead3316 100644 (file)
 #include <linux/pci.h>
 #include "felix.h"
 
+#define VSC9959_NUM_PORTS              6
+
 #define VSC9959_TAS_GCL_ENTRY_MAX      63
 #define VSC9959_VCAP_POLICER_BASE      63
 #define VSC9959_VCAP_POLICER_MAX       383
 #define VSC9959_SWITCH_PCI_BAR         4
 #define VSC9959_IMDIO_PCI_BAR          0
 
+#define VSC9959_PORT_MODE_SERDES       (OCELOT_PORT_MODE_SGMII | \
+                                        OCELOT_PORT_MODE_QSGMII | \
+                                        OCELOT_PORT_MODE_2500BASEX | \
+                                        OCELOT_PORT_MODE_USXGMII)
+
+static const u32 vsc9959_port_modes[VSC9959_NUM_PORTS] = {
+       VSC9959_PORT_MODE_SERDES,
+       VSC9959_PORT_MODE_SERDES,
+       VSC9959_PORT_MODE_SERDES,
+       VSC9959_PORT_MODE_SERDES,
+       OCELOT_PORT_MODE_INTERNAL,
+};
+
 static const u32 vsc9959_ana_regmap[] = {
        REG(ANA_ADVLEARN,                       0x0089a0),
        REG(ANA_VLANMASK,                       0x0089a4),
@@ -968,27 +983,6 @@ static void vsc9959_phylink_validate(struct ocelot *ocelot, int port,
        linkmode_and(state->advertising, state->advertising, mask);
 }
 
-static int vsc9959_prevalidate_phy_mode(struct ocelot *ocelot, int port,
-                                       phy_interface_t phy_mode)
-{
-       switch (phy_mode) {
-       case PHY_INTERFACE_MODE_INTERNAL:
-               if (port != 4 && port != 5)
-                       return -ENOTSUPP;
-               return 0;
-       case PHY_INTERFACE_MODE_SGMII:
-       case PHY_INTERFACE_MODE_QSGMII:
-       case PHY_INTERFACE_MODE_USXGMII:
-       case PHY_INTERFACE_MODE_2500BASEX:
-               /* Not supported on internal to-CPU ports */
-               if (port == 4 || port == 5)
-                       return -ENOTSUPP;
-               return 0;
-       default:
-               return -ENOTSUPP;
-       }
-}
-
 /* Watermark encode
  * Bit 8:   Unit; 0:1, 1:16
  * Bit 7-0: Value to be multiplied with unit
@@ -2224,14 +2218,14 @@ static const struct felix_info felix_info_vsc9959 = {
        .vcap_pol_base2         = 0,
        .vcap_pol_max2          = 0,
        .num_mact_rows          = 2048,
-       .num_ports              = 6,
+       .num_ports              = VSC9959_NUM_PORTS,
        .num_tx_queues          = OCELOT_NUM_TC,
        .quirk_no_xtr_irq       = true,
        .ptp_caps               = &vsc9959_ptp_caps,
        .mdio_bus_alloc         = vsc9959_mdio_bus_alloc,
        .mdio_bus_free          = vsc9959_mdio_bus_free,
        .phylink_validate       = vsc9959_phylink_validate,
-       .prevalidate_phy_mode   = vsc9959_prevalidate_phy_mode,
+       .port_modes             = vsc9959_port_modes,
        .port_setup_tc          = vsc9959_port_setup_tc,
        .port_sched_speed_set   = vsc9959_sched_speed_set,
        .init_regmap            = ocelot_regmap_init,
index f12c1a1..68ef8f1 100644 (file)
 #include <linux/iopoll.h>
 #include "felix.h"
 
+#define VSC9953_NUM_PORTS                      10
+
 #define VSC9953_VCAP_POLICER_BASE              11
 #define VSC9953_VCAP_POLICER_MAX               31
 #define VSC9953_VCAP_POLICER_BASE2             120
 #define VSC9953_VCAP_POLICER_MAX2              161
 
+#define VSC9953_PORT_MODE_SERDES               (OCELOT_PORT_MODE_SGMII | \
+                                                OCELOT_PORT_MODE_QSGMII)
+
+static const u32 vsc9953_port_modes[VSC9953_NUM_PORTS] = {
+       VSC9953_PORT_MODE_SERDES,
+       VSC9953_PORT_MODE_SERDES,
+       VSC9953_PORT_MODE_SERDES,
+       VSC9953_PORT_MODE_SERDES,
+       VSC9953_PORT_MODE_SERDES,
+       VSC9953_PORT_MODE_SERDES,
+       VSC9953_PORT_MODE_SERDES,
+       VSC9953_PORT_MODE_SERDES,
+       OCELOT_PORT_MODE_INTERNAL,
+       OCELOT_PORT_MODE_INTERNAL,
+};
+
 static const u32 vsc9953_ana_regmap[] = {
        REG(ANA_ADVLEARN,                       0x00b500),
        REG(ANA_VLANMASK,                       0x00b504),
@@ -938,25 +956,6 @@ static void vsc9953_phylink_validate(struct ocelot *ocelot, int port,
        linkmode_and(state->advertising, state->advertising, mask);
 }
 
-static int vsc9953_prevalidate_phy_mode(struct ocelot *ocelot, int port,
-                                       phy_interface_t phy_mode)
-{
-       switch (phy_mode) {
-       case PHY_INTERFACE_MODE_INTERNAL:
-               if (port != 8 && port != 9)
-                       return -ENOTSUPP;
-               return 0;
-       case PHY_INTERFACE_MODE_SGMII:
-       case PHY_INTERFACE_MODE_QSGMII:
-               /* Not supported on internal to-CPU ports */
-               if (port == 8 || port == 9)
-                       return -ENOTSUPP;
-               return 0;
-       default:
-               return -ENOTSUPP;
-       }
-}
-
 /* Watermark encode
  * Bit 9:   Unit; 0:1, 1:16
  * Bit 8-0: Value to be multiplied with unit
@@ -1094,12 +1093,12 @@ static const struct felix_info seville_info_vsc9953 = {
        .vcap_pol_base2         = VSC9953_VCAP_POLICER_BASE2,
        .vcap_pol_max2          = VSC9953_VCAP_POLICER_MAX2,
        .num_mact_rows          = 2048,
-       .num_ports              = 10,
+       .num_ports              = VSC9953_NUM_PORTS,
        .num_tx_queues          = OCELOT_NUM_TC,
        .mdio_bus_alloc         = vsc9953_mdio_bus_alloc,
        .mdio_bus_free          = vsc9953_mdio_bus_free,
        .phylink_validate       = vsc9953_phylink_validate,
-       .prevalidate_phy_mode   = vsc9953_prevalidate_phy_mode,
+       .port_modes             = vsc9953_port_modes,
        .init_regmap            = ocelot_regmap_init,
 };