1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
4  *
5  * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
6  *	Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
7  */
8 
9 #include <common.h>
10 #include <clk.h>
11 #include <dm.h>
12 #include <dma.h>
13 #include <log.h>
14 #include <malloc.h>
15 #include <miiphy.h>
16 #include <net.h>
17 #include <reset.h>
18 #include <wait_bit.h>
19 #include <asm/io.h>
20 #include <dm/device_compat.h>
21 #include <linux/delay.h>
22 
23 #define ETH_PORT_STR			"brcm,enetsw-port"
24 
25 #define ETH_RX_DESC			PKTBUFSRX
26 #define ETH_ZLEN			60
27 #define ETH_TIMEOUT			100
28 
29 #define ETH_MAX_PORT			8
30 #define ETH_RGMII_PORT0			4
31 
32 /* Port traffic control */
33 #define ETH_PTCTRL_REG(x)		(0x0 + (x))
34 #define ETH_PTCTRL_RXDIS_SHIFT		0
35 #define ETH_PTCTRL_RXDIS_MASK		(1 << ETH_PTCTRL_RXDIS_SHIFT)
36 #define ETH_PTCTRL_TXDIS_SHIFT		1
37 #define ETH_PTCTRL_TXDIS_MASK		(1 << ETH_PTCTRL_TXDIS_SHIFT)
38 
39 /* Switch mode register */
40 #define ETH_SWMODE_REG			0xb
41 #define ETH_SWMODE_FWD_EN_SHIFT		1
42 #define ETH_SWMODE_FWD_EN_MASK		(1 << ETH_SWMODE_FWD_EN_SHIFT)
43 
44 /* IMP override Register */
45 #define ETH_IMPOV_REG			0xe
46 #define ETH_IMPOV_LINKUP_SHIFT		0
47 #define ETH_IMPOV_LINKUP_MASK		(1 << ETH_IMPOV_LINKUP_SHIFT)
48 #define ETH_IMPOV_FDX_SHIFT		1
49 #define ETH_IMPOV_FDX_MASK		(1 << ETH_IMPOV_FDX_SHIFT)
50 #define ETH_IMPOV_100_SHIFT		2
51 #define ETH_IMPOV_100_MASK		(1 << ETH_IMPOV_100_SHIFT)
52 #define ETH_IMPOV_1000_SHIFT		3
53 #define ETH_IMPOV_1000_MASK		(1 << ETH_IMPOV_1000_SHIFT)
54 #define ETH_IMPOV_RXFLOW_SHIFT		4
55 #define ETH_IMPOV_RXFLOW_MASK		(1 << ETH_IMPOV_RXFLOW_SHIFT)
56 #define ETH_IMPOV_TXFLOW_SHIFT		5
57 #define ETH_IMPOV_TXFLOW_MASK		(1 << ETH_IMPOV_TXFLOW_SHIFT)
58 #define ETH_IMPOV_FORCE_SHIFT		7
59 #define ETH_IMPOV_FORCE_MASK		(1 << ETH_IMPOV_FORCE_SHIFT)
60 
61 /* Port override Register */
62 #define ETH_PORTOV_REG(x)		(0x58 + (x))
63 #define ETH_PORTOV_LINKUP_SHIFT		0
64 #define ETH_PORTOV_LINKUP_MASK		(1 << ETH_PORTOV_LINKUP_SHIFT)
65 #define ETH_PORTOV_FDX_SHIFT		1
66 #define ETH_PORTOV_FDX_MASK		(1 << ETH_PORTOV_FDX_SHIFT)
67 #define ETH_PORTOV_100_SHIFT		2
68 #define ETH_PORTOV_100_MASK		(1 << ETH_PORTOV_100_SHIFT)
69 #define ETH_PORTOV_1000_SHIFT		3
70 #define ETH_PORTOV_1000_MASK		(1 << ETH_PORTOV_1000_SHIFT)
71 #define ETH_PORTOV_RXFLOW_SHIFT		4
72 #define ETH_PORTOV_RXFLOW_MASK		(1 << ETH_PORTOV_RXFLOW_SHIFT)
73 #define ETH_PORTOV_TXFLOW_SHIFT		5
74 #define ETH_PORTOV_TXFLOW_MASK		(1 << ETH_PORTOV_TXFLOW_SHIFT)
75 #define ETH_PORTOV_ENABLE_SHIFT		6
76 #define ETH_PORTOV_ENABLE_MASK		(1 << ETH_PORTOV_ENABLE_SHIFT)
77 
78 /* Port RGMII control register */
79 #define ETH_RGMII_CTRL_REG(x)		(0x60 + (x))
80 #define ETH_RGMII_CTRL_GMII_CLK_EN	(1 << 7)
81 #define ETH_RGMII_CTRL_MII_OVERRIDE_EN	(1 << 6)
82 #define ETH_RGMII_CTRL_MII_MODE_MASK	(3 << 4)
83 #define ETH_RGMII_CTRL_RGMII_MODE	(0 << 4)
84 #define ETH_RGMII_CTRL_MII_MODE		(1 << 4)
85 #define ETH_RGMII_CTRL_RVMII_MODE	(2 << 4)
86 #define ETH_RGMII_CTRL_TIMING_SEL_EN	(1 << 0)
87 
88 /* Port RGMII timing register */
89 #define ENETSW_RGMII_TIMING_REG(x)	(0x68 + (x))
90 
91 /* MDIO control register */
92 #define MII_SC_REG			0xb0
93 #define MII_SC_EXT_SHIFT		16
94 #define MII_SC_EXT_MASK			(1 << MII_SC_EXT_SHIFT)
95 #define MII_SC_REG_SHIFT		20
96 #define MII_SC_PHYID_SHIFT		25
97 #define MII_SC_RD_SHIFT			30
98 #define MII_SC_RD_MASK			(1 << MII_SC_RD_SHIFT)
99 #define MII_SC_WR_SHIFT			31
100 #define MII_SC_WR_MASK			(1 << MII_SC_WR_SHIFT)
101 
102 /* MDIO data register */
103 #define MII_DAT_REG			0xb4
104 
105 /* Global Management Configuration Register */
106 #define ETH_GMCR_REG			0x200
107 #define ETH_GMCR_RST_MIB_SHIFT		0
108 #define ETH_GMCR_RST_MIB_MASK		(1 << ETH_GMCR_RST_MIB_SHIFT)
109 
110 /* Jumbo control register port mask register */
111 #define ETH_JMBCTL_PORT_REG		0x4004
112 
113 /* Jumbo control mib good frame register */
114 #define ETH_JMBCTL_MAXSIZE_REG		0x4008
115 
116 /* ETH port data */
117 struct bcm_enetsw_port {
118 	bool used;
119 	const char *name;
120 	/* Config */
121 	bool bypass_link;
122 	int force_speed;
123 	bool force_duplex_full;
124 	/* PHY */
125 	int phy_id;
126 };
127 
128 /* ETH data */
129 struct bcm6368_eth_priv {
130 	void __iomem *base;
131 	/* DMA */
132 	struct dma rx_dma;
133 	struct dma tx_dma;
134 	/* Ports */
135 	uint8_t num_ports;
136 	struct bcm_enetsw_port used_ports[ETH_MAX_PORT];
137 	int sw_port_link[ETH_MAX_PORT];
138 	bool rgmii_override;
139 	bool rgmii_timing;
140 	/* PHY */
141 	int phy_id;
142 };
143 
bcm_enet_port_is_rgmii(int portid)144 static inline bool bcm_enet_port_is_rgmii(int portid)
145 {
146 	return portid >= ETH_RGMII_PORT0;
147 }
148 
bcm6368_mdio_read(struct bcm6368_eth_priv * priv,uint8_t ext,int phy_id,int reg)149 static int bcm6368_mdio_read(struct bcm6368_eth_priv *priv, uint8_t ext,
150 			     int phy_id, int reg)
151 {
152 	uint32_t val;
153 
154 	writel_be(0, priv->base + MII_SC_REG);
155 
156 	val = MII_SC_RD_MASK |
157 	      (phy_id << MII_SC_PHYID_SHIFT) |
158 	      (reg << MII_SC_REG_SHIFT);
159 
160 	if (ext)
161 		val |= MII_SC_EXT_MASK;
162 
163 	writel_be(val, priv->base + MII_SC_REG);
164 	udelay(50);
165 
166 	return readw_be(priv->base + MII_DAT_REG);
167 }
168 
bcm6368_mdio_write(struct bcm6368_eth_priv * priv,uint8_t ext,int phy_id,int reg,u16 data)169 static int bcm6368_mdio_write(struct bcm6368_eth_priv *priv, uint8_t ext,
170 			      int phy_id, int reg, u16 data)
171 {
172 	uint32_t val;
173 
174 	writel_be(0, priv->base + MII_SC_REG);
175 
176 	val = MII_SC_WR_MASK |
177 	      (phy_id << MII_SC_PHYID_SHIFT) |
178 	      (reg << MII_SC_REG_SHIFT);
179 
180 	if (ext)
181 		val |= MII_SC_EXT_MASK;
182 
183 	val |= data;
184 
185 	writel_be(val, priv->base + MII_SC_REG);
186 	udelay(50);
187 
188 	return 0;
189 }
190 
bcm6368_eth_free_pkt(struct udevice * dev,uchar * packet,int len)191 static int bcm6368_eth_free_pkt(struct udevice *dev, uchar *packet, int len)
192 {
193 	struct bcm6368_eth_priv *priv = dev_get_priv(dev);
194 
195 	return dma_prepare_rcv_buf(&priv->rx_dma, packet, len);
196 }
197 
bcm6368_eth_recv(struct udevice * dev,int flags,uchar ** packetp)198 static int bcm6368_eth_recv(struct udevice *dev, int flags, uchar **packetp)
199 {
200 	struct bcm6368_eth_priv *priv = dev_get_priv(dev);
201 
202 	return dma_receive(&priv->rx_dma, (void**)packetp, NULL);
203 }
204 
bcm6368_eth_send(struct udevice * dev,void * packet,int length)205 static int bcm6368_eth_send(struct udevice *dev, void *packet, int length)
206 {
207 	struct bcm6368_eth_priv *priv = dev_get_priv(dev);
208 
209 	/* pad packets smaller than ETH_ZLEN */
210 	if (length < ETH_ZLEN) {
211 		memset(packet + length, 0, ETH_ZLEN - length);
212 		length = ETH_ZLEN;
213 	}
214 
215 	return dma_send(&priv->tx_dma, packet, length, NULL);
216 }
217 
bcm6368_eth_adjust_link(struct udevice * dev)218 static int bcm6368_eth_adjust_link(struct udevice *dev)
219 {
220 	struct bcm6368_eth_priv *priv = dev_get_priv(dev);
221 	unsigned int i;
222 
223 	for (i = 0; i < priv->num_ports; i++) {
224 		struct bcm_enetsw_port *port;
225 		int val, j, up, adv, lpa, speed, duplex, media;
226 		int external_phy = bcm_enet_port_is_rgmii(i);
227 		u8 override;
228 
229 		port = &priv->used_ports[i];
230 		if (!port->used)
231 			continue;
232 
233 		if (port->bypass_link)
234 			continue;
235 
236 		/* dummy read to clear */
237 		for (j = 0; j < 2; j++)
238 			val = bcm6368_mdio_read(priv, external_phy,
239 						port->phy_id, MII_BMSR);
240 
241 		if (val == 0xffff)
242 			continue;
243 
244 		up = (val & BMSR_LSTATUS) ? 1 : 0;
245 		if (!(up ^ priv->sw_port_link[i]))
246 			continue;
247 
248 		priv->sw_port_link[i] = up;
249 
250 		/* link changed */
251 		if (!up) {
252 			dev_info(dev, "link DOWN on %s\n", port->name);
253 			writeb_be(ETH_PORTOV_ENABLE_MASK,
254 				  priv->base + ETH_PORTOV_REG(i));
255 			writeb_be(ETH_PTCTRL_RXDIS_MASK |
256 				  ETH_PTCTRL_TXDIS_MASK,
257 				  priv->base + ETH_PTCTRL_REG(i));
258 			continue;
259 		}
260 
261 		adv = bcm6368_mdio_read(priv, external_phy,
262 					port->phy_id, MII_ADVERTISE);
263 
264 		lpa = bcm6368_mdio_read(priv, external_phy, port->phy_id,
265 					MII_LPA);
266 
267 		/* figure out media and duplex from advertise and LPA values */
268 		media = mii_nway_result(lpa & adv);
269 		duplex = (media & ADVERTISE_FULL) ? 1 : 0;
270 
271 		if (media & (ADVERTISE_100FULL | ADVERTISE_100HALF))
272 			speed = 100;
273 		else
274 			speed = 10;
275 
276 		if (val & BMSR_ESTATEN) {
277 			adv = bcm6368_mdio_read(priv, external_phy,
278 						port->phy_id, MII_CTRL1000);
279 
280 			lpa = bcm6368_mdio_read(priv, external_phy,
281 						port->phy_id, MII_STAT1000);
282 
283 			if ((adv & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) &&
284 			    (lpa & (LPA_1000FULL | LPA_1000HALF))) {
285 				speed = 1000;
286 				duplex = (lpa & LPA_1000FULL);
287 			}
288 		}
289 
290 		pr_alert("link UP on %s, %dMbps, %s-duplex\n",
291 			 port->name, speed, duplex ? "full" : "half");
292 
293 		override = ETH_PORTOV_ENABLE_MASK |
294 			   ETH_PORTOV_LINKUP_MASK;
295 
296 		if (speed == 1000)
297 			override |= ETH_PORTOV_1000_MASK;
298 		else if (speed == 100)
299 			override |= ETH_PORTOV_100_MASK;
300 		if (duplex)
301 			override |= ETH_PORTOV_FDX_MASK;
302 
303 		writeb_be(override, priv->base + ETH_PORTOV_REG(i));
304 		writeb_be(0, priv->base + ETH_PTCTRL_REG(i));
305 	}
306 
307 	return 0;
308 }
309 
bcm6368_eth_start(struct udevice * dev)310 static int bcm6368_eth_start(struct udevice *dev)
311 {
312 	struct bcm6368_eth_priv *priv = dev_get_priv(dev);
313 	uint8_t i;
314 
315 	/* disable all ports */
316 	for (i = 0; i < priv->num_ports; i++) {
317 		setbits_8(priv->base + ETH_PORTOV_REG(i),
318 			  ETH_PORTOV_ENABLE_MASK);
319 		setbits_8(priv->base + ETH_PTCTRL_REG(i),
320 			  ETH_PTCTRL_RXDIS_MASK | ETH_PTCTRL_TXDIS_MASK);
321 		priv->sw_port_link[i] = 0;
322 	}
323 
324 	/* enable external ports */
325 	for (i = ETH_RGMII_PORT0; i < priv->num_ports; i++) {
326 		u8 rgmii_ctrl = ETH_RGMII_CTRL_GMII_CLK_EN;
327 
328 		if (!priv->used_ports[i].used)
329 			continue;
330 
331 		if (priv->rgmii_override)
332 			rgmii_ctrl |= ETH_RGMII_CTRL_MII_OVERRIDE_EN;
333 		if (priv->rgmii_timing)
334 			rgmii_ctrl |= ETH_RGMII_CTRL_TIMING_SEL_EN;
335 
336 		setbits_8(priv->base + ETH_RGMII_CTRL_REG(i), rgmii_ctrl);
337 	}
338 
339 	/* reset mib */
340 	setbits_8(priv->base + ETH_GMCR_REG, ETH_GMCR_RST_MIB_MASK);
341 	mdelay(1);
342 	clrbits_8(priv->base + ETH_GMCR_REG, ETH_GMCR_RST_MIB_MASK);
343 	mdelay(1);
344 
345 	/* force CPU port state */
346 	setbits_8(priv->base + ETH_IMPOV_REG,
347 		  ETH_IMPOV_FORCE_MASK | ETH_IMPOV_LINKUP_MASK);
348 
349 	/* enable switch forward engine */
350 	setbits_8(priv->base + ETH_SWMODE_REG, ETH_SWMODE_FWD_EN_MASK);
351 
352 	/* prepare rx dma buffers */
353 	for (i = 0; i < ETH_RX_DESC; i++) {
354 		int ret = dma_prepare_rcv_buf(&priv->rx_dma, net_rx_packets[i],
355 					      PKTSIZE_ALIGN);
356 		if (ret < 0)
357 			break;
358 	}
359 
360 	/* enable dma rx channel */
361 	dma_enable(&priv->rx_dma);
362 
363 	/* enable dma tx channel */
364 	dma_enable(&priv->tx_dma);
365 
366 	/* apply override config for bypass_link ports here. */
367 	for (i = 0; i < priv->num_ports; i++) {
368 		struct bcm_enetsw_port *port;
369 		u8 override;
370 
371 		port = &priv->used_ports[i];
372 		if (!port->used)
373 			continue;
374 
375 		if (!port->bypass_link)
376 			continue;
377 
378 		override = ETH_PORTOV_ENABLE_MASK |
379 			   ETH_PORTOV_LINKUP_MASK;
380 
381 		switch (port->force_speed) {
382 		case 1000:
383 			override |= ETH_PORTOV_1000_MASK;
384 			break;
385 		case 100:
386 			override |= ETH_PORTOV_100_MASK;
387 			break;
388 		case 10:
389 			break;
390 		default:
391 			pr_warn("%s: invalid forced speed on port %s\n",
392 				__func__, port->name);
393 			break;
394 		}
395 
396 		if (port->force_duplex_full)
397 			override |= ETH_PORTOV_FDX_MASK;
398 
399 		writeb_be(override, priv->base + ETH_PORTOV_REG(i));
400 		writeb_be(0, priv->base + ETH_PTCTRL_REG(i));
401 	}
402 
403 	bcm6368_eth_adjust_link(dev);
404 
405 	return 0;
406 }
407 
bcm6368_eth_stop(struct udevice * dev)408 static void bcm6368_eth_stop(struct udevice *dev)
409 {
410 	struct bcm6368_eth_priv *priv = dev_get_priv(dev);
411 	uint8_t i;
412 
413 	/* disable all ports */
414 	for (i = 0; i < priv->num_ports; i++) {
415 		setbits_8(priv->base + ETH_PORTOV_REG(i),
416 			  ETH_PORTOV_ENABLE_MASK);
417 		setbits_8(priv->base + ETH_PTCTRL_REG(i),
418 			  ETH_PTCTRL_RXDIS_MASK | ETH_PTCTRL_TXDIS_MASK);
419 	}
420 
421 	/* disable external ports */
422 	for (i = ETH_RGMII_PORT0; i < priv->num_ports; i++) {
423 		if (!priv->used_ports[i].used)
424 			continue;
425 
426 		clrbits_8(priv->base + ETH_RGMII_CTRL_REG(i),
427 			  ETH_RGMII_CTRL_GMII_CLK_EN);
428 	}
429 
430 	/* disable CPU port */
431 	clrbits_8(priv->base + ETH_IMPOV_REG,
432 		  ETH_IMPOV_FORCE_MASK | ETH_IMPOV_LINKUP_MASK);
433 
434 	/* disable switch forward engine */
435 	clrbits_8(priv->base + ETH_SWMODE_REG, ETH_SWMODE_FWD_EN_MASK);
436 
437 	/* disable dma rx channel */
438 	dma_disable(&priv->rx_dma);
439 
440 	/* disable dma tx channel */
441 	dma_disable(&priv->tx_dma);
442 }
443 
444 static const struct eth_ops bcm6368_eth_ops = {
445 	.free_pkt = bcm6368_eth_free_pkt,
446 	.recv = bcm6368_eth_recv,
447 	.send = bcm6368_eth_send,
448 	.start = bcm6368_eth_start,
449 	.stop = bcm6368_eth_stop,
450 };
451 
452 static const struct udevice_id bcm6368_eth_ids[] = {
453 	{ .compatible = "brcm,bcm6368-enet", },
454 	{ /* sentinel */ }
455 };
456 
bcm6368_phy_is_external(struct bcm6368_eth_priv * priv,int phy_id)457 static bool bcm6368_phy_is_external(struct bcm6368_eth_priv *priv, int phy_id)
458 {
459 	uint8_t i;
460 
461 	for (i = 0; i < priv->num_ports; ++i) {
462 		if (!priv->used_ports[i].used)
463 			continue;
464 		if (priv->used_ports[i].phy_id == phy_id)
465 			return bcm_enet_port_is_rgmii(i);
466 	}
467 
468 	return true;
469 }
470 
bcm6368_mii_mdio_read(struct mii_dev * bus,int addr,int devaddr,int reg)471 static int bcm6368_mii_mdio_read(struct mii_dev *bus, int addr, int devaddr,
472 				 int reg)
473 {
474 	struct bcm6368_eth_priv *priv = bus->priv;
475 	bool ext = bcm6368_phy_is_external(priv, addr);
476 
477 	return bcm6368_mdio_read(priv, ext, addr, reg);
478 }
479 
bcm6368_mii_mdio_write(struct mii_dev * bus,int addr,int devaddr,int reg,u16 data)480 static int bcm6368_mii_mdio_write(struct mii_dev *bus, int addr, int devaddr,
481 				  int reg, u16 data)
482 {
483 	struct bcm6368_eth_priv *priv = bus->priv;
484 	bool ext = bcm6368_phy_is_external(priv, addr);
485 
486 	return bcm6368_mdio_write(priv, ext, addr, reg, data);
487 }
488 
bcm6368_mdio_init(const char * name,struct bcm6368_eth_priv * priv)489 static int bcm6368_mdio_init(const char *name, struct bcm6368_eth_priv *priv)
490 {
491 	struct mii_dev *bus;
492 
493 	bus = mdio_alloc();
494 	if (!bus) {
495 		pr_err("%s: failed to allocate MDIO bus\n", __func__);
496 		return -ENOMEM;
497 	}
498 
499 	bus->read = bcm6368_mii_mdio_read;
500 	bus->write = bcm6368_mii_mdio_write;
501 	bus->priv = priv;
502 	snprintf(bus->name, sizeof(bus->name), "%s", name);
503 
504 	return mdio_register(bus);
505 }
506 
bcm6368_eth_probe(struct udevice * dev)507 static int bcm6368_eth_probe(struct udevice *dev)
508 {
509 	struct eth_pdata *pdata = dev_get_plat(dev);
510 	struct bcm6368_eth_priv *priv = dev_get_priv(dev);
511 	int num_ports, ret, i;
512 	ofnode node;
513 
514 	/* get base address */
515 	priv->base = dev_remap_addr(dev);
516 	if (!priv->base)
517 		return -EINVAL;
518 	pdata->iobase = (phys_addr_t) priv->base;
519 
520 	/* get number of ports */
521 	num_ports = dev_read_u32_default(dev, "brcm,num-ports", ETH_MAX_PORT);
522 	if (!num_ports || num_ports > ETH_MAX_PORT)
523 		return -EINVAL;
524 
525 	/* get dma channels */
526 	ret = dma_get_by_name(dev, "tx", &priv->tx_dma);
527 	if (ret)
528 		return -EINVAL;
529 
530 	ret = dma_get_by_name(dev, "rx", &priv->rx_dma);
531 	if (ret)
532 		return -EINVAL;
533 
534 	/* try to enable clocks */
535 	for (i = 0; ; i++) {
536 		struct clk clk;
537 		int ret;
538 
539 		ret = clk_get_by_index(dev, i, &clk);
540 		if (ret < 0)
541 			break;
542 
543 		ret = clk_enable(&clk);
544 		if (ret < 0) {
545 			pr_err("%s: error enabling clock %d\n", __func__, i);
546 			return ret;
547 		}
548 
549 		ret = clk_free(&clk);
550 		if (ret < 0) {
551 			pr_err("%s: error freeing clock %d\n", __func__, i);
552 			return ret;
553 		}
554 	}
555 
556 	/* try to perform resets */
557 	for (i = 0; ; i++) {
558 		struct reset_ctl reset;
559 		int ret;
560 
561 		ret = reset_get_by_index(dev, i, &reset);
562 		if (ret < 0)
563 			break;
564 
565 		ret = reset_deassert(&reset);
566 		if (ret < 0) {
567 			pr_err("%s: error deasserting reset %d\n", __func__, i);
568 			return ret;
569 		}
570 
571 		ret = reset_free(&reset);
572 		if (ret < 0) {
573 			pr_err("%s: error freeing reset %d\n", __func__, i);
574 			return ret;
575 		}
576 	}
577 
578 	/* set priv data */
579 	priv->num_ports = num_ports;
580 	if (dev_read_bool(dev, "brcm,rgmii-override"))
581 		priv->rgmii_override = true;
582 	if (dev_read_bool(dev, "brcm,rgmii-timing"))
583 		priv->rgmii_timing = true;
584 
585 	/* get ports */
586 	dev_for_each_subnode(node, dev) {
587 		const char *comp;
588 		const char *label;
589 		unsigned int p;
590 		int phy_id;
591 		int speed;
592 
593 		comp = ofnode_read_string(node, "compatible");
594 		if (!comp || memcmp(comp, ETH_PORT_STR, sizeof(ETH_PORT_STR)))
595 			continue;
596 
597 		p = ofnode_read_u32_default(node, "reg", ETH_MAX_PORT);
598 		if (p >= num_ports)
599 			return -EINVAL;
600 
601 		label = ofnode_read_string(node, "label");
602 		if (!label) {
603 			debug("%s: node %s has no label\n", __func__,
604 			      ofnode_get_name(node));
605 			return -EINVAL;
606 		}
607 
608 		phy_id = ofnode_read_u32_default(node, "brcm,phy-id", -1);
609 
610 		priv->used_ports[p].used = true;
611 		priv->used_ports[p].name = label;
612 		priv->used_ports[p].phy_id = phy_id;
613 
614 		if (ofnode_read_bool(node, "full-duplex"))
615 			priv->used_ports[p].force_duplex_full = true;
616 		if (ofnode_read_bool(node, "bypass-link"))
617 			priv->used_ports[p].bypass_link = true;
618 		speed = ofnode_read_u32_default(node, "speed", 0);
619 		if (speed)
620 			priv->used_ports[p].force_speed = speed;
621 	}
622 
623 	/* init mii bus */
624 	ret = bcm6368_mdio_init(dev->name, priv);
625 	if (ret)
626 		return ret;
627 
628 	/* enable jumbo on all ports */
629 	writel_be(0x1ff, priv->base + ETH_JMBCTL_PORT_REG);
630 	writew_be(9728, priv->base + ETH_JMBCTL_MAXSIZE_REG);
631 
632 	return 0;
633 }
634 
635 U_BOOT_DRIVER(bcm6368_eth) = {
636 	.name = "bcm6368_eth",
637 	.id = UCLASS_ETH,
638 	.of_match = bcm6368_eth_ids,
639 	.ops = &bcm6368_eth_ops,
640 	.plat_auto	= sizeof(struct eth_pdata),
641 	.priv_auto	= sizeof(struct bcm6368_eth_priv),
642 	.probe = bcm6368_eth_probe,
643 };
644