source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/targets/TARGET_RENESAS/TARGET_RZ_A1H/ethernet_api.c@ 352

Last change on this file since 352 was 352, checked in by coas-nagasima, 6 years ago

arm向けASP3版ECNLを追加

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