1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * SMSC LAN9[12]1[567] Network driver
4 *
5 * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
6 */
7
8 #include <common.h>
9 #include <command.h>
10 #include <malloc.h>
11 #include <net.h>
12 #include <miiphy.h>
13 #include <linux/io.h>
14 #include <linux/delay.h>
15 #include <linux/types.h>
16
17 #include "smc911x.h"
18
19 struct chip_id {
20 u16 id;
21 char *name;
22 };
23
24 struct smc911x_priv {
25 #ifndef CONFIG_DM_ETH
26 struct eth_device dev;
27 #endif
28 phys_addr_t iobase;
29 const struct chip_id *chipid;
30 unsigned char enetaddr[6];
31 };
32
33 static const struct chip_id chip_ids[] = {
34 { CHIP_89218, "LAN89218" },
35 { CHIP_9115, "LAN9115" },
36 { CHIP_9116, "LAN9116" },
37 { CHIP_9117, "LAN9117" },
38 { CHIP_9118, "LAN9118" },
39 { CHIP_9211, "LAN9211" },
40 { CHIP_9215, "LAN9215" },
41 { CHIP_9216, "LAN9216" },
42 { CHIP_9217, "LAN9217" },
43 { CHIP_9218, "LAN9218" },
44 { CHIP_9220, "LAN9220" },
45 { CHIP_9221, "LAN9221" },
46 { 0, NULL },
47 };
48
49 #define DRIVERNAME "smc911x"
50
51 #if defined (CONFIG_SMC911X_32_BIT) && \
52 defined (CONFIG_SMC911X_16_BIT)
53 #error "SMC911X: Only one of CONFIG_SMC911X_32_BIT and \
54 CONFIG_SMC911X_16_BIT shall be set"
55 #endif
56
57 #if defined (CONFIG_SMC911X_32_BIT)
smc911x_reg_read(struct smc911x_priv * priv,u32 offset)58 static u32 smc911x_reg_read(struct smc911x_priv *priv, u32 offset)
59 {
60 return readl(priv->iobase + offset);
61 }
62
smc911x_reg_write(struct smc911x_priv * priv,u32 offset,u32 val)63 static void smc911x_reg_write(struct smc911x_priv *priv, u32 offset, u32 val)
64 {
65 writel(val, priv->iobase + offset);
66 }
67 #elif defined (CONFIG_SMC911X_16_BIT)
smc911x_reg_read(struct smc911x_priv * priv,u32 offset)68 static u32 smc911x_reg_read(struct smc911x_priv *priv, u32 offset)
69 {
70 return (readw(priv->iobase + offset) & 0xffff) |
71 (readw(priv->iobase + offset + 2) << 16);
72 }
smc911x_reg_write(struct smc911x_priv * priv,u32 offset,u32 val)73 static void smc911x_reg_write(struct smc911x_priv *priv, u32 offset, u32 val)
74 {
75 writew(val & 0xffff, priv->iobase + offset);
76 writew(val >> 16, priv->iobase + offset + 2);
77 }
78 #else
79 #error "SMC911X: undefined bus width"
80 #endif /* CONFIG_SMC911X_16_BIT */
81
smc911x_get_mac_csr(struct smc911x_priv * priv,u8 reg)82 static u32 smc911x_get_mac_csr(struct smc911x_priv *priv, u8 reg)
83 {
84 while (smc911x_reg_read(priv, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
85 ;
86 smc911x_reg_write(priv, MAC_CSR_CMD,
87 MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg);
88 while (smc911x_reg_read(priv, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
89 ;
90
91 return smc911x_reg_read(priv, MAC_CSR_DATA);
92 }
93
smc911x_set_mac_csr(struct smc911x_priv * priv,u8 reg,u32 data)94 static void smc911x_set_mac_csr(struct smc911x_priv *priv, u8 reg, u32 data)
95 {
96 while (smc911x_reg_read(priv, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
97 ;
98 smc911x_reg_write(priv, MAC_CSR_DATA, data);
99 smc911x_reg_write(priv, MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | reg);
100 while (smc911x_reg_read(priv, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
101 ;
102 }
103
smc911x_detect_chip(struct smc911x_priv * priv)104 static int smc911x_detect_chip(struct smc911x_priv *priv)
105 {
106 unsigned long val, i;
107
108 val = smc911x_reg_read(priv, BYTE_TEST);
109 if (val == 0xffffffff) {
110 /* Special case -- no chip present */
111 return -1;
112 } else if (val != 0x87654321) {
113 printf(DRIVERNAME ": Invalid chip endian 0x%08lx\n", val);
114 return -1;
115 }
116
117 val = smc911x_reg_read(priv, ID_REV) >> 16;
118 for (i = 0; chip_ids[i].id != 0; i++) {
119 if (chip_ids[i].id == val) break;
120 }
121 if (!chip_ids[i].id) {
122 printf(DRIVERNAME ": Unknown chip ID %04lx\n", val);
123 return -1;
124 }
125
126 priv->chipid = &chip_ids[i];
127
128 return 0;
129 }
130
smc911x_reset(struct smc911x_priv * priv)131 static void smc911x_reset(struct smc911x_priv *priv)
132 {
133 int timeout;
134
135 /*
136 * Take out of PM setting first
137 * Device is already wake up if PMT_CTRL_READY bit is set
138 */
139 if ((smc911x_reg_read(priv, PMT_CTRL) & PMT_CTRL_READY) == 0) {
140 /* Write to the bytetest will take out of powerdown */
141 smc911x_reg_write(priv, BYTE_TEST, 0x0);
142
143 timeout = 10;
144
145 while (timeout-- &&
146 !(smc911x_reg_read(priv, PMT_CTRL) & PMT_CTRL_READY))
147 udelay(10);
148 if (timeout < 0) {
149 printf(DRIVERNAME
150 ": timeout waiting for PM restore\n");
151 return;
152 }
153 }
154
155 /* Disable interrupts */
156 smc911x_reg_write(priv, INT_EN, 0);
157
158 smc911x_reg_write(priv, HW_CFG, HW_CFG_SRST);
159
160 timeout = 1000;
161 while (timeout-- && smc911x_reg_read(priv, E2P_CMD) & E2P_CMD_EPC_BUSY)
162 udelay(10);
163
164 if (timeout < 0) {
165 printf(DRIVERNAME ": reset timeout\n");
166 return;
167 }
168
169 /* Reset the FIFO level and flow control settings */
170 smc911x_set_mac_csr(priv, FLOW, FLOW_FCPT | FLOW_FCEN);
171 smc911x_reg_write(priv, AFC_CFG, 0x0050287F);
172
173 /* Set to LED outputs */
174 smc911x_reg_write(priv, GPIO_CFG, 0x70070000);
175 }
176
smc911x_handle_mac_address(struct smc911x_priv * priv)177 static void smc911x_handle_mac_address(struct smc911x_priv *priv)
178 {
179 unsigned long addrh, addrl;
180 unsigned char *m = priv->enetaddr;
181
182 addrl = m[0] | (m[1] << 8) | (m[2] << 16) | (m[3] << 24);
183 addrh = m[4] | (m[5] << 8);
184 smc911x_set_mac_csr(priv, ADDRL, addrl);
185 smc911x_set_mac_csr(priv, ADDRH, addrh);
186
187 printf(DRIVERNAME ": MAC %pM\n", m);
188 }
189
smc911x_read_mac_address(struct smc911x_priv * priv)190 static bool smc911x_read_mac_address(struct smc911x_priv *priv)
191 {
192 u32 addrh, addrl;
193
194 /* address is obtained from optional eeprom */
195 addrh = smc911x_get_mac_csr(priv, ADDRH);
196 addrl = smc911x_get_mac_csr(priv, ADDRL);
197 if (addrl == 0xffffffff && addrh == 0x0000ffff)
198 return false;
199
200 priv->enetaddr[0] = addrl;
201 priv->enetaddr[1] = addrl >> 8;
202 priv->enetaddr[2] = addrl >> 16;
203 priv->enetaddr[3] = addrl >> 24;
204 priv->enetaddr[4] = addrh;
205 priv->enetaddr[5] = addrh >> 8;
206
207 return true;
208 }
209
smc911x_eth_phy_read(struct smc911x_priv * priv,u8 phy,u8 reg,u16 * val)210 static int smc911x_eth_phy_read(struct smc911x_priv *priv,
211 u8 phy, u8 reg, u16 *val)
212 {
213 while (smc911x_get_mac_csr(priv, MII_ACC) & MII_ACC_MII_BUSY)
214 ;
215
216 smc911x_set_mac_csr(priv, MII_ACC, phy << 11 | reg << 6 |
217 MII_ACC_MII_BUSY);
218
219 while (smc911x_get_mac_csr(priv, MII_ACC) & MII_ACC_MII_BUSY)
220 ;
221
222 *val = smc911x_get_mac_csr(priv, MII_DATA);
223
224 return 0;
225 }
226
smc911x_eth_phy_write(struct smc911x_priv * priv,u8 phy,u8 reg,u16 val)227 static int smc911x_eth_phy_write(struct smc911x_priv *priv,
228 u8 phy, u8 reg, u16 val)
229 {
230 while (smc911x_get_mac_csr(priv, MII_ACC) & MII_ACC_MII_BUSY)
231 ;
232
233 smc911x_set_mac_csr(priv, MII_DATA, val);
234 smc911x_set_mac_csr(priv, MII_ACC,
235 phy << 11 | reg << 6 | MII_ACC_MII_BUSY | MII_ACC_MII_WRITE);
236
237 while (smc911x_get_mac_csr(priv, MII_ACC) & MII_ACC_MII_BUSY)
238 ;
239 return 0;
240 }
241
smc911x_phy_reset(struct smc911x_priv * priv)242 static int smc911x_phy_reset(struct smc911x_priv *priv)
243 {
244 u32 reg;
245
246 reg = smc911x_reg_read(priv, PMT_CTRL);
247 reg &= ~0xfffff030;
248 reg |= PMT_CTRL_PHY_RST;
249 smc911x_reg_write(priv, PMT_CTRL, reg);
250
251 mdelay(100);
252
253 return 0;
254 }
255
smc911x_phy_configure(struct smc911x_priv * priv)256 static void smc911x_phy_configure(struct smc911x_priv *priv)
257 {
258 int timeout;
259 u16 status;
260
261 smc911x_phy_reset(priv);
262
263 smc911x_eth_phy_write(priv, 1, MII_BMCR, BMCR_RESET);
264 mdelay(1);
265 smc911x_eth_phy_write(priv, 1, MII_ADVERTISE, 0x01e1);
266 smc911x_eth_phy_write(priv, 1, MII_BMCR, BMCR_ANENABLE |
267 BMCR_ANRESTART);
268
269 timeout = 5000;
270 do {
271 mdelay(1);
272 if ((timeout--) == 0)
273 goto err_out;
274
275 if (smc911x_eth_phy_read(priv, 1, MII_BMSR, &status) != 0)
276 goto err_out;
277 } while (!(status & BMSR_LSTATUS));
278
279 printf(DRIVERNAME ": phy initialized\n");
280
281 return;
282
283 err_out:
284 printf(DRIVERNAME ": autonegotiation timed out\n");
285 }
286
smc911x_enable(struct smc911x_priv * priv)287 static void smc911x_enable(struct smc911x_priv *priv)
288 {
289 /* Enable TX */
290 smc911x_reg_write(priv, HW_CFG, 8 << 16 | HW_CFG_SF);
291
292 smc911x_reg_write(priv, GPT_CFG, GPT_CFG_TIMER_EN | 10000);
293
294 smc911x_reg_write(priv, TX_CFG, TX_CFG_TX_ON);
295
296 /* no padding to start of packets */
297 smc911x_reg_write(priv, RX_CFG, 0);
298
299 smc911x_set_mac_csr(priv, MAC_CR, MAC_CR_TXEN | MAC_CR_RXEN |
300 MAC_CR_HBDIS);
301 }
302
smc911x_init_common(struct smc911x_priv * priv)303 static int smc911x_init_common(struct smc911x_priv *priv)
304 {
305 const struct chip_id *id = priv->chipid;
306
307 printf(DRIVERNAME ": detected %s controller\n", id->name);
308
309 smc911x_reset(priv);
310
311 /* Configure the PHY, initialize the link state */
312 smc911x_phy_configure(priv);
313
314 smc911x_handle_mac_address(priv);
315
316 /* Turn on Tx + Rx */
317 smc911x_enable(priv);
318
319 return 0;
320 }
321
smc911x_send_common(struct smc911x_priv * priv,void * packet,int length)322 static int smc911x_send_common(struct smc911x_priv *priv,
323 void *packet, int length)
324 {
325 u32 *data = (u32*)packet;
326 u32 tmplen;
327 u32 status;
328
329 smc911x_reg_write(priv, TX_DATA_FIFO, TX_CMD_A_INT_FIRST_SEG |
330 TX_CMD_A_INT_LAST_SEG | length);
331 smc911x_reg_write(priv, TX_DATA_FIFO, length);
332
333 tmplen = (length + 3) / 4;
334
335 while (tmplen--)
336 smc911x_reg_write(priv, TX_DATA_FIFO, *data++);
337
338 /* wait for transmission */
339 while (!((smc911x_reg_read(priv, TX_FIFO_INF) &
340 TX_FIFO_INF_TSUSED) >> 16));
341
342 /* get status. Ignore 'no carrier' error, it has no meaning for
343 * full duplex operation
344 */
345 status = smc911x_reg_read(priv, TX_STATUS_FIFO) &
346 (TX_STS_LOC | TX_STS_LATE_COLL | TX_STS_MANY_COLL |
347 TX_STS_MANY_DEFER | TX_STS_UNDERRUN);
348
349 if (!status)
350 return 0;
351
352 printf(DRIVERNAME ": failed to send packet: %s%s%s%s%s\n",
353 status & TX_STS_LOC ? "TX_STS_LOC " : "",
354 status & TX_STS_LATE_COLL ? "TX_STS_LATE_COLL " : "",
355 status & TX_STS_MANY_COLL ? "TX_STS_MANY_COLL " : "",
356 status & TX_STS_MANY_DEFER ? "TX_STS_MANY_DEFER " : "",
357 status & TX_STS_UNDERRUN ? "TX_STS_UNDERRUN" : "");
358
359 return -1;
360 }
361
smc911x_halt_common(struct smc911x_priv * priv)362 static void smc911x_halt_common(struct smc911x_priv *priv)
363 {
364 smc911x_reset(priv);
365 smc911x_handle_mac_address(priv);
366 }
367
smc911x_recv_common(struct smc911x_priv * priv,u32 * data)368 static int smc911x_recv_common(struct smc911x_priv *priv, u32 *data)
369 {
370 u32 pktlen, tmplen;
371 u32 status;
372
373 status = smc911x_reg_read(priv, RX_FIFO_INF);
374 if (!(status & RX_FIFO_INF_RXSUSED))
375 return 0;
376
377 status = smc911x_reg_read(priv, RX_STATUS_FIFO);
378 pktlen = (status & RX_STS_PKT_LEN) >> 16;
379
380 smc911x_reg_write(priv, RX_CFG, 0);
381
382 tmplen = (pktlen + 3) / 4;
383 while (tmplen--)
384 *data++ = smc911x_reg_read(priv, RX_DATA_FIFO);
385
386 if (status & RX_STS_ES) {
387 printf(DRIVERNAME
388 ": dropped bad packet. Status: 0x%08x\n",
389 status);
390 return 0;
391 }
392
393 return pktlen;
394 }
395
396 #ifndef CONFIG_DM_ETH
397
398 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
399 /* wrapper for smc911x_eth_phy_read */
smc911x_miiphy_read(struct mii_dev * bus,int phy,int devad,int reg)400 static int smc911x_miiphy_read(struct mii_dev *bus, int phy, int devad,
401 int reg)
402 {
403 struct eth_device *dev = eth_get_dev_by_name(bus->name);
404 struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev);
405 u16 val = 0;
406 int ret;
407
408 if (!dev || !priv)
409 return -ENODEV;
410
411 ret = smc911x_eth_phy_read(priv, phy, reg, &val);
412 if (ret < 0)
413 return ret;
414
415 return val;
416 }
417
418 /* wrapper for smc911x_eth_phy_write */
smc911x_miiphy_write(struct mii_dev * bus,int phy,int devad,int reg,u16 val)419 static int smc911x_miiphy_write(struct mii_dev *bus, int phy, int devad,
420 int reg, u16 val)
421 {
422 struct eth_device *dev = eth_get_dev_by_name(bus->name);
423 struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev);
424
425 if (!dev || !priv)
426 return -ENODEV;
427
428 return smc911x_eth_phy_write(priv, phy, reg, val);
429 }
430
smc911x_initialize_mii(struct smc911x_priv * priv)431 static int smc911x_initialize_mii(struct smc911x_priv *priv)
432 {
433 struct mii_dev *mdiodev = mdio_alloc();
434 int ret;
435
436 if (!mdiodev)
437 return -ENOMEM;
438
439 strncpy(mdiodev->name, priv->dev.name, MDIO_NAME_LEN);
440 mdiodev->read = smc911x_miiphy_read;
441 mdiodev->write = smc911x_miiphy_write;
442
443 ret = mdio_register(mdiodev);
444 if (ret < 0) {
445 mdio_free(mdiodev);
446 return ret;
447 }
448
449 return 0;
450 }
451 #else
smc911x_initialize_mii(struct smc911x_priv * priv)452 static int smc911x_initialize_mii(struct smc911x_priv *priv)
453 {
454 return 0;
455 }
456 #endif
457
smc911x_init(struct eth_device * dev,struct bd_info * bd)458 static int smc911x_init(struct eth_device *dev, struct bd_info *bd)
459 {
460 struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev);
461
462 return smc911x_init_common(priv);
463 }
464
smc911x_halt(struct eth_device * dev)465 static void smc911x_halt(struct eth_device *dev)
466 {
467 struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev);
468
469 smc911x_halt_common(priv);
470 }
471
smc911x_send(struct eth_device * dev,void * packet,int length)472 static int smc911x_send(struct eth_device *dev, void *packet, int length)
473 {
474 struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev);
475
476 return smc911x_send_common(priv, packet, length);
477 }
478
smc911x_recv(struct eth_device * dev)479 static int smc911x_recv(struct eth_device *dev)
480 {
481 struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev);
482 u32 *data = (u32 *)net_rx_packets[0];
483 int ret;
484
485 ret = smc911x_recv_common(priv, data);
486 if (ret)
487 net_process_received_packet(net_rx_packets[0], ret);
488
489 return ret;
490 }
491
smc911x_initialize(u8 dev_num,int base_addr)492 int smc911x_initialize(u8 dev_num, int base_addr)
493 {
494 struct smc911x_priv *priv;
495 int ret;
496
497 priv = calloc(1, sizeof(*priv));
498 if (!priv)
499 return -ENOMEM;
500
501 priv->iobase = base_addr;
502 priv->dev.iobase = base_addr;
503
504 /* Try to detect chip. Will fail if not present. */
505 ret = smc911x_detect_chip(priv);
506 if (ret) {
507 ret = 0; /* Card not detected is not an error */
508 goto err_detect;
509 }
510
511 if (smc911x_read_mac_address(priv))
512 memcpy(priv->dev.enetaddr, priv->enetaddr, 6);
513
514 priv->dev.init = smc911x_init;
515 priv->dev.halt = smc911x_halt;
516 priv->dev.send = smc911x_send;
517 priv->dev.recv = smc911x_recv;
518 sprintf(priv->dev.name, "%s-%hu", DRIVERNAME, dev_num);
519
520 eth_register(&priv->dev);
521
522 ret = smc911x_initialize_mii(priv);
523 if (ret)
524 goto err_mii;
525
526 return 1;
527
528 err_mii:
529 eth_unregister(&priv->dev);
530 err_detect:
531 free(priv);
532 return ret;
533 }
534
535 #else /* ifdef CONFIG_DM_ETH */
536
smc911x_start(struct udevice * dev)537 static int smc911x_start(struct udevice *dev)
538 {
539 struct eth_pdata *plat = dev_get_plat(dev);
540 struct smc911x_priv *priv = dev_get_priv(dev);
541
542 memcpy(priv->enetaddr, plat->enetaddr, sizeof(plat->enetaddr));
543
544 return smc911x_init_common(priv);
545 }
546
smc911x_stop(struct udevice * dev)547 static void smc911x_stop(struct udevice *dev)
548 {
549 struct smc911x_priv *priv = dev_get_priv(dev);
550
551 smc911x_halt_common(priv);
552 }
553
smc911x_send(struct udevice * dev,void * packet,int length)554 static int smc911x_send(struct udevice *dev, void *packet, int length)
555 {
556 struct smc911x_priv *priv = dev_get_priv(dev);
557 int ret;
558
559 ret = smc911x_send_common(priv, packet, length);
560
561 return ret ? 0 : -ETIMEDOUT;
562 }
563
smc911x_recv(struct udevice * dev,int flags,uchar ** packetp)564 static int smc911x_recv(struct udevice *dev, int flags, uchar **packetp)
565 {
566 struct smc911x_priv *priv = dev_get_priv(dev);
567 u32 *data = (u32 *)net_rx_packets[0];
568 int ret;
569
570 ret = smc911x_recv_common(priv, data);
571 if (ret)
572 *packetp = (void *)data;
573
574 return ret ? ret : -EAGAIN;
575 }
576
smc911x_read_rom_hwaddr(struct udevice * dev)577 static int smc911x_read_rom_hwaddr(struct udevice *dev)
578 {
579 struct smc911x_priv *priv = dev_get_priv(dev);
580 struct eth_pdata *pdata = dev_get_plat(dev);
581
582 if (!smc911x_read_mac_address(priv))
583 return -ENODEV;
584
585 memcpy(pdata->enetaddr, priv->enetaddr, sizeof(pdata->enetaddr));
586
587 return 0;
588 }
589
smc911x_bind(struct udevice * dev)590 static int smc911x_bind(struct udevice *dev)
591 {
592 return device_set_name(dev, dev->name);
593 }
594
smc911x_probe(struct udevice * dev)595 static int smc911x_probe(struct udevice *dev)
596 {
597 struct smc911x_priv *priv = dev_get_priv(dev);
598 int ret;
599
600 /* Try to detect chip. Will fail if not present. */
601 ret = smc911x_detect_chip(priv);
602 if (ret)
603 return ret;
604
605 smc911x_read_rom_hwaddr(dev);
606
607 return 0;
608 }
609
smc911x_of_to_plat(struct udevice * dev)610 static int smc911x_of_to_plat(struct udevice *dev)
611 {
612 struct smc911x_priv *priv = dev_get_priv(dev);
613 struct eth_pdata *pdata = dev_get_plat(dev);
614
615 pdata->iobase = dev_read_addr(dev);
616 priv->iobase = pdata->iobase;
617
618 return 0;
619 }
620
621 static const struct eth_ops smc911x_ops = {
622 .start = smc911x_start,
623 .send = smc911x_send,
624 .recv = smc911x_recv,
625 .stop = smc911x_stop,
626 .read_rom_hwaddr = smc911x_read_rom_hwaddr,
627 };
628
629 static const struct udevice_id smc911x_ids[] = {
630 { .compatible = "smsc,lan9115" },
631 { }
632 };
633
634 U_BOOT_DRIVER(smc911x) = {
635 .name = "eth_smc911x",
636 .id = UCLASS_ETH,
637 .of_match = smc911x_ids,
638 .bind = smc911x_bind,
639 .of_to_plat = smc911x_of_to_plat,
640 .probe = smc911x_probe,
641 .ops = &smc911x_ops,
642 .priv_auto = sizeof(struct smc911x_priv),
643 .plat_auto = sizeof(struct eth_pdata),
644 .flags = DM_FLAG_ALLOC_PRIV_DMA,
645 };
646 #endif
647