📄 auend.c
字号:
};
/******************************************************************************
*
* auEndLoad - 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 <initString>, which
* expects a string of the following format:
*
* <unit>:<devMemAddr>:<devIoAddr>:<enableAddr>:<vecNum>:<intLvl>:<offset>
* :<qtyCluster>:<flags>
*
* This routine can be called in two modes. If it is called with an empty but
* allocated string, it places the name of this device (that is, "aumac") into
* the <initString> and returns 0.
*
* If the string is allocated and not empty, the routine attempts to load
* the driver using the values specified in the string.
*
* RETURNS: An END object pointer, or NULL on error, or 0 and the name of the
* device if the <initString> was NULL.
*/
END_OBJ * auEndLoad
(
char * initString /* string to be parse by the driver */
)
{
AU_DRV_CTRL * pDrvCtrl;
DRV_LOG (DRV_DEBUG_LOAD, "auEndLoad: Loading aumac...debug @ 0X%X\n",
(int)&auDebug, 2, 3, 4, 5, 6);
if (initString == NULL)
return (NULL);
if (initString [0] == 0)
{
bcopy ((char *)AU_DEV_NAME, initString, AU_DEV_NAME_LEN);
DRV_LOG (DRV_DEBUG_LOAD, "auEndLoad: Returning device name...\n", 1, 2, 3, 4, 5, 6);
return ((END_OBJ *)OK);
}
DRV_LOG (DRV_DEBUG_LOAD, "auEndLoad: Load string: [%s]\n",
initString, 2, 3, 4, 5, 6);
/* allocate the device structure */
pDrvCtrl = (AU_DRV_CTRL *)calloc (sizeof (AU_DRV_CTRL), 1);
if (pDrvCtrl == NULL)
goto errorExit;
DRV_LOG (DRV_DEBUG_LOAD, "auEndLoad: DrvControl : 0x%X\n", (int)pDrvCtrl,
2, 3, 4, 5, 6);
/* parse the init string, filling in the device structure */
if (auInitParse (pDrvCtrl, initString) == ERROR)
{
DRV_LOG (DRV_DEBUG_LOAD, "auEndLoad: Parse failed!\n", 1, 2, 3, 4, 5, 6);
goto errorExit;
}
DRV_LOG (DRV_DEBUG_LOAD, "auEndLoad: initial mac addr %08x %08x\n",
AU_MAC_ADDRESS_HIGH,
AU_MAC_ADDRESS_LOW, 0, 0, 0, 0);
DRV_LOG (DRV_DEBUG_LOAD, "auEndLoad: initial multi addr %08x %08x\n",
AU_MULTICAST_HASH_ADDRESS_HIGH,
AU_MULTICAST_HASH_ADDRESS_LOW, 0, 0, 0, 0);
/* Have the BSP hand us our address. */
SYS_ENET_ADDR_GET (pDrvCtrl, &(pDrvCtrl->enetAddr [0]));
/* initialize the END and MIB2 parts of the structure */
if (END_OBJ_INIT (&pDrvCtrl->endObj, (DEV_OBJ *)(&pDrvCtrl->endObj.devObject), AU_DEV_NAME,
pDrvCtrl->unit, &auFuncTable,
"Au MAC Enhanced Network Driver") == ERROR
|| END_MIB_INIT (&pDrvCtrl->endObj, M2_ifType_ethernet_csmacd,
&pDrvCtrl->enetAddr[0], MAC_ADDRS_SIZE, ETHERMTU,
AU_SPEED)
== ERROR)
goto errorExit;
DRV_LOG (DRV_DEBUG_LOAD, "auEndLoad: END init done\n", 1, 2, 3, 4, 5, 6);
/* Allocate PHY structure */
/* Perform memory allocation */
if (auMemInit (pDrvCtrl) == ERROR)
goto errorExit;
DRV_LOG (DRV_DEBUG_LOAD, "auEndLoad: Mem malloc done\n", 1, 2, 3, 4, 5, 6);
/* Perform memory distribution and reset and reconfigure the device */
if (auRestartSetup (pDrvCtrl) == ERROR)
goto errorExit;
DRV_LOG (DRV_DEBUG_LOAD, "auEndLoad: Restart setup done\n", 1, 2, 3, 4, 5, 6);
/* set the flags to indicate readiness */
END_OBJ_READY (&pDrvCtrl->endObj, IFF_NOTRAILERS | IFF_BROADCAST |
IFF_MULTICAST | IFF_SIMPLEX);
DRV_LOG (DRV_DEBUG_LOAD, "auEndLoad: Load aumac...done\n", 1, 2, 3, 4, 5, 6);
#ifdef DRV_DEBUG
dbgDrvCtrl[pDrvCtrl->unit] = pDrvCtrl;
#endif
return (&pDrvCtrl->endObj);
errorExit:
if (pDrvCtrl != NULL)
free ((char *)pDrvCtrl);
return ((END_OBJ *)NULL);
}
/*******************************************************************************
*
* auInitParse - parse the initialization string
*
* Parse the input string. This routine is called from auEndLoad() which
* intializes some values in the driver control structure with the values
* passed in the intialization string.
*
* The initialization string format is:
* <unit>:<devMemAddr>:<devIoAddr>:<vecNum>:<intLvl>:<offset>:<flags>
*
* .IP <unit>
* Device unit number, a small integer.
* .IP <devMemAddr>
* Device register base memory address
* .IP <devIoAddr>
* DMA I/O register base memory address
* .IP <enableAddr>
* Address of MAC enable register
* .IP <vecNum>
* Interrupt vector number.
* .IP <intLvl>
* Interrupt level.
* .IP <offset>
* Offset of starting of data in the device buffers.
* .IP <qtyCluster>
* Number of clusters to allocate
* .IP <flags>
* Device specific flags, for future use.
*
* RETURNS: OK, or ERROR if any arguments are invalid.
*/
STATUS auInitParse
(
AU_DRV_CTRL * pDrvCtrl, /* pointer to the control structure */
char * initString /* initialization string */
)
{
char* tok;
char* holder = NULL;
DRV_LOG (DRV_DEBUG_LOAD, "auInitParse: Parse starting ...\n", 1, 2, 3, 4, 5, 6);
/* Parse the initString */
/* Unit number. */
tok = strtok_r (initString, ":", &holder);
if (tok == NULL)
return ERROR;
pDrvCtrl->unit = atoi (tok);
DRV_LOG (DRV_DEBUG_LOAD, "Unit : %d ...\n", pDrvCtrl->unit, 2, 3, 4, 5, 6);
/* devAdrs address. */
tok = strtok_r (NULL, ":", &holder);
if (tok == NULL)
return ERROR;
pDrvCtrl->devAdrs = (UINT32) strtoul (tok, NULL, 16);
DRV_LOG (DRV_DEBUG_LOAD, "devAdrs : 0x%X ...\n", pDrvCtrl->devAdrs,
2, 3, 4, 5, 6);
/* dmaAdrs address. */
tok = strtok_r (NULL, ":", &holder);
if (tok == NULL)
return ERROR;
pDrvCtrl->dmaAdrs = (UINT32) strtoul (tok, NULL, 16);
DRV_LOG (DRV_DEBUG_LOAD, "dmaAdrs : 0x%X ...\n", pDrvCtrl->dmaAdrs,
2, 3, 4, 5, 6);
/* enableAdrs address. */
tok = strtok_r (NULL, ":", &holder);
if (tok == NULL)
return ERROR;
pDrvCtrl->enableAdrs = (UINT32) strtoul (tok, NULL, 16);
DRV_LOG (DRV_DEBUG_LOAD, "enableAdrs : 0x%X ...\n", pDrvCtrl->enableAdrs,
2, 3, 4, 5, 6);
/* Interrupt vector. */
tok = strtok_r (NULL, ":", &holder);
if (tok == NULL)
return ERROR;
pDrvCtrl->ivec = atoi (tok);
DRV_LOG (DRV_DEBUG_LOAD, "ivec : 0x%X ...\n", pDrvCtrl->ivec,
2, 3, 4, 5, 6);
/* Interrupt level. */
tok = strtok_r (NULL, ":", &holder);
if (tok == NULL)
return ERROR;
pDrvCtrl->ilevel = atoi (tok);
DRV_LOG (DRV_DEBUG_LOAD, "ilevel : 0x%X ...\n", pDrvCtrl->ilevel,
2, 3, 4, 5, 6);
/* Caller supplied alignment offset. */
tok = strtok_r (NULL, ":", &holder);
if (tok == NULL)
return ERROR;
pDrvCtrl->offset = atoi (tok);
DRV_LOG (DRV_DEBUG_LOAD, "Offset : 0x%X ...\n", pDrvCtrl->offset,
2, 3, 4, 5, 6);
/* Caller supplied cluster qty */
tok = strtok_r (NULL, ":", &holder);
if (tok == NULL)
return ERROR;
pDrvCtrl->clDesc.clNum = atoi (tok);
DRV_LOG (DRV_DEBUG_LOAD, "Cluster quantity : 0x%X ...\n", pDrvCtrl->clDesc.clNum,
2, 3, 4, 5, 6);
/* caller supplied flags */
tok = strtok_r (NULL, ":", &holder);
if (tok == NULL)
return ERROR;
pDrvCtrl->flags |= strtoul (tok, NULL, 16);
DRV_LOG (DRV_DEBUG_LOAD, "flags : 0x%X ...\n", pDrvCtrl->flags,
2, 3, 4, 5, 6);
DRV_LOG (DRV_DEBUG_LOAD, "auInitParse:... Parse load string done.\n", 1, 2, 3, 4, 5, 6);
return (OK);
}
/*******************************************************************************
*
* auMemInit - initialize memory.
*
* 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.
*/
LOCAL STATUS auMemInit
(
AU_DRV_CTRL * pDrvCtrl /* device to be initialized */
)
{
int i;
char * pRxMem;
char * pTxMem;
UINT32 rxSize;
UINT32 txSize;
UINT32 bufPtr;
/* Tx/Rx buffer base */
pDrvCtrl->rringSize = AU_N_RX_BUF;
pDrvCtrl->tringSize = AU_N_TX_BUF;
rxSize = pDrvCtrl->rringSize * ROUND_UP(AU_DMA_BUFSIZ, 32) + 32;
pRxMem = (char *) cacheDmaMalloc (rxSize);
txSize = pDrvCtrl->tringSize * ROUND_UP(AU_DMA_BUFSIZ, 32) + 32;
pTxMem = (char *) cacheDmaMalloc (txSize);
if ((pRxMem == NULL) || (pTxMem == NULL))
{
DRV_LOG(DRV_DEBUG_LOAD,
"auMemInit: System memory unavailable\n", 1, 2, 3, 4, 5, 6);
return (ERROR);
}
pDrvCtrl->pRxMemBase = pRxMem;
pDrvCtrl->pTxMemBase = pTxMem;
/* copy the DMA structure, Tx/Rx buffer pointers */
pDrvCtrl->cacheFuncs = cacheDmaFuncs;
bufPtr = (UINT32)pRxMem;
for (i = 0; i < pDrvCtrl->rringSize; ++i)
{
pDrvCtrl->pRxMem[i] = (char *)ROUND_UP(bufPtr, 32);
bufPtr += AU_DMA_BUFSIZ;
}
bufPtr = (UINT32)pTxMem;
for (i = 0; i < pDrvCtrl->tringSize; ++i)
{
pDrvCtrl->pTxMem[i] = (char *)ROUND_UP(bufPtr, 32);
bufPtr += AU_DMA_BUFSIZ;
}
/* allocate pool structure for mblks, clBlk, and clusters */
if ((pDrvCtrl->endObj.pNetPool = malloc (sizeof(NET_POOL))) == NULL)
return (ERROR);
/* number of clusters is passed in by the endLoadString
* pDrvCtrl->clDesc.clNum = pDrvCtrl->rringSize * 2;
*/
pDrvCtrl->mClCfg.clBlkNum = pDrvCtrl->clDesc.clNum;
pDrvCtrl->mClCfg.mBlkNum = pDrvCtrl->mClCfg.clBlkNum * 2;
/* total memory size for mBlks and clBlks */
pDrvCtrl->mClCfg.memSize =
(pDrvCtrl->mClCfg.mBlkNum * (MSIZE + sizeof (long))) +
(pDrvCtrl->mClCfg.clBlkNum * (CL_BLK_SZ + sizeof (long)));
/* total memory for mBlks and clBlks */
if ((pDrvCtrl->mClCfg.memArea =
(char *) memalign (sizeof(long), pDrvCtrl->mClCfg.memSize)) == NULL)
return (ERROR);
/* total memory size for all clusters */
pDrvCtrl->clDesc.clSize = AU_BUFSIZ;
pDrvCtrl->clDesc.memSize =
(pDrvCtrl->clDesc.clNum * (pDrvCtrl->clDesc.clSize + 8)) + sizeof(int);
/* Allocate cluster memory */
pDrvCtrl->clDesc.memArea = malloc (pDrvCtrl->clDesc.memSize);
if (pDrvCtrl->clDesc.memArea == NULL)
{
DRV_LOG(DRV_DEBUG_LOAD,
"auMemInit: System memory unavailable\n", 1, 2, 3, 4, 5, 6);
return (ERROR);
}
/* initialize the device net pool */
if (netPoolInit (pDrvCtrl->endObj.pNetPool, &pDrvCtrl->mClCfg,
&pDrvCtrl->clDesc, 1, NULL) == ERROR)
{
DRV_LOG (DRV_DEBUG_LOAD, "auMemInit: Could not init buffering\n",
1, 2, 3, 4, 5, 6);
return (ERROR);
}
/* Store the cluster pool id as others need it later. */
pDrvCtrl->pClPoolId = clPoolIdGet (pDrvCtrl->endObj.pNetPool,
AU_BUFSIZ, FALSE);
return (OK);
}
/***************************************************************************
*
* auMiiInit - initialize the chip to use the MII interface
*
* This routine initializes the chip to use the MII interface.
*
* RETURNS: OK, or ERROR
*/
LOCAL STATUS auMiiInit
(
AU_DRV_CTRL * pDrvCtrl /* pointer to DRV_CTRL structure */
)
{
DRV_LOG (DRV_DEBUG_MII, "auMiiInit...\n", 0, 0, 0, 0, 0, 0);
/* initialize some fields in the PHY info structure */
if (auPhyPreInit (pDrvCtrl) != OK)
{
DRV_LOG (DRV_DEBUG_LOAD, ("Failed to pre-initialize PHY\n"),
0, 0, 0, 0, 0, 0);
return (ERROR);
}
if (miiPhyInit (pDrvCtrl->pPhyInfo) != OK)
{
DRV_LOG (DRV_DEBUG_LOAD, "Failed to initialize PHY\n", 0,0,0,0,0,0);
return (ERROR);
}
/* deal with full duplex mode and speed */
if (pDrvCtrl->pPhyInfo->phyFlags & MII_PHY_FD)
{
AU_MAC_CONTROL |= AU_MAC_CONTROL_F;
SYS_WB_FLUSH();
DRV_LOG (DRV_DEBUG_LOAD, "In full duplex mode\n", 0,0,0,0,0,0);
}
else
{
DRV_LOG (DRV_DEBUG_LOAD, "In half duplex mode\n", 0,0,0,0,0,0);
}
if (pDrvCtrl->pPhyInfo->phyFlags & MII_PHY_100)
{
DRV_LOG (DRV_DEBUG_LOAD, "In 100Mbps mode\n", 0,0,0,0,0,0);
}
else
{
DRV_LOG (DRV_DEBUG_LOAD, "In 10Mbps mode\n", 0,0,0,0,0,0);
}
DRV_LOG (DRV_DEBUG_MII, "auMiiInit...done\n", 0, 0, 0, 0, 0, 0);
return (OK);
}
/***************************************************************************
*
* auPhyPreInit - initialize some fields in the phy info structure
*
* This routine initializes some fields in the phy info structure,
* for use of the phyInit() routine.
*
* RETURNS: OK, or ERROR if could not obtain memory.
*/
LOCAL STATUS auPhyPreInit
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -