4873 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Microchip switch driver main logic4 *5 * Copyright (C) 2017-2024 Microchip Technology Inc.6 */7 8#include <linux/delay.h>9#include <linux/dsa/ksz_common.h>10#include <linux/export.h>11#include <linux/gpio/consumer.h>12#include <linux/kernel.h>13#include <linux/module.h>14#include <linux/platform_data/microchip-ksz.h>15#include <linux/phy.h>16#include <linux/etherdevice.h>17#include <linux/if_bridge.h>18#include <linux/if_vlan.h>19#include <linux/if_hsr.h>20#include <linux/irq.h>21#include <linux/irqdomain.h>22#include <linux/of.h>23#include <linux/of_mdio.h>24#include <linux/of_net.h>25#include <linux/micrel_phy.h>26#include <net/dsa.h>27#include <net/ieee8021q.h>28#include <net/pkt_cls.h>29#include <net/switchdev.h>30 31#include "ksz_common.h"32#include "ksz_dcb.h"33#include "ksz_ptp.h"34#include "ksz8.h"35#include "ksz9477.h"36#include "lan937x.h"37 38#define MIB_COUNTER_NUM 0x2039 40struct ksz_stats_raw {41 u64 rx_hi;42 u64 rx_undersize;43 u64 rx_fragments;44 u64 rx_oversize;45 u64 rx_jabbers;46 u64 rx_symbol_err;47 u64 rx_crc_err;48 u64 rx_align_err;49 u64 rx_mac_ctrl;50 u64 rx_pause;51 u64 rx_bcast;52 u64 rx_mcast;53 u64 rx_ucast;54 u64 rx_64_or_less;55 u64 rx_65_127;56 u64 rx_128_255;57 u64 rx_256_511;58 u64 rx_512_1023;59 u64 rx_1024_1522;60 u64 rx_1523_2000;61 u64 rx_2001;62 u64 tx_hi;63 u64 tx_late_col;64 u64 tx_pause;65 u64 tx_bcast;66 u64 tx_mcast;67 u64 tx_ucast;68 u64 tx_deferred;69 u64 tx_total_col;70 u64 tx_exc_col;71 u64 tx_single_col;72 u64 tx_mult_col;73 u64 rx_total;74 u64 tx_total;75 u64 rx_discards;76 u64 tx_discards;77};78 79struct ksz88xx_stats_raw {80 u64 rx;81 u64 rx_hi;82 u64 rx_undersize;83 u64 rx_fragments;84 u64 rx_oversize;85 u64 rx_jabbers;86 u64 rx_symbol_err;87 u64 rx_crc_err;88 u64 rx_align_err;89 u64 rx_mac_ctrl;90 u64 rx_pause;91 u64 rx_bcast;92 u64 rx_mcast;93 u64 rx_ucast;94 u64 rx_64_or_less;95 u64 rx_65_127;96 u64 rx_128_255;97 u64 rx_256_511;98 u64 rx_512_1023;99 u64 rx_1024_1522;100 u64 tx;101 u64 tx_hi;102 u64 tx_late_col;103 u64 tx_pause;104 u64 tx_bcast;105 u64 tx_mcast;106 u64 tx_ucast;107 u64 tx_deferred;108 u64 tx_total_col;109 u64 tx_exc_col;110 u64 tx_single_col;111 u64 tx_mult_col;112 u64 rx_discards;113 u64 tx_discards;114};115 116static const struct ksz_mib_names ksz88xx_mib_names[] = {117 { 0x00, "rx" },118 { 0x01, "rx_hi" },119 { 0x02, "rx_undersize" },120 { 0x03, "rx_fragments" },121 { 0x04, "rx_oversize" },122 { 0x05, "rx_jabbers" },123 { 0x06, "rx_symbol_err" },124 { 0x07, "rx_crc_err" },125 { 0x08, "rx_align_err" },126 { 0x09, "rx_mac_ctrl" },127 { 0x0a, "rx_pause" },128 { 0x0b, "rx_bcast" },129 { 0x0c, "rx_mcast" },130 { 0x0d, "rx_ucast" },131 { 0x0e, "rx_64_or_less" },132 { 0x0f, "rx_65_127" },133 { 0x10, "rx_128_255" },134 { 0x11, "rx_256_511" },135 { 0x12, "rx_512_1023" },136 { 0x13, "rx_1024_1522" },137 { 0x14, "tx" },138 { 0x15, "tx_hi" },139 { 0x16, "tx_late_col" },140 { 0x17, "tx_pause" },141 { 0x18, "tx_bcast" },142 { 0x19, "tx_mcast" },143 { 0x1a, "tx_ucast" },144 { 0x1b, "tx_deferred" },145 { 0x1c, "tx_total_col" },146 { 0x1d, "tx_exc_col" },147 { 0x1e, "tx_single_col" },148 { 0x1f, "tx_mult_col" },149 { 0x100, "rx_discards" },150 { 0x101, "tx_discards" },151};152 153static const struct ksz_mib_names ksz9477_mib_names[] = {154 { 0x00, "rx_hi" },155 { 0x01, "rx_undersize" },156 { 0x02, "rx_fragments" },157 { 0x03, "rx_oversize" },158 { 0x04, "rx_jabbers" },159 { 0x05, "rx_symbol_err" },160 { 0x06, "rx_crc_err" },161 { 0x07, "rx_align_err" },162 { 0x08, "rx_mac_ctrl" },163 { 0x09, "rx_pause" },164 { 0x0A, "rx_bcast" },165 { 0x0B, "rx_mcast" },166 { 0x0C, "rx_ucast" },167 { 0x0D, "rx_64_or_less" },168 { 0x0E, "rx_65_127" },169 { 0x0F, "rx_128_255" },170 { 0x10, "rx_256_511" },171 { 0x11, "rx_512_1023" },172 { 0x12, "rx_1024_1522" },173 { 0x13, "rx_1523_2000" },174 { 0x14, "rx_2001" },175 { 0x15, "tx_hi" },176 { 0x16, "tx_late_col" },177 { 0x17, "tx_pause" },178 { 0x18, "tx_bcast" },179 { 0x19, "tx_mcast" },180 { 0x1A, "tx_ucast" },181 { 0x1B, "tx_deferred" },182 { 0x1C, "tx_total_col" },183 { 0x1D, "tx_exc_col" },184 { 0x1E, "tx_single_col" },185 { 0x1F, "tx_mult_col" },186 { 0x80, "rx_total" },187 { 0x81, "tx_total" },188 { 0x82, "rx_discards" },189 { 0x83, "tx_discards" },190};191 192struct ksz_driver_strength_prop {193 const char *name;194 int offset;195 int value;196};197 198enum ksz_driver_strength_type {199 KSZ_DRIVER_STRENGTH_HI,200 KSZ_DRIVER_STRENGTH_LO,201 KSZ_DRIVER_STRENGTH_IO,202};203 204/**205 * struct ksz_drive_strength - drive strength mapping206 * @reg_val: register value207 * @microamp: microamp value208 */209struct ksz_drive_strength {210 u32 reg_val;211 u32 microamp;212};213 214/* ksz9477_drive_strengths - Drive strength mapping for KSZ9477 variants215 *216 * This values are not documented in KSZ9477 variants but confirmed by217 * Microchip that KSZ9477, KSZ9567, KSZ8567, KSZ9897, KSZ9896, KSZ9563, KSZ9893218 * and KSZ8563 are using same register (drive strength) settings like KSZ8795.219 *220 * Documentation in KSZ8795CLX provides more information with some221 * recommendations:222 * - for high speed signals223 * 1. 4 mA or 8 mA is often used for MII, RMII, and SPI interface with using224 * 2.5V or 3.3V VDDIO.225 * 2. 12 mA or 16 mA is often used for MII, RMII, and SPI interface with226 * using 1.8V VDDIO.227 * 3. 20 mA or 24 mA is often used for GMII/RGMII interface with using 2.5V228 * or 3.3V VDDIO.229 * 4. 28 mA is often used for GMII/RGMII interface with using 1.8V VDDIO.230 * 5. In same interface, the heavy loading should use higher one of the231 * drive current strength.232 * - for low speed signals233 * 1. 3.3V VDDIO, use either 4 mA or 8 mA.234 * 2. 2.5V VDDIO, use either 8 mA or 12 mA.235 * 3. 1.8V VDDIO, use either 12 mA or 16 mA.236 * 4. If it is heavy loading, can use higher drive current strength.237 */238static const struct ksz_drive_strength ksz9477_drive_strengths[] = {239 { SW_DRIVE_STRENGTH_2MA, 2000 },240 { SW_DRIVE_STRENGTH_4MA, 4000 },241 { SW_DRIVE_STRENGTH_8MA, 8000 },242 { SW_DRIVE_STRENGTH_12MA, 12000 },243 { SW_DRIVE_STRENGTH_16MA, 16000 },244 { SW_DRIVE_STRENGTH_20MA, 20000 },245 { SW_DRIVE_STRENGTH_24MA, 24000 },246 { SW_DRIVE_STRENGTH_28MA, 28000 },247};248 249/* ksz88x3_drive_strengths - Drive strength mapping for KSZ8863, KSZ8873, ..250 * variants.251 * This values are documented in KSZ8873 and KSZ8863 datasheets.252 */253static const struct ksz_drive_strength ksz88x3_drive_strengths[] = {254 { 0, 8000 },255 { KSZ8873_DRIVE_STRENGTH_16MA, 16000 },256};257 258static void ksz88x3_phylink_mac_config(struct phylink_config *config,259 unsigned int mode,260 const struct phylink_link_state *state);261static void ksz_phylink_mac_config(struct phylink_config *config,262 unsigned int mode,263 const struct phylink_link_state *state);264static void ksz_phylink_mac_link_down(struct phylink_config *config,265 unsigned int mode,266 phy_interface_t interface);267 268static const struct phylink_mac_ops ksz88x3_phylink_mac_ops = {269 .mac_config = ksz88x3_phylink_mac_config,270 .mac_link_down = ksz_phylink_mac_link_down,271 .mac_link_up = ksz8_phylink_mac_link_up,272};273 274static const struct phylink_mac_ops ksz8_phylink_mac_ops = {275 .mac_config = ksz_phylink_mac_config,276 .mac_link_down = ksz_phylink_mac_link_down,277 .mac_link_up = ksz8_phylink_mac_link_up,278};279 280static const struct ksz_dev_ops ksz88xx_dev_ops = {281 .setup = ksz8_setup,282 .get_port_addr = ksz8_get_port_addr,283 .cfg_port_member = ksz8_cfg_port_member,284 .flush_dyn_mac_table = ksz8_flush_dyn_mac_table,285 .port_setup = ksz8_port_setup,286 .r_phy = ksz8_r_phy,287 .w_phy = ksz8_w_phy,288 .r_mib_cnt = ksz8_r_mib_cnt,289 .r_mib_pkt = ksz8_r_mib_pkt,290 .r_mib_stat64 = ksz88xx_r_mib_stats64,291 .freeze_mib = ksz8_freeze_mib,292 .port_init_cnt = ksz8_port_init_cnt,293 .fdb_dump = ksz8_fdb_dump,294 .fdb_add = ksz8_fdb_add,295 .fdb_del = ksz8_fdb_del,296 .mdb_add = ksz8_mdb_add,297 .mdb_del = ksz8_mdb_del,298 .vlan_filtering = ksz8_port_vlan_filtering,299 .vlan_add = ksz8_port_vlan_add,300 .vlan_del = ksz8_port_vlan_del,301 .mirror_add = ksz8_port_mirror_add,302 .mirror_del = ksz8_port_mirror_del,303 .get_caps = ksz8_get_caps,304 .config_cpu_port = ksz8_config_cpu_port,305 .enable_stp_addr = ksz8_enable_stp_addr,306 .reset = ksz8_reset_switch,307 .init = ksz8_switch_init,308 .exit = ksz8_switch_exit,309 .change_mtu = ksz8_change_mtu,310 .pme_write8 = ksz8_pme_write8,311 .pme_pread8 = ksz8_pme_pread8,312 .pme_pwrite8 = ksz8_pme_pwrite8,313};314 315static const struct ksz_dev_ops ksz87xx_dev_ops = {316 .setup = ksz8_setup,317 .get_port_addr = ksz8_get_port_addr,318 .cfg_port_member = ksz8_cfg_port_member,319 .flush_dyn_mac_table = ksz8_flush_dyn_mac_table,320 .port_setup = ksz8_port_setup,321 .r_phy = ksz8_r_phy,322 .w_phy = ksz8_w_phy,323 .r_mib_cnt = ksz8_r_mib_cnt,324 .r_mib_pkt = ksz8_r_mib_pkt,325 .r_mib_stat64 = ksz_r_mib_stats64,326 .freeze_mib = ksz8_freeze_mib,327 .port_init_cnt = ksz8_port_init_cnt,328 .fdb_dump = ksz8_fdb_dump,329 .fdb_add = ksz8_fdb_add,330 .fdb_del = ksz8_fdb_del,331 .mdb_add = ksz8_mdb_add,332 .mdb_del = ksz8_mdb_del,333 .vlan_filtering = ksz8_port_vlan_filtering,334 .vlan_add = ksz8_port_vlan_add,335 .vlan_del = ksz8_port_vlan_del,336 .mirror_add = ksz8_port_mirror_add,337 .mirror_del = ksz8_port_mirror_del,338 .get_caps = ksz8_get_caps,339 .config_cpu_port = ksz8_config_cpu_port,340 .enable_stp_addr = ksz8_enable_stp_addr,341 .reset = ksz8_reset_switch,342 .init = ksz8_switch_init,343 .exit = ksz8_switch_exit,344 .change_mtu = ksz8_change_mtu,345 .pme_write8 = ksz8_pme_write8,346 .pme_pread8 = ksz8_pme_pread8,347 .pme_pwrite8 = ksz8_pme_pwrite8,348};349 350static void ksz9477_phylink_mac_link_up(struct phylink_config *config,351 struct phy_device *phydev,352 unsigned int mode,353 phy_interface_t interface,354 int speed, int duplex, bool tx_pause,355 bool rx_pause);356 357static const struct phylink_mac_ops ksz9477_phylink_mac_ops = {358 .mac_config = ksz_phylink_mac_config,359 .mac_link_down = ksz_phylink_mac_link_down,360 .mac_link_up = ksz9477_phylink_mac_link_up,361};362 363static const struct ksz_dev_ops ksz9477_dev_ops = {364 .setup = ksz9477_setup,365 .get_port_addr = ksz9477_get_port_addr,366 .cfg_port_member = ksz9477_cfg_port_member,367 .flush_dyn_mac_table = ksz9477_flush_dyn_mac_table,368 .port_setup = ksz9477_port_setup,369 .set_ageing_time = ksz9477_set_ageing_time,370 .r_phy = ksz9477_r_phy,371 .w_phy = ksz9477_w_phy,372 .r_mib_cnt = ksz9477_r_mib_cnt,373 .r_mib_pkt = ksz9477_r_mib_pkt,374 .r_mib_stat64 = ksz_r_mib_stats64,375 .freeze_mib = ksz9477_freeze_mib,376 .port_init_cnt = ksz9477_port_init_cnt,377 .vlan_filtering = ksz9477_port_vlan_filtering,378 .vlan_add = ksz9477_port_vlan_add,379 .vlan_del = ksz9477_port_vlan_del,380 .mirror_add = ksz9477_port_mirror_add,381 .mirror_del = ksz9477_port_mirror_del,382 .get_caps = ksz9477_get_caps,383 .fdb_dump = ksz9477_fdb_dump,384 .fdb_add = ksz9477_fdb_add,385 .fdb_del = ksz9477_fdb_del,386 .mdb_add = ksz9477_mdb_add,387 .mdb_del = ksz9477_mdb_del,388 .change_mtu = ksz9477_change_mtu,389 .pme_write8 = ksz_write8,390 .pme_pread8 = ksz_pread8,391 .pme_pwrite8 = ksz_pwrite8,392 .config_cpu_port = ksz9477_config_cpu_port,393 .tc_cbs_set_cinc = ksz9477_tc_cbs_set_cinc,394 .enable_stp_addr = ksz9477_enable_stp_addr,395 .reset = ksz9477_reset_switch,396 .init = ksz9477_switch_init,397 .exit = ksz9477_switch_exit,398};399 400static const struct phylink_mac_ops lan937x_phylink_mac_ops = {401 .mac_config = ksz_phylink_mac_config,402 .mac_link_down = ksz_phylink_mac_link_down,403 .mac_link_up = ksz9477_phylink_mac_link_up,404};405 406static const struct ksz_dev_ops lan937x_dev_ops = {407 .setup = lan937x_setup,408 .teardown = lan937x_teardown,409 .get_port_addr = ksz9477_get_port_addr,410 .cfg_port_member = ksz9477_cfg_port_member,411 .flush_dyn_mac_table = ksz9477_flush_dyn_mac_table,412 .port_setup = lan937x_port_setup,413 .set_ageing_time = lan937x_set_ageing_time,414 .r_phy = lan937x_r_phy,415 .w_phy = lan937x_w_phy,416 .r_mib_cnt = ksz9477_r_mib_cnt,417 .r_mib_pkt = ksz9477_r_mib_pkt,418 .r_mib_stat64 = ksz_r_mib_stats64,419 .freeze_mib = ksz9477_freeze_mib,420 .port_init_cnt = ksz9477_port_init_cnt,421 .vlan_filtering = ksz9477_port_vlan_filtering,422 .vlan_add = ksz9477_port_vlan_add,423 .vlan_del = ksz9477_port_vlan_del,424 .mirror_add = ksz9477_port_mirror_add,425 .mirror_del = ksz9477_port_mirror_del,426 .get_caps = lan937x_phylink_get_caps,427 .setup_rgmii_delay = lan937x_setup_rgmii_delay,428 .fdb_dump = ksz9477_fdb_dump,429 .fdb_add = ksz9477_fdb_add,430 .fdb_del = ksz9477_fdb_del,431 .mdb_add = ksz9477_mdb_add,432 .mdb_del = ksz9477_mdb_del,433 .change_mtu = lan937x_change_mtu,434 .config_cpu_port = lan937x_config_cpu_port,435 .tc_cbs_set_cinc = lan937x_tc_cbs_set_cinc,436 .enable_stp_addr = ksz9477_enable_stp_addr,437 .reset = lan937x_reset_switch,438 .init = lan937x_switch_init,439 .exit = lan937x_switch_exit,440};441 442static const u16 ksz8795_regs[] = {443 [REG_SW_MAC_ADDR] = 0x68,444 [REG_IND_CTRL_0] = 0x6E,445 [REG_IND_DATA_8] = 0x70,446 [REG_IND_DATA_CHECK] = 0x72,447 [REG_IND_DATA_HI] = 0x71,448 [REG_IND_DATA_LO] = 0x75,449 [REG_IND_MIB_CHECK] = 0x74,450 [REG_IND_BYTE] = 0xA0,451 [P_FORCE_CTRL] = 0x0C,452 [P_LINK_STATUS] = 0x0E,453 [P_LOCAL_CTRL] = 0x07,454 [P_NEG_RESTART_CTRL] = 0x0D,455 [P_REMOTE_STATUS] = 0x08,456 [P_SPEED_STATUS] = 0x09,457 [S_TAIL_TAG_CTRL] = 0x0C,458 [P_STP_CTRL] = 0x02,459 [S_START_CTRL] = 0x01,460 [S_BROADCAST_CTRL] = 0x06,461 [S_MULTICAST_CTRL] = 0x04,462 [P_XMII_CTRL_0] = 0x06,463 [P_XMII_CTRL_1] = 0x06,464 [REG_SW_PME_CTRL] = 0x8003,465 [REG_PORT_PME_STATUS] = 0x8003,466 [REG_PORT_PME_CTRL] = 0x8007,467};468 469static const u32 ksz8795_masks[] = {470 [PORT_802_1P_REMAPPING] = BIT(7),471 [SW_TAIL_TAG_ENABLE] = BIT(1),472 [MIB_COUNTER_OVERFLOW] = BIT(6),473 [MIB_COUNTER_VALID] = BIT(5),474 [VLAN_TABLE_FID] = GENMASK(6, 0),475 [VLAN_TABLE_MEMBERSHIP] = GENMASK(11, 7),476 [VLAN_TABLE_VALID] = BIT(12),477 [STATIC_MAC_TABLE_VALID] = BIT(21),478 [STATIC_MAC_TABLE_USE_FID] = BIT(23),479 [STATIC_MAC_TABLE_FID] = GENMASK(30, 24),480 [STATIC_MAC_TABLE_OVERRIDE] = BIT(22),481 [STATIC_MAC_TABLE_FWD_PORTS] = GENMASK(20, 16),482 [DYNAMIC_MAC_TABLE_ENTRIES_H] = GENMASK(6, 0),483 [DYNAMIC_MAC_TABLE_MAC_EMPTY] = BIT(7),484 [DYNAMIC_MAC_TABLE_NOT_READY] = BIT(7),485 [DYNAMIC_MAC_TABLE_ENTRIES] = GENMASK(31, 29),486 [DYNAMIC_MAC_TABLE_FID] = GENMASK(22, 16),487 [DYNAMIC_MAC_TABLE_SRC_PORT] = GENMASK(26, 24),488 [DYNAMIC_MAC_TABLE_TIMESTAMP] = GENMASK(28, 27),489 [P_MII_TX_FLOW_CTRL] = BIT(5),490 [P_MII_RX_FLOW_CTRL] = BIT(5),491};492 493static const u8 ksz8795_xmii_ctrl0[] = {494 [P_MII_100MBIT] = 0,495 [P_MII_10MBIT] = 1,496 [P_MII_FULL_DUPLEX] = 0,497 [P_MII_HALF_DUPLEX] = 1,498};499 500static const u8 ksz8795_xmii_ctrl1[] = {501 [P_RGMII_SEL] = 3,502 [P_GMII_SEL] = 2,503 [P_RMII_SEL] = 1,504 [P_MII_SEL] = 0,505 [P_GMII_1GBIT] = 1,506 [P_GMII_NOT_1GBIT] = 0,507};508 509static const u8 ksz8795_shifts[] = {510 [VLAN_TABLE_MEMBERSHIP_S] = 7,511 [VLAN_TABLE] = 16,512 [STATIC_MAC_FWD_PORTS] = 16,513 [STATIC_MAC_FID] = 24,514 [DYNAMIC_MAC_ENTRIES_H] = 3,515 [DYNAMIC_MAC_ENTRIES] = 29,516 [DYNAMIC_MAC_FID] = 16,517 [DYNAMIC_MAC_TIMESTAMP] = 27,518 [DYNAMIC_MAC_SRC_PORT] = 24,519};520 521static const u16 ksz8863_regs[] = {522 [REG_SW_MAC_ADDR] = 0x70,523 [REG_IND_CTRL_0] = 0x79,524 [REG_IND_DATA_8] = 0x7B,525 [REG_IND_DATA_CHECK] = 0x7B,526 [REG_IND_DATA_HI] = 0x7C,527 [REG_IND_DATA_LO] = 0x80,528 [REG_IND_MIB_CHECK] = 0x80,529 [P_FORCE_CTRL] = 0x0C,530 [P_LINK_STATUS] = 0x0E,531 [P_LOCAL_CTRL] = 0x0C,532 [P_NEG_RESTART_CTRL] = 0x0D,533 [P_REMOTE_STATUS] = 0x0E,534 [P_SPEED_STATUS] = 0x0F,535 [S_TAIL_TAG_CTRL] = 0x03,536 [P_STP_CTRL] = 0x02,537 [S_START_CTRL] = 0x01,538 [S_BROADCAST_CTRL] = 0x06,539 [S_MULTICAST_CTRL] = 0x04,540};541 542static const u32 ksz8863_masks[] = {543 [PORT_802_1P_REMAPPING] = BIT(3),544 [SW_TAIL_TAG_ENABLE] = BIT(6),545 [MIB_COUNTER_OVERFLOW] = BIT(7),546 [MIB_COUNTER_VALID] = BIT(6),547 [VLAN_TABLE_FID] = GENMASK(15, 12),548 [VLAN_TABLE_MEMBERSHIP] = GENMASK(18, 16),549 [VLAN_TABLE_VALID] = BIT(19),550 [STATIC_MAC_TABLE_VALID] = BIT(19),551 [STATIC_MAC_TABLE_USE_FID] = BIT(21),552 [STATIC_MAC_TABLE_FID] = GENMASK(25, 22),553 [STATIC_MAC_TABLE_OVERRIDE] = BIT(20),554 [STATIC_MAC_TABLE_FWD_PORTS] = GENMASK(18, 16),555 [DYNAMIC_MAC_TABLE_ENTRIES_H] = GENMASK(1, 0),556 [DYNAMIC_MAC_TABLE_MAC_EMPTY] = BIT(2),557 [DYNAMIC_MAC_TABLE_NOT_READY] = BIT(7),558 [DYNAMIC_MAC_TABLE_ENTRIES] = GENMASK(31, 24),559 [DYNAMIC_MAC_TABLE_FID] = GENMASK(19, 16),560 [DYNAMIC_MAC_TABLE_SRC_PORT] = GENMASK(21, 20),561 [DYNAMIC_MAC_TABLE_TIMESTAMP] = GENMASK(23, 22),562};563 564static u8 ksz8863_shifts[] = {565 [VLAN_TABLE_MEMBERSHIP_S] = 16,566 [STATIC_MAC_FWD_PORTS] = 16,567 [STATIC_MAC_FID] = 22,568 [DYNAMIC_MAC_ENTRIES_H] = 8,569 [DYNAMIC_MAC_ENTRIES] = 24,570 [DYNAMIC_MAC_FID] = 16,571 [DYNAMIC_MAC_TIMESTAMP] = 22,572 [DYNAMIC_MAC_SRC_PORT] = 20,573};574 575static const u16 ksz8895_regs[] = {576 [REG_SW_MAC_ADDR] = 0x68,577 [REG_IND_CTRL_0] = 0x6E,578 [REG_IND_DATA_8] = 0x70,579 [REG_IND_DATA_CHECK] = 0x72,580 [REG_IND_DATA_HI] = 0x71,581 [REG_IND_DATA_LO] = 0x75,582 [REG_IND_MIB_CHECK] = 0x75,583 [P_FORCE_CTRL] = 0x0C,584 [P_LINK_STATUS] = 0x0E,585 [P_LOCAL_CTRL] = 0x0C,586 [P_NEG_RESTART_CTRL] = 0x0D,587 [P_REMOTE_STATUS] = 0x0E,588 [P_SPEED_STATUS] = 0x09,589 [S_TAIL_TAG_CTRL] = 0x0C,590 [P_STP_CTRL] = 0x02,591 [S_START_CTRL] = 0x01,592 [S_BROADCAST_CTRL] = 0x06,593 [S_MULTICAST_CTRL] = 0x04,594};595 596static const u32 ksz8895_masks[] = {597 [PORT_802_1P_REMAPPING] = BIT(7),598 [SW_TAIL_TAG_ENABLE] = BIT(1),599 [MIB_COUNTER_OVERFLOW] = BIT(7),600 [MIB_COUNTER_VALID] = BIT(6),601 [VLAN_TABLE_FID] = GENMASK(6, 0),602 [VLAN_TABLE_MEMBERSHIP] = GENMASK(11, 7),603 [VLAN_TABLE_VALID] = BIT(12),604 [STATIC_MAC_TABLE_VALID] = BIT(21),605 [STATIC_MAC_TABLE_USE_FID] = BIT(23),606 [STATIC_MAC_TABLE_FID] = GENMASK(30, 24),607 [STATIC_MAC_TABLE_OVERRIDE] = BIT(22),608 [STATIC_MAC_TABLE_FWD_PORTS] = GENMASK(20, 16),609 [DYNAMIC_MAC_TABLE_ENTRIES_H] = GENMASK(6, 0),610 [DYNAMIC_MAC_TABLE_MAC_EMPTY] = BIT(7),611 [DYNAMIC_MAC_TABLE_NOT_READY] = BIT(7),612 [DYNAMIC_MAC_TABLE_ENTRIES] = GENMASK(31, 29),613 [DYNAMIC_MAC_TABLE_FID] = GENMASK(22, 16),614 [DYNAMIC_MAC_TABLE_SRC_PORT] = GENMASK(26, 24),615 [DYNAMIC_MAC_TABLE_TIMESTAMP] = GENMASK(28, 27),616};617 618static const u8 ksz8895_shifts[] = {619 [VLAN_TABLE_MEMBERSHIP_S] = 7,620 [VLAN_TABLE] = 13,621 [STATIC_MAC_FWD_PORTS] = 16,622 [STATIC_MAC_FID] = 24,623 [DYNAMIC_MAC_ENTRIES_H] = 3,624 [DYNAMIC_MAC_ENTRIES] = 29,625 [DYNAMIC_MAC_FID] = 16,626 [DYNAMIC_MAC_TIMESTAMP] = 27,627 [DYNAMIC_MAC_SRC_PORT] = 24,628};629 630static const u16 ksz9477_regs[] = {631 [REG_SW_MAC_ADDR] = 0x0302,632 [P_STP_CTRL] = 0x0B04,633 [S_START_CTRL] = 0x0300,634 [S_BROADCAST_CTRL] = 0x0332,635 [S_MULTICAST_CTRL] = 0x0331,636 [P_XMII_CTRL_0] = 0x0300,637 [P_XMII_CTRL_1] = 0x0301,638 [REG_SW_PME_CTRL] = 0x0006,639 [REG_PORT_PME_STATUS] = 0x0013,640 [REG_PORT_PME_CTRL] = 0x0017,641};642 643static const u32 ksz9477_masks[] = {644 [ALU_STAT_WRITE] = 0,645 [ALU_STAT_READ] = 1,646 [P_MII_TX_FLOW_CTRL] = BIT(5),647 [P_MII_RX_FLOW_CTRL] = BIT(3),648};649 650static const u8 ksz9477_shifts[] = {651 [ALU_STAT_INDEX] = 16,652};653 654static const u8 ksz9477_xmii_ctrl0[] = {655 [P_MII_100MBIT] = 1,656 [P_MII_10MBIT] = 0,657 [P_MII_FULL_DUPLEX] = 1,658 [P_MII_HALF_DUPLEX] = 0,659};660 661static const u8 ksz9477_xmii_ctrl1[] = {662 [P_RGMII_SEL] = 0,663 [P_RMII_SEL] = 1,664 [P_GMII_SEL] = 2,665 [P_MII_SEL] = 3,666 [P_GMII_1GBIT] = 0,667 [P_GMII_NOT_1GBIT] = 1,668};669 670static const u32 lan937x_masks[] = {671 [ALU_STAT_WRITE] = 1,672 [ALU_STAT_READ] = 2,673 [P_MII_TX_FLOW_CTRL] = BIT(5),674 [P_MII_RX_FLOW_CTRL] = BIT(3),675};676 677static const u8 lan937x_shifts[] = {678 [ALU_STAT_INDEX] = 8,679};680 681static const struct regmap_range ksz8563_valid_regs[] = {682 regmap_reg_range(0x0000, 0x0003),683 regmap_reg_range(0x0006, 0x0006),684 regmap_reg_range(0x000f, 0x001f),685 regmap_reg_range(0x0100, 0x0100),686 regmap_reg_range(0x0104, 0x0107),687 regmap_reg_range(0x010d, 0x010d),688 regmap_reg_range(0x0110, 0x0113),689 regmap_reg_range(0x0120, 0x012b),690 regmap_reg_range(0x0201, 0x0201),691 regmap_reg_range(0x0210, 0x0213),692 regmap_reg_range(0x0300, 0x0300),693 regmap_reg_range(0x0302, 0x031b),694 regmap_reg_range(0x0320, 0x032b),695 regmap_reg_range(0x0330, 0x0336),696 regmap_reg_range(0x0338, 0x033e),697 regmap_reg_range(0x0340, 0x035f),698 regmap_reg_range(0x0370, 0x0370),699 regmap_reg_range(0x0378, 0x0378),700 regmap_reg_range(0x037c, 0x037d),701 regmap_reg_range(0x0390, 0x0393),702 regmap_reg_range(0x0400, 0x040e),703 regmap_reg_range(0x0410, 0x042f),704 regmap_reg_range(0x0500, 0x0519),705 regmap_reg_range(0x0520, 0x054b),706 regmap_reg_range(0x0550, 0x05b3),707 708 /* port 1 */709 regmap_reg_range(0x1000, 0x1001),710 regmap_reg_range(0x1004, 0x100b),711 regmap_reg_range(0x1013, 0x1013),712 regmap_reg_range(0x1017, 0x1017),713 regmap_reg_range(0x101b, 0x101b),714 regmap_reg_range(0x101f, 0x1021),715 regmap_reg_range(0x1030, 0x1030),716 regmap_reg_range(0x1100, 0x1111),717 regmap_reg_range(0x111a, 0x111d),718 regmap_reg_range(0x1122, 0x1127),719 regmap_reg_range(0x112a, 0x112b),720 regmap_reg_range(0x1136, 0x1139),721 regmap_reg_range(0x113e, 0x113f),722 regmap_reg_range(0x1400, 0x1401),723 regmap_reg_range(0x1403, 0x1403),724 regmap_reg_range(0x1410, 0x1417),725 regmap_reg_range(0x1420, 0x1423),726 regmap_reg_range(0x1500, 0x1507),727 regmap_reg_range(0x1600, 0x1612),728 regmap_reg_range(0x1800, 0x180f),729 regmap_reg_range(0x1900, 0x1907),730 regmap_reg_range(0x1914, 0x191b),731 regmap_reg_range(0x1a00, 0x1a03),732 regmap_reg_range(0x1a04, 0x1a08),733 regmap_reg_range(0x1b00, 0x1b01),734 regmap_reg_range(0x1b04, 0x1b04),735 regmap_reg_range(0x1c00, 0x1c05),736 regmap_reg_range(0x1c08, 0x1c1b),737 738 /* port 2 */739 regmap_reg_range(0x2000, 0x2001),740 regmap_reg_range(0x2004, 0x200b),741 regmap_reg_range(0x2013, 0x2013),742 regmap_reg_range(0x2017, 0x2017),743 regmap_reg_range(0x201b, 0x201b),744 regmap_reg_range(0x201f, 0x2021),745 regmap_reg_range(0x2030, 0x2030),746 regmap_reg_range(0x2100, 0x2111),747 regmap_reg_range(0x211a, 0x211d),748 regmap_reg_range(0x2122, 0x2127),749 regmap_reg_range(0x212a, 0x212b),750 regmap_reg_range(0x2136, 0x2139),751 regmap_reg_range(0x213e, 0x213f),752 regmap_reg_range(0x2400, 0x2401),753 regmap_reg_range(0x2403, 0x2403),754 regmap_reg_range(0x2410, 0x2417),755 regmap_reg_range(0x2420, 0x2423),756 regmap_reg_range(0x2500, 0x2507),757 regmap_reg_range(0x2600, 0x2612),758 regmap_reg_range(0x2800, 0x280f),759 regmap_reg_range(0x2900, 0x2907),760 regmap_reg_range(0x2914, 0x291b),761 regmap_reg_range(0x2a00, 0x2a03),762 regmap_reg_range(0x2a04, 0x2a08),763 regmap_reg_range(0x2b00, 0x2b01),764 regmap_reg_range(0x2b04, 0x2b04),765 regmap_reg_range(0x2c00, 0x2c05),766 regmap_reg_range(0x2c08, 0x2c1b),767 768 /* port 3 */769 regmap_reg_range(0x3000, 0x3001),770 regmap_reg_range(0x3004, 0x300b),771 regmap_reg_range(0x3013, 0x3013),772 regmap_reg_range(0x3017, 0x3017),773 regmap_reg_range(0x301b, 0x301b),774 regmap_reg_range(0x301f, 0x3021),775 regmap_reg_range(0x3030, 0x3030),776 regmap_reg_range(0x3300, 0x3301),777 regmap_reg_range(0x3303, 0x3303),778 regmap_reg_range(0x3400, 0x3401),779 regmap_reg_range(0x3403, 0x3403),780 regmap_reg_range(0x3410, 0x3417),781 regmap_reg_range(0x3420, 0x3423),782 regmap_reg_range(0x3500, 0x3507),783 regmap_reg_range(0x3600, 0x3612),784 regmap_reg_range(0x3800, 0x380f),785 regmap_reg_range(0x3900, 0x3907),786 regmap_reg_range(0x3914, 0x391b),787 regmap_reg_range(0x3a00, 0x3a03),788 regmap_reg_range(0x3a04, 0x3a08),789 regmap_reg_range(0x3b00, 0x3b01),790 regmap_reg_range(0x3b04, 0x3b04),791 regmap_reg_range(0x3c00, 0x3c05),792 regmap_reg_range(0x3c08, 0x3c1b),793};794 795static const struct regmap_access_table ksz8563_register_set = {796 .yes_ranges = ksz8563_valid_regs,797 .n_yes_ranges = ARRAY_SIZE(ksz8563_valid_regs),798};799 800static const struct regmap_range ksz9477_valid_regs[] = {801 regmap_reg_range(0x0000, 0x0003),802 regmap_reg_range(0x0006, 0x0006),803 regmap_reg_range(0x0010, 0x001f),804 regmap_reg_range(0x0100, 0x0100),805 regmap_reg_range(0x0103, 0x0107),806 regmap_reg_range(0x010d, 0x010d),807 regmap_reg_range(0x0110, 0x0113),808 regmap_reg_range(0x0120, 0x012b),809 regmap_reg_range(0x0201, 0x0201),810 regmap_reg_range(0x0210, 0x0213),811 regmap_reg_range(0x0300, 0x0300),812 regmap_reg_range(0x0302, 0x031b),813 regmap_reg_range(0x0320, 0x032b),814 regmap_reg_range(0x0330, 0x0336),815 regmap_reg_range(0x0338, 0x033b),816 regmap_reg_range(0x033e, 0x033e),817 regmap_reg_range(0x0340, 0x035f),818 regmap_reg_range(0x0370, 0x0370),819 regmap_reg_range(0x0378, 0x0378),820 regmap_reg_range(0x037c, 0x037d),821 regmap_reg_range(0x0390, 0x0393),822 regmap_reg_range(0x0400, 0x040e),823 regmap_reg_range(0x0410, 0x042f),824 regmap_reg_range(0x0444, 0x044b),825 regmap_reg_range(0x0450, 0x046f),826 regmap_reg_range(0x0500, 0x0519),827 regmap_reg_range(0x0520, 0x054b),828 regmap_reg_range(0x0550, 0x05b3),829 regmap_reg_range(0x0604, 0x060b),830 regmap_reg_range(0x0610, 0x0612),831 regmap_reg_range(0x0614, 0x062c),832 regmap_reg_range(0x0640, 0x0645),833 regmap_reg_range(0x0648, 0x064d),834 835 /* port 1 */836 regmap_reg_range(0x1000, 0x1001),837 regmap_reg_range(0x1013, 0x1013),838 regmap_reg_range(0x1017, 0x1017),839 regmap_reg_range(0x101b, 0x101b),840 regmap_reg_range(0x101f, 0x1020),841 regmap_reg_range(0x1030, 0x1030),842 regmap_reg_range(0x1100, 0x1115),843 regmap_reg_range(0x111a, 0x111f),844 regmap_reg_range(0x1120, 0x112b),845 regmap_reg_range(0x1134, 0x113b),846 regmap_reg_range(0x113c, 0x113f),847 regmap_reg_range(0x1400, 0x1401),848 regmap_reg_range(0x1403, 0x1403),849 regmap_reg_range(0x1410, 0x1417),850 regmap_reg_range(0x1420, 0x1423),851 regmap_reg_range(0x1500, 0x1507),852 regmap_reg_range(0x1600, 0x1613),853 regmap_reg_range(0x1800, 0x180f),854 regmap_reg_range(0x1820, 0x1827),855 regmap_reg_range(0x1830, 0x1837),856 regmap_reg_range(0x1840, 0x184b),857 regmap_reg_range(0x1900, 0x1907),858 regmap_reg_range(0x1914, 0x191b),859 regmap_reg_range(0x1920, 0x1920),860 regmap_reg_range(0x1923, 0x1927),861 regmap_reg_range(0x1a00, 0x1a03),862 regmap_reg_range(0x1a04, 0x1a07),863 regmap_reg_range(0x1b00, 0x1b01),864 regmap_reg_range(0x1b04, 0x1b04),865 regmap_reg_range(0x1c00, 0x1c05),866 regmap_reg_range(0x1c08, 0x1c1b),867 868 /* port 2 */869 regmap_reg_range(0x2000, 0x2001),870 regmap_reg_range(0x2013, 0x2013),871 regmap_reg_range(0x2017, 0x2017),872 regmap_reg_range(0x201b, 0x201b),873 regmap_reg_range(0x201f, 0x2020),874 regmap_reg_range(0x2030, 0x2030),875 regmap_reg_range(0x2100, 0x2115),876 regmap_reg_range(0x211a, 0x211f),877 regmap_reg_range(0x2120, 0x212b),878 regmap_reg_range(0x2134, 0x213b),879 regmap_reg_range(0x213c, 0x213f),880 regmap_reg_range(0x2400, 0x2401),881 regmap_reg_range(0x2403, 0x2403),882 regmap_reg_range(0x2410, 0x2417),883 regmap_reg_range(0x2420, 0x2423),884 regmap_reg_range(0x2500, 0x2507),885 regmap_reg_range(0x2600, 0x2613),886 regmap_reg_range(0x2800, 0x280f),887 regmap_reg_range(0x2820, 0x2827),888 regmap_reg_range(0x2830, 0x2837),889 regmap_reg_range(0x2840, 0x284b),890 regmap_reg_range(0x2900, 0x2907),891 regmap_reg_range(0x2914, 0x291b),892 regmap_reg_range(0x2920, 0x2920),893 regmap_reg_range(0x2923, 0x2927),894 regmap_reg_range(0x2a00, 0x2a03),895 regmap_reg_range(0x2a04, 0x2a07),896 regmap_reg_range(0x2b00, 0x2b01),897 regmap_reg_range(0x2b04, 0x2b04),898 regmap_reg_range(0x2c00, 0x2c05),899 regmap_reg_range(0x2c08, 0x2c1b),900 901 /* port 3 */902 regmap_reg_range(0x3000, 0x3001),903 regmap_reg_range(0x3013, 0x3013),904 regmap_reg_range(0x3017, 0x3017),905 regmap_reg_range(0x301b, 0x301b),906 regmap_reg_range(0x301f, 0x3020),907 regmap_reg_range(0x3030, 0x3030),908 regmap_reg_range(0x3100, 0x3115),909 regmap_reg_range(0x311a, 0x311f),910 regmap_reg_range(0x3120, 0x312b),911 regmap_reg_range(0x3134, 0x313b),912 regmap_reg_range(0x313c, 0x313f),913 regmap_reg_range(0x3400, 0x3401),914 regmap_reg_range(0x3403, 0x3403),915 regmap_reg_range(0x3410, 0x3417),916 regmap_reg_range(0x3420, 0x3423),917 regmap_reg_range(0x3500, 0x3507),918 regmap_reg_range(0x3600, 0x3613),919 regmap_reg_range(0x3800, 0x380f),920 regmap_reg_range(0x3820, 0x3827),921 regmap_reg_range(0x3830, 0x3837),922 regmap_reg_range(0x3840, 0x384b),923 regmap_reg_range(0x3900, 0x3907),924 regmap_reg_range(0x3914, 0x391b),925 regmap_reg_range(0x3920, 0x3920),926 regmap_reg_range(0x3923, 0x3927),927 regmap_reg_range(0x3a00, 0x3a03),928 regmap_reg_range(0x3a04, 0x3a07),929 regmap_reg_range(0x3b00, 0x3b01),930 regmap_reg_range(0x3b04, 0x3b04),931 regmap_reg_range(0x3c00, 0x3c05),932 regmap_reg_range(0x3c08, 0x3c1b),933 934 /* port 4 */935 regmap_reg_range(0x4000, 0x4001),936 regmap_reg_range(0x4013, 0x4013),937 regmap_reg_range(0x4017, 0x4017),938 regmap_reg_range(0x401b, 0x401b),939 regmap_reg_range(0x401f, 0x4020),940 regmap_reg_range(0x4030, 0x4030),941 regmap_reg_range(0x4100, 0x4115),942 regmap_reg_range(0x411a, 0x411f),943 regmap_reg_range(0x4120, 0x412b),944 regmap_reg_range(0x4134, 0x413b),945 regmap_reg_range(0x413c, 0x413f),946 regmap_reg_range(0x4400, 0x4401),947 regmap_reg_range(0x4403, 0x4403),948 regmap_reg_range(0x4410, 0x4417),949 regmap_reg_range(0x4420, 0x4423),950 regmap_reg_range(0x4500, 0x4507),951 regmap_reg_range(0x4600, 0x4613),952 regmap_reg_range(0x4800, 0x480f),953 regmap_reg_range(0x4820, 0x4827),954 regmap_reg_range(0x4830, 0x4837),955 regmap_reg_range(0x4840, 0x484b),956 regmap_reg_range(0x4900, 0x4907),957 regmap_reg_range(0x4914, 0x491b),958 regmap_reg_range(0x4920, 0x4920),959 regmap_reg_range(0x4923, 0x4927),960 regmap_reg_range(0x4a00, 0x4a03),961 regmap_reg_range(0x4a04, 0x4a07),962 regmap_reg_range(0x4b00, 0x4b01),963 regmap_reg_range(0x4b04, 0x4b04),964 regmap_reg_range(0x4c00, 0x4c05),965 regmap_reg_range(0x4c08, 0x4c1b),966 967 /* port 5 */968 regmap_reg_range(0x5000, 0x5001),969 regmap_reg_range(0x5013, 0x5013),970 regmap_reg_range(0x5017, 0x5017),971 regmap_reg_range(0x501b, 0x501b),972 regmap_reg_range(0x501f, 0x5020),973 regmap_reg_range(0x5030, 0x5030),974 regmap_reg_range(0x5100, 0x5115),975 regmap_reg_range(0x511a, 0x511f),976 regmap_reg_range(0x5120, 0x512b),977 regmap_reg_range(0x5134, 0x513b),978 regmap_reg_range(0x513c, 0x513f),979 regmap_reg_range(0x5400, 0x5401),980 regmap_reg_range(0x5403, 0x5403),981 regmap_reg_range(0x5410, 0x5417),982 regmap_reg_range(0x5420, 0x5423),983 regmap_reg_range(0x5500, 0x5507),984 regmap_reg_range(0x5600, 0x5613),985 regmap_reg_range(0x5800, 0x580f),986 regmap_reg_range(0x5820, 0x5827),987 regmap_reg_range(0x5830, 0x5837),988 regmap_reg_range(0x5840, 0x584b),989 regmap_reg_range(0x5900, 0x5907),990 regmap_reg_range(0x5914, 0x591b),991 regmap_reg_range(0x5920, 0x5920),992 regmap_reg_range(0x5923, 0x5927),993 regmap_reg_range(0x5a00, 0x5a03),994 regmap_reg_range(0x5a04, 0x5a07),995 regmap_reg_range(0x5b00, 0x5b01),996 regmap_reg_range(0x5b04, 0x5b04),997 regmap_reg_range(0x5c00, 0x5c05),998 regmap_reg_range(0x5c08, 0x5c1b),999 1000 /* port 6 */1001 regmap_reg_range(0x6000, 0x6001),1002 regmap_reg_range(0x6013, 0x6013),1003 regmap_reg_range(0x6017, 0x6017),1004 regmap_reg_range(0x601b, 0x601b),1005 regmap_reg_range(0x601f, 0x6020),1006 regmap_reg_range(0x6030, 0x6030),1007 regmap_reg_range(0x6300, 0x6301),1008 regmap_reg_range(0x6400, 0x6401),1009 regmap_reg_range(0x6403, 0x6403),1010 regmap_reg_range(0x6410, 0x6417),1011 regmap_reg_range(0x6420, 0x6423),1012 regmap_reg_range(0x6500, 0x6507),1013 regmap_reg_range(0x6600, 0x6613),1014 regmap_reg_range(0x6800, 0x680f),1015 regmap_reg_range(0x6820, 0x6827),1016 regmap_reg_range(0x6830, 0x6837),1017 regmap_reg_range(0x6840, 0x684b),1018 regmap_reg_range(0x6900, 0x6907),1019 regmap_reg_range(0x6914, 0x691b),1020 regmap_reg_range(0x6920, 0x6920),1021 regmap_reg_range(0x6923, 0x6927),1022 regmap_reg_range(0x6a00, 0x6a03),1023 regmap_reg_range(0x6a04, 0x6a07),1024 regmap_reg_range(0x6b00, 0x6b01),1025 regmap_reg_range(0x6b04, 0x6b04),1026 regmap_reg_range(0x6c00, 0x6c05),1027 regmap_reg_range(0x6c08, 0x6c1b),1028 1029 /* port 7 */1030 regmap_reg_range(0x7000, 0x7001),1031 regmap_reg_range(0x7013, 0x7013),1032 regmap_reg_range(0x7017, 0x7017),1033 regmap_reg_range(0x701b, 0x701b),1034 regmap_reg_range(0x701f, 0x7020),1035 regmap_reg_range(0x7030, 0x7030),1036 regmap_reg_range(0x7200, 0x7203),1037 regmap_reg_range(0x7206, 0x7207),1038 regmap_reg_range(0x7300, 0x7301),1039 regmap_reg_range(0x7400, 0x7401),1040 regmap_reg_range(0x7403, 0x7403),1041 regmap_reg_range(0x7410, 0x7417),1042 regmap_reg_range(0x7420, 0x7423),1043 regmap_reg_range(0x7500, 0x7507),1044 regmap_reg_range(0x7600, 0x7613),1045 regmap_reg_range(0x7800, 0x780f),1046 regmap_reg_range(0x7820, 0x7827),1047 regmap_reg_range(0x7830, 0x7837),1048 regmap_reg_range(0x7840, 0x784b),1049 regmap_reg_range(0x7900, 0x7907),1050 regmap_reg_range(0x7914, 0x791b),1051 regmap_reg_range(0x7920, 0x7920),1052 regmap_reg_range(0x7923, 0x7927),1053 regmap_reg_range(0x7a00, 0x7a03),1054 regmap_reg_range(0x7a04, 0x7a07),1055 regmap_reg_range(0x7b00, 0x7b01),1056 regmap_reg_range(0x7b04, 0x7b04),1057 regmap_reg_range(0x7c00, 0x7c05),1058 regmap_reg_range(0x7c08, 0x7c1b),1059};1060 1061static const struct regmap_access_table ksz9477_register_set = {1062 .yes_ranges = ksz9477_valid_regs,1063 .n_yes_ranges = ARRAY_SIZE(ksz9477_valid_regs),1064};1065 1066static const struct regmap_range ksz9896_valid_regs[] = {1067 regmap_reg_range(0x0000, 0x0003),1068 regmap_reg_range(0x0006, 0x0006),1069 regmap_reg_range(0x0010, 0x001f),1070 regmap_reg_range(0x0100, 0x0100),1071 regmap_reg_range(0x0103, 0x0107),1072 regmap_reg_range(0x010d, 0x010d),1073 regmap_reg_range(0x0110, 0x0113),1074 regmap_reg_range(0x0120, 0x0127),1075 regmap_reg_range(0x0201, 0x0201),1076 regmap_reg_range(0x0210, 0x0213),1077 regmap_reg_range(0x0300, 0x0300),1078 regmap_reg_range(0x0302, 0x030b),1079 regmap_reg_range(0x0310, 0x031b),1080 regmap_reg_range(0x0320, 0x032b),1081 regmap_reg_range(0x0330, 0x0336),1082 regmap_reg_range(0x0338, 0x033b),1083 regmap_reg_range(0x033e, 0x033e),1084 regmap_reg_range(0x0340, 0x035f),1085 regmap_reg_range(0x0370, 0x0370),1086 regmap_reg_range(0x0378, 0x0378),1087 regmap_reg_range(0x037c, 0x037d),1088 regmap_reg_range(0x0390, 0x0393),1089 regmap_reg_range(0x0400, 0x040e),1090 regmap_reg_range(0x0410, 0x042f),1091 1092 /* port 1 */1093 regmap_reg_range(0x1000, 0x1001),1094 regmap_reg_range(0x1013, 0x1013),1095 regmap_reg_range(0x1017, 0x1017),1096 regmap_reg_range(0x101b, 0x101b),1097 regmap_reg_range(0x101f, 0x1020),1098 regmap_reg_range(0x1030, 0x1030),1099 regmap_reg_range(0x1100, 0x1115),1100 regmap_reg_range(0x111a, 0x111f),1101 regmap_reg_range(0x1122, 0x1127),1102 regmap_reg_range(0x112a, 0x112b),1103 regmap_reg_range(0x1136, 0x1139),1104 regmap_reg_range(0x113e, 0x113f),1105 regmap_reg_range(0x1400, 0x1401),1106 regmap_reg_range(0x1403, 0x1403),1107 regmap_reg_range(0x1410, 0x1417),1108 regmap_reg_range(0x1420, 0x1423),1109 regmap_reg_range(0x1500, 0x1507),1110 regmap_reg_range(0x1600, 0x1612),1111 regmap_reg_range(0x1800, 0x180f),1112 regmap_reg_range(0x1820, 0x1827),1113 regmap_reg_range(0x1830, 0x1837),1114 regmap_reg_range(0x1840, 0x184b),1115 regmap_reg_range(0x1900, 0x1907),1116 regmap_reg_range(0x1914, 0x1915),1117 regmap_reg_range(0x1a00, 0x1a03),1118 regmap_reg_range(0x1a04, 0x1a07),1119 regmap_reg_range(0x1b00, 0x1b01),1120 regmap_reg_range(0x1b04, 0x1b04),1121 1122 /* port 2 */1123 regmap_reg_range(0x2000, 0x2001),1124 regmap_reg_range(0x2013, 0x2013),1125 regmap_reg_range(0x2017, 0x2017),1126 regmap_reg_range(0x201b, 0x201b),1127 regmap_reg_range(0x201f, 0x2020),1128 regmap_reg_range(0x2030, 0x2030),1129 regmap_reg_range(0x2100, 0x2115),1130 regmap_reg_range(0x211a, 0x211f),1131 regmap_reg_range(0x2122, 0x2127),1132 regmap_reg_range(0x212a, 0x212b),1133 regmap_reg_range(0x2136, 0x2139),1134 regmap_reg_range(0x213e, 0x213f),1135 regmap_reg_range(0x2400, 0x2401),1136 regmap_reg_range(0x2403, 0x2403),1137 regmap_reg_range(0x2410, 0x2417),1138 regmap_reg_range(0x2420, 0x2423),1139 regmap_reg_range(0x2500, 0x2507),1140 regmap_reg_range(0x2600, 0x2612),1141 regmap_reg_range(0x2800, 0x280f),1142 regmap_reg_range(0x2820, 0x2827),1143 regmap_reg_range(0x2830, 0x2837),1144 regmap_reg_range(0x2840, 0x284b),1145 regmap_reg_range(0x2900, 0x2907),1146 regmap_reg_range(0x2914, 0x2915),1147 regmap_reg_range(0x2a00, 0x2a03),1148 regmap_reg_range(0x2a04, 0x2a07),1149 regmap_reg_range(0x2b00, 0x2b01),1150 regmap_reg_range(0x2b04, 0x2b04),1151 1152 /* port 3 */1153 regmap_reg_range(0x3000, 0x3001),1154 regmap_reg_range(0x3013, 0x3013),1155 regmap_reg_range(0x3017, 0x3017),1156 regmap_reg_range(0x301b, 0x301b),1157 regmap_reg_range(0x301f, 0x3020),1158 regmap_reg_range(0x3030, 0x3030),1159 regmap_reg_range(0x3100, 0x3115),1160 regmap_reg_range(0x311a, 0x311f),1161 regmap_reg_range(0x3122, 0x3127),1162 regmap_reg_range(0x312a, 0x312b),1163 regmap_reg_range(0x3136, 0x3139),1164 regmap_reg_range(0x313e, 0x313f),1165 regmap_reg_range(0x3400, 0x3401),1166 regmap_reg_range(0x3403, 0x3403),1167 regmap_reg_range(0x3410, 0x3417),1168 regmap_reg_range(0x3420, 0x3423),1169 regmap_reg_range(0x3500, 0x3507),1170 regmap_reg_range(0x3600, 0x3612),1171 regmap_reg_range(0x3800, 0x380f),1172 regmap_reg_range(0x3820, 0x3827),1173 regmap_reg_range(0x3830, 0x3837),1174 regmap_reg_range(0x3840, 0x384b),1175 regmap_reg_range(0x3900, 0x3907),1176 regmap_reg_range(0x3914, 0x3915),1177 regmap_reg_range(0x3a00, 0x3a03),1178 regmap_reg_range(0x3a04, 0x3a07),1179 regmap_reg_range(0x3b00, 0x3b01),1180 regmap_reg_range(0x3b04, 0x3b04),1181 1182 /* port 4 */1183 regmap_reg_range(0x4000, 0x4001),1184 regmap_reg_range(0x4013, 0x4013),1185 regmap_reg_range(0x4017, 0x4017),1186 regmap_reg_range(0x401b, 0x401b),1187 regmap_reg_range(0x401f, 0x4020),1188 regmap_reg_range(0x4030, 0x4030),1189 regmap_reg_range(0x4100, 0x4115),1190 regmap_reg_range(0x411a, 0x411f),1191 regmap_reg_range(0x4122, 0x4127),1192 regmap_reg_range(0x412a, 0x412b),1193 regmap_reg_range(0x4136, 0x4139),1194 regmap_reg_range(0x413e, 0x413f),1195 regmap_reg_range(0x4400, 0x4401),1196 regmap_reg_range(0x4403, 0x4403),1197 regmap_reg_range(0x4410, 0x4417),1198 regmap_reg_range(0x4420, 0x4423),1199 regmap_reg_range(0x4500, 0x4507),1200 regmap_reg_range(0x4600, 0x4612),1201 regmap_reg_range(0x4800, 0x480f),1202 regmap_reg_range(0x4820, 0x4827),1203 regmap_reg_range(0x4830, 0x4837),1204 regmap_reg_range(0x4840, 0x484b),1205 regmap_reg_range(0x4900, 0x4907),1206 regmap_reg_range(0x4914, 0x4915),1207 regmap_reg_range(0x4a00, 0x4a03),1208 regmap_reg_range(0x4a04, 0x4a07),1209 regmap_reg_range(0x4b00, 0x4b01),1210 regmap_reg_range(0x4b04, 0x4b04),1211 1212 /* port 5 */1213 regmap_reg_range(0x5000, 0x5001),1214 regmap_reg_range(0x5013, 0x5013),1215 regmap_reg_range(0x5017, 0x5017),1216 regmap_reg_range(0x501b, 0x501b),1217 regmap_reg_range(0x501f, 0x5020),1218 regmap_reg_range(0x5030, 0x5030),1219 regmap_reg_range(0x5100, 0x5115),1220 regmap_reg_range(0x511a, 0x511f),1221 regmap_reg_range(0x5122, 0x5127),1222 regmap_reg_range(0x512a, 0x512b),1223 regmap_reg_range(0x5136, 0x5139),1224 regmap_reg_range(0x513e, 0x513f),1225 regmap_reg_range(0x5400, 0x5401),1226 regmap_reg_range(0x5403, 0x5403),1227 regmap_reg_range(0x5410, 0x5417),1228 regmap_reg_range(0x5420, 0x5423),1229 regmap_reg_range(0x5500, 0x5507),1230 regmap_reg_range(0x5600, 0x5612),1231 regmap_reg_range(0x5800, 0x580f),1232 regmap_reg_range(0x5820, 0x5827),1233 regmap_reg_range(0x5830, 0x5837),1234 regmap_reg_range(0x5840, 0x584b),1235 regmap_reg_range(0x5900, 0x5907),1236 regmap_reg_range(0x5914, 0x5915),1237 regmap_reg_range(0x5a00, 0x5a03),1238 regmap_reg_range(0x5a04, 0x5a07),1239 regmap_reg_range(0x5b00, 0x5b01),1240 regmap_reg_range(0x5b04, 0x5b04),1241 1242 /* port 6 */1243 regmap_reg_range(0x6000, 0x6001),1244 regmap_reg_range(0x6013, 0x6013),1245 regmap_reg_range(0x6017, 0x6017),1246 regmap_reg_range(0x601b, 0x601b),1247 regmap_reg_range(0x601f, 0x6020),1248 regmap_reg_range(0x6030, 0x6030),1249 regmap_reg_range(0x6100, 0x6115),1250 regmap_reg_range(0x611a, 0x611f),1251 regmap_reg_range(0x6122, 0x6127),1252 regmap_reg_range(0x612a, 0x612b),1253 regmap_reg_range(0x6136, 0x6139),1254 regmap_reg_range(0x613e, 0x613f),1255 regmap_reg_range(0x6300, 0x6301),1256 regmap_reg_range(0x6400, 0x6401),1257 regmap_reg_range(0x6403, 0x6403),1258 regmap_reg_range(0x6410, 0x6417),1259 regmap_reg_range(0x6420, 0x6423),1260 regmap_reg_range(0x6500, 0x6507),1261 regmap_reg_range(0x6600, 0x6612),1262 regmap_reg_range(0x6800, 0x680f),1263 regmap_reg_range(0x6820, 0x6827),1264 regmap_reg_range(0x6830, 0x6837),1265 regmap_reg_range(0x6840, 0x684b),1266 regmap_reg_range(0x6900, 0x6907),1267 regmap_reg_range(0x6914, 0x6915),1268 regmap_reg_range(0x6a00, 0x6a03),1269 regmap_reg_range(0x6a04, 0x6a07),1270 regmap_reg_range(0x6b00, 0x6b01),1271 regmap_reg_range(0x6b04, 0x6b04),1272};1273 1274static const struct regmap_access_table ksz9896_register_set = {1275 .yes_ranges = ksz9896_valid_regs,1276 .n_yes_ranges = ARRAY_SIZE(ksz9896_valid_regs),1277};1278 1279static const struct regmap_range ksz8873_valid_regs[] = {1280 regmap_reg_range(0x00, 0x01),1281 /* global control register */1282 regmap_reg_range(0x02, 0x0f),1283 1284 /* port registers */1285 regmap_reg_range(0x10, 0x1d),1286 regmap_reg_range(0x1e, 0x1f),1287 regmap_reg_range(0x20, 0x2d),1288 regmap_reg_range(0x2e, 0x2f),1289 regmap_reg_range(0x30, 0x39),1290 regmap_reg_range(0x3f, 0x3f),1291 1292 /* advanced control registers */1293 regmap_reg_range(0x60, 0x6f),1294 regmap_reg_range(0x70, 0x75),1295 regmap_reg_range(0x76, 0x78),1296 regmap_reg_range(0x79, 0x7a),1297 regmap_reg_range(0x7b, 0x83),1298 regmap_reg_range(0x8e, 0x99),1299 regmap_reg_range(0x9a, 0xa5),1300 regmap_reg_range(0xa6, 0xa6),1301 regmap_reg_range(0xa7, 0xaa),1302 regmap_reg_range(0xab, 0xae),1303 regmap_reg_range(0xaf, 0xba),1304 regmap_reg_range(0xbb, 0xbc),1305 regmap_reg_range(0xbd, 0xbd),1306 regmap_reg_range(0xc0, 0xc0),1307 regmap_reg_range(0xc2, 0xc2),1308 regmap_reg_range(0xc3, 0xc3),1309 regmap_reg_range(0xc4, 0xc4),1310 regmap_reg_range(0xc6, 0xc6),1311};1312 1313static const struct regmap_access_table ksz8873_register_set = {1314 .yes_ranges = ksz8873_valid_regs,1315 .n_yes_ranges = ARRAY_SIZE(ksz8873_valid_regs),1316};1317 1318const struct ksz_chip_data ksz_switch_chips[] = {1319 [KSZ8563] = {1320 .chip_id = KSZ8563_CHIP_ID,1321 .dev_name = "KSZ8563",1322 .num_vlans = 4096,1323 .num_alus = 4096,1324 .num_statics = 16,1325 .cpu_ports = 0x07, /* can be configured as cpu port */1326 .port_cnt = 3, /* total port count */1327 .port_nirqs = 3,1328 .num_tx_queues = 4,1329 .num_ipms = 8,1330 .tc_cbs_supported = true,1331 .ops = &ksz9477_dev_ops,1332 .phylink_mac_ops = &ksz9477_phylink_mac_ops,1333 .mib_names = ksz9477_mib_names,1334 .mib_cnt = ARRAY_SIZE(ksz9477_mib_names),1335 .reg_mib_cnt = MIB_COUNTER_NUM,1336 .regs = ksz9477_regs,1337 .masks = ksz9477_masks,1338 .shifts = ksz9477_shifts,1339 .xmii_ctrl0 = ksz9477_xmii_ctrl0,1340 .xmii_ctrl1 = ksz8795_xmii_ctrl1, /* Same as ksz8795 */1341 .supports_mii = {false, false, true},1342 .supports_rmii = {false, false, true},1343 .supports_rgmii = {false, false, true},1344 .internal_phy = {true, true, false},1345 .gbit_capable = {false, false, true},1346 .wr_table = &ksz8563_register_set,1347 .rd_table = &ksz8563_register_set,1348 },1349 1350 [KSZ8795] = {1351 .chip_id = KSZ8795_CHIP_ID,1352 .dev_name = "KSZ8795",1353 .num_vlans = 4096,1354 .num_alus = 0,1355 .num_statics = 32,1356 .cpu_ports = 0x10, /* can be configured as cpu port */1357 .port_cnt = 5, /* total cpu and user ports */1358 .num_tx_queues = 4,1359 .num_ipms = 4,1360 .ops = &ksz87xx_dev_ops,1361 .phylink_mac_ops = &ksz8_phylink_mac_ops,1362 .ksz87xx_eee_link_erratum = true,1363 .mib_names = ksz9477_mib_names,1364 .mib_cnt = ARRAY_SIZE(ksz9477_mib_names),1365 .reg_mib_cnt = MIB_COUNTER_NUM,1366 .regs = ksz8795_regs,1367 .masks = ksz8795_masks,1368 .shifts = ksz8795_shifts,1369 .xmii_ctrl0 = ksz8795_xmii_ctrl0,1370 .xmii_ctrl1 = ksz8795_xmii_ctrl1,1371 .supports_mii = {false, false, false, false, true},1372 .supports_rmii = {false, false, false, false, true},1373 .supports_rgmii = {false, false, false, false, true},1374 .internal_phy = {true, true, true, true, false},1375 },1376 1377 [KSZ8794] = {1378 /* WARNING1379 * =======1380 * KSZ8794 is similar to KSZ8795, except the port map1381 * contains a gap between external and CPU ports, the1382 * port map is NOT continuous. The per-port register1383 * map is shifted accordingly too, i.e. registers at1384 * offset 0x40 are NOT used on KSZ8794 and they ARE1385 * used on KSZ8795 for external port 3.1386 * external cpu1387 * KSZ8794 0,1,2 41388 * KSZ8795 0,1,2,3 41389 * KSZ8765 0,1,2,3 41390 * port_cnt is configured as 5, even though it is 41391 */1392 .chip_id = KSZ8794_CHIP_ID,1393 .dev_name = "KSZ8794",1394 .num_vlans = 4096,1395 .num_alus = 0,1396 .num_statics = 32,1397 .cpu_ports = 0x10, /* can be configured as cpu port */1398 .port_cnt = 5, /* total cpu and user ports */1399 .num_tx_queues = 4,1400 .num_ipms = 4,1401 .ops = &ksz87xx_dev_ops,1402 .phylink_mac_ops = &ksz8_phylink_mac_ops,1403 .ksz87xx_eee_link_erratum = true,1404 .mib_names = ksz9477_mib_names,1405 .mib_cnt = ARRAY_SIZE(ksz9477_mib_names),1406 .reg_mib_cnt = MIB_COUNTER_NUM,1407 .regs = ksz8795_regs,1408 .masks = ksz8795_masks,1409 .shifts = ksz8795_shifts,1410 .xmii_ctrl0 = ksz8795_xmii_ctrl0,1411 .xmii_ctrl1 = ksz8795_xmii_ctrl1,1412 .supports_mii = {false, false, false, false, true},1413 .supports_rmii = {false, false, false, false, true},1414 .supports_rgmii = {false, false, false, false, true},1415 .internal_phy = {true, true, true, false, false},1416 },1417 1418 [KSZ8765] = {1419 .chip_id = KSZ8765_CHIP_ID,1420 .dev_name = "KSZ8765",1421 .num_vlans = 4096,1422 .num_alus = 0,1423 .num_statics = 32,1424 .cpu_ports = 0x10, /* can be configured as cpu port */1425 .port_cnt = 5, /* total cpu and user ports */1426 .num_tx_queues = 4,1427 .num_ipms = 4,1428 .ops = &ksz87xx_dev_ops,1429 .phylink_mac_ops = &ksz8_phylink_mac_ops,1430 .ksz87xx_eee_link_erratum = true,1431 .mib_names = ksz9477_mib_names,1432 .mib_cnt = ARRAY_SIZE(ksz9477_mib_names),1433 .reg_mib_cnt = MIB_COUNTER_NUM,1434 .regs = ksz8795_regs,1435 .masks = ksz8795_masks,1436 .shifts = ksz8795_shifts,1437 .xmii_ctrl0 = ksz8795_xmii_ctrl0,1438 .xmii_ctrl1 = ksz8795_xmii_ctrl1,1439 .supports_mii = {false, false, false, false, true},1440 .supports_rmii = {false, false, false, false, true},1441 .supports_rgmii = {false, false, false, false, true},1442 .internal_phy = {true, true, true, true, false},1443 },1444 1445 [KSZ88X3] = {1446 .chip_id = KSZ88X3_CHIP_ID,1447 .dev_name = "KSZ8863/KSZ8873",1448 .num_vlans = 16,1449 .num_alus = 0,1450 .num_statics = 8,1451 .cpu_ports = 0x4, /* can be configured as cpu port */1452 .port_cnt = 3,1453 .num_tx_queues = 4,1454 .num_ipms = 4,1455 .ops = &ksz88xx_dev_ops,1456 .phylink_mac_ops = &ksz88x3_phylink_mac_ops,1457 .mib_names = ksz88xx_mib_names,1458 .mib_cnt = ARRAY_SIZE(ksz88xx_mib_names),1459 .reg_mib_cnt = MIB_COUNTER_NUM,1460 .regs = ksz8863_regs,1461 .masks = ksz8863_masks,1462 .shifts = ksz8863_shifts,1463 .supports_mii = {false, false, true},1464 .supports_rmii = {false, false, true},1465 .internal_phy = {true, true, false},1466 .wr_table = &ksz8873_register_set,1467 .rd_table = &ksz8873_register_set,1468 },1469 1470 [KSZ8864] = {1471 /* WARNING1472 * =======1473 * KSZ8864 is similar to KSZ8895, except the first port1474 * does not exist.1475 * external cpu1476 * KSZ8864 1,2,3 41477 * KSZ8895 0,1,2,3 41478 * port_cnt is configured as 5, even though it is 41479 */1480 .chip_id = KSZ8864_CHIP_ID,1481 .dev_name = "KSZ8864",1482 .num_vlans = 4096,1483 .num_alus = 0,1484 .num_statics = 32,1485 .cpu_ports = 0x10, /* can be configured as cpu port */1486 .port_cnt = 5, /* total cpu and user ports */1487 .num_tx_queues = 4,1488 .num_ipms = 4,1489 .ops = &ksz88xx_dev_ops,1490 .phylink_mac_ops = &ksz88x3_phylink_mac_ops,1491 .mib_names = ksz88xx_mib_names,1492 .mib_cnt = ARRAY_SIZE(ksz88xx_mib_names),1493 .reg_mib_cnt = MIB_COUNTER_NUM,1494 .regs = ksz8895_regs,1495 .masks = ksz8895_masks,1496 .shifts = ksz8895_shifts,1497 .supports_mii = {false, false, false, false, true},1498 .supports_rmii = {false, false, false, false, true},1499 .internal_phy = {false, true, true, true, false},1500 },1501 1502 [KSZ8895] = {1503 .chip_id = KSZ8895_CHIP_ID,1504 .dev_name = "KSZ8895",1505 .num_vlans = 4096,1506 .num_alus = 0,1507 .num_statics = 32,1508 .cpu_ports = 0x10, /* can be configured as cpu port */1509 .port_cnt = 5, /* total cpu and user ports */1510 .num_tx_queues = 4,1511 .num_ipms = 4,1512 .ops = &ksz88xx_dev_ops,1513 .phylink_mac_ops = &ksz88x3_phylink_mac_ops,1514 .mib_names = ksz88xx_mib_names,1515 .mib_cnt = ARRAY_SIZE(ksz88xx_mib_names),1516 .reg_mib_cnt = MIB_COUNTER_NUM,1517 .regs = ksz8895_regs,1518 .masks = ksz8895_masks,1519 .shifts = ksz8895_shifts,1520 .supports_mii = {false, false, false, false, true},1521 .supports_rmii = {false, false, false, false, true},1522 .internal_phy = {true, true, true, true, false},1523 },1524 1525 [KSZ9477] = {1526 .chip_id = KSZ9477_CHIP_ID,1527 .dev_name = "KSZ9477",1528 .num_vlans = 4096,1529 .num_alus = 4096,1530 .num_statics = 16,1531 .cpu_ports = 0x7F, /* can be configured as cpu port */1532 .port_cnt = 7, /* total physical port count */1533 .port_nirqs = 4,1534 .num_tx_queues = 4,1535 .num_ipms = 8,1536 .tc_cbs_supported = true,1537 .ops = &ksz9477_dev_ops,1538 .phylink_mac_ops = &ksz9477_phylink_mac_ops,1539 .phy_errata_9477 = true,1540 .mib_names = ksz9477_mib_names,1541 .mib_cnt = ARRAY_SIZE(ksz9477_mib_names),1542 .reg_mib_cnt = MIB_COUNTER_NUM,1543 .regs = ksz9477_regs,1544 .masks = ksz9477_masks,1545 .shifts = ksz9477_shifts,1546 .xmii_ctrl0 = ksz9477_xmii_ctrl0,1547 .xmii_ctrl1 = ksz9477_xmii_ctrl1,1548 .supports_mii = {false, false, false, false,1549 false, true, false},1550 .supports_rmii = {false, false, false, false,1551 false, true, false},1552 .supports_rgmii = {false, false, false, false,1553 false, true, false},1554 .internal_phy = {true, true, true, true,1555 true, false, false},1556 .gbit_capable = {true, true, true, true, true, true, true},1557 .wr_table = &ksz9477_register_set,1558 .rd_table = &ksz9477_register_set,1559 },1560 1561 [KSZ9896] = {1562 .chip_id = KSZ9896_CHIP_ID,1563 .dev_name = "KSZ9896",1564 .num_vlans = 4096,1565 .num_alus = 4096,1566 .num_statics = 16,1567 .cpu_ports = 0x3F, /* can be configured as cpu port */1568 .port_cnt = 6, /* total physical port count */1569 .port_nirqs = 2,1570 .num_tx_queues = 4,1571 .num_ipms = 8,1572 .ops = &ksz9477_dev_ops,1573 .phylink_mac_ops = &ksz9477_phylink_mac_ops,1574 .phy_errata_9477 = true,1575 .mib_names = ksz9477_mib_names,1576 .mib_cnt = ARRAY_SIZE(ksz9477_mib_names),1577 .reg_mib_cnt = MIB_COUNTER_NUM,1578 .regs = ksz9477_regs,1579 .masks = ksz9477_masks,1580 .shifts = ksz9477_shifts,1581 .xmii_ctrl0 = ksz9477_xmii_ctrl0,1582 .xmii_ctrl1 = ksz9477_xmii_ctrl1,1583 .supports_mii = {false, false, false, false,1584 false, true},1585 .supports_rmii = {false, false, false, false,1586 false, true},1587 .supports_rgmii = {false, false, false, false,1588 false, true},1589 .internal_phy = {true, true, true, true,1590 true, false},1591 .gbit_capable = {true, true, true, true, true, true},1592 .wr_table = &ksz9896_register_set,1593 .rd_table = &ksz9896_register_set,1594 },1595 1596 [KSZ9897] = {1597 .chip_id = KSZ9897_CHIP_ID,1598 .dev_name = "KSZ9897",1599 .num_vlans = 4096,1600 .num_alus = 4096,1601 .num_statics = 16,1602 .cpu_ports = 0x7F, /* can be configured as cpu port */1603 .port_cnt = 7, /* total physical port count */1604 .port_nirqs = 2,1605 .num_tx_queues = 4,1606 .num_ipms = 8,1607 .ops = &ksz9477_dev_ops,1608 .phylink_mac_ops = &ksz9477_phylink_mac_ops,1609 .phy_errata_9477 = true,1610 .mib_names = ksz9477_mib_names,1611 .mib_cnt = ARRAY_SIZE(ksz9477_mib_names),1612 .reg_mib_cnt = MIB_COUNTER_NUM,1613 .regs = ksz9477_regs,1614 .masks = ksz9477_masks,1615 .shifts = ksz9477_shifts,1616 .xmii_ctrl0 = ksz9477_xmii_ctrl0,1617 .xmii_ctrl1 = ksz9477_xmii_ctrl1,1618 .supports_mii = {false, false, false, false,1619 false, true, true},1620 .supports_rmii = {false, false, false, false,1621 false, true, true},1622 .supports_rgmii = {false, false, false, false,1623 false, true, true},1624 .internal_phy = {true, true, true, true,1625 true, false, false},1626 .gbit_capable = {true, true, true, true, true, true, true},1627 },1628 1629 [KSZ9893] = {1630 .chip_id = KSZ9893_CHIP_ID,1631 .dev_name = "KSZ9893",1632 .num_vlans = 4096,1633 .num_alus = 4096,1634 .num_statics = 16,1635 .cpu_ports = 0x07, /* can be configured as cpu port */1636 .port_cnt = 3, /* total port count */1637 .port_nirqs = 2,1638 .num_tx_queues = 4,1639 .num_ipms = 8,1640 .ops = &ksz9477_dev_ops,1641 .phylink_mac_ops = &ksz9477_phylink_mac_ops,1642 .mib_names = ksz9477_mib_names,1643 .mib_cnt = ARRAY_SIZE(ksz9477_mib_names),1644 .reg_mib_cnt = MIB_COUNTER_NUM,1645 .regs = ksz9477_regs,1646 .masks = ksz9477_masks,1647 .shifts = ksz9477_shifts,1648 .xmii_ctrl0 = ksz9477_xmii_ctrl0,1649 .xmii_ctrl1 = ksz8795_xmii_ctrl1, /* Same as ksz8795 */1650 .supports_mii = {false, false, true},1651 .supports_rmii = {false, false, true},1652 .supports_rgmii = {false, false, true},1653 .internal_phy = {true, true, false},1654 .gbit_capable = {true, true, true},1655 },1656 1657 [KSZ9563] = {1658 .chip_id = KSZ9563_CHIP_ID,1659 .dev_name = "KSZ9563",1660 .num_vlans = 4096,1661 .num_alus = 4096,1662 .num_statics = 16,1663 .cpu_ports = 0x07, /* can be configured as cpu port */1664 .port_cnt = 3, /* total port count */1665 .port_nirqs = 3,1666 .num_tx_queues = 4,1667 .num_ipms = 8,1668 .tc_cbs_supported = true,1669 .ops = &ksz9477_dev_ops,1670 .phylink_mac_ops = &ksz9477_phylink_mac_ops,1671 .mib_names = ksz9477_mib_names,1672 .mib_cnt = ARRAY_SIZE(ksz9477_mib_names),1673 .reg_mib_cnt = MIB_COUNTER_NUM,1674 .regs = ksz9477_regs,1675 .masks = ksz9477_masks,1676 .shifts = ksz9477_shifts,1677 .xmii_ctrl0 = ksz9477_xmii_ctrl0,1678 .xmii_ctrl1 = ksz8795_xmii_ctrl1, /* Same as ksz8795 */1679 .supports_mii = {false, false, true},1680 .supports_rmii = {false, false, true},1681 .supports_rgmii = {false, false, true},1682 .internal_phy = {true, true, false},1683 .gbit_capable = {true, true, true},1684 },1685 1686 [KSZ8567] = {1687 .chip_id = KSZ8567_CHIP_ID,1688 .dev_name = "KSZ8567",1689 .num_vlans = 4096,1690 .num_alus = 4096,1691 .num_statics = 16,1692 .cpu_ports = 0x7F, /* can be configured as cpu port */1693 .port_cnt = 7, /* total port count */1694 .port_nirqs = 3,1695 .num_tx_queues = 4,1696 .num_ipms = 8,1697 .tc_cbs_supported = true,1698 .ops = &ksz9477_dev_ops,1699 .phylink_mac_ops = &ksz9477_phylink_mac_ops,1700 .phy_errata_9477 = true,1701 .mib_names = ksz9477_mib_names,1702 .mib_cnt = ARRAY_SIZE(ksz9477_mib_names),1703 .reg_mib_cnt = MIB_COUNTER_NUM,1704 .regs = ksz9477_regs,1705 .masks = ksz9477_masks,1706 .shifts = ksz9477_shifts,1707 .xmii_ctrl0 = ksz9477_xmii_ctrl0,1708 .xmii_ctrl1 = ksz9477_xmii_ctrl1,1709 .supports_mii = {false, false, false, false,1710 false, true, true},1711 .supports_rmii = {false, false, false, false,1712 false, true, true},1713 .supports_rgmii = {false, false, false, false,1714 false, true, true},1715 .internal_phy = {true, true, true, true,1716 true, false, false},1717 .gbit_capable = {false, false, false, false, false,1718 true, true},1719 },1720 1721 [KSZ9567] = {1722 .chip_id = KSZ9567_CHIP_ID,1723 .dev_name = "KSZ9567",1724 .num_vlans = 4096,1725 .num_alus = 4096,1726 .num_statics = 16,1727 .cpu_ports = 0x7F, /* can be configured as cpu port */1728 .port_cnt = 7, /* total physical port count */1729 .port_nirqs = 3,1730 .num_tx_queues = 4,1731 .num_ipms = 8,1732 .tc_cbs_supported = true,1733 .ops = &ksz9477_dev_ops,1734 .mib_names = ksz9477_mib_names,1735 .mib_cnt = ARRAY_SIZE(ksz9477_mib_names),1736 .reg_mib_cnt = MIB_COUNTER_NUM,1737 .regs = ksz9477_regs,1738 .masks = ksz9477_masks,1739 .shifts = ksz9477_shifts,1740 .xmii_ctrl0 = ksz9477_xmii_ctrl0,1741 .xmii_ctrl1 = ksz9477_xmii_ctrl1,1742 .supports_mii = {false, false, false, false,1743 false, true, true},1744 .supports_rmii = {false, false, false, false,1745 false, true, true},1746 .supports_rgmii = {false, false, false, false,1747 false, true, true},1748 .internal_phy = {true, true, true, true,1749 true, false, false},1750 .gbit_capable = {true, true, true, true, true, true, true},1751 },1752 1753 [LAN9370] = {1754 .chip_id = LAN9370_CHIP_ID,1755 .dev_name = "LAN9370",1756 .num_vlans = 4096,1757 .num_alus = 1024,1758 .num_statics = 256,1759 .cpu_ports = 0x10, /* can be configured as cpu port */1760 .port_cnt = 5, /* total physical port count */1761 .port_nirqs = 6,1762 .num_tx_queues = 8,1763 .num_ipms = 8,1764 .tc_cbs_supported = true,1765 .ops = &lan937x_dev_ops,1766 .phylink_mac_ops = &lan937x_phylink_mac_ops,1767 .mib_names = ksz9477_mib_names,1768 .mib_cnt = ARRAY_SIZE(ksz9477_mib_names),1769 .reg_mib_cnt = MIB_COUNTER_NUM,1770 .regs = ksz9477_regs,1771 .masks = lan937x_masks,1772 .shifts = lan937x_shifts,1773 .xmii_ctrl0 = ksz9477_xmii_ctrl0,1774 .xmii_ctrl1 = ksz9477_xmii_ctrl1,1775 .supports_mii = {false, false, false, false, true},1776 .supports_rmii = {false, false, false, false, true},1777 .supports_rgmii = {false, false, false, false, true},1778 .internal_phy = {true, true, true, true, false},1779 },1780 1781 [LAN9371] = {1782 .chip_id = LAN9371_CHIP_ID,1783 .dev_name = "LAN9371",1784 .num_vlans = 4096,1785 .num_alus = 1024,1786 .num_statics = 256,1787 .cpu_ports = 0x30, /* can be configured as cpu port */1788 .port_cnt = 6, /* total physical port count */1789 .port_nirqs = 6,1790 .num_tx_queues = 8,1791 .num_ipms = 8,1792 .tc_cbs_supported = true,1793 .ops = &lan937x_dev_ops,1794 .phylink_mac_ops = &lan937x_phylink_mac_ops,1795 .mib_names = ksz9477_mib_names,1796 .mib_cnt = ARRAY_SIZE(ksz9477_mib_names),1797 .reg_mib_cnt = MIB_COUNTER_NUM,1798 .regs = ksz9477_regs,1799 .masks = lan937x_masks,1800 .shifts = lan937x_shifts,1801 .xmii_ctrl0 = ksz9477_xmii_ctrl0,1802 .xmii_ctrl1 = ksz9477_xmii_ctrl1,1803 .supports_mii = {false, false, false, false, true, true},1804 .supports_rmii = {false, false, false, false, true, true},1805 .supports_rgmii = {false, false, false, false, true, true},1806 .internal_phy = {true, true, true, true, false, false},1807 },1808 1809 [LAN9372] = {1810 .chip_id = LAN9372_CHIP_ID,1811 .dev_name = "LAN9372",1812 .num_vlans = 4096,1813 .num_alus = 1024,1814 .num_statics = 256,1815 .cpu_ports = 0x30, /* can be configured as cpu port */1816 .port_cnt = 8, /* total physical port count */1817 .port_nirqs = 6,1818 .num_tx_queues = 8,1819 .num_ipms = 8,1820 .tc_cbs_supported = true,1821 .ops = &lan937x_dev_ops,1822 .phylink_mac_ops = &lan937x_phylink_mac_ops,1823 .mib_names = ksz9477_mib_names,1824 .mib_cnt = ARRAY_SIZE(ksz9477_mib_names),1825 .reg_mib_cnt = MIB_COUNTER_NUM,1826 .regs = ksz9477_regs,1827 .masks = lan937x_masks,1828 .shifts = lan937x_shifts,1829 .xmii_ctrl0 = ksz9477_xmii_ctrl0,1830 .xmii_ctrl1 = ksz9477_xmii_ctrl1,1831 .supports_mii = {false, false, false, false,1832 true, true, false, false},1833 .supports_rmii = {false, false, false, false,1834 true, true, false, false},1835 .supports_rgmii = {false, false, false, false,1836 true, true, false, false},1837 .internal_phy = {true, true, true, true,1838 false, false, true, true},1839 },1840 1841 [LAN9373] = {1842 .chip_id = LAN9373_CHIP_ID,1843 .dev_name = "LAN9373",1844 .num_vlans = 4096,1845 .num_alus = 1024,1846 .num_statics = 256,1847 .cpu_ports = 0x38, /* can be configured as cpu port */1848 .port_cnt = 5, /* total physical port count */1849 .port_nirqs = 6,1850 .num_tx_queues = 8,1851 .num_ipms = 8,1852 .tc_cbs_supported = true,1853 .ops = &lan937x_dev_ops,1854 .phylink_mac_ops = &lan937x_phylink_mac_ops,1855 .mib_names = ksz9477_mib_names,1856 .mib_cnt = ARRAY_SIZE(ksz9477_mib_names),1857 .reg_mib_cnt = MIB_COUNTER_NUM,1858 .regs = ksz9477_regs,1859 .masks = lan937x_masks,1860 .shifts = lan937x_shifts,1861 .xmii_ctrl0 = ksz9477_xmii_ctrl0,1862 .xmii_ctrl1 = ksz9477_xmii_ctrl1,1863 .supports_mii = {false, false, false, false,1864 true, true, false, false},1865 .supports_rmii = {false, false, false, false,1866 true, true, false, false},1867 .supports_rgmii = {false, false, false, false,1868 true, true, false, false},1869 .internal_phy = {true, true, true, false,1870 false, false, true, true},1871 },1872 1873 [LAN9374] = {1874 .chip_id = LAN9374_CHIP_ID,1875 .dev_name = "LAN9374",1876 .num_vlans = 4096,1877 .num_alus = 1024,1878 .num_statics = 256,1879 .cpu_ports = 0x30, /* can be configured as cpu port */1880 .port_cnt = 8, /* total physical port count */1881 .port_nirqs = 6,1882 .num_tx_queues = 8,1883 .num_ipms = 8,1884 .tc_cbs_supported = true,1885 .ops = &lan937x_dev_ops,1886 .phylink_mac_ops = &lan937x_phylink_mac_ops,1887 .mib_names = ksz9477_mib_names,1888 .mib_cnt = ARRAY_SIZE(ksz9477_mib_names),1889 .reg_mib_cnt = MIB_COUNTER_NUM,1890 .regs = ksz9477_regs,1891 .masks = lan937x_masks,1892 .shifts = lan937x_shifts,1893 .xmii_ctrl0 = ksz9477_xmii_ctrl0,1894 .xmii_ctrl1 = ksz9477_xmii_ctrl1,1895 .supports_mii = {false, false, false, false,1896 true, true, false, false},1897 .supports_rmii = {false, false, false, false,1898 true, true, false, false},1899 .supports_rgmii = {false, false, false, false,1900 true, true, false, false},1901 .internal_phy = {true, true, true, true,1902 false, false, true, true},1903 },1904};1905EXPORT_SYMBOL_GPL(ksz_switch_chips);1906 1907static const struct ksz_chip_data *ksz_lookup_info(unsigned int prod_num)1908{1909 int i;1910 1911 for (i = 0; i < ARRAY_SIZE(ksz_switch_chips); i++) {1912 const struct ksz_chip_data *chip = &ksz_switch_chips[i];1913 1914 if (chip->chip_id == prod_num)1915 return chip;1916 }1917 1918 return NULL;1919}1920 1921static int ksz_check_device_id(struct ksz_device *dev)1922{1923 const struct ksz_chip_data *expected_chip_data;1924 u32 expected_chip_id;1925 1926 if (dev->pdata) {1927 expected_chip_id = dev->pdata->chip_id;1928 expected_chip_data = ksz_lookup_info(expected_chip_id);1929 if (WARN_ON(!expected_chip_data))1930 return -ENODEV;1931 } else {1932 expected_chip_data = of_device_get_match_data(dev->dev);1933 expected_chip_id = expected_chip_data->chip_id;1934 }1935 1936 if (expected_chip_id != dev->chip_id) {1937 dev_err(dev->dev,1938 "Device tree specifies chip %s but found %s, please fix it!\n",1939 expected_chip_data->dev_name, dev->info->dev_name);1940 return -ENODEV;1941 }1942 1943 return 0;1944}1945 1946static void ksz_phylink_get_caps(struct dsa_switch *ds, int port,1947 struct phylink_config *config)1948{1949 struct ksz_device *dev = ds->priv;1950 1951 if (dev->info->supports_mii[port])1952 __set_bit(PHY_INTERFACE_MODE_MII, config->supported_interfaces);1953 1954 if (dev->info->supports_rmii[port])1955 __set_bit(PHY_INTERFACE_MODE_RMII,1956 config->supported_interfaces);1957 1958 if (dev->info->supports_rgmii[port])1959 phy_interface_set_rgmii(config->supported_interfaces);1960 1961 if (dev->info->internal_phy[port]) {1962 __set_bit(PHY_INTERFACE_MODE_INTERNAL,1963 config->supported_interfaces);1964 /* Compatibility for phylib's default interface type when the1965 * phy-mode property is absent1966 */1967 __set_bit(PHY_INTERFACE_MODE_GMII,1968 config->supported_interfaces);1969 }1970 1971 if (dev->dev_ops->get_caps)1972 dev->dev_ops->get_caps(dev, port, config);1973}1974 1975void ksz_r_mib_stats64(struct ksz_device *dev, int port)1976{1977 struct ethtool_pause_stats *pstats;1978 struct rtnl_link_stats64 *stats;1979 struct ksz_stats_raw *raw;1980 struct ksz_port_mib *mib;1981 int ret;1982 1983 mib = &dev->ports[port].mib;1984 stats = &mib->stats64;1985 pstats = &mib->pause_stats;1986 raw = (struct ksz_stats_raw *)mib->counters;1987 1988 spin_lock(&mib->stats64_lock);1989 1990 stats->rx_packets = raw->rx_bcast + raw->rx_mcast + raw->rx_ucast +1991 raw->rx_pause;1992 stats->tx_packets = raw->tx_bcast + raw->tx_mcast + raw->tx_ucast +1993 raw->tx_pause;1994 1995 /* HW counters are counting bytes + FCS which is not acceptable1996 * for rtnl_link_stats64 interface1997 */1998 stats->rx_bytes = raw->rx_total - stats->rx_packets * ETH_FCS_LEN;1999 stats->tx_bytes = raw->tx_total - stats->tx_packets * ETH_FCS_LEN;2000 2001 stats->rx_length_errors = raw->rx_undersize + raw->rx_fragments +2002 raw->rx_oversize;2003 2004 stats->rx_crc_errors = raw->rx_crc_err;2005 stats->rx_frame_errors = raw->rx_align_err;2006 stats->rx_dropped = raw->rx_discards;2007 stats->rx_errors = stats->rx_length_errors + stats->rx_crc_errors +2008 stats->rx_frame_errors + stats->rx_dropped;2009 2010 stats->tx_window_errors = raw->tx_late_col;2011 stats->tx_fifo_errors = raw->tx_discards;2012 stats->tx_aborted_errors = raw->tx_exc_col;2013 stats->tx_errors = stats->tx_window_errors + stats->tx_fifo_errors +2014 stats->tx_aborted_errors;2015 2016 stats->multicast = raw->rx_mcast;2017 stats->collisions = raw->tx_total_col;2018 2019 pstats->tx_pause_frames = raw->tx_pause;2020 pstats->rx_pause_frames = raw->rx_pause;2021 2022 spin_unlock(&mib->stats64_lock);2023 2024 if (dev->info->phy_errata_9477) {2025 ret = ksz9477_errata_monitor(dev, port, raw->tx_late_col);2026 if (ret)2027 dev_err(dev->dev, "Failed to monitor transmission halt\n");2028 }2029}2030 2031void ksz88xx_r_mib_stats64(struct ksz_device *dev, int port)2032{2033 struct ethtool_pause_stats *pstats;2034 struct rtnl_link_stats64 *stats;2035 struct ksz88xx_stats_raw *raw;2036 struct ksz_port_mib *mib;2037 2038 mib = &dev->ports[port].mib;2039 stats = &mib->stats64;2040 pstats = &mib->pause_stats;2041 raw = (struct ksz88xx_stats_raw *)mib->counters;2042 2043 spin_lock(&mib->stats64_lock);2044 2045 stats->rx_packets = raw->rx_bcast + raw->rx_mcast + raw->rx_ucast +2046 raw->rx_pause;2047 stats->tx_packets = raw->tx_bcast + raw->tx_mcast + raw->tx_ucast +2048 raw->tx_pause;2049 2050 /* HW counters are counting bytes + FCS which is not acceptable2051 * for rtnl_link_stats64 interface2052 */2053 stats->rx_bytes = raw->rx + raw->rx_hi - stats->rx_packets * ETH_FCS_LEN;2054 stats->tx_bytes = raw->tx + raw->tx_hi - stats->tx_packets * ETH_FCS_LEN;2055 2056 stats->rx_length_errors = raw->rx_undersize + raw->rx_fragments +2057 raw->rx_oversize;2058 2059 stats->rx_crc_errors = raw->rx_crc_err;2060 stats->rx_frame_errors = raw->rx_align_err;2061 stats->rx_dropped = raw->rx_discards;2062 stats->rx_errors = stats->rx_length_errors + stats->rx_crc_errors +2063 stats->rx_frame_errors + stats->rx_dropped;2064 2065 stats->tx_window_errors = raw->tx_late_col;2066 stats->tx_fifo_errors = raw->tx_discards;2067 stats->tx_aborted_errors = raw->tx_exc_col;2068 stats->tx_errors = stats->tx_window_errors + stats->tx_fifo_errors +2069 stats->tx_aborted_errors;2070 2071 stats->multicast = raw->rx_mcast;2072 stats->collisions = raw->tx_total_col;2073 2074 pstats->tx_pause_frames = raw->tx_pause;2075 pstats->rx_pause_frames = raw->rx_pause;2076 2077 spin_unlock(&mib->stats64_lock);2078}2079 2080static void ksz_get_stats64(struct dsa_switch *ds, int port,2081 struct rtnl_link_stats64 *s)2082{2083 struct ksz_device *dev = ds->priv;2084 struct ksz_port_mib *mib;2085 2086 mib = &dev->ports[port].mib;2087 2088 spin_lock(&mib->stats64_lock);2089 memcpy(s, &mib->stats64, sizeof(*s));2090 spin_unlock(&mib->stats64_lock);2091}2092 2093static void ksz_get_pause_stats(struct dsa_switch *ds, int port,2094 struct ethtool_pause_stats *pause_stats)2095{2096 struct ksz_device *dev = ds->priv;2097 struct ksz_port_mib *mib;2098 2099 mib = &dev->ports[port].mib;2100 2101 spin_lock(&mib->stats64_lock);2102 memcpy(pause_stats, &mib->pause_stats, sizeof(*pause_stats));2103 spin_unlock(&mib->stats64_lock);2104}2105 2106static void ksz_get_strings(struct dsa_switch *ds, int port,2107 u32 stringset, uint8_t *buf)2108{2109 struct ksz_device *dev = ds->priv;2110 int i;2111 2112 if (stringset != ETH_SS_STATS)2113 return;2114 2115 for (i = 0; i < dev->info->mib_cnt; i++) {2116 memcpy(buf + i * ETH_GSTRING_LEN,2117 dev->info->mib_names[i].string, ETH_GSTRING_LEN);2118 }2119}2120 2121/**2122 * ksz_update_port_member - Adjust port forwarding rules based on STP state and2123 * isolation settings.2124 * @dev: A pointer to the struct ksz_device representing the device.2125 * @port: The port number to adjust.2126 *2127 * This function dynamically adjusts the port membership configuration for a2128 * specified port and other device ports, based on Spanning Tree Protocol (STP)2129 * states and port isolation settings. Each port, including the CPU port, has a2130 * membership register, represented as a bitfield, where each bit corresponds2131 * to a port number. A set bit indicates permission to forward frames to that2132 * port. This function iterates over all ports, updating the membership register2133 * to reflect current forwarding permissions:2134 *2135 * 1. Forwards frames only to ports that are part of the same bridge group and2136 * in the BR_STATE_FORWARDING state.2137 * 2. Takes into account the isolation status of ports; ports in the2138 * BR_STATE_FORWARDING state with BR_ISOLATED configuration will not forward2139 * frames to each other, even if they are in the same bridge group.2140 * 3. Ensures that the CPU port is included in the membership based on its2141 * upstream port configuration, allowing for management and control traffic2142 * to flow as required.2143 */2144static void ksz_update_port_member(struct ksz_device *dev, int port)2145{2146 struct ksz_port *p = &dev->ports[port];2147 struct dsa_switch *ds = dev->ds;2148 u8 port_member = 0, cpu_port;2149 const struct dsa_port *dp;2150 int i, j;2151 2152 if (!dsa_is_user_port(ds, port))2153 return;2154 2155 dp = dsa_to_port(ds, port);2156 cpu_port = BIT(dsa_upstream_port(ds, port));2157 2158 for (i = 0; i < ds->num_ports; i++) {2159 const struct dsa_port *other_dp = dsa_to_port(ds, i);2160 struct ksz_port *other_p = &dev->ports[i];2161 u8 val = 0;2162 2163 if (!dsa_is_user_port(ds, i))2164 continue;2165 if (port == i)2166 continue;2167 if (!dsa_port_bridge_same(dp, other_dp))2168 continue;2169 if (other_p->stp_state != BR_STATE_FORWARDING)2170 continue;2171 2172 /* At this point we know that "port" and "other" port [i] are in2173 * the same bridge group and that "other" port [i] is in2174 * forwarding stp state. If "port" is also in forwarding stp2175 * state, we can allow forwarding from port [port] to port [i].2176 * Except if both ports are isolated.2177 */2178 if (p->stp_state == BR_STATE_FORWARDING &&2179 !(p->isolated && other_p->isolated)) {2180 val |= BIT(port);2181 port_member |= BIT(i);2182 }2183 2184 /* Retain port [i]'s relationship to other ports than [port] */2185 for (j = 0; j < ds->num_ports; j++) {2186 const struct dsa_port *third_dp;2187 struct ksz_port *third_p;2188 2189 if (j == i)2190 continue;2191 if (j == port)2192 continue;2193 if (!dsa_is_user_port(ds, j))2194 continue;2195 third_p = &dev->ports[j];2196 if (third_p->stp_state != BR_STATE_FORWARDING)2197 continue;2198 2199 third_dp = dsa_to_port(ds, j);2200 2201 /* Now we updating relation of the "other" port [i] to2202 * the "third" port [j]. We already know that "other"2203 * port [i] is in forwarding stp state and that "third"2204 * port [j] is in forwarding stp state too.2205 * We need to check if "other" port [i] and "third" port2206 * [j] are in the same bridge group and not isolated2207 * before allowing forwarding from port [i] to port [j].2208 */2209 if (dsa_port_bridge_same(other_dp, third_dp) &&2210 !(other_p->isolated && third_p->isolated))2211 val |= BIT(j);2212 }2213 2214 dev->dev_ops->cfg_port_member(dev, i, val | cpu_port);2215 }2216 2217 dev->dev_ops->cfg_port_member(dev, port, port_member | cpu_port);2218}2219 2220static int ksz_sw_mdio_read(struct mii_bus *bus, int addr, int regnum)2221{2222 struct ksz_device *dev = bus->priv;2223 u16 val;2224 int ret;2225 2226 ret = dev->dev_ops->r_phy(dev, addr, regnum, &val);2227 if (ret < 0)2228 return ret;2229 2230 return val;2231}2232 2233static int ksz_sw_mdio_write(struct mii_bus *bus, int addr, int regnum,2234 u16 val)2235{2236 struct ksz_device *dev = bus->priv;2237 2238 return dev->dev_ops->w_phy(dev, addr, regnum, val);2239}2240 2241static int ksz_irq_phy_setup(struct ksz_device *dev)2242{2243 struct dsa_switch *ds = dev->ds;2244 int phy;2245 int irq;2246 int ret;2247 2248 for (phy = 0; phy < KSZ_MAX_NUM_PORTS; phy++) {2249 if (BIT(phy) & ds->phys_mii_mask) {2250 irq = irq_find_mapping(dev->ports[phy].pirq.domain,2251 PORT_SRC_PHY_INT);2252 if (irq < 0) {2253 ret = irq;2254 goto out;2255 }2256 ds->user_mii_bus->irq[phy] = irq;2257 }2258 }2259 return 0;2260out:2261 while (phy--)2262 if (BIT(phy) & ds->phys_mii_mask)2263 irq_dispose_mapping(ds->user_mii_bus->irq[phy]);2264 2265 return ret;2266}2267 2268static void ksz_irq_phy_free(struct ksz_device *dev)2269{2270 struct dsa_switch *ds = dev->ds;2271 int phy;2272 2273 for (phy = 0; phy < KSZ_MAX_NUM_PORTS; phy++)2274 if (BIT(phy) & ds->phys_mii_mask)2275 irq_dispose_mapping(ds->user_mii_bus->irq[phy]);2276}2277 2278static int ksz_mdio_register(struct ksz_device *dev)2279{2280 struct dsa_switch *ds = dev->ds;2281 struct device_node *mdio_np;2282 struct mii_bus *bus;2283 int ret;2284 2285 mdio_np = of_get_child_by_name(dev->dev->of_node, "mdio");2286 if (!mdio_np)2287 return 0;2288 2289 bus = devm_mdiobus_alloc(ds->dev);2290 if (!bus) {2291 of_node_put(mdio_np);2292 return -ENOMEM;2293 }2294 2295 bus->priv = dev;2296 bus->read = ksz_sw_mdio_read;2297 bus->write = ksz_sw_mdio_write;2298 bus->name = "ksz user smi";2299 snprintf(bus->id, MII_BUS_ID_SIZE, "SMI-%d", ds->index);2300 bus->parent = ds->dev;2301 bus->phy_mask = ~ds->phys_mii_mask;2302 2303 ds->user_mii_bus = bus;2304 2305 if (dev->irq > 0) {2306 ret = ksz_irq_phy_setup(dev);2307 if (ret) {2308 of_node_put(mdio_np);2309 return ret;2310 }2311 }2312 2313 ret = devm_of_mdiobus_register(ds->dev, bus, mdio_np);2314 if (ret) {2315 dev_err(ds->dev, "unable to register MDIO bus %s\n",2316 bus->id);2317 if (dev->irq > 0)2318 ksz_irq_phy_free(dev);2319 }2320 2321 of_node_put(mdio_np);2322 2323 return ret;2324}2325 2326static void ksz_irq_mask(struct irq_data *d)2327{2328 struct ksz_irq *kirq = irq_data_get_irq_chip_data(d);2329 2330 kirq->masked |= BIT(d->hwirq);2331}2332 2333static void ksz_irq_unmask(struct irq_data *d)2334{2335 struct ksz_irq *kirq = irq_data_get_irq_chip_data(d);2336 2337 kirq->masked &= ~BIT(d->hwirq);2338}2339 2340static void ksz_irq_bus_lock(struct irq_data *d)2341{2342 struct ksz_irq *kirq = irq_data_get_irq_chip_data(d);2343 2344 mutex_lock(&kirq->dev->lock_irq);2345}2346 2347static void ksz_irq_bus_sync_unlock(struct irq_data *d)2348{2349 struct ksz_irq *kirq = irq_data_get_irq_chip_data(d);2350 struct ksz_device *dev = kirq->dev;2351 int ret;2352 2353 ret = ksz_write8(dev, kirq->reg_mask, kirq->masked);2354 if (ret)2355 dev_err(dev->dev, "failed to change IRQ mask\n");2356 2357 mutex_unlock(&dev->lock_irq);2358}2359 2360static const struct irq_chip ksz_irq_chip = {2361 .name = "ksz-irq",2362 .irq_mask = ksz_irq_mask,2363 .irq_unmask = ksz_irq_unmask,2364 .irq_bus_lock = ksz_irq_bus_lock,2365 .irq_bus_sync_unlock = ksz_irq_bus_sync_unlock,2366};2367 2368static int ksz_irq_domain_map(struct irq_domain *d,2369 unsigned int irq, irq_hw_number_t hwirq)2370{2371 irq_set_chip_data(irq, d->host_data);2372 irq_set_chip_and_handler(irq, &ksz_irq_chip, handle_level_irq);2373 irq_set_noprobe(irq);2374 2375 return 0;2376}2377 2378static const struct irq_domain_ops ksz_irq_domain_ops = {2379 .map = ksz_irq_domain_map,2380 .xlate = irq_domain_xlate_twocell,2381};2382 2383static void ksz_irq_free(struct ksz_irq *kirq)2384{2385 int irq, virq;2386 2387 free_irq(kirq->irq_num, kirq);2388 2389 for (irq = 0; irq < kirq->nirqs; irq++) {2390 virq = irq_find_mapping(kirq->domain, irq);2391 irq_dispose_mapping(virq);2392 }2393 2394 irq_domain_remove(kirq->domain);2395}2396 2397static irqreturn_t ksz_irq_thread_fn(int irq, void *dev_id)2398{2399 struct ksz_irq *kirq = dev_id;2400 unsigned int nhandled = 0;2401 struct ksz_device *dev;2402 unsigned int sub_irq;2403 u8 data;2404 int ret;2405 u8 n;2406 2407 dev = kirq->dev;2408 2409 /* Read interrupt status register */2410 ret = ksz_read8(dev, kirq->reg_status, &data);2411 if (ret)2412 goto out;2413 2414 for (n = 0; n < kirq->nirqs; ++n) {2415 if (data & BIT(n)) {2416 sub_irq = irq_find_mapping(kirq->domain, n);2417 handle_nested_irq(sub_irq);2418 ++nhandled;2419 }2420 }2421out:2422 return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);2423}2424 2425static int ksz_irq_common_setup(struct ksz_device *dev, struct ksz_irq *kirq)2426{2427 int ret, n;2428 2429 kirq->dev = dev;2430 kirq->masked = ~0;2431 2432 kirq->domain = irq_domain_add_simple(dev->dev->of_node, kirq->nirqs, 0,2433 &ksz_irq_domain_ops, kirq);2434 if (!kirq->domain)2435 return -ENOMEM;2436 2437 for (n = 0; n < kirq->nirqs; n++)2438 irq_create_mapping(kirq->domain, n);2439 2440 ret = request_threaded_irq(kirq->irq_num, NULL, ksz_irq_thread_fn,2441 IRQF_ONESHOT, kirq->name, kirq);2442 if (ret)2443 goto out;2444 2445 return 0;2446 2447out:2448 ksz_irq_free(kirq);2449 2450 return ret;2451}2452 2453static int ksz_girq_setup(struct ksz_device *dev)2454{2455 struct ksz_irq *girq = &dev->girq;2456 2457 girq->nirqs = dev->info->port_cnt;2458 girq->reg_mask = REG_SW_PORT_INT_MASK__1;2459 girq->reg_status = REG_SW_PORT_INT_STATUS__1;2460 snprintf(girq->name, sizeof(girq->name), "global_port_irq");2461 2462 girq->irq_num = dev->irq;2463 2464 return ksz_irq_common_setup(dev, girq);2465}2466 2467static int ksz_pirq_setup(struct ksz_device *dev, u8 p)2468{2469 struct ksz_irq *pirq = &dev->ports[p].pirq;2470 2471 pirq->nirqs = dev->info->port_nirqs;2472 pirq->reg_mask = dev->dev_ops->get_port_addr(p, REG_PORT_INT_MASK);2473 pirq->reg_status = dev->dev_ops->get_port_addr(p, REG_PORT_INT_STATUS);2474 snprintf(pirq->name, sizeof(pirq->name), "port_irq-%d", p);2475 2476 pirq->irq_num = irq_find_mapping(dev->girq.domain, p);2477 if (pirq->irq_num < 0)2478 return pirq->irq_num;2479 2480 return ksz_irq_common_setup(dev, pirq);2481}2482 2483static int ksz_parse_drive_strength(struct ksz_device *dev);2484 2485static int ksz_setup(struct dsa_switch *ds)2486{2487 struct ksz_device *dev = ds->priv;2488 struct dsa_port *dp;2489 struct ksz_port *p;2490 const u16 *regs;2491 int ret;2492 2493 regs = dev->info->regs;2494 2495 dev->vlan_cache = devm_kcalloc(dev->dev, sizeof(struct vlan_table),2496 dev->info->num_vlans, GFP_KERNEL);2497 if (!dev->vlan_cache)2498 return -ENOMEM;2499 2500 ret = dev->dev_ops->reset(dev);2501 if (ret) {2502 dev_err(ds->dev, "failed to reset switch\n");2503 return ret;2504 }2505 2506 ret = ksz_parse_drive_strength(dev);2507 if (ret)2508 return ret;2509 2510 /* set broadcast storm protection 10% rate */2511 regmap_update_bits(ksz_regmap_16(dev), regs[S_BROADCAST_CTRL],2512 BROADCAST_STORM_RATE,2513 (BROADCAST_STORM_VALUE *2514 BROADCAST_STORM_PROT_RATE) / 100);2515 2516 dev->dev_ops->config_cpu_port(ds);2517 2518 dev->dev_ops->enable_stp_addr(dev);2519 2520 ds->num_tx_queues = dev->info->num_tx_queues;2521 2522 regmap_update_bits(ksz_regmap_8(dev), regs[S_MULTICAST_CTRL],2523 MULTICAST_STORM_DISABLE, MULTICAST_STORM_DISABLE);2524 2525 ksz_init_mib_timer(dev);2526 2527 ds->configure_vlan_while_not_filtering = false;2528 ds->dscp_prio_mapping_is_global = true;2529 2530 if (dev->dev_ops->setup) {2531 ret = dev->dev_ops->setup(ds);2532 if (ret)2533 return ret;2534 }2535 2536 /* Start with learning disabled on standalone user ports, and enabled2537 * on the CPU port. In lack of other finer mechanisms, learning on the2538 * CPU port will avoid flooding bridge local addresses on the network2539 * in some cases.2540 */2541 p = &dev->ports[dev->cpu_port];2542 p->learning = true;2543 2544 if (dev->irq > 0) {2545 ret = ksz_girq_setup(dev);2546 if (ret)2547 return ret;2548 2549 dsa_switch_for_each_user_port(dp, dev->ds) {2550 ret = ksz_pirq_setup(dev, dp->index);2551 if (ret)2552 goto out_girq;2553 2554 ret = ksz_ptp_irq_setup(ds, dp->index);2555 if (ret)2556 goto out_pirq;2557 }2558 }2559 2560 ret = ksz_ptp_clock_register(ds);2561 if (ret) {2562 dev_err(dev->dev, "Failed to register PTP clock: %d\n", ret);2563 goto out_ptpirq;2564 }2565 2566 ret = ksz_mdio_register(dev);2567 if (ret < 0) {2568 dev_err(dev->dev, "failed to register the mdio");2569 goto out_ptp_clock_unregister;2570 }2571 2572 ret = ksz_dcb_init(dev);2573 if (ret)2574 goto out_ptp_clock_unregister;2575 2576 /* start switch */2577 regmap_update_bits(ksz_regmap_8(dev), regs[S_START_CTRL],2578 SW_START, SW_START);2579 2580 return 0;2581 2582out_ptp_clock_unregister:2583 ksz_ptp_clock_unregister(ds);2584out_ptpirq:2585 if (dev->irq > 0)2586 dsa_switch_for_each_user_port(dp, dev->ds)2587 ksz_ptp_irq_free(ds, dp->index);2588out_pirq:2589 if (dev->irq > 0)2590 dsa_switch_for_each_user_port(dp, dev->ds)2591 ksz_irq_free(&dev->ports[dp->index].pirq);2592out_girq:2593 if (dev->irq > 0)2594 ksz_irq_free(&dev->girq);2595 2596 return ret;2597}2598 2599static void ksz_teardown(struct dsa_switch *ds)2600{2601 struct ksz_device *dev = ds->priv;2602 struct dsa_port *dp;2603 2604 ksz_ptp_clock_unregister(ds);2605 2606 if (dev->irq > 0) {2607 dsa_switch_for_each_user_port(dp, dev->ds) {2608 ksz_ptp_irq_free(ds, dp->index);2609 2610 ksz_irq_free(&dev->ports[dp->index].pirq);2611 }2612 2613 ksz_irq_free(&dev->girq);2614 }2615 2616 if (dev->dev_ops->teardown)2617 dev->dev_ops->teardown(ds);2618}2619 2620static void port_r_cnt(struct ksz_device *dev, int port)2621{2622 struct ksz_port_mib *mib = &dev->ports[port].mib;2623 u64 *dropped;2624 2625 /* Some ports may not have MIB counters before SWITCH_COUNTER_NUM. */2626 while (mib->cnt_ptr < dev->info->reg_mib_cnt) {2627 dev->dev_ops->r_mib_cnt(dev, port, mib->cnt_ptr,2628 &mib->counters[mib->cnt_ptr]);2629 ++mib->cnt_ptr;2630 }2631 2632 /* last one in storage */2633 dropped = &mib->counters[dev->info->mib_cnt];2634 2635 /* Some ports may not have MIB counters after SWITCH_COUNTER_NUM. */2636 while (mib->cnt_ptr < dev->info->mib_cnt) {2637 dev->dev_ops->r_mib_pkt(dev, port, mib->cnt_ptr,2638 dropped, &mib->counters[mib->cnt_ptr]);2639 ++mib->cnt_ptr;2640 }2641 mib->cnt_ptr = 0;2642}2643 2644static void ksz_mib_read_work(struct work_struct *work)2645{2646 struct ksz_device *dev = container_of(work, struct ksz_device,2647 mib_read.work);2648 struct ksz_port_mib *mib;2649 struct ksz_port *p;2650 int i;2651 2652 for (i = 0; i < dev->info->port_cnt; i++) {2653 if (dsa_is_unused_port(dev->ds, i))2654 continue;2655 2656 p = &dev->ports[i];2657 mib = &p->mib;2658 mutex_lock(&mib->cnt_mutex);2659 2660 /* Only read MIB counters when the port is told to do.2661 * If not, read only dropped counters when link is not up.2662 */2663 if (!p->read) {2664 const struct dsa_port *dp = dsa_to_port(dev->ds, i);2665 2666 if (!netif_carrier_ok(dp->user))2667 mib->cnt_ptr = dev->info->reg_mib_cnt;2668 }2669 port_r_cnt(dev, i);2670 p->read = false;2671 2672 if (dev->dev_ops->r_mib_stat64)2673 dev->dev_ops->r_mib_stat64(dev, i);2674 2675 mutex_unlock(&mib->cnt_mutex);2676 }2677 2678 schedule_delayed_work(&dev->mib_read, dev->mib_read_interval);2679}2680 2681void ksz_init_mib_timer(struct ksz_device *dev)2682{2683 int i;2684 2685 INIT_DELAYED_WORK(&dev->mib_read, ksz_mib_read_work);2686 2687 for (i = 0; i < dev->info->port_cnt; i++) {2688 struct ksz_port_mib *mib = &dev->ports[i].mib;2689 2690 dev->dev_ops->port_init_cnt(dev, i);2691 2692 mib->cnt_ptr = 0;2693 memset(mib->counters, 0, dev->info->mib_cnt * sizeof(u64));2694 }2695}2696 2697static int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg)2698{2699 struct ksz_device *dev = ds->priv;2700 u16 val = 0xffff;2701 int ret;2702 2703 ret = dev->dev_ops->r_phy(dev, addr, reg, &val);2704 if (ret)2705 return ret;2706 2707 return val;2708}2709 2710static int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val)2711{2712 struct ksz_device *dev = ds->priv;2713 int ret;2714 2715 ret = dev->dev_ops->w_phy(dev, addr, reg, val);2716 if (ret)2717 return ret;2718 2719 return 0;2720}2721 2722static u32 ksz_get_phy_flags(struct dsa_switch *ds, int port)2723{2724 struct ksz_device *dev = ds->priv;2725 2726 switch (dev->chip_id) {2727 case KSZ88X3_CHIP_ID:2728 /* Silicon Errata Sheet (DS80000830A):2729 * Port 1 does not work with LinkMD Cable-Testing.2730 * Port 1 does not respond to received PAUSE control frames.2731 */2732 if (!port)2733 return MICREL_KSZ8_P1_ERRATA;2734 break;2735 case KSZ8567_CHIP_ID:2736 /* KSZ8567R Errata DS80000752C Module 4 */2737 case KSZ8765_CHIP_ID:2738 case KSZ8794_CHIP_ID:2739 case KSZ8795_CHIP_ID:2740 /* KSZ879x/KSZ877x/KSZ876x Errata DS80000687C Module 2 */2741 case KSZ9477_CHIP_ID:2742 /* KSZ9477S Errata DS80000754A Module 4 */2743 case KSZ9567_CHIP_ID:2744 /* KSZ9567S Errata DS80000756A Module 4 */2745 case KSZ9896_CHIP_ID:2746 /* KSZ9896C Errata DS80000757A Module 3 */2747 case KSZ9897_CHIP_ID:2748 /* KSZ9897R Errata DS80000758C Module 4 */2749 /* Energy Efficient Ethernet (EEE) feature select must be manually disabled2750 * The EEE feature is enabled by default, but it is not fully2751 * operational. It must be manually disabled through register2752 * controls. If not disabled, the PHY ports can auto-negotiate2753 * to enable EEE, and this feature can cause link drops when2754 * linked to another device supporting EEE.2755 *2756 * The same item appears in the errata for all switches above.2757 */2758 return MICREL_NO_EEE;2759 }2760 2761 return 0;2762}2763 2764static void ksz_phylink_mac_link_down(struct phylink_config *config,2765 unsigned int mode,2766 phy_interface_t interface)2767{2768 struct dsa_port *dp = dsa_phylink_to_port(config);2769 struct ksz_device *dev = dp->ds->priv;2770 2771 /* Read all MIB counters when the link is going down. */2772 dev->ports[dp->index].read = true;2773 /* timer started */2774 if (dev->mib_read_interval)2775 schedule_delayed_work(&dev->mib_read, 0);2776}2777 2778static int ksz_sset_count(struct dsa_switch *ds, int port, int sset)2779{2780 struct ksz_device *dev = ds->priv;2781 2782 if (sset != ETH_SS_STATS)2783 return 0;2784 2785 return dev->info->mib_cnt;2786}2787 2788static void ksz_get_ethtool_stats(struct dsa_switch *ds, int port,2789 uint64_t *buf)2790{2791 const struct dsa_port *dp = dsa_to_port(ds, port);2792 struct ksz_device *dev = ds->priv;2793 struct ksz_port_mib *mib;2794 2795 mib = &dev->ports[port].mib;2796 mutex_lock(&mib->cnt_mutex);2797 2798 /* Only read dropped counters if no link. */2799 if (!netif_carrier_ok(dp->user))2800 mib->cnt_ptr = dev->info->reg_mib_cnt;2801 port_r_cnt(dev, port);2802 memcpy(buf, mib->counters, dev->info->mib_cnt * sizeof(u64));2803 mutex_unlock(&mib->cnt_mutex);2804}2805 2806static int ksz_port_bridge_join(struct dsa_switch *ds, int port,2807 struct dsa_bridge bridge,2808 bool *tx_fwd_offload,2809 struct netlink_ext_ack *extack)2810{2811 /* port_stp_state_set() will be called after to put the port in2812 * appropriate state so there is no need to do anything.2813 */2814 2815 return 0;2816}2817 2818static void ksz_port_bridge_leave(struct dsa_switch *ds, int port,2819 struct dsa_bridge bridge)2820{2821 /* port_stp_state_set() will be called after to put the port in2822 * forwarding state so there is no need to do anything.2823 */2824}2825 2826static void ksz_port_fast_age(struct dsa_switch *ds, int port)2827{2828 struct ksz_device *dev = ds->priv;2829 2830 dev->dev_ops->flush_dyn_mac_table(dev, port);2831}2832 2833static int ksz_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)2834{2835 struct ksz_device *dev = ds->priv;2836 2837 if (!dev->dev_ops->set_ageing_time)2838 return -EOPNOTSUPP;2839 2840 return dev->dev_ops->set_ageing_time(dev, msecs);2841}2842 2843static int ksz_port_fdb_add(struct dsa_switch *ds, int port,2844 const unsigned char *addr, u16 vid,2845 struct dsa_db db)2846{2847 struct ksz_device *dev = ds->priv;2848 2849 if (!dev->dev_ops->fdb_add)2850 return -EOPNOTSUPP;2851 2852 return dev->dev_ops->fdb_add(dev, port, addr, vid, db);2853}2854 2855static int ksz_port_fdb_del(struct dsa_switch *ds, int port,2856 const unsigned char *addr,2857 u16 vid, struct dsa_db db)2858{2859 struct ksz_device *dev = ds->priv;2860 2861 if (!dev->dev_ops->fdb_del)2862 return -EOPNOTSUPP;2863 2864 return dev->dev_ops->fdb_del(dev, port, addr, vid, db);2865}2866 2867static int ksz_port_fdb_dump(struct dsa_switch *ds, int port,2868 dsa_fdb_dump_cb_t *cb, void *data)2869{2870 struct ksz_device *dev = ds->priv;2871 2872 if (!dev->dev_ops->fdb_dump)2873 return -EOPNOTSUPP;2874 2875 return dev->dev_ops->fdb_dump(dev, port, cb, data);2876}2877 2878static int ksz_port_mdb_add(struct dsa_switch *ds, int port,2879 const struct switchdev_obj_port_mdb *mdb,2880 struct dsa_db db)2881{2882 struct ksz_device *dev = ds->priv;2883 2884 if (!dev->dev_ops->mdb_add)2885 return -EOPNOTSUPP;2886 2887 return dev->dev_ops->mdb_add(dev, port, mdb, db);2888}2889 2890static int ksz_port_mdb_del(struct dsa_switch *ds, int port,2891 const struct switchdev_obj_port_mdb *mdb,2892 struct dsa_db db)2893{2894 struct ksz_device *dev = ds->priv;2895 2896 if (!dev->dev_ops->mdb_del)2897 return -EOPNOTSUPP;2898 2899 return dev->dev_ops->mdb_del(dev, port, mdb, db);2900}2901 2902static int ksz9477_set_default_prio_queue_mapping(struct ksz_device *dev,2903 int port)2904{2905 u32 queue_map = 0;2906 int ipm;2907 2908 for (ipm = 0; ipm < dev->info->num_ipms; ipm++) {2909 int queue;2910 2911 /* Traffic Type (TT) is corresponding to the Internal Priority2912 * Map (IPM) in the switch. Traffic Class (TC) is2913 * corresponding to the queue in the switch.2914 */2915 queue = ieee8021q_tt_to_tc(ipm, dev->info->num_tx_queues);2916 if (queue < 0)2917 return queue;2918 2919 queue_map |= queue << (ipm * KSZ9477_PORT_TC_MAP_S);2920 }2921 2922 return ksz_pwrite32(dev, port, KSZ9477_PORT_MRI_TC_MAP__4, queue_map);2923}2924 2925static int ksz_port_setup(struct dsa_switch *ds, int port)2926{2927 struct ksz_device *dev = ds->priv;2928 int ret;2929 2930 if (!dsa_is_user_port(ds, port))2931 return 0;2932 2933 /* setup user port */2934 dev->dev_ops->port_setup(dev, port, false);2935 2936 if (!is_ksz8(dev)) {2937 ret = ksz9477_set_default_prio_queue_mapping(dev, port);2938 if (ret)2939 return ret;2940 }2941 2942 /* port_stp_state_set() will be called after to enable the port so2943 * there is no need to do anything.2944 */2945 2946 return ksz_dcb_init_port(dev, port);2947}2948 2949void ksz_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)2950{2951 struct ksz_device *dev = ds->priv;2952 struct ksz_port *p;2953 const u16 *regs;2954 u8 data;2955 2956 regs = dev->info->regs;2957 2958 ksz_pread8(dev, port, regs[P_STP_CTRL], &data);2959 data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE | PORT_LEARN_DISABLE);2960 2961 p = &dev->ports[port];2962 2963 switch (state) {2964 case BR_STATE_DISABLED:2965 data |= PORT_LEARN_DISABLE;2966 break;2967 case BR_STATE_LISTENING:2968 data |= (PORT_RX_ENABLE | PORT_LEARN_DISABLE);2969 break;2970 case BR_STATE_LEARNING:2971 data |= PORT_RX_ENABLE;2972 if (!p->learning)2973 data |= PORT_LEARN_DISABLE;2974 break;2975 case BR_STATE_FORWARDING:2976 data |= (PORT_TX_ENABLE | PORT_RX_ENABLE);2977 if (!p->learning)2978 data |= PORT_LEARN_DISABLE;2979 break;2980 case BR_STATE_BLOCKING:2981 data |= PORT_LEARN_DISABLE;2982 break;2983 default:2984 dev_err(ds->dev, "invalid STP state: %d\n", state);2985 return;2986 }2987 2988 ksz_pwrite8(dev, port, regs[P_STP_CTRL], data);2989 2990 p->stp_state = state;2991 2992 ksz_update_port_member(dev, port);2993}2994 2995static void ksz_port_teardown(struct dsa_switch *ds, int port)2996{2997 struct ksz_device *dev = ds->priv;2998 2999 switch (dev->chip_id) {3000 case KSZ8563_CHIP_ID:3001 case KSZ8567_CHIP_ID:3002 case KSZ9477_CHIP_ID:3003 case KSZ9563_CHIP_ID:3004 case KSZ9567_CHIP_ID:3005 case KSZ9893_CHIP_ID:3006 case KSZ9896_CHIP_ID:3007 case KSZ9897_CHIP_ID:3008 if (dsa_is_user_port(ds, port))3009 ksz9477_port_acl_free(dev, port);3010 }3011}3012 3013static int ksz_port_pre_bridge_flags(struct dsa_switch *ds, int port,3014 struct switchdev_brport_flags flags,3015 struct netlink_ext_ack *extack)3016{3017 if (flags.mask & ~(BR_LEARNING | BR_ISOLATED))3018 return -EINVAL;3019 3020 return 0;3021}3022 3023static int ksz_port_bridge_flags(struct dsa_switch *ds, int port,3024 struct switchdev_brport_flags flags,3025 struct netlink_ext_ack *extack)3026{3027 struct ksz_device *dev = ds->priv;3028 struct ksz_port *p = &dev->ports[port];3029 3030 if (flags.mask & (BR_LEARNING | BR_ISOLATED)) {3031 if (flags.mask & BR_LEARNING)3032 p->learning = !!(flags.val & BR_LEARNING);3033 3034 if (flags.mask & BR_ISOLATED)3035 p->isolated = !!(flags.val & BR_ISOLATED);3036 3037 /* Make the change take effect immediately */3038 ksz_port_stp_state_set(ds, port, p->stp_state);3039 }3040 3041 return 0;3042}3043 3044static enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds,3045 int port,3046 enum dsa_tag_protocol mp)3047{3048 struct ksz_device *dev = ds->priv;3049 enum dsa_tag_protocol proto = DSA_TAG_PROTO_NONE;3050 3051 if (ksz_is_ksz87xx(dev) || ksz_is_8895_family(dev))3052 proto = DSA_TAG_PROTO_KSZ8795;3053 3054 if (dev->chip_id == KSZ88X3_CHIP_ID ||3055 dev->chip_id == KSZ8563_CHIP_ID ||3056 dev->chip_id == KSZ9893_CHIP_ID ||3057 dev->chip_id == KSZ9563_CHIP_ID)3058 proto = DSA_TAG_PROTO_KSZ9893;3059 3060 if (dev->chip_id == KSZ8567_CHIP_ID ||3061 dev->chip_id == KSZ9477_CHIP_ID ||3062 dev->chip_id == KSZ9896_CHIP_ID ||3063 dev->chip_id == KSZ9897_CHIP_ID ||3064 dev->chip_id == KSZ9567_CHIP_ID)3065 proto = DSA_TAG_PROTO_KSZ9477;3066 3067 if (is_lan937x(dev))3068 proto = DSA_TAG_PROTO_LAN937X;3069 3070 return proto;3071}3072 3073static int ksz_connect_tag_protocol(struct dsa_switch *ds,3074 enum dsa_tag_protocol proto)3075{3076 struct ksz_tagger_data *tagger_data;3077 3078 switch (proto) {3079 case DSA_TAG_PROTO_KSZ8795:3080 return 0;3081 case DSA_TAG_PROTO_KSZ9893:3082 case DSA_TAG_PROTO_KSZ9477:3083 case DSA_TAG_PROTO_LAN937X:3084 tagger_data = ksz_tagger_data(ds);3085 tagger_data->xmit_work_fn = ksz_port_deferred_xmit;3086 return 0;3087 default:3088 return -EPROTONOSUPPORT;3089 }3090}3091 3092static int ksz_port_vlan_filtering(struct dsa_switch *ds, int port,3093 bool flag, struct netlink_ext_ack *extack)3094{3095 struct ksz_device *dev = ds->priv;3096 3097 if (!dev->dev_ops->vlan_filtering)3098 return -EOPNOTSUPP;3099 3100 return dev->dev_ops->vlan_filtering(dev, port, flag, extack);3101}3102 3103static int ksz_port_vlan_add(struct dsa_switch *ds, int port,3104 const struct switchdev_obj_port_vlan *vlan,3105 struct netlink_ext_ack *extack)3106{3107 struct ksz_device *dev = ds->priv;3108 3109 if (!dev->dev_ops->vlan_add)3110 return -EOPNOTSUPP;3111 3112 return dev->dev_ops->vlan_add(dev, port, vlan, extack);3113}3114 3115static int ksz_port_vlan_del(struct dsa_switch *ds, int port,3116 const struct switchdev_obj_port_vlan *vlan)3117{3118 struct ksz_device *dev = ds->priv;3119 3120 if (!dev->dev_ops->vlan_del)3121 return -EOPNOTSUPP;3122 3123 return dev->dev_ops->vlan_del(dev, port, vlan);3124}3125 3126static int ksz_port_mirror_add(struct dsa_switch *ds, int port,3127 struct dsa_mall_mirror_tc_entry *mirror,3128 bool ingress, struct netlink_ext_ack *extack)3129{3130 struct ksz_device *dev = ds->priv;3131 3132 if (!dev->dev_ops->mirror_add)3133 return -EOPNOTSUPP;3134 3135 return dev->dev_ops->mirror_add(dev, port, mirror, ingress, extack);3136}3137 3138static void ksz_port_mirror_del(struct dsa_switch *ds, int port,3139 struct dsa_mall_mirror_tc_entry *mirror)3140{3141 struct ksz_device *dev = ds->priv;3142 3143 if (dev->dev_ops->mirror_del)3144 dev->dev_ops->mirror_del(dev, port, mirror);3145}3146 3147static int ksz_change_mtu(struct dsa_switch *ds, int port, int mtu)3148{3149 struct ksz_device *dev = ds->priv;3150 3151 if (!dev->dev_ops->change_mtu)3152 return -EOPNOTSUPP;3153 3154 return dev->dev_ops->change_mtu(dev, port, mtu);3155}3156 3157static int ksz_max_mtu(struct dsa_switch *ds, int port)3158{3159 struct ksz_device *dev = ds->priv;3160 3161 switch (dev->chip_id) {3162 case KSZ8795_CHIP_ID:3163 case KSZ8794_CHIP_ID:3164 case KSZ8765_CHIP_ID:3165 return KSZ8795_HUGE_PACKET_SIZE - VLAN_ETH_HLEN - ETH_FCS_LEN;3166 case KSZ88X3_CHIP_ID:3167 case KSZ8864_CHIP_ID:3168 case KSZ8895_CHIP_ID:3169 return KSZ8863_HUGE_PACKET_SIZE - VLAN_ETH_HLEN - ETH_FCS_LEN;3170 case KSZ8563_CHIP_ID:3171 case KSZ8567_CHIP_ID:3172 case KSZ9477_CHIP_ID:3173 case KSZ9563_CHIP_ID:3174 case KSZ9567_CHIP_ID:3175 case KSZ9893_CHIP_ID:3176 case KSZ9896_CHIP_ID:3177 case KSZ9897_CHIP_ID:3178 case LAN9370_CHIP_ID:3179 case LAN9371_CHIP_ID:3180 case LAN9372_CHIP_ID:3181 case LAN9373_CHIP_ID:3182 case LAN9374_CHIP_ID:3183 return KSZ9477_MAX_FRAME_SIZE - VLAN_ETH_HLEN - ETH_FCS_LEN;3184 }3185 3186 return -EOPNOTSUPP;3187}3188 3189static int ksz_validate_eee(struct dsa_switch *ds, int port)3190{3191 struct ksz_device *dev = ds->priv;3192 3193 if (!dev->info->internal_phy[port])3194 return -EOPNOTSUPP;3195 3196 switch (dev->chip_id) {3197 case KSZ8563_CHIP_ID:3198 case KSZ8567_CHIP_ID:3199 case KSZ9477_CHIP_ID:3200 case KSZ9563_CHIP_ID:3201 case KSZ9567_CHIP_ID:3202 case KSZ9893_CHIP_ID:3203 case KSZ9896_CHIP_ID:3204 case KSZ9897_CHIP_ID:3205 return 0;3206 }3207 3208 return -EOPNOTSUPP;3209}3210 3211static int ksz_get_mac_eee(struct dsa_switch *ds, int port,3212 struct ethtool_keee *e)3213{3214 int ret;3215 3216 ret = ksz_validate_eee(ds, port);3217 if (ret)3218 return ret;3219 3220 /* There is no documented control of Tx LPI configuration. */3221 e->tx_lpi_enabled = true;3222 3223 /* There is no documented control of Tx LPI timer. According to tests3224 * Tx LPI timer seems to be set by default to minimal value.3225 */3226 e->tx_lpi_timer = 0;3227 3228 return 0;3229}3230 3231static int ksz_set_mac_eee(struct dsa_switch *ds, int port,3232 struct ethtool_keee *e)3233{3234 struct ksz_device *dev = ds->priv;3235 int ret;3236 3237 ret = ksz_validate_eee(ds, port);3238 if (ret)3239 return ret;3240 3241 if (!e->tx_lpi_enabled) {3242 dev_err(dev->dev, "Disabling EEE Tx LPI is not supported\n");3243 return -EINVAL;3244 }3245 3246 if (e->tx_lpi_timer) {3247 dev_err(dev->dev, "Setting EEE Tx LPI timer is not supported\n");3248 return -EINVAL;3249 }3250 3251 return 0;3252}3253 3254static void ksz_set_xmii(struct ksz_device *dev, int port,3255 phy_interface_t interface)3256{3257 const u8 *bitval = dev->info->xmii_ctrl1;3258 struct ksz_port *p = &dev->ports[port];3259 const u16 *regs = dev->info->regs;3260 u8 data8;3261 3262 ksz_pread8(dev, port, regs[P_XMII_CTRL_1], &data8);3263 3264 data8 &= ~(P_MII_SEL_M | P_RGMII_ID_IG_ENABLE |3265 P_RGMII_ID_EG_ENABLE);3266 3267 switch (interface) {3268 case PHY_INTERFACE_MODE_MII:3269 data8 |= bitval[P_MII_SEL];3270 break;3271 case PHY_INTERFACE_MODE_RMII:3272 data8 |= bitval[P_RMII_SEL];3273 break;3274 case PHY_INTERFACE_MODE_GMII:3275 data8 |= bitval[P_GMII_SEL];3276 break;3277 case PHY_INTERFACE_MODE_RGMII:3278 case PHY_INTERFACE_MODE_RGMII_ID:3279 case PHY_INTERFACE_MODE_RGMII_TXID:3280 case PHY_INTERFACE_MODE_RGMII_RXID:3281 data8 |= bitval[P_RGMII_SEL];3282 /* On KSZ9893, disable RGMII in-band status support */3283 if (dev->chip_id == KSZ9893_CHIP_ID ||3284 dev->chip_id == KSZ8563_CHIP_ID ||3285 dev->chip_id == KSZ9563_CHIP_ID ||3286 is_lan937x(dev))3287 data8 &= ~P_MII_MAC_MODE;3288 break;3289 default:3290 dev_err(dev->dev, "Unsupported interface '%s' for port %d\n",3291 phy_modes(interface), port);3292 return;3293 }3294 3295 if (p->rgmii_tx_val)3296 data8 |= P_RGMII_ID_EG_ENABLE;3297 3298 if (p->rgmii_rx_val)3299 data8 |= P_RGMII_ID_IG_ENABLE;3300 3301 /* Write the updated value */3302 ksz_pwrite8(dev, port, regs[P_XMII_CTRL_1], data8);3303}3304 3305phy_interface_t ksz_get_xmii(struct ksz_device *dev, int port, bool gbit)3306{3307 const u8 *bitval = dev->info->xmii_ctrl1;3308 const u16 *regs = dev->info->regs;3309 phy_interface_t interface;3310 u8 data8;3311 u8 val;3312 3313 ksz_pread8(dev, port, regs[P_XMII_CTRL_1], &data8);3314 3315 val = FIELD_GET(P_MII_SEL_M, data8);3316 3317 if (val == bitval[P_MII_SEL]) {3318 if (gbit)3319 interface = PHY_INTERFACE_MODE_GMII;3320 else3321 interface = PHY_INTERFACE_MODE_MII;3322 } else if (val == bitval[P_RMII_SEL]) {3323 interface = PHY_INTERFACE_MODE_RMII;3324 } else {3325 interface = PHY_INTERFACE_MODE_RGMII;3326 if (data8 & P_RGMII_ID_EG_ENABLE)3327 interface = PHY_INTERFACE_MODE_RGMII_TXID;3328 if (data8 & P_RGMII_ID_IG_ENABLE) {3329 interface = PHY_INTERFACE_MODE_RGMII_RXID;3330 if (data8 & P_RGMII_ID_EG_ENABLE)3331 interface = PHY_INTERFACE_MODE_RGMII_ID;3332 }3333 }3334 3335 return interface;3336}3337 3338static void ksz88x3_phylink_mac_config(struct phylink_config *config,3339 unsigned int mode,3340 const struct phylink_link_state *state)3341{3342 struct dsa_port *dp = dsa_phylink_to_port(config);3343 struct ksz_device *dev = dp->ds->priv;3344 3345 dev->ports[dp->index].manual_flow = !(state->pause & MLO_PAUSE_AN);3346}3347 3348static void ksz_phylink_mac_config(struct phylink_config *config,3349 unsigned int mode,3350 const struct phylink_link_state *state)3351{3352 struct dsa_port *dp = dsa_phylink_to_port(config);3353 struct ksz_device *dev = dp->ds->priv;3354 int port = dp->index;3355 3356 /* Internal PHYs */3357 if (dev->info->internal_phy[port])3358 return;3359 3360 if (phylink_autoneg_inband(mode)) {3361 dev_err(dev->dev, "In-band AN not supported!\n");3362 return;3363 }3364 3365 ksz_set_xmii(dev, port, state->interface);3366 3367 if (dev->dev_ops->setup_rgmii_delay)3368 dev->dev_ops->setup_rgmii_delay(dev, port);3369}3370 3371bool ksz_get_gbit(struct ksz_device *dev, int port)3372{3373 const u8 *bitval = dev->info->xmii_ctrl1;3374 const u16 *regs = dev->info->regs;3375 bool gbit = false;3376 u8 data8;3377 bool val;3378 3379 ksz_pread8(dev, port, regs[P_XMII_CTRL_1], &data8);3380 3381 val = FIELD_GET(P_GMII_1GBIT_M, data8);3382 3383 if (val == bitval[P_GMII_1GBIT])3384 gbit = true;3385 3386 return gbit;3387}3388 3389static void ksz_set_gbit(struct ksz_device *dev, int port, bool gbit)3390{3391 const u8 *bitval = dev->info->xmii_ctrl1;3392 const u16 *regs = dev->info->regs;3393 u8 data8;3394 3395 ksz_pread8(dev, port, regs[P_XMII_CTRL_1], &data8);3396 3397 data8 &= ~P_GMII_1GBIT_M;3398 3399 if (gbit)3400 data8 |= FIELD_PREP(P_GMII_1GBIT_M, bitval[P_GMII_1GBIT]);3401 else3402 data8 |= FIELD_PREP(P_GMII_1GBIT_M, bitval[P_GMII_NOT_1GBIT]);3403 3404 /* Write the updated value */3405 ksz_pwrite8(dev, port, regs[P_XMII_CTRL_1], data8);3406}3407 3408static void ksz_set_100_10mbit(struct ksz_device *dev, int port, int speed)3409{3410 const u8 *bitval = dev->info->xmii_ctrl0;3411 const u16 *regs = dev->info->regs;3412 u8 data8;3413 3414 ksz_pread8(dev, port, regs[P_XMII_CTRL_0], &data8);3415 3416 data8 &= ~P_MII_100MBIT_M;3417 3418 if (speed == SPEED_100)3419 data8 |= FIELD_PREP(P_MII_100MBIT_M, bitval[P_MII_100MBIT]);3420 else3421 data8 |= FIELD_PREP(P_MII_100MBIT_M, bitval[P_MII_10MBIT]);3422 3423 /* Write the updated value */3424 ksz_pwrite8(dev, port, regs[P_XMII_CTRL_0], data8);3425}3426 3427static void ksz_port_set_xmii_speed(struct ksz_device *dev, int port, int speed)3428{3429 if (speed == SPEED_1000)3430 ksz_set_gbit(dev, port, true);3431 else3432 ksz_set_gbit(dev, port, false);3433 3434 if (speed == SPEED_100 || speed == SPEED_10)3435 ksz_set_100_10mbit(dev, port, speed);3436}3437 3438static void ksz_duplex_flowctrl(struct ksz_device *dev, int port, int duplex,3439 bool tx_pause, bool rx_pause)3440{3441 const u8 *bitval = dev->info->xmii_ctrl0;3442 const u32 *masks = dev->info->masks;3443 const u16 *regs = dev->info->regs;3444 u8 mask;3445 u8 val;3446 3447 mask = P_MII_DUPLEX_M | masks[P_MII_TX_FLOW_CTRL] |3448 masks[P_MII_RX_FLOW_CTRL];3449 3450 if (duplex == DUPLEX_FULL)3451 val = FIELD_PREP(P_MII_DUPLEX_M, bitval[P_MII_FULL_DUPLEX]);3452 else3453 val = FIELD_PREP(P_MII_DUPLEX_M, bitval[P_MII_HALF_DUPLEX]);3454 3455 if (tx_pause)3456 val |= masks[P_MII_TX_FLOW_CTRL];3457 3458 if (rx_pause)3459 val |= masks[P_MII_RX_FLOW_CTRL];3460 3461 ksz_prmw8(dev, port, regs[P_XMII_CTRL_0], mask, val);3462}3463 3464static void ksz9477_phylink_mac_link_up(struct phylink_config *config,3465 struct phy_device *phydev,3466 unsigned int mode,3467 phy_interface_t interface,3468 int speed, int duplex, bool tx_pause,3469 bool rx_pause)3470{3471 struct dsa_port *dp = dsa_phylink_to_port(config);3472 struct ksz_device *dev = dp->ds->priv;3473 int port = dp->index;3474 struct ksz_port *p;3475 3476 p = &dev->ports[port];3477 3478 /* Internal PHYs */3479 if (dev->info->internal_phy[port])3480 return;3481 3482 p->phydev.speed = speed;3483 3484 ksz_port_set_xmii_speed(dev, port, speed);3485 3486 ksz_duplex_flowctrl(dev, port, duplex, tx_pause, rx_pause);3487}3488 3489static int ksz_switch_detect(struct ksz_device *dev)3490{3491 u8 id1, id2, id4;3492 u16 id16;3493 u32 id32;3494 int ret;3495 3496 /* read chip id */3497 ret = ksz_read16(dev, REG_CHIP_ID0, &id16);3498 if (ret)3499 return ret;3500 3501 id1 = FIELD_GET(SW_FAMILY_ID_M, id16);3502 id2 = FIELD_GET(SW_CHIP_ID_M, id16);3503 3504 switch (id1) {3505 case KSZ87_FAMILY_ID:3506 if (id2 == KSZ87_CHIP_ID_95) {3507 u8 val;3508 3509 dev->chip_id = KSZ8795_CHIP_ID;3510 3511 ksz_read8(dev, KSZ8_PORT_STATUS_0, &val);3512 if (val & KSZ8_PORT_FIBER_MODE)3513 dev->chip_id = KSZ8765_CHIP_ID;3514 } else if (id2 == KSZ87_CHIP_ID_94) {3515 dev->chip_id = KSZ8794_CHIP_ID;3516 } else {3517 return -ENODEV;3518 }3519 break;3520 case KSZ88_FAMILY_ID:3521 if (id2 == KSZ88_CHIP_ID_63)3522 dev->chip_id = KSZ88X3_CHIP_ID;3523 else3524 return -ENODEV;3525 break;3526 case KSZ8895_FAMILY_ID:3527 if (id2 == KSZ8895_CHIP_ID_95 ||3528 id2 == KSZ8895_CHIP_ID_95R)3529 dev->chip_id = KSZ8895_CHIP_ID;3530 else3531 return -ENODEV;3532 ret = ksz_read8(dev, REG_KSZ8864_CHIP_ID, &id4);3533 if (ret)3534 return ret;3535 if (id4 & SW_KSZ8864)3536 dev->chip_id = KSZ8864_CHIP_ID;3537 break;3538 default:3539 ret = ksz_read32(dev, REG_CHIP_ID0, &id32);3540 if (ret)3541 return ret;3542 3543 dev->chip_rev = FIELD_GET(SW_REV_ID_M, id32);3544 id32 &= ~0xFF;3545 3546 switch (id32) {3547 case KSZ9477_CHIP_ID:3548 case KSZ9896_CHIP_ID:3549 case KSZ9897_CHIP_ID:3550 case KSZ9567_CHIP_ID:3551 case KSZ8567_CHIP_ID:3552 case LAN9370_CHIP_ID:3553 case LAN9371_CHIP_ID:3554 case LAN9372_CHIP_ID:3555 case LAN9373_CHIP_ID:3556 case LAN9374_CHIP_ID:3557 dev->chip_id = id32;3558 break;3559 case KSZ9893_CHIP_ID:3560 ret = ksz_read8(dev, REG_CHIP_ID4,3561 &id4);3562 if (ret)3563 return ret;3564 3565 if (id4 == SKU_ID_KSZ8563)3566 dev->chip_id = KSZ8563_CHIP_ID;3567 else if (id4 == SKU_ID_KSZ9563)3568 dev->chip_id = KSZ9563_CHIP_ID;3569 else3570 dev->chip_id = KSZ9893_CHIP_ID;3571 3572 break;3573 default:3574 dev_err(dev->dev,3575 "unsupported switch detected %x)\n", id32);3576 return -ENODEV;3577 }3578 }3579 return 0;3580}3581 3582static int ksz_cls_flower_add(struct dsa_switch *ds, int port,3583 struct flow_cls_offload *cls, bool ingress)3584{3585 struct ksz_device *dev = ds->priv;3586 3587 switch (dev->chip_id) {3588 case KSZ8563_CHIP_ID:3589 case KSZ8567_CHIP_ID:3590 case KSZ9477_CHIP_ID:3591 case KSZ9563_CHIP_ID:3592 case KSZ9567_CHIP_ID:3593 case KSZ9893_CHIP_ID:3594 case KSZ9896_CHIP_ID:3595 case KSZ9897_CHIP_ID:3596 return ksz9477_cls_flower_add(ds, port, cls, ingress);3597 }3598 3599 return -EOPNOTSUPP;3600}3601 3602static int ksz_cls_flower_del(struct dsa_switch *ds, int port,3603 struct flow_cls_offload *cls, bool ingress)3604{3605 struct ksz_device *dev = ds->priv;3606 3607 switch (dev->chip_id) {3608 case KSZ8563_CHIP_ID:3609 case KSZ8567_CHIP_ID:3610 case KSZ9477_CHIP_ID:3611 case KSZ9563_CHIP_ID:3612 case KSZ9567_CHIP_ID:3613 case KSZ9893_CHIP_ID:3614 case KSZ9896_CHIP_ID:3615 case KSZ9897_CHIP_ID:3616 return ksz9477_cls_flower_del(ds, port, cls, ingress);3617 }3618 3619 return -EOPNOTSUPP;3620}3621 3622/* Bandwidth is calculated by idle slope/transmission speed. Then the Bandwidth3623 * is converted to Hex-decimal using the successive multiplication method. On3624 * every step, integer part is taken and decimal part is carry forwarded.3625 */3626static int cinc_cal(s32 idle_slope, s32 send_slope, u32 *bw)3627{3628 u32 cinc = 0;3629 u32 txrate;3630 u32 rate;3631 u8 temp;3632 u8 i;3633 3634 txrate = idle_slope - send_slope;3635 3636 if (!txrate)3637 return -EINVAL;3638 3639 rate = idle_slope;3640 3641 /* 24 bit register */3642 for (i = 0; i < 6; i++) {3643 rate = rate * 16;3644 3645 temp = rate / txrate;3646 3647 rate %= txrate;3648 3649 cinc = ((cinc << 4) | temp);3650 }3651 3652 *bw = cinc;3653 3654 return 0;3655}3656 3657static int ksz_setup_tc_mode(struct ksz_device *dev, int port, u8 scheduler,3658 u8 shaper)3659{3660 return ksz_pwrite8(dev, port, REG_PORT_MTI_QUEUE_CTRL_0,3661 FIELD_PREP(MTI_SCHEDULE_MODE_M, scheduler) |3662 FIELD_PREP(MTI_SHAPING_M, shaper));3663}3664 3665static int ksz_setup_tc_cbs(struct dsa_switch *ds, int port,3666 struct tc_cbs_qopt_offload *qopt)3667{3668 struct ksz_device *dev = ds->priv;3669 int ret;3670 u32 bw;3671 3672 if (!dev->info->tc_cbs_supported)3673 return -EOPNOTSUPP;3674 3675 if (qopt->queue > dev->info->num_tx_queues)3676 return -EINVAL;3677 3678 /* Queue Selection */3679 ret = ksz_pwrite32(dev, port, REG_PORT_MTI_QUEUE_INDEX__4, qopt->queue);3680 if (ret)3681 return ret;3682 3683 if (!qopt->enable)3684 return ksz_setup_tc_mode(dev, port, MTI_SCHEDULE_WRR,3685 MTI_SHAPING_OFF);3686 3687 /* High Credit */3688 ret = ksz_pwrite16(dev, port, REG_PORT_MTI_HI_WATER_MARK,3689 qopt->hicredit);3690 if (ret)3691 return ret;3692 3693 /* Low Credit */3694 ret = ksz_pwrite16(dev, port, REG_PORT_MTI_LO_WATER_MARK,3695 qopt->locredit);3696 if (ret)3697 return ret;3698 3699 /* Credit Increment Register */3700 ret = cinc_cal(qopt->idleslope, qopt->sendslope, &bw);3701 if (ret)3702 return ret;3703 3704 if (dev->dev_ops->tc_cbs_set_cinc) {3705 ret = dev->dev_ops->tc_cbs_set_cinc(dev, port, bw);3706 if (ret)3707 return ret;3708 }3709 3710 return ksz_setup_tc_mode(dev, port, MTI_SCHEDULE_STRICT_PRIO,3711 MTI_SHAPING_SRP);3712}3713 3714static int ksz_disable_egress_rate_limit(struct ksz_device *dev, int port)3715{3716 int queue, ret;3717 3718 /* Configuration will not take effect until the last Port Queue X3719 * Egress Limit Control Register is written.3720 */3721 for (queue = 0; queue < dev->info->num_tx_queues; queue++) {3722 ret = ksz_pwrite8(dev, port, KSZ9477_REG_PORT_OUT_RATE_0 + queue,3723 KSZ9477_OUT_RATE_NO_LIMIT);3724 if (ret)3725 return ret;3726 }3727 3728 return 0;3729}3730 3731static int ksz_ets_band_to_queue(struct tc_ets_qopt_offload_replace_params *p,3732 int band)3733{3734 /* Compared to queues, bands prioritize packets differently. In strict3735 * priority mode, the lowest priority is assigned to Queue 0 while the3736 * highest priority is given to Band 0.3737 */3738 return p->bands - 1 - band;3739}3740 3741static int ksz_queue_set_strict(struct ksz_device *dev, int port, int queue)3742{3743 int ret;3744 3745 ret = ksz_pwrite32(dev, port, REG_PORT_MTI_QUEUE_INDEX__4, queue);3746 if (ret)3747 return ret;3748 3749 return ksz_setup_tc_mode(dev, port, MTI_SCHEDULE_STRICT_PRIO,3750 MTI_SHAPING_OFF);3751}3752 3753static int ksz_queue_set_wrr(struct ksz_device *dev, int port, int queue,3754 int weight)3755{3756 int ret;3757 3758 ret = ksz_pwrite32(dev, port, REG_PORT_MTI_QUEUE_INDEX__4, queue);3759 if (ret)3760 return ret;3761 3762 ret = ksz_setup_tc_mode(dev, port, MTI_SCHEDULE_WRR,3763 MTI_SHAPING_OFF);3764 if (ret)3765 return ret;3766 3767 return ksz_pwrite8(dev, port, KSZ9477_PORT_MTI_QUEUE_CTRL_1, weight);3768}3769 3770static int ksz_tc_ets_add(struct ksz_device *dev, int port,3771 struct tc_ets_qopt_offload_replace_params *p)3772{3773 int ret, band, tc_prio;3774 u32 queue_map = 0;3775 3776 /* In order to ensure proper prioritization, it is necessary to set the3777 * rate limit for the related queue to zero. Otherwise strict priority3778 * or WRR mode will not work. This is a hardware limitation.3779 */3780 ret = ksz_disable_egress_rate_limit(dev, port);3781 if (ret)3782 return ret;3783 3784 /* Configure queue scheduling mode for all bands. Currently only strict3785 * prio mode is supported.3786 */3787 for (band = 0; band < p->bands; band++) {3788 int queue = ksz_ets_band_to_queue(p, band);3789 3790 ret = ksz_queue_set_strict(dev, port, queue);3791 if (ret)3792 return ret;3793 }3794 3795 /* Configure the mapping between traffic classes and queues. Note:3796 * priomap variable support 16 traffic classes, but the chip can handle3797 * only 8 classes.3798 */3799 for (tc_prio = 0; tc_prio < ARRAY_SIZE(p->priomap); tc_prio++) {3800 int queue;3801 3802 if (tc_prio >= dev->info->num_ipms)3803 break;3804 3805 queue = ksz_ets_band_to_queue(p, p->priomap[tc_prio]);3806 queue_map |= queue << (tc_prio * KSZ9477_PORT_TC_MAP_S);3807 }3808 3809 return ksz_pwrite32(dev, port, KSZ9477_PORT_MRI_TC_MAP__4, queue_map);3810}3811 3812static int ksz_tc_ets_del(struct ksz_device *dev, int port)3813{3814 int ret, queue;3815 3816 /* To restore the default chip configuration, set all queues to use the3817 * WRR scheduler with a weight of 1.3818 */3819 for (queue = 0; queue < dev->info->num_tx_queues; queue++) {3820 ret = ksz_queue_set_wrr(dev, port, queue,3821 KSZ9477_DEFAULT_WRR_WEIGHT);3822 if (ret)3823 return ret;3824 }3825 3826 /* Revert the queue mapping for TC-priority to its default setting on3827 * the chip.3828 */3829 return ksz9477_set_default_prio_queue_mapping(dev, port);3830}3831 3832static int ksz_tc_ets_validate(struct ksz_device *dev, int port,3833 struct tc_ets_qopt_offload_replace_params *p)3834{3835 int band;3836 3837 /* Since it is not feasible to share one port among multiple qdisc,3838 * the user must configure all available queues appropriately.3839 */3840 if (p->bands != dev->info->num_tx_queues) {3841 dev_err(dev->dev, "Not supported amount of bands. It should be %d\n",3842 dev->info->num_tx_queues);3843 return -EOPNOTSUPP;3844 }3845 3846 for (band = 0; band < p->bands; ++band) {3847 /* The KSZ switches utilize a weighted round robin configuration3848 * where a certain number of packets can be transmitted from a3849 * queue before the next queue is serviced. For more information3850 * on this, refer to section 5.2.8.4 of the KSZ8565R3851 * documentation on the Port Transmit Queue Control 1 Register.3852 * However, the current ETS Qdisc implementation (as of February3853 * 2023) assigns a weight to each queue based on the number of3854 * bytes or extrapolated bandwidth in percentages. Since this3855 * differs from the KSZ switches' method and we don't want to3856 * fake support by converting bytes to packets, it is better to3857 * return an error instead.3858 */3859 if (p->quanta[band]) {3860 dev_err(dev->dev, "Quanta/weights configuration is not supported.\n");3861 return -EOPNOTSUPP;3862 }3863 }3864 3865 return 0;3866}3867 3868static int ksz_tc_setup_qdisc_ets(struct dsa_switch *ds, int port,3869 struct tc_ets_qopt_offload *qopt)3870{3871 struct ksz_device *dev = ds->priv;3872 int ret;3873 3874 if (is_ksz8(dev))3875 return -EOPNOTSUPP;3876 3877 if (qopt->parent != TC_H_ROOT) {3878 dev_err(dev->dev, "Parent should be \"root\"\n");3879 return -EOPNOTSUPP;3880 }3881 3882 switch (qopt->command) {3883 case TC_ETS_REPLACE:3884 ret = ksz_tc_ets_validate(dev, port, &qopt->replace_params);3885 if (ret)3886 return ret;3887 3888 return ksz_tc_ets_add(dev, port, &qopt->replace_params);3889 case TC_ETS_DESTROY:3890 return ksz_tc_ets_del(dev, port);3891 case TC_ETS_STATS:3892 case TC_ETS_GRAFT:3893 return -EOPNOTSUPP;3894 }3895 3896 return -EOPNOTSUPP;3897}3898 3899static int ksz_setup_tc(struct dsa_switch *ds, int port,3900 enum tc_setup_type type, void *type_data)3901{3902 switch (type) {3903 case TC_SETUP_QDISC_CBS:3904 return ksz_setup_tc_cbs(ds, port, type_data);3905 case TC_SETUP_QDISC_ETS:3906 return ksz_tc_setup_qdisc_ets(ds, port, type_data);3907 default:3908 return -EOPNOTSUPP;3909 }3910}3911 3912/**3913 * ksz_handle_wake_reason - Handle wake reason on a specified port.3914 * @dev: The device structure.3915 * @port: The port number.3916 *3917 * This function reads the PME (Power Management Event) status register of a3918 * specified port to determine the wake reason. If there is no wake event, it3919 * returns early. Otherwise, it logs the wake reason which could be due to a3920 * "Magic Packet", "Link Up", or "Energy Detect" event. The PME status register3921 * is then cleared to acknowledge the handling of the wake event.3922 *3923 * Return: 0 on success, or an error code on failure.3924 */3925int ksz_handle_wake_reason(struct ksz_device *dev, int port)3926{3927 const struct ksz_dev_ops *ops = dev->dev_ops;3928 const u16 *regs = dev->info->regs;3929 u8 pme_status;3930 int ret;3931 3932 ret = ops->pme_pread8(dev, port, regs[REG_PORT_PME_STATUS],3933 &pme_status);3934 if (ret)3935 return ret;3936 3937 if (!pme_status)3938 return 0;3939 3940 dev_dbg(dev->dev, "Wake event on port %d due to:%s%s%s\n", port,3941 pme_status & PME_WOL_MAGICPKT ? " \"Magic Packet\"" : "",3942 pme_status & PME_WOL_LINKUP ? " \"Link Up\"" : "",3943 pme_status & PME_WOL_ENERGY ? " \"Energy detect\"" : "");3944 3945 return ops->pme_pwrite8(dev, port, regs[REG_PORT_PME_STATUS],3946 pme_status);3947}3948 3949/**3950 * ksz_get_wol - Get Wake-on-LAN settings for a specified port.3951 * @ds: The dsa_switch structure.3952 * @port: The port number.3953 * @wol: Pointer to ethtool Wake-on-LAN settings structure.3954 *3955 * This function checks the device PME wakeup_source flag and chip_id.3956 * If enabled and supported, it sets the supported and active WoL3957 * flags.3958 */3959static void ksz_get_wol(struct dsa_switch *ds, int port,3960 struct ethtool_wolinfo *wol)3961{3962 struct ksz_device *dev = ds->priv;3963 const u16 *regs = dev->info->regs;3964 u8 pme_ctrl;3965 int ret;3966 3967 if (!is_ksz9477(dev) && !ksz_is_ksz87xx(dev))3968 return;3969 3970 if (!dev->wakeup_source)3971 return;3972 3973 wol->supported = WAKE_PHY;3974 3975 /* Check if the current MAC address on this port can be set3976 * as global for WAKE_MAGIC support. The result may vary3977 * dynamically based on other ports configurations.3978 */3979 if (ksz_is_port_mac_global_usable(dev->ds, port))3980 wol->supported |= WAKE_MAGIC;3981 3982 ret = dev->dev_ops->pme_pread8(dev, port, regs[REG_PORT_PME_CTRL],3983 &pme_ctrl);3984 if (ret)3985 return;3986 3987 if (pme_ctrl & PME_WOL_MAGICPKT)3988 wol->wolopts |= WAKE_MAGIC;3989 if (pme_ctrl & (PME_WOL_LINKUP | PME_WOL_ENERGY))3990 wol->wolopts |= WAKE_PHY;3991}3992 3993/**3994 * ksz_set_wol - Set Wake-on-LAN settings for a specified port.3995 * @ds: The dsa_switch structure.3996 * @port: The port number.3997 * @wol: Pointer to ethtool Wake-on-LAN settings structure.3998 *3999 * This function configures Wake-on-LAN (WoL) settings for a specified4000 * port. It validates the provided WoL options, checks if PME is4001 * enabled and supported, clears any previous wake reasons, and sets4002 * the Magic Packet flag in the port's PME control register if4003 * specified.4004 *4005 * Return: 0 on success, or other error codes on failure.4006 */4007static int ksz_set_wol(struct dsa_switch *ds, int port,4008 struct ethtool_wolinfo *wol)4009{4010 u8 pme_ctrl = 0, pme_ctrl_old = 0;4011 struct ksz_device *dev = ds->priv;4012 const u16 *regs = dev->info->regs;4013 bool magic_switched_off;4014 bool magic_switched_on;4015 int ret;4016 4017 if (wol->wolopts & ~(WAKE_PHY | WAKE_MAGIC))4018 return -EINVAL;4019 4020 if (!is_ksz9477(dev) && !ksz_is_ksz87xx(dev))4021 return -EOPNOTSUPP;4022 4023 if (!dev->wakeup_source)4024 return -EOPNOTSUPP;4025 4026 ret = ksz_handle_wake_reason(dev, port);4027 if (ret)4028 return ret;4029 4030 if (wol->wolopts & WAKE_MAGIC)4031 pme_ctrl |= PME_WOL_MAGICPKT;4032 if (wol->wolopts & WAKE_PHY)4033 pme_ctrl |= PME_WOL_LINKUP | PME_WOL_ENERGY;4034 4035 ret = dev->dev_ops->pme_pread8(dev, port, regs[REG_PORT_PME_CTRL],4036 &pme_ctrl_old);4037 if (ret)4038 return ret;4039 4040 if (pme_ctrl_old == pme_ctrl)4041 return 0;4042 4043 magic_switched_off = (pme_ctrl_old & PME_WOL_MAGICPKT) &&4044 !(pme_ctrl & PME_WOL_MAGICPKT);4045 magic_switched_on = !(pme_ctrl_old & PME_WOL_MAGICPKT) &&4046 (pme_ctrl & PME_WOL_MAGICPKT);4047 4048 /* To keep reference count of MAC address, we should do this4049 * operation only on change of WOL settings.4050 */4051 if (magic_switched_on) {4052 ret = ksz_switch_macaddr_get(dev->ds, port, NULL);4053 if (ret)4054 return ret;4055 } else if (magic_switched_off) {4056 ksz_switch_macaddr_put(dev->ds);4057 }4058 4059 ret = dev->dev_ops->pme_pwrite8(dev, port, regs[REG_PORT_PME_CTRL],4060 pme_ctrl);4061 if (ret) {4062 if (magic_switched_on)4063 ksz_switch_macaddr_put(dev->ds);4064 return ret;4065 }4066 4067 return 0;4068}4069 4070/**4071 * ksz_wol_pre_shutdown - Prepares the switch device for shutdown while4072 * considering Wake-on-LAN (WoL) settings.4073 * @dev: The switch device structure.4074 * @wol_enabled: Pointer to a boolean which will be set to true if WoL is4075 * enabled on any port.4076 *4077 * This function prepares the switch device for a safe shutdown while taking4078 * into account the Wake-on-LAN (WoL) settings on the user ports. It updates4079 * the wol_enabled flag accordingly to reflect whether WoL is active on any4080 * port.4081 */4082static void ksz_wol_pre_shutdown(struct ksz_device *dev, bool *wol_enabled)4083{4084 const struct ksz_dev_ops *ops = dev->dev_ops;4085 const u16 *regs = dev->info->regs;4086 u8 pme_pin_en = PME_ENABLE;4087 struct dsa_port *dp;4088 int ret;4089 4090 *wol_enabled = false;4091 4092 if (!is_ksz9477(dev) && !ksz_is_ksz87xx(dev))4093 return;4094 4095 if (!dev->wakeup_source)4096 return;4097 4098 dsa_switch_for_each_user_port(dp, dev->ds) {4099 u8 pme_ctrl = 0;4100 4101 ret = ops->pme_pread8(dev, dp->index,4102 regs[REG_PORT_PME_CTRL], &pme_ctrl);4103 if (!ret && pme_ctrl)4104 *wol_enabled = true;4105 4106 /* make sure there are no pending wake events which would4107 * prevent the device from going to sleep/shutdown.4108 */4109 ksz_handle_wake_reason(dev, dp->index);4110 }4111 4112 /* Now we are save to enable PME pin. */4113 if (*wol_enabled) {4114 if (dev->pme_active_high)4115 pme_pin_en |= PME_POLARITY;4116 ops->pme_write8(dev, regs[REG_SW_PME_CTRL], pme_pin_en);4117 if (ksz_is_ksz87xx(dev))4118 ksz_write8(dev, KSZ87XX_REG_INT_EN, KSZ87XX_INT_PME_MASK);4119 }4120}4121 4122static int ksz_port_set_mac_address(struct dsa_switch *ds, int port,4123 const unsigned char *addr)4124{4125 struct dsa_port *dp = dsa_to_port(ds, port);4126 struct ethtool_wolinfo wol;4127 4128 if (dp->hsr_dev) {4129 dev_err(ds->dev,4130 "Cannot change MAC address on port %d with active HSR offload\n",4131 port);4132 return -EBUSY;4133 }4134 4135 /* Need to initialize variable as the code to fill in settings may4136 * not be executed.4137 */4138 wol.wolopts = 0;4139 4140 ksz_get_wol(ds, dp->index, &wol);4141 if (wol.wolopts & WAKE_MAGIC) {4142 dev_err(ds->dev,4143 "Cannot change MAC address on port %d with active Wake on Magic Packet\n",4144 port);4145 return -EBUSY;4146 }4147 4148 return 0;4149}4150 4151/**4152 * ksz_is_port_mac_global_usable - Check if the MAC address on a given port4153 * can be used as a global address.4154 * @ds: Pointer to the DSA switch structure.4155 * @port: The port number on which the MAC address is to be checked.4156 *4157 * This function examines the MAC address set on the specified port and4158 * determines if it can be used as a global address for the switch.4159 *4160 * Return: true if the port's MAC address can be used as a global address, false4161 * otherwise.4162 */4163bool ksz_is_port_mac_global_usable(struct dsa_switch *ds, int port)4164{4165 struct net_device *user = dsa_to_port(ds, port)->user;4166 const unsigned char *addr = user->dev_addr;4167 struct ksz_switch_macaddr *switch_macaddr;4168 struct ksz_device *dev = ds->priv;4169 4170 ASSERT_RTNL();4171 4172 switch_macaddr = dev->switch_macaddr;4173 if (switch_macaddr && !ether_addr_equal(switch_macaddr->addr, addr))4174 return false;4175 4176 return true;4177}4178 4179/**4180 * ksz_switch_macaddr_get - Program the switch's MAC address register.4181 * @ds: DSA switch instance.4182 * @port: Port number.4183 * @extack: Netlink extended acknowledgment.4184 *4185 * This function programs the switch's MAC address register with the MAC address4186 * of the requesting user port. This single address is used by the switch for4187 * multiple features like HSR self-address filtering and WoL. Other user ports4188 * can share ownership of this address as long as their MAC address is the same.4189 * The MAC addresses of user ports must not change while they have ownership of4190 * the switch MAC address.4191 *4192 * Return: 0 on success, or other error codes on failure.4193 */4194int ksz_switch_macaddr_get(struct dsa_switch *ds, int port,4195 struct netlink_ext_ack *extack)4196{4197 struct net_device *user = dsa_to_port(ds, port)->user;4198 const unsigned char *addr = user->dev_addr;4199 struct ksz_switch_macaddr *switch_macaddr;4200 struct ksz_device *dev = ds->priv;4201 const u16 *regs = dev->info->regs;4202 int i, ret;4203 4204 /* Make sure concurrent MAC address changes are blocked */4205 ASSERT_RTNL();4206 4207 switch_macaddr = dev->switch_macaddr;4208 if (switch_macaddr) {4209 if (!ether_addr_equal(switch_macaddr->addr, addr)) {4210 NL_SET_ERR_MSG_FMT_MOD(extack,4211 "Switch already configured for MAC address %pM",4212 switch_macaddr->addr);4213 return -EBUSY;4214 }4215 4216 refcount_inc(&switch_macaddr->refcount);4217 return 0;4218 }4219 4220 switch_macaddr = kzalloc(sizeof(*switch_macaddr), GFP_KERNEL);4221 if (!switch_macaddr)4222 return -ENOMEM;4223 4224 ether_addr_copy(switch_macaddr->addr, addr);4225 refcount_set(&switch_macaddr->refcount, 1);4226 dev->switch_macaddr = switch_macaddr;4227 4228 /* Program the switch MAC address to hardware */4229 for (i = 0; i < ETH_ALEN; i++) {4230 ret = ksz_write8(dev, regs[REG_SW_MAC_ADDR] + i, addr[i]);4231 if (ret)4232 goto macaddr_drop;4233 }4234 4235 return 0;4236 4237macaddr_drop:4238 dev->switch_macaddr = NULL;4239 refcount_set(&switch_macaddr->refcount, 0);4240 kfree(switch_macaddr);4241 4242 return ret;4243}4244 4245void ksz_switch_macaddr_put(struct dsa_switch *ds)4246{4247 struct ksz_switch_macaddr *switch_macaddr;4248 struct ksz_device *dev = ds->priv;4249 const u16 *regs = dev->info->regs;4250 int i;4251 4252 /* Make sure concurrent MAC address changes are blocked */4253 ASSERT_RTNL();4254 4255 switch_macaddr = dev->switch_macaddr;4256 if (!refcount_dec_and_test(&switch_macaddr->refcount))4257 return;4258 4259 for (i = 0; i < ETH_ALEN; i++)4260 ksz_write8(dev, regs[REG_SW_MAC_ADDR] + i, 0);4261 4262 dev->switch_macaddr = NULL;4263 kfree(switch_macaddr);4264}4265 4266static int ksz_hsr_join(struct dsa_switch *ds, int port, struct net_device *hsr,4267 struct netlink_ext_ack *extack)4268{4269 struct ksz_device *dev = ds->priv;4270 enum hsr_version ver;4271 int ret;4272 4273 ret = hsr_get_version(hsr, &ver);4274 if (ret)4275 return ret;4276 4277 if (dev->chip_id != KSZ9477_CHIP_ID) {4278 NL_SET_ERR_MSG_MOD(extack, "Chip does not support HSR offload");4279 return -EOPNOTSUPP;4280 }4281 4282 /* KSZ9477 can support HW offloading of only 1 HSR device */4283 if (dev->hsr_dev && hsr != dev->hsr_dev) {4284 NL_SET_ERR_MSG_MOD(extack, "Offload supported for a single HSR");4285 return -EOPNOTSUPP;4286 }4287 4288 /* KSZ9477 only supports HSR v0 and v1 */4289 if (!(ver == HSR_V0 || ver == HSR_V1)) {4290 NL_SET_ERR_MSG_MOD(extack, "Only HSR v0 and v1 supported");4291 return -EOPNOTSUPP;4292 }4293 4294 /* KSZ9477 can only perform HSR offloading for up to two ports */4295 if (hweight8(dev->hsr_ports) >= 2) {4296 NL_SET_ERR_MSG_MOD(extack,4297 "Cannot offload more than two ports - using software HSR");4298 return -EOPNOTSUPP;4299 }4300 4301 /* Self MAC address filtering, to avoid frames traversing4302 * the HSR ring more than once.4303 */4304 ret = ksz_switch_macaddr_get(ds, port, extack);4305 if (ret)4306 return ret;4307 4308 ksz9477_hsr_join(ds, port, hsr);4309 dev->hsr_dev = hsr;4310 dev->hsr_ports |= BIT(port);4311 4312 return 0;4313}4314 4315static int ksz_hsr_leave(struct dsa_switch *ds, int port,4316 struct net_device *hsr)4317{4318 struct ksz_device *dev = ds->priv;4319 4320 WARN_ON(dev->chip_id != KSZ9477_CHIP_ID);4321 4322 ksz9477_hsr_leave(ds, port, hsr);4323 dev->hsr_ports &= ~BIT(port);4324 if (!dev->hsr_ports)4325 dev->hsr_dev = NULL;4326 4327 ksz_switch_macaddr_put(ds);4328 4329 return 0;4330}4331 4332static const struct dsa_switch_ops ksz_switch_ops = {4333 .get_tag_protocol = ksz_get_tag_protocol,4334 .connect_tag_protocol = ksz_connect_tag_protocol,4335 .get_phy_flags = ksz_get_phy_flags,4336 .setup = ksz_setup,4337 .teardown = ksz_teardown,4338 .phy_read = ksz_phy_read16,4339 .phy_write = ksz_phy_write16,4340 .phylink_get_caps = ksz_phylink_get_caps,4341 .port_setup = ksz_port_setup,4342 .set_ageing_time = ksz_set_ageing_time,4343 .get_strings = ksz_get_strings,4344 .get_ethtool_stats = ksz_get_ethtool_stats,4345 .get_sset_count = ksz_sset_count,4346 .port_bridge_join = ksz_port_bridge_join,4347 .port_bridge_leave = ksz_port_bridge_leave,4348 .port_hsr_join = ksz_hsr_join,4349 .port_hsr_leave = ksz_hsr_leave,4350 .port_set_mac_address = ksz_port_set_mac_address,4351 .port_stp_state_set = ksz_port_stp_state_set,4352 .port_teardown = ksz_port_teardown,4353 .port_pre_bridge_flags = ksz_port_pre_bridge_flags,4354 .port_bridge_flags = ksz_port_bridge_flags,4355 .port_fast_age = ksz_port_fast_age,4356 .port_vlan_filtering = ksz_port_vlan_filtering,4357 .port_vlan_add = ksz_port_vlan_add,4358 .port_vlan_del = ksz_port_vlan_del,4359 .port_fdb_dump = ksz_port_fdb_dump,4360 .port_fdb_add = ksz_port_fdb_add,4361 .port_fdb_del = ksz_port_fdb_del,4362 .port_mdb_add = ksz_port_mdb_add,4363 .port_mdb_del = ksz_port_mdb_del,4364 .port_mirror_add = ksz_port_mirror_add,4365 .port_mirror_del = ksz_port_mirror_del,4366 .get_stats64 = ksz_get_stats64,4367 .get_pause_stats = ksz_get_pause_stats,4368 .port_change_mtu = ksz_change_mtu,4369 .port_max_mtu = ksz_max_mtu,4370 .get_wol = ksz_get_wol,4371 .set_wol = ksz_set_wol,4372 .get_ts_info = ksz_get_ts_info,4373 .port_hwtstamp_get = ksz_hwtstamp_get,4374 .port_hwtstamp_set = ksz_hwtstamp_set,4375 .port_txtstamp = ksz_port_txtstamp,4376 .port_rxtstamp = ksz_port_rxtstamp,4377 .cls_flower_add = ksz_cls_flower_add,4378 .cls_flower_del = ksz_cls_flower_del,4379 .port_setup_tc = ksz_setup_tc,4380 .get_mac_eee = ksz_get_mac_eee,4381 .set_mac_eee = ksz_set_mac_eee,4382 .port_get_default_prio = ksz_port_get_default_prio,4383 .port_set_default_prio = ksz_port_set_default_prio,4384 .port_get_dscp_prio = ksz_port_get_dscp_prio,4385 .port_add_dscp_prio = ksz_port_add_dscp_prio,4386 .port_del_dscp_prio = ksz_port_del_dscp_prio,4387 .port_get_apptrust = ksz_port_get_apptrust,4388 .port_set_apptrust = ksz_port_set_apptrust,4389};4390 4391struct ksz_device *ksz_switch_alloc(struct device *base, void *priv)4392{4393 struct dsa_switch *ds;4394 struct ksz_device *swdev;4395 4396 ds = devm_kzalloc(base, sizeof(*ds), GFP_KERNEL);4397 if (!ds)4398 return NULL;4399 4400 ds->dev = base;4401 ds->num_ports = DSA_MAX_PORTS;4402 ds->ops = &ksz_switch_ops;4403 4404 swdev = devm_kzalloc(base, sizeof(*swdev), GFP_KERNEL);4405 if (!swdev)4406 return NULL;4407 4408 ds->priv = swdev;4409 swdev->dev = base;4410 4411 swdev->ds = ds;4412 swdev->priv = priv;4413 4414 return swdev;4415}4416EXPORT_SYMBOL(ksz_switch_alloc);4417 4418/**4419 * ksz_switch_shutdown - Shutdown routine for the switch device.4420 * @dev: The switch device structure.4421 *4422 * This function is responsible for initiating a shutdown sequence for the4423 * switch device. It invokes the reset operation defined in the device4424 * operations, if available, to reset the switch. Subsequently, it calls the4425 * DSA framework's shutdown function to ensure a proper shutdown of the DSA4426 * switch.4427 */4428void ksz_switch_shutdown(struct ksz_device *dev)4429{4430 bool wol_enabled = false;4431 4432 ksz_wol_pre_shutdown(dev, &wol_enabled);4433 4434 if (dev->dev_ops->reset && !wol_enabled)4435 dev->dev_ops->reset(dev);4436 4437 dsa_switch_shutdown(dev->ds);4438}4439EXPORT_SYMBOL(ksz_switch_shutdown);4440 4441static void ksz_parse_rgmii_delay(struct ksz_device *dev, int port_num,4442 struct device_node *port_dn)4443{4444 phy_interface_t phy_mode = dev->ports[port_num].interface;4445 int rx_delay = -1, tx_delay = -1;4446 4447 if (!phy_interface_mode_is_rgmii(phy_mode))4448 return;4449 4450 of_property_read_u32(port_dn, "rx-internal-delay-ps", &rx_delay);4451 of_property_read_u32(port_dn, "tx-internal-delay-ps", &tx_delay);4452 4453 if (rx_delay == -1 && tx_delay == -1) {4454 dev_warn(dev->dev,4455 "Port %d interpreting RGMII delay settings based on \"phy-mode\" property, "4456 "please update device tree to specify \"rx-internal-delay-ps\" and "4457 "\"tx-internal-delay-ps\"",4458 port_num);4459 4460 if (phy_mode == PHY_INTERFACE_MODE_RGMII_RXID ||4461 phy_mode == PHY_INTERFACE_MODE_RGMII_ID)4462 rx_delay = 2000;4463 4464 if (phy_mode == PHY_INTERFACE_MODE_RGMII_TXID ||4465 phy_mode == PHY_INTERFACE_MODE_RGMII_ID)4466 tx_delay = 2000;4467 }4468 4469 if (rx_delay < 0)4470 rx_delay = 0;4471 if (tx_delay < 0)4472 tx_delay = 0;4473 4474 dev->ports[port_num].rgmii_rx_val = rx_delay;4475 dev->ports[port_num].rgmii_tx_val = tx_delay;4476}4477 4478/**4479 * ksz_drive_strength_to_reg() - Convert drive strength value to corresponding4480 * register value.4481 * @array: The array of drive strength values to search.4482 * @array_size: The size of the array.4483 * @microamp: The drive strength value in microamp to be converted.4484 *4485 * This function searches the array of drive strength values for the given4486 * microamp value and returns the corresponding register value for that drive.4487 *4488 * Returns: If found, the corresponding register value for that drive strength4489 * is returned. Otherwise, -EINVAL is returned indicating an invalid value.4490 */4491static int ksz_drive_strength_to_reg(const struct ksz_drive_strength *array,4492 size_t array_size, int microamp)4493{4494 int i;4495 4496 for (i = 0; i < array_size; i++) {4497 if (array[i].microamp == microamp)4498 return array[i].reg_val;4499 }4500 4501 return -EINVAL;4502}4503 4504/**4505 * ksz_drive_strength_error() - Report invalid drive strength value4506 * @dev: ksz device4507 * @array: The array of drive strength values to search.4508 * @array_size: The size of the array.4509 * @microamp: Invalid drive strength value in microamp4510 *4511 * This function logs an error message when an unsupported drive strength value4512 * is detected. It lists out all the supported drive strength values for4513 * reference in the error message.4514 */4515static void ksz_drive_strength_error(struct ksz_device *dev,4516 const struct ksz_drive_strength *array,4517 size_t array_size, int microamp)4518{4519 char supported_values[100];4520 size_t remaining_size;4521 int added_len;4522 char *ptr;4523 int i;4524 4525 remaining_size = sizeof(supported_values);4526 ptr = supported_values;4527 4528 for (i = 0; i < array_size; i++) {4529 added_len = snprintf(ptr, remaining_size,4530 i == 0 ? "%d" : ", %d", array[i].microamp);4531 4532 if (added_len >= remaining_size)4533 break;4534 4535 ptr += added_len;4536 remaining_size -= added_len;4537 }4538 4539 dev_err(dev->dev, "Invalid drive strength %d, supported values are %s\n",4540 microamp, supported_values);4541}4542 4543/**4544 * ksz9477_drive_strength_write() - Set the drive strength for specific KSZ94774545 * chip variants.4546 * @dev: ksz device4547 * @props: Array of drive strength properties to be applied4548 * @num_props: Number of properties in the array4549 *4550 * This function configures the drive strength for various KSZ9477 chip variants4551 * based on the provided properties. It handles chip-specific nuances and4552 * ensures only valid drive strengths are written to the respective chip.4553 *4554 * Return: 0 on successful configuration, a negative error code on failure.4555 */4556static int ksz9477_drive_strength_write(struct ksz_device *dev,4557 struct ksz_driver_strength_prop *props,4558 int num_props)4559{4560 size_t array_size = ARRAY_SIZE(ksz9477_drive_strengths);4561 int i, ret, reg;4562 u8 mask = 0;4563 u8 val = 0;4564 4565 if (props[KSZ_DRIVER_STRENGTH_IO].value != -1)4566 dev_warn(dev->dev, "%s is not supported by this chip variant\n",4567 props[KSZ_DRIVER_STRENGTH_IO].name);4568 4569 if (dev->chip_id == KSZ8795_CHIP_ID ||4570 dev->chip_id == KSZ8794_CHIP_ID ||4571 dev->chip_id == KSZ8765_CHIP_ID)4572 reg = KSZ8795_REG_SW_CTRL_20;4573 else4574 reg = KSZ9477_REG_SW_IO_STRENGTH;4575 4576 for (i = 0; i < num_props; i++) {4577 if (props[i].value == -1)4578 continue;4579 4580 ret = ksz_drive_strength_to_reg(ksz9477_drive_strengths,4581 array_size, props[i].value);4582 if (ret < 0) {4583 ksz_drive_strength_error(dev, ksz9477_drive_strengths,4584 array_size, props[i].value);4585 return ret;4586 }4587 4588 mask |= SW_DRIVE_STRENGTH_M << props[i].offset;4589 val |= ret << props[i].offset;4590 }4591 4592 return ksz_rmw8(dev, reg, mask, val);4593}4594 4595/**4596 * ksz88x3_drive_strength_write() - Set the drive strength configuration for4597 * KSZ8863 compatible chip variants.4598 * @dev: ksz device4599 * @props: Array of drive strength properties to be set4600 * @num_props: Number of properties in the array4601 *4602 * This function applies the specified drive strength settings to KSZ88X3 chip4603 * variants (KSZ8873, KSZ8863).4604 * It ensures the configurations align with what the chip variant supports and4605 * warns or errors out on unsupported settings.4606 *4607 * Return: 0 on success, error code otherwise4608 */4609static int ksz88x3_drive_strength_write(struct ksz_device *dev,4610 struct ksz_driver_strength_prop *props,4611 int num_props)4612{4613 size_t array_size = ARRAY_SIZE(ksz88x3_drive_strengths);4614 int microamp;4615 int i, ret;4616 4617 for (i = 0; i < num_props; i++) {4618 if (props[i].value == -1 || i == KSZ_DRIVER_STRENGTH_IO)4619 continue;4620 4621 dev_warn(dev->dev, "%s is not supported by this chip variant\n",4622 props[i].name);4623 }4624 4625 microamp = props[KSZ_DRIVER_STRENGTH_IO].value;4626 ret = ksz_drive_strength_to_reg(ksz88x3_drive_strengths, array_size,4627 microamp);4628 if (ret < 0) {4629 ksz_drive_strength_error(dev, ksz88x3_drive_strengths,4630 array_size, microamp);4631 return ret;4632 }4633 4634 return ksz_rmw8(dev, KSZ8873_REG_GLOBAL_CTRL_12,4635 KSZ8873_DRIVE_STRENGTH_16MA, ret);4636}4637 4638/**4639 * ksz_parse_drive_strength() - Extract and apply drive strength configurations4640 * from device tree properties.4641 * @dev: ksz device4642 *4643 * This function reads the specified drive strength properties from the4644 * device tree, validates against the supported chip variants, and sets4645 * them accordingly. An error should be critical here, as the drive strength4646 * settings are crucial for EMI compliance.4647 *4648 * Return: 0 on success, error code otherwise4649 */4650static int ksz_parse_drive_strength(struct ksz_device *dev)4651{4652 struct ksz_driver_strength_prop of_props[] = {4653 [KSZ_DRIVER_STRENGTH_HI] = {4654 .name = "microchip,hi-drive-strength-microamp",4655 .offset = SW_HI_SPEED_DRIVE_STRENGTH_S,4656 .value = -1,4657 },4658 [KSZ_DRIVER_STRENGTH_LO] = {4659 .name = "microchip,lo-drive-strength-microamp",4660 .offset = SW_LO_SPEED_DRIVE_STRENGTH_S,4661 .value = -1,4662 },4663 [KSZ_DRIVER_STRENGTH_IO] = {4664 .name = "microchip,io-drive-strength-microamp",4665 .offset = 0, /* don't care */4666 .value = -1,4667 },4668 };4669 struct device_node *np = dev->dev->of_node;4670 bool have_any_prop = false;4671 int i, ret;4672 4673 for (i = 0; i < ARRAY_SIZE(of_props); i++) {4674 ret = of_property_read_u32(np, of_props[i].name,4675 &of_props[i].value);4676 if (ret && ret != -EINVAL)4677 dev_warn(dev->dev, "Failed to read %s\n",4678 of_props[i].name);4679 if (ret)4680 continue;4681 4682 have_any_prop = true;4683 }4684 4685 if (!have_any_prop)4686 return 0;4687 4688 switch (dev->chip_id) {4689 case KSZ88X3_CHIP_ID:4690 return ksz88x3_drive_strength_write(dev, of_props,4691 ARRAY_SIZE(of_props));4692 case KSZ8795_CHIP_ID:4693 case KSZ8794_CHIP_ID:4694 case KSZ8765_CHIP_ID:4695 case KSZ8563_CHIP_ID:4696 case KSZ8567_CHIP_ID:4697 case KSZ9477_CHIP_ID:4698 case KSZ9563_CHIP_ID:4699 case KSZ9567_CHIP_ID:4700 case KSZ9893_CHIP_ID:4701 case KSZ9896_CHIP_ID:4702 case KSZ9897_CHIP_ID:4703 return ksz9477_drive_strength_write(dev, of_props,4704 ARRAY_SIZE(of_props));4705 default:4706 for (i = 0; i < ARRAY_SIZE(of_props); i++) {4707 if (of_props[i].value == -1)4708 continue;4709 4710 dev_warn(dev->dev, "%s is not supported by this chip variant\n",4711 of_props[i].name);4712 }4713 }4714 4715 return 0;4716}4717 4718int ksz_switch_register(struct ksz_device *dev)4719{4720 const struct ksz_chip_data *info;4721 struct device_node *ports;4722 phy_interface_t interface;4723 unsigned int port_num;4724 int ret;4725 int i;4726 4727 dev->reset_gpio = devm_gpiod_get_optional(dev->dev, "reset",4728 GPIOD_OUT_LOW);4729 if (IS_ERR(dev->reset_gpio))4730 return PTR_ERR(dev->reset_gpio);4731 4732 if (dev->reset_gpio) {4733 gpiod_set_value_cansleep(dev->reset_gpio, 1);4734 usleep_range(10000, 12000);4735 gpiod_set_value_cansleep(dev->reset_gpio, 0);4736 msleep(100);4737 }4738 4739 mutex_init(&dev->dev_mutex);4740 mutex_init(&dev->regmap_mutex);4741 mutex_init(&dev->alu_mutex);4742 mutex_init(&dev->vlan_mutex);4743 4744 ret = ksz_switch_detect(dev);4745 if (ret)4746 return ret;4747 4748 info = ksz_lookup_info(dev->chip_id);4749 if (!info)4750 return -ENODEV;4751 4752 /* Update the compatible info with the probed one */4753 dev->info = info;4754 4755 dev_info(dev->dev, "found switch: %s, rev %i\n",4756 dev->info->dev_name, dev->chip_rev);4757 4758 ret = ksz_check_device_id(dev);4759 if (ret)4760 return ret;4761 4762 dev->dev_ops = dev->info->ops;4763 4764 ret = dev->dev_ops->init(dev);4765 if (ret)4766 return ret;4767 4768 dev->ports = devm_kzalloc(dev->dev,4769 dev->info->port_cnt * sizeof(struct ksz_port),4770 GFP_KERNEL);4771 if (!dev->ports)4772 return -ENOMEM;4773 4774 for (i = 0; i < dev->info->port_cnt; i++) {4775 spin_lock_init(&dev->ports[i].mib.stats64_lock);4776 mutex_init(&dev->ports[i].mib.cnt_mutex);4777 dev->ports[i].mib.counters =4778 devm_kzalloc(dev->dev,4779 sizeof(u64) * (dev->info->mib_cnt + 1),4780 GFP_KERNEL);4781 if (!dev->ports[i].mib.counters)4782 return -ENOMEM;4783 4784 dev->ports[i].ksz_dev = dev;4785 dev->ports[i].num = i;4786 }4787 4788 /* set the real number of ports */4789 dev->ds->num_ports = dev->info->port_cnt;4790 4791 /* set the phylink ops */4792 dev->ds->phylink_mac_ops = dev->info->phylink_mac_ops;4793 4794 /* Host port interface will be self detected, or specifically set in4795 * device tree.4796 */4797 for (port_num = 0; port_num < dev->info->port_cnt; ++port_num)4798 dev->ports[port_num].interface = PHY_INTERFACE_MODE_NA;4799 if (dev->dev->of_node) {4800 ret = of_get_phy_mode(dev->dev->of_node, &interface);4801 if (ret == 0)4802 dev->compat_interface = interface;4803 ports = of_get_child_by_name(dev->dev->of_node, "ethernet-ports");4804 if (!ports)4805 ports = of_get_child_by_name(dev->dev->of_node, "ports");4806 if (ports) {4807 for_each_available_child_of_node_scoped(ports, port) {4808 if (of_property_read_u32(port, "reg",4809 &port_num))4810 continue;4811 if (!(dev->port_mask & BIT(port_num))) {4812 of_node_put(ports);4813 return -EINVAL;4814 }4815 of_get_phy_mode(port,4816 &dev->ports[port_num].interface);4817 4818 ksz_parse_rgmii_delay(dev, port_num, port);4819 }4820 of_node_put(ports);4821 }4822 dev->synclko_125 = of_property_read_bool(dev->dev->of_node,4823 "microchip,synclko-125");4824 dev->synclko_disable = of_property_read_bool(dev->dev->of_node,4825 "microchip,synclko-disable");4826 if (dev->synclko_125 && dev->synclko_disable) {4827 dev_err(dev->dev, "inconsistent synclko settings\n");4828 return -EINVAL;4829 }4830 4831 dev->wakeup_source = of_property_read_bool(dev->dev->of_node,4832 "wakeup-source");4833 dev->pme_active_high = of_property_read_bool(dev->dev->of_node,4834 "microchip,pme-active-high");4835 }4836 4837 ret = dsa_register_switch(dev->ds);4838 if (ret) {4839 dev->dev_ops->exit(dev);4840 return ret;4841 }4842 4843 /* Read MIB counters every 30 seconds to avoid overflow. */4844 dev->mib_read_interval = msecs_to_jiffies(5000);4845 4846 /* Start the MIB timer. */4847 schedule_delayed_work(&dev->mib_read, 0);4848 4849 return ret;4850}4851EXPORT_SYMBOL(ksz_switch_register);4852 4853void ksz_switch_remove(struct ksz_device *dev)4854{4855 /* timer started */4856 if (dev->mib_read_interval) {4857 dev->mib_read_interval = 0;4858 cancel_delayed_work_sync(&dev->mib_read);4859 }4860 4861 dev->dev_ops->exit(dev);4862 dsa_unregister_switch(dev->ds);4863 4864 if (dev->reset_gpio)4865 gpiod_set_value_cansleep(dev->reset_gpio, 1);4866 4867}4868EXPORT_SYMBOL(ksz_switch_remove);4869 4870MODULE_AUTHOR("Woojung Huh <Woojung.Huh@microchip.com>");4871MODULE_DESCRIPTION("Microchip KSZ Series Switch DSA Driver");4872MODULE_LICENSE("GPL");4873