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

📄 vxbufs.c

📁 基于vxworks操作系统,Tornado2.0平台,生成树STP源码.直接在其对应的设备中添加即可.
💻 C
📖 第 1 页 / 共 2 页
字号:
        /*
         * make sure entire ether_header + llc_hdr is in first M_BLK 
         * if not then copy the data to a temporary buffer 
         */
        if (pMblk->mBlkHdr.mLen < sizeof(LAN_FRAME_HEADER) +
            LLC_SNAP_FRAMELEN)
        {
            pLLCHdr = &llcHdr;
            if (netMblkOffsetToBufCopy (pMblk, sizeof(LAN_FRAME_HEADER), 
                                        (char *) pLLCHdr, etherType,
                                        (FUNCPTR) bcopy) < etherType)
            {
                return (A_ERROR);
            }
        } else {
            pLLCHdr = (struct llc *)((char *)pEnetHdr +
                                     sizeof(LAN_FRAME_HEADER));
        }
        /* Now it may be IP over 802.x so we check to see if the */
        /* destination SAP is IP, if so we snag the ethertype from the */
        /* proper place. */
        
        /* Now if it's NOT IP over 802.x then we just used the DSAP as */
        /* the etherType.  */

        if (pLLCHdr->llc_dsap == LLC_SNAP_LSAP) {
            etherType = ntohs(pLLCHdr->llc_un.type_snap.ether_type);
            pLinkHdrInfo->dataOffset = sizeof(LAN_FRAME_HEADER) + 8;
        } else if (isL2UF((A_UINT8 *)pLLCHdr)) {
            pLinkHdrInfo->dataOffset = 0; // No data in this frame
        } else { /* no SNAP header */
            etherType = pLLCHdr->llc_dsap;
            pLinkHdrInfo->dataOffset = sizeof(LAN_FRAME_HEADER) + 3;
        }
    } else {
        pLinkHdrInfo->dataOffset        = sizeof(LAN_FRAME_HEADER);
    }
    pLinkHdrInfo->pktType               = etherType;

    return (A_OK);
}

/**************************************************************************
* hwAllocatePhysBuffer - allocate a physically contiguous buffer
*
* This routine will create a physically contiguous buffer and get
* the virtual and physical address of it.
*
* RETURNS: A_OK if got buffer, A_ERROR otherwise
*/
A_STATUS
hwAllocatePhysBuffer(WLAN_DEV_INFO *pdevInfo,
                     A_UINT16 buffSize,         /* size to create */
                     A_UINT32 *pPhysAddress,    /* return physical address */
                     void **ppVirtAddress,      /* return virtual address */
                     CL_BLK_ID *ppOSDescPtr)    /* return OS desc address */
{
    NET_POOL_ID pNetPoolId;             /* pointer to the net pool */
    CL_POOL_ID  pClPoolId;              /* pointer to the cluster pool */
    CL_BLK_ID   pClBlk;                 /* pointer to the CLBlk */

    /* Get the net Pool ID */
    pNetPoolId = pdevInfo->pNetPool;

    /* Get the cluster pool ID */
    if ((pClPoolId = netClPoolIdGet(pNetPoolId, buffSize, FALSE)) == NULL) {
        /* this shouldn't fail generally; the latter fails when the
         * pool is empty
         */
        uiPrintf("\nnetClPoolIdGet error!\n");
        return A_NO_MEMORY;
    }

    /* Get the cluster */
    if ((*ppVirtAddress = netClusterGet(pNetPoolId, pClPoolId)) == NULL) {
        return A_NO_MEMORY;
    }

    *pPhysAddress = (A_UINT32)A_DATA_V2P(*ppVirtAddress);

    /* For VxWorks, the os descriptor is the ClBlk */
    if ((pClBlk = netClBlkGet(pNetPoolId, M_DONTWAIT)) == NULL) {
        uiPrintf("\nClBlk reserve error!\n");
        netClFree(pNetPoolId, *ppVirtAddress);
        return A_NO_MEMORY;
    }

    /* join the cluster with the clBlk */
    if ((*ppOSDescPtr = netClBlkJoin(pClBlk, *ppVirtAddress, buffSize, NULL,
                                     0, 0, 0)) == NULL)
    {
        uiPrintf("\nClBLK join error!\n");
        netClFree(pNetPoolId, *ppVirtAddress);
        netClBlkFree(pNetPoolId, pClBlk);
        return A_NO_MEMORY;
    }

    return A_OK;
}

/**************************************************************************
* hwFreePhysBuffer - free the physically contiguous buffer
*
* This routine will free the physically contiguous buffer previously
* allocated by hwAllocatePhysBuffer()
*
* RETURNS: N/A
*/
void
hwFreePhysBuffer(WLAN_DEV_INFO *pdevInfo, void *pVirtAddress,
                 CL_BLK_ID pOSDescPtr)
{
    NET_POOL_ID pNetPoolId;

    /* get the net Pool ID */
    pNetPoolId = pOSDescPtr->pNetPool;

    /* free the cluster */
    netClBlkFree(pNetPoolId, pOSDescPtr);

    return;
}


/**************************************************************************
* Ideally these are system utilities and do not belong in this
* file - but we don't have another file!
*/

LOCAL void
vxDelayedExecISR(DELAYED_EXEC_RECORD *pRecord)
{
    pRecord->func(pRecord->pdevInfo);
    wdDelete(pRecord->wdog);
    A_DRIVER_FREE(pRecord, sizeof(DELAYED_EXEC_RECORD));
}

