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

📄 gei82543end.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 5 页
字号:
            pDrvCtrl->txReqDescNum = mBlkNum;            if (pDrvCtrl->adaptor.boardType == PRO1000_546_BOARD)	       {               /* enable the TXD_LOW interrupt */               GEI_WRITE_REG(INTEL_82543GC_IMS, IMS_TXDLOW_BIT);               }            GEI_WRITE_REG(INTEL_82543GC_TIDV, MIN_TXINT_DELAY);            }                   END_TX_SEM_GIVE (&pDrvCtrl->end);                return (END_ERR_BLOCK);             }             /* bump statistic counter */        if (pMblk->mBlkHdr.mData[0] & (UINT8) 0x01)        pDrvCtrl->end.mib2Tbl.ifOutNUcastPkts += 1;       else        END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);    DRV_LOG (DRV_DEBUG_TX, "loan buffers of the packet and transmit...\n",                                1, 2, 3, 4, 5, 6);    pDrvCtrl->txActivity = TRUE;    gei82543LoanTransmit (pDrvCtrl, pMblk);    /* release semaphore now */    END_TX_SEM_GIVE (&pDrvCtrl->end);    DRV_LOG (DRV_DEBUG_TX, ("gei82543EndSend...Done"), 1, 2, 3, 4, 5, 6);    return (OK);    }/************************************************************************ gei82543LoanTransmit - store the mbuf address into TX descriptor to transmit** This routine stores the mbuf address into the Tx descriptors address field,* and then directly transfer data from mbuf to chip memory without copying,* The loaned mBlk will be freed later** RETURNS: N/A.*/LOCAL void gei82543LoanTransmit     (    END_DEVICE *     pDrvCtrl,      /* END device structure */    M_BLK_ID         pMblkFirst     /* pointer to the beginning of a mBlk */    )    {    P_TX_DESCTL     pDescCtl;       /* pointer to a Tx descriptor */                                     /* control structure*/    char *          pDesc;          /* pointer to a descriptor */    M_BLK_ID        pMblk;          /* pointer to a Mblk */    UINT32          len;            /* temporary len for each mBlk */    UINT32          totalLen = 0;   /* total length of this packet */    UINT32          index = 0;      /* index to the number of mBlk */     int             tmpTail;        /* temporary tail index of TX descriptor*/    UINT32          poptSta = 0;    /* value in the option and status filed */    UINT32          dataCtx;        /* value in the command field */    dataCtx = ((TXD_CMD_IDE | TXD_CMD_RS) << 24);     pMblk = pMblkFirst;    FOREVER        {        /* get the available TX descriptor and its manager */        GEI_GET_TX_DESC_TAIL_UPDATE(tmpTail, index);                 pDescCtl = GEI_GET_TX_DESC_CTL_ADDR(tmpTail);        pDesc = GEI_GET_TX_DESC_ADDR(tmpTail);          len = pMblk->mBlkHdr.mLen;                totalLen += len;             /* flush buffer for cache coherence */        cacheFlush(DATA_CACHE, (void *)(pMblk->mBlkHdr.mData), len);           GEI_WRITE_DESC_LONG(pDesc, TXDESC_BUFADRHIGH_OFFSET, 0);        GEI_WRITE_DESC_LONG(pDesc, TXDESC_BUFADRLOW_OFFSET,             (UINT32)GEI_VIRT_TO_BUS((UINT32)(pMblk->mBlkHdr.mData)));               /* zero the status field in the TX descriptor */        GEI_WRITE_DESC_LONG(pDesc, TXDESC_STATUS_OFFSET, poptSta);                      pMblk = pMblk->mBlkHdr.mNext;        index++;        if (pMblk == NULL || pMblk->mBlkHdr.mLen == 0)            {                    /* the last mBlk for this packet */            pDescCtl->txType = TX_DESC_TYPE_EOP;             pDescCtl->mBlk = pMblkFirst;                          if (totalLen < ETHERSMALL)                len = max (len, len + ETHERSMALL - totalLen);            /* set up the length/commond field */                 GEI_WRITE_DESC_LONG(pDesc, TXDESC_LENGTH_OFFSET,                                 ((UINT16)len | (dataCtx) |                                 ((TXD_CMD_EOP | TXD_CMD_IFCS) << 24)));            break;            }        else            {            pDescCtl->txType = TX_DESC_TYPE_CHAIN;             pDescCtl->mBlk = NULL;                         /* set up the length field */            GEI_WRITE_DESC_LONG(pDesc, TXDESC_LENGTH_OFFSET,                                 ((UINT16)len | dataCtx));            }        } /* FOREVER */           /* update the tail pointer in the driver structure */    GEI_GET_TX_DESC_TAIL_UPDATE(pDrvCtrl->txDescTail, index);    pDrvCtrl->txDescFreeNum -= index;    CACHE_PIPE_FLUSH();    /* update the tail pointer in TDT register */    GEI_WRITE_REG(INTEL_82543GC_TDT, pDrvCtrl->txDescTail);    return;    }    /*************************************************************************** gei82543TxDesCleanGet - clean up TX descriptors ** This routine cleans up TX descriptors and update available TX descriptor * for transmitting. ** RETURNS: number of available TX descriptors*/LOCAL int gei82543TxDesCleanGet    (    END_DEVICE * pDrvCtrl,      /* device to clean up TX descriptor */    int          mode           /* clean up mode Force/Auto */    )    {    P_TX_DESCTL pDescCtl;       /* TX descriptor control structure */    char *      pDesc;          /* pointer to descriptor */    int         maxTxDesFree;   /* maximum available TX descriptors to free */    int         index;          /* index */    /* check the maximum free TX Desc */    maxTxDesFree = pDrvCtrl->txDescNum - 1;    while (pDrvCtrl->txDescFreeNum != maxTxDesFree)        {        index = (pDrvCtrl->txDescLastCheck + 1) % (pDrvCtrl->txDescNum);        pDesc =  GEI_GET_TX_DESC_ADDR(index);        /* check data has been transmitted */        if (mode != FREE_ALL_FORCE)            if (!(GEI_READ_DESC_BYTE(pDesc, TXDESC_STATUS_OFFSET) &                   TXD_STAT_DD))                break;         pDescCtl = GEI_GET_TX_DESC_CTL_ADDR(index);                if (pDescCtl->txType == TX_DESC_TYPE_EOP && pDescCtl->mBlk != NULL)            {            /* free loaned TX buffers */            netMblkClChainFree (pDescCtl->mBlk);                  pDescCtl->mBlk = NULL;            }        /* mark descrptor clean */        pDescCtl->txType = TX_DESC_TYPE_CLEAN;        /* update the index of descriptor checked */        pDrvCtrl->txDescLastCheck = index;        /* update the available TX descriptor */        pDrvCtrl->txDescFreeNum++;        }           return (pDrvCtrl->txDescFreeNum);    }/*************************************************************************** gei82543EndInt - handle 82543 chip interrupt event** This routine is called at interrupt level in response to an interrupt from* the controller.** RETURNS: N/A.*/LOCAL void gei82543EndInt    (    END_DEVICE *    pDrvCtrl    /* device to handle interrupt */    )    {    UINT32 stat;                /* cause of interrupt */    UINT32 statusRegVal;        /* status register value */    UINT32 intTypeChk;          /* type of interrupt to be checked */    DRV_LOG (DRV_DEBUG_INT, "gei82543EndInt ...\n", 1, 2, 3, 4, 5, 6);    /* read the device status register */    GEI_READ_REG(INTEL_82543GC_ICR, stat);     stat &= INTEL_82543GC_VALID_INT;    /* return if not interrupt for this device */     if (stat == 0)         {        DRV_LOG (DRV_DEBUG_INT, "gei82543EndInt: PCI interrupt is not                 caused by this GEI device\n", 1, 2, 3, 4, 5, 6);        return;            }    /* handle link interrupt event */    if (stat & INT_LINK_CHECK)        {        DRV_LOG (DRV_DEBUG_INT, "gei82543EndInt: get a Link problem\n",                                  1, 2, 3, 4, 5, 6);        /* link status change, get status register */        GEI_READ_REG(INTEL_82543GC_STATUS, statusRegVal);        if (statusRegVal & STATUS_LU_BIT)            {                            /* link is up */            if (pDrvCtrl->cableType == GEI_FIBER_MEDIA)                {                /*                  * restart link if partner send back a TXCW after                 * force link                 */                UINT32 rxcwRegVal;                UINT32 txcwRegVal;                      GEI_READ_REG(INTEL_82543GC_RXCW, rxcwRegVal);                GEI_READ_REG(INTEL_82543GC_TXCW, txcwRegVal);                if ((pDrvCtrl->linkMethod == GEI82543_FORCE_LINK) &&                    (rxcwRegVal & RXCW_C_BIT) &&                              (!(txcwRegVal & TXCW_ANE_BIT)))                    {                    DRV_LOG (DRV_DEBUG_INT, "gei82543EndInt: Hardware                              Auto-Negotiation restart\n", 1, 2, 3, 4, 5, 6);                    netJobAdd ((FUNCPTR)gei82543linkTBISetup, (int)pDrvCtrl,                                         FALSE, 0, 0, 0);                                 return;                    }                }            else if (pDrvCtrl->cableType == GEI_COPPER_MEDIA)                {                LOGMSG("Reconfig device ... \n",1,2,3,4,5,6);                 /* re-configure device based on GMII negotiation results */                   if (pDrvCtrl->linkMethod == GEI82543_HW_AUTO)                    {                    netJobAdd ((FUNCPTR) gei82543GMIIphyReConfig,                                          (int)pDrvCtrl, 0, 0, 0, 0);                                 return;                    }                }            }        else  /* if link is down */            {            return;            }        }    if (pDrvCtrl->adaptor.boardType == PRO1000_546_BOARD)        {   	if (stat & INT_RXTO_BIT)	    pDrvCtrl->rxIntCount++;  	if (stat & INT_RXO_BIT)	    pDrvCtrl->rxORunIntCount++; 	if (stat & (INT_TXDW_BIT | INT_TXDLOW_BIT))	    pDrvCtrl->txIntCount++;        intTypeChk = AVAIL_RX_TX_INT | INT_TXDLOW_BIT;        }    else        {        intTypeChk = AVAIL_RX_TX_INT;        }                        /* tNetTask handles RX/TX interrupts */    if ((stat & intTypeChk) && (pDrvCtrl->rxtxHandling != TRUE))        {        pDrvCtrl->rxtxHandling = TRUE;         /* disable receive / transmit interrupt */                GEI_WRITE_REG(INTEL_82543GC_IMC, intTypeChk);        /*         * NOTE: Read back any chip register to flush PCI         * bridge write buffer in case this adaptor is behind         * a PCI bridge.         */             CACHE_PIPE_FLUSH ();        GEI_READ_REG(INTEL_82543GC_IMS, stat);        /* defer the handling ... */        netJobAdd ((FUNCPTR) gei82543RxTxIntHandle, (int)pDrvCtrl, 0,                              0, 0, 0);        }    DRV_LOG (DRV_DEBUG_INT, "gei82543EndInt...Done\n", 1, 2, 3, 4, 5, 6);    return;    }/*************************************************************************** gei82543RxTxIntHandle - receive/transmit interrupt handle in task mode** This routine gets the receive packet and pass them to upper network stack.* It also cleans up TX descriptor if necessary. ** RETURNS: N/A.*/LOCAL void gei82543RxTxIntHandle    (    END_DEVICE *    pDrvCtrl     /* device to handle RX/TX */    )    {    UINT32  rxCountPerInt = 0;   /* maximum RX descriptors to handle a int */    UINT32  retry 

⌨️ 快捷键说明

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