📄 sn83932end.c
字号:
if (initString[0] == 0) { bcopy ((char *)SN_DEV_NAME, initString, SN_DEV_NAME_LEN); return (0); } if (snInitParse (&initParm, initString) == ERROR) return NULL; /* Sanity check the unit number */ if (initParm.unit < 0 || initParm.unit >= MAX_UNITS) return NULL; /* allocate the device structure */ pDrvCtrl = (DRV_CTRL *)calloc (sizeof(DRV_CTRL), 1); if (pDrvCtrl == NULL) return (NULL); if (pDrvCtrl->endData.attached == TRUE) return (&pDrvCtrl->endData); /* save the inputted parameters */ pDrvCtrl->unit = initParm.unit; pDrvCtrl->ivec = initParm.ivec; pDrvCtrl->pDev = (SONIC *) initParm.devaddr; /* Initialize the default interrupt mask configuration in control block */ pDrvCtrl->imr = SN_IMR_INIT; /* EndData Initialization */ if (END_OBJ_INIT (&pDrvCtrl->endData, (DEV_OBJ *)pDrvCtrl, "sn", pDrvCtrl->unit, &snFuncTable, "Sonic 83932 Enhanced Network Driver") == ERROR) return (NULL); /* get an Ethernet addr from BSP and intialize the MIB2 */ if (sysEnetAddrGet (initParm.unit, pDrvCtrl->enetAddr) == ERROR) return (NULL); if (END_MIB_INIT (&pDrvCtrl->endData, M2_ifType_ethernet_csmacd, (UCHAR *)pDrvCtrl->enetAddr,6,ETHERMTU, SN_SPEED) == ERROR) return (NULL); /* Allocate, initialize and set up shared memory region */ if (snInitMem (pDrvCtrl) == ERROR) return (NULL); /***** Perform device initialization *****/ snChipReset (pDrvCtrl); /* reset device */ sysEnetInit (pDrvCtrl->unit); /* do any board specific set up */ sysEnetIntDisable (pDrvCtrl->unit); /* board specific int disable */ snChipInit (pDrvCtrl); /* init the device */ /* Set flags */ END_OBJ_READY (&pDrvCtrl->endData, (IFF_NOTRAILERS | IFF_MULTICAST | IFF_BROADCAST)); return (&pDrvCtrl->endData); }/********************************************************************************* snInitParse - parse parameter values from initString according to the* following format:** int unit, * unit number ** char * pDevRegs, * addr of device's regs ** int ivec * vector number **** RETURNS: OK or ERROR*/LOCAL STATUS snInitParse ( INIT_PARM * pParms, /* pointer contains the data in the initstring */ char * pinitString ) { char * ptok; /* token for the initString */ char * pHolder=NULL; /* temp string holder */ ptok = strtok_r(pinitString, ":", &pHolder); if (ptok == NULL) return ERROR; pParms->unit = atoi(ptok); ptok=strtok_r(NULL, ":", &pHolder); if (ptok == NULL) return ERROR; pParms->devaddr = strtoul (ptok, NULL, 16); ptok=strtok_r(NULL, ":", &pHolder); if (ptok == NULL) return ERROR; pParms->ivec = atoi (ptok); return OK; }/********************************************************************************* sn83932Start - start the device** This function connects interrupt, calls BSP to enable them, and starts the* device running in interrupt mode.** RETURNS: OK or ERROR* NOMANUAL*/LOCAL STATUS sn83932Start ( DRV_CTRL * pDrvCtrl ) {#ifdef DEBUG SN_LOGMSG ("sn83932Start...\n",0,0,0,0,0,0);#endif /* Sanity Check */ if (pDrvCtrl == NULL) return EINVAL; if (pDrvCtrl->online) return OK; /* Connect the interrupt vector */ if (intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC(pDrvCtrl->ivec), sn83932Int, (int)pDrvCtrl) != OK) return ERROR; /* Enable device interrupts at system level */ sysEnetIntEnable (pDrvCtrl->unit); /* Initialize the physical address in the CAM */ snCamMacLoad (pDrvCtrl); /* Bring up the device */ snChipStart (pDrvCtrl); /* Denote it as online */ pDrvCtrl->online = TRUE; /* mark the interface as up */ END_FLAGS_SET (&pDrvCtrl->endData, (IFF_UP | IFF_RUNNING));#ifdef DEBUG SN_LOGMSG ("end of sn83932Start...\n",0,0,0,0,0,0);#endif return (OK); } /* End of sn83932Start() *//********************************************************************************* sn83932Stop - Stop the device** This routine disables interrupts and resets the device.** RETURNS: OK or ERROR* NOMANUAL*/LOCAL STATUS sn83932Stop ( DRV_CTRL * pDrvCtrl ) { /* Sanity Check */ if (pDrvCtrl == NULL) return EINVAL; sysEnetIntDisable (pDrvCtrl->unit); /* board specific int */ /* disable */ pDrvCtrl->pDev->imr = 0; /* Turn off interrupts */ pDrvCtrl->online = FALSE; /* denote unit as offline */ /* mark the interface as down */ END_FLAGS_CLR (&pDrvCtrl->endData, (IFF_UP | IFF_RUNNING)); return OK; }/********************************************************************************* sn83932Unload - unload the device by freeing any allocated memory and* releasing the EndData objects from the MUX.*** RETURNS: OK or ERROR* NOMANUAL**/LOCAL STATUS sn83932Unload ( DRV_CTRL *pDrvCtrl ) { /* Sanity Check */ if (pDrvCtrl == NULL) return EINVAL; if (pDrvCtrl->endData.attached == TRUE) { /* Stop the device if still on line */ if (pDrvCtrl->online) sn83932Stop (pDrvCtrl); /* Reset the Chip to pre-empt any further action */ snChipReset (pDrvCtrl); /* release EndData objects */ END_OBJECT_UNLOAD (&pDrvCtrl->endData); /* Free up malloc'd memory */ cacheDmaFree (pDrvCtrl->pMem); /* Denote device as detached */ pDrvCtrl->endData.attached = FALSE; } return OK; }/******************************************************************************** snInitMem - establish shared memory region for sonic chip** The driver and the device share areas of memory. Each area has a* specific use. The device imposes a nasty restriction, in that* an area's bounds must lie in the same 64k page. The entire amount of* shared memory that is needed is much less than 64k. Therefore, we* will group all the individual areas into one area, and attempt to* ensure that this total area lies in a single 64k page.** We must also consider data cache coherency of this shared memory.* We therefore use the special system functions that allow us to* obtain cache-safe memory, or at least allow us to maintain the* coherency of this memory ourselves.** RETURNS: OK or ERROR.*/LOCAL STATUS snInitMem ( DRV_CTRL * pDrvCtrl ) { int cnt; u_long temp; /* Temporary address holder */ char *pCur; /* Block local variable */ CAM_DESC * pCam; /* CAM working descriptor */ TX_DESC * pTXD; RX_DESC * pRXD; /* Rx working descriptor */ RRA_DESC * pRRAD; /* RRA working descriptor */ /* The first step is to calculate the size of this shared region. */ pDrvCtrl->shMemSize = CAM_SIZE + /* the area used for Ethernet addrs */ RRA_SIZE + /* the area that describes Rx buffers */ RDA_SIZE + /* the area that holds Rx descriptors */ TDA_SIZE + /* the area that holds Tx descriptors */ RBA_SIZE; /* the area that holds all Rx buffers */ /* * That was easy. Now we request some memory from the system. * For now, we are taking a simple approach. We simply request one * big region, large enough to ensure that we can position our shared * area in a single 64k page. This approach will waste memory, but * blame the board designers who picked the SONIC without realizing * that the device has this weird restriction. */ if (!CACHE_DMA_IS_WRITE_COHERENT ()) return (ERROR); pDrvCtrl->pMem = cacheDmaMalloc (pDrvCtrl->shMemSize + 0x00010000); if (pDrvCtrl->pMem == NULL) /* no memory, so abort */ return (ERROR); /* * Find start of 64k page in the region. This becomes start of our * region. */ pDrvCtrl->pShMem = (char *) (((u_long)pDrvCtrl->pMem & 0xffff0000) + 0x00010000); /***** Carve up the shared area into specific areas *****/ pCur = pDrvCtrl->pShMem; /* start of shared area */ pDrvCtrl->CDA = (u_long) pCur; /* CAM area */ pCur += CAM_SIZE; /* advance the pointer */ pDrvCtrl->RSA = (u_long) pCur; /* receive resource table */ pCur += RRA_SIZE; /* advance the pointer */ pDrvCtrl->REA = (u_long) pCur; /* save end pointer */ pDrvCtrl->RDA = (u_long) pCur; /* receive descriptor area */ pCur += RDA_SIZE; /* advance the pointer */ pDrvCtrl->pTDA = (TX_DESC *)pCur; /* transmit descriptor area */ pCur += TDA_SIZE; /* advance the pointer */ pDrvCtrl->RBA1 = (u_long) pCur; /* Receive Buffer 1 */ pCur += RX_BUF_SIZE + RX_BUF_EXTRA; /* advance the pointer */ pDrvCtrl->RBA2 = (u_long) pCur; /* Receive Buffer 2 */ pCur += RX_BUF_SIZE + RX_BUF_EXTRA; /* advance the pointer */ pDrvCtrl->RBA3 = (u_long) pCur; /* Receive Buffer 3 */ pCur += RX_BUF_SIZE + RX_BUF_EXTRA; /* advance the pointer */ pDrvCtrl->RBA4 = (u_long) pCur; /* Receive Buffer 4 */ /* Init the CAM Descriptors to all broadcasts */ pCam = (CAM_DESC *)pDrvCtrl->CDA; /* Program the descriptor entry for each CAM register */ for (cnt = 0; cnt < CAM_COUNT; cnt++, pCam++) { pCam->cep = cnt; pCam->cap0 = 0xffff; pCam->cap1 = 0xffff; pCam->cap2 = 0xffff; } pDrvCtrl->pCamEnableMask = (u_long *)pCam; *pDrvCtrl->pCamEnableMask = 0; /* All Addresses Disabled */ /*** init the Tx descriptors ***/ pTXD = pDrvCtrl->pTDA; /* get initial ptr */ bzero ((char *)pTXD, TDA_SIZE); /* zero the whole enchilada */ for (cnt = 0; cnt < NUM_TX_DESC; cnt++) /* loop thru each */ { pTXD->number = cnt; pTXD->pLink = pTXD + 1; /* link to next */ pTXD++; /* bump to next */ } /* * The link field of the last desc is special; it needs to point * back to the first desc. So, we fix it here. */ (--pTXD)->pLink = pDrvCtrl->pTDA; pDrvCtrl->pTXDFree = pDrvCtrl->pTDA; /* initial value */ pDrvCtrl->pTXDReclaim = pDrvCtrl->pTDA; /* initial value */ pDrvCtrl->pTXDLast = pDrvCtrl->pTDA; /* initial value */ /*** init the Rx buffer descriptors ***/ /* Build the RRA */ pRRAD = (RRA_DESC *)pDrvCtrl->RSA; /* get ptr to first entry */ /* Stuff buffer ptr; least significant 16 bits, then most significant 16 */ temp = (u_long) CACHE_DMA_VIRT_TO_PHYS (pDrvCtrl->RBA1); pRRAD->buff_ptr0 = temp & UMASK; pRRAD->buff_ptr1 = temp >> 16; /* Stuff word count; least significant 16 bits, then most significant 16 */ pRRAD->buff_wc0 = (RX_BUF_SIZE >> 1) & UMASK; pRRAD->buff_wc1 = (RX_BUF_SIZE >> 1) >> 16; pRRAD++; /* bump to next entry */ /* Stuff buffer ptr; least significant 16 bits, then most significant 16 */ temp = (u_long) CACHE_DMA_VIRT_TO_PHYS (pDrvCtrl->RBA2); pRRAD->buff_ptr0 = (u_long) temp & UMASK; pRRAD->buff_ptr1 = (u_long) temp >> 16; /* Stuff word count; least significant 16 bits, then most significant 16 */ pRRAD->buff_wc0 = RX_BUF_SIZE >> 1 & UMASK; pRRAD->buff_wc1 = RX_BUF_SIZE >> 1 >> 16; pRRAD++; /* bump to next entry */ /* Stuff buffer ptr; least significant 16 bits, then most significant 16 */ temp = (u_long) CACHE_DMA_VIRT_TO_PHYS (pDrvCtrl->RBA3); pRRAD->buff_ptr0 = (u_long) temp & UMASK; pRRAD->buff_ptr1 = (u_long) temp >> 16; /* Stuff word count; least significant 16 bits, then most significant 16 */ pRRAD->buff_wc0 = RX_BUF_SIZE >> 1 & UMASK; pRRAD->buff_wc1 = RX_BUF_SIZE >> 1 >> 16; pRRAD++; /* bump to next entry */ /* Stuff buffer ptr; least significant 16 bits, then most significant 16 */ temp = (u_long) CACHE_DMA_VIRT_TO_PHYS (pDrvCtrl->RBA4); pRRAD->buff_ptr0 = (u_long) temp & UMASK; pRRAD->buff_ptr1 = (u_long) temp >> 16; /* Stuff word count; least significant 16 bits, then most significant 16 */ pRRAD->buff_wc0 = RX_BUF_SIZE >> 1 & UMASK; pRRAD->buff_wc1 = RX_BUF_SIZE >> 1 >> 16; /* Setup the Rx frame descriptors */ pRXD = (RX_DESC *) pDrvCtrl->RDA; /* get initial ptr */ bzero ((char *)pRXD, RDA_SIZE); /* zero the whole tomato */ pDrvCtrl->pRXDNext = pRXD; /* start from the start! */ pDrvCtrl->pRXDLast = /* stuff ptr to last */ (RX_DESC *) ((u_long)pRXD + RDA_SIZE - RX_DESC_SIZ); while (pRXD <= pDrvCtrl->pRXDLast) /* loop thru each */ { pRXD->in_use = IN_USE; /* set IN_USE by device */ pRXD->link = /* set link */ (RX_DESC *) CACHE_DMA_VIRT_TO_PHYS (pRXD + 1); pRXD++; /* bump to next */ } /* * The link field of the last desc is special; it points nowhere, * but must mark the end-of-list. So, we fix it here. */ pDrvCtrl->pRXDLast->link = RX_EOL; /* memory allocation for NetPool */ if((pDrvCtrl->endData.pNetPool = malloc (sizeof(NET_POOL))) == NULL) return (ERROR); /* number of clusters in each cluster pool */ SnClDescTbl[0].clNum = NUM_OPTIMAL_CLUSTER; SnClDescTbl[1].clNum = NUM_MTU_CLUSTER; /* number of cluster blocks */ SnMclConfig.clBlkNum = NUM_CL_BLK; /* number of mblks */ SnMclConfig.mBlkNum = NUM_MBLK; /* memory requirement for cluster blks and mblks */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -