📄 ultraend.c
字号:
if (pDrvCtrl != NULL) free ((char *)pDrvCtrl); return (NULL); } /********************************************************************************* ultraParse - parse the init string** Parse the input string. Fill in values in the driver control structure.* The initialization string format is:* <unit>:<ioAddr>:<memAddr>:<vecNum>:<intLvl>:<config>:<offset>"** .IP <unit>* Device unit number, a small integer.* .IP <ioAddr>* I/O address* .IP <memAddr>* Memory address, assumed to be 16k bytes in length.* .IP <vecNum>* Interrupt vector number (used with sysIntConnect()).* .IP <intLvl>* Interrupt level.* .IP <config>* Ultra config (0: RJ45 + AUI(Thick) 1: RJ45 + BNC(Thin)).* .IP <offset>* Memory offset for alignment.** RETURNS: OK, or ERROR if any arguments are invalid.*/STATUS ultraParse ( ULTRA_DEVICE * pDrvCtrl, /* device pointer */ char * initString /* information string */ ) { char * tok; char * pHolder = NULL; /* Parse the initString */ /* Unit number. */ tok = strtok_r (initString, ":", &pHolder); if (tok == NULL) return (ERROR); pDrvCtrl->unit = atoi (tok); /* I/O address. */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return (ERROR); pDrvCtrl->ioAddr = strtoul (tok, NULL, 16); /* Memory address. */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return (ERROR); pDrvCtrl->memAddr = strtoul (tok, NULL, 16); /* Interrupt vector. */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return (ERROR); pDrvCtrl->ivec = strtoul (tok, NULL, 16); /* Interrupt level. */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return (ERROR); pDrvCtrl->ilevel = strtoul (tok, NULL, 16); /* config */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return (ERROR); pDrvCtrl->config = strtoul (tok, NULL, 16); /* offset */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return (ERROR); pDrvCtrl->offset = strtoul (tok, NULL, 16); return (OK); }/********************************************************************************* ultraMemInit - initialize memory for the chip** Using data in the control structure, setup and initialize the memory* areas needed. If the memory address is not already specified, then allocate* cache safe memory.** RETURNS: OK or ERROR.*/STATUS ultraMemInit ( ULTRA_DEVICE * pDrvCtrl, /* device to be initialized */ int clNum /* number of clusters to allocate */ ) { CL_DESC clDesc; /* cluster description */ M_CL_CONFIG ultraMclBlkConfig; bzero ((char *)&ultraMclBlkConfig, sizeof(ultraMclBlkConfig)); bzero ((char *)&clDesc, sizeof(clDesc)); pDrvCtrl->endObj.pNetPool = (NET_POOL_ID) malloc (sizeof(NET_POOL)); if (pDrvCtrl->endObj.pNetPool == NULL) return (ERROR); clDesc.clNum = clNum; clDesc.clSize = MEM_ROUND_UP(ULTRA_BUFSIZ + pDrvCtrl->offset); clDesc.memSize = ((clDesc.clNum * (clDesc.clSize + 4)) + 4); ultraMclBlkConfig.mBlkNum = clDesc.clNum * 2; ultraMclBlkConfig.clBlkNum = clDesc.clNum; /* * mBlk and cluster configuration memory size initialization * memory size adjusted to hold the netPool pointer at the head. */ ultraMclBlkConfig.memSize = (ultraMclBlkConfig.mBlkNum * (M_BLK_SZ + sizeof (long))) + (ultraMclBlkConfig.clBlkNum * (CL_BLK_SZ + sizeof (long))); ultraMclBlkConfig.memArea = (char *) memalign(sizeof (long), ultraMclBlkConfig.memSize); if (ultraMclBlkConfig.memArea == NULL) { free (pDrvCtrl->endObj.pNetPool); pDrvCtrl->endObj.pNetPool = NULL; return (ERROR); } clDesc.memArea = (char *) malloc (clDesc.memSize); if (clDesc.memArea == NULL) { free (ultraMclBlkConfig.memArea); free (pDrvCtrl->endObj.pNetPool); pDrvCtrl->endObj.pNetPool = NULL; return (ERROR); } /* Initialize the net buffer pool with transmit buffers */ if (netPoolInit (pDrvCtrl->endObj.pNetPool, &ultraMclBlkConfig, &clDesc, 1, NULL) == ERROR) { free (clDesc.memArea); free (ultraMclBlkConfig.memArea); free (pDrvCtrl->endObj.pNetPool); pDrvCtrl->endObj.pNetPool = NULL; return (ERROR); } pDrvCtrl->clPoolId = clPoolIdGet (pDrvCtrl->endObj.pNetPool, ULTRA_BUFSIZ + pDrvCtrl->offset, FALSE); DRV_LOG (DRV_DEBUG_LOAD, "%s%d: ultraMemInit: %d clusters\n", (int) DEV_NAME, pDrvCtrl->unit, clNum, 4, 5, 6); return (OK); }/******************************************************************************** ultraReset - reset the ultra device** Stop and reset the Ultra chip.** RETURNS: N/A*/LOCAL void ultraReset ( ULTRA_DEVICE * pDrvCtrl ) { int tmp; DRV_LOG (DRV_DEBUG_LOAD, "%s%d: ultraReset\n", (int)DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6); SYS_OUT_BYTE (pDrvCtrl, LAN_INTMASK, 0x00); SYS_OUT_BYTE (pDrvCtrl, LAN_CMD, CMD_STP); do SYS_IN_BYTE (pDrvCtrl, LAN_INTSTAT, &tmp); while ((tmp & ISTAT_RST) != ISTAT_RST); SYS_OUT_BYTE (pDrvCtrl, CTRL_CON, CON_RESET); SYS_OUT_BYTE (pDrvCtrl, CTRL_CON, 0x00); SYS_OUT_BYTE (pDrvCtrl, CTRL_HARD, 0x08); taskDelay (sysClkRateGet () >> 2); SYS_OUT_BYTE (pDrvCtrl, CTRL_CON, CON_MENABLE); SYS_OUT_BYTE (pDrvCtrl, LAN_INTSTAT, 0xff); DRV_LOG (DRV_DEBUG_LOAD, "%s%d: ultraReset done\n", (int)DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6); }/******************************************************************************** ultraStart - start the device** This function calls BSP functions to connect interrupts and start the* device running in interrupt mode.** RETURNS: OK or ERROR**/LOCAL STATUS ultraStart ( void * pObj /* device ID */ ) { STATUS result; ULTRA_DEVICE * pDrvCtrl = pObj; DRV_LOG (DRV_DEBUG_LOAD, "%s%d: ultraStart\n", (int) DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6); SYS_INT_CONNECT (pDrvCtrl, ultraInt, (int)pDrvCtrl, &result); if (result == ERROR) { DRV_LOG (DRV_DEBUG_LOAD, "%s%d: ultraStart: could not attach interrupt\n", (int) DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6); return (ERROR); } SYS_INT_ENABLE (pDrvCtrl); /* start the device */ SYS_OUT_BYTE (pDrvCtrl, LAN_CMD, CMD_STA); /* initialize Transmit Configuration Register */ SYS_OUT_BYTE (pDrvCtrl, LAN_TCON, 0x00); /* enable interrupts */ SYS_OUT_BYTE (pDrvCtrl, LAN_INTMASK, 0x00); SYS_OUT_BYTE (pDrvCtrl, CTRL_INT, INT_ENABLE); SYS_OUT_BYTE (pDrvCtrl, LAN_INTMASK, IM_OVWE | IM_TXEE | IM_PTXE | IM_PRXE); return (OK); }/******************************************************************************** ultraStop - stop the device** This function calls BSP functions to disconnect interrupts and stop* the device from operating in interrupt mode.** RETURNS: OK or ERROR.*/LOCAL STATUS ultraStop ( void * pObj /* device to be stopped */ ) { int tmp; int oldLevel; STATUS result = OK; ULTRA_DEVICE * pDrvCtrl = pObj; DRV_LOG (DRV_DEBUG_LOAD, "%s%d: ultraStop\n", (int)DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6); /* Stop/disable the device. */ oldLevel = intLock (); SYS_OUT_BYTE (pDrvCtrl, LAN_INTMASK, 0x00); SYS_OUT_BYTE (pDrvCtrl, LAN_CMD, CMD_STP); do SYS_IN_BYTE (pDrvCtrl, LAN_INTSTAT, &tmp); while ((tmp & ISTAT_RST) != ISTAT_RST); SYS_OUT_BYTE (pDrvCtrl, LAN_RCON, 0x00); SYS_OUT_BYTE (pDrvCtrl, LAN_TCON, TCON_LB1); SYS_OUT_BYTE (pDrvCtrl, LAN_INTSTAT, 0xff); SYS_INT_DISABLE (pDrvCtrl); intUnlock (oldLevel); /* Remove the ISR */ SYS_INT_DISCONNECT (pDrvCtrl, ultraInt, (int)pDrvCtrl, &result); if (result == ERROR) { DRV_LOG (DRV_DEBUG_LOAD, "Could not disconnect interrupt!\n", 1, 2, 3, 4, 5, 6); } return (result); }/******************************************************************************** ultraConfig - reconfigure the interface under us.** Reconfigure the interface setting promiscuous mode, and changing the* multicast interface list.** RETURNS: N/A.*/LOCAL void ultraConfig ( ULTRA_DEVICE * pDrvCtrl /* device to be re-configured */ ) { int i; int tmp; UCHAR rcon; UCHAR memAddr; UCHAR intLevel; UCHAR ioAddr; UCHAR eeromGcon; DRV_LOG (DRV_DEBUG_LOAD, "%s%d: ultraConfig: flags=%x\n", (int) DEV_NAME, pDrvCtrl->unit, pDrvCtrl->flags, 4, 5, 6); /* Mask interrupts */ SYS_OUT_BYTE (pDrvCtrl, LAN_INTMASK, 0x00); /* program Command Register for page 0, stop device */ SYS_OUT_BYTE (pDrvCtrl, LAN_CMD, CMD_STP); do SYS_IN_BYTE (pDrvCtrl, LAN_INTSTAT, &tmp); while ((tmp & ISTAT_RST) != ISTAT_RST); /* get values set by EEROM */ SYS_OUT_BYTE (pDrvCtrl, CTRL_HARD, 0x80); SYS_IN_BYTE (pDrvCtrl, CTRL_GCON, &eeromGcon); /* IO address, Memory address, Interrupt request */ memAddr = (((pDrvCtrl->memAddr & 0x1e000) >> 13) | ((pDrvCtrl->memAddr & 0x20000) >> 10)); intLevel = (((pDrvCtrl->intLevel & 0x03) << 2) | ((pDrvCtrl->intLevel & 0x04) << 6)); ioAddr = (((pDrvCtrl->ioAddr & 0xe000) >> 8) | ((pDrvCtrl->ioAddr & 0x01e0) >> 4)); SYS_OUT_BYTE (pDrvCtrl, CTRL_HARD, 0x80); SYS_OUT_BYTE (pDrvCtrl, CTRL_IOADDR, ioAddr); SYS_OUT_BYTE (pDrvCtrl, CTRL_MEMADDR, memAddr | 0x10); if (pDrvCtrl->config == 1) SYS_OUT_BYTE (pDrvCtrl, CTRL_GCON, irqTable [pDrvCtrl->intLevel].reg | (eeromGcon & 0x20)); else if (pDrvCtrl->config == 2) SYS_OUT_BYTE (pDrvCtrl, CTRL_GCON, (irqTable [pDrvCtrl->intLevel].reg | 0x02 | (eeromGcon & 0x20))); else SYS_OUT_BYTE (pDrvCtrl, CTRL_GCON, irqTable [pDrvCtrl->intLevel].reg | (eeromGcon & 0x22)); /* set FINE16 bit in BIO register to get finer res for M16CS decode */ SYS_IN_BYTE (pDrvCtrl, CTRL_BIO, &tmp); SYS_OUT_BYTE (pDrvCtrl, CTRL_BIO, tmp | BIO_FINE16); SYS_OUT_BYTE (pDrvCtrl, CTRL_HARD, 0x00); /* 16 bit enable */ SYS_OUT_BYTE (pDrvCtrl, CTRL_BIOS, BIOS_M16EN); /* initialize Data Configuration Register */ SYS_OUT_BYTE (pDrvCtrl, LAN_DCON, DCON_BSIZE1 | DCON_BUS16); /* initialize Receive Configuration Register */ ultraAddrFilterSet (pDrvCtrl); /* always accept broadcast packets */ rcon = RCON_BROAD; if (END_MULTI_LST_CNT(&pDrvCtrl->endObj) > 0) rcon |= RCON_GROUP; if (END_FLAGS_GET(&pDrvCtrl->endObj) & IFF_PROMISC) rcon |= (RCON_PROM | RCON_GROUP); if (END_FLAGS_GET(&pDrvCtrl->endObj) & (IFF_PROMISC|IFF_ALLMULTI)) { /* receive all multicast packets */ rcon |= RCON_GROUP; /* Set multicast hashing array to all 1's */ for (i = 0; i < 8; ++i) pDrvCtrl->mcastFilter[i] = 0xff; } SYS_OUT_BYTE (pDrvCtrl, LAN_RCON, rcon); if (rcon & RCON_GROUP) DRV_LOG (DRV_DEBUG_IOCTL, "%s%d: Setting multicast mode on!\n", (int) DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6); if (rcon & RCON_PROM) DRV_LOG (DRV_DEBUG_IOCTL, "%s%d: Setting promiscuous mode on!\n", (int) DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6); /* place the Ultra in external LOOPBACK mode */ SYS_OUT_BYTE (pDrvCtrl, LAN_TCON, TCON_LB1); /* initialize Receive Buffer Ring */ SYS_OUT_BYTE (pDrvCtrl, LAN_RSTART, ULTRA_PSTART); SYS_OUT_BYTE (pDrvCtrl, LAN_RSTOP, ULTRA_PSTOP); SYS_OUT_BYTE (pDrvCtrl, LAN_BOUND, ULTRA_PSTART); /* clear Interrupt Status Register */ SYS_OUT_BYTE (pDrvCtrl, LAN_INTSTAT, 0xff); /* initialize Interrupt Mask Register */ SYS_OUT_BYTE (pDrvCtrl, LAN_INTMASK, 0x00); /* Set command register for page 1 */ SYS_OUT_BYTE (pDrvCtrl, LAN_CMD, CMD_PS0 | CMD_STP); /* Program ethernet address (page 1) */ SYS_OUT_BYTE (pDrvCtrl, LAN_STA0, pDrvCtrl->enetAddr[0]); SYS_OUT_BYTE (pDrvCtrl, LAN_STA1, pDrvCtrl->enetAddr[1]); SYS_OUT_BYTE (pDrvCtrl, LAN_STA2, pDrvCtrl->enetAddr[2]); SYS_OUT_BYTE (pDrvCtrl, LAN_STA3, pDrvCtrl->enetAddr[3]); SYS_OUT_BYTE (pDrvCtrl, LAN_STA4, pDrvCtrl->enetAddr[4]); SYS_OUT_BYTE (pDrvCtrl, LAN_STA5, pDrvCtrl->enetAddr[5]); /* Program multicast mask (page 1) */ SYS_OUT_BYTE (pDrvCtrl, LAN_MAR0, pDrvCtrl->mcastFilter[0]); SYS_OUT_BYTE (pDrvCtrl, LAN_MAR1, pDrvCtrl->mcastFilter[1]); SYS_OUT_BYTE (pDrvCtrl, LAN_MAR2, pDrvCtrl->mcastFilter[2]); SYS_OUT_BYTE (pDrvCtrl, LAN_MAR3, pDrvCtrl->mcastFilter[3]); SYS_OUT_BYTE (pDrvCtrl, LAN_MAR4, pDrvCtrl->mcastFilter[4]); SYS_OUT_BYTE (pDrvCtrl, LAN_MAR5, pDrvCtrl->mcastFilter[5]); SYS_OUT_BYTE (pDrvCtrl, LAN_MAR6, pDrvCtrl->mcastFilter[6]); SYS_OUT_BYTE (pDrvCtrl, LAN_MAR7, pDrvCtrl->mcastFilter[7]); /* Initialize current page pointer (page 1) */ SYS_OUT_BYTE (pDrvCtrl, LAN_CURR, ULTRA_PSTART + 1); pDrvCtrl->nextPacket = ULTRA_PSTART + 1; /* Switch to page 2 registers */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -