]>
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> | |
15 | #include <asm/errno.h> | |
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 | */ | |
229 | static int mii_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 *data) | |
230 | { | |
231 | struct eth_device *dev = eth_get_dev_by_name(devname); | |
232 | struct lpc32xx_eth_device *dlpc32xx_eth = to_lpc32xx_eth(dev); | |
233 | struct lpc32xx_eth_registers *regs = dlpc32xx_eth->regs; | |
234 | u32 mind_reg; | |
235 | u32 timeout; | |
236 | ||
237 | /* check parameters */ | |
238 | if (phy_adr > MII_MAX_PHY) { | |
239 | printf("%s:%u: Invalid PHY address %d\n", | |
240 | __func__, __LINE__, phy_adr); | |
241 | return -EFAULT; | |
242 | } | |
243 | if (reg_ofs > MII_MAX_REG) { | |
244 | printf("%s:%u: Invalid register offset %d\n", | |
245 | __func__, __LINE__, reg_ofs); | |
246 | return -EFAULT; | |
247 | } | |
248 | ||
249 | /* write the phy and reg addressse into the MII address reg */ | |
250 | writel((phy_adr << MADR_PHY_OFFSET) | (reg_ofs << MADR_REG_OFFSET), | |
251 | ®s->madr); | |
252 | ||
253 | /* write 1 to the MII command register to cause a read */ | |
254 | writel(1, ®s->mcmd); | |
255 | ||
256 | /* wait till the MII is not busy */ | |
257 | timeout = MII_TIMEOUT; | |
258 | do { | |
259 | /* read MII indicators register */ | |
260 | mind_reg = readl(®s->mind); | |
261 | if (--timeout == 0) | |
262 | break; | |
263 | } while (mind_reg & MIND_BUSY); | |
264 | ||
265 | /* write 0 to the MII command register to finish the read */ | |
266 | writel(0, ®s->mcmd); | |
267 | ||
268 | if (timeout == 0) { | |
269 | printf("%s:%u: MII busy timeout\n", __func__, __LINE__); | |
270 | return -EFAULT; | |
271 | } | |
272 | ||
273 | *data = (u16) readl(®s->mrdd); | |
274 | ||
275 | debug("%s:(adr %d, off %d) => %04x\n", __func__, phy_adr, | |
276 | reg_ofs, *data); | |
277 | ||
278 | return 0; | |
279 | } | |
280 | ||
281 | /* | |
282 | * mii_reg_write - imiiphy_write callback function. | |
283 | * | |
284 | * Returns 0 if write succeed, -EINVAL on bad parameters | |
285 | * -ETIME on timeout | |
286 | */ | |
287 | static int mii_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data) | |
288 | { | |
289 | struct eth_device *dev = eth_get_dev_by_name(devname); | |
290 | struct lpc32xx_eth_device *dlpc32xx_eth = to_lpc32xx_eth(dev); | |
291 | struct lpc32xx_eth_registers *regs = dlpc32xx_eth->regs; | |
292 | u32 mind_reg; | |
293 | u32 timeout; | |
294 | ||
295 | /* check parameters */ | |
296 | if (phy_adr > MII_MAX_PHY) { | |
297 | printf("%s:%u: Invalid PHY address %d\n", | |
298 | __func__, __LINE__, phy_adr); | |
299 | return -EFAULT; | |
300 | } | |
301 | if (reg_ofs > MII_MAX_REG) { | |
302 | printf("%s:%u: Invalid register offset %d\n", | |
303 | __func__, __LINE__, reg_ofs); | |
304 | return -EFAULT; | |
305 | } | |
306 | ||
79206c04 VZ |
307 | /* write the phy and reg addressse into the MII address reg */ |
308 | writel((phy_adr << MADR_PHY_OFFSET) | (reg_ofs << MADR_REG_OFFSET), | |
309 | ®s->madr); | |
310 | ||
311 | /* write data to the MII write register */ | |
312 | writel(data, ®s->mwtd); | |
313 | ||
ac2916a2 AA |
314 | /* wait till the MII is not busy */ |
315 | timeout = MII_TIMEOUT; | |
316 | do { | |
317 | /* read MII indicators register */ | |
318 | mind_reg = readl(®s->mind); | |
319 | if (--timeout == 0) | |
320 | break; | |
321 | } while (mind_reg & MIND_BUSY); | |
322 | ||
323 | if (timeout == 0) { | |
324 | printf("%s:%u: MII busy timeout\n", __func__, | |
325 | __LINE__); | |
326 | return -EFAULT; | |
327 | } | |
328 | ||
ac2916a2 AA |
329 | /*debug("%s:(adr %d, off %d) <= %04x\n", __func__, phy_adr, |
330 | reg_ofs, data);*/ | |
331 | ||
332 | return 0; | |
333 | } | |
334 | #endif | |
335 | ||
336 | #if defined(CONFIG_PHYLIB) | |
337 | int lpc32xx_eth_phy_read(struct mii_dev *bus, int phy_addr, int dev_addr, | |
338 | int reg_addr) | |
339 | { | |
340 | u16 data; | |
341 | int ret; | |
342 | ret = mii_reg_read(bus->name, phy_addr, reg_addr, &data); | |
343 | if (ret) | |
344 | return ret; | |
345 | return data; | |
346 | } | |
347 | ||
348 | int lpc32xx_eth_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr, | |
349 | int reg_addr, u16 data) | |
350 | { | |
351 | return mii_reg_write(bus->name, phy_addr, reg_addr, data); | |
352 | } | |
353 | #endif | |
354 | ||
355 | /* | |
68a77668 | 356 | * Provide default Ethernet buffers base address if target did not. |
ac2916a2 AA |
357 | * Locate buffers in SRAM at 0x00001000 to avoid cache issues and |
358 | * maximize throughput. | |
359 | */ | |
68a77668 SL |
360 | #if !defined(CONFIG_LPC32XX_ETH_BUFS_BASE) |
361 | #define CONFIG_LPC32XX_ETH_BUFS_BASE 0x00001000 | |
362 | #endif | |
ac2916a2 AA |
363 | |
364 | static struct lpc32xx_eth_device lpc32xx_eth = { | |
365 | .regs = (struct lpc32xx_eth_registers *)LPC32XX_ETH_BASE, | |
68a77668 | 366 | .bufs = (struct lpc32xx_eth_buffers *)CONFIG_LPC32XX_ETH_BUFS_BASE, |
1a791892 VZ |
367 | #if defined(CONFIG_RMII) |
368 | .phy_rmii = true, | |
369 | #endif | |
ac2916a2 AA |
370 | }; |
371 | ||
372 | #define TX_TIMEOUT 10000 | |
373 | ||
374 | static int lpc32xx_eth_send(struct eth_device *dev, void *dataptr, int datasize) | |
375 | { | |
376 | struct lpc32xx_eth_device *lpc32xx_eth_device = | |
377 | container_of(dev, struct lpc32xx_eth_device, dev); | |
378 | struct lpc32xx_eth_registers *regs = lpc32xx_eth_device->regs; | |
379 | struct lpc32xx_eth_buffers *bufs = lpc32xx_eth_device->bufs; | |
380 | int timeout, tx_index; | |
381 | ||
382 | /* time out if transmit descriptor array remains full too long */ | |
383 | timeout = TX_TIMEOUT; | |
384 | while ((readl(®s->status) & STATUS_TXSTATUS) && | |
385 | (readl(®s->txconsumeindex) | |
386 | == readl(®s->txproduceindex))) { | |
387 | if (timeout-- == 0) | |
388 | return -1; | |
389 | } | |
390 | ||
391 | /* determine next transmit packet index to use */ | |
392 | tx_index = readl(®s->txproduceindex); | |
393 | ||
394 | /* set up transmit packet */ | |
395 | writel((u32)dataptr, &bufs->tx_desc[tx_index].packet); | |
396 | writel(TX_CTRL_LAST | ((datasize - 1) & TX_CTRL_TXSIZE), | |
397 | &bufs->tx_desc[tx_index].control); | |
398 | writel(0, &bufs->tx_stat[tx_index].statusinfo); | |
399 | ||
400 | /* pass transmit packet to DMA engine */ | |
401 | tx_index = (tx_index + 1) % TX_BUF_COUNT; | |
402 | writel(tx_index, ®s->txproduceindex); | |
403 | ||
404 | /* transmission succeeded */ | |
405 | return 0; | |
406 | } | |
407 | ||
408 | #define RX_TIMEOUT 1000000 | |
409 | ||
410 | static int lpc32xx_eth_recv(struct eth_device *dev) | |
411 | { | |
412 | struct lpc32xx_eth_device *lpc32xx_eth_device = | |
413 | container_of(dev, struct lpc32xx_eth_device, dev); | |
414 | struct lpc32xx_eth_registers *regs = lpc32xx_eth_device->regs; | |
415 | struct lpc32xx_eth_buffers *bufs = lpc32xx_eth_device->bufs; | |
416 | int timeout, rx_index; | |
417 | ||
418 | /* time out if receive descriptor array remains empty too long */ | |
419 | timeout = RX_TIMEOUT; | |
420 | while (readl(®s->rxproduceindex) == readl(®s->rxconsumeindex)) { | |
421 | if (timeout-- == 0) | |
422 | return -1; | |
423 | } | |
424 | ||
425 | /* determine next receive packet index to use */ | |
426 | rx_index = readl(®s->rxconsumeindex); | |
427 | ||
428 | /* if data was valid, pass it on */ | |
1fd92db8 JH |
429 | if (!(bufs->rx_stat[rx_index].statusinfo & RX_STAT_ERRORS)) { |
430 | net_process_received_packet( | |
431 | &(bufs->rx_buf[rx_index * PKTSIZE_ALIGN]), | |
432 | (bufs->rx_stat[rx_index].statusinfo | |
433 | & RX_STAT_RXSIZE) + 1); | |
434 | } | |
ac2916a2 AA |
435 | |
436 | /* pass receive slot back to DMA engine */ | |
437 | rx_index = (rx_index + 1) % RX_BUF_COUNT; | |
438 | writel(rx_index, ®s->rxconsumeindex); | |
439 | ||
440 | /* reception successful */ | |
441 | return 0; | |
442 | } | |
443 | ||
444 | static int lpc32xx_eth_write_hwaddr(struct eth_device *dev) | |
445 | { | |
446 | struct lpc32xx_eth_device *lpc32xx_eth_device = | |
447 | container_of(dev, struct lpc32xx_eth_device, dev); | |
448 | struct lpc32xx_eth_registers *regs = lpc32xx_eth_device->regs; | |
449 | ||
450 | /* Save station address */ | |
451 | writel((unsigned long) (dev->enetaddr[0] | | |
452 | (dev->enetaddr[1] << 8)), ®s->sa2); | |
453 | writel((unsigned long) (dev->enetaddr[2] | | |
454 | (dev->enetaddr[3] << 8)), ®s->sa1); | |
455 | writel((unsigned long) (dev->enetaddr[4] | | |
456 | (dev->enetaddr[5] << 8)), ®s->sa0); | |
457 | ||
458 | return 0; | |
459 | } | |
460 | ||
461 | static int lpc32xx_eth_init(struct eth_device *dev) | |
462 | { | |
463 | struct lpc32xx_eth_device *lpc32xx_eth_device = | |
464 | container_of(dev, struct lpc32xx_eth_device, dev); | |
465 | struct lpc32xx_eth_registers *regs = lpc32xx_eth_device->regs; | |
466 | struct lpc32xx_eth_buffers *bufs = lpc32xx_eth_device->bufs; | |
467 | int index; | |
468 | ||
23f5db0e VZ |
469 | /* Initial MAC initialization */ |
470 | writel(MAC1_PASS_ALL_RX_FRAMES, ®s->mac1); | |
471 | writel(MAC2_PAD_CRC_ENABLE | MAC2_CRC_ENABLE, ®s->mac2); | |
472 | writel(PKTSIZE_ALIGN, ®s->maxf); | |
473 | ||
474 | /* Retries: 15 (0xF). Collision window: 57 (0x37). */ | |
475 | writel(0x370F, ®s->clrt); | |
476 | ||
477 | /* Set IP gap pt 2 to default 0x12 but pt 1 to non-default 0 */ | |
478 | writel(0x0012, ®s->ipgr); | |
479 | ||
480 | /* pass runt (smaller than 64 bytes) frames */ | |
1a791892 VZ |
481 | if (lpc32xx_eth_device->phy_rmii) |
482 | writel(COMMAND_PASSRUNTFRAME | COMMAND_RMII, ®s->command); | |
483 | else | |
484 | writel(COMMAND_PASSRUNTFRAME, ®s->command); | |
ac2916a2 AA |
485 | |
486 | /* Configure Full/Half Duplex mode */ | |
487 | if (miiphy_duplex(dev->name, CONFIG_PHY_ADDR) == FULL) { | |
488 | setbits_le32(®s->mac2, MAC2_FULL_DUPLEX); | |
489 | setbits_le32(®s->command, COMMAND_FULL_DUPLEX); | |
490 | writel(0x15, ®s->ipgt); | |
491 | } else { | |
492 | writel(0x12, ®s->ipgt); | |
493 | } | |
494 | ||
495 | /* Configure 100MBit/10MBit mode */ | |
496 | if (miiphy_speed(dev->name, CONFIG_PHY_ADDR) == _100BASET) | |
497 | writel(SUPP_SPEED, ®s->supp); | |
498 | else | |
499 | writel(0, ®s->supp); | |
500 | ||
ac2916a2 AA |
501 | /* Save station address */ |
502 | writel((unsigned long) (dev->enetaddr[0] | | |
503 | (dev->enetaddr[1] << 8)), ®s->sa2); | |
504 | writel((unsigned long) (dev->enetaddr[2] | | |
505 | (dev->enetaddr[3] << 8)), ®s->sa1); | |
506 | writel((unsigned long) (dev->enetaddr[4] | | |
507 | (dev->enetaddr[5] << 8)), ®s->sa0); | |
508 | ||
509 | /* set up transmit buffers */ | |
510 | for (index = 0; index < TX_BUF_COUNT; index++) { | |
511 | bufs->tx_desc[index].control = 0; | |
512 | bufs->tx_stat[index].statusinfo = 0; | |
513 | } | |
514 | writel((u32)(&bufs->tx_desc), (u32 *)®s->txdescriptor); | |
515 | writel((u32)(&bufs->tx_stat), ®s->txstatus); | |
516 | writel(TX_BUF_COUNT-1, ®s->txdescriptornumber); | |
517 | ||
518 | /* set up receive buffers */ | |
519 | for (index = 0; index < RX_BUF_COUNT; index++) { | |
520 | bufs->rx_desc[index].packet = | |
521 | (u32) (bufs->rx_buf+index*PKTSIZE_ALIGN); | |
522 | bufs->rx_desc[index].control = PKTSIZE_ALIGN - 1; | |
523 | bufs->rx_stat[index].statusinfo = 0; | |
524 | bufs->rx_stat[index].statushashcrc = 0; | |
525 | } | |
526 | writel((u32)(&bufs->rx_desc), ®s->rxdescriptor); | |
527 | writel((u32)(&bufs->rx_stat), ®s->rxstatus); | |
528 | writel(RX_BUF_COUNT-1, ®s->rxdescriptornumber); | |
529 | ||
530 | /* Enable broadcast and matching address packets */ | |
531 | writel(RXFILTERCTRL_ACCEPTBROADCAST | | |
532 | RXFILTERCTRL_ACCEPTPERFECT, ®s->rxfilterctrl); | |
533 | ||
534 | /* Clear and disable interrupts */ | |
535 | writel(0xFFFF, ®s->intclear); | |
536 | writel(0, ®s->intenable); | |
537 | ||
538 | /* Enable receive and transmit mode of MAC ethernet core */ | |
539 | setbits_le32(®s->command, COMMAND_RXENABLE | COMMAND_TXENABLE); | |
540 | setbits_le32(®s->mac1, MAC1_RECV_ENABLE); | |
541 | ||
542 | /* | |
543 | * Perform a 'dummy' first send to work around Ethernet.1 | |
544 | * erratum (see ES_LPC3250 rev. 9 dated 1 June 2011). | |
545 | * Use zeroed "index" variable as the dummy. | |
546 | */ | |
547 | ||
548 | index = 0; | |
549 | lpc32xx_eth_send(dev, &index, 4); | |
550 | ||
551 | return 0; | |
552 | } | |
553 | ||
554 | static int lpc32xx_eth_halt(struct eth_device *dev) | |
555 | { | |
556 | struct lpc32xx_eth_device *lpc32xx_eth_device = | |
557 | container_of(dev, struct lpc32xx_eth_device, dev); | |
558 | struct lpc32xx_eth_registers *regs = lpc32xx_eth_device->regs; | |
559 | ||
560 | /* Reset all MAC logic */ | |
561 | writel(MAC1_RESETS, ®s->mac1); | |
562 | writel(COMMAND_RESETS, ®s->command); | |
563 | /* Let reset condition settle */ | |
564 | udelay(2000); | |
565 | ||
566 | return 0; | |
567 | } | |
568 | ||
569 | #if defined(CONFIG_PHYLIB) | |
570 | int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid) | |
571 | { | |
1a791892 VZ |
572 | struct lpc32xx_eth_device *lpc32xx_eth_device = |
573 | container_of(dev, struct lpc32xx_eth_device, dev); | |
ac2916a2 AA |
574 | struct mii_dev *bus; |
575 | struct phy_device *phydev; | |
576 | int ret; | |
577 | ||
578 | bus = mdio_alloc(); | |
579 | if (!bus) { | |
580 | printf("mdio_alloc failed\n"); | |
581 | return -ENOMEM; | |
582 | } | |
583 | bus->read = lpc32xx_eth_phy_read; | |
584 | bus->write = lpc32xx_eth_phy_write; | |
585 | sprintf(bus->name, dev->name); | |
586 | ||
587 | ret = mdio_register(bus); | |
588 | if (ret) { | |
589 | printf("mdio_register failed\n"); | |
590 | free(bus); | |
591 | return -ENOMEM; | |
592 | } | |
593 | ||
1a791892 VZ |
594 | if (lpc32xx_eth_device->phy_rmii) |
595 | phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RMII); | |
596 | else | |
597 | phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_MII); | |
598 | ||
ac2916a2 AA |
599 | if (!phydev) { |
600 | printf("phy_connect failed\n"); | |
601 | return -ENODEV; | |
602 | } | |
603 | ||
604 | phy_config(phydev); | |
605 | phy_startup(phydev); | |
606 | ||
607 | return 0; | |
608 | } | |
609 | #endif | |
610 | ||
611 | int lpc32xx_eth_initialize(bd_t *bis) | |
612 | { | |
613 | struct eth_device *dev = &lpc32xx_eth.dev; | |
614 | struct lpc32xx_eth_registers *regs = lpc32xx_eth.regs; | |
615 | ||
616 | /* | |
617 | * Set RMII management clock rate. With HCLK at 104 MHz and | |
618 | * a divider of 28, this will be 3.72 MHz. | |
619 | */ | |
23f5db0e | 620 | writel(MCFG_RESET_MII_MGMT, ®s->mcfg); |
ac2916a2 AA |
621 | writel(MCFG_CLOCK_SELECT_DIV28, ®s->mcfg); |
622 | ||
623 | /* Reset all MAC logic */ | |
624 | writel(MAC1_RESETS, ®s->mac1); | |
625 | writel(COMMAND_RESETS, ®s->command); | |
626 | ||
627 | /* wait 10 ms for the whole I/F to reset */ | |
628 | udelay(10000); | |
629 | ||
630 | /* must be less than sizeof(dev->name) */ | |
631 | strcpy(dev->name, "eth0"); | |
632 | ||
633 | dev->init = (void *)lpc32xx_eth_init; | |
634 | dev->halt = (void *)lpc32xx_eth_halt; | |
635 | dev->send = (void *)lpc32xx_eth_send; | |
636 | dev->recv = (void *)lpc32xx_eth_recv; | |
637 | dev->write_hwaddr = (void *)lpc32xx_eth_write_hwaddr; | |
638 | ||
639 | /* Release SOFT reset to let MII talk to PHY */ | |
640 | clrbits_le32(®s->mac1, MAC1_SOFT_RESET); | |
641 | ||
642 | /* register driver before talking to phy */ | |
643 | eth_register(dev); | |
644 | ||
645 | #if defined(CONFIG_PHYLIB) | |
fe0596ca | 646 | lpc32xx_eth_phylib_init(dev, CONFIG_PHY_ADDR); |
ac2916a2 AA |
647 | #elif defined(CONFIG_MII) || defined(CONFIG_CMD_MII) |
648 | miiphy_register(dev->name, mii_reg_read, mii_reg_write); | |
649 | #endif | |
650 | ||
651 | return 0; | |
652 | } |