]> git.sur5r.net Git - u-boot/blob - drivers/net/vsc9953.c
drivers: net: vsc9953: Fix FDB aging time
[u-boot] / drivers / net / vsc9953.c
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 }