亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? csl_emac.c

?? 合眾達的開發板自帶測試程序
?? C
?? 第 1 頁 / 共 4 頁
字號:
/*****************************************************************************\
*           Copyright (C) 1999-2003 Texas Instruments Incorporated.
*                           All Rights Reserved
*------------------------------------------------------------------------------
* FILENAME...... csl_emac.c
* DATE CREATED.. 02/08/2002
* LAST MODIFIED. 05/23/2003
*------------------------------------------------------------------------------
* NOTE:
*   When used in an multitasking environment, no EMAC function may be
*   called while another EMAC function is operating on the same device
*   handle in another thread. It is the responsibility of the application
*   to assure adherence to this restriction.
*
\******************************************************************************/

/* Include the EMAC file from CSL */
#include <csl_emachal.h>
#include <csl_emac.h>
#include <csl_mdio.h>

#if (EMAC_SUPPORT)
extern void   *memset(void *_mem, int _ch, uint _n);

/*
// We keep a local packet queue for transmit and receive packets.
// The queue structure is OS independent.
*/

/*
// Packet Queue
*/
typedef struct _pktq {
  uint              Count;      // Number of packets in queue
  EMAC_Pkt          *pHead;     // Pointer to first packet
  EMAC_Pkt          *pTail;     // Pointer to last packet
} PKTQ;

/*
// Queue Helper Functions
*/
static EMAC_Pkt *pqPop( PKTQ *pq );
static void pqPush( PKTQ *pq, EMAC_Pkt *pPktHdr );
static void pqPushChain( PKTQ *pq, EMAC_Pkt *pPktHdrFirst,
                         EMAC_Pkt *pPktHdrLast, uint Count );


/*
// Transmit/Receive Descriptor Channel Structure
// (One receive and up to 8 transmit in this driver)
*/
typedef struct _EMAC_DescCh {
    struct _EMAC_Device *pd;      /* Pointer to parent structure   */
    PKTQ            DescQueue;    /* Packets queued as desc        */
    PKTQ            WaitQueue;    /* Packets waiting for TX desc   */
    uint            ChannelIndex; /* Channel index 0-7             */
    uint            DescMax;      /* Max number of desc (buffs)    */
    uint            DescCount;    /* Current number of desc        */
    EMAC_Desc       *pDescFirst;  /* First desc location           */
    EMAC_Desc       *pDescLast;   /* Last desc location            */
    EMAC_Desc       *pDescRead;   /* Location to read next desc    */
    EMAC_Desc       *pDescWrite;  /* Location to write nest desc   */
} EMAC_DescCh;


/*
// Main Device Instance Structure
*/
typedef struct _EMAC_Device {
    Uint32          DevMagic;     /* Magic ID for this instance    */
    Handle          hApplication; /* Calling Application's Handle  */
    Handle          hMDIO;        /* Handle to MDIO Module      */
    uint            RxFilter;     /* Current RX filter value       */
    uint            PktMTU;       /* Max physical packet size      */
    Uint32          MacHash1;     /* Hash value cache              */
    Uint32          MacHash2;     /* Hash value cache              */
    Uint32          FatalError;   /* Fatal Error Code              */
    EMAC_Config     Config;       /* Original User Configuration   */
    EMAC_Statistics Stats;        /* Current running statistics    */
    EMAC_DescCh     RxCh;         /* Receive channel status        */
    EMAC_DescCh     TxCh[8];      /* Transmit channel status       */
} EMAC_Device;


/*
// Although the EMAC API is defined to support multiple device instances,
// this version supports a single device instance
*/

/* Local copy of the EMAC device instance */
static uint             openFlag = 0;
static EMAC_Device      localDev;
#define EMAC_DEVMAGIC   0x0aceface
#define EMAC_NUMSTATS   36         /* The number of statistics regs */

/*
// Local Helper Functions
*/
static void emacUpdateStats( EMAC_Device *pd );
static void emacEnqueueTx( EMAC_DescCh *pdc );
static void emacDequeueTx( EMAC_DescCh *pdc, EMAC_Desc *pDescLast );
static void emacEnqueueRx( EMAC_DescCh *pdc, uint fRestart );
static void emacDequeueRx( EMAC_DescCh *pdc, EMAC_Desc *pDescAck );


/*--------------------------------------------------------------------*\
* pqPop()
*
* Pop a desc buffer off a queue
\*--------------------------------------------------------------------*/
static EMAC_Pkt *pqPop( PKTQ *pq )
{
    EMAC_Pkt *pPktHdr;

    pPktHdr = pq->pHead;

    if( pPktHdr )
    {
        pq->pHead = pPktHdr->pNext;
        pq->Count--;
    }

    pPktHdr->pPrev = pPktHdr->pNext = 0;

    return( pPktHdr );
}

