2 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
3 * Copyright (C) 2013-2015 Czech Technical University in Prague
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
20 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
22 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
28 * This file is part of the lwIP TCP/IP stack.
30 * Author: Adam Dunkels <adam@sics.se>
31 * Carlos Jenkins <carlos@jenkins.co.cr>
32 * Rostislav Lisovy <lisovy@gmail.com>
33 * Jan Doležal <pm.jenik@gmail.com>
38 * Copyright (c) 2010 Texas Instruments Incorporated
40 * This file is dervied from the "ethernetif.c" skeleton Ethernet network
41 * interface driver for lwIP.
47 #ifndef FREERTOS_POSIX
50 #include "lwip/init.h"
51 #include "lwip/timers.h" /* for DHCP binding in NO_SYS mode */
52 #include "lwip/sys.h" /* includes - lwip/opt.h, lwip/err.h, arch/sys_arch.h */
53 #include "lwip/tcpip.h" /* includes - lwip/opt.h, lwip/api_msg.h, lwip/netifapi.h, lwip/pbuf.h, lwip/api.h, lwip/sys.h, lwip/timers.h, lwip/netif.h */
54 #include "lwip/stats.h" /* includes - lwip/mem.h, lwip/memp.h, lwip/opt.h */
55 #include "netif/etharp.h" /* includes - lwip/ip.h, lwip/netif.h, lwip/ip_addr.h, lwip/pbuf.h */
57 #include "lwip/snmp.h"
58 #include "lwip/dhcp.h"
59 #include "lwip/autoip.h"
60 #include "netif/ppp_oe.h"
61 /* end - lwIP headers */
64 #include "sys/sys.h" /* includes - sys/phy_dp83848h.h */
70 /* Number of EMAC Instances */
71 #define MAX_EMAC_INSTANCE 1
73 #define DEFAULT_PHY_ADDR 0x1
74 #define FIND_FIRST_PHY_ALIVE 1 /* or use default (phy_address: 1) */
75 #define NUM_OF_PHYs 32
77 /* Size of the Buffer descriptor defined by the EMAC in bytes */
78 #define SIZE_OF_DESC 16
80 /* Channel number used for for RX, TX, unicast, broadcast or damaged frames;
81 * there are different channels for rx and tx operations (i.e. RXCH0 != TXCH0) */
84 /* take in account oversized frames */
85 #define MAX_TRANSFER_UNIT 1500
88 * Be very carefull when setting this value. We have to keep in mind
89 * that pbuf_alloc(..., PBUF_POOL) will usualy return a chain of PBUFs
90 * pointing to the statically preallocated buffers (of the same size).
91 * The problem is that if we ask to allocate 300 bytes whereby the size
92 * of the statically preallocated PBUFs (PBUF_POOL_BUFSIZE) is 256, we
93 * will get a chain containing two PBUFs -- one *reporting* its size to
94 * be 256 bytes, the other one 44 bytes.
95 * Everything seems to be just fine however during RX, after we call
96 * netif->input(pbuf, netif) we have to newly allocate the PBUF(s) and
97 * properly set the apropriate BDs. This will however work only if the
98 * number of the freed BDs is the same as the number of the BDs newly
99 * initialized. One possible situation when this may fail is when multiple
100 * non-256 byte sized PBUFs will move near to each other, i.e. 3 BDs:
101 * 256 B, 44 B, 44 B -- 344 bytes will be freed (3 BDs) but the new call
102 * to pbuf_alloc(...) will return a chain comprising only two PBUFs
104 * This is the implementation limitation. The PBUF_LEN_MAX should therefore
105 * be multiple of PBUF_POOL_BUFSIZE
107 #define PBUF_LEN_MAX (PBUF_POOL_BUFSIZE * 6)
109 /* Maximum number of PBUFs preallocated in the driver
110 * init function to be used for the RX
112 #define MAX_RX_PBUF_ALLOC 10
113 #define MIN_PKT_LEN 60
115 /* Define those to better describe the network interface. */
119 /* Time to wait for autonegotiation in ticks. */
120 #define TICKS_PHY_AUTONEG 4000
123 * TODO -- not implemented
124 * When cable is connected (link status goes up)
125 * autonegotiation and/or dhcp is started.
127 #define PHY_LINK_MONITOR_INT 0
130 /* Statically allocated structure describing interface state -- one per instance */
131 static struct hdkif hdkif_data[MAX_EMAC_INSTANCE];
133 /* The lwIP network interface structure for the HDK Ethernet MAC. */
134 static struct netif hdkNetIF[MAX_EMAC_INSTANCE];
136 /* RPP startup init indicator */
137 static boolean_t initialized = FALSE;
138 static boolean_t postInitialized = FALSE;
140 /***testing functions**********************************************/
141 boolean_t isPostInitialized()
143 return postInitialized;
146 uint32_t rpp_eth_phylinkstat(uint32_t instNum)
148 struct hdkif *hdkif = &hdkif_data[instNum];
149 return PHY_link_status_get(hdkif->mdio_base, hdkif->phy_addr, 1);
152 #define BYTE_BUFF_SIZE 2
153 #define OFFSET_MAC_LETTERS (MAC_BIG_LETTERS ? 'A' : 'a')
154 /* puts string of MAC address assigned to EMAC instance reffered by instNum into *mac */
155 void rpp_eth_get_macAddrStr(uint32_t instNum, uint8_t *macStr)
157 uint8_t index, outindex = 0;
158 char buff[BYTE_BUFF_SIZE];
159 struct hdkif *hdkif = &hdkif_data[instNum];
160 for(index = 0; index < MAC_ADDR_LEN; index++) {
161 if(index)macStr[outindex++] = ':';
162 buff[0] = (hdkif->mac_addr[(MAC_ADDR_LEN - 1) - index] >> 4);
163 buff[1] = (hdkif->mac_addr[(MAC_ADDR_LEN - 1) - index] & 0xf);
164 macStr[outindex++] = (buff[0]<10) ? (buff[0] + '0') : (buff[0] - '\012' + OFFSET_MAC_LETTERS);
165 macStr[outindex++] = (buff[1]<10) ? (buff[1] + '0') : (buff[1] - '\012' + OFFSET_MAC_LETTERS);
167 macStr[outindex] = '\0';
170 /* @param ip will be filled accroding to content of ipstr */
171 err_t rpp_eth_stringToIP(ip_addr_t * ip, uint8_t * ipstr)
173 uint8_t charProccessed, index = 0, dotindex = 0xff, tmp = 0, dots = 0, fldEdit = 0;
175 for(charProccessed = ipstr[index]; (charProccessed >= '0' && charProccessed <= '9') || charProccessed == '.' ; charProccessed = ipstr[++index])
177 if(charProccessed == '.')
179 if(++dotindex == index)
186 ipaddr = (ipaddr << 8) + tmp;
197 tmp = tmp*10 + charProccessed - '0';
200 if(dots != 3 || !fldEdit)
202 /* if unsuccesful, don't modify previous content */
205 ipaddr = (ipaddr << 8) + tmp;
210 /* returns number in range 0-65535 where 0 is error */
211 uint16_t rpp_eth_portStrToInt(uint8_t *string)
215 for(index = 0;string[index] != '\0';index++)
217 if(string[index] < '0' || string[index] > '9')
222 portNO = portNO * 10 + string[index] - '0';
227 struct netif *rpp_eth_get_netif(uint32_t instNum)
229 return &hdkNetIF[instNum];
232 /***** forward declarations **********************************************/
235 * interface initializes
237 err_t rpp_eth_lwip_init(struct netif *netif);
240 * Initializes hw such as PHY, MDIO, EMAC, EMAC control module
242 * @return SUCCESS if initialization successful.\n
243 * FAILURE if initialization not successful.
245 err_t rpp_eth_hw_init(struct hdkif *hdkif);
248 * Initializes hw, after lwIP was initialized and
249 * OS was initialized in case OS is used.
251 err_t rpp_eth_hw_init_postInit(struct netif *netif);
253 /***** utility functions **********************************************/
256 * Function to set the MAC address to the interface
257 * @param inst_num the instance number
259 * @note mac_addr[0] is considered MSB
261 static void hdkif_macaddrset(u32_t inst_num, u8_t *mac_addr)
266 hdkif = &hdkif_data[inst_num];
268 /* set MAC hardware address */
269 for (temp = 0; temp < MAC_ADDR_LEN; temp++) {
270 hdkif->mac_addr[temp] = mac_addr[(MAC_ADDR_LEN - 1) - temp];
274 rpp_eth_get_macAddrStr(inst_num, macStr);
275 rpp_debug_printf("Setting MAC... %s\r\n", macStr);
280 * Function to setup the instance parameters inside the interface
284 static void hdkif_inst_config(struct hdkif *hdkif)
286 if (hdkif->inst_num == 0)
288 hdkif->emac_base = EMAC_BASE_m(0);
289 hdkif->emac_ctrl_base = EMAC_CTRL_BASE_m(0);
290 hdkif->emac_ctrl_ram = EMAC_CTRL_RAM_BASE_m(0);
291 hdkif->mdio_base = MDIO_BASE_m(0);
293 /* Default address of PHY on "MDIO bus"
294 * (depends on PHY hw configuration)
296 hdkif->phy_addr = DEFAULT_PHY_ADDR;
297 hdkif->phy_autoneg = PHY_auto_negotiate;
298 hdkif->phy_autoneg_start = PHY_start_auto_negotiate;
299 hdkif->phy_autoneg_is_done = PHY_is_done_auto_negotiate;
300 hdkif->phy_partnerability = PHY_partner_ability_get;
304 /***** initializing functions **********************************************/
305 int8_t rpp_eth_init()
307 unsigned int instNum;
308 int8_t retVal = SUCCESS;
313 /* Config each EMAC instance */
314 for (instNum = 0; instNum < MAX_EMAC_INSTANCE; instNum++)
316 struct hdkif *hdkif = &hdkif_data[instNum];
318 hdkif->inst_num = instNum;
319 hdkif_inst_config(hdkif);
321 retVal = rpp_eth_hw_init(hdkif);
322 if (retVal != SUCCESS) {
323 rpp_debug_printf("rpp_eth_hw_init: %d", retVal);
332 int8_t rpp_eth_init_postInit(uint32_t instNum, uint8_t *macArray)
334 volatile unsigned int dhcpBindWait = 0x3FFFFFFF;
335 struct ip_addr ip_addr;
336 struct ip_addr net_mask;
337 struct ip_addr gw_addr;
338 int8_t retVal = SUCCESS;
340 struct netif *netif = &hdkNetIF[instNum];
341 struct netif *netif_tmp;
342 u8_t mac_addr[MAC_ADDR_LEN] = RPP_MAC_ADDR;
348 if (macArray == NULL)
349 macArray = mac_addr; /* use default MAC */
351 hdkif_macaddrset(instNum, macArray);
356 /* This can be called only within post OS init */
359 * calls lwip_init() implicitly, starts lwIP task (thread),
360 * when started function given to tcpip_init is executed first
362 tcpip_init(NULL, NULL);
365 #if STATIC_IP_ADDRESS
366 ip_addr.addr = htonl(RPP_IP_ADDR);
367 net_mask.addr = htonl(RPP_NETMASK);
368 gw_addr.addr = htonl(RPP_GW);
376 /* Add new network interface to lwIP list of ifaces
377 * and initialize netif with specific function
379 netif_tmp = netif_add(netif, &ip_addr, &net_mask, &gw_addr,
380 &hdkif_data[instNum], rpp_eth_lwip_init,
383 netif_tmp = netif_add(netif, &ip_addr, &net_mask, &gw_addr,
384 &hdkif_data[instNum], rpp_eth_lwip_init,
387 if (netif_tmp == NULL)
388 return NETIF_ADD_ERR;
390 netif_set_default(netif);
392 hdkif = netif->state;
395 /* Semaphores used to block/unblock RX/TX threads doing the
396 * 'deferred' RX/TX handling -- semgive is callend in RX/TX ISR
398 vSemaphoreCreateBinary(hdkif->goRX);
399 vSemaphoreCreateBinary(hdkif->goTX);
401 xTaskCreate(rpp_eth_recv_raw_thr, "RXHandler", 500, netif, 0, NULL);
402 xTaskCreate(rpp_eth_send_raw_thr, "TXHandler", 500, netif, 0, NULL);
405 /* If we don't use link int change, then it must be done here */
406 #if !PHY_LINK_MONITOR_INT
407 if (rpp_eth_phylinkstat(hdkif->inst_num)) {
408 rpp_debug_printf("cable connected ... setting IP params\r\n");
410 #if STATIC_IP_ADDRESS
413 ret = dhcp_start(netif);
415 rpp_debug_printf("dhcp mem err\r\n");
419 rpp_debug_printf("binding DHCP\r");
420 while ((netif->dhcp->state != DHCP_BOUND) && (dhcpBindWait--))
421 ; /* FIXME: sys_check_timeouts()*/
424 rpp_debug_printf("dhcp binding timeout...\r\n");
425 #else /* FIXME there should be some kind of waiting until IP address is assigned */
430 uint8_t ipString[16]; // FIXME change the functions to use char
431 rpp_eth_getIPDecimalStr(netif->ip_addr, ipString);
432 rpp_debug_printf("Address: %s\n", ipString);
433 rpp_eth_getIPDecimalStr(netif->netmask, ipString);
434 rpp_debug_printf("Netmask: %s\n", ipString);
435 rpp_eth_getIPDecimalStr(netif->gw, ipString);
436 rpp_debug_printf("Gateway: %s\n", ipString);
440 rpp_debug_printf("cable not connected\r\n");
441 retVal = PHY_LINK_DOWN;
444 #else /* !PHY_LINK_MONITOR_INT */
445 /* Link Status change handled in an interrupt -- NOT IMPLEMENTED */
448 * Now when we established environment needed for phy link status
449 * change we can allow it. Set PHY number which is monitored for
450 * link changes in MDIO and enable interrupt
452 HWREG(hdkif->mdio_base + MDIO_USERPHYSEL0) =
453 ((hdkif->phy_addr && 0x1f) | MDIO_USERPHYSEL0_LINKINTENB);
455 /* Enable MISC interrupt - link monitoring in EMAC control module */
456 HWREG(hdkif->emac_ctrl_base + EMAC_CTRL_CnMISCEN(0)) |=
457 EMAC_CTRL_MISC_LINKINT0ENB;
459 #endif /* !PHY_LINK_MONITOR_INT */
461 postInitialized = TRUE;
465 err_t rpp_eth_lwip_init(struct netif *netif)
467 struct hdkif *hdkif = netif->state;
469 #if LWIP_NETIF_HOSTNAME
470 netif->hostname = "rpp";
472 netif->state = hdkif;
474 netif->name[0] = IFNAME0;
475 netif->name[1] = IFNAME1;
478 hdkif->waitTicksForPHYAneg = TICKS_PHY_AUTONEG;
482 * Initialize the snmp variables and counters inside the struct netif.
483 * The last argument should be replaced with your link speed, in units
484 * of bits per second.
486 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000);
488 /* We directly use etharp_output() here to save a function call.
489 * You can instead declare yo_SKIP_TO_HWur own function an call etharp_output()
490 * from it if you have to do some checks before sending (e.g. if link
493 netif->output = etharp_output;
494 netif->linkoutput = rpp_eth_send;
496 return rpp_eth_hw_init_postInit(netif);
499 #define INIT_ONLY_AFTER_RESET 1 // FIXME Why? Wat? Wut? For future implementation?
500 static err_t rpp_eth_hw_init(struct hdkif *hdkif)
506 /* Deactivate reset pin of PHY */
508 * For hw reset of PHY, it is necessary that PIN_NAME_ETHRST is 1us
509 * logical low state, before putting it to logical high
511 #if !INIT_ONLY_AFTER_RESET
514 * Initially used to hw reset of PHY connected to GIO pin.
515 * This means 1us - for 80MHz clock.
520 * Initially used to hw reset of PHY connected to GIO pin
521 * 'rpp project only'; 1us - according to PHY specification.
523 index = configCPU_CLOCK_HZ/1000000;
525 hal_gpio_pin_set_value(*hal_gpio_pin_get_dsc(PIN_NAME_ETHRST, -1), 0);
528 #endif /* !INIT_ONLY_AFTER_RESET */
531 * We have pull-down resistor, so after reset, we only need
532 * to put ETHRST pin to log. high
534 hal_gpio_pin_set_value(*hal_gpio_pin_get_dsc(PIN_NAME_ETHRST, -1), 1);
536 /* Initialize EMAC control module and EMAC module */
537 EMACInit(hdkif->emac_ctrl_base, hdkif->emac_base);
538 /* Initialize MDIO module (reset) */
539 MDIOInit(hdkif->mdio_base, 0x0, 0x0);
542 * Try to read random register from defaultPhy to make MDIO fill alive
543 * bit for this one if it returned ACK bit in msg response -- this must
544 * be done, because MDIO has not set alive bit of PHY after that
545 * short time after MDIOInit()
547 MDIOPhyRegRead(hdkif->mdio_base, hdkif->phy_addr, PHY_BMSR, ®Content);
549 /* Find first alive PHY -- or use default if alive */
550 physAlive = MDIOPhyAliveStatusGet(hdkif->mdio_base);
551 if (!(physAlive & (1 << hdkif->phy_addr))) {
552 #if FIND_FIRST_PHY_ALIVE
553 for (index = 0; index < NUM_OF_PHYs; index++) {
554 if (physAlive && (1 << index)) {
555 hdkif->phy_addr = index;
559 * Try to 'wake up' PHY on 'index' address by
560 * reading random register, making MDIO set
561 * alive bit for current PHY
563 MDIOPhyRegRead(hdkif->mdio_base, index,
564 PHY_BMCR, ®Content);
566 /* Get updated register */
567 physAlive = MDIOPhyAliveStatusGet(hdkif->mdio_base);
568 if (physAlive && (1 << index)) {
569 hdkif->phy_addr = index;
575 if (!physAlive) { /* FIXME je to ok? */
576 rpp_debug_printf("no phy found, phys: %d\n", physAlive);
580 rpp_debug_printf("default phy not alive\n");
581 return DFLT_PHY_NOT_ALIVE;
586 * Start autonegotiation and check on completion later or
587 * when complete link register will be updated
589 hdkif->phy_autoneg_start(hdkif->mdio_base, hdkif->phy_addr,
590 PHY_100BASETXDUPL_m | PHY_100BASETX_m |
591 PHY_10BASETDUPL_m | PHY_10BASET_m);
594 * TODO: you can implement init of receive flow control somewhere
595 * here if desired - set RXBUFFERFLOWEN in MACCONTROL
599 /* Acknowledge EMAC control module RX, TX and MISC interrupts */
600 EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_RX);
601 EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_TX);
602 EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_MISC);
604 /* Sets which channel will receive broadcasts */
605 EMACRxBroadCastEnable(hdkif->emac_base, CHANNEL);
608 * Sets channel where all frames will be copied to --
609 * either with MAC address different from local device address,
610 * either packets with error will be copied; appropriate error
611 * will be set in the frame EOP buffer descriptor
613 EMACRxPromiscEnable(hdkif->emac_base, CHANNEL);
616 EMACRxUnicastSet(hdkif->emac_base, CHANNEL);
618 /* Enable TX and RX interrupts in both EMAC module and EMAC control module */
619 EMACTxIntPulseEnable(hdkif->emac_base, hdkif->emac_ctrl_base, 0, CHANNEL);
620 EMACRxIntPulseEnable(hdkif->emac_base, hdkif->emac_ctrl_base, 0, CHANNEL);
625 static err_t rpp_eth_hw_init_postInit(struct netif *netif)
627 /* 0x3FFFFFFF is for 80MHz aproximately 13s */
628 volatile unsigned int autonegFinishWait = 0x3FFFFFFF;
631 uint32_t num_bd, pbuf_cnt = 0;
632 volatile struct emac_tx_bd *curr_txbd, *last_txbd;
633 volatile struct emac_rx_bd *curr_rxbd, *last_rxbd;
638 struct hdkif *hdkif = (struct hdkif *)netif->state;
640 rxch = &(hdkif->rxch);
641 txch = &(hdkif->txch);
643 rpp_debug_printf("autoneg started -- check on cable if it's connected!\r\n");
646 * Use the CPPI RAM to store RX/TX Buffer Descriptors (= BD).
647 * 1/2 of CPPI RAM is used for TX BDs, another 1/2 for RX BDs.
648 * All the TX BDs are 'owned' by the software. They are initialized
649 * as a linked-list forming a ring. They are awaiting the application
650 * to append pbuf payload to the them and correctly configure for
651 * actual transmission.
652 * Only such number of RX BDs is configured that the pbufs can be
653 * allocated for (i.e. MAX_RX_PBUF_ALLOC). Pbufs are allocated from
654 * the PBUF_POOL (thus the allocated pbufs might be chained).
655 * Each payload part of a payload is them used to initialize single
656 * RX BD. The RX BDs are then configured to be 'owned' bythe EMAC
660 * Initialize the Descriptor Memory For TX and RX
661 * Only Channel 0 is supported for both TX and RX
663 txch->free_head = (volatile struct emac_tx_bd *)hdkif->emac_ctrl_ram;
664 txch->next_bd_to_process = txch->free_head;
665 txch->active_tail = NULL;
667 /* Set the number of descriptors for the channel */
668 /* take half of CPPI ram for TX BDs */
669 num_bd = ((SIZE_EMAC_CTRL_RAM >> 1) / sizeof(struct emac_tx_bd));
671 curr_txbd = txch->free_head;
673 /* Initialize all the TX buffer Descriptors */
675 curr_txbd->next = curr_txbd + 1;
676 curr_txbd->flags_pktlen = 0;
677 last_txbd = curr_txbd;
678 curr_txbd = curr_txbd->next;
680 last_txbd->next = txch->free_head;
681 /* curr_txbd now points to the BD that is the first BD
682 * after the last_txbd -- this will be the first RX BD
685 /* Initialize the descriptors for the RX channel */
686 rxch->active_head = (volatile struct emac_rx_bd*)curr_txbd;
687 rxch->free_head = NULL; /* Not used */
688 rxch->freed_pbuf_len = 0;
690 num_bd = ((SIZE_EMAC_CTRL_RAM >> 1) / sizeof(struct emac_rx_bd));
691 curr_rxbd = rxch->active_head;
692 last_rxbd = curr_rxbd;
694 /* Allocate the pbufs for the maximum count permitted or
695 * till the number of buffer descriptors expire,
696 * whichever is earlier.
698 while (pbuf_cnt < MAX_RX_PBUF_ALLOC) {
699 /* Sidenote -- remember that the PBUF might be chained */
700 p = pbuf_alloc(PBUF_RAW, PBUF_LEN_MAX, PBUF_POOL);
702 /* Watch out not to excede the number of available BDs */
703 if (((uint32_t)pbuf_clen(p)) <= num_bd) {
704 /* Fill in the BD to reference the allocated pbuf */
705 /* for each PBUF chunk */
706 for (q = p; q != NULL; q = q->next) {
707 curr_rxbd->bufptr = (uint8_t *)q->payload;
708 curr_rxbd->bufoff_len = q->len;
709 curr_rxbd->next = curr_rxbd + 1;
710 curr_rxbd->flags_pktlen = EMAC_DSC_FLAG_OWNER;
714 last_rxbd = curr_rxbd;
715 curr_rxbd = curr_rxbd->next;
719 /* free the allocated pbuf if no free
720 * descriptors are left */
730 rpp_sci_printf("No pbufs attached to RX BD during init\n");
732 last_rxbd->next = NULL;
733 rxch->active_tail = last_rxbd;
736 num_bd = (((uintptr_t)rxch->active_tail - (uintptr_t)rxch->active_head)
737 / sizeof(struct emac_rx_bd)) + 1;
738 rpp_debug_printf("%d pbuf chains allocated for %d rx buffer descriptors\n",
742 /* Set header descriptor pointers -- this shows EMAC which descriptor
743 * is the first one for writing received frames/packets
745 EMACRxHdrDescPtrWrite(hdkif->emac_base, (uint32_t)rxch->active_head, CHANNEL);
747 /* set MAC address */
748 netif->hwaddr_len = MAC_ADDR_LEN;
749 for (regContent = 0; regContent < MAC_ADDR_LEN; regContent++) {
750 netif->hwaddr[regContent] =
751 hdkif->mac_addr[(MAC_ADDR_LEN - 1) - regContent];
754 /* maximum transfer unit */
755 netif->mtu = MAX_TRANSFER_UNIT;
757 /* device capabilities */
758 /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
759 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
762 /* for flow control frames */
763 EMACMACSrcAddrSet(hdkif->emac_base, hdkif->mac_addr);
765 /* Be sure to program all eight MAC address registers -
766 * whether the receive channel is to be enabled or not.
768 for (regContent = 0; regContent < 8; regContent++) {
769 EMACMACAddrSet(hdkif->emac_base, regContent, hdkif->mac_addr,
770 EMAC_MACADDR_NO_MATCH_NO_FILTER);
773 #if !PHY_LINK_MONITOR_INT
774 /* In case we don't use interrupt when phy link status changes,
775 * we need to try to finish autoneg in here
777 /* wait for autonegotiation to be done or continue, when delay was reached */
779 uint32_t timeToWake = hdkif->waitTicksForPHYAneg + sys_jiffies();
780 while (hdkif->phy_autoneg_is_done(hdkif->mdio_base, hdkif->phy_addr) == FALSE &&
781 timeToWake > sys_jiffies())
784 /* XXX: if init is not done at the startup,
785 * but couple days later, this might cause troubles */
789 while (hdkif->phy_autoneg_is_done(hdkif->mdio_base, hdkif->phy_addr) == FALSE &&
791 ; /* wait till aneg done */
794 if (hdkif->phy_autoneg_is_done(hdkif->mdio_base, hdkif->phy_addr) != FALSE)
795 rpp_debug_printf("autoneg finished\n");
797 rpp_debug_printf("autoneg timeout\n");
799 /* provide informations retrieved from autoneg to EMAC module */
800 hdkif->phy_partnerability(hdkif->mdio_base, hdkif->phy_addr, ®Content);
801 if (regContent & (PHY_100BASETXDUPL_m | PHY_10BASETDUPL_m)) {
802 EMACDuplexSet(hdkif->emac_base, EMAC_DUPLEX_FULL);
803 /* this is right place to implement transmit flow control if desired --
804 * set TXFLOWEN in MACCONTROL
806 } else if (regContent & (PHY_100BASETX_m | PHY_10BASET_m)) {
807 EMACDuplexSet(hdkif->emac_base, EMAC_DUPLEX_HALF);
809 rpp_debug_printf("Unknown duplex mode\r\n");
810 return UNKN_DUPLEX_MODE;
812 #endif /* !PHY_LINK_MONITOR_INT */
814 /* enable hostpend interrupts in emac module */
815 HWREG(hdkif->emac_base + EMAC_MACINTMASKSET) |=
816 EMAC_MACINTMASKSET_HOSTMASK;
818 /* enable hostpend interrupts in emac control module */
819 HWREG(hdkif->emac_ctrl_base + EMAC_CTRL_CnMISCEN(0)) |=
820 EMAC_CTRL_MISC_HOSTPENDENB;
822 EMACMIIEnable(hdkif->emac_base);
823 EMACTxEnable(hdkif->emac_base);
824 EMACRxEnable(hdkif->emac_base);
829 /* send and receive functions / ISRs ******************************************/
831 err_t rpp_eth_send(struct netif *netif, struct pbuf *p)
833 err_t retVal = SUCCESS;
834 SYS_ARCH_DECL_PROTECT(lev);
837 * This entire function must be protected to preserve
838 * the integrity of the transmit pbuf queue.
840 SYS_ARCH_PROTECT(lev);
841 #if !SYS_LIGHTWEIGHT_PROT
842 uint32_t prevProt = (uint32_t) _get_CPSR() & 0x80;
846 /* adjust the packet length if less than minimum required */
847 if (p->tot_len < MIN_PKT_LEN) {
848 p->tot_len = MIN_PKT_LEN;
849 p->len = MIN_PKT_LEN;
853 * Bump the reference count on the pbuf to prevent it from being
854 * freed until we are done with it.
858 /* call the actual transmit function */
859 retVal = rpp_eth_send_raw(netif, p);
861 /* Return to prior interrupt state and return. */
862 SYS_ARCH_UNPROTECT(lev);
863 #if !SYS_LIGHTWEIGHT_PROT
872 * When called from rpp_eth_send(), the 'lev' lock is held
874 static err_t rpp_eth_send_raw(struct netif *netif, struct pbuf *pbuf)
879 volatile struct emac_tx_bd *curr_bd;
880 /* Head of the BD chain representing 'active' BDs --
881 * those that are modified/added in this function
883 volatile struct emac_tx_bd *active_head;
884 /* Same as active_head, but this is the tail of the list */
885 volatile struct emac_tx_bd *active_tail;
887 hdkif = (struct hdkif *)netif->state;
888 txch = &(hdkif->txch);
890 /* Get the first BD that is unused and will be used for TX */
891 curr_bd = txch->free_head;
892 active_head = curr_bd;
894 /* Be sure that the free_head didn't wrap around the chain
895 * of all BDs pointing to the BD being processed by the EMAC
896 * (in such case txch->free_head would be the same as
897 * txch->next_bd_to_process)
899 while (curr_bd->flags_pktlen & EMAC_DSC_FLAG_OWNER)
902 /* First 'part' of packet flags */
903 curr_bd->flags_pktlen = pbuf->tot_len |
907 /* Copy pbuf information into TX BDs --
908 * remember that the pbuf for a single packet might be chained!
910 for (q = pbuf; q != NULL; q = q->next) {
911 curr_bd->bufptr = (uint8_t *)(q->payload);
912 curr_bd->bufoff_len = (q->len) & 0xFFFF;
914 active_tail = curr_bd;
915 /* This is an extra field that is not par of the in-HW BD.
916 * This is used when freeing the pbuf after the TX processing
919 curr_bd->pbuf = pbuf;
921 curr_bd = curr_bd->next;
922 curr_bd->flags_pktlen = 0x0;
924 /* Indicate the end of the packet */
925 active_tail->next = NULL;
926 active_tail->flags_pktlen |= EMAC_DSC_FLAG_EOP;
928 /* Since we used the txch->free_head as the first BD for our purpose,
929 * set the new free_head just behind the active_tail
931 txch->free_head = curr_bd;
933 /* For the first time, write the HDP with the filled bd */
934 if (txch->active_tail == NULL) {
935 EMACTxHdrDescPtrWrite(hdkif->emac_base,
936 (unsigned int)(active_head), CHANNEL);
938 /* Chain the bd's. If the DMA engine already reached the
939 * end of the chain, the EOQ will be set. In that case,
940 * the HDP shall be written again.
942 curr_bd = txch->active_tail;
943 curr_bd->next = active_head;
946 /* Just a workaround in case "appending" to
947 * the last active BD will not work
949 while (!(curr_bd->flags_pktlen & EMAC_DSC_FLAG_EOQ))
953 /* We were too slow and the EMAC already read the
954 * 'pNext = NULL' of the former txch->active_tail. In this
955 * case the transmission stopped and we need to write the
956 * pointer to newly added BDs to the TX HDP
958 if (curr_bd->flags_pktlen & EMAC_DSC_FLAG_EOQ) {
959 /* Writes to TX HDP are allowed only when it is 0 */
960 while (HWREG(hdkif->emac_base + EMAC_TXHDP(CHANNEL)) != 0)
962 EMACTxHdrDescPtrWrite(hdkif->emac_base,
963 (unsigned int)(active_head), CHANNEL);
966 txch->active_tail = active_tail;
971 void rpp_eth_send_raw_thr(void *arg)
975 volatile struct emac_tx_bd *curr_bd;
976 volatile struct emac_tx_bd *next_bd_to_process;
977 struct netif *netif = (struct netif*)arg;
979 hdkif = netif->state;
980 txch = &(hdkif->txch);
983 /* Block if there is nothing to do.
984 * Wake up if an TX interrupt occured.
986 xSemaphoreTake(hdkif->goTX, portMAX_DELAY);
988 next_bd_to_process = txch->next_bd_to_process;
989 curr_bd = next_bd_to_process;
991 /* Traverse the list of BDs used for transmission --
992 * stop on the first unused
994 while (curr_bd->flags_pktlen & EMAC_DSC_FLAG_SOP) {
995 /* Make sure the transmission is over */
996 while (curr_bd->flags_pktlen & EMAC_DSC_FLAG_OWNER)
999 /* Find the last chunk of the packet */
1000 while (!(curr_bd->flags_pktlen & EMAC_DSC_FLAG_EOP))
1001 curr_bd = curr_bd->next;
1003 /* Remove flags for the transmitted BDs */
1004 next_bd_to_process->flags_pktlen &= (~EMAC_DSC_FLAG_SOP);
1005 curr_bd->flags_pktlen &= (~EMAC_DSC_FLAG_EOP);
1007 /* Point the txch->next_bd_to_process to the BDs
1008 * following the 'last BD belonging to the packet
1011 if (curr_bd->next == NULL)
1012 txch->next_bd_to_process = txch->free_head;
1014 txch->next_bd_to_process = curr_bd->next;
1016 /* Ack the Interrupt in the EMAC peripheral */
1017 EMACTxCPWrite(hdkif->emac_base, CHANNEL,
1020 /* Free the corresponding pbuf
1021 * Sidenote: Each fragment of the single packet points
1022 * to the same pbuf // FIXME is it true?
1024 pbuf_free(curr_bd->pbuf);
1026 LINK_STATS_INC(link.xmit);
1028 /* Move to the next packet */
1029 next_bd_to_process = txch->next_bd_to_process;
1030 curr_bd = next_bd_to_process;
1033 /* Ack the Interrupt in the EMAC peripheral */
1034 EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_TX);
1035 //EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_RX); // Proc?
1036 /* Enable the interrupt in the VIM */
1037 vim_mask_set(TXinterruptVectorNumber);
1041 void rpp_eth_recv_raw_thr(void *arg)
1043 struct hdkif *hdkif;
1045 struct netif *netif = (struct netif*)arg;
1046 volatile struct emac_rx_bd *curr_bd;
1047 volatile struct emac_rx_bd *curr_tail;
1048 volatile struct emac_rx_bd *curr_head;
1049 volatile struct pbuf *pbuf;
1050 volatile struct pbuf *new_pbuf;
1051 volatile struct pbuf *q;
1053 hdkif = netif->state;
1054 rxch = &(hdkif->rxch);
1057 /* Block if there is nothing to do.
1058 * Wake up if an RX interrupt occured.
1061 sys_arch_sem_wait(&(hdkif->goRX), 0);
1063 xSemaphoreTake(hdkif->goRX, portMAX_DELAY);
1065 /* Get the bd which contains the earliest filled data */
1066 curr_bd = rxch->active_head;
1068 /* For each valid frame */
1069 while (curr_bd->flags_pktlen & EMAC_DSC_FLAG_SOP) {
1070 unsigned int total_rx_len;
1071 unsigned int processed_rx_len = 0;
1073 /* Start processing once the packet is released by the EMAC. */
1074 while (curr_bd->flags_pktlen & EMAC_DSC_FLAG_OWNER)
1077 pbuf = curr_bd->pbuf;
1078 total_rx_len = curr_bd->flags_pktlen & 0xFFFF;
1080 /* The received frame might be fragmented into muliple
1081 * pieces -- each one referenced by a separate BD.
1082 * To further process the data, we need to 'make' a
1083 * proper PBUF out of it -- that means linking each
1084 * buffer together, copy the length information form
1085 * the DB to PBUF, calculate the 'tot_len' etc.
1089 /* Since this pbuf will be freed, we need to
1090 * keep track of its size to be able to
1091 * allocate it back again
1093 rxch->freed_pbuf_len += q->len;
1095 /* This is the size of the "received data" not the PBUF */
1096 q->tot_len = total_rx_len - processed_rx_len;
1097 q->len = curr_bd->bufoff_len & 0xFFFF;
1099 if (curr_bd->flags_pktlen & EMAC_DSC_FLAG_EOP)
1102 * If we are executing here, it means this
1103 * packet is being split over multiple BDs
1106 /* chain the pbufs since they belong
1107 * to the same packet
1109 q->next = (curr_bd->next)->pbuf;
1111 processed_rx_len += q->len;
1112 curr_bd = curr_bd->next;
1114 /* Close the chain */
1117 LINK_STATS_INC(link.recv);
1119 /* Process the packet */
1120 /* ethernet_input((struct pbuf *)pbuf, netif) */
1121 if (netif->input((struct pbuf *)pbuf, netif) != ERR_OK) {
1122 LINK_STATS_INC(link.memerr);
1123 LINK_STATS_INC(link.drop);
1126 /* Acknowledge that this packet is processed */
1127 EMACRxCPWrite(hdkif->emac_base, 0, (unsigned int)curr_bd);
1129 curr_head = rxch->active_head;
1130 rxch->active_head = curr_bd->next;
1132 /* The earlier PBUF chain is freed from the upper layer.
1133 * So, we need to allocate a new pbuf chain and update
1134 * the descriptors with the PBUF info.
1135 * Care should be taken even if the allocation fails.
1138 new_pbuf = pbuf_alloc(PBUF_RAW,
1139 rxch->freed_pbuf_len,
1141 if (new_pbuf == NULL) {
1142 /* Cycle until the pbuf is
1143 * succesfully allocated
1145 /* Actively poll to decrease the time
1146 * when the RX interrupts are disabled
1150 curr_tail = curr_bd;
1151 curr_tail->next = NULL;
1152 curr_bd = curr_head;
1155 curr_bd = curr_head;
1159 if (curr_bd == NULL)
1162 curr_bd->bufptr = (uint8_t *)q->payload;
1163 curr_bd->bufoff_len = q->len;
1164 curr_bd->flags_pktlen =
1165 EMAC_DSC_FLAG_OWNER;
1168 rxch->freed_pbuf_len -= q->len;
1170 curr_bd = curr_bd->next;
1173 /* At this point either the whole pbuf
1174 * was used or there are no RX BDs left.
1175 * If there is not enough RX BDs to assign
1176 * all pbufs in the chain, free the
1177 * rest of the pbufs.
1180 pbuf_free((struct pbuf *)q);
1182 /* Add the newly allocated BDs to the
1185 rxch->active_tail->next = curr_head;
1186 /* Check if the reception has ended.
1187 * If the EOQ flag is set, the NULL
1188 * pointer is taken by the DMA engine.
1189 * So we need to write the RX HDP
1190 * with the next descriptor.
1192 if (rxch->active_tail->flags_pktlen &
1195 /* Writes to RX HDP are allowed
1198 while (HWREG(hdkif->emac_base +
1199 EMAC_RXHDP(CHANNEL)) != 0)
1202 EMACRxHdrDescPtrWrite(
1204 (uint32_t)curr_head,
1208 rxch->active_tail = curr_tail;
1212 curr_bd = rxch->active_head;
1215 /* Ack the Interrupt in the EMAC peripheral */
1216 EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_RX);
1217 //EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_TX);
1218 /* Enable the interrupt in the VIM */
1219 vim_mask_set(RXinterruptVectorNumber);
1223 void RxIntHandler(u32_t instNum)
1225 vim_mask_clr(RXinterruptVectorNumber);
1226 /* Unblock the RX task. */
1227 xSemaphoreGiveFromISR(hdkif_data[instNum].goRX, NULL);
1230 void TxIntHandler(u32_t instNum)
1232 vim_mask_clr(TXinterruptVectorNumber); /* see sys_startup.c */
1233 xSemaphoreGiveFromISR(hdkif_data[instNum].goTX, NULL);
1239 * 1h SOP error; the buffer is the first buffer in a packet,
1240 * but the SOP bit is not set in software.
1241 * 2h Ownership bit not set in SOP buffer
1242 * 3h Zero next buffer descriptor pointer without EOP
1243 * 4h Zero buffer pointer
1244 * 5h Zero buffer length
1245 * 6h Packet length error (sum of buffers is less than packet length)
1250 * 2h Ownership bit not set in SOP buffer
1252 * 4h Zero buffer pointer
1254 boolean_t HostPendErrHandler(void)
1256 uint8_t index = MAX_EMAC_INSTANCE;
1257 uint8_t errFound = FALSE;
1259 struct hdkif *hdkif;
1262 hdkif = &hdkif_data[--index];
1264 if (EMACIntVectorGet(hdkif->emac_base) & EMAC_MACINVECTOR_HOSTPEND)
1269 return FALSE; /* this is not the cause of the interrupt */
1271 rpp_sci_printk("HOSTPEND err\n");
1272 reg = HWREG(hdkif->emac_base + EMAC_MACSTATUS);
1273 rpp_sci_printk("TXCHERR: %d at CH: %d\n",
1274 ((reg >> EMAC_MACSTATUS_TXERRCODE_SHIFT) & 0x7),
1275 ((reg >> EMAC_MACSTATUS_TXERRCH_SHIFT) & 0x7));
1276 rpp_sci_printk("RXCHERR: %d at CH: %d\n",
1277 ((reg >> EMAC_MACSTATUS_RXERRCODE_SHIFT) & 0x7),
1278 ((reg >> EMAC_MACSTATUS_RXERRCH_SHIFT) & 0x7));
1280 { /* Print out all the RX BDs */
1282 volatile struct emac_rx_bd *curr_bd;
1283 rxch = &(hdkif->rxch);
1286 rpp_sci_printk("rxch->active_head: %p\n", rxch->active_head);
1287 rpp_sci_printk("rxch->active_tail: %p\n", rxch->active_tail);
1288 rpp_sci_printk("rxch->freed_pbuf_len: %p\n", rxch->freed_pbuf_len);
1289 rpp_sci_printk("RXCP: 0x%x\n", *((uint32_t*)(hdkif->emac_base + EMAC_RXCP(0))));
1291 for (curr_bd = rxch->active_head; curr_bd != 0; curr_bd = curr_bd->next) {
1292 glob_len += curr_bd->pbuf->len;
1294 rpp_sci_printk("[%p: buf: %p buffoff_len: 0x%x "
1295 "\tflags: 0x%x pktlen: 0x%x]",
1298 curr_bd->bufoff_len,
1299 (curr_bd->flags_pktlen >> 16) & 0xFFFF,
1300 curr_bd->flags_pktlen & 0xFFFF);
1301 rpp_sci_printk(" pbuf: tot_len: 0x%x \tlen: 0x%x ref: 0x%x\n",
1302 curr_bd->pbuf->tot_len,
1304 curr_bd->pbuf->ref);
1306 rpp_sci_printk("glob_len: %d\n", glob_len);
1309 /* no acknowledge - emac module has to be restarted */
1311 /* this was the reason of interrupt */
1315 #if PHY_LINK_MONITOR_INT
1316 boolean_t LinkIntHandler(void)
1318 uint8_t index = MAX_EMAC_INSTANCE;
1319 uint8_t phyFound = FALSE;
1320 struct hdkif *hdkif;
1321 uint16_t regContent;
1322 volatile unsigned int autonegFinishWait = 0xFFFFFFF;
1323 volatile unsigned int dhcpBindWait = 0x3FFFFFFF;
1325 /* check each instance, whether this interrupt was meant for this
1326 * function, if not return FALSE so other function may be tried
1329 hdkif = &hdkif_data[--index];
1330 if ((hdkif->phy_addr ==
1331 (HWREG(hdkif->mdio_base + MDIO_USERPHYSEL0) & 0x1f)) &&
1332 (EMACIntVectorGet(hdkif->emac_base) &
1333 EMAC_MACINVECTOR_LINKINT0))
1338 struct netif *netif = &hdkNetIF[hdkif->inst_num];
1340 /* we handle here connection of cable after startup, not changes of linkstatus */
1342 /* wait for autonegotiation to be done */
1344 while (hdkif->phy_autoneg_is_done(hdkif->mdio_base, hdkif->phy_addr) ==
1347 #else /* ONCE_LINK_SETUP */
1348 while (hdkif->phy_autoneg_is_done(hdkif->mdio_base, hdkif->phy_addr) ==
1349 FALSE & autonegFinishWait--)
1351 #endif /* ONCE_LINK_SETUP */
1353 /* provide informations retrieved from autoneg to EMAC module */
1354 hdkif->phy_partnerability(hdkif->mdio_base, hdkif->phy_addr, ®Content);
1355 if (regContent & (PHY_100BASETXDUPL_m | PHY_10BASETDUPL_m)) {
1356 EMACDuplexSet(hdkif->emac_base, EMAC_DUPLEX_FULL);
1357 /* this is right place to implement transmit flow control
1358 * if desired - set TXFLOWEN in MACCONTROL
1360 } else if (regContent & (PHY_100BASETX_m | PHY_10BASET_m)) {
1361 EMACDuplexSet(hdkif->emac_base, EMAC_DUPLEX_HALF);
1363 /* acknowledge MDIO module */
1364 HWREG(hdkif->mdio_base + MDIO_LINKINTRAW) =
1365 MDIO_LINKINTMASKED_USERPHY0;
1366 HWREG(hdkif->mdio_base + MDIO_LINKINTMASKED) =
1367 MDIO_LINKINTMASKED_USERPHY0;
1369 /* acknowledge EMAC control module by writing
1370 * appropriate key to MACEOIVECTOR
1372 EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_MISC);
1375 /* if link is up configure lwip struct netif */
1376 if (rpp_eth_phylinkstat(hdkif->inst_num)) {
1377 #if STATIC_IP_ADDRESS
1378 netif_set_up(netif);
1379 #elif LWIP_DHCP /* STATIC_IP_ADDRESS-LWIP_DHCP */
1380 if (dhcp_start(netif) != ERR_OK) { /* XXX: can't be used from ISR (mem_malloc()) */
1381 return DHCP_MEM_ERR;
1384 while (netif->dhcp->state != DHCP_BOUND)
1387 while (netif->dhcp->state != DHCP_BOUND & dhcpBindWait--)
1389 if (!dhcpBindWait) {
1390 /* acknowledge MDIO module */
1391 HWREG(hdkif->mdio_base + MDIO_LINKINTRAW) =
1392 MDIO_LINKINTMASKED_USERPHY0;
1393 HWREG(hdkif->mdio_base + MDIO_LINKINTMASKED) =
1394 MDIO_LINKINTMASKED_USERPHY0;
1396 /* acknowledge EMAC control module by writing
1397 * appropriate key to MACEOIVECTOR
1399 EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_MISC);
1403 #else /* LWIP_DHCP-LWIP_AUTOIP FIXME: there should be some kind of waiting till ip is assigned */
1404 autoip_start(netif);
1405 #endif /* STATIC_IP_ADDRESS-LWIP_DHCP-LWIP_AUTOIP */
1407 /* turn this interrupt off */
1408 HWREG(hdkif->emac_ctrl_base + EMAC_CTRL_CnMISCEN(0)) &=
1409 (~EMAC_CTRL_MISC_LINKINT0ENB & 0xf);
1410 #endif /* ONCE_LINK_SETUP */
1413 /* acknowledge MDIO module */
1414 HWREG(hdkif->mdio_base + MDIO_LINKINTRAW) =
1415 MDIO_LINKINTMASKED_USERPHY0;
1416 HWREG(hdkif->mdio_base + MDIO_LINKINTMASKED) =
1417 MDIO_LINKINTMASKED_USERPHY0;
1419 /* acknowledge EMAC control module by writing
1420 * appropriate key to MACEOIVECTOR
1422 EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_MISC);
1425 #if STATIC_IP_ADDRESS
1426 netif_set_down(netif);
1427 #elif LWIP_DHCP /* STATIC_IP_ADDRESS-LWIP_DHCP */
1429 #endif /* STATIC_IP_ADDRESS-LWIP_DHCP-LWIP_AUTOIP */
1433 /* acknowledge MDIO module */
1434 HWREG(hdkif->mdio_base + MDIO_LINKINTRAW) =
1435 MDIO_LINKINTMASKED_USERPHY0;
1436 HWREG(hdkif->mdio_base + MDIO_LINKINTMASKED) =
1437 MDIO_LINKINTMASKED_USERPHY0;
1439 /* acknowledge EMAC control module by writing appropriate key to MACEOIVECTOR */
1440 EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_MISC);
1444 #endif /* PHY_LINK_MONITOR_INT */
1445 #endif /* FREERTOS_POSIX */