diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c index 06e4f44df628..9da9e534e9c0 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c @@ -983,12 +983,20 @@ static const struct sparx5_consts sparx5_consts = { .tod_pin = 4, }; +static const struct sparx5_ops sparx5_ops = { + .is_port_2g5 = &sparx5_port_is_2g5, + .is_port_5g = &sparx5_port_is_5g, + .is_port_10g = &sparx5_port_is_10g, + .is_port_25g = &sparx5_port_is_25g, +}; + static const struct sparx5_match_data sparx5_desc = { .iomap = sparx5_main_iomap, .iomap_size = ARRAY_SIZE(sparx5_main_iomap), .ioranges = 3, .regs = &sparx5_regs, .consts = &sparx5_consts, + .ops = &sparx5_ops, }; static const struct of_device_id mchp_sparx5_match[] = { diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h index 6e6067568f2a..f3716bd2f9a2 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h @@ -258,6 +258,13 @@ struct sparx5_consts { u32 tod_pin; /* PTP TOD pin */ }; +struct sparx5_ops { + bool (*is_port_2g5)(int portno); + bool (*is_port_5g)(int portno); + bool (*is_port_10g)(int portno); + bool (*is_port_25g)(int portno); +}; + struct sparx5_main_io_resource { enum sparx5_target id; phys_addr_t offset; @@ -267,6 +274,7 @@ struct sparx5_main_io_resource { struct sparx5_match_data { const struct sparx5_regs *regs; const struct sparx5_consts *consts; + const struct sparx5_ops *ops; const struct sparx5_main_io_resource *iomap; int ioranges; int iomap_size; diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c index ea3454342665..c5dfe0fa847b 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c @@ -213,11 +213,13 @@ static int sparx5_port_verify_speed(struct sparx5 *sparx5, struct sparx5_port *port, struct sparx5_port_config *conf) { - if ((sparx5_port_is_2g5(port->portno) && + const struct sparx5_ops *ops = sparx5->data->ops; + + if ((ops->is_port_2g5(port->portno) && conf->speed > SPEED_2500) || - (sparx5_port_is_5g(port->portno) && + (ops->is_port_5g(port->portno) && conf->speed > SPEED_5000) || - (sparx5_port_is_10g(port->portno) && + (ops->is_port_10g(port->portno) && conf->speed > SPEED_10000)) return sparx5_port_error(port, conf, SPX5_PERR_SPEED); @@ -226,14 +228,14 @@ static int sparx5_port_verify_speed(struct sparx5 *sparx5, return -EINVAL; case PHY_INTERFACE_MODE_1000BASEX: if (conf->speed != SPEED_1000 || - sparx5_port_is_2g5(port->portno)) + ops->is_port_2g5(port->portno)) return sparx5_port_error(port, conf, SPX5_PERR_SPEED); - if (sparx5_port_is_2g5(port->portno)) + if (ops->is_port_2g5(port->portno)) return sparx5_port_error(port, conf, SPX5_PERR_IFTYPE); break; case PHY_INTERFACE_MODE_2500BASEX: if (conf->speed != SPEED_2500 || - sparx5_port_is_2g5(port->portno)) + ops->is_port_2g5(port->portno)) return sparx5_port_error(port, conf, SPX5_PERR_SPEED); break; case PHY_INTERFACE_MODE_QSGMII: @@ -320,6 +322,7 @@ static int sparx5_port_disable(struct sparx5 *sparx5, struct sparx5_port *port, u32 dev = high_spd_dev ? sparx5_to_high_dev(sparx5, port->portno) : TARGET_DEV2G5; void __iomem *devinst = spx5_inst_get(sparx5, dev, tinst); + const struct sparx5_ops *ops = sparx5->data->ops; u32 spd = port->conf.speed; u32 spd_prm; int err; @@ -436,7 +439,7 @@ static int sparx5_port_disable(struct sparx5 *sparx5, struct sparx5_port *port, pcsinst, PCS10G_BR_PCS_CFG(0)); - if (sparx5_port_is_25g(port->portno)) + if (ops->is_port_25g(port->portno)) /* Disable 25G PCS */ spx5_rmw(DEV25G_PCS25G_CFG_PCS25G_ENA_SET(0), DEV25G_PCS25G_CFG_PCS25G_ENA, @@ -561,6 +564,7 @@ static int sparx5_port_max_tags_set(struct sparx5 *sparx5, u32 dev = sparx5_to_high_dev(sparx5, port->portno); u32 tinst = sparx5_port_dev_index(sparx5, port->portno); void __iomem *inst = spx5_inst_get(sparx5, dev, tinst); + const struct sparx5_ops *ops = sparx5->data->ops; u32 etype; etype = (vlan_type == SPX5_VLAN_PORT_TYPE_S_CUSTOM ? @@ -575,7 +579,7 @@ static int sparx5_port_max_tags_set(struct sparx5 *sparx5, sparx5, DEV2G5_MAC_TAGS_CFG(port->portno)); - if (sparx5_port_is_2g5(port->portno)) + if (ops->is_port_2g5(port->portno)) return 0; spx5_inst_rmw(DEV10G_MAC_TAGS_CFG_TAG_ID_SET(etype) | @@ -844,18 +848,19 @@ static int sparx5_port_pcs_high_set(struct sparx5 *sparx5, static void sparx5_dev_switch(struct sparx5 *sparx5, int port, bool hsd) { int bt_indx = BIT(sparx5_port_dev_index(sparx5, port)); + const struct sparx5_ops *ops = sparx5->data->ops; - if (sparx5_port_is_5g(port)) { + if (ops->is_port_5g(port)) { spx5_rmw(hsd ? 0 : bt_indx, bt_indx, sparx5, PORT_CONF_DEV5G_MODES); - } else if (sparx5_port_is_10g(port)) { + } else if (ops->is_port_10g(port)) { spx5_rmw(hsd ? 0 : bt_indx, bt_indx, sparx5, PORT_CONF_DEV10G_MODES); - } else if (sparx5_port_is_25g(port)) { + } else if (ops->is_port_25g(port)) { spx5_rmw(hsd ? 0 : bt_indx, bt_indx, sparx5, @@ -1016,6 +1021,7 @@ int sparx5_port_init(struct sparx5 *sparx5, { u32 pause_start = sparx5_wm_enc(6 * (ETH_MAXLEN / SPX5_BUFFER_CELL_SZ)); u32 atop = sparx5_wm_enc(20 * (ETH_MAXLEN / SPX5_BUFFER_CELL_SZ)); + const struct sparx5_ops *ops = sparx5->data->ops; u32 devhigh = sparx5_to_high_dev(sparx5, port->portno); u32 pix = sparx5_port_dev_index(sparx5, port->portno); u32 pcs = sparx5_to_pcs_dev(sparx5, port->portno); @@ -1082,7 +1088,7 @@ int sparx5_port_init(struct sparx5 *sparx5, if (err) return err; - if (!sparx5_port_is_2g5(port->portno)) + if (!ops->is_port_2g5(port->portno)) /* Enable shadow device */ spx5_rmw(DSM_DEV_TX_STOP_WM_CFG_DEV10G_SHADOW_ENA_SET(1), DSM_DEV_TX_STOP_WM_CFG_DEV10G_SHADOW_ENA, @@ -1105,7 +1111,7 @@ int sparx5_port_init(struct sparx5 *sparx5, sparx5, DEV2G5_MAC_IFG_CFG(port->portno)); - if (sparx5_port_is_2g5(port->portno)) + if (ops->is_port_2g5(port->portno)) return 0; /* Low speed device only - return */ /* Now setup the high speed device */ @@ -1128,7 +1134,7 @@ int sparx5_port_init(struct sparx5 *sparx5, pcsinst, PCS10G_BR_PCS_SD_CFG(0)); - if (sparx5_port_is_25g(port->portno)) { + if (ops->is_port_25g(port->portno)) { /* Handle Signal Detect in 25G PCS */ spx5_wr(DEV25G_PCS25G_SD_CFG_SD_POL_SET(sd_pol) | DEV25G_PCS25G_SD_CFG_SD_SEL_SET(sd_sel) | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h index 468e3d34d6e1..934e2d3dedbb 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h @@ -42,18 +42,22 @@ static inline bool sparx5_port_is_25g(int portno) static inline u32 sparx5_to_high_dev(struct sparx5 *sparx5, int port) { - if (sparx5_port_is_5g(port)) + const struct sparx5_ops *ops = sparx5->data->ops; + + if (ops->is_port_5g(port)) return TARGET_DEV5G; - if (sparx5_port_is_10g(port)) + if (ops->is_port_10g(port)) return TARGET_DEV10G; return TARGET_DEV25G; } static inline u32 sparx5_to_pcs_dev(struct sparx5 *sparx5, int port) { - if (sparx5_port_is_5g(port)) + const struct sparx5_ops *ops = sparx5->data->ops; + + if (ops->is_port_5g(port)) return TARGET_PCS5G_BR; - if (sparx5_port_is_10g(port)) + if (ops->is_port_10g(port)) return TARGET_PCS10G_BR; return TARGET_PCS25G_BR; }