📄 sh7615end.c
字号:
END_ERR_ADD (pEndObj, MIB2_OUT_ERRS, +1); END_ERR_ADD (pEndObj, MIB2_OUT_UCAST, -1); } /* Mark descriptors free */#if 0 pTxD->tDesc0 &= TD0_CLEAR_ERRORS_N_STATS;#else /* Mark descriptors free */ pTxD->tDesc0 = 0; pTxD->tDesc1 = 0; pTxD->tDesc2 = 0; pTxD->tDesc3 = 0; if (count == 1) /* if it is last one */ pTxD->tDesc0 |= TD0_TDL; /* end of transmit ring */#endif } /* Start the device */ sh7615EndStart (pDrvCtrl); }/********************************************************************************* sh7615EndStart - start the device** This function calls BSP functions to connect interrupts and start the* device running in interrupt mode. The driver must have already been loaded * with the sh7615EndLoad() routine.** RETURNS: OK or ERROR**/LOCAL STATUS sh7615EndStart ( DRV_CTRL * pDrvCtrl /* device ID */ ) { STATUS result; DRV_LOG (DRV_DEBUG_LOAD, "Starting shend \n", 0, 0, 0, 0, 0, 0); /* must have been loaded */ if (!pDrvCtrl->loaded) return (ERROR); /* Reset the device */ sh7615EndReset (pDrvCtrl); /* Clear all indices */ pDrvCtrl->rxIndex = 0; pDrvCtrl->txIndex = 0; pDrvCtrl->txDiIndex = 0; pDrvCtrl->txCleaning = FALSE; pDrvCtrl->rxHandling = FALSE; pDrvCtrl->txBlocked = FALSE; /* Configure and start the device */ sh7615EndConfig (pDrvCtrl); /* Connect the interrupt handler */ SYS_INT_CONNECT (pDrvCtrl, sh7615EndInt, (int)pDrvCtrl, &result); if (result == ERROR) return ERROR; /* mark the interface -- up */ END_FLAGS_SET (&pDrvCtrl->end, (IFF_UP | IFF_RUNNING)); /* Enable LAN interrupts */ SYS_INT_ENABLE (pDrvCtrl); return (OK); }/********************************************************************************* sh7615EndStop - stop the device** This function calls BSP functions to disconnect interrupts and stop* the device from operating in interrupt mode.** RETURNS: OK or ERROR.*/LOCAL STATUS sh7615EndStop ( DRV_CTRL * pDrvCtrl /* device to be stopped */ ) { STATUS result = OK; /* mark the interface -- down */ END_FLAGS_CLR (&pDrvCtrl->end, IFF_UP | IFF_RUNNING); /* stop transmit and receive */ SH7615END_BIT_CLR(ETHERC_ECMR, ECMR_TE); SH7615END_BIT_CLR(ETHERC_ECMR, ECMR_RE); /* Disable LAN interrupts */ SYS_INT_DISABLE (pDrvCtrl); SYS_INT_DISCONNECT (pDrvCtrl, sh7615EndInt, (int)pDrvCtrl, &result); return (result); }/********************************************************************************* sh7615EndInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the controller.** RETURNS: N/A.*/LOCAL void sh7615EndInt ( DRV_CTRL * pDrvCtrl /* interrupting device */ ) { UINT32 status; /* Read the device status register */ SH7615END_REG_READ (E_DMAC_EESR, status); /* if not one of our interrupts, exit */ if ((status & pDrvCtrl->intrMask) == 0) { return; } /* * read is not destructive, so, lets clear the sources by writing * the status back. This is safe to do since writing a 0 value does * not clear the bit. New sources may have come in, but they'll be * latched into the interrupt controller and caught when we exit here. */ SH7615END_REG_WRITE (E_DMAC_EESR, status); /* Handle link status change */ if ((status & EESR_ECI) != 0) { UINT32 ecsr; SH7615END_REG_READ (ETHERC_ECSR, ecsr); SH7615END_REG_WRITE (ETHERC_ECSR, ecsr); if ((ecsr & ECSR_LCHNG) != 0) { DRV_LOG (DRV_DEBUG_INT, "%s%d - link status change\n", (int)SH7615END_DEV_NAME, pDrvCtrl->unit, 0, 0, 0, 0); sh7615EndStop (pDrvCtrl); netJobAdd ((FUNCPTR)sh7615EndRestart, (int)pDrvCtrl, 0, 0, 0, 0); return; } } /* Handle received packets */ if ((status & EESR_FR) && (!pDrvCtrl->rxHandling)) { /* DRV_LOG (DRV_DEBUG_INT, "Recieve Int!! \n", 0, 0, 0, 0, 0, 0); */ if (netJobAdd ((FUNCPTR)sh7615EndRcvIntHandle, (int)pDrvCtrl, 0, 0, 0, 0) == OK) { /* * prevent additional scheduling of task level recv handling due * to new recv ints that may have been latched since we entered * here. */ pDrvCtrl->rxHandling = TRUE; /* * disable Rx ints - we've already got a handler scheduled so * no need to come in here again. Note, that we may already have * latched a recv int since we entered here and cleared the status * bits above. the rxHandling will ensure that guy schedules no * no more jobs. */ SH7615END_BIT_CLR (E_DMAC_EESIPR, EESIPR_FRIP); } }#ifdef DRV_DEBUG if (status & EESR_RFCOF) sh7615EndRfcof++; if (status & EESR_ECI) sh7615EndEci++; if (status & EESR_TC) sh7615EndTc++; if (status & EESR_TDE) sh7615EndTde++; if (status & EESR_TFUF) sh7615EndTfuf++; if (status & EESR_FR) sh7615EndFr++; if (status & EESR_RDE) sh7615EndRde++; if (status & EESR_RFOF) sh7615EndRfof++; if (status & EESR_ITF) sh7615EndItf++; if (status & EESR_CND) sh7615EndCnd++; if (status & EESR_DLC) sh7615EndDlc++; if (status & EESR_CD) sh7615EndCd++; if (status & EESR_TRO) sh7615EndTro++; if (status & EESR_RMAF) sh7615EndRmaf++; if (status & EESR_RRF) sh7615EndRrf++; if (status & EESR_RTLF) sh7615EndRtlf++; if (status & EESR_RTSF) sh7615EndRtsf++; if (status & EESR_PRE) sh7615EndPre++; if (status & EESR_CERF) sh7615EndCerf++;#endif /* Cleanup TxRing */ if ((status & EESR_TC) && (!pDrvCtrl->txCleaning)) { DRV_LOG (DRV_DEBUG_INT, "Cleanup TxRing from Int() \n", 0, 0, 0, 0, 0, 0); pDrvCtrl->txCleaning = TRUE; netJobAdd ((FUNCPTR)sh7615EndTxRingClean, (int)pDrvCtrl, 0, 0, 0, 0); } if (pDrvCtrl->txBlocked) { pDrvCtrl->txBlocked = FALSE; netJobAdd ((FUNCPTR)muxTxRestart, (int)&pDrvCtrl->end, 0, 0, 0, 0); } }/********************************************************************************* sh7615EndRxDGet - get next receive descriptor** Get next receive descriptor. Returns NULL if none are ready.** RETURNS: ptr to next packet, or NULL if none ready.*/LOCAL SH7615_RD * sh7615EndRxDGet ( DRV_CTRL * pDrvCtrl /* device structure */ ) { SH7615_RD * pRxD = pDrvCtrl->rxRing + pDrvCtrl->rxIndex; /* check if the descriptor is owned by the chip. The chip will clear * this bit once it has completed writing to the buffer. */ if (pRxD->rDesc0 & RD0_OWN) return NULL; return pRxD; }/********************************************************************************* sh7615EndTxDGet - get an available transmit descriptor** Get next transmit descriptor. Returns NULL if none are ready.** RETURNS: an available transmit descriptor, otherwise NULL.*/ LOCAL SH7615_TD * sh7615EndTxDGet ( DRV_CTRL * pDrvCtrl ) { SH7615_TD * pTxD = pDrvCtrl->txRing + pDrvCtrl->txIndex; /* check if this descriptor is owned by the chip or is out of bounds */ if ((pTxD->tDesc0 & TD0_OWN) || (((pDrvCtrl->txIndex + 1) % pDrvCtrl->numTds) == pDrvCtrl->txDiIndex)) return (NULL); return pTxD; }/********************************************************************************* sh7615EndTxRingClean - clean up processed tx descriptors** This routine processes the transmit queue, freeing all transmitted* descriptors.** RETURNS: None*/LOCAL void sh7615EndTxRingClean ( DRV_CTRL * pDrvCtrl ) { SH7615_TD * pTxD; pDrvCtrl->txCleaning = TRUE; while (pDrvCtrl->txDiIndex != pDrvCtrl->txIndex) { pTxD = pDrvCtrl->txRing + pDrvCtrl->txDiIndex; /* All handled, break from the loop */ if (pTxD->tDesc0 & TD0_OWN) break; /* free the buffer */ if (pDrvCtrl->freeBuf[pDrvCtrl->txDiIndex].pClBuf != NULL) { NET_BUF_FREE(pDrvCtrl->freeBuf[pDrvCtrl->txDiIndex].pClBuf); pDrvCtrl->freeBuf[pDrvCtrl->txDiIndex].pClBuf = NULL; } pDrvCtrl->txDiIndex = (pDrvCtrl->txDiIndex + 1) % pDrvCtrl->numTds; /* count collisions */#if 0 if (! (pTxD->tDesc0 & TD0_CD)) END_ERR_ADD (pEndObj, MIB2_COLLISIONS, SH7615END_REG_READ (ETHERC_CDCR));#endif if (pTxD->tDesc0 & TD0_TFE) { END_OBJ *pEndObj = &pDrvCtrl->end; END_ERR_ADD (pEndObj, MIB2_OUT_ERRS, +1); END_ERR_ADD (pEndObj, MIB2_OUT_UCAST, -1); #ifdef DRV_DEBUG /* check for no carrier */ if (pTxD->tDesc0 & (TD0_CND | TD0_DLC)) { logMsg ("%s%d - no carrier\n", (int)SH7615END_DEV_NAME, pDrvCtrl->unit, 0, 0, 0, 0); } sh7615EndTfe++;#endif /* DRV_DEBUG */ } /* clear errors and stats but don't touch TDL bit */ pTxD->tDesc0 &= TD0_CLEAR_ERRORS_N_STATS; } pDrvCtrl->txCleaning = FALSE; return; }/********************************************************************************* sh7615EndRecv - process the next incoming packet** Handle one incoming packet. The packet is checked for errors.** RETURNS: N/A.*/LOCAL STATUS sh7615EndRecv ( DRV_CTRL * pDrvCtrl, /* device structure */ SH7615_RD * pRxD /* packet to process */ ) { END_OBJ * pEndObj = &pDrvCtrl->end; M_BLK_ID pMblk; CL_BLK_ID pClBlk; char* pNewCluster; int len; UCHAR * pMacAddr = NULL; UCHAR * pPktAddr = NULL; /* * If the packet is a multicast frame and originated from us, we drop it. */ if ( (pRxD->rDesc0 & RD0_RFS7) && (DRV_FLAGS_GET() & SH7615END_MCAST) ) { pMacAddr = (UCHAR *)END_HADDR (pDrvCtrl); pPktAddr = (UCHAR *)pRxD->rDesc2; if ( (pMacAddr[0] == pPktAddr[6]) && (pMacAddr[1] == pPktAddr[7]) && (pMacAddr[2] == pPktAddr[8]) && (pMacAddr[3] == pPktAddr[9]) && (pMacAddr[4] == pPktAddr[10]) && (pMacAddr[5] == pPktAddr[11]) ) { /* We received a multicast packet that originated from us */ DRV_LOG (DRV_DEBUG_RX, "Received our own multicast transmission RD0 = 0x%08x \n", pRxD->rDesc0, 2, 3, 4, 5, 6); goto cleanRxD; } } /* check for errors */ if (pRxD->rDesc0 & RD0_RFE) { /* Check if packet is multicast and multicast support is enabled */ if (!(pRxD->rDesc0 & RD0_RFS7) || !(DRV_FLAGS_GET() & SH7615END_MCAST)) { DRV_LOG (DRV_DEBUG_RX, "Receive with error RD0 = 0x%08x \n", pRxD->rDesc0, 2, 3, 4, 5, 6); END_ERR_ADD (pEndObj, MIB2_IN_ERRS, +1); goto cleanRxD; } } DRV_LOG (DRV_DEBUG_RX, "Receive start \n", 1, 2, 3, 4, 5, 6);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -