source: edk_user_repository/WARP/sw_services/WARPxilnet_v3_02_a/src/xilnet_eth.c

Last change on this file was 2151, checked in by welsh, 11 years ago

Update to performance monitoring code. No functional changes when not using the performance monitor define.

File size: 46.6 KB
Line 
1////////////////////////////////////////////////////////////////////////////////
2// Copyright (c) 2004 Xilinx, Inc.  All rights reserved.
3//
4// Xilinx, Inc.
5// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
6// COURTESY TO YOU.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
7// ONE POSSIBLE   IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
8// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
9// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
10// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
11// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
12// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
13// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
14// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
15// AND FITNESS FOR A PARTICULAR PURPOSE.
16//
17// File   : eth.c
18// Date   : 2002, March 20.
19// Author : Sathya Thammanur
20// Company: Xilinx
21// Group  : Emerging Software Technologies
22//
23// Summary:
24// Ethernet layer specific functions
25//
26// $Id: eth.c,v 1.2.8.6 2005/11/15 23:41:10 salindac Exp $
27//
28////////////////////////////////////////////////////////////////////////////////
29
30////////////////////////////////////////////////////////////////////////////////
31// see copyright.txt for Rice University/Mango Communications modifications
32////////////////////////////////////////////////////////////////////////////////
33
34
35/***************************** Include Files *********************************/
36
37#include <string.h>
38#include <xilnet_config.h>
39#include <xilnet_xilsock.h>
40
41#include "xio.h"
42#include "stdio.h"
43
44
45/*************************** Constant Definitions ****************************/
46
47
48
49/*********************** Global Variable Definitions *************************/
50
51
52
53/*************************** Variable Definitions ****************************/
54
55
56// Xilnet HW Address Table
57//   Note:  There is only one address table to be shared among all the
58//       Ethernet devices.  This can be updated in the future.
59struct xilnet_hw_addr_table xilnet_hw_tbl[HW_ADDR_TBL_ENTRIES];
60
61
62// Flags
63unsigned char             ishwaddrinit = 0;
64static unsigned long long curr_age     = 0;
65
66
67/*************************** Function Prototypes *****************************/
68
69#ifdef _DEBUG_
70void print_pkt(unsigned char *buf, int size);
71
72#if 0
73void print_hw_tbl();
74#endif
75
76#ifdef  XILNET_AXI_DMA_INF_USED
77void print_XAxiDma_Bd( XAxiDma_Bd *BD_ptr );
78void print_XAxiDma_BdRing( XAxiDma_BdRing *BD_RING_ptr );
79void print_XAxiDma_Config( XAxiDma_Config * DMA_CFG_ptr );
80#endif
81
82#ifdef XILNET_AXI_FIFO_INF_USED
83void print_XLlFifo( XLlFifo * FIFO_ptr );
84#endif
85
86#endif
87
88
89/******************************** Functions **********************************/
90
91int xilnet_eth_device_init( unsigned int    eth_dev_num,
92                            unsigned int    base_addr,
93                            unsigned char * node_ip_addr,
94                            unsigned char * node_hw_addr
95                          ) {
96
97    int          status;
98
99#ifdef  XILNET_AXI_DMA_INF_USED
100    XAxiDma_Bd   BD_template;
101#endif
102
103    // Check to see if we are initializing a valid interface
104    if ( eth_dev_num >= XILNET_NUM_ETH_DEVICES ) {
105        xil_printf("  **** ERROR:  Trying to initialize Ethernet device %d.  Only %d configured in the HW. \n", (eth_dev_num+1), XILNET_NUM_ETH_DEVICES);
106        return -1;
107    }
108
109#ifdef _DEBUG_
110    xil_printf("xilnet_eth_device_init: Device %d \n", eth_dev_num);
111#endif
112
113    // Initialize the Ethernet device structure
114    xilnet_init_eth_device_struct(eth_dev_num);
115
116    // Set up HW info
117    xilnet_eth_set_inf_hw_info(eth_dev_num, node_ip_addr, node_hw_addr);
118
119    // Depending on the interface type, set up the device
120    switch( eth_device[eth_dev_num].inf_type ) {
121
122    case XILNET_AXI_FIFO_INF:
123
124#ifdef XILNET_AXI_FIFO_INF_USED
125
126        xil_printf("  Configuring ETH %d for AXI FIFO mode with %d byte buffers (%d receive, 1 send)\n", eth_dev_num, eth_device[eth_dev_num].buf_size, eth_device[eth_dev_num].num_recvbuf );
127
128        XLlFifo_Initialize( eth_device[eth_dev_num].inf_ref, base_addr);
129
130#ifdef _DEBUG_
131        print_XLlFifo( eth_device[eth_dev_num].inf_ref );
132#endif
133
134#else
135        xil_printf("  **** ERROR:  Trying to initialize Ethernet device %d.  Driver not configured to use AXI FIFO. \n", (eth_dev_num+1));
136        return -1;
137#endif
138        break;
139
140
141    case XILNET_AXI_DMA_INF:
142
143#ifdef XILNET_AXI_DMA_INF_USED
144        xil_printf("  Configuring ETH %d for AXI DMA mode with %d byte buffers (%d receive, 1 send)\n", eth_dev_num, eth_device[eth_dev_num].buf_size, eth_device[eth_dev_num].num_recvbuf );
145
146        // Initialize DMA pointers
147        eth_device[eth_dev_num].inf_cfg_ref      = (void *) XAxiDma_LookupConfig( eth_device[eth_dev_num].inf_id );
148        eth_device[eth_dev_num].dma_rx_ring_ref  = (void *) XAxiDma_GetRxRing( (XAxiDma *)eth_device[eth_dev_num].inf_ref );
149        eth_device[eth_dev_num].dma_tx_ring_ref  = (void *) XAxiDma_GetTxRing( (XAxiDma *)eth_device[eth_dev_num].inf_ref );
150
151#ifdef _DEBUG_
152        print_XAxiDma_Config( eth_device[eth_dev_num].inf_cfg_ref );
153#endif
154
155        // Initialize AXIDMA engine. AXIDMA engine must be initialized before AxiEthernet.
156        // During AXIDMA engine initialization, AXIDMA hardware is reset, and since AXIDMA
157        // reset line is connected to AxiEthernet, this would ensure a reset of AxiEthernet.
158
159        status = XAxiDma_CfgInitialize( (XAxiDma *)eth_device[eth_dev_num].inf_ref, eth_device[eth_dev_num].inf_cfg_ref);
160        if(status != XST_SUCCESS) {
161            xil_printf("*** Error initializing DMA\n");
162        }
163
164        // Setup RX BD space:
165        //   - RX_BD_space is a properly aligned area of memory
166        //   - No MMU is being used so the physical and virtual addresses are the same.
167        //   - Setup a BD template for the channel. This template will be copied to every BD.
168
169#ifdef _DEBUG_
170        xil_printf("RX BD Space    = 0x%x\n", eth_device[eth_dev_num].dma_rx_bd_ref);
171#endif
172
173        // Create the RX BD ring
174        status = XAxiDma_BdRingCreate( eth_device[eth_dev_num].dma_rx_ring_ref,
175                                 (u32) eth_device[eth_dev_num].dma_rx_bd_ref,
176                                 (u32) eth_device[eth_dev_num].dma_rx_bd_ref,
177                                       XILNET_BD_ALIGNMENT,
178                                       eth_device[eth_dev_num].dma_rx_bd_cnt);
179        if (status != XST_SUCCESS) {
180            xil_printf("*** Error setting up RX BD space\n");
181        }
182
183        XAxiDma_BdClear(&BD_template);
184
185        status = XAxiDma_BdRingClone(eth_device[eth_dev_num].dma_rx_ring_ref, &BD_template);
186        if (status != XST_SUCCESS) {
187            xil_printf("*** Error initializing RX BD space\n");
188        }
189
190        // Setup TX BD space:
191        //   - TX_BD_space is a properly aligned area of memory
192        //   - No MMU is being used so the physical and virtual addresses are the same.
193        //   - Setup a BD template for the channel. This template will be copied to every BD.
194
195#ifdef _DEBUG_
196        xil_printf("TX BD Space    = 0x%x\n", eth_device[eth_dev_num].dma_tx_bd_ref);
197#endif
198
199        // Create the TX BD ring
200        status = XAxiDma_BdRingCreate( eth_device[eth_dev_num].dma_tx_ring_ref,
201                                 (u32) eth_device[eth_dev_num].dma_tx_bd_ref,
202                                 (u32) eth_device[eth_dev_num].dma_tx_bd_ref,
203                                       XILNET_BD_ALIGNMENT,
204                                       eth_device[eth_dev_num].dma_tx_bd_cnt);
205        if (status != XST_SUCCESS) {
206            xil_printf("*** Error setting up TX BD space\n");
207        }
208
209        // We can re-use the BD_template from above
210        status = XAxiDma_BdRingClone(eth_device[eth_dev_num].dma_tx_ring_ref, &BD_template);
211        if (status != XST_SUCCESS) {
212            xil_printf("*** Error initializing TX BD space\n");
213        }
214
215#else
216        xil_printf("  **** ERROR:  Trying to initialize Ethernet device %d.  Driver not configured to use AXI DMA. \n", (eth_dev_num+1));
217        return -1;
218#endif
219        break;
220
221    case XILNET_TEMAC_INF:
222
223#ifdef XILNET_TEMAC_INF_USED
224
225        xil_printf("  Configuring ETH %d for TEMAC mode with %d byte buffers (%d receive, 1 send)\n", eth_dev_num, eth_device[eth_dev_num].buf_size, eth_device[eth_dev_num].num_recvbuf );
226
227        // Initialize DMA pointers
228        eth_device[eth_dev_num].inf_dma_cfg_ref      = (void *) XDmaCentral_LookupConfig( eth_device[eth_dev_num].inf_dma_id );
229
230        //Initialize the config struct
231        status = XDmaCentral_CfgInitialize((XDmaCentral *)       eth_device[eth_dev_num].inf_dma_ref,
232                                           (XDmaCentral_Config *)eth_device[eth_dev_num].inf_dma_cfg_ref,
233                                          ((XDmaCentral_Config *)eth_device[eth_dev_num].inf_dma_cfg_ref)->BaseAddress );
234        if(status != XST_SUCCESS) {
235            xil_printf("*** Error initializing DMA\n");
236        }
237
238        //Disable Interrupts
239        XDmaCentral_InterruptEnableSet(eth_device[eth_dev_num].inf_dma_ref, 0);
240
241#ifdef _DEBUG_
242        xil_printf("Initializing FIFO: %x     %x    \n", eth_device[eth_dev_num].inf_ref, base_addr);
243#endif       
244
245        // Initialize the FIFO
246        XLlFifo_Initialize( eth_device[eth_dev_num].inf_ref, base_addr);
247
248
249#else
250        xil_printf("  **** ERROR:  Trying to initialize Ethernet device %d.  Driver not configured to use TEMAC. \n", (eth_dev_num+1));
251        return -1;
252#endif
253        break;
254
255    default:
256        xil_printf("  **** ERROR:  Trying to initialize Ethernet device %d.  Interface %d does not exist. \n", (eth_dev_num+1), eth_device[eth_dev_num].inf_type);
257        return -1;
258        break;
259    }
260
261#ifdef _DEBUG_
262        xil_printf("xilnet_eth_device_init done\n");
263#endif       
264       
265    return 0;
266}
267
268
269
270int xilnet_eth_set_inf_hw_info( unsigned int eth_dev_num, unsigned char * node_ip_addr, unsigned char * node_hw_addr ) {
271
272    int i;
273
274    // Check to see if we are initializing a valid interface
275    if ( eth_dev_num >= XILNET_NUM_ETH_DEVICES ) {
276        xil_printf("  **** ERROR:  Trying to start Ethernet device %d.  Only %d configured in the HW. \n", (eth_dev_num+1), XILNET_NUM_ETH_DEVICES);
277        return -1;
278    }
279
280#ifdef _DEBUG_
281    xil_printf("Setting IP Address:  %d.%d.%d.%d \n", node_ip_addr[0], node_ip_addr[1], node_ip_addr[2], node_ip_addr[3]);
282    xil_printf("Setting HW Address:  %2x-%2x-%2x-%2x-%2x-%2x \n", node_hw_addr[0], node_hw_addr[1], node_hw_addr[2], node_hw_addr[3], node_hw_addr[4], node_hw_addr[5]);
283#endif
284
285    // Update the IP Address
286    for ( i = 0; i < IP_VERSION; i++) {
287        eth_device[eth_dev_num].node_ip_addr[i] = node_ip_addr[i];
288    }
289
290    // Update the MAC Address
291    for ( i = 0; i < ETH_ADDR_LEN; i++ ) {
292        eth_device[eth_dev_num].node_hw_addr[i] = node_hw_addr[i];
293    }
294
295    return 0;
296}
297
298
299
300int xilnet_eth_get_inf_ip_addr( unsigned int eth_dev_num, unsigned char * node_ip_addr ) {
301
302    int i;
303
304    // Check to see if we are initializing a valid interface
305    if ( eth_dev_num >= XILNET_NUM_ETH_DEVICES ) {
306        xil_printf("  **** ERROR:  Trying to start Ethernet device %d.  Only %d configured in the HW. \n", (eth_dev_num+1), XILNET_NUM_ETH_DEVICES);
307        return -1;
308    }
309
310    // Update the IP Address
311    for ( i = 0; i < IP_VERSION; i++) {
312        node_ip_addr[i] = eth_device[eth_dev_num].node_ip_addr[i];
313    }
314
315#ifdef _DEBUG_
316    xil_printf("Getting IP Address:  %d.%d.%d.%d \n", node_ip_addr[0], node_ip_addr[1], node_ip_addr[2], node_ip_addr[3]);
317#endif
318
319    return 0;
320}
321
322
323
324int xilnet_eth_get_inf_hw_addr( unsigned int eth_dev_num, unsigned char * node_hw_addr ) {
325
326    int i;
327
328    // Check to see if we are initializing a valid interface
329    if ( eth_dev_num >= XILNET_NUM_ETH_DEVICES ) {
330        xil_printf("  **** ERROR:  Trying to start Ethernet device %d.  Only %d configured in the HW. \n", (eth_dev_num+1), XILNET_NUM_ETH_DEVICES);
331        return -1;
332    }
333
334    // Update the MAC Address
335    for ( i = 0; i < ETH_ADDR_LEN; i++ ) {
336        node_hw_addr[i] = eth_device[eth_dev_num].node_hw_addr[i];
337    }
338
339#ifdef _DEBUG_
340    xil_printf("Getting HW Address:  %2x-%2x-%2x-%2x-%2x-%2x \n", node_hw_addr[0], node_hw_addr[1], node_hw_addr[2], node_hw_addr[3], node_hw_addr[4], node_hw_addr[5]);
341#endif
342
343    return 0;
344}
345
346
347
348int xilnet_eth_device_start( unsigned int eth_dev_num ) {
349
350    int              status;
351    int              i;
352    int              free_BD_count;
353
354#ifdef  XILNET_AXI_DMA_INF_USED
355    XAxiDma_BdRing  *RX_RING_ptr;
356    XAxiDma_Bd      *BD_ptr;
357    XAxiDma_Bd      *BD_cur_ptr;
358#endif
359
360    // Check to see if we are initializing a valid interface
361    if ( eth_dev_num >= XILNET_NUM_ETH_DEVICES ) {
362        xil_printf("  **** ERROR:  Trying to start Ethernet device %d.  Only %d configured in the HW. \n", (eth_dev_num+1), XILNET_NUM_ETH_DEVICES);
363        return -1;
364    }
365
366    // Depending on the interface type, set up the device
367    switch( eth_device[eth_dev_num].inf_type ) {
368
369    case XILNET_AXI_FIFO_INF:
370
371#ifdef XILNET_AXI_FIFO_INF_USED
372        // Do nothing, interface is already ready to go
373
374#ifdef _DEBUG_
375        xil_printf("Starting Ethernet Device %d with AXI FIFO\n", eth_dev_num);
376#endif       
377       
378#else
379        xil_printf("  **** ERROR:  Trying to start Ethernet device %d.  Driver not configured to use AXI FIFO. \n", (eth_dev_num+1));
380        return -1;
381#endif
382
383        break;
384
385
386    case XILNET_AXI_DMA_INF:
387
388#ifdef XILNET_AXI_DMA_INF_USED
389
390        // Get the TX Buffer Descriptor Ring pointer
391        RX_RING_ptr = (XAxiDma_BdRing *)eth_device[eth_dev_num].dma_rx_ring_ref;
392
393        // Initialize RX BD space:
394        //   - Configure buffer descriptors
395        free_BD_count = XAxiDma_BdRingGetFreeCnt(RX_RING_ptr);
396
397        // Allocate receive buffers
398        status = XAxiDma_BdRingAlloc(RX_RING_ptr, free_BD_count, &BD_ptr);
399        if (status != XST_SUCCESS) {
400            xil_printf("*** Error allocating RxBD\n");
401            return -1;
402        }
403
404#ifdef _DEBUG_
405        xil_printf("Recieve Buffer = 0x%x    size= %d \n", eth_device[eth_dev_num].recvbuf, sizeof(eth_device[eth_dev_num].recvbuf));
406        print_XAxiDma_Bd( BD_ptr );
407#endif
408
409        if ( eth_device[eth_dev_num].num_recvbuf != free_BD_count ) {
410            xil_printf("*** Error number of receive buffers %d not equal to number of buffer descriptors %d \n", eth_device[eth_dev_num].num_recvbuf, free_BD_count);
411            return -1;
412        }
413
414        // Setup the Buffer descriptors
415        BD_cur_ptr = BD_ptr;
416        for ( i=0; i<free_BD_count; i++ ){
417
418            XAxiDma_BdSetBufAddr(BD_cur_ptr, (u32) (eth_device[eth_dev_num].recvbuf + (i * eth_device[eth_dev_num].buf_size)));
419            XAxiDma_BdSetLength(BD_cur_ptr, eth_device[eth_dev_num].buf_size, RX_RING_ptr->MaxTransferLen);
420            XAxiDma_BdSetCtrl(BD_cur_ptr, 0);
421            XAxiDma_BdSetId(BD_cur_ptr, (u32) (eth_device[eth_dev_num].recvbuf + (i * eth_device[eth_dev_num].buf_size)));
422
423            BD_cur_ptr = XAxiDma_BdRingNext(RX_RING_ptr, BD_cur_ptr);
424        }
425
426
427        // Enqueue to HW
428        status = XAxiDma_BdRingToHw(RX_RING_ptr, free_BD_count, BD_ptr);
429        if (status != XST_SUCCESS) {
430            xil_printf("*** Error committing RxBD to HW\n");
431            return -1;
432        }
433
434#ifdef _DEBUG_
435        xil_printf("ETH_B_DMA_RX_RING_ptr: \n");
436        print_XAxiDma_BdRing( RX_RING_ptr );
437        print_XAxiDma_Bd( BD_ptr );
438#endif
439
440        // Start DMA RX channel. Now it's ready to receive data.
441        status = XAxiDma_BdRingStart( RX_RING_ptr );
442        if (status != XST_SUCCESS) {
443            xil_printf("*** Error starting RX channel\n");
444            return -1;
445        }
446
447#else
448        xil_printf("  **** ERROR:  Trying to start Ethernet device %d.  Driver not configured to use AXI DMA. \n", (eth_dev_num+1));
449        return -1;
450#endif
451        break;
452
453
454    case XILNET_TEMAC_INF:
455
456#ifdef XILNET_TEMAC_INF_USED
457        // Do nothing, interface is already ready to go
458
459#ifdef _DEBUG_
460#if 0
461        xil_printf("Starting Ethernet Device %d with TEMAC\n", eth_dev_num);
462#endif
463#endif       
464
465#else
466        xil_printf("  **** ERROR:  Trying to initialize Ethernet device %d.  Driver not configured to use TEMAC. \n", (eth_dev_num+1));
467        return -1;
468#endif
469        break;
470
471    default:
472        xil_printf("  **** ERROR:  Trying to start Ethernet device %d.  Interface %d does not exist. \n", (eth_dev_num+1), eth_device[eth_dev_num].inf_type);
473        return -1;
474        break;
475    }
476
477    return 0;
478}
479
480
481
482/*
483 * initialize xilnet hardware address
484 */
485void xilnet_eth_init_hw_addr(int eth_dev_num, unsigned char* addr) {
486   int k = 0;
487   int j;
488   int sum = 0;
489   int val = 0;
490   
491   for (j = 0; j < 5; j++) {
492   
493      // parse input for colon separated hw address
494      while(addr[k] != ':') {
495         if (addr[k] >= 'a' && addr[k] <= 'f') 
496            val = addr[k] - 'a' + 10;
497         else if (addr[k] >= 'A' && addr[k] <= 'F')
498            val = addr[k] - 'A' + 10;
499         else
500            val = addr[k] - '0';
501         sum = sum * 16 + val;
502         k++;
503      }
504   
505      k++; // move over the colon
506      eth_device[eth_dev_num].node_hw_addr[j] = (unsigned char) sum;
507      sum = 0;   
508   }
509   
510   // read last byte of hw address
511   while (addr[k] != '\0') {
512      if (addr[k] >= 'a' && addr[k] <= 'f') 
513         val = addr[k] - 'a' + 10;
514      else if (addr[k] >= 'A' && addr[k] <= 'F')
515         val = addr[k] - 'A' + 10;
516      else
517         val = addr[k] - '0';
518      sum = sum * 16 + val;
519      k++;
520   } 
521   eth_device[eth_dev_num].node_hw_addr[5] = (unsigned char) sum;
522}
523
524
525#ifdef XILNET_TEMAC_INF_USED
526inline void waitForDMA( unsigned int eth_dev_num )
527{
528    int RegValue;
529
530    // Wait until the DMA transfer is done by checking the Status register
531    do {RegValue = XDmaCentral_GetStatus((XDmaCentral *)eth_device[eth_dev_num].inf_dma_ref);}
532    while ((RegValue & XDMC_DMASR_BUSY_MASK) == XDMC_DMASR_BUSY_MASK);
533
534    return;
535}
536#endif
537
538
539/*
540 * Receive frame
541 *
542 * Returns either -1 or a pointer to the buffer of the received frame
543 *
544 */
545unsigned int xilnet_eth_recv_frame( unsigned int eth_dev_num ) {
546
547    // TODO: FIX - NEEDS TO RETURN THE POINTER TO THE BUFFER
548
549    int status             = -1;
550    int processed_BD_count = 0;
551    int free_BD_count      = 0;
552    int size               = -1;
553    struct xilnet_eth_hdr *eth;
554    void                  *pktBufPtr;
555#ifdef XILNET_AXI_DMA_INF_USED
556    int dma_error           = 0;
557
558    XAxiDma_BdRing        *RX_RING_ptr;
559    XAxiDma_BdRing        *TX_RING_ptr;
560    XAxiDma_Bd            *BD_ptr;
561#endif
562
563#ifdef _DEBUG_
564    unsigned char         *tmp_ptr;
565#endif
566
567    // Check to see if we are receiving on a valid interface
568    if ( eth_dev_num >= XILNET_NUM_ETH_DEVICES ) {
569        xil_printf("  **** ERROR:  Trying to receive on Ethernet device %d.  Only %d configured in the HW. \n", (eth_dev_num+1), XILNET_NUM_ETH_DEVICES);
570        return -1;
571    }
572
573    // Device specific routine for getting a frame
574    switch( eth_device[eth_dev_num].inf_type ) {
575
576    case XILNET_AXI_FIFO_INF:
577
578#ifdef XILNET_AXI_FIFO_INF_USED
579
580#if 0
581#ifdef _DEBUG_
582        xil_printf("AXI ETHERNET FIFO:  \n");
583        xil_printf("FIFO_INST:  0x%x \n", eth_device[eth_dev_num].inf_ref);
584        xil_printf("Ethernet FIFO is empty: %d \n", XLlFifo_IsRxEmpty((XLlFifo *)eth_device[eth_dev_num].inf_ref));
585        xil_printf("Base Addr             : 0x%x \n", ((XLlFifo *)eth_device[eth_dev_num].inf_ref)->BaseAddress );
586        xil_printf("RX Occupancy value    : 0x%x \n", ((*(volatile u32 *)((((XLlFifo *)eth_device[eth_dev_num].inf_ref)->BaseAddress) + (0x0000001c)))) );
587#endif
588#endif
589
590        pktBufPtr = eth_device[eth_dev_num].recvbuf;
591
592        if(XLlFifo_IsRxEmpty((XLlFifo *)eth_device[eth_dev_num].inf_ref)) {
593
594            size=-1;
595
596        } else {
597
598#ifdef _PERFORMANCE_MONITOR_
599            wl_setDebugGPIO(0x1);
600#endif
601
602            if(XLlFifo_RxOccupancy((XLlFifo *)eth_device[eth_dev_num].inf_ref)) {
603                size = XLlFifo_RxGetLen((XLlFifo *)eth_device[eth_dev_num].inf_ref);
604                XLlFifo_Read((XLlFifo *)eth_device[eth_dev_num].inf_ref, pktBufPtr, size);
605            }
606        }
607#else
608        xil_printf("  **** ERROR:  Trying to receive on Ethernet device %d.  Driver not configured to use AXI FIFO. \n", (eth_dev_num+1));
609        return -1;
610#endif
611        break;
612
613
614    case XILNET_AXI_DMA_INF:
615
616#ifdef XILNET_AXI_DMA_INF_USED
617
618#if 0
619#ifdef _DEBUG_
620        xil_printf("AXI ETHERNET DMA:  \n");
621#endif
622#endif
623
624        // Get the RX Buffer Descriptor Ring pointer
625        RX_RING_ptr = (XAxiDma_BdRing *)eth_device[eth_dev_num].dma_rx_ring_ref;
626
627        // Check to see that the HW is started (if it is not started, we must have gotten an error somewhere
628        if ( !XAxiDma_BdRingHwIsStarted( RX_RING_ptr ) ) {
629
630            // Get the TX Buffer Descriptor Ring pointer
631            TX_RING_ptr = (XAxiDma_BdRing *)eth_device[eth_dev_num].dma_tx_ring_ref;
632       
633            // Check to see if we have a RX error
634            if ( XAxiDma_BdRingGetError( RX_RING_ptr ) ) {
635#ifdef _DEBUG_
636                print_XAxiDma_BdRing( RX_RING_ptr );
637#endif
638                xil_printf("*** ERROR in RX DMA transfer: 0x%8x \n", XAxiDma_BdRingGetError( RX_RING_ptr ));
639                dma_error = 1;
640            }
641       
642            // Check to see if we have a TX error
643            if ( XAxiDma_BdRingGetError( TX_RING_ptr ) ) {
644#ifdef _DEBUG_
645                print_XAxiDma_BdRing( TX_RING_ptr );
646#endif
647                xil_printf("*** ERROR in TX DMA transfer: 0x%8x \n", XAxiDma_BdRingGetError( TX_RING_ptr ));
648                dma_error = 1;
649            }
650           
651            // If there is an error, reset the DMA
652            if ( dma_error ) {
653                xil_printf("*** Resetting DMA \n");
654                XAxiDma_Reset( (XAxiDma *)eth_device[eth_dev_num].inf_ref );
655            }
656
657            // If not, then start DMA RX channel
658            status = XAxiDma_BdRingStart( RX_RING_ptr );
659            if (status != XST_SUCCESS) {
660                xil_printf("*** Error starting RX channel\n");
661                return -1;
662            }
663        }
664       
665        // See if we have any data to process
666        // NOTE:  We will only process one buffer descriptor at a time in this function call
667        processed_BD_count = XAxiDma_BdRingFromHw(RX_RING_ptr, 0x1, &BD_ptr);
668
669        // If we have data, then we need process the buffer
670        if ( processed_BD_count > 0 ) {
671
672#ifdef _PERFORMANCE_MONITOR_
673            wl_setDebugGPIO(0x1);
674#endif
675
676            status = XAxiDma_BdGetSts(BD_ptr);
677
678            if ((status & XAXIDMA_BD_STS_ALL_ERR_MASK) || (!(status & XAXIDMA_BD_STS_COMPLETE_MASK))) {
679                xil_printf("*** Rx Error: 0x%8x\n", status);
680                return -1;
681            } else {
682                size = (XAxiDma_BdRead(BD_ptr, XAXIDMA_BD_USR4_OFFSET)) & 0x0000FFFF;
683            }
684
685            pktBufPtr = (void *)XAxiDma_BdGetId(BD_ptr);       // BD ID was set to the base address of the buffer
686        }
687#else
688        xil_printf("  **** ERROR:  Trying to receive on Ethernet device %d.  Driver not configured to use AXI DMA. \n", (eth_dev_num+1));
689        return -1;
690#endif
691        break;
692
693
694    case XILNET_TEMAC_INF:
695
696#ifdef XILNET_TEMAC_INF_USED
697
698#if 0
699#ifdef _DEBUG_
700        xil_printf("TEMAC FIFO:  \n");
701        xil_printf("FIFO_INST:  0x%x \n", eth_device[eth_dev_num].inf_ref);
702        xil_printf("Ethernet FIFO is empty: %d \n", XLlFifo_IsRxEmpty((XLlFifo *)eth_device[eth_dev_num].inf_ref));
703        xil_printf("Base Addr             : 0x%x \n", ((XLlFifo *)eth_device[eth_dev_num].inf_ref)->BaseAddress );
704        xil_printf("RX Occupancy value    : 0x%x \n", ((*(volatile u32 *)((((XLlFifo *)eth_device[eth_dev_num].inf_ref)->BaseAddress) + (0x0000001c)))) );
705#endif
706#endif
707
708        pktBufPtr = eth_device[eth_dev_num].recvbuf;
709
710        if( XLlFifo_IsRxEmpty( (XLlFifo *)eth_device[eth_dev_num].inf_ref ) ) {
711            size=-1;
712        } else {
713
714#ifdef _PERFORMANCE_MONITOR_
715            wl_setDebugGPIO(0x1);
716#endif
717
718            if( XLlFifo_RxOccupancy( (XLlFifo *)eth_device[eth_dev_num].inf_ref ) ) {
719
720                waitForDMA(eth_dev_num);
721
722                // Set DMA to non-increment source, increment dest addresses
723                XDmaCentral_SetControl( (XDmaCentral *)eth_device[eth_dev_num].inf_dma_ref, XDMC_DMACR_DEST_INCR_MASK );
724                size = XLlFifo_RxGetLen( (XLlFifo *)eth_device[eth_dev_num].inf_ref );
725                XDmaCentral_Transfer((XDmaCentral *)eth_device[eth_dev_num].inf_dma_ref,
726                                     (u8 *)(((XLlFifo *)eth_device[eth_dev_num].inf_ref)->BaseAddress+XLLF_RDFD_OFFSET),
727                                     (u8 *)pktBufPtr, size);
728            }
729        }
730#else
731        xil_printf("  **** ERROR:  Trying to receive on Ethernet device %d.  Driver not configured to use TEMAC. \n", (eth_dev_num+1));
732        return -1;
733#endif
734        break;
735
736    default:
737        xil_printf("  **** ERROR:  Receiving packet on Ethernet device %d.  Interface %d does not exist. \n", (eth_dev_num+1), eth_device[eth_dev_num].inf_type);
738        return -1;
739        break;
740    }
741
742#if 0
743#ifdef _DEBUG_
744    xil_printf("Ethernet Recvd Frame of size %d...\n", size);
745    tmp_ptr = (unsigned char *)pktBufPtr;
746    xil_printf("src : %d%d%d%d%d%d...\n", tmp_ptr[0], tmp_ptr[1], tmp_ptr[2], tmp_ptr[3], tmp_ptr[4], tmp_ptr[5]);
747    xil_printf("dst : %d%d%d%d%d%d...\n", tmp_ptr[6], tmp_ptr[7], tmp_ptr[8], tmp_ptr[9], tmp_ptr[10], tmp_ptr[11]);
748    xil_printf("type : %d%d...\n", tmp_ptr[12], tmp_ptr[13]);
749#endif
750#endif
751 
752    // Strip off the FCS (or CRC) from the received frame
753    size -= 4;
754 
755    // Process the packet
756    if ( size > 0 ) {
757
758#ifdef _DEBUG_
759        xil_printf("BEGIN xilnet_eth_recv_frame() \n" );
760        xil_printf("  Received %d bytes\n", size);
761        tmp_ptr = (unsigned char *)pktBufPtr;
762        xil_printf("  src  : %2x %2x %2x %2x %2x %2x \n", tmp_ptr[0], tmp_ptr[1], tmp_ptr[2], tmp_ptr[3], tmp_ptr[4], tmp_ptr[5]);
763        xil_printf("  dst  : %2x %2x %2x %2x %2x %2x \n", tmp_ptr[6], tmp_ptr[7], tmp_ptr[8], tmp_ptr[9], tmp_ptr[10], tmp_ptr[11]);
764        xil_printf("  type : %2x %2x \n\n", tmp_ptr[12], tmp_ptr[13]);
765        print_pkt((unsigned char *)pktBufPtr, size);
766#endif
767
768        eth = (struct xilnet_eth_hdr*) pktBufPtr;
769   
770        switch (Xil_Ntohs(eth->type)) {
771            case ETH_PROTO_IP:
772                status = (xilnet_ip(pktBufPtr, size, eth_dev_num));
773                break;
774            case ETH_PROTO_ARP:
775                status = (xilnet_arp(pktBufPtr, size, eth_dev_num));
776                break;
777            default:
778#ifdef _DEBUG_
779                xil_printf("Unknown protocol %x...\r\n", eth->type);
780#endif
781            break;
782        }
783
784
785#ifdef XILNET_AXI_DMA_INF_USED
786        // Post process the DMA buffer descriptors now that we are done with them
787        if (eth_device[eth_dev_num].inf_type == XILNET_AXI_DMA_INF) {
788
789            // Free all processed RX BDs for future transmission
790            status = XAxiDma_BdRingFree(RX_RING_ptr, processed_BD_count, BD_ptr);
791            if (status != XST_SUCCESS) {
792                xil_printf("*** Error freeing up %d RxBDs:  0x%8x\n", processed_BD_count, status);
793            }
794
795            // Return processed BDs to RX channel so we are ready to receive new packets:
796            //    - Allocate all free RX BDs
797            //    - Pass the BDs to RX channel
798            free_BD_count = XAxiDma_BdRingGetFreeCnt(RX_RING_ptr);
799
800            status = XAxiDma_BdRingAlloc(RX_RING_ptr, free_BD_count, &BD_ptr);
801            if (status != XST_SUCCESS) {
802                xil_printf("*** Error allocating %d RxBDs:  0x%8x\n", free_BD_count, status);
803            }
804
805            status = XAxiDma_BdRingToHw(RX_RING_ptr, free_BD_count, BD_ptr);
806            if (status != XST_SUCCESS) {
807                xil_printf("*** Error submiting %d rx BDs failed: 0x%8x\r\n", free_BD_count, status);
808            }
809        }
810#endif
811
812#ifdef _DEBUG_
813        xil_printf("END xilnet_eth_recv_frame() \n" );
814#endif
815
816#ifdef _PERFORMANCE_MONITOR_
817        wl_clearDebugGPIO(0x1);
818#endif
819    }
820
821    return status;
822}
823
824
825/*
826 * Send frame to peer ip addr, peer hw addr
827 */
828int xilnet_eth_send_frame(unsigned char *pkt, int len, unsigned char *dip_addr,
829                          void *dhw_addr, unsigned short type, unsigned int eth_dev_num)
830{
831    int i;
832    int hw_tbl_index = 0;
833
834    int status;
835    int size                = 0;
836    int transmit_flag       = 0;
837    unsigned char  *hw_addr = (unsigned char *)dhw_addr;
838
839#ifdef XILNET_AXI_DMA_INF_USED
840    int processed_BD_count  = 0;
841    int dma_status          = 0;
842    int dma_error           = 0;
843    int dma_hang_count      = 1000;
844
845    XAxiDma_BdRing *RX_RING_ptr;
846    XAxiDma_BdRing *TX_RING_ptr;
847    XAxiDma_Bd     *BD_ptr;
848#endif
849
850    // Check to see if we are sending on a valid interface
851    if ( eth_dev_num >= XILNET_NUM_ETH_DEVICES ) {
852        xil_printf("  **** ERROR:  Trying to send on Ethernet device %d.  Only %d configured in the HW. \n", (eth_dev_num+1), XILNET_NUM_ETH_DEVICES);
853        return -1;
854    }
855   
856#ifdef _DEBUG_
857    xil_printf("BEGIN xilnet_eth_send_frame(): \n");
858    xil_printf("  pkt      = %x \n", pkt);
859    xil_printf("  len      = %d \n", len);
860    xil_printf("  dip_addr = %d.%d.%d.%d \n", dip_addr[0], dip_addr[1], dip_addr[2], dip_addr[3]);
861    xil_printf("  dhw_addr = %02x-%02x-%02x-%02x-%02x-%02x \n", hw_addr[0], hw_addr[1], hw_addr[2], hw_addr[3], hw_addr[4], hw_addr[5]);
862    xil_printf("  type     = %x \n", type);
863    xil_printf("  eth_dev  = %d \n", eth_dev_num);
864#endif
865
866#ifdef _PERFORMANCE_MONITOR_
867    wl_setDebugGPIO(0x2);
868#endif
869
870    // Set the source MAC address
871    for (i = 0; i < ETH_ADDR_LEN; i++) {
872        ((struct xilnet_eth_hdr*)pkt)->src_addr[i] = eth_device[eth_dev_num].node_hw_addr[i];
873    }
874
875    // Set the destination MAC address
876    if (dhw_addr)
877        memcpy(((struct xilnet_eth_hdr*)pkt)->dest_addr, dhw_addr, ETH_ADDR_LEN);
878    else {
879        // find the hw tbl entry index corr to dip_addr
880        hw_tbl_index = xilnet_eth_get_hw_addr(dip_addr, eth_dev_num);
881     
882        for (i = 0; i < ETH_ADDR_LEN; i++) {
883            ((struct xilnet_eth_hdr*)pkt)->dest_addr[i] = xilnet_hw_tbl[hw_tbl_index].hw_addr[i];
884        }
885    }
886
887    // Convert Endianess of type
888    ((struct xilnet_eth_hdr*)pkt)->type = Xil_Htons(type);
889   
890    // pad the ethernet frame if < 60 bytes
891    if (len < 60) {
892        for(i = len; i < ETH_MIN_FRAME_LEN; i++) {
893            pkt[i] = 0;
894        }
895        len = ETH_MIN_FRAME_LEN;
896    }
897
898    // Device specific routine for sending a frame
899    switch( eth_device[eth_dev_num].inf_type ) {
900
901    case XILNET_AXI_FIFO_INF:
902
903#ifdef XILNET_AXI_FIFO_INF_USED
904        XLlFifo_Write((XLlFifo *) eth_device[eth_dev_num].inf_ref, pkt, len);
905
906        // Write the length to the LL_FIFO; this write initiates the TEMAC transmission
907        XLlFifo_TxSetLen((XLlFifo *) eth_device[eth_dev_num].inf_ref, len);
908#else
909        xil_printf("  **** ERROR:  Trying to send on Ethernet device %d.  Driver not configured to use AXI FIFO. \n", (eth_dev_num+1));
910        return -1;
911#endif
912        break;
913
914
915    case XILNET_AXI_DMA_INF:
916
917#ifdef XILNET_AXI_DMA_INF_USED
918
919        // Get the TX Buffer Descriptor Ring pointer
920        TX_RING_ptr = (XAxiDma_BdRing *)eth_device[eth_dev_num].dma_tx_ring_ref;
921       
922        // Get the RX Buffer Descriptor Ring pointer
923        RX_RING_ptr = (XAxiDma_BdRing *)eth_device[eth_dev_num].dma_rx_ring_ref;
924       
925        // Check to see if we have a RX error
926        if ( XAxiDma_BdRingGetError( RX_RING_ptr ) ) {
927#ifdef _DEBUG_
928            print_XAxiDma_BdRing( RX_RING_ptr );
929#endif
930            xil_printf("*** ERROR in RX DMA transfer: 0x%8x \n", XAxiDma_BdRingGetError( RX_RING_ptr ));
931            dma_error = 1;
932        }
933   
934        // Check to see if we have a TX error
935        if ( XAxiDma_BdRingGetError( TX_RING_ptr ) ) {
936#ifdef _DEBUG_
937            print_XAxiDma_BdRing( TX_RING_ptr );
938#endif
939            xil_printf("*** ERROR in TX DMA transfer: 0x%8x \n", XAxiDma_BdRingGetError( TX_RING_ptr ));
940            dma_error = 1;
941        }
942       
943        // If there is an error, reset the DMA
944        if ( dma_error ) {
945            xil_printf("*** Resetting DMA \n");
946            XAxiDma_Reset( (XAxiDma *)eth_device[eth_dev_num].inf_ref );
947        }
948
949        // Allocate, setup and enqueue a TX BD for the Frame
950        status = XAxiDma_BdRingAlloc(TX_RING_ptr, 1, &BD_ptr);
951        if (status != XST_SUCCESS) {
952            xil_printf("*** Error allocating TX BDs:  0x%8x\n", status);
953        }
954
955        // Set the BD address to the start of the packet
956        status = XAxiDma_BdSetBufAddr(BD_ptr, (u32) pkt);
957        if (status != XST_SUCCESS) {
958            xil_printf("*** Error setting TX Address:  status = 0x%8x;  BD = 0x%x;  addr = 0x%x\n", status, BD_ptr, (u32) pkt);
959        }
960
961        // Set the BD length to the length field
962        status = XAxiDma_BdSetLength(BD_ptr, len, TX_RING_ptr->MaxTransferLen);
963        if (status != XST_SUCCESS) {
964            xil_printf("*** Error setting TX Length:  status = 0x%8x;  BD = 0x%x;  len = %d;  max_len = %d\n", status, BD_ptr, len, TX_RING_ptr->MaxTransferLen);
965        }
966
967        // Since this is a single descriptor, set both SOF and EOF
968        XAxiDma_BdSetCtrl(BD_ptr, XAXIDMA_BD_CTRL_TXSOF_MASK | XAXIDMA_BD_CTRL_TXEOF_MASK);
969
970        // Set the Application specific words
971        XAxiDma_BdSetAppWord( BD_ptr, 0, 0x00000000 );
972        XAxiDma_BdSetAppWord( BD_ptr, 1, 0x00000000 );
973        XAxiDma_BdSetAppWord( BD_ptr, 2, 0x00000000 );
974        XAxiDma_BdSetAppWord( BD_ptr, 3, 0x00000000 );
975        XAxiDma_BdSetAppWord( BD_ptr, 4, 0x00000000 );       
976
977#ifdef _DEBUG_
978        print_XAxiDma_BdRing( TX_RING_ptr );
979        print_XAxiDma_Bd( BD_ptr );
980#endif
981
982        // Enqueue to the HW
983        status = XAxiDma_BdRingToHw(TX_RING_ptr, 1, BD_ptr);
984        if (status != XST_SUCCESS) {
985             // Undo BD allocation and exit
986            XAxiDma_BdRingUnAlloc(TX_RING_ptr, 1, BD_ptr);
987            xil_printf("*** Error committing TX BD to HW:  0x%8x\n", status);
988        }
989
990        // Start DMA TX channel. Transmission starts at once. 
991        //   If the channel is already started, then the XAxiDma_BdRingToHw() call will start the transmission
992        if (TX_RING_ptr->RunState == AXIDMA_CHANNEL_HALTED) {
993            status = XAxiDma_BdRingStart(TX_RING_ptr);
994            if (status != XST_SUCCESS) {
995                xil_printf("*** Error starting TX BD:  0x%8x\n", status);
996            }
997        }
998
999        // Poll to find when we are done transmitting the packet
1000        // TODO:  We can change this to non-blocking by moving these checks above the allocate calls
1001        transmit_flag = 0;
1002
1003        while ( transmit_flag == 0 ) {
1004       
1005            processed_BD_count = XAxiDma_BdRingFromHw(TX_RING_ptr, 1, &BD_ptr);
1006
1007            if ( processed_BD_count > 0 ) {
1008
1009#ifdef _DEBUG_
1010                print_XAxiDma_BdRing( TX_RING_ptr );
1011                print_XAxiDma_Bd( BD_ptr );
1012#endif
1013                status = XAxiDma_BdGetSts(BD_ptr);
1014
1015                if ((status & XAXIDMA_BD_STS_ALL_ERR_MASK) || (!(status & XAXIDMA_BD_STS_COMPLETE_MASK))) {
1016                    xil_printf("*** TX Error: 0x%x\n", status);
1017                } else {
1018                    size = (XAxiDma_BdRead(BD_ptr, XAXIDMA_BD_STS_OFFSET)) & 0x0000FFFF;
1019                }
1020
1021                if ( size != len ) {
1022                    xil_printf("*** Size of transmission (0x%x) does not match length of packet (0x%x)\n", size, len);
1023                }
1024
1025                // Clear out all the control / status information before freeing the buffer descriptor
1026                XAxiDma_BdClear(BD_ptr);
1027
1028                // Free all processed RX BDs for future transmission
1029                status = XAxiDma_BdRingFree(TX_RING_ptr, processed_BD_count, BD_ptr);
1030                if (status != XST_SUCCESS) {
1031                    xil_printf("*** Error freeing up %d RxBDs:  0x%8x\n", processed_BD_count, status);
1032                }
1033
1034#ifdef _DEBUG_
1035                print_XAxiDma_BdRing( TX_RING_ptr );
1036                print_XAxiDma_Bd( BD_ptr );
1037#endif
1038
1039                transmit_flag = 1;
1040            }
1041            else {
1042
1043                if ( XAxiDma_BdRingBusy( TX_RING_ptr ) ) {
1044               
1045                    // HW is still busy with the transfer                   
1046                    if ( dma_hang_count == 0 ) {
1047                        xil_printf("  **** ERROR:  Trying to send on Ethernet device %d.  Driver timed out while device was busy.  Unknown ERROR. \n", (eth_dev_num+1));
1048                        return -1;
1049                    } else {
1050                        dma_hang_count--;
1051                    }
1052                } else {
1053
1054                    // Check to see if we have an error
1055                    dma_status = XAxiDma_BdRingGetError( TX_RING_ptr );
1056                   
1057                    if ( dma_status != 0 ) {
1058                        xil_printf("*** ERROR in DMA transfer: 0x%8x \n", dma_status);
1059#ifdef _DEBUG_
1060                        print_XAxiDma_BdRing( TX_RING_ptr );
1061                        print_XAxiDma_Bd( TX_RING_ptr->HwHead );
1062#endif
1063                        // Restart DMA TX channel.
1064                        xil_printf("*** Restarting transfer \n");
1065                        XAxiDma_Reset( (XAxiDma *)eth_device[eth_dev_num].inf_ref );
1066                       
1067                        status = XAxiDma_BdRingStart(TX_RING_ptr);
1068                        if (status != XST_SUCCESS) {
1069                            xil_printf("*** Error starting TX BD:  0x%8x\n", status);
1070                        }
1071                    } else {
1072                        // In the case of large packets, we can encounter a situation where we finish the processing of the
1073                        // packet between the XAxiDma_BdRingFromHw() function call and the XAxiDma_BdRingBusy() function call.
1074                        // In this case, we now have a situation where the DMA is not busy and does not have an error, but we
1075                        // just need to run through the loop one more time in order to finish the transaction.  However,
1076                        // to make sure we don't get stuck in this case (ie there is a packet to process, we are going to
1077                        // enforce a timeout.
1078                       
1079                        if ( dma_hang_count == 0 ) {
1080                            xil_printf("  **** ERROR:  Trying to send on Ethernet device %d.  Driver timed out while device was idle.  Unknown ERROR. \n", (eth_dev_num+1));
1081                            return -1;
1082                        } else {
1083                            dma_hang_count--;
1084                        }
1085                    }
1086                }
1087            }
1088        }
1089
1090#else
1091        xil_printf("  **** ERROR:  Trying to send on Ethernet device %d.  Driver not configured to use AXI DMA. \n", (eth_dev_num+1));
1092        return -1;
1093#endif
1094        break;
1095
1096    case XILNET_TEMAC_INF:
1097
1098#ifdef XILNET_TEMAC_INF_USED
1099        waitForDMA(eth_dev_num);
1100
1101        // Set DMA to increment src, non-increment dest addresses
1102        XDmaCentral_SetControl((XDmaCentral *)eth_device[eth_dev_num].inf_dma_ref, XDMC_DMACR_SOURCE_INCR_MASK);
1103
1104        // Transfer the packet into the LLFIFO
1105        XDmaCentral_Transfer((XDmaCentral *)eth_device[eth_dev_num].inf_dma_ref, (u8 *)(pkt),
1106                             (u8 *)(((XLlFifo *)eth_device[eth_dev_num].inf_ref)->BaseAddress + XLLF_TDFD_OFFSET), len);
1107
1108        waitForDMA(eth_dev_num);
1109
1110        // Write the length to the LL_FIFO; this write initiates the TEMAC transmission
1111        XLlFifo_TxSetLen((XLlFifo *)eth_device[eth_dev_num].inf_ref, len);
1112
1113#else
1114        xil_printf("  **** ERROR:  Trying to send on Ethernet device %d.  Driver not configured to use TEMAC. \n", (eth_dev_num+1));
1115        return -1;
1116#endif
1117        break;
1118
1119    default:
1120        xil_printf("  **** ERROR:  Receiving packet on Ethernet device %d.  Interface %d does not exist. \n", (eth_dev_num+1), eth_device[eth_dev_num].inf_type);
1121        return -1;
1122        break;
1123    }
1124
1125#ifdef _PERFORMANCE_MONITOR_
1126    wl_clearDebugGPIO(0x2);
1127#endif
1128   
1129#ifdef _DEBUG_
1130    xil_printf("  Sent %d bytes\n",len);
1131    xil_printf("END xilnet_eth_send_frame() \n\n");
1132#endif
1133
1134   return len;
1135}
1136
1137
1138/*
1139 * Update Hardware Address Table
1140 */
1141
1142void xilnet_eth_update_hw_tbl(unsigned char *buf, int proto, unsigned int eth_dev_num) {
1143   
1144   unsigned char ip[IP_VERSION];
1145   unsigned char hw[ETH_ADDR_LEN];
1146   int i, j;
1147
1148   // Update the current age
1149   curr_age++;
1150   
1151   // get hw addr
1152   for (i = 0; i < ETH_ADDR_LEN; i++) {
1153      hw[i] = ((struct xilnet_eth_hdr*)buf)->src_addr[i];
1154   }     
1155
1156   // get ip addr
1157   switch (proto) {
1158   case ETH_PROTO_ARP:
1159      for (i = 0; i < IP_VERSION; i++) {
1160         ip[i] = (buf+ETH_HDR_LEN)[ARP_SIP_OFFSET+i];
1161      }
1162      break;
1163   case ETH_PROTO_IP:
1164      for (i = 0; i < IP_VERSION; i++) {
1165         ip[i] = (buf+ETH_HDR_LEN)[IP_SADDR_BASE+i];
1166      }
1167      break;
1168   }
1169
1170   // update the hw addr table
1171   for (i = 0; i < HW_ADDR_TBL_ENTRIES; i++) {
1172      if (xilnet_hw_tbl[i].flag) {
1173         if ( (hw[0] == xilnet_hw_tbl[i].hw_addr[0]) &&
1174              (hw[1] == xilnet_hw_tbl[i].hw_addr[1]) &&
1175              (hw[2] == xilnet_hw_tbl[i].hw_addr[2]) &&
1176              (hw[3] == xilnet_hw_tbl[i].hw_addr[3]) &&
1177              (hw[4] == xilnet_hw_tbl[i].hw_addr[4]) &&
1178              (hw[5] == xilnet_hw_tbl[i].hw_addr[5])
1179              ) {
1180            for (j = 0; j < IP_VERSION; j++)
1181               xilnet_hw_tbl[i].ip_addr[j] = ip[j];;
1182            xilnet_hw_tbl[i].flag = HW_ADDR_ENTRY_IS_TRUE;
1183            xilnet_hw_tbl[i].age = curr_age;
1184            return;
1185         }
1186      }
1187   }
1188   xilnet_eth_add_hw_tbl_entry(ip, hw, eth_dev_num);
1189}
1190
1191
1192/*
1193 * Add an entry into Hw Addr table
1194 */
1195
1196void xilnet_eth_add_hw_tbl_entry(unsigned char *ip, unsigned char *hw, unsigned int eth_dev_num)
1197{
1198   int i, j;
1199   
1200   for (i = 0; i < HW_ADDR_TBL_ENTRIES; i++) {
1201      if (!xilnet_hw_tbl[i].flag) {
1202         for (j = 0; j < ETH_ADDR_LEN; j++) {
1203            xilnet_hw_tbl[i].hw_addr[j] = hw[j];
1204         }
1205         for (j = 0; j < IP_VERSION; j++)  {
1206            xilnet_hw_tbl[i].ip_addr[j] = ip[j];
1207         }
1208         xilnet_hw_tbl[i].flag = HW_ADDR_ENTRY_IS_TRUE;
1209         xilnet_hw_tbl[i].age = curr_age;
1210         return;
1211      }
1212   }
1213   
1214   // Find an old entry to be eliminated from hw tbl
1215   i = xilnet_eth_find_old_entry(eth_dev_num);
1216   for (j = 0; j < ETH_ADDR_LEN; j++) {
1217      xilnet_hw_tbl[i].hw_addr[j] = hw[j];
1218   }
1219   for (j = 0; j < IP_VERSION; j++)  {
1220      xilnet_hw_tbl[i].ip_addr[j] = ip[j];
1221   }
1222   xilnet_hw_tbl[i].flag = HW_ADDR_ENTRY_IS_TRUE;
1223   xilnet_hw_tbl[i].age = curr_age;
1224
1225#ifdef _DEBUG_
1226#if 0
1227   xil_printf("xilnet_add_hw_tbl_entry: \n");
1228   print_hw_tbl();
1229#endif
1230#endif
1231}
1232
1233
1234/*
1235 * Get index into hw tbl for ip_addr
1236 */
1237
1238int xilnet_eth_get_hw_addr(unsigned char *ip, unsigned int eth_dev_num) {
1239   
1240   int i;
1241   
1242   for (i = 0; i < HW_ADDR_TBL_ENTRIES; i++) {
1243      if (xilnet_hw_tbl[i].flag) 
1244         if ( (ip[0] == xilnet_hw_tbl[i].ip_addr[0]) &&
1245              (ip[1] == xilnet_hw_tbl[i].ip_addr[1]) &&
1246              (ip[2] == xilnet_hw_tbl[i].ip_addr[2]) &&
1247              (ip[3] == xilnet_hw_tbl[i].ip_addr[3]) ) {
1248            return i;
1249         }
1250   }
1251   
1252   xil_printf("Hw Addr Not found for IP \r\n");
1253   return -1;
1254}
1255
1256
1257/* 
1258 * Init the hw addr table
1259 */
1260
1261void xilnet_eth_init_hw_addr_tbl(unsigned int eth_dev_num) {
1262   
1263  int i;
1264 
1265  for (i = 0; i < HW_ADDR_TBL_ENTRIES; i++) {
1266     xilnet_hw_tbl[i].flag = HW_ADDR_ENTRY_IS_FALSE;
1267     xilnet_hw_tbl[i].age = 0;
1268  }
1269 
1270  ishwaddrinit = 1;
1271
1272#ifdef _DEBUG_
1273#if 0
1274  xil_printf("xilnet_eth_init_hw_addr_tbl: \n");
1275  print_hw_tbl();
1276#endif
1277#endif
1278}
1279
1280
1281/*
1282 * Find the oldest entry in the Hw Table and
1283 * return its index
1284 */
1285
1286int xilnet_eth_find_old_entry(unsigned int eth_dev_num)
1287{
1288   int i;
1289   int oldest_age = 0;
1290   int oldest = 0;
1291   
1292   for (i = 0; i < HW_ADDR_TBL_ENTRIES; i++) {
1293     
1294      if (curr_age - xilnet_hw_tbl[i].age > HW_ADDR_TBL_MAXAGE) {
1295         oldest = i;
1296         break;
1297      }
1298      else {
1299         if (( curr_age - xilnet_hw_tbl[i].age) > oldest_age) {
1300            oldest_age = curr_age - xilnet_hw_tbl[i].age;
1301            oldest = i;
1302         }
1303      }
1304   }
1305   
1306   return oldest;
1307}
1308
1309
1310// Debug printing functions for various structures
1311
1312#ifdef _DEBUG_
1313
1314void print_pkt(unsigned char *buf, int size)
1315{
1316    int i;
1317
1318    xil_printf("Ethernet Packet: (0x%x bytes)\n", size);
1319
1320    for (i=0; i<size; i++) {
1321        xil_printf("%2x ", buf[i]);
1322        if ( (((i + 1) % 16) == 0) && ((i + 1) != size) ) {
1323            xil_printf("\n");
1324        }
1325    }
1326    xil_printf("\n\n");
1327}
1328
1329
1330#if 0
1331void print_hw_tbl()
1332{
1333    int i, j;
1334
1335    xil_printf("Ethernet HW Table \n");
1336
1337    for (i=0; i<HW_ADDR_TBL_ENTRIES; i++) {
1338        xil_printf("  IP : ");
1339        for (j=0; j<IP_VERSION; j++) {
1340            xil_printf("%d.", xilnet_hw_tbl[i].ip_addr[j]);
1341        }
1342
1343        xil_printf("    HW : ");
1344        for (j=0; j<ETH_ADDR_LEN; j++) {
1345            xil_printf("%x ", xilnet_hw_tbl[i].hw_addr[j]);
1346        }
1347
1348        xil_printf("    \n");
1349    }
1350    xil_printf("\n");
1351}
1352#endif
1353
1354
1355#ifdef  XILNET_AXI_DMA_INF_USED
1356void print_XAxiDma_Bd( XAxiDma_Bd *BD_ptr ) {
1357
1358    int i;
1359
1360    xil_printf("Buffer Descriptor: 0x%x\n", BD_ptr);
1361    for ( i = 0; i < XAXIDMA_BD_NUM_WORDS; i++ ) {
1362        xil_printf("  Value[%2d]:        0x%x \n", i, (*BD_ptr)[i]);
1363    }
1364    xil_printf("\n");
1365}
1366
1367
1368void print_XAxiDma_BdRing( XAxiDma_BdRing *BD_RING_ptr ) {
1369
1370    xil_printf("Buffer Descriptor Ring Pointer: \n");
1371    xil_printf("  ChanBase:         0x%x \n", BD_RING_ptr->ChanBase);
1372    xil_printf("  IsRxChannel:      0x%x \n", BD_RING_ptr->IsRxChannel);
1373    xil_printf("  RunState:         0x%x \n", BD_RING_ptr->RunState);
1374    xil_printf("  HasStsCntrlStrm:  0x%x \n", BD_RING_ptr->HasStsCntrlStrm);
1375    xil_printf("  HasDRE:           0x%x \n", BD_RING_ptr->HasDRE);
1376    xil_printf("  DataWidth:        0x%x \n", BD_RING_ptr->DataWidth);
1377    xil_printf("  MaxTransferLen:   0x%x \n", BD_RING_ptr->MaxTransferLen);
1378    xil_printf("  FirstBdPhysAddr:  0x%x \n", BD_RING_ptr->FirstBdPhysAddr);
1379    xil_printf("  FirstBdAddr:      0x%x \n", BD_RING_ptr->FirstBdAddr);
1380    xil_printf("  LastBdAddr:       0x%x \n", BD_RING_ptr->LastBdAddr);
1381    xil_printf("  Length:           0x%x \n", BD_RING_ptr->Length);
1382    xil_printf("  Separation:       0x%x \n", BD_RING_ptr->Separation);
1383    xil_printf("  FreeHead:         0x%x \n", BD_RING_ptr->FreeHead);
1384    xil_printf("  PreHead:          0x%x \n", BD_RING_ptr->PreHead);
1385    xil_printf("  HwHead:           0x%x \n", BD_RING_ptr->HwHead);
1386    xil_printf("  HwTail:           0x%x \n", BD_RING_ptr->HwTail);
1387    xil_printf("  PostHead:         0x%x \n", BD_RING_ptr->PostHead);
1388    xil_printf("  BdaRestart:       0x%x \n", BD_RING_ptr->BdaRestart);
1389    xil_printf("  FreeCnt:          0x%x \n", BD_RING_ptr->FreeCnt);
1390    xil_printf("  PreCnt:           0x%x \n", BD_RING_ptr->PreCnt);
1391    xil_printf("  HwCnt:            0x%x \n", BD_RING_ptr->HwCnt);
1392    xil_printf("  PostCnt:          0x%x \n", BD_RING_ptr->PostCnt);
1393    xil_printf("  AllCnt:           0x%x \n", BD_RING_ptr->AllCnt);
1394    xil_printf("  RingIndex:        0x%x \n", BD_RING_ptr->RingIndex);
1395    xil_printf("\n");
1396}
1397
1398
1399void print_XAxiDma_Config( XAxiDma_Config * DMA_CFG_ptr ) {
1400
1401    xil_printf("DMA Config Pointer: \n");
1402    xil_printf("  DeviceId:         0x%x \n", DMA_CFG_ptr->DeviceId);
1403    xil_printf("  BaseAddr:         0x%x \n", DMA_CFG_ptr->BaseAddr);
1404    xil_printf("  HasStsCntrlStrm:  0x%x \n", DMA_CFG_ptr->HasStsCntrlStrm);
1405    xil_printf("  HasMm2S:          0x%x \n", DMA_CFG_ptr->HasMm2S);
1406    xil_printf("  HasMm2SDRE:       0x%x \n", DMA_CFG_ptr->HasMm2SDRE);
1407    xil_printf("  Mm2SDataWidth:    0x%x \n", DMA_CFG_ptr->Mm2SDataWidth);
1408    xil_printf("  HasS2Mm:          0x%x \n", DMA_CFG_ptr->HasS2Mm);
1409    xil_printf("  HasS2MmDRE:       0x%x \n", DMA_CFG_ptr->HasS2MmDRE);
1410    xil_printf("  S2MmDataWidth:    0x%x \n", DMA_CFG_ptr->S2MmDataWidth);
1411    xil_printf("  HasSg:            0x%x \n", DMA_CFG_ptr->HasSg);
1412    xil_printf("  Mm2sNumChannels:  0x%x \n", DMA_CFG_ptr->Mm2sNumChannels);
1413    xil_printf("  S2MmNumChannels:  0x%x \n", DMA_CFG_ptr->S2MmNumChannels);
1414    xil_printf("\n");
1415}
1416#endif
1417
1418#ifdef XILNET_AXI_FIFO_INF_USED
1419void print_XLlFifo( XLlFifo * FIFO_ptr ) {
1420
1421    xil_printf("FIFO Pointer: \n");
1422    xil_printf("  BaseAddress:       0x%x \n", FIFO_ptr->BaseAddress);
1423    xil_printf("  IsReady:           0x%x \n", FIFO_ptr->IsReady);
1424    xil_printf("  RX instance:       0x%x \n", FIFO_ptr->RxStreamer.FifoInstance);
1425    xil_printf("  RX width:          0x%x \n", FIFO_ptr->RxStreamer.FifoWidth);
1426    xil_printf("  RX HeadIndex:      0x%x \n", FIFO_ptr->RxStreamer.HeadIndex);
1427    xil_printf("  RX FrmByteCnt:     0x%x \n", FIFO_ptr->RxStreamer.FrmByteCnt);
1428    xil_printf("  TX instance:       0x%x \n", FIFO_ptr->TxStreamer.FifoInstance);
1429    xil_printf("  TX width:          0x%x \n", FIFO_ptr->TxStreamer.FifoWidth);
1430    xil_printf("  TX HeadIndex:      0x%x \n", FIFO_ptr->TxStreamer.TailIndex);
1431    xil_printf("\n");
1432}
1433#endif
1434
1435#endif
1436
1437
1438
Note: See TracBrowser for help on using the repository browser.