?? vxbufs.c
字號(hào):
/*
* Copyright (c) 2000-2002 Atheros Communications, Inc., All Rights Reserved
*
* $Id: //depot/sw/releases/4.0/src/ap/vxbufs.c#3 $
*
* This module implements the conversion between mBlk and Atheros descriptors
* functions.
*
* mBlk are specially designed for VxWorks. It is defined as a structure of
* clusters.
*
* typedef struct mBlk {
* M_BLK_HDR mBlkHdr; // header
* M_PKT_HDR mBlkPktHdr; // pkthdr
* CL_BLK *pClBLK; // pointer to cluster blk
* } M_BLK;
*
* // header at beginning of each mBlk
*
* typedef struct mHdr {
* struct mBlk *mNext; // next buffer in chain
* struct mBlk *mNextPkt; // next chain in queue/record
* char *mData; // location of data
* int mLen; // amount of data in this mBlk
* UCHAR mType; // type of data in this mBlk
* UCHAR mFlags; // flags; see below
* USHORT reserved;
* } M_BLK_HDR;
*
* record/packet header in first mBlk of chain; valid if M_PKTHDR set
*
* typedef struct pktHdr {
* struct ifnet *rcvif; // rcv interface
* int len; // total packet length
* } M_PKT_HDR;
*
* description of external storage mapped into mBlk, valid if M_EXT set
*
* typedef struct clBlk {
* CL_BLK_LIST clNode; // union of next clBlk, buffer ptr
* UINT clSize; // cluster size
* int clRefCnt; // reference count of the cluster
* FUNCPTR pClFreeRtn; // pointer to cluster free routine
* int clFreeArg1; // free routine arg 1
* int clFreeArg2; // free routine arg 2
* int clFreeArg3; // free routine arg 3
* struct netPool *pNetPool; // pointer to the netPool
* } CL_BLK;
*
* The Atheros descriptors, ATHEROS_DESC, is a combination of the MAC
* hardware DMA descriptor and software only fields.
*
* The header and frame body are put into separate descriptors. Chances are the
* header will always be a contingous physical buffer and the frame body may
* occupy serveral smaller physical buffers.
*
* All clusters are allocated as received buffers for the incoming data.
*
* The MBlk and Atheros structures are the different way of the link for
* the input data buffers.
*
* To convert Atheros Descriptors to mBlk structures: XXX
*
* To convert mBlk structures to Atheros Descriptors: XXX
*
*/
#include "vxbufs.h"
#include "stdlib.h"
#include "netBufLib.h"
#include "private\timerLibP.h"
#include "wlandrv.h"
#include "wlanext.h"
#include "wlansmeext.h"
#include "wlanSend.h"
#include "apdefs.h"
#include "halApi.h"
#include "ui.h"
#define IS_ETHERTYPE(_typeOrLen) ((_typeOrLen) >= 0x0600)
int vxDescNoMblk;
/*******************************************************************************
*
* vxDescToMBlk - converts Atheros Descriptors to VxWorks mBlk structures
*
* The input data from MAC has to be put into clusters directly. The clusters
* are reserved for the receive function during initialization phase by calling
* netClusterGet(). And the receive descriptors are pre-allocated and built up
* using clusters.
* After the incoming frame is received and put into the descriptor, i.e. cluster
* Then the clusters are linked using Mblk structures chain and passed to the
* protocol or DSM layer.
*
* the input descriptor is kept for DS purpose. The calling part should free the
* input descriptor when it is no longer needed or error condition
*
*
* RETURNS: NULL if unsuccesful
* pointer of mBlk structures if successful
*/
M_BLK*
vxDescToMblk(WLAN_DEV_INFO *pdevInfo, ATHEROS_DESC *pDesc, A_BOOL dup)
{
NET_POOL_ID pNetPool = pdevInfo->pNetPool;
ATHEROS_DESC *pCurrDesc;
M_BLK *pMblk = NULL;
M_BLK *pPrevMblk = NULL;
M_BLK *pVarMblk, *pAllocMblk;
ATHEROS_DESC *pHeadDesc = NULL;
pHeadDesc = pDesc;
/* any field can we use to check the integrity of descriptor ??? */
while (pDesc != NULL) {
/* reserve a Mblk */
if ( (pAllocMblk = netMblkGet(pNetPool, M_DONTWAIT, MT_DATA)) == NULL ) {
/* ran out of mblks, a receive resource => loaned resources aren't
* being returned in time; slow ethernet? slow stack?
*/
LOG_DROP_FRAME(pdevInfo, rx);
if (pMblk != NULL) {
netMblkClChainFree(pMblk);
}
++vxDescNoMblk;
freeBuffandDescChain(pdevInfo, dup ? pHeadDesc : pDesc);
return NULL;
}
/* join Mblk */
if ((pVarMblk = netMblkClJoin(pAllocMblk, pDesc->pOSDescPtr)) == NULL ) {
/* generally shouldn't happen */
uiPrintf("\nvxDescToMblk: error in join mBlk\n");
netMblkFree(pNetPool, pAllocMblk);
if (pMblk != NULL) {
netMblkClChainFree(pMblk);
}
freeBuffandDescChain(pdevInfo, dup ? pHeadDesc : pDesc);
return NULL;
}
/* assign the first M_BLK */
if (pMblk == NULL) {
pMblk = pVarMblk;
pMblk->mBlkHdr.mFlags |= M_PKTHDR;
pMblk->mBlkPktHdr.len = 0;
}
ASSERT((void *)A_DATA_P2V(pDesc->bufferPhysPtr) == pDesc->pBufferVirtPtr.ptr);
pVarMblk->mBlkHdr.mNext = NULL;
pVarMblk->mBlkHdr.mNextPkt = NULL;
pVarMblk->mBlkHdr.mData = pDesc->pBufferVirtPtr.byte;
pVarMblk->mBlkHdr.mLen = pDesc->hw.txControl.bufferLength;
/* calculate the total length of the frame */
pMblk->mBlkPktHdr.len += pVarMblk->mBlkHdr.mLen;
/* get the previous mblk in the chain */
if (pPrevMblk != NULL) {
pPrevMblk->mBlkHdr.mNext = pVarMblk;
}
/* next descriptor */
pCurrDesc = pDesc;
pDesc = pDesc->pNextVirtPtr;
pPrevMblk = pVarMblk;
/* free the current descriptor */
if (dup) {
pCurrDesc->pOSDescPtr->clRefCnt += 1;
} else {
memFreeDescriptor(pdevInfo, pCurrDesc);
}
}
return pMblk;
}
/*******************************************************************************
*
* vxMblkToDesc - converts VxWorks mBlk structures to Atheros Descriptors
*
* This routine allocates a descriptor to put the 802.3 header in it and then
* walk through all the strucures to link the data. this routine could be part
* of the driver sending routine
*
* The calling routine is responsible for the releasing of input mBlk due to DS
*
* Ref: Tornado BSP Developer's kit for VxWorks pp 366
*
* RETURNS: NULL if unsuccesful
* pointer of Atheros Descriptors if successful
*/
ATHEROS_DESC*
vxMblkToDesc(WLAN_DEV_INFO* pdevInfo, M_BLK* pHeadMblk)
{
ATHEROS_DESC *pHeadDesc = NULL;
ATHEROS_DESC *pLastDesc = NULL;
ATHEROS_DESC *pDesc;
M_BLK *pMblk;
/* verify the first MBLK contains the header */
if ((pHeadMblk->mBlkHdr.mFlags & M_PKTHDR) != M_PKTHDR) {
uiPrintf("vxMblkToDesc: M_PKTHDR not set on first mblk\n");
netMblkClChainFree(pHeadMblk);
return NULL;
}
/* generate a descriptor for each of the Mblk */
for (pMblk = pHeadMblk; pMblk; pMblk = pMblk->mBlkHdr.mNext) {
/* vxWorks protocol stack is known to send empty mblks */
if (pMblk->mBlkHdr.mLen == 0) {
continue;
}
/* allocate a descriptor for Mblk, i.e. frame data */
pDesc = memAllocateDescriptor(pdevInfo);
if (!pDesc) {
/* clean up before leaving */
freeBuffandDescChain(pdevInfo, pHeadDesc);
netMblkClChainFree(pHeadMblk);
LOG_DROP_FRAME(pdevInfo, tx);
return NULL;
}
/* Initialize the fields of descriptor */
pDesc->pOSDescPtr = pMblk->pClBlk;
pDesc->pBufferVirtPtr.ptr = pMblk->mBlkHdr.mData;
pDesc->bufferPhysPtr = (A_UINT32)A_DATA_V2P(pDesc->pBufferVirtPtr.ptr);
pDesc->pOrigBufferVirtPtr = pDesc->pOSDescPtr->clNode.pClBuf;
pDesc->pOrigbufferPhysPtr = (A_UINT32)A_DATA_V2P(pDesc->pOrigBufferVirtPtr);
pDesc->hw.txControl.bufferLength = pMblk->mBlkHdr.mLen;
pDesc->pOSDescPtr->clRefCnt += 1;
if (pHeadDesc) {
/* Link to last descriptor */
ASSERT(pLastDesc);
pLastDesc->nextPhysPtr = pDesc->thisPhysPtr;
pLastDesc->pNextVirtPtr = pDesc;
pLastDesc->hw.txControl.more = 1;
} else {
pHeadDesc = pDesc;
pHeadDesc->hw.txControl.frameLength = pMblk->mBlkPktHdr.len;
}
pLastDesc = pDesc;
}
netMblkClChainFree(pHeadMblk);
return pHeadDesc;
}
/******************************************************************************
*
* wlanPacketDataGet - return the beginning of the packet data
*
* This routine fills the given <pLinkHdrInfo> with the appropriate offsets.
* We call this in the MUX, only after decapsulation from dot11 to to 802.3
* or DIX.
*
* RETURNS: OK or ERROR.
*/
A_STATUS
wlanPacketDataGet(M_BLK_ID pMblk, LL_HDR_INFO *pLinkHdrInfo)
{
LAN_FRAME_HEADER *pEnetHdr;
LAN_FRAME_HEADER enetHdr;
struct llc * pLLCHdr;
struct llc llcHdr;
A_UINT16 etherType;
pLinkHdrInfo->destAddrOffset = 0;
pLinkHdrInfo->destSize = 6;
pLinkHdrInfo->srcAddrOffset = 6;
pLinkHdrInfo->srcSize = 6;
/* Try for RFC 894 first as it's the most common. */
/*
* make sure entire ether_header is in first M_BLK
* if not then copy the data to a temporary buffer
*/
if (pMblk->mBlkHdr.mLen < sizeof(LAN_FRAME_HEADER)) {
pEnetHdr = &enetHdr;
if (netMblkOffsetToBufCopy (pMblk, 0, (char *) pEnetHdr,
sizeof(LAN_FRAME_HEADER), (FUNCPTR) bcopy)
< sizeof(LAN_FRAME_HEADER))
{
return (ERROR);
}
} else {
pEnetHdr = (LAN_FRAME_HEADER *)pMblk->mBlkHdr.mData;
}
etherType = be2cpu16(pEnetHdr->lanTypeOrLen);
/* Deal with 802.3 addressing. */
/* Here is the algorithm. */
/* If the etherType is less than the MTU then we know that */
/* this is an 802.x address from RFC 1700. */
/*if (etherType < sizeof(LAN_FRAME_HEADER)) */
if(!IS_ETHERTYPE(etherType)){
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -