⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 auend.c

📁 au1500开发的应用程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    };

/******************************************************************************
*
* 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 + -