/*--------------------------------------------------------------------*\
* pqPush()
*
* Push a desc buffer onto a queue
\*--------------------------------------------------------------------*/
static void pqPush( PKTQ *pq, EMAC_Pkt *pPktHdr )
{
    pPktHdr->pNext = 0;

    if( !pq->pHead )
    {
        // Queue is empty - Initialize it with this one packet
        pq->pHead = pPktHdr;
        pq->pTail = pPktHdr;
    }
    else
    {
        // Queue is not empty - Push onto END
        pq->pTail->pNext = pPktHdr;
        pq->pTail        = pPktHdr;
    }
    pq->Count++;
}

/*--------------------------------------------------------------------*\
* pqPushChain()
*
* Push a desc buffer chain onto a queue
\*--------------------------------------------------------------------*/
static void pqPushChain( PKTQ *pq, EMAC_Pkt *pPktHdrFirst,
                         EMAC_Pkt *pPktHdrLast, uint Count )
{
    pPktHdrLast->pNext = 0;

    if( !pq->pHead )
    {
        // Queue is empty - Initialize it with this one packet
        pq->pHead = pPktHdrFirst;
        pq->pTail = pPktHdrLast;
    }
    else
    {
        // Queue is not empty - Push onto END
        pq->pTail->pNext = pPktHdrFirst;
        pq->pTail        = pPktHdrLast;
    }
    pq->Count += Count;
}


/*--------------------------------------------------------------------*\
* emacUpdateStats()
*
* Update our local copy of the statistics
\*--------------------------------------------------------------------*/
static void emacUpdateStats( EMAC_Device *pd )
{
    int             i;
    volatile Uint32 *pRegAddr;
    Uint32          *pStatAddr;
    Uint32          statval;

    pRegAddr = EMAC_ADDR(RXGOODFRAMES);
    pStatAddr = (Uint32 *)(&pd->Stats);

    /*
    // There are "EMAC_NUMSTATS" statistics registers
    // Note that when MIIEN is set in MACCONTROL, these registers
    // are "write to decrement".
    */
    for( i=0; i<EMAC_NUMSTATS; i++ )
    {
        statval = *pRegAddr;
        *pRegAddr++ = statval;
        statval += *pStatAddr;
        *pStatAddr++ = statval;
    }
}

/*--------------------------------------------------------------------*\
* emacEnqueueTx()
*
* Enqueue a TX packet and restart transmitter as needed
\*--------------------------------------------------------------------*/
static void emacEnqueueTx( EMAC_DescCh *pdc )
{
    EMAC_Desc   *pDescOrg,*pDescThis;
    EMAC_Pkt     *pPkt;
    uint        PktFrags;
    uint        CountOrg;

    /*
    // We need to be careful that we don't post half a packet to
    // the list. Otherwise; we just fill in as much packet descriptor
    // stuff as we can.
    */
    pDescOrg = pdc->pDescWrite;
    CountOrg = pdc->DescCount;

    /* Try to post any waiting packets */
    while( pdc->WaitQueue.Count )
    {
        /* See if we have enough room for a new packet */
        pPkt = pdc->WaitQueue.pHead;
        PktFrags = pPkt->PktFrags;

        /* If we don't have room, break out */
        if( (PktFrags+pdc->DescCount) > pdc->DescMax )
            break;

        /* The next packet will fit, post it. */
        while( PktFrags )
    {
            /* Pop the next frag off the wait queue */
            pPkt = pqPop( &pdc->WaitQueue );

        /* Assign the pointer to "this" desc */
        pDescThis = pdc->pDescWrite;

        /* Move the write pointer and bump count */
        if( pdc->pDescWrite == pdc->pDescLast )
            pdc->pDescWrite = pdc->pDescFirst;
        else
            pdc->pDescWrite++;
        pdc->DescCount++;

        /*
        // If this is the last frag, the forward pointer is NULL
        // Otherwise; this desc points to the next frag's desc
        */
            if( PktFrags==1 )
            pDescThis->pNext = 0;
        else
            pDescThis->pNext = pdc->pDescWrite;

            pDescThis->pBuffer   = pPkt->pDataBuffer + pPkt->DataOffset;
            pDescThis->BufOffLen = pPkt->ValidLen;

            if( pPkt->Flags & EMAC_PKT_FLAGS_SOP )
                pDescThis->PktFlgLen = ((pPkt->Flags&
                                       (EMAC_PKT_FLAGS_SOP|EMAC_PKT_FLAGS_EOP))
                                       |pPkt->PktLength|EMAC_DSC_FLAG_OWNER);
        else
                pDescThis->PktFlgLen = (pPkt->Flags&EMAC_PKT_FLAGS_EOP)
                                       |EMAC_DSC_FLAG_OWNER;

            /* Enqueue this frag onto the desc queue */
        pqPush( &pdc->DescQueue, pPkt );
            PktFrags--;
        }
    }

    /* If we posted anything, chain on the list or start the transmitter */
    if( CountOrg != pdc->DescCount )
    {
        if( CountOrg )
        {
    /*
            // Transmitter is already running. Just tack this packet on
            // to the end of the list (we need to "back up" one descriptor)
    */
            if( pDescOrg == pdc->pDescFirst )
            pDescThis = pdc->pDescLast;
        else
            pDescThis = pDescOrg - 1;
        pDescThis->pNext = pDescOrg;
    }
    else
    {
        /* Transmitter is not running, start it up */
            EMAC_RSETI( TXHDP, pdc->ChannelIndex, (Uint32)pDescOrg );
        }
    }
}