A_STATUS
vxDelayedExec(WLAN_DEV_INFO* pdevInfo, A_UINT32 delay,
              void (*func)(WLAN_DEV_INFO *))
{
    DELAYED_EXEC_RECORD *pRecord;

    pRecord = (DELAYED_EXEC_RECORD *) A_DRIVER_MALLOC(sizeof(*pRecord));
    if (!pRecord) {
        return A_ERROR;
    }

    pRecord->func     = func;
    pRecord->pdevInfo = pdevInfo;
    pRecord->wdog     = wdCreate();
    if (!pRecord->wdog) {
        A_DRIVER_FREE(pRecord, sizeof(DELAYED_EXEC_RECORD));
        return A_ERROR;
    }

    delay = (delay * sysClkRateGet()) >> 10;
    if (wdStart(pRecord->wdog, delay,
                (FUNCPTR)vxDelayedExecISR, (int)pRecord) == ERROR)
    {
        wdDelete(pRecord->wdog);
        A_DRIVER_FREE(pRecord, sizeof(DELAYED_EXEC_RECORD));
        return A_ERROR;
    }

    return OK;
}

/**************************************************************************
* timer routines, os dependent
*
*/

LOCAL void
drvVxTimerHandler(timer_t timerId, int arg)
{
    A_TIMER *pTimer = (A_TIMER *)arg;
    
    ASSERT(pTimer);
    ASSERT(pTimer->pFunc);
    
    pTimer->pFunc((void *)pTimer->param);
}

/* drvVxTimerInit - Initialize Atheros timer in vxWorks environment
 * This function stores parameters in the Atheros timer object and
 * and initializes vxWorks timer object part of Atheros timer using
 * vxWorks call.
 * Called by A_TIMER_INIT() macro.
 */
A_STATUS
drvVxTimerInit(
    WLAN_DEV_INFO   *pDevInfo,
    A_TIMER         *pTimer,    /* Pointer to timer object */
    void            *pFunc,     /* timer function */
    A_BOOL          repeat)     /* 0 if one shot timer, 1 if periodic */
{

    pTimer->pdevInfo   = pDevInfo;
    pTimer->pFunc      = pFunc;
    pTimer->repeat     = repeat;
    pTimer->state      = FALSE;
    

    /* Init a timer in vxWorks */
    if (timer_create(CLOCK_REALTIME, NULL, (timer_t *)&pTimer->osTimerObj) !=
        A_OK)
    {
        uiPrintf("Timer allocate fails!\n");
        return A_ERROR;
    }

    if (timer_connect((timer_t)pTimer->osTimerObj, (VOIDFUNCPTR)drvVxTimerHandler,
                      (int)pTimer) != A_OK)
    {
        uiPrintf("Timer binding fails!\n");
        return A_ERROR;
    }
    return A_OK;
}

/* drvVxTimerSet - Fire off the timer that is already initialized.
 * This function stores timer parameter in the fixed location in the
 * timer object and sets the vx timer with given timeout period value.
 * Called by A_TIMEOUT() macro.
 */
A_STATUS
drvVxTimerSet(A_TIMER *pTimer, A_UINT32 timeVal,
              A_UINT32 param, A_UINT32 oper)
{
    struct itimerspec timerValue;
    A_UINT32          tv_sec = 0, tv_msec = timeVal;

    if (timeVal > 1000) {
        tv_sec = timeVal/1000;
        tv_msec = timeVal - tv_sec * 1000;
    }

    pTimer->param     = param;
    pTimer->operation = oper;
    pTimer->timeVal   = timeVal;
    pTimer->state     = FALSE;
    timerValue.it_value.tv_sec      = tv_sec;
    timerValue.it_value.tv_nsec     = tv_msec*1000*1000;
    timerValue.it_interval.tv_sec   = 0;

    if (pTimer->osTimerObj == NULL) {
        return A_ERROR;
    }

    if (pTimer->repeat) {
        timerValue.it_interval.tv_sec = tv_sec;
        timerValue.it_interval.tv_nsec = tv_msec*1000*1000;
        timer_settime((timer_t)pTimer->osTimerObj, 0,
                      &timerValue, NULL);
    } else {
        timerValue.it_interval.tv_nsec = 0;
        timer_settime((timer_t)pTimer->osTimerObj, 0,
                      &timerValue, NULL);
    }

    return A_OK;
}

/* drvVxTimerCancel - This function cancels a timer that is already
 * fired off. It doesn't know if the timer has expired, it cancels the timeout
 * anyway.
 * Called by A_UNTIMEOUT() macro.
 */
A_BOOL
drvVxTimerCancel(A_TIMER *pTimer)
{
    A_BOOL cancelled = FALSE;

    ASSERT(pTimer);

    if (pTimer->osTimerObj && pTimer->state == FALSE) {
        if (timer_cancel((timer_t)pTimer->osTimerObj) == A_OK) {
            cancelled = TRUE;
        }
    }
    
    pTimer->operation = INVALID_TIMEOUT;

    return cancelled;
}

/* drvVxTimerDelete - This function deletes a timer.
 * It doesn't know if the timer has expired, it cancels the timeout
 * anyway.
 * Called by A_DELETE_TIMER() macro.
 */
A_STATUS
drvVxTimerDelete(A_TIMER *pTimer)
{
    A_BOOL cancelled = FALSE;

    if (pTimer && pTimer->osTimerObj) {
        if (pTimer->state == FALSE) {
            if (timer_delete((timer_t)pTimer->osTimerObj) == A_OK) {
                cancelled     = TRUE;
                pTimer->state = TRUE;
            }
        }

        /* delete the object now. */
        pTimer->osTimerObj = NULL;
    }
    
    return A_OK;
}




⌨️ 快捷键说明

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