1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright 2014 - 2015 Freescale Semiconductor, Inc.
5 * Driver for the Vitesse VSC9953 L2 Switch
12 #include <asm/fsl_serdes.h>
14 #include <fsl_memac.h>
21 static struct vsc9953_info vsc9953_l2sw = {
22 .port[0] = VSC9953_PORT_INFO_INITIALIZER(0),
23 .port[1] = VSC9953_PORT_INFO_INITIALIZER(1),
24 .port[2] = VSC9953_PORT_INFO_INITIALIZER(2),
25 .port[3] = VSC9953_PORT_INFO_INITIALIZER(3),
26 .port[4] = VSC9953_PORT_INFO_INITIALIZER(4),
27 .port[5] = VSC9953_PORT_INFO_INITIALIZER(5),
28 .port[6] = VSC9953_PORT_INFO_INITIALIZER(6),
29 .port[7] = VSC9953_PORT_INFO_INITIALIZER(7),
30 .port[8] = VSC9953_PORT_INFO_INITIALIZER(8),
31 .port[9] = VSC9953_PORT_INFO_INITIALIZER(9),
34 void vsc9953_port_info_set_mdio(int port_no, struct mii_dev *bus)
36 if (!VSC9953_PORT_CHECK(port_no))
39 vsc9953_l2sw.port[port_no].bus = bus;
42 void vsc9953_port_info_set_phy_address(int port_no, int address)
44 if (!VSC9953_PORT_CHECK(port_no))
47 vsc9953_l2sw.port[port_no].phyaddr = address;
50 void vsc9953_port_info_set_phy_int(int port_no, phy_interface_t phy_int)
52 if (!VSC9953_PORT_CHECK(port_no))
55 vsc9953_l2sw.port[port_no].enet_if = phy_int;
58 void vsc9953_port_enable(int port_no)
60 if (!VSC9953_PORT_CHECK(port_no))
63 vsc9953_l2sw.port[port_no].enabled = 1;
66 void vsc9953_port_disable(int port_no)
68 if (!VSC9953_PORT_CHECK(port_no))
71 vsc9953_l2sw.port[port_no].enabled = 0;
74 static void vsc9953_mdio_write(struct vsc9953_mii_mng *phyregs, int port_addr,
75 int regnum, int value)
79 out_le32(&phyregs->miimcmd, (0x1 << 31) | ((port_addr & 0x1f) << 25) |
80 ((regnum & 0x1f) << 20) | ((value & 0xffff) << 4) |
84 while ((in_le32(&phyregs->miimstatus) & 0x8) && --timeout)
88 debug("Timeout waiting for MDIO write\n");
91 static int vsc9953_mdio_read(struct vsc9953_mii_mng *phyregs, int port_addr,
97 while ((in_le32(&phyregs->miimstatus) & MIIMIND_OPR_PEND) && --timeout)
100 debug("Timeout waiting for MDIO operation to finish\n");
104 /* Put the address of the phy, and the register
107 out_le32(&phyregs->miimcmd, (0x1 << 31) | ((port_addr & 0x1f) << 25) |
108 ((regnum & 0x1f) << 20) | ((value & 0xffff) << 4) |
112 /* Wait for the the indication that the read is done */
113 while ((in_le32(&phyregs->miimstatus) & 0x8) && --timeout)
116 debug("Timeout waiting for MDIO read\n");
118 /* Grab the value read from the PHY */
119 value = in_le32(&phyregs->miimdata);
121 if ((value & 0x00030000) == 0)
122 return value & 0x0000ffff;
127 static int init_phy(struct eth_device *dev)
129 struct vsc9953_port_info *l2sw_port = dev->priv;
130 struct phy_device *phydev = NULL;
135 phydev = phy_connect(l2sw_port->bus, l2sw_port->phyaddr, dev,
138 printf("Failed to connect\n");
142 phydev->supported &= SUPPORTED_10baseT_Half |
143 SUPPORTED_10baseT_Full |
144 SUPPORTED_100baseT_Half |
145 SUPPORTED_100baseT_Full |
146 SUPPORTED_1000baseT_Full;
147 phydev->advertising = phydev->supported;
149 l2sw_port->phydev = phydev;
157 static int vsc9953_port_init(int port_no)
159 struct eth_device *dev;
161 /* Internal ports never have a PHY */
162 if (VSC9953_INTERNAL_PORT_CHECK(port_no))
165 /* alloc eth device */
166 dev = (struct eth_device *)calloc(1, sizeof(struct eth_device));
170 sprintf(dev->name, "SW@PORT%d", port_no);
171 dev->priv = &vsc9953_l2sw.port[port_no];
185 static int vsc9953_vlan_table_poll_idle(void)
187 struct vsc9953_analyzer *l2ana_reg;
190 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
194 while (((in_le32(&l2ana_reg->ana_tables.vlan_access) &
195 VSC9953_VLAN_CMD_MASK) != VSC9953_VLAN_CMD_IDLE) && --timeout)
198 return timeout ? 0 : -EBUSY;
201 #ifdef CONFIG_CMD_ETHSW
202 /* Add/remove a port to/from a VLAN */
203 static void vsc9953_vlan_table_membership_set(int vid, u32 port_no, u8 add)
206 struct vsc9953_analyzer *l2ana_reg;
208 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
211 if (vsc9953_vlan_table_poll_idle() < 0) {
212 debug("VLAN table timeout\n");
216 val = in_le32(&l2ana_reg->ana_tables.vlan_tidx);
217 val = bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK, vid);
218 out_le32(&l2ana_reg->ana_tables.vlan_tidx, val);
220 clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access,
221 VSC9953_VLAN_CMD_MASK, VSC9953_VLAN_CMD_READ);
223 if (vsc9953_vlan_table_poll_idle() < 0) {
224 debug("VLAN table timeout\n");
228 val = in_le32(&l2ana_reg->ana_tables.vlan_tidx);
229 val = bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK, vid);
230 out_le32(&l2ana_reg->ana_tables.vlan_tidx, val);
232 val = in_le32(&l2ana_reg->ana_tables.vlan_access);
234 val = bitfield_replace_by_mask(val, VSC9953_VLAN_CMD_MASK,
235 VSC9953_VLAN_CMD_WRITE) &
236 ~(bitfield_replace_by_mask(0, VSC9953_VLAN_PORT_MASK,
240 val = bitfield_replace_by_mask(val, VSC9953_VLAN_CMD_MASK,
241 VSC9953_VLAN_CMD_WRITE) |
242 bitfield_replace_by_mask(0, VSC9953_VLAN_PORT_MASK,
245 out_le32(&l2ana_reg->ana_tables.vlan_access, val);
247 /* wait for VLAN table command to flush */
248 if (vsc9953_vlan_table_poll_idle() < 0) {
249 debug("VLAN table timeout\n");
254 /* show VLAN membership for a port */
255 static void vsc9953_vlan_membership_show(int port_no)
258 struct vsc9953_analyzer *l2ana_reg;
261 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
264 printf("Port %d VLAN membership: ", port_no);
266 for (vid = 0; vid < VSC9953_MAX_VLAN; vid++) {
267 if (vsc9953_vlan_table_poll_idle() < 0) {
268 debug("VLAN table timeout\n");
272 val = in_le32(&l2ana_reg->ana_tables.vlan_tidx);
273 val = bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK,
275 out_le32(&l2ana_reg->ana_tables.vlan_tidx, val);
277 clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access,
278 VSC9953_VLAN_CMD_MASK, VSC9953_VLAN_CMD_READ);
280 if (vsc9953_vlan_table_poll_idle() < 0) {
281 debug("VLAN table timeout\n");
285 val = in_le32(&l2ana_reg->ana_tables.vlan_access);
287 if (bitfield_extract_by_mask(val, VSC9953_VLAN_PORT_MASK) &
295 /* vlan table set/clear all membership of vid */
296 static void vsc9953_vlan_table_membership_all_set(int vid, int set_member)
299 struct vsc9953_analyzer *l2ana_reg;
301 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
304 if (vsc9953_vlan_table_poll_idle() < 0) {
305 debug("VLAN table timeout\n");
309 /* read current vlan configuration */
310 val = in_le32(&l2ana_reg->ana_tables.vlan_tidx);
311 out_le32(&l2ana_reg->ana_tables.vlan_tidx,
312 bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK, vid));
314 clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access,
315 VSC9953_VLAN_CMD_MASK, VSC9953_VLAN_CMD_READ);
317 if (vsc9953_vlan_table_poll_idle() < 0) {
318 debug("VLAN table timeout\n");
322 val = in_le32(&l2ana_reg->ana_tables.vlan_tidx);
323 out_le32(&l2ana_reg->ana_tables.vlan_tidx,
324 bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK, vid));
326 clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access,
327 VSC9953_VLAN_PORT_MASK | VSC9953_VLAN_CMD_MASK,
328 VSC9953_VLAN_CMD_WRITE |
329 (set_member ? VSC9953_VLAN_PORT_MASK : 0));
332 #ifdef CONFIG_CMD_ETHSW
333 /* Get PVID of a VSC9953 port */
334 static int vsc9953_port_vlan_pvid_get(int port_nr, int *pvid)
337 struct vsc9953_analyzer *l2ana_reg;
339 /* Administrative down */
340 if (!vsc9953_l2sw.port[port_nr].enabled) {
341 printf("Port %d is administrative down\n", port_nr);
345 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
348 /* Get ingress PVID */
349 val = in_le32(&l2ana_reg->port[port_nr].vlan_cfg);
350 *pvid = bitfield_extract_by_mask(val, VSC9953_VLAN_CFG_VID_MASK);
356 /* Set PVID for a VSC9953 port */
357 static void vsc9953_port_vlan_pvid_set(int port_no, int pvid)
360 struct vsc9953_analyzer *l2ana_reg;
361 struct vsc9953_rew_reg *l2rew_reg;
363 /* Administrative down */
364 if (!vsc9953_l2sw.port[port_no].enabled) {
365 printf("Port %d is administrative down\n", port_no);
369 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
371 l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET +
374 /* Set PVID on ingress */
375 val = in_le32(&l2ana_reg->port[port_no].vlan_cfg);
376 val = bitfield_replace_by_mask(val, VSC9953_VLAN_CFG_VID_MASK, pvid);
377 out_le32(&l2ana_reg->port[port_no].vlan_cfg, val);
379 /* Set PVID on egress */
380 val = in_le32(&l2rew_reg->port[port_no].port_vlan_cfg);
381 val = bitfield_replace_by_mask(val, VSC9953_PORT_VLAN_CFG_VID_MASK,
383 out_le32(&l2rew_reg->port[port_no].port_vlan_cfg, val);
386 static void vsc9953_port_all_vlan_pvid_set(int pvid)
390 for (i = 0; i < VSC9953_MAX_PORTS; i++)
391 vsc9953_port_vlan_pvid_set(i, pvid);
394 /* Enable/disable vlan aware of a VSC9953 port */
395 static void vsc9953_port_vlan_aware_set(int port_no, int enabled)
397 struct vsc9953_analyzer *l2ana_reg;
399 /* Administrative down */
400 if (!vsc9953_l2sw.port[port_no].enabled) {
401 printf("Port %d is administrative down\n", port_no);
405 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
409 setbits_le32(&l2ana_reg->port[port_no].vlan_cfg,
410 VSC9953_VLAN_CFG_AWARE_ENA);
412 clrbits_le32(&l2ana_reg->port[port_no].vlan_cfg,
413 VSC9953_VLAN_CFG_AWARE_ENA);
416 /* Set all VSC9953 ports' vlan aware */
417 static void vsc9953_port_all_vlan_aware_set(int enabled)
421 for (i = 0; i < VSC9953_MAX_PORTS; i++)
422 vsc9953_port_vlan_aware_set(i, enabled);
425 /* Enable/disable vlan pop count of a VSC9953 port */
426 static void vsc9953_port_vlan_popcnt_set(int port_no, int popcnt)
429 struct vsc9953_analyzer *l2ana_reg;
431 /* Administrative down */
432 if (!vsc9953_l2sw.port[port_no].enabled) {
433 printf("Port %d is administrative down\n", port_no);
437 if (popcnt > 3 || popcnt < 0) {
438 printf("Invalid pop count value: %d\n", port_no);
442 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
445 val = in_le32(&l2ana_reg->port[port_no].vlan_cfg);
446 val = bitfield_replace_by_mask(val, VSC9953_VLAN_CFG_POP_CNT_MASK,
448 out_le32(&l2ana_reg->port[port_no].vlan_cfg, val);
451 /* Set all VSC9953 ports' pop count */
452 static void vsc9953_port_all_vlan_poncnt_set(int popcnt)
456 for (i = 0; i < VSC9953_MAX_PORTS; i++)
457 vsc9953_port_vlan_popcnt_set(i, popcnt);
460 /* Enable/disable learning for frames dropped due to ingress filtering */
461 static void vsc9953_vlan_ingr_fltr_learn_drop(int enable)
463 struct vsc9953_analyzer *l2ana_reg;
465 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
469 setbits_le32(&l2ana_reg->ana.adv_learn, VSC9953_VLAN_CHK);
471 clrbits_le32(&l2ana_reg->ana.adv_learn, VSC9953_VLAN_CHK);
474 enum aggr_code_mode {
476 AGGR_CODE_ALL, /* S/D MAC, IPv4 S/D IP, IPv6 Flow Label, S/D PORT */
479 /* Set aggregation code generation mode */
480 static int vsc9953_aggr_code_set(enum aggr_code_mode ac)
483 struct vsc9953_analyzer *l2ana_reg;
485 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
490 clrsetbits_le32(&l2ana_reg->common.aggr_cfg,
491 VSC9953_AC_DMAC_ENA | VSC9953_AC_SMAC_ENA |
492 VSC9953_AC_IP6_LBL_ENA |
493 VSC9953_AC_IP6_TCPUDP_ENA |
494 VSC9953_AC_IP4_SIPDIP_ENA |
495 VSC9953_AC_IP4_TCPUDP_ENA, VSC9953_AC_RND_ENA);
499 clrsetbits_le32(&l2ana_reg->common.aggr_cfg, VSC9953_AC_RND_ENA,
500 VSC9953_AC_DMAC_ENA | VSC9953_AC_SMAC_ENA |
501 VSC9953_AC_IP6_LBL_ENA |
502 VSC9953_AC_IP6_TCPUDP_ENA |
503 VSC9953_AC_IP4_SIPDIP_ENA |
504 VSC9953_AC_IP4_TCPUDP_ENA);
508 /* unknown mode for aggregation code */
515 /* Egress untag modes of a VSC9953 port */
516 enum egress_untag_mode {
517 EGRESS_UNTAG_ALL = 0,
518 EGRESS_UNTAG_PVID_AND_ZERO,
523 #ifdef CONFIG_CMD_ETHSW
524 /* Get egress tagging configuration for a VSC9953 port */
525 static int vsc9953_port_vlan_egr_untag_get(int port_no,
526 enum egress_untag_mode *mode)
529 struct vsc9953_rew_reg *l2rew_reg;
531 /* Administrative down */
532 if (!vsc9953_l2sw.port[port_no].enabled) {
533 printf("Port %d is administrative down\n", port_no);
537 l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET +
540 val = in_le32(&l2rew_reg->port[port_no].port_tag_cfg);
542 switch (val & VSC9953_TAG_CFG_MASK) {
543 case VSC9953_TAG_CFG_NONE:
544 *mode = EGRESS_UNTAG_ALL;
546 case VSC9953_TAG_CFG_ALL_BUT_PVID_ZERO:
547 *mode = EGRESS_UNTAG_PVID_AND_ZERO;
549 case VSC9953_TAG_CFG_ALL_BUT_ZERO:
550 *mode = EGRESS_UNTAG_ZERO;
552 case VSC9953_TAG_CFG_ALL:
553 *mode = EGRESS_UNTAG_NONE;
556 printf("Unknown egress tagging configuration for port %d\n",
562 /* Show egress tagging configuration for a VSC9953 port */
563 static void vsc9953_port_vlan_egr_untag_show(int port_no)
565 enum egress_untag_mode mode;
567 if (vsc9953_port_vlan_egr_untag_get(port_no, &mode)) {
568 printf("%7d\t%17s\n", port_no, "-");
572 printf("%7d\t", port_no);
574 case EGRESS_UNTAG_ALL:
575 printf("%17s\n", "all");
577 case EGRESS_UNTAG_NONE:
578 printf("%17s\n", "none");
580 case EGRESS_UNTAG_PVID_AND_ZERO:
581 printf("%17s\n", "PVID and 0");
583 case EGRESS_UNTAG_ZERO:
584 printf("%17s\n", "0");
587 printf("%17s\n", "-");
592 static void vsc9953_port_vlan_egr_untag_set(int port_no,
593 enum egress_untag_mode mode)
595 struct vsc9953_rew_reg *l2rew_reg;
597 /* Administrative down */
598 if (!vsc9953_l2sw.port[port_no].enabled) {
599 printf("Port %d is administrative down\n", port_no);
603 l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET +
607 case EGRESS_UNTAG_ALL:
608 clrsetbits_le32(&l2rew_reg->port[port_no].port_tag_cfg,
609 VSC9953_TAG_CFG_MASK, VSC9953_TAG_CFG_NONE);
611 case EGRESS_UNTAG_PVID_AND_ZERO:
612 clrsetbits_le32(&l2rew_reg->port[port_no].port_tag_cfg,
613 VSC9953_TAG_CFG_MASK,
614 VSC9953_TAG_CFG_ALL_BUT_PVID_ZERO);
616 case EGRESS_UNTAG_ZERO:
617 clrsetbits_le32(&l2rew_reg->port[port_no].port_tag_cfg,
618 VSC9953_TAG_CFG_MASK,
619 VSC9953_TAG_CFG_ALL_BUT_ZERO);
621 case EGRESS_UNTAG_NONE:
622 clrsetbits_le32(&l2rew_reg->port[port_no].port_tag_cfg,
623 VSC9953_TAG_CFG_MASK, VSC9953_TAG_CFG_ALL);
626 printf("Unknown untag mode for port %d\n", port_no);
630 static void vsc9953_port_all_vlan_egress_untagged_set(
631 enum egress_untag_mode mode)
635 for (i = 0; i < VSC9953_MAX_PORTS; i++)
636 vsc9953_port_vlan_egr_untag_set(i, mode);
639 static int vsc9953_autoage_time_set(int age_period)
642 struct vsc9953_analyzer *l2ana_reg;
644 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
647 if (age_period < 0 || age_period > VSC9953_AUTOAGE_PERIOD_MASK)
650 autoage = bitfield_replace_by_mask(in_le32(&l2ana_reg->ana.auto_age),
651 VSC9953_AUTOAGE_PERIOD_MASK,
653 out_le32(&l2ana_reg->ana.auto_age, autoage);
658 #ifdef CONFIG_CMD_ETHSW
660 /* Enable/disable status of a VSC9953 port */
661 static void vsc9953_port_status_set(int port_no, u8 enabled)
663 struct vsc9953_qsys_reg *l2qsys_reg;
665 /* Administrative down */
666 if (!vsc9953_l2sw.port[port_no].enabled)
669 l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET +
670 VSC9953_QSYS_OFFSET);
673 setbits_le32(&l2qsys_reg->sys.switch_port_mode[port_no],
676 clrbits_le32(&l2qsys_reg->sys.switch_port_mode[port_no],
680 /* Start autonegotiation for a VSC9953 PHY */
681 static void vsc9953_phy_autoneg(int port_no)
683 if (!vsc9953_l2sw.port[port_no].phydev)
686 if (vsc9953_l2sw.port[port_no].phydev->drv->startup(
687 vsc9953_l2sw.port[port_no].phydev))
688 printf("Failed to start PHY for port %d\n", port_no);
691 /* Print a VSC9953 port's configuration */
692 static void vsc9953_port_config_show(int port_no)
699 struct vsc9953_qsys_reg *l2qsys_reg;
701 l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET +
702 VSC9953_QSYS_OFFSET);
704 val = in_le32(&l2qsys_reg->sys.switch_port_mode[port_no]);
705 enabled = vsc9953_l2sw.port[port_no].enabled &&
706 (val & VSC9953_PORT_ENA);
708 /* internal ports (8 and 9) are fixed */
709 if (VSC9953_INTERNAL_PORT_CHECK(port_no)) {
712 duplex = DUPLEX_FULL;
714 if (vsc9953_l2sw.port[port_no].phydev) {
715 link = vsc9953_l2sw.port[port_no].phydev->link;
716 speed = vsc9953_l2sw.port[port_no].phydev->speed;
717 duplex = vsc9953_l2sw.port[port_no].phydev->duplex;
725 printf("%8d ", port_no);
726 printf("%8s ", enabled == 1 ? "enabled" : "disabled");
727 printf("%8s ", link == 1 ? "up" : "down");
737 printf("%8d ", 1000);
740 printf("%8d ", 2500);
743 printf("%8d ", 10000);
749 printf("%8s\n", duplex == DUPLEX_FULL ? "full" : "half");
752 /* Show VSC9953 ports' statistics */
753 static void vsc9953_port_statistics_show(int port_no)
757 struct vsc9953_system_reg *l2sys_reg;
759 /* Administrative down */
760 if (!vsc9953_l2sw.port[port_no].enabled) {
761 printf("Port %d is administrative down\n", port_no);
765 l2sys_reg = (struct vsc9953_system_reg *)(VSC9953_OFFSET +
768 printf("Statistics for L2 Switch port %d:\n", port_no);
770 /* Set counter view for our port */
771 out_le32(&l2sys_reg->sys.stat_cfg, port_no);
773 #define VSC9953_STATS_PRINTF "%-15s %10u"
775 /* Get number of Rx and Tx frames */
776 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_short) +
777 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_frag) +
778 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_jabber) +
779 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_long) +
780 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_64) +
781 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_65_127) +
782 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_128_255) +
783 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_256_511) +
784 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_512_1023) +
785 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_1024_1526) +
786 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_jumbo);
787 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_64) +
788 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_65_127) +
789 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_128_255) +
790 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_256_511) +
791 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_512_1023) +
792 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_1024_1526) +
793 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_jumbo);
794 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
795 "Rx frames:", rx_val, "Tx frames:", tx_val);
797 /* Get number of Rx and Tx bytes */
798 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_oct);
799 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_oct);
800 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
801 "Rx bytes:", rx_val, "Tx bytes:", tx_val);
803 /* Get number of Rx frames received ok and Tx frames sent ok */
804 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_0) +
805 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_1) +
806 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_2) +
807 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_3) +
808 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_4) +
809 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_5) +
810 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_6) +
811 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_7) +
812 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_0) +
813 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_1) +
814 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_2) +
815 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_3) +
816 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_4) +
817 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_5) +
818 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_6) +
819 in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_7);
820 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_64) +
821 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_65_127) +
822 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_128_255) +
823 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_256_511) +
824 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_512_1023) +
825 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_1024_1526) +
826 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_jumbo);
827 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
828 "Rx frames ok:", rx_val, "Tx frames ok:", tx_val);
830 /* Get number of Rx and Tx unicast frames */
831 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_uc);
832 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_uc);
833 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
834 "Rx unicast:", rx_val, "Tx unicast:", tx_val);
836 /* Get number of Rx and Tx broadcast frames */
837 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_bc);
838 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_bc);
839 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
840 "Rx broadcast:", rx_val, "Tx broadcast:", tx_val);
842 /* Get number of Rx and Tx frames of 64B */
843 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_64);
844 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_64);
845 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
846 "Rx 64B:", rx_val, "Tx 64B:", tx_val);
848 /* Get number of Rx and Tx frames with sizes between 65B and 127B */
849 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_65_127);
850 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_65_127);
851 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
852 "Rx 65B-127B:", rx_val, "Tx 65B-127B:", tx_val);
854 /* Get number of Rx and Tx frames with sizes between 128B and 255B */
855 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_128_255);
856 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_128_255);
857 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
858 "Rx 128B-255B:", rx_val, "Tx 128B-255B:", tx_val);
860 /* Get number of Rx and Tx frames with sizes between 256B and 511B */
861 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_256_511);
862 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_256_511);
863 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
864 "Rx 256B-511B:", rx_val, "Tx 256B-511B:", tx_val);
866 /* Get number of Rx and Tx frames with sizes between 512B and 1023B */
867 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_512_1023);
868 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_512_1023);
869 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
870 "Rx 512B-1023B:", rx_val, "Tx 512B-1023B:", tx_val);
872 /* Get number of Rx and Tx frames with sizes between 1024B and 1526B */
873 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_1024_1526);
874 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_1024_1526);
875 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
876 "Rx 1024B-1526B:", rx_val, "Tx 1024B-1526B:", tx_val);
878 /* Get number of Rx and Tx jumbo frames */
879 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_jumbo);
880 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_jumbo);
881 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
882 "Rx jumbo:", rx_val, "Tx jumbo:", tx_val);
884 /* Get number of Rx and Tx dropped frames */
885 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_cat_drop) +
886 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_tail) +
887 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_0) +
888 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_1) +
889 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_2) +
890 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_3) +
891 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_4) +
892 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_5) +
893 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_6) +
894 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_7) +
895 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_0) +
896 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_1) +
897 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_2) +
898 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_3) +
899 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_4) +
900 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_5) +
901 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_6) +
902 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_7);
903 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_drop) +
904 in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_aged);
905 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
906 "Rx drops:", rx_val, "Tx drops:", tx_val);
909 * Get number of Rx frames with CRC or alignment errors
910 * and number of detected Tx collisions
912 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_crc);
913 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_col);
914 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
915 "Rx CRC&align:", rx_val, "Tx coll:", tx_val);
918 * Get number of Rx undersized frames and
919 * number of Tx aged frames
921 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_short);
922 tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_aged);
923 printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n",
924 "Rx undersize:", rx_val, "Tx aged:", tx_val);
926 /* Get number of Rx oversized frames */
927 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_long);
928 printf(VSC9953_STATS_PRINTF"\n", "Rx oversized:", rx_val);
930 /* Get number of Rx fragmented frames */
931 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_frag);
932 printf(VSC9953_STATS_PRINTF"\n", "Rx fragments:", rx_val);
934 /* Get number of Rx jabber errors */
935 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_jabber);
936 printf(VSC9953_STATS_PRINTF"\n", "Rx jabbers:", rx_val);
939 * Get number of Rx frames filtered due to classification rules or
940 * no destination ports
942 rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_cat_drop) +
943 in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_local);
944 printf(VSC9953_STATS_PRINTF"\n", "Rx filtered:", rx_val);
949 /* Clear statistics for a VSC9953 port */
950 static void vsc9953_port_statistics_clear(int port_no)
952 struct vsc9953_system_reg *l2sys_reg;
954 /* Administrative down */
955 if (!vsc9953_l2sw.port[port_no].enabled) {
956 printf("Port %d is administrative down\n", port_no);
960 l2sys_reg = (struct vsc9953_system_reg *)(VSC9953_OFFSET +
963 /* Clear all counter groups for our ports */
964 out_le32(&l2sys_reg->sys.stat_cfg, port_no |
965 VSC9953_STAT_CLEAR_RX | VSC9953_STAT_CLEAR_TX |
966 VSC9953_STAT_CLEAR_DR);
969 enum port_learn_mode {
974 /* Set learning configuration for a VSC9953 port */
975 static void vsc9953_port_learn_mode_set(int port_no, enum port_learn_mode mode)
977 struct vsc9953_analyzer *l2ana_reg;
979 /* Administrative down */
980 if (!vsc9953_l2sw.port[port_no].enabled) {
981 printf("Port %d is administrative down\n", port_no);
985 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
989 case PORT_LEARN_NONE:
990 clrbits_le32(&l2ana_reg->port[port_no].port_cfg,
991 VSC9953_PORT_CFG_LEARN_DROP |
992 VSC9953_PORT_CFG_LEARN_CPU |
993 VSC9953_PORT_CFG_LEARN_AUTO |
994 VSC9953_PORT_CFG_LEARN_ENA);
996 case PORT_LEARN_AUTO:
997 clrsetbits_le32(&l2ana_reg->port[port_no].port_cfg,
998 VSC9953_PORT_CFG_LEARN_DROP |
999 VSC9953_PORT_CFG_LEARN_CPU,
1000 VSC9953_PORT_CFG_LEARN_ENA |
1001 VSC9953_PORT_CFG_LEARN_AUTO);
1004 printf("Unknown learn mode for port %d\n", port_no);
1008 /* Get learning configuration for a VSC9953 port */
1009 static int vsc9953_port_learn_mode_get(int port_no, enum port_learn_mode *mode)
1012 struct vsc9953_analyzer *l2ana_reg;
1014 /* Administrative down */
1015 if (!vsc9953_l2sw.port[port_no].enabled) {
1016 printf("Port %d is administrative down\n", port_no);
1020 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
1021 VSC9953_ANA_OFFSET);
1023 /* For now we only support HW learning (auto) and no learning */
1024 val = in_le32(&l2ana_reg->port[port_no].port_cfg);
1025 if ((val & (VSC9953_PORT_CFG_LEARN_ENA |
1026 VSC9953_PORT_CFG_LEARN_AUTO)) ==
1027 (VSC9953_PORT_CFG_LEARN_ENA | VSC9953_PORT_CFG_LEARN_AUTO))
1028 *mode = PORT_LEARN_AUTO;
1030 *mode = PORT_LEARN_NONE;
1035 /* wait for FDB to become available */
1036 static int vsc9953_mac_table_poll_idle(void)
1038 struct vsc9953_analyzer *l2ana_reg;
1041 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
1042 VSC9953_ANA_OFFSET);
1045 while (((in_le32(&l2ana_reg->ana_tables.mac_access) &
1046 VSC9953_MAC_CMD_MASK) !=
1047 VSC9953_MAC_CMD_IDLE) && --timeout)
1050 return timeout ? 0 : -EBUSY;
1053 /* enum describing available commands for the MAC table */
1054 enum mac_table_cmd {
1064 /* Issues a command to the FDB table */
1065 static int vsc9953_mac_table_cmd(enum mac_table_cmd cmd)
1067 struct vsc9953_analyzer *l2ana_reg;
1069 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
1070 VSC9953_ANA_OFFSET);
1073 case MAC_TABLE_READ:
1074 clrsetbits_le32(&l2ana_reg->ana_tables.mac_access,
1075 VSC9953_MAC_CMD_MASK | VSC9953_MAC_CMD_VALID,
1076 VSC9953_MAC_CMD_READ);
1078 case MAC_TABLE_LOOKUP:
1079 clrsetbits_le32(&l2ana_reg->ana_tables.mac_access,
1080 VSC9953_MAC_CMD_MASK, VSC9953_MAC_CMD_READ |
1081 VSC9953_MAC_CMD_VALID);
1083 case MAC_TABLE_WRITE:
1084 clrsetbits_le32(&l2ana_reg->ana_tables.mac_access,
1085 VSC9953_MAC_CMD_MASK |
1086 VSC9953_MAC_ENTRYTYPE_MASK,
1087 VSC9953_MAC_CMD_WRITE |
1088 VSC9953_MAC_ENTRYTYPE_LOCKED);
1090 case MAC_TABLE_LEARN:
1091 clrsetbits_le32(&l2ana_reg->ana_tables.mac_access,
1092 VSC9953_MAC_CMD_MASK |
1093 VSC9953_MAC_ENTRYTYPE_MASK,
1094 VSC9953_MAC_CMD_LEARN |
1095 VSC9953_MAC_ENTRYTYPE_LOCKED |
1096 VSC9953_MAC_CMD_VALID);
1098 case MAC_TABLE_FORGET:
1099 clrsetbits_le32(&l2ana_reg->ana_tables.mac_access,
1100 VSC9953_MAC_CMD_MASK |
1101 VSC9953_MAC_ENTRYTYPE_MASK,
1102 VSC9953_MAC_CMD_FORGET);
1104 case MAC_TABLE_GET_NEXT:
1105 clrsetbits_le32(&l2ana_reg->ana_tables.mac_access,
1106 VSC9953_MAC_CMD_MASK |
1107 VSC9953_MAC_ENTRYTYPE_MASK,
1108 VSC9953_MAC_CMD_NEXT);
1111 clrsetbits_le32(&l2ana_reg->ana_tables.mac_access,
1112 VSC9953_MAC_CMD_MASK |
1113 VSC9953_MAC_ENTRYTYPE_MASK,
1114 VSC9953_MAC_CMD_AGE);
1117 printf("Unknown MAC table command\n");
1120 if (vsc9953_mac_table_poll_idle() < 0) {
1121 debug("MAC table timeout\n");
1128 /* show the FDB entries that correspond to a port and a VLAN */
1129 static void vsc9953_mac_table_show(int port_no, int vid)
1131 int rc[VSC9953_MAX_PORTS];
1132 enum port_learn_mode mode[VSC9953_MAX_PORTS];
1139 struct vsc9953_analyzer *l2ana_reg;
1141 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
1142 VSC9953_ANA_OFFSET);
1144 /* disable auto learning */
1145 if (port_no == ETHSW_CMD_PORT_ALL) {
1146 for (i = 0; i < VSC9953_MAX_PORTS; i++) {
1147 rc[i] = vsc9953_port_learn_mode_get(i, &mode[i]);
1148 if (!rc[i] && mode[i] != PORT_LEARN_NONE)
1149 vsc9953_port_learn_mode_set(i, PORT_LEARN_NONE);
1152 rc[port_no] = vsc9953_port_learn_mode_get(port_no,
1154 if (!rc[port_no] && mode[port_no] != PORT_LEARN_NONE)
1155 vsc9953_port_learn_mode_set(port_no, PORT_LEARN_NONE);
1158 /* write port and vid to get selected FDB entries */
1159 val = in_le32(&l2ana_reg->ana.anag_efil);
1160 if (port_no != ETHSW_CMD_PORT_ALL) {
1161 val = bitfield_replace_by_mask(val, VSC9953_AGE_PORT_MASK,
1162 port_no) | VSC9953_AGE_PORT_EN;
1164 if (vid != ETHSW_CMD_VLAN_ALL) {
1165 val = bitfield_replace_by_mask(val, VSC9953_AGE_VID_MASK,
1166 vid) | VSC9953_AGE_VID_EN;
1168 out_le32(&l2ana_reg->ana.anag_efil, val);
1170 /* set MAC and VLAN to 0 to look from beginning */
1171 clrbits_le32(&l2ana_reg->ana_tables.mach_data,
1172 VSC9953_MAC_VID_MASK | VSC9953_MAC_MACH_MASK);
1173 out_le32(&l2ana_reg->ana_tables.macl_data, 0);
1176 printf("%10s %17s %5s %4s\n", "EntryType", "MAC", "PORT", "VID");
1178 if (vsc9953_mac_table_cmd(MAC_TABLE_GET_NEXT) < 0) {
1179 debug("GET NEXT MAC table command failed\n");
1183 val = in_le32(&l2ana_reg->ana_tables.mac_access);
1185 /* get out when an invalid entry is found */
1186 if (!(val & VSC9953_MAC_CMD_VALID))
1189 switch (val & VSC9953_MAC_ENTRYTYPE_MASK) {
1190 case VSC9953_MAC_ENTRYTYPE_NORMAL:
1191 printf("%10s ", "Dynamic");
1193 case VSC9953_MAC_ENTRYTYPE_LOCKED:
1194 printf("%10s ", "Static");
1196 case VSC9953_MAC_ENTRYTYPE_IPV4MCAST:
1197 printf("%10s ", "IPv4 Mcast");
1199 case VSC9953_MAC_ENTRYTYPE_IPV6MCAST:
1200 printf("%10s ", "IPv6 Mcast");
1203 printf("%10s ", "Unknown");
1206 dest_indx = bitfield_extract_by_mask(val,
1207 VSC9953_MAC_DESTIDX_MASK);
1209 val = in_le32(&l2ana_reg->ana_tables.mach_data);
1210 vlan = bitfield_extract_by_mask(val, VSC9953_MAC_VID_MASK);
1211 mach = bitfield_extract_by_mask(val, VSC9953_MAC_MACH_MASK);
1212 macl = in_le32(&l2ana_reg->ana_tables.macl_data);
1214 printf("%02x:%02x:%02x:%02x:%02x:%02x ", (mach >> 8) & 0xff,
1215 mach & 0xff, (macl >> 24) & 0xff, (macl >> 16) & 0xff,
1216 (macl >> 8) & 0xff, macl & 0xff);
1217 printf("%5d ", dest_indx);
1218 printf("%4d\n", vlan);
1221 /* set learning mode to previous value */
1222 if (port_no == ETHSW_CMD_PORT_ALL) {
1223 for (i = 0; i < VSC9953_MAX_PORTS; i++) {
1224 if (!rc[i] && mode[i] != PORT_LEARN_NONE)
1225 vsc9953_port_learn_mode_set(i, mode[i]);
1228 /* If administrative down, skip */
1229 if (!rc[port_no] && mode[port_no] != PORT_LEARN_NONE)
1230 vsc9953_port_learn_mode_set(port_no, mode[port_no]);
1233 /* reset FDB port and VLAN FDB selection */
1234 clrbits_le32(&l2ana_reg->ana.anag_efil, VSC9953_AGE_PORT_EN |
1235 VSC9953_AGE_PORT_MASK | VSC9953_AGE_VID_EN |
1236 VSC9953_AGE_VID_MASK);
1239 /* Add a static FDB entry */
1240 static int vsc9953_mac_table_add(u8 port_no, uchar mac[6], int vid)
1243 struct vsc9953_analyzer *l2ana_reg;
1245 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
1246 VSC9953_ANA_OFFSET);
1248 val = in_le32(&l2ana_reg->ana_tables.mach_data);
1249 val = bitfield_replace_by_mask(val, VSC9953_MACHDATA_VID_MASK, vid) |
1250 (mac[0] << 8) | (mac[1] << 0);
1251 out_le32(&l2ana_reg->ana_tables.mach_data, val);
1253 out_le32(&l2ana_reg->ana_tables.macl_data,
1254 (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) |
1257 /* set on which port is the MAC address added */
1258 val = in_le32(&l2ana_reg->ana_tables.mac_access);
1259 val = bitfield_replace_by_mask(val, VSC9953_MAC_DESTIDX_MASK, port_no);
1260 out_le32(&l2ana_reg->ana_tables.mac_access, val);
1262 if (vsc9953_mac_table_cmd(MAC_TABLE_LEARN) < 0)
1265 /* check if the MAC address was indeed added */
1266 val = in_le32(&l2ana_reg->ana_tables.mach_data);
1267 val = bitfield_replace_by_mask(val, VSC9953_MACHDATA_VID_MASK, vid) |
1268 (mac[0] << 8) | (mac[1] << 0);
1269 out_le32(&l2ana_reg->ana_tables.mach_data, val);
1271 out_le32(&l2ana_reg->ana_tables.macl_data,
1272 (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) |
1275 if (vsc9953_mac_table_cmd(MAC_TABLE_READ) < 0)
1278 val = in_le32(&l2ana_reg->ana_tables.mac_access);
1280 if ((port_no != bitfield_extract_by_mask(val,
1281 VSC9953_MAC_DESTIDX_MASK))) {
1282 printf("Failed to add MAC address\n");
1288 /* Delete a FDB entry */
1289 static int vsc9953_mac_table_del(uchar mac[6], u16 vid)
1292 struct vsc9953_analyzer *l2ana_reg;
1294 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
1295 VSC9953_ANA_OFFSET);
1297 /* check first if MAC entry is present */
1298 val = in_le32(&l2ana_reg->ana_tables.mach_data);
1299 val = bitfield_replace_by_mask(val, VSC9953_MACHDATA_VID_MASK, vid) |
1300 (mac[0] << 8) | (mac[1] << 0);
1301 out_le32(&l2ana_reg->ana_tables.mach_data, val);
1303 out_le32(&l2ana_reg->ana_tables.macl_data,
1304 (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) |
1307 if (vsc9953_mac_table_cmd(MAC_TABLE_LOOKUP) < 0) {
1308 debug("Lookup in the MAC table failed\n");
1312 if (!(in_le32(&l2ana_reg->ana_tables.mac_access) &
1313 VSC9953_MAC_CMD_VALID)) {
1314 printf("The MAC address: %02x:%02x:%02x:%02x:%02x:%02x ",
1315 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
1316 printf("VLAN: %d does not exist.\n", vid);
1320 /* FDB entry found, proceed to delete */
1321 val = in_le32(&l2ana_reg->ana_tables.mach_data);
1322 val = bitfield_replace_by_mask(val, VSC9953_MACHDATA_VID_MASK, vid) |
1323 (mac[0] << 8) | (mac[1] << 0);
1324 out_le32(&l2ana_reg->ana_tables.mach_data, val);
1326 out_le32(&l2ana_reg->ana_tables.macl_data, (mac[2] << 24) |
1327 (mac[3] << 16) | (mac[4] << 8) | (mac[5] << 0));
1329 if (vsc9953_mac_table_cmd(MAC_TABLE_FORGET) < 0)
1332 /* check if the MAC entry is still in FDB */
1333 val = in_le32(&l2ana_reg->ana_tables.mach_data);
1334 val = bitfield_replace_by_mask(val, VSC9953_MACHDATA_VID_MASK, vid) |
1335 (mac[0] << 8) | (mac[1] << 0);
1336 out_le32(&l2ana_reg->ana_tables.mach_data, val);
1338 out_le32(&l2ana_reg->ana_tables.macl_data, (mac[2] << 24) |
1339 (mac[3] << 16) | (mac[4] << 8) | (mac[5] << 0));
1341 if (vsc9953_mac_table_cmd(MAC_TABLE_LOOKUP) < 0) {
1342 debug("Lookup in the MAC table failed\n");
1345 if (in_le32(&l2ana_reg->ana_tables.mac_access) &
1346 VSC9953_MAC_CMD_VALID) {
1347 printf("Failed to delete MAC address\n");
1354 /* age the unlocked entries in FDB */
1355 static void vsc9953_mac_table_age(int port_no, int vid)
1357 int rc[VSC9953_MAX_PORTS];
1358 enum port_learn_mode mode[VSC9953_MAX_PORTS];
1361 struct vsc9953_analyzer *l2ana_reg;
1363 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
1364 VSC9953_ANA_OFFSET);
1366 /* set port and VID for selective aging */
1367 val = in_le32(&l2ana_reg->ana.anag_efil);
1368 if (port_no != ETHSW_CMD_PORT_ALL) {
1369 /* disable auto learning */
1370 rc[port_no] = vsc9953_port_learn_mode_get(port_no,
1372 if (!rc[port_no] && mode[port_no] != PORT_LEARN_NONE)
1373 vsc9953_port_learn_mode_set(port_no, PORT_LEARN_NONE);
1375 val = bitfield_replace_by_mask(val, VSC9953_AGE_PORT_MASK,
1376 port_no) | VSC9953_AGE_PORT_EN;
1378 /* disable auto learning on all ports */
1379 for (i = 0; i < VSC9953_MAX_PORTS; i++) {
1380 rc[i] = vsc9953_port_learn_mode_get(i, &mode[i]);
1381 if (!rc[i] && mode[i] != PORT_LEARN_NONE)
1382 vsc9953_port_learn_mode_set(i, PORT_LEARN_NONE);
1386 if (vid != ETHSW_CMD_VLAN_ALL) {
1387 val = bitfield_replace_by_mask(val, VSC9953_AGE_VID_MASK, vid) |
1390 out_le32(&l2ana_reg->ana.anag_efil, val);
1392 /* age the dynamic FDB entries */
1393 vsc9953_mac_table_cmd(MAC_TABLE_AGE);
1395 /* clear previously set port and VID */
1396 clrbits_le32(&l2ana_reg->ana.anag_efil, VSC9953_AGE_PORT_EN |
1397 VSC9953_AGE_PORT_MASK | VSC9953_AGE_VID_EN |
1398 VSC9953_AGE_VID_MASK);
1400 if (port_no != ETHSW_CMD_PORT_ALL) {
1401 if (!rc[port_no] && mode[port_no] != PORT_LEARN_NONE)
1402 vsc9953_port_learn_mode_set(port_no, mode[port_no]);
1404 for (i = 0; i < VSC9953_MAX_PORTS; i++) {
1405 if (!rc[i] && mode[i] != PORT_LEARN_NONE)
1406 vsc9953_port_learn_mode_set(i, mode[i]);
1411 /* Delete all the dynamic FDB entries */
1412 static void vsc9953_mac_table_flush(int port, int vid)
1414 vsc9953_mac_table_age(port, vid);
1415 vsc9953_mac_table_age(port, vid);
1418 enum egress_vlan_tag {
1423 /* Set egress tag mode for a VSC9953 port */
1424 static void vsc9953_port_vlan_egress_tag_set(int port_no,
1425 enum egress_vlan_tag mode)
1427 struct vsc9953_rew_reg *l2rew_reg;
1429 l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET +
1430 VSC9953_REW_OFFSET);
1434 clrbits_le32(&l2rew_reg->port[port_no].port_tag_cfg,
1435 VSC9953_TAG_VID_PVID);
1438 setbits_le32(&l2rew_reg->port[port_no].port_tag_cfg,
1439 VSC9953_TAG_VID_PVID);
1442 printf("Unknown egress VLAN tag mode for port %d\n", port_no);
1446 /* Get egress tag mode for a VSC9953 port */
1447 static void vsc9953_port_vlan_egress_tag_get(int port_no,
1448 enum egress_vlan_tag *mode)
1451 struct vsc9953_rew_reg *l2rew_reg;
1453 l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET +
1454 VSC9953_REW_OFFSET);
1456 val = in_le32(&l2rew_reg->port[port_no].port_tag_cfg);
1457 if (val & VSC9953_TAG_VID_PVID)
1458 *mode = EGR_TAG_PVID;
1460 *mode = EGR_TAG_CLASS;
1463 /* VSC9953 VLAN learning modes */
1464 enum vlan_learning_mode {
1465 SHARED_VLAN_LEARNING,
1466 PRIVATE_VLAN_LEARNING,
1469 /* Set VLAN learning mode for VSC9953 */
1470 static void vsc9953_vlan_learning_set(enum vlan_learning_mode lrn_mode)
1472 struct vsc9953_analyzer *l2ana_reg;
1474 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
1475 VSC9953_ANA_OFFSET);
1478 case SHARED_VLAN_LEARNING:
1479 setbits_le32(&l2ana_reg->ana.agen_ctrl, VSC9953_FID_MASK_ALL);
1481 case PRIVATE_VLAN_LEARNING:
1482 clrbits_le32(&l2ana_reg->ana.agen_ctrl, VSC9953_FID_MASK_ALL);
1485 printf("Unknown VLAN learn mode\n");
1489 /* Get VLAN learning mode for VSC9953 */
1490 static int vsc9953_vlan_learning_get(enum vlan_learning_mode *lrn_mode)
1493 struct vsc9953_analyzer *l2ana_reg;
1495 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
1496 VSC9953_ANA_OFFSET);
1498 val = in_le32(&l2ana_reg->ana.agen_ctrl);
1500 if (!(val & VSC9953_FID_MASK_ALL)) {
1501 *lrn_mode = PRIVATE_VLAN_LEARNING;
1502 } else if ((val & VSC9953_FID_MASK_ALL) == VSC9953_FID_MASK_ALL) {
1503 *lrn_mode = SHARED_VLAN_LEARNING;
1505 printf("Unknown VLAN learning mode\n");
1512 /* Enable/disable VLAN ingress filtering on a VSC9953 port */
1513 static void vsc9953_port_ingress_filtering_set(int port_no, int enabled)
1515 struct vsc9953_analyzer *l2ana_reg;
1517 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
1518 VSC9953_ANA_OFFSET);
1521 setbits_le32(&l2ana_reg->ana.vlan_mask, 1 << port_no);
1523 clrbits_le32(&l2ana_reg->ana.vlan_mask, 1 << port_no);
1526 /* Return VLAN ingress filtering on a VSC9953 port */
1527 static int vsc9953_port_ingress_filtering_get(int port_no)
1530 struct vsc9953_analyzer *l2ana_reg;
1532 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
1533 VSC9953_ANA_OFFSET);
1535 val = in_le32(&l2ana_reg->ana.vlan_mask);
1536 return !!(val & (1 << port_no));
1539 /* Get the aggregation group of a port */
1540 static int vsc9953_port_aggr_grp_get(int port_no, int *aggr_grp)
1543 struct vsc9953_analyzer *l2ana_reg;
1545 if (!VSC9953_PORT_CHECK(port_no))
1548 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
1549 VSC9953_ANA_OFFSET);
1551 val = in_le32(&l2ana_reg->port[port_no].port_cfg);
1552 *aggr_grp = bitfield_extract_by_mask(val,
1553 VSC9953_PORT_CFG_PORTID_MASK);
1558 static void vsc9953_aggr_grp_members_get(int aggr_grp,
1559 u8 aggr_membr[VSC9953_MAX_PORTS])
1564 for (port_no = 0; port_no < VSC9953_MAX_PORTS; port_no++) {
1565 aggr_membr[port_no] = 0;
1567 if (vsc9953_port_aggr_grp_get(port_no, &aggr_membr_grp))
1570 if (aggr_grp == aggr_membr_grp)
1571 aggr_membr[port_no] = 1;
1575 static void vsc9953_update_dest_members_masks(int port_no, u32 membr_bitfld_old,
1576 u32 membr_bitfld_new)
1580 struct vsc9953_analyzer *l2ana_reg;
1582 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
1583 VSC9953_ANA_OFFSET);
1586 * NOTE: Only the unicast destination masks are updated, since
1587 * we do not support for now Layer-2 multicast entries
1589 for (i = 0; i < VSC9953_MAX_PORTS; i++) {
1591 clrsetbits_le32(&l2ana_reg->port_id_tbl.port_grp_id[i],
1592 VSC9953_PGID_PORT_MASK,
1597 pgid = in_le32(&l2ana_reg->port_id_tbl.port_grp_id[i]);
1598 if ((u32)(1 << i) & membr_bitfld_old & VSC9953_PGID_PORT_MASK)
1599 pgid &= ~((u32)(1 << port_no));
1600 if ((u32)(1 << i) & membr_bitfld_new & VSC9953_PGID_PORT_MASK)
1601 pgid |= ((u32)(1 << port_no));
1603 out_le32(&l2ana_reg->port_id_tbl.port_grp_id[i], pgid);
1607 static void vsc9953_update_source_members_masks(int port_no,
1608 u32 membr_bitfld_old,
1609 u32 membr_bitfld_new)
1614 struct vsc9953_analyzer *l2ana_reg;
1616 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
1617 VSC9953_ANA_OFFSET);
1619 for (i = 0; i < VSC9953_MAX_PORTS + 1; i++) {
1620 index = PGID_SRC_START + i;
1621 pgid = in_le32(&l2ana_reg->port_id_tbl.port_grp_id[index]);
1623 pgid = (pgid | VSC9953_PGID_PORT_MASK) &
1625 out_le32(&l2ana_reg->port_id_tbl.port_grp_id[index],
1630 if ((u32)(1 << i) & membr_bitfld_old & VSC9953_PGID_PORT_MASK)
1631 pgid |= (u32)(1 << port_no);
1633 if ((u32)(1 << i) & membr_bitfld_new & VSC9953_PGID_PORT_MASK)
1634 pgid &= ~(u32)(1 << port_no);
1635 out_le32(&l2ana_reg->port_id_tbl.port_grp_id[index], pgid);
1639 static u32 vsc9953_aggr_mask_get_next(u32 aggr_mask, u32 member_bitfield)
1641 if (!member_bitfield)
1644 if (!(aggr_mask & VSC9953_PGID_PORT_MASK))
1649 while (!(aggr_mask & member_bitfield)) {
1651 if (!(aggr_mask & VSC9953_PGID_PORT_MASK))
1658 static void vsc9953_update_aggr_members_masks(int port_no, u32 membr_bitfld_old,
1659 u32 membr_bitfld_new)
1663 u32 aggr_mask_old = 0;
1664 u32 aggr_mask_new = 0;
1665 struct vsc9953_analyzer *l2ana_reg;
1667 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
1668 VSC9953_ANA_OFFSET);
1670 /* Update all the PGID aggregation masks */
1671 for (i = PGID_AGGR_START; i < PGID_SRC_START; i++) {
1672 pgid = in_le32(&l2ana_reg->port_id_tbl.port_grp_id[i]);
1674 aggr_mask_old = vsc9953_aggr_mask_get_next(aggr_mask_old,
1676 pgid = (pgid & ~membr_bitfld_old) | aggr_mask_old;
1678 aggr_mask_new = vsc9953_aggr_mask_get_next(aggr_mask_new,
1680 pgid = (pgid & ~membr_bitfld_new) | aggr_mask_new;
1682 out_le32(&l2ana_reg->port_id_tbl.port_grp_id[i], pgid);
1686 static u32 vsc9953_aggr_membr_bitfield_get(u8 member[VSC9953_MAX_PORTS])
1689 u32 member_bitfield = 0;
1691 for (i = 0; i < VSC9953_MAX_PORTS; i++) {
1693 member_bitfield |= 1 << i;
1695 member_bitfield &= VSC9953_PGID_PORT_MASK;
1697 return member_bitfield;
1700 static void vsc9953_update_members_masks(int port_no,
1701 u8 member_old[VSC9953_MAX_PORTS],
1702 u8 member_new[VSC9953_MAX_PORTS])
1704 u32 membr_bitfld_old = vsc9953_aggr_membr_bitfield_get(member_old);
1705 u32 membr_bitfld_new = vsc9953_aggr_membr_bitfield_get(member_new);
1707 vsc9953_update_dest_members_masks(port_no, membr_bitfld_old,
1709 vsc9953_update_source_members_masks(port_no, membr_bitfld_old,
1711 vsc9953_update_aggr_members_masks(port_no, membr_bitfld_old,
1715 /* Set the aggregation group of a port */
1716 static int vsc9953_port_aggr_grp_set(int port_no, int aggr_grp)
1718 u8 aggr_membr_old[VSC9953_MAX_PORTS];
1719 u8 aggr_membr_new[VSC9953_MAX_PORTS];
1723 struct vsc9953_analyzer *l2ana_reg;
1725 if (!VSC9953_PORT_CHECK(port_no) || !VSC9953_PORT_CHECK(aggr_grp))
1728 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
1729 VSC9953_ANA_OFFSET);
1731 rc = vsc9953_port_aggr_grp_get(port_no, &aggr_grp_old);
1735 /* get all the members of the old aggregation group */
1736 vsc9953_aggr_grp_members_get(aggr_grp_old, aggr_membr_old);
1738 /* get all the members of the same aggregation group */
1739 vsc9953_aggr_grp_members_get(aggr_grp, aggr_membr_new);
1741 /* add current port as member to the new aggregation group */
1742 aggr_membr_old[port_no] = 0;
1743 aggr_membr_new[port_no] = 1;
1746 vsc9953_update_members_masks(port_no, aggr_membr_old, aggr_membr_new);
1748 /* Change logical port number */
1749 val = in_le32(&l2ana_reg->port[port_no].port_cfg);
1750 val = bitfield_replace_by_mask(val,
1751 VSC9953_PORT_CFG_PORTID_MASK, aggr_grp);
1752 out_le32(&l2ana_reg->port[port_no].port_cfg, val);
1757 static int vsc9953_port_status_key_func(struct ethsw_command_def *parsed_cmd)
1762 /* Last keyword should tell us if we should enable/disable the port */
1763 if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
1766 else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
1770 return CMD_RET_USAGE;
1772 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
1773 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
1774 printf("Invalid port number: %d\n", parsed_cmd->port);
1775 return CMD_RET_FAILURE;
1777 vsc9953_port_status_set(parsed_cmd->port, enabled);
1779 for (i = 0; i < VSC9953_MAX_PORTS; i++)
1780 vsc9953_port_status_set(i, enabled);
1783 return CMD_RET_SUCCESS;
1786 static int vsc9953_port_config_key_func(struct ethsw_command_def *parsed_cmd)
1790 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
1791 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
1792 printf("Invalid port number: %d\n", parsed_cmd->port);
1793 return CMD_RET_FAILURE;
1795 vsc9953_phy_autoneg(parsed_cmd->port);
1796 printf("%8s %8s %8s %8s %8s\n",
1797 "Port", "Status", "Link", "Speed",
1799 vsc9953_port_config_show(parsed_cmd->port);
1802 for (i = 0; i < VSC9953_MAX_PORTS; i++)
1803 vsc9953_phy_autoneg(i);
1804 printf("%8s %8s %8s %8s %8s\n",
1805 "Port", "Status", "Link", "Speed", "Duplex");
1806 for (i = 0; i < VSC9953_MAX_PORTS; i++)
1807 vsc9953_port_config_show(i);
1810 return CMD_RET_SUCCESS;
1813 static int vsc9953_port_stats_key_func(struct ethsw_command_def *parsed_cmd)
1817 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
1818 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
1819 printf("Invalid port number: %d\n", parsed_cmd->port);
1820 return CMD_RET_FAILURE;
1822 vsc9953_port_statistics_show(parsed_cmd->port);
1824 for (i = 0; i < VSC9953_MAX_PORTS; i++)
1825 vsc9953_port_statistics_show(i);
1828 return CMD_RET_SUCCESS;
1831 static int vsc9953_port_stats_clear_key_func(struct ethsw_command_def
1836 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
1837 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
1838 printf("Invalid port number: %d\n", parsed_cmd->port);
1839 return CMD_RET_FAILURE;
1841 vsc9953_port_statistics_clear(parsed_cmd->port);
1843 for (i = 0; i < VSC9953_MAX_PORTS; i++)
1844 vsc9953_port_statistics_clear(i);
1847 return CMD_RET_SUCCESS;
1850 static int vsc9953_learn_show_key_func(struct ethsw_command_def *parsed_cmd)
1853 enum port_learn_mode mode;
1855 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
1856 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
1857 printf("Invalid port number: %d\n", parsed_cmd->port);
1858 return CMD_RET_FAILURE;
1860 if (vsc9953_port_learn_mode_get(parsed_cmd->port, &mode))
1861 return CMD_RET_FAILURE;
1862 printf("%7s %11s\n", "Port", "Learn mode");
1864 case PORT_LEARN_NONE:
1865 printf("%7d %11s\n", parsed_cmd->port, "disable");
1867 case PORT_LEARN_AUTO:
1868 printf("%7d %11s\n", parsed_cmd->port, "auto");
1871 printf("%7d %11s\n", parsed_cmd->port, "-");
1874 printf("%7s %11s\n", "Port", "Learn mode");
1875 for (i = 0; i < VSC9953_MAX_PORTS; i++) {
1876 if (vsc9953_port_learn_mode_get(i, &mode))
1879 case PORT_LEARN_NONE:
1880 printf("%7d %11s\n", i, "disable");
1882 case PORT_LEARN_AUTO:
1883 printf("%7d %11s\n", i, "auto");
1886 printf("%7d %11s\n", i, "-");
1891 return CMD_RET_SUCCESS;
1894 static int vsc9953_learn_set_key_func(struct ethsw_command_def *parsed_cmd)
1897 enum port_learn_mode mode;
1899 /* Last keyword should tell us the learn mode */
1900 if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
1902 mode = PORT_LEARN_AUTO;
1903 else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
1905 mode = PORT_LEARN_NONE;
1907 return CMD_RET_USAGE;
1909 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
1910 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
1911 printf("Invalid port number: %d\n", parsed_cmd->port);
1912 return CMD_RET_FAILURE;
1914 vsc9953_port_learn_mode_set(parsed_cmd->port, mode);
1916 for (i = 0; i < VSC9953_MAX_PORTS; i++)
1917 vsc9953_port_learn_mode_set(i, mode);
1920 return CMD_RET_SUCCESS;
1923 static int vsc9953_fdb_show_key_func(struct ethsw_command_def *parsed_cmd)
1925 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL &&
1926 !VSC9953_PORT_CHECK(parsed_cmd->port)) {
1927 printf("Invalid port number: %d\n", parsed_cmd->port);
1928 return CMD_RET_FAILURE;
1931 if (parsed_cmd->vid != ETHSW_CMD_VLAN_ALL &&
1932 !VSC9953_VLAN_CHECK(parsed_cmd->vid)) {
1933 printf("Invalid VID number: %d\n", parsed_cmd->vid);
1934 return CMD_RET_FAILURE;
1937 vsc9953_mac_table_show(parsed_cmd->port, parsed_cmd->vid);
1939 return CMD_RET_SUCCESS;
1942 static int vsc9953_fdb_flush_key_func(struct ethsw_command_def *parsed_cmd)
1944 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL &&
1945 !VSC9953_PORT_CHECK(parsed_cmd->port)) {
1946 printf("Invalid port number: %d\n", parsed_cmd->port);
1947 return CMD_RET_FAILURE;
1950 if (parsed_cmd->vid != ETHSW_CMD_VLAN_ALL &&
1951 !VSC9953_VLAN_CHECK(parsed_cmd->vid)) {
1952 printf("Invalid VID number: %d\n", parsed_cmd->vid);
1953 return CMD_RET_FAILURE;
1956 vsc9953_mac_table_flush(parsed_cmd->port, parsed_cmd->vid);
1958 return CMD_RET_SUCCESS;
1961 static int vsc9953_fdb_entry_add_key_func(struct ethsw_command_def *parsed_cmd)
1965 /* a port number must be present */
1966 if (parsed_cmd->port == ETHSW_CMD_PORT_ALL) {
1967 printf("Please specify a port\n");
1968 return CMD_RET_FAILURE;
1971 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
1972 printf("Invalid port number: %d\n", parsed_cmd->port);
1973 return CMD_RET_FAILURE;
1976 /* Use VLAN 1 if VID is not set */
1977 vid = (parsed_cmd->vid == ETHSW_CMD_VLAN_ALL ? 1 : parsed_cmd->vid);
1979 if (!VSC9953_VLAN_CHECK(vid)) {
1980 printf("Invalid VID number: %d\n", vid);
1981 return CMD_RET_FAILURE;
1984 if (vsc9953_mac_table_add(parsed_cmd->port, parsed_cmd->ethaddr, vid))
1985 return CMD_RET_FAILURE;
1987 return CMD_RET_SUCCESS;
1990 static int vsc9953_fdb_entry_del_key_func(struct ethsw_command_def *parsed_cmd)
1994 /* Use VLAN 1 if VID is not set */
1995 vid = (parsed_cmd->vid == ETHSW_CMD_VLAN_ALL ? 1 : parsed_cmd->vid);
1997 if (!VSC9953_VLAN_CHECK(vid)) {
1998 printf("Invalid VID number: %d\n", vid);
1999 return CMD_RET_FAILURE;
2002 if (vsc9953_mac_table_del(parsed_cmd->ethaddr, vid))
2003 return CMD_RET_FAILURE;
2005 return CMD_RET_SUCCESS;
2008 static int vsc9953_pvid_show_key_func(struct ethsw_command_def *parsed_cmd)
2013 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
2014 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
2015 printf("Invalid port number: %d\n", parsed_cmd->port);
2016 return CMD_RET_FAILURE;
2019 if (vsc9953_port_vlan_pvid_get(parsed_cmd->port, &pvid))
2020 return CMD_RET_FAILURE;
2021 printf("%7s %7s\n", "Port", "PVID");
2022 printf("%7d %7d\n", parsed_cmd->port, pvid);
2024 printf("%7s %7s\n", "Port", "PVID");
2025 for (i = 0; i < VSC9953_MAX_PORTS; i++) {
2026 if (vsc9953_port_vlan_pvid_get(i, &pvid))
2028 printf("%7d %7d\n", i, pvid);
2032 return CMD_RET_SUCCESS;
2035 static int vsc9953_pvid_set_key_func(struct ethsw_command_def *parsed_cmd)
2037 /* PVID number should be set in parsed_cmd->vid */
2038 if (parsed_cmd->vid == ETHSW_CMD_VLAN_ALL) {
2039 printf("Please set a pvid value\n");
2040 return CMD_RET_FAILURE;
2043 if (!VSC9953_VLAN_CHECK(parsed_cmd->vid)) {
2044 printf("Invalid VID number: %d\n", parsed_cmd->vid);
2045 return CMD_RET_FAILURE;
2048 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
2049 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
2050 printf("Invalid port number: %d\n", parsed_cmd->port);
2051 return CMD_RET_FAILURE;
2053 vsc9953_port_vlan_pvid_set(parsed_cmd->port, parsed_cmd->vid);
2055 vsc9953_port_all_vlan_pvid_set(parsed_cmd->vid);
2058 return CMD_RET_SUCCESS;
2061 static int vsc9953_vlan_show_key_func(struct ethsw_command_def *parsed_cmd)
2065 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
2066 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
2067 printf("Invalid port number: %d\n", parsed_cmd->port);
2068 return CMD_RET_FAILURE;
2070 vsc9953_vlan_membership_show(parsed_cmd->port);
2072 for (i = 0; i < VSC9953_MAX_PORTS; i++)
2073 vsc9953_vlan_membership_show(i);
2076 return CMD_RET_SUCCESS;
2079 static int vsc9953_vlan_set_key_func(struct ethsw_command_def *parsed_cmd)
2084 /* VLAN should be set in parsed_cmd->vid */
2085 if (parsed_cmd->vid == ETHSW_CMD_VLAN_ALL) {
2086 printf("Please set a vlan value\n");
2087 return CMD_RET_FAILURE;
2090 if (!VSC9953_VLAN_CHECK(parsed_cmd->vid)) {
2091 printf("Invalid VID number: %d\n", parsed_cmd->vid);
2092 return CMD_RET_FAILURE;
2095 /* keywords add/delete should be the last but one in array */
2096 if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 2] ==
2099 else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 2] ==
2103 return CMD_RET_USAGE;
2105 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
2106 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
2107 printf("Invalid port number: %d\n", parsed_cmd->port);
2108 return CMD_RET_FAILURE;
2110 vsc9953_vlan_table_membership_set(parsed_cmd->vid,
2111 parsed_cmd->port, add);
2113 for (i = 0; i < VSC9953_MAX_PORTS; i++)
2114 vsc9953_vlan_table_membership_set(parsed_cmd->vid, i,
2118 return CMD_RET_SUCCESS;
2120 static int vsc9953_port_untag_show_key_func(
2121 struct ethsw_command_def *parsed_cmd)
2125 printf("%7s\t%17s\n", "Port", "Untag");
2126 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
2127 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
2128 printf("Invalid port number: %d\n", parsed_cmd->port);
2129 return CMD_RET_FAILURE;
2131 vsc9953_port_vlan_egr_untag_show(parsed_cmd->port);
2133 for (i = 0; i < VSC9953_MAX_PORTS; i++)
2134 vsc9953_port_vlan_egr_untag_show(i);
2137 return CMD_RET_SUCCESS;
2140 static int vsc9953_port_untag_set_key_func(struct ethsw_command_def *parsed_cmd)
2143 enum egress_untag_mode mode;
2145 /* keywords for the untagged mode are the last in the array */
2146 if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
2148 mode = EGRESS_UNTAG_ALL;
2149 else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
2151 mode = EGRESS_UNTAG_NONE;
2152 else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
2154 mode = EGRESS_UNTAG_PVID_AND_ZERO;
2156 return CMD_RET_USAGE;
2158 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
2159 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
2160 printf("Invalid port number: %d\n", parsed_cmd->port);
2161 return CMD_RET_FAILURE;
2163 vsc9953_port_vlan_egr_untag_set(parsed_cmd->port, mode);
2165 for (i = 0; i < VSC9953_MAX_PORTS; i++)
2166 vsc9953_port_vlan_egr_untag_set(i, mode);
2169 return CMD_RET_SUCCESS;
2172 static int vsc9953_egr_vlan_tag_show_key_func(
2173 struct ethsw_command_def *parsed_cmd)
2176 enum egress_vlan_tag mode;
2178 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
2179 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
2180 printf("Invalid port number: %d\n", parsed_cmd->port);
2181 return CMD_RET_FAILURE;
2183 vsc9953_port_vlan_egress_tag_get(parsed_cmd->port, &mode);
2184 printf("%7s\t%12s\n", "Port", "Egress VID");
2185 printf("%7d\t", parsed_cmd->port);
2188 printf("%12s\n", "classified");
2191 printf("%12s\n", "pvid");
2194 printf("%12s\n", "-");
2197 printf("%7s\t%12s\n", "Port", "Egress VID");
2198 for (i = 0; i < VSC9953_MAX_PORTS; i++) {
2199 vsc9953_port_vlan_egress_tag_get(i, &mode);
2202 printf("%7d\t%12s\n", i, "classified");
2205 printf("%7d\t%12s\n", i, "pvid");
2208 printf("%7d\t%12s\n", i, "-");
2213 return CMD_RET_SUCCESS;
2216 static int vsc9953_egr_vlan_tag_set_key_func(
2217 struct ethsw_command_def *parsed_cmd)
2220 enum egress_vlan_tag mode;
2222 /* keywords for the egress vlan tag mode are the last in the array */
2223 if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
2225 mode = EGR_TAG_PVID;
2226 else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
2227 ethsw_id_classified)
2228 mode = EGR_TAG_CLASS;
2230 return CMD_RET_USAGE;
2232 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
2233 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
2234 printf("Invalid port number: %d\n", parsed_cmd->port);
2235 return CMD_RET_FAILURE;
2237 vsc9953_port_vlan_egress_tag_set(parsed_cmd->port, mode);
2239 for (i = 0; i < VSC9953_MAX_PORTS; i++)
2240 vsc9953_port_vlan_egress_tag_set(i, mode);
2243 return CMD_RET_SUCCESS;
2246 static int vsc9953_vlan_learn_show_key_func(
2247 struct ethsw_command_def *parsed_cmd)
2250 enum vlan_learning_mode mode;
2252 rc = vsc9953_vlan_learning_get(&mode);
2254 return CMD_RET_FAILURE;
2257 case SHARED_VLAN_LEARNING:
2258 printf("VLAN learning mode: shared\n");
2260 case PRIVATE_VLAN_LEARNING:
2261 printf("VLAN learning mode: private\n");
2264 printf("Unknown VLAN learning mode\n");
2265 rc = CMD_RET_FAILURE;
2268 return CMD_RET_SUCCESS;
2271 static int vsc9953_vlan_learn_set_key_func(struct ethsw_command_def *parsed_cmd)
2273 enum vlan_learning_mode mode;
2275 /* keywords for shared/private are the last in the array */
2276 if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
2278 mode = SHARED_VLAN_LEARNING;
2279 else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
2281 mode = PRIVATE_VLAN_LEARNING;
2283 return CMD_RET_USAGE;
2285 vsc9953_vlan_learning_set(mode);
2287 return CMD_RET_SUCCESS;
2290 static int vsc9953_ingr_fltr_show_key_func(struct ethsw_command_def *parsed_cmd)
2295 printf("%7s\t%18s\n", "Port", "Ingress filtering");
2296 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
2297 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
2298 printf("Invalid port number: %d\n", parsed_cmd->port);
2299 return CMD_RET_FAILURE;
2301 enabled = vsc9953_port_ingress_filtering_get(parsed_cmd->port);
2302 printf("%7d\t%18s\n", parsed_cmd->port, enabled ? "enable" :
2305 for (i = 0; i < VSC9953_MAX_PORTS; i++) {
2306 enabled = vsc9953_port_ingress_filtering_get(i);
2307 printf("%7d\t%18s\n", parsed_cmd->port, enabled ?
2313 return CMD_RET_SUCCESS;
2316 static int vsc9953_ingr_fltr_set_key_func(struct ethsw_command_def *parsed_cmd)
2321 /* keywords for enabling/disabling ingress filtering
2322 * are the last in the array
2324 if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
2327 else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
2331 return CMD_RET_USAGE;
2333 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
2334 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
2335 printf("Invalid port number: %d\n", parsed_cmd->port);
2336 return CMD_RET_FAILURE;
2338 vsc9953_port_ingress_filtering_set(parsed_cmd->port, enable);
2340 for (i = 0; i < VSC9953_MAX_PORTS; i++)
2341 vsc9953_port_ingress_filtering_set(i, enable);
2344 return CMD_RET_SUCCESS;
2347 static int vsc9953_port_aggr_show_key_func(struct ethsw_command_def *parsed_cmd)
2352 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
2353 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
2354 printf("Invalid port number: %d\n", parsed_cmd->port);
2355 return CMD_RET_FAILURE;
2358 if (vsc9953_port_aggr_grp_get(parsed_cmd->port, &aggr_grp))
2359 return CMD_RET_FAILURE;
2360 printf("%7s %10s\n", "Port", "Aggr grp");
2361 printf("%7d %10d\n", parsed_cmd->port, aggr_grp);
2363 printf("%7s %10s\n", "Port", "Aggr grp");
2364 for (i = 0; i < VSC9953_MAX_PORTS; i++) {
2365 if (vsc9953_port_aggr_grp_get(i, &aggr_grp))
2367 printf("%7d %10d\n", i, aggr_grp);
2371 return CMD_RET_SUCCESS;
2374 static int vsc9953_port_aggr_set_key_func(struct ethsw_command_def *parsed_cmd)
2378 /* Aggregation group number should be set in parsed_cmd->aggr_grp */
2379 if (parsed_cmd->aggr_grp == ETHSW_CMD_AGGR_GRP_NONE) {
2380 printf("Please set an aggregation group value\n");
2381 return CMD_RET_FAILURE;
2384 if (!VSC9953_PORT_CHECK(parsed_cmd->aggr_grp)) {
2385 printf("Invalid aggregation group number: %d\n",
2386 parsed_cmd->aggr_grp);
2387 return CMD_RET_FAILURE;
2390 if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
2391 if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
2392 printf("Invalid port number: %d\n", parsed_cmd->port);
2393 return CMD_RET_FAILURE;
2395 if (vsc9953_port_aggr_grp_set(parsed_cmd->port,
2396 parsed_cmd->aggr_grp)) {
2397 printf("Port %d: failed to set aggr group %d\n",
2398 parsed_cmd->port, parsed_cmd->aggr_grp);
2401 for (i = 0; i < VSC9953_MAX_PORTS; i++) {
2402 if (vsc9953_port_aggr_grp_set(i,
2403 parsed_cmd->aggr_grp)) {
2404 printf("Port %d: failed to set aggr group %d\n",
2405 i, parsed_cmd->aggr_grp);
2410 return CMD_RET_SUCCESS;
2413 static struct ethsw_command_func vsc9953_cmd_func = {
2414 .ethsw_name = "L2 Switch VSC9953",
2415 .port_enable = &vsc9953_port_status_key_func,
2416 .port_disable = &vsc9953_port_status_key_func,
2417 .port_show = &vsc9953_port_config_key_func,
2418 .port_stats = &vsc9953_port_stats_key_func,
2419 .port_stats_clear = &vsc9953_port_stats_clear_key_func,
2420 .port_learn = &vsc9953_learn_set_key_func,
2421 .port_learn_show = &vsc9953_learn_show_key_func,
2422 .fdb_show = &vsc9953_fdb_show_key_func,
2423 .fdb_flush = &vsc9953_fdb_flush_key_func,
2424 .fdb_entry_add = &vsc9953_fdb_entry_add_key_func,
2425 .fdb_entry_del = &vsc9953_fdb_entry_del_key_func,
2426 .pvid_show = &vsc9953_pvid_show_key_func,
2427 .pvid_set = &vsc9953_pvid_set_key_func,
2428 .vlan_show = &vsc9953_vlan_show_key_func,
2429 .vlan_set = &vsc9953_vlan_set_key_func,
2430 .port_untag_show = &vsc9953_port_untag_show_key_func,
2431 .port_untag_set = &vsc9953_port_untag_set_key_func,
2432 .port_egr_vlan_show = &vsc9953_egr_vlan_tag_show_key_func,
2433 .port_egr_vlan_set = &vsc9953_egr_vlan_tag_set_key_func,
2434 .vlan_learn_show = &vsc9953_vlan_learn_show_key_func,
2435 .vlan_learn_set = &vsc9953_vlan_learn_set_key_func,
2436 .port_ingr_filt_show = &vsc9953_ingr_fltr_show_key_func,
2437 .port_ingr_filt_set = &vsc9953_ingr_fltr_set_key_func,
2438 .port_aggr_show = &vsc9953_port_aggr_show_key_func,
2439 .port_aggr_set = &vsc9953_port_aggr_set_key_func,
2442 #endif /* CONFIG_CMD_ETHSW */
2444 /*****************************************************************************
2445 At startup, the default configuration would be:
2446 - HW learning enabled on all ports; (HW default)
2447 - All ports are in VLAN 1;
2448 - All ports are VLAN aware;
2449 - All ports have POP_COUNT 1;
2450 - All ports have PVID 1;
2451 - All ports have TPID 0x8100; (HW default)
2452 - All ports tag frames classified to all VLANs that are not PVID;
2453 *****************************************************************************/
2454 void vsc9953_default_configuration(void)
2458 if (vsc9953_autoage_time_set(VSC9953_DEFAULT_AGE_TIME))
2459 debug("VSC9953: failed to set AGE time to %d\n",
2460 VSC9953_DEFAULT_AGE_TIME);
2462 for (i = 0; i < VSC9953_MAX_VLAN; i++)
2463 vsc9953_vlan_table_membership_all_set(i, 0);
2464 vsc9953_port_all_vlan_aware_set(1);
2465 vsc9953_port_all_vlan_pvid_set(1);
2466 vsc9953_port_all_vlan_poncnt_set(1);
2467 vsc9953_vlan_table_membership_all_set(1, 1);
2468 vsc9953_vlan_ingr_fltr_learn_drop(1);
2469 vsc9953_port_all_vlan_egress_untagged_set(EGRESS_UNTAG_PVID_AND_ZERO);
2470 if (vsc9953_aggr_code_set(AGGR_CODE_ALL))
2471 debug("VSC9953: failed to set default aggregation code mode\n");
2474 static void vcap_entry2cache_init(u32 target, u32 entry_words)
2478 for (i = 0; i < entry_words; i++) {
2479 out_le32((unsigned int *)(VSC9953_OFFSET +
2480 VSC9953_VCAP_CACHE_ENTRY_DAT(target, i)), 0x00);
2481 out_le32((unsigned int *)(VSC9953_OFFSET +
2482 VSC9953_VCAP_CACHE_MASK_DAT(target, i)), 0xFF);
2485 out_le32((unsigned int *)(VSC9953_OFFSET +
2486 VSC9953_VCAP_CACHE_TG_DAT(target)), 0x00);
2487 out_le32((unsigned int *)(VSC9953_OFFSET +
2488 VSC9953_VCAP_CFG_MV_CFG(target)),
2489 VSC9953_VCAP_CFG_MV_CFG_SIZE(entry_words));
2492 static void vcap_action2cache_init(u32 target, u32 action_words,
2497 for (i = 0; i < action_words; i++)
2498 out_le32((unsigned int *)(VSC9953_OFFSET +
2499 VSC9953_VCAP_CACHE_ACTION_DAT(target, i)), 0x00);
2501 for (i = 0; i < counter_words; i++)
2502 out_le32((unsigned int *)(VSC9953_OFFSET +
2503 VSC9953_VCAP_CACHE_CNT_DAT(target, i)), 0x00);
2506 static int vcap_cmd(u32 target, u16 ix, int cmd, int sel, int entry_count)
2509 u32 value = (VSC9953_VCAP_UPDATE_CTRL_UPDATE_CMD(cmd) |
2510 VSC9953_VCAP_UPDATE_CTRL_UPDATE_ADDR(ix) |
2511 VSC9953_VCAP_UPDATE_CTRL_UPDATE_SHOT);
2513 if ((sel & TCAM_SEL_ENTRY) && ix >= entry_count)
2514 return CMD_RET_FAILURE;
2516 if (!(sel & TCAM_SEL_ENTRY))
2517 value |= VSC9953_VCAP_UPDATE_CTRL_UPDATE_ENTRY_DIS;
2519 if (!(sel & TCAM_SEL_ACTION))
2520 value |= VSC9953_VCAP_UPDATE_CTRL_UPDATE_ACTION_DIS;
2522 if (!(sel & TCAM_SEL_COUNTER))
2523 value |= VSC9953_VCAP_UPDATE_CTRL_UPDATE_CNT_DIS;
2525 out_le32((unsigned int *)(VSC9953_OFFSET +
2526 VSC9953_VCAP_CFG_UPDATE_CTRL(tgt)), value);
2529 value = in_le32((unsigned int *)(VSC9953_OFFSET +
2530 VSC9953_VCAP_CFG_UPDATE_CTRL(tgt)));
2532 } while (value & VSC9953_VCAP_UPDATE_CTRL_UPDATE_SHOT);
2534 return CMD_RET_SUCCESS;
2537 static void vsc9953_vcap_init(void)
2539 u32 tgt = VSC9953_ES0;
2543 vcap_entry2cache_init(tgt, ENTRY_WORDS_ES0);
2544 cmd_ret = vcap_cmd(tgt, 0, TCAM_CMD_INITIALIZE, TCAM_SEL_ENTRY,
2546 if (cmd_ret != CMD_RET_SUCCESS)
2547 debug("VSC9953:%d invalid TCAM_SEL_ENTRY\n",
2550 /* write actions and counters */
2551 vcap_action2cache_init(tgt, BITS_TO_DWORD(ES0_ACT_WIDTH),
2552 BITS_TO_DWORD(ES0_CNT_WIDTH));
2553 out_le32((unsigned int *)(VSC9953_OFFSET +
2554 VSC9953_VCAP_CFG_MV_CFG(tgt)),
2555 VSC9953_VCAP_CFG_MV_CFG_SIZE(ES0_ACT_COUNT));
2556 cmd_ret = vcap_cmd(tgt, 0, TCAM_CMD_INITIALIZE,
2557 TCAM_SEL_ACTION | TCAM_SEL_COUNTER, ENTRY_WORDS_ES0);
2558 if (cmd_ret != CMD_RET_SUCCESS)
2559 debug("VSC9953:%d invalid TCAM_SEL_ACTION | TCAM_SEL_COUNTER\n",
2565 vcap_entry2cache_init(tgt, ENTRY_WORDS_IS1);
2566 cmd_ret = vcap_cmd(tgt, 0, TCAM_CMD_INITIALIZE, TCAM_SEL_ENTRY,
2568 if (cmd_ret != CMD_RET_SUCCESS)
2569 debug("VSC9953:%d invalid TCAM_SEL_ENTRY\n",
2572 /* write actions and counters */
2573 vcap_action2cache_init(tgt, BITS_TO_DWORD(IS1_ACT_WIDTH),
2574 BITS_TO_DWORD(IS1_CNT_WIDTH));
2575 out_le32((unsigned int *)(VSC9953_OFFSET +
2576 VSC9953_VCAP_CFG_MV_CFG(tgt)),
2577 VSC9953_VCAP_CFG_MV_CFG_SIZE(IS1_ACT_COUNT));
2578 cmd_ret = vcap_cmd(tgt, 0, TCAM_CMD_INITIALIZE,
2579 TCAM_SEL_ACTION | TCAM_SEL_COUNTER, ENTRY_WORDS_IS1);
2580 if (cmd_ret != CMD_RET_SUCCESS)
2581 debug("VSC9953:%d invalid TCAM_SEL_ACTION | TCAM_SEL_COUNTER\n",
2587 vcap_entry2cache_init(tgt, ENTRY_WORDS_IS2);
2588 cmd_ret = vcap_cmd(tgt, 0, TCAM_CMD_INITIALIZE, TCAM_SEL_ENTRY,
2590 if (cmd_ret != CMD_RET_SUCCESS)
2591 debug("VSC9953:%d invalid selection: TCAM_SEL_ENTRY\n",
2594 /* write actions and counters */
2595 vcap_action2cache_init(tgt, BITS_TO_DWORD(IS2_ACT_WIDTH),
2596 BITS_TO_DWORD(IS2_CNT_WIDTH));
2597 out_le32((unsigned int *)(VSC9953_OFFSET +
2598 VSC9953_VCAP_CFG_MV_CFG(tgt)),
2599 VSC9953_VCAP_CFG_MV_CFG_SIZE(IS2_ACT_COUNT));
2600 cmd_ret = vcap_cmd(tgt, 0, TCAM_CMD_INITIALIZE,
2601 TCAM_SEL_ACTION | TCAM_SEL_COUNTER, ENTRY_WORDS_IS2);
2602 if (cmd_ret != CMD_RET_SUCCESS)
2603 debug("VSC9953:%d invalid TCAM_SEL_ACTION | TCAM_SEL_COUNTER\n",
2607 void vsc9953_init(bd_t *bis)
2613 struct vsc9953_system_reg *l2sys_reg;
2614 struct vsc9953_qsys_reg *l2qsys_reg;
2615 struct vsc9953_dev_gmii *l2dev_gmii_reg;
2616 struct vsc9953_analyzer *l2ana_reg;
2617 struct vsc9953_devcpu_gcb *l2dev_gcb;
2619 l2dev_gmii_reg = (struct vsc9953_dev_gmii *)(VSC9953_OFFSET +
2620 VSC9953_DEV_GMII_OFFSET);
2622 l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
2623 VSC9953_ANA_OFFSET);
2625 l2sys_reg = (struct vsc9953_system_reg *)(VSC9953_OFFSET +
2626 VSC9953_SYS_OFFSET);
2628 l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET +
2629 VSC9953_QSYS_OFFSET);
2631 l2dev_gcb = (struct vsc9953_devcpu_gcb *)(VSC9953_OFFSET +
2632 VSC9953_DEVCPU_GCB);
2634 out_le32(&l2dev_gcb->chip_regs.soft_rst,
2635 VSC9953_SOFT_SWC_RST_ENA);
2637 while ((in_le32(&l2dev_gcb->chip_regs.soft_rst) &
2638 VSC9953_SOFT_SWC_RST_ENA) && --timeout)
2639 udelay(1); /* busy wait for vsc9953 soft reset */
2641 debug("Timeout waiting for VSC9953 to reset\n");
2643 out_le32(&l2sys_reg->sys.reset_cfg, VSC9953_MEM_ENABLE |
2647 while ((in_le32(&l2sys_reg->sys.reset_cfg) &
2648 VSC9953_MEM_INIT) && --timeout)
2649 udelay(1); /* busy wait for vsc9953 memory init */
2651 debug("Timeout waiting for VSC9953 memory to initialize\n");
2653 out_le32(&l2sys_reg->sys.reset_cfg, (in_le32(&l2sys_reg->sys.reset_cfg)
2654 | VSC9953_CORE_ENABLE));
2656 /* VSC9953 Setting to be done once only */
2657 out_le32(&l2qsys_reg->sys.ext_cpu_cfg, 0x00000b00);
2659 for (i = 0; i < VSC9953_MAX_PORTS; i++) {
2660 if (vsc9953_port_init(i))
2661 printf("Failed to initialize l2switch port %d\n", i);
2663 if (!vsc9953_l2sw.port[i].enabled)
2666 /* Enable VSC9953 GMII Ports Port ID 0 - 7 */
2667 if (VSC9953_INTERNAL_PORT_CHECK(i)) {
2668 out_le32(&l2ana_reg->pfc[i].pfc_cfg,
2669 VSC9953_PFC_FC_QSGMII);
2670 out_le32(&l2sys_reg->pause_cfg.mac_fc_cfg[i],
2671 VSC9953_MAC_FC_CFG_QSGMII);
2673 out_le32(&l2ana_reg->pfc[i].pfc_cfg,
2675 out_le32(&l2sys_reg->pause_cfg.mac_fc_cfg[i],
2676 VSC9953_MAC_FC_CFG);
2679 l2dev_gmii_reg = (struct vsc9953_dev_gmii *)
2680 (VSC9953_OFFSET + VSC9953_DEV_GMII_OFFSET +
2681 T1040_SWITCH_GMII_DEV_OFFSET * i);
2683 out_le32(&l2dev_gmii_reg->port_mode.clock_cfg,
2685 out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_ena_cfg,
2686 VSC9953_MAC_ENA_CFG);
2687 out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_mode_cfg,
2688 VSC9953_MAC_MODE_CFG);
2689 out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_ifg_cfg,
2690 VSC9953_MAC_IFG_CFG);
2691 /* mac_hdx_cfg varies with port id*/
2692 hdx_cfg = VSC9953_MAC_HDX_CFG | (i << 16);
2693 out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_hdx_cfg, hdx_cfg);
2694 out_le32(&l2sys_reg->sys.front_port_mode[i],
2695 VSC9953_FRONT_PORT_MODE);
2696 setbits_le32(&l2qsys_reg->sys.switch_port_mode[i],
2698 out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_maxlen_cfg,
2699 VSC9953_MAC_MAX_LEN);
2700 out_le32(&l2sys_reg->pause_cfg.pause_cfg[i],
2705 /* Initialize Lynx PHY Wrappers */
2707 if (vsc9953_l2sw.port[i].enet_if ==
2708 PHY_INTERFACE_MODE_QSGMII)
2709 phy_addr = (i + 0x4) & 0x1F;
2710 else if (vsc9953_l2sw.port[i].enet_if ==
2711 PHY_INTERFACE_MODE_SGMII)
2712 phy_addr = (i + 1) & 0x1F;
2715 /* SGMII IF mode + AN enable */
2716 vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr,
2717 0x14, PHY_SGMII_IF_MODE_AN |
2718 PHY_SGMII_IF_MODE_SGMII);
2719 /* Dev ability according to SGMII specification */
2720 vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr,
2721 0x4, PHY_SGMII_DEV_ABILITY_SGMII);
2722 /* Adjust link timer for SGMII
2723 * 1.6 ms in units of 8 ns = 2 * 10^5 = 0x30d40
2725 vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr,
2727 vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr,
2730 vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr,
2731 0x0, PHY_SGMII_CR_DEF_VAL |
2732 PHY_SGMII_CR_RESET_AN);
2735 while ((vsc9953_mdio_read(&l2dev_gcb->mii_mng[0],
2736 phy_addr, 0x01) & 0x0020) && --timeout)
2737 udelay(1); /* wait for AN to complete */
2739 debug("Timeout waiting for AN to complete\n");
2743 vsc9953_vcap_init();
2744 vsc9953_default_configuration();
2746 #ifdef CONFIG_CMD_ETHSW
2747 if (ethsw_define_functions(&vsc9953_cmd_func) < 0)
2748 debug("Unable to use \"ethsw\" commands\n");
2751 printf("VSC9953 L2 switch initialized\n");