David Brazdil | 0f672f6 | 2019-12-10 10:32:29 +0000 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | /* |
| 3 | * Microchip KSZ9477 switch driver main logic |
| 4 | * |
| 5 | * Copyright (C) 2017-2019 Microchip Technology Inc. |
| 6 | */ |
| 7 | |
| 8 | #include <linux/kernel.h> |
| 9 | #include <linux/module.h> |
| 10 | #include <linux/iopoll.h> |
| 11 | #include <linux/platform_data/microchip-ksz.h> |
| 12 | #include <linux/phy.h> |
| 13 | #include <linux/if_bridge.h> |
| 14 | #include <net/dsa.h> |
| 15 | #include <net/switchdev.h> |
| 16 | |
| 17 | #include "ksz9477_reg.h" |
| 18 | #include "ksz_common.h" |
| 19 | |
| 20 | /* Used with variable features to indicate capabilities. */ |
| 21 | #define GBIT_SUPPORT BIT(0) |
| 22 | #define NEW_XMII BIT(1) |
| 23 | #define IS_9893 BIT(2) |
| 24 | |
| 25 | static const struct { |
| 26 | int index; |
| 27 | char string[ETH_GSTRING_LEN]; |
| 28 | } ksz9477_mib_names[TOTAL_SWITCH_COUNTER_NUM] = { |
| 29 | { 0x00, "rx_hi" }, |
| 30 | { 0x01, "rx_undersize" }, |
| 31 | { 0x02, "rx_fragments" }, |
| 32 | { 0x03, "rx_oversize" }, |
| 33 | { 0x04, "rx_jabbers" }, |
| 34 | { 0x05, "rx_symbol_err" }, |
| 35 | { 0x06, "rx_crc_err" }, |
| 36 | { 0x07, "rx_align_err" }, |
| 37 | { 0x08, "rx_mac_ctrl" }, |
| 38 | { 0x09, "rx_pause" }, |
| 39 | { 0x0A, "rx_bcast" }, |
| 40 | { 0x0B, "rx_mcast" }, |
| 41 | { 0x0C, "rx_ucast" }, |
| 42 | { 0x0D, "rx_64_or_less" }, |
| 43 | { 0x0E, "rx_65_127" }, |
| 44 | { 0x0F, "rx_128_255" }, |
| 45 | { 0x10, "rx_256_511" }, |
| 46 | { 0x11, "rx_512_1023" }, |
| 47 | { 0x12, "rx_1024_1522" }, |
| 48 | { 0x13, "rx_1523_2000" }, |
| 49 | { 0x14, "rx_2001" }, |
| 50 | { 0x15, "tx_hi" }, |
| 51 | { 0x16, "tx_late_col" }, |
| 52 | { 0x17, "tx_pause" }, |
| 53 | { 0x18, "tx_bcast" }, |
| 54 | { 0x19, "tx_mcast" }, |
| 55 | { 0x1A, "tx_ucast" }, |
| 56 | { 0x1B, "tx_deferred" }, |
| 57 | { 0x1C, "tx_total_col" }, |
| 58 | { 0x1D, "tx_exc_col" }, |
| 59 | { 0x1E, "tx_single_col" }, |
| 60 | { 0x1F, "tx_mult_col" }, |
| 61 | { 0x80, "rx_total" }, |
| 62 | { 0x81, "tx_total" }, |
| 63 | { 0x82, "rx_discards" }, |
| 64 | { 0x83, "tx_discards" }, |
| 65 | }; |
| 66 | |
| 67 | static void ksz_cfg(struct ksz_device *dev, u32 addr, u8 bits, bool set) |
| 68 | { |
| 69 | regmap_update_bits(dev->regmap[0], addr, bits, set ? bits : 0); |
| 70 | } |
| 71 | |
| 72 | static void ksz_port_cfg(struct ksz_device *dev, int port, int offset, u8 bits, |
| 73 | bool set) |
| 74 | { |
| 75 | regmap_update_bits(dev->regmap[0], PORT_CTRL_ADDR(port, offset), |
| 76 | bits, set ? bits : 0); |
| 77 | } |
| 78 | |
| 79 | static void ksz9477_cfg32(struct ksz_device *dev, u32 addr, u32 bits, bool set) |
| 80 | { |
| 81 | regmap_update_bits(dev->regmap[2], addr, bits, set ? bits : 0); |
| 82 | } |
| 83 | |
| 84 | static void ksz9477_port_cfg32(struct ksz_device *dev, int port, int offset, |
| 85 | u32 bits, bool set) |
| 86 | { |
| 87 | regmap_update_bits(dev->regmap[2], PORT_CTRL_ADDR(port, offset), |
| 88 | bits, set ? bits : 0); |
| 89 | } |
| 90 | |
| 91 | static int ksz9477_wait_vlan_ctrl_ready(struct ksz_device *dev) |
| 92 | { |
| 93 | unsigned int val; |
| 94 | |
| 95 | return regmap_read_poll_timeout(dev->regmap[0], REG_SW_VLAN_CTRL, |
| 96 | val, !(val & VLAN_START), 10, 1000); |
| 97 | } |
| 98 | |
| 99 | static int ksz9477_get_vlan_table(struct ksz_device *dev, u16 vid, |
| 100 | u32 *vlan_table) |
| 101 | { |
| 102 | int ret; |
| 103 | |
| 104 | mutex_lock(&dev->vlan_mutex); |
| 105 | |
| 106 | ksz_write16(dev, REG_SW_VLAN_ENTRY_INDEX__2, vid & VLAN_INDEX_M); |
| 107 | ksz_write8(dev, REG_SW_VLAN_CTRL, VLAN_READ | VLAN_START); |
| 108 | |
| 109 | /* wait to be cleared */ |
| 110 | ret = ksz9477_wait_vlan_ctrl_ready(dev); |
| 111 | if (ret) { |
| 112 | dev_dbg(dev->dev, "Failed to read vlan table\n"); |
| 113 | goto exit; |
| 114 | } |
| 115 | |
| 116 | ksz_read32(dev, REG_SW_VLAN_ENTRY__4, &vlan_table[0]); |
| 117 | ksz_read32(dev, REG_SW_VLAN_ENTRY_UNTAG__4, &vlan_table[1]); |
| 118 | ksz_read32(dev, REG_SW_VLAN_ENTRY_PORTS__4, &vlan_table[2]); |
| 119 | |
| 120 | ksz_write8(dev, REG_SW_VLAN_CTRL, 0); |
| 121 | |
| 122 | exit: |
| 123 | mutex_unlock(&dev->vlan_mutex); |
| 124 | |
| 125 | return ret; |
| 126 | } |
| 127 | |
| 128 | static int ksz9477_set_vlan_table(struct ksz_device *dev, u16 vid, |
| 129 | u32 *vlan_table) |
| 130 | { |
| 131 | int ret; |
| 132 | |
| 133 | mutex_lock(&dev->vlan_mutex); |
| 134 | |
| 135 | ksz_write32(dev, REG_SW_VLAN_ENTRY__4, vlan_table[0]); |
| 136 | ksz_write32(dev, REG_SW_VLAN_ENTRY_UNTAG__4, vlan_table[1]); |
| 137 | ksz_write32(dev, REG_SW_VLAN_ENTRY_PORTS__4, vlan_table[2]); |
| 138 | |
| 139 | ksz_write16(dev, REG_SW_VLAN_ENTRY_INDEX__2, vid & VLAN_INDEX_M); |
| 140 | ksz_write8(dev, REG_SW_VLAN_CTRL, VLAN_START | VLAN_WRITE); |
| 141 | |
| 142 | /* wait to be cleared */ |
| 143 | ret = ksz9477_wait_vlan_ctrl_ready(dev); |
| 144 | if (ret) { |
| 145 | dev_dbg(dev->dev, "Failed to write vlan table\n"); |
| 146 | goto exit; |
| 147 | } |
| 148 | |
| 149 | ksz_write8(dev, REG_SW_VLAN_CTRL, 0); |
| 150 | |
| 151 | /* update vlan cache table */ |
| 152 | dev->vlan_cache[vid].table[0] = vlan_table[0]; |
| 153 | dev->vlan_cache[vid].table[1] = vlan_table[1]; |
| 154 | dev->vlan_cache[vid].table[2] = vlan_table[2]; |
| 155 | |
| 156 | exit: |
| 157 | mutex_unlock(&dev->vlan_mutex); |
| 158 | |
| 159 | return ret; |
| 160 | } |
| 161 | |
| 162 | static void ksz9477_read_table(struct ksz_device *dev, u32 *table) |
| 163 | { |
| 164 | ksz_read32(dev, REG_SW_ALU_VAL_A, &table[0]); |
| 165 | ksz_read32(dev, REG_SW_ALU_VAL_B, &table[1]); |
| 166 | ksz_read32(dev, REG_SW_ALU_VAL_C, &table[2]); |
| 167 | ksz_read32(dev, REG_SW_ALU_VAL_D, &table[3]); |
| 168 | } |
| 169 | |
| 170 | static void ksz9477_write_table(struct ksz_device *dev, u32 *table) |
| 171 | { |
| 172 | ksz_write32(dev, REG_SW_ALU_VAL_A, table[0]); |
| 173 | ksz_write32(dev, REG_SW_ALU_VAL_B, table[1]); |
| 174 | ksz_write32(dev, REG_SW_ALU_VAL_C, table[2]); |
| 175 | ksz_write32(dev, REG_SW_ALU_VAL_D, table[3]); |
| 176 | } |
| 177 | |
| 178 | static int ksz9477_wait_alu_ready(struct ksz_device *dev) |
| 179 | { |
| 180 | unsigned int val; |
| 181 | |
| 182 | return regmap_read_poll_timeout(dev->regmap[2], REG_SW_ALU_CTRL__4, |
| 183 | val, !(val & ALU_START), 10, 1000); |
| 184 | } |
| 185 | |
| 186 | static int ksz9477_wait_alu_sta_ready(struct ksz_device *dev) |
| 187 | { |
| 188 | unsigned int val; |
| 189 | |
| 190 | return regmap_read_poll_timeout(dev->regmap[2], |
| 191 | REG_SW_ALU_STAT_CTRL__4, |
| 192 | val, !(val & ALU_STAT_START), |
| 193 | 10, 1000); |
| 194 | } |
| 195 | |
| 196 | static int ksz9477_reset_switch(struct ksz_device *dev) |
| 197 | { |
| 198 | u8 data8; |
| 199 | u32 data32; |
| 200 | |
| 201 | /* reset switch */ |
| 202 | ksz_cfg(dev, REG_SW_OPERATION, SW_RESET, true); |
| 203 | |
| 204 | /* turn off SPI DO Edge select */ |
| 205 | regmap_update_bits(dev->regmap[0], REG_SW_GLOBAL_SERIAL_CTRL_0, |
| 206 | SPI_AUTO_EDGE_DETECTION, 0); |
| 207 | |
| 208 | /* default configuration */ |
| 209 | ksz_read8(dev, REG_SW_LUE_CTRL_1, &data8); |
| 210 | data8 = SW_AGING_ENABLE | SW_LINK_AUTO_AGING | |
| 211 | SW_SRC_ADDR_FILTER | SW_FLUSH_STP_TABLE | SW_FLUSH_MSTP_TABLE; |
| 212 | ksz_write8(dev, REG_SW_LUE_CTRL_1, data8); |
| 213 | |
| 214 | /* disable interrupts */ |
| 215 | ksz_write32(dev, REG_SW_INT_MASK__4, SWITCH_INT_MASK); |
| 216 | ksz_write32(dev, REG_SW_PORT_INT_MASK__4, 0x7F); |
| 217 | ksz_read32(dev, REG_SW_PORT_INT_STATUS__4, &data32); |
| 218 | |
| 219 | /* set broadcast storm protection 10% rate */ |
| 220 | regmap_update_bits(dev->regmap[1], REG_SW_MAC_CTRL_2, |
| 221 | BROADCAST_STORM_RATE, |
| 222 | (BROADCAST_STORM_VALUE * |
| 223 | BROADCAST_STORM_PROT_RATE) / 100); |
| 224 | |
| 225 | if (dev->synclko_125) |
| 226 | ksz_write8(dev, REG_SW_GLOBAL_OUTPUT_CTRL__1, |
| 227 | SW_ENABLE_REFCLKO | SW_REFCLKO_IS_125MHZ); |
| 228 | |
| 229 | return 0; |
| 230 | } |
| 231 | |
| 232 | static void ksz9477_r_mib_cnt(struct ksz_device *dev, int port, u16 addr, |
| 233 | u64 *cnt) |
| 234 | { |
| 235 | struct ksz_port *p = &dev->ports[port]; |
| 236 | unsigned int val; |
| 237 | u32 data; |
| 238 | int ret; |
| 239 | |
| 240 | /* retain the flush/freeze bit */ |
| 241 | data = p->freeze ? MIB_COUNTER_FLUSH_FREEZE : 0; |
| 242 | data |= MIB_COUNTER_READ; |
| 243 | data |= (addr << MIB_COUNTER_INDEX_S); |
| 244 | ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, data); |
| 245 | |
| 246 | ret = regmap_read_poll_timeout(dev->regmap[2], |
| 247 | PORT_CTRL_ADDR(port, REG_PORT_MIB_CTRL_STAT__4), |
| 248 | val, !(val & MIB_COUNTER_READ), 10, 1000); |
| 249 | /* failed to read MIB. get out of loop */ |
| 250 | if (ret) { |
| 251 | dev_dbg(dev->dev, "Failed to get MIB\n"); |
| 252 | return; |
| 253 | } |
| 254 | |
| 255 | /* count resets upon read */ |
| 256 | ksz_pread32(dev, port, REG_PORT_MIB_DATA, &data); |
| 257 | *cnt += data; |
| 258 | } |
| 259 | |
| 260 | static void ksz9477_r_mib_pkt(struct ksz_device *dev, int port, u16 addr, |
| 261 | u64 *dropped, u64 *cnt) |
| 262 | { |
| 263 | addr = ksz9477_mib_names[addr].index; |
| 264 | ksz9477_r_mib_cnt(dev, port, addr, cnt); |
| 265 | } |
| 266 | |
| 267 | static void ksz9477_freeze_mib(struct ksz_device *dev, int port, bool freeze) |
| 268 | { |
| 269 | u32 val = freeze ? MIB_COUNTER_FLUSH_FREEZE : 0; |
| 270 | struct ksz_port *p = &dev->ports[port]; |
| 271 | |
| 272 | /* enable/disable the port for flush/freeze function */ |
| 273 | mutex_lock(&p->mib.cnt_mutex); |
| 274 | ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, val); |
| 275 | |
| 276 | /* used by MIB counter reading code to know freeze is enabled */ |
| 277 | p->freeze = freeze; |
| 278 | mutex_unlock(&p->mib.cnt_mutex); |
| 279 | } |
| 280 | |
| 281 | static void ksz9477_port_init_cnt(struct ksz_device *dev, int port) |
| 282 | { |
| 283 | struct ksz_port_mib *mib = &dev->ports[port].mib; |
| 284 | |
| 285 | /* flush all enabled port MIB counters */ |
| 286 | mutex_lock(&mib->cnt_mutex); |
| 287 | ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, |
| 288 | MIB_COUNTER_FLUSH_FREEZE); |
| 289 | ksz_write8(dev, REG_SW_MAC_CTRL_6, SW_MIB_COUNTER_FLUSH); |
| 290 | ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, 0); |
| 291 | mutex_unlock(&mib->cnt_mutex); |
| 292 | |
| 293 | mib->cnt_ptr = 0; |
| 294 | memset(mib->counters, 0, dev->mib_cnt * sizeof(u64)); |
| 295 | } |
| 296 | |
| 297 | static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds, |
| 298 | int port) |
| 299 | { |
| 300 | enum dsa_tag_protocol proto = DSA_TAG_PROTO_KSZ9477; |
| 301 | struct ksz_device *dev = ds->priv; |
| 302 | |
| 303 | if (dev->features & IS_9893) |
| 304 | proto = DSA_TAG_PROTO_KSZ9893; |
| 305 | return proto; |
| 306 | } |
| 307 | |
| 308 | static int ksz9477_phy_read16(struct dsa_switch *ds, int addr, int reg) |
| 309 | { |
| 310 | struct ksz_device *dev = ds->priv; |
| 311 | u16 val = 0xffff; |
| 312 | |
| 313 | /* No real PHY after this. Simulate the PHY. |
| 314 | * A fixed PHY can be setup in the device tree, but this function is |
| 315 | * still called for that port during initialization. |
| 316 | * For RGMII PHY there is no way to access it so the fixed PHY should |
| 317 | * be used. For SGMII PHY the supporting code will be added later. |
| 318 | */ |
| 319 | if (addr >= dev->phy_port_cnt) { |
| 320 | struct ksz_port *p = &dev->ports[addr]; |
| 321 | |
| 322 | switch (reg) { |
| 323 | case MII_BMCR: |
| 324 | val = 0x1140; |
| 325 | break; |
| 326 | case MII_BMSR: |
| 327 | val = 0x796d; |
| 328 | break; |
| 329 | case MII_PHYSID1: |
| 330 | val = 0x0022; |
| 331 | break; |
| 332 | case MII_PHYSID2: |
| 333 | val = 0x1631; |
| 334 | break; |
| 335 | case MII_ADVERTISE: |
| 336 | val = 0x05e1; |
| 337 | break; |
| 338 | case MII_LPA: |
| 339 | val = 0xc5e1; |
| 340 | break; |
| 341 | case MII_CTRL1000: |
| 342 | val = 0x0700; |
| 343 | break; |
| 344 | case MII_STAT1000: |
| 345 | if (p->phydev.speed == SPEED_1000) |
| 346 | val = 0x3800; |
| 347 | else |
| 348 | val = 0; |
| 349 | break; |
| 350 | } |
| 351 | } else { |
| 352 | ksz_pread16(dev, addr, 0x100 + (reg << 1), &val); |
| 353 | } |
| 354 | |
| 355 | return val; |
| 356 | } |
| 357 | |
| 358 | static int ksz9477_phy_write16(struct dsa_switch *ds, int addr, int reg, |
| 359 | u16 val) |
| 360 | { |
| 361 | struct ksz_device *dev = ds->priv; |
| 362 | |
| 363 | /* No real PHY after this. */ |
| 364 | if (addr >= dev->phy_port_cnt) |
| 365 | return 0; |
| 366 | |
| 367 | /* No gigabit support. Do not write to this register. */ |
| 368 | if (!(dev->features & GBIT_SUPPORT) && reg == MII_CTRL1000) |
| 369 | return 0; |
| 370 | ksz_pwrite16(dev, addr, 0x100 + (reg << 1), val); |
| 371 | |
| 372 | return 0; |
| 373 | } |
| 374 | |
| 375 | static void ksz9477_get_strings(struct dsa_switch *ds, int port, |
| 376 | u32 stringset, uint8_t *buf) |
| 377 | { |
| 378 | int i; |
| 379 | |
| 380 | if (stringset != ETH_SS_STATS) |
| 381 | return; |
| 382 | |
| 383 | for (i = 0; i < TOTAL_SWITCH_COUNTER_NUM; i++) { |
| 384 | memcpy(buf + i * ETH_GSTRING_LEN, ksz9477_mib_names[i].string, |
| 385 | ETH_GSTRING_LEN); |
| 386 | } |
| 387 | } |
| 388 | |
| 389 | static void ksz9477_cfg_port_member(struct ksz_device *dev, int port, |
| 390 | u8 member) |
| 391 | { |
| 392 | ksz_pwrite32(dev, port, REG_PORT_VLAN_MEMBERSHIP__4, member); |
| 393 | dev->ports[port].member = member; |
| 394 | } |
| 395 | |
| 396 | static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port, |
| 397 | u8 state) |
| 398 | { |
| 399 | struct ksz_device *dev = ds->priv; |
| 400 | struct ksz_port *p = &dev->ports[port]; |
| 401 | u8 data; |
| 402 | int member = -1; |
| 403 | int forward = dev->member; |
| 404 | |
| 405 | ksz_pread8(dev, port, P_STP_CTRL, &data); |
| 406 | data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE | PORT_LEARN_DISABLE); |
| 407 | |
| 408 | switch (state) { |
| 409 | case BR_STATE_DISABLED: |
| 410 | data |= PORT_LEARN_DISABLE; |
| 411 | if (port != dev->cpu_port) |
| 412 | member = 0; |
| 413 | break; |
| 414 | case BR_STATE_LISTENING: |
| 415 | data |= (PORT_RX_ENABLE | PORT_LEARN_DISABLE); |
| 416 | if (port != dev->cpu_port && |
| 417 | p->stp_state == BR_STATE_DISABLED) |
| 418 | member = dev->host_mask | p->vid_member; |
| 419 | break; |
| 420 | case BR_STATE_LEARNING: |
| 421 | data |= PORT_RX_ENABLE; |
| 422 | break; |
| 423 | case BR_STATE_FORWARDING: |
| 424 | data |= (PORT_TX_ENABLE | PORT_RX_ENABLE); |
| 425 | |
| 426 | /* This function is also used internally. */ |
| 427 | if (port == dev->cpu_port) |
| 428 | break; |
| 429 | |
| 430 | member = dev->host_mask | p->vid_member; |
| 431 | mutex_lock(&dev->dev_mutex); |
| 432 | |
| 433 | /* Port is a member of a bridge. */ |
| 434 | if (dev->br_member & (1 << port)) { |
| 435 | dev->member |= (1 << port); |
| 436 | member = dev->member; |
| 437 | } |
| 438 | mutex_unlock(&dev->dev_mutex); |
| 439 | break; |
| 440 | case BR_STATE_BLOCKING: |
| 441 | data |= PORT_LEARN_DISABLE; |
| 442 | if (port != dev->cpu_port && |
| 443 | p->stp_state == BR_STATE_DISABLED) |
| 444 | member = dev->host_mask | p->vid_member; |
| 445 | break; |
| 446 | default: |
| 447 | dev_err(ds->dev, "invalid STP state: %d\n", state); |
| 448 | return; |
| 449 | } |
| 450 | |
| 451 | ksz_pwrite8(dev, port, P_STP_CTRL, data); |
| 452 | p->stp_state = state; |
| 453 | mutex_lock(&dev->dev_mutex); |
| 454 | if (data & PORT_RX_ENABLE) |
| 455 | dev->rx_ports |= (1 << port); |
| 456 | else |
| 457 | dev->rx_ports &= ~(1 << port); |
| 458 | if (data & PORT_TX_ENABLE) |
| 459 | dev->tx_ports |= (1 << port); |
| 460 | else |
| 461 | dev->tx_ports &= ~(1 << port); |
| 462 | |
| 463 | /* Port membership may share register with STP state. */ |
| 464 | if (member >= 0 && member != p->member) |
| 465 | ksz9477_cfg_port_member(dev, port, (u8)member); |
| 466 | |
| 467 | /* Check if forwarding needs to be updated. */ |
| 468 | if (state != BR_STATE_FORWARDING) { |
| 469 | if (dev->br_member & (1 << port)) |
| 470 | dev->member &= ~(1 << port); |
| 471 | } |
| 472 | |
| 473 | /* When topology has changed the function ksz_update_port_member |
| 474 | * should be called to modify port forwarding behavior. |
| 475 | */ |
| 476 | if (forward != dev->member) |
| 477 | ksz_update_port_member(dev, port); |
| 478 | mutex_unlock(&dev->dev_mutex); |
| 479 | } |
| 480 | |
| 481 | static void ksz9477_flush_dyn_mac_table(struct ksz_device *dev, int port) |
| 482 | { |
| 483 | u8 data; |
| 484 | |
| 485 | regmap_update_bits(dev->regmap[0], REG_SW_LUE_CTRL_2, |
| 486 | SW_FLUSH_OPTION_M << SW_FLUSH_OPTION_S, |
| 487 | SW_FLUSH_OPTION_DYN_MAC << SW_FLUSH_OPTION_S); |
| 488 | |
| 489 | if (port < dev->mib_port_cnt) { |
| 490 | /* flush individual port */ |
| 491 | ksz_pread8(dev, port, P_STP_CTRL, &data); |
| 492 | if (!(data & PORT_LEARN_DISABLE)) |
| 493 | ksz_pwrite8(dev, port, P_STP_CTRL, |
| 494 | data | PORT_LEARN_DISABLE); |
| 495 | ksz_cfg(dev, S_FLUSH_TABLE_CTRL, SW_FLUSH_DYN_MAC_TABLE, true); |
| 496 | ksz_pwrite8(dev, port, P_STP_CTRL, data); |
| 497 | } else { |
| 498 | /* flush all */ |
| 499 | ksz_cfg(dev, S_FLUSH_TABLE_CTRL, SW_FLUSH_STP_TABLE, true); |
| 500 | } |
| 501 | } |
| 502 | |
| 503 | static int ksz9477_port_vlan_filtering(struct dsa_switch *ds, int port, |
| 504 | bool flag) |
| 505 | { |
| 506 | struct ksz_device *dev = ds->priv; |
| 507 | |
| 508 | if (flag) { |
| 509 | ksz_port_cfg(dev, port, REG_PORT_LUE_CTRL, |
| 510 | PORT_VLAN_LOOKUP_VID_0, true); |
| 511 | ksz_cfg(dev, REG_SW_LUE_CTRL_0, SW_VLAN_ENABLE, true); |
| 512 | } else { |
| 513 | ksz_cfg(dev, REG_SW_LUE_CTRL_0, SW_VLAN_ENABLE, false); |
| 514 | ksz_port_cfg(dev, port, REG_PORT_LUE_CTRL, |
| 515 | PORT_VLAN_LOOKUP_VID_0, false); |
| 516 | } |
| 517 | |
| 518 | return 0; |
| 519 | } |
| 520 | |
| 521 | static void ksz9477_port_vlan_add(struct dsa_switch *ds, int port, |
| 522 | const struct switchdev_obj_port_vlan *vlan) |
| 523 | { |
| 524 | struct ksz_device *dev = ds->priv; |
| 525 | u32 vlan_table[3]; |
| 526 | u16 vid; |
| 527 | bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; |
| 528 | |
| 529 | for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) { |
| 530 | if (ksz9477_get_vlan_table(dev, vid, vlan_table)) { |
| 531 | dev_dbg(dev->dev, "Failed to get vlan table\n"); |
| 532 | return; |
| 533 | } |
| 534 | |
| 535 | vlan_table[0] = VLAN_VALID | (vid & VLAN_FID_M); |
| 536 | if (untagged) |
| 537 | vlan_table[1] |= BIT(port); |
| 538 | else |
| 539 | vlan_table[1] &= ~BIT(port); |
| 540 | vlan_table[1] &= ~(BIT(dev->cpu_port)); |
| 541 | |
| 542 | vlan_table[2] |= BIT(port) | BIT(dev->cpu_port); |
| 543 | |
| 544 | if (ksz9477_set_vlan_table(dev, vid, vlan_table)) { |
| 545 | dev_dbg(dev->dev, "Failed to set vlan table\n"); |
| 546 | return; |
| 547 | } |
| 548 | |
| 549 | /* change PVID */ |
| 550 | if (vlan->flags & BRIDGE_VLAN_INFO_PVID) |
| 551 | ksz_pwrite16(dev, port, REG_PORT_DEFAULT_VID, vid); |
| 552 | } |
| 553 | } |
| 554 | |
| 555 | static int ksz9477_port_vlan_del(struct dsa_switch *ds, int port, |
| 556 | const struct switchdev_obj_port_vlan *vlan) |
| 557 | { |
| 558 | struct ksz_device *dev = ds->priv; |
| 559 | bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; |
| 560 | u32 vlan_table[3]; |
| 561 | u16 vid; |
| 562 | u16 pvid; |
| 563 | |
| 564 | ksz_pread16(dev, port, REG_PORT_DEFAULT_VID, &pvid); |
| 565 | pvid = pvid & 0xFFF; |
| 566 | |
| 567 | for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) { |
| 568 | if (ksz9477_get_vlan_table(dev, vid, vlan_table)) { |
| 569 | dev_dbg(dev->dev, "Failed to get vlan table\n"); |
| 570 | return -ETIMEDOUT; |
| 571 | } |
| 572 | |
| 573 | vlan_table[2] &= ~BIT(port); |
| 574 | |
| 575 | if (pvid == vid) |
| 576 | pvid = 1; |
| 577 | |
| 578 | if (untagged) |
| 579 | vlan_table[1] &= ~BIT(port); |
| 580 | |
| 581 | if (ksz9477_set_vlan_table(dev, vid, vlan_table)) { |
| 582 | dev_dbg(dev->dev, "Failed to set vlan table\n"); |
| 583 | return -ETIMEDOUT; |
| 584 | } |
| 585 | } |
| 586 | |
| 587 | ksz_pwrite16(dev, port, REG_PORT_DEFAULT_VID, pvid); |
| 588 | |
| 589 | return 0; |
| 590 | } |
| 591 | |
| 592 | static int ksz9477_port_fdb_add(struct dsa_switch *ds, int port, |
| 593 | const unsigned char *addr, u16 vid) |
| 594 | { |
| 595 | struct ksz_device *dev = ds->priv; |
| 596 | u32 alu_table[4]; |
| 597 | u32 data; |
| 598 | int ret = 0; |
| 599 | |
| 600 | mutex_lock(&dev->alu_mutex); |
| 601 | |
| 602 | /* find any entry with mac & vid */ |
| 603 | data = vid << ALU_FID_INDEX_S; |
| 604 | data |= ((addr[0] << 8) | addr[1]); |
| 605 | ksz_write32(dev, REG_SW_ALU_INDEX_0, data); |
| 606 | |
| 607 | data = ((addr[2] << 24) | (addr[3] << 16)); |
| 608 | data |= ((addr[4] << 8) | addr[5]); |
| 609 | ksz_write32(dev, REG_SW_ALU_INDEX_1, data); |
| 610 | |
| 611 | /* start read operation */ |
| 612 | ksz_write32(dev, REG_SW_ALU_CTRL__4, ALU_READ | ALU_START); |
| 613 | |
| 614 | /* wait to be finished */ |
| 615 | ret = ksz9477_wait_alu_ready(dev); |
| 616 | if (ret) { |
| 617 | dev_dbg(dev->dev, "Failed to read ALU\n"); |
| 618 | goto exit; |
| 619 | } |
| 620 | |
| 621 | /* read ALU entry */ |
| 622 | ksz9477_read_table(dev, alu_table); |
| 623 | |
| 624 | /* update ALU entry */ |
| 625 | alu_table[0] = ALU_V_STATIC_VALID; |
| 626 | alu_table[1] |= BIT(port); |
| 627 | if (vid) |
| 628 | alu_table[1] |= ALU_V_USE_FID; |
| 629 | alu_table[2] = (vid << ALU_V_FID_S); |
| 630 | alu_table[2] |= ((addr[0] << 8) | addr[1]); |
| 631 | alu_table[3] = ((addr[2] << 24) | (addr[3] << 16)); |
| 632 | alu_table[3] |= ((addr[4] << 8) | addr[5]); |
| 633 | |
| 634 | ksz9477_write_table(dev, alu_table); |
| 635 | |
| 636 | ksz_write32(dev, REG_SW_ALU_CTRL__4, ALU_WRITE | ALU_START); |
| 637 | |
| 638 | /* wait to be finished */ |
| 639 | ret = ksz9477_wait_alu_ready(dev); |
| 640 | if (ret) |
| 641 | dev_dbg(dev->dev, "Failed to write ALU\n"); |
| 642 | |
| 643 | exit: |
| 644 | mutex_unlock(&dev->alu_mutex); |
| 645 | |
| 646 | return ret; |
| 647 | } |
| 648 | |
| 649 | static int ksz9477_port_fdb_del(struct dsa_switch *ds, int port, |
| 650 | const unsigned char *addr, u16 vid) |
| 651 | { |
| 652 | struct ksz_device *dev = ds->priv; |
| 653 | u32 alu_table[4]; |
| 654 | u32 data; |
| 655 | int ret = 0; |
| 656 | |
| 657 | mutex_lock(&dev->alu_mutex); |
| 658 | |
| 659 | /* read any entry with mac & vid */ |
| 660 | data = vid << ALU_FID_INDEX_S; |
| 661 | data |= ((addr[0] << 8) | addr[1]); |
| 662 | ksz_write32(dev, REG_SW_ALU_INDEX_0, data); |
| 663 | |
| 664 | data = ((addr[2] << 24) | (addr[3] << 16)); |
| 665 | data |= ((addr[4] << 8) | addr[5]); |
| 666 | ksz_write32(dev, REG_SW_ALU_INDEX_1, data); |
| 667 | |
| 668 | /* start read operation */ |
| 669 | ksz_write32(dev, REG_SW_ALU_CTRL__4, ALU_READ | ALU_START); |
| 670 | |
| 671 | /* wait to be finished */ |
| 672 | ret = ksz9477_wait_alu_ready(dev); |
| 673 | if (ret) { |
| 674 | dev_dbg(dev->dev, "Failed to read ALU\n"); |
| 675 | goto exit; |
| 676 | } |
| 677 | |
| 678 | ksz_read32(dev, REG_SW_ALU_VAL_A, &alu_table[0]); |
| 679 | if (alu_table[0] & ALU_V_STATIC_VALID) { |
| 680 | ksz_read32(dev, REG_SW_ALU_VAL_B, &alu_table[1]); |
| 681 | ksz_read32(dev, REG_SW_ALU_VAL_C, &alu_table[2]); |
| 682 | ksz_read32(dev, REG_SW_ALU_VAL_D, &alu_table[3]); |
| 683 | |
| 684 | /* clear forwarding port */ |
| 685 | alu_table[2] &= ~BIT(port); |
| 686 | |
| 687 | /* if there is no port to forward, clear table */ |
| 688 | if ((alu_table[2] & ALU_V_PORT_MAP) == 0) { |
| 689 | alu_table[0] = 0; |
| 690 | alu_table[1] = 0; |
| 691 | alu_table[2] = 0; |
| 692 | alu_table[3] = 0; |
| 693 | } |
| 694 | } else { |
| 695 | alu_table[0] = 0; |
| 696 | alu_table[1] = 0; |
| 697 | alu_table[2] = 0; |
| 698 | alu_table[3] = 0; |
| 699 | } |
| 700 | |
| 701 | ksz9477_write_table(dev, alu_table); |
| 702 | |
| 703 | ksz_write32(dev, REG_SW_ALU_CTRL__4, ALU_WRITE | ALU_START); |
| 704 | |
| 705 | /* wait to be finished */ |
| 706 | ret = ksz9477_wait_alu_ready(dev); |
| 707 | if (ret) |
| 708 | dev_dbg(dev->dev, "Failed to write ALU\n"); |
| 709 | |
| 710 | exit: |
| 711 | mutex_unlock(&dev->alu_mutex); |
| 712 | |
| 713 | return ret; |
| 714 | } |
| 715 | |
| 716 | static void ksz9477_convert_alu(struct alu_struct *alu, u32 *alu_table) |
| 717 | { |
| 718 | alu->is_static = !!(alu_table[0] & ALU_V_STATIC_VALID); |
| 719 | alu->is_src_filter = !!(alu_table[0] & ALU_V_SRC_FILTER); |
| 720 | alu->is_dst_filter = !!(alu_table[0] & ALU_V_DST_FILTER); |
| 721 | alu->prio_age = (alu_table[0] >> ALU_V_PRIO_AGE_CNT_S) & |
| 722 | ALU_V_PRIO_AGE_CNT_M; |
| 723 | alu->mstp = alu_table[0] & ALU_V_MSTP_M; |
| 724 | |
| 725 | alu->is_override = !!(alu_table[1] & ALU_V_OVERRIDE); |
| 726 | alu->is_use_fid = !!(alu_table[1] & ALU_V_USE_FID); |
| 727 | alu->port_forward = alu_table[1] & ALU_V_PORT_MAP; |
| 728 | |
| 729 | alu->fid = (alu_table[2] >> ALU_V_FID_S) & ALU_V_FID_M; |
| 730 | |
| 731 | alu->mac[0] = (alu_table[2] >> 8) & 0xFF; |
| 732 | alu->mac[1] = alu_table[2] & 0xFF; |
| 733 | alu->mac[2] = (alu_table[3] >> 24) & 0xFF; |
| 734 | alu->mac[3] = (alu_table[3] >> 16) & 0xFF; |
| 735 | alu->mac[4] = (alu_table[3] >> 8) & 0xFF; |
| 736 | alu->mac[5] = alu_table[3] & 0xFF; |
| 737 | } |
| 738 | |
| 739 | static int ksz9477_port_fdb_dump(struct dsa_switch *ds, int port, |
| 740 | dsa_fdb_dump_cb_t *cb, void *data) |
| 741 | { |
| 742 | struct ksz_device *dev = ds->priv; |
| 743 | int ret = 0; |
| 744 | u32 ksz_data; |
| 745 | u32 alu_table[4]; |
| 746 | struct alu_struct alu; |
| 747 | int timeout; |
| 748 | |
| 749 | mutex_lock(&dev->alu_mutex); |
| 750 | |
| 751 | /* start ALU search */ |
| 752 | ksz_write32(dev, REG_SW_ALU_CTRL__4, ALU_START | ALU_SEARCH); |
| 753 | |
| 754 | do { |
| 755 | timeout = 1000; |
| 756 | do { |
| 757 | ksz_read32(dev, REG_SW_ALU_CTRL__4, &ksz_data); |
| 758 | if ((ksz_data & ALU_VALID) || !(ksz_data & ALU_START)) |
| 759 | break; |
| 760 | usleep_range(1, 10); |
| 761 | } while (timeout-- > 0); |
| 762 | |
| 763 | if (!timeout) { |
| 764 | dev_dbg(dev->dev, "Failed to search ALU\n"); |
| 765 | ret = -ETIMEDOUT; |
| 766 | goto exit; |
| 767 | } |
| 768 | |
| 769 | /* read ALU table */ |
| 770 | ksz9477_read_table(dev, alu_table); |
| 771 | |
| 772 | ksz9477_convert_alu(&alu, alu_table); |
| 773 | |
| 774 | if (alu.port_forward & BIT(port)) { |
| 775 | ret = cb(alu.mac, alu.fid, alu.is_static, data); |
| 776 | if (ret) |
| 777 | goto exit; |
| 778 | } |
| 779 | } while (ksz_data & ALU_START); |
| 780 | |
| 781 | exit: |
| 782 | |
| 783 | /* stop ALU search */ |
| 784 | ksz_write32(dev, REG_SW_ALU_CTRL__4, 0); |
| 785 | |
| 786 | mutex_unlock(&dev->alu_mutex); |
| 787 | |
| 788 | return ret; |
| 789 | } |
| 790 | |
| 791 | static void ksz9477_port_mdb_add(struct dsa_switch *ds, int port, |
| 792 | const struct switchdev_obj_port_mdb *mdb) |
| 793 | { |
| 794 | struct ksz_device *dev = ds->priv; |
| 795 | u32 static_table[4]; |
| 796 | u32 data; |
| 797 | int index; |
| 798 | u32 mac_hi, mac_lo; |
| 799 | |
| 800 | mac_hi = ((mdb->addr[0] << 8) | mdb->addr[1]); |
| 801 | mac_lo = ((mdb->addr[2] << 24) | (mdb->addr[3] << 16)); |
| 802 | mac_lo |= ((mdb->addr[4] << 8) | mdb->addr[5]); |
| 803 | |
| 804 | mutex_lock(&dev->alu_mutex); |
| 805 | |
| 806 | for (index = 0; index < dev->num_statics; index++) { |
| 807 | /* find empty slot first */ |
| 808 | data = (index << ALU_STAT_INDEX_S) | |
| 809 | ALU_STAT_READ | ALU_STAT_START; |
| 810 | ksz_write32(dev, REG_SW_ALU_STAT_CTRL__4, data); |
| 811 | |
| 812 | /* wait to be finished */ |
| 813 | if (ksz9477_wait_alu_sta_ready(dev)) { |
| 814 | dev_dbg(dev->dev, "Failed to read ALU STATIC\n"); |
| 815 | goto exit; |
| 816 | } |
| 817 | |
| 818 | /* read ALU static table */ |
| 819 | ksz9477_read_table(dev, static_table); |
| 820 | |
| 821 | if (static_table[0] & ALU_V_STATIC_VALID) { |
| 822 | /* check this has same vid & mac address */ |
| 823 | if (((static_table[2] >> ALU_V_FID_S) == mdb->vid) && |
| 824 | ((static_table[2] & ALU_V_MAC_ADDR_HI) == mac_hi) && |
| 825 | static_table[3] == mac_lo) { |
| 826 | /* found matching one */ |
| 827 | break; |
| 828 | } |
| 829 | } else { |
| 830 | /* found empty one */ |
| 831 | break; |
| 832 | } |
| 833 | } |
| 834 | |
| 835 | /* no available entry */ |
| 836 | if (index == dev->num_statics) |
| 837 | goto exit; |
| 838 | |
| 839 | /* add entry */ |
| 840 | static_table[0] = ALU_V_STATIC_VALID; |
| 841 | static_table[1] |= BIT(port); |
| 842 | if (mdb->vid) |
| 843 | static_table[1] |= ALU_V_USE_FID; |
| 844 | static_table[2] = (mdb->vid << ALU_V_FID_S); |
| 845 | static_table[2] |= mac_hi; |
| 846 | static_table[3] = mac_lo; |
| 847 | |
| 848 | ksz9477_write_table(dev, static_table); |
| 849 | |
| 850 | data = (index << ALU_STAT_INDEX_S) | ALU_STAT_START; |
| 851 | ksz_write32(dev, REG_SW_ALU_STAT_CTRL__4, data); |
| 852 | |
| 853 | /* wait to be finished */ |
| 854 | if (ksz9477_wait_alu_sta_ready(dev)) |
| 855 | dev_dbg(dev->dev, "Failed to read ALU STATIC\n"); |
| 856 | |
| 857 | exit: |
| 858 | mutex_unlock(&dev->alu_mutex); |
| 859 | } |
| 860 | |
| 861 | static int ksz9477_port_mdb_del(struct dsa_switch *ds, int port, |
| 862 | const struct switchdev_obj_port_mdb *mdb) |
| 863 | { |
| 864 | struct ksz_device *dev = ds->priv; |
| 865 | u32 static_table[4]; |
| 866 | u32 data; |
| 867 | int index; |
| 868 | int ret = 0; |
| 869 | u32 mac_hi, mac_lo; |
| 870 | |
| 871 | mac_hi = ((mdb->addr[0] << 8) | mdb->addr[1]); |
| 872 | mac_lo = ((mdb->addr[2] << 24) | (mdb->addr[3] << 16)); |
| 873 | mac_lo |= ((mdb->addr[4] << 8) | mdb->addr[5]); |
| 874 | |
| 875 | mutex_lock(&dev->alu_mutex); |
| 876 | |
| 877 | for (index = 0; index < dev->num_statics; index++) { |
| 878 | /* find empty slot first */ |
| 879 | data = (index << ALU_STAT_INDEX_S) | |
| 880 | ALU_STAT_READ | ALU_STAT_START; |
| 881 | ksz_write32(dev, REG_SW_ALU_STAT_CTRL__4, data); |
| 882 | |
| 883 | /* wait to be finished */ |
| 884 | ret = ksz9477_wait_alu_sta_ready(dev); |
| 885 | if (ret) { |
| 886 | dev_dbg(dev->dev, "Failed to read ALU STATIC\n"); |
| 887 | goto exit; |
| 888 | } |
| 889 | |
| 890 | /* read ALU static table */ |
| 891 | ksz9477_read_table(dev, static_table); |
| 892 | |
| 893 | if (static_table[0] & ALU_V_STATIC_VALID) { |
| 894 | /* check this has same vid & mac address */ |
| 895 | |
| 896 | if (((static_table[2] >> ALU_V_FID_S) == mdb->vid) && |
| 897 | ((static_table[2] & ALU_V_MAC_ADDR_HI) == mac_hi) && |
| 898 | static_table[3] == mac_lo) { |
| 899 | /* found matching one */ |
| 900 | break; |
| 901 | } |
| 902 | } |
| 903 | } |
| 904 | |
| 905 | /* no available entry */ |
| 906 | if (index == dev->num_statics) |
| 907 | goto exit; |
| 908 | |
| 909 | /* clear port */ |
| 910 | static_table[1] &= ~BIT(port); |
| 911 | |
| 912 | if ((static_table[1] & ALU_V_PORT_MAP) == 0) { |
| 913 | /* delete entry */ |
| 914 | static_table[0] = 0; |
| 915 | static_table[1] = 0; |
| 916 | static_table[2] = 0; |
| 917 | static_table[3] = 0; |
| 918 | } |
| 919 | |
| 920 | ksz9477_write_table(dev, static_table); |
| 921 | |
| 922 | data = (index << ALU_STAT_INDEX_S) | ALU_STAT_START; |
| 923 | ksz_write32(dev, REG_SW_ALU_STAT_CTRL__4, data); |
| 924 | |
| 925 | /* wait to be finished */ |
| 926 | ret = ksz9477_wait_alu_sta_ready(dev); |
| 927 | if (ret) |
| 928 | dev_dbg(dev->dev, "Failed to read ALU STATIC\n"); |
| 929 | |
| 930 | exit: |
| 931 | mutex_unlock(&dev->alu_mutex); |
| 932 | |
| 933 | return ret; |
| 934 | } |
| 935 | |
| 936 | static int ksz9477_port_mirror_add(struct dsa_switch *ds, int port, |
| 937 | struct dsa_mall_mirror_tc_entry *mirror, |
| 938 | bool ingress) |
| 939 | { |
| 940 | struct ksz_device *dev = ds->priv; |
| 941 | |
| 942 | if (ingress) |
| 943 | ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_RX, true); |
| 944 | else |
| 945 | ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_TX, true); |
| 946 | |
| 947 | ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_SNIFFER, false); |
| 948 | |
| 949 | /* configure mirror port */ |
| 950 | ksz_port_cfg(dev, mirror->to_local_port, P_MIRROR_CTRL, |
| 951 | PORT_MIRROR_SNIFFER, true); |
| 952 | |
| 953 | ksz_cfg(dev, S_MIRROR_CTRL, SW_MIRROR_RX_TX, false); |
| 954 | |
| 955 | return 0; |
| 956 | } |
| 957 | |
| 958 | static void ksz9477_port_mirror_del(struct dsa_switch *ds, int port, |
| 959 | struct dsa_mall_mirror_tc_entry *mirror) |
| 960 | { |
| 961 | struct ksz_device *dev = ds->priv; |
| 962 | u8 data; |
| 963 | |
| 964 | if (mirror->ingress) |
| 965 | ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_RX, false); |
| 966 | else |
| 967 | ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_TX, false); |
| 968 | |
| 969 | ksz_pread8(dev, port, P_MIRROR_CTRL, &data); |
| 970 | |
| 971 | if (!(data & (PORT_MIRROR_RX | PORT_MIRROR_TX))) |
| 972 | ksz_port_cfg(dev, mirror->to_local_port, P_MIRROR_CTRL, |
| 973 | PORT_MIRROR_SNIFFER, false); |
| 974 | } |
| 975 | |
| 976 | static void ksz9477_phy_setup(struct ksz_device *dev, int port, |
| 977 | struct phy_device *phy) |
| 978 | { |
| 979 | /* Only apply to port with PHY. */ |
| 980 | if (port >= dev->phy_port_cnt) |
| 981 | return; |
| 982 | |
| 983 | /* The MAC actually cannot run in 1000 half-duplex mode. */ |
| 984 | phy_remove_link_mode(phy, |
| 985 | ETHTOOL_LINK_MODE_1000baseT_Half_BIT); |
| 986 | |
| 987 | /* PHY does not support gigabit. */ |
| 988 | if (!(dev->features & GBIT_SUPPORT)) |
| 989 | phy_remove_link_mode(phy, |
| 990 | ETHTOOL_LINK_MODE_1000baseT_Full_BIT); |
| 991 | } |
| 992 | |
| 993 | static bool ksz9477_get_gbit(struct ksz_device *dev, u8 data) |
| 994 | { |
| 995 | bool gbit; |
| 996 | |
| 997 | if (dev->features & NEW_XMII) |
| 998 | gbit = !(data & PORT_MII_NOT_1GBIT); |
| 999 | else |
| 1000 | gbit = !!(data & PORT_MII_1000MBIT_S1); |
| 1001 | return gbit; |
| 1002 | } |
| 1003 | |
| 1004 | static void ksz9477_set_gbit(struct ksz_device *dev, bool gbit, u8 *data) |
| 1005 | { |
| 1006 | if (dev->features & NEW_XMII) { |
| 1007 | if (gbit) |
| 1008 | *data &= ~PORT_MII_NOT_1GBIT; |
| 1009 | else |
| 1010 | *data |= PORT_MII_NOT_1GBIT; |
| 1011 | } else { |
| 1012 | if (gbit) |
| 1013 | *data |= PORT_MII_1000MBIT_S1; |
| 1014 | else |
| 1015 | *data &= ~PORT_MII_1000MBIT_S1; |
| 1016 | } |
| 1017 | } |
| 1018 | |
| 1019 | static int ksz9477_get_xmii(struct ksz_device *dev, u8 data) |
| 1020 | { |
| 1021 | int mode; |
| 1022 | |
| 1023 | if (dev->features & NEW_XMII) { |
| 1024 | switch (data & PORT_MII_SEL_M) { |
| 1025 | case PORT_MII_SEL: |
| 1026 | mode = 0; |
| 1027 | break; |
| 1028 | case PORT_RMII_SEL: |
| 1029 | mode = 1; |
| 1030 | break; |
| 1031 | case PORT_GMII_SEL: |
| 1032 | mode = 2; |
| 1033 | break; |
| 1034 | default: |
| 1035 | mode = 3; |
| 1036 | } |
| 1037 | } else { |
| 1038 | switch (data & PORT_MII_SEL_M) { |
| 1039 | case PORT_MII_SEL_S1: |
| 1040 | mode = 0; |
| 1041 | break; |
| 1042 | case PORT_RMII_SEL_S1: |
| 1043 | mode = 1; |
| 1044 | break; |
| 1045 | case PORT_GMII_SEL_S1: |
| 1046 | mode = 2; |
| 1047 | break; |
| 1048 | default: |
| 1049 | mode = 3; |
| 1050 | } |
| 1051 | } |
| 1052 | return mode; |
| 1053 | } |
| 1054 | |
| 1055 | static void ksz9477_set_xmii(struct ksz_device *dev, int mode, u8 *data) |
| 1056 | { |
| 1057 | u8 xmii; |
| 1058 | |
| 1059 | if (dev->features & NEW_XMII) { |
| 1060 | switch (mode) { |
| 1061 | case 0: |
| 1062 | xmii = PORT_MII_SEL; |
| 1063 | break; |
| 1064 | case 1: |
| 1065 | xmii = PORT_RMII_SEL; |
| 1066 | break; |
| 1067 | case 2: |
| 1068 | xmii = PORT_GMII_SEL; |
| 1069 | break; |
| 1070 | default: |
| 1071 | xmii = PORT_RGMII_SEL; |
| 1072 | break; |
| 1073 | } |
| 1074 | } else { |
| 1075 | switch (mode) { |
| 1076 | case 0: |
| 1077 | xmii = PORT_MII_SEL_S1; |
| 1078 | break; |
| 1079 | case 1: |
| 1080 | xmii = PORT_RMII_SEL_S1; |
| 1081 | break; |
| 1082 | case 2: |
| 1083 | xmii = PORT_GMII_SEL_S1; |
| 1084 | break; |
| 1085 | default: |
| 1086 | xmii = PORT_RGMII_SEL_S1; |
| 1087 | break; |
| 1088 | } |
| 1089 | } |
| 1090 | *data &= ~PORT_MII_SEL_M; |
| 1091 | *data |= xmii; |
| 1092 | } |
| 1093 | |
| 1094 | static phy_interface_t ksz9477_get_interface(struct ksz_device *dev, int port) |
| 1095 | { |
| 1096 | phy_interface_t interface; |
| 1097 | bool gbit; |
| 1098 | int mode; |
| 1099 | u8 data8; |
| 1100 | |
| 1101 | if (port < dev->phy_port_cnt) |
| 1102 | return PHY_INTERFACE_MODE_NA; |
| 1103 | ksz_pread8(dev, port, REG_PORT_XMII_CTRL_1, &data8); |
| 1104 | gbit = ksz9477_get_gbit(dev, data8); |
| 1105 | mode = ksz9477_get_xmii(dev, data8); |
| 1106 | switch (mode) { |
| 1107 | case 2: |
| 1108 | interface = PHY_INTERFACE_MODE_GMII; |
| 1109 | if (gbit) |
| 1110 | break; |
| 1111 | /* fall through */ |
| 1112 | case 0: |
| 1113 | interface = PHY_INTERFACE_MODE_MII; |
| 1114 | break; |
| 1115 | case 1: |
| 1116 | interface = PHY_INTERFACE_MODE_RMII; |
| 1117 | break; |
| 1118 | default: |
| 1119 | interface = PHY_INTERFACE_MODE_RGMII; |
| 1120 | if (data8 & PORT_RGMII_ID_EG_ENABLE) |
| 1121 | interface = PHY_INTERFACE_MODE_RGMII_TXID; |
| 1122 | if (data8 & PORT_RGMII_ID_IG_ENABLE) { |
| 1123 | interface = PHY_INTERFACE_MODE_RGMII_RXID; |
| 1124 | if (data8 & PORT_RGMII_ID_EG_ENABLE) |
| 1125 | interface = PHY_INTERFACE_MODE_RGMII_ID; |
| 1126 | } |
| 1127 | break; |
| 1128 | } |
| 1129 | return interface; |
| 1130 | } |
| 1131 | |
| 1132 | static void ksz9477_port_mmd_write(struct ksz_device *dev, int port, |
| 1133 | u8 dev_addr, u16 reg_addr, u16 val) |
| 1134 | { |
| 1135 | ksz_pwrite16(dev, port, REG_PORT_PHY_MMD_SETUP, |
| 1136 | MMD_SETUP(PORT_MMD_OP_INDEX, dev_addr)); |
| 1137 | ksz_pwrite16(dev, port, REG_PORT_PHY_MMD_INDEX_DATA, reg_addr); |
| 1138 | ksz_pwrite16(dev, port, REG_PORT_PHY_MMD_SETUP, |
| 1139 | MMD_SETUP(PORT_MMD_OP_DATA_NO_INCR, dev_addr)); |
| 1140 | ksz_pwrite16(dev, port, REG_PORT_PHY_MMD_INDEX_DATA, val); |
| 1141 | } |
| 1142 | |
| 1143 | static void ksz9477_phy_errata_setup(struct ksz_device *dev, int port) |
| 1144 | { |
| 1145 | /* Apply PHY settings to address errata listed in |
| 1146 | * KSZ9477, KSZ9897, KSZ9896, KSZ9567, KSZ8565 |
| 1147 | * Silicon Errata and Data Sheet Clarification documents: |
| 1148 | * |
| 1149 | * Register settings are needed to improve PHY receive performance |
| 1150 | */ |
| 1151 | ksz9477_port_mmd_write(dev, port, 0x01, 0x6f, 0xdd0b); |
| 1152 | ksz9477_port_mmd_write(dev, port, 0x01, 0x8f, 0x6032); |
| 1153 | ksz9477_port_mmd_write(dev, port, 0x01, 0x9d, 0x248c); |
| 1154 | ksz9477_port_mmd_write(dev, port, 0x01, 0x75, 0x0060); |
| 1155 | ksz9477_port_mmd_write(dev, port, 0x01, 0xd3, 0x7777); |
| 1156 | ksz9477_port_mmd_write(dev, port, 0x1c, 0x06, 0x3008); |
| 1157 | ksz9477_port_mmd_write(dev, port, 0x1c, 0x08, 0x2001); |
| 1158 | |
| 1159 | /* Transmit waveform amplitude can be improved |
| 1160 | * (1000BASE-T, 100BASE-TX, 10BASE-Te) |
| 1161 | */ |
| 1162 | ksz9477_port_mmd_write(dev, port, 0x1c, 0x04, 0x00d0); |
| 1163 | |
| 1164 | /* Energy Efficient Ethernet (EEE) feature select must |
| 1165 | * be manually disabled (except on KSZ8565 which is 100Mbit) |
| 1166 | */ |
| 1167 | if (dev->features & GBIT_SUPPORT) |
| 1168 | ksz9477_port_mmd_write(dev, port, 0x07, 0x3c, 0x0000); |
| 1169 | |
| 1170 | /* Register settings are required to meet data sheet |
| 1171 | * supply current specifications |
| 1172 | */ |
| 1173 | ksz9477_port_mmd_write(dev, port, 0x1c, 0x13, 0x6eff); |
| 1174 | ksz9477_port_mmd_write(dev, port, 0x1c, 0x14, 0xe6ff); |
| 1175 | ksz9477_port_mmd_write(dev, port, 0x1c, 0x15, 0x6eff); |
| 1176 | ksz9477_port_mmd_write(dev, port, 0x1c, 0x16, 0xe6ff); |
| 1177 | ksz9477_port_mmd_write(dev, port, 0x1c, 0x17, 0x00ff); |
| 1178 | ksz9477_port_mmd_write(dev, port, 0x1c, 0x18, 0x43ff); |
| 1179 | ksz9477_port_mmd_write(dev, port, 0x1c, 0x19, 0xc3ff); |
| 1180 | ksz9477_port_mmd_write(dev, port, 0x1c, 0x1a, 0x6fff); |
| 1181 | ksz9477_port_mmd_write(dev, port, 0x1c, 0x1b, 0x07ff); |
| 1182 | ksz9477_port_mmd_write(dev, port, 0x1c, 0x1c, 0x0fff); |
| 1183 | ksz9477_port_mmd_write(dev, port, 0x1c, 0x1d, 0xe7ff); |
| 1184 | ksz9477_port_mmd_write(dev, port, 0x1c, 0x1e, 0xefff); |
| 1185 | ksz9477_port_mmd_write(dev, port, 0x1c, 0x20, 0xeeee); |
| 1186 | } |
| 1187 | |
| 1188 | static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port) |
| 1189 | { |
| 1190 | u8 data8; |
| 1191 | u8 member; |
| 1192 | u16 data16; |
| 1193 | struct ksz_port *p = &dev->ports[port]; |
| 1194 | |
| 1195 | /* enable tag tail for host port */ |
| 1196 | if (cpu_port) |
| 1197 | ksz_port_cfg(dev, port, REG_PORT_CTRL_0, PORT_TAIL_TAG_ENABLE, |
| 1198 | true); |
| 1199 | |
| 1200 | ksz_port_cfg(dev, port, REG_PORT_CTRL_0, PORT_MAC_LOOPBACK, false); |
| 1201 | |
| 1202 | /* set back pressure */ |
| 1203 | ksz_port_cfg(dev, port, REG_PORT_MAC_CTRL_1, PORT_BACK_PRESSURE, true); |
| 1204 | |
| 1205 | /* enable broadcast storm limit */ |
| 1206 | ksz_port_cfg(dev, port, P_BCAST_STORM_CTRL, PORT_BROADCAST_STORM, true); |
| 1207 | |
| 1208 | /* disable DiffServ priority */ |
| 1209 | ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_DIFFSERV_PRIO_ENABLE, false); |
| 1210 | |
| 1211 | /* replace priority */ |
| 1212 | ksz_port_cfg(dev, port, REG_PORT_MRI_MAC_CTRL, PORT_USER_PRIO_CEILING, |
| 1213 | false); |
| 1214 | ksz9477_port_cfg32(dev, port, REG_PORT_MTI_QUEUE_CTRL_0__4, |
| 1215 | MTI_PVID_REPLACE, false); |
| 1216 | |
| 1217 | /* enable 802.1p priority */ |
| 1218 | ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_802_1P_PRIO_ENABLE, true); |
| 1219 | |
| 1220 | if (port < dev->phy_port_cnt) { |
| 1221 | /* do not force flow control */ |
| 1222 | ksz_port_cfg(dev, port, REG_PORT_CTRL_0, |
| 1223 | PORT_FORCE_TX_FLOW_CTRL | PORT_FORCE_RX_FLOW_CTRL, |
| 1224 | false); |
| 1225 | |
| 1226 | if (dev->phy_errata_9477) |
| 1227 | ksz9477_phy_errata_setup(dev, port); |
| 1228 | } else { |
| 1229 | /* force flow control */ |
| 1230 | ksz_port_cfg(dev, port, REG_PORT_CTRL_0, |
| 1231 | PORT_FORCE_TX_FLOW_CTRL | PORT_FORCE_RX_FLOW_CTRL, |
| 1232 | true); |
| 1233 | |
| 1234 | /* configure MAC to 1G & RGMII mode */ |
| 1235 | ksz_pread8(dev, port, REG_PORT_XMII_CTRL_1, &data8); |
| 1236 | switch (dev->interface) { |
| 1237 | case PHY_INTERFACE_MODE_MII: |
| 1238 | ksz9477_set_xmii(dev, 0, &data8); |
| 1239 | ksz9477_set_gbit(dev, false, &data8); |
| 1240 | p->phydev.speed = SPEED_100; |
| 1241 | break; |
| 1242 | case PHY_INTERFACE_MODE_RMII: |
| 1243 | ksz9477_set_xmii(dev, 1, &data8); |
| 1244 | ksz9477_set_gbit(dev, false, &data8); |
| 1245 | p->phydev.speed = SPEED_100; |
| 1246 | break; |
| 1247 | case PHY_INTERFACE_MODE_GMII: |
| 1248 | ksz9477_set_xmii(dev, 2, &data8); |
| 1249 | ksz9477_set_gbit(dev, true, &data8); |
| 1250 | p->phydev.speed = SPEED_1000; |
| 1251 | break; |
| 1252 | default: |
| 1253 | ksz9477_set_xmii(dev, 3, &data8); |
| 1254 | ksz9477_set_gbit(dev, true, &data8); |
| 1255 | data8 &= ~PORT_RGMII_ID_IG_ENABLE; |
| 1256 | data8 &= ~PORT_RGMII_ID_EG_ENABLE; |
| 1257 | if (dev->interface == PHY_INTERFACE_MODE_RGMII_ID || |
| 1258 | dev->interface == PHY_INTERFACE_MODE_RGMII_RXID) |
| 1259 | data8 |= PORT_RGMII_ID_IG_ENABLE; |
| 1260 | if (dev->interface == PHY_INTERFACE_MODE_RGMII_ID || |
| 1261 | dev->interface == PHY_INTERFACE_MODE_RGMII_TXID) |
| 1262 | data8 |= PORT_RGMII_ID_EG_ENABLE; |
| 1263 | p->phydev.speed = SPEED_1000; |
| 1264 | break; |
| 1265 | } |
| 1266 | ksz_pwrite8(dev, port, REG_PORT_XMII_CTRL_1, data8); |
| 1267 | p->phydev.duplex = 1; |
| 1268 | } |
| 1269 | mutex_lock(&dev->dev_mutex); |
| 1270 | if (cpu_port) { |
| 1271 | member = dev->port_mask; |
| 1272 | dev->on_ports = dev->host_mask; |
| 1273 | dev->live_ports = dev->host_mask; |
| 1274 | } else { |
| 1275 | member = dev->host_mask | p->vid_member; |
| 1276 | dev->on_ports |= (1 << port); |
| 1277 | |
| 1278 | /* Link was detected before port is enabled. */ |
| 1279 | if (p->phydev.link) |
| 1280 | dev->live_ports |= (1 << port); |
| 1281 | } |
| 1282 | mutex_unlock(&dev->dev_mutex); |
| 1283 | ksz9477_cfg_port_member(dev, port, member); |
| 1284 | |
| 1285 | /* clear pending interrupts */ |
| 1286 | if (port < dev->phy_port_cnt) |
| 1287 | ksz_pread16(dev, port, REG_PORT_PHY_INT_ENABLE, &data16); |
| 1288 | } |
| 1289 | |
| 1290 | static void ksz9477_config_cpu_port(struct dsa_switch *ds) |
| 1291 | { |
| 1292 | struct ksz_device *dev = ds->priv; |
| 1293 | struct ksz_port *p; |
| 1294 | int i; |
| 1295 | |
| 1296 | ds->num_ports = dev->port_cnt; |
| 1297 | |
| 1298 | for (i = 0; i < dev->port_cnt; i++) { |
| 1299 | if (dsa_is_cpu_port(ds, i) && (dev->cpu_ports & (1 << i))) { |
| 1300 | phy_interface_t interface; |
| 1301 | |
| 1302 | dev->cpu_port = i; |
| 1303 | dev->host_mask = (1 << dev->cpu_port); |
| 1304 | dev->port_mask |= dev->host_mask; |
| 1305 | |
| 1306 | /* Read from XMII register to determine host port |
| 1307 | * interface. If set specifically in device tree |
| 1308 | * note the difference to help debugging. |
| 1309 | */ |
| 1310 | interface = ksz9477_get_interface(dev, i); |
| 1311 | if (!dev->interface) |
| 1312 | dev->interface = interface; |
| 1313 | if (interface && interface != dev->interface) |
| 1314 | dev_info(dev->dev, |
| 1315 | "use %s instead of %s\n", |
| 1316 | phy_modes(dev->interface), |
| 1317 | phy_modes(interface)); |
| 1318 | |
| 1319 | /* enable cpu port */ |
| 1320 | ksz9477_port_setup(dev, i, true); |
| 1321 | p = &dev->ports[dev->cpu_port]; |
| 1322 | p->vid_member = dev->port_mask; |
| 1323 | p->on = 1; |
| 1324 | } |
| 1325 | } |
| 1326 | |
| 1327 | dev->member = dev->host_mask; |
| 1328 | |
| 1329 | for (i = 0; i < dev->mib_port_cnt; i++) { |
| 1330 | if (i == dev->cpu_port) |
| 1331 | continue; |
| 1332 | p = &dev->ports[i]; |
| 1333 | |
| 1334 | /* Initialize to non-zero so that ksz_cfg_port_member() will |
| 1335 | * be called. |
| 1336 | */ |
| 1337 | p->vid_member = (1 << i); |
| 1338 | p->member = dev->port_mask; |
| 1339 | ksz9477_port_stp_state_set(ds, i, BR_STATE_DISABLED); |
| 1340 | p->on = 1; |
| 1341 | if (i < dev->phy_port_cnt) |
| 1342 | p->phy = 1; |
| 1343 | if (dev->chip_id == 0x00947700 && i == 6) { |
| 1344 | p->sgmii = 1; |
| 1345 | |
| 1346 | /* SGMII PHY detection code is not implemented yet. */ |
| 1347 | p->phy = 0; |
| 1348 | } |
| 1349 | } |
| 1350 | } |
| 1351 | |
| 1352 | static int ksz9477_setup(struct dsa_switch *ds) |
| 1353 | { |
| 1354 | struct ksz_device *dev = ds->priv; |
| 1355 | int ret = 0; |
| 1356 | |
| 1357 | dev->vlan_cache = devm_kcalloc(dev->dev, sizeof(struct vlan_table), |
| 1358 | dev->num_vlans, GFP_KERNEL); |
| 1359 | if (!dev->vlan_cache) |
| 1360 | return -ENOMEM; |
| 1361 | |
| 1362 | ret = ksz9477_reset_switch(dev); |
| 1363 | if (ret) { |
| 1364 | dev_err(ds->dev, "failed to reset switch\n"); |
| 1365 | return ret; |
| 1366 | } |
| 1367 | |
| 1368 | /* Required for port partitioning. */ |
| 1369 | ksz9477_cfg32(dev, REG_SW_QM_CTRL__4, UNICAST_VLAN_BOUNDARY, |
| 1370 | true); |
| 1371 | |
| 1372 | /* Do not work correctly with tail tagging. */ |
| 1373 | ksz_cfg(dev, REG_SW_MAC_CTRL_0, SW_CHECK_LENGTH, false); |
| 1374 | |
| 1375 | /* accept packet up to 2000bytes */ |
| 1376 | ksz_cfg(dev, REG_SW_MAC_CTRL_1, SW_LEGAL_PACKET_DISABLE, true); |
| 1377 | |
| 1378 | ksz9477_config_cpu_port(ds); |
| 1379 | |
| 1380 | ksz_cfg(dev, REG_SW_MAC_CTRL_1, MULTICAST_STORM_DISABLE, true); |
| 1381 | |
| 1382 | /* queue based egress rate limit */ |
| 1383 | ksz_cfg(dev, REG_SW_MAC_CTRL_5, SW_OUT_RATE_LIMIT_QUEUE_BASED, true); |
| 1384 | |
| 1385 | /* enable global MIB counter freeze function */ |
| 1386 | ksz_cfg(dev, REG_SW_MAC_CTRL_6, SW_MIB_COUNTER_FREEZE, true); |
| 1387 | |
| 1388 | /* start switch */ |
| 1389 | ksz_cfg(dev, REG_SW_OPERATION, SW_START, true); |
| 1390 | |
| 1391 | ksz_init_mib_timer(dev); |
| 1392 | |
| 1393 | return 0; |
| 1394 | } |
| 1395 | |
| 1396 | static const struct dsa_switch_ops ksz9477_switch_ops = { |
| 1397 | .get_tag_protocol = ksz9477_get_tag_protocol, |
| 1398 | .setup = ksz9477_setup, |
| 1399 | .phy_read = ksz9477_phy_read16, |
| 1400 | .phy_write = ksz9477_phy_write16, |
| 1401 | .adjust_link = ksz_adjust_link, |
| 1402 | .port_enable = ksz_enable_port, |
| 1403 | .port_disable = ksz_disable_port, |
| 1404 | .get_strings = ksz9477_get_strings, |
| 1405 | .get_ethtool_stats = ksz_get_ethtool_stats, |
| 1406 | .get_sset_count = ksz_sset_count, |
| 1407 | .port_bridge_join = ksz_port_bridge_join, |
| 1408 | .port_bridge_leave = ksz_port_bridge_leave, |
| 1409 | .port_stp_state_set = ksz9477_port_stp_state_set, |
| 1410 | .port_fast_age = ksz_port_fast_age, |
| 1411 | .port_vlan_filtering = ksz9477_port_vlan_filtering, |
| 1412 | .port_vlan_prepare = ksz_port_vlan_prepare, |
| 1413 | .port_vlan_add = ksz9477_port_vlan_add, |
| 1414 | .port_vlan_del = ksz9477_port_vlan_del, |
| 1415 | .port_fdb_dump = ksz9477_port_fdb_dump, |
| 1416 | .port_fdb_add = ksz9477_port_fdb_add, |
| 1417 | .port_fdb_del = ksz9477_port_fdb_del, |
| 1418 | .port_mdb_prepare = ksz_port_mdb_prepare, |
| 1419 | .port_mdb_add = ksz9477_port_mdb_add, |
| 1420 | .port_mdb_del = ksz9477_port_mdb_del, |
| 1421 | .port_mirror_add = ksz9477_port_mirror_add, |
| 1422 | .port_mirror_del = ksz9477_port_mirror_del, |
| 1423 | }; |
| 1424 | |
| 1425 | static u32 ksz9477_get_port_addr(int port, int offset) |
| 1426 | { |
| 1427 | return PORT_CTRL_ADDR(port, offset); |
| 1428 | } |
| 1429 | |
| 1430 | static int ksz9477_switch_detect(struct ksz_device *dev) |
| 1431 | { |
| 1432 | u8 data8; |
| 1433 | u8 id_hi; |
| 1434 | u8 id_lo; |
| 1435 | u32 id32; |
| 1436 | int ret; |
| 1437 | |
| 1438 | /* turn off SPI DO Edge select */ |
| 1439 | ret = ksz_read8(dev, REG_SW_GLOBAL_SERIAL_CTRL_0, &data8); |
| 1440 | if (ret) |
| 1441 | return ret; |
| 1442 | |
| 1443 | data8 &= ~SPI_AUTO_EDGE_DETECTION; |
| 1444 | ret = ksz_write8(dev, REG_SW_GLOBAL_SERIAL_CTRL_0, data8); |
| 1445 | if (ret) |
| 1446 | return ret; |
| 1447 | |
| 1448 | /* read chip id */ |
| 1449 | ret = ksz_read32(dev, REG_CHIP_ID0__1, &id32); |
| 1450 | if (ret) |
| 1451 | return ret; |
| 1452 | ret = ksz_read8(dev, REG_GLOBAL_OPTIONS, &data8); |
| 1453 | if (ret) |
| 1454 | return ret; |
| 1455 | |
| 1456 | /* Number of ports can be reduced depending on chip. */ |
| 1457 | dev->mib_port_cnt = TOTAL_PORT_NUM; |
| 1458 | dev->phy_port_cnt = 5; |
| 1459 | |
| 1460 | /* Default capability is gigabit capable. */ |
| 1461 | dev->features = GBIT_SUPPORT; |
| 1462 | |
| 1463 | id_hi = (u8)(id32 >> 16); |
| 1464 | id_lo = (u8)(id32 >> 8); |
| 1465 | if ((id_lo & 0xf) == 3) { |
| 1466 | /* Chip is from KSZ9893 design. */ |
| 1467 | dev->features |= IS_9893; |
| 1468 | |
| 1469 | /* Chip does not support gigabit. */ |
| 1470 | if (data8 & SW_QW_ABLE) |
| 1471 | dev->features &= ~GBIT_SUPPORT; |
| 1472 | dev->mib_port_cnt = 3; |
| 1473 | dev->phy_port_cnt = 2; |
| 1474 | } else { |
| 1475 | /* Chip uses new XMII register definitions. */ |
| 1476 | dev->features |= NEW_XMII; |
| 1477 | |
| 1478 | /* Chip does not support gigabit. */ |
| 1479 | if (!(data8 & SW_GIGABIT_ABLE)) |
| 1480 | dev->features &= ~GBIT_SUPPORT; |
| 1481 | } |
| 1482 | |
| 1483 | /* Change chip id to known ones so it can be matched against them. */ |
| 1484 | id32 = (id_hi << 16) | (id_lo << 8); |
| 1485 | |
| 1486 | dev->chip_id = id32; |
| 1487 | |
| 1488 | return 0; |
| 1489 | } |
| 1490 | |
| 1491 | struct ksz_chip_data { |
| 1492 | u32 chip_id; |
| 1493 | const char *dev_name; |
| 1494 | int num_vlans; |
| 1495 | int num_alus; |
| 1496 | int num_statics; |
| 1497 | int cpu_ports; |
| 1498 | int port_cnt; |
| 1499 | bool phy_errata_9477; |
| 1500 | }; |
| 1501 | |
| 1502 | static const struct ksz_chip_data ksz9477_switch_chips[] = { |
| 1503 | { |
| 1504 | .chip_id = 0x00947700, |
| 1505 | .dev_name = "KSZ9477", |
| 1506 | .num_vlans = 4096, |
| 1507 | .num_alus = 4096, |
| 1508 | .num_statics = 16, |
| 1509 | .cpu_ports = 0x7F, /* can be configured as cpu port */ |
| 1510 | .port_cnt = 7, /* total physical port count */ |
| 1511 | .phy_errata_9477 = true, |
| 1512 | }, |
| 1513 | { |
| 1514 | .chip_id = 0x00989700, |
| 1515 | .dev_name = "KSZ9897", |
| 1516 | .num_vlans = 4096, |
| 1517 | .num_alus = 4096, |
| 1518 | .num_statics = 16, |
| 1519 | .cpu_ports = 0x7F, /* can be configured as cpu port */ |
| 1520 | .port_cnt = 7, /* total physical port count */ |
| 1521 | .phy_errata_9477 = true, |
| 1522 | }, |
| 1523 | { |
| 1524 | .chip_id = 0x00989300, |
| 1525 | .dev_name = "KSZ9893", |
| 1526 | .num_vlans = 4096, |
| 1527 | .num_alus = 4096, |
| 1528 | .num_statics = 16, |
| 1529 | .cpu_ports = 0x07, /* can be configured as cpu port */ |
| 1530 | .port_cnt = 3, /* total port count */ |
| 1531 | }, |
| 1532 | { |
| 1533 | .chip_id = 0x00956700, |
| 1534 | .dev_name = "KSZ9567", |
| 1535 | .num_vlans = 4096, |
| 1536 | .num_alus = 4096, |
| 1537 | .num_statics = 16, |
| 1538 | .cpu_ports = 0x7F, /* can be configured as cpu port */ |
| 1539 | .port_cnt = 7, /* total physical port count */ |
| 1540 | }, |
| 1541 | }; |
| 1542 | |
| 1543 | static int ksz9477_switch_init(struct ksz_device *dev) |
| 1544 | { |
| 1545 | int i; |
| 1546 | |
| 1547 | dev->ds->ops = &ksz9477_switch_ops; |
| 1548 | |
| 1549 | for (i = 0; i < ARRAY_SIZE(ksz9477_switch_chips); i++) { |
| 1550 | const struct ksz_chip_data *chip = &ksz9477_switch_chips[i]; |
| 1551 | |
| 1552 | if (dev->chip_id == chip->chip_id) { |
| 1553 | dev->name = chip->dev_name; |
| 1554 | dev->num_vlans = chip->num_vlans; |
| 1555 | dev->num_alus = chip->num_alus; |
| 1556 | dev->num_statics = chip->num_statics; |
| 1557 | dev->port_cnt = chip->port_cnt; |
| 1558 | dev->cpu_ports = chip->cpu_ports; |
| 1559 | dev->phy_errata_9477 = chip->phy_errata_9477; |
| 1560 | |
| 1561 | break; |
| 1562 | } |
| 1563 | } |
| 1564 | |
| 1565 | /* no switch found */ |
| 1566 | if (!dev->port_cnt) |
| 1567 | return -ENODEV; |
| 1568 | |
| 1569 | dev->port_mask = (1 << dev->port_cnt) - 1; |
| 1570 | |
| 1571 | dev->reg_mib_cnt = SWITCH_COUNTER_NUM; |
| 1572 | dev->mib_cnt = TOTAL_SWITCH_COUNTER_NUM; |
| 1573 | |
| 1574 | i = dev->mib_port_cnt; |
| 1575 | dev->ports = devm_kzalloc(dev->dev, sizeof(struct ksz_port) * i, |
| 1576 | GFP_KERNEL); |
| 1577 | if (!dev->ports) |
| 1578 | return -ENOMEM; |
| 1579 | for (i = 0; i < dev->mib_port_cnt; i++) { |
| 1580 | mutex_init(&dev->ports[i].mib.cnt_mutex); |
| 1581 | dev->ports[i].mib.counters = |
| 1582 | devm_kzalloc(dev->dev, |
| 1583 | sizeof(u64) * |
| 1584 | (TOTAL_SWITCH_COUNTER_NUM + 1), |
| 1585 | GFP_KERNEL); |
| 1586 | if (!dev->ports[i].mib.counters) |
| 1587 | return -ENOMEM; |
| 1588 | } |
| 1589 | |
| 1590 | return 0; |
| 1591 | } |
| 1592 | |
| 1593 | static void ksz9477_switch_exit(struct ksz_device *dev) |
| 1594 | { |
| 1595 | ksz9477_reset_switch(dev); |
| 1596 | } |
| 1597 | |
| 1598 | static const struct ksz_dev_ops ksz9477_dev_ops = { |
| 1599 | .get_port_addr = ksz9477_get_port_addr, |
| 1600 | .cfg_port_member = ksz9477_cfg_port_member, |
| 1601 | .flush_dyn_mac_table = ksz9477_flush_dyn_mac_table, |
| 1602 | .phy_setup = ksz9477_phy_setup, |
| 1603 | .port_setup = ksz9477_port_setup, |
| 1604 | .r_mib_cnt = ksz9477_r_mib_cnt, |
| 1605 | .r_mib_pkt = ksz9477_r_mib_pkt, |
| 1606 | .freeze_mib = ksz9477_freeze_mib, |
| 1607 | .port_init_cnt = ksz9477_port_init_cnt, |
| 1608 | .shutdown = ksz9477_reset_switch, |
| 1609 | .detect = ksz9477_switch_detect, |
| 1610 | .init = ksz9477_switch_init, |
| 1611 | .exit = ksz9477_switch_exit, |
| 1612 | }; |
| 1613 | |
| 1614 | int ksz9477_switch_register(struct ksz_device *dev) |
| 1615 | { |
| 1616 | return ksz_switch_register(dev, &ksz9477_dev_ops); |
| 1617 | } |
| 1618 | EXPORT_SYMBOL(ksz9477_switch_register); |
| 1619 | |
| 1620 | MODULE_AUTHOR("Woojung Huh <Woojung.Huh@microchip.com>"); |
| 1621 | MODULE_DESCRIPTION("Microchip KSZ9477 Series Switch DSA Driver"); |
| 1622 | MODULE_LICENSE("GPL"); |