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

📄 gei82543end.c

📁 intel 82543 千兆网卡 vxworks驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    UINT8        tmpBuf[ETHER_ADDRESS_SIZE]; /* array to save ETH addr */
    UINT16       hashVal;                    /* hash value for MTA */
    UINT32       lowAdr;                     /* adr low in RTA */
    UINT32       highAdr;                    /* adr high in RTA */

    DRV_LOG (DRV_DEBUG_IOCTL, ("gei82543AddrFilterSet...\n"), 0,0,0,0,0,0);

    /* clean up all multicasting address in RTA and MTA */
    gei82543McastAdrClean(pDrvCtrl);

    /* get the number of multicasting address */
    if ((count = pDrvCtrl->drvObj.nMulti) == 0)
    {
        return;
    }

    if (count > MAX_NUM_MULTI)
    {
        LOGMSG("only accept %d multicast address\n",MAX_NUM_MULTI,2,3,4,5,6);
        count =  MAX_NUM_MULTI;
    }

    /*
     * The first 15 multicast will stored in the RAT (RAL/RAH)
     * the rest are stored in MAT
     */

    pCurr = (ETHER_MULTI *)lstFirst(&(pDrvCtrl->drvObj.multiList));

    /* the first entry (i=0) in RAT is not for multicast addr */
    for (i = 1; i< NUM_RAR && count; i++, count--)
    {
        memcpy ((void * )tmpBuf, (const void *)pCurr->addr, ETHER_ADDRESS_SIZE);

        lowAdr = tmpBuf[0] | (tmpBuf[1] << 8) | (tmpBuf[2] << 16) |
                   (tmpBuf[3] << 24);

        highAdr = tmpBuf[4] | (tmpBuf[5] << 8);

        GEI_WRITE_REG((INTEL_82543GC_RAL + 8 *(UINT32)i), lowAdr);

        GEI_WRITE_REG((INTEL_82543GC_RAH +8 * (UINT32)i), (highAdr | RAH_AV_BIT));

        pCurr = END_MULTI_LST_NEXT(pCurr);
    }

    /* configure MTA table if more multicast address remaining */
    while (count--)
    {
        memcpy ((void *)tmpBuf, (const void *)pCurr->addr, ETHER_ADDRESS_SIZE);

        /*
         * compose hash value based on filter type :
         * MULTI_FILTER_TYPE_47_36: 47 - 36 bits for dest multicast addr match
         * MULTI_FILTER_TYPE_46_35: 46 - 35 bits for dest multicast addr match
         * MULTI_FILTER_TYPE_45_34: 45 - 34 bits for dest multicast addr match
         * MULTI_FILTER_TYPE_43_32: 43 - 32 bits for dest multicast addr match
         */

        if (pDrvCtrl->multiCastFilterType == MULTI_FILTER_TYPE_47_36)
        {
            hashVal = (tmpBuf[4] >> 4) | ((UINT16)(tmpBuf[5]) << 4);
        }

        else if (pDrvCtrl->multiCastFilterType == MULTI_FILTER_TYPE_46_35)
        {
            hashVal = (tmpBuf[4] >> 3) | ((UINT16)(tmpBuf[5]) << 5);
        }

        else if (pDrvCtrl->multiCastFilterType == MULTI_FILTER_TYPE_45_34)
        {
            hashVal = (tmpBuf[4] >> 2) | ((UINT16)(tmpBuf[5]) << 6 );
        }

        else if (pDrvCtrl->multiCastFilterType == MULTI_FILTER_TYPE_43_32)
        {
            hashVal = tmpBuf[4] | ((UINT16)(tmpBuf[5]) << 8 );
        }

        else
        {
            LOGMSG("Error in compose multicast hash value\n",1,2,3,4,5,6);
            return;
        }

        /* the first 5 bits is the bit location (32 maximum) in a register */
        col = hashVal & 0x1f;

        /* the remaining 7 bits is for the register offset (128 maximum) */
        row = (hashVal >> 5) & 0x7f;

        GEI_READ_REG((INTEL_82543GC_MTA + (UINT32)row * 32), (UINT32)tmp);/*lint !e63*/

        /* find the right bit location */
        tmp |= (1 << col);

        GEI_WRITE_REG((INTEL_82543GC_MTA +(UINT32)row * 32), (UINT32)tmp);

        pCurr = END_MULTI_LST_NEXT(pCurr);
     }

    taskDelay (sysClkRateGet() / 20);

    DRV_LOG (DRV_DEBUG_IOCTL,("gei82543AddrFilterSet...Done\n"), 0,0,0,0,0,0);

    return;
}