/*--------------------------------------------------------------------*\
* emacDequeueTx()
*
* Dequeue all completed TX packets and return buffers to application
\*--------------------------------------------------------------------*/
static void emacDequeueTx( EMAC_DescCh *pdc, EMAC_Desc *pDescAck )
{
    EMAC_Pkt     *pPkt;
    Uint32      PktFlgLen;
    register uint  i,j = (uint)pdc->pDescRead;

    /* Get the status of the ACK descriptor */
    PktFlgLen = pDescAck->PktFlgLen;

    /* Calc the new "Read" descriptor */
    if( pDescAck == pdc->pDescLast )
        pdc->pDescRead = pdc->pDescFirst;
    else
        pdc->pDescRead = pDescAck+1;

    i = (uint)pdc->pDescRead;

    /* Turn i into a descriptor count */
    if( j < i )
        i = (i-j)/sizeof(EMAC_Desc);
    else
        i = pdc->DescMax - ((j-i)/sizeof(EMAC_Desc));

    pdc->DescCount-=i;

    /* Pop & Free Buffers 'till the last Descriptor */
    while(i--)
    {
        /* Recover the buffer and free it */
        pPkt = pqPop( &pdc->DescQueue );
        if( pPkt )
            (*localDev.Config.pfcbFreePacket)(pdc->pd->hApplication,pPkt);
    }

    /* If the transmitter stopped and we have more descriptors, then restart */
    if( (PktFlgLen & EMAC_DSC_FLAG_EOQ) && pdc->DescCount )
        EMAC_RSETI( TXHDP, pdc->ChannelIndex, (Uint32)pdc->pDescRead );

    /* Try to post any waiting TX packets */
    if( pdc->WaitQueue.Count )
        emacEnqueueTx( pdc );
}


