📄 gei82543end.c
字号:
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 + -