📄 if_cs.c
字号:
CS_RXBUF *pRxBuff ) { FAST USHORT *pFrame = pCs->pPacketPage + (CS_PKTPG_RX_LENGTH/2); FAST int rxDataPort = pCs->ioAddr + CS_PORT_RXTX_DATA; FAST USHORT *pBuff; FAST USHORT *pBuffLimit; USHORT temp; /* Get the length of the received frame */ if (pCs->inMemoryMode) { pRxBuff->length = *pFrame++; } else /* In IO mode */ { CS_IN_WORD (rxDataPort, &temp); /* Discard RxStatus */ CS_IN_WORD (rxDataPort, &pRxBuff->length); } /* Setup pointers to the buffer for copying */ pBuff = (USHORT *)pRxBuff->data; pBuffLimit = pBuff + ((pRxBuff->length + 1)/2); /* Copy the frame from the chip to the buffer */ if (pCs->inMemoryMode) while (pBuff < pBuffLimit) *pBuff++ = *pFrame++; else while (pBuff < pBuffLimit) { CS_IN_WORD (rxDataPort, pBuff); pBuff++; } }/********************************************************************************* csRxProcess - processes a received packet in task level** This routine processes a received packet. The received packet was copied to* a receive buffer at interrupt time and this routine processses the receive* buffer at task time via netTask().* * If a recieve hook routine is specified, then the packet is given to the* hook routine for processing. If the received packet does not use trailers* and the packet is large, then a cluster mbuf is built that points to the* receive buffer directly. If a cluster mbuf is not used, then the packet* is copied to an mbuf chain. The cluster mbuf or mbuf chain is then passed* up to the protocol stack.** RETURNS: N/A*/LOCAL void csRxProcess ( CS_SOFTC *pCs, CS_RXBUF *pRxBuff ) { struct ifnet *pIf = &pCs->arpCom.ac_if; struct mbuf *pMbufChain; ETH_HDR *pEtherHeader; UCHAR *pData; int dataLength;#ifdef BSD43_DRIVER int trailerOffset; USHORT type;#endif /* BSD43_DRIVER */ /* If a hook routine is specified */ if (etherInputHookRtn != NULL) { /* Call the hook routine */ if ((*etherInputHookRtn) (pIf, pRxBuff->data, pRxBuff->length) != 0) { /* The hook routine has handled the received frame */ csRxBuffFree (pCs, pRxBuff); return; } } /* Setup working variables */ pEtherHeader = (ETH_HDR *)pRxBuff->data; pData = &pRxBuff->data[SIZEOF_ETHERHEADER]; dataLength = pRxBuff->length - SIZEOF_ETHERHEADER;#ifdef BSD43_DRIVER /* Check if the received frame uses trailers */ check_trailer (pEtherHeader, pData, &dataLength, &trailerOffset, pIf); /* Save the type because build_cluster() will overwrite it */ type = pEtherHeader->ether_type; /* If trailers are not used and there is enough data for clustering */ if ((trailerOffset == 0) && USE_CLUSTER (dataLength))#else /* BSD43_DRIVER */ /* If trailers are not used and there is enough data for clustering */ if (USE_CLUSTER (dataLength))#endif /* BSD43_DRIVER */ { /* Build a cluster mbuf that points to my receive buffer */ pMbufChain = build_cluster (pData, dataLength, pIf, CS_MC_LOANED, &pRxBuff->refCount, (FUNCPTR)csRxBuffFree , (int)pCs, (int)pRxBuff, 0); if (pMbufChain != NULL) { pRxBuff->status = CS_RXBUF_LOANED; pCs->loanCount++; } else csRxBuffFree (pCs, pRxBuff); } else /* Can not do clustering */ { /* Copy the received data to a chain of mbufs */#ifdef BSD43_DRIVER pMbufChain = copy_to_mbufs (pData, dataLength, trailerOffset, pIf);#else /* BSD43_DRIVER */ pMbufChain = copy_to_mbufs (pData, dataLength, 0, pIf);#endif /* BSD43_DRIVER */ csRxBuffFree (pCs, pRxBuff); } /* If could not get an mbuf */ if (pMbufChain == NULL) { pIf->if_ierrors++; csError (pCs, "No receive mbuf available"); return; } /* Pass the mbuf chain up to the protocol stack */#ifdef BSD43_DRIVER do_protocol_with_type (type, pMbufChain, &pCs->arpCom, dataLength);#else /* BSD43_DRIVER */ do_protocol (pEtherHeader, pMbufChain, &pCs->arpCom, dataLength);#endif /* BSD43_DRIVER */ /* Another packet successfully received! */ pIf->if_ipackets++; }/********************************************************************************* csRxBuffInit - initializes the receive buffers** This routine initializes the network interface driver's collection of* receive buffers. The receive buffers are allocated from system memory* and linked together in a linked list of free receive buffers.** RETURNS: OK or ERROR*/LOCAL STATUS csRxBuffInit ( CS_SOFTC *pCs ) { CS_RXBUF *pRxBuff; CS_RXBUF *pRxLast; /* Allocate the receive frame buffers */ pCs->pFreeRxBuff = (CS_RXBUF *)malloc (sizeof(CS_RXBUF) * CS_RXBUFCOUNT); if (pCs->pFreeRxBuff == NULL) return (ERROR); /* Link all the receive frame buffers together on the free list */ pRxLast = pCs->pFreeRxBuff + CS_RXBUFCOUNT - 1; for (pRxBuff=pCs->pFreeRxBuff; pRxBuff<pRxLast; pRxBuff++) { pRxBuff->pNext = pRxBuff + 1; pRxBuff->status = CS_RXBUF_FREE; } pRxLast->pNext = NULL; pRxLast->status = CS_RXBUF_FREE; return (OK); }/********************************************************************************* csRxBuffAlloc - removes a receive buffer from the free receive buffer list** This routine removes a receive buffer from the free receive buffer list.** RETURNS: pointer of the buffer*/LOCAL CS_RXBUF *csRxBuffAlloc ( CS_SOFTC *pCs ) { CS_RXBUF *pRxBuff; if (pCs->pFreeRxBuff == NULL) return (NULL); /* Remove a buffer from the free list */ pRxBuff = pCs->pFreeRxBuff; pCs->pFreeRxBuff = pRxBuff->pNext; pRxBuff->pNext = NULL; /* Init the reference count to zero */ pRxBuff->refCount = 0; /* The buffer is now allocated */ pRxBuff->status = CS_RXBUF_ALLOCATED; /* Increment number of receive buffers currently in use */ pCs->rxDepth++; if (pCs->rxDepth > pCs->maxRxDepth) pCs->maxRxDepth = pCs->rxDepth; return (pRxBuff); }/********************************************************************************* csRxBuffFree - returns an allocated receive buffer back to the free list** This routine returns an allocated receive buffer back to the free list.** RETURNS: N/A*/LOCAL void csRxBuffFree ( CS_SOFTC *pCs, CS_RXBUF *pRxBuff ) { int intState = intLock(); /* INT LOCK (csRxBuffAlloc() won't interrupt) */ /* Put the buffer at the head of the free list */ pRxBuff->pNext = pCs->pFreeRxBuff; pCs->pFreeRxBuff = pRxBuff; /* The buffer is now free */ pRxBuff->status = CS_RXBUF_FREE; /* Decrement the outstanding receive depth */ pCs->rxDepth--; /* Re-enable interrupts at the CPU */ intUnlock (intState); /* INT UNLOCK */ }/********************************************************************************* csPacketPageR - reads a word from the PacketPage** This routine reads a word from the PacketPage at the specified offset.** RETURNS: a word in the offset*/LOCAL USHORT csPacketPageR ( CS_SOFTC *pCs, USHORT offset ) { if (pCs->inMemoryMode) { return (*((pCs->pPacketPage) + (offset/2))); } else /* In IO mode */ { USHORT temp; CS_OUT_WORD (pCs->ioAddr + CS_PORT_PKTPG_PTR, offset); CS_IN_WORD (pCs->ioAddr + CS_PORT_PKTPG_DATA, &temp); return (temp); } }/********************************************************************************* csPacketPageW - writes a value to the PacketPage** This routine writes a value to the PacketPage at the specified offset.** RETURNS: N/A*/LOCAL void csPacketPageW ( CS_SOFTC *pCs, USHORT offset, USHORT value ) { if (pCs->inMemoryMode) { *((pCs->pPacketPage) + (offset/2)) = value; } else /* In IO mode */ { CS_OUT_WORD (pCs->ioAddr + CS_PORT_PKTPG_PTR, offset); CS_OUT_WORD (pCs->ioAddr + CS_PORT_PKTPG_DATA, value); } }/********************************************************************************* csError - logs a message to the logging task** This routine logs a message to the logging task if debugging is enabled.** RETURNS: N/A*/LOCAL void csError ( CS_SOFTC *pCs, char *pString ) { /* If debugging is enabled */ if (pCs->arpCom.ac_if.if_flags & IFF_DEBUG) { logMsg ("cs%d - %s\n", pCs->arpCom.ac_if.if_unit, (int)pString, 0, 0, 0, 0); } }/********************************************************************************* csShow - shows statistics for the `cs' network interface** This routine displays statistics about the `cs' Ethernet network interface.* It has two parameters:* .iP <unit>* interface unit; should be 0.* .iP <zap>* if 1, all collected statistics are cleared to zero.* .LP** RETURNS: N/A*/void csShow ( int unit, /* interface unit */ BOOL zap /* zero totals */ ) { FAST CS_SOFTC *pCs = &cs_softc[unit]; struct ifnet *pIf = &pCs->arpCom.ac_if; if (unit >= MAXUNITS) { printf ("cs%d - Invalid unit number\n", unit); return; } if (zap) { /* Reset all the statistics to zero */ pIf->if_ipackets = 0; pIf->if_opackets = 0; pIf->if_ierrors = 0; pIf->if_oerrors = 0; pIf->if_collisions = 0; /* Reset counters to zero */ pCs->rxDepth = 0; pCs->maxRxDepth = 0; pCs->maxTxDepth = 0; pCs->loanCount = 0; } printf ("\n"); printf ("Show cs%d: ", unit); printf ("Crystal Semiconductor CS8900 Network Interface Driver\n"); printf ("I/O Address : 0x%X\n", pCs->ioAddr); printf ("Interrupt Level : %d\n", pCs->intLevel); printf ("Interrupt Vector : %d\n", pCs->intVector); printf ("Access Mode : "); if (pCs->inMemoryMode) { printf ("Memory Mode\n"); printf ("Memory Address : 0x%X\n", (int)pCs->pPacketPage); } else printf ("I/O Mode\n"); printf ("Media Type : "); switch (pCs->mediaType) { case CS_MEDIA_AUI: printf ("AUI\n"); break; case CS_MEDIA_10BASE2: printf ("10Base2\n"); break; case CS_MEDIA_10BASET: if (pCs->configFlags & CS_CFGFLG_FDX) printf ("10BaseT, FDX\n"); else printf ("10BaseT\n"); break; default: printf ("Unknown\n"); break; } printf ("Interface Flags : "); if (pIf->if_flags & IFF_UP) printf ("UP"); else printf ("DOWN"); if (pIf->if_flags & IFF_RUNNING) printf (", RUNNING"); if (pIf->if_flags & IFF_BROADCAST) printf (", BROADCAST"); if (pIf->if_flags & IFF_DEBUG) printf (", DEBUG"); if (pIf->if_flags & IFF_LOOPBACK) printf (", LOOPBACK"); if (pIf->if_flags & IFF_POINTOPOINT) printf (", POINTOPOINT"); if (pIf->if_flags & IFF_NOTRAILERS) printf (", NOTRAILERS"); if (pIf->if_flags & IFF_NOARP) printf (", NOARP"); if (pIf->if_flags & IFF_PROMISC) printf (", PROMISC"); if (pIf->if_flags & IFF_ALLMULTI) printf (", ALLMULTI"); printf ("\n"); printf ("Input Packets : %d\n", pIf->if_ipackets); printf ("Output Packets : %d\n", pIf->if_opackets); printf ("Input Errors : %d\n", pIf->if_ierrors ); printf ("Output Errors : %d\n", pIf->if_oerrors ); printf ("Collisions : %d\n", pIf->if_collisions); printf ("Current Tx Depth : %d\n", pIf->if_snd.ifq_len); printf ("Current Rx Depth : %d\n", pCs->rxDepth); printf ("Maximum Tx Depth : %d\n", pCs->maxTxDepth); printf ("Maximum Rx Depth : %d\n", pCs->maxRxDepth); printf ("Loan Count : %d\n", pCs->loanCount); printf ("\n"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -