📄 ethernet_test.c
字号:
/*****************************************************************************
** **
** Name: ethernet_TEST.c **
** **
******************************************************************************
(C) Copyright 2006 - Analog Devices, Inc. All rights reserved.
This software is proprietary and confidential. By using this software you agree
to the terms of the associated Analog Devices License Agreement.
Purpose:
Perform a POST for ethernet on USBLAN Extender board on the BF533 EZ-Kit Lite
******************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <services\services.h>
#include <drivers\adi_dev.h>
#include <ADI_ETHER_USBLAN.h>
#define USBLAN
#if defined(__ADSPBF533__)
#include <cdefbf533.h>
#elif defined(__ADSPBF561__)
#include <cdefbf561.h>
#elif defined(__ADSPBF538__)
#include <cdefbf538.h>
#endif /* __ADSPBF533__ */
/*****************************************************************************
*
* Configuration Parameters
**/
//#define _ETHERNET_DEBUG_ /* Enables Output Messages */
#define NO_FRAMES 1000 /* Total Number of Test frames */
#define NEGOTIATE /* Driver starts in Auto Neg mode */
#define FILL_AND_CHECK /* A pattern is filled and checked */
#define NO_RCVES 20 /* Number of receive buffers */
#define NO_XMITS 1 /* Number of transmit buffers */
//#define SET_LOOPBACK
//#define CHECK_FRAMES
//#define BOARD_TO_BOARD
//#define SENDING
#ifdef _ETHERNET_DEBUG_
#define DEBUG_PRINT(_str) do { \
printf("%s\n",_str); \
}while(0)
#else
#define DEBUG_PRINT(_str)
#endif /* _ETHERNET_DEBUG_ */
/****************************************************************************
*
* Structure Declarations
*
**/
typedef struct template_info {
short id;
short lnth;
unsigned char pattern;
} TEMPLATE_INFO;
typedef struct stats {
unsigned int nbytes;
unsigned int nframes;
} STATS;
typedef struct buffer {
struct buffer *next;
ADI_ETHER_BUFFER ctrl;
struct buffer *chain;
ADI_ETHER_FRAME_BUFFER hdr;
int template_id;
unsigned char data[1600];
} BUFFER;
/****************************************************************************
*
* Global Varaibles
*
**/
#pragma alignment_region (4)
char intmgr_storage[8*ADI_INT_SECONDARY_MEMORY];
char devmgr_storage[ADI_DEV_BASE_MEMORY+2*ADI_DEV_DEVICE_MEMORY];
char dcbmgr_storage[ADI_DCB_QUEUE_SIZE+4]; // safety margin
char dcbqueue_storage[16*ADI_DCB_ENTRY_SIZE];
char BaseMemSize[ADI_ETHER_MEM_USBLAN_BASE_SIZE];
char MemRcve[NO_RCVES*ADI_ETHER_MEM_USBLAN_PER_RECV];
char MemXmit[NO_XMITS*ADI_ETHER_MEM_USBLAN_PER_XMIT];
#pragma alignment_region_end
#ifdef CHECK_FRAMES
volatile bool FrameRcvd,FrameXmit;
int FrameSize=0;
bool SizeOK[2000];
#ifndef BOARD_TO_BOARD
#ifndef SENDING
#define SENDING
#endif
#endif
#endif /* CHECK_FRAMES */
#define NO_BUFFERS NO_RCVES+NO_XMITS+10
#define MAX_RCVES (NO_RCVES+2)
#define MAX_XMITS (NO_XMITS)
bool g_SystemInitialized= false;
int heap_ndx=-1;
u16 phyregs[32];
int CurXmit = 0,CurRcve=0;
int NoRcvd = 0, NoXmit = 0, NoInts = 0;
int NoWrites = 0, NoXmitErrs= 0, NoRcvdErrs= 0, NoIgnored= 0;
static TEMPLATE_INFO templates[]={
{0, 256,0xa1}, // always fails
{3, 512,0x33}, // always fails
{1,1496,0x10}, // never
{2, 60,0x04}, // never
{4, 128,0x5a}, // never fails
{5,1024,0x00}, // never fails
{6, 60,0x43}, // never fails
{7, 129,0x63}, // never
{8,1301,0x89}, // never
{9, 65,0x77} //never
};
STATS CurRxStat = {0} ,CurTxStat ={0};
STATS AvgRxStat[10],AvgTxStat[10];
bool TxActive= true;
int CurMinute,DumpStats;
int NoTemplates = sizeof(templates)/sizeof(TEMPLATE_INFO);
int CtTemplates[100];
BUFFER *FreeBuf=NULL; BUFFER *FirstBuffer;
unsigned int MinRecvBufsize = 0, BufferPrefix=0;
int SizeOfAdiEtherBuffer = sizeof(ADI_ETHER_BUFFER[2])/2;
ADI_DEV_DEVICE_HANDLE lan_handle;
void *DriverHandle;
ADI_ETHER_SUPPLY_MEM memtable = {
MemRcve,sizeof(MemRcve),0,
MemXmit,sizeof(MemXmit),0,
BaseMemSize,sizeof(BaseMemSize)};
#ifdef USBLAN
char MacAddr[] = {0x00,0x01,0x02,0x03,0x04,0x05};
#else
#ifdef SENDING
char MacAddr[] = {0x00,0x01,0x02,0x03,0x04,0x06};
#else
char MacAddr[] = {0x00,0x01,0x02,0x03,0x04,0x07};
#endif
#endif
/**
* Device I/O Control Command table
**/
ADI_DEV_CMD_VALUE_PAIR setup[] ={
{ADI_ETHER_CMD_SET_MAC_ADDR,MacAddr},
{ADI_ETHER_CMD_GET_BUFFER_PREFIX,&BufferPrefix},
{ADI_ETHER_CMD_GET_MIN_RECV_BUFSIZE,&MinRecvBufsize},
#ifndef NEGOTIATE
{ADI_ETHER_CMD_SET_SPEED,(void *)2 /* 100 */},
{ADI_ETHER_CMD_SET_FULL_DUPLEX,(void *)TRUE},
#else
{ADI_ETHER_CMD_SET_NEGOTIATE,(void *)TRUE},
#endif
{ADI_DEV_CMD_SET_DATAFLOW_METHOD,(void *)ADI_DEV_MODE_CHAINED},
{ADI_DEV_CMD_SET_DATAFLOW,(void *)TRUE},
#ifdef SET_LOOPBACK
{ADI_ETHER_CMD_SET_LOOPBACK,(void *)TRUE},
#endif
{ADI_DEV_CMD_END,(void *)0}
};
/************************************************************************
*
* Local Functions
**/
TEMPLATE_INFO *NextTemplate(void)
{
int ndx = rand()%(sizeof(templates)/sizeof(templates[0]));
return templates+ndx;
}
TEMPLATE_INFO *GetTemplate(int id)
{
int ndx = id%(sizeof(templates)/sizeof(templates[0]));
return templates+ndx;
}
/************************************************************************
*
* Configures the given heap into list of buffers, FirstBuffer
* points to the head of the list.
*
**/
void AllocateBuffers(int heap_ndx)
{
BUFFER *nxt;
int i;
for (i=0;i<NO_BUFFERS;i++)
{
nxt = (BUFFER *)heap_malloc(heap_ndx,sizeof(BUFFER));
if (nxt == NULL)
{
DEBUG_PRINT("Failed to Allocate Buffers");
}
nxt->next = FreeBuf;
nxt->chain = FreeBuf;
FreeBuf = nxt;
}
FirstBuffer = FreeBuf;
}
/************************************************************************
*
* Returns a free buffer.
*
**/
BUFFER *GetBuffer(void)
{
void *xit = adi_int_EnterCriticalRegion(NULL);
BUFFER *buf;
buf = FreeBuf;
if (buf != NULL)
{
FreeBuf = buf->next;
}
adi_int_ExitCriticalRegion(xit);
return buf;
}
/************************************************************************
*
* Adds buffer to the free list
*
**/
void FreeBuffer(BUFFER *buf)
{
void *xit = adi_int_EnterCriticalRegion(NULL);
buf->next = FreeBuf;
FreeBuf = buf;
adi_int_ExitCriticalRegion(xit);
}
/************************************************************************
*
* Dumps contents of the buffer.
*
**/
void DumpBuffer(ADI_ETHER_BUFFER *bf, bool tx)
{
#ifdef DUMP_BUFFER
unsigned short *elnth=(unsigned short *)bf->Data;
int ninline=0;
int nbytes,nodump;
int cmpl;
unsigned char *dmp;
cmpl = (tx?bf->StatusWord&1:bf->StatusWord&0x1000);
printf("%s %s StatusWord = %8.8x\n", (tx?"TX":"RX"),(cmpl?"Completed":" "),bf->StatusWord);
nbytes = (tx?bf->StatusWord>>16:bf->StatusWord)&0x7ff;
printf("Embedded no bytes = %d, lnth from status word = %d\n",*elnth,nbytes);
nbytes = (tx?bf->StatusWord>>16:bf->StatusWord)&0x7ff;
if (tx)
{
nodump = *elnth+2;
if (cmpl && (nodump<nbytes+2)) nodump = nbytes+2;
}
else
{
nodump = (nbytes==0?32:nbytes+2);
}
dmp = (unsigned char *)bf->Data;
ninline = 0;
while (nodump>0)
{
printf("%2.2x ",*dmp++);
ninline++;
if (ninline>=16)
{
ninline = 0;
printf("\n");
}
nodump--;
}
printf("\n-----------------------------------------------------\n");
#endif /* DUMP_BUFFER */
}
/************************************************************************
*
* Atomic increment / Decrement Routines
*
**/
int IncrInt(int *val)
{
void *xit = adi_int_EnterCriticalRegion(NULL);
int vl = *val + 1;
*val = vl;
adi_int_ExitCriticalRegion(xit);
return vl;
}
int DecrInt(int *val)
{
void *xit = adi_int_EnterCriticalRegion(NULL);
int vl = *val - 1;
*val = vl;
adi_int_ExitCriticalRegion(xit);
return vl;
}
/************************************************************************
*
* Lends a free buffer to the driver. Buffer parameters are initialized.
*
**/
void IssueRead(ADI_DEV_DEVICE_HANDLE lan_handle)
{
void *xit = adi_int_EnterCriticalRegion(NULL);
BUFFER *buf = GetBuffer();
int result;
if (buf != NULL)
{
// build the structure
memset(&buf->ctrl,0,SizeOfAdiEtherBuffer);
buf->ctrl.Data = &buf->hdr; // start of the data buffer
buf->ctrl.ElementCount = sizeof(BUFFER)-sizeof(void *)-sizeof(ADI_ETHER_BUFFER);
buf->ctrl.ElementWidth = 1;
buf->ctrl.CallbackParameter = buf;
result = adi_dev_Read(lan_handle,ADI_DEV_1D,(ADI_DEV_BUFFER *)&buf->ctrl);
if (result != ADI_DEV_RESULT_SUCCESS)
{
DEBUG_PRINT("adi_dev_Read Failed");
}
else
{
IncrInt(&CurRcve);
}
}
adi_int_ExitCriticalRegion(xit);
}
/************************************************************************
*
* Gets a free buffers, sets the destination address to be Broadcast
* address fills the frame with a pattern and send it across.
*
**/
int IssueWrite(ADI_DEV_DEVICE_HANDLE lan_handle)
{
void *xit = adi_int_EnterCriticalRegion(NULL);
ADI_ETHER_FRAME_BUFFER *frm;
int result;
BUFFER *buf;
TEMPLATE_INFO *tm = NextTemplate();
int i,*d;
int ok=1;
unsigned short int lt;
if (TxActive)
{
buf = GetBuffer();
if (buf != NULL)
{
CtTemplates[tm->id]++;
// build the structure
memset(&buf->ctrl,0,SizeOfAdiEtherBuffer);
// setup ethernet header
frm = (ADI_ETHER_FRAME_BUFFER *)&buf->hdr;
#ifdef SET_LOOPBACK
memset(frm->Dest,0xff,6); // broadcast
#else
memcpy(frm->Dest,MacAddr,6);
#endif
memcpy(frm->Srce,MacAddr,6);
#ifdef CHECK_FRAMES
lt = sizeof(int)+FrameSize;
#else
lt = sizeof(int)+tm->lnth;
#endif
frm->LTfield[0] = (lt>>8)&0xff;
frm->LTfield[1] = lt&0xff;
frm->NoBytes = lt + sizeof(ADI_ETHER_FRAME_BUFFER)-2;
#ifdef FILL_AND_CHECK
// layout the frame contents
#ifdef CHECK_FRAMES
buf->template_id = FrameSize;
memset(buf->data,0x5a,FrameSize);
#else
buf->template_id = tm->id;
memset(buf->data,tm->pattern,tm->lnth);
#endif
#endif /* FILL_AND_CHECK */
// layout the buffer control structure
buf->ctrl.Data = &buf->hdr; // start of the data buffer
buf->ctrl.ElementCount = frm->NoBytes+2;
buf->ctrl.ElementWidth = 1;
buf->ctrl.CallbackParameter = buf;
#if 0
if ((rand()&0x3)==1)
{
buf->ctrl.ElementCount = 32;
buf->ctrl.PayLoad = ((char *)buf->ctrl.Data) +buf->ctrl.ElementCount;
}
#endif
DumpBuffer(&buf->ctrl,1);
result = adi_dev_Write(lan_handle,ADI_DEV_1D,(ADI_DEV_BUFFER *)&buf->ctrl);
if (result != ADI_DEV_RESULT_SUCCESS)
{
DEBUG_PRINT("adi_dev_Write Failed");
}
else
{
IncrInt(&NoWrites);
#ifndef CHECK_FRAMES
if (NoWrites>=NO_FRAMES)
{
TxActive = false;
}
#endif
IncrInt(&CurXmit);
}
}
else
{
ok =0;
}
}
// RX_OVER_RUN errors FIXME:
// The driver is not fast enough in loopback mode
// Check the driver if anywhere we can optimize.
#ifdef USBLAN
{
int i=0;
for (i=0;i<10000;i++)
;
}
#endif
adi_int_ExitCriticalRegion(xit);
return ok;
}
void IncrIgnored(void)
{
IncrInt(&NoIgnored);
}
/************************************************************************
*
* Callback that gets called when Buffer has been transmitted or a buffer
* is received on the Ethernet.
*
**/
void LanCallback (void* client_handle, u32 event, void *parm)
{
BUFFER *nbuf = (BUFFER *)parm, *nxt_buffer;
ADI_ETHER_BUFFER *buf, *nxt_ether_buffer;
ADI_ETHER_FRAME_BUFFER *frm;
int result;
ADI_DEV_DEVICE_HANDLE handle = *((ADI_DEV_DEVICE_HANDLE *)client_handle);
unsigned char *ch;
int i,ok,reuse,nx;
void *xit = adi_int_EnterCriticalRegion(NULL);
if (handle != DriverHandle)
{
int k=4;
}
if (event != ADI_ETHER_EVENT_INTERRUPT)
{
nbuf = (BUFFER *)parm;
while (nbuf != NULL)
{
buf = &nbuf->ctrl;
nxt_ether_buffer = buf->pNext;
if (nxt_ether_buffer != NULL)
{
nxt_buffer = (BUFFER *)(((char *)nxt_ether_buffer) - sizeof(struct buffer*));
}
else
{
nxt_buffer = NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -