📄 dm9000end.c
字号:
static void dm9000_hash_table(END_DEVICE *dev);
static void program_dm9801( END_DEVICE *dev, UWORD HPNA_rev );
static void program_dm9802(END_DEVICE *dev);
static UWORD phy_read( END_DEVICE *dev, int reg );
static void phy_write( END_DEVICE *dev, int reg, UWORD value);
static UWORD read_srom_word( END_DEVICE *dev, UCHAR offset);
static void write_srom_word( END_DEVICE *dev, UCHAR offset, UWORD value );
static unsigned long cal_CRC(unsigned char * Data, unsigned int Len, UCHAR flag);
static void udelay( int us );
static void Delay500ns(void);
static void dm9000Reset(END_DEVICE *pDrvCtrl);
static void dm9000Config(END_DEVICE *pDrvCtrl);
static void dm9000Int(END_DEVICE *pDrvCtrl);
static void dm9000HandleRcvInt(END_DEVICE *pDrvCtrl);
static STATUS dm9000Recv(END_DEVICE *pDrvCtrl, char* pData);
static UINT dm9000StatusRead(END_DEVICE *pDrvCtrl);
static void dm9000needreset( END_DEVICE *pDrvCtrl );
/* END Specific interfaces. */
/* This is the only externally visible interface. */
/* END_OBJ* dm9000Load (char* initString); */
END_OBJ * sysEtherEndLoad (char* initString, void *pBSP);
static STATUS dm9000Start(END_DEVICE* pDrvCtrl);
static STATUS dm9000Stop(END_DEVICE* pDrvCtrl);
static int dm9000Ioctl(END_DEVICE* pDrvCtrl, int cmd, caddr_t data);
static STATUS dm9000Unload(END_DEVICE* pDrvCtrl);
static STATUS dm9000Send(END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);
static STATUS dm9000MCastAdd(END_DEVICE* pDrvCtrl, char* pAddress);
static STATUS dm9000MCastDel(END_DEVICE* pDrvCtrl, char* pAddress);
static STATUS dm9000MCastGet(END_DEVICE* pDrvCtrl, MULTI_TABLE* pTable);
static STATUS dm9000PollStart(END_DEVICE* pDrvCtrl);
static STATUS dm9000PollStop(END_DEVICE* pDrvCtrl);
static STATUS dm9000PollSend(END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);
static STATUS dm9000PollRcv(END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);
static void dm9000AddrFilterSet(END_DEVICE *pDrvCtrl);
static STATUS dm9000Parse( END_DEVICE * pDrvCtrl, char * initString );
static STATUS dm9000MemInit( END_DEVICE * pDrvCtrl);
void dm9000Mode( END_DEVICE *pDrvCtrl, int mode, int reset );
/*
* Declare our function table. This is static across all driver
* instances.
*/
static NET_FUNCS dm9000FuncTable =
{
(FUNCPTR) dm9000Start, /* Function to start the device. */
(FUNCPTR) dm9000Stop, /* Function to stop the device. */
(FUNCPTR) dm9000Unload, /* Unloading function for the driver. */
(FUNCPTR) dm9000Ioctl, /* Ioctl function for the driver. */
(FUNCPTR) dm9000Send, /* Send function for the driver. */
(FUNCPTR) dm9000MCastAdd, /* Multicast add function for the */
/* driver. */
(FUNCPTR) dm9000MCastDel, /* Multicast delete function for */
/* the driver. */
(FUNCPTR) dm9000MCastGet, /* Multicast retrieve function for */
/* the driver. */
(FUNCPTR) dm9000PollSend, /* Polling send function */
(FUNCPTR) dm9000PollRcv, /* Polling receive function */
endEtherAddressForm, /* put address info into a NET_BUFFER */
endEtherPacketDataGet, /* get pointer to data in NET_BUFFER */
endEtherPacketAddrGet /* Get packet addresses. */
};
/*static isrLink_t sysEndIsrLink =
{
(void*)dm9000Int, /* rtn */
/*0, /* arg */
/* NULL /* next */
/*};*/
END_DEVICE *DrvCtrl;
/*****************************************
* Init DM9000 I/O pin
*****************************************/
void InitDM9000()
{
/*printf("Init DM9000...\n");*/
IODIR=IODIR|NET_RST0;
udelay(100);
IOCLR=NET_RST0;
udelay(100);
IOSET=NET_RST0;
udelay(100);
IOCLR=NET_RST0;
udelay(100);
PINSEL0|=0x03<<18; /* set P0.9 to EINT3 */
udelay(100);
/*printf("Init DM9000 Done...\n");*/
}
UCHAR sysInByte (ULONG port)
{
return (REG8(port));
}
void sysOutByte (ULONG port, UCHAR data)
{
(REG8(port))=data;
}
USHORT sysInWord (ULONG port)
{
return (REG16(port));
}
void sysOutWord (ULONG port, UINT16 data)
{
(REG16(port))=data;
}
void dm9000OutChar(UINT8 addr,UINT8 value)
{
sysOutByte(DM9000_IOADDR,addr);
/* udelay(BUS_DELAY); */
sysOutByte(DM9000_IODATA,value);
/* udelay(BUS_DELAY); */
}
UINT8 dm9000InChar(UINT8 addr)
{
/* udelay(BUS_DELAY); */
sysOutByte(DM9000_IOADDR,addr);
/* udelay(BUS_DELAY); */
return sysInByte(DM9000_IODATA);
}
/*******************************************************************************
*
* sysEtherEndLoad - initialize the driver and device
*
* This routine initializes the driver and the device to the operational state.
* All of the device specific parameters are passed in the initString.
*
* The string contains the target specific parameters like this:
*
* "register addr:int vector:int level:shmem addr:shmem size:shmem width"
*
* RETURNS: An END object pointer or NULL on error.
*/
END_OBJ* sysEtherEndLoad( char* initString, void *pBSP ) /* String to be parsed by the driver. */
{
END_DEVICE *pDrvCtrl;
char tmp;
DRV_LOG (DRV_DEBUG_LOAD, "Loading dm9000...", 1, 2, 3, 4, 5, 6);
/* printf("loading dm9000......\n");
DM9000_IN_CHAR(0x28,tmp);
printf("tmp = %x\n",tmp);*/
if (initString == NULL)
{
DRV_LOG (DRV_DEBUG_LOAD, "initString == NULL", 1, 2, 3, 4, 5, 6);
return (NULL);
}
if (initString[0] == '\0')
{
DRV_LOG (DRV_DEBUG_LOAD, "initString[0] == 0", 1, 2, 3, 4, 5, 6);
bcopy((char *)DM9000_DEV_NAME, initString, DM9000_DEV_NAME_LEN);
return (NULL);
}
/*if (sysMedusaPresent == FALSE)
{
DRV_LOG (DRV_DEBUG_LOAD, "sysMedusaPresent == FALSE", 1, 2, 3, 4, 5, 6);
return NULL;
}*/
/* allocate the device structure */
pDrvCtrl = (END_DEVICE *)calloc(sizeof (END_DEVICE), 1);
DrvCtrl = pDrvCtrl;
if (pDrvCtrl == NULL)
{
DRV_LOG (DRV_DEBUG_LOAD, "calloc() == NULL", 1, 2, 3, 4, 5, 6);
goto errorExit;
printf("error exit\n");
}
memset( (void*)pDrvCtrl, 0, sizeof( END_DEVICE ) );
(pDrvCtrl->flags) = 0;
(pDrvCtrl->op_mode) = DM9000_MEDIA_MODE;
/* parse the init string, filling in the device structure */
if (dm9000Parse(pDrvCtrl, initString) == ERROR)
{
DRV_LOG (DRV_DEBUG_LOAD, "Parse() == ERROR", 1, 2, 3, 4, 5, 6);
goto errorExit;
}
/* Ask the BSP to provide the ethernet address. */
dm9000Reset (pDrvCtrl);
/*printf("reset.....\n");*/
/* initialize the END and MIB2 parts of the structure */
/*
* The M2 element must come from m2Lib.h
* This dm9000 is set up for a DIX type ethernet device.
*/
if (END_OBJ_INIT (&pDrvCtrl->end, (DEV_OBJ *)pDrvCtrl, DM9000_DEV_NAME,
pDrvCtrl->unit, &dm9000FuncTable,
"END Template Driver.") == ERROR
|| END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd,
&pDrvCtrl->enetAddr[0], 6, END_BUFSIZ,
END_SPEED)
== ERROR)
{
DRV_LOG (DRV_DEBUG_LOAD, "END_OBJ_INIT() == END_MIB_INIT()==ERROR", 1, 2, 3, 4, 5, 6);
printf("obj init error\n");
goto errorExit;
}
/* Perform memory allocation/distribution */
if (dm9000MemInit (pDrvCtrl) == ERROR)
{
DRV_LOG (DRV_DEBUG_LOAD, "MemInit() == ERROR", 1, 2, 3, 4, 5, 6);
goto errorExit;
}
/* reset and reconfigure the device */
dm9000Reset (pDrvCtrl);
dm9000Config (pDrvCtrl);
/* set the flags to indicate readiness */
END_OBJ_READY (&pDrvCtrl->end,
IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX);
DRV_LOG (DRV_DEBUG_LOAD, "Done loading Template...", 1, 2, 3, 4, 5, 6);
/*printf("Done loading Template...\n");*/
return (&pDrvCtrl->end);
errorExit:
if (pDrvCtrl != NULL)
free ((char *)pDrvCtrl);
return NULL;
}
/*******************************************************************************
*
* dm9000Parse - parse the init string
*
* Parse the input string. Fill in values in the driver control structure.
*
* The muxLib.o module automatically prepends the unit number to the user's
* initialization string from the BSP (configNet.h).
*
* .IP <unit>
* Device unit number, a small integer.
* .IP <vecNum>
* Interrupt vector number (used with sysIntConnect)
* .IP <intLvl>
* Interrupt level
* .LP
*
* RETURNS: OK or ERROR for invalid arguments.
*/
static STATUS dm9000Parse( END_DEVICE * pDrvCtrl, /* device pointer */
char * initString ) /* information string */
{
int tmp1;
unsigned long int tmp2, tmp3, tmp4;
int tmp5;
/* Parse the initString */
DRV_LOG (DRV_DEBUG_LOAD, "dm9000Parse()", 1, 2, 3, 4, 5, 6);
DRV_LOG (DRV_DEBUG_LOAD, initString, 1, 2, 3, 4, 5, 6);
if (sscanf(initString, "%d:%d:%lx:%lx:%lx:%d",
&tmp1,
&(pDrvCtrl->unit),
&tmp2,
&tmp3,
&tmp4,
&tmp5 ) != 6 /* the number of parameters */ )
return ERROR;
pDrvCtrl->ivec = INT_VEC_EXTINT3;
pDrvCtrl->ilevel = INT_LVL_EXTINT3;
/*printf("parm ok\n");*/
return OK;
}
/*******************************************************************************
*
* dm9000MemInit - initialize memory for the chip
*
* This routine is highly specific to the device.
*
* RETURNS: OK or ERROR.
*/
static STATUS dm9000MemInit( END_DEVICE * pDrvCtrl ) /* device to be initialized */
{
/* This is how we would set up and END netPool using netBufLib(1).
* This code is pretty generic.
*/
if ((pDrvCtrl->end.pNetPool = malloc (sizeof(NET_POOL))) == NULL)
return (ERROR);
dm9000MclBlkConfig.mBlkNum = 128; /*16;*/
dm9000ClDescTbl[0].clNum = 128; /*16;*/
dm9000MclBlkConfig.clBlkNum = dm9000ClDescTbl[0].clNum;
/* Calculate the total memory for all the M-Blks and CL-Blks. */
dm9000MclBlkConfig.memSize = (dm9000MclBlkConfig.mBlkNum *
(MSIZE + sizeof (long))) +
(dm9000MclBlkConfig.clBlkNum *
(CL_BLK_SZ + sizeof(long)));
if ((dm9000MclBlkConfig.memArea = (char *) memalign (sizeof(long),
dm9000MclBlkConfig.memSize)) == NULL)
return (ERROR);
/* Calculate the memory size of all the clusters. */
dm9000ClDescTbl[0].memSize = (dm9000ClDescTbl[0].clNum *
(END_BUFSIZ + 8)) + sizeof(int);
/* Allocate the memory for the clusters from cache safe memory. */
if ((dm9000ClDescTbl[0].memArea = (char *) memalign ( sizeof(long),
dm9000ClDescTbl[0].memSize)) == NULL)
return (ERROR);
if ((int)dm9000ClDescTbl[0].memArea == NULL)
{
DRV_LOG (DRV_DEBUG_LOAD, "system memory unavailable",
1, 2, 3, 4, 5, 6);
return (ERROR);
}
/* Initialize the memory pool. */
if (netPoolInit(pDrvCtrl->end.pNetPool, &dm9000MclBlkConfig,
&dm9000ClDescTbl[0], dm9000ClDescTblNumEnt,
NULL) == ERROR)
{
DRV_LOG (DRV_DEBUG_LOAD, "Could not init buffering",
1, 2, 3, 4, 5, 6);
return (ERROR);
}
/*
* If you need clusters to store received packets into then get them
* here ahead of time.
*/
if ((pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->end.pNetPool,
(END_BUFSIZ), FALSE))
== NULL)
return (ERROR);
DRV_LOG (DRV_DEBUG_LOAD, "Memory setup complete", 1, 2, 3, 4, 5, 6);
return OK;
}
/*******************************************************************************
*
* dm9000Start - start the device
*
* This function calls BSP functions to connect interrupts and start the
* device running in interrupt mode.
*
* RETURNS: OK or ERROR
*
*/
static STATUS dm9000Start( END_DEVICE * pDrvCtrl ) /* device ID */
{
STATUS result;
DRV_LOG (DRV_DEBUG_LOAD, "dm9000Start.", 1, 2, 3, 4, 5, 6);
/*printf("dm9000 startd\n");*/
/* sysEndIsrLink.arg = (int)pDrvCtrl;*/
SYS_INT_CONNECT (pDrvCtrl, dm9000Int, (int)pDrvCtrl, &result);
VICIntEnable|=1<<17; /* enable eint3 */
/*result = intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivec), \
dm9000Int, 0);*/
if (result == ERROR)
{
printf("interrupt connect error\n");
return ERROR;
}
/*printf("Interrupt connected.\n");*/
DRV_LOG (DRV_DEBUG_LOAD, "Interrupt connected.", 1, 2, 3, 4, 5, 6);
SYS_INT_ENABLE (pDrvCtrl);
/* sysIntEnablePIC (pDrvCtrl->ilevel); */
DRV_LOG (DRV_DEBUG_LOAD, "interrupt enabled.", 1, 2, 3, 4, 5, 6);
/* TODO - start the device, enabling interrupts */
/* Activate DM9000 */
DM9000_OUT_CHAR( 0x05, DM9000_REG05 | 1 ); /* RX enable */
DM9000_OUT_CHAR( 0xff, DM9000_REGFF ); /* Enable TX/RX interrupt mask */
pDrvCtrl->tbusy=0;
/*printf("dm9000Start tbusy=0\n");*/
return (OK);
}
/*******************************************************************************
*
* dm9000Int - handle controller interrupt
*
* This routine is called at interrupt level in response to an interrupt from
* the controller.
*
* RETURNS: N/A.
*/
static void dm9000Int( END_DEVICE *pDrvCtrl ) /* interrupting device */
{
UCHAR stat, reg_save, isr_status, nsr_status; /* tx_status, */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -