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

Last change on this file was 2660, checked in by welsh, 10 years ago

Transparent changes to make it easier to debug HW table issues.

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