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