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 int bcm_sf2_port_setup(struct dsa_switch *ds, int port, 237 struct phy_device *phy) 238 { 239 struct bcm_sf2_priv *priv = ds_to_priv(ds); 240 s8 cpu_port = ds->dst[ds->index].cpu_port; 241 u32 reg; 242 243 /* Clear the memory power down */ 244 reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL); 245 reg &= ~P_TXQ_PSM_VDD(port); 246 core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL); 247 248 /* Clear the Rx and Tx disable bits and set to no spanning tree */ 249 core_writel(priv, 0, CORE_G_PCTL_PORT(port)); 250 251 /* Enable port 7 interrupts to get notified */ 252 if (port == 7) 253 intrl2_1_mask_clear(priv, P_IRQ_MASK(P7_IRQ_OFF)); 254 255 /* Set this port, and only this one to be in the default VLAN */ 256 reg = core_readl(priv, CORE_PORT_VLAN_CTL_PORT(port)); 257 reg &= ~PORT_VLAN_CTRL_MASK; 258 reg |= (1 << port); 259 core_writel(priv, reg, CORE_PORT_VLAN_CTL_PORT(port)); 260 261 bcm_sf2_imp_vlan_setup(ds, cpu_port); 262 263 /* If EEE was enabled, restore it */ 264 if (priv->port_sts[port].eee.eee_enabled) 265 bcm_sf2_eee_enable_set(ds, port, true); 266 267 return 0; 268 } 269 270 static void bcm_sf2_port_disable(struct dsa_switch *ds, int port, 271 struct phy_device *phy) 272 { 273 struct bcm_sf2_priv *priv = ds_to_priv(ds); 274 u32 off, reg; 275 276 if (priv->wol_ports_mask & (1 << port)) 277 return; 278 279 if (port == 7) { 280 intrl2_1_mask_set(priv, P_IRQ_MASK(P7_IRQ_OFF)); 281 intrl2_1_writel(priv, P_IRQ_MASK(P7_IRQ_OFF), INTRL2_CPU_CLEAR); 282 } 283 284 if (dsa_is_cpu_port(ds, port)) 285 off = CORE_IMP_CTL; 286 else 287 off = CORE_G_PCTL_PORT(port); 288 289 reg = core_readl(priv, off); 290 reg |= RX_DIS | TX_DIS; 291 core_writel(priv, reg, off); 292 293 /* Power down the port memory */ 294 reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL); 295 reg |= P_TXQ_PSM_VDD(port); 296 core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL); 297 } 298 299 /* Returns 0 if EEE was not enabled, or 1 otherwise 300 */ 301 static int bcm_sf2_eee_init(struct dsa_switch *ds, int port, 302 struct phy_device *phy) 303 { 304 struct bcm_sf2_priv *priv = ds_to_priv(ds); 305 struct ethtool_eee *p = &priv->port_sts[port].eee; 306 int ret; 307 308 p->supported = (SUPPORTED_1000baseT_Full | SUPPORTED_100baseT_Full); 309 310 ret = phy_init_eee(phy, 0); 311 if (ret) 312 return 0; 313 314 bcm_sf2_eee_enable_set(ds, port, true); 315 316 return 1; 317 } 318 319 static int bcm_sf2_sw_get_eee(struct dsa_switch *ds, int port, 320 struct ethtool_eee *e) 321 { 322 struct bcm_sf2_priv *priv = ds_to_priv(ds); 323 struct ethtool_eee *p = &priv->port_sts[port].eee; 324 u32 reg; 325 326 reg = core_readl(priv, CORE_EEE_LPI_INDICATE); 327 e->eee_enabled = p->eee_enabled; 328 e->eee_active = !!(reg & (1 << port)); 329 330 return 0; 331 } 332 333 static int bcm_sf2_sw_set_eee(struct dsa_switch *ds, int port, 334 struct phy_device *phydev, 335 struct ethtool_eee *e) 336 { 337 struct bcm_sf2_priv *priv = ds_to_priv(ds); 338 struct ethtool_eee *p = &priv->port_sts[port].eee; 339 340 p->eee_enabled = e->eee_enabled; 341 342 if (!p->eee_enabled) { 343 bcm_sf2_eee_enable_set(ds, port, false); 344 } else { 345 p->eee_enabled = bcm_sf2_eee_init(ds, port, phydev); 346 if (!p->eee_enabled) 347 return -EOPNOTSUPP; 348 } 349 350 return 0; 351 } 352 353 static irqreturn_t bcm_sf2_switch_0_isr(int irq, void *dev_id) 354 { 355 struct bcm_sf2_priv *priv = dev_id; 356 357 priv->irq0_stat = intrl2_0_readl(priv, INTRL2_CPU_STATUS) & 358 ~priv->irq0_mask; 359 intrl2_0_writel(priv, priv->irq0_stat, INTRL2_CPU_CLEAR); 360 361 return IRQ_HANDLED; 362 } 363 364 static irqreturn_t bcm_sf2_switch_1_isr(int irq, void *dev_id) 365 { 366 struct bcm_sf2_priv *priv = dev_id; 367 368 priv->irq1_stat = intrl2_1_readl(priv, INTRL2_CPU_STATUS) & 369 ~priv->irq1_mask; 370 intrl2_1_writel(priv, priv->irq1_stat, INTRL2_CPU_CLEAR); 371 372 if (priv->irq1_stat & P_LINK_UP_IRQ(P7_IRQ_OFF)) 373 priv->port_sts[7].link = 1; 374 if (priv->irq1_stat & P_LINK_DOWN_IRQ(P7_IRQ_OFF)) 375 priv->port_sts[7].link = 0; 376 377 return IRQ_HANDLED; 378 } 379 380 static int bcm_sf2_sw_setup(struct dsa_switch *ds) 381 { 382 const char *reg_names[BCM_SF2_REGS_NUM] = BCM_SF2_REGS_NAME; 383 struct bcm_sf2_priv *priv = ds_to_priv(ds); 384 struct device_node *dn; 385 void __iomem **base; 386 unsigned int port; 387 unsigned int i; 388 u32 reg, rev; 389 int ret; 390 391 spin_lock_init(&priv->indir_lock); 392 mutex_init(&priv->stats_mutex); 393 394 /* All the interesting properties are at the parent device_node 395 * level 396 */ 397 dn = ds->pd->of_node->parent; 398 399 priv->irq0 = irq_of_parse_and_map(dn, 0); 400 priv->irq1 = irq_of_parse_and_map(dn, 1); 401 402 base = &priv->core; 403 for (i = 0; i < BCM_SF2_REGS_NUM; i++) { 404 *base = of_iomap(dn, i); 405 if (*base == NULL) { 406 pr_err("unable to find register: %s\n", reg_names[i]); 407 return -ENODEV; 408 } 409 base++; 410 } 411 412 /* Disable all interrupts and request them */ 413 intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_MASK_SET); 414 intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR); 415 intrl2_0_writel(priv, 0, INTRL2_CPU_MASK_CLEAR); 416 intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_MASK_SET); 417 intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR); 418 intrl2_1_writel(priv, 0, INTRL2_CPU_MASK_CLEAR); 419 420 ret = request_irq(priv->irq0, bcm_sf2_switch_0_isr, 0, 421 "switch_0", priv); 422 if (ret < 0) { 423 pr_err("failed to request switch_0 IRQ\n"); 424 goto out_unmap; 425 } 426 427 ret = request_irq(priv->irq1, bcm_sf2_switch_1_isr, 0, 428 "switch_1", priv); 429 if (ret < 0) { 430 pr_err("failed to request switch_1 IRQ\n"); 431 goto out_free_irq0; 432 } 433 434 /* Reset the MIB counters */ 435 reg = core_readl(priv, CORE_GMNCFGCFG); 436 reg |= RST_MIB_CNT; 437 core_writel(priv, reg, CORE_GMNCFGCFG); 438 reg &= ~RST_MIB_CNT; 439 core_writel(priv, reg, CORE_GMNCFGCFG); 440 441 /* Get the maximum number of ports for this switch */ 442 priv->hw_params.num_ports = core_readl(priv, CORE_IMP0_PRT_ID) + 1; 443 if (priv->hw_params.num_ports > DSA_MAX_PORTS) 444 priv->hw_params.num_ports = DSA_MAX_PORTS; 445 446 /* Assume a single GPHY setup if we can't read that property */ 447 if (of_property_read_u32(dn, "brcm,num-gphy", 448 &priv->hw_params.num_gphy)) 449 priv->hw_params.num_gphy = 1; 450 451 /* Enable all valid ports and disable those unused */ 452 for (port = 0; port < priv->hw_params.num_ports; port++) { 453 /* IMP port receives special treatment */ 454 if ((1 << port) & ds->phys_port_mask) 455 bcm_sf2_port_setup(ds, port, NULL); 456 else if (dsa_is_cpu_port(ds, port)) 457 bcm_sf2_imp_setup(ds, port); 458 else 459 bcm_sf2_port_disable(ds, port, NULL); 460 } 461 462 /* Include the pseudo-PHY address and the broadcast PHY address to 463 * divert reads towards our workaround 464 */ 465 ds->phys_mii_mask |= ((1 << 30) | (1 << 0)); 466 467 rev = reg_readl(priv, REG_SWITCH_REVISION); 468 priv->hw_params.top_rev = (rev >> SWITCH_TOP_REV_SHIFT) & 469 SWITCH_TOP_REV_MASK; 470 priv->hw_params.core_rev = (rev & SF2_REV_MASK); 471 472 rev = reg_readl(priv, REG_PHY_REVISION); 473 priv->hw_params.gphy_rev = rev & PHY_REVISION_MASK; 474 475 pr_info("Starfighter 2 top: %x.%02x, core: %x.%02x base: 0x%p, IRQs: %d, %d\n", 476 priv->hw_params.top_rev >> 8, priv->hw_params.top_rev & 0xff, 477 priv->hw_params.core_rev >> 8, priv->hw_params.core_rev & 0xff, 478 priv->core, priv->irq0, priv->irq1); 479 480 return 0; 481 482 out_free_irq0: 483 free_irq(priv->irq0, priv); 484 out_unmap: 485 base = &priv->core; 486 for (i = 0; i < BCM_SF2_REGS_NUM; i++) { 487 iounmap(*base); 488 base++; 489 } 490 return ret; 491 } 492 493 static int bcm_sf2_sw_set_addr(struct dsa_switch *ds, u8 *addr) 494 { 495 return 0; 496 } 497 498 static u32 bcm_sf2_sw_get_phy_flags(struct dsa_switch *ds, int port) 499 { 500 struct bcm_sf2_priv *priv = ds_to_priv(ds); 501 502 /* The BCM7xxx PHY driver expects to find the integrated PHY revision 503 * in bits 15:8 and the patch level in bits 7:0 which is exactly what 504 * the REG_PHY_REVISION register layout is. 505 */ 506 507 return priv->hw_params.gphy_rev; 508 } 509 510 static int bcm_sf2_sw_indir_rw(struct dsa_switch *ds, int op, int addr, 511 int regnum, u16 val) 512 { 513 struct bcm_sf2_priv *priv = ds_to_priv(ds); 514 int ret = 0; 515 u32 reg; 516 517 reg = reg_readl(priv, REG_SWITCH_CNTRL); 518 reg |= MDIO_MASTER_SEL; 519 reg_writel(priv, reg, REG_SWITCH_CNTRL); 520 521 /* Page << 8 | offset */ 522 reg = 0x70; 523 reg <<= 2; 524 core_writel(priv, addr, reg); 525 526 /* Page << 8 | offset */ 527 reg = 0x80 << 8 | regnum << 1; 528 reg <<= 2; 529 530 if (op) 531 ret = core_readl(priv, reg); 532 else 533 core_writel(priv, val, reg); 534 535 reg = reg_readl(priv, REG_SWITCH_CNTRL); 536 reg &= ~MDIO_MASTER_SEL; 537 reg_writel(priv, reg, REG_SWITCH_CNTRL); 538 539 return ret & 0xffff; 540 } 541 542 static int bcm_sf2_sw_phy_read(struct dsa_switch *ds, int addr, int regnum) 543 { 544 /* Intercept reads from the MDIO broadcast address or Broadcom 545 * pseudo-PHY address 546 */ 547 switch (addr) { 548 case 0: 549 case 30: 550 return bcm_sf2_sw_indir_rw(ds, 1, addr, regnum, 0); 551 default: 552 return 0xffff; 553 } 554 } 555 556 static int bcm_sf2_sw_phy_write(struct dsa_switch *ds, int addr, int regnum, 557 u16 val) 558 { 559 /* Intercept writes to the MDIO broadcast address or Broadcom 560 * pseudo-PHY address 561 */ 562 switch (addr) { 563 case 0: 564 case 30: 565 bcm_sf2_sw_indir_rw(ds, 0, addr, regnum, val); 566 break; 567 } 568 569 return 0; 570 } 571 572 static void bcm_sf2_sw_adjust_link(struct dsa_switch *ds, int port, 573 struct phy_device *phydev) 574 { 575 struct bcm_sf2_priv *priv = ds_to_priv(ds); 576 u32 id_mode_dis = 0, port_mode; 577 const char *str = NULL; 578 u32 reg; 579 580 switch (phydev->interface) { 581 case PHY_INTERFACE_MODE_RGMII: 582 str = "RGMII (no delay)"; 583 id_mode_dis = 1; 584 case PHY_INTERFACE_MODE_RGMII_TXID: 585 if (!str) 586 str = "RGMII (TX delay)"; 587 port_mode = EXT_GPHY; 588 break; 589 case PHY_INTERFACE_MODE_MII: 590 str = "MII"; 591 port_mode = EXT_EPHY; 592 break; 593 case PHY_INTERFACE_MODE_REVMII: 594 str = "Reverse MII"; 595 port_mode = EXT_REVMII; 596 break; 597 default: 598 /* All other PHYs: internal and MoCA */ 599 goto force_link; 600 } 601 602 /* If the link is down, just disable the interface to conserve power */ 603 if (!phydev->link) { 604 reg = reg_readl(priv, REG_RGMII_CNTRL_P(port)); 605 reg &= ~RGMII_MODE_EN; 606 reg_writel(priv, reg, REG_RGMII_CNTRL_P(port)); 607 goto force_link; 608 } 609 610 /* Clear id_mode_dis bit, and the existing port mode, but 611 * make sure we enable the RGMII block for data to pass 612 */ 613 reg = reg_readl(priv, REG_RGMII_CNTRL_P(port)); 614 reg &= ~ID_MODE_DIS; 615 reg &= ~(PORT_MODE_MASK << PORT_MODE_SHIFT); 616 reg &= ~(RX_PAUSE_EN | TX_PAUSE_EN); 617 618 reg |= port_mode | RGMII_MODE_EN; 619 if (id_mode_dis) 620 reg |= ID_MODE_DIS; 621 622 if (phydev->pause) { 623 if (phydev->asym_pause) 624 reg |= TX_PAUSE_EN; 625 reg |= RX_PAUSE_EN; 626 } 627 628 reg_writel(priv, reg, REG_RGMII_CNTRL_P(port)); 629 630 pr_info("Port %d configured for %s\n", port, str); 631 632 force_link: 633 /* Force link settings detected from the PHY */ 634 reg = SW_OVERRIDE; 635 switch (phydev->speed) { 636 case SPEED_1000: 637 reg |= SPDSTS_1000 << SPEED_SHIFT; 638 break; 639 case SPEED_100: 640 reg |= SPDSTS_100 << SPEED_SHIFT; 641 break; 642 } 643 644 if (phydev->link) 645 reg |= LINK_STS; 646 if (phydev->duplex == DUPLEX_FULL) 647 reg |= DUPLX_MODE; 648 649 core_writel(priv, reg, CORE_STS_OVERRIDE_GMIIP_PORT(port)); 650 } 651 652 static void bcm_sf2_sw_fixed_link_update(struct dsa_switch *ds, int port, 653 struct fixed_phy_status *status) 654 { 655 struct bcm_sf2_priv *priv = ds_to_priv(ds); 656 u32 link, duplex, pause, speed; 657 u32 reg; 658 659 link = core_readl(priv, CORE_LNKSTS); 660 duplex = core_readl(priv, CORE_DUPSTS); 661 pause = core_readl(priv, CORE_PAUSESTS); 662 speed = core_readl(priv, CORE_SPDSTS); 663 664 speed >>= (port * SPDSTS_SHIFT); 665 speed &= SPDSTS_MASK; 666 667 status->link = 0; 668 669 /* Port 7 is special as we do not get link status from CORE_LNKSTS, 670 * which means that we need to force the link at the port override 671 * level to get the data to flow. We do use what the interrupt handler 672 * did determine before. 673 */ 674 if (port == 7) { 675 status->link = priv->port_sts[port].link; 676 reg = core_readl(priv, CORE_STS_OVERRIDE_GMIIP_PORT(7)); 677 reg |= SW_OVERRIDE; 678 if (status->link) 679 reg |= LINK_STS; 680 else 681 reg &= ~LINK_STS; 682 core_writel(priv, reg, CORE_STS_OVERRIDE_GMIIP_PORT(7)); 683 status->duplex = 1; 684 } else { 685 status->link = !!(link & (1 << port)); 686 status->duplex = !!(duplex & (1 << port)); 687 } 688 689 switch (speed) { 690 case SPDSTS_10: 691 status->speed = SPEED_10; 692 break; 693 case SPDSTS_100: 694 status->speed = SPEED_100; 695 break; 696 case SPDSTS_1000: 697 status->speed = SPEED_1000; 698 break; 699 } 700 701 if ((pause & (1 << port)) && 702 (pause & (1 << (port + PAUSESTS_TX_PAUSE_SHIFT)))) { 703 status->asym_pause = 1; 704 status->pause = 1; 705 } 706 707 if (pause & (1 << port)) 708 status->pause = 1; 709 } 710 711 static int bcm_sf2_sw_suspend(struct dsa_switch *ds) 712 { 713 struct bcm_sf2_priv *priv = ds_to_priv(ds); 714 unsigned int port; 715 716 intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_MASK_SET); 717 intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR); 718 intrl2_0_writel(priv, 0, INTRL2_CPU_MASK_CLEAR); 719 intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_MASK_SET); 720 intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR); 721 intrl2_1_writel(priv, 0, INTRL2_CPU_MASK_CLEAR); 722 723 /* Disable all ports physically present including the IMP 724 * port, the other ones have already been disabled during 725 * bcm_sf2_sw_setup 726 */ 727 for (port = 0; port < DSA_MAX_PORTS; port++) { 728 if ((1 << port) & ds->phys_port_mask || 729 dsa_is_cpu_port(ds, port)) 730 bcm_sf2_port_disable(ds, port, NULL); 731 } 732 733 return 0; 734 } 735 736 static int bcm_sf2_sw_rst(struct bcm_sf2_priv *priv) 737 { 738 unsigned int timeout = 1000; 739 u32 reg; 740 741 reg = core_readl(priv, CORE_WATCHDOG_CTRL); 742 reg |= SOFTWARE_RESET | EN_CHIP_RST | EN_SW_RESET; 743 core_writel(priv, reg, CORE_WATCHDOG_CTRL); 744 745 do { 746 reg = core_readl(priv, CORE_WATCHDOG_CTRL); 747 if (!(reg & SOFTWARE_RESET)) 748 break; 749 750 usleep_range(1000, 2000); 751 } while (timeout-- > 0); 752 753 if (timeout == 0) 754 return -ETIMEDOUT; 755 756 return 0; 757 } 758 759 static int bcm_sf2_sw_resume(struct dsa_switch *ds) 760 { 761 struct bcm_sf2_priv *priv = ds_to_priv(ds); 762 unsigned int port; 763 u32 reg; 764 int ret; 765 766 ret = bcm_sf2_sw_rst(priv); 767 if (ret) { 768 pr_err("%s: failed to software reset switch\n", __func__); 769 return ret; 770 } 771 772 /* Reinitialize the single GPHY */ 773 if (priv->hw_params.num_gphy == 1) { 774 reg = reg_readl(priv, REG_SPHY_CNTRL); 775 reg |= PHY_RESET; 776 reg &= ~(EXT_PWR_DOWN | IDDQ_BIAS); 777 reg_writel(priv, reg, REG_SPHY_CNTRL); 778 udelay(21); 779 reg = reg_readl(priv, REG_SPHY_CNTRL); 780 reg &= ~PHY_RESET; 781 reg_writel(priv, reg, REG_SPHY_CNTRL); 782 } 783 784 for (port = 0; port < DSA_MAX_PORTS; port++) { 785 if ((1 << port) & ds->phys_port_mask) 786 bcm_sf2_port_setup(ds, port, NULL); 787 else if (dsa_is_cpu_port(ds, port)) 788 bcm_sf2_imp_setup(ds, port); 789 } 790 791 return 0; 792 } 793 794 static void bcm_sf2_sw_get_wol(struct dsa_switch *ds, int port, 795 struct ethtool_wolinfo *wol) 796 { 797 struct net_device *p = ds->dst[ds->index].master_netdev; 798 struct bcm_sf2_priv *priv = ds_to_priv(ds); 799 struct ethtool_wolinfo pwol; 800 801 /* Get the parent device WoL settings */ 802 p->ethtool_ops->get_wol(p, &pwol); 803 804 /* Advertise the parent device supported settings */ 805 wol->supported = pwol.supported; 806 memset(&wol->sopass, 0, sizeof(wol->sopass)); 807 808 if (pwol.wolopts & WAKE_MAGICSECURE) 809 memcpy(&wol->sopass, pwol.sopass, sizeof(wol->sopass)); 810 811 if (priv->wol_ports_mask & (1 << port)) 812 wol->wolopts = pwol.wolopts; 813 else 814 wol->wolopts = 0; 815 } 816 817 static int bcm_sf2_sw_set_wol(struct dsa_switch *ds, int port, 818 struct ethtool_wolinfo *wol) 819 { 820 struct net_device *p = ds->dst[ds->index].master_netdev; 821 struct bcm_sf2_priv *priv = ds_to_priv(ds); 822 s8 cpu_port = ds->dst[ds->index].cpu_port; 823 struct ethtool_wolinfo pwol; 824 825 p->ethtool_ops->get_wol(p, &pwol); 826 if (wol->wolopts & ~pwol.supported) 827 return -EINVAL; 828 829 if (wol->wolopts) 830 priv->wol_ports_mask |= (1 << port); 831 else 832 priv->wol_ports_mask &= ~(1 << port); 833 834 /* If we have at least one port enabled, make sure the CPU port 835 * is also enabled. If the CPU port is the last one enabled, we disable 836 * it since this configuration does not make sense. 837 */ 838 if (priv->wol_ports_mask && priv->wol_ports_mask != (1 << cpu_port)) 839 priv->wol_ports_mask |= (1 << cpu_port); 840 else 841 priv->wol_ports_mask &= ~(1 << cpu_port); 842 843 return p->ethtool_ops->set_wol(p, wol); 844 } 845 846 static struct dsa_switch_driver bcm_sf2_switch_driver = { 847 .tag_protocol = DSA_TAG_PROTO_BRCM, 848 .priv_size = sizeof(struct bcm_sf2_priv), 849 .probe = bcm_sf2_sw_probe, 850 .setup = bcm_sf2_sw_setup, 851 .set_addr = bcm_sf2_sw_set_addr, 852 .get_phy_flags = bcm_sf2_sw_get_phy_flags, 853 .phy_read = bcm_sf2_sw_phy_read, 854 .phy_write = bcm_sf2_sw_phy_write, 855 .get_strings = bcm_sf2_sw_get_strings, 856 .get_ethtool_stats = bcm_sf2_sw_get_ethtool_stats, 857 .get_sset_count = bcm_sf2_sw_get_sset_count, 858 .adjust_link = bcm_sf2_sw_adjust_link, 859 .fixed_link_update = bcm_sf2_sw_fixed_link_update, 860 .suspend = bcm_sf2_sw_suspend, 861 .resume = bcm_sf2_sw_resume, 862 .get_wol = bcm_sf2_sw_get_wol, 863 .set_wol = bcm_sf2_sw_set_wol, 864 .port_enable = bcm_sf2_port_setup, 865 .port_disable = bcm_sf2_port_disable, 866 .get_eee = bcm_sf2_sw_get_eee, 867 .set_eee = bcm_sf2_sw_set_eee, 868 }; 869 870 static int __init bcm_sf2_init(void) 871 { 872 register_switch_driver(&bcm_sf2_switch_driver); 873 874 return 0; 875 } 876 module_init(bcm_sf2_init); 877 878 static void __exit bcm_sf2_exit(void) 879 { 880 unregister_switch_driver(&bcm_sf2_switch_driver); 881 } 882 module_exit(bcm_sf2_exit); 883 884 MODULE_AUTHOR("Broadcom Corporation"); 885 MODULE_DESCRIPTION("Driver for Broadcom Starfighter 2 ethernet switch chip"); 886 MODULE_LICENSE("GPL"); 887 MODULE_ALIAS("platform:brcm-sf2"); 888