?? vxbufs.c
字號:
/*
* 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 + -