/*************************************************************************
*
* gei82543EndMCastAdd - add a multicast address for the device
*
* This routine adds a multicast address to whatever the driver
* is already listening for.  It then resets the address filter.
*
* RETURNS: OK or ERROR.
*/
 LOCAL STATUS  gei82543EndMCastAdd
    (
    END_DEVICE *   pDrvCtrl,       /* pointer to drvObject */
    char* pAddress         /* address you want to add to list */
    )
{
     int error;

    if ((error = etherMultiAdd (&pDrvCtrl->drvObj.multiList, pAddress)) ==
          ENETRESET)
    {
        pDrvCtrl->drvObj.nMulti++;

        if (pDrvCtrl->drvObj.nMulti  > MAX_NUM_MULTI)
        {
            pDrvCtrl->drvObj.nMulti--;

            etherMultiDel (&pDrvCtrl->drvObj.multiList,pAddress);

            return ERROR;
        }
        else
            gei82543AddrFilterSet(pDrvCtrl);
    }

    return (OK);
}

/*************************************************************************
*
* gei82543EndMCastDel - delete a multicast address for the device
*
* This routine removes a multicast address from whatever the driver
* is listening for.  It then resets the address filter.
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS gei82543EndMCastDel
    (
    END_DEVICE *     pDrvCtrl,        /* device pointer */
    char *           pAddress         /* address to be deleted */
    )
{

    int error;

    if ((error = etherMultiDel (&pDrvCtrl->drvObj.multiList,(char *)pAddress))
        == ENETRESET)
    {
        gei82543AddrFilterSet(pDrvCtrl);

        pDrvCtrl->drvObj.nMulti--;
    }

    return OK;
}

/*****************************************************************************
*
* gei82543EndMCastGet - get the multicast address list for the device
*
* This routine gets the multicast list of whatever the driver
* is already listening for.
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS gei82543EndMCastGet
    (
    END_DEVICE *    pDrvCtrl,        /* device pointer */
    MULTI_TABLE *   pTable            /* address table to be filled in */
    )
{
    return (etherMultiGet (&pDrvCtrl->drvObj.multiList, pTable));

}
/*************************************************************************
*
* gei82543EndStop - stop the device
*
* This function calls BSP functions to disconnect interrupts and stop
* the device from operating in interrupt mode.
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS gei82543EndStop
    (
    END_DEVICE *pDrvCtrl    /* device to be stopped */
    )
{
    /* check device attach flag */
    if (pDrvCtrl->attach != TRUE)
    {
        return ERROR;
        DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStop:Driver does not load successfully!\n", 1, 2,3, 4, 5, 6);
    }

    IF_DRV_TX_SEM_TAKE (&pDrvCtrl->drvObj, WAIT_FOREVER);
    /* check device start flag */
    if (pDrvCtrl->devStartFlag != TRUE)
    {
        DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStop:Driver has not been started!\n", 1, 2,3, 4, 5, 6);
        IF_DRV_TX_SEM_GIVE(&pDrvCtrl->drvObj);
        return OK;
    }

    /* turn off system interrupts */
    if(ERROR == b_pciUnitIntDisable((UINT8)pDrvCtrl->drvObj.slot))
    {
        DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStop:Could not disable interrupt!\n", 1, 2, 3, 4, 5, 6);
    }
    /* disable TX/RX operation */
    gei82543TxRxDisable (pDrvCtrl);

    /*disable 82543 chip interrupt*/
    gei82543DisableChipInt (pDrvCtrl);

    /*wait for rx interrupt handling*/
    while (pDrvCtrl->rxtxHandling)
    {
        DRV_LOG (DRV_DEBUG_LOAD,"gei82543EndStop:wait slot %d's Rx handler!\n", pDrvCtrl->drvObj.slot, 2, 3, 4, 5, 6);
        taskDelay(1);
    }

    /*mark the driver stop*/
    pDrvCtrl->devStartFlag = FALSE;
    DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStop:Driver stops successfully!\n", 1, 2, 3, 4, 5, 6);

    IF_DRV_TX_SEM_GIVE(&pDrvCtrl->drvObj);
    return OK;
}
/*************************************************************************
*
* gei82543EndUnload - 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 gei82543EndUnload
    (
    END_DEVICE* pDrvCtrl    /* device to be unloaded */
    )
{
    /* stop the device if not yet */
    if (pDrvCtrl->devStartFlag != FALSE)
    {
        gei82543EndStop (pDrvCtrl);
    }
    /*
     * netJob queue may still have some unfinished work for this device, so
     * inserting the "unload" function after those unfinished work.
     * Warning - It's not a good idea to place much burden on
     * tNetTask since it may be the only vehicle to pass packets (including
     * other interfaces) to the high layer.
     */

    if (netTaskId != ERROR && netTaskId != 0)
    {
        fwdJobAdd ((FUNCPTR)gei8254xNowUnload , (int)pDrvCtrl,
                   0,0,0,0);
    }
    else
        gei8254xNowUnload (pDrvCtrl);

    return OK;
}

