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