]>
Commit | Line | Data |
---|---|---|
ac2916a2 AA |
1 | /* |
2 | * LPC32xx Ethernet MAC interface driver | |
3 | * | |
4 | * (C) Copyright 2014 DENX Software Engineering GmbH | |
5 | * Written-by: Albert ARIBAUD - 3ADEV <albert.aribaud@3adev.fr> | |
6 | * | |
7 | * SPDX-License-Identifier: GPL-2.0+ | |
8 | */ | |
9 | ||
10 | #include <common.h> | |
11 | #include <net.h> | |
12 | #include <malloc.h> | |
13 | #include <miiphy.h> | |
14 | #include <asm/io.h> | |
1221ce45 | 15 | #include <linux/errno.h> |
ac2916a2 AA |
16 | #include <asm/types.h> |
17 | #include <asm/system.h> | |
18 | #include <asm/byteorder.h> | |
19 | #include <asm/arch/cpu.h> | |
20 | #include <asm/arch/config.h> | |
21 | ||
22 | /* | |
23 | * Notes: | |
24 | * | |
25 | * 1. Unless specified otherwise, all references to tables or paragraphs | |
26 | * are to UM10326, "LPC32x0 and LPC32x0/01 User manual". | |
27 | * | |
28 | * 2. Only bitfield masks/values which are actually used by the driver | |
29 | * are defined. | |
30 | */ | |
31 | ||
32 | /* a single RX descriptor. The controller has an array of these */ | |
33 | struct lpc32xx_eth_rxdesc { | |
34 | u32 packet; /* Receive packet pointer */ | |
35 | u32 control; /* Descriptor command status */ | |
36 | }; | |
37 | ||
38 | #define LPC32XX_ETH_RX_DESC_SIZE (sizeof(struct lpc32xx_eth_rxdesc)) | |
39 | ||
40 | /* RX control bitfields/masks (see Table 330) */ | |
41 | #define LPC32XX_ETH_RX_CTRL_SIZE_MASK 0x000007FF | |
42 | #define LPC32XX_ETH_RX_CTRL_UNUSED 0x7FFFF800 | |
43 | #define LPC32XX_ETH_RX_CTRL_INTERRUPT 0x80000000 | |
44 | ||
45 | /* a single RX status. The controller has an array of these */ | |
46 | struct lpc32xx_eth_rxstat { | |
47 | u32 statusinfo; /* Transmit Descriptor status */ | |
48 | u32 statushashcrc; /* Transmit Descriptor CRCs */ | |
49 | }; | |
50 | ||
51 | #define LPC32XX_ETH_RX_STAT_SIZE (sizeof(struct lpc32xx_eth_rxstat)) | |
52 | ||
53 | /* RX statusinfo bitfields/masks (see Table 333) */ | |
54 | #define RX_STAT_RXSIZE 0x000007FF | |
55 | /* Helper: OR of all errors except RANGE */ | |
56 | #define RX_STAT_ERRORS 0x1B800000 | |
57 | ||
58 | /* a single TX descriptor. The controller has an array of these */ | |
59 | struct lpc32xx_eth_txdesc { | |
60 | u32 packet; /* Transmit packet pointer */ | |
61 | u32 control; /* Descriptor control */ | |
62 | }; | |
63 | ||
64 | #define LPC32XX_ETH_TX_DESC_SIZE (sizeof(struct lpc32xx_eth_txdesc)) | |
65 | ||
66 | /* TX control bitfields/masks (see Table 335) */ | |
67 | #define TX_CTRL_TXSIZE 0x000007FF | |
68 | #define TX_CTRL_LAST 0x40000000 | |
69 | ||
70 | /* a single TX status. The controller has an array of these */ | |
71 | struct lpc32xx_eth_txstat { | |
72 | u32 statusinfo; /* Transmit Descriptor status */ | |
73 | }; | |
74 | ||
75 | #define LPC32XX_ETH_TX_STAT_SIZE (sizeof(struct lpc32xx_eth_txstat)) | |
76 | ||
77 | /* Ethernet MAC interface registers (see Table 283) */ | |
78 | struct lpc32xx_eth_registers { | |
79 | /* MAC registers - 0x3106_0000 to 0x3106_01FC */ | |
80 | u32 mac1; /* MAC configuration register 1 */ | |
81 | u32 mac2; /* MAC configuration register 2 */ | |
82 | u32 ipgt; /* Back-to-back Inter-Packet Gap reg. */ | |
83 | u32 ipgr; /* Non-back-to-back IPG register */ | |
84 | u32 clrt; /* Collision Window / Retry register */ | |
85 | u32 maxf; /* Maximum Frame register */ | |
86 | u32 supp; /* Phy Support register */ | |
87 | u32 test; | |
88 | u32 mcfg; /* MII management configuration reg. */ | |
89 | u32 mcmd; /* MII management command register */ | |
90 | u32 madr; /* MII management address register */ | |
91 | u32 mwtd; /* MII management wite data register */ | |
92 | u32 mrdd; /* MII management read data register */ | |
93 | u32 mind; /* MII management indicators register */ | |
94 | u32 reserved1[2]; | |
95 | u32 sa0; /* Station address register 0 */ | |
96 | u32 sa1; /* Station address register 1 */ | |
97 | u32 sa2; /* Station address register 2 */ | |
98 | u32 reserved2[45]; | |
99 | /* Control registers */ | |
100 | u32 command; | |
101 | u32 status; | |
102 | u32 rxdescriptor; | |
103 | u32 rxstatus; | |
104 | u32 rxdescriptornumber; /* actually, number MINUS ONE */ | |
105 | u32 rxproduceindex; /* head of rx desc fifo */ | |
106 | u32 rxconsumeindex; /* tail of rx desc fifo */ | |
107 | u32 txdescriptor; | |
108 | u32 txstatus; | |
109 | u32 txdescriptornumber; /* actually, number MINUS ONE */ | |
110 | u32 txproduceindex; /* head of rx desc fifo */ | |
111 | u32 txconsumeindex; /* tail of rx desc fifo */ | |
112 | u32 reserved3[10]; | |
113 | u32 tsv0; /* Transmit status vector register 0 */ | |
114 | u32 tsv1; /* Transmit status vector register 1 */ | |
115 | u32 rsv; /* Receive status vector register */ | |
116 | u32 reserved4[3]; | |
117 | u32 flowcontrolcounter; | |
118 | u32 flowcontrolstatus; | |
119 | u32 reserved5[34]; | |
120 | /* RX filter registers - 0x3106_0200 to 0x3106_0FDC */ | |
121 | u32 rxfilterctrl; | |
122 | u32 rxfilterwolstatus; | |
123 | u32 rxfilterwolclear; | |
124 | u32 reserved6; | |
125 | u32 hashfilterl; | |
126 | u32 hashfilterh; | |
127 | u32 reserved7[882]; | |
128 | /* Module control registers - 0x3106_0FE0 to 0x3106_0FF8 */ | |
129 | u32 intstatus; /* Interrupt status register */ | |
130 | u32 intenable; | |
131 | u32 intclear; | |
132 | u32 intset; | |
133 | u32 reserved8; | |
134 | u32 powerdown; | |
135 | u32 reserved9; | |
136 | }; | |
137 | ||
138 | /* MAC1 register bitfields/masks and offsets (see Table 283) */ | |
139 | #define MAC1_RECV_ENABLE 0x00000001 | |
140 | #define MAC1_PASS_ALL_RX_FRAMES 0x00000002 | |
141 | #define MAC1_SOFT_RESET 0x00008000 | |
142 | /* Helper: general reset */ | |
143 | #define MAC1_RESETS 0x0000CF00 | |
144 | ||
145 | /* MAC2 register bitfields/masks and offsets (see Table 284) */ | |
146 | #define MAC2_FULL_DUPLEX 0x00000001 | |
147 | #define MAC2_CRC_ENABLE 0x00000010 | |
148 | #define MAC2_PAD_CRC_ENABLE 0x00000020 | |
149 | ||
150 | /* SUPP register bitfields/masks and offsets (see Table 290) */ | |
151 | #define SUPP_SPEED 0x00000100 | |
152 | ||
153 | /* MCFG register bitfields/masks and offsets (see Table 292) */ | |
23f5db0e | 154 | #define MCFG_RESET_MII_MGMT 0x00008000 |
ac2916a2 AA |
155 | /* divide clock by 28 (see Table 293) */ |
156 | #define MCFG_CLOCK_SELECT_DIV28 0x0000001C | |
157 | ||
158 | /* MADR register bitfields/masks and offsets (see Table 295) */ | |
159 | #define MADR_REG_MASK 0x0000001F | |
160 | #define MADR_PHY_MASK 0x00001F00 | |
161 | #define MADR_REG_OFFSET 0 | |
162 | #define MADR_PHY_OFFSET 8 | |
163 | ||
164 | /* MIND register bitfields/masks (see Table 298) */ | |
165 | #define MIND_BUSY 0x00000001 | |
166 | ||
167 | /* COMMAND register bitfields/masks and offsets (see Table 283) */ | |
168 | #define COMMAND_RXENABLE 0x00000001 | |
169 | #define COMMAND_TXENABLE 0x00000002 | |
170 | #define COMMAND_PASSRUNTFRAME 0x00000040 | |
1a791892 | 171 | #define COMMAND_RMII 0x00000200 |
ac2916a2 AA |
172 | #define COMMAND_FULL_DUPLEX 0x00000400 |
173 | /* Helper: general reset */ | |
6e039b4c | 174 | #define COMMAND_RESETS 0x00000038 |
ac2916a2 AA |
175 | |
176 | /* STATUS register bitfields/masks and offsets (see Table 283) */ | |
177 | #define STATUS_RXSTATUS 0x00000001 | |
178 | #define STATUS_TXSTATUS 0x00000002 | |
179 | ||
180 | /* RXFILTERCTRL register bitfields/masks (see Table 319) */ | |
181 | #define RXFILTERCTRL_ACCEPTBROADCAST 0x00000002 | |
182 | #define RXFILTERCTRL_ACCEPTPERFECT 0x00000020 | |
183 | ||
184 | /* Buffers and descriptors */ | |
185 | ||
186 | #define ATTRS(n) __aligned(n) | |
187 | ||
188 | #define TX_BUF_COUNT 4 | |
189 | #define RX_BUF_COUNT 4 | |
190 | ||
191 | struct lpc32xx_eth_buffers { | |
192 | ATTRS(4) struct lpc32xx_eth_txdesc tx_desc[TX_BUF_COUNT]; | |
193 | ATTRS(4) struct lpc32xx_eth_txstat tx_stat[TX_BUF_COUNT]; | |
194 | ATTRS(PKTALIGN) u8 tx_buf[TX_BUF_COUNT*PKTSIZE_ALIGN]; | |
195 | ATTRS(4) struct lpc32xx_eth_rxdesc rx_desc[RX_BUF_COUNT]; | |
196 | ATTRS(8) struct lpc32xx_eth_rxstat rx_stat[RX_BUF_COUNT]; | |
197 | ATTRS(PKTALIGN) u8 rx_buf[RX_BUF_COUNT*PKTSIZE_ALIGN]; | |
198 | }; | |
199 | ||
200 | /* port device data struct */ | |
201 | struct lpc32xx_eth_device { | |
202 | struct eth_device dev; | |
203 | struct lpc32xx_eth_registers *regs; | |
204 | struct lpc32xx_eth_buffers *bufs; | |
1a791892 | 205 | bool phy_rmii; |
ac2916a2 AA |
206 | }; |
207 | ||
208 | #define LPC32XX_ETH_DEVICE_SIZE (sizeof(struct lpc32xx_eth_device)) | |
209 | ||
210 | /* generic macros */ | |
211 | #define to_lpc32xx_eth(_d) container_of(_d, struct lpc32xx_eth_device, dev) | |
212 | ||
213 | /* timeout for MII polling */ | |
214 | #define MII_TIMEOUT 10000000 | |
215 | ||
216 | /* limits for PHY and register addresses */ | |
217 | #define MII_MAX_REG (MADR_REG_MASK >> MADR_REG_OFFSET) | |
218 | ||
219 | #define MII_MAX_PHY (MADR_PHY_MASK >> MADR_PHY_OFFSET) | |
220 | ||
221 | DECLARE_GLOBAL_DATA_PTR; | |
222 | ||
223 | #if defined(CONFIG_PHYLIB) || defined(CONFIG_MII) || defined(CONFIG_CMD_MII) | |
224 | /* | |
225 | * mii_reg_read - miiphy_read callback function. | |
226 | * | |
227 | * Returns 16bit phy register value, or 0xffff on error | |
228 | */ | |
5a49f174 JH |
229 | static int mii_reg_read(struct mii_dev *bus, int phy_adr, int devad, |
230 | int reg_ofs) | |
ac2916a2 | 231 | { |
5a49f174 JH |
232 | u16 data = 0; |
233 | struct eth_device *dev = eth_get_dev_by_name(bus->name); | |
ac2916a2 AA |
234 | struct lpc32xx_eth_device *dlpc32xx_eth = to_lpc32xx_eth(dev); |
235 | struct lpc32xx_eth_registers *regs = dlpc32xx_eth->regs; | |
236 | u32 mind_reg; | |
237 | u32 timeout; | |
238 | ||
239 | /* check parameters */ | |
240 | if (phy_adr > MII_MAX_PHY) { | |
241 | printf("%s:%u: Invalid PHY address %d\n", | |
242 | __func__, __LINE__, phy_adr); | |
243 | return -EFAULT; | |
244 | } | |
245 | if (reg_ofs > MII_MAX_REG) { | |
246 | printf("%s:%u: Invalid register offset %d\n", | |
247 | __func__, __LINE__, reg_ofs); | |
248 | return -EFAULT; | |
249 | } | |
250 | ||
251 | /* write the phy and reg addressse into the MII address reg */ | |
252 | writel((phy_adr << MADR_PHY_OFFSET) | (reg_ofs << MADR_REG_OFFSET), | |
253 | ®s->madr); | |
254 | ||
255 | /* write 1 to the MII command register to cause a read */ | |
256 | writel(1, ®s->mcmd); | |
257 | ||
258 | /* wait till the MII is not busy */ | |
259 | timeout = MII_TIMEOUT; | |
260 | do { | |
261 | /* read MII indicators register */ | |
262 | mind_reg = readl(®s->mind); | |
263 | if (--timeout == 0) | |
264 | break; | |
265 | } while (mind_reg & MIND_BUSY); | |
266 | ||
267 | /* write 0 to the MII command register to finish the read */ | |
268 | writel(0, ®s->mcmd); | |
269 | ||
270 | if (timeout == 0) { | |
271 | printf("%s:%u: MII busy timeout\n", __func__, __LINE__); | |
272 | return -EFAULT; | |
273 | } | |
274 | ||
5a49f174 | 275 | data = (u16) readl(®s->mrdd); |
ac2916a2 AA |
276 | |
277 | debug("%s:(adr %d, off %d) => %04x\n", __func__, phy_adr, | |
5a49f174 | 278 | reg_ofs, data); |
ac2916a2 | 279 | |
5a49f174 | 280 | return data; |
ac2916a2 AA |
281 | } |
282 | ||
283 | /* | |
284 | * mii_reg_write - imiiphy_write callback function. | |
285 | * | |
286 | * Returns 0 if write succeed, -EINVAL on bad parameters | |
287 | * -ETIME on timeout | |
288 | */ | |
5a49f174 JH |
289 | static int mii_reg_write(struct mii_dev *bus, int phy_adr, int devad, |
290 | int reg_ofs, u16 data) | |
ac2916a2 | 291 | { |
5a49f174 | 292 | struct eth_device *dev = eth_get_dev_by_name(bus->name); |
ac2916a2 AA |
293 | struct lpc32xx_eth_device *dlpc32xx_eth = to_lpc32xx_eth(dev); |
294 | struct lpc32xx_eth_registers *regs = dlpc32xx_eth->regs; | |
295 | u32 mind_reg; | |
296 | u32 timeout; | |
297 | ||
298 | /* check parameters */ | |
299 | if (phy_adr > MII_MAX_PHY) { | |
300 | printf("%s:%u: Invalid PHY address %d\n", | |
301 | __func__, __LINE__, phy_adr); | |
302 | return -EFAULT; | |
303 | } | |
304 | if (reg_ofs > MII_MAX_REG) { | |
305 | printf("%s:%u: Invalid register offset %d\n", | |
306 | __func__, __LINE__, reg_ofs); | |
307 | return -EFAULT; | |
308 | } | |
309 | ||
79206c04 VZ |
310 | /* write the phy and reg addressse into the MII address reg */ |
311 | writel((phy_adr << MADR_PHY_OFFSET) | (reg_ofs << MADR_REG_OFFSET), | |
312 | ®s->madr); | |
313 | ||
314 | /* write data to the MII write register */ | |
315 | writel(data, ®s->mwtd); | |
316 | ||
ac2916a2 AA |
317 | /* wait till the MII is not busy */ |
318 | timeout = MII_TIMEOUT; | |
319 | do { | |
320 | /* read MII indicators register */ | |
321 | mind_reg = readl(®s->mind); | |
322 | if (--timeout == 0) | |
323 | break; | |
324 | } while (mind_reg & MIND_BUSY); | |
325 | ||
326 | if (timeout == 0) { | |
327 | printf("%s:%u: MII busy timeout\n", __func__, | |
328 | __LINE__); | |
329 | return -EFAULT; | |
330 | } | |
331 | ||
ac2916a2 AA |
332 | /*debug("%s:(adr %d, off %d) <= %04x\n", __func__, phy_adr, |
333 | reg_ofs, data);*/ | |
334 | ||
335 | return 0; | |
336 | } | |
337 | #endif | |
338 | ||
ac2916a2 | 339 | /* |
68a77668 | 340 | * Provide default Ethernet buffers base address if target did not. |
ac2916a2 AA |
341 | * Locate buffers in SRAM at 0x00001000 to avoid cache issues and |
342 | * maximize throughput. | |
343 | */ | |
68a77668 SL |
344 | #if !defined(CONFIG_LPC32XX_ETH_BUFS_BASE) |
345 | #define CONFIG_LPC32XX_ETH_BUFS_BASE 0x00001000 | |
346 | #endif | |
ac2916a2 AA |
347 | |
348 | static struct lpc32xx_eth_device lpc32xx_eth = { | |
349 | .regs = (struct lpc32xx_eth_registers *)LPC32XX_ETH_BASE, | |
68a77668 | 350 | .bufs = (struct lpc32xx_eth_buffers *)CONFIG_LPC32XX_ETH_BUFS_BASE, |
1a791892 VZ |
351 | #if defined(CONFIG_RMII) |
352 | .phy_rmii = true, | |
353 | #endif | |
ac2916a2 AA |
354 | }; |
355 | ||
356 | #define TX_TIMEOUT 10000 | |
357 | ||
358 | static int lpc32xx_eth_send(struct eth_device *dev, void *dataptr, int datasize) | |
359 | { | |
360 | struct lpc32xx_eth_device *lpc32xx_eth_device = | |
361 | container_of(dev, struct lpc32xx_eth_device, dev); | |
362 | struct lpc32xx_eth_registers *regs = lpc32xx_eth_device->regs; | |
363 | struct lpc32xx_eth_buffers *bufs = lpc32xx_eth_device->bufs; | |
364 | int timeout, tx_index; | |
365 | ||
366 | /* time out if transmit descriptor array remains full too long */ | |
367 | timeout = TX_TIMEOUT; | |
368 | while ((readl(®s->status) & STATUS_TXSTATUS) && | |
369 | (readl(®s->txconsumeindex) | |
370 | == readl(®s->txproduceindex))) { | |
371 | if (timeout-- == 0) | |
372 | return -1; | |
373 | } | |
374 | ||
375 | /* determine next transmit packet index to use */ | |
376 | tx_index = readl(®s->txproduceindex); | |
377 | ||
378 | /* set up transmit packet */ | |
379 | writel((u32)dataptr, &bufs->tx_desc[tx_index].packet); | |
380 | writel(TX_CTRL_LAST | ((datasize - 1) & TX_CTRL_TXSIZE), | |
381 | &bufs->tx_desc[tx_index].control); | |
382 | writel(0, &bufs->tx_stat[tx_index].statusinfo); | |
383 | ||
384 | /* pass transmit packet to DMA engine */ | |
385 | tx_index = (tx_index + 1) % TX_BUF_COUNT; | |
386 | writel(tx_index, ®s->txproduceindex); | |
387 | ||
388 | /* transmission succeeded */ | |
389 | return 0; | |
390 | } | |
391 | ||
392 | #define RX_TIMEOUT 1000000 | |
393 | ||
394 | static int lpc32xx_eth_recv(struct eth_device *dev) | |
395 | { | |
396 | struct lpc32xx_eth_device *lpc32xx_eth_device = | |
397 | container_of(dev, struct lpc32xx_eth_device, dev); | |
398 | struct lpc32xx_eth_registers *regs = lpc32xx_eth_device->regs; | |
399 | struct lpc32xx_eth_buffers *bufs = lpc32xx_eth_device->bufs; | |
400 | int timeout, rx_index; | |
401 | ||
402 | /* time out if receive descriptor array remains empty too long */ | |
403 | timeout = RX_TIMEOUT; | |
404 | while (readl(®s->rxproduceindex) == readl(®s->rxconsumeindex)) { | |
405 | if (timeout-- == 0) | |
406 | return -1; | |
407 | } | |
408 | ||
409 | /* determine next receive packet index to use */ | |
410 | rx_index = readl(®s->rxconsumeindex); | |
411 | ||
412 | /* if data was valid, pass it on */ | |
1fd92db8 JH |
413 | if (!(bufs->rx_stat[rx_index].statusinfo & RX_STAT_ERRORS)) { |
414 | net_process_received_packet( | |
415 | &(bufs->rx_buf[rx_index * PKTSIZE_ALIGN]), | |
416 | (bufs->rx_stat[rx_index].statusinfo | |
417 | & RX_STAT_RXSIZE) + 1); | |
418 | } | |
ac2916a2 AA |
419 | |
420 | /* pass receive slot back to DMA engine */ | |
421 | rx_index = (rx_index + 1) % RX_BUF_COUNT; | |
422 | writel(rx_index, ®s->rxconsumeindex); | |
423 | ||
424 | /* reception successful */ | |
425 | return 0; | |
426 | } | |
427 | ||
428 | static int lpc32xx_eth_write_hwaddr(struct eth_device *dev) | |
429 | { | |
430 | struct lpc32xx_eth_device *lpc32xx_eth_device = | |
431 | container_of(dev, struct lpc32xx_eth_device, dev); | |
432 | struct lpc32xx_eth_registers *regs = lpc32xx_eth_device->regs; | |
433 | ||
434 | /* Save station address */ | |
435 | writel((unsigned long) (dev->enetaddr[0] | | |
436 | (dev->enetaddr[1] << 8)), ®s->sa2); | |
437 | writel((unsigned long) (dev->enetaddr[2] | | |
438 | (dev->enetaddr[3] << 8)), ®s->sa1); | |
439 | writel((unsigned long) (dev->enetaddr[4] | | |
440 | (dev->enetaddr[5] << 8)), ®s->sa0); | |
441 | ||
442 | return 0; | |
443 | } | |
444 | ||
445 | static int lpc32xx_eth_init(struct eth_device *dev) | |
446 | { | |
447 | struct lpc32xx_eth_device *lpc32xx_eth_device = | |
448 | container_of(dev, struct lpc32xx_eth_device, dev); | |
449 | struct lpc32xx_eth_registers *regs = lpc32xx_eth_device->regs; | |
450 | struct lpc32xx_eth_buffers *bufs = lpc32xx_eth_device->bufs; | |
451 | int index; | |
452 | ||
23f5db0e VZ |
453 | /* Initial MAC initialization */ |
454 | writel(MAC1_PASS_ALL_RX_FRAMES, ®s->mac1); | |
455 | writel(MAC2_PAD_CRC_ENABLE | MAC2_CRC_ENABLE, ®s->mac2); | |
456 | writel(PKTSIZE_ALIGN, ®s->maxf); | |
457 | ||
458 | /* Retries: 15 (0xF). Collision window: 57 (0x37). */ | |
459 | writel(0x370F, ®s->clrt); | |
460 | ||
461 | /* Set IP gap pt 2 to default 0x12 but pt 1 to non-default 0 */ | |
462 | writel(0x0012, ®s->ipgr); | |
463 | ||
464 | /* pass runt (smaller than 64 bytes) frames */ | |
1a791892 VZ |
465 | if (lpc32xx_eth_device->phy_rmii) |
466 | writel(COMMAND_PASSRUNTFRAME | COMMAND_RMII, ®s->command); | |
467 | else | |
468 | writel(COMMAND_PASSRUNTFRAME, ®s->command); | |
ac2916a2 AA |
469 | |
470 | /* Configure Full/Half Duplex mode */ | |
471 | if (miiphy_duplex(dev->name, CONFIG_PHY_ADDR) == FULL) { | |
472 | setbits_le32(®s->mac2, MAC2_FULL_DUPLEX); | |
473 | setbits_le32(®s->command, COMMAND_FULL_DUPLEX); | |
474 | writel(0x15, ®s->ipgt); | |
475 | } else { | |
476 | writel(0x12, ®s->ipgt); | |
477 | } | |
478 | ||
479 | /* Configure 100MBit/10MBit mode */ | |
480 | if (miiphy_speed(dev->name, CONFIG_PHY_ADDR) == _100BASET) | |
481 | writel(SUPP_SPEED, ®s->supp); | |
482 | else | |
483 | writel(0, ®s->supp); | |
484 | ||
ac2916a2 AA |
485 | /* Save station address */ |
486 | writel((unsigned long) (dev->enetaddr[0] | | |
487 | (dev->enetaddr[1] << 8)), ®s->sa2); | |
488 | writel((unsigned long) (dev->enetaddr[2] | | |
489 | (dev->enetaddr[3] << 8)), ®s->sa1); | |
490 | writel((unsigned long) (dev->enetaddr[4] | | |
491 | (dev->enetaddr[5] << 8)), ®s->sa0); | |
492 | ||
493 | /* set up transmit buffers */ | |
494 | for (index = 0; index < TX_BUF_COUNT; index++) { | |
495 | bufs->tx_desc[index].control = 0; | |
496 | bufs->tx_stat[index].statusinfo = 0; | |
497 | } | |
498 | writel((u32)(&bufs->tx_desc), (u32 *)®s->txdescriptor); | |
499 | writel((u32)(&bufs->tx_stat), ®s->txstatus); | |
500 | writel(TX_BUF_COUNT-1, ®s->txdescriptornumber); | |
501 | ||
502 | /* set up receive buffers */ | |
503 | for (index = 0; index < RX_BUF_COUNT; index++) { | |
504 | bufs->rx_desc[index].packet = | |
505 | (u32) (bufs->rx_buf+index*PKTSIZE_ALIGN); | |
506 | bufs->rx_desc[index].control = PKTSIZE_ALIGN - 1; | |
507 | bufs->rx_stat[index].statusinfo = 0; | |
508 | bufs->rx_stat[index].statushashcrc = 0; | |
509 | } | |
510 | writel((u32)(&bufs->rx_desc), ®s->rxdescriptor); | |
511 | writel((u32)(&bufs->rx_stat), ®s->rxstatus); | |
512 | writel(RX_BUF_COUNT-1, ®s->rxdescriptornumber); | |
513 | ||
514 | /* Enable broadcast and matching address packets */ | |
515 | writel(RXFILTERCTRL_ACCEPTBROADCAST | | |
516 | RXFILTERCTRL_ACCEPTPERFECT, ®s->rxfilterctrl); | |
517 | ||
518 | /* Clear and disable interrupts */ | |
519 | writel(0xFFFF, ®s->intclear); | |
520 | writel(0, ®s->intenable); | |
521 | ||
522 | /* Enable receive and transmit mode of MAC ethernet core */ | |
523 | setbits_le32(®s->command, COMMAND_RXENABLE | COMMAND_TXENABLE); | |
524 | setbits_le32(®s->mac1, MAC1_RECV_ENABLE); | |
525 | ||
526 | /* | |
527 | * Perform a 'dummy' first send to work around Ethernet.1 | |
528 | * erratum (see ES_LPC3250 rev. 9 dated 1 June 2011). | |
529 | * Use zeroed "index" variable as the dummy. | |
530 | */ | |
531 | ||
532 | index = 0; | |
533 | lpc32xx_eth_send(dev, &index, 4); | |
534 | ||
535 | return 0; | |
536 | } | |
537 | ||
538 | static int lpc32xx_eth_halt(struct eth_device *dev) | |
539 | { | |
540 | struct lpc32xx_eth_device *lpc32xx_eth_device = | |
541 | container_of(dev, struct lpc32xx_eth_device, dev); | |
542 | struct lpc32xx_eth_registers *regs = lpc32xx_eth_device->regs; | |
543 | ||
544 | /* Reset all MAC logic */ | |
545 | writel(MAC1_RESETS, ®s->mac1); | |
546 | writel(COMMAND_RESETS, ®s->command); | |
547 | /* Let reset condition settle */ | |
548 | udelay(2000); | |
549 | ||
550 | return 0; | |
551 | } | |
552 | ||
553 | #if defined(CONFIG_PHYLIB) | |
554 | int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid) | |
555 | { | |
1a791892 VZ |
556 | struct lpc32xx_eth_device *lpc32xx_eth_device = |
557 | container_of(dev, struct lpc32xx_eth_device, dev); | |
ac2916a2 AA |
558 | struct mii_dev *bus; |
559 | struct phy_device *phydev; | |
560 | int ret; | |
561 | ||
562 | bus = mdio_alloc(); | |
563 | if (!bus) { | |
564 | printf("mdio_alloc failed\n"); | |
565 | return -ENOMEM; | |
566 | } | |
875e0bc6 JH |
567 | bus->read = mii_reg_read; |
568 | bus->write = mii_reg_write; | |
192bc694 | 569 | strcpy(bus->name, dev->name); |
ac2916a2 AA |
570 | |
571 | ret = mdio_register(bus); | |
572 | if (ret) { | |
573 | printf("mdio_register failed\n"); | |
574 | free(bus); | |
575 | return -ENOMEM; | |
576 | } | |
577 | ||
1a791892 VZ |
578 | if (lpc32xx_eth_device->phy_rmii) |
579 | phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RMII); | |
580 | else | |
581 | phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_MII); | |
582 | ||
ac2916a2 AA |
583 | if (!phydev) { |
584 | printf("phy_connect failed\n"); | |
585 | return -ENODEV; | |
586 | } | |
587 | ||
588 | phy_config(phydev); | |
589 | phy_startup(phydev); | |
590 | ||
591 | return 0; | |
592 | } | |
593 | #endif | |
594 | ||
595 | int lpc32xx_eth_initialize(bd_t *bis) | |
596 | { | |
597 | struct eth_device *dev = &lpc32xx_eth.dev; | |
598 | struct lpc32xx_eth_registers *regs = lpc32xx_eth.regs; | |
599 | ||
600 | /* | |
601 | * Set RMII management clock rate. With HCLK at 104 MHz and | |
602 | * a divider of 28, this will be 3.72 MHz. | |
603 | */ | |
23f5db0e | 604 | writel(MCFG_RESET_MII_MGMT, ®s->mcfg); |
ac2916a2 AA |
605 | writel(MCFG_CLOCK_SELECT_DIV28, ®s->mcfg); |
606 | ||
607 | /* Reset all MAC logic */ | |
608 | writel(MAC1_RESETS, ®s->mac1); | |
609 | writel(COMMAND_RESETS, ®s->command); | |
610 | ||
611 | /* wait 10 ms for the whole I/F to reset */ | |
612 | udelay(10000); | |
613 | ||
614 | /* must be less than sizeof(dev->name) */ | |
615 | strcpy(dev->name, "eth0"); | |
616 | ||
617 | dev->init = (void *)lpc32xx_eth_init; | |
618 | dev->halt = (void *)lpc32xx_eth_halt; | |
619 | dev->send = (void *)lpc32xx_eth_send; | |
620 | dev->recv = (void *)lpc32xx_eth_recv; | |
621 | dev->write_hwaddr = (void *)lpc32xx_eth_write_hwaddr; | |
622 | ||
623 | /* Release SOFT reset to let MII talk to PHY */ | |
624 | clrbits_le32(®s->mac1, MAC1_SOFT_RESET); | |
625 | ||
626 | /* register driver before talking to phy */ | |
627 | eth_register(dev); | |
628 | ||
629 | #if defined(CONFIG_PHYLIB) | |
fe0596ca | 630 | lpc32xx_eth_phylib_init(dev, CONFIG_PHY_ADDR); |
ac2916a2 | 631 | #elif defined(CONFIG_MII) || defined(CONFIG_CMD_MII) |
5a49f174 JH |
632 | int retval; |
633 | struct mii_dev *mdiodev = mdio_alloc(); | |
634 | if (!mdiodev) | |
635 | return -ENOMEM; | |
636 | strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN); | |
637 | mdiodev->read = mii_reg_read; | |
638 | mdiodev->write = mii_reg_write; | |
639 | ||
640 | retval = mdio_register(mdiodev); | |
641 | if (retval < 0) | |
642 | return retval; | |
ac2916a2 AA |
643 | #endif |
644 | ||
645 | return 0; | |
646 | } |