Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: dsa: microchip: add the support for set_ageing_time

KSZ9477 has the 11 bit ageing count value which is split across the two
registers. And LAN937x has the 20 bit ageing count which is also split
into two registers. Each count in the registers represents 1 second.
This patch add the support for ageing time for KSZ9477 and LAN937x
series of switch.

Signed-off-by: Arun Ramadoss <arun.ramadoss@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Arun Ramadoss and committed by
David S. Miller
2c119d99 862deb68

+67 -1
+25
drivers/net/dsa/microchip/ksz9477.c
··· 963 963 config->mac_capabilities |= MAC_1000FD; 964 964 } 965 965 966 + int ksz9477_set_ageing_time(struct ksz_device *dev, unsigned int msecs) 967 + { 968 + u32 secs = msecs / 1000; 969 + u8 value; 970 + u8 data; 971 + int ret; 972 + 973 + value = FIELD_GET(SW_AGE_PERIOD_7_0_M, secs); 974 + 975 + ret = ksz_write8(dev, REG_SW_LUE_CTRL_3, value); 976 + if (ret < 0) 977 + return ret; 978 + 979 + data = FIELD_GET(SW_AGE_PERIOD_10_8_M, secs); 980 + 981 + ret = ksz_read8(dev, REG_SW_LUE_CTRL_0, &value); 982 + if (ret < 0) 983 + return ret; 984 + 985 + value &= ~SW_AGE_CNT_M; 986 + value |= FIELD_PREP(SW_AGE_CNT_M, data); 987 + 988 + return ksz_write8(dev, REG_SW_LUE_CTRL_0, value); 989 + } 990 + 966 991 void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port) 967 992 { 968 993 struct dsa_switch *ds = dev->ds;
+1
drivers/net/dsa/microchip/ksz9477.h
··· 16 16 void ksz9477_cfg_port_member(struct ksz_device *dev, int port, u8 member); 17 17 void ksz9477_flush_dyn_mac_table(struct ksz_device *dev, int port); 18 18 void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port); 19 + int ksz9477_set_ageing_time(struct ksz_device *dev, unsigned int msecs); 19 20 int ksz9477_r_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 *data); 20 21 int ksz9477_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val); 21 22 void ksz9477_r_mib_cnt(struct ksz_device *dev, int port, u16 addr, u64 *cnt);
+3 -1
drivers/net/dsa/microchip/ksz9477_reg.h
··· 189 189 190 190 #define SW_VLAN_ENABLE BIT(7) 191 191 #define SW_DROP_INVALID_VID BIT(6) 192 - #define SW_AGE_CNT_M 0x7 192 + #define SW_AGE_CNT_M GENMASK(5, 3) 193 193 #define SW_AGE_CNT_S 3 194 + #define SW_AGE_PERIOD_10_8_M GENMASK(10, 8) 194 195 #define SW_RESV_MCAST_ENABLE BIT(2) 195 196 #define SW_HASH_OPTION_M 0x03 196 197 #define SW_HASH_OPTION_CRC 1 ··· 226 225 #define SW_PRIO_LOWEST_DA_SA 3 227 226 228 227 #define REG_SW_LUE_CTRL_3 0x0313 228 + #define SW_AGE_PERIOD_7_0_M GENMASK(7, 0) 229 229 230 230 #define REG_SW_LUE_INT_STATUS 0x0314 231 231 #define REG_SW_LUE_INT_ENABLE 0x0315
+13
drivers/net/dsa/microchip/ksz_common.c
··· 183 183 .cfg_port_member = ksz9477_cfg_port_member, 184 184 .flush_dyn_mac_table = ksz9477_flush_dyn_mac_table, 185 185 .port_setup = ksz9477_port_setup, 186 + .set_ageing_time = ksz9477_set_ageing_time, 186 187 .r_phy = ksz9477_r_phy, 187 188 .w_phy = ksz9477_w_phy, 188 189 .r_mib_cnt = ksz9477_r_mib_cnt, ··· 219 218 .cfg_port_member = ksz9477_cfg_port_member, 220 219 .flush_dyn_mac_table = ksz9477_flush_dyn_mac_table, 221 220 .port_setup = lan937x_port_setup, 221 + .set_ageing_time = lan937x_set_ageing_time, 222 222 .r_phy = lan937x_r_phy, 223 223 .w_phy = lan937x_w_phy, 224 224 .r_mib_cnt = ksz9477_r_mib_cnt, ··· 1895 1893 dev->dev_ops->flush_dyn_mac_table(dev, port); 1896 1894 } 1897 1895 1896 + static int ksz_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) 1897 + { 1898 + struct ksz_device *dev = ds->priv; 1899 + 1900 + if (!dev->dev_ops->set_ageing_time) 1901 + return -EOPNOTSUPP; 1902 + 1903 + return dev->dev_ops->set_ageing_time(dev, msecs); 1904 + } 1905 + 1898 1906 static int ksz_port_fdb_add(struct dsa_switch *ds, int port, 1899 1907 const unsigned char *addr, u16 vid, 1900 1908 struct dsa_db db) ··· 2487 2475 .phylink_mac_link_up = ksz_phylink_mac_link_up, 2488 2476 .phylink_mac_link_down = ksz_mac_link_down, 2489 2477 .port_enable = ksz_enable_port, 2478 + .set_ageing_time = ksz_set_ageing_time, 2490 2479 .get_strings = ksz_get_strings, 2491 2480 .get_ethtool_stats = ksz_get_ethtool_stats, 2492 2481 .get_sset_count = ksz_sset_count,
+1
drivers/net/dsa/microchip/ksz_common.h
··· 281 281 void (*flush_dyn_mac_table)(struct ksz_device *dev, int port); 282 282 void (*port_cleanup)(struct ksz_device *dev, int port); 283 283 void (*port_setup)(struct ksz_device *dev, int port, bool cpu_port); 284 + int (*set_ageing_time)(struct ksz_device *dev, unsigned int msecs); 284 285 int (*r_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 *val); 285 286 int (*w_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 val); 286 287 void (*r_mib_cnt)(struct ksz_device *dev, int port, u16 addr,
+1
drivers/net/dsa/microchip/lan937x.h
··· 19 19 void lan937x_phylink_get_caps(struct ksz_device *dev, int port, 20 20 struct phylink_config *config); 21 21 void lan937x_setup_rgmii_delay(struct ksz_device *dev, int port); 22 + int lan937x_set_ageing_time(struct ksz_device *dev, unsigned int msecs); 22 23 #endif
+17
drivers/net/dsa/microchip/lan937x_main.c
··· 367 367 return 0; 368 368 } 369 369 370 + int lan937x_set_ageing_time(struct ksz_device *dev, unsigned int msecs) 371 + { 372 + u32 secs = msecs / 1000; 373 + u32 value; 374 + int ret; 375 + 376 + value = FIELD_GET(SW_AGE_PERIOD_7_0_M, secs); 377 + 378 + ret = ksz_write8(dev, REG_SW_AGE_PERIOD__1, value); 379 + if (ret < 0) 380 + return ret; 381 + 382 + value = FIELD_GET(SW_AGE_PERIOD_19_8_M, secs); 383 + 384 + return ksz_write16(dev, REG_SW_AGE_PERIOD__2, value); 385 + } 386 + 370 387 static void lan937x_set_tune_adj(struct ksz_device *dev, int port, 371 388 u16 reg, u8 val) 372 389 {
+6
drivers/net/dsa/microchip/lan937x_reg.h
··· 62 62 #define SW_FAST_AGING BIT(1) 63 63 #define SW_LINK_AUTO_AGING BIT(0) 64 64 65 + #define REG_SW_AGE_PERIOD__1 0x0313 66 + #define SW_AGE_PERIOD_7_0_M GENMASK(7, 0) 67 + 68 + #define REG_SW_AGE_PERIOD__2 0x0320 69 + #define SW_AGE_PERIOD_19_8_M GENMASK(19, 8) 70 + 65 71 #define REG_SW_MAC_CTRL_0 0x0330 66 72 #define SW_NEW_BACKOFF BIT(7) 67 73 #define SW_PAUSE_UNH_MODE BIT(1)