/*******************************************************************
* gei8254xNowUnload - free memory when unload the device
*
* This function will free all memory allocated by this devices;
* It is called when gei82543EndUnload is involved
*
* RETURN: N/A
*/

LOCAL void gei8254xNowUnload
    (
    END_DEVICE* pDrvCtrl    /* device to be unloaded */
    )
{
    DRV_LOG (DRV_DEBUG_LOAD, ("gei82543Unload end....\n"), 1, 2, 3, 4, 5, 6);

    if (pDrvCtrl->drvObj.txSem !=(SEM_ID) NULL)
        semDelete (pDrvCtrl->drvObj.txSem);

    /* free allocated memory */
    pDrvCtrl->attach = FALSE;
    gei82543MemAllFree (pDrvCtrl);

    DRV_LOG (DRV_DEBUG_LOAD, ("gei82543Unload... Done\n"), 1, 2, 3, 4, 5, 6);

    return (void)OK;
}

/**************************************************************************
*
* gei82543TxSetup - configure and setup TX for running
*
* This routine sets up the data structure for TX and configures transmitter
*
* RETURNS: N/A
*/

LOCAL void gei82543TxSetup
    (
    END_DEVICE * pDrvCtrl    /* device to set up TX descriptors */
    )
{
    int ix;
    INTEL82543_TX_DES*  pTxDesc;
    UINT32 txdctlVal;    /* TXDCTL register value */
    UINT32 count;        /* temp var */
    UINT32 tmpAddr=0;
    char *  pEndBuf;
	
    /* initialization for TX operation*/
    pDrvCtrl->txDescTail  = 0;
    pDrvCtrl->txStall    = FALSE;
    pDrvCtrl->txDescFreeNum = (volatile UINT32 )pDrvCtrl->txDescNum - 1;
    pDrvCtrl->txDescLastCheck = (volatile UINT32 )pDrvCtrl->txDescNum - 1;

    /* pre-init the transmit buffer memory */
    for (ix = 0; ix < pDrvCtrl->txDescNum; ix++)
    {
        /*empty current DESC which packet have been sent out by MAC controller.*/
        pEndBuf = pDrvCtrl->pEndBufForMng[ix];
        if ((char *)NULL != pEndBuf)
        {
            DRV_LOG (DRV_DEBUG_LOAD, "gei82543TxSetup...Free TxBD!\n", 1, 2, 3, 4, 5, 6);
            endPktFree(pEndBuf);/* clean the tx buffer */
            pEndBuf=NULL;
            pDrvCtrl->pEndBufForMng[ix]=NULL;
            DRV_CHG_CNT(pDrvCtrl->txResFreeNum,1);      
        }
        /*get the txBDs pointer*/
        pTxDesc = (INTEL82543_TX_DES*)GEI_GET_TX_DESC_ADDR(ix);
        /* set up the command field */
        GEI_WRITE_DESC_BYTE(pTxDesc, TXDESC_CMD_OFFSET,
                              (TXD_CMD_EOP | TXD_CMD_IFCS |
                               TXD_CMD_IDE | TXD_CMD_RS));

        /* set DD bits in STATUS field */
        GEI_WRITE_DESC_BYTE(pTxDesc, TXDESC_STATUS_OFFSET, TXD_STAT_DD);
    }

    /* set the TX descriptor BASE register */
    tmpAddr= (UINT32)sysVirtToPhys((void *)(pDrvCtrl->pTxDescBase));
    GEI_WRITE_REG(INTEL_82543GC_TDBAL, tmpAddr);
    GEI_WRITE_RE

⌨️ 快捷键说明

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