ixethaccend.c

来自「ixEthAccEnd END network interface driver」· C语言 代码 · 共 1,681 行 · 第 1/4 页

C
1,681
字号
    IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "Loading IxEthAccEnd...\n", 1, 2, 3, 4, 5, 6);    /* VxWorks needs the device name on the first call */    if (initString[0] == '\0')        {        bcopy("ixe", initString, 4);        IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD,"Returning the ixp425 Ethernet device name string..\n",0,0,0,0,0,0);        return(END_OBJ *) OK;        }    /* allocate the device structure */    pDrvCtrl = (END_DEVICE *)calloc (sizeof (END_DEVICE), 1);    if (pDrvCtrl == NULL)        goto errorExit;    /* parse the init string, filling in the device structure */    if (ixEthAccEndParse (pDrvCtrl, initString) == ERROR)        goto errorExit;    /* Capture pDrvCtrl */    ixEthAccpDrvCtrl[pDrvCtrl->unit] = pDrvCtrl;    /* Point to the top of the list */    pDrvCtrl->recNext = pDrvCtrl->recBufList;    /* Link the buffers */    for ( index = 0, rBufList = pDrvCtrl->recBufList; index < MAX_IX_ETH_ACC_REC_BUF; index++)        {        rBufList++;        pDrvCtrl->recBufList[index].ix_rec_next = rBufList;        }    pDrvCtrl->recBufList[MAX_IX_ETH_ACC_REC_BUF - 1].ix_rec_next = pDrvCtrl->recBufList;    /* Make sure the Intel Ethernet Engine's are initialized */    if ( !ixdp425EthLibInitialised )        if ( ixdp425EthLibInit() != IX_SUCCESS )            {            logMsg("ixdp425EthLibInit Failed\n",1,2,3,4,5,6);            goto errorExit;            }    /* Init the eth port */    if ( ixdp425EthPhysInit(pDrvCtrl->unit) != IX_SUCCESS )        {        logMsg("ixdp425EthPhysInit( %d ) Failed\n", pDrvCtrl->unit,2,3,4,5,6);        goto errorExit;        }    /* Ask the BSP to provide the ethernet address. */    /* This comes after ixdp425EthPhysInit */    SYS_ENET_ADDR_GET(pDrvCtrl);    /* initialize the END and MIB2 parts of the structure */    /*     * The M2 element must come from m2Lib.h     * This IxEthAccEnd is set up for a DIX type ethernet device.     */    if (END_OBJ_INIT (&pDrvCtrl->end, (DEV_OBJ *)pDrvCtrl, "ixe",                      pDrvCtrl->unit, &ixEthAccEndFuncTable,                      "END IXP425 IxEthAccEnd 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 (ixEthAccEndMemInit (pDrvCtrl) == ERROR)        goto errorExit;    /* reset and reconfigure the device */    ixEthAccEndReset (pDrvCtrl);    ixEthAccEndConfig (pDrvCtrl);    /* set the flags to indicate readiness */#ifdef IXEETHACC_MULTICAST_ENABLE    END_OBJ_READY (&pDrvCtrl->end,                   IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST                   | IFF_MULTICAST);#else    END_OBJ_READY (&pDrvCtrl->end,                   IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST);#endif    IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "Done loading IxEthAccEnd...", 1, 2, 3, 4, 5, 6);    return(&pDrvCtrl->end);    errorExit:    if (pDrvCtrl != NULL)        {        if ( pDrvCtrl->recBufList != NULL )            free ( pDrvCtrl->recBufList );        free ((char *)pDrvCtrl);        }    logMsg("IxEthAccEndLoad Failed\n", 1, 2, 3, 4, 5, 6);    return NULL;}/********************************************************************************* ixEthAccEndParse - parse the init string** Parse the input string.  Fill in values in the driver control structure.** The muxLib.o module automatically prepends the unit number to the user's* initialization string from the BSP (configNet.h).** .IP <unit>* Device unit number, a small integer.* .IP <vecNum>* Interrupt vector number (used with sysIntConnect)* .IP <intLvl>* Interrupt level* .LP** RETURNS: OK or ERROR for invalid arguments.*/STATUS ixEthAccEndParse(END_DEVICE * pDrvCtrl,  /* device pointer */char * initString       /* information string */){    char*   tok;    char*   pHolder = NULL;    /* Parse the initString */    /* Unit number. (from muxLib.o) */    tok = strtok_r (initString, ":", &pHolder);    if (tok == NULL)        return ERROR;    pDrvCtrl->unit = atoi (tok);    IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "Parsed unit number %d\n",pDrvCtrl->unit , 2, 3, 4, 5, 6);    /* Interrupt vector. */#if 0    tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL)        return ERROR;    pDrvCtrl->ivec = atoi (tok);    /* Interrupt level. */    tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL)        return ERROR;    pDrvCtrl->ilevel = atoi (tok);#else    pDrvCtrl->ivec = 0;    pDrvCtrl->ilevel = 0;#endif    IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "Processed all arguments\n", 1, 2, 3, 4, 5, 6);    return OK;}/********************************************************************************* ixEthAccEndMemInit - initialize memory for the chip** This routine is highly specific to the device.** RETURNS: OK or ERROR.*/STATUS ixEthAccEndMemInit(END_DEVICE * pDrvCtrl   /* device to be initialized */){    IxEthAccStatus result;    M_CL_CONFIG IxEthAccEndMclBlkConfig;   /* network mbuf configuration table */    int count;    int IxEthAccEndClDescTblNumEnt = (NELEMENTS(IxEthAccEndClDescTbl));    /*     * This is how we would set up and END ETHERMTU + IXP_EH_SIZE using netBufLib(1).     * This code is pretty generic.     */    if ((pDrvCtrl->end.pNetPool = malloc (sizeof(NET_POOL))) == NULL)        return(ERROR);    IxEthAccEndMclBlkConfig.mBlkNum = IXETHACC_MBLKS; /* Number of allocated mBlks per IxEth */    IxEthAccEndClDescTbl[0].clNum = IXETHACC_CLSTS;   /* Number of allocated cLists per IxEth */    IxEthAccEndMclBlkConfig.clBlkNum = IxEthAccEndClDescTbl[0].clNum;    /* Calculate the total memory for all the M-Blks and CL-Blks. */    IxEthAccEndMclBlkConfig.memSize = (IxEthAccEndMclBlkConfig.mBlkNum *                                       (MSIZE + sizeof (long))) +                                      (IxEthAccEndMclBlkConfig.clBlkNum *                                       (CL_BLK_SZ + sizeof(long)));#ifdef IXE_CACHED_BUFFERS_ENABLE    IxEthAccEndMclBlkConfig.memArea = (char *) memalign ( _CACHE_ALIGN_SIZE, IxEthAccEndMclBlkConfig.memSize );#else    /* Allocate the memory for the buffers from cache safe memory. */    IxEthAccEndMclBlkConfig.memArea = (char *) cacheDmaMalloc ( IxEthAccEndMclBlkConfig.memSize);#endif /* IXE_CACHED_BUFFERS_ENABLE */    if (IxEthAccEndMclBlkConfig.memArea == NULL)        {        IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "system memory unavailable\n",                 1, 2, 3, 4, 5, 6);        return(ERROR);        }    /* Calculate the memory size of all the clusters. */    IxEthAccEndClDescTbl[0].memSize = (IxEthAccEndClDescTbl[0].clNum *                                        (IxEthAccEndClDescTbl[0].clSize + 8)) + sizeof(int);#ifdef IXE_CACHED_BUFFERS_ENABLE    IxEthAccEndClDescTbl[0].memArea = (char *) memalign ( _CACHE_ALIGN_SIZE, IxEthAccEndClDescTbl[0].memSize );#else    /* Allocate the memory for the clusters from cache safe memory. */    IxEthAccEndClDescTbl[0].memArea = (char *) cacheDmaMalloc (IxEthAccEndClDescTbl[0].memSize);#endif /* IXE_CACHED_BUFFERS_ENABLE */    if (IxEthAccEndClDescTbl[0].memArea == NULL)        {        IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "system memory unavailable\n",                 1, 2, 3, 4, 5, 6);        return(ERROR);        }    IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD,                "\nIxEthAccEndClDescTbl[0].memArea : start:0x%08X End:0x%08X\n",                (int)IxEthAccEndClDescTbl[0].memArea,                (int)IxEthAccEndClDescTbl[0].memArea + IxEthAccEndClDescTbl[0].memSize,                3, 4, 5, 6);    /* Initialize the memory pool. */    if (netPoolInit(pDrvCtrl->end.pNetPool, &IxEthAccEndMclBlkConfig,                    &IxEthAccEndClDescTbl[0], IxEthAccEndClDescTblNumEnt,                    NULL) == ERROR)        {        IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "Could not init buffering\n",                 1, 2, 3, 4, 5, 6);        return(ERROR);        }    /*     * If you need clusters to store received packets into then get them     * here ahead of time.     */    if ((pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->end.pNetPool,                                               IX_ETHACC_RX_MBUF_MIN_SIZE, FALSE))        == NULL)        return(ERROR);    IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD             , "Loading Rx buffers: Unit: %d , num buffs: [%d]  NetPooId: 0x%08X ClPoolId: 0x%08X\n"             ,pDrvCtrl->unit,IxEthAccEndClDescTbl[0].clNum , (int)pDrvCtrl->end.pNetPool, (int)pDrvCtrl->pClPoolId, 5, 6);    /* Provision the NPE with receive buffers */    /* The number of cblk/mblk pairs allocated for NPE */    pDrvCtrl->rxBufsAlloc = (IxEthAccEndClDescTbl[0].clNum - 8);    for ( count = 0; count < pDrvCtrl->rxBufsAlloc ; count++ )        {        M_BLK_ID  pMblk;        if ((pMblk = netTupleGet(pDrvCtrl->end.pNetPool,                                    IX_ETHACC_RX_MBUF_MIN_SIZE,                                    M_DONTWAIT,                                    MT_HEADER,                                    FALSE ))            == NULL)            {            IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "Could not get a buffer [%d]\n",                     count, 2, 3, 4, 5, 6);            return(ERROR);            }        IXP_DRV_LOG (IXP_DRV_DEBUG_BUFINIT, "Rx Buff unit[%d]: mBlk: 0x%08X Buff: 0x%08X\n",                 pDrvCtrl->unit, (int)pMblk, (int)pMblk->m_data, 4, 5, 6);#ifdef IXE_CACHED_BUFFERS_ENABLE        /* Flush the buffer */        IXP425_END_CACHE_FLUSH(pMblk->m_data, IX_ETHACC_RX_MBUF_MIN_SIZE);#endif /* IXE_CACHED_BUFFERS_ENABLE */        /* Force Quad align for Ip packet */        pMblk->m_data += 2;        pMblk->m_len = IX_ETHACC_RX_MBUF_MIN_SIZE;        pMblk->m_next = NULL;#ifdef IXE_CACHED_BUFFERS_ENABLE        /* Flush the header */        IXP425_END_CACHE_FLUSH(pMblk,sizeof(M_BLK));#endif /* IXE_CACHED_BUFFERS_ENABLE */        result = ixEthAccPortRxFreeReplenish    ( pDrvCtrl->unit, pMblk);        if ( result != IX_ETH_ACC_SUCCESS)            {            /* Free buffer back */            netMblkClChainFree (pMblk);            IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD,"Error:Registering IxEthAcc Rx Callbacks Port[%d]\n",pDrvCtrl->unit,2,3,4,5,6);            return(ERROR);            }        }    pDrvCtrl->rxBufsActive = count;     /* The number of cblk/mblk pairs allocated for NPE */    IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "Memory setup complete\n", 1, 2, 3, 4, 5, 6);#ifdef IXP_DRV_DEBUG    /* allow log messages to print */    taskDelay(240);#endif    return OK;}/********************************************************************************* ixEthAccEndStart - 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 ixEthAccEndStart(END_OBJ * pDrv  /* device ID */){    IxEthAccStatus result;    END_DEVICE *pDrvCtrl = (END_DEVICE *)pDrv;    /*     * Register Tx Done Callback     */    IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD,"Registering IxEthAcc Callbacks Port[%d]\n",pDrvCtrl->unit,2,3,4,5,6);    result = ixEthAccPortTxDoneCallbackRegister( pDrvCtrl->unit,                                                 ixEthAccEndTxDoneCallback,                                                 (UINT32) pDrv);    if ( result != IX_ETH_ACC_SUCCESS)        {        IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD,"Error:Registering IxEthAcc Tx Callbacks Port[%d]\n",pDrvCtrl->unit,2,3,4,5,6);        return(ERROR);        }    /*     * Now register Rx Done Callback     */    result = ixEthAccPortRxCallbackRegister( pDrvCtrl->unit,                                             (IxEthAccPortRxCallback) ixEthAccEndRxCallback,                                             (UINT32) pDrv);        if ( result != IX_ETH_ACC_SUCCESS)        {        IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD,"Error:Registering IxEthAcc Rx Callbacks Port[%d]\n",pDrvCtrl->unit,2,3,4,5,6);        return(ERROR);        }    IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD,"Enable IxEthAcc Port[%d]\n",pDrvCtrl->unit,2,3,4,5,6);    result = ixEthAccPortEnable(pDrvCtrl->unit);    if ( result != IX_ETH_ACC_SUCCESS)        {        IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD,"Error:Enabling IxEthAcc Port[%d]\n",pDrvCtrl->unit,2,3,4,5,6);        return(ERROR);        }    END_FLAGS_SET (&pDrvCtrl->end, (IFF_UP | IFF_RUNNING));    return(OK);}/********************************************************************************* ixEthAccEndPacketGet - get next received message** Get next received message.  Returns NULL if none are* ready.** RETURNS: ptr to next packet, or NULL if none ready.*/char* ixEthAccEndPacketGet(

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?