]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/rpp/eth.c
Merge branch 'master' of git@rtime.felk.cvut.cz:pes-rpp/rpp-lib into personal/vajnama...
[pes-rpp/rpp-lib.git] / rpp / src / rpp / eth.c
1 /**
2  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
3  * Copyright (C) 2013-2015 Czech Technical University in Prague
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without modification,
7  * are permitted provided that the following conditions are met:
8  *
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.
16  *
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
26  * OF SUCH DAMAGE.
27  *
28  * This file is part of the lwIP TCP/IP stack.
29  *
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>
34  *
35  */
36
37 /**
38  * Copyright (c) 2010 Texas Instruments Incorporated
39  *
40  * This file is dervied from the "ethernetif.c" skeleton Ethernet network
41  * interface driver for lwIP.
42  *
43  */
44
45 #include "rpp/rpp.h"
46
47 #ifndef FREERTOS_POSIX
48
49 /* lwIP headers */
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 */
56 #include "lwip/def.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 */
62
63 #include "hal/hal.h"
64 #include "sys/sys.h" /* includes - sys/phy_dp83848h.h */
65 #include "drv/emac.h"
66 #include "os/os.h"
67 #include "types.h"
68
69
70 /* Number of EMAC Instances */
71 #define MAX_EMAC_INSTANCE                       1
72
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
76
77 /* Size of the Buffer descriptor defined by the EMAC in bytes */
78 #define SIZE_OF_DESC                            16
79
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) */
82 #define CHANNEL                                 0
83
84 /* take in account oversized frames */
85 #define MAX_TRANSFER_UNIT                       1500
86
87 /* WARNING!
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
103  * (256 B, 88 B).
104  * This is the implementation limitation. The PBUF_LEN_MAX should therefore
105  * be multiple of PBUF_POOL_BUFSIZE
106  */
107 #define PBUF_LEN_MAX                            (PBUF_POOL_BUFSIZE * 6)
108
109 /* Maximum number of PBUFs preallocated in the driver
110  * init function to be used for the RX
111  */
112 #define MAX_RX_PBUF_ALLOC                       10
113 #define MIN_PKT_LEN                             60
114
115 /* Define those to better describe the network interface. */
116 #define IFNAME0                                 'e'
117 #define IFNAME1                                 'n'
118
119 /* Time to wait for autonegotiation in ticks. */
120 #define TICKS_PHY_AUTONEG                       4000
121
122 /**
123  * TODO -- not implemented
124  * When cable is connected (link status goes up)
125  * autonegotiation and/or dhcp is started.
126  */
127 #define PHY_LINK_MONITOR_INT                    0
128
129
130 /* Statically allocated structure describing interface state -- one per instance */
131 static struct hdkif hdkif_data[MAX_EMAC_INSTANCE];
132
133 /* The lwIP network interface structure for the HDK Ethernet MAC. */
134 static struct netif hdkNetIF[MAX_EMAC_INSTANCE];
135
136 /* RPP startup init indicator */
137 static boolean_t initialized = FALSE;
138 static boolean_t postInitialized = FALSE;
139
140 /***testing functions**********************************************/
141 boolean_t isPostInitialized()
142 {
143         return postInitialized;
144 }
145
146 uint32_t rpp_eth_phylinkstat(uint32_t instNum)
147 {
148         struct hdkif *hdkif = &hdkif_data[instNum];
149         return PHY_link_status_get(hdkif->mdio_base, hdkif->phy_addr, 1);
150 }
151
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)
156 {
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);
166         }
167         macStr[outindex] = '\0';
168 }
169
170 /* @param ip will be filled accroding to content of ipstr */
171 err_t rpp_eth_stringToIP(ip_addr_t * ip, uint8_t * ipstr)
172 {
173         uint8_t charProccessed, index = 0, dotindex = 0xff, tmp = 0, dots = 0, fldEdit = 0;
174         uint32_t ipaddr = 0;
175         for(charProccessed = ipstr[index]; (charProccessed >= '0' && charProccessed <= '9') || charProccessed == '.' ; charProccessed = ipstr[++index])
176         {
177                 if(charProccessed == '.')
178                 {
179                         if(++dotindex == index)
180                         {
181                                 dots = 0;
182                                 break;
183                         }
184                         dotindex = index;
185
186                         ipaddr = (ipaddr << 8) + tmp;
187
188                         dots++;
189                         if(dots > 3)break;
190
191                         tmp = 0;
192                         fldEdit = FALSE;
193                 }
194                 else
195                 {
196                         fldEdit = TRUE;
197                         tmp = tmp*10 + charProccessed - '0';
198                 }
199         }
200         if(dots != 3 || !fldEdit)
201         {
202                 /* if unsuccesful, don't modify previous content */
203                 return FAILURE;
204         }
205         ipaddr = (ipaddr << 8) + tmp;
206         ip->addr = ipaddr;
207         return SUCCESS;
208 }
209
210 /* returns number in range 0-65535 where 0 is error */
211 uint16_t rpp_eth_portStrToInt(uint8_t *string)
212 {
213         uint8_t index;
214         uint16_t portNO = 0;
215         for(index = 0;string[index] != '\0';index++)
216         {
217                 if(string[index] < '0' || string[index] > '9')
218                 {
219                         portNO = 0;
220                         break;
221                 }
222                 portNO = portNO * 10 + string[index] - '0';
223         }
224         return portNO;
225 }
226
227 struct netif *rpp_eth_get_netif(uint32_t instNum)
228 {
229         return &hdkNetIF[instNum];
230 }
231
232 /***** forward declarations **********************************************/
233
234 /*
235  * interface initializes
236  */
237 err_t rpp_eth_lwip_init(struct netif *netif);
238
239 /*
240  * Initializes hw such as PHY, MDIO, EMAC, EMAC control module
241  *
242  * @return SUCCESS if initialization successful.\n
243  *         FAILURE if initialization not successful.
244  */
245 err_t rpp_eth_hw_init(struct hdkif *hdkif);
246
247 /*
248  * Initializes hw, after lwIP was initialized and
249  * OS was initialized in case OS is used.
250  */
251 err_t rpp_eth_hw_init_postInit(struct netif *netif);
252
253 /***** utility functions **********************************************/
254
255 /*
256 * Function to set the MAC address to the interface
257 * @param   inst_num the instance number
258 *
259 * @note    mac_addr[0] is considered MSB
260 */
261 static void hdkif_macaddrset(u32_t inst_num, u8_t *mac_addr)
262 {
263         struct hdkif *hdkif;
264         u32_t temp;
265
266         hdkif = &hdkif_data[inst_num];
267
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];
271         }
272 #ifdef DEBUG
273         uint8_t macStr[18];
274         rpp_eth_get_macAddrStr(inst_num, macStr);
275         rpp_debug_printf("Setting MAC... %s\r\n", macStr);
276 #endif
277 }
278
279 /**
280 * Function to setup the instance parameters inside the interface
281 * @param   hdkif
282 * @return  none.
283 */
284 static void hdkif_inst_config(struct hdkif *hdkif)
285 {
286         if (hdkif->inst_num == 0)
287         {
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);
292
293                 /* Default address of PHY on "MDIO bus"
294                  * (depends on PHY hw configuration)
295                  */
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;
301         }
302 }
303
304 /***** initializing functions **********************************************/
305 int8_t rpp_eth_init()
306 {
307         unsigned int instNum;
308         int8_t retVal = SUCCESS;
309
310         if (initialized)
311                 return FAILURE;
312
313         /* Config each EMAC instance */
314         for (instNum = 0; instNum < MAX_EMAC_INSTANCE; instNum++)
315         {
316                 struct hdkif *hdkif = &hdkif_data[instNum];
317
318                 hdkif->inst_num = instNum;
319                 hdkif_inst_config(hdkif);
320
321                 retVal = rpp_eth_hw_init(hdkif);
322                 if (retVal != SUCCESS) {
323                         rpp_debug_printf("rpp_eth_hw_init: %d", retVal);
324                         return FAILURE;
325                 }
326         }
327
328         initialized = TRUE;
329         return retVal;
330 }
331
332 int8_t rpp_eth_init_postInit(uint32_t instNum, uint8_t *macArray)
333 {
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;
339         int ret;
340         struct netif *netif = &hdkNetIF[instNum];
341         struct netif *netif_tmp;
342         u8_t mac_addr[MAC_ADDR_LEN] = RPP_MAC_ADDR;
343         struct hdkif *hdkif;
344
345         if (postInitialized)
346                 return FAILURE;
347
348         if (macArray == NULL)
349                 macArray = mac_addr; /* use default MAC */
350
351         hdkif_macaddrset(instNum, macArray);
352
353 #if NO_SYS
354         lwip_init();
355 #else
356         /* This can be called only within post OS init */
357
358         /*
359          * calls lwip_init() implicitly, starts lwIP task (thread),
360          * when started function given to tcpip_init is executed first
361          */
362         tcpip_init(NULL, NULL);
363 #endif
364
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);
369 #else
370         ip_addr.addr = 0;
371         net_mask.addr = 0;
372         gw_addr.addr = 0;
373 #endif
374
375 #if NO_SYS
376         /* Add new network interface to lwIP list of ifaces
377          * and initialize netif with specific function
378          */
379         netif_tmp = netif_add(netif, &ip_addr, &net_mask, &gw_addr,
380                               &hdkif_data[instNum], rpp_eth_lwip_init,
381                               ethernet_input);
382 #else
383         netif_tmp = netif_add(netif, &ip_addr, &net_mask, &gw_addr,
384                               &hdkif_data[instNum], rpp_eth_lwip_init,
385                               tcpip_input);
386 #endif
387         if (netif_tmp == NULL)
388                 return NETIF_ADD_ERR;
389
390         netif_set_default(netif);
391
392         hdkif = netif->state;
393
394 #if !NO_SYS
395         /* Semaphores used to block/unblock RX/TX threads doing the
396          * 'deferred' RX/TX handling -- semgive is callend in RX/TX ISR
397          */
398         vSemaphoreCreateBinary(hdkif->goRX);
399         vSemaphoreCreateBinary(hdkif->goTX);
400
401         xTaskCreate(rpp_eth_recv_raw_thr, "RXHandler", 500, netif, 0, NULL);
402         xTaskCreate(rpp_eth_send_raw_thr, "TXHandler", 500, netif, 0, NULL);
403 #endif
404
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");
409
410   #if STATIC_IP_ADDRESS
411                 netif_set_up(netif);
412   #elif LWIP_DHCP
413                 ret = dhcp_start(netif);
414                 if (ret != ERR_OK) {
415                         rpp_debug_printf("dhcp mem err\r\n");
416                         return DHCP_MEM_ERR;
417                 }
418
419                 rpp_debug_printf("binding DHCP\r");
420                 while ((netif->dhcp->state != DHCP_BOUND) && (dhcpBindWait--))
421                         ; /* FIXME: sys_check_timeouts()*/
422
423                 if (!dhcpBindWait)
424                         rpp_debug_printf("dhcp binding timeout...\r\n");
425   #else /* FIXME there should be some kind of waiting until IP address is assigned */
426                 autoip_start(netif);
427   #endif
428
429   #ifdef DEBUG
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);
437   #endif
438
439         } else {
440                 rpp_debug_printf("cable not connected\r\n");
441                 retVal = PHY_LINK_DOWN;
442         }
443
444 #else /* !PHY_LINK_MONITOR_INT */
445         /* Link Status change handled in an interrupt -- NOT IMPLEMENTED */
446
447         /*
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
451          */
452         HWREG(hdkif->mdio_base + MDIO_USERPHYSEL0) =
453                 ((hdkif->phy_addr && 0x1f) | MDIO_USERPHYSEL0_LINKINTENB);
454
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;
458
459 #endif /* !PHY_LINK_MONITOR_INT */
460
461         postInitialized = TRUE;
462         return retVal;
463 }
464
465 err_t rpp_eth_lwip_init(struct netif *netif)
466 {
467         struct hdkif *hdkif = netif->state;
468
469 #if LWIP_NETIF_HOSTNAME
470         netif->hostname = "rpp";
471 #endif
472         netif->state = hdkif;
473
474         netif->name[0] = IFNAME0;
475         netif->name[1] = IFNAME1;
476
477 #if !NO_SYS
478         hdkif->waitTicksForPHYAneg = TICKS_PHY_AUTONEG;
479 #endif
480
481         /*
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.
485          */
486         NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000);
487
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
491          * is available...)
492          */
493         netif->output = etharp_output;
494         netif->linkoutput = rpp_eth_send;
495
496         return rpp_eth_hw_init_postInit(netif);
497 }
498
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)
501 {
502         uint8_t index;
503         uint16_t regContent;
504         uint32_t physAlive;
505
506         /* Deactivate reset pin of PHY */
507         /*
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
510          */
511 #if !INIT_ONLY_AFTER_RESET
512 #if NO_SYS
513         /*
514          * Initially used to hw reset of PHY connected to GIO pin.
515          * This means 1us - for 80MHz clock.
516          */
517         index = 80;
518 #else /* NO_SYS */
519         /*
520          * Initially used to hw reset of PHY connected to GIO pin
521          * 'rpp project only'; 1us - according to PHY specification.
522          */
523         index = configCPU_CLOCK_HZ/1000000;
524 #endif /* NO_SYS */
525         hal_gpio_pin_set_value(*hal_gpio_pin_get_dsc(PIN_NAME_ETHRST, -1), 0);
526         while(index--)
527                 ;
528 #endif /* !INIT_ONLY_AFTER_RESET */
529
530         /*
531          * We have pull-down resistor, so after reset, we only need
532          * to put ETHRST pin to log. high
533          */
534         hal_gpio_pin_set_value(*hal_gpio_pin_get_dsc(PIN_NAME_ETHRST, -1), 1);
535
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);
540
541         /*
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()
546          */
547         MDIOPhyRegRead(hdkif->mdio_base, hdkif->phy_addr, PHY_BMSR, &regContent);
548
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;
556                                 break;
557                         } else {
558                                 /*
559                                  * Try to 'wake up' PHY on 'index' address by
560                                  * reading random register, making MDIO set
561                                  * alive bit for current PHY
562                                  */
563                                 MDIOPhyRegRead(hdkif->mdio_base, index,
564                                                 PHY_BMCR, &regContent);
565
566                                 /* Get updated register */
567                                 physAlive = MDIOPhyAliveStatusGet(hdkif->mdio_base);
568                                 if (physAlive && (1 << index)) {
569                                         hdkif->phy_addr = index;
570                                         break;
571                                 }
572                         }
573                 }
574
575                 if (!physAlive) { /* FIXME je to ok? */
576                         rpp_debug_printf("no phy found, phys: %d\n", physAlive);
577                         return NO_PHY_ALIVE;
578                 }
579 #else
580                 rpp_debug_printf("default phy not alive\n");
581                 return DFLT_PHY_NOT_ALIVE;
582 #endif
583         }
584
585         /*
586          * Start autonegotiation and check on completion later or
587          * when complete link register will be updated
588          */
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);
592
593         /*
594          * TODO: you can implement init of receive flow control somewhere
595          * here if desired - set RXBUFFERFLOWEN in MACCONTROL
596          */
597
598
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);
603
604         /* Sets which channel will receive broadcasts */
605         EMACRxBroadCastEnable(hdkif->emac_base, CHANNEL);
606
607         /*
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
612          */
613         EMACRxPromiscEnable(hdkif->emac_base, CHANNEL);
614
615         /* Enable unicast */
616         EMACRxUnicastSet(hdkif->emac_base, CHANNEL);
617
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);
621
622         return SUCCESS;
623 }
624
625 static err_t rpp_eth_hw_init_postInit(struct netif *netif)
626 {
627         /* 0x3FFFFFFF is for 80MHz aproximately 13s */
628         volatile unsigned int autonegFinishWait = 0x3FFFFFFF;
629
630         uint16_t regContent;
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;
634         struct pbuf *p, *q;
635         struct rxch *rxch;
636         struct txch *txch;
637
638         struct hdkif *hdkif = (struct hdkif *)netif->state;
639
640         rxch = &(hdkif->rxch);
641         txch = &(hdkif->txch);
642
643         rpp_debug_printf("autoneg started -- check on cable if it's connected!\r\n");
644
645         /*
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
657          */
658
659         /*
660          * Initialize the Descriptor Memory For TX and RX
661          * Only Channel 0 is supported for both TX and RX
662          */
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;
666
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));
670
671         curr_txbd = txch->free_head;
672
673         /* Initialize all the TX buffer Descriptors */
674         while (num_bd--) {
675                 curr_txbd->next = curr_txbd + 1;
676                 curr_txbd->flags_pktlen = 0;
677                 last_txbd = curr_txbd;
678                 curr_txbd = curr_txbd->next;
679         }
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
683          */
684
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;
689
690         num_bd = ((SIZE_EMAC_CTRL_RAM >> 1) / sizeof(struct emac_rx_bd));
691         curr_rxbd = rxch->active_head;
692         last_rxbd = curr_rxbd;
693
694          /* Allocate the pbufs for the maximum count permitted or
695           * till the number of buffer descriptors expire,
696           * whichever is earlier.
697           */
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);
701                 if (p != NULL) {
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;
711
712                                         /* Save the pbuf */
713                                         curr_rxbd->pbuf = q;
714                                         last_rxbd = curr_rxbd;
715                                         curr_rxbd = curr_rxbd->next;
716                                         num_bd--;
717                                 }
718                         } else {
719                                 /* free the allocated pbuf if no free
720                                  * descriptors are left */
721                                 pbuf_free(p);
722                                 break;
723                         }
724                 } else {
725                         break;
726                 }
727                 pbuf_cnt++;
728         }
729         if (!pbuf_cnt)
730                 rpp_sci_printf("No pbufs attached to RX BD during init\n");
731
732         last_rxbd->next = NULL;
733         rxch->active_tail = last_rxbd;
734
735 #ifdef DEBUG
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",
739                          pbuf_cnt, num_bd);
740 #endif
741
742         /* Set header descriptor pointers -- this shows EMAC which descriptor
743          * is the first one for writing received frames/packets
744          */
745         EMACRxHdrDescPtrWrite(hdkif->emac_base, (uint32_t)rxch->active_head, CHANNEL);
746
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];
752         }
753
754         /* maximum transfer unit */
755         netif->mtu = MAX_TRANSFER_UNIT;
756
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;
760
761
762         /* for flow control frames */
763         EMACMACSrcAddrSet(hdkif->emac_base, hdkif->mac_addr);
764
765         /*  Be sure to program all eight MAC address registers -
766          *  whether the receive channel is to be enabled or not.
767          */
768         for (regContent = 0; regContent < 8; regContent++) {
769                 EMACMACAddrSet(hdkif->emac_base, regContent, hdkif->mac_addr,
770                                EMAC_MACADDR_NO_MATCH_NO_FILTER);
771         }
772
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
776          */
777         /* wait for autonegotiation to be done or continue, when delay was reached */
778   #if !NO_SYS
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())
782         {
783                 vTaskDelay(20);
784                 /* XXX: if init is not done at the startup,
785                  * but couple days later, this might cause troubles */
786         }
787
788   #else
789         while (hdkif->phy_autoneg_is_done(hdkif->mdio_base, hdkif->phy_addr) == FALSE &&
790                autonegFinishWait--)
791                 ; /* wait till aneg done */
792   #endif
793
794         if (hdkif->phy_autoneg_is_done(hdkif->mdio_base, hdkif->phy_addr) != FALSE)
795                 rpp_debug_printf("autoneg finished\n");
796         else
797                 rpp_debug_printf("autoneg timeout\n");
798
799         /* provide informations retrieved from autoneg to EMAC module */
800         hdkif->phy_partnerability(hdkif->mdio_base, hdkif->phy_addr, &regContent);
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
805                  */
806         } else if (regContent & (PHY_100BASETX_m | PHY_10BASET_m)) {
807                 EMACDuplexSet(hdkif->emac_base, EMAC_DUPLEX_HALF);
808         } else {
809                 rpp_debug_printf("Unknown duplex mode\r\n");
810                 return UNKN_DUPLEX_MODE;
811         }
812 #endif /* !PHY_LINK_MONITOR_INT */
813
814         /* enable hostpend interrupts in emac module */
815         HWREG(hdkif->emac_base + EMAC_MACINTMASKSET) |=
816                 EMAC_MACINTMASKSET_HOSTMASK;
817
818         /* enable hostpend interrupts in emac control module */
819         HWREG(hdkif->emac_ctrl_base + EMAC_CTRL_CnMISCEN(0)) |=
820                 EMAC_CTRL_MISC_HOSTPENDENB;
821
822         EMACMIIEnable(hdkif->emac_base);
823         EMACTxEnable(hdkif->emac_base);
824         EMACRxEnable(hdkif->emac_base);
825
826         return SUCCESS;
827 }
828
829 /* send and receive functions / ISRs ******************************************/
830
831 err_t rpp_eth_send(struct netif *netif, struct pbuf *p)
832 {
833         err_t retVal = SUCCESS;
834         SYS_ARCH_DECL_PROTECT(lev);
835
836         /**
837          * This entire function must be protected to preserve
838          * the integrity of the transmit pbuf queue.
839          */
840         SYS_ARCH_PROTECT(lev);
841 #if !SYS_LIGHTWEIGHT_PROT
842         uint32_t prevProt = (uint32_t) _get_CPSR() & 0x80;
843         _disable_IRQ();
844 #endif
845
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;
850         }
851
852         /**
853          * Bump the reference count on the pbuf to prevent it from being
854          * freed until we are done with it.
855          */
856         pbuf_ref(p);
857
858         /* call the actual transmit function */
859         retVal = rpp_eth_send_raw(netif, p);
860
861         /* Return to prior interrupt state and return. */
862         SYS_ARCH_UNPROTECT(lev);
863 #if !SYS_LIGHTWEIGHT_PROT
864         if (!prevProt)
865                 _enable_IRQ();
866 #endif
867
868         return retVal;
869 }
870
871 /**
872  * When called from rpp_eth_send(), the 'lev' lock is held
873  */
874 static err_t rpp_eth_send_raw(struct netif *netif, struct pbuf *pbuf)
875 {
876         struct pbuf *q;
877         struct txch *txch;
878         struct hdkif *hdkif;
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
882          */
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;
886
887         hdkif = (struct hdkif *)netif->state;
888         txch = &(hdkif->txch);
889
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;
893
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)
898          */
899         while (curr_bd->flags_pktlen & EMAC_DSC_FLAG_OWNER)
900                 ;
901
902         /* First 'part' of packet flags */
903         curr_bd->flags_pktlen = pbuf->tot_len |
904                                 EMAC_DSC_FLAG_SOP |
905                                 EMAC_DSC_FLAG_OWNER;
906
907         /* Copy pbuf information into TX BDs --
908          * remember that the pbuf for a single packet might be chained!
909          */
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;
913
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
917                  * is done in EMAC
918                  */
919                 curr_bd->pbuf = pbuf;
920
921                 curr_bd = curr_bd->next;
922                 curr_bd->flags_pktlen = 0x0;
923         }
924         /* Indicate the end of the packet */
925         active_tail->next = NULL;
926         active_tail->flags_pktlen |= EMAC_DSC_FLAG_EOP;
927
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
930          */
931         txch->free_head = curr_bd;
932
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);
937         } else {
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.
941                  */
942                 curr_bd = txch->active_tail;
943                 curr_bd->next = active_head;
944
945 #if 0
946                 /* Just a workaround in case "appending" to
947                  * the last active BD will not work
948                  */
949                 while (!(curr_bd->flags_pktlen & EMAC_DSC_FLAG_EOQ))
950                         ;
951 #endif
952
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
957                  */
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)
961                                 ;
962                         EMACTxHdrDescPtrWrite(hdkif->emac_base,
963                                         (unsigned int)(active_head), CHANNEL);
964                 }
965         }
966         txch->active_tail = active_tail;
967
968         return SUCCESS;
969 }
970
971 void rpp_eth_send_raw_thr(void *arg)
972 {
973         struct hdkif *hdkif;
974         struct txch *txch;
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;
978
979         hdkif = netif->state;
980         txch = &(hdkif->txch);
981
982         for (;;) {
983                 /* Block if there is nothing to do.
984                  * Wake up if an TX interrupt occured.
985                  */
986                 xSemaphoreTake(hdkif->goTX, portMAX_DELAY);
987
988                 next_bd_to_process = txch->next_bd_to_process;
989                 curr_bd = next_bd_to_process;
990
991                 /* Traverse the list of BDs used for transmission --
992                  * stop on the first unused
993                  */
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)
997                                 ;
998
999                         /* Find the last chunk of the packet */
1000                         while (!(curr_bd->flags_pktlen & EMAC_DSC_FLAG_EOP))
1001                                 curr_bd = curr_bd->next;
1002
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);
1006
1007                         /* Point the txch->next_bd_to_process to the BDs
1008                          * following the 'last BD belonging to the packet
1009                          * being processed'
1010                          */
1011                         if (curr_bd->next == NULL)
1012                                 txch->next_bd_to_process = txch->free_head;
1013                         else
1014                                 txch->next_bd_to_process = curr_bd->next;
1015
1016                         /* Ack the Interrupt in the EMAC peripheral */
1017                         EMACTxCPWrite(hdkif->emac_base, CHANNEL,
1018                                       (uint32_t)curr_bd);
1019
1020                         /* Free the corresponding pbuf
1021                          * Sidenote: Each fragment of the single packet points
1022                          * to the same pbuf // FIXME is it true?
1023                          */
1024                         pbuf_free(curr_bd->pbuf);
1025
1026                         LINK_STATS_INC(link.xmit);
1027
1028                         /* Move to the next packet */
1029                         next_bd_to_process = txch->next_bd_to_process;
1030                         curr_bd = next_bd_to_process;
1031                 }
1032
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);
1038         }
1039 }
1040
1041 void rpp_eth_recv_raw_thr(void *arg)
1042 {
1043         struct hdkif *hdkif;
1044         struct rxch *rxch;
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;
1052
1053         hdkif = netif->state;
1054         rxch = &(hdkif->rxch);
1055
1056         for (;;) {
1057                 /* Block if there is nothing to do.
1058                  * Wake up if an RX interrupt occured.
1059                  */
1060 #if 0
1061                 sys_arch_sem_wait(&(hdkif->goRX), 0);
1062 #endif
1063                 xSemaphoreTake(hdkif->goRX, portMAX_DELAY);
1064
1065                 /* Get the bd which contains the earliest filled data */
1066                 curr_bd = rxch->active_head;
1067
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;
1072
1073                         /* Start processing once the packet is released by the EMAC. */
1074                         while (curr_bd->flags_pktlen & EMAC_DSC_FLAG_OWNER)
1075                                 ;
1076
1077                         pbuf = curr_bd->pbuf;
1078                         total_rx_len = curr_bd->flags_pktlen & 0xFFFF;
1079
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.
1086                          */
1087                         for (;;) {
1088                                 q = curr_bd->pbuf;
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
1092                                  */
1093                                 rxch->freed_pbuf_len += q->len;
1094
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;
1098
1099                                 if (curr_bd->flags_pktlen & EMAC_DSC_FLAG_EOP)
1100                                         break;
1101                                 /*
1102                                  * If we are executing here, it means this
1103                                  * packet is being split over multiple BDs
1104                                  */
1105
1106                                 /* chain the pbufs since they belong
1107                                  * to the same packet
1108                                  */
1109                                 q->next = (curr_bd->next)->pbuf;
1110
1111                                 processed_rx_len += q->len;
1112                                 curr_bd = curr_bd->next;
1113                         }
1114                         /* Close the chain */
1115                         q->next = NULL;
1116
1117                         LINK_STATS_INC(link.recv);
1118
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);
1124                         }
1125
1126                         /* Acknowledge that this packet is processed */
1127                         EMACRxCPWrite(hdkif->emac_base, 0, (unsigned int)curr_bd);
1128
1129                         curr_head = rxch->active_head;
1130                         rxch->active_head = curr_bd->next;
1131
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.
1136                          */
1137                         for (;;) {
1138                                 new_pbuf = pbuf_alloc(PBUF_RAW,
1139                                                       rxch->freed_pbuf_len,
1140                                                       PBUF_POOL);
1141                                 if (new_pbuf == NULL) {
1142                                         /* Cycle until the pbuf is
1143                                          * succesfully allocated
1144                                          */
1145                                         /* Actively poll to decrease the time
1146                                          * when the RX interrupts are disabled
1147                                          */
1148                                         continue;
1149                                 } else {
1150                                         curr_tail = curr_bd;
1151                                         curr_tail->next = NULL;
1152                                         curr_bd = curr_head;
1153
1154                                         q = new_pbuf;
1155                                         curr_bd = curr_head;
1156                                         for (;;) {
1157                                                 if (q == NULL)
1158                                                         break;
1159                                                 if (curr_bd == NULL)
1160                                                         break;
1161
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;
1166                                                 curr_bd->pbuf = q;
1167
1168                                                 rxch->freed_pbuf_len -= q->len;
1169                                                 q = q->next;
1170                                                 curr_bd = curr_bd->next;
1171                                         }
1172
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.
1178                                          */
1179                                         if (q != NULL)
1180                                                 pbuf_free((struct pbuf *)q);
1181
1182                                         /* Add the newly allocated BDs to the
1183                                          * end of the list
1184                                          */
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.
1191                                          */
1192                                         if (rxch->active_tail->flags_pktlen &
1193                                             EMAC_DSC_FLAG_EOQ)
1194                                         {
1195                                                 /* Writes to RX HDP are allowed
1196                                                  * only when it is 0
1197                                                  */
1198                                                 while (HWREG(hdkif->emac_base +
1199                                                        EMAC_RXHDP(CHANNEL)) != 0)
1200                                                         ;
1201
1202                                                 EMACRxHdrDescPtrWrite(
1203                                                         hdkif->emac_base,
1204                                                         (uint32_t)curr_head,
1205                                                         CHANNEL);
1206                                         }
1207
1208                                         rxch->active_tail = curr_tail;
1209                                         break;
1210                                 }
1211                         }
1212                         curr_bd = rxch->active_head;
1213                 }
1214
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);
1220         }
1221 }
1222
1223 void RxIntHandler(u32_t instNum)
1224 {
1225         vim_mask_clr(RXinterruptVectorNumber);
1226         /* Unblock the RX task. */
1227         xSemaphoreGiveFromISR(hdkif_data[instNum].goRX, NULL);
1228 }
1229
1230 void TxIntHandler(u32_t instNum)
1231 {
1232         vim_mask_clr(TXinterruptVectorNumber); /* see sys_startup.c */
1233         xSemaphoreGiveFromISR(hdkif_data[instNum].goTX, NULL);
1234 }
1235
1236 /**
1237  * TX err codes:
1238  * 0   No error
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)
1246  *
1247  * RX err codes:
1248  * 0   No error
1249  * 1h  Reserved
1250  * 2h  Ownership bit not set in SOP buffer
1251  * 3h  Reserved
1252  * 4h  Zero buffer pointer
1253  */
1254 boolean_t HostPendErrHandler(void)
1255 {
1256         uint8_t index = MAX_EMAC_INSTANCE;
1257         uint8_t errFound = FALSE;
1258         uint32_t reg;
1259         struct hdkif *hdkif;
1260
1261         while (index) {
1262                 hdkif = &hdkif_data[--index];
1263
1264                 if (EMACIntVectorGet(hdkif->emac_base) & EMAC_MACINVECTOR_HOSTPEND)
1265                         errFound = TRUE;
1266         }
1267
1268         if (!errFound)
1269                 return FALSE; /* this is not the cause of the interrupt */
1270
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));
1279
1280         { /* Print out all the RX BDs */
1281                 struct rxch *rxch;
1282                 volatile struct emac_rx_bd *curr_bd;
1283                 rxch = &(hdkif->rxch);
1284                 int glob_len = 0;
1285
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))));
1290
1291                 for (curr_bd = rxch->active_head; curr_bd != 0; curr_bd = curr_bd->next) {
1292                         glob_len += curr_bd->pbuf->len;
1293
1294                         rpp_sci_printk("[%p: buf: %p buffoff_len: 0x%x "
1295                                         "\tflags: 0x%x pktlen: 0x%x]",
1296                                         curr_bd,
1297                                         curr_bd->bufptr,
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,
1303                                         curr_bd->pbuf->len,
1304                                         curr_bd->pbuf->ref);
1305                 }
1306                 rpp_sci_printk("glob_len: %d\n", glob_len);
1307         }
1308
1309         /* no acknowledge - emac module has to be restarted */
1310
1311         /* this was the reason of interrupt */
1312         return TRUE;
1313 }
1314
1315 #if PHY_LINK_MONITOR_INT
1316 boolean_t LinkIntHandler(void)
1317 {
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;
1324
1325         /* check each instance, whether this interrupt was meant for this
1326          * function, if not return FALSE so other function may be tried
1327          */
1328         while (index) {
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))
1334                         phyFound = TRUE;
1335         }
1336         if (!phyFound)
1337                 return FALSE;
1338         struct netif *netif = &hdkNetIF[hdkif->inst_num];
1339
1340         /* we handle here connection of cable after startup, not changes of linkstatus */
1341
1342         /* wait for autonegotiation to be done */
1343 #if ONCE_LINK_SETUP
1344         while (hdkif->phy_autoneg_is_done(hdkif->mdio_base, hdkif->phy_addr) ==
1345                FALSE)
1346                 ;
1347 #else /* ONCE_LINK_SETUP */
1348         while (hdkif->phy_autoneg_is_done(hdkif->mdio_base, hdkif->phy_addr) ==
1349                FALSE & autonegFinishWait--)
1350                 ;
1351 #endif /* ONCE_LINK_SETUP */
1352
1353         /* provide informations retrieved from autoneg to EMAC module */
1354         hdkif->phy_partnerability(hdkif->mdio_base, hdkif->phy_addr, &regContent);
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
1359                  */
1360         } else if (regContent & (PHY_100BASETX_m | PHY_10BASET_m)) {
1361                 EMACDuplexSet(hdkif->emac_base, EMAC_DUPLEX_HALF);
1362         } else {
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;
1368
1369                 /* acknowledge EMAC control module by writing
1370                  * appropriate key to MACEOIVECTOR
1371                  */
1372                 EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_MISC);
1373                 return FALSE;
1374         }
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;
1382                 }
1383 #if ONCE_LINK_SETUP
1384                 while (netif->dhcp->state != DHCP_BOUND)
1385                         ;
1386 #else
1387                 while (netif->dhcp->state != DHCP_BOUND & dhcpBindWait--)
1388                         ;
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;
1395
1396                         /* acknowledge EMAC control module by writing
1397                          * appropriate key to MACEOIVECTOR
1398                          */
1399                         EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_MISC);
1400                         return FALSE;
1401                 }
1402 #endif
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 */
1406 #if ONCE_LINK_SETUP
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 */
1411         } else {
1412 #if 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;
1418
1419                 /* acknowledge EMAC control module by writing
1420                  * appropriate key to MACEOIVECTOR
1421                  */
1422                 EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_MISC);
1423                 return FALSE;
1424 #else
1425 #if STATIC_IP_ADDRESS
1426                 netif_set_down(netif);
1427 #elif LWIP_DHCP /* STATIC_IP_ADDRESS-LWIP_DHCP */
1428                 dhcp_stop(netif);
1429 #endif /* STATIC_IP_ADDRESS-LWIP_DHCP-LWIP_AUTOIP */
1430 #endif
1431         }
1432
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;
1438
1439         /* acknowledge EMAC control module by writing appropriate key to MACEOIVECTOR */
1440         EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_MISC);
1441
1442         return TRUE;
1443 }
1444 #endif /* PHY_LINK_MONITOR_INT */
1445 #endif /* FREERTOS_POSIX */