1 /* 2 * Broadcom Starfighter 2 DSA switch driver 3 * 4 * Copyright (C) 2014, Broadcom Corporation 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 */ 11 12 #include <linux/list.h> 13 #include <linux/module.h> 14 #include <linux/netdevice.h> 15 #include <linux/interrupt.h> 16 #include <linux/platform_device.h> 17 #include <linux/of.h> 18 #include <linux/phy.h> 19 #include <linux/phy_fixed.h> 20 #include <linux/mii.h> 21 #include <linux/of.h> 22 #include <linux/of_irq.h> 23 #include <linux/of_address.h> 24 #include <net/dsa.h> 25 #include <linux/ethtool.h> 26 27 #include "bcm_sf2.h" 28 #include "bcm_sf2_regs.h" 29 30 /* String, offset, and register size in bytes if different from 4 bytes */ 31 static const struct bcm_sf2_hw_stats bcm_sf2_mib[] = { 32 { "TxOctets", 0x000, 8 }, 33 { "TxDropPkts", 0x020 }, 34 { "TxQPKTQ0", 0x030 }, 35 { "TxBroadcastPkts", 0x040 }, 36 { "TxMulticastPkts", 0x050 }, 37 { "TxUnicastPKts", 0x060 }, 38 { "TxCollisions", 0x070 }, 39 { "TxSingleCollision", 0x080 }, 40 { "TxMultipleCollision", 0x090 }, 41 { "TxDeferredCollision", 0x0a0 }, 42 { "TxLateCollision", 0x0b0 }, 43 { "TxExcessiveCollision", 0x0c0 }, 44 { "TxFrameInDisc", 0x0d0 }, 45 { "TxPausePkts", 0x0e0 }, 46 { "TxQPKTQ1", 0x0f0 }, 47 { "TxQPKTQ2", 0x100 }, 48 { "TxQPKTQ3", 0x110 }, 49 { "TxQPKTQ4", 0x120 }, 50 { "TxQPKTQ5", 0x130 }, 51 { "RxOctets", 0x140, 8 }, 52 { "RxUndersizePkts", 0x160 }, 53 { "RxPausePkts", 0x170 }, 54 { "RxPkts64Octets", 0x180 }, 55 { "RxPkts65to127Octets", 0x190 }, 56 { "RxPkts128to255Octets", 0x1a0 }, 57 { "RxPkts256to511Octets", 0x1b0 }, 58 { "RxPkts512to1023Octets", 0x1c0 }, 59 { "RxPkts1024toMaxPktsOctets", 0x1d0 }, 60 { "RxOversizePkts", 0x1e0 }, 61 { "RxJabbers", 0x1f0 }, 62 { "RxAlignmentErrors", 0x200 }, 63 { "RxFCSErrors", 0x210 }, 64 { "RxGoodOctets", 0x220, 8 }, 65 { "RxDropPkts", 0x240 }, 66 { "RxUnicastPkts", 0x250 }, 67 { "RxMulticastPkts", 0x260 }, 68 { "RxBroadcastPkts", 0x270 }, 69 { "RxSAChanges", 0x280 }, 70 { "RxFragments", 0x290 }, 71 { "RxJumboPkt", 0x2a0 }, 72 { "RxSymblErr", 0x2b0 }, 73 { "InRangeErrCount", 0x2c0 }, 74 { "OutRangeErrCount", 0x2d0 }, 75 { "EEELpiEvent", 0x2e0 }, 76 { "EEELpiDuration", 0x2f0 }, 77 { "RxDiscard", 0x300, 8 }, 78 { "TxQPKTQ6", 0x320 }, 79 { "TxQPKTQ7", 0x330 }, 80 { "TxPkts64Octets", 0x340 }, 81 { "TxPkts65to127Octets", 0x350 }, 82 { "TxPkts128to255Octets", 0x360 }, 83 { "TxPkts256to511Ocets", 0x370 }, 84 { "TxPkts512to1023Ocets", 0x380 }, 85 { "TxPkts1024toMaxPktOcets", 0x390 }, 86 }; 87 88 #define BCM_SF2_STATS_SIZE ARRAY_SIZE(bcm_sf2_mib) 89 90 static void bcm_sf2_sw_get_strings(struct dsa_switch *ds, 91 int port, uint8_t *data) 92 { 93 unsigned int i; 94 95 for (i = 0; i < BCM_SF2_STATS_SIZE; i++) 96 memcpy(data + i * ETH_GSTRING_LEN, 97 bcm_sf2_mib[i].string, ETH_GSTRING_LEN); 98 } 99 100 static void bcm_sf2_sw_get_ethtool_stats(struct dsa_switch *ds, 101 int port, uint64_t *data) 102 { 103 struct bcm_sf2_priv *priv = ds_to_priv(ds); 104 const struct bcm_sf2_hw_stats *s; 105 unsigned int i; 106 u64 val = 0; 107 u32 offset; 108 109 mutex_lock(&priv->stats_mutex); 110 111 /* Now fetch the per-port counters */ 112 for (i = 0; i < BCM_SF2_STATS_SIZE; i++) { 113 s = &bcm_sf2_mib[i]; 114 115 /* Do a latched 64-bit read if needed */ 116 offset = s->reg + CORE_P_MIB_OFFSET(port); 117 if (s->sizeof_stat == 8) 118 val = core_readq(priv, offset); 119 else 120 val = core_readl(priv, offset); 121 122 data[i] = (u64)val; 123 } 124 125 mutex_unlock(&priv->stats_mutex); 126 } 127 128 static int bcm_sf2_sw_get_sset_count(struct dsa_switch *ds) 129 { 130 return BCM_SF2_STATS_SIZE; 131 } 132 133 static char *bcm_sf2_sw_probe(struct device *host_dev, int sw_addr) 134 { 135 return "Broadcom Starfighter 2"; 136 } 137 138 static void bcm_sf2_imp_vlan_setup(struct dsa_switch *ds, int cpu_port) 139 { 140 struct bcm_sf2_priv *priv = ds_to_priv(ds); 141 unsigned int i; 142 u32 reg; 143 144 /* Enable the IMP Port to be in the same VLAN as the other ports 145 * on a per-port basis such that we only have Port i and IMP in 146 * the same VLAN. 147 */ 148 for (i = 0; i < priv->hw_params.num_ports; i++) { 149 if (!((1 << i) & ds->phys_port_mask)) 150 continue; 151 152 reg = core_readl(priv, CORE_PORT_VLAN_CTL_PORT(i)); 153 reg |= (1 << cpu_port); 154 core_writel(priv, reg, CORE_PORT_VLAN_CTL_PORT(i)); 155 } 156 } 157 158 static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port) 159 { 160 struct bcm_sf2_priv *priv = ds_to_priv(ds); 161 u32 reg, val; 162 163 /* Enable the port memories */ 164 reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL); 165 reg &= ~P_TXQ_PSM_VDD(port); 166 core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL); 167 168 /* Enable Broadcast, Multicast, Unicast forwarding to IMP port */ 169 reg = core_readl(priv, CORE_IMP_CTL); 170 reg |= (RX_BCST_EN | RX_MCST_EN | RX_UCST_EN); 171 reg &= ~(RX_DIS | TX_DIS); 172 core_writel(priv, reg, CORE_IMP_CTL); 173 174 /* Enable forwarding */ 175 core_writel(priv, SW_FWDG_EN, CORE_SWMODE); 176 177 /* Enable IMP port in dumb mode */ 178 reg = core_readl(priv, CORE_SWITCH_CTRL); 179 reg |= MII_DUMB_FWDG_EN; 180 core_writel(priv, reg, CORE_SWITCH_CTRL); 181 182 /* Resolve which bit controls the Broadcom tag */ 183 switch (port) { 184 case 8: 185 val = BRCM_HDR_EN_P8; 186 break; 187 case 7: 188 val = BRCM_HDR_EN_P7; 189 break; 190 case 5: 191 val = BRCM_HDR_EN_P5; 192 break; 193 default: 194 val = 0; 195 break; 196 } 197 198 /* Enable Broadcom tags for IMP port */ 199 reg = core_readl(priv, CORE_BRCM_HDR_CTRL); 200 reg |= val; 201 core_writel(priv, reg, CORE_BRCM_HDR_CTRL); 202 203 /* Enable reception Broadcom tag for CPU TX (switch RX) to 204 * allow us to tag outgoing frames 205 */ 206 reg = core_readl(priv, CORE_BRCM_HDR_RX_DIS); 207 reg &= ~(1 << port); 208 core_writel(priv, reg, CORE_BRCM_HDR_RX_DIS); 209 210 /* Enable transmission of Broadcom tags from the switch (CPU RX) to 211 * allow delivering frames to the per-port net_devices 212 */ 213 reg = core_readl(priv, CORE_BRCM_HDR_TX_DIS); 214 reg &= ~(1 << port); 215 core_writel(priv, reg, CORE_BRCM_HDR_TX_DIS); 216 217 /* Force link status for IMP port */ 218 reg = core_readl(priv, CORE_STS_OVERRIDE_IMP); 219 reg |= (MII_SW_OR | LINK_STS); 220 core_writel(priv, reg, CORE_STS_OVERRIDE_IMP); 221 } 222 223 static void bcm_sf2_eee_enable_set(struct dsa_switch *ds, int port, bool enable) 224 { 225 struct bcm_sf2_priv *priv = ds_to_priv(ds); 226 u32 reg; 227 228 reg = core_readl(priv, CORE_EEE_EN_CTRL); 229 if (enable) 230 reg |= 1 << port; 231 else 232 reg &= ~(1 << port); 233 core_writel(priv, reg, CORE_EEE_EN_CTRL); 234 } 235 236 static void bcm_sf2_gphy_enable_set(struct dsa_switch *ds, bool enable) 237 { 238 struct bcm_sf2_priv *priv = ds_to_priv(ds); 239 u32 reg; 240 241 reg = reg_readl(priv, REG_SPHY_CNTRL); 242 if (enable) { 243 reg |= PHY_RESET; 244 reg &= ~(EXT_PWR_DOWN | IDDQ_BIAS | CK25_DIS); 245 reg_writel(priv, reg, REG_SPHY_CNTRL); 246 udelay(21); 247 reg = reg_readl(priv, REG_SPHY_CNTRL); 248 reg &= ~PHY_RESET; 249 } else { 250 reg |= EXT_PWR_DOWN | IDDQ_BIAS | PHY_RESET; 251 reg_writel(priv, reg, REG_SPHY_CNTRL); 252 mdelay(1); 253 reg |= CK25_DIS; 254 } 255 reg_writel(priv, reg, REG_SPHY_CNTRL); 256 257 /* Use PHY-driven LED signaling */ 258 if (!enable) { 259 reg = reg_readl(priv, REG_LED_CNTRL(0)); 260 reg |= SPDLNK_SRC_SEL; 261 reg_writel(priv, reg, REG_LED_CNTRL(0)); 262 } 263 } 264 265 static int bcm_sf2_port_setup(struct dsa_switch *ds, int port, 266 struct phy_device *phy) 267 { 268 struct bcm_sf2_priv *priv = ds_to_priv(ds); 269 s8 cpu_port = ds->dst[ds->index].cpu_port; 270 u32 reg; 271 272 /* Clear the memory power down */ 273 reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL); 274 reg &= ~P_TXQ_PSM_VDD(port); 275 core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL); 276 277 /* Clear the Rx and Tx disable bits and set to no spanning tree */ 278 core_writel(priv, 0, CORE_G_PCTL_PORT(port)); 279 280 /* Re-enable the GPHY and re-apply workarounds */ 281 if (port == 0 && priv->hw_params.num_gphy == 1) { 282 bcm_sf2_gphy_enable_set(ds, true); 283 if (phy) { 284 /* if phy_stop() has been called before, phy 285 * will be in halted state, and phy_start() 286 * will call resume. 287 * 288 * the resume path does not configure back 289 * autoneg settings, and since we hard reset 290 * the phy manually here, we need to reset the 291 * state machine also. 292 */ 293 phy->state = PHY_READY; 294 phy_init_hw(phy); 295 } 296 } 297 298 /* Enable port 7 interrupts to get notified */ 299 if (port == 7) 300 intrl2_1_mask_clear(priv, P_IRQ_MASK(P7_IRQ_OFF)); 301 302 /* Set this port, and only this one to be in the default VLAN */ 303 reg = core_readl(priv, CORE_PORT_VLAN_CTL_PORT(port)); 304 reg &= ~PORT_VLAN_CTRL_MASK; 305 reg |= (1 << port); 306 core_writel(priv, reg, CORE_PORT_VLAN_CTL_PORT(port)); 307 308 bcm_sf2_imp_vlan_setup(ds, cpu_port); 309 310 /* If EEE was enabled, restore it */ 311 if (priv->port_sts[port].eee.eee_enabled) 312 bcm_sf2_eee_enable_set(ds, port, true); 313 314 return 0; 315 } 316 317 static void bcm_sf2_port_disable(struct dsa_switch *ds, int port, 318 struct phy_device *phy) 319 { 320 struct bcm_sf2_priv *priv = ds_to_priv(ds); 321 u32 off, reg; 322 323 if (priv->wol_ports_mask & (1 << port)) 324 return; 325 326 if (port == 7) { 327 intrl2_1_mask_set(priv, P_IRQ_MASK(P7_IRQ_OFF)); 328 intrl2_1_writel(priv, P_IRQ_MASK(P7_IRQ_OFF), INTRL2_CPU_CLEAR); 329 } 330 331 if (port == 0 && priv->hw_params.num_gphy == 1) 332 bcm_sf2_gphy_enable_set(ds, false); 333 334 if (dsa_is_cpu_port(ds, port)) 335 off = CORE_IMP_CTL; 336 else 337 off = CORE_G_PCTL_PORT(port); 338 339 reg = core_readl(priv, off); 340 reg |= RX_DIS | TX_DIS; 341 core_writel(priv, reg, off); 342 343 /* Power down the port memory */ 344 reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL); 345 reg |= P_TXQ_PSM_VDD(port); 346 core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL); 347 } 348 349 /* Returns 0 if EEE was not enabled, or 1 otherwise 350 */ 351 static int bcm_sf2_eee_init(struct dsa_switch *ds, int port, 352 struct phy_device *phy) 353 { 354 struct bcm_sf2_priv *priv = ds_to_priv(ds); 355 struct ethtool_eee *p = &priv->port_sts[port].eee; 356 int ret; 357 358 p->supported = (SUPPORTED_1000baseT_Full | SUPPORTED_100baseT_Full); 359 360 ret = phy_init_eee(phy, 0); 361 if (ret) 362 return 0; 363 364 bcm_sf2_eee_enable_set(ds, port, true); 365 366 return 1; 367 } 368 369 static int bcm_sf2_sw_get_eee(struct dsa_switch *ds, int port, 370 struct ethtool_eee *e) 371 { 372 struct bcm_sf2_priv *priv = ds_to_priv(ds); 373 struct ethtool_eee *p = &priv->port_sts[port].eee; 374 u32 reg; 375 376 reg = core_readl(priv, CORE_EEE_LPI_INDICATE); 377 e->eee_enabled = p->eee_enabled; 378 e->eee_active = !!(reg & (1 << port)); 379 380 return 0; 381 } 382 383 static int bcm_sf2_sw_set_eee(struct dsa_switch *ds, int port, 384 struct phy_device *phydev, 385 struct ethtool_eee *e) 386 { 387 struct bcm_sf2_priv *priv = ds_to_priv(ds); 388 struct ethtool_eee *p = &priv->port_sts[port].eee; 389 390 p->eee_enabled = e->eee_enabled; 391 392 if (!p->eee_enabled) { 393 bcm_sf2_eee_enable_set(ds, port, false); 394 } else { 395 p->eee_enabled = bcm_sf2_eee_init(ds, port, phydev); 396 if (!p->eee_enabled) 397 return -EOPNOTSUPP; 398 } 399 400 return 0; 401 } 402 403 static irqreturn_t bcm_sf2_switch_0_isr(int irq, void *dev_id) 404 { 405 struct bcm_sf2_priv *priv = dev_id; 406 407 priv->irq0_stat = intrl2_0_readl(priv, INTRL2_CPU_STATUS) & 408 ~priv->irq0_mask; 409 intrl2_0_writel(priv, priv->irq0_stat, INTRL2_CPU_CLEAR); 410 411 return IRQ_HANDLED; 412 } 413 414 static irqreturn_t bcm_sf2_switch_1_isr(int irq, void *dev_id) 415 { 416 struct bcm_sf2_priv *priv = dev_id; 417 418 priv->irq1_stat = intrl2_1_readl(priv, INTRL2_CPU_STATUS) & 419 ~priv->irq1_mask; 420 intrl2_1_writel(priv, priv->irq1_stat, INTRL2_CPU_CLEAR); 421 422 if (priv->irq1_stat & P_LINK_UP_IRQ(P7_IRQ_OFF)) 423 priv->port_sts[7].link = 1; 424 if (priv->irq1_stat & P_LINK_DOWN_IRQ(P7_IRQ_OFF)) 425 priv->port_sts[7].link = 0; 426 427 return IRQ_HANDLED; 428 } 429 430 static int bcm_sf2_sw_rst(struct bcm_sf2_priv *priv) 431 { 432 unsigned int timeout = 1000; 433 u32 reg; 434 435 reg = core_readl(priv, CORE_WATCHDOG_CTRL); 436 reg |= SOFTWARE_RESET | EN_CHIP_RST | EN_SW_RESET; 437 core_writel(priv, reg, CORE_WATCHDOG_CTRL); 438 439 do { 440 reg = core_readl(priv, CORE_WATCHDOG_CTRL); 441 if (!(reg & SOFTWARE_RESET)) 442 break; 443 444 usleep_range(1000, 2000); 445 } while (timeout-- > 0); 446 447 if (timeout == 0) 448 return -ETIMEDOUT; 449 450 return 0; 451 } 452 453 static void bcm_sf2_intr_disable(struct bcm_sf2_priv *priv) 454 { 455 intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_MASK_SET); 456 intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR); 457 intrl2_0_writel(priv, 0, INTRL2_CPU_MASK_CLEAR); 458 intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_MASK_SET); 459 intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR); 460 intrl2_1_writel(priv, 0, INTRL2_CPU_MASK_CLEAR); 461 } 462 463 static int bcm_sf2_sw_setup(struct dsa_switch *ds) 464 { 465 const char *reg_names[BCM_SF2_REGS_NUM] = BCM_SF2_REGS_NAME; 466 struct bcm_sf2_priv *priv = ds_to_priv(ds); 467 struct device_node *dn; 468 void __iomem **base; 469 unsigned int port; 470 unsigned int i; 471 u32 reg, rev; 472 int ret; 473 474 spin_lock_init(&priv->indir_lock); 475 mutex_init(&priv->stats_mutex); 476 477 /* All the interesting properties are at the parent device_node 478 * level 479 */ 480 dn = ds->pd->of_node->parent; 481 482 priv->irq0 = irq_of_parse_and_map(dn, 0); 483 priv->irq1 = irq_of_parse_and_map(dn, 1); 484 485 base = &priv->core; 486 for (i = 0; i < BCM_SF2_REGS_NUM; i++) { 487 *base = of_iomap(dn, i); 488 if (*base == NULL) { 489 pr_err("unable to find register: %s\n", reg_names[i]); 490 ret = -ENOMEM; 491 goto out_unmap; 492 } 493 base++; 494 } 495 496 ret = bcm_sf2_sw_rst(priv); 497 if (ret) { 498 pr_err("unable to software reset switch: %d\n", ret); 499 goto out_unmap; 500 } 501 502 /* Disable all interrupts and request them */ 503 bcm_sf2_intr_disable(priv); 504 505 ret = request_irq(priv->irq0, bcm_sf2_switch_0_isr, 0, 506 "switch_0", priv); 507 if (ret < 0) { 508 pr_err("failed to request switch_0 IRQ\n"); 509 goto out_unmap; 510 } 511 512 ret = request_irq(priv->irq1, bcm_sf2_switch_1_isr, 0, 513 "switch_1", priv); 514 if (ret < 0) { 515 pr_err("failed to request switch_1 IRQ\n"); 516 goto out_free_irq0; 517 } 518 519 /* Reset the MIB counters */ 520 reg = core_readl(priv, CORE_GMNCFGCFG); 521 reg |= RST_MIB_CNT; 522 core_writel(priv, reg, CORE_GMNCFGCFG); 523 reg &= ~RST_MIB_CNT; 524 core_writel(priv, reg, CORE_GMNCFGCFG); 525 526 /* Get the maximum number of ports for this switch */ 527 priv->hw_params.num_ports = core_readl(priv, CORE_IMP0_PRT_ID) + 1; 528 if (priv->hw_params.num_ports > DSA_MAX_PORTS) 529 priv->hw_params.num_ports = DSA_MAX_PORTS; 530 531 /* Assume a single GPHY setup if we can't read that property */ 532 if (of_property_read_u32(dn, "brcm,num-gphy", 533 &priv->hw_params.num_gphy)) 534 priv->hw_params.num_gphy = 1; 535 536 /* Enable all valid ports and disable those unused */ 537 for (port = 0; port < priv->hw_params.num_ports; port++) { 538 /* IMP port receives special treatment */ 539 if ((1 << port) & ds->phys_port_mask) 540 bcm_sf2_port_setup(ds, port, NULL); 541 else if (dsa_is_cpu_port(ds, port)) 542 bcm_sf2_imp_setup(ds, port); 543 else 544 bcm_sf2_port_disable(ds, port, NULL); 545 } 546 547 /* Include the pseudo-PHY address and the broadcast PHY address to 548 * divert reads towards our workaround 549 */ 550 ds->phys_mii_mask |= ((1 << 30) | (1 << 0)); 551 552 rev = reg_readl(priv, REG_SWITCH_REVISION); 553 priv->hw_params.top_rev = (rev >> SWITCH_TOP_REV_SHIFT) & 554 SWITCH_TOP_REV_MASK; 555 priv->hw_params.core_rev = (rev & SF2_REV_MASK); 556 557 rev = reg_readl(priv, REG_PHY_REVISION); 558 priv->hw_params.gphy_rev = rev & PHY_REVISION_MASK; 559 560 pr_info("Starfighter 2 top: %x.%02x, core: %x.%02x base: 0x%p, IRQs: %d, %d\n", 561 priv->hw_params.top_rev >> 8, priv->hw_params.top_rev & 0xff, 562 priv->hw_params.core_rev >> 8, priv->hw_params.core_rev & 0xff, 563 priv->core, priv->irq0, priv->irq1); 564 565 return 0; 566 567 out_free_irq0: 568 free_irq(priv->irq0, priv); 569 out_unmap: 570 base = &priv->core; 571 for (i = 0; i < BCM_SF2_REGS_NUM; i++) { 572 if (*base) 573 iounmap(*base); 574 base++; 575 } 576 return ret; 577 } 578 579 static int bcm_sf2_sw_set_addr(struct dsa_switch *ds, u8 *addr) 580 { 581 return 0; 582 } 583 584 static u32 bcm_sf2_sw_get_phy_flags(struct dsa_switch *ds, int port) 585 { 586 struct bcm_sf2_priv *priv = ds_to_priv(ds); 587 588 /* The BCM7xxx PHY driver expects to find the integrated PHY revision 589 * in bits 15:8 and the patch level in bits 7:0 which is exactly what 590 * the REG_PHY_REVISION register layout is. 591 */ 592 593 return priv->hw_params.gphy_rev; 594 } 595 596 static int bcm_sf2_sw_indir_rw(struct dsa_switch *ds, int op, int addr, 597 int regnum, u16 val) 598 { 599 struct bcm_sf2_priv *priv = ds_to_priv(ds); 600 int ret = 0; 601 u32 reg; 602 603 reg = reg_readl(priv, REG_SWITCH_CNTRL); 604 reg |= MDIO_MASTER_SEL; 605 reg_writel(priv, reg, REG_SWITCH_CNTRL); 606 607 /* Page << 8 | offset */ 608 reg = 0x70; 609 reg <<= 2; 610 core_writel(priv, addr, reg); 611 612 /* Page << 8 | offset */ 613 reg = 0x80 << 8 | regnum << 1; 614 reg <<= 2; 615 616 if (op) 617 ret = core_readl(priv, reg); 618 else 619 core_writel(priv, val, reg); 620 621 reg = reg_readl(priv, REG_SWITCH_CNTRL); 622 reg &= ~MDIO_MASTER_SEL; 623 reg_writel(priv, reg, REG_SWITCH_CNTRL); 624 625 return ret & 0xffff; 626 } 627 628 static int bcm_sf2_sw_phy_read(struct dsa_switch *ds, int addr, int regnum) 629 { 630 /* Intercept reads from the MDIO broadcast address or Broadcom 631 * pseudo-PHY address 632 */ 633 switch (addr) { 634 case 0: 635 case 30: 636 return bcm_sf2_sw_indir_rw(ds, 1, addr, regnum, 0); 637 default: 638 return 0xffff; 639 } 640 } 641 642 static int bcm_sf2_sw_phy_write(struct dsa_switch *ds, int addr, int regnum, 643 u16 val) 644 { 645 /* Intercept writes to the MDIO broadcast address or Broadcom 646 * pseudo-PHY address 647 */ 648 switch (addr) { 649 case 0: 650 case 30: 651 bcm_sf2_sw_indir_rw(ds, 0, addr, regnum, val); 652 break; 653 } 654 655 return 0; 656 } 657 658 static void bcm_sf2_sw_adjust_link(struct dsa_switch *ds, int port, 659 struct phy_device *phydev) 660 { 661 struct bcm_sf2_priv *priv = ds_to_priv(ds); 662 u32 id_mode_dis = 0, port_mode; 663 const char *str = NULL; 664 u32 reg; 665 666 switch (phydev->interface) { 667 case PHY_INTERFACE_MODE_RGMII: 668 str = "RGMII (no delay)"; 669 id_mode_dis = 1; 670 case PHY_INTERFACE_MODE_RGMII_TXID: 671 if (!str) 672 str = "RGMII (TX delay)"; 673 port_mode = EXT_GPHY; 674 break; 675 case PHY_INTERFACE_MODE_MII: 676 str = "MII"; 677 port_mode = EXT_EPHY; 678 break; 679 case PHY_INTERFACE_MODE_REVMII: 680 str = "Reverse MII"; 681 port_mode = EXT_REVMII; 682 break; 683 default: 684 /* All other PHYs: internal and MoCA */ 685 goto force_link; 686 } 687 688 /* If the link is down, just disable the interface to conserve power */ 689 if (!phydev->link) { 690 reg = reg_readl(priv, REG_RGMII_CNTRL_P(port)); 691 reg &= ~RGMII_MODE_EN; 692 reg_writel(priv, reg, REG_RGMII_CNTRL_P(port)); 693 goto force_link; 694 } 695 696 /* Clear id_mode_dis bit, and the existing port mode, but 697 * make sure we enable the RGMII block for data to pass 698 */ 699 reg = reg_readl(priv, REG_RGMII_CNTRL_P(port)); 700 reg &= ~ID_MODE_DIS; 701 reg &= ~(PORT_MODE_MASK << PORT_MODE_SHIFT); 702 reg &= ~(RX_PAUSE_EN | TX_PAUSE_EN); 703 704 reg |= port_mode | RGMII_MODE_EN; 705 if (id_mode_dis) 706 reg |= ID_MODE_DIS; 707 708 if (phydev->pause) { 709 if (phydev->asym_pause) 710 reg |= TX_PAUSE_EN; 711 reg |= RX_PAUSE_EN; 712 } 713 714 reg_writel(priv, reg, REG_RGMII_CNTRL_P(port)); 715 716 pr_info("Port %d configured for %s\n", port, str); 717 718 force_link: 719 /* Force link settings detected from the PHY */ 720 reg = SW_OVERRIDE; 721 switch (phydev->speed) { 722 case SPEED_1000: 723 reg |= SPDSTS_1000 << SPEED_SHIFT; 724 break; 725 case SPEED_100: 726 reg |= SPDSTS_100 << SPEED_SHIFT; 727 break; 728 } 729 730 if (phydev->link) 731 reg |= LINK_STS; 732 if (phydev->duplex == DUPLEX_FULL) 733 reg |= DUPLX_MODE; 734 735 core_writel(priv, reg, CORE_STS_OVERRIDE_GMIIP_PORT(port)); 736 } 737 738 static void bcm_sf2_sw_fixed_link_update(struct dsa_switch *ds, int port, 739 struct fixed_phy_status *status) 740 { 741 struct bcm_sf2_priv *priv = ds_to_priv(ds); 742 u32 duplex, pause, speed; 743 u32 reg; 744 745 duplex = core_readl(priv, CORE_DUPSTS); 746 pause = core_readl(priv, CORE_PAUSESTS); 747 speed = core_readl(priv, CORE_SPDSTS); 748 749 speed >>= (port * SPDSTS_SHIFT); 750 speed &= SPDSTS_MASK; 751 752 status->link = 0; 753 754 /* Port 7 is special as we do not get link status from CORE_LNKSTS, 755 * which means that we need to force the link at the port override 756 * level to get the data to flow. We do use what the interrupt handler 757 * did determine before. 758 * 759 * For the other ports, we just force the link status, since this is 760 * a fixed PHY device. 761 */ 762 if (port == 7) { 763 status->link = priv->port_sts[port].link; 764 status->duplex = 1; 765 } else { 766 status->link = 1; 767 status->duplex = !!(duplex & (1 << port)); 768 } 769 770 reg = core_readl(priv, CORE_STS_OVERRIDE_GMIIP_PORT(port)); 771 reg |= SW_OVERRIDE; 772 if (status->link) 773 reg |= LINK_STS; 774 else 775 reg &= ~LINK_STS; 776 core_writel(priv, reg, CORE_STS_OVERRIDE_GMIIP_PORT(port)); 777 778 switch (speed) { 779 case SPDSTS_10: 780 status->speed = SPEED_10; 781 break; 782 case SPDSTS_100: 783 status->speed = SPEED_100; 784 break; 785 case SPDSTS_1000: 786 status->speed = SPEED_1000; 787 break; 788 } 789 790 if ((pause & (1 << port)) && 791 (pause & (1 << (port + PAUSESTS_TX_PAUSE_SHIFT)))) { 792 status->asym_pause = 1; 793 status->pause = 1; 794 } 795 796 if (pause & (1 << port)) 797 status->pause = 1; 798 } 799 800 static int bcm_sf2_sw_suspend(struct dsa_switch *ds) 801 { 802 struct bcm_sf2_priv *priv = ds_to_priv(ds); 803 unsigned int port; 804 805 bcm_sf2_intr_disable(priv); 806 807 /* Disable all ports physically present including the IMP 808 * port, the other ones have already been disabled during 809 * bcm_sf2_sw_setup 810 */ 811 for (port = 0; port < DSA_MAX_PORTS; port++) { 812 if ((1 << port) & ds->phys_port_mask || 813 dsa_is_cpu_port(ds, port)) 814 bcm_sf2_port_disable(ds, port, NULL); 815 } 816 817 return 0; 818 } 819 820 static int bcm_sf2_sw_resume(struct dsa_switch *ds) 821 { 822 struct bcm_sf2_priv *priv = ds_to_priv(ds); 823 unsigned int port; 824 int ret; 825 826 ret = bcm_sf2_sw_rst(priv); 827 if (ret) { 828 pr_err("%s: failed to software reset switch\n", __func__); 829 return ret; 830 } 831 832 if (priv->hw_params.num_gphy == 1) 833 bcm_sf2_gphy_enable_set(ds, true); 834 835 for (port = 0; port < DSA_MAX_PORTS; port++) { 836 if ((1 << port) & ds->phys_port_mask) 837 bcm_sf2_port_setup(ds, port, NULL); 838 else if (dsa_is_cpu_port(ds, port)) 839 bcm_sf2_imp_setup(ds, port); 840 } 841 842 return 0; 843 } 844 845 static void bcm_sf2_sw_get_wol(struct dsa_switch *ds, int port, 846 struct ethtool_wolinfo *wol) 847 { 848 struct net_device *p = ds->dst[ds->index].master_netdev; 849 struct bcm_sf2_priv *priv = ds_to_priv(ds); 850 struct ethtool_wolinfo pwol; 851 852 /* Get the parent device WoL settings */ 853 p->ethtool_ops->get_wol(p, &pwol); 854 855 /* Advertise the parent device supported settings */ 856 wol->supported = pwol.supported; 857 memset(&wol->sopass, 0, sizeof(wol->sopass)); 858 859 if (pwol.wolopts & WAKE_MAGICSECURE) 860 memcpy(&wol->sopass, pwol.sopass, sizeof(wol->sopass)); 861 862 if (priv->wol_ports_mask & (1 << port)) 863 wol->wolopts = pwol.wolopts; 864 else 865 wol->wolopts = 0; 866 } 867 868 static int bcm_sf2_sw_set_wol(struct dsa_switch *ds, int port, 869 struct ethtool_wolinfo *wol) 870 { 871 struct net_device *p = ds->dst[ds->index].master_netdev; 872 struct bcm_sf2_priv *priv = ds_to_priv(ds); 873 s8 cpu_port = ds->dst[ds->index].cpu_port; 874 struct ethtool_wolinfo pwol; 875 876 p->ethtool_ops->get_wol(p, &pwol); 877 if (wol->wolopts & ~pwol.supported) 878 return -EINVAL; 879 880 if (wol->wolopts) 881 priv->wol_ports_mask |= (1 << port); 882 else 883 priv->wol_ports_mask &= ~(1 << port); 884 885 /* If we have at least one port enabled, make sure the CPU port 886 * is also enabled. If the CPU port is the last one enabled, we disable 887 * it since this configuration does not make sense. 888 */ 889 if (priv->wol_ports_mask && priv->wol_ports_mask != (1 << cpu_port)) 890 priv->wol_ports_mask |= (1 << cpu_port); 891 else 892 priv->wol_ports_mask &= ~(1 << cpu_port); 893 894 return p->ethtool_ops->set_wol(p, wol); 895 } 896 897 static struct dsa_switch_driver bcm_sf2_switch_driver = { 898 .tag_protocol = DSA_TAG_PROTO_BRCM, 899 .priv_size = sizeof(struct bcm_sf2_priv), 900 .probe = bcm_sf2_sw_probe, 901 .setup = bcm_sf2_sw_setup, 902 .set_addr = bcm_sf2_sw_set_addr, 903 .get_phy_flags = bcm_sf2_sw_get_phy_flags, 904 .phy_read = bcm_sf2_sw_phy_read, 905 .phy_write = bcm_sf2_sw_phy_write, 906 .get_strings = bcm_sf2_sw_get_strings, 907 .get_ethtool_stats = bcm_sf2_sw_get_ethtool_stats, 908 .get_sset_count = bcm_sf2_sw_get_sset_count, 909 .adjust_link = bcm_sf2_sw_adjust_link, 910 .fixed_link_update = bcm_sf2_sw_fixed_link_update, 911 .suspend = bcm_sf2_sw_suspend, 912 .resume = bcm_sf2_sw_resume, 913 .get_wol = bcm_sf2_sw_get_wol, 914 .set_wol = bcm_sf2_sw_set_wol, 915 .port_enable = bcm_sf2_port_setup, 916 .port_disable = bcm_sf2_port_disable, 917 .get_eee = bcm_sf2_sw_get_eee, 918 .set_eee = bcm_sf2_sw_set_eee, 919 }; 920 921 static int __init bcm_sf2_init(void) 922 { 923 register_switch_driver(&bcm_sf2_switch_driver); 924 925 return 0; 926 } 927 module_init(bcm_sf2_init); 928 929 static void __exit bcm_sf2_exit(void) 930 { 931 unregister_switch_driver(&bcm_sf2_switch_driver); 932 } 933 module_exit(bcm_sf2_exit); 934 935 MODULE_AUTHOR("Broadcom Corporation"); 936 MODULE_DESCRIPTION("Driver for Broadcom Starfighter 2 ethernet switch chip"); 937 MODULE_LICENSE("GPL"); 938 MODULE_ALIAS("platform:brcm-sf2"); 939