1 /******************************************************************************
2 *
3 * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
4 * Analog Devices, Inc.),
5 * Copyright (C) 2023-2024 Analog Devices, Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 ******************************************************************************/
20
21 /******* Includes *******/
22 #include <string.h>
23 #include "emac.h"
24 #include "emac_reva.h"
25
26 /******* Variables *******/
27 mxc_emac_reva_device_t mxc_emac_context;
28 static mxc_emac_reva_device_t *emac = &mxc_emac_context;
29
30 /******* Functions *******/
31 /* ************************************************************************* */
32 /* Private Functions */
33 /* ************************************************************************* */
emac_mdio_write(unsigned char reg,uint16_t value)34 static void emac_mdio_write(unsigned char reg, uint16_t value)
35 {
36 unsigned int netctl;
37 unsigned int netstat;
38 unsigned int frame;
39
40 netctl = EMAC_READL(emac, cn);
41 netctl |= EMAC_BIT(CN, MPEN);
42 EMAC_WRITEL(emac, cn, netctl);
43
44 frame = (EMAC_BF(PHY_MT, SOP, 1) | EMAC_BF(PHY_MT, OP, 1) |
45 EMAC_BF(PHY_MT, PHYADDR, emac->phy_addr) | EMAC_BF(PHY_MT, REGADDR, reg) |
46 EMAC_BF(PHY_MT, CODE, 2) | EMAC_BF(PHY_MT, DATA, value));
47 EMAC_WRITEL(emac, phy_mt, frame);
48
49 do {
50 netstat = EMAC_READL(emac, status);
51 } while (!(netstat & EMAC_BIT(STATUS, IDLE)));
52
53 netctl = EMAC_READL(emac, cn);
54 netctl &= ~EMAC_BIT(CN, MPEN);
55 EMAC_WRITEL(emac, cn, netctl);
56 }
57
emac_mdio_read(unsigned char reg)58 static uint16_t emac_mdio_read(unsigned char reg)
59 {
60 unsigned int netctl;
61 unsigned int netstat;
62 unsigned int frame;
63
64 netctl = EMAC_READL(emac, cn);
65 netctl |= EMAC_BIT(CN, MPEN);
66 EMAC_WRITEL(emac, cn, netctl);
67
68 frame = (EMAC_BF(PHY_MT, SOP, 1) | EMAC_BF(PHY_MT, OP, 2) |
69 EMAC_BF(PHY_MT, PHYADDR, emac->phy_addr) | EMAC_BF(PHY_MT, REGADDR, reg) |
70 EMAC_BF(PHY_MT, CODE, 2));
71 EMAC_WRITEL(emac, phy_mt, frame);
72
73 do {
74 netstat = EMAC_READL(emac, status);
75 } while (!(netstat & EMAC_BIT(STATUS, IDLE)));
76
77 frame = EMAC_READL(emac, phy_mt);
78
79 netctl = EMAC_READL(emac, cn);
80 netctl &= ~EMAC_BIT(CN, MPEN);
81 EMAC_WRITEL(emac, cn, netctl);
82
83 return EMAC_BFEXT(PHY_MT, DATA, frame);
84 }
85
emac_reclaim_rx_buffers(unsigned int new_tail)86 static void emac_reclaim_rx_buffers(unsigned int new_tail)
87 {
88 unsigned int i;
89
90 i = emac->rx_tail;
91
92 while (i > new_tail) {
93 emac->rx_ring[i].addr &= ~RXADDR_USED;
94 i++;
95
96 if (emac->rx_ring_size < i) {
97 i = 0;
98 }
99 }
100
101 while (i < new_tail) {
102 emac->rx_ring[i].addr &= ~RXADDR_USED;
103 i++;
104 }
105
106 barrier();
107 emac->rx_tail = new_tail;
108 }
109
emac_phy_reset(void)110 static void emac_phy_reset(void)
111 {
112 uint16_t status;
113 int i;
114
115 emac_mdio_write(MII_ADVERTISE, (ADVERTISE_CSMA | ADVERTISE_ALL));
116 emac_mdio_write(MII_BMCR, (BMCR_ANENABLE | BMCR_ANRESTART));
117
118 for (i = 0; i < (CONFIG_SYS_EMAC_AUTONEG_TIMEOUT / 100); i++) {
119 status = emac_mdio_read(MII_BMSR);
120
121 if (status & BMSR_ANEGCOMPLETE) {
122 break;
123 }
124
125 emac->delay_us(100);
126 }
127 }
128
129 #ifdef CONFIG_EMAC_SEARCH_PHY
emac_phy_find(void)130 static int emac_phy_find(void)
131 {
132 int i;
133 uint16_t phy_id;
134
135 for (i = 0; i < 32; i++) {
136 emac->phy_addr = i;
137
138 phy_id = emac_mdio_read(MII_PHYSID1);
139
140 if (0xffff != phy_id) {
141 return E_NO_ERROR;
142 }
143 }
144
145 return E_NO_DEVICE;
146 }
147 #endif //CONFIG_EMAC_SEARCH_PHY
148
emac_mii_nway_result(unsigned int negotiated)149 static unsigned int emac_mii_nway_result(unsigned int negotiated)
150 {
151 unsigned int ret;
152
153 if (negotiated & LPA_100FULL) {
154 ret = LPA_100FULL;
155 } else if (negotiated & LPA_100BASE4) {
156 ret = LPA_100BASE4;
157 } else if (negotiated & LPA_100HALF) {
158 ret = LPA_100HALF;
159 } else if (negotiated & LPA_10FULL) {
160 ret = LPA_10FULL;
161 } else {
162 ret = LPA_10HALF;
163 }
164
165 return ret;
166 }
167
emac_phy_init(void)168 static int emac_phy_init(void)
169 {
170 int result = E_NO_ERROR;
171 uint16_t phy_id;
172 uint16_t status;
173 uint16_t adv;
174 uint16_t lpa;
175 int media;
176 int speed;
177 int duplex;
178 int i;
179 unsigned int ncfgr;
180
181 #ifdef CONFIG_EMAC_SEARCH_PHY
182 result = emac_phy_find();
183
184 if (result) {
185 return result;
186 }
187
188 #endif //CONFIG_EMAC_SEARCH_PHY
189
190 phy_id = emac_mdio_read(MII_PHYSID1);
191
192 if (0xffff == phy_id) {
193 return E_NO_DEVICE;
194 }
195
196 status = emac_mdio_read(MII_BMSR);
197
198 if (!(status & BMSR_LSTATUS)) {
199 emac_phy_reset();
200
201 for (i = 0; i < (CONFIG_SYS_EMAC_AUTONEG_TIMEOUT / 100); i++) {
202 status = emac_mdio_read(MII_BMSR);
203
204 if (status & BMSR_LSTATUS) {
205 break;
206 }
207
208 emac->delay_us(100);
209 }
210 }
211
212 if (!(status & BMSR_LSTATUS)) {
213 return E_NO_RESPONSE; //PHY Link Down
214 } else {
215 adv = emac_mdio_read(MII_ADVERTISE);
216 lpa = emac_mdio_read(MII_LPA);
217
218 media = emac_mii_nway_result(lpa & adv);
219 speed = ((media & (ADVERTISE_100FULL | ADVERTISE_100HALF)) ? 1 : 0);
220 duplex = (media & ADVERTISE_FULL) ? 1 : 0;
221
222 ncfgr = EMAC_READL(emac, cfg);
223 ncfgr &= ~(EMAC_BIT(CFG, SPD) | EMAC_BIT(CFG, FULLDPLX));
224
225 if (speed) {
226 ncfgr |= EMAC_BIT(CFG, SPD);
227 }
228
229 if (duplex) {
230 ncfgr |= EMAC_BIT(CFG, FULLDPLX);
231 }
232
233 /* Discard FCS Field */
234 ncfgr |= EMAC_BIT(CFG, DCRXFCS);
235
236 EMAC_WRITEL(emac, cfg, ncfgr);
237 }
238
239 return result;
240 }
241
242 /* ************************************************************************* */
243 /* Control/Configuration Functions */
244 /* ************************************************************************* */
MXC_EMAC_RevA_Init(mxc_emac_reva_config_t * config)245 int MXC_EMAC_RevA_Init(mxc_emac_reva_config_t *config)
246 {
247 int result = E_UNKNOWN;
248 unsigned int ncfgr, emac_pclk_rate, clk_div;
249
250 if (!config) {
251 return E_NULL_PTR;
252 }
253
254 if (!emac->first_init) {
255 /* Assign interface base address */
256 emac->regs = (mxc_emac_reva_regs_t *)MXC_EMAC;
257
258 /* Clock configuration */
259 emac_pclk_rate = PeripheralClock;
260
261 if (emac_pclk_rate < 20000000) {
262 clk_div = EMAC_CLK_DIV8;
263 } else if (emac_pclk_rate < 40000000) {
264 clk_div = EMAC_CLK_DIV16;
265 } else if (emac_pclk_rate < 80000000) {
266 clk_div = EMAC_CLK_DIV32;
267 } else {
268 clk_div = EMAC_CLK_DIV64;
269 }
270
271 ncfgr = EMAC_BF(CFG, MDCCLK, clk_div);
272 EMAC_WRITEL(emac, cfg, ncfgr);
273
274 /* Initialization to be finished */
275 emac->first_init = 1;
276 }
277
278 /* Set configuration */
279 result = MXC_EMAC_RevA_SetConfiguration(config);
280
281 return result;
282 }
283
MXC_EMAC_RevA_SetConfiguration(mxc_emac_reva_config_t * config)284 int MXC_EMAC_RevA_SetConfiguration(mxc_emac_reva_config_t *config)
285 {
286 if (!emac->first_init) {
287 return E_UNINITIALIZED;
288 }
289
290 if (!(config->rx_buff) || !(config->rx_ring_buff) || !(config->tx_ring_buff)) {
291 return E_NULL_PTR;
292 }
293
294 if ((config->rx_ring_buff_size % sizeof(mxc_emac_dma_desc_t)) ||
295 (config->tx_ring_buff_size % sizeof(mxc_emac_dma_desc_t)) ||
296 (config->rx_buff_size % EMAC_RX_BUFFER_SIZE)) {
297 return E_INVALID;
298 }
299
300 if (((config->rx_ring_buff_size / sizeof(mxc_emac_dma_desc_t)) > MAX_SYS_EMAC_RX_RING_SIZE) ||
301 ((config->tx_ring_buff_size / sizeof(mxc_emac_dma_desc_t)) > MAX_SYS_EMAC_TX_RING_SIZE) ||
302 (config->rx_buff_size > MAX_SYS_EMAC_RX_BUFFER_SIZE)) {
303 return E_INVALID;
304 }
305
306 if (!config->delay_us) {
307 return E_INVALID;
308 }
309
310 emac->rx_buffer = (void *)(config->rx_buff);
311 emac->rx_buffer_dma = (unsigned int)(config->rx_buff);
312 emac->rx_buffer_size = config->rx_buff_size;
313
314 emac->rx_ring = (mxc_emac_reva_dma_desc_t *)(config->rx_ring_buff);
315 emac->rx_ring_dma = (unsigned int)(config->rx_ring_buff);
316 emac->rx_ring_size = (config->rx_ring_buff_size / sizeof(mxc_emac_dma_desc_t));
317
318 emac->tx_ring = (mxc_emac_reva_dma_desc_t *)(config->tx_ring_buff);
319 emac->tx_ring_dma = (unsigned int)(config->tx_ring_buff);
320 emac->tx_ring_size = (config->tx_ring_buff_size / sizeof(mxc_emac_dma_desc_t));
321
322 emac->phy_addr = config->phy_addr;
323 emac->delay_us = config->delay_us;
324
325 if (config->interrupt_mode) {
326 memcpy((void *)&emac->cb_funcs, (const void *)&config->conf_cb_funcs,
327 sizeof(mxc_emac_cb_funcs_tbl_t));
328 MXC_EMAC_RevA_EnableInterruptEvents(config->interrupt_events);
329 } else {
330 memset((void *)&emac->cb_funcs, 0, sizeof(mxc_emac_cb_funcs_tbl_t));
331 MXC_EMAC_RevA_DisableInterruptEvents(0xFFFFFFFF);
332 }
333
334 return E_NO_ERROR;
335 }
336
MXC_EMAC_RevA_SetHwAddr(unsigned char * enetaddr)337 int MXC_EMAC_RevA_SetHwAddr(unsigned char *enetaddr)
338 {
339 uint16_t hwaddr_top;
340 unsigned int hwaddr_bottom;
341
342 if (!enetaddr) {
343 return E_NULL_PTR;
344 }
345
346 /* Set Hardware Address */
347 hwaddr_bottom =
348 ((enetaddr[0]) | (enetaddr[1] << 8) | (enetaddr[2] << 16) | (enetaddr[3] << 24));
349 EMAC_WRITEL(emac, sa1l, hwaddr_bottom);
350
351 hwaddr_top = (enetaddr[4] | (enetaddr[5] << 8));
352 EMAC_WRITEL(emac, sa1h, hwaddr_top);
353
354 return E_NO_ERROR;
355 }
356
MXC_EMAC_RevA_EnableInterruptEvents(unsigned int events)357 int MXC_EMAC_RevA_EnableInterruptEvents(unsigned int events)
358 {
359 unsigned int ier, imr;
360
361 if (!emac->first_init) {
362 return E_UNINITIALIZED;
363 }
364
365 /* First Read from Interrupt Mask Register */
366 imr = EMAC_READL(emac, int_mask);
367
368 /* IER is Write-Only */
369 ier = ~imr | events;
370 EMAC_WRITEL(emac, int_en, ier);
371
372 return E_NO_ERROR;
373 }
374
MXC_EMAC_RevA_DisableInterruptEvents(unsigned int events)375 int MXC_EMAC_RevA_DisableInterruptEvents(unsigned int events)
376 {
377 unsigned int idr, imr;
378
379 if (!emac->first_init) {
380 return E_UNINITIALIZED;
381 }
382
383 /* First Read from Interrupt Mask Register */
384 imr = EMAC_READL(emac, int_mask);
385
386 /* IDR is Write-Only */
387 idr = imr | events;
388 EMAC_WRITEL(emac, int_dis, idr);
389
390 return E_NO_ERROR;
391 }
392
393 /* ************************************************************************* */
394 /* Low-Level Functions */
395 /* ************************************************************************* */
MXC_EMAC_RevA_Start(void)396 int MXC_EMAC_RevA_Start(void)
397 {
398 int result = E_UNKNOWN;
399 unsigned int i;
400 unsigned int paddr;
401 unsigned int ncr;
402
403 if (!emac->first_init) {
404 return E_UNINITIALIZED;
405 }
406
407 /* DMA Descriptors */
408 paddr = emac->rx_buffer_dma;
409
410 for (i = 0; i < emac->rx_ring_size; i++) {
411 if ((emac->rx_ring_size - 1) == i) {
412 paddr |= RXADDR_WRAP;
413 }
414
415 emac->rx_ring[i].addr = paddr;
416 emac->rx_ring[i].ctrl = 0;
417
418 paddr += EMAC_RX_BUFFER_SIZE;
419 }
420
421 for (i = 0; i < emac->tx_ring_size; i++) {
422 emac->tx_ring[i].addr = 0;
423
424 if ((emac->tx_ring_size - 1) == i) {
425 emac->tx_ring[i].ctrl = TXBUF_USED | TXBUF_WRAP;
426 } else {
427 emac->tx_ring[i].ctrl = TXBUF_USED;
428 }
429 }
430
431 emac->tx_tail = 0;
432 emac->tx_head = 0;
433 emac->rx_tail = 0;
434
435 EMAC_WRITEL(emac, rxbuf_ptr, emac->rx_ring_dma);
436 EMAC_WRITEL(emac, txbuf_ptr, emac->tx_ring_dma);
437
438 #ifdef CONFIG_EMAC_MII_MODE
439 EMAC_WRITEL(emac, usrio, EMAC_BIT(USRIO, MII));
440 #endif
441
442 result = emac_phy_init();
443
444 if (E_NO_ERROR == result) {
445 /* For Diagnostic */
446 #ifdef CONFIG_EMAC_LOCAL_LOOPBACK_MODE
447 ncr = EMAC_READL(emac, cn);
448
449 ncr &= ~EMAC_BIT(CN, LB);
450 ncr |= EMAC_BIT(CN, LBL);
451
452 EMAC_WRITEL(emac, cn, ncr);
453 #endif
454 /* Enable TX and RX */
455 ncr = EMAC_READL(emac, cn);
456 ncr |= EMAC_BIT(CN, TXEN);
457 ncr |= EMAC_BIT(CN, TXSTART);
458 EMAC_WRITEL(emac, cn, ncr);
459
460 ncr = EMAC_READL(emac, cn);
461 ncr |= EMAC_BIT(CN, RXEN);
462 EMAC_WRITEL(emac, cn, ncr);
463 }
464
465 return result;
466 }
467
MXC_EMAC_RevA_Stop(void)468 int MXC_EMAC_RevA_Stop(void)
469 {
470 unsigned int ncr;
471 unsigned int tsr;
472
473 /* Halt the Controller and Wait for Any Ongoing Transmission to End */
474 ncr = EMAC_READL(emac, cn);
475 ncr |= EMAC_BIT(CN, TXHALT);
476 EMAC_WRITEL(emac, cn, ncr);
477
478 do {
479 tsr = EMAC_READL(emac, tx_st);
480 } while (tsr & EMAC_BIT(TX_ST, TXGO));
481
482 /* Clear Statistics */
483 EMAC_WRITEL(emac, cn, EMAC_BIT(CN, CLST));
484
485 return E_NO_ERROR;
486 }
487
MXC_EMAC_RevA_ReadLinkStatus(void)488 int MXC_EMAC_RevA_ReadLinkStatus(void)
489 {
490 int result = E_UNKNOWN;
491 uint16_t status;
492
493 status = emac_mdio_read(MII_BMSR);
494
495 if (status & BMSR_LSTATUS) {
496 result = E_NO_ERROR;
497 } else {
498 result = E_NO_DEVICE; //PHY Link Down
499 }
500
501 return result;
502 }
503
504 /* ************************************************************************* */
505 /* Transaction-Level Functions */
506 /* ************************************************************************* */
MXC_EMAC_RevA_SendSync(const void * packet,unsigned int length)507 int MXC_EMAC_RevA_SendSync(const void *packet, unsigned int length)
508 {
509 int i;
510 unsigned int paddr;
511 unsigned int ctrl;
512 unsigned int tx_head;
513 unsigned int ncr;
514
515 if (!packet) {
516 return E_NULL_PTR;
517 }
518
519 if (!emac->delay_us) {
520 return E_UNINITIALIZED;
521 }
522
523 tx_head = emac->tx_head;
524 paddr = (unsigned int)packet;
525
526 ctrl = length & TXBUF_FRMLEN_MASK;
527 ctrl |= TXBUF_FRAME_END;
528
529 if (tx_head == (emac->tx_ring_size - 1)) {
530 ctrl |= TXBUF_WRAP;
531 emac->tx_head = 0;
532 } else {
533 emac->tx_head++;
534 }
535
536 emac->tx_ring[tx_head].ctrl = ctrl;
537 emac->tx_ring[tx_head].addr = paddr;
538 barrier();
539
540 ncr = EMAC_READL(emac, cn);
541 ncr |= EMAC_BIT(CN, TXEN);
542 ncr |= EMAC_BIT(CN, TXSTART);
543 ncr |= EMAC_BIT(CN, RXEN);
544 EMAC_WRITEL(emac, cn, ncr);
545
546 for (i = 0; i <= CONFIG_SYS_EMAC_TX_TIMEOUT; i++) {
547 barrier();
548
549 ctrl = emac->tx_ring[tx_head].ctrl;
550
551 if (ctrl & TXBUF_USED) {
552 break;
553 }
554
555 emac->delay_us(1);
556 }
557
558 if (i <= CONFIG_SYS_EMAC_TX_TIMEOUT) {
559 if (ctrl & TXBUF_UNDERRUN) {
560 return E_UNDERFLOW;
561 }
562
563 if (ctrl & TXBUF_EXHAUSTED) {
564 return E_OVERFLOW;
565 }
566 } else {
567 return E_TIME_OUT;
568 }
569
570 return E_NO_ERROR;
571 }
572
MXC_EMAC_RevA_SendAsync(const void * packet,unsigned int length)573 int MXC_EMAC_RevA_SendAsync(const void *packet, unsigned int length)
574 {
575 unsigned int paddr;
576 unsigned int ctrl;
577 unsigned int tx_head;
578 unsigned int ncr;
579
580 if (!packet) {
581 return E_NULL_PTR;
582 }
583
584 tx_head = emac->tx_head;
585 paddr = (unsigned int)packet;
586
587 ctrl = length & TXBUF_FRMLEN_MASK;
588 ctrl |= TXBUF_FRAME_END;
589
590 if (tx_head == (emac->tx_ring_size - 1)) {
591 ctrl |= TXBUF_WRAP;
592 emac->tx_head = 0;
593 } else {
594 emac->tx_head++;
595 }
596
597 emac->tx_ring[tx_head].ctrl = ctrl;
598 emac->tx_ring[tx_head].addr = paddr;
599 barrier();
600
601 ncr = EMAC_READL(emac, cn);
602 ncr |= EMAC_BIT(CN, TXEN);
603 ncr |= EMAC_BIT(CN, TXSTART);
604 ncr |= EMAC_BIT(CN, RXEN);
605 EMAC_WRITEL(emac, cn, ncr);
606
607 barrier();
608
609 return E_NO_ERROR;
610 }
611
MXC_EMAC_RevA_Recv(void * rx_buff,unsigned int max_len)612 int MXC_EMAC_RevA_Recv(void *rx_buff, unsigned int max_len)
613 {
614 int result = E_UNKNOWN;
615 int wrapped = 0;
616 unsigned int length;
617 unsigned int status;
618 unsigned int rx_tail;
619 unsigned int headlen;
620 unsigned int taillen;
621 unsigned char packet_received = 0;
622 unsigned char *tail_buff_ptr;
623 void *buffer;
624
625 if (!emac->first_init) {
626 return E_UNINITIALIZED;
627 }
628
629 if (!rx_buff) {
630 return E_NULL_PTR;
631 }
632
633 rx_tail = emac->rx_tail;
634
635 while (1) {
636 if (!(emac->rx_ring[rx_tail].addr & RXADDR_USED)) {
637 /* No RX Frame */
638 return 0;
639 }
640
641 status = emac->rx_ring[rx_tail].ctrl;
642
643 if (status & RXBUF_FRAME_START) {
644 if (rx_tail != emac->rx_tail) {
645 emac_reclaim_rx_buffers(rx_tail);
646 }
647
648 wrapped = 0;
649 }
650
651 if (status & RXBUF_FRAME_END) {
652 packet_received = 1;
653
654 buffer = emac->rx_buffer + (EMAC_RX_BUFFER_SIZE * emac->rx_tail);
655 length = status & RXBUF_FRMLEN_MASK;
656
657 if (wrapped) {
658 headlen = EMAC_RX_BUFFER_SIZE * (emac->rx_ring_size - emac->rx_tail);
659 taillen = length - headlen;
660 tail_buff_ptr = (unsigned char *)rx_buff + headlen;
661
662 if ((headlen + taillen) <= max_len) {
663 memcpy(rx_buff, (const void *)buffer, headlen);
664 memcpy((void *)tail_buff_ptr, (const void *)emac->rx_buffer, taillen);
665 result = headlen + taillen;
666 } else {
667 result = E_NONE_AVAIL; //RX User Buffer Full
668 }
669 } else if (length <= max_len) {
670 memcpy(rx_buff, (const void *)buffer, length);
671 result = length;
672 } else {
673 result = E_NONE_AVAIL; //RX User Buffer Full
674 }
675
676 if (++rx_tail >= emac->rx_ring_size) {
677 rx_tail = 0;
678 }
679
680 emac_reclaim_rx_buffers(rx_tail);
681 } else {
682 if (++rx_tail >= emac->rx_ring_size) {
683 wrapped = 1;
684 rx_tail = 0;
685 }
686 }
687
688 barrier();
689
690 if (packet_received) {
691 return result;
692 }
693 }
694
695 return result;
696 }
697
MXC_EMAC_RevA_IrqHandler(void)698 void MXC_EMAC_RevA_IrqHandler(void)
699 {
700 unsigned int isr = 0;
701
702 isr = EMAC_READL(emac, int_st);
703
704 if ((isr & MXC_EMAC_REVA_EVENT_MPS) && emac->cb_funcs.mps_handler) {
705 emac->cb_funcs.mps_handler();
706 }
707
708 if ((isr & MXC_EMAC_REVA_EVENT_RXCMPL) && emac->cb_funcs.rxcmpl_handler) {
709 emac->cb_funcs.rxcmpl_handler();
710 }
711
712 if ((isr & MXC_EMAC_REVA_EVENT_RXUBR) && emac->cb_funcs.rxubr_handler) {
713 emac->cb_funcs.rxubr_handler();
714 }
715
716 if ((isr & MXC_EMAC_REVA_EVENT_TXUBR) && emac->cb_funcs.txubr_handler) {
717 emac->cb_funcs.txubr_handler();
718 }
719
720 if ((isr & MXC_EMAC_REVA_EVENT_TXUR) && emac->cb_funcs.txur_handler) {
721 emac->cb_funcs.txur_handler();
722 }
723
724 if ((isr & MXC_EMAC_REVA_EVENT_RLE) && emac->cb_funcs.rle_handler) {
725 emac->cb_funcs.rle_handler();
726 }
727
728 if ((isr & MXC_EMAC_REVA_EVENT_TXERR) && emac->cb_funcs.txerr_handler) {
729 emac->cb_funcs.txerr_handler();
730 }
731
732 if ((isr & MXC_EMAC_REVA_EVENT_TXCMPL) && emac->cb_funcs.txcmpl_handler) {
733 emac->cb_funcs.txcmpl_handler();
734 }
735
736 if ((isr & MXC_EMAC_REVA_EVENT_LC) && emac->cb_funcs.lc_handler) {
737 emac->cb_funcs.lc_handler();
738 }
739
740 if ((isr & MXC_EMAC_REVA_EVENT_RXOR) && emac->cb_funcs.rxor_handler) {
741 emac->cb_funcs.rxor_handler();
742 }
743
744 if ((isr & MXC_EMAC_REVA_EVENT_HRESPNO) && emac->cb_funcs.hrespno_handler) {
745 emac->cb_funcs.hrespno_handler();
746 }
747
748 if ((isr & MXC_EMAC_REVA_EVENT_PPR) && emac->cb_funcs.ppr_handler) {
749 emac->cb_funcs.ppr_handler();
750 }
751
752 if ((isr & MXC_EMAC_REVA_EVENT_PTZ) && emac->cb_funcs.ptz_handler) {
753 emac->cb_funcs.ptz_handler();
754 }
755 }
756