From 24a23deb90eea0acf049e226a70d8507394833c5 Mon Sep 17 00:00:00 2001 From: Codrin Ciubotariu Date: Fri, 24 Jul 2015 16:55:28 +0300 Subject: drivers/net/vsc9953: Use the generic Ethernet Switch parser This patch replaces the parser used by VSC9953 L2 Switch driver with the generic one. Also, the config macro that enables the VSC9953 commands has been replaced in all the platforms that use this driver with the config macro that corresponds to the generic parser. Signed-off-by: Codrin Ciubotariu Acked-by: Joe Hershberger Reviewed-by: York Sun --- drivers/net/vsc9953.c | 349 ++++++++++++++++++++++++-------------------------- 1 file changed, 165 insertions(+), 184 deletions(-) (limited to 'drivers') diff --git a/drivers/net/vsc9953.c b/drivers/net/vsc9953.c index 59e0fab..bf53535 100644 --- a/drivers/net/vsc9953.c +++ b/drivers/net/vsc9953.c @@ -14,6 +14,7 @@ #include #include #include +#include static struct vsc9953_info vsc9953_l2sw = { .port[0] = VSC9953_PORT_INFO_INITIALIZER(0), @@ -405,6 +406,165 @@ static void vsc9953_port_all_vlan_egress_untagged_set( vsc9953_port_vlan_egr_untag_set(i, mode); } +#ifdef CONFIG_CMD_ETHSW + +/* Enable/disable status of a VSC9953 port */ +static void vsc9953_port_status_set(int port_no, u8 enabled) +{ + struct vsc9953_qsys_reg *l2qsys_reg; + + /* Administrative down */ + if (!vsc9953_l2sw.port[port_no].enabled) + return; + + l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET + + VSC9953_QSYS_OFFSET); + + if (enabled) + setbits_le32(&l2qsys_reg->sys.switch_port_mode[port_no], + VSC9953_PORT_ENA); + else + clrbits_le32(&l2qsys_reg->sys.switch_port_mode[port_no], + VSC9953_PORT_ENA); +} + +/* Start autonegotiation for a VSC9953 PHY */ +static void vsc9953_phy_autoneg(int port_no) +{ + if (!vsc9953_l2sw.port[port_no].phydev) + return; + + if (vsc9953_l2sw.port[port_no].phydev->drv->startup( + vsc9953_l2sw.port[port_no].phydev)) + printf("Failed to start PHY for port %d\n", port_no); +} + +/* Print a VSC9953 port's configuration */ +static void vsc9953_port_config_show(int port_no) +{ + int speed; + int duplex; + int link; + u8 enabled; + u32 val; + struct vsc9953_qsys_reg *l2qsys_reg; + + l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET + + VSC9953_QSYS_OFFSET); + + val = in_le32(&l2qsys_reg->sys.switch_port_mode[port_no]); + enabled = vsc9953_l2sw.port[port_no].enabled && + (val & VSC9953_PORT_ENA); + + /* internal ports (8 and 9) are fixed */ + if (VSC9953_INTERNAL_PORT_CHECK(port_no)) { + link = 1; + speed = SPEED_2500; + duplex = DUPLEX_FULL; + } else { + if (vsc9953_l2sw.port[port_no].phydev) { + link = vsc9953_l2sw.port[port_no].phydev->link; + speed = vsc9953_l2sw.port[port_no].phydev->speed; + duplex = vsc9953_l2sw.port[port_no].phydev->duplex; + } else { + link = -1; + speed = -1; + duplex = -1; + } + } + + printf("%8d ", port_no); + printf("%8s ", enabled == 1 ? "enabled" : "disabled"); + printf("%8s ", link == 1 ? "up" : "down"); + + switch (speed) { + case SPEED_10: + printf("%8d ", 10); + break; + case SPEED_100: + printf("%8d ", 100); + break; + case SPEED_1000: + printf("%8d ", 1000); + break; + case SPEED_2500: + printf("%8d ", 2500); + break; + case SPEED_10000: + printf("%8d ", 10000); + break; + default: + printf("%8s ", "-"); + } + + printf("%8s\n", duplex == DUPLEX_FULL ? "full" : "half"); +} + +static int vsc9953_port_status_key_func(struct ethsw_command_def *parsed_cmd) +{ + int i; + u8 enabled; + + /* Last keyword should tell us if we should enable/disable the port */ + if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == + ethsw_id_enable) + enabled = 1; + else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == + ethsw_id_disable) + enabled = 0; + else + return CMD_RET_USAGE; + + if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { + if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + vsc9953_port_status_set(parsed_cmd->port, enabled); + } else { + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_port_status_set(i, enabled); + } + + return CMD_RET_SUCCESS; +} + +static int vsc9953_port_config_key_func(struct ethsw_command_def *parsed_cmd) +{ + int i; + + if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { + if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + vsc9953_phy_autoneg(parsed_cmd->port); + printf("%8s %8s %8s %8s %8s\n", + "Port", "Status", "Link", "Speed", + "Duplex"); + vsc9953_port_config_show(parsed_cmd->port); + + } else { + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_phy_autoneg(i); + printf("%8s %8s %8s %8s %8s\n", + "Port", "Status", "Link", "Speed", "Duplex"); + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_port_config_show(i); + } + + return CMD_RET_SUCCESS; +} + +static struct ethsw_command_func vsc9953_cmd_func = { + .ethsw_name = "L2 Switch VSC9953", + .port_enable = &vsc9953_port_status_key_func, + .port_disable = &vsc9953_port_status_key_func, + .port_show = &vsc9953_port_config_key_func, +}; + +#endif /* CONFIG_CMD_ETHSW */ + /***************************************************************************** At startup, the default configuration would be: - HW learning enabled on all ports; (HW default) @@ -563,190 +723,11 @@ void vsc9953_init(bd_t *bis) vsc9953_default_configuration(); +#ifdef CONFIG_CMD_ETHSW + if (ethsw_define_functions(&vsc9953_cmd_func) < 0) + debug("Unable to use \"ethsw\" commands\n"); +#endif + printf("VSC9953 L2 switch initialized\n"); return; } - -#ifdef CONFIG_VSC9953_CMD -/* Enable/disable status of a VSC9953 port */ -static void vsc9953_port_status_set(int port_no, u8 enabled) -{ - struct vsc9953_qsys_reg *l2qsys_reg; - - /* Administrative down */ - if (!vsc9953_l2sw.port[port_no].enabled) - return; - - l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET + - VSC9953_QSYS_OFFSET); - - if (enabled) - setbits_le32(&l2qsys_reg->sys.switch_port_mode[port_no], - VSC9953_PORT_ENA); - else - clrbits_le32(&l2qsys_reg->sys.switch_port_mode[port_no], - VSC9953_PORT_ENA); -} - -/* Set all VSC9953 ports' status */ -static void vsc9953_port_all_status_set(u8 enabled) -{ - int i; - - for (i = 0; i < VSC9953_MAX_PORTS; i++) - vsc9953_port_status_set(i, enabled); -} - -/* Start autonegotiation for a VSC9953 PHY */ -static void vsc9953_phy_autoneg(int port_no) -{ - if (!vsc9953_l2sw.port[port_no].phydev) - return; - - if (vsc9953_l2sw.port[port_no].phydev->drv->startup( - vsc9953_l2sw.port[port_no].phydev)) - printf("Failed to start PHY for port %d\n", port_no); -} - -/* Start autonegotiation for all VSC9953 PHYs */ -static void vsc9953_phy_all_autoneg(void) -{ - int i; - - for (i = 0; i < VSC9953_MAX_PORTS; i++) - vsc9953_phy_autoneg(i); -} - -/* Print a VSC9953 port's configuration */ -static void vsc9953_port_config_show(int port_no) -{ - int speed; - int duplex; - int link; - u8 enabled; - u32 val; - struct vsc9953_qsys_reg *l2qsys_reg; - - l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET + - VSC9953_QSYS_OFFSET); - - val = in_le32(&l2qsys_reg->sys.switch_port_mode[port_no]); - enabled = vsc9953_l2sw.port[port_no].enabled && - (val & VSC9953_PORT_ENA); - - /* internal ports (8 and 9) are fixed */ - if (VSC9953_INTERNAL_PORT_CHECK(port_no)) { - link = 1; - speed = SPEED_2500; - duplex = DUPLEX_FULL; - } else { - if (vsc9953_l2sw.port[port_no].phydev) { - link = vsc9953_l2sw.port[port_no].phydev->link; - speed = vsc9953_l2sw.port[port_no].phydev->speed; - duplex = vsc9953_l2sw.port[port_no].phydev->duplex; - } else { - link = -1; - speed = -1; - duplex = -1; - } - } - - printf("%8d ", port_no); - printf("%8s ", enabled == 1 ? "enabled" : "disabled"); - printf("%8s ", link == 1 ? "up" : "down"); - - switch (speed) { - case SPEED_10: - printf("%8d ", 10); - break; - case SPEED_100: - printf("%8d ", 100); - break; - case SPEED_1000: - printf("%8d ", 1000); - break; - case SPEED_2500: - printf("%8d ", 2500); - break; - case SPEED_10000: - printf("%8d ", 10000); - break; - default: - printf("%8s ", "-"); - } - - printf("%8s\n", duplex == DUPLEX_FULL ? "full" : "half"); -} - -/* Print VSC9953 ports' configuration */ -static void vsc9953_port_all_config_show(void) -{ - int i; - - for (i = 0; i < VSC9953_MAX_PORTS; i++) - vsc9953_port_config_show(i); -} - -/* function to interpret commands starting with "ethsw " */ -static int do_ethsw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - u8 enable; - u32 port; - - if (argc < 4) - return -1; - - if (strcmp(argv[1], "port")) - return -1; - - if (!strcmp(argv[3], "show")) { - if (!strcmp(argv[2], "all")) { - vsc9953_phy_all_autoneg(); - printf("%8s %8s %8s %8s %8s\n", - "Port", "Status", "Link", "Speed", - "Duplex"); - vsc9953_port_all_config_show(); - return 0; - } else { - port = simple_strtoul(argv[2], NULL, 10); - if (!VSC9953_PORT_CHECK(port)) - return -1; - vsc9953_phy_autoneg(port); - printf("%8s %8s %8s %8s %8s\n", - "Port", "Status", "Link", "Speed", - "Duplex"); - vsc9953_port_config_show(port); - return 0; - } - } else if (!strcmp(argv[3], "enable")) { - enable = 1; - } else if (!strcmp(argv[3], "disable")) { - enable = 0; - } else { - return -1; - } - - if (!strcmp(argv[2], "all")) { - vsc9953_port_all_status_set(enable); - return 0; - } else { - port = simple_strtoul(argv[2], NULL, 10); - if (!VSC9953_PORT_CHECK(port)) - return -1; - vsc9953_port_status_set(port, enable); - return 0; - } - - return -1; -} - -U_BOOT_CMD(ethsw, 5, 0, do_ethsw, - "vsc9953 l2 switch commands", - "port enable|disable\n" - " - enable/disable an l2 switch port\n" - " port_no=0..9; use \"all\" for all ports\n" - "ethsw port show\n" - " - show an l2 switch port's configuration\n" - " port_no=0..9; use \"all\" for all ports\n" -); -#endif /* CONFIG_VSC9953_CMD */ -- cgit v1.1