亚洲欧美第一页_禁久久精品乱码_粉嫩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一区二区三区免费野_久草精品视频
夜夜亚洲天天久久| 懂色av一区二区三区免费观看| 韩国中文字幕2020精品| www.66久久| 精品免费视频.| 午夜精品123| 色国产综合视频| 国产日本一区二区| 人禽交欧美网站| 欧美亚洲日本一区| 国产精品进线69影院| 激情综合五月婷婷| 欧美日韩久久一区二区| 国产精品免费看片| 国产精品乡下勾搭老头1| 欧美老年两性高潮| 亚洲国产乱码最新视频| 97se亚洲国产综合自在线观| 日本一区二区三区dvd视频在线| 香蕉成人啪国产精品视频综合网 | 欧美视频在线播放| 亚洲婷婷综合色高清在线| 国产成人一级电影| 2023国产一二三区日本精品2022| 日韩电影在线免费看| 欧美日韩国产小视频| 亚洲与欧洲av电影| 在线精品观看国产| 亚洲一区二区三区免费视频| 色视频一区二区| 一区二区在线观看免费| 色综合久久久久| 亚洲日本欧美天堂| www.欧美色图| 1区2区3区国产精品| av网站免费线看精品| 亚洲欧美在线高清| 91麻豆自制传媒国产之光| 制服丝袜av成人在线看| 国产精品久久久久久久久动漫 | 日本不卡中文字幕| 欧美一区二区三区小说| 久久99蜜桃精品| 精品日韩在线观看| 国产成人丝袜美腿| 日韩va欧美va亚洲va久久| 欧美日韩国产综合一区二区三区| 亚洲一区二区三区精品在线| 欧美日韩三级一区二区| 日韩黄色小视频| 精品国产乱码91久久久久久网站| 国产一区二区91| 国产精品国产三级国产三级人妇 | 91久久精品网| 日韩国产成人精品| 精品国产一区二区三区忘忧草 | 国产成人av一区二区三区在线| 久久精品视频一区二区三区| 成人久久视频在线观看| 亚洲最大色网站| 日韩视频免费观看高清完整版在线观看 | 国产亚洲一本大道中文在线| 成人午夜激情影院| 亚洲成国产人片在线观看| 日本精品裸体写真集在线观看| 亚洲国产视频网站| 精品不卡在线视频| 中文字幕巨乱亚洲| 亚洲日本一区二区| 色88888久久久久久影院野外| 国产一区二区电影| 亚洲免费在线电影| 欧美精品777| 成人一区二区三区在线观看| 亚洲一区二区影院| 国产欧美视频在线观看| 欧美日韩1234| 91在线porny国产在线看| 日本不卡一区二区三区 | 久久久亚洲精品石原莉奈| 色8久久人人97超碰香蕉987| 国产毛片精品一区| 午夜视频在线观看一区二区 | 亚洲激情综合网| xvideos.蜜桃一区二区| 欧洲亚洲国产日韩| 成人午夜短视频| 老汉av免费一区二区三区 | 国产精品美女久久久久aⅴ| 欧美剧在线免费观看网站 | 豆国产96在线|亚洲| 日韩高清国产一区在线| 亚洲永久免费av| 日韩美女视频一区二区| 日本一区二区三级电影在线观看 | 亚洲猫色日本管| 久久午夜色播影院免费高清| 欧美精品丝袜久久久中文字幕| 99久久精品国产一区| 国产一区二区电影| 狠狠色丁香婷婷综合久久片| 亚洲成a人片在线观看中文| 一区二区三区91| 1区2区3区精品视频| 国产精品免费视频网站| 国产欧美一区在线| 久久奇米777| 精品理论电影在线观看| 日韩一级片网址| 日韩一本二本av| 欧美一区二区三区成人| 这里只有精品电影| 3atv在线一区二区三区| 欧美精品久久久久久久多人混战| 欧洲av一区二区嗯嗯嗯啊| 色综合久久精品| 欧美三级日韩三级| 欧美日韩国产精品成人| 91精品国产一区二区三区蜜臀| 制服丝袜亚洲精品中文字幕| 6080国产精品一区二区| 日韩亚洲欧美在线观看| 欧美一区午夜精品| 欧美va日韩va| 国产欧美视频一区二区| 国产精品久久久久久久久免费樱桃| 欧美激情综合网| 一区二区三区在线视频免费| 夜夜爽夜夜爽精品视频| 免费在线观看精品| 国产精品2024| 97精品国产露脸对白| 制服丝袜日韩国产| 久久影院视频免费| 1区2区3区精品视频| 天堂va蜜桃一区二区三区漫画版| 天天综合天天做天天综合| 九九精品视频在线看| 国产福利精品一区二区| 色综合久久综合网| 日韩欧美国产综合一区| 国产精品污www在线观看| 一区二区三区四区不卡在线| 日韩精品一区第一页| 国产一区在线观看麻豆| 色猫猫国产区一区二在线视频| 欧美日韩亚洲综合一区二区三区| 精品国产免费一区二区三区香蕉| 日本一区二区不卡视频| 亚洲美女偷拍久久| 久久se精品一区二区| 色婷婷国产精品| 欧美不卡一区二区三区| 亚洲免费观看高清完整版在线| 日韩av电影免费观看高清完整版在线观看| 久久精品国产色蜜蜜麻豆| 一本久道中文字幕精品亚洲嫩| 日韩欧美一二三四区| 麻豆精品视频在线| 95精品视频在线| 精品伦理精品一区| 亚洲国产成人tv| 成人av在线播放网址| 日韩视频永久免费| 亚洲国产裸拍裸体视频在线观看乱了 | 亚洲天堂久久久久久久| 精品在线你懂的| 欧美夫妻性生活| 亚洲免费成人av| 国产成人精品在线看| 日韩免费在线观看| 亚洲国产精品久久不卡毛片| 99视频精品免费视频| 久久久www免费人成精品| 亚洲国产毛片aaaaa无费看| caoporm超碰国产精品| 国产亚洲一区二区三区在线观看| 午夜激情一区二区三区| 色呦呦国产精品| 中文字幕在线不卡| 丁香另类激情小说| 精品少妇一区二区三区在线视频| 亚洲综合清纯丝袜自拍| 91首页免费视频| 国产欧美日韩视频一区二区| 国产在线播放一区| 日韩免费福利电影在线观看| 亚洲国产一二三| 欧美中文一区二区三区| 怡红院av一区二区三区| 99久久精品国产精品久久| 国产亚洲精品aa午夜观看| 国产综合色精品一区二区三区| 在线91免费看| 青青青伊人色综合久久| 91精品国产综合久久精品麻豆 | 午夜日韩在线电影| 在线欧美日韩国产| 一区二区成人在线| 欧美日韩视频在线一区二区|