📄 rtl8019end.c
字号:
};#ifdef DEBUGvoid hex_dump( unsigned char* data, int size){ int index; for( index = 0; index < size; index++) { if( (index & 0x0f) == 0 ) DBG_PRINTF(("\n0x%02x ", (unsigned char)index)); DBG_PRINTF(("%02x ", *(data+index))); } DBG_PRINTF(("\n"));}#endifvoid sysOutByte (ULONG port, UCHAR data){ *(UCHAR*)port = data;}UCHAR sysInByte(ULONG port){ return *(UCHAR*)port;}void sysInWordString(ULONG port, UINT16 *pData, int count){ int index; for( index = 0; index < count; index++) { *pData = *(UINT16*)(port); pData++; }}void sysInByteString(ULONG port, UCHAR *pData, int count){ int index; for( index = 0; index < count; index++) { *pData = *(UCHAR*)(port); pData++; }}void sysOutWordString(ULONG port, UINT16 *pData, int count){ int index; for( index = 0; index < count; index++) { *(UINT16*)(port) = *pData; pData++; }}void sysOutByteString(ULONG port, UCHAR *pData, int count){ int index; for( index = 0; index < count; index++) { *(UCHAR*)(port) = *pData; pData++; }}/******************************************************************************** rtl8019EndLoad - 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:** "unit:register addr:int vector:int level:shmem addr:shmem size:shmem width"** RETURNS: An END object pointer or NULL on error.*/END_OBJ* rtl8019EndLoad ( char* initString, /* String to be parsed by the driver. */ void* pBSP /* for BSP group */ ) { RTL8019END_DEVICE *pDrvCtrl; int level; UCHAR regVal; if (initString == NULL){ DBG_PRINTF(("EndLoad:initString is zero.\n")); } else { DBG_PRINTF(("EndLoad:initString is %s.\n", initString)); } if (initString == NULL) { DBG_PRINTF(("EndLoad:initString is zero.\n")); return (NULL); } else { DBG_PRINTF(("EndLoad:initString is %s\n", initString)); } if (initString[0] == '\0') { bcopy((char *)RTL8019_DEV_NAME, initString, RTL8019_DEV_NAME_LEN); return (NULL); } /* allocate the device structure */ pDrvCtrl = (RTL8019END_DEVICE *) calloc (sizeof(RTL8019END_DEVICE), 1); if (pDrvCtrl == NULL) { DBG_PRINTF(("allocate the device structure fail!\n")); goto errorExit; } /* parse the init string, filling in the device structure */ if (rtl8019Parse (pDrvCtrl, initString) == ERROR) { DBG_PRINTF(("parse the init string fail!\n")); goto errorExit; } if(rtl8019Verify(pDrvCtrl)!=OK) { ERR_PRINTF(("RTL8019 not found at 0x%x!\n", pDrvCtrl->base)); goto errorExit; } /* * If the optional load string parameters configRegA or configRegB * are passed in with the load string then load the passed in value * into the appropriate register. */ if (pDrvCtrl->configRegA != 0) { /* This must be an atomic transaction, so it must be intLocked */ level = intLock (); SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_PAGE0); SYS_IN_CHAR (pDrvCtrl, ENE_RBCR0, ®Val); SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR0, pDrvCtrl->configRegA); intUnlock (level); } if (pDrvCtrl->configRegB != 0) { /* This must be an atomic transaction, so it must be intLocked */ level = intLock (); SYS_IN_CHAR (pDrvCtrl, ENE_RBCR1, ®Val); SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR1, pDrvCtrl->configRegB); intUnlock (level); } /* stop device */ SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_NODMA | CMD_PAGE0 | CMD_STOP); /* * HELP: * In the generic driver it always uses BUS16 here. I agree that this * code looks better, but if the device is inactive why are we doing this * here at all. Why not call rtl8019Config from rtl8019Start and let it set * up the chip when we actually start it ??? */ if (pDrvCtrl->byteAccess) SYS_OUT_CHAR (pDrvCtrl, ENE_DCON, DCON_BSIZE1 | DCON_BUS_8 | DCON_LOOPBK_OFF); else SYS_OUT_CHAR (pDrvCtrl, ENE_DCON, DCON_BSIZE1 | DCON_BUS16 | DCON_LOOPBK_OFF); /* Ask the BSP to provide the ethernet address. */ SYS_ENET_ADDR_GET (pDrvCtrl); /* initialize the END parts of the structure */ if (END_OBJ_INIT (&pDrvCtrl->endObj, (DEV_OBJ *)pDrvCtrl, (char*)RTL8019_DEV_NAME, pDrvCtrl->unit, &rtl8019FuncTable, "rtl8019 Enhanced Network Driver") == ERROR) { DBG_PRINTF(("initialize the END parts of the structure fail!\n")); goto errorExit; } /* Perform memory allocation/distribution */ if (rtl8019MemInit (pDrvCtrl) == ERROR) { DBG_PRINTF(("Perform memory allocation/distribution fail!\n")); goto errorExit; } /* initialize the MIB2 parts of the structure */ if (END_MIB_INIT (&pDrvCtrl->endObj, M2_ifType_ethernet_csmacd, &pDrvCtrl->enetAddr[0], 6, SIZEOF_ETHERHEADER+ETHERMTU, /*ETHERMTU,*/ END_SPEED) == ERROR) { DBG_PRINTF(("initialize the MIB2 parts of the structure fail!\n")); goto errorExit; } /* set the flags to indicate readiness */ END_OBJ_READY (&pDrvCtrl->endObj, IFF_NOTRAILERS | IFF_MULTICAST | IFF_BROADCAST); DBG_PRINTF(("rtl8019EndLoad OK!\n")); /*rtl8019Init(pDrvCtrl);*/ return (&pDrvCtrl->endObj);errorExit: if (pDrvCtrl != NULL) free ((char *)pDrvCtrl); return (NULL); }LOCAL STATUS rtl8019Verify ( RTL8019END_DEVICE * pDrvCtrl ){ unsigned char id0, id1, regVal; SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_STOP); /* halt nic */ UDELAY(2); /* wait 2 ms */ SYS_IN_CHAR (pDrvCtrl, ENE_RESET, ®Val); /* reset nic */ SYS_OUT_CHAR (pDrvCtrl, ENE_RESET, regVal); SYS_OUT_CHAR (pDrvCtrl, ENE_INTSTAT, 0xff); UDELAY(2); /* wait 2 ms */ SYS_IN_CHAR (pDrvCtrl, ENE_RBCR0, &id0); /* read id */ SYS_IN_CHAR (pDrvCtrl, ENE_RBCR1, &id1); if(id0 != 0x50 || id1 != 0x70) { DBG_PRINTF(("error: RTL8019AS chip not found { 0x%x(0x50), 0x%x(0x70)}!\n", id0, id1)); return (ERROR); } return (OK);}/******************************************************************************** rtl8019Parse - parse the init string** Parse the input string. Fill in values in the driver control structure.** The initialization string format is:* .CS* "unit:adrs:vecnum:intLvl:byteAccess:usePromEnetAddr:offset"* .CE** .IP <unit>* Device unit number, a small integer.* .IP <adrs>* Base address* .IP <vecNum>* Interrupt vector number (used with sysIntConnect)* .IP <intLvl>* Interrupt level (used with sysLanIntEnable)* .IP <byteAccess>* Use 8-bit access mode.* .IP <usePromEnetAddr>* get ethernet address from PROM.* .IP <offset>* offset for memory alignment* Set Configuration Register A. Defaults to reset value. * .IP <configRegA>* Set Configuration Register B. Defaults to reset value. * .IP <configRegB>* .LP** RETURNS: OK or ERROR for invalid arguments.*/LOCAL STATUS rtl8019Parse ( RTL8019END_DEVICE * pDrvCtrl, char * initString ) { char* tok; char* holder = NULL; /* Parse the initString */ DBG_PRINTF (("rtl8019Parse: (initString=%s)\n",initString)); /* Unit number. */ tok = strtok_r (initString, ":", &holder); if (tok == NULL) return (ERROR); pDrvCtrl->unit = atoi (tok); /* Base address. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return (ERROR); pDrvCtrl->base = strtoul (tok, NULL, 16); /* Interrupt vector. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return (ERROR); pDrvCtrl->ivec = strtoul (tok, NULL, 16); /* Interrupt level. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return (ERROR); pDrvCtrl->ilevel = strtoul (tok, NULL, 16); /* 8-bit access. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return (ERROR); pDrvCtrl->byteAccess = atoi (tok); /* ethernet address from PROM. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return (ERROR); pDrvCtrl->usePromEnetAddr = atoi (tok); /* memory alignment offset */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return (ERROR); pDrvCtrl->offset = strtoul (tok, NULL, 16); /* Set configuration register A - optional parameter */ pDrvCtrl->configRegA = 0; tok = strtok_r (NULL, ":", &holder); if (tok != NULL) pDrvCtrl->configRegA = strtoul (tok, NULL, 16); /* Set configuration register B - optional parameter */ pDrvCtrl->configRegB = 0; tok = strtok_r (NULL, ":", &holder); if (tok != NULL) pDrvCtrl->configRegB = strtoul (tok, NULL, 16);#ifdef LIST_INIT_PARAMS DBG_PRINTF(("configRegA = 0x%x\n", pDrvCtrl->configRegA)); DBG_PRINTF(("configRegB = 0x%x\n", pDrvCtrl->configRegB)); DBG_PRINTF(("offset = 0x%x\n", pDrvCtrl->offset)); DBG_PRINTF(("usePromEnetAddr = 0x%x\n", pDrvCtrl->usePromEnetAddr)); DBG_PRINTF(("byteAccess = 0x%x\n", pDrvCtrl->byteAccess)); DBG_PRINTF(("Interrupt level = 0x%x\n", pDrvCtrl->ilevel)); DBG_PRINTF(("Interrupt vector = 0x%x\n", pDrvCtrl->ivec)); DBG_PRINTF(("Base = 0x%x\n", pDrvCtrl->base)); DBG_PRINTF(("Unit = 0x%x\n", pDrvCtrl->unit)); DBG_PRINTF (("rtl8019Parse: (OK!%s)\n"));#endif return (OK); }/********************************************************************************* rtl8019MemInit - initialize memory for the chip** This routine is highly specific to the device.** RETURNS: OK or ERROR.*/LOCAL STATUS rtl8019MemInit ( RTL8019END_DEVICE * pDrvCtrl /* device to be initialized */ ) { M_CL_CONFIG eneMclBlkConfig; CL_DESC clDesc; /* cluster description */ bzero ((char *)&eneMclBlkConfig, sizeof(eneMclBlkConfig)); bzero ((char *)&clDesc, sizeof(clDesc)); clDesc.clNum = RTL8019_RX_BUFS; clDesc.clSize = RTL8019_BUFSIZ; /* allow for alignment */ clDesc.memSize = ((clDesc.clNum * (clDesc.clSize + 8)) + 4); eneMclBlkConfig.mBlkNum = RTL8019_RX_BUFS*2; eneMclBlkConfig.clBlkNum = clDesc.clNum; /* * mBlk and cluster configuration memory size initialization * memory size adjusted to hold the netPool pointer at the head. */ eneMclBlkConfig.memSize = (eneMclBlkConfig.mBlkNum * (MSIZE + sizeof (long))) + (eneMclBlkConfig.clBlkNum * (CL_BLK_SZ + sizeof (long))); eneMclBlkConfig.memArea = (char *) memalign(sizeof (long), eneMclBlkConfig.memSize); if (eneMclBlkConfig.memArea == NULL) return (ERROR); /*clDesc.memArea = (char *) malloc (clDesc.memSize);*/ clDesc.memArea = (char *) cacheDmaMalloc (clDesc.memSize); if (clDesc.memArea == NULL) return (ERROR); pDrvCtrl->endObj.pNetPool = (NET_POOL_ID) malloc (sizeof(NET_POOL)); if (pDrvCtrl->endObj.pNetPool == NULL) return (ERROR); /* Initialize the net buffer pool with transmit buffers */ if (netPoolInit (pDrvCtrl->endObj.pNetPool, &eneMclBlkConfig, &clDesc, 1, NULL) == ERROR) return (ERROR); /* Save the cluster pool id */ pDrvCtrl->clPoolId = clPoolIdGet (pDrvCtrl->endObj.pNetPool, RTL8019_BUFSIZ, FALSE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -