📄 gei82543end.c
字号:
} /* disable TX/RX now */ gei82543TxRxDisable (pDrvCtrl); DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart: set up TX structure\n", 1, 2, 3, 4, 5, 6); /* initialize SW/HW structures for TX */ gei82543TxSetup (pDrvCtrl); /* initialize SW/HW structure for RX */ gei82543RxSetup (pDrvCtrl); DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart: configure device\n", 1, 2, 3, 4, 5, 6); /* configure devices */ pDrvCtrl->flags = DEFAULT_DRV_FLAGS; END_FLAGS_CLR (&pDrvCtrl->end, IFF_UP | IFF_RUNNING); gei82543EndConfigure (pDrvCtrl); DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart: Connect interrupt\n", 1, 2, 3, 4, 5, 6); /* connect interrupt handler */ SYS_INT_CONNECT(pDrvCtrl, gei82543EndInt, (int)pDrvCtrl, &result); if (result == ERROR) { DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart: connect interrupt ERROR !\n", 1, 2, 3, 4, 5, 6); return ERROR; } /* clean up all statistic registers */ gei82543HwStatusDump (pDrvCtrl); /* clean all pending interrupts */ gei82543DisableChipInt (pDrvCtrl); /* turn on system interrupt */ SYS_INT_ENABLE(pDrvCtrl); /* enable interrupt in chip level */ gei82543EnableChipInt (pDrvCtrl); DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart: Interrupt enable\n", 1, 2, 3, 4, 5, 6); /* set the END flags, make driver ready to start */#ifdef INCLUDE_RFC_1213 END_FLAGS_SET (&pDrvCtrl->end, (IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST)); #else END_FLAGS_SET (&pDrvCtrl->end, (IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST | END_MIB_2233));#endif gei82543EndConfigure (pDrvCtrl); /* wait for chip to settle down */ taskDelay (sysClkRateGet () / 20); /* check link status again before really start */ if (gei82543linkStatusCheck (pDrvCtrl) != OK) { LOGMSG("gei82543EndStart:Link is down \n", 1, 2, 3, 4, 5, 6); } /* set the internal timer */ if (pDrvCtrl->adaptor.boardType == PRO1000_546_BOARD) { ADAPTOR_INFO * pBoard = &pDrvCtrl->adaptor; /* pointer to board specific struct */ if (pBoard->sysGeiInitTimerSetup != NULL) if (pBoard->sysGeiInitTimerSetup (&pDrvCtrl->adaptor)) { if (!(pBoard->devTimerUpdate.rdtrVal & 0xffff0000)) GEI_WRITE_REG(INTEL_82543GC_RDTR,pBoard->devTimerUpdate.rdtrVal); if (!(pBoard->devTimerUpdate.radvVal & 0xffff0000)) GEI_WRITE_REG(INTEL_82546EB_RADV,pBoard->devTimerUpdate.radvVal); if (!(pBoard->devTimerUpdate.itrVal & 0xffff0000)) GEI_WRITE_REG(INTEL_82546EB_ITR,pBoard->devTimerUpdate.itrVal); pDrvCtrl->timerInterval = (pBoard->devTimerUpdate.watchDogIntVal <= 0) ? DEFAULT_TIMER_INTERVAL : (pBoard->devTimerUpdate.watchDogIntVal); } } /* start the timer if configured */ if (pDrvCtrl->usrFlags & GEI_END_SET_TIMER) { if (pDrvCtrl->timerId) wdStart(pDrvCtrl->timerId, pDrvCtrl->timerInterval * sysClkRateGet(), (FUNCPTR) gei82543EndTimerHandler, (int) pDrvCtrl); } /* set the device start flag */ pDrvCtrl->devStartFlag = TRUE; /* enable TX and RX operation */ gei82543TxRxEnable (pDrvCtrl); DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart...Done\n", 1, 2, 3, 4, 5, 6); return (OK); }/*************************************************************************** gei82543EndSend - driver send routine** This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.* The buffer must already have the addressing information properly installed* in it. This is done by a higher layer. ** RETURNS: OK or ERROR.** ERRNO: EINVAL*/LOCAL STATUS gei82543EndSend ( END_DEVICE * pDrvCtrl, /* device ptr */ M_BLK_ID pMblk /* data to send */ ) { M_BLK_ID pMblkDup = pMblk; /* temporary pMblk */ int mBlkNum; /* num of mBlk of a packet */ DRV_LOG (DRV_DEBUG_TX, "gei82543EndSend...\n", 1, 2, 3, 4, 5, 6); if (pMblk == NULL) return ERROR; /* return if entering polling mode */ if (pDrvCtrl->flags & FLAG_POLLING_MODE) { netMblkClChainFree (pMblk); errno = EINVAL; return (ERROR); } END_TX_SEM_TAKE (&pDrvCtrl->end, WAIT_FOREVER); /* get the mBlk number in this packet */ mBlkNum = 0; while (pMblkDup != NULL) { mBlkNum++; pMblkDup = pMblkDup->mBlkHdr.mNext; } /* * release mBlks if the number of mBlks in this packet exceeds the maximum * available transmit descriptors */ if (mBlkNum >= pDrvCtrl->txDescNum) { DRV_LOG (DRV_DEBUG_TX, ("gei82543EndSend:mBlks num exceeds max TX desc\n"), 1, 2, 3, 4, 5, 6); netMblkClChainFree (pMblk); errno = EINVAL; END_TX_SEM_GIVE (&pDrvCtrl->end); return (ERROR); } pDrvCtrl->txDescResChk = TRUE; if ((mBlkNum > pDrvCtrl->txDescFreeNum) && (mBlkNum > gei82543TxDesCleanGet(pDrvCtrl,FREE_ALL_AUTO))) { /* not enough TX descriptors */ DRV_LOG (DRV_DEBUG_TX, ("gei82543EndSend: No TX descriptor available\n"), 1, 2, 3, 4, 5, 6); if (pDrvCtrl->txStall != TRUE) { pDrvCtrl->txStall = TRUE; 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); } pDrvCtrl->txDescResChk = FALSE; END_TX_SEM_GIVE (&pDrvCtrl->end); return (END_ERR_BLOCK); } pDrvCtrl->txDescResChk = FALSE; /* bump statistic counter */#ifdef INCLUDE_RFC_1213 if (pMblk->mBlkHdr.mData[0] & (UINT8) 0x01) pDrvCtrl->end.mib2Tbl.ifOutNUcastPkts += 1; else END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);#endif DRV_LOG (DRV_DEBUG_TX, "loan buffers of the packet and transmit...\n", 1, 2, 3, 4, 5, 6); 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 */ END_USR_CACHE_FLUSH(((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; /* update the tail pointer in TDT register */ GEI_WRITE_REG(INTEL_82543GC_TDT, pDrvCtrl->txDescTail); CACHE_PIPE_FLUSH(); 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 gei82543TxDesC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -