]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/ethernet_api.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / hal / TARGET_RENESAS / TARGET_RZ_A1H / ethernet_api.c
1 /* mbed Microcontroller Library
2  * Copyright (c) 2006-2013 ARM Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <string.h>
17 #include "ethernet_api.h"
18 #include "cmsis.h"
19 #include "mbed_interface.h"
20 #include "toolchain.h"
21 #include "mbed_error.h"
22 #include "ether_iodefine.h"
23 #include "ethernetext_api.h"
24
25 /* Descriptor info */
26 #define NUM_OF_TX_DESCRIPTOR    (16)
27 #define NUM_OF_RX_DESCRIPTOR    (16)
28 #define SIZE_OF_BUFFER          (1600)     /* Must be an integral multiple of 32 */
29 #define MAX_SEND_SIZE           (1514)
30 /* Ethernet Descriptor Value Define */
31 #define TD0_TFP_TOP_BOTTOM      (0x30000000)
32 #define TD0_TACT                (0x80000000)
33 #define TD0_TDLE                (0x40000000)
34 #define RD0_RACT                (0x80000000)
35 #define RD0_RDLE                (0x40000000)
36 #define RD0_RFE                 (0x08000000)
37 #define RD0_RCSE                (0x04000000)
38 #define RD0_RFS                 (0x03FF0000)
39 #define RD0_RCS                 (0x0000FFFF)
40 #define RD0_RFS_RFOF            (0x02000000)
41 #define RD0_RFS_RUAF            (0x00400000)
42 #define RD0_RFS_RRF             (0x00100000)
43 #define RD0_RFS_RTLF            (0x00080000)
44 #define RD0_RFS_RTSF            (0x00040000)
45 #define RD0_RFS_PRE             (0x00020000)
46 #define RD0_RFS_CERF            (0x00010000)
47 #define RD0_RFS_ERROR           (RD0_RFS_RFOF | RD0_RFS_RUAF | RD0_RFS_RRF | RD0_RFS_RTLF | \
48                                  RD0_RFS_RTSF | RD0_RFS_PRE | RD0_RFS_CERF)
49 #define RD1_RDL_MSK             (0x0000FFFF)
50 /* PHY Register */
51 #define BASIC_MODE_CONTROL_REG  (0)
52 #define BASIC_MODE_STATUS_REG   (1)
53 #define PHY_IDENTIFIER1_REG     (2)
54 #define PHY_IDENTIFIER2_REG     (3)
55 #define PHY_SP_CTL_STS_REG      (31)
56 /* MII management interface access */
57 #define PHY_ADDR                (0)        /* Confirm the pin connection of the PHY-LSI */
58 #define PHY_ST                  (1)
59 #define PHY_WRITE               (1)
60 #define PHY_READ                (2)
61 #define MDC_WAIT                (6)        /* 400ns/4 */
62 #define BASIC_STS_MSK_LINK      (0x0004)   /* Link Status */
63 #define BASIC_STS_MSK_AUTO_CMP  (0x0010)   /* Auto-Negotiate Complete */
64 #define M_PHY_ID                (0xFFFFFFF0)
65 #define PHY_ID_LAN8710A         (0x0007C0F0)
66 /* ETHERPIR0 */
67 #define PIR0_MDI                (0x00000008)
68 #define PIR0_MDO                (0x00000004)
69 #define PIR0_MMD                (0x00000002)
70 #define PIR0_MDC                (0x00000001)
71 #define PIR0_MDC_HIGH           (0x00000001)
72 #define PIR0_MDC_LOW            (0x00000000)
73 /* ETHEREDRRR0 */
74 #define EDRRR0_RR               (0x00000001)
75 /* ETHEREDTRR0 */
76 #define EDTRR0_TR               (0x00000003)
77 /* software wait */
78 #define LOOP_100us              (6700)     /* Loop counter for software wait  6666=100us/((1/400MHz)*6cyc) */
79
80 #define EDMAC_EESIPR_INI_RECV   (0x0205001F)    /* 0x02000000 : Detect reception suspended */
81                                                 /* 0x00040000 : Detect frame reception */
82                                                 /* 0x00010000 : Receive FIFO overflow */
83                                                 /* 0x00000010 : Residual bit frame reception */
84                                                 /* 0x00000008 : Long frame reception */
85                                                 /* 0x00000004 : Short frame reception */
86                                                 /* 0x00000002 : PHY-LSI reception error */
87                                                 /* 0x00000001 : Receive frame CRC error */
88 #define EDMAC_EESIPR_INI_EtherC (0x00400000)    /* 0x00400000 : E-MAC status register */
89
90 /* Send descriptor */
91 typedef struct tag_edmac_send_desc {
92     uint32_t    td0;
93     uint32_t    td1;
94     uint8_t     *td2;
95     uint32_t    padding4;
96 } edmac_send_desc_t;
97
98 /* Receive descriptor */
99 typedef struct tag_edmac_recv_desc {
100     uint32_t    rd0;
101     uint32_t    rd1;
102     uint8_t     *rd2;
103     uint32_t    padding4;
104 } edmac_recv_desc_t;
105
106 /* memory */
107 /* The whole transmit/receive descriptors (must be allocated in 16-byte boundaries) */
108 /* Transmit/receive buffers (must be allocated in 16-byte boundaries) */
109 static uint8_t ehernet_nc_memory[(sizeof(edmac_send_desc_t) * NUM_OF_TX_DESCRIPTOR) +
110                                  (sizeof(edmac_recv_desc_t) * NUM_OF_RX_DESCRIPTOR) +
111                                  (NUM_OF_TX_DESCRIPTOR * SIZE_OF_BUFFER) +
112                                  (NUM_OF_RX_DESCRIPTOR * SIZE_OF_BUFFER)]
113                                  __attribute((section("NC_BSS"),aligned(16)));  //16 bytes aligned!
114 static int32_t            rx_read_offset;   /* read offset */
115 static int32_t            tx_wite_offset;   /* write offset */
116 static uint32_t           send_top_index;
117 static uint32_t           recv_top_index;
118 static int32_t            Interrupt_priority;
119 static edmac_send_desc_t  *p_eth_desc_dsend = NULL;
120 static edmac_recv_desc_t  *p_eth_desc_drecv = NULL;
121 static edmac_recv_desc_t  *p_recv_end_desc  = NULL;
122 static ethernetext_cb_fnc *p_recv_cb_fnc    = NULL;
123 static char               mac_addr[6]       = {0x00, 0x02, 0xF7, 0xF0, 0x00, 0x00}; /* MAC Address */
124 static uint32_t           phy_id            = 0;
125 static uint32_t           start_stop        = 1;  /* 0:stop  1:start */
126
127 /* function */
128 static void lan_reg_reset(void);
129 static void lan_desc_create(void);
130 static void lan_reg_set(int32_t link);
131 static uint16_t phy_reg_read(uint16_t reg_addr);
132 static void phy_reg_write(uint16_t reg_addr, uint16_t data);
133 static void mii_preamble(void);
134 static void mii_cmd(uint16_t reg_addr, uint32_t option);
135 static void mii_reg_read(uint16_t *data);
136 static void mii_reg_write(uint16_t data);
137 static void mii_z(void);
138 static void mii_write_1(void);
139 static void mii_write_0(void);
140 static void set_ether_pir(uint32_t set_data);
141 static void wait_100us(int32_t wait_cnt);
142
143
144 int ethernetext_init(ethernet_cfg_t *p_ethcfg) {
145     int32_t  i;
146     uint16_t val;
147
148     CPGSTBCR7 &= ~(CPG_STBCR7_BIT_MSTP74);  /* enable ETHER clock */
149
150     /* P4_2(PHY Reset) */
151     GPIOP4      &= ~0x0004;         /* Outputs low level */
152     GPIOPMC4    &= ~0x0004;         /* Port mode */
153     GPIOPM4     &= ~0x0004;         /* Output mode */
154
155     /* GPIO P1  P1_14(ET_COL) */
156     GPIOPMC1    |=  0x4000;
157     GPIOPFCAE1  &= ~0x4000;
158     GPIOPFCE1   |=  0x4000;
159     GPIOPFC1    |=  0x4000;
160
161     /* P3_0(ET_TXCLK), P3_3(ET_MDIO), P3_4(ET_RXCLK), P3_5(ET_RXER), P3_6(ET_RXDV) */
162     GPIOPMC3    |=  0x0079;
163     GPIOPFCAE3  &= ~0x0079;
164     GPIOPFCE3   &= ~0x0079;
165     GPIOPFC3    |=  0x0079;
166     GPIOPIPC3   |=  0x0079;
167
168     /* P5_9(ET_MDC) */
169     GPIOPMC5    |=  0x0200;
170     GPIOPFCAE5  &= ~0x0200;
171     GPIOPFCE5   &= ~0x0200;
172     GPIOPFC5    |=  0x0200;
173     GPIOPIPC5   |=  0x0200;
174
175     /* P10_1(ET_TXER), P10_2(ET_TXEN), P10_3(ET_CRS), P10_4(ET_TXD0), P10_5(ET_TXD1) */
176     /* P10_6(ET_TXD2), P10_7(ET_TXD3), P10_8(ET_RXD0), P10_9(ET_RXD1), P10_10(ET_RXD2), P10_11(ET_RXD3) */
177     GPIOPMC10   |=  0x0FFE;
178     GPIOPFCAE10 &= ~0x0FFE;
179     GPIOPFCE10  |=  0x0FFE;
180     GPIOPFC10   |=  0x0FFE;
181     GPIOPIPC10  |=  0x0FFE;
182
183     /* Resets the E-MAC,E-DMAC */
184     lan_reg_reset();
185
186     /* PHY Reset */
187     GPIOP4      &= ~0x0004;         /* P4_2 Outputs low level */
188     wait_100us(250);                /* 25msec */
189     GPIOP4      |=  0x0004;         /* P4_2 Outputs high level */
190     wait_100us(100);                /* 10msec */
191
192     /* Resets the PHY-LSI */
193     phy_reg_write(BASIC_MODE_CONTROL_REG, 0x8000);
194     for (i = 10000; i > 0; i--) {
195         val = phy_reg_read(BASIC_MODE_CONTROL_REG);
196         if (((uint32_t)val & 0x8000uL) == 0) {
197             break;                  /* Reset complete */
198         }
199     }
200
201     phy_id = ((uint32_t)phy_reg_read(PHY_IDENTIFIER1_REG) << 16)
202            |  (uint32_t)phy_reg_read(PHY_IDENTIFIER2_REG);
203
204     Interrupt_priority = p_ethcfg->int_priority;
205     p_recv_cb_fnc      = p_ethcfg->recv_cb;
206     start_stop         = 1;
207
208     if (p_ethcfg->ether_mac != NULL) {
209         (void)memcpy(mac_addr, p_ethcfg->ether_mac, sizeof(mac_addr));
210     } else {
211                 ethernet_address(mac_addr); /* Get MAC Address */
212     }
213
214     return 0;
215 }
216
217 void ethernetext_start_stop(int32_t mode) {
218     if (mode == 1) {
219         /* start */
220         ETHEREDTRR0 |= EDTRR0_TR;
221         ETHEREDRRR0 |= EDRRR0_RR;
222         start_stop   = 1;
223     } else {
224         /* stop */
225         ETHEREDTRR0 &= ~EDTRR0_TR;
226         ETHEREDRRR0 &= ~EDRRR0_RR;
227         start_stop   = 0;
228     }
229 }
230
231 int ethernetext_chk_link_mode(void) {
232     int32_t  link;
233     uint16_t data;
234
235     if ((phy_id & M_PHY_ID) == PHY_ID_LAN8710A) {
236         data = phy_reg_read(PHY_SP_CTL_STS_REG);
237         switch (((uint32_t)data >> 2) & 0x00000007) {
238             case 0x0001:
239                 link = HALF_10M;
240                 break;
241             case 0x0005:
242                 link = FULL_10M;
243                 break;
244             case 0x0002:
245                 link = HALF_TX;
246                 break;
247             case 0x0006:
248                 link = FULL_TX;
249                 break;
250             default:
251                 link = NEGO_FAIL;
252                 break;
253         }
254     } else {
255         link = NEGO_FAIL;
256     }
257
258     return link;
259 }
260
261 void ethernetext_set_link_mode(int32_t link) {
262     lan_reg_reset();            /* Resets the E-MAC,E-DMAC */
263     lan_desc_create();          /* Initialize of buffer memory */
264     lan_reg_set(link);          /* E-DMAC, E-MAC initialization */
265 }
266
267 int ethernet_init() {
268     ethernet_cfg_t ethcfg;
269
270     ethcfg.int_priority = 5;
271     ethcfg.recv_cb      = NULL;
272     ethcfg.ether_mac    = NULL;
273     ethernetext_init(&ethcfg);
274     ethernet_set_link(-1, 0);   /* Auto-Negotiation */
275
276     return 0;
277 }
278
279 void ethernet_free() {
280     ETHERARSTR |= 0x00000001;            /* ETHER software reset */
281     CPGSTBCR7  |= CPG_STBCR7_BIT_MSTP74; /* disable ETHER clock */
282 }
283
284 int ethernet_write(const char *data, int slen) {
285     edmac_send_desc_t *p_send_desc;
286     int32_t           copy_size;
287
288     if ((p_eth_desc_dsend == NULL) || (data == NULL) || (slen < 0)
289      || (tx_wite_offset < 0) || (tx_wite_offset >= MAX_SEND_SIZE)) {
290         copy_size = 0;
291     } else {
292         p_send_desc = &p_eth_desc_dsend[send_top_index];   /* Current descriptor */
293         if ((p_send_desc->td0 & TD0_TACT) != 0) {
294             copy_size = 0;
295         } else {
296             copy_size = MAX_SEND_SIZE - tx_wite_offset;
297             if (copy_size > slen) {
298                 copy_size = slen;
299             }
300             (void)memcpy(&p_send_desc->td2[tx_wite_offset], data, copy_size);
301             tx_wite_offset += copy_size;
302         }
303     }
304
305     return copy_size;
306 }
307
308 int ethernet_send() {
309     edmac_send_desc_t *p_send_desc;
310     int32_t           ret;
311
312     if ((p_eth_desc_dsend == NULL) || (tx_wite_offset <= 0)) {
313         ret = 0;
314     } else {
315         /* Transfer 1 frame */
316         p_send_desc = &p_eth_desc_dsend[send_top_index];   /* Current descriptor */
317
318         /* Sets the frame length */
319         p_send_desc->td1 = ((uint32_t)tx_wite_offset << 16);
320         tx_wite_offset   = 0;
321
322         /* Sets the transmit descriptor to transmit again */
323         p_send_desc->td0 &= (TD0_TACT | TD0_TDLE | TD0_TFP_TOP_BOTTOM);
324         p_send_desc->td0 |= TD0_TACT;
325         if ((start_stop == 1) && ((ETHEREDTRR0 & EDTRR0_TR) != EDTRR0_TR)) {
326             ETHEREDTRR0 |= EDTRR0_TR;
327         }
328
329         /* Update the current descriptor */
330         send_top_index++;
331         if (send_top_index >= NUM_OF_TX_DESCRIPTOR) {
332             send_top_index = 0;
333         }
334         ret = 1;
335     }
336
337     return ret;
338 }
339
340 int ethernet_receive() {
341     edmac_recv_desc_t *p_recv_desc;
342     int32_t           receive_size = 0;
343
344     if (p_eth_desc_drecv != NULL) {
345         if (p_recv_end_desc != NULL) {
346             /* Sets the receive descriptor to receive again */
347             p_recv_end_desc->rd0 &= (RD0_RACT | RD0_RDLE);
348             p_recv_end_desc->rd0 |= RD0_RACT;
349             if ((start_stop == 1) && ((ETHEREDRRR0 & EDRRR0_RR) == 0)) {
350                 ETHEREDRRR0 |= EDRRR0_RR;
351             }
352             p_recv_end_desc = NULL;
353         }
354
355         p_recv_desc = &p_eth_desc_drecv[recv_top_index];   /* Current descriptor */
356         if ((p_recv_desc->rd0 & RD0_RACT) == 0) {
357             /* Receives 1 frame */
358             if (((p_recv_desc->rd0 & RD0_RFE) != 0) && ((p_recv_desc->rd0 & RD0_RFS_ERROR) != 0)) {
359                 /* Receive frame error */
360                 /* Sets the receive descriptor to receive again */
361                 p_recv_desc->rd0 &= (RD0_RACT | RD0_RDLE);
362                 p_recv_desc->rd0 |= RD0_RACT;
363                 if ((start_stop == 1) && ((ETHEREDRRR0 & EDRRR0_RR) == 0)) {
364                     ETHEREDRRR0 |= EDRRR0_RR;
365                 }
366             } else {
367                 /* Copies the received frame */
368                 rx_read_offset  = 0;
369                 p_recv_end_desc = p_recv_desc;
370                 receive_size    = (p_recv_desc->rd1 & RD1_RDL_MSK);    /* number of bytes received */
371             }
372
373             /* Update the current descriptor */
374             recv_top_index++;
375             if (recv_top_index >= NUM_OF_TX_DESCRIPTOR) {
376                 recv_top_index = 0;
377             }
378         }
379     }
380
381     return receive_size;
382 }
383
384 int ethernet_read(char *data, int dlen) {
385     edmac_recv_desc_t *p_recv_desc = p_recv_end_desc;                   /* Read top descriptor */
386     int32_t           copy_size;
387
388     if ((data == NULL) || (dlen < 0) || (p_recv_desc == NULL)) {
389         copy_size = 0;
390     } else {
391         copy_size = (p_recv_desc->rd1 & RD1_RDL_MSK) - rx_read_offset;
392         if (copy_size > dlen) {
393             copy_size = dlen;
394         }
395         (void)memcpy(data, &p_recv_desc->rd2[rx_read_offset], (size_t)copy_size);
396         rx_read_offset += copy_size;
397     }
398
399     return copy_size;
400 }
401
402 void ethernet_address(char *mac) {
403     if (mac != NULL) {
404                 mbed_mac_address(mac); /* Get MAC Address */
405     }
406 }
407
408 int ethernet_link(void) {
409     int32_t  ret;
410     uint16_t data;
411
412     data = phy_reg_read(BASIC_MODE_STATUS_REG);
413     if (((uint32_t)data & BASIC_STS_MSK_LINK) != 0) {
414         ret = 1;
415     } else {
416         ret = 0;
417     }
418
419     return ret;
420 }
421
422 void ethernet_set_link(int speed, int duplex) {
423     uint16_t data;
424     int32_t  i;
425     int32_t  link;
426
427     if ((speed < 0) || (speed > 1)) {
428         data = 0x1000;      /* Auto-Negotiation Enable */
429         phy_reg_write(BASIC_MODE_CONTROL_REG, data);
430         data = phy_reg_read(BASIC_MODE_STATUS_REG);
431         for (i = 0; i < 1000; i++) {
432             if (((uint32_t)data & BASIC_STS_MSK_AUTO_CMP) != 0) {
433                 break;
434             }
435             wait_100us(10);
436         }
437     } else {
438         data = (uint16_t)(((uint32_t)speed << 13) | ((uint32_t)duplex << 8));
439         phy_reg_write(BASIC_MODE_CONTROL_REG, data);
440         wait_100us(1);
441     }
442
443     link = ethernetext_chk_link_mode();
444     ethernetext_set_link_mode(link);
445 }
446
447 void INT_Ether(void) {
448     uint32_t stat_edmac;
449     uint32_t stat_etherc;
450
451     /* Clear the interrupt request flag */
452     stat_edmac = (ETHEREESR0 & ETHEREESIPR0);       /* Targets are restricted to allowed interrupts */
453     ETHEREESR0 = stat_edmac;
454     /* Reception-related */
455     if (stat_edmac & EDMAC_EESIPR_INI_RECV) {
456         if (p_recv_cb_fnc != NULL) {
457             p_recv_cb_fnc();
458         }
459     }
460     /* E-MAC-related */
461     if (stat_edmac & EDMAC_EESIPR_INI_EtherC) {
462         /* Clear the interrupt request flag */
463         stat_etherc = (ETHERECSR0 & ETHERECSIPR0);  /* Targets are restricted to allowed interrupts */
464         ETHERECSR0  = stat_etherc;
465     }
466 }
467
468 static void lan_reg_reset(void) {
469     volatile int32_t j = 400;    /* Wait for B dia 256 cycles  ((I dia/B dia)*256)/6cyc = 8*256/6 = 342 */
470
471     ETHERARSTR      |= 0x00000001;      /* ETHER software reset */
472     while (j--) {
473         /* Do Nothing */
474     }
475
476     ETHEREDSR0      |= 0x00000003;      /* E-DMAC software reset */
477     ETHEREDMR0      |= 0x00000003;      /* Set SWRR and SWRT simultaneously */
478
479     /* Check clear software reset */
480     while ((ETHEREDMR0 & 0x00000003) != 0) {
481         /* Do Nothing */
482     }
483 }
484
485 static void lan_desc_create(void) {
486     int32_t i;
487     uint8_t *p_memory_top;
488
489     (void)memset((void *)ehernet_nc_memory, 0, sizeof(ehernet_nc_memory));
490     p_memory_top = ehernet_nc_memory;
491
492     /* Descriptor area configuration */
493     p_eth_desc_dsend  = (edmac_send_desc_t *)p_memory_top;
494     p_memory_top     += (sizeof(edmac_send_desc_t) * NUM_OF_TX_DESCRIPTOR);
495     p_eth_desc_drecv  = (edmac_recv_desc_t *)p_memory_top;
496     p_memory_top     += (sizeof(edmac_recv_desc_t) * NUM_OF_RX_DESCRIPTOR);
497
498     /* Transmit descriptor */
499     for (i = 0; i < NUM_OF_TX_DESCRIPTOR; i++) {
500         p_eth_desc_dsend[i].td2  = p_memory_top;                     /* TD2 TBA */
501         p_memory_top            += SIZE_OF_BUFFER;
502         p_eth_desc_dsend[i].td1  = 0;                                /* TD1 TDL */
503         p_eth_desc_dsend[i].td0  = TD0_TFP_TOP_BOTTOM;               /* TD0:1frame/1buf1buf, transmission disabled */
504     }
505     p_eth_desc_dsend[i - 1].td0 |= TD0_TDLE;                         /* Set the last descriptor */
506
507     /* Receive descriptor */
508     for (i = 0; i < NUM_OF_RX_DESCRIPTOR; i++) {
509         p_eth_desc_drecv[i].rd2  = p_memory_top;                     /* RD2 RBA */
510         p_memory_top            += SIZE_OF_BUFFER;
511         p_eth_desc_drecv[i].rd1  = ((uint32_t)SIZE_OF_BUFFER << 16); /* RD1 RBL */
512         p_eth_desc_drecv[i].rd0  = RD0_RACT;                         /* RD0:reception enabled */
513     }
514     p_eth_desc_drecv[i - 1].rd0 |= RD0_RDLE;                         /* Set the last descriptor */
515
516     /* Initialize descriptor management information */
517     send_top_index  = 0;
518     recv_top_index  = 0;
519     rx_read_offset  = 0;
520     tx_wite_offset  = 0;
521     p_recv_end_desc = NULL;
522 }
523
524 static void lan_reg_set(int32_t link) {
525     /* MAC address setting */
526     ETHERMAHR0      = ((uint32_t)mac_addr[0] << 24)
527                     | ((uint32_t)mac_addr[1] << 16)
528                     | ((uint32_t)mac_addr[2] << 8)
529                     |  (uint32_t)mac_addr[3];
530     ETHERMALR0      = ((uint32_t)mac_addr[4] << 8)
531                     |  (uint32_t)mac_addr[5];
532
533     /* E-DMAC */
534     ETHERTDLAR0     = (uint32_t)&p_eth_desc_dsend[0];
535     ETHERRDLAR0     = (uint32_t)&p_eth_desc_drecv[0];
536     ETHERTDFAR0     = (uint32_t)&p_eth_desc_dsend[0];
537     ETHERRDFAR0     = (uint32_t)&p_eth_desc_drecv[0];
538     ETHERTDFXR0     = (uint32_t)&p_eth_desc_dsend[NUM_OF_TX_DESCRIPTOR - 1];
539     ETHERRDFXR0     = (uint32_t)&p_eth_desc_drecv[NUM_OF_RX_DESCRIPTOR - 1];
540     ETHERTDFFR0    |=  0x00000001;      /* TDLF  Transmit Descriptor Queue Last Flag : Last descriptor (1) */
541     ETHERRDFFR0    |=  0x00000001;      /* RDLF  Receive Descriptor Queue Last Flag : Last descriptor (1) */
542     ETHEREDMR0     |=  0x00000040;      /* Little endian */
543     ETHERTRSCER0   &= ~0x0003009F;      /* All clear */
544     ETHERTFTR0     &= ~0x000007FF;      /* TFT[10:0]  Transmit FIFO Threshold : Store and forward modes (H'000) */
545     ETHERFDR0      |=  0x00000707;      /* Transmit FIFO Size:2048 bytes, Receive FIFO Size:2048 bytes */
546     ETHERRMCR0     |=  0x00000001;      /* RNC  Receive Enable Control : Continuous reception enabled (1) */
547     ETHERFCFTR0    &= ~0x001F00FF;
548     ETHERFCFTR0    |=  0x00070007;
549     ETHERRPADIR0   &= ~0x001FFFFF;      /* Padding Size:No padding insertion, Padding Slot:Inserts at first byte */
550
551     /* E-MAC */
552     ETHERECMR0     &= ~0x04BF2063;      /* All clear */
553     ETHERRFLR0     &= ~0x0003FFFF;      /* RFL[17:0]  Receive Frame Length : 1518 bytes (H'00000) */
554     ETHERAPR0      &= ~0x0000FFFF;      /* AP[15:0]   Automatic PAUSE : Flow control is disabled (H'0000) */
555     ETHERMPR0      &= ~0x0000FFFF;      /* MP[15:0]   Manual PAUSE : Flow control is disabled (H'0000) */
556     ETHERTPAUSER0  &= ~0x0000FFFF;      /* Upper Limit for Automatic PAUSE Frame : Retransmit count is unlimited */
557     ETHERCSMR      &= ~0xC000003F;      /* The result of checksum is not written back to the receive descriptor */
558     if ((link == FULL_TX) || (link == FULL_10M) || (link == NEGO_FAIL)) {
559         ETHERECMR0 |= 0x00000002;       /* Set to full-duplex mode */
560     } else {
561         ETHERECMR0 &= ~0x00000002;      /* Set to half-duplex mode */
562     }
563
564     /* Interrupt-related */
565     if (p_recv_cb_fnc != NULL) {
566         ETHEREESR0     |=  0xFF7F009F;                     /* Clear all status (by writing 1) */
567         ETHEREESIPR0   |=  0x00040000;                     /* FR  Frame Reception (1) */
568         ETHERECSR0     |=  0x00000011;                     /* Clear all status (clear by writing 1) */
569         ETHERECSIPR0   &= ~0x00000011;                     /* PFROIP Disable, ICDIP Disable */
570         InterruptHandlerRegister(ETHERI_IRQn, INT_Ether);  /* Ethernet interrupt handler registration */
571         GIC_SetPriority(ETHERI_IRQn, Interrupt_priority);  /* Ethernet interrupt priority */
572         GIC_EnableIRQ(ETHERI_IRQn);                        /* Enables the E-DMAC interrupt */
573     }
574
575     ETHERECMR0     |=  0x00000060;      /* RE Enable, TE Enable */
576
577     /* Enable transmission/reception */
578     if ((start_stop == 1) && ((ETHEREDRRR0 & 0x00000001) == 0)) {
579         ETHEREDRRR0 |= 0x00000001;       /* RR */
580     }
581 }
582
583 static uint16_t phy_reg_read(uint16_t reg_addr) {
584     uint16_t data;
585
586     mii_preamble();
587     mii_cmd(reg_addr, PHY_READ);
588     mii_z();
589     mii_reg_read(&data);
590     mii_z();
591
592     return data;
593 }
594
595 static void phy_reg_write(uint16_t reg_addr, uint16_t data) {
596     mii_preamble();
597     mii_cmd(reg_addr, PHY_WRITE);
598     mii_write_1();
599     mii_write_0();
600     mii_reg_write(data);
601     mii_z();
602 }
603
604 static void mii_preamble(void) {
605     int32_t i = 32;
606
607     for (i = 32; i > 0; i--) {
608         /* 1 is output via the MII (Media Independent Interface) block. */
609         mii_write_1();
610     }
611 }
612
613 static void mii_cmd(uint16_t reg_addr, uint32_t option) {
614     int32_t  i;
615     uint16_t data = 0;
616
617     data |= (PHY_ST << 14);             /* ST code      */
618     data |= (option << 12);             /* OP code      */
619     data |= (PHY_ADDR << 7);            /* PHY Address  */
620     data |= (uint16_t)(reg_addr << 2);  /* Reg Address  */
621     for (i = 14; i > 0; i--) {
622         if ((data & 0x8000) == 0) {
623             mii_write_0();
624         } else {
625             mii_write_1();
626         }
627         data <<= 1;
628     }
629 }
630
631 static void mii_reg_read(uint16_t *data) {
632     int32_t  i;
633     uint16_t reg_data = 0;
634
635     /* Data are read in one bit at a time */
636     for (i = 16; i > 0; i--) {
637         set_ether_pir(PIR0_MDC_LOW);
638         set_ether_pir(PIR0_MDC_HIGH);
639         reg_data <<= 1;
640         reg_data |= (uint16_t)((ETHERPIR0 & PIR0_MDI) >> 3);  /* MDI read */
641         set_ether_pir(PIR0_MDC_HIGH);
642         set_ether_pir(PIR0_MDC_LOW);
643     }
644     *data = reg_data;
645 }
646
647 static void mii_reg_write(uint16_t data) {
648     int32_t i;
649
650     /* Data are written one bit at a time */
651     for (i = 16; i > 0; i--) {
652         if ((data & 0x8000) == 0) {
653             mii_write_0();
654         } else {
655             mii_write_1();
656         }
657         data <<= 1;
658     }
659 }
660
661 static void mii_z(void) {
662     set_ether_pir(PIR0_MDC_LOW);
663     set_ether_pir(PIR0_MDC_HIGH);
664     set_ether_pir(PIR0_MDC_HIGH);
665     set_ether_pir(PIR0_MDC_LOW);
666 }
667
668 static void mii_write_1(void) {
669     set_ether_pir(PIR0_MDO | PIR0_MMD);
670     set_ether_pir(PIR0_MDO | PIR0_MMD | PIR0_MDC);
671     set_ether_pir(PIR0_MDO | PIR0_MMD | PIR0_MDC);
672     set_ether_pir(PIR0_MDO | PIR0_MMD);
673 }
674
675 static void mii_write_0(void) {
676     set_ether_pir(PIR0_MMD);
677     set_ether_pir(PIR0_MMD | PIR0_MDC);
678     set_ether_pir(PIR0_MMD | PIR0_MDC);
679     set_ether_pir(PIR0_MMD);
680 }
681
682 static void set_ether_pir(uint32_t set_data) {
683     int32_t i;
684
685     for (i = MDC_WAIT; i > 0; i--) {
686         ETHERPIR0 = set_data;
687     }
688 }
689
690 static void wait_100us(int32_t wait_cnt) {
691     volatile int32_t j = LOOP_100us * wait_cnt;
692
693     while (--j) {
694         /* Do Nothing */
695     }
696 }