📄 sngks32cend.c
字号:
LOCAL STATUS at91cEndPollRcv (END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);LOCAL STATUS at91cEndPollStart (END_DEVICE* pDrvCtrl);LOCAL STATUS at91cEndPollStop (END_DEVICE* pDrvCtrl);LOCAL STATUS at91cEndParse ();LOCAL STATUS at91cEndMemInit ();int firstSend;/** Declare our function table. This is static across all driver* instances.*/LOCAL NET_FUNCS endFuncTable = { /* Function to start the device. */ (STATUS (*) (END_OBJ*))at91cEndStart, /* Function to stop the device. */ (STATUS (*) (END_OBJ*))at91cEndStop, /* Unloading function for the driver. */ (STATUS (*) (END_OBJ*))at91cEndUnload, /* Ioctl function for the driver. */ (int (*) (END_OBJ*, int, caddr_t))at91cEndIoctl, /* Send function for the driver. */ (STATUS (*) (END_OBJ* , M_BLK_ID))at91cEndSend, /* Multicast address add function for the driver. */ (STATUS (*) (END_OBJ*, char*))at91cEndMCastAdd, /* Multicast address delete function for the driver. */ (STATUS (*) (END_OBJ*, char*))at91cEndMCastDel, /* Multicast table retrieve function for the driver. */ (STATUS (*) (END_OBJ*, MULTI_TABLE*))at91cEndMCastGet, /* Polling send function for the driver. */ (STATUS (*) (END_OBJ*, M_BLK_ID))at91cEndPollSend, /* Polling receive function for the driver. */ (STATUS (*) (END_OBJ*, M_BLK_ID))at91cEndPollRcv, /* Put address info into a packet. */ endEtherAddressForm, /* Get a pointer to packet data. */ endEtherPacketDataGet, /* Get packet addresses. */ endEtherPacketAddrGet };extern CACHE_FUNCS at91cCacheFuncs;#undef DYNAMIC_PHY/********************************************************************************* phyPoll - checks the current status of the PHY** Description* Checks the current status of the PHY and sets the full duplex bit of maccon* accordingly. If not done, packets will be lost (very seldom)* * Caveat* We don't know if it's OK to change the MACCON during runtime*/LOCAL void phyPoll ( int dummy ) { UINT32 phyStat2; /* init MAC register */ phyStat2 = at91cEndPhyRead (PHY_DSCSR_REG,0); if (phyStat2 & FDX) *(volatile UINT32 *)AT91C_EMAC_CFG |= AT91C_EMAC_FD; else *(volatile UINT32 *)AT91C_EMAC_CFG &= ~AT91C_EMAC_FD; (void) wdStart (phyPollWdog, PHY_WDOG_PERIOD , (FUNCPTR) phyPoll, 0); } /*DYNAMIC_PHY*//******************************************************************************** at91cEndLoad - 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>:<Speed>:<duplex>:<autoneg>"** RETURNS: An END object pointer or NULL on error.*/END_OBJ* at91cEndLoad ( char* initString /* String to be parsed by the driver. */ ) { END_DEVICE *pDrvCtrl; DRV_LOG (DRV_DEBUG_LOAD, "Loading at91cEnd...\n", 1, 2, 3, 4, 5, 6); if (initString == NULL) { DRV_LOG (DRV_DEBUG_LOAD, "at91cEndLoad: NULL initString\r\n", 0,0,0,0,0,0); return NULL; } if (initString[0] == '\0') { strcpy (initString, AT91CEND_DEV_NAME); return (END_OBJ *)0; } /* allocate the device structure */ pDrvCtrl = (END_DEVICE *)calloc (sizeof (END_DEVICE), 1); if (pDrvCtrl == NULL) { printf ("%s - Failed to allocate control structure\n", AT91CEND_DEV_NAME ); goto errorExit; } /* parse the init string, filling in the device structure */ if (at91cEndParse (pDrvCtrl, initString) == ERROR) goto errorExit; pDrvCtrl->ivecEMAC = AT91C_INT_LVL_EMAC;#ifdef INCLUDE_CACHE_SUPPORT /* install cache functions defined in sysLib.c */ pDrvCtrl->cacheFuncs = &at91cCacheFuncs;#endif /*INCLUDE_CACHE_SUPPORT*/ /* Ask the BSP to provide the ethernet address. */ SYS_ENET_ADDR_GET(pDrvCtrl); strcpy (pDrvCtrl->end.devObject.name, AT91CEND_DEV_NAME); strcpy (pDrvCtrl->end.devObject.description, "atmel AT91C ARM9 END Driver"); /* initialize some flags */ pDrvCtrl->loaded = TRUE; /* initialize the END and MIB2 parts of the structure */ /* * The M2 element must come from m2Lib.h * This at91cEnd is set up for a DIX type ethernet device. */ if (END_OBJ_INIT (&pDrvCtrl->end, (DEV_OBJ *)pDrvCtrl, AT91CEND_DEV_NAME, pDrvCtrl->unit, &endFuncTable, "atmel AT91C ARM9 END Driver") == ERROR || END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd, &pDrvCtrl->enetAddr[0], 6, ETHERMTU, END_SPEED) == ERROR) goto errorExit; /* Perform memory allocation/distribution */ if (at91cEndMemInit (pDrvCtrl) == ERROR) goto errorExit;#ifdef DYNAMIC_PHY if ((phyPollWdog = wdCreate ()) == NULL) { logMsg ("\nCould not create phyPollWdog\n",1,2,3,4,5,6); goto errorExit; }#endif /*DYNAMIC_PHY*/ /* reset and reconfigure the device */ at91cEndConfig (pDrvCtrl);#if 1 if (pDrvCtrl->fdInitialized == TRUE) at91cEndFdFree(pDrvCtrl); /* Free the FDs */ /* Reinitialize FDs */ if (at91cEndFdInitialize(pDrvCtrl) == ERROR) { DRV_LOG (DRV_DEBUG_LOAD, "at91cEndFdInitialize failed \n", 0, 0, 0, 0, 0, 0); return; }#endif /* set the flags to indicate readiness */ END_OBJ_READY (&pDrvCtrl->end, IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST); DRV_LOG (DRV_DEBUG_LOAD, "Done loading at91cEnd...", 1, 2, 3, 4, 5, 6); return (&pDrvCtrl->end); errorExit: at91cEndUnload (pDrvCtrl); if (pDrvCtrl != NULL) free ((char *)pDrvCtrl); return NULL; }/******************************************************************************** at91cEndUnload - unload a driver from the system** This function first brings down the device, and then frees any* stuff that was allocated by the driver in the load function.** RETURNS: OK or ERROR.*/LOCAL STATUS at91cEndUnload ( END_DEVICE* pDrvCtrl /* device to be unloaded */ ) { DRV_LOG (DRV_DEBUG_LOAD, "EndUnload\n", 0, 0, 0, 0, 0, 0); if (pDrvCtrl == NULL) return (ERROR); pDrvCtrl->loaded = FALSE; /*this call will indicate protocol that the device will be unloaded */ END_OBJECT_UNLOAD (&pDrvCtrl->end); /* TODO - Free any shared DMA memory *//*before unloading the device will stop functioning*/ at91cEndStop(pDrvCtrl); /*then it will reset the registers in order to clear any pending interrupts */ at91cEndReset(pDrvCtrl); if (pDrvCtrl->fdInitialized) at91cEndFdFree(pDrvCtrl); if (pDrvCtrl->end.pNetPool) { netPoolDelete (pDrvCtrl->end.pNetPool); free (pDrvCtrl->end.pNetPool); pDrvCtrl->end.pNetPool = (NET_POOL_ID)0; } if (endClDescTbl[0].memArea) { free (endClDescTbl[0].memArea); endClDescTbl[0].memArea = (char *)0; } if (endMclConfig.memArea) { free (endMclConfig.memArea); endMclConfig.memArea = (char *)0; } free (pDrvCtrl); pDrvCtrl = NULL; return (OK); }/******************************************************************************** at91cEndParse - parse the init string** Parse the input string. Fill in values in the driver control structure.** The initialization string format is:* "<unit>:<Speed>:<duplex>:<autoneg>"** .bS* unit Device unit number, a small integer.* Speed 10 (10Mbps) or 100 (100 Mbps)* duplex 0 (HDX) or 1 (FDX)* autoneg Autonegotiation disabled (0) or enabled (1)* .bE** RETURNS: OK or ERROR for invalid arguments.*/LOCAL STATUS at91cEndParse ( END_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); /* netSpeed */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->netSpeed = atoi (tok); /* DuplexMode */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->duplexMode = atoi (tok); /* auto Negotiation */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->autoNeg = atoi (tok); return OK; }/******************************************************************************** at91cEndMemInit - initialize memory for the chip** This routine is highly specific to the device. ** RETURNS: OK or ERROR.*/LOCAL STATUS at91cEndMemInit ( END_DEVICE * pDrvCtrl /* device to be initialized */ ) { DRV_LOG (DRV_DEBUG_LOAD, "InitMem\n", 0, 0, 0, 0, 0, 0); /* this driver can't handle write incoherent caches */ if (!CACHE_DMA_IS_WRITE_COHERENT ()) { DRV_LOG (DRV_DEBUG_LOAD, "at91cEndMemInit: shared memory not cache coherent\n", 1, 2, 3, 4, 5, 6); return (ERROR); } /* * Set up an END netPool using netBufLib(1). */ endMclConfig.mBlkNum = END_MBLK_NUM; endClDescTbl[0].clNum = END_CL_NUM; endMclConfig.clBlkNum = endClDescTbl[0].clNum; /* Calculate the total memory for all the M-Blks and CL-Blks. */ endMclConfig.memSize = (endMclConfig.mBlkNum * (MSIZE + sizeof (long))) + (endMclConfig.clBlkNum * (CL_BLK_SZ + sizeof(long))); if ((endMclConfig.memArea = (char *) memalign (sizeof(long), endMclConfig.memSize)) == NULL) return (ERROR); /* Calculate the memory size of all the clusters. */ endClDescTbl[0].memSize = (endClDescTbl[0].clNum * (endClDescTbl[0].clSize + 8)) + sizeof(int); /* +8 is for proper alignment */ /* Allocate the memory for the clusters */#ifdef INCLUDE_CACHE_SUPPORT endClDescTbl[0].memArea = (char *) cacheDmaMalloc (endClDescTbl[0].memSize);#else endClDescTbl[0].memArea = (char *) malloc (endClDescTbl[0].memSize); #endif if (endClDescTbl[0].memArea == NULL) { DRV_LOG (DRV_DEBUG_LOAD, "system memory unavailable\n", 1, 2, 3, 4, 5, 6); return (ERROR); } if ((pDrvCtrl->end.pNetPool = (NET_POOL_ID) malloc (sizeof(NET_POOL))) == NULL) return (ERROR); /* Initialize the memory pool. */ if (netPoolInit(pDrvCtrl->end.pNetPool, &endMclConfig, &endClDescTbl[0], endClDescTblNumEnt, NULL) == ERROR) { return (ERROR); } return OK; }/******************************************************************************** at91cEndStart - 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 at91cEndStart ( END_DEVICE *pDrvCtrl /* device to be started */ ) { DRV_LOG (DRV_DEBUG_LOAD, "Starting atm \n", 0, 0, 0, 0, 0, 0); if (!pDrvCtrl->loaded) return (ERROR); pDrvCtrl->rxHandling = FALSE; pDrvCtrl->resetting = FALSE;/*INT ENABLE:rec complete; Enable Receive */ *(volatile UINT32 *)AT91C_EMAC_IER = AT91C_EMAC_RCOM; /*| AT91C_EMAC_RBNA;*//*发送使能*/ *(volatile UINT32 *)AT91C_EMAC_CTL |= AT91C_EMAC_RE |AT91C_EMAC_TE; *(volatile UINT32 *)AT91C_AIC_ICCR=~0; /* Connect MAC interrupts */ pDrvCtrl->tail=0; intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivecEMAC), at91cEndInt,(int) pDrvCtrl); /* Enable the interrupt */ intEnable (pDrvCtrl->ivecEMAC);#ifdef DYNAMIC_PHY (void) wdStart (phyPollWdog, PHY_WDOG_PERIOD , (FUNCPTR) phyPoll, 0);#endif /*DYNAMIC_PHY*/ /* Set the flags to indicate that the device is up */ END_FLAGS_SET (&pDrvCtrl->end, IFF_UP | IFF_RUNNING); return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -