1 /* 2 * Copyright 2014 - 2015 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 #include <ethsw.h> 18 19 static struct vsc9953_info vsc9953_l2sw = { 20 .port[0] = VSC9953_PORT_INFO_INITIALIZER(0), 21 .port[1] = VSC9953_PORT_INFO_INITIALIZER(1), 22 .port[2] = VSC9953_PORT_INFO_INITIALIZER(2), 23 .port[3] = VSC9953_PORT_INFO_INITIALIZER(3), 24 .port[4] = VSC9953_PORT_INFO_INITIALIZER(4), 25 .port[5] = VSC9953_PORT_INFO_INITIALIZER(5), 26 .port[6] = VSC9953_PORT_INFO_INITIALIZER(6), 27 .port[7] = VSC9953_PORT_INFO_INITIALIZER(7), 28 .port[8] = VSC9953_PORT_INFO_INITIALIZER(8), 29 .port[9] = VSC9953_PORT_INFO_INITIALIZER(9), 30 }; 31 32 void vsc9953_port_info_set_mdio(int port_no, struct mii_dev *bus) 33 { 34 if (!VSC9953_PORT_CHECK(port_no)) 35 return; 36 37 vsc9953_l2sw.port[port_no].bus = bus; 38 } 39 40 void vsc9953_port_info_set_phy_address(int port_no, int address) 41 { 42 if (!VSC9953_PORT_CHECK(port_no)) 43 return; 44 45 vsc9953_l2sw.port[port_no].phyaddr = address; 46 } 47 48 void vsc9953_port_info_set_phy_int(int port_no, phy_interface_t phy_int) 49 { 50 if (!VSC9953_PORT_CHECK(port_no)) 51 return; 52 53 vsc9953_l2sw.port[port_no].enet_if = phy_int; 54 } 55 56 void vsc9953_port_enable(int port_no) 57 { 58 if (!VSC9953_PORT_CHECK(port_no)) 59 return; 60 61 vsc9953_l2sw.port[port_no].enabled = 1; 62 } 63 64 void vsc9953_port_disable(int port_no) 65 { 66 if (!VSC9953_PORT_CHECK(port_no)) 67 return; 68 69 vsc9953_l2sw.port[port_no].enabled = 0; 70 } 71 72 static void vsc9953_mdio_write(struct vsc9953_mii_mng *phyregs, int port_addr, 73 int regnum, int value) 74 { 75 int timeout = 50000; 76 77 out_le32(&phyregs->miimcmd, (0x1 << 31) | ((port_addr & 0x1f) << 25) | 78 ((regnum & 0x1f) << 20) | ((value & 0xffff) << 4) | 79 (0x1 << 1)); 80 asm("sync"); 81 82 while ((in_le32(&phyregs->miimstatus) & 0x8) && --timeout) 83 udelay(1); 84 85 if (timeout == 0) 86 debug("Timeout waiting for MDIO write\n"); 87 } 88 89 static int vsc9953_mdio_read(struct vsc9953_mii_mng *phyregs, int port_addr, 90 int regnum) 91 { 92 int value = 0xFFFF; 93 int timeout = 50000; 94 95 while ((in_le32(&phyregs->miimstatus) & MIIMIND_OPR_PEND) && --timeout) 96 udelay(1); 97 if (timeout == 0) { 98 debug("Timeout waiting for MDIO operation to finish\n"); 99 return value; 100 } 101 102 /* Put the address of the phy, and the register 103 * number into MIICMD 104 */ 105 out_le32(&phyregs->miimcmd, (0x1 << 31) | ((port_addr & 0x1f) << 25) | 106 ((regnum & 0x1f) << 20) | ((value & 0xffff) << 4) | 107 (0x2 << 1)); 108 109 timeout = 50000; 110 /* Wait for the the indication that the read is done */ 111 while ((in_le32(&phyregs->miimstatus) & 0x8) && --timeout) 112 udelay(1); 113 if (timeout == 0) 114 debug("Timeout waiting for MDIO read\n"); 115 116 /* Grab the value read from the PHY */ 117 value = in_le32(&phyregs->miimdata); 118 119 if ((value & 0x00030000) == 0) 120 return value & 0x0000ffff; 121 122 return value; 123 } 124 125 static int init_phy(struct eth_device *dev) 126 { 127 struct vsc9953_port_info *l2sw_port = dev->priv; 128 struct phy_device *phydev = NULL; 129 130 #ifdef CONFIG_PHYLIB 131 if (!l2sw_port->bus) 132 return 0; 133 phydev = phy_connect(l2sw_port->bus, l2sw_port->phyaddr, dev, 134 l2sw_port->enet_if); 135 if (!phydev) { 136 printf("Failed to connect\n"); 137 return -1; 138 } 139 140 phydev->supported &= SUPPORTED_10baseT_Half | 141 SUPPORTED_10baseT_Full | 142 SUPPORTED_100baseT_Half | 143 SUPPORTED_100baseT_Full | 144 SUPPORTED_1000baseT_Full; 145 phydev->advertising = phydev->supported; 146 147 l2sw_port->phydev = phydev; 148 149 phy_config(phydev); 150 #endif 151 152 return 0; 153 } 154 155 static int vsc9953_port_init(int port_no) 156 { 157 struct eth_device *dev; 158 159 /* Internal ports never have a PHY */ 160 if (VSC9953_INTERNAL_PORT_CHECK(port_no)) 161 return 0; 162 163 /* alloc eth device */ 164 dev = (struct eth_device *)calloc(1, sizeof(struct eth_device)); 165 if (!dev) 166 return -ENOMEM; 167 168 sprintf(dev->name, "SW@PORT%d", port_no); 169 dev->priv = &vsc9953_l2sw.port[port_no]; 170 dev->init = NULL; 171 dev->halt = NULL; 172 dev->send = NULL; 173 dev->recv = NULL; 174 175 if (init_phy(dev)) { 176 free(dev); 177 return -ENODEV; 178 } 179 180 return 0; 181 } 182 183 static int vsc9953_vlan_table_poll_idle(void) 184 { 185 struct vsc9953_analyzer *l2ana_reg; 186 int timeout; 187 188 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 189 VSC9953_ANA_OFFSET); 190 191 timeout = 50000; 192 while (((in_le32(&l2ana_reg->ana_tables.vlan_access) & 193 VSC9953_VLAN_CMD_MASK) != VSC9953_VLAN_CMD_IDLE) && --timeout) 194 udelay(1); 195 196 return timeout ? 0 : -EBUSY; 197 } 198 199 #ifdef CONFIG_CMD_ETHSW 200 /* Add/remove a port to/from a VLAN */ 201 static void vsc9953_vlan_table_membership_set(int vid, u32 port_no, u8 add) 202 { 203 u32 val; 204 struct vsc9953_analyzer *l2ana_reg; 205 206 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 207 VSC9953_ANA_OFFSET); 208 209 if (vsc9953_vlan_table_poll_idle() < 0) { 210 debug("VLAN table timeout\n"); 211 return; 212 } 213 214 val = in_le32(&l2ana_reg->ana_tables.vlan_tidx); 215 val = bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK, vid); 216 out_le32(&l2ana_reg->ana_tables.vlan_tidx, val); 217 218 clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access, 219 VSC9953_VLAN_CMD_MASK, VSC9953_VLAN_CMD_READ); 220 221 if (vsc9953_vlan_table_poll_idle() < 0) { 222 debug("VLAN table timeout\n"); 223 return; 224 } 225 226 val = in_le32(&l2ana_reg->ana_tables.vlan_tidx); 227 val = bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK, vid); 228 out_le32(&l2ana_reg->ana_tables.vlan_tidx, val); 229 230 val = in_le32(&l2ana_reg->ana_tables.vlan_access); 231 if (!add) { 232 val = bitfield_replace_by_mask(val, VSC9953_VLAN_CMD_MASK, 233 VSC9953_VLAN_CMD_WRITE) & 234 ~(bitfield_replace_by_mask(0, VSC9953_VLAN_PORT_MASK, 235 (1 << port_no))); 236 ; 237 } else { 238 val = bitfield_replace_by_mask(val, VSC9953_VLAN_CMD_MASK, 239 VSC9953_VLAN_CMD_WRITE) | 240 bitfield_replace_by_mask(0, VSC9953_VLAN_PORT_MASK, 241 (1 << port_no)); 242 } 243 out_le32(&l2ana_reg->ana_tables.vlan_access, val); 244 245 /* wait for VLAN table command to flush */ 246 if (vsc9953_vlan_table_poll_idle() < 0) { 247 debug("VLAN table timeout\n"); 248 return; 249 } 250 } 251 252 /* show VLAN membership for a port */ 253 static void vsc9953_vlan_membership_show(int port_no) 254 { 255 u32 val; 256 struct vsc9953_analyzer *l2ana_reg; 257 u32 vid; 258 259 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 260 VSC9953_ANA_OFFSET); 261 262 printf("Port %d VLAN membership: ", port_no); 263 264 for (vid = 0; vid < VSC9953_MAX_VLAN; vid++) { 265 if (vsc9953_vlan_table_poll_idle() < 0) { 266 debug("VLAN table timeout\n"); 267 return; 268 } 269 270 val = in_le32(&l2ana_reg->ana_tables.vlan_tidx); 271 val = bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK, 272 vid); 273 out_le32(&l2ana_reg->ana_tables.vlan_tidx, val); 274 275 clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access, 276 VSC9953_VLAN_CMD_MASK, VSC9953_VLAN_CMD_READ); 277 278 if (vsc9953_vlan_table_poll_idle() < 0) { 279 debug("VLAN table timeout\n"); 280 return; 281 } 282 283 val = in_le32(&l2ana_reg->ana_tables.vlan_access); 284 285 if (bitfield_extract_by_mask(val, VSC9953_VLAN_PORT_MASK) & 286 (1 << port_no)) 287 printf("%d ", vid); 288 } 289 printf("\n"); 290 } 291 #endif 292 293 /* vlan table set/clear all membership of vid */ 294 static void vsc9953_vlan_table_membership_all_set(int vid, int set_member) 295 { 296 uint val; 297 struct vsc9953_analyzer *l2ana_reg; 298 299 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 300 VSC9953_ANA_OFFSET); 301 302 if (vsc9953_vlan_table_poll_idle() < 0) { 303 debug("VLAN table timeout\n"); 304 return; 305 } 306 307 /* read current vlan configuration */ 308 val = in_le32(&l2ana_reg->ana_tables.vlan_tidx); 309 out_le32(&l2ana_reg->ana_tables.vlan_tidx, 310 bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK, vid)); 311 312 clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access, 313 VSC9953_VLAN_CMD_MASK, VSC9953_VLAN_CMD_READ); 314 315 if (vsc9953_vlan_table_poll_idle() < 0) { 316 debug("VLAN table timeout\n"); 317 return; 318 } 319 320 val = in_le32(&l2ana_reg->ana_tables.vlan_tidx); 321 out_le32(&l2ana_reg->ana_tables.vlan_tidx, 322 bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK, vid)); 323 324 clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access, 325 VSC9953_VLAN_PORT_MASK | VSC9953_VLAN_CMD_MASK, 326 VSC9953_VLAN_CMD_WRITE | 327 (set_member ? VSC9953_VLAN_PORT_MASK : 0)); 328 } 329 330 #ifdef CONFIG_CMD_ETHSW 331 /* Get PVID of a VSC9953 port */ 332 static int vsc9953_port_vlan_pvid_get(int port_nr, int *pvid) 333 { 334 u32 val; 335 struct vsc9953_analyzer *l2ana_reg; 336 337 /* Administrative down */ 338 if (vsc9953_l2sw.port[port_nr].enabled) { 339 printf("Port %d is administrative down\n", port_nr); 340 return -1; 341 } 342 343 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 344 VSC9953_ANA_OFFSET); 345 346 /* Get ingress PVID */ 347 val = in_le32(&l2ana_reg->port[port_nr].vlan_cfg); 348 *pvid = bitfield_extract_by_mask(val, VSC9953_VLAN_CFG_VID_MASK); 349 350 return 0; 351 } 352 #endif 353 354 /* Set PVID for a VSC9953 port */ 355 static void vsc9953_port_vlan_pvid_set(int port_no, int pvid) 356 { 357 uint val; 358 struct vsc9953_analyzer *l2ana_reg; 359 struct vsc9953_rew_reg *l2rew_reg; 360 361 /* Administrative down */ 362 if (!vsc9953_l2sw.port[port_no].enabled) { 363 printf("Port %d is administrative down\n", port_no); 364 return; 365 } 366 367 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 368 VSC9953_ANA_OFFSET); 369 l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET + 370 VSC9953_REW_OFFSET); 371 372 /* Set PVID on ingress */ 373 val = in_le32(&l2ana_reg->port[port_no].vlan_cfg); 374 val = bitfield_replace_by_mask(val, VSC9953_VLAN_CFG_VID_MASK, pvid); 375 out_le32(&l2ana_reg->port[port_no].vlan_cfg, val); 376 377 /* Set PVID on egress */ 378 val = in_le32(&l2rew_reg->port[port_no].port_vlan_cfg); 379 val = bitfield_replace_by_mask(val, VSC9953_PORT_VLAN_CFG_VID_MASK, 380 pvid); 381 out_le32(&l2rew_reg->port[port_no].port_vlan_cfg, val); 382 } 383 384 static void vsc9953_port_all_vlan_pvid_set(int pvid) 385 { 386 int i; 387 388 for (i = 0; i < VSC9953_MAX_PORTS; i++) 389 vsc9953_port_vlan_pvid_set(i, pvid); 390 } 391 392 /* Enable/disable vlan aware of a VSC9953 port */ 393 static void vsc9953_port_vlan_aware_set(int port_no, int enabled) 394 { 395 struct vsc9953_analyzer *l2ana_reg; 396 397 /* Administrative down */ 398 if (!vsc9953_l2sw.port[port_no].enabled) { 399 printf("Port %d is administrative down\n", port_no); 400 return; 401 } 402 403 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 404 VSC9953_ANA_OFFSET); 405 406 if (enabled) 407 setbits_le32(&l2ana_reg->port[port_no].vlan_cfg, 408 VSC9953_VLAN_CFG_AWARE_ENA); 409 else 410 clrbits_le32(&l2ana_reg->port[port_no].vlan_cfg, 411 VSC9953_VLAN_CFG_AWARE_ENA); 412 } 413 414 /* Set all VSC9953 ports' vlan aware */ 415 static void vsc9953_port_all_vlan_aware_set(int enabled) 416 { 417 int i; 418 419 for (i = 0; i < VSC9953_MAX_PORTS; i++) 420 vsc9953_port_vlan_aware_set(i, enabled); 421 } 422 423 /* Enable/disable vlan pop count of a VSC9953 port */ 424 static void vsc9953_port_vlan_popcnt_set(int port_no, int popcnt) 425 { 426 uint val; 427 struct vsc9953_analyzer *l2ana_reg; 428 429 /* Administrative down */ 430 if (!vsc9953_l2sw.port[port_no].enabled) { 431 printf("Port %d is administrative down\n", port_no); 432 return; 433 } 434 435 if (popcnt > 3 || popcnt < 0) { 436 printf("Invalid pop count value: %d\n", port_no); 437 return; 438 } 439 440 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 441 VSC9953_ANA_OFFSET); 442 443 val = in_le32(&l2ana_reg->port[port_no].vlan_cfg); 444 val = bitfield_replace_by_mask(val, VSC9953_VLAN_CFG_POP_CNT_MASK, 445 popcnt); 446 out_le32(&l2ana_reg->port[port_no].vlan_cfg, val); 447 } 448 449 /* Set all VSC9953 ports' pop count */ 450 static void vsc9953_port_all_vlan_poncnt_set(int popcnt) 451 { 452 int i; 453 454 for (i = 0; i < VSC9953_MAX_PORTS; i++) 455 vsc9953_port_vlan_popcnt_set(i, popcnt); 456 } 457 458 /* Enable/disable learning for frames dropped due to ingress filtering */ 459 static void vsc9953_vlan_ingr_fltr_learn_drop(int enable) 460 { 461 struct vsc9953_analyzer *l2ana_reg; 462 463 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 464 VSC9953_ANA_OFFSET); 465 466 if (enable) 467 setbits_le32(&l2ana_reg->ana.adv_learn, VSC9953_VLAN_CHK); 468 else 469 clrbits_le32(&l2ana_reg->ana.adv_learn, VSC9953_VLAN_CHK); 470 } 471 472 /* Egress untag modes of a VSC9953 port */ 473 enum egress_untag_mode { 474 EGRESS_UNTAG_ALL = 0, 475 EGRESS_UNTAG_PVID_AND_ZERO, 476 EGRESS_UNTAG_ZERO, 477 EGRESS_UNTAG_NONE, 478 }; 479 480 #ifdef CONFIG_CMD_ETHSW 481 /* Get egress tagging configuration for a VSC9953 port */ 482 static int vsc9953_port_vlan_egr_untag_get(int port_no, 483 enum egress_untag_mode *mode) 484 { 485 u32 val; 486 struct vsc9953_rew_reg *l2rew_reg; 487 488 /* Administrative down */ 489 if (!vsc9953_l2sw.port[port_no].enabled) { 490 printf("Port %d is administrative down\n", port_no); 491 return -1; 492 } 493 494 l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET + 495 VSC9953_REW_OFFSET); 496 497 val = in_le32(&l2rew_reg->port[port_no].port_tag_cfg); 498 499 switch (val & VSC9953_TAG_CFG_MASK) { 500 case VSC9953_TAG_CFG_NONE: 501 *mode = EGRESS_UNTAG_ALL; 502 return 0; 503 case VSC9953_TAG_CFG_ALL_BUT_PVID_ZERO: 504 *mode = EGRESS_UNTAG_PVID_AND_ZERO; 505 return 0; 506 case VSC9953_TAG_CFG_ALL_BUT_ZERO: 507 *mode = EGRESS_UNTAG_ZERO; 508 return 0; 509 case VSC9953_TAG_CFG_ALL: 510 *mode = EGRESS_UNTAG_NONE; 511 return 0; 512 default: 513 printf("Unknown egress tagging configuration for port %d\n", 514 port_no); 515 return -1; 516 } 517 } 518 519 /* Show egress tagging configuration for a VSC9953 port */ 520 static void vsc9953_port_vlan_egr_untag_show(int port_no) 521 { 522 enum egress_untag_mode mode; 523 524 if (vsc9953_port_vlan_egr_untag_get(port_no, &mode)) { 525 printf("%7d\t%17s\n", port_no, "-"); 526 return; 527 } 528 529 printf("%7d\t", port_no); 530 switch (mode) { 531 case EGRESS_UNTAG_ALL: 532 printf("%17s\n", "all"); 533 break; 534 case EGRESS_UNTAG_NONE: 535 printf("%17s\n", "none"); 536 break; 537 case EGRESS_UNTAG_PVID_AND_ZERO: 538 printf("%17s\n", "PVID and 0"); 539 break; 540 case EGRESS_UNTAG_ZERO: 541 printf("%17s\n", "0"); 542 break; 543 default: 544 printf("%17s\n", "-"); 545 } 546 } 547 #endif 548 549 static void vsc9953_port_vlan_egr_untag_set(int port_no, 550 enum egress_untag_mode mode) 551 { 552 struct vsc9953_rew_reg *l2rew_reg; 553 554 /* Administrative down */ 555 if (!vsc9953_l2sw.port[port_no].enabled) { 556 printf("Port %d is administrative down\n", port_no); 557 return; 558 } 559 560 l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET + 561 VSC9953_REW_OFFSET); 562 563 switch (mode) { 564 case EGRESS_UNTAG_ALL: 565 clrsetbits_le32(&l2rew_reg->port[port_no].port_tag_cfg, 566 VSC9953_TAG_CFG_MASK, VSC9953_TAG_CFG_NONE); 567 break; 568 case EGRESS_UNTAG_PVID_AND_ZERO: 569 clrsetbits_le32(&l2rew_reg->port[port_no].port_tag_cfg, 570 VSC9953_TAG_CFG_MASK, 571 VSC9953_TAG_CFG_ALL_BUT_PVID_ZERO); 572 break; 573 case EGRESS_UNTAG_ZERO: 574 clrsetbits_le32(&l2rew_reg->port[port_no].port_tag_cfg, 575 VSC9953_TAG_CFG_MASK, 576 VSC9953_TAG_CFG_ALL_BUT_ZERO); 577 break; 578 case EGRESS_UNTAG_NONE: 579 clrsetbits_le32(&l2rew_reg->port[port_no].port_tag_cfg, 580 VSC9953_TAG_CFG_MASK, VSC9953_TAG_CFG_ALL); 581 break; 582 default: 583 printf("Unknown untag mode for port %d\n", port_no); 584 } 585 } 586 587 static void vsc9953_port_all_vlan_egress_untagged_set( 588 enum egress_untag_mode mode) 589 { 590 int i; 591 592 for (i = 0; i < VSC9953_MAX_PORTS; i++) 593 vsc9953_port_vlan_egr_untag_set(i, mode); 594 } 595 596 static int vsc9953_autoage_time_set(int age_period) 597 { 598 u32 autoage; 599 struct vsc9953_analyzer *l2ana_reg; 600 601 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 602 VSC9953_ANA_OFFSET); 603 604 if (age_period < 0 || age_period > VSC9953_AUTOAGE_PERIOD_MASK) 605 return -EINVAL; 606 607 autoage = bitfield_replace_by_mask(in_le32(&l2ana_reg->ana.auto_age), 608 VSC9953_AUTOAGE_PERIOD_MASK, 609 age_period); 610 out_le32(&l2ana_reg->ana.auto_age, autoage); 611 612 return 0; 613 } 614 615 #ifdef CONFIG_CMD_ETHSW 616 617 /* Enable/disable status of a VSC9953 port */ 618 static void vsc9953_port_status_set(int port_no, u8 enabled) 619 { 620 struct vsc9953_qsys_reg *l2qsys_reg; 621 622 /* Administrative down */ 623 if (!vsc9953_l2sw.port[port_no].enabled) 624 return; 625 626 l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET + 627 VSC9953_QSYS_OFFSET); 628 629 if (enabled) 630 setbits_le32(&l2qsys_reg->sys.switch_port_mode[port_no], 631 VSC9953_PORT_ENA); 632 else 633 clrbits_le32(&l2qsys_reg->sys.switch_port_mode[port_no], 634 VSC9953_PORT_ENA); 635 } 636 637 /* Start autonegotiation for a VSC9953 PHY */ 638 static void vsc9953_phy_autoneg(int port_no) 639 { 640 if (!vsc9953_l2sw.port[port_no].phydev) 641 return; 642 643 if (vsc9953_l2sw.port[port_no].phydev->drv->startup( 644 vsc9953_l2sw.port[port_no].phydev)) 645 printf("Failed to start PHY for port %d\n", port_no); 646 } 647 648 /* Print a VSC9953 port's configuration */ 649 static void vsc9953_port_config_show(int port_no) 650 { 651 int speed; 652 int duplex; 653 int link; 654 u8 enabled; 655 u32 val; 656 struct vsc9953_qsys_reg *l2qsys_reg; 657 658 l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET + 659 VSC9953_QSYS_OFFSET); 660 661 val = in_le32(&l2qsys_reg->sys.switch_port_mode[port_no]); 662 enabled = vsc9953_l2sw.port[port_no].enabled && 663 (val & VSC9953_PORT_ENA); 664 665 /* internal ports (8 and 9) are fixed */ 666 if (VSC9953_INTERNAL_PORT_CHECK(port_no)) { 667 link = 1; 668 speed = SPEED_2500; 669 duplex = DUPLEX_FULL; 670 } else { 671 if (vsc9953_l2sw.port[port_no].phydev) { 672 link = vsc9953_l2sw.port[port_no].phydev->link; 673 speed = vsc9953_l2sw.port[port_no].phydev->speed; 674 duplex = vsc9953_l2sw.port[port_no].phydev->duplex; 675 } else { 676 link = -1; 677 speed = -1; 678 duplex = -1; 679 } 680 } 681 682 printf("%8d ", port_no); 683 printf("%8s ", enabled == 1 ? "enabled" : "disabled"); 684 printf("%8s ", link == 1 ? "up" : "down"); 685 686 switch (speed) { 687 case SPEED_10: 688 printf("%8d ", 10); 689 break; 690 case SPEED_100: 691 printf("%8d ", 100); 692 break; 693 case SPEED_1000: 694 printf("%8d ", 1000); 695 break; 696 case SPEED_2500: 697 printf("%8d ", 2500); 698 break; 699 case SPEED_10000: 700 printf("%8d ", 10000); 701 break; 702 default: 703 printf("%8s ", "-"); 704 } 705 706 printf("%8s\n", duplex == DUPLEX_FULL ? "full" : "half"); 707 } 708 709 /* Show VSC9953 ports' statistics */ 710 static void vsc9953_port_statistics_show(int port_no) 711 { 712 u32 rx_val; 713 u32 tx_val; 714 struct vsc9953_system_reg *l2sys_reg; 715 716 /* Administrative down */ 717 if (!vsc9953_l2sw.port[port_no].enabled) { 718 printf("Port %d is administrative down\n", port_no); 719 return; 720 } 721 722 l2sys_reg = (struct vsc9953_system_reg *)(VSC9953_OFFSET + 723 VSC9953_SYS_OFFSET); 724 725 printf("Statistics for L2 Switch port %d:\n", port_no); 726 727 /* Set counter view for our port */ 728 out_le32(&l2sys_reg->sys.stat_cfg, port_no); 729 730 #define VSC9953_STATS_PRINTF "%-15s %10u" 731 732 /* Get number of Rx and Tx frames */ 733 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_short) + 734 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_frag) + 735 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_jabber) + 736 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_long) + 737 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_64) + 738 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_65_127) + 739 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_128_255) + 740 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_256_511) + 741 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_512_1023) + 742 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_1024_1526) + 743 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_jumbo); 744 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_64) + 745 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_65_127) + 746 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_128_255) + 747 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_256_511) + 748 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_512_1023) + 749 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_1024_1526) + 750 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_jumbo); 751 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", 752 "Rx frames:", rx_val, "Tx frames:", tx_val); 753 754 /* Get number of Rx and Tx bytes */ 755 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_oct); 756 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_oct); 757 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", 758 "Rx bytes:", rx_val, "Tx bytes:", tx_val); 759 760 /* Get number of Rx frames received ok and Tx frames sent ok */ 761 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_0) + 762 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_1) + 763 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_2) + 764 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_3) + 765 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_4) + 766 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_5) + 767 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_6) + 768 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_7) + 769 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_0) + 770 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_1) + 771 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_2) + 772 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_3) + 773 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_4) + 774 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_5) + 775 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_6) + 776 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_7); 777 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_64) + 778 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_65_127) + 779 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_128_255) + 780 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_256_511) + 781 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_512_1023) + 782 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_1024_1526) + 783 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_jumbo); 784 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", 785 "Rx frames ok:", rx_val, "Tx frames ok:", tx_val); 786 787 /* Get number of Rx and Tx unicast frames */ 788 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_uc); 789 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_uc); 790 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", 791 "Rx unicast:", rx_val, "Tx unicast:", tx_val); 792 793 /* Get number of Rx and Tx broadcast frames */ 794 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_bc); 795 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_bc); 796 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", 797 "Rx broadcast:", rx_val, "Tx broadcast:", tx_val); 798 799 /* Get number of Rx and Tx frames of 64B */ 800 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_64); 801 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_64); 802 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", 803 "Rx 64B:", rx_val, "Tx 64B:", tx_val); 804 805 /* Get number of Rx and Tx frames with sizes between 65B and 127B */ 806 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_65_127); 807 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_65_127); 808 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", 809 "Rx 65B-127B:", rx_val, "Tx 65B-127B:", tx_val); 810 811 /* Get number of Rx and Tx frames with sizes between 128B and 255B */ 812 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_128_255); 813 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_128_255); 814 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", 815 "Rx 128B-255B:", rx_val, "Tx 128B-255B:", tx_val); 816 817 /* Get number of Rx and Tx frames with sizes between 256B and 511B */ 818 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_256_511); 819 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_256_511); 820 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", 821 "Rx 256B-511B:", rx_val, "Tx 256B-511B:", tx_val); 822 823 /* Get number of Rx and Tx frames with sizes between 512B and 1023B */ 824 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_512_1023); 825 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_512_1023); 826 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", 827 "Rx 512B-1023B:", rx_val, "Tx 512B-1023B:", tx_val); 828 829 /* Get number of Rx and Tx frames with sizes between 1024B and 1526B */ 830 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_1024_1526); 831 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_1024_1526); 832 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", 833 "Rx 1024B-1526B:", rx_val, "Tx 1024B-1526B:", tx_val); 834 835 /* Get number of Rx and Tx jumbo frames */ 836 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_jumbo); 837 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_jumbo); 838 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", 839 "Rx jumbo:", rx_val, "Tx jumbo:", tx_val); 840 841 /* Get number of Rx and Tx dropped frames */ 842 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_cat_drop) + 843 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_tail) + 844 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_0) + 845 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_1) + 846 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_2) + 847 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_3) + 848 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_4) + 849 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_5) + 850 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_6) + 851 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_7) + 852 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_0) + 853 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_1) + 854 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_2) + 855 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_3) + 856 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_4) + 857 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_5) + 858 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_6) + 859 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_7); 860 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_drop) + 861 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_aged); 862 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", 863 "Rx drops:", rx_val, "Tx drops:", tx_val); 864 865 /* 866 * Get number of Rx frames with CRC or alignment errors 867 * and number of detected Tx collisions 868 */ 869 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_crc); 870 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_col); 871 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", 872 "Rx CRC&align:", rx_val, "Tx coll:", tx_val); 873 874 /* 875 * Get number of Rx undersized frames and 876 * number of Tx aged frames 877 */ 878 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_short); 879 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_aged); 880 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", 881 "Rx undersize:", rx_val, "Tx aged:", tx_val); 882 883 /* Get number of Rx oversized frames */ 884 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_long); 885 printf(VSC9953_STATS_PRINTF"\n", "Rx oversized:", rx_val); 886 887 /* Get number of Rx fragmented frames */ 888 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_frag); 889 printf(VSC9953_STATS_PRINTF"\n", "Rx fragments:", rx_val); 890 891 /* Get number of Rx jabber errors */ 892 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_jabber); 893 printf(VSC9953_STATS_PRINTF"\n", "Rx jabbers:", rx_val); 894 895 /* 896 * Get number of Rx frames filtered due to classification rules or 897 * no destination ports 898 */ 899 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_cat_drop) + 900 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_local); 901 printf(VSC9953_STATS_PRINTF"\n", "Rx filtered:", rx_val); 902 903 printf("\n"); 904 } 905 906 /* Clear statistics for a VSC9953 port */ 907 static void vsc9953_port_statistics_clear(int port_no) 908 { 909 struct vsc9953_system_reg *l2sys_reg; 910 911 /* Administrative down */ 912 if (!vsc9953_l2sw.port[port_no].enabled) { 913 printf("Port %d is administrative down\n", port_no); 914 return; 915 } 916 917 l2sys_reg = (struct vsc9953_system_reg *)(VSC9953_OFFSET + 918 VSC9953_SYS_OFFSET); 919 920 /* Clear all counter groups for our ports */ 921 out_le32(&l2sys_reg->sys.stat_cfg, port_no | 922 VSC9953_STAT_CLEAR_RX | VSC9953_STAT_CLEAR_TX | 923 VSC9953_STAT_CLEAR_DR); 924 } 925 926 enum port_learn_mode { 927 PORT_LEARN_NONE, 928 PORT_LEARN_AUTO 929 }; 930 931 /* Set learning configuration for a VSC9953 port */ 932 static void vsc9953_port_learn_mode_set(int port_no, enum port_learn_mode mode) 933 { 934 struct vsc9953_analyzer *l2ana_reg; 935 936 /* Administrative down */ 937 if (!vsc9953_l2sw.port[port_no].enabled) { 938 printf("Port %d is administrative down\n", port_no); 939 return; 940 } 941 942 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 943 VSC9953_ANA_OFFSET); 944 945 switch (mode) { 946 case PORT_LEARN_NONE: 947 clrbits_le32(&l2ana_reg->port[port_no].port_cfg, 948 VSC9953_PORT_CFG_LEARN_DROP | 949 VSC9953_PORT_CFG_LEARN_CPU | 950 VSC9953_PORT_CFG_LEARN_AUTO | 951 VSC9953_PORT_CFG_LEARN_ENA); 952 break; 953 case PORT_LEARN_AUTO: 954 clrsetbits_le32(&l2ana_reg->port[port_no].port_cfg, 955 VSC9953_PORT_CFG_LEARN_DROP | 956 VSC9953_PORT_CFG_LEARN_CPU, 957 VSC9953_PORT_CFG_LEARN_ENA | 958 VSC9953_PORT_CFG_LEARN_AUTO); 959 break; 960 default: 961 printf("Unknown learn mode for port %d\n", port_no); 962 } 963 } 964 965 /* Get learning configuration for a VSC9953 port */ 966 static int vsc9953_port_learn_mode_get(int port_no, enum port_learn_mode *mode) 967 { 968 u32 val; 969 struct vsc9953_analyzer *l2ana_reg; 970 971 /* Administrative down */ 972 if (!vsc9953_l2sw.port[port_no].enabled) { 973 printf("Port %d is administrative down\n", port_no); 974 return -1; 975 } 976 977 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 978 VSC9953_ANA_OFFSET); 979 980 /* For now we only support HW learning (auto) and no learning */ 981 val = in_le32(&l2ana_reg->port[port_no].port_cfg); 982 if ((val & (VSC9953_PORT_CFG_LEARN_ENA | 983 VSC9953_PORT_CFG_LEARN_AUTO)) == 984 (VSC9953_PORT_CFG_LEARN_ENA | VSC9953_PORT_CFG_LEARN_AUTO)) 985 *mode = PORT_LEARN_AUTO; 986 else 987 *mode = PORT_LEARN_NONE; 988 989 return 0; 990 } 991 992 /* wait for FDB to become available */ 993 static int vsc9953_mac_table_poll_idle(void) 994 { 995 struct vsc9953_analyzer *l2ana_reg; 996 u32 timeout; 997 998 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 999 VSC9953_ANA_OFFSET); 1000 1001 timeout = 50000; 1002 while (((in_le32(&l2ana_reg->ana_tables.mac_access) & 1003 VSC9953_MAC_CMD_MASK) != 1004 VSC9953_MAC_CMD_IDLE) && --timeout) 1005 udelay(1); 1006 1007 return timeout ? 0 : -EBUSY; 1008 } 1009 1010 /* enum describing available commands for the MAC table */ 1011 enum mac_table_cmd { 1012 MAC_TABLE_READ, 1013 MAC_TABLE_LOOKUP, 1014 MAC_TABLE_WRITE, 1015 MAC_TABLE_LEARN, 1016 MAC_TABLE_FORGET, 1017 MAC_TABLE_GET_NEXT, 1018 MAC_TABLE_AGE, 1019 }; 1020 1021 /* Issues a command to the FDB table */ 1022 static int vsc9953_mac_table_cmd(enum mac_table_cmd cmd) 1023 { 1024 struct vsc9953_analyzer *l2ana_reg; 1025 1026 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 1027 VSC9953_ANA_OFFSET); 1028 1029 switch (cmd) { 1030 case MAC_TABLE_READ: 1031 clrsetbits_le32(&l2ana_reg->ana_tables.mac_access, 1032 VSC9953_MAC_CMD_MASK | VSC9953_MAC_CMD_VALID, 1033 VSC9953_MAC_CMD_READ); 1034 break; 1035 case MAC_TABLE_LOOKUP: 1036 clrsetbits_le32(&l2ana_reg->ana_tables.mac_access, 1037 VSC9953_MAC_CMD_MASK, VSC9953_MAC_CMD_READ | 1038 VSC9953_MAC_CMD_VALID); 1039 break; 1040 case MAC_TABLE_WRITE: 1041 clrsetbits_le32(&l2ana_reg->ana_tables.mac_access, 1042 VSC9953_MAC_CMD_MASK | 1043 VSC9953_MAC_ENTRYTYPE_MASK, 1044 VSC9953_MAC_CMD_WRITE | 1045 VSC9953_MAC_ENTRYTYPE_LOCKED); 1046 break; 1047 case MAC_TABLE_LEARN: 1048 clrsetbits_le32(&l2ana_reg->ana_tables.mac_access, 1049 VSC9953_MAC_CMD_MASK | 1050 VSC9953_MAC_ENTRYTYPE_MASK, 1051 VSC9953_MAC_CMD_LEARN | 1052 VSC9953_MAC_ENTRYTYPE_LOCKED | 1053 VSC9953_MAC_CMD_VALID); 1054 break; 1055 case MAC_TABLE_FORGET: 1056 clrsetbits_le32(&l2ana_reg->ana_tables.mac_access, 1057 VSC9953_MAC_CMD_MASK | 1058 VSC9953_MAC_ENTRYTYPE_MASK, 1059 VSC9953_MAC_CMD_FORGET); 1060 break; 1061 case MAC_TABLE_GET_NEXT: 1062 clrsetbits_le32(&l2ana_reg->ana_tables.mac_access, 1063 VSC9953_MAC_CMD_MASK | 1064 VSC9953_MAC_ENTRYTYPE_MASK, 1065 VSC9953_MAC_CMD_NEXT); 1066 break; 1067 case MAC_TABLE_AGE: 1068 clrsetbits_le32(&l2ana_reg->ana_tables.mac_access, 1069 VSC9953_MAC_CMD_MASK | 1070 VSC9953_MAC_ENTRYTYPE_MASK, 1071 VSC9953_MAC_CMD_AGE); 1072 break; 1073 default: 1074 printf("Unknown MAC table command\n"); 1075 } 1076 1077 if (vsc9953_mac_table_poll_idle() < 0) { 1078 debug("MAC table timeout\n"); 1079 return -1; 1080 } 1081 1082 return 0; 1083 } 1084 1085 /* show the FDB entries that correspond to a port and a VLAN */ 1086 static void vsc9953_mac_table_show(int port_no, int vid) 1087 { 1088 int rc[VSC9953_MAX_PORTS]; 1089 enum port_learn_mode mode[VSC9953_MAX_PORTS]; 1090 int i; 1091 u32 val; 1092 u32 vlan; 1093 u32 mach; 1094 u32 macl; 1095 u32 dest_indx; 1096 struct vsc9953_analyzer *l2ana_reg; 1097 1098 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 1099 VSC9953_ANA_OFFSET); 1100 1101 /* disable auto learning */ 1102 if (port_no == ETHSW_CMD_PORT_ALL) { 1103 for (i = 0; i < VSC9953_MAX_PORTS; i++) { 1104 rc[i] = vsc9953_port_learn_mode_get(i, &mode[i]); 1105 if (!rc[i] && mode[i] != PORT_LEARN_NONE) 1106 vsc9953_port_learn_mode_set(i, PORT_LEARN_NONE); 1107 } 1108 } else { 1109 rc[port_no] = vsc9953_port_learn_mode_get(port_no, 1110 &mode[port_no]); 1111 if (!rc[port_no] && mode[port_no] != PORT_LEARN_NONE) 1112 vsc9953_port_learn_mode_set(port_no, PORT_LEARN_NONE); 1113 } 1114 1115 /* write port and vid to get selected FDB entries */ 1116 val = in_le32(&l2ana_reg->ana.anag_efil); 1117 if (port_no != ETHSW_CMD_PORT_ALL) { 1118 val = bitfield_replace_by_mask(val, VSC9953_AGE_PORT_MASK, 1119 port_no) | VSC9953_AGE_PORT_EN; 1120 } 1121 if (vid != ETHSW_CMD_VLAN_ALL) { 1122 val = bitfield_replace_by_mask(val, VSC9953_AGE_VID_MASK, 1123 vid) | VSC9953_AGE_VID_EN; 1124 } 1125 out_le32(&l2ana_reg->ana.anag_efil, val); 1126 1127 /* set MAC and VLAN to 0 to look from beginning */ 1128 clrbits_le32(&l2ana_reg->ana_tables.mach_data, 1129 VSC9953_MAC_VID_MASK | VSC9953_MAC_MACH_MASK); 1130 out_le32(&l2ana_reg->ana_tables.macl_data, 0); 1131 1132 /* get entries */ 1133 printf("%10s %17s %5s %4s\n", "EntryType", "MAC", "PORT", "VID"); 1134 do { 1135 if (vsc9953_mac_table_cmd(MAC_TABLE_GET_NEXT) < 0) { 1136 debug("GET NEXT MAC table command failed\n"); 1137 break; 1138 } 1139 1140 val = in_le32(&l2ana_reg->ana_tables.mac_access); 1141 1142 /* get out when an invalid entry is found */ 1143 if (!(val & VSC9953_MAC_CMD_VALID)) 1144 break; 1145 1146 switch (val & VSC9953_MAC_ENTRYTYPE_MASK) { 1147 case VSC9953_MAC_ENTRYTYPE_NORMAL: 1148 printf("%10s ", "Dynamic"); 1149 break; 1150 case VSC9953_MAC_ENTRYTYPE_LOCKED: 1151 printf("%10s ", "Static"); 1152 break; 1153 case VSC9953_MAC_ENTRYTYPE_IPV4MCAST: 1154 printf("%10s ", "IPv4 Mcast"); 1155 break; 1156 case VSC9953_MAC_ENTRYTYPE_IPV6MCAST: 1157 printf("%10s ", "IPv6 Mcast"); 1158 break; 1159 default: 1160 printf("%10s ", "Unknown"); 1161 } 1162 1163 dest_indx = bitfield_extract_by_mask(val, 1164 VSC9953_MAC_DESTIDX_MASK); 1165 1166 val = in_le32(&l2ana_reg->ana_tables.mach_data); 1167 vlan = bitfield_extract_by_mask(val, VSC9953_MAC_VID_MASK); 1168 mach = bitfield_extract_by_mask(val, VSC9953_MAC_MACH_MASK); 1169 macl = in_le32(&l2ana_reg->ana_tables.macl_data); 1170 1171 printf("%02x:%02x:%02x:%02x:%02x:%02x ", (mach >> 8) & 0xff, 1172 mach & 0xff, (macl >> 24) & 0xff, (macl >> 16) & 0xff, 1173 (macl >> 8) & 0xff, macl & 0xff); 1174 printf("%5d ", dest_indx); 1175 printf("%4d\n", vlan); 1176 } while (1); 1177 1178 /* set learning mode to previous value */ 1179 if (port_no == ETHSW_CMD_PORT_ALL) { 1180 for (i = 0; i < VSC9953_MAX_PORTS; i++) { 1181 if (!rc[i] && mode[i] != PORT_LEARN_NONE) 1182 vsc9953_port_learn_mode_set(i, mode[i]); 1183 } 1184 } else { 1185 /* If administrative down, skip */ 1186 if (!rc[port_no] && mode[port_no] != PORT_LEARN_NONE) 1187 vsc9953_port_learn_mode_set(port_no, mode[port_no]); 1188 } 1189 1190 /* reset FDB port and VLAN FDB selection */ 1191 clrbits_le32(&l2ana_reg->ana.anag_efil, VSC9953_AGE_PORT_EN | 1192 VSC9953_AGE_PORT_MASK | VSC9953_AGE_VID_EN | 1193 VSC9953_AGE_VID_MASK); 1194 } 1195 1196 /* Add a static FDB entry */ 1197 static int vsc9953_mac_table_add(u8 port_no, uchar mac[6], int vid) 1198 { 1199 u32 val; 1200 struct vsc9953_analyzer *l2ana_reg; 1201 1202 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 1203 VSC9953_ANA_OFFSET); 1204 1205 val = in_le32(&l2ana_reg->ana_tables.mach_data); 1206 val = bitfield_replace_by_mask(val, VSC9953_MACHDATA_VID_MASK, vid) | 1207 (mac[0] << 8) | (mac[1] << 0); 1208 out_le32(&l2ana_reg->ana_tables.mach_data, val); 1209 1210 out_le32(&l2ana_reg->ana_tables.macl_data, 1211 (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | 1212 (mac[5] << 0)); 1213 1214 /* set on which port is the MAC address added */ 1215 val = in_le32(&l2ana_reg->ana_tables.mac_access); 1216 val = bitfield_replace_by_mask(val, VSC9953_MAC_DESTIDX_MASK, port_no); 1217 out_le32(&l2ana_reg->ana_tables.mac_access, val); 1218 1219 if (vsc9953_mac_table_cmd(MAC_TABLE_LEARN) < 0) 1220 return -1; 1221 1222 /* check if the MAC address was indeed added */ 1223 val = in_le32(&l2ana_reg->ana_tables.mach_data); 1224 val = bitfield_replace_by_mask(val, VSC9953_MACHDATA_VID_MASK, vid) | 1225 (mac[0] << 8) | (mac[1] << 0); 1226 out_le32(&l2ana_reg->ana_tables.mach_data, val); 1227 1228 out_le32(&l2ana_reg->ana_tables.macl_data, 1229 (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | 1230 (mac[5] << 0)); 1231 1232 if (vsc9953_mac_table_cmd(MAC_TABLE_READ) < 0) 1233 return -1; 1234 1235 val = in_le32(&l2ana_reg->ana_tables.mac_access); 1236 1237 if ((port_no != bitfield_extract_by_mask(val, 1238 VSC9953_MAC_DESTIDX_MASK))) { 1239 printf("Failed to add MAC address\n"); 1240 return -1; 1241 } 1242 return 0; 1243 } 1244 1245 /* Delete a FDB entry */ 1246 static int vsc9953_mac_table_del(uchar mac[6], u16 vid) 1247 { 1248 u32 val; 1249 struct vsc9953_analyzer *l2ana_reg; 1250 1251 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 1252 VSC9953_ANA_OFFSET); 1253 1254 /* check first if MAC entry is present */ 1255 val = in_le32(&l2ana_reg->ana_tables.mach_data); 1256 val = bitfield_replace_by_mask(val, VSC9953_MACHDATA_VID_MASK, vid) | 1257 (mac[0] << 8) | (mac[1] << 0); 1258 out_le32(&l2ana_reg->ana_tables.mach_data, val); 1259 1260 out_le32(&l2ana_reg->ana_tables.macl_data, 1261 (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | 1262 (mac[5] << 0)); 1263 1264 if (vsc9953_mac_table_cmd(MAC_TABLE_LOOKUP) < 0) { 1265 debug("Lookup in the MAC table failed\n"); 1266 return -1; 1267 } 1268 1269 if (!(in_le32(&l2ana_reg->ana_tables.mac_access) & 1270 VSC9953_MAC_CMD_VALID)) { 1271 printf("The MAC address: %02x:%02x:%02x:%02x:%02x:%02x ", 1272 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 1273 printf("VLAN: %d does not exist.\n", vid); 1274 return -1; 1275 } 1276 1277 /* FDB entry found, proceed to delete */ 1278 val = in_le32(&l2ana_reg->ana_tables.mach_data); 1279 val = bitfield_replace_by_mask(val, VSC9953_MACHDATA_VID_MASK, vid) | 1280 (mac[0] << 8) | (mac[1] << 0); 1281 out_le32(&l2ana_reg->ana_tables.mach_data, val); 1282 1283 out_le32(&l2ana_reg->ana_tables.macl_data, (mac[2] << 24) | 1284 (mac[3] << 16) | (mac[4] << 8) | (mac[5] << 0)); 1285 1286 if (vsc9953_mac_table_cmd(MAC_TABLE_FORGET) < 0) 1287 return -1; 1288 1289 /* check if the MAC entry is still in FDB */ 1290 val = in_le32(&l2ana_reg->ana_tables.mach_data); 1291 val = bitfield_replace_by_mask(val, VSC9953_MACHDATA_VID_MASK, vid) | 1292 (mac[0] << 8) | (mac[1] << 0); 1293 out_le32(&l2ana_reg->ana_tables.mach_data, val); 1294 1295 out_le32(&l2ana_reg->ana_tables.macl_data, (mac[2] << 24) | 1296 (mac[3] << 16) | (mac[4] << 8) | (mac[5] << 0)); 1297 1298 if (vsc9953_mac_table_cmd(MAC_TABLE_LOOKUP) < 0) { 1299 debug("Lookup in the MAC table failed\n"); 1300 return -1; 1301 } 1302 if (in_le32(&l2ana_reg->ana_tables.mac_access) & 1303 VSC9953_MAC_CMD_VALID) { 1304 printf("Failed to delete MAC address\n"); 1305 return -1; 1306 } 1307 1308 return 0; 1309 } 1310 1311 /* age the unlocked entries in FDB */ 1312 static void vsc9953_mac_table_age(int port_no, int vid) 1313 { 1314 int rc[VSC9953_MAX_PORTS]; 1315 enum port_learn_mode mode[VSC9953_MAX_PORTS]; 1316 u32 val; 1317 int i; 1318 struct vsc9953_analyzer *l2ana_reg; 1319 1320 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 1321 VSC9953_ANA_OFFSET); 1322 1323 /* set port and VID for selective aging */ 1324 val = in_le32(&l2ana_reg->ana.anag_efil); 1325 if (port_no != ETHSW_CMD_PORT_ALL) { 1326 /* disable auto learning */ 1327 rc[port_no] = vsc9953_port_learn_mode_get(port_no, 1328 &mode[port_no]); 1329 if (!rc[port_no] && mode[port_no] != PORT_LEARN_NONE) 1330 vsc9953_port_learn_mode_set(port_no, PORT_LEARN_NONE); 1331 1332 val = bitfield_replace_by_mask(val, VSC9953_AGE_PORT_MASK, 1333 port_no) | VSC9953_AGE_PORT_EN; 1334 } else { 1335 /* disable auto learning on all ports */ 1336 for (i = 0; i < VSC9953_MAX_PORTS; i++) { 1337 rc[i] = vsc9953_port_learn_mode_get(i, &mode[i]); 1338 if (!rc[i] && mode[i] != PORT_LEARN_NONE) 1339 vsc9953_port_learn_mode_set(i, PORT_LEARN_NONE); 1340 } 1341 } 1342 1343 if (vid != ETHSW_CMD_VLAN_ALL) { 1344 val = bitfield_replace_by_mask(val, VSC9953_AGE_VID_MASK, vid) | 1345 VSC9953_AGE_VID_EN; 1346 } 1347 out_le32(&l2ana_reg->ana.anag_efil, val); 1348 1349 /* age the dynamic FDB entries */ 1350 vsc9953_mac_table_cmd(MAC_TABLE_AGE); 1351 1352 /* clear previously set port and VID */ 1353 clrbits_le32(&l2ana_reg->ana.anag_efil, VSC9953_AGE_PORT_EN | 1354 VSC9953_AGE_PORT_MASK | VSC9953_AGE_VID_EN | 1355 VSC9953_AGE_VID_MASK); 1356 1357 if (port_no != ETHSW_CMD_PORT_ALL) { 1358 if (!rc[port_no] && mode[port_no] != PORT_LEARN_NONE) 1359 vsc9953_port_learn_mode_set(port_no, mode[port_no]); 1360 } else { 1361 for (i = 0; i < VSC9953_MAX_PORTS; i++) { 1362 if (!rc[i] && mode[i] != PORT_LEARN_NONE) 1363 vsc9953_port_learn_mode_set(i, mode[i]); 1364 } 1365 } 1366 } 1367 1368 /* Delete all the dynamic FDB entries */ 1369 static void vsc9953_mac_table_flush(int port, int vid) 1370 { 1371 vsc9953_mac_table_age(port, vid); 1372 vsc9953_mac_table_age(port, vid); 1373 } 1374 1375 enum egress_vlan_tag { 1376 EGR_TAG_CLASS = 0, 1377 EGR_TAG_PVID, 1378 }; 1379 1380 /* Set egress tag mode for a VSC9953 port */ 1381 static void vsc9953_port_vlan_egress_tag_set(int port_no, 1382 enum egress_vlan_tag mode) 1383 { 1384 struct vsc9953_rew_reg *l2rew_reg; 1385 1386 l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET + 1387 VSC9953_REW_OFFSET); 1388 1389 switch (mode) { 1390 case EGR_TAG_CLASS: 1391 clrbits_le32(&l2rew_reg->port[port_no].port_tag_cfg, 1392 VSC9953_TAG_VID_PVID); 1393 break; 1394 case EGR_TAG_PVID: 1395 setbits_le32(&l2rew_reg->port[port_no].port_tag_cfg, 1396 VSC9953_TAG_VID_PVID); 1397 break; 1398 default: 1399 printf("Unknown egress VLAN tag mode for port %d\n", port_no); 1400 } 1401 } 1402 1403 /* Get egress tag mode for a VSC9953 port */ 1404 static void vsc9953_port_vlan_egress_tag_get(int port_no, 1405 enum egress_vlan_tag *mode) 1406 { 1407 u32 val; 1408 struct vsc9953_rew_reg *l2rew_reg; 1409 1410 l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET + 1411 VSC9953_REW_OFFSET); 1412 1413 val = in_le32(&l2rew_reg->port[port_no].port_tag_cfg); 1414 if (val & VSC9953_TAG_VID_PVID) 1415 *mode = EGR_TAG_PVID; 1416 else 1417 *mode = EGR_TAG_CLASS; 1418 } 1419 1420 /* VSC9953 VLAN learning modes */ 1421 enum vlan_learning_mode { 1422 SHARED_VLAN_LEARNING, 1423 PRIVATE_VLAN_LEARNING, 1424 }; 1425 1426 /* Set VLAN learning mode for VSC9953 */ 1427 static void vsc9953_vlan_learning_set(enum vlan_learning_mode lrn_mode) 1428 { 1429 struct vsc9953_analyzer *l2ana_reg; 1430 1431 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 1432 VSC9953_ANA_OFFSET); 1433 1434 switch (lrn_mode) { 1435 case SHARED_VLAN_LEARNING: 1436 setbits_le32(&l2ana_reg->ana.agen_ctrl, VSC9953_FID_MASK_ALL); 1437 break; 1438 case PRIVATE_VLAN_LEARNING: 1439 clrbits_le32(&l2ana_reg->ana.agen_ctrl, VSC9953_FID_MASK_ALL); 1440 break; 1441 default: 1442 printf("Unknown VLAN learn mode\n"); 1443 } 1444 } 1445 1446 /* Get VLAN learning mode for VSC9953 */ 1447 static int vsc9953_vlan_learning_get(enum vlan_learning_mode *lrn_mode) 1448 { 1449 u32 val; 1450 struct vsc9953_analyzer *l2ana_reg; 1451 1452 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 1453 VSC9953_ANA_OFFSET); 1454 1455 val = in_le32(&l2ana_reg->ana.agen_ctrl); 1456 1457 if (!(val & VSC9953_FID_MASK_ALL)) { 1458 *lrn_mode = PRIVATE_VLAN_LEARNING; 1459 } else if ((val & VSC9953_FID_MASK_ALL) == VSC9953_FID_MASK_ALL) { 1460 *lrn_mode = SHARED_VLAN_LEARNING; 1461 } else { 1462 printf("Unknown VLAN learning mode\n"); 1463 return -EINVAL; 1464 } 1465 1466 return 0; 1467 } 1468 1469 /* Enable/disable VLAN ingress filtering on a VSC9953 port */ 1470 static void vsc9953_port_ingress_filtering_set(int port_no, int enabled) 1471 { 1472 struct vsc9953_analyzer *l2ana_reg; 1473 1474 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 1475 VSC9953_ANA_OFFSET); 1476 1477 if (enabled) 1478 setbits_le32(&l2ana_reg->ana.vlan_mask, 1 << port_no); 1479 else 1480 clrbits_le32(&l2ana_reg->ana.vlan_mask, 1 << port_no); 1481 } 1482 1483 /* Return VLAN ingress filtering on a VSC9953 port */ 1484 static int vsc9953_port_ingress_filtering_get(int port_no) 1485 { 1486 u32 val; 1487 struct vsc9953_analyzer *l2ana_reg; 1488 1489 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 1490 VSC9953_ANA_OFFSET); 1491 1492 val = in_le32(&l2ana_reg->ana.vlan_mask); 1493 return !!(val & (1 << port_no)); 1494 } 1495 1496 static int vsc9953_port_status_key_func(struct ethsw_command_def *parsed_cmd) 1497 { 1498 int i; 1499 u8 enabled; 1500 1501 /* Last keyword should tell us if we should enable/disable the port */ 1502 if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == 1503 ethsw_id_enable) 1504 enabled = 1; 1505 else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == 1506 ethsw_id_disable) 1507 enabled = 0; 1508 else 1509 return CMD_RET_USAGE; 1510 1511 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { 1512 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { 1513 printf("Invalid port number: %d\n", parsed_cmd->port); 1514 return CMD_RET_FAILURE; 1515 } 1516 vsc9953_port_status_set(parsed_cmd->port, enabled); 1517 } else { 1518 for (i = 0; i < VSC9953_MAX_PORTS; i++) 1519 vsc9953_port_status_set(i, enabled); 1520 } 1521 1522 return CMD_RET_SUCCESS; 1523 } 1524 1525 static int vsc9953_port_config_key_func(struct ethsw_command_def *parsed_cmd) 1526 { 1527 int i; 1528 1529 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { 1530 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { 1531 printf("Invalid port number: %d\n", parsed_cmd->port); 1532 return CMD_RET_FAILURE; 1533 } 1534 vsc9953_phy_autoneg(parsed_cmd->port); 1535 printf("%8s %8s %8s %8s %8s\n", 1536 "Port", "Status", "Link", "Speed", 1537 "Duplex"); 1538 vsc9953_port_config_show(parsed_cmd->port); 1539 1540 } else { 1541 for (i = 0; i < VSC9953_MAX_PORTS; i++) 1542 vsc9953_phy_autoneg(i); 1543 printf("%8s %8s %8s %8s %8s\n", 1544 "Port", "Status", "Link", "Speed", "Duplex"); 1545 for (i = 0; i < VSC9953_MAX_PORTS; i++) 1546 vsc9953_port_config_show(i); 1547 } 1548 1549 return CMD_RET_SUCCESS; 1550 } 1551 1552 static int vsc9953_port_stats_key_func(struct ethsw_command_def *parsed_cmd) 1553 { 1554 int i; 1555 1556 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { 1557 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { 1558 printf("Invalid port number: %d\n", parsed_cmd->port); 1559 return CMD_RET_FAILURE; 1560 } 1561 vsc9953_port_statistics_show(parsed_cmd->port); 1562 } else { 1563 for (i = 0; i < VSC9953_MAX_PORTS; i++) 1564 vsc9953_port_statistics_show(i); 1565 } 1566 1567 return CMD_RET_SUCCESS; 1568 } 1569 1570 static int vsc9953_port_stats_clear_key_func(struct ethsw_command_def 1571 *parsed_cmd) 1572 { 1573 int i; 1574 1575 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { 1576 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { 1577 printf("Invalid port number: %d\n", parsed_cmd->port); 1578 return CMD_RET_FAILURE; 1579 } 1580 vsc9953_port_statistics_clear(parsed_cmd->port); 1581 } else { 1582 for (i = 0; i < VSC9953_MAX_PORTS; i++) 1583 vsc9953_port_statistics_clear(i); 1584 } 1585 1586 return CMD_RET_SUCCESS; 1587 } 1588 1589 static int vsc9953_learn_show_key_func(struct ethsw_command_def *parsed_cmd) 1590 { 1591 int i; 1592 enum port_learn_mode mode; 1593 1594 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { 1595 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { 1596 printf("Invalid port number: %d\n", parsed_cmd->port); 1597 return CMD_RET_FAILURE; 1598 } 1599 if (vsc9953_port_learn_mode_get(parsed_cmd->port, &mode)) 1600 return CMD_RET_FAILURE; 1601 printf("%7s %11s\n", "Port", "Learn mode"); 1602 switch (mode) { 1603 case PORT_LEARN_NONE: 1604 printf("%7d %11s\n", parsed_cmd->port, "disable"); 1605 break; 1606 case PORT_LEARN_AUTO: 1607 printf("%7d %11s\n", parsed_cmd->port, "auto"); 1608 break; 1609 default: 1610 printf("%7d %11s\n", parsed_cmd->port, "-"); 1611 } 1612 } else { 1613 printf("%7s %11s\n", "Port", "Learn mode"); 1614 for (i = 0; i < VSC9953_MAX_PORTS; i++) { 1615 if (vsc9953_port_learn_mode_get(i, &mode)) 1616 continue; 1617 switch (mode) { 1618 case PORT_LEARN_NONE: 1619 printf("%7d %11s\n", i, "disable"); 1620 break; 1621 case PORT_LEARN_AUTO: 1622 printf("%7d %11s\n", i, "auto"); 1623 break; 1624 default: 1625 printf("%7d %11s\n", i, "-"); 1626 } 1627 } 1628 } 1629 1630 return CMD_RET_SUCCESS; 1631 } 1632 1633 static int vsc9953_learn_set_key_func(struct ethsw_command_def *parsed_cmd) 1634 { 1635 int i; 1636 enum port_learn_mode mode; 1637 1638 /* Last keyword should tell us the learn mode */ 1639 if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == 1640 ethsw_id_auto) 1641 mode = PORT_LEARN_AUTO; 1642 else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == 1643 ethsw_id_disable) 1644 mode = PORT_LEARN_NONE; 1645 else 1646 return CMD_RET_USAGE; 1647 1648 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { 1649 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { 1650 printf("Invalid port number: %d\n", parsed_cmd->port); 1651 return CMD_RET_FAILURE; 1652 } 1653 vsc9953_port_learn_mode_set(parsed_cmd->port, mode); 1654 } else { 1655 for (i = 0; i < VSC9953_MAX_PORTS; i++) 1656 vsc9953_port_learn_mode_set(i, mode); 1657 } 1658 1659 return CMD_RET_SUCCESS; 1660 } 1661 1662 static int vsc9953_fdb_show_key_func(struct ethsw_command_def *parsed_cmd) 1663 { 1664 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL && 1665 !VSC9953_PORT_CHECK(parsed_cmd->port)) { 1666 printf("Invalid port number: %d\n", parsed_cmd->port); 1667 return CMD_RET_FAILURE; 1668 } 1669 1670 if (parsed_cmd->vid != ETHSW_CMD_VLAN_ALL && 1671 !VSC9953_VLAN_CHECK(parsed_cmd->vid)) { 1672 printf("Invalid VID number: %d\n", parsed_cmd->vid); 1673 return CMD_RET_FAILURE; 1674 } 1675 1676 vsc9953_mac_table_show(parsed_cmd->port, parsed_cmd->vid); 1677 1678 return CMD_RET_SUCCESS; 1679 } 1680 1681 static int vsc9953_fdb_flush_key_func(struct ethsw_command_def *parsed_cmd) 1682 { 1683 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL && 1684 !VSC9953_PORT_CHECK(parsed_cmd->port)) { 1685 printf("Invalid port number: %d\n", parsed_cmd->port); 1686 return CMD_RET_FAILURE; 1687 } 1688 1689 if (parsed_cmd->vid != ETHSW_CMD_VLAN_ALL && 1690 !VSC9953_VLAN_CHECK(parsed_cmd->vid)) { 1691 printf("Invalid VID number: %d\n", parsed_cmd->vid); 1692 return CMD_RET_FAILURE; 1693 } 1694 1695 vsc9953_mac_table_flush(parsed_cmd->port, parsed_cmd->vid); 1696 1697 return CMD_RET_SUCCESS; 1698 } 1699 1700 static int vsc9953_fdb_entry_add_key_func(struct ethsw_command_def *parsed_cmd) 1701 { 1702 int vid; 1703 1704 /* a port number must be present */ 1705 if (parsed_cmd->port == ETHSW_CMD_PORT_ALL) { 1706 printf("Please specify a port\n"); 1707 return CMD_RET_FAILURE; 1708 } 1709 1710 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { 1711 printf("Invalid port number: %d\n", parsed_cmd->port); 1712 return CMD_RET_FAILURE; 1713 } 1714 1715 /* Use VLAN 1 if VID is not set */ 1716 vid = (parsed_cmd->vid == ETHSW_CMD_VLAN_ALL ? 1 : parsed_cmd->vid); 1717 1718 if (!VSC9953_VLAN_CHECK(vid)) { 1719 printf("Invalid VID number: %d\n", vid); 1720 return CMD_RET_FAILURE; 1721 } 1722 1723 if (vsc9953_mac_table_add(parsed_cmd->port, parsed_cmd->ethaddr, vid)) 1724 return CMD_RET_FAILURE; 1725 1726 return CMD_RET_SUCCESS; 1727 } 1728 1729 static int vsc9953_fdb_entry_del_key_func(struct ethsw_command_def *parsed_cmd) 1730 { 1731 int vid; 1732 1733 /* Use VLAN 1 if VID is not set */ 1734 vid = (parsed_cmd->vid == ETHSW_CMD_VLAN_ALL ? 1 : parsed_cmd->vid); 1735 1736 if (!VSC9953_VLAN_CHECK(vid)) { 1737 printf("Invalid VID number: %d\n", vid); 1738 return CMD_RET_FAILURE; 1739 } 1740 1741 if (vsc9953_mac_table_del(parsed_cmd->ethaddr, vid)) 1742 return CMD_RET_FAILURE; 1743 1744 return CMD_RET_SUCCESS; 1745 } 1746 1747 static int vsc9953_pvid_show_key_func(struct ethsw_command_def *parsed_cmd) 1748 { 1749 int i; 1750 int pvid; 1751 1752 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { 1753 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { 1754 printf("Invalid port number: %d\n", parsed_cmd->port); 1755 return CMD_RET_FAILURE; 1756 } 1757 1758 if (vsc9953_port_vlan_pvid_get(parsed_cmd->port, &pvid)) 1759 return CMD_RET_FAILURE; 1760 printf("%7s %7s\n", "Port", "PVID"); 1761 printf("%7d %7d\n", parsed_cmd->port, pvid); 1762 } else { 1763 printf("%7s %7s\n", "Port", "PVID"); 1764 for (i = 0; i < VSC9953_MAX_PORTS; i++) { 1765 if (vsc9953_port_vlan_pvid_get(i, &pvid)) 1766 continue; 1767 printf("%7d %7d\n", i, pvid); 1768 } 1769 } 1770 1771 return CMD_RET_SUCCESS; 1772 } 1773 1774 static int vsc9953_pvid_set_key_func(struct ethsw_command_def *parsed_cmd) 1775 { 1776 /* PVID number should be set in parsed_cmd->vid */ 1777 if (parsed_cmd->vid == ETHSW_CMD_VLAN_ALL) { 1778 printf("Please set a pvid value\n"); 1779 return CMD_RET_FAILURE; 1780 } 1781 1782 if (!VSC9953_VLAN_CHECK(parsed_cmd->vid)) { 1783 printf("Invalid VID number: %d\n", parsed_cmd->vid); 1784 return CMD_RET_FAILURE; 1785 } 1786 1787 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { 1788 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { 1789 printf("Invalid port number: %d\n", parsed_cmd->port); 1790 return CMD_RET_FAILURE; 1791 } 1792 vsc9953_port_vlan_pvid_set(parsed_cmd->port, parsed_cmd->vid); 1793 } else { 1794 vsc9953_port_all_vlan_pvid_set(parsed_cmd->vid); 1795 } 1796 1797 return CMD_RET_SUCCESS; 1798 } 1799 1800 static int vsc9953_vlan_show_key_func(struct ethsw_command_def *parsed_cmd) 1801 { 1802 int i; 1803 1804 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { 1805 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { 1806 printf("Invalid port number: %d\n", parsed_cmd->port); 1807 return CMD_RET_FAILURE; 1808 } 1809 vsc9953_vlan_membership_show(parsed_cmd->port); 1810 } else { 1811 for (i = 0; i < VSC9953_MAX_PORTS; i++) 1812 vsc9953_vlan_membership_show(i); 1813 } 1814 1815 return CMD_RET_SUCCESS; 1816 } 1817 1818 static int vsc9953_vlan_set_key_func(struct ethsw_command_def *parsed_cmd) 1819 { 1820 int i; 1821 int add; 1822 1823 /* VLAN should be set in parsed_cmd->vid */ 1824 if (parsed_cmd->vid == ETHSW_CMD_VLAN_ALL) { 1825 printf("Please set a vlan value\n"); 1826 return CMD_RET_FAILURE; 1827 } 1828 1829 if (!VSC9953_VLAN_CHECK(parsed_cmd->vid)) { 1830 printf("Invalid VID number: %d\n", parsed_cmd->vid); 1831 return CMD_RET_FAILURE; 1832 } 1833 1834 /* keywords add/delete should be the last but one in array */ 1835 if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 2] == 1836 ethsw_id_add) 1837 add = 1; 1838 else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 2] == 1839 ethsw_id_del) 1840 add = 0; 1841 else 1842 return CMD_RET_USAGE; 1843 1844 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { 1845 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { 1846 printf("Invalid port number: %d\n", parsed_cmd->port); 1847 return CMD_RET_FAILURE; 1848 } 1849 vsc9953_vlan_table_membership_set(parsed_cmd->vid, 1850 parsed_cmd->port, add); 1851 } else { 1852 for (i = 0; i < VSC9953_MAX_PORTS; i++) 1853 vsc9953_vlan_table_membership_set(parsed_cmd->vid, i, 1854 add); 1855 } 1856 1857 return CMD_RET_SUCCESS; 1858 } 1859 static int vsc9953_port_untag_show_key_func( 1860 struct ethsw_command_def *parsed_cmd) 1861 { 1862 int i; 1863 1864 printf("%7s\t%17s\n", "Port", "Untag"); 1865 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { 1866 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { 1867 printf("Invalid port number: %d\n", parsed_cmd->port); 1868 return CMD_RET_FAILURE; 1869 } 1870 vsc9953_port_vlan_egr_untag_show(parsed_cmd->port); 1871 } else { 1872 for (i = 0; i < VSC9953_MAX_PORTS; i++) 1873 vsc9953_port_vlan_egr_untag_show(i); 1874 } 1875 1876 return CMD_RET_SUCCESS; 1877 } 1878 1879 static int vsc9953_port_untag_set_key_func(struct ethsw_command_def *parsed_cmd) 1880 { 1881 int i; 1882 enum egress_untag_mode mode; 1883 1884 /* keywords for the untagged mode are the last in the array */ 1885 if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == 1886 ethsw_id_all) 1887 mode = EGRESS_UNTAG_ALL; 1888 else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == 1889 ethsw_id_none) 1890 mode = EGRESS_UNTAG_NONE; 1891 else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == 1892 ethsw_id_pvid) 1893 mode = EGRESS_UNTAG_PVID_AND_ZERO; 1894 else 1895 return CMD_RET_USAGE; 1896 1897 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { 1898 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { 1899 printf("Invalid port number: %d\n", parsed_cmd->port); 1900 return CMD_RET_FAILURE; 1901 } 1902 vsc9953_port_vlan_egr_untag_set(parsed_cmd->port, mode); 1903 } else { 1904 for (i = 0; i < VSC9953_MAX_PORTS; i++) 1905 vsc9953_port_vlan_egr_untag_set(i, mode); 1906 } 1907 1908 return CMD_RET_SUCCESS; 1909 } 1910 1911 static int vsc9953_egr_vlan_tag_show_key_func( 1912 struct ethsw_command_def *parsed_cmd) 1913 { 1914 int i; 1915 enum egress_vlan_tag mode; 1916 1917 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { 1918 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { 1919 printf("Invalid port number: %d\n", parsed_cmd->port); 1920 return CMD_RET_FAILURE; 1921 } 1922 vsc9953_port_vlan_egress_tag_get(parsed_cmd->port, &mode); 1923 printf("%7s\t%12s\n", "Port", "Egress VID"); 1924 printf("%7d\t", parsed_cmd->port); 1925 switch (mode) { 1926 case EGR_TAG_CLASS: 1927 printf("%12s\n", "classified"); 1928 break; 1929 case EGR_TAG_PVID: 1930 printf("%12s\n", "pvid"); 1931 break; 1932 default: 1933 printf("%12s\n", "-"); 1934 } 1935 } else { 1936 printf("%7s\t%12s\n", "Port", "Egress VID"); 1937 for (i = 0; i < VSC9953_MAX_PORTS; i++) { 1938 vsc9953_port_vlan_egress_tag_get(i, &mode); 1939 switch (mode) { 1940 case EGR_TAG_CLASS: 1941 printf("%7d\t%12s\n", i, "classified"); 1942 break; 1943 case EGR_TAG_PVID: 1944 printf("%7d\t%12s\n", i, "pvid"); 1945 break; 1946 default: 1947 printf("%7d\t%12s\n", i, "-"); 1948 } 1949 } 1950 } 1951 1952 return CMD_RET_SUCCESS; 1953 } 1954 1955 static int vsc9953_egr_vlan_tag_set_key_func( 1956 struct ethsw_command_def *parsed_cmd) 1957 { 1958 int i; 1959 enum egress_vlan_tag mode; 1960 1961 /* keywords for the egress vlan tag mode are the last in the array */ 1962 if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == 1963 ethsw_id_pvid) 1964 mode = EGR_TAG_PVID; 1965 else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == 1966 ethsw_id_classified) 1967 mode = EGR_TAG_CLASS; 1968 else 1969 return CMD_RET_USAGE; 1970 1971 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { 1972 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { 1973 printf("Invalid port number: %d\n", parsed_cmd->port); 1974 return CMD_RET_FAILURE; 1975 } 1976 vsc9953_port_vlan_egress_tag_set(parsed_cmd->port, mode); 1977 } else { 1978 for (i = 0; i < VSC9953_MAX_PORTS; i++) 1979 vsc9953_port_vlan_egress_tag_set(i, mode); 1980 } 1981 1982 return CMD_RET_SUCCESS; 1983 } 1984 1985 static int vsc9953_vlan_learn_show_key_func( 1986 struct ethsw_command_def *parsed_cmd) 1987 { 1988 int rc; 1989 enum vlan_learning_mode mode; 1990 1991 rc = vsc9953_vlan_learning_get(&mode); 1992 if (rc) 1993 return CMD_RET_FAILURE; 1994 1995 switch (mode) { 1996 case SHARED_VLAN_LEARNING: 1997 printf("VLAN learning mode: shared\n"); 1998 break; 1999 case PRIVATE_VLAN_LEARNING: 2000 printf("VLAN learning mode: private\n"); 2001 break; 2002 default: 2003 printf("Unknown VLAN learning mode\n"); 2004 rc = CMD_RET_FAILURE; 2005 } 2006 2007 return CMD_RET_SUCCESS; 2008 } 2009 2010 static int vsc9953_vlan_learn_set_key_func(struct ethsw_command_def *parsed_cmd) 2011 { 2012 enum vlan_learning_mode mode; 2013 2014 /* keywords for shared/private are the last in the array */ 2015 if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == 2016 ethsw_id_shared) 2017 mode = SHARED_VLAN_LEARNING; 2018 else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == 2019 ethsw_id_private) 2020 mode = PRIVATE_VLAN_LEARNING; 2021 else 2022 return CMD_RET_USAGE; 2023 2024 vsc9953_vlan_learning_set(mode); 2025 2026 return CMD_RET_SUCCESS; 2027 } 2028 2029 static int vsc9953_ingr_fltr_show_key_func(struct ethsw_command_def *parsed_cmd) 2030 { 2031 int i; 2032 int enabled; 2033 2034 printf("%7s\t%18s\n", "Port", "Ingress filtering"); 2035 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { 2036 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { 2037 printf("Invalid port number: %d\n", parsed_cmd->port); 2038 return CMD_RET_FAILURE; 2039 } 2040 enabled = vsc9953_port_ingress_filtering_get(parsed_cmd->port); 2041 printf("%7d\t%18s\n", parsed_cmd->port, enabled ? "enable" : 2042 "disable"); 2043 } else { 2044 for (i = 0; i < VSC9953_MAX_PORTS; i++) { 2045 enabled = vsc9953_port_ingress_filtering_get(i); 2046 printf("%7d\t%18s\n", parsed_cmd->port, enabled ? 2047 "enable" : 2048 "disable"); 2049 } 2050 } 2051 2052 return CMD_RET_SUCCESS; 2053 } 2054 2055 static int vsc9953_ingr_fltr_set_key_func(struct ethsw_command_def *parsed_cmd) 2056 { 2057 int i; 2058 int enable; 2059 2060 /* keywords for enabling/disabling ingress filtering 2061 * are the last in the array 2062 */ 2063 if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == 2064 ethsw_id_enable) 2065 enable = 1; 2066 else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == 2067 ethsw_id_disable) 2068 enable = 0; 2069 else 2070 return CMD_RET_USAGE; 2071 2072 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { 2073 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { 2074 printf("Invalid port number: %d\n", parsed_cmd->port); 2075 return CMD_RET_FAILURE; 2076 } 2077 vsc9953_port_ingress_filtering_set(parsed_cmd->port, enable); 2078 } else { 2079 for (i = 0; i < VSC9953_MAX_PORTS; i++) 2080 vsc9953_port_ingress_filtering_set(i, enable); 2081 } 2082 2083 return CMD_RET_SUCCESS; 2084 } 2085 2086 static struct ethsw_command_func vsc9953_cmd_func = { 2087 .ethsw_name = "L2 Switch VSC9953", 2088 .port_enable = &vsc9953_port_status_key_func, 2089 .port_disable = &vsc9953_port_status_key_func, 2090 .port_show = &vsc9953_port_config_key_func, 2091 .port_stats = &vsc9953_port_stats_key_func, 2092 .port_stats_clear = &vsc9953_port_stats_clear_key_func, 2093 .port_learn = &vsc9953_learn_set_key_func, 2094 .port_learn_show = &vsc9953_learn_show_key_func, 2095 .fdb_show = &vsc9953_fdb_show_key_func, 2096 .fdb_flush = &vsc9953_fdb_flush_key_func, 2097 .fdb_entry_add = &vsc9953_fdb_entry_add_key_func, 2098 .fdb_entry_del = &vsc9953_fdb_entry_del_key_func, 2099 .pvid_show = &vsc9953_pvid_show_key_func, 2100 .pvid_set = &vsc9953_pvid_set_key_func, 2101 .vlan_show = &vsc9953_vlan_show_key_func, 2102 .vlan_set = &vsc9953_vlan_set_key_func, 2103 .port_untag_show = &vsc9953_port_untag_show_key_func, 2104 .port_untag_set = &vsc9953_port_untag_set_key_func, 2105 .port_egr_vlan_show = &vsc9953_egr_vlan_tag_show_key_func, 2106 .port_egr_vlan_set = &vsc9953_egr_vlan_tag_set_key_func, 2107 .vlan_learn_show = &vsc9953_vlan_learn_show_key_func, 2108 .vlan_learn_set = &vsc9953_vlan_learn_set_key_func, 2109 .port_ingr_filt_show = &vsc9953_ingr_fltr_show_key_func, 2110 .port_ingr_filt_set = &vsc9953_ingr_fltr_set_key_func 2111 }; 2112 2113 #endif /* CONFIG_CMD_ETHSW */ 2114 2115 /***************************************************************************** 2116 At startup, the default configuration would be: 2117 - HW learning enabled on all ports; (HW default) 2118 - All ports are in VLAN 1; 2119 - All ports are VLAN aware; 2120 - All ports have POP_COUNT 1; 2121 - All ports have PVID 1; 2122 - All ports have TPID 0x8100; (HW default) 2123 - All ports tag frames classified to all VLANs that are not PVID; 2124 *****************************************************************************/ 2125 void vsc9953_default_configuration(void) 2126 { 2127 int i; 2128 2129 if (vsc9953_autoage_time_set(VSC9953_DEFAULT_AGE_TIME)) 2130 debug("VSC9953: failed to set AGE time to %d\n", 2131 VSC9953_DEFAULT_AGE_TIME); 2132 2133 for (i = 0; i < VSC9953_MAX_VLAN; i++) 2134 vsc9953_vlan_table_membership_all_set(i, 0); 2135 vsc9953_port_all_vlan_aware_set(1); 2136 vsc9953_port_all_vlan_pvid_set(1); 2137 vsc9953_port_all_vlan_poncnt_set(1); 2138 vsc9953_vlan_table_membership_all_set(1, 1); 2139 vsc9953_vlan_ingr_fltr_learn_drop(1); 2140 vsc9953_port_all_vlan_egress_untagged_set(EGRESS_UNTAG_PVID_AND_ZERO); 2141 } 2142 2143 void vsc9953_init(bd_t *bis) 2144 { 2145 u32 i; 2146 u32 hdx_cfg = 0; 2147 u32 phy_addr = 0; 2148 int timeout; 2149 struct vsc9953_system_reg *l2sys_reg; 2150 struct vsc9953_qsys_reg *l2qsys_reg; 2151 struct vsc9953_dev_gmii *l2dev_gmii_reg; 2152 struct vsc9953_analyzer *l2ana_reg; 2153 struct vsc9953_devcpu_gcb *l2dev_gcb; 2154 2155 l2dev_gmii_reg = (struct vsc9953_dev_gmii *)(VSC9953_OFFSET + 2156 VSC9953_DEV_GMII_OFFSET); 2157 2158 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + 2159 VSC9953_ANA_OFFSET); 2160 2161 l2sys_reg = (struct vsc9953_system_reg *)(VSC9953_OFFSET + 2162 VSC9953_SYS_OFFSET); 2163 2164 l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET + 2165 VSC9953_QSYS_OFFSET); 2166 2167 l2dev_gcb = (struct vsc9953_devcpu_gcb *)(VSC9953_OFFSET + 2168 VSC9953_DEVCPU_GCB); 2169 2170 out_le32(&l2dev_gcb->chip_regs.soft_rst, 2171 VSC9953_SOFT_SWC_RST_ENA); 2172 timeout = 50000; 2173 while ((in_le32(&l2dev_gcb->chip_regs.soft_rst) & 2174 VSC9953_SOFT_SWC_RST_ENA) && --timeout) 2175 udelay(1); /* busy wait for vsc9953 soft reset */ 2176 if (timeout == 0) 2177 debug("Timeout waiting for VSC9953 to reset\n"); 2178 2179 out_le32(&l2sys_reg->sys.reset_cfg, VSC9953_MEM_ENABLE | 2180 VSC9953_MEM_INIT); 2181 2182 timeout = 50000; 2183 while ((in_le32(&l2sys_reg->sys.reset_cfg) & 2184 VSC9953_MEM_INIT) && --timeout) 2185 udelay(1); /* busy wait for vsc9953 memory init */ 2186 if (timeout == 0) 2187 debug("Timeout waiting for VSC9953 memory to initialize\n"); 2188 2189 out_le32(&l2sys_reg->sys.reset_cfg, (in_le32(&l2sys_reg->sys.reset_cfg) 2190 | VSC9953_CORE_ENABLE)); 2191 2192 /* VSC9953 Setting to be done once only */ 2193 out_le32(&l2qsys_reg->sys.ext_cpu_cfg, 0x00000b00); 2194 2195 for (i = 0; i < VSC9953_MAX_PORTS; i++) { 2196 if (vsc9953_port_init(i)) 2197 printf("Failed to initialize l2switch port %d\n", i); 2198 2199 /* Enable VSC9953 GMII Ports Port ID 0 - 7 */ 2200 if (VSC9953_INTERNAL_PORT_CHECK(i)) { 2201 out_le32(&l2ana_reg->pfc[i].pfc_cfg, 2202 VSC9953_PFC_FC_QSGMII); 2203 out_le32(&l2sys_reg->pause_cfg.mac_fc_cfg[i], 2204 VSC9953_MAC_FC_CFG_QSGMII); 2205 } else { 2206 out_le32(&l2ana_reg->pfc[i].pfc_cfg, 2207 VSC9953_PFC_FC); 2208 out_le32(&l2sys_reg->pause_cfg.mac_fc_cfg[i], 2209 VSC9953_MAC_FC_CFG); 2210 } 2211 out_le32(&l2dev_gmii_reg->port_mode.clock_cfg, 2212 VSC9953_CLOCK_CFG); 2213 out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_ena_cfg, 2214 VSC9953_MAC_ENA_CFG); 2215 out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_mode_cfg, 2216 VSC9953_MAC_MODE_CFG); 2217 out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_ifg_cfg, 2218 VSC9953_MAC_IFG_CFG); 2219 /* mac_hdx_cfg varies with port id*/ 2220 hdx_cfg = VSC9953_MAC_HDX_CFG | (i << 16); 2221 out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_hdx_cfg, hdx_cfg); 2222 out_le32(&l2sys_reg->sys.front_port_mode[i], 2223 VSC9953_FRONT_PORT_MODE); 2224 setbits_le32(&l2qsys_reg->sys.switch_port_mode[i], 2225 VSC9953_PORT_ENA); 2226 out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_maxlen_cfg, 2227 VSC9953_MAC_MAX_LEN); 2228 out_le32(&l2sys_reg->pause_cfg.pause_cfg[i], 2229 VSC9953_PAUSE_CFG); 2230 /* WAIT FOR 2 us*/ 2231 udelay(2); 2232 2233 l2dev_gmii_reg = (struct vsc9953_dev_gmii *)( 2234 (char *)l2dev_gmii_reg 2235 + T1040_SWITCH_GMII_DEV_OFFSET); 2236 2237 /* Initialize Lynx PHY Wrappers */ 2238 phy_addr = 0; 2239 if (vsc9953_l2sw.port[i].enet_if == 2240 PHY_INTERFACE_MODE_QSGMII) 2241 phy_addr = (i + 0x4) & 0x1F; 2242 else if (vsc9953_l2sw.port[i].enet_if == 2243 PHY_INTERFACE_MODE_SGMII) 2244 phy_addr = (i + 1) & 0x1F; 2245 2246 if (phy_addr) { 2247 /* SGMII IF mode + AN enable */ 2248 vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, 2249 0x14, PHY_SGMII_IF_MODE_AN | 2250 PHY_SGMII_IF_MODE_SGMII); 2251 /* Dev ability according to SGMII specification */ 2252 vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, 2253 0x4, PHY_SGMII_DEV_ABILITY_SGMII); 2254 /* Adjust link timer for SGMII 2255 * 1.6 ms in units of 8 ns = 2 * 10^5 = 0x30d40 2256 */ 2257 vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, 2258 0x13, 0x0003); 2259 vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, 2260 0x12, 0x0d40); 2261 /* Restart AN */ 2262 vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, 2263 0x0, PHY_SGMII_CR_DEF_VAL | 2264 PHY_SGMII_CR_RESET_AN); 2265 2266 timeout = 50000; 2267 while ((vsc9953_mdio_read(&l2dev_gcb->mii_mng[0], 2268 phy_addr, 0x01) & 0x0020) && --timeout) 2269 udelay(1); /* wait for AN to complete */ 2270 if (timeout == 0) 2271 debug("Timeout waiting for AN to complete\n"); 2272 } 2273 } 2274 2275 vsc9953_default_configuration(); 2276 2277 #ifdef CONFIG_CMD_ETHSW 2278 if (ethsw_define_functions(&vsc9953_cmd_func) < 0) 2279 debug("Unable to use \"ethsw\" commands\n"); 2280 #endif 2281 2282 printf("VSC9953 L2 switch initialized\n"); 2283 return; 2284 } 2285