1 /* 2 * Copyright 2014 Freescale Semiconductor, Inc. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 * 6 * Driver for the Vitesse VSC9953 L2 Switch 7 */ 8 9 #include <asm/io.h> 10 #include <asm/fsl_serdes.h> 11 #include <fm_eth.h> 12 #include <fsl_memac.h> 13 #include <errno.h> 14 #include <malloc.h> 15 #include <vsc9953.h> 16 17 static struct vsc9953_info vsc9953_l2sw = { 18 .port[0] = VSC9953_PORT_INFO_INITIALIZER(0), 19 .port[1] = VSC9953_PORT_INFO_INITIALIZER(1), 20 .port[2] = VSC9953_PORT_INFO_INITIALIZER(2), 21 .port[3] = VSC9953_PORT_INFO_INITIALIZER(3), 22 .port[4] = VSC9953_PORT_INFO_INITIALIZER(4), 23 .port[5] = VSC9953_PORT_INFO_INITIALIZER(5), 24 .port[6] = VSC9953_PORT_INFO_INITIALIZER(6), 25 .port[7] = VSC9953_PORT_INFO_INITIALIZER(7), 26 .port[8] = VSC9953_PORT_INFO_INITIALIZER(8), 27 .port[9] = VSC9953_PORT_INFO_INITIALIZER(9), 28 }; 29 30 void vsc9953_port_info_set_mdio(int port_no, struct mii_dev *bus) 31 { 32 if (!VSC9953_PORT_CHECK(port_no)) 33 return; 34 35 vsc9953_l2sw.port[port_no].bus = bus; 36 } 37 38 void vsc9953_port_info_set_phy_address(int port_no, int address) 39 { 40 if (!VSC9953_PORT_CHECK(port_no)) 41 return; 42 43 vsc9953_l2sw.port[port_no].phyaddr = address; 44 } 45 46 void vsc9953_port_info_set_phy_int(int port_no, phy_interface_t phy_int) 47 { 48 if (!VSC9953_PORT_CHECK(port_no)) 49 return; 50 51 vsc9953_l2sw.port[port_no].enet_if = phy_int; 52 } 53 54 void vsc9953_port_enable(int port_no) 55 { 56 if (!VSC9953_PORT_CHECK(port_no)) 57 return; 58 59 vsc9953_l2sw.port[port_no].enabled = 1; 60 } 61 62 void vsc9953_port_disable(int port_no) 63 { 64 if (!VSC9953_PORT_CHECK(port_no)) 65 return; 66 67 vsc9953_l2sw.port[port_no].enabled = 0; 68 } 69 70 static void vsc9953_mdio_write(struct vsc9953_mii_mng *phyregs, int port_addr, 71 int regnum, int value) 72 { 73 int timeout = 50000; 74 75 out_le32(&phyregs->miimcmd, (0x1 << 31) | ((port_addr & 0x1f) << 25) | 76 ((regnum & 0x1f) << 20) | ((value & 0xffff) << 4) | 77 (0x1 << 1)); 78 asm("sync"); 79 80 while ((in_le32(&phyregs->miimstatus) & 0x8) && --timeout) 81 udelay(1); 82 83 if (timeout == 0) 84 debug("Timeout waiting for MDIO write\n"); 85 } 86 87 static int vsc9953_mdio_read(struct vsc9953_mii_mng *phyregs, int port_addr, 88 int regnum) 89 { 90 int value = 0xFFFF; 91 int timeout = 50000; 92 93 while ((in_le32(&phyregs->miimstatus) & MIIMIND_OPR_PEND) && --timeout) 94 udelay(1); 95 if (timeout == 0) { 96 debug("Timeout waiting for MDIO operation to finish\n"); 97 return value; 98 } 99 100 /* Put the address of the phy, and the register 101 * number into MIICMD 102 */ 103 out_le32(&phyregs->miimcmd, (0x1 << 31) | ((port_addr & 0x1f) << 25) | 104 ((regnum & 0x1f) << 20) | ((value & 0xffff) << 4) | 105 (0x2 << 1)); 106 107 timeout = 50000; 108 /* Wait for the the indication that the read is done */ 109 while ((in_le32(&phyregs->miimstatus) & 0x8) && --timeout) 110 udelay(1); 111 if (timeout == 0) 112 debug("Timeout waiting for MDIO read\n"); 113 114 /* Grab the value read from the PHY */ 115 value = in_le32(&phyregs->miimdata); 116 117 if ((value & 0x00030000) == 0) 118 return value & 0x0000ffff; 119 120 return value; 121 } 122 123 static int init_phy(struct eth_device *dev) 124 { 125 struct vsc9953_port_info *l2sw_port = dev->priv; 126 struct phy_device *phydev = NULL; 127 128 #ifdef CONFIG_PHYLIB 129 if (!l2sw_port->bus) 130 return 0; 131 phydev = phy_connect(l2sw_port->bus, l2sw_port->phyaddr, dev, 132 l2sw_port->enet_if); 133 if (!phydev) { 134 printf("Failed to connect\n"); 135 return -1; 136 } 137 138 phydev->supported &= SUPPORTED_10baseT_Half | 139 SUPPORTED_10baseT_Full | 140 SUPPORTED_100baseT_Half | 141 SUPPORTED_100baseT_Full | 142 SUPPORTED_1000baseT_Full; 143 phydev->advertising = phydev->supported; 144 145 l2sw_port->phydev = phydev; 146 147 phy_config(phydev); 148 #endif 149 150 return 0; 151 } 152 153 static int vsc9953_port_init(int port_no) 154 { 155 struct eth_device *dev; 156 157 /* Internal ports never have a PHY */ 158 if (VSC9953_INTERNAL_PORT_CHECK(port_no)) 159 return 0; 160 161 /* alloc eth device */ 162 dev = (struct eth_device *)calloc(1, sizeof(struct eth_device)); 163 if (!dev) 164 return -ENOMEM; 165 166 sprintf(dev->name, "SW@PORT%d", port_no); 167 dev->priv = &vsc9953_l2sw.port[port_no]; 168 dev->init = NULL; 169 dev->halt = NULL; 170 dev->send = NULL; 171 dev->recv = NULL; 172 173 if (init_phy(dev)) { 174 free(dev); 175 return -ENODEV; 176 } 177 178 return 0; 179 } 180 181 void vsc9953_init(bd_t *bis) 182 { 183 u32 i; 184 u32 hdx_cfg = 0; 185 u32 phy_addr = 0; 186 int timeout; 187 struct vsc9953_system_reg *l2sys_reg; 188 struct vsc9953_qsys_reg *l2qsys_reg; 189 struct vsc9953_dev_gmii *l2dev_gmii_reg; 190 struct vsc9953_analyzer *l2ana_reg; 191 struct vsc9953_devcpu_gcb *l2dev_gcb; 192 193 l2dev_gmii_reg = (struct vsc9953_dev_gmii *)(VSC9953_OFFSET + 194 VSC9953_DEV_GMII_OFFSET); 195 196 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 197 VSC9953_ANA_OFFSET); 198 199 l2sys_reg = (struct vsc9953_system_reg *)(VSC9953_OFFSET + 200 VSC9953_SYS_OFFSET); 201 202 l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET + 203 VSC9953_QSYS_OFFSET); 204 205 l2dev_gcb = (struct vsc9953_devcpu_gcb *)(VSC9953_OFFSET + 206 VSC9953_DEVCPU_GCB); 207 208 out_le32(&l2dev_gcb->chip_regs.soft_rst, 209 VSC9953_SOFT_SWC_RST_ENA); 210 timeout = 50000; 211 while ((in_le32(&l2dev_gcb->chip_regs.soft_rst) & 212 VSC9953_SOFT_SWC_RST_ENA) && --timeout) 213 udelay(1); /* busy wait for vsc9953 soft reset */ 214 if (timeout == 0) 215 debug("Timeout waiting for VSC9953 to reset\n"); 216 217 out_le32(&l2sys_reg->sys.reset_cfg, VSC9953_MEM_ENABLE | 218 VSC9953_MEM_INIT); 219 220 timeout = 50000; 221 while ((in_le32(&l2sys_reg->sys.reset_cfg) & 222 VSC9953_MEM_INIT) && --timeout) 223 udelay(1); /* busy wait for vsc9953 memory init */ 224 if (timeout == 0) 225 debug("Timeout waiting for VSC9953 memory to initialize\n"); 226 227 out_le32(&l2sys_reg->sys.reset_cfg, (in_le32(&l2sys_reg->sys.reset_cfg) 228 | VSC9953_CORE_ENABLE)); 229 230 /* VSC9953 Setting to be done once only */ 231 out_le32(&l2qsys_reg->sys.ext_cpu_cfg, 0x00000b00); 232 233 for (i = 0; i < VSC9953_MAX_PORTS; i++) { 234 if (vsc9953_port_init(i)) 235 printf("Failed to initialize l2switch port %d\n", i); 236 237 /* Enable VSC9953 GMII Ports Port ID 0 - 7 */ 238 if (VSC9953_INTERNAL_PORT_CHECK(i)) { 239 out_le32(&l2ana_reg->pfc[i].pfc_cfg, 240 VSC9953_PFC_FC_QSGMII); 241 out_le32(&l2sys_reg->pause_cfg.mac_fc_cfg[i], 242 VSC9953_MAC_FC_CFG_QSGMII); 243 } else { 244 out_le32(&l2ana_reg->pfc[i].pfc_cfg, 245 VSC9953_PFC_FC); 246 out_le32(&l2sys_reg->pause_cfg.mac_fc_cfg[i], 247 VSC9953_MAC_FC_CFG); 248 } 249 out_le32(&l2dev_gmii_reg->port_mode.clock_cfg, 250 VSC9953_CLOCK_CFG); 251 out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_ena_cfg, 252 VSC9953_MAC_ENA_CFG); 253 out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_mode_cfg, 254 VSC9953_MAC_MODE_CFG); 255 out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_ifg_cfg, 256 VSC9953_MAC_IFG_CFG); 257 /* mac_hdx_cfg varies with port id*/ 258 hdx_cfg = VSC9953_MAC_HDX_CFG | (i << 16); 259 out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_hdx_cfg, hdx_cfg); 260 out_le32(&l2sys_reg->sys.front_port_mode[i], 261 VSC9953_FRONT_PORT_MODE); 262 out_le32(&l2qsys_reg->sys.switch_port_mode[i], 263 VSC9953_PORT_ENA); 264 out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_maxlen_cfg, 265 VSC9953_MAC_MAX_LEN); 266 out_le32(&l2sys_reg->pause_cfg.pause_cfg[i], 267 VSC9953_PAUSE_CFG); 268 /* WAIT FOR 2 us*/ 269 udelay(2); 270 271 l2dev_gmii_reg = (struct vsc9953_dev_gmii *)( 272 (char *)l2dev_gmii_reg 273 + T1040_SWITCH_GMII_DEV_OFFSET); 274 275 /* Initialize Lynx PHY Wrappers */ 276 phy_addr = 0; 277 if (vsc9953_l2sw.port[i].enet_if == 278 PHY_INTERFACE_MODE_QSGMII) 279 phy_addr = (i + 0x4) & 0x1F; 280 else if (vsc9953_l2sw.port[i].enet_if == 281 PHY_INTERFACE_MODE_SGMII) 282 phy_addr = (i + 1) & 0x1F; 283 284 if (phy_addr) { 285 /* SGMII IF mode + AN enable */ 286 vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, 287 0x14, PHY_SGMII_IF_MODE_AN | 288 PHY_SGMII_IF_MODE_SGMII); 289 /* Dev ability according to SGMII specification */ 290 vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, 291 0x4, PHY_SGMII_DEV_ABILITY_SGMII); 292 /* Adjust link timer for SGMII 293 * 1.6 ms in units of 8 ns = 2 * 10^5 = 0x30d40 294 */ 295 vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, 296 0x13, 0x0003); 297 vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, 298 0x12, 0x0d40); 299 /* Restart AN */ 300 vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, 301 0x0, PHY_SGMII_CR_DEF_VAL | 302 PHY_SGMII_CR_RESET_AN); 303 304 timeout = 50000; 305 while ((vsc9953_mdio_read(&l2dev_gcb->mii_mng[0], 306 phy_addr, 0x01) & 0x0020) && --timeout) 307 udelay(1); /* wait for AN to complete */ 308 if (timeout == 0) 309 debug("Timeout waiting for AN to complete\n"); 310 } 311 } 312 313 printf("VSC9953 L2 switch initialized\n"); 314 return; 315 } 316 317 #ifdef CONFIG_VSC9953_CMD 318 /* Enable/disable status of a VSC9953 port */ 319 static void vsc9953_port_status_set(int port_no, u8 enabled) 320 { 321 struct vsc9953_qsys_reg *l2qsys_reg; 322 323 /* Administrative down */ 324 if (!vsc9953_l2sw.port[port_no].enabled) 325 return; 326 327 l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET + 328 VSC9953_QSYS_OFFSET); 329 330 if (enabled) 331 setbits_le32(&l2qsys_reg->sys.switch_port_mode[port_no], 332 VSC9953_PORT_ENA); 333 else 334 clrbits_le32(&l2qsys_reg->sys.switch_port_mode[port_no], 335 VSC9953_PORT_ENA); 336 } 337 338 /* Set all VSC9953 ports' status */ 339 static void vsc9953_port_all_status_set(u8 enabled) 340 { 341 int i; 342 343 for (i = 0; i < VSC9953_MAX_PORTS; i++) 344 vsc9953_port_status_set(i, enabled); 345 } 346 347 /* Start autonegotiation for a VSC9953 PHY */ 348 static void vsc9953_phy_autoneg(int port_no) 349 { 350 if (!vsc9953_l2sw.port[port_no].phydev) 351 return; 352 353 if (vsc9953_l2sw.port[port_no].phydev->drv->startup( 354 vsc9953_l2sw.port[port_no].phydev)) 355 printf("Failed to start PHY for port %d\n", port_no); 356 } 357 358 /* Start autonegotiation for all VSC9953 PHYs */ 359 static void vsc9953_phy_all_autoneg(void) 360 { 361 int i; 362 363 for (i = 0; i < VSC9953_MAX_PORTS; i++) 364 vsc9953_phy_autoneg(i); 365 } 366 367 /* Print a VSC9953 port's configuration */ 368 static void vsc9953_port_config_show(int port_no) 369 { 370 int speed; 371 int duplex; 372 int link; 373 u8 enabled; 374 u32 val; 375 struct vsc9953_qsys_reg *l2qsys_reg; 376 377 l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET + 378 VSC9953_QSYS_OFFSET); 379 380 val = in_le32(&l2qsys_reg->sys.switch_port_mode[port_no]); 381 enabled = vsc9953_l2sw.port[port_no].enabled && 382 (val & VSC9953_PORT_ENA); 383 384 /* internal ports (8 and 9) are fixed */ 385 if (VSC9953_INTERNAL_PORT_CHECK(port_no)) { 386 link = 1; 387 speed = SPEED_2500; 388 duplex = DUPLEX_FULL; 389 } else { 390 if (vsc9953_l2sw.port[port_no].phydev) { 391 link = vsc9953_l2sw.port[port_no].phydev->link; 392 speed = vsc9953_l2sw.port[port_no].phydev->speed; 393 duplex = vsc9953_l2sw.port[port_no].phydev->duplex; 394 } else { 395 link = -1; 396 speed = -1; 397 duplex = -1; 398 } 399 } 400 401 printf("%8d ", port_no); 402 printf("%8s ", enabled == 1 ? "enabled" : "disabled"); 403 printf("%8s ", link == 1 ? "up" : "down"); 404 405 switch (speed) { 406 case SPEED_10: 407 printf("%8d ", 10); 408 break; 409 case SPEED_100: 410 printf("%8d ", 100); 411 break; 412 case SPEED_1000: 413 printf("%8d ", 1000); 414 break; 415 case SPEED_2500: 416 printf("%8d ", 2500); 417 break; 418 case SPEED_10000: 419 printf("%8d ", 10000); 420 break; 421 default: 422 printf("%8s ", "-"); 423 } 424 425 printf("%8s\n", duplex == DUPLEX_FULL ? "full" : "half"); 426 } 427 428 /* Print VSC9953 ports' configuration */ 429 static void vsc9953_port_all_config_show(void) 430 { 431 int i; 432 433 for (i = 0; i < VSC9953_MAX_PORTS; i++) 434 vsc9953_port_config_show(i); 435 } 436 437 /* function to interpret commands starting with "ethsw " */ 438 static int do_ethsw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 439 { 440 u8 enable; 441 u32 port; 442 443 if (argc < 4) 444 return -1; 445 446 if (strcmp(argv[1], "port")) 447 return -1; 448 449 if (!strcmp(argv[3], "show")) { 450 if (!strcmp(argv[2], "all")) { 451 vsc9953_phy_all_autoneg(); 452 printf("%8s %8s %8s %8s %8s\n", 453 "Port", "Status", "Link", "Speed", 454 "Duplex"); 455 vsc9953_port_all_config_show(); 456 return 0; 457 } else { 458 port = simple_strtoul(argv[2], NULL, 10); 459 if (!VSC9953_PORT_CHECK(port)) 460 return -1; 461 vsc9953_phy_autoneg(port); 462 printf("%8s %8s %8s %8s %8s\n", 463 "Port", "Status", "Link", "Speed", 464 "Duplex"); 465 vsc9953_port_config_show(port); 466 return 0; 467 } 468 } else if (!strcmp(argv[3], "enable")) { 469 enable = 1; 470 } else if (!strcmp(argv[3], "disable")) { 471 enable = 0; 472 } else { 473 return -1; 474 } 475 476 if (!strcmp(argv[2], "all")) { 477 vsc9953_port_all_status_set(enable); 478 return 0; 479 } else { 480 port = simple_strtoul(argv[2], NULL, 10); 481 if (!VSC9953_PORT_CHECK(port)) 482 return -1; 483 vsc9953_port_status_set(port, enable); 484 return 0; 485 } 486 487 return -1; 488 } 489 490 U_BOOT_CMD(ethsw, 5, 0, do_ethsw, 491 "vsc9953 l2 switch commands", 492 "port <port_no> enable|disable\n" 493 " - enable/disable an l2 switch port\n" 494 " port_no=0..9; use \"all\" for all ports\n" 495 "ethsw port <port_no> show\n" 496 " - show an l2 switch port's configuration\n" 497 " port_no=0..9; use \"all\" for all ports\n" 498 ); 499 #endif /* CONFIG_VSC9953_CMD */ 500