📄 elt3c509end.c
字号:
if (initString [0] == NULL) { bcopy ((char *)ELT3C509_DEV_NAME, initString, ELT3C509_DEV_NAME_LEN); return (0); } /* allocate the device structure */ pDrvCtrl = (ELT3C509_DEVICE *)calloc (sizeof (ELT3C509_DEVICE), 1); if (pDrvCtrl == NULL) goto errorExit; /* parse the init string, filling in the device structure */ if (elt3c509Parse (pDrvCtrl, initString) == ERROR) goto errorExit; /* initialize the END and MIB2 parts of the structure */ /* * The M2 element must come from m2Lib.h * */ if (END_OBJ_INIT (&pDrvCtrl->endObj, (DEV_OBJ *)pDrvCtrl, ELT3C509_DEV_NAME, pDrvCtrl->unit, &elt3c509FuncTable, "3COM 3c509 EtherLink III Endhanced Network Driver.") == ERROR) goto errorExit; productID = elt3c509EepromRead (pDrvCtrl->port, EE_A_PRODUCT_ID); if (productID == ELT_PRODUCTID_3C589) { pAddr = (short *)pDrvCtrl->enetAddr; *pAddr++ = htons (elt3c509EepromRead (pDrvCtrl->port, EE_A_OEM_NODE_0)); *pAddr++ = htons (elt3c509EepromRead (pDrvCtrl->port, EE_A_OEM_NODE_1)); *pAddr++ = htons (elt3c509EepromRead (pDrvCtrl->port, EE_A_OEM_NODE_2)); SYS_OUT_WORD (pDrvCtrl, pDrvCtrl->port + ELT3C509_COMMAND, SELECT_WINDOW | WIN_CONFIG); SYS_OUT_WORD (pDrvCtrl, pDrvCtrl->port + ADDRESS_CONFIG, elt3c509EepromRead (pDrvCtrl->port, EE_A_ADDRESS)); SYS_OUT_WORD (pDrvCtrl, pDrvCtrl->port + RESOURCE_CONFIG, elt3c509EepromRead (pDrvCtrl->port,EE_A_RESOURCE)); } else { if (elt3c509Activate (pDrvCtrl) != OK) return (NULL); } if (END_MIB_INIT (&pDrvCtrl->endObj, M2_ifType_ethernet_csmacd, &pDrvCtrl->enetAddr[0], 6, ETHERMTU, ELT3C509_SPEED) == ERROR) goto errorExit; /* Initialize the Board here */ if (elt3c509BoardInit (pDrvCtrl) == ERROR) goto errorExit; /* Perform memory allocation/distribution */ if (elt3c509MemInit (pDrvCtrl) == ERROR) goto errorExit; /* set the flags to indicate readiness */ END_OBJ_READY (&pDrvCtrl->endObj, IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST | IFF_UP | IFF_RUNNING); pDrvCtrl->rxFilter = RX_F_NORMAL; /* configure the device */ elt3c509Config (pDrvCtrl); ENDLOGMSG (("Done loading end...", 1, 2, 3, 4, 5, 6)); return (&pDrvCtrl->endObj);errorExit: if (pDrvCtrl != NULL) free ((char *)pDrvCtrl); return NULL; }/********************************************************************************* elt3c509Parse - parse the init string** Parse the input string. Fill in values in the driver control structure.** The initialization string format is:* .CS* <unit>:<port>:<intVector>:<intLevel>:<attachementType>:<noRxFrames>* .CE* .IP <unit>* Device unit number, a small integer.* .IP <port>* base I/O address* .IP <intVector>* Interrupt vector number (used with sysIntConnect)* .IP <intLevel>* Interrupt level* .IP <attachmentType>* type of Ethernet connector* .IP <nRxFrames>* no. of Rx Frames in integer format* .LP** RETURNS: OK or ERROR for invalid arguments.*/STATUS elt3c509Parse ( ELT3C509_DEVICE * pDrvCtrl, /* device pointer */ char * initString /* initialization info string */ ) { char * tok; char * holder = NULL; /* unit number. */ tok = strtok_r (initString, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->unit = atoi (tok); /* port number */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->port = 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->intLevel = strtoul (tok, NULL, 16); /* attachment Type */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->attachment = atoi (tok); /* no. of Rx Frames */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->nRxFrames = atoi (tok); ENDLOGMSG (("Processed all arugments\n", 1, 2, 3, 4, 5, 6)); return OK; }/********************************************************************************* elt3c509BoardInit - Initialise the device** This function prepares the board for operation** RETURNS: OK or ERROR**/LOCAL STATUS elt3c509BoardInit ( ELT3C509_DEVICE * pDrvCtrl /* device to be initialized */ ) { int port; int index; UINT16 transceiver; UINT16 mediaStatus; port = pDrvCtrl->port; END_FLAGS_CLR (&pDrvCtrl->endObj, IFF_UP | IFF_RUNNING); elt3c509IntDisable (pDrvCtrl); /* make it OK to change register window */ SYS_OUT_WORD (pDrvCtrl, port + ELT3C509_COMMAND, (SELECT_WINDOW | WIN_ADDRESS)); for (index = 0; index < EA_SIZE; index++) SYS_OUT_BYTE (pDrvCtrl, port + index, pDrvCtrl->enetAddr [index]); /* Select the transceiver hardware (attachment) then do whatever is * necessary to activate the selected attachment. * A truly complete implementation would probably check to see * if the selected attachment were present. */ SYS_OUT_WORD (pDrvCtrl, port + ELT3C509_COMMAND, (SELECT_WINDOW | WIN_CONFIG)); SYS_IN_WORD (pDrvCtrl, port + ADDRESS_CONFIG, transceiver); if (pDrvCtrl->attachment == ATTACHMENT_DEFAULT) { switch (transceiver & AC_XCVR_MASK) { case AC_XCVR_TPE: pDrvCtrl->attachment = ATTACHMENT_RJ45; break; case AC_XCVR_BNC: pDrvCtrl->attachment = ATTACHMENT_BNC; break; case AC_XCVR_AUI: pDrvCtrl->attachment = ATTACHMENT_AUI; break; default: /* there's only one other value; it's "reserved" */ pDrvCtrl->attachment = ATTACHMENT_AUI; /* good enough */ break; } } /* Now set the selected attachment type, even if it was already selected */ transceiver &= ~AC_XCVR_MASK; switch (pDrvCtrl->attachment) { case ATTACHMENT_RJ45: SYS_OUT_WORD (pDrvCtrl, port + ADDRESS_CONFIG, (transceiver | AC_XCVR_TPE)); SYS_OUT_WORD (pDrvCtrl, port + ELT3C509_COMMAND, (SELECT_WINDOW | WIN_DIAGNOSTIC)); SYS_IN_BYTE (pDrvCtrl, port + MEDIA_STATUS, mediaStatus); SYS_OUT_BYTE (pDrvCtrl, port + MEDIA_STATUS, mediaStatus | MT_S_JABBER_ENABLE | MT_S_LINK_BEAT_ENABLE); break; case ATTACHMENT_BNC: SYS_OUT_WORD (pDrvCtrl, port + ADDRESS_CONFIG, transceiver | AC_XCVR_BNC); SYS_OUT_WORD (pDrvCtrl, port + ELT3C509_COMMAND, START_COAX); break; case ATTACHMENT_AUI: default: SYS_OUT_WORD (pDrvCtrl, port + ADDRESS_CONFIG, transceiver | AC_XCVR_AUI); break; } /* * Define the set of status bits that could cause interrupts. * There is no interrupt cause indicator separate from the board status. * To keep the ISR from seeing status conditions we didn't want to be * interrrupted for, we must mask the STATUS off, not the interrupt. * This prevents the condition from interrupting and also prevents * the ISR from seeing the condition even if it is true. * The interrupt mask is set only once to the set of all conditions * we might want to be interrupted by; the status mask is set and * cleared according to which conditions we want at any particular * time. The intMask field in the control structure * is named for its effect; it is really used in the status mask * command (3Com calls it the read zero mask). */ /* enable the status bits we currently want to cause interrupts */ elt3c509IntMaskSet (pDrvCtrl, ADAPTER_FAILURE | TX_COMPLETE | RX_COMPLETE | RX_EARLY | UPDATE_STATS); /* enable the collection of statistics */ SYS_OUT_WORD (pDrvCtrl, port + ELT3C509_COMMAND, STATS_ENABLE); /* enable the hardware to generate interrupt requests */ SYS_OUT_WORD (pDrvCtrl, port + ELT3C509_COMMAND, SELECT_WINDOW | WIN_CONFIG); SYS_OUT_WORD (pDrvCtrl, port + CONFIG_CONTROL, CC_ENABLE); SYS_OUT_WORD (pDrvCtrl, port + ELT3C509_COMMAND, SELECT_WINDOW | WIN_OPERATING); elt3c509IntEnable (pDrvCtrl); elt3c509RxStart (pDrvCtrl); elt3c509TxStart (pDrvCtrl); return (OK); }/********************************************************************************* elt3c509MemInit - initialize memory for the chip** This routine is highly specific to the device. ** RETURNS: OK or ERROR.*/LOCAL STATUS elt3c509MemInit ( ELT3C509_DEVICE * pDrvCtrl /* device to be initialized */ ) { if ((pDrvCtrl->endObj.pNetPool = malloc (sizeof(NET_POOL))) == NULL) return (ERROR);#ifdef DRV_DEBUG pEltPool = pDrvCtrl->endObj.pNetPool;#endif /* check if the value of nRxFrames is valid */ pDrvCtrl->nRxFrames = pDrvCtrl->nRxFrames ? pDrvCtrl->nRxFrames : DEF_NUM_RX_FRAMES; /* assign static cluster config/desc structures to unit specific structures * This is done to enable multiple units to operate. */ pDrvCtrl->endClDesc = elt3c509ClDescTbl [0]; pDrvCtrl->endClConfig = elt3c509MclConfig; pDrvCtrl->endClDesc.clNum = pDrvCtrl->nRxFrames + 1; pDrvCtrl->endClConfig.mBlkNum = (2 * pDrvCtrl->endClDesc.clNum); pDrvCtrl->endClConfig.clBlkNum = pDrvCtrl->endClDesc.clNum; /* Calculate the total memory for all the M-Blks and CL-Blks. */ pDrvCtrl->endClConfig.memSize = (pDrvCtrl->endClConfig.mBlkNum * (MSIZE + sizeof (long))) + (pDrvCtrl->endClConfig.clBlkNum * (CL_BLK_SZ + sizeof(long))); if ((pDrvCtrl->endClConfig.memArea = (char *) memalign (sizeof(long), pDrvCtrl->endClConfig.memSize)) == NULL) { return (ERROR); } /* Calculate the memory size of all the clusters. */ pDrvCtrl->endClDesc.memSize = ((pDrvCtrl->endClDesc.clNum * (ELT3C509_BUFSIZ + 8)) + sizeof(int)); /* Allocate the memory for the clusters from cache safe memory. */ pDrvCtrl->endClDesc.memArea = (char *) memalign (sizeof(long), pDrvCtrl->endClDesc.memSize); if ((int)pDrvCtrl->endClDesc.memArea == NULL) { ENDLOGMSG(("system memory unavailable\n", 1,2,3,4,5,6)); return (ERROR); } pDrvCtrl->cacheFuncs = cacheNullFuncs; /* Initialize the memory pool. */ if (netPoolInit (pDrvCtrl->endObj.pNetPool, &pDrvCtrl->endClConfig, &pDrvCtrl->endClDesc, elt3c509ClDescTblNumEnt, NULL) == ERROR) { ENDLOGMSG (("Could not init buffering\n",1,2,3,4,5,6)); return (ERROR); } /* Get Cluster POOL ID here */ pDrvCtrl->pClPoolId = clPoolIdGet (pDrvCtrl->endObj.pNetPool, ELT3C509_BUFSIZ, FALSE); /* allocate one cluster for the transmit frame */ pDrvCtrl->pTxCluster = (char *)netClusterGet (pDrvCtrl->endObj.pNetPool, pDrvCtrl->pClPoolId); ENDLOGMSG (("Memory setup complete\n",1,2,3,4,5,6)); return OK; }/********************************************************************************* elt3c509Start - 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 elt3c509Start ( void * pEnd /* device to be started */ ) { STATUS result; ELT3C509_DEVICE * pDrvCtrl; VOID_TO_DRVCTRL (pEnd, pDrvCtrl); SYS_INT_CONNECT (pDrvCtrl, elt3c509Int, (int)pDrvCtrl, &result); if (result == ERROR) return ERROR; ENDLOGMSG (("Interrupt connected.\n", 1, 2, 3, 4, 5, 6)); SYS_INT_ENABLE (pDrvCtrl); ENDLOGMSG (("interrupt enabled.\n", 1, 2, 3, 4, 5, 6)); return (OK); }/********************************************************************************* elt3c509Stop - stop the device** This function calls BSP functions to disconnect interrupts and stop
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -