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

📄 vxbufs.c

📁 基于vxworks操作系统,Tornado2.0平台,生成树STP源码.直接在其对应的设备中添加即可.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * 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)){

⌨️ 快捷键说明

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