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 <bitfield.h> 14 #include <errno.h> 15 #include <malloc.h> 16 #include <vsc9953.h> 17 18 static struct vsc9953_info vsc9953_l2sw = { 19 .port[0] = VSC9953_PORT_INFO_INITIALIZER(0), 20 .port[1] = VSC9953_PORT_INFO_INITIALIZER(1), 21 .port[2] = VSC9953_PORT_INFO_INITIALIZER(2), 22 .port[3] = VSC9953_PORT_INFO_INITIALIZER(3), 23 .port[4] = VSC9953_PORT_INFO_INITIALIZER(4), 24 .port[5] = VSC9953_PORT_INFO_INITIALIZER(5), 25 .port[6] = VSC9953_PORT_INFO_INITIALIZER(6), 26 .port[7] = VSC9953_PORT_INFO_INITIALIZER(7), 27 .port[8] = VSC9953_PORT_INFO_INITIALIZER(8), 28 .port[9] = VSC9953_PORT_INFO_INITIALIZER(9), 29 }; 30 31 void vsc9953_port_info_set_mdio(int port_no, struct mii_dev *bus) 32 { 33 if (!VSC9953_PORT_CHECK(port_no)) 34 return; 35 36 vsc9953_l2sw.port[port_no].bus = bus; 37 } 38 39 void vsc9953_port_info_set_phy_address(int port_no, int address) 40 { 41 if (!VSC9953_PORT_CHECK(port_no)) 42 return; 43 44 vsc9953_l2sw.port[port_no].phyaddr = address; 45 } 46 47 void vsc9953_port_info_set_phy_int(int port_no, phy_interface_t phy_int) 48 { 49 if (!VSC9953_PORT_CHECK(port_no)) 50 return; 51 52 vsc9953_l2sw.port[port_no].enet_if = phy_int; 53 } 54 55 void vsc9953_port_enable(int port_no) 56 { 57 if (!VSC9953_PORT_CHECK(port_no)) 58 return; 59 60 vsc9953_l2sw.port[port_no].enabled = 1; 61 } 62 63 void vsc9953_port_disable(int port_no) 64 { 65 if (!VSC9953_PORT_CHECK(port_no)) 66 return; 67 68 vsc9953_l2sw.port[port_no].enabled = 0; 69 } 70 71 static void vsc9953_mdio_write(struct vsc9953_mii_mng *phyregs, int port_addr, 72 int regnum, int value) 73 { 74 int timeout = 50000; 75 76 out_le32(&phyregs->miimcmd, (0x1 << 31) | ((port_addr & 0x1f) << 25) | 77 ((regnum & 0x1f) << 20) | ((value & 0xffff) << 4) | 78 (0x1 << 1)); 79 asm("sync"); 80 81 while ((in_le32(&phyregs->miimstatus) & 0x8) && --timeout) 82 udelay(1); 83 84 if (timeout == 0) 85 debug("Timeout waiting for MDIO write\n"); 86 } 87 88 static int vsc9953_mdio_read(struct vsc9953_mii_mng *phyregs, int port_addr, 89 int regnum) 90 { 91 int value = 0xFFFF; 92 int timeout = 50000; 93 94 while ((in_le32(&phyregs->miimstatus) & MIIMIND_OPR_PEND) && --timeout) 95 udelay(1); 96 if (timeout == 0) { 97 debug("Timeout waiting for MDIO operation to finish\n"); 98 return value; 99 } 100 101 /* Put the address of the phy, and the register 102 * number into MIICMD 103 */ 104 out_le32(&phyregs->miimcmd, (0x1 << 31) | ((port_addr & 0x1f) << 25) | 105 ((regnum & 0x1f) << 20) | ((value & 0xffff) << 4) | 106 (0x2 << 1)); 107 108 timeout = 50000; 109 /* Wait for the the indication that the read is done */ 110 while ((in_le32(&phyregs->miimstatus) & 0x8) && --timeout) 111 udelay(1); 112 if (timeout == 0) 113 debug("Timeout waiting for MDIO read\n"); 114 115 /* Grab the value read from the PHY */ 116 value = in_le32(&phyregs->miimdata); 117 118 if ((value & 0x00030000) == 0) 119 return value & 0x0000ffff; 120 121 return value; 122 } 123 124 static int init_phy(struct eth_device *dev) 125 { 126 struct vsc9953_port_info *l2sw_port = dev->priv; 127 struct phy_device *phydev = NULL; 128 129 #ifdef CONFIG_PHYLIB 130 if (!l2sw_port->bus) 131 return 0; 132 phydev = phy_connect(l2sw_port->bus, l2sw_port->phyaddr, dev, 133 l2sw_port->enet_if); 134 if (!phydev) { 135 printf("Failed to connect\n"); 136 return -1; 137 } 138 139 phydev->supported &= SUPPORTED_10baseT_Half | 140 SUPPORTED_10baseT_Full | 141 SUPPORTED_100baseT_Half | 142 SUPPORTED_100baseT_Full | 143 SUPPORTED_1000baseT_Full; 144 phydev->advertising = phydev->supported; 145 146 l2sw_port->phydev = phydev; 147 148 phy_config(phydev); 149 #endif 150 151 return 0; 152 } 153 154 static int vsc9953_port_init(int port_no) 155 { 156 struct eth_device *dev; 157 158 /* Internal ports never have a PHY */ 159 if (VSC9953_INTERNAL_PORT_CHECK(port_no)) 160 return 0; 161 162 /* alloc eth device */ 163 dev = (struct eth_device *)calloc(1, sizeof(struct eth_device)); 164 if (!dev) 165 return -ENOMEM; 166 167 sprintf(dev->name, "SW@PORT%d", port_no); 168 dev->priv = &vsc9953_l2sw.port[port_no]; 169 dev->init = NULL; 170 dev->halt = NULL; 171 dev->send = NULL; 172 dev->recv = NULL; 173 174 if (init_phy(dev)) { 175 free(dev); 176 return -ENODEV; 177 } 178 179 return 0; 180 } 181 182 static int vsc9953_vlan_table_poll_idle(void) 183 { 184 struct vsc9953_analyzer *l2ana_reg; 185 int timeout; 186 187 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 188 VSC9953_ANA_OFFSET); 189 190 timeout = 50000; 191 while (((in_le32(&l2ana_reg->ana_tables.vlan_access) & 192 VSC9953_VLAN_CMD_MASK) != VSC9953_VLAN_CMD_IDLE) && --timeout) 193 udelay(1); 194 195 return timeout ? 0 : -EBUSY; 196 } 197 198 /* vlan table set/clear all membership of vid */ 199 static void vsc9953_vlan_table_membership_all_set(int vid, int set_member) 200 { 201 uint val; 202 struct vsc9953_analyzer *l2ana_reg; 203 204 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 205 VSC9953_ANA_OFFSET); 206 207 if (vsc9953_vlan_table_poll_idle() < 0) { 208 debug("VLAN table timeout\n"); 209 return; 210 } 211 212 /* read current vlan configuration */ 213 val = in_le32(&l2ana_reg->ana_tables.vlan_tidx); 214 out_le32(&l2ana_reg->ana_tables.vlan_tidx, 215 bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK, vid)); 216 217 clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access, 218 VSC9953_VLAN_CMD_MASK, VSC9953_VLAN_CMD_READ); 219 220 if (vsc9953_vlan_table_poll_idle() < 0) { 221 debug("VLAN table timeout\n"); 222 return; 223 } 224 225 val = in_le32(&l2ana_reg->ana_tables.vlan_tidx); 226 out_le32(&l2ana_reg->ana_tables.vlan_tidx, 227 bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK, vid)); 228 229 clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access, 230 VSC9953_VLAN_PORT_MASK | VSC9953_VLAN_CMD_MASK, 231 VSC9953_VLAN_CMD_WRITE | 232 (set_member ? VSC9953_VLAN_PORT_MASK : 0)); 233 } 234 235 /* Set PVID for a VSC9953 port */ 236 static void vsc9953_port_vlan_pvid_set(int port_no, int pvid) 237 { 238 uint val; 239 struct vsc9953_analyzer *l2ana_reg; 240 struct vsc9953_rew_reg *l2rew_reg; 241 242 /* Administrative down */ 243 if (!vsc9953_l2sw.port[port_no].enabled) { 244 printf("Port %d is administrative down\n", port_no); 245 return; 246 } 247 248 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 249 VSC9953_ANA_OFFSET); 250 l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET + 251 VSC9953_REW_OFFSET); 252 253 /* Set PVID on ingress */ 254 val = in_le32(&l2ana_reg->port[port_no].vlan_cfg); 255 val = bitfield_replace_by_mask(val, VSC9953_VLAN_CFG_VID_MASK, pvid); 256 out_le32(&l2ana_reg->port[port_no].vlan_cfg, val); 257 258 /* Set PVID on egress */ 259 val = in_le32(&l2rew_reg->port[port_no].port_vlan_cfg); 260 val = bitfield_replace_by_mask(val, VSC9953_PORT_VLAN_CFG_VID_MASK, 261 pvid); 262 out_le32(&l2rew_reg->port[port_no].port_vlan_cfg, val); 263 } 264 265 static void vsc9953_port_all_vlan_pvid_set(int pvid) 266 { 267 int i; 268 269 for (i = 0; i < VSC9953_MAX_PORTS; i++) 270 vsc9953_port_vlan_pvid_set(i, pvid); 271 } 272 273 /* Enable/disable vlan aware of a VSC9953 port */ 274 static void vsc9953_port_vlan_aware_set(int port_no, int enabled) 275 { 276 struct vsc9953_analyzer *l2ana_reg; 277 278 /* Administrative down */ 279 if (!vsc9953_l2sw.port[port_no].enabled) { 280 printf("Port %d is administrative down\n", port_no); 281 return; 282 } 283 284 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 285 VSC9953_ANA_OFFSET); 286 287 if (enabled) 288 setbits_le32(&l2ana_reg->port[port_no].vlan_cfg, 289 VSC9953_VLAN_CFG_AWARE_ENA); 290 else 291 clrbits_le32(&l2ana_reg->port[port_no].vlan_cfg, 292 VSC9953_VLAN_CFG_AWARE_ENA); 293 } 294 295 /* Set all VSC9953 ports' vlan aware */ 296 static void vsc9953_port_all_vlan_aware_set(int enabled) 297 { 298 int i; 299 300 for (i = 0; i < VSC9953_MAX_PORTS; i++) 301 vsc9953_port_vlan_aware_set(i, enabled); 302 } 303 304 /* Enable/disable vlan pop count of a VSC9953 port */ 305 static void vsc9953_port_vlan_popcnt_set(int port_no, int popcnt) 306 { 307 uint val; 308 struct vsc9953_analyzer *l2ana_reg; 309 310 /* Administrative down */ 311 if (!vsc9953_l2sw.port[port_no].enabled) { 312 printf("Port %d is administrative down\n", port_no); 313 return; 314 } 315 316 if (popcnt > 3 || popcnt < 0) { 317 printf("Invalid pop count value: %d\n", port_no); 318 return; 319 } 320 321 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 322 VSC9953_ANA_OFFSET); 323 324 val = in_le32(&l2ana_reg->port[port_no].vlan_cfg); 325 val = bitfield_replace_by_mask(val, VSC9953_VLAN_CFG_POP_CNT_MASK, 326 popcnt); 327 out_le32(&l2ana_reg->port[port_no].vlan_cfg, val); 328 } 329 330 /* Set all VSC9953 ports' pop count */ 331 static void vsc9953_port_all_vlan_poncnt_set(int popcnt) 332 { 333 int i; 334 335 for (i = 0; i < VSC9953_MAX_PORTS; i++) 336 vsc9953_port_vlan_popcnt_set(i, popcnt); 337 } 338 339 /* Enable/disable learning for frames dropped due to ingress filtering */ 340 static void vsc9953_vlan_ingr_fltr_learn_drop(int enable) 341 { 342 struct vsc9953_analyzer *l2ana_reg; 343 344 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 345 VSC9953_ANA_OFFSET); 346 347 if (enable) 348 setbits_le32(&l2ana_reg->ana.adv_learn, VSC9953_VLAN_CHK); 349 else 350 clrbits_le32(&l2ana_reg->ana.adv_learn, VSC9953_VLAN_CHK); 351 } 352 353 /* Egress untag modes of a VSC9953 port */ 354 enum egress_untag_mode { 355 EGRESS_UNTAG_ALL = 0, 356 EGRESS_UNTAG_PVID_AND_ZERO, 357 EGRESS_UNTAG_ZERO, 358 EGRESS_UNTAG_NONE, 359 }; 360 361 static void vsc9953_port_vlan_egr_untag_set(int port_no, 362 enum egress_untag_mode mode) 363 { 364 struct vsc9953_rew_reg *l2rew_reg; 365 366 /* Administrative down */ 367 if (!vsc9953_l2sw.port[port_no].enabled) { 368 printf("Port %d is administrative down\n", port_no); 369 return; 370 } 371 372 l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET + 373 VSC9953_REW_OFFSET); 374 375 switch (mode) { 376 case EGRESS_UNTAG_ALL: 377 clrsetbits_le32(&l2rew_reg->port[port_no].port_tag_cfg, 378 VSC9953_TAG_CFG_MASK, VSC9953_TAG_CFG_NONE); 379 break; 380 case EGRESS_UNTAG_PVID_AND_ZERO: 381 clrsetbits_le32(&l2rew_reg->port[port_no].port_tag_cfg, 382 VSC9953_TAG_CFG_MASK, 383 VSC9953_TAG_CFG_ALL_BUT_PVID_ZERO); 384 break; 385 case EGRESS_UNTAG_ZERO: 386 clrsetbits_le32(&l2rew_reg->port[port_no].port_tag_cfg, 387 VSC9953_TAG_CFG_MASK, 388 VSC9953_TAG_CFG_ALL_BUT_ZERO); 389 break; 390 case EGRESS_UNTAG_NONE: 391 clrsetbits_le32(&l2rew_reg->port[port_no].port_tag_cfg, 392 VSC9953_TAG_CFG_MASK, VSC9953_TAG_CFG_ALL); 393 break; 394 default: 395 printf("Unknown untag mode for port %d\n", port_no); 396 } 397 } 398 399 static void vsc9953_port_all_vlan_egress_untagged_set( 400 enum egress_untag_mode mode) 401 { 402 int i; 403 404 for (i = 0; i < VSC9953_MAX_PORTS; i++) 405 vsc9953_port_vlan_egr_untag_set(i, mode); 406 } 407 408 /***************************************************************************** 409 At startup, the default configuration would be: 410 - HW learning enabled on all ports; (HW default) 411 - All ports are in VLAN 1; 412 - All ports are VLAN aware; 413 - All ports have POP_COUNT 1; 414 - All ports have PVID 1; 415 - All ports have TPID 0x8100; (HW default) 416 - All ports tag frames classified to all VLANs that are not PVID; 417 *****************************************************************************/ 418 void vsc9953_default_configuration(void) 419 { 420 int i; 421 422 for (i = 0; i < VSC9953_MAX_VLAN; i++) 423 vsc9953_vlan_table_membership_all_set(i, 0); 424 vsc9953_port_all_vlan_aware_set(1); 425 vsc9953_port_all_vlan_pvid_set(1); 426 vsc9953_port_all_vlan_poncnt_set(1); 427 vsc9953_vlan_table_membership_all_set(1, 1); 428 vsc9953_vlan_ingr_fltr_learn_drop(1); 429 vsc9953_port_all_vlan_egress_untagged_set(EGRESS_UNTAG_PVID_AND_ZERO); 430 } 431 432 void vsc9953_init(bd_t *bis) 433 { 434 u32 i; 435 u32 hdx_cfg = 0; 436 u32 phy_addr = 0; 437 int timeout; 438 struct vsc9953_system_reg *l2sys_reg; 439 struct vsc9953_qsys_reg *l2qsys_reg; 440 struct vsc9953_dev_gmii *l2dev_gmii_reg; 441 struct vsc9953_analyzer *l2ana_reg; 442 struct vsc9953_devcpu_gcb *l2dev_gcb; 443 444 l2dev_gmii_reg = (struct vsc9953_dev_gmii *)(VSC9953_OFFSET + 445 VSC9953_DEV_GMII_OFFSET); 446 447 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 448 VSC9953_ANA_OFFSET); 449 450 l2sys_reg = (struct vsc9953_system_reg *)(VSC9953_OFFSET + 451 VSC9953_SYS_OFFSET); 452 453 l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET + 454 VSC9953_QSYS_OFFSET); 455 456 l2dev_gcb = (struct vsc9953_devcpu_gcb *)(VSC9953_OFFSET + 457 VSC9953_DEVCPU_GCB); 458 459 out_le32(&l2dev_gcb->chip_regs.soft_rst, 460 VSC9953_SOFT_SWC_RST_ENA); 461 timeout = 50000; 462 while ((in_le32(&l2dev_gcb->chip_regs.soft_rst) & 463 VSC9953_SOFT_SWC_RST_ENA) && --timeout) 464 udelay(1); /* busy wait for vsc9953 soft reset */ 465 if (timeout == 0) 466 debug("Timeout waiting for VSC9953 to reset\n"); 467 468 out_le32(&l2sys_reg->sys.reset_cfg, VSC9953_MEM_ENABLE | 469 VSC9953_MEM_INIT); 470 471 timeout = 50000; 472 while ((in_le32(&l2sys_reg->sys.reset_cfg) & 473 VSC9953_MEM_INIT) && --timeout) 474 udelay(1); /* busy wait for vsc9953 memory init */ 475 if (timeout == 0) 476 debug("Timeout waiting for VSC9953 memory to initialize\n"); 477 478 out_le32(&l2sys_reg->sys.reset_cfg, (in_le32(&l2sys_reg->sys.reset_cfg) 479 | VSC9953_CORE_ENABLE)); 480 481 /* VSC9953 Setting to be done once only */ 482 out_le32(&l2qsys_reg->sys.ext_cpu_cfg, 0x00000b00); 483 484 for (i = 0; i < VSC9953_MAX_PORTS; i++) { 485 if (vsc9953_port_init(i)) 486 printf("Failed to initialize l2switch port %d\n", i); 487 488 /* Enable VSC9953 GMII Ports Port ID 0 - 7 */ 489 if (VSC9953_INTERNAL_PORT_CHECK(i)) { 490 out_le32(&l2ana_reg->pfc[i].pfc_cfg, 491 VSC9953_PFC_FC_QSGMII); 492 out_le32(&l2sys_reg->pause_cfg.mac_fc_cfg[i], 493 VSC9953_MAC_FC_CFG_QSGMII); 494 } else { 495 out_le32(&l2ana_reg->pfc[i].pfc_cfg, 496 VSC9953_PFC_FC); 497 out_le32(&l2sys_reg->pause_cfg.mac_fc_cfg[i], 498 VSC9953_MAC_FC_CFG); 499 } 500 out_le32(&l2dev_gmii_reg->port_mode.clock_cfg, 501 VSC9953_CLOCK_CFG); 502 out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_ena_cfg, 503 VSC9953_MAC_ENA_CFG); 504 out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_mode_cfg, 505 VSC9953_MAC_MODE_CFG); 506 out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_ifg_cfg, 507 VSC9953_MAC_IFG_CFG); 508 /* mac_hdx_cfg varies with port id*/ 509 hdx_cfg = VSC9953_MAC_HDX_CFG | (i << 16); 510 out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_hdx_cfg, hdx_cfg); 511 out_le32(&l2sys_reg->sys.front_port_mode[i], 512 VSC9953_FRONT_PORT_MODE); 513 setbits_le32(&l2qsys_reg->sys.switch_port_mode[i], 514 VSC9953_PORT_ENA); 515 out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_maxlen_cfg, 516 VSC9953_MAC_MAX_LEN); 517 out_le32(&l2sys_reg->pause_cfg.pause_cfg[i], 518 VSC9953_PAUSE_CFG); 519 /* WAIT FOR 2 us*/ 520 udelay(2); 521 522 l2dev_gmii_reg = (struct vsc9953_dev_gmii *)( 523 (char *)l2dev_gmii_reg 524 + T1040_SWITCH_GMII_DEV_OFFSET); 525 526 /* Initialize Lynx PHY Wrappers */ 527 phy_addr = 0; 528 if (vsc9953_l2sw.port[i].enet_if == 529 PHY_INTERFACE_MODE_QSGMII) 530 phy_addr = (i + 0x4) & 0x1F; 531 else if (vsc9953_l2sw.port[i].enet_if == 532 PHY_INTERFACE_MODE_SGMII) 533 phy_addr = (i + 1) & 0x1F; 534 535 if (phy_addr) { 536 /* SGMII IF mode + AN enable */ 537 vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, 538 0x14, PHY_SGMII_IF_MODE_AN | 539 PHY_SGMII_IF_MODE_SGMII); 540 /* Dev ability according to SGMII specification */ 541 vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, 542 0x4, PHY_SGMII_DEV_ABILITY_SGMII); 543 /* Adjust link timer for SGMII 544 * 1.6 ms in units of 8 ns = 2 * 10^5 = 0x30d40 545 */ 546 vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, 547 0x13, 0x0003); 548 vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, 549 0x12, 0x0d40); 550 /* Restart AN */ 551 vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, 552 0x0, PHY_SGMII_CR_DEF_VAL | 553 PHY_SGMII_CR_RESET_AN); 554 555 timeout = 50000; 556 while ((vsc9953_mdio_read(&l2dev_gcb->mii_mng[0], 557 phy_addr, 0x01) & 0x0020) && --timeout) 558 udelay(1); /* wait for AN to complete */ 559 if (timeout == 0) 560 debug("Timeout waiting for AN to complete\n"); 561 } 562 } 563 564 vsc9953_default_configuration(); 565 566 printf("VSC9953 L2 switch initialized\n"); 567 return; 568 } 569 570 #ifdef CONFIG_VSC9953_CMD 571 /* Enable/disable status of a VSC9953 port */ 572 static void vsc9953_port_status_set(int port_no, u8 enabled) 573 { 574 struct vsc9953_qsys_reg *l2qsys_reg; 575 576 /* Administrative down */ 577 if (!vsc9953_l2sw.port[port_no].enabled) 578 return; 579 580 l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET + 581 VSC9953_QSYS_OFFSET); 582 583 if (enabled) 584 setbits_le32(&l2qsys_reg->sys.switch_port_mode[port_no], 585 VSC9953_PORT_ENA); 586 else 587 clrbits_le32(&l2qsys_reg->sys.switch_port_mode[port_no], 588 VSC9953_PORT_ENA); 589 } 590 591 /* Set all VSC9953 ports' status */ 592 static void vsc9953_port_all_status_set(u8 enabled) 593 { 594 int i; 595 596 for (i = 0; i < VSC9953_MAX_PORTS; i++) 597 vsc9953_port_status_set(i, enabled); 598 } 599 600 /* Start autonegotiation for a VSC9953 PHY */ 601 static void vsc9953_phy_autoneg(int port_no) 602 { 603 if (!vsc9953_l2sw.port[port_no].phydev) 604 return; 605 606 if (vsc9953_l2sw.port[port_no].phydev->drv->startup( 607 vsc9953_l2sw.port[port_no].phydev)) 608 printf("Failed to start PHY for port %d\n", port_no); 609 } 610 611 /* Start autonegotiation for all VSC9953 PHYs */ 612 static void vsc9953_phy_all_autoneg(void) 613 { 614 int i; 615 616 for (i = 0; i < VSC9953_MAX_PORTS; i++) 617 vsc9953_phy_autoneg(i); 618 } 619 620 /* Print a VSC9953 port's configuration */ 621 static void vsc9953_port_config_show(int port_no) 622 { 623 int speed; 624 int duplex; 625 int link; 626 u8 enabled; 627 u32 val; 628 struct vsc9953_qsys_reg *l2qsys_reg; 629 630 l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET + 631 VSC9953_QSYS_OFFSET); 632 633 val = in_le32(&l2qsys_reg->sys.switch_port_mode[port_no]); 634 enabled = vsc9953_l2sw.port[port_no].enabled && 635 (val & VSC9953_PORT_ENA); 636 637 /* internal ports (8 and 9) are fixed */ 638 if (VSC9953_INTERNAL_PORT_CHECK(port_no)) { 639 link = 1; 640 speed = SPEED_2500; 641 duplex = DUPLEX_FULL; 642 } else { 643 if (vsc9953_l2sw.port[port_no].phydev) { 644 link = vsc9953_l2sw.port[port_no].phydev->link; 645 speed = vsc9953_l2sw.port[port_no].phydev->speed; 646 duplex = vsc9953_l2sw.port[port_no].phydev->duplex; 647 } else { 648 link = -1; 649 speed = -1; 650 duplex = -1; 651 } 652 } 653 654 printf("%8d ", port_no); 655 printf("%8s ", enabled == 1 ? "enabled" : "disabled"); 656 printf("%8s ", link == 1 ? "up" : "down"); 657 658 switch (speed) { 659 case SPEED_10: 660 printf("%8d ", 10); 661 break; 662 case SPEED_100: 663 printf("%8d ", 100); 664 break; 665 case SPEED_1000: 666 printf("%8d ", 1000); 667 break; 668 case SPEED_2500: 669 printf("%8d ", 2500); 670 break; 671 case SPEED_10000: 672 printf("%8d ", 10000); 673 break; 674 default: 675 printf("%8s ", "-"); 676 } 677 678 printf("%8s\n", duplex == DUPLEX_FULL ? "full" : "half"); 679 } 680 681 /* Print VSC9953 ports' configuration */ 682 static void vsc9953_port_all_config_show(void) 683 { 684 int i; 685 686 for (i = 0; i < VSC9953_MAX_PORTS; i++) 687 vsc9953_port_config_show(i); 688 } 689 690 /* function to interpret commands starting with "ethsw " */ 691 static int do_ethsw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 692 { 693 u8 enable; 694 u32 port; 695 696 if (argc < 4) 697 return -1; 698 699 if (strcmp(argv[1], "port")) 700 return -1; 701 702 if (!strcmp(argv[3], "show")) { 703 if (!strcmp(argv[2], "all")) { 704 vsc9953_phy_all_autoneg(); 705 printf("%8s %8s %8s %8s %8s\n", 706 "Port", "Status", "Link", "Speed", 707 "Duplex"); 708 vsc9953_port_all_config_show(); 709 return 0; 710 } else { 711 port = simple_strtoul(argv[2], NULL, 10); 712 if (!VSC9953_PORT_CHECK(port)) 713 return -1; 714 vsc9953_phy_autoneg(port); 715 printf("%8s %8s %8s %8s %8s\n", 716 "Port", "Status", "Link", "Speed", 717 "Duplex"); 718 vsc9953_port_config_show(port); 719 return 0; 720 } 721 } else if (!strcmp(argv[3], "enable")) { 722 enable = 1; 723 } else if (!strcmp(argv[3], "disable")) { 724 enable = 0; 725 } else { 726 return -1; 727 } 728 729 if (!strcmp(argv[2], "all")) { 730 vsc9953_port_all_status_set(enable); 731 return 0; 732 } else { 733 port = simple_strtoul(argv[2], NULL, 10); 734 if (!VSC9953_PORT_CHECK(port)) 735 return -1; 736 vsc9953_port_status_set(port, enable); 737 return 0; 738 } 739 740 return -1; 741 } 742 743 U_BOOT_CMD(ethsw, 5, 0, do_ethsw, 744 "vsc9953 l2 switch commands", 745 "port <port_no> enable|disable\n" 746 " - enable/disable an l2 switch port\n" 747 " port_no=0..9; use \"all\" for all ports\n" 748 "ethsw port <port_no> show\n" 749 " - show an l2 switch port's configuration\n" 750 " port_no=0..9; use \"all\" for all ports\n" 751 ); 752 #endif /* CONFIG_VSC9953_CMD */ 753