]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/MicroBlaze_Kintex7_EthernetLite/RTOSDemo/src/lwIP_Demo/lwIP_port/netif/xadapter.c
Recreated MicroBlaze example using Vivado 2016.1 - the Microblaze project is still...
[freertos] / FreeRTOS / Demo / MicroBlaze_Kintex7_EthernetLite / RTOSDemo / src / lwIP_Demo / lwIP_port / netif / xadapter.c
1 /******************************************************************************
2 *
3 * Copyright (C) 2007 - 2014 Xilinx, Inc.  All rights reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * Use of the Software is limited solely to applications:
16 * (a) running on a Xilinx device, or
17 * (b) that interact with a Xilinx device through a bus or interconnect.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
26 *
27 * Except as contained in this notice, the name of the Xilinx shall not be used
28 * in advertising or otherwise to promote the sale, use or other dealings in
29 * this Software without prior written authorization from Xilinx.
30 *
31 ******************************************************************************/
32
33 #include "lwipopts.h"
34 #include "xlwipconfig.h"
35
36 #if !NO_SYS
37 #ifdef OS_IS_XILKERNEL
38 #include "xmk.h"
39 #include "sys/process.h"
40 #endif
41 #endif
42
43 #include "lwip/mem.h"
44 #include "lwip/stats.h"
45 #include "lwip/sys.h"
46 #include "lwip/ip.h"
47 #include "lwip/tcp.h"
48 #include "lwip/udp.h"
49 #include "lwip/tcp_impl.h"
50
51 #include "netif/etharp.h"
52 #include "netif/xadapter.h"
53
54 #ifdef XLWIP_CONFIG_INCLUDE_EMACLITE
55 #include "netif/xemacliteif.h"
56 #endif
57
58 #ifdef XLWIP_CONFIG_INCLUDE_TEMAC
59 #include "netif/xlltemacif.h"
60 #endif
61
62 #ifdef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET
63 #include "netif/xaxiemacif.h"
64 #endif
65
66 #ifdef XLWIP_CONFIG_INCLUDE_GEM
67 #include "netif/xemacpsif.h"
68 #endif
69
70 #if !NO_SYS
71 #include "lwip/tcpip.h"
72 #endif
73
74
75 /* global lwip debug variable used for debugging */
76 int lwip_runtime_debug = 0;
77
78 void
79 lwip_raw_init()
80 {
81         ip_init();      /* Doesn't do much, it should be called to handle future changes. */
82 #if LWIP_UDP
83         udp_init();     /* Clears the UDP PCB list. */
84 #endif
85 #if LWIP_TCP
86         tcp_init();     /* Clears the TCP PCB list and clears some internal TCP timers. */
87                         /* Note: you must call tcp_fasttmr() and tcp_slowtmr() at the */
88                         /* predefined regular intervals after this initialization. */
89 #endif
90 }
91
92 static enum xemac_types
93 find_mac_type(unsigned base)
94 {
95         int i;
96
97         for (i = 0; i < xtopology_n_emacs; i++) {
98                 if (xtopology[i].emac_baseaddr == base)
99                         return xtopology[i].emac_type;
100         }
101
102         return xemac_type_unknown;
103 }
104
105 int
106 xtopology_find_index(unsigned base)
107 {
108         int i;
109
110         for (i = 0; i < xtopology_n_emacs; i++) {
111                 if (xtopology[i].emac_baseaddr == base)
112                         return i;
113         }
114
115         return -1;
116 }
117
118 /*
119  * xemac_add: this is a wrapper around lwIP's netif_add function.
120  * The objective is to provide portability between the different Xilinx MAC's
121  * This function can be used to add both xps_ethernetlite and xps_ll_temac
122  * based interfaces
123  */
124 struct netif *
125 xemac_add(struct netif *netif,
126         struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw,
127         unsigned char *mac_ethernet_address,
128         unsigned mac_baseaddr)
129 {
130         int i;
131
132         /* set mac address */
133         netif->hwaddr_len = 6;
134         for (i = 0; i < 6; i++)
135                 netif->hwaddr[i] = mac_ethernet_address[i];
136
137         /* initialize based on MAC type */
138                 switch (find_mac_type(mac_baseaddr)) {
139                         case xemac_type_xps_emaclite:
140 #ifdef XLWIP_CONFIG_INCLUDE_EMACLITE
141                                 return netif_add(netif, ipaddr, netmask, gw,
142                                         (void*)mac_baseaddr,
143                                         xemacliteif_init,
144 #if NO_SYS
145                                         ethernet_input
146 #else
147                                         tcpip_input
148 #endif
149                                         );
150 #else
151                                 return NULL;
152 #endif
153                         case xemac_type_xps_ll_temac:
154 #ifdef XLWIP_CONFIG_INCLUDE_TEMAC
155                                 return netif_add(netif, ipaddr, netmask, gw,
156                                         (void*)mac_baseaddr,
157                                         xlltemacif_init,
158 #if NO_SYS
159                                         ethernet_input
160 #else
161                                         tcpip_input
162 #endif
163                                         );
164 #else
165                                 return NULL;
166 #endif
167                         case xemac_type_axi_ethernet:
168 #ifdef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET
169                                 return netif_add(netif, ipaddr, netmask, gw,
170                                         (void*)mac_baseaddr,
171                                         xaxiemacif_init,
172 #if NO_SYS
173                                         ethernet_input
174 #else
175                                         tcpip_input
176 #endif
177                                         );
178 #else
179                                 return NULL;
180 #endif
181 #ifdef __arm__
182                         case xemac_type_emacps:
183 #ifdef XLWIP_CONFIG_INCLUDE_GEM
184                                 return netif_add(netif, ipaddr, netmask, gw,
185                                                 (void*)mac_baseaddr,
186                                                 xemacpsif_init,
187 #if NO_SYS
188                                                 ethernet_input
189 #else
190                                                 tcpip_input
191 #endif
192
193                                                 );
194 #endif
195 #endif
196                         default:
197                                 printf("unable to determine type of EMAC with baseaddress 0x%08x\r\n",
198                                                 mac_baseaddr);
199                                 return NULL;
200         }
201 }
202
203 #if !NO_SYS
204 /*
205  * The input thread calls lwIP to process any received packets.
206  * This thread waits until a packet is received (sem_rx_data_available),
207  * and then calls xemacif_input which processes 1 packet at a time.
208  */
209 void
210 xemacif_input_thread(struct netif *netif)
211 {
212         struct xemac_s *emac = (struct xemac_s *)netif->state;
213         while (1) {
214                 /* sleep until there are packets to process
215                  * This semaphore is set by the packet receive interrupt
216                  * routine.
217                  */
218                 sys_arch_sem_wait( &emac->sem_rx_data_available, pdMS_TO_TICKS( 250 ) );
219
220                 /* move all received packets to lwIP */
221                 xemacif_input(netif);
222         }
223 }
224 #endif
225
226 int
227 xemacif_input(struct netif *netif)
228 {
229         struct xemac_s *emac = (struct xemac_s *)netif->state;
230         SYS_ARCH_DECL_PROTECT(lev);
231
232         int n_packets = 0;
233
234         switch (emac->type) {
235                 case xemac_type_xps_emaclite:
236 #ifdef XLWIP_CONFIG_INCLUDE_EMACLITE
237                         SYS_ARCH_PROTECT(lev);
238                         n_packets = xemacliteif_input(netif);
239                         SYS_ARCH_UNPROTECT(lev);
240                         break;
241 #else
242                         print("incorrect configuration: xps_ethernetlite drivers not present?");
243                         while(1);
244                         return 0;
245 #endif
246                 case xemac_type_xps_ll_temac:
247 #ifdef XLWIP_CONFIG_INCLUDE_TEMAC
248                         SYS_ARCH_PROTECT(lev);
249                         n_packets = xlltemacif_input(netif);
250                         SYS_ARCH_UNPROTECT(lev);
251                         break;
252 #else
253                         print("incorrect configuration: xps_ll_temac drivers not present?");
254                         while(1);
255                         return 0;
256 #endif
257                 case xemac_type_axi_ethernet:
258 #ifdef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET
259                         SYS_ARCH_PROTECT(lev);
260                         n_packets = xaxiemacif_input(netif);
261                         SYS_ARCH_UNPROTECT(lev);
262                         break;
263 #else
264                         print("incorrect configuration: axi_ethernet drivers not present?");
265                         while(1);
266                         return 0;
267 #endif
268 #ifdef __arm__
269                 case xemac_type_emacps:
270 #ifdef XLWIP_CONFIG_INCLUDE_GEM
271                         SYS_ARCH_PROTECT(lev);
272                         n_packets = xemacpsif_input(netif);
273                         SYS_ARCH_UNPROTECT(lev);
274                         break;
275 #else
276                         xil_printf("incorrect configuration: ps7_ethernet drivers not present?\r\n");
277                         while(1);
278                         return 0;
279 #endif
280 #endif
281                 default:
282                         print("incorrect configuration: unknown temac type");
283                         while(1);
284                         return 0;
285         }
286
287         return n_packets;
288 }