2 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
27 * This file is part of the lwIP TCP/IP stack.
29 * Author: Adam Dunkels <adam@sics.se>
34 * Copyright (c) 2010 Texas Instruments Incorporated
36 * This file is dervied from the "ethernetif.c" skeleton Ethernet network
37 * interface driver for lwIP.
40 /* Copyright (C) 2013 Czech Technical University in Prague
43 * - Carlos Jenkins <carlos@jenkins.co.cr>
45 * - Jan Doležal <pm.jenik@gmail.com>
47 * This program is free software; you can redistribute it and/or modify
48 * it under the terms of the GNU General Public License as published by
49 * the Free Software Foundation; either version 2 of the License, or
50 * (at your option) any later version.
52 * This program is distributed in the hope that it will be useful,
53 * but WITHOUT ANY WARRANTY; without even the implied warranty of
54 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55 * GNU General Public License for more details.
57 * You should have received a copy of the GNU General Public License
58 * along with this program. If not, see <http://www.gnu.org/licenses/>.
62 * Ethernet Communication RPP API implementation file. Using one PHY.
66 * RPP API documentation.
70 #include "lwip/init.h"
71 #include "lwip/timers.h" /* for DHCP binding in NO_SYS mode */
72 #include "lwip/sys.h" /* includes - lwip/opt.h, lwip/err.h, arch/sys_arch.h */
73 #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 */
74 #include "lwip/stats.h" /* includes - lwip/mem.h, lwip/memp.h, lwip/opt.h */
75 #include "netif/etharp.h" /* includes - lwip/ip.h, lwip/netif.h, lwip/ip_addr.h, lwip/pbuf.h */
77 #include "lwip/snmp.h"
78 #include "lwip/dhcp.h"
79 #include "lwip/autoip.h"
80 #include "netif/ppp_oe.h"
81 /* end - lwIP headers */
85 #include "sys/sys.h" /* includes - sys/phy_dp83848h.h */
91 #if rppCONFIG_INCLUDE_ETH == 1
95 /* Number of EMAC Instances */
96 #define MAX_EMAC_INSTANCE 1
98 #define DEFAULT_PHY_ADDR 0x1
99 #define FIND_FIRST_PHY_ALIVE 1 /* or use default (phy_address: 1) */
100 #define NUM_OF_PHYs 32
101 #define SIZE_OF_DESC 16 /* in bytes */
102 #define CHANNEL 0 /* channel number for everything - for rx, tx, unicast, broadcast or damaged frames ; there are different channels for rx and tx operations */
104 #define MAX_TRANSFER_UNIT 1500 /* take in account oversized frames */
105 #define PBUF_LEN_MAX MAX_TRANSFER_UNIT
106 #define MAX_RX_PBUF_ALLOC 10
107 #define MIN_PKT_LEN 60
109 /* Define those to better describe the network interface. */
115 * Time to wait for autonegotiation in ticks.
117 #define TICKS_PHY_AUTONEG 4000
121 * When cable is connected (link status goes up) autonegotiation and/or dhcp is started.
123 #define PHY_LINK_MONITOR_INT 0 /* turn on handling interrupt - not implemented now */
126 /* Defining interface for all the emac instances */
127 static struct hdkif hdkif_data[MAX_EMAC_INSTANCE];
130 ** The lwIP network interface structure for the HDK Ethernet MAC.
132 static struct netif hdkNetIF[MAX_EMAC_INSTANCE];
134 /* rpp startup init indicator */
135 static boolean_t initialized = FALSE, postInitialized = FALSE;
137 boolean_t sendDone = TRUE;
139 /* free pbuf notification */
141 xSemaphoreHandle pbufFreed;
144 /**********************************************testing functions**********************************************/
146 boolean_t isPostInitialized()
148 return postInitialized;
151 uint32_t rpp_eth_phylinkstat(uint32_t instNum)
153 struct hdkif *hdkif = &hdkif_data[instNum];
154 return PHY_link_status_get(hdkif->mdio_base, hdkif->phy_addr, 1);
157 #define BYTE_BUFF_SIZE 2
158 #define OFFSET_MAC_LETTERS (MAC_BIG_LETTERS ? 'A' : 'a')
159 /* puts string of MAC address assigned to EMAC instance reffered by instNum into *mac */
160 void rpp_eth_get_macAddrStr(uint32_t instNum, uint8_t *macStr)
162 uint8_t index, outindex = 0;
163 char buff[BYTE_BUFF_SIZE];
164 struct hdkif *hdkif = &hdkif_data[instNum];
165 for(index = 0; index < MAC_ADDR_LEN; index++) {
166 if(index)macStr[outindex++] = ':';
167 buff[0] = (hdkif->mac_addr[(MAC_ADDR_LEN - 1) - index] >> 4);
168 buff[1] = (hdkif->mac_addr[(MAC_ADDR_LEN - 1) - index] & 0xf);
169 macStr[outindex++] = (buff[0]<10) ? (buff[0] + '0') : (buff[0] - '\012' + OFFSET_MAC_LETTERS);
170 macStr[outindex++] = (buff[1]<10) ? (buff[1] + '0') : (buff[1] - '\012' + OFFSET_MAC_LETTERS);
172 macStr[outindex] = '\0';
175 /* @param ip will be filled accroding to content of ipstr */
176 err_t rpp_eth_stringToIP(ip_addr_t * ip, uint8_t * ipstr)
178 uint8_t charProccessed, index = 0, dotindex = 0xff, tmp = 0, dots = 0, fldEdit = 0;
180 for(charProccessed = ipstr[index]; (charProccessed >= '0' && charProccessed <= '9') || charProccessed == '.' ; charProccessed = ipstr[++index])
182 if(charProccessed == '.')
184 if(++dotindex == index)
191 ipaddr = (ipaddr << 8) + tmp;
202 tmp = tmp*10 + charProccessed - '0';
205 if(dots != 3 || !fldEdit)
207 /* if unsuccesful, don't modify previous content */
210 ipaddr = (ipaddr << 8) + tmp;
215 /* returns number in range 0-65535 where 0 is error */
216 uint16_t rpp_eth_portStrToInt(uint8_t *string)
220 for(index = 0;string[index] != '\0';index++)
222 if(string[index] < '0' || string[index] > '9')
227 portNO = portNO * 10 + string[index] - '0';
232 struct netif *rpp_eth_get_netif(uint32_t instNum)
234 return &hdkNetIF[instNum];
237 /********************************************** forward declares **********************************************/
240 * interface initializes
242 err_t rpp_eth_lwip_init(struct netif *netif);
245 * Initializes hw such as PHY, MDIO, EMAC, EMAC control module
247 * @return SUCCESS if initialization successful.\n
248 * FAILURE if initialization not successful.
250 err_t rpp_eth_hw_init(struct hdkif *hdkif);
253 * Initializes hw, after lwIP was initialized and
254 * OS was initialized in case OS is used.
256 err_t rpp_eth_hw_init_postInit(struct netif *netif);
258 /********************************************** utility functions **********************************************/
261 * Function to set the MAC address to the interface
262 * @param inst_num the instance number
264 * @note mac_addr[0] is considered MSB
267 hdkif_macaddrset(u32_t inst_num, u8_t *mac_addr) {
271 hdkif = &hdkif_data[inst_num];
273 /* set MAC hardware address */
274 for(temp = 0; temp < MAC_ADDR_LEN; temp++) {
275 hdkif->mac_addr[temp] = mac_addr[(MAC_ADDR_LEN - 1) - temp];
279 rpp_eth_get_macAddrStr(inst_num, macStr);
280 rpp_debug_printf("Setting MAC... %s\r\n", macStr);
285 * Function to setup the instance parameters inside the interface
290 hdkif_inst_config(struct hdkif *hdkif) {
291 if(hdkif->inst_num == 0)
293 hdkif->emac_base = EMAC_BASE_m(0);
294 hdkif->emac_ctrl_base = EMAC_CTRL_BASE_m(0);
295 hdkif->emac_ctrl_ram = EMAC_CTRL_RAM_BASE_m(0);
296 hdkif->mdio_base = MDIO_BASE_m(0);
297 hdkif->phy_addr = DEFAULT_PHY_ADDR; /* Default address of PHY on "MDIO bus" (depends on PHY hw configuration) */
298 hdkif->phy_autoneg = PHY_auto_negotiate;
299 hdkif->phy_autoneg_start = PHY_start_auto_negotiate;
300 hdkif->phy_autoneg_is_done = PHY_is_done_auto_negotiate;
301 hdkif->phy_partnerability = PHY_partner_ability_get;
305 /********************************************** initializing functions **********************************************/
307 int8_t rpp_eth_init()
310 int8_t retVal = SUCCESS;
315 /* config of EMAC instances and other stuff */
316 for(instNum = 0; instNum < MAX_EMAC_INSTANCE; instNum++)
318 hdkif_data[instNum].inst_num = instNum;
319 hdkif_inst_config(&hdkif_data[instNum]); /* hdkif_inst_config must contain instNum specific settings */
320 if(retVal = rpp_eth_hw_init(&hdkif_data[instNum]))
323 rpp_sci_printk("rpp_eth_hw_init: %d", retVal);
329 /* when one of instances was not initialized correctly return FAILURE without setting initialized variable to TRUE */
330 if(retVal)return FAILURE;
343 int8_t rpp_eth_init_postInit(uint32_t instNum, uint8_t *macArray)
345 if(postInitialized) {
348 int8_t retVal = SUCCESS;
349 struct netif *netif = &hdkNetIF[instNum];
350 u8_t mac_addr[MAC_ADDR_LEN] = RPP_MAC_ADDR;
352 /* ----- lwIP stuff ----- */
353 struct ip_addr ip_addr;
354 struct ip_addr net_mask;
355 struct ip_addr gw_addr;
356 volatile unsigned int dhcpBindWait = 0x3FFFFFFF;
360 macArray = mac_addr; /* use default MAC */
362 hdkif_macaddrset(instNum, macArray);
368 /* this can be called only within post OS init */
369 tcpip_init(NULL,NULL); /* calls lwip_init() implicitly, starts lwIP task (thread), when started function given to tcpip_init is executed first */
372 #if STATIC_IP_ADDRESS
373 ip_addr.addr = htonl(RPP_IP_ADDR);
374 net_mask.addr = htonl(RPP_NETMASK);
375 gw_addr.addr = htonl(RPP_GW);
376 #else /* STATIC_IP_ADDRESS */
380 #endif /* STATIC_IP_ADDRESS */
382 /* init and add new netif */
383 /* add new network interface to lwIP list of ifaces and initialize netif with specific function */
385 if( netif_add(netif, &ip_addr, &net_mask, &gw_addr, (void *) instNum, rpp_eth_lwip_init, ethernet_input) == NULL )
387 if( netif_add(netif, &ip_addr, &net_mask, &gw_addr, (void *) instNum, rpp_eth_lwip_init, tcpip_input) == NULL )
390 return NETIF_ADD_ERR;
393 netif_set_default(netif);
395 hdkif = (struct hdkif *) netif->state;
397 /* ----- freeRTOS elements ----- */
398 /* semaphore blocking receive task (rpp_eth_recv_raw) from receive operation, till RX interrupt occurs and notify it */
399 vSemaphoreCreateBinary(hdkif->goRX);
400 vSemaphoreCreateBinary(hdkif->goTX);
401 /* create semaphore notificating that pbuf was freed */
402 vSemaphoreCreateBinary(pbufFreed);
403 /* run task rpp_eth_recv_raw */
404 xTaskCreate( rpp_eth_recv_raw, "RXHandler", 200, netif, 0, NULL );
405 /* ----- end - freeRTOS ----- */
408 /* if we don't use link int change, then it must be done here */
409 #if !PHY_LINK_MONITOR_INT
410 if(rpp_eth_phylinkstat(hdkif->inst_num))
412 rpp_debug_printf((const char *)"cable connected ... setting IP params\r\n");
413 #if STATIC_IP_ADDRESS
415 #elif LWIP_DHCP /* STATIC_IP_ADDRESS-LWIP_DHCP */
416 if(dhcp_start(netif) != ERR_OK)
418 rpp_debug_printf("dhcp mem err\r\n");
421 rpp_debug_printf("binding DHCP\r");
422 while((netif->dhcp->state != DHCP_BOUND) && (dhcpBindWait--))/*sys_check_timeouts()*/;
424 rpp_debug_printf("dhcp binding timeout...\r\n");
425 #else /* LWIP_DHCP-LWIP_AUTOIP FIXME: there should be some kind of waiting till ip is assigned */
427 #endif /* STATIC_IP_ADDRESS-LWIP_DHCP-LWIP_AUTOIP */
429 uint8_t ipString[16];
430 rpp_eth_getIPDecimalStr(netif->ip_addr, ipString);
431 rpp_debug_printf("Address: %s\r\n", ipString);
432 rpp_eth_getIPDecimalStr(netif->netmask, ipString);
433 rpp_debug_printf("Netmask: %s\r\n", ipString);
434 rpp_eth_getIPDecimalStr(netif->gw, ipString);
435 rpp_debug_printf("Gateway: %s\r\n", ipString);
440 rpp_debug_printf((const char *)"cable not connected\r\n");
441 retVal = PHY_LINK_DOWN;
444 #else /* !PHY_LINK_MONITOR_INT */
445 /* now when we established environment needed for phy link status change we can allow it */
446 /* set PHY number which is monitored for link changes in MDIO and enable interrupt */
447 HWREG(hdkif->mdio_base + MDIO_USERPHYSEL0) = ((hdkif->phy_addr && 0x1f) | MDIO_USERPHYSEL0_LINKINTENB);
449 /* enable MISC interrupt - link monitoring in EMAC controle module */
450 HWREG(hdkif->emac_ctrl_base + EMAC_CTRL_CnMISCEN(0)) |= EMAC_CTRL_MISC_LINKINT0ENB;
452 #endif /* !PHY_LINK_MONITOR_INT */
453 /* ----- end - lwIP stuff ----- */
455 postInitialized = TRUE;
459 err_t rpp_eth_lwip_init(struct netif *netif)
461 #if LWIP_NETIF_HOSTNAME
462 /* Initialize interface hostname */
463 netif->hostname = "rpp";
464 #endif /* LWIP_NETIF_HOSTNAME */
466 uint32_t instNum = (uint32_t)netif->state;
467 /*netif->num = instNum; - auto-initiated when netif_add is called */
469 /* netif->state contained instNum, we replace it with corresponding hdkif */
470 struct hdkif *hdkif = &hdkif_data[instNum];
471 netif->state = hdkif;
473 netif->name[0] = IFNAME0;
474 netif->name[1] = IFNAME1;
477 hdkif->waitTicksForPHYAneg = TICKS_PHY_AUTONEG;
481 * Initialize the snmp variables and counters inside the struct netif.
482 * The last argument should be replaced with your link speed, in units
483 * of bits per second.
485 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000);
487 /* We directly use etharp_output() here to save a function call.
488 * You can instead declare yo_SKIP_TO_HWur own function an call etharp_output()
489 * from it if you have to do some checks before sending (e.g. if link
492 netif->output = etharp_output;
493 netif->linkoutput = rpp_eth_send;
494 return rpp_eth_hw_init_postInit(netif);
497 #define INIT_ONLY_AFTER_RESET 1
498 err_t rpp_eth_hw_init(struct hdkif *hdkif)
504 /* Deactivate reset pin of PHY */
505 /* for hw reset of PHY, it is necessary that PIN_NAME_ETHRST is 1us logical low state, before putting it to logical high */
506 #if !INIT_ONLY_AFTER_RESET
508 uint8_t index = 80; /* Initially used to hw reset of PHY connected to GIO pin. This means 1us - for 80MHz clock. */
510 uint8_t index = configCPU_CLOCK_HZ/1000000; /* Initially used to hw reset of PHY connected to GIO pin 'rpp project only'; 1us - according to PHY specification. */
512 hal_gpio_pin_set_value(*hal_gpio_pin_get_dsc(PIN_NAME_ETHRST,-1),0);
514 #endif /* !INIT_ONLY_AFTER_RESET */
515 /* we have pull-down resistor, so after reset, we only need to put ETHRST pin to log. high */
516 hal_gpio_pin_set_value(*hal_gpio_pin_get_dsc(PIN_NAME_ETHRST,-1),1);
518 /* initializes EMAC control module and EMAC module */
519 EMACInit(hdkif->emac_ctrl_base, hdkif->emac_base);
520 /* initializes MDIO module (reset) */
521 MDIOInit(hdkif->mdio_base, 0x0, 0x0);
523 /* enable used receive channel if necessary */
526 /* try to read random register from defaultPhy to make MDIO fill alive bit for this one if it returned
527 ACK bit in msg response - this must be done, because MDIO has not set alive bit of PHY after that
528 short time after MDIOInit() */
529 MDIOPhyRegRead(hdkif->mdio_base, hdkif->phy_addr, PHY_BMSR, ®Content);
531 /* find first alive PHY - or use default if alive */
532 physAlive = MDIOPhyAliveStatusGet(hdkif->mdio_base);
533 if(!(physAlive & (1 << hdkif->phy_addr)))
535 #if FIND_FIRST_PHY_ALIVE
536 for(index = 0;index < NUM_OF_PHYs;index++) /* i..PHY tested */
538 if(physAlive && (1 << index))
540 hdkif->phy_addr = index;
545 MDIOPhyRegRead(hdkif->mdio_base, index, PHY_BMCR, ®Content); /* try to 'wake up' PHY on 'index' address by reading random register, making MDIO set alive bit for current PHY */
546 physAlive = MDIOPhyAliveStatusGet(hdkif->mdio_base); /* get updated register */
547 if(physAlive && (1 << index))
549 hdkif->phy_addr = index;
556 rpp_debug_printf("no phy found, phys: %d\r\n", physAlive);
560 rpp_debug_printf("default phy not alive\r\n");
561 return DFLT_PHY_NOT_ALIVE;
565 /* start autonegotiation and check on completion later or when complete link register will be updated */
566 hdkif->phy_autoneg_start(hdkif->mdio_base, hdkif->phy_addr, PHY_100BASETXDUPL_m | PHY_100BASETX_m | PHY_10BASETDUPL_m | PHY_10BASET_m);
568 /* TODO: you can implement init of receive flow control somewhere here if desired - set RXBUFFERFLOWEN in MACCONTROL */
571 /* acknowledge EMAC control module RX, TX and MISC interrupts */
572 EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_RX);
573 EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_TX);
574 EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_MISC);
576 /* sets which channel will receive broadcasts */
577 EMACRxBroadCastEnable(hdkif->emac_base, CHANNEL);
578 /* sets channel where all frames will be copied to - either with MAC address different from local device address, either packets with error will be copied; appropriate error will be set in the frame EOP buffer descriptor */
579 EMACRxPromiscEnable(hdkif->emac_base, CHANNEL);
580 /* enables unicast */
581 EMACRxUnicastSet(hdkif->emac_base, CHANNEL);
583 /* enable TX and RX interrupts in both EMAC module and EMAC control module */
584 EMACTxIntPulseEnable(hdkif->emac_base, hdkif->emac_ctrl_base, 0, CHANNEL);
585 EMACRxIntPulseEnable(hdkif->emac_base, hdkif->emac_ctrl_base, 0, CHANNEL);
587 /* switch of send bd handling and when sending, just wait till send was done and then return (making the driver simple) */
588 //vim_mask_clr(TXinterruptVectorNumber);
593 err_t rpp_eth_hw_init_postInit(struct netif *netif)
595 volatile unsigned int autonegFinishWait = 0x3FFFFFFF; /* 0x3FFFFFFF is for 80MHz aproximately 13s */
597 uint32_t num_bd, pbuf_cnt = 0;
598 volatile struct emac_tx_bd *curr_txbd, *last_txbd;
599 volatile struct emac_rx_bd *curr_rxbd, *last_rxbd;
604 struct hdkif *hdkif = (struct hdkif *) netif->state;
606 rxch = &(hdkif->rxch);
607 txch = &(hdkif->txch);
609 rpp_debug_printf("autoneg started - check on cable if it's connected!\r\n");
613 * Initialize the Descriptor Memory For TX and RX
614 * Only Channel 0 is supported for both TX and RX
616 txch->free_head = ((volatile struct emac_tx_bd *) hdkif->emac_ctrl_ram);
617 txch->next_bd_to_process = txch->free_head;
618 txch->active_tail = NULL;
620 /* Set the number of descriptors for the channel */
621 num_bd = (SIZE_EMAC_CTRL_RAM >> 1) / sizeof(struct emac_tx_bd); /* take half of CPPI ram for TX BDs */
623 curr_txbd = txch->free_head;
625 /* Initialize all the TX buffer Descriptors */
627 curr_txbd->next = curr_txbd + 1;
628 curr_txbd->flags_pktlen = 0;
629 last_txbd = curr_txbd;
630 curr_txbd = curr_txbd->next;
632 last_txbd->next = txch->free_head;
634 /* Initialize the descriptors for the RX channel */
635 rxch->active_head = (volatile struct emac_rx_bd*)(curr_txbd);
636 rxch->free_head = NULL;
637 rxch->freed_pbuf_len = 0;
638 num_bd = ((SIZE_EMAC_CTRL_RAM >> 1) / sizeof(struct emac_rx_bd)); /* when using 20B emac_bd structs, u can allocate one more ;) ( 8192/20 = 409 together rx and tx and there is still 12 bytes remaining) */
639 curr_rxbd = rxch->active_head;
640 last_rxbd = curr_rxbd;
643 ** Allocate the pbufs for the maximum count permitted or till the
644 ** number of buffer desceriptors expire, which ever is earlier.
646 while(pbuf_cnt < MAX_RX_PBUF_ALLOC) {
647 p = pbuf_alloc(PBUF_RAW, PBUF_LEN_MAX, PBUF_POOL);
650 /* write the descriptors if there are enough numbers to hold the pbuf*/
651 if(((uint32_t)pbuf_clen(p)) <= num_bd) {
652 for(q = p; q != NULL; q = q->next) {
653 curr_rxbd->bufptr = (uint8_t *)(q->payload);
654 curr_rxbd->bufoff_len = q->len;
655 curr_rxbd->next = curr_rxbd + 1;
656 curr_rxbd->flags_pktlen = EMAC_DSC_FLAG_OWNER;
660 last_rxbd = curr_rxbd;
661 curr_rxbd = curr_rxbd->next;
666 /* free the allocated pbuf if no free descriptors are left */
678 if(!pbuf_cnt)rpp_debug_printf("no pbufs attached to rx buffer descriptors during init\n");
680 last_rxbd->next = NULL;
681 rxch->active_tail = last_rxbd;
683 num_bd = ( ((uint32_t)rxch->active_tail - (uint32_t)rxch->active_head) / sizeof(struct emac_rx_bd) + 1 );
684 rpp_debug_printf("%d pbuf chains allocated for %d rx buffer descriptors\n", pbuf_cnt, num_bd);
685 /* for flow control or QoS - there could be set an interrupt when we reach preset amount of receive descriptors remaining - see RXBUFFERFLOWEN */
686 /* EMACNumFreeBufSet(hdkif->emac_base, CHANNEL, num_bd); */ /* not used */
688 /* set header descriptor pointers - this shows EMAC which descriptor is beginning one for writing received frames/packets */
689 EMACRxHdrDescPtrWrite(hdkif->emac_base, (uint32_t)rxch->active_head, CHANNEL);
693 /* set length of MAC address */
694 netif->hwaddr_len = MAC_ADDR_LEN;
696 /* set MAC address */
697 for(regContent = 0; regContent < MAC_ADDR_LEN; regContent++) {
698 netif->hwaddr[regContent] = hdkif->mac_addr[(MAC_ADDR_LEN - 1) - regContent];
701 /* maximum transfer unit */
702 netif->mtu = MAX_TRANSFER_UNIT;
704 /* device capabilities */
705 /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
706 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
708 /* lwIP stuff - end */
710 /* for flow control frames */
711 EMACMACSrcAddrSet(hdkif->emac_base, hdkif->mac_addr);
713 /* Be sure to program all eight MAC address registers -
714 * whether the receive channel is to be enabled or not.
716 for (regContent = 0; regContent < 8; regContent++) /* i..channel_number */
717 EMACMACAddrSet(hdkif->emac_base, regContent, hdkif->mac_addr, EMAC_MACADDR_NO_MATCH_NO_FILTER);
719 #if !PHY_LINK_MONITOR_INT /* in case we don't use interrupt when phy link status changes, we need to try to finish autoneg in here */
720 /* wait for autonegotiation to be done or continue, when delay was reached */
722 uint32_t timeToWake = hdkif->waitTicksForPHYAneg + sys_jiffies();
723 while(hdkif->phy_autoneg_is_done(hdkif->mdio_base, hdkif->phy_addr) == FALSE && timeToWake > sys_jiffies())vTaskDelay(20); /* XXX: if init is not done at the startup, but couple days later, this might cause troubles */
725 while(hdkif->phy_autoneg_is_done(hdkif->mdio_base, hdkif->phy_addr) == FALSE && autonegFinishWait--); /* wait till aneg done */
728 if(hdkif->phy_autoneg_is_done(hdkif->mdio_base, hdkif->phy_addr) != FALSE)
729 rpp_debug_printf("aneg finished \r\n");
731 rpp_debug_printf("aneg timeout \r\n");
733 /* provide informations retrieved from autoneg to EMAC module */
734 hdkif->phy_partnerability(hdkif->mdio_base, hdkif->phy_addr, ®Content);
735 if (regContent & (PHY_100BASETXDUPL_m | PHY_10BASETDUPL_m)) {
736 EMACDuplexSet(hdkif->emac_base, EMAC_DUPLEX_FULL);
737 /* this is right place to implement transmit flow control if desired - set TXFLOWEN in MACCONTROL */
738 } else if (regContent & (PHY_100BASETX_m | PHY_10BASET_m)) {
739 EMACDuplexSet(hdkif->emac_base, EMAC_DUPLEX_HALF);
741 rpp_debug_printf("Unknown duplex mode\r\n");
742 return UNKN_DUPLEX_MODE;
744 #endif /* !PHY_LINK_MONITOR_INT */
746 /* enable hostpend interrupts in emac module */
747 HWREG(hdkif->emac_base + EMAC_MACINTMASKSET) |= EMAC_MACINTMASKSET_HOSTMASK;
749 /* enable hostpend interrupts in emac control module */
750 HWREG(hdkif->emac_ctrl_base + EMAC_CTRL_CnMISCEN(0)) |= EMAC_CTRL_MISC_HOSTPENDENB;
752 /* enable EMAC's Media Independent Interface TX and RX */
753 EMACMIIEnable(hdkif->emac_base);
754 /* enable EMAC transmit */
755 EMACTxEnable(hdkif->emac_base);
756 /* enable EMAC receive */
757 EMACRxEnable(hdkif->emac_base);
775 /********************************************** send and receive functions / ISRs **********************************************/
777 err_t rpp_eth_send(struct netif * netif, struct pbuf *p)
779 err_t retVal = SUCCESS;
780 SYS_ARCH_DECL_PROTECT(lev);
783 * This entire function must run within a "critical section" to preserve
784 * the integrity of the transmit pbuf queue.
787 SYS_ARCH_PROTECT(lev);
789 /* protect from access receive acces from interrupt */
790 #if !SYS_LIGHTWEIGHT_PROT
791 uint32_t prevProt = (uint32_t) _get_CPSR() & 0x80;
796 /* adjust the packet length if less than minimum required */
797 if(p->tot_len < MIN_PKT_LEN) {
798 p->tot_len = MIN_PKT_LEN;
799 p->len = MIN_PKT_LEN;
802 /* call the actual transmit function */
803 retVal = rpp_eth_send_raw(netif, p);
805 /* Return to prior interrupt state and return. */
806 SYS_ARCH_UNPROTECT(lev);
808 #if !SYS_LIGHTWEIGHT_PROT
809 if(!prevProt)_enable_IRQ();
816 * send packet, blocks till it is sent
817 * every send uses bds on the beginning of CPPI RAM
819 err_t rpp_eth_send_raw(struct netif *netif, struct pbuf *p)
822 volatile struct emac_tx_bd *curr_bd, *bd_end;
825 hdkif = (struct hdkif *) netif->state;
826 curr_bd = (struct emac_tx_bd *) hdkif->emac_ctrl_ram;
828 /* destroy all flags previously set and update the total packet length */
829 curr_bd->flags_pktlen = p->tot_len;
831 /* Indicate the start of the packet */
832 curr_bd->flags_pktlen |= (EMAC_DSC_FLAG_SOP | EMAC_DSC_FLAG_OWNER);
834 /* Copy pbuf information into TX buffer descriptors */
835 for(q = p; q != NULL; q = q->next) {
837 /* Intialize the buffer pointer and length */
838 curr_bd->bufptr = (uint8_t *)(q->payload);
839 curr_bd->bufoff_len = (q->len) & 0xFFFF;
842 curr_bd = curr_bd->next;
843 curr_bd->flags_pktlen = 0x0; /* destroy all previously set flags */
846 /* Indicate the end of the packet */
848 bd_end->flags_pktlen |= EMAC_DSC_FLAG_EOP;
850 /* don't write to hdp till it turns zero */
851 while (0 != *((volatile uint32_t *) (hdkif->emac_base + EMAC_TXHDP(CHANNEL)) ));
852 /* notify hw where to start transmission from */
853 HWREG(hdkif->emac_base + EMAC_TXHDP(CHANNEL)) = hdkif->emac_ctrl_ram;
854 //EMACTxHdrDescPtrWrite(hdkif->emac_base, hdkif->emac_ctrl_ram, CHANNEL);
856 /* wait till queued pkt is sent */
857 vim_mask_set(TXinterruptVectorNumber);
858 xSemaphoreTake(hdkif->goTX, portMAX_DELAY);
859 while (!(bd_end->flags_pktlen & EMAC_DSC_FLAG_EOQ) || (((struct emac_tx_bd *)(hdkif->emac_ctrl_ram))->flags_pktlen & EMAC_DSC_FLAG_OWNER))rpp_sci_printk("!");
861 EMACTxCPWrite(hdkif->emac_base, CHANNEL, (uint32_t) bd_end);
863 EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_TX);
865 /* restore bds chain */
866 bd_end->next = curr_bd;
868 LINK_STATS_INC(link.xmit);
872 void rpp_eth_recv_raw(void *arg)
874 volatile struct emac_rx_bd *curr_bd, *processed_bd, *curr_tail, *last_bd;
875 volatile struct pbuf *pbuf, *q, *new_pbuf;
876 uint32_t ex_len, len_to_alloc;
878 struct netif *netif = (struct netif *) arg;
879 struct hdkif *hdkif = (struct hdkif *) netif->state;
882 rxch = &(hdkif->rxch);
885 #if !NO_SYS && !ONE_DRIVER_TASK
886 SYS_ARCH_DECL_PROTECT(lev);
889 vim_mask_set(RXinterruptVectorNumber);
890 sys_arch_sem_wait(&(hdkif->goRX), 0);
891 SYS_ARCH_PROTECT(lev);
895 /* Get the bd which contains the earliest filled data */
896 curr_bd = rxch->active_head;
897 last_bd = rxch->active_tail;
899 if(curr_bd->flags_pktlen & EMAC_DSC_FLAG_SOP != EMAC_DSC_FLAG_SOP)rpp_debug_printf("ERR: Active head is not SOP!\n");
902 * Process the descriptors as long as data is available
903 * when the DMA is receiving data, SOP flag will be set
905 while(curr_bd->flags_pktlen & EMAC_DSC_FLAG_SOP)
909 /* Start processing once the packet is loaded */
910 if((curr_bd->flags_pktlen & EMAC_DSC_FLAG_OWNER) != EMAC_DSC_FLAG_OWNER)
912 if(rxch->free_head == NULL)
914 /* this bd chain will be freed after processing */
915 rxch->free_head = curr_bd;
918 /* Get the total length of the packet. curr_bd points to the start
921 tot_len = (curr_bd->flags_pktlen) & 0xFFFF;
923 /* Get the start of the pbuf queue */
927 /* Get the pbuf pointer which is associated with the current bd */
928 pbuf = curr_bd->pbuf;
930 /* If the earlier pbuf ended, update the chain */
931 if(pbuf->next == NULL)
933 pbuf->next = (struct pbuf*)(curr_bd->next)->pbuf;
936 len_to_alloc += pbuf->len;
937 /* Update the len and tot_len fields for the pbuf in the chain*/
938 pbuf->len = (curr_bd->bufoff_len) & 0xFFFF;
939 pbuf->tot_len = tot_len - ex_len ;
940 processed_bd = curr_bd;
942 curr_bd = curr_bd->next;
944 if(curr_bd == NULL)rpp_debug_printf("rx curr_bd set to zero!\n");
946 /* FIXME: curr_bd here could be NULL - (currently solved by having always allocated enough pbufs -> waiting for pbuf_free() function) a solution could be: we need to keep at least TCP_MSS bytes, so allocate at least that if not possible block */
947 } while((processed_bd->flags_pktlen & EMAC_DSC_FLAG_EOP) != EMAC_DSC_FLAG_EOP);
950 * Close the chain for this pbuf. A full packet is received in
951 * this pbuf chain. Now this pbuf can be given to upper layers for
952 * processing. The start of the pbuf chain is now 'q'.
956 /* Adjust the link statistics */
957 LINK_STATS_INC(link.recv);
959 /* Process the packet - this function is specified while adding netif using netif_add() function */
960 if(netif->input((struct pbuf *)q, netif) != ERR_OK)
962 /* Adjust the link statistics */
963 LINK_STATS_INC(link.memerr);
964 LINK_STATS_INC(link.drop);
967 /* Acknowledge that this packet is processed */
968 EMACRxCPWrite(hdkif->emac_base, CHANNEL, (unsigned int)processed_bd);
972 rxch->active_head = curr_bd;
976 rxch->active_head = processed_bd + 1; //todo:reconsider
980 * The earlier pbuf chain is freed from the upper layer. So, we need to
981 * allocate a new pbuf chain and update the descriptors with the pbuf info.
982 * To support chaining, the total length freed by the upper layer is tracked.
983 * Care should be taken even if the allocation fails.
986 * now len_to_alloc will contain the length of the pbuf which was freed
987 * from the upper layer
989 rxch->freed_pbuf_len += len_to_alloc;
991 /* if there is not enough pbufs predefined, we need application to process them and return them back to pool -> YIELD */
992 /* XXX: this is not fixed in NO_SYS version - problem is when curr_bd is set to NULL (see above), and we don't obtain new_pbuf
993 * from pool, then in *bd pointing to NULL might be such values (EMAC_DSC_FLAG_SOP == 1 &| EMAC_DSC_FLAG_OWNER == 0), that we
994 * stay cycling around */
998 new_pbuf = pbuf_alloc(PBUF_RAW, (rxch->freed_pbuf_len), PBUF_POOL);
1000 if(new_pbuf != NULL)
1003 xSemaphoreTake(pbufFreed, 0);
1004 xSemaphoreTake(pbufFreed, portMAX_DELAY);
1008 /* Write the descriptors with the pbuf info till either of them expires */
1009 if(new_pbuf != NULL)
1011 curr_bd = rxch->free_head;
1013 for(q = new_pbuf; (q != NULL) && (curr_bd != rxch->active_head); q = q->next)
1015 curr_bd->bufptr = (uint8_t *)(q->payload);
1017 /* no support for buf_offset. RXBUFFEROFFSET register is 0 */
1018 curr_bd->bufoff_len = (q->len) & 0xFFFF;
1019 curr_bd->flags_pktlen = EMAC_DSC_FLAG_OWNER;
1021 rxch->freed_pbuf_len -= q->len;
1026 curr_bd = curr_bd->next;
1030 * At this point either pbuf expired or no rxbd to allocate. If
1031 * there are no, enough rx bds to allocate all pbufs in the chain,
1032 * free the rest of the pbuf
1036 pbuf_free((struct pbuf *)q);
1039 curr_tail = rxch->active_tail;
1040 last_bd->next = NULL;
1042 curr_tail->next = rxch->free_head;
1045 * Check if the reception has ended. If the EOQ flag is set, the NULL
1046 * Pointer is taken by the DMA engine. So we need to write the RX HDP
1047 * with the next descriptor.
1049 if(curr_tail->flags_pktlen & EMAC_DSC_FLAG_EOQ)
1051 EMACRxHdrDescPtrWrite(hdkif->emac_base, (u32_t)(rxch->free_head), CHANNEL);
1054 rxch->free_head = curr_bd;
1055 rxch->active_tail = last_bd;
1058 curr_bd = rxch->active_head;
1060 EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_RX);
1062 #if !NO_SYS && !ONE_DRIVER_TASK
1063 SYS_ARCH_UNPROTECT(lev);
1068 void RxIntHandler(u32_t instNum)
1071 vim_mask_clr(RXinterruptVectorNumber);
1073 static portBASE_TYPE xHigherPriorityTaskWoken;
1074 xHigherPriorityTaskWoken = pdFALSE;
1076 /* 'Give' the semaphore to unblock the task. */
1077 xSemaphoreGiveFromISR(hdkif_data[instNum].goRX, NULL); // whenever there is time to process received packets, wake up task processing them
1079 if( xHigherPriorityTaskWoken == pdTRUE )
1082 /* Giving the semaphore unblocked a task, and the priority of the
1083 unblocked task is higher than or equal to the currently running task
1084 - force a context switch to ensure that the interrupt returns directly
1085 to the unblocked (higher priority) task.
1086 NOTE: The actual macro to use to force a context switch from an
1087 ISR is dependent on the port. This is the correct macro for the
1088 Open Watcom DOS port. Other ports may require different syntax.
1089 Refer to the examples provided for the port being used to determine
1090 the syntax required. */
1092 portSWITCH_CONTEXT();
1096 rpp_eth_recv_raw((void *) &hdkNetIF[instNum]);
1100 void TxIntHandler(u32_t instNum)
1102 //struct hdkif *hdkif = &hdkif_data[instNum];
1104 vim_mask_clr(TXinterruptVectorNumber); /* see sys_startup.c */
1105 xSemaphoreGiveFromISR(hdkif_data[instNum].goTX, NULL);
1108 //rpp_eth_send_bd_handler((void *) &hdkif_data[instNum]);
1116 * 1h SOP error; the buffer is the first buffer in a packet, but the SOP bit is not set in software.
1117 * 2h Ownership bit not set in SOP buffer
1118 * 3h Zero next buffer descriptor pointer without EOP
1119 * 4h Zero buffer pointer
1120 * 5h Zero buffer length
1121 * 6h Packet length error (sum of buffers is less than packet length)
1128 * 2h Ownership bit not set in SOP buffer
1130 * 4h Zero buffer pointer
1132 boolean_t HostPendErrHandler(void)
1134 uint8_t index = MAX_EMAC_INSTANCE, errFound = FALSE;
1136 struct hdkif *hdkif;
1139 hdkif = &hdkif_data[--index];
1140 if(EMACIntVectorGet(hdkif->emac_base) & EMAC_MACINVECTOR_HOSTPEND)errFound = TRUE;
1142 if(!errFound)return FALSE; /* this is not the cause of the interrupt */
1143 rpp_sci_printk("HOSTPEND err\n");
1144 reg = HWREG(hdkif->emac_base + EMAC_MACSTATUS);
1145 rpp_sci_printk("TXCHERR: %d at CH: %d\n", ((reg >> EMAC_MACSTATUS_TXERRCODE_SHIFT) & 0x7), ((reg >> EMAC_MACSTATUS_TXERRCH_SHIFT) & 0x7));
1146 rpp_sci_printk("RXCHERR: %d at CH: %d\n", ((reg >> EMAC_MACSTATUS_RXERRCODE_SHIFT) & 0x7), ((reg >> EMAC_MACSTATUS_RXERRCH_SHIFT) & 0x7));
1147 /* no acknowledge - emac module has to be restarted */
1148 return TRUE; /* this was the reason of interrupt */
1151 #if PHY_LINK_MONITOR_INT
1152 boolean_t LinkIntHandler(void)
1154 uint8_t index = MAX_EMAC_INSTANCE, phyFound = FALSE;
1155 struct hdkif *hdkif;
1156 uint16_t regContent;
1157 volatile unsigned int autonegFinishWait = 0xFFFFFFF;
1158 volatile unsigned int dhcpBindWait = 0x3FFFFFFF;
1160 /* check each instance, whether this interrupt was meant for this function, if not return FALSE so other function may be tried */
1162 hdkif = &hdkif_data[--index];
1163 if( hdkif->phy_addr == (HWREG(hdkif->mdio_base + MDIO_USERPHYSEL0) & 0x1f) && EMACIntVectorGet(hdkif->emac_base) & EMAC_MACINVECTOR_LINKINT0 )phyFound = TRUE;
1165 if(!phyFound)return FALSE;
1166 struct netif *netif = &hdkNetIF[hdkif->inst_num];
1168 /* we handles here connection of cable after startup, not changes of linkstatus */
1170 /* wait for autonegotiation to be done */
1172 while(hdkif->phy_autoneg_is_done(hdkif->mdio_base, hdkif->phy_addr) == FALSE);
1173 #else /* ONCE_LINK_SETUP */
1174 while(hdkif->phy_autoneg_is_done(hdkif->mdio_base, hdkif->phy_addr) == FALSE & autonegFinishWait--);
1175 #endif /* ONCE_LINK_SETUP */
1177 /* provide informations retrieved from autoneg to EMAC module */
1178 hdkif->phy_partnerability(hdkif->mdio_base, hdkif->phy_addr, ®Content);
1179 if (regContent & (PHY_100BASETXDUPL_m | PHY_10BASETDUPL_m)) {
1180 EMACDuplexSet(hdkif->emac_base, EMAC_DUPLEX_FULL);
1181 /* this is right place to implement transmit flow control if desired - set TXFLOWEN in MACCONTROL */
1182 } else if (regContent & (PHY_100BASETX_m | PHY_10BASET_m)) {
1183 EMACDuplexSet(hdkif->emac_base, EMAC_DUPLEX_HALF);
1185 /* acknowledge MDIO module */
1186 HWREG(hdkif->mdio_base + MDIO_LINKINTRAW) = MDIO_LINKINTMASKED_USERPHY0;
1187 HWREG(hdkif->mdio_base + MDIO_LINKINTMASKED) = MDIO_LINKINTMASKED_USERPHY0;
1189 /* acknowledge EMAC control module by writing appropriate key to MACEOIVECTOR */
1190 EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_MISC);
1193 /* if link is up configure lwip struct netif */
1194 if(rpp_eth_phylinkstat(hdkif->inst_num))
1196 #if STATIC_IP_ADDRESS
1197 netif_set_up(netif);
1198 #elif LWIP_DHCP /* STATIC_IP_ADDRESS-LWIP_DHCP */
1199 if(dhcp_start(netif) != ERR_OK) /* XXX: can't be used from ISR (mem_malloc()) */
1201 return DHCP_MEM_ERR;
1204 while(netif->dhcp->state != DHCP_BOUND);
1206 while(netif->dhcp->state != DHCP_BOUND & dhcpBindWait--);
1209 /* acknowledge MDIO module */
1210 HWREG(hdkif->mdio_base + MDIO_LINKINTRAW) = MDIO_LINKINTMASKED_USERPHY0;
1211 HWREG(hdkif->mdio_base + MDIO_LINKINTMASKED) = MDIO_LINKINTMASKED_USERPHY0;
1213 /* acknowledge EMAC control module by writing appropriate key to MACEOIVECTOR */
1214 EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_MISC);
1218 #else /* LWIP_DHCP-LWIP_AUTOIP FIXME: there should be some kind of waiting till ip is assigned */
1219 autoip_start(netif);
1220 #endif /* STATIC_IP_ADDRESS-LWIP_DHCP-LWIP_AUTOIP */
1222 /* turn this interrupt off */
1223 HWREG(hdkif->emac_ctrl_base + EMAC_CTRL_CnMISCEN(0)) &= (~EMAC_CTRL_MISC_LINKINT0ENB & 0xf);
1224 #endif /* ONCE_LINK_SETUP */
1229 /* acknowledge MDIO module */
1230 HWREG(hdkif->mdio_base + MDIO_LINKINTRAW) = MDIO_LINKINTMASKED_USERPHY0;
1231 HWREG(hdkif->mdio_base + MDIO_LINKINTMASKED) = MDIO_LINKINTMASKED_USERPHY0;
1233 /* acknowledge EMAC control module by writing appropriate key to MACEOIVECTOR */
1234 EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_MISC);
1237 #if STATIC_IP_ADDRESS
1238 netif_set_down(netif);
1239 #elif LWIP_DHCP /* STATIC_IP_ADDRESS-LWIP_DHCP */
1241 #endif /* STATIC_IP_ADDRESS-LWIP_DHCP-LWIP_AUTOIP */
1245 /* acknowledge MDIO module */
1246 HWREG(hdkif->mdio_base + MDIO_LINKINTRAW) = MDIO_LINKINTMASKED_USERPHY0;
1247 HWREG(hdkif->mdio_base + MDIO_LINKINTMASKED) = MDIO_LINKINTMASKED_USERPHY0;
1249 /* acknowledge EMAC control module by writing appropriate key to MACEOIVECTOR */
1250 EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_MISC);
1254 #endif /* PHY_LINK_MONITOR_INT */
1256 #endif /* rppCONFIG_INCLUDE_ETH */