source: edk_user_repository/WARP/sw_services/WARPxilnet_v3_04_a/src/xilnet_xilsock.c

Last change on this file was 4361, checked in by welsh, 9 years ago

Update to WARPxilnet. Fixed issue with the location of the second DMA buffer. Placed all WARPxilnet defined memories into a single section so that they can be placed differently in the linker file.

File size: 14.7 KB
Line 
1
2////////////////////////////////////////////////////////////////////////////////
3// Copyright (c) 2004 Xilinx, Inc.  All rights reserved.
4//
5// Xilinx, Inc.
6// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
7// COURTESY TO YOU.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
8// ONE POSSIBLE   IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
9// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
10// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
11// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
12// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
13// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
14// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
15// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
16// AND FITNESS FOR A PARTICULAR PURPOSE.
17//
18// File   : xilsock.c
19// Date   : 2002, March 20.
20// Author : Sathya Thammanur
21// Company: Xilinx
22// Group  : Emerging Software Technologies
23//
24// Summary:
25// Xilinx internal socket related functions (xilsock functions)
26//
27// $Id: xilsock.c,v 1.2.8.6 2005/11/15 23:41:10 salindac Exp $
28//
29////////////////////////////////////////////////////////////////////////////////
30
31////////////////////////////////////////////////////////////////////////////////
32// see copyright.txt for Rice University/Mango Communications modifications
33////////////////////////////////////////////////////////////////////////////////
34
35#include <xilnet_config.h>
36
37/*
38 * Print the xilsock error message
39 */
40
41void xilsock_print_error_msg( unsigned int eth_dev_num ) {
42    xil_printf("  **** ERROR:  Ethernet device %d is not supported by the WARPxilnet library.  \n", (eth_dev_num+1) );
43    xil_printf("               Please check library configuration in the BSP.   \n" );
44}
45
46
47
48/*
49 * Initialization of xilsock_sockets
50 */
51
52int xilsock_init (unsigned int eth_dev_num) {
53
54    int i;
55   
56    struct xilsock_socket * sockets = (struct xilsock_socket *)eth_device[eth_dev_num].xilsock_sockets;
57   
58    // Check to see if the xilnet driver uses the Ethernet instance
59    if ( !eth_device[eth_dev_num].uses_driver ) {
60        xilsock_print_error_msg( eth_dev_num );
61        return -1;
62    }
63
64    if (!eth_device[eth_dev_num].is_xilsock_init) {
65        for (i = 0; i < NO_OF_XILSOCKS; i++) {
66            sockets[i].type          = 0;
67            sockets[i].domain        = 0;
68            sockets[i].proto         = 0;
69            sockets[i].listen        = 0;
70            sockets[i].bound         = 0;
71            sockets[i].accept        = 0;
72            sockets[i].connect       = 0;
73            sockets[i].closing       = 0;
74            sockets[i].closed        = 0;
75            sockets[i].free          = 1;
76            sockets[i].conn.tcp_conn = NULL;
77            sockets[i].recvbuf.buf   = NULL;
78            sockets[i].recvbuf.size  = 0;
79        }
80        eth_device[eth_dev_num].is_xilsock_init = 1;
81    }
82    return eth_device[eth_dev_num].is_xilsock_init;
83}
84
85
86/*
87 * Release a socket
88 */
89
90void xilsock_rel_socket (int sd, unsigned int eth_dev_num) {
91
92    struct xilsock_socket * sockets = (struct xilsock_socket *)eth_device[eth_dev_num].xilsock_sockets;
93
94    // Check to see if the xilnet driver uses the Ethernet instance
95    if ( !eth_device[eth_dev_num].uses_driver ) {
96        xilsock_print_error_msg( eth_dev_num );
97        return;
98    }
99
100    // Zero out the socket
101    memset( &( sockets[sd] ), 0x0, sizeof( xilsock_socket ) );
102
103    // Set the free field
104    sockets[sd].free = 1;
105   
106   
107#if 0   
108    if (sockets[sd].type == SOCK_STREAM) {
109        sockets[sd].conn.tcp_conn = NULL;
110    }
111    else {
112        sockets[sd].conn.udp_conn = NULL;
113    }
114    sockets[sd].type         = 0;
115    sockets[sd].domain       = 0;
116    sockets[sd].proto        = 0;
117    sockets[sd].listen       = 0;
118    sockets[sd].bound        = 0;
119    sockets[sd].accept       = 0;
120    sockets[sd].connect      = 0;
121    sockets[sd].closing      = 0;
122    sockets[sd].closed       = 0;
123    sockets[sd].free         = 1;
124    sockets[sd].recvbuf.buf  = NULL;
125    sockets[sd].recvbuf.size = 0;
126#endif
127
128}
129
130
131/*
132 * Allocate a xilsock_socket and return socket descriptor
133 * if not able to alloc socket, return -1
134 */
135
136int xilsock_socket(int domain, int type, int proto, unsigned int eth_dev_num) {
137
138    int sd;
139    struct xilsock_socket * sockets = (struct xilsock_socket *)eth_device[eth_dev_num].xilsock_sockets;
140
141    // Check to see if the xilnet driver uses the Ethernet instance
142    if ( !eth_device[eth_dev_num].uses_driver ) {
143        xilsock_print_error_msg( eth_dev_num );
144        return -1;
145    }
146
147    // find a free xilsock_socket
148    if (!xilsock_init(eth_dev_num)){
149        xil_printf("xilsock is not initialized\n");
150        return (-1);
151    }
152   
153    for (sd = 0; sd < NO_OF_XILSOCKS; sd++) {
154        if (sockets[sd].free) {
155            // initialise the socket & make it unavailable
156            sockets[sd].domain = domain;
157            sockets[sd].type   = type;
158            sockets[sd].proto  = proto;
159            sockets[sd].free   = 0;
160
161            // Debug print:
162            // xil_printf("Socket %d: [%d, %d, %d, %d] \n", sd, domain, type, proto, eth_dev_num);
163            return sd;
164        }
165    }
166    // return as no sockets available
167    xil_printf("No sockets available on ethernet device %d!\n", eth_dev_num);
168    return -1;
169}
170
171
172/*
173 * bind a socket to the specified address.
174 * binds addr to socket sd. returns 1 if bound
175 * returns -1 if not able to bind
176 */
177
178int xilsock_bind(int sd, struct sockaddr* addr, int addrlen, void (*callback) (), unsigned int eth_dev_num) {
179
180    int connd;
181    struct xilsock_socket  * sockets = (struct xilsock_socket  *)eth_device[eth_dev_num].xilsock_sockets;
182    struct xilnet_udp_conn * conns   = (struct xilnet_udp_conn *)eth_device[eth_dev_num].xilnet_udp_conns;
183
184    // Check to see if the xilnet driver uses the Ethernet instance
185    if ( !eth_device[eth_dev_num].uses_driver ) {
186        xilsock_print_error_msg( eth_dev_num );
187        return -1;
188    }
189
190    // open a tcp conn/udp conn
191    if (sockets[sd].type == SOCK_STREAM) {
192        xil_printf("*** Error xilsock_bind: tcp sockets not available \n");
193        xilsock_rel_socket(sd, eth_dev_num);
194        return -1;
195    }
196    else if (sockets[sd].type == SOCK_DGRAM) {
197        if ( (connd = xilnet_udp_open_conn (((struct sockaddr_in*)addr)->sin_port, callback, eth_dev_num)) == -1) {
198            xil_printf("*** Error xilsock_bind: udp sockets not available \n");
199            xilsock_rel_socket(sd, eth_dev_num);
200            return -1;
201        }
202        sockets[sd].conn.udp_conn = (conns + connd);
203        // update fd of udp conn
204        conns[connd].fd = sd;
205    }
206
207    return 1;
208}
209
210
211/*
212 * listen on a socket
213 * called from listen()
214 */
215
216int xilsock_listen(int s, int backlog, unsigned int eth_dev_num) {
217
218    struct xilsock_socket  * sockets = (struct xilsock_socket  *)eth_device[eth_dev_num].xilsock_sockets;
219
220    // Check to see if the xilnet driver uses the Ethernet instance
221    if ( !eth_device[eth_dev_num].uses_driver ) {
222        xilsock_print_error_msg( eth_dev_num );
223        return -1;
224    }
225
226    sockets[s].listen = 1;
227    return 1;
228}
229
230
231
232/*
233 * recv data on socket
234 * called from recv()
235 * returns -1 if no data recvd for "s" (non_blocking call) or
236 * number of bytes recvd for "s"
237 */
238
239int xilsock_recv(int s, unsigned char *buf, unsigned int len, unsigned int eth_dev_num) {
240
241    unsigned int n;
242    struct xilsock_socket  * sockets = (struct xilsock_socket  *)eth_device[eth_dev_num].xilsock_sockets;
243    int bytes_recvd = 0;
244
245    // Check to see if the xilnet driver uses the Ethernet instance
246    if ( !eth_device[eth_dev_num].uses_driver ) {
247        xilsock_print_error_msg( eth_dev_num );
248        return -1;
249    }
250
251    if (s > NO_OF_XILSOCKS) {
252        xil_printf("*** Error xilsock_recv: invalid socket descriptor %d \n", s);
253        return -1;
254    }
255
256   n = xilnet_eth_recv_frame(eth_dev_num);
257
258   // Return if data not for socket s
259   if ((n == -1) || (sockets[s].recvbuf.buf == NULL))
260      return -1;
261
262   // Copy data if required onto buf
263   if (sockets[s].recvbuf.buf != buf)
264   {
265      memcpy(buf, sockets[s].recvbuf.buf, len);
266      bytes_recvd = sockets[s].recvbuf.size;
267
268      //reset socket buffer and size
269      sockets[s].recvbuf.buf  = NULL;
270      sockets[s].recvbuf.size = 0;
271   }
272
273   // return no of bytes recvd for this conn
274   return bytes_recvd;
275}
276
277
278/*
279 * send data on socket
280 * called from send()
281 */
282
283int xilsock_send(int s,  unsigned char* buf, unsigned int len, unsigned int eth_dev_num) {
284
285    xil_printf("*** Error xilsock_send: TCP connections are not supported\n");
286    return -1;
287
288#if 0
289    struct xilnet_tcp_conn *conn;
290    struct xilsock_socket  * sockets = (struct xilsock_socket  *)eth_device[eth_dev_num].xilsock_sockets;
291    unsigned char          * sendbuf = (unsigned char *)eth_device[eth_dev_num].sendbuf;
292
293
294    conn = sockets[s].conn.tcp_conn;
295
296    if (!conn) {
297        xil_printf("*** Error xilsock_send: no such socket %d \n", conn);
298        return -1;
299    }
300
301    if (buf != sendbuf) {
302        memset(sendbuf, 0, eth_device[eth_dev_num].buf_size);
303        memcpy(sendbuf+LINK_HDR_LEN+IP_HDR_LEN*4+(TCP_HDR_LEN*4), buf, len);
304    }
305
306     xilnet_tcp_send_pkt(conn, sendbuf+LINK_HDR_LEN+IP_HDR_LEN*4, len, TCP_ACK, eth_dev_num);
307     xilnet_ip_header(sendbuf+LINK_HDR_LEN, len+(TCP_HDR_LEN*4)+IP_HDR_LEN*4, IP_PROTO_TCP, conn->dst_ip, eth_dev_num);
308
309     xilnet_eth_send_frame(sendbuf, len+(TCP_HDR_LEN*4)+IP_HDR_LEN*4+ETH_HDR_LEN, conn->dst_ip, NULL, ETH_PROTO_IP, eth_dev_num);
310
311     return len;
312#endif
313}
314
315
316/*
317 * recvfrom socket
318 * Data recvd on any UDP socket
319 * return -1 if data not for socket "s" [non-blocking call]
320 */
321int xilsock_recvfrom(int s, unsigned char *buf, unsigned int len,
322                     struct sockaddr* from, unsigned int *fromlen, unsigned int eth_dev_num)
323{
324    int n;
325    int bytes_recvd = 0;
326    struct xilsock_socket  * sockets = (struct xilsock_socket  *)eth_device[eth_dev_num].xilsock_sockets;
327    struct xilnet_udp_conn * conn    = sockets[s].conn.udp_conn;
328
329    // Check to see if the xilnet driver uses the Ethernet instance
330    if ( !eth_device[eth_dev_num].uses_driver ) {
331        xilsock_print_error_msg( eth_dev_num );
332        return -1;
333    }
334
335    if (s > NO_OF_XILSOCKS) {
336        xil_printf("*** Error xilsock_recvfrom: invalid socket descriptor %d \n", s);
337        return -1;
338    }
339
340    n = xilnet_eth_recv_frame(eth_dev_num);
341
342    // Return if data not for socket s
343    if ((n < 0 ) || (sockets[s].recvbuf.buf == NULL))
344        return -1;
345
346   // Copy data if required onto buf
347   if (sockets[s].recvbuf.buf != buf)
348   {
349      memcpy(buf, sockets[s].recvbuf.buf, len);
350      bytes_recvd = sockets[s].recvbuf.size;
351
352      //reset socket buffer and size
353      sockets[s].recvbuf.buf = NULL;
354      sockets[s].recvbuf.size = 0;
355   }
356
357   // Copy the source address onto "to"
358   ((struct sockaddr_in*)from)->sin_addr.s_addr =
359      (conn->dst_ip[0] << 24) + (conn->dst_ip[1] << 16) + (conn->dst_ip[2] << 8) + conn->dst_ip[3];
360   ((struct sockaddr_in*)from)->sin_port = conn->dst_port;
361   *fromlen = sizeof(from);
362
363   // return no of bytes recvd for this conn
364   return bytes_recvd;
365}
366
367
368/*
369 * sendto socket
370 * called from sendto()
371 */
372
373int xilsock_sendto(int s,  unsigned char* buf, unsigned int len, struct sockaddr* to, unsigned int eth_dev_num)
374{
375
376    struct xilnet_udp_conn * conn;
377    struct xilsock_socket  * sockets = (struct xilsock_socket  *)eth_device[eth_dev_num].xilsock_sockets;
378    unsigned int             dstaddr = ((struct sockaddr_in*)to)->sin_addr.s_addr;
379    unsigned char          * sendbuf = buf;
380
381    // Updated function so that it uses the provided buffer instead of copying the data to the sendbuf of the
382    //   given ethernet device.  This enables callers to maintain buffers beyond the single send buffer
383    //   provided by the Xilnet framework.
384    //
385    // unsigned char          * sendbuf = (unsigned char *)eth_device[eth_dev_num].sendbuf;
386
387    // Check to see if the xilnet driver uses the Ethernet instance
388    if ( !eth_device[eth_dev_num].uses_driver ) {
389        xilsock_print_error_msg( eth_dev_num );
390        return -1;
391    }
392   
393    conn = sockets[s].conn.udp_conn;
394    conn->dst_ip[0] = (unsigned char) ((dstaddr >> 24) & 0xFF);
395    conn->dst_ip[1] = (unsigned char) ((dstaddr >> 16) & 0xFF);
396    conn->dst_ip[2] = (unsigned char) ((dstaddr >> 8) & 0xFF);
397    conn->dst_ip[3] = (unsigned char) ((dstaddr) & 0xFF);
398    conn->dst_port  = ((struct sockaddr_in*)to)->sin_port;
399
400    if (!conn) {
401        xil_printf("*** Error xilsock_sendto: no such socket %d \n", conn);
402        return -1;
403    }
404
405    // See comments above.
406    //
407    // if (buf != sendbuf) {
408    //     memset(sendbuf, 0, eth_device[eth_dev_num].buf_size);
409    //     memcpy(sendbuf+LINK_HDR_LEN+IP_HDR_LEN*4+UDP_HDR_LEN, buf, len);
410    // }
411
412    // calls to udp stack
413    xilnet_udp_header(conn, sendbuf+LINK_HDR_LEN+IP_HDR_LEN*4, len+UDP_HDR_LEN, eth_dev_num);
414
415    xilnet_ip_header(sendbuf+LINK_HDR_LEN, len+UDP_HDR_LEN+IP_HDR_LEN*4, IP_PROTO_UDP, conn->dst_ip, eth_dev_num);
416
417    xilnet_eth_send_frame(sendbuf, len+UDP_HDR_LEN+IP_HDR_LEN*4+ETH_HDR_LEN, conn->dst_ip, NULL, ETH_PROTO_IP, eth_dev_num);
418
419    return len;
420}
421
422
423/*
424 * close socket
425 */
426
427void xilsock_close(int s, unsigned int eth_dev_num) {
428
429#if 0
430    unsigned char flags = 0;
431    unsigned short check = 0;
432    unsigned char *tcp_reply;
433    unsigned char          * sendbuf = (unsigned char *)eth_device[eth_dev_num].sendbuf;
434#endif
435    struct xilsock_socket  * sockets = (struct xilsock_socket  *)eth_device[eth_dev_num].xilsock_sockets;
436
437    // Check to see if the xilnet driver uses the Ethernet instance
438    if ( !eth_device[eth_dev_num].uses_driver ) {
439        xilsock_print_error_msg( eth_dev_num );
440        return;
441    }
442
443    if (sockets[s].type == SOCK_STREAM) {
444
445        xil_printf("*** Error xilsock_close: TCP connections are not supported\n");
446
447#if 0
448        struct xilnet_tcp_conn *conn = sockets[s].conn.tcp_conn;
449
450        // construct the FIN and wait for ack & FIN from client
451        flags = (TCP_FIN | TCP_ACK);
452        ((struct xilnet_tcp_conn*)conn)->state = TCP_FIN_WAIT1;
453        memset(sendbuf, 0, LINK_FRAME_LEN);
454        tcp_reply = sendbuf+ETH_HDR_LEN+(IP_HDR_LEN*4);
455
456        xilnet_tcp_header(((struct xilnet_tcp_conn*)conn), tcp_reply, 1, flags, eth_dev_num);
457
458        // calculate tcp checksum
459        check = xilnet_udp_tcp_calc_chksum(tcp_reply, (TCP_HDR_LEN*4), eth_device[eth_dev_num].node_ip_addr, ((struct xilnet_tcp_conn*)conn)->dst_ip, IP_PROTO_TCP);
460        tcp_reply[TCP_CHECK_OFF]   = (check & 0xff00) >> 8;
461        tcp_reply[TCP_CHECK_OFF+1] = (check & 0x00ff);
462
463        xilnet_ip_header(sendbuf+ETH_HDR_LEN,(IP_HDR_LEN*4)+(TCP_HDR_LEN*4), IP_PROTO_TCP, ((struct xilnet_tcp_conn*)conn)->dst_ip, eth_dev_num);
464        xilnet_eth_send_frame(sendbuf, (TCP_HDR_LEN*4)+(IP_HDR_LEN*4)+ETH_HDR_LEN, ((struct xilnet_tcp_conn*)conn)->dst_ip, NULL, ETH_PROTO_IP, eth_dev_num);
465#endif
466
467    }
468    else if (sockets[s].type == SOCK_DGRAM) {
469        xilnet_udp_close_conn(sockets[s].conn.udp_conn, eth_dev_num);
470        // close the socket
471        xilsock_rel_socket(s, eth_dev_num);
472    }
473}
Note: See TracBrowser for help on using the repository browser.