From 96b2c792c295d01ce11ffc96f51dcf8896387cb4 Mon Sep 17 00:00:00 2001 From: Jukka Laitinen Date: Tue, 19 Dec 2023 15:20:48 +0200 Subject: [PATCH] drivers/net/ksz9477: Add simple port-based static VLAN configuration Add a static port-based VLAN configuration for KSZ9477 switch. This doesn't use the VLAN tagging, but is a switch's internal mechanism to simply configure if the packet forwarding is allowed from one port to another. Signed-off-by: Jukka Laitinen --- drivers/net/Kconfig | 64 ++++++++++++++++--- drivers/net/ksz9477.c | 124 ++++++++++++++++++++++++++++++++++++ drivers/net/ksz9477_reg.h | 8 +++ include/nuttx/net/ksz9477.h | 56 ++++++++++++++++ 4 files changed, 242 insertions(+), 10 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 5028e0db17521..926f9031fc41d 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -392,6 +392,18 @@ menuconfig NET_W5500 References: W5500 Datasheet, Version 1.0.9, 2013 WIZnet Co., Ltd. +if NET_W5500 + +config NET_W5500_NINTERFACES + int "Number of physical W5500 devices" + default 1 + range 1 1 + ---help--- + Specifies the number of physical WIZnet W5500 + devices that will be supported. + +endif # W5500 + config NET_KSZ9477 bool "Management interface for ksz9477 ethernet switch" default n @@ -416,17 +428,49 @@ config NET_KSZ9477_SPI endchoice -if NET_W5500 - -config NET_W5500_NINTERFACES - int "Number of physical W5500 devices" - default 1 - range 1 1 +config NET_KSZ9477_PORT_VLAN + bool "Use simple port-based VLAN configuration by default" + depends on NET_KSZ9477 + default n ---help--- - Specifies the number of physical WIZnet W5500 - devices that will be supported. - -endif # W5500 + Set connections between switch ports by default at switch init. + For each port, set a bit mask indicating to which ports it is allowed + to forward packets. Bit 0 is for PHY1 port, bit 1 for PHY2 port etc. + +config NET_KSZ9477_PORT_VLAN_PHY1 + hex "Bitmask for PHY1 port connections" + depends on NET_KSZ9477_PORT_VLAN + default 0x1f + +config NET_KSZ9477_PORT_VLAN_PHY2 + hex "Bitmask for PHY2 port connections" + depends on NET_KSZ9477_PORT_VLAN + default 0x1f + +config NET_KSZ9477_PORT_VLAN_PHY3 + hex "Bitmask for PHY3 port connections" + depends on NET_KSZ9477_PORT_VLAN + default 0x1f + +config NET_KSZ9477_PORT_VLAN_PHY4 + hex "Bitmask for PHY4 port connections" + depends on NET_KSZ9477_PORT_VLAN + default 0x1f + +config NET_KSZ9477_PORT_VLAN_PHY5 + hex "Bitmask for PHY4 port connections" + depends on NET_KSZ9477_PORT_VLAN + default 0x1f + +config NET_KSZ9477_PORT_VLAN_RMII + hex "Bitmask for RMII port connections" + depends on NET_KSZ9477_PORT_VLAN + default 0x1f + +config NET_KSZ9477_PORT_VLAN_SGMII + hex "Bitmask for SGMII port connections" + depends on NET_KSZ9477_PORT_VLAN + default 0x1f if ARCH_HAVE_PHY diff --git a/drivers/net/ksz9477.c b/drivers/net/ksz9477.c index 4cb5cb5d2ef3c..1f348ea318848 100644 --- a/drivers/net/ksz9477.c +++ b/drivers/net/ksz9477.c @@ -36,6 +36,21 @@ * Private Data ****************************************************************************/ +#ifdef CONFIG_NET_KSZ9477_PORT_VLAN + +static uint8_t g_port_vlan_config[] = +{ + CONFIG_NET_KSZ9477_PORT_VLAN_PHY1, + CONFIG_NET_KSZ9477_PORT_VLAN_PHY2, + CONFIG_NET_KSZ9477_PORT_VLAN_PHY3, + CONFIG_NET_KSZ9477_PORT_VLAN_PHY4, + CONFIG_NET_KSZ9477_PORT_VLAN_PHY5, + CONFIG_NET_KSZ9477_PORT_VLAN_RMII, + CONFIG_NET_KSZ9477_PORT_VLAN_SGMII +}; + +#endif + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -197,6 +212,95 @@ static int ksz9477_sgmii_write_indirect(uint32_t address, uint16_t *value, * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: ksz9477_enable_port_vlan + * + * Description: + * Enables static port-based VLAN, which can be configured in the switch + * queue management's port control registers + * + * Input Parameters: + * None + * + * Returned Value: + * OK or negative error number + * + ****************************************************************************/ + +int ksz9477_enable_port_vlan(void) +{ + uint32_t reg; + int ret = ksz9477_reg_read32(KSZ9477_Q_MGMT_CONTROL0, ®); + if (ret) + { + reg |= KSZ9477_Q_MGMT_PORT_VLAN_ENABLE; + ret = ksz9477_reg_write32(KSZ9477_Q_MGMT_CONTROL0, reg); + } + + return ret; +} + +/**************************************************************************** + * Name: ksz9477_disable_port_vlan + * + * Description: + * Disables the static port-based VLAN + * + * Input Parameters: + * None + * + * Returned Value: + * OK or negative error number + * + ****************************************************************************/ + +int ksz9477_disable_port_vlan(void) +{ + uint32_t reg; + int ret = ksz9477_reg_read32(KSZ9477_Q_MGMT_CONTROL0, ®); + if (ret) + { + reg &= ~KSZ9477_Q_MGMT_PORT_VLAN_ENABLE; + ret = ksz9477_reg_write32(KSZ9477_Q_MGMT_CONTROL0, reg); + } + + return ret; +} + +/**************************************************************************** + * Name: ksz9477_configure_port_vlan + * + * Description: + * Configures the static port-based VLAN for a single port + * The change will become effective next time when the switch is + * initialized. + * + * Input Parameters: + * port: The port being configured (1-7) + * disable: Bitmask of ports where frames may not be forwarded to. + * Bit 0 is for port 1, bit 1 for port 2 etc. + * enable: Bitmask of ports where frames may be forwarded to. + * Bit 0 is for port 1, bit 1 for port 2 etc. + * + * Returned Value: + * OK or negative error number + * + ****************************************************************************/ + +int ksz9477_configure_port_vlan(ksz9477_port_t port, uint8_t disable, + uint8_t enable) +{ + if (port < KSZ9477_PORT_PHY1 || port > KSZ9477_PORT_SGMII) + { + return -EINVAL; + } + + g_port_vlan_config[port - KSZ9477_PORT_PHY1] &= ~disable; + g_port_vlan_config[port - KSZ9477_PORT_PHY1] |= enable; + + return OK; +} + /**************************************************************************** * Name: ksz9477_init * @@ -215,6 +319,7 @@ static int ksz9477_sgmii_write_indirect(uint32_t address, uint16_t *value, int ksz9477_init(ksz9477_port_t master_port) { int ret; + int i; uint16_t regval16; uint32_t regval32; @@ -256,5 +361,24 @@ int ksz9477_init(ksz9477_port_t master_port) ®val16, 1); } + /* Configure the static port-based VLANs */ + +#ifdef CONFIG_NET_KSZ9477_PORT_VLAN + + /* Restrict traffic according to Q_MGMT_PORT_CONTROL1 registers */ + + ret = ksz9477_enable_port_vlan(); + + /* Configure traffic control for each port */ + + for (i = 0; ret == OK && i < 7; i++) + { + ret = ksz9477_reg_write32( + KSZ9477_Q_MGMT_PORT_CONTROL1(KSZ9477_PORT_PHY1 + i), + g_port_vlan_config[i]); + } + +#endif + return ret; } diff --git a/drivers/net/ksz9477_reg.h b/drivers/net/ksz9477_reg.h index 3423edb8ef603..1d75da8fe930f 100644 --- a/drivers/net/ksz9477_reg.h +++ b/drivers/net/ksz9477_reg.h @@ -67,6 +67,14 @@ #define KSZ9477_PORT_ADDRESS(p) KSZ9477_PORT_REG(p, 0x200) #define KSZ9477_PORT_DATA(p) KSZ9477_PORT_REG(p, 0x204) +/* Switch queue management registers */ + +#define KSZ9477_Q_MGMT_CONTROL0 0x0390 +#define KSZ9477_Q_MGMT_PORT_VLAN_ENABLE (1 << 1) + +#define KSZ9477_Q_MGMT_PORT_CONTROL0(p) KSZ9477_PORT_REG(p, 0xA00) +#define KSZ9477_Q_MGMT_PORT_CONTROL1(p) KSZ9477_PORT_REG(p, 0xA04) + #define KSZ9477_SGMII_PORT_ADDRESS KSZ9477_PORT_ADDRESS(7) #define KSZ9477_SGMII_PORT_DATA KSZ9477_PORT_DATA(7) diff --git a/include/nuttx/net/ksz9477.h b/include/nuttx/net/ksz9477.h index cc37adb48a40a..3ca96f1fe6cd2 100644 --- a/include/nuttx/net/ksz9477.h +++ b/include/nuttx/net/ksz9477.h @@ -91,6 +91,62 @@ int ksz9477_i2c_init(struct i2c_master_s *i2c_bus, # error Only I2c interface currently supported #endif +/**************************************************************************** + * Name: ksz9477_enable_port_vlan + * + * Description: + * Enables static port-based VLAN, which can be configured in the switch + * queue management's port control registers + * + * Input Parameters: + * None + * + * Returned Value: + * OK or negative error number + * + ****************************************************************************/ + +int ksz9477_enable_port_vlan(void); + +/**************************************************************************** + * Name: ksz9477_disable_port_vlan + * + * Description: + * Disables the static port-based VLAN + * + * Input Parameters: + * None + * + * Returned Value: + * OK or negative error number + * + ****************************************************************************/ + +int ksz9477_disable_port_vlan(void); + +/**************************************************************************** + * Name: ksz9477_configure_port_vlan + * + * Description: + * Configures the static port-based VLAN for a single port + * The change will become effective next time when the switch is + * initialized. + * + * Input Parameters: + * port: The port being configured (1-7) + * disable: Bitmask of ports where frames may not be forwarded to. + * Bit 0 is for port 1, bit 1 for port 2 etc. + * enable: Bitmask of ports where frames may be forwarded to. + * Bit 0 is for port 1, bit 1 for port 2 etc. + * + * Returned Value: + * OK or negative error number + * + ****************************************************************************/ + +int ksz9477_configure_port_vlan(ksz9477_port_t port, uint8_t disable, + uint8_t enable); + #if defined(__cplusplus) } #endif