📄 ibmemacend.c
字号:
/* DRV_DEBUG_DEBUG */ );#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) \ if (ibmEmacDebug & FLG) \ logMsg((char *)X0, (int)X1, (int)X2, (int)X3, (int)X4, \ (int)X5, (int)X6);#define DRV_PRINT(FLG,X) \ if (ibmEmacDebug & FLG) printf X;#else /*DRV_DEBUG*/#define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)#define DRV_PRINT(DBG_SW,X)#endif /*DRV_DEBUG*//* forward static functions */LOCAL STATUS ibmEmacSendCopy(EMAC_DRV_CTRL * pDrvCtrl, M_BLK_ID pMblk);LOCAL STATUS ibmEmacSendNoCopy(EMAC_DRV_CTRL * pDrvCtrl, M_BLK_ID pMblk);LOCAL void ibmEmacReset(EMAC_DRV_CTRL * pDrvCtrl);LOCAL void ibmEmacInt(EMAC_DRV_CTRL * pDrvCtrl);LOCAL void ibmEmacTxeobInt(EMAC_DRV_CTRL * pDrvCtrl);LOCAL void ibmEmacRxeobInt(EMAC_DRV_CTRL * pDrvCtrl);LOCAL void ibmEmacTxdeInt(EMAC_DRV_CTRL * pDrvCtrl);LOCAL void ibmEmacRxdeInt(EMAC_DRV_CTRL * pDrvCtrl);LOCAL void ibmEmacMalSerrInt(EMAC_DRV_CTRL * pDrvCtrl);LOCAL void ibmEmacHandleRecvInt(EMAC_DRV_CTRL * pDrvCtrl, int resetChan);LOCAL STATUS ibmEmacRecv(EMAC_DRV_CTRL * pDrvCtrl, MAL_BD * pRxDesc);LOCAL MAL_BD * ibmEmacRecvDescGet(EMAC_DRV_CTRL * pDrvCtrl);LOCAL void ibmEmacRestart(EMAC_DRV_CTRL * pDrvCtrl);LOCAL STATUS ibmEmacRestartSetup(EMAC_DRV_CTRL * pDrvCtrl);LOCAL void ibmEmacAddrFilterSet(EMAC_DRV_CTRL * pDrvCtrl);LOCAL void ibmEmacSendCleanup(EMAC_DRV_CTRL * pDrvCtrl);LOCAL void ibmEmacConfig(EMAC_DRV_CTRL * pDrvCtrl);LOCAL STATUS ibmEmacMemInit(EMAC_DRV_CTRL * pDrvCtrl);LOCAL STATUS ibmEmacPhyRead(EMAC_DRV_CTRL * pDrvCtrl, UINT8 phyReg, USHORT * value);LOCAL STATUS ibmEmacPhyWrite(EMAC_DRV_CTRL * pDrvCtrl, UINT8 phyReg, USHORT value);LOCAL STATUS ibmEmacPhyAutoNegWait(EMAC_DRV_CTRL * pDrvCtrl, UINT ticks);LOCAL STATUS ibmEmacPhyGetData(EMAC_DRV_CTRL * pDrvCtrl);LOCAL void ibmEmacWdRestart(EMAC_DRV_CTRL * pDrvCtrl );/* END Specific interfaces. */LOCAL STATUS ibmEmacStart(EMAC_DRV_CTRL * pDrvCtrl);LOCAL STATUS ibmEmacStop(EMAC_DRV_CTRL * pDrvCtrl);LOCAL STATUS ibmEmacUnload(EMAC_DRV_CTRL * pDrvCtrl);LOCAL int ibmEmacIoctl(EMAC_DRV_CTRL * pDrvCtrl, unsigned int cmd, caddr_t data);LOCAL STATUS ibmEmacSend(EMAC_DRV_CTRL * pDrvCtrl, M_BLK_ID pBuf);LOCAL STATUS ibmEmacMCastAddrAdd(EMAC_DRV_CTRL * pDrvCtrl, char * pAddress);LOCAL STATUS ibmEmacMCastAddrDel(EMAC_DRV_CTRL * pDrvCtrl, char * pAddress);LOCAL STATUS ibmEmacMCastAddrGet(EMAC_DRV_CTRL * pDrvCtrl, MULTI_TABLE * pTable);LOCAL STATUS ibmEmacPollSend(EMAC_DRV_CTRL * pDrvCtrl, M_BLK_ID pBuf);LOCAL STATUS ibmEmacPollReceive(EMAC_DRV_CTRL * pDrvCtrl, M_BLK_ID pBuf);LOCAL STATUS ibmEmacPollStart(EMAC_DRV_CTRL * pDrvCtrl);LOCAL STATUS ibmEmacPollStop(EMAC_DRV_CTRL * pDrvCtrl);/* * Declare the driver function table. This is static across all driver * instances. */LOCAL NET_FUNCS ibmEmacFuncTable = { (FUNCPTR) ibmEmacStart, /* Function to start the device. */ (FUNCPTR) ibmEmacStop, /* Function to stop the device. */ (FUNCPTR) ibmEmacUnload, /* Unload function for the driver. */ (FUNCPTR) ibmEmacIoctl, /* Ioctl function for the driver. */ (FUNCPTR) ibmEmacSend, /* Send function for the driver. */ (FUNCPTR) ibmEmacMCastAddrAdd, /* Multicast address add. */ (FUNCPTR) ibmEmacMCastAddrDel, /* Multicast address delete. */ (FUNCPTR) ibmEmacMCastAddrGet, /* Multicast table retrieve. */ (FUNCPTR) ibmEmacPollSend, /* Polling send function. */ (FUNCPTR) ibmEmacPollReceive, /* Polling receive function. */ endEtherAddressForm, /* Put address info into a packet. */ endEtherPacketDataGet, /* Get a pointer to packet data. */ endEtherPacketAddrGet /* Get packet addresses. */ };/******************************************************************************** ibmEmacEndLoad - 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.** See ibmEmacInitParse() for the specific format of the string.** This function is meant to be called two different times during the driver* load process. If this routine is called with the first character of the* initialization string equal to NULL, this routine will return with the name of* the device "ibmEmac" copied into initString.* If this routine is called with the actual driver parameters in initString,* it will use the parms to initialize the device and prepare the rest of the* driver for operation.** RETURNS: An END object pointer, NULL if there is an error, or 0 and the* name of the device if the first character of initString is NULL.*/END_OBJ * ibmEmacEndLoad ( char * initString /* String to be parsed by the driver */ ) { EMAC_DRV_CTRL * pDrvCtrl; pDrvCtrl = NULL; /* If initString is NULL, this is an error. */ if (initString == NULL) return (NULL); /* * If the first char of initString is a null char, just copy * the name of this device "emac" into initString and return. */ if (initString[0] == 0) { DRV_LOG (DRV_DEBUG_LOAD, "ibmEmacEndLoad NULL \n", 1, 2, 3, 4, 5, 6); strcpy(initString, (char *)EMAC_DEV_NAME); return ((END_OBJ *)OK); } DRV_LOG (DRV_DEBUG_LOAD, "ibmEmacEndLoad Load \n", 1, 2, 3, 4, 5, 6); /* * Allocate the main device structure the driver uses to keep track of * everything. */ pDrvCtrl = (EMAC_DRV_CTRL *)calloc(sizeof(EMAC_DRV_CTRL), 1); if (pDrvCtrl == NULL) goto errorExit; DRV_LOG (DRV_DEBUG_INFO, "pDrvCtrl = 0x%x\n", pDrvCtrl, 2, 3, 4, 5, 6); /* Parse initString, and fill in the device structure */ if (ibmEmacInitParse(pDrvCtrl, initString) == ERROR) { goto errorExit; } /* Create the restart WatchDog */ pDrvCtrl->wdRestart = wdCreate(); /* Get the MAC address from the BSP. */ EMAC_ENET_ADDR_GET (pDrvCtrl, &(pDrvCtrl->enetAddr[0])); /* * Depending on the value of inputFlags, store the value needed to initiate * the transmit of a new packet when written to the TMR0 register. */ if (pDrvCtrl->inputFlags & EMAC_INPUT_TX_2_CHANNEL) { /* Use both TX channel 0 and 1 in independent mode */ pDrvCtrl->numTxChannels = 2; pDrvCtrl->txInfo[0].getNewPacketTX = EMAC_TMR0_GNP0; pDrvCtrl->txInfo[1].getNewPacketTX = EMAC_TMR0_GNP1; } else { /* Use TX channel 0 only */ pDrvCtrl->numTxChannels = 1; pDrvCtrl->txInfo[0].getNewPacketTX = EMAC_TMR0_GNP0; } /* Initialize the END and MIB2 parts of the structure */ if (END_OBJ_INIT (&pDrvCtrl->end, (DEV_OBJ *)pDrvCtrl, EMAC_DEV_NAME, pDrvCtrl->unit, &ibmEmacFuncTable, EMAC_DEV_DESC) == ERROR || END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd, &pDrvCtrl->enetAddr[0], 6, ETHERMTU, EMAC_SPEED) == ERROR) goto errorExit; /* Call a routine to allocate memory for various needs */ if (ibmEmacMemInit(pDrvCtrl) == ERROR) goto errorExit;#ifdef INCLUDE_ZMII /* * ZMII must give the desired EMAC clocks, or else the EMAC * will not come out of reset. */ if (zmiiSetInterface(pDrvCtrl->baseAdrs)) goto errorExit;#endif /* * Depending on the OPB bus speed, determine the correct value to use * in the EMAC_STACR register when accessing the PHY through the MDI. */ if (pDrvCtrl->opbSpeedMhz <= 50) pDrvCtrl->stacrOpbSpeed = EMAC_STACR_CLK_50MHZ; else if (pDrvCtrl->opbSpeedMhz <= 66) pDrvCtrl->stacrOpbSpeed = EMAC_STACR_CLK_66MHZ; else if (pDrvCtrl->opbSpeedMhz <= 83) pDrvCtrl->stacrOpbSpeed = EMAC_STACR_CLK_83MHZ; else pDrvCtrl->stacrOpbSpeed = EMAC_STACR_CLK_100MHZ; /* Setup buffer descriptors and configure the EMAC core */ if (ibmEmacRestartSetup(pDrvCtrl) == ERROR) goto errorExit; /* Set the flags to indicate readiness */ END_OBJ_READY (&pDrvCtrl->end, IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST); DRV_LOG (DRV_DEBUG_LOAD, "Done loading ibmEmac...\n", 1, 2, 3, 4, 5, 6);#ifdef DRV_DEBUG ibmEmacDebugPtr = pDrvCtrl;#endif return (&pDrvCtrl->end);errorExit: if (pDrvCtrl != NULL) { /* Free buffer memory if it was allocated */ if (pDrvCtrl->memAdrsMalloc != NULL) { if (pDrvCtrl->inputFlags & EMAC_INPUT_UNCACHED_BUF) cacheDmaFree(pDrvCtrl->memAdrsMalloc); else free(pDrvCtrl->memAdrsMalloc); } /* Free the memory allocated for driver pool structure */ if (pDrvCtrl->end.pNetPool != NULL) free(pDrvCtrl->end.pNetPool); /* Free the memory allocated for mBlks and clBlks */ if (pDrvCtrl->mClCfg.memArea != NULL) free(pDrvCtrl->mClCfg.memArea); /* Free the driver control structure itself */ free((char *)pDrvCtrl); } return ((END_OBJ *)NULL); }/********************************************************************************* ibmEmacInitParse - parse the initialization string** ibmEmacEndLoad() calls this function to parse the driver initialization* string and then put the parameters in the the driver control structure.** The muxLib.o module automatically prepends the unit number to the user's* initialization string from the BSP (found in configNet.h).*** RETURNS: OK, or ERROR if any arguments are invalid.*/STATUS ibmEmacInitParse ( EMAC_DRV_CTRL * pDrvCtrl, char * initString ) { char* tok; char* pHolder = NULL; /* string placeholder */ char** ppHolder = &pHolder; /* pointer to string placeholder */ /* Parse initString */ /* First parameter is the unit number (from muxLib.o) */ tok = strtok_r (initString, ":", ppHolder); if (tok == NULL) return ERROR; pDrvCtrl->unit = atoi (tok); /* Second parameter is the base address of the EMAC core registers */ tok = strtok_r (NULL, ":", ppHolder); if (tok == NULL) return ERROR; pDrvCtrl->baseAdrs = (UINT)strtoul (tok, NULL, 16); /* * Third parameter is the MAL channel number EMAC TX channel 0 is * connected to. */ tok = strtok_r (NULL, ":", ppHolder); if (tok == NULL) return ERROR; pDrvCtrl->txChn0MalChannel = atoi (tok); /* * Fourth parameter is the MAL channel number EMAC TX channel 1 is * connected to. */ tok = strtok_r (NULL, ":", ppHolder); if (tok == NULL) return ERROR; pDrvCtrl->txChn1MalChannel = atoi (tok); /* * Fifth parameter is the MAL channel number EMAC RX channel 0 is * connected to. */ tok = strtok_r (NULL, ":", ppHolder); if (tok == NULL) return ERROR; pDrvCtrl->rxChn0MalChannel = atoi (tok); /* Sixth parameter is the Ethernet interrupt vector */ tok = strtok_r (NULL, ":", ppHolder); if (tok == NULL) return ERROR; pDrvCtrl->ivec = atoi (tok); /* Seventh parameter is the Ethernet interrupt level. */ tok = strtok_r (NULL, ":", ppHolder); if (tok == NULL) return ERROR; pDrvCtrl->ilevel = atoi (tok); /* Eighth parameter is the memory address which will contain buffers. */ tok = strtok_r (NULL, ":", ppHolder); if (tok == NULL) return ERROR; pDrvCtrl->memInputAdrs = (char *)strtoul (tok, NULL, 16); /* Ninth parameter is the size of the memory pointed to above. */ tok = strtok_r (NULL, ":", ppHolder); if (tok == NULL) return ERROR; pDrvCtrl->memInputSize = strtoul (tok, NULL, 16); /* Tenth parameter is input flags */ tok = strtok_r (NULL, ":", ppHolder); if (tok == NULL) return ERROR; pDrvCtrl->inputFlags |= strtoul (tok, NULL, 16); /* Eleventh parameter is the PHY address */ tok = strtok_r (NULL, ":", ppHolder); if (tok == NULL) return ERROR; pDrvCtrl->phyAdrs = strtoul (tok, NULL, 10); /* Twelveth parameter is the size of the processor's data cache line */ tok = strtok_r (NULL, ":", ppHolder); if (tok == NULL) return ERROR; pDrvCtrl->cacheLineSize = atoi (tok); /* * Thirteenth parameter is a pointer to the MAL driver structure for the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -