1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2000-2004
4  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5  *
6  * (C) Copyright 2007 Freescale Semiconductor, Inc.
7  * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
8  *
9  * Conversion to DM
10  * (C) 2019 Angelo Dureghello <angelo.dureghello@timesys.com>
11  */
12 
13 #include <common.h>
14 #include <env.h>
15 #include <hang.h>
16 #include <malloc.h>
17 #include <command.h>
18 #include <net.h>
19 #include <miiphy.h>
20 #include <asm/fec.h>
21 #include <asm/global_data.h>
22 #include <asm/immap.h>
23 #include <linux/delay.h>
24 #include <linux/mii.h>
25 
26 #undef	ET_DEBUG
27 #undef	MII_DEBUG
28 
29 /* Ethernet Transmit and Receive Buffers */
30 #define DBUF_LENGTH		1520
31 #define TX_BUF_CNT		2
32 #define PKT_MAXBUF_SIZE		1518
33 #define PKT_MAXBLR_SIZE		1520
34 #define LAST_PKTBUFSRX		PKTBUFSRX - 1
35 #define BD_ENET_RX_W_E		(BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY)
36 #define BD_ENET_TX_RDY_LST	(BD_ENET_TX_READY | BD_ENET_TX_LAST)
37 
38 DECLARE_GLOBAL_DATA_PTR;
39 
init_eth_info(struct fec_info_s * info)40 static void init_eth_info(struct fec_info_s *info)
41 {
42 #ifdef CFG_SYS_FEC_BUF_USE_SRAM
43 	static u32 tmp;
44 
45 	if (info->index == 0)
46 		tmp = CFG_SYS_INIT_RAM_ADDR + 0x1000;
47 	else
48 		info->rxbd = (cbd_t *)DBUF_LENGTH;
49 
50 	/* setup Receive and Transmit buffer descriptor */
51 	info->rxbd = (cbd_t *)((u32)info->rxbd + tmp);
52 	tmp = (u32)info->rxbd;
53 	info->txbd =
54 	    (cbd_t *)((u32)info->txbd + tmp +
55 	    (PKTBUFSRX * sizeof(cbd_t)));
56 	tmp = (u32)info->txbd;
57 	info->txbuf =
58 	    (char *)((u32)info->txbuf + tmp +
59 	    (CFG_SYS_TX_ETH_BUFFER * sizeof(cbd_t)));
60 	tmp = (u32)info->txbuf;
61 #else
62 	info->rxbd =
63 	    (cbd_t *)memalign(CONFIG_SYS_CACHELINE_SIZE,
64 			       (PKTBUFSRX * sizeof(cbd_t)));
65 	info->txbd =
66 	    (cbd_t *)memalign(CONFIG_SYS_CACHELINE_SIZE,
67 			       (TX_BUF_CNT * sizeof(cbd_t)));
68 	info->txbuf =
69 	    (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, DBUF_LENGTH);
70 #endif
71 
72 #ifdef ET_DEBUG
73 	printf("rxbd %x txbd %x\n", (int)info->rxbd, (int)info->txbd);
74 #endif
75 	info->phy_name = (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, 32);
76 }
77 
fec_reset(struct fec_info_s * info)78 static void fec_reset(struct fec_info_s *info)
79 {
80 	volatile fec_t *fecp = (fec_t *)(info->iobase);
81 	int i;
82 
83 	fecp->ecr = FEC_ECR_RESET;
84 	for (i = 0; (fecp->ecr & FEC_ECR_RESET) && (i < FEC_RESET_DELAY); ++i)
85 		udelay(1);
86 
87 	if (i == FEC_RESET_DELAY)
88 		printf("FEC_RESET_DELAY timeout\n");
89 }
90 
set_fec_duplex_speed(volatile fec_t * fecp,int dup_spd)91 static void set_fec_duplex_speed(volatile fec_t *fecp, int dup_spd)
92 {
93 	struct bd_info *bd = gd->bd;
94 
95 	if ((dup_spd >> 16) == FULL) {
96 		/* Set maximum frame length */
97 		fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) | FEC_RCR_MII_MODE |
98 		    FEC_RCR_PROM | 0x100;
99 		fecp->tcr = FEC_TCR_FDEN;
100 	} else {
101 		/* Half duplex mode */
102 		fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) |
103 		    FEC_RCR_MII_MODE | FEC_RCR_DRT;
104 		fecp->tcr &= ~FEC_TCR_FDEN;
105 	}
106 
107 	if ((dup_spd & 0xFFFF) == _100BASET) {
108 #ifdef MII_DEBUG
109 		printf("100Mbps\n");
110 #endif
111 		bd->bi_ethspeed = 100;
112 	} else {
113 #ifdef MII_DEBUG
114 		printf("10Mbps\n");
115 #endif
116 		bd->bi_ethspeed = 10;
117 	}
118 }
119 
120 #ifdef ET_DEBUG
dbg_fec_regs(struct udevice * dev)121 static void dbg_fec_regs(struct udevice *dev)
122 {
123 	struct fec_info_s *info = dev_get_priv(dev);
124 	volatile fec_t *fecp = (fec_t *)(info->iobase);
125 
126 	printf("=====\n");
127 	printf("ievent       %x - %x\n", (int)&fecp->eir, fecp->eir);
128 	printf("imask        %x - %x\n", (int)&fecp->eimr, fecp->eimr);
129 	printf("r_des_active %x - %x\n", (int)&fecp->rdar, fecp->rdar);
130 	printf("x_des_active %x - %x\n", (int)&fecp->tdar, fecp->tdar);
131 	printf("ecntrl       %x - %x\n", (int)&fecp->ecr, fecp->ecr);
132 	printf("mii_mframe   %x - %x\n", (int)&fecp->mmfr, fecp->mmfr);
133 	printf("mii_speed    %x - %x\n", (int)&fecp->mscr, fecp->mscr);
134 	printf("mii_ctrlstat %x - %x\n", (int)&fecp->mibc, fecp->mibc);
135 	printf("r_cntrl      %x - %x\n", (int)&fecp->rcr, fecp->rcr);
136 	printf("x_cntrl      %x - %x\n", (int)&fecp->tcr, fecp->tcr);
137 	printf("padr_l       %x - %x\n", (int)&fecp->palr, fecp->palr);
138 	printf("padr_u       %x - %x\n", (int)&fecp->paur, fecp->paur);
139 	printf("op_pause     %x - %x\n", (int)&fecp->opd, fecp->opd);
140 	printf("iadr_u       %x - %x\n", (int)&fecp->iaur, fecp->iaur);
141 	printf("iadr_l       %x - %x\n", (int)&fecp->ialr, fecp->ialr);
142 	printf("gadr_u       %x - %x\n", (int)&fecp->gaur, fecp->gaur);
143 	printf("gadr_l       %x - %x\n", (int)&fecp->galr, fecp->galr);
144 	printf("x_wmrk       %x - %x\n", (int)&fecp->tfwr, fecp->tfwr);
145 	printf("r_bound      %x - %x\n", (int)&fecp->frbr, fecp->frbr);
146 	printf("r_fstart     %x - %x\n", (int)&fecp->frsr, fecp->frsr);
147 	printf("r_drng       %x - %x\n", (int)&fecp->erdsr, fecp->erdsr);
148 	printf("x_drng       %x - %x\n", (int)&fecp->etdsr, fecp->etdsr);
149 	printf("r_bufsz      %x - %x\n", (int)&fecp->emrbr, fecp->emrbr);
150 
151 	printf("\n");
152 	printf("rmon_t_drop        %x - %x\n", (int)&fecp->rmon_t_drop,
153 	       fecp->rmon_t_drop);
154 	printf("rmon_t_packets     %x - %x\n", (int)&fecp->rmon_t_packets,
155 	       fecp->rmon_t_packets);
156 	printf("rmon_t_bc_pkt      %x - %x\n", (int)&fecp->rmon_t_bc_pkt,
157 	       fecp->rmon_t_bc_pkt);
158 	printf("rmon_t_mc_pkt      %x - %x\n", (int)&fecp->rmon_t_mc_pkt,
159 	       fecp->rmon_t_mc_pkt);
160 	printf("rmon_t_crc_align   %x - %x\n", (int)&fecp->rmon_t_crc_align,
161 	       fecp->rmon_t_crc_align);
162 	printf("rmon_t_undersize   %x - %x\n", (int)&fecp->rmon_t_undersize,
163 	       fecp->rmon_t_undersize);
164 	printf("rmon_t_oversize    %x - %x\n", (int)&fecp->rmon_t_oversize,
165 	       fecp->rmon_t_oversize);
166 	printf("rmon_t_frag        %x - %x\n", (int)&fecp->rmon_t_frag,
167 	       fecp->rmon_t_frag);
168 	printf("rmon_t_jab         %x - %x\n", (int)&fecp->rmon_t_jab,
169 	       fecp->rmon_t_jab);
170 	printf("rmon_t_col         %x - %x\n", (int)&fecp->rmon_t_col,
171 	       fecp->rmon_t_col);
172 	printf("rmon_t_p64         %x - %x\n", (int)&fecp->rmon_t_p64,
173 	       fecp->rmon_t_p64);
174 	printf("rmon_t_p65to127    %x - %x\n", (int)&fecp->rmon_t_p65to127,
175 	       fecp->rmon_t_p65to127);
176 	printf("rmon_t_p128to255   %x - %x\n", (int)&fecp->rmon_t_p128to255,
177 	       fecp->rmon_t_p128to255);
178 	printf("rmon_t_p256to511   %x - %x\n", (int)&fecp->rmon_t_p256to511,
179 	       fecp->rmon_t_p256to511);
180 	printf("rmon_t_p512to1023  %x - %x\n", (int)&fecp->rmon_t_p512to1023,
181 	       fecp->rmon_t_p512to1023);
182 	printf("rmon_t_p1024to2047 %x - %x\n", (int)&fecp->rmon_t_p1024to2047,
183 	       fecp->rmon_t_p1024to2047);
184 	printf("rmon_t_p_gte2048   %x - %x\n", (int)&fecp->rmon_t_p_gte2048,
185 	       fecp->rmon_t_p_gte2048);
186 	printf("rmon_t_octets      %x - %x\n", (int)&fecp->rmon_t_octets,
187 	       fecp->rmon_t_octets);
188 
189 	printf("\n");
190 	printf("ieee_t_drop      %x - %x\n", (int)&fecp->ieee_t_drop,
191 	       fecp->ieee_t_drop);
192 	printf("ieee_t_frame_ok  %x - %x\n", (int)&fecp->ieee_t_frame_ok,
193 	       fecp->ieee_t_frame_ok);
194 	printf("ieee_t_1col      %x - %x\n", (int)&fecp->ieee_t_1col,
195 	       fecp->ieee_t_1col);
196 	printf("ieee_t_mcol      %x - %x\n", (int)&fecp->ieee_t_mcol,
197 	       fecp->ieee_t_mcol);
198 	printf("ieee_t_def       %x - %x\n", (int)&fecp->ieee_t_def,
199 	       fecp->ieee_t_def);
200 	printf("ieee_t_lcol      %x - %x\n", (int)&fecp->ieee_t_lcol,
201 	       fecp->ieee_t_lcol);
202 	printf("ieee_t_excol     %x - %x\n", (int)&fecp->ieee_t_excol,
203 	       fecp->ieee_t_excol);
204 	printf("ieee_t_macerr    %x - %x\n", (int)&fecp->ieee_t_macerr,
205 	       fecp->ieee_t_macerr);
206 	printf("ieee_t_cserr     %x - %x\n", (int)&fecp->ieee_t_cserr,
207 	       fecp->ieee_t_cserr);
208 	printf("ieee_t_sqe       %x - %x\n", (int)&fecp->ieee_t_sqe,
209 	       fecp->ieee_t_sqe);
210 	printf("ieee_t_fdxfc     %x - %x\n", (int)&fecp->ieee_t_fdxfc,
211 	       fecp->ieee_t_fdxfc);
212 	printf("ieee_t_octets_ok %x - %x\n", (int)&fecp->ieee_t_octets_ok,
213 	       fecp->ieee_t_octets_ok);
214 
215 	printf("\n");
216 	printf("rmon_r_drop        %x - %x\n", (int)&fecp->rmon_r_drop,
217 	       fecp->rmon_r_drop);
218 	printf("rmon_r_packets     %x - %x\n", (int)&fecp->rmon_r_packets,
219 	       fecp->rmon_r_packets);
220 	printf("rmon_r_bc_pkt      %x - %x\n", (int)&fecp->rmon_r_bc_pkt,
221 	       fecp->rmon_r_bc_pkt);
222 	printf("rmon_r_mc_pkt      %x - %x\n", (int)&fecp->rmon_r_mc_pkt,
223 	       fecp->rmon_r_mc_pkt);
224 	printf("rmon_r_crc_align   %x - %x\n", (int)&fecp->rmon_r_crc_align,
225 	       fecp->rmon_r_crc_align);
226 	printf("rmon_r_undersize   %x - %x\n", (int)&fecp->rmon_r_undersize,
227 	       fecp->rmon_r_undersize);
228 	printf("rmon_r_oversize    %x - %x\n", (int)&fecp->rmon_r_oversize,
229 	       fecp->rmon_r_oversize);
230 	printf("rmon_r_frag        %x - %x\n", (int)&fecp->rmon_r_frag,
231 	       fecp->rmon_r_frag);
232 	printf("rmon_r_jab         %x - %x\n", (int)&fecp->rmon_r_jab,
233 	       fecp->rmon_r_jab);
234 	printf("rmon_r_p64         %x - %x\n", (int)&fecp->rmon_r_p64,
235 	       fecp->rmon_r_p64);
236 	printf("rmon_r_p65to127    %x - %x\n", (int)&fecp->rmon_r_p65to127,
237 	       fecp->rmon_r_p65to127);
238 	printf("rmon_r_p128to255   %x - %x\n", (int)&fecp->rmon_r_p128to255,
239 	       fecp->rmon_r_p128to255);
240 	printf("rmon_r_p256to511   %x - %x\n", (int)&fecp->rmon_r_p256to511,
241 	       fecp->rmon_r_p256to511);
242 	printf("rmon_r_p512to1023  %x - %x\n", (int)&fecp->rmon_r_p512to1023,
243 	       fecp->rmon_r_p512to1023);
244 	printf("rmon_r_p1024to2047 %x - %x\n", (int)&fecp->rmon_r_p1024to2047,
245 	       fecp->rmon_r_p1024to2047);
246 	printf("rmon_r_p_gte2048   %x - %x\n", (int)&fecp->rmon_r_p_gte2048,
247 	       fecp->rmon_r_p_gte2048);
248 	printf("rmon_r_octets      %x - %x\n", (int)&fecp->rmon_r_octets,
249 	       fecp->rmon_r_octets);
250 
251 	printf("\n");
252 	printf("ieee_r_drop      %x - %x\n", (int)&fecp->ieee_r_drop,
253 	       fecp->ieee_r_drop);
254 	printf("ieee_r_frame_ok  %x - %x\n", (int)&fecp->ieee_r_frame_ok,
255 	       fecp->ieee_r_frame_ok);
256 	printf("ieee_r_crc       %x - %x\n", (int)&fecp->ieee_r_crc,
257 	       fecp->ieee_r_crc);
258 	printf("ieee_r_align     %x - %x\n", (int)&fecp->ieee_r_align,
259 	       fecp->ieee_r_align);
260 	printf("ieee_r_macerr    %x - %x\n", (int)&fecp->ieee_r_macerr,
261 	       fecp->ieee_r_macerr);
262 	printf("ieee_r_fdxfc     %x - %x\n", (int)&fecp->ieee_r_fdxfc,
263 	       fecp->ieee_r_fdxfc);
264 	printf("ieee_r_octets_ok %x - %x\n", (int)&fecp->ieee_r_octets_ok,
265 	       fecp->ieee_r_octets_ok);
266 
267 	printf("\n\n\n");
268 }
269 #endif
270 
mcffec_init(struct udevice * dev)271 int mcffec_init(struct udevice *dev)
272 {
273 	struct fec_info_s *info = dev_get_priv(dev);
274 	volatile fec_t *fecp = (fec_t *) (info->iobase);
275 	int rval, i;
276 	uchar ea[6];
277 
278 	fecpin_setclear(info, 1);
279 	fec_reset(info);
280 
281 	mii_init();
282 
283 	set_fec_duplex_speed(fecp, info->dup_spd);
284 
285 	/* We use strictly polling mode only */
286 	fecp->eimr = 0;
287 
288 	/* Clear any pending interrupt */
289 	fecp->eir = 0xffffffff;
290 
291 	/* Set station address   */
292 	if (info->index == 0)
293 		rval = eth_env_get_enetaddr("ethaddr", ea);
294 	else
295 		rval = eth_env_get_enetaddr("eth1addr", ea);
296 
297 	if (!rval) {
298 		puts("Please set a valid MAC address\n");
299 		return -EINVAL;
300 	}
301 
302 	fecp->palr =
303 	    (ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]);
304 	fecp->paur = (ea[4] << 24) | (ea[5] << 16);
305 
306 	/* Clear unicast address hash table */
307 	fecp->iaur = 0;
308 	fecp->ialr = 0;
309 
310 	/* Clear multicast address hash table */
311 	fecp->gaur = 0;
312 	fecp->galr = 0;
313 
314 	/* Set maximum receive buffer size. */
315 	fecp->emrbr = PKT_MAXBLR_SIZE;
316 
317 	/*
318 	 * Setup Buffers and Buffer Descriptors
319 	 */
320 	info->rx_idx = 0;
321 	info->tx_idx = 0;
322 
323 	/*
324 	 * Setup Receiver Buffer Descriptors (13.14.24.18)
325 	 * Settings:
326 	 *     Empty, Wrap
327 	 */
328 	for (i = 0; i < PKTBUFSRX; i++) {
329 		info->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
330 		info->rxbd[i].cbd_datlen = 0;	/* Reset */
331 		info->rxbd[i].cbd_bufaddr = (uint) net_rx_packets[i];
332 	}
333 	info->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
334 
335 	/*
336 	 * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
337 	 * Settings:
338 	 *    Last, Tx CRC
339 	 */
340 	for (i = 0; i < TX_BUF_CNT; i++) {
341 		info->txbd[i].cbd_sc = BD_ENET_TX_LAST | BD_ENET_TX_TC;
342 		info->txbd[i].cbd_datlen = 0;	/* Reset */
343 		info->txbd[i].cbd_bufaddr = (uint) (&info->txbuf[0]);
344 	}
345 	info->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
346 
347 	/* Set receive and transmit descriptor base */
348 	fecp->erdsr = (unsigned int)(&info->rxbd[0]);
349 	fecp->etdsr = (unsigned int)(&info->txbd[0]);
350 
351 	/* Now enable the transmit and receive processing */
352 	fecp->ecr |= FEC_ECR_ETHER_EN;
353 
354 	/* And last, try to fill Rx Buffer Descriptors
355 	 * Descriptor polling active
356 	 */
357 	fecp->rdar = 0x01000000;
358 
359 	return 0;
360 }
361 
mcffec_send(struct udevice * dev,void * packet,int length)362 static int mcffec_send(struct udevice *dev, void *packet, int length)
363 {
364 	struct fec_info_s *info = dev_get_priv(dev);
365 	volatile fec_t *fecp = (fec_t *)info->iobase;
366 	int j, rc;
367 	u16 phy_status;
368 
369 	miiphy_read(dev->name, info->phy_addr, MII_BMSR, &phy_status);
370 
371 	/* section 16.9.23.3
372 	 * Wait for ready
373 	 */
374 	j = 0;
375 	while ((info->txbd[info->tx_idx].cbd_sc & BD_ENET_TX_READY) &&
376 	       (j < info->to_loop)) {
377 		udelay(1);
378 		j++;
379 	}
380 	if (j >= info->to_loop)
381 		printf("TX not ready\n");
382 
383 	info->txbd[info->tx_idx].cbd_bufaddr = (uint)packet;
384 	info->txbd[info->tx_idx].cbd_datlen = length;
385 	info->txbd[info->tx_idx].cbd_sc |= BD_ENET_TX_RDY_LST;
386 
387 	/* Activate transmit Buffer Descriptor polling */
388 	fecp->tdar = 0x01000000;	/* Descriptor polling active    */
389 
390 #ifndef CFG_SYS_FEC_BUF_USE_SRAM
391 	/*
392 	 * FEC unable to initial transmit data packet.
393 	 * A nop will ensure the descriptor polling active completed.
394 	 * CF Internal RAM has shorter cycle access than DRAM. If use
395 	 * DRAM as Buffer descriptor and data, a nop is a must.
396 	 * Affect only V2 and V3.
397 	 */
398 	__asm__ ("nop");
399 #endif
400 
401 #ifdef CONFIG_SYS_UNIFY_CACHE
402 	icache_invalid();
403 #endif
404 
405 	j = 0;
406 	while ((info->txbd[info->tx_idx].cbd_sc & BD_ENET_TX_READY) &&
407 	       (j < info->to_loop)) {
408 		udelay(1);
409 		j++;
410 	}
411 	if (j >= info->to_loop)
412 		printf("TX timeout\n");
413 
414 #ifdef ET_DEBUG
415 	printf("%s[%d] %s: cycles: %d    status: %x  retry cnt: %d\n",
416 	       __FILE__, __LINE__, __func__, j,
417 	       info->txbd[info->tx_idx].cbd_sc,
418 	       (info->txbd[info->tx_idx].cbd_sc & 0x003C) >> 2);
419 #endif
420 
421 	/* return only status bits */
422 	rc = (info->txbd[info->tx_idx].cbd_sc & BD_ENET_TX_STATS);
423 	info->tx_idx = (info->tx_idx + 1) % TX_BUF_CNT;
424 
425 	return rc;
426 }
427 
mcffec_recv(struct udevice * dev,int flags,uchar ** packetp)428 static int mcffec_recv(struct udevice *dev, int flags, uchar **packetp)
429 {
430 	struct fec_info_s *info = dev_get_priv(dev);
431 	volatile fec_t *fecp = (fec_t *)info->iobase;
432 	int length = -1;
433 
434 	for (;;) {
435 #ifdef CONFIG_SYS_UNIFY_CACHE
436 		icache_invalid();
437 #endif
438 		/* If nothing received - leave for() loop */
439 		if (info->rxbd[info->rx_idx].cbd_sc & BD_ENET_RX_EMPTY)
440 			break;
441 
442 		length = info->rxbd[info->rx_idx].cbd_datlen;
443 
444 		if (info->rxbd[info->rx_idx].cbd_sc & 0x003f) {
445 			printf("%s[%d] err: %x\n",
446 			       __func__, __LINE__,
447 			       info->rxbd[info->rx_idx].cbd_sc);
448 		} else {
449 			length -= 4;
450 
451 			/*
452 			 * Pass the buffer ptr up to the protocol layers.
453 			 */
454 			*packetp = net_rx_packets[info->rx_idx];
455 
456 			fecp->eir |= FEC_EIR_RXF;
457 		}
458 
459 		/* Give the buffer back to the FEC. */
460 		info->rxbd[info->rx_idx].cbd_datlen = 0;
461 
462 		/* wrap around buffer index when necessary */
463 		if (info->rx_idx == LAST_PKTBUFSRX) {
464 			info->rxbd[PKTBUFSRX - 1].cbd_sc = BD_ENET_RX_W_E;
465 			info->rx_idx = 0;
466 		} else {
467 			info->rxbd[info->rx_idx].cbd_sc = BD_ENET_RX_EMPTY;
468 			info->rx_idx++;
469 		}
470 
471 		/* Try to fill Buffer Descriptors
472 		 * Descriptor polling active
473 		 */
474 		fecp->rdar = 0x01000000;
475 	}
476 
477 	return length;
478 }
479 
mcffec_halt(struct udevice * dev)480 static void mcffec_halt(struct udevice *dev)
481 {
482 	struct fec_info_s *info = dev_get_priv(dev);
483 
484 	fec_reset(info);
485 	fecpin_setclear(info, 0);
486 
487 	info->rx_idx = 0;
488 	info->tx_idx = 0;
489 
490 	memset(info->rxbd, 0, PKTBUFSRX * sizeof(cbd_t));
491 	memset(info->txbd, 0, TX_BUF_CNT * sizeof(cbd_t));
492 	memset(info->txbuf, 0, DBUF_LENGTH);
493 }
494 
495 static const struct eth_ops mcffec_ops = {
496 	.start	= mcffec_init,
497 	.send	= mcffec_send,
498 	.recv	= mcffec_recv,
499 	.stop	= mcffec_halt,
500 };
501 
502 /*
503  * Boot sequence, called just after mcffec_of_to_plat,
504  * as DM way, it replaces old mcffec_initialize.
505  */
mcffec_probe(struct udevice * dev)506 static int mcffec_probe(struct udevice *dev)
507 {
508 	struct eth_pdata *pdata = dev_get_plat(dev);
509 	struct fec_info_s *info = dev_get_priv(dev);
510 	int node = dev_of_offset(dev);
511 	int retval, fec_idx;
512 	const u32 *val;
513 
514 	info->index = dev_seq(dev);
515 	info->iobase = pdata->iobase;
516 	info->phy_addr = -1;
517 
518 	val = fdt_getprop(gd->fdt_blob, node, "mii-base", NULL);
519 	if (val) {
520 		u32 fec_iobase;
521 
522 		fec_idx = fdt32_to_cpu(*val);
523 		if (fec_idx == info->index) {
524 			fec_iobase = info->iobase;
525 		} else {
526 			printf("mii base != base address, fec_idx %d\n",
527 			       fec_idx);
528 			retval = fec_get_base_addr(fec_idx, &fec_iobase);
529 			if (retval)
530 				return retval;
531 		}
532 		info->miibase = fec_iobase;
533 	}
534 
535 	val = fdt_getprop(gd->fdt_blob, node, "phy-addr", NULL);
536 	if (val)
537 		info->phy_addr = fdt32_to_cpu(*val);
538 
539 	val = fdt_getprop(gd->fdt_blob, node, "timeout-loop", NULL);
540 	if (val)
541 		info->to_loop = fdt32_to_cpu(*val);
542 
543 	init_eth_info(info);
544 
545 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
546 	info->bus = mdio_alloc();
547 	if (!info->bus)
548 		return -ENOMEM;
549 	strcpy(info->bus->name, dev->name);
550 	info->bus->read = mcffec_miiphy_read;
551 	info->bus->write = mcffec_miiphy_write;
552 
553 	retval = mdio_register(info->bus);
554 	if (retval < 0)
555 		return retval;
556 #endif
557 
558 	return 0;
559 }
560 
mcffec_remove(struct udevice * dev)561 static int mcffec_remove(struct udevice *dev)
562 {
563 	struct fec_info_s *priv = dev_get_priv(dev);
564 
565 	mdio_unregister(priv->bus);
566 	mdio_free(priv->bus);
567 
568 	return 0;
569 }
570 
571 /*
572  * Boot sequence, called 1st
573  */
mcffec_of_to_plat(struct udevice * dev)574 static int mcffec_of_to_plat(struct udevice *dev)
575 {
576 	struct eth_pdata *pdata = dev_get_plat(dev);
577 	const u32 *val;
578 
579 	pdata->iobase = dev_read_addr(dev);
580 	/* Default to 10Mbit/s */
581 	pdata->max_speed = 10;
582 
583 	val = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
584 			  "max-speed", NULL);
585 	if (val)
586 		pdata->max_speed = fdt32_to_cpu(*val);
587 
588 	return 0;
589 }
590 
591 static const struct udevice_id mcffec_ids[] = {
592 	{ .compatible = "fsl,mcf-fec" },
593 	{ }
594 };
595 
596 U_BOOT_DRIVER(mcffec) = {
597 	.name	= "mcffec",
598 	.id	= UCLASS_ETH,
599 	.of_match = mcffec_ids,
600 	.of_to_plat = mcffec_of_to_plat,
601 	.probe	= mcffec_probe,
602 	.remove	= mcffec_remove,
603 	.ops	= &mcffec_ops,
604 	.priv_auto	= sizeof(struct fec_info_s),
605 	.plat_auto	= sizeof(struct eth_pdata),
606 };
607