/*--------------------------------------------------------------------*\
* emacEnqueueRx()
*
* Fill any empty RX descriptors with new buffers from the application
\*--------------------------------------------------------------------*/
static void emacEnqueueRx( EMAC_DescCh *pdc, uint fRestart )
{
    EMAC_Pkt     *pPkt;
    EMAC_Desc   *pDesc;
    uint        CountOrg;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
色噜噜久久综合| 欧美性猛交xxxx黑人交| 午夜精品爽啪视频| 亚洲狼人国产精品| 亚洲欧美精品午睡沙发| 国产精品视频看| 久久精品欧美一区二区三区不卡| 精品人在线二区三区| 91精品国产入口| 欧美电影免费观看高清完整版在线观看| 欧美日韩第一区日日骚| 91精品国产91热久久久做人人| 91精品国产品国语在线不卡| 欧美一区二区三级| xf在线a精品一区二区视频网站| 26uuu亚洲综合色| 国产精品视频你懂的| 亚洲欧洲综合另类在线| 亚洲丰满少妇videoshd| 日本欧美加勒比视频| 国产在线精品一区在线观看麻豆| 韩国毛片一区二区三区| 成人午夜电影小说| 91久久国产最好的精华液| 欧美久久久久久久久| 日韩精品一区在线观看| 国产欧美精品在线观看| 亚洲激情一二三区| 久久99精品久久久久久国产越南| 国产成人在线观看| 色88888久久久久久影院野外| 91精品在线免费| 久久久不卡网国产精品二区| 日韩毛片在线免费观看| 亚洲国产精品嫩草影院| 久久成人久久爱| 成人丝袜视频网| 欧美日韩国产小视频| 久久先锋影音av鲁色资源网| 一区二区中文字幕在线| 青青青爽久久午夜综合久久午夜 | 国产精品小仙女| 成人18视频日本| 欧美精品在线观看一区二区| 精品日韩欧美在线| 亚洲综合在线电影| 国产精品18久久久久久vr| 欧美日韩综合一区| 久久午夜羞羞影院免费观看| 亚洲二区在线视频| 99精品视频一区二区| 精品福利av导航| 亚洲不卡av一区二区三区| 懂色av一区二区夜夜嗨| 欧美一个色资源| 亚洲婷婷国产精品电影人久久| 美女视频一区二区| 欧美精品久久99久久在免费线| 国产精品二三区| 国产精品系列在线观看| 日韩视频免费观看高清在线视频| 亚洲另类在线视频| 成人激情电影免费在线观看| 久久伊99综合婷婷久久伊| 日韩精品一二三四| 欧美色大人视频| 亚洲综合一区二区| 色素色在线综合| 亚洲日本成人在线观看| 成人三级在线视频| 久久精品在这里| 国产一区二区h| 国产亚洲va综合人人澡精品| 狠狠色丁香九九婷婷综合五月| 欧美精品123区| 亚洲第一主播视频| 欧美久久久久久久久久| 日韩福利电影在线观看| 91精品婷婷国产综合久久性色| 午夜激情一区二区| 91精品国产综合久久久久久久久久| 亚洲宅男天堂在线观看无病毒| 欧美在线影院一区二区| 亚洲精品一二三区| 欧美日韩在线一区二区| 午夜精品视频一区| 精品免费国产一区二区三区四区| 久久精品二区亚洲w码| 久久综合色8888| 风流少妇一区二区| 亚洲视频你懂的| 欧美亚洲一区二区在线| 日本成人在线网站| 久久久亚洲精品一区二区三区| 国产精品亚洲视频| 亚洲三级在线看| 欧美精品一级二级三级| 久久国产精品无码网站| 欧美激情在线一区二区三区| 色老综合老女人久久久| 日本亚洲最大的色成网站www| 久久婷婷色综合| 91热门视频在线观看| 免费精品视频最新在线| 国产欧美一区二区三区在线看蜜臀| 一本色道a无线码一区v| 日日夜夜免费精品| 久久九九99视频| 欧美视频日韩视频在线观看| 国模冰冰炮一区二区| 一区二区三区在线视频播放| 日韩视频永久免费| 91在线视频免费观看| 喷白浆一区二区| 中文字幕一区二区三| 日韩无一区二区| 色婷婷精品久久二区二区蜜臂av | 国产精品成人免费精品自在线观看 | 一区二区三区加勒比av| 日韩欧美国产麻豆| 色视频一区二区| 国产成人综合在线| 青青草国产精品亚洲专区无| 亚洲天堂av老司机| 精品理论电影在线观看| 一本大道久久a久久精二百| 卡一卡二国产精品| 亚洲线精品一区二区三区| 另类综合日韩欧美亚洲| 久久久精品天堂| 欧美日韩精品欧美日韩精品| 成人动漫一区二区在线| 蜜臀国产一区二区三区在线播放| 国产精品久久久久婷婷二区次| 日韩精品一区二区三区视频 | 51精品视频一区二区三区| 成人免费毛片片v| 精品在线观看视频| 日本欧美在线看| 亚洲成年人影院| 亚洲美女精品一区| 国产精品色哟哟网站| 久久午夜国产精品| 精品少妇一区二区三区日产乱码 | 久久蜜臀精品av| 欧美一区二区三区视频在线观看| 一本久道久久综合中文字幕| av一区二区久久| 国产精品亚洲一区二区三区妖精 | 欧美性色欧美a在线播放| www.欧美精品一二区| 成人免费观看男女羞羞视频| 国产美女一区二区三区| 激情综合色综合久久| 麻豆国产91在线播放| 久久99久久99| 激情综合色播激情啊| 国产酒店精品激情| 成人夜色视频网站在线观看| 国产成人精品三级麻豆| 成人午夜av电影| 色综合天天做天天爱| 91久久一区二区| 欧美日韩国产另类一区| 久久久国际精品| 欧美国产丝袜视频| 国产精品毛片久久久久久| 综合久久给合久久狠狠狠97色| 亚洲欧美韩国综合色| 亚洲国产精品嫩草影院| 奇米色一区二区三区四区| 精品亚洲成a人在线观看 | 成人黄色a**站在线观看| 成人黄色777网| 欧美在线小视频| 3d动漫精品啪啪一区二区竹菊| 日韩精品一区二区三区视频播放 | 亚洲精品一二三区| 亚洲午夜国产一区99re久久| 美女任你摸久久 | 国产精品久久久久一区二区三区| 综合欧美一区二区三区| 香蕉加勒比综合久久| 久久99九九99精品| 成人av小说网| 欧美精品久久99久久在免费线| 精品sm捆绑视频| 亚洲品质自拍视频| 日本人妖一区二区| www.av亚洲| 51精品秘密在线观看| 国产精品精品国产色婷婷| 亚洲国产欧美在线人成| 久久福利视频一区二区| 99久久久国产精品| 精品电影一区二区| 亚洲男人电影天堂| 激情图片小说一区| 欧美亚洲综合久久| 国产精品无人区|