📄 if_enp.c
字号:
/********************************************************************************* enpgetaddr - get hardwired ethernet address.** Read the ethernet address off the board, one byte at a time.** INTERNAL* CMC changed the LINK-10 ROMs and did not make the change* to ENPDEVICE backward compatable with v3.x.* To determine the proper ENPDEVICE structure (or rather LINK-10* revision) the Ethernet base address should be 0.* If it is we assume that the LINK-10 PROMs are v4.0.* This assumtion is based on the hope that the new LINK-10 ROMs will* leave the RING32 buffers that were inserted in the ENPDEVICE structure* set to 0 after a reset. This seems to work. (see if_enp.h for differences* in the ENPDEVICE structure).* The fields e_stat, and/or e_netaddr (AKA enp_stat and enp_addr) should* are dependent on the ROM version.*/LOCAL void enpgetaddr ( int unit ) { DRV_CTRL *pDrvCtrl = & drvCtrl[unit]; ENPDEVICE_OLD *oldaddr = (ENPDEVICE_OLD *) pDrvCtrl->enpAddr; ENPDEVICE *addr = pDrvCtrl->enpAddr; USHORT *pChk = (USHORT *) &oldaddr->enp_addr.e_baseaddr; /* check version of LINK-10 PROMs */ enpNewROM = (*pChk == 0x00); /* TRUE = new ROMs */ if (enpNewROM) { bcopyBytes ( (caddr_t) & addr->enp_addr.e_baseaddr, (caddr_t) pDrvCtrl->idr.ac_enaddr, sizeof (pDrvCtrl->idr.ac_enaddr) ); } else { /* CMC LINK-10 v4.0 PROMs */ bcopyBytes ( (caddr_t) & oldaddr->enp_addr.e_baseaddr, (caddr_t) pDrvCtrl->idr.ac_enaddr, sizeof (pDrvCtrl->idr.ac_enaddr) ); } }/********************************************************************************* enpringempty - check for ring empty.** RETURNS: TRUE or FALSE*/LOCAL BOOL enpringempty ( RING *rp ) { return (rp->r_rdidx == rp->r_wrtidx); }/********************************************************************************* enpringput - write to next ring location** RETURNS: Number of entries left in ring or 0 if full.*/LOCAL int enpringput ( RING *rp, BCB *pBCB ) { int idx; int wrtidx = ntohs (rp->r_wrtidx); int rdidx = ntohs (rp->r_rdidx); int size = ntohs (rp->r_size); idx = (wrtidx + 1) & (size-1); if (idx != rdidx) { pBCB = (BCB *) htonl ((u_long) pBCB); WRITELONG (&rp->r_slot[ wrtidx ], pBCB); rp->r_wrtidx = htons (idx); CACHE_PIPE_FLUSH (); if ((idx -= rdidx) < 0) idx += size; return (idx); /* num ring entries */ } return (0); }/********************************************************************************* enpringget - get the next item from a ring** RETURNS: Pointer to next item or 0 if none.*/LOCAL int enpringget ( RING *rp ) { int buf = 0; int wrtidx = ntohs (rp->r_wrtidx); int rdidx = ntohs (rp->r_rdidx); int size = ntohs (rp->r_size); if (rdidx != wrtidx) { READLONG (&rp->r_slot [rdidx], &buf); buf = ntohl (buf); rp->r_rdidx = htons ((++rdidx) & (size-1)); CACHE_PIPE_FLUSH (); } return (buf); }/********************************************************************************* enpShow - show ENP-10 statistics** INTERNAL* This works only on some versions of the ENP 10/L onboard software* e.g. LINK-10 4.0 is fine, 3.1 is not.** RETURNS: 0** NOMANUAL*/STATUS enpShow ( int unit, /* interface unit */ BOOL zap /* zero totals */ ) { int ix; int status; DRV_CTRL *pDrvCtrl; ENPDEVICE *addr; ENPDEVICE_OLD *oldaddr; static char *e_message [] = { "successful transmissions", "multiple retries on xmit", "single retries", "too many retries", "transmission delayed", "xmit data chaining failed", "transmit data fetch failed", "collision after xmit", "lost carrier", "xmit length > 1518", "transceiver mismatch", "xmit memory error", "good receptions", "no recv buff available", "checksum failed", "crc error AND data length != 0 mod 8", "rcv data chain failure", "receive data store failed", "rcv memory error" }; /* Safety check unit number */ if (unit < 0 || unit >= MAX_UNITS) { errnoSet (S_iosLib_CONTROLLER_NOT_PRESENT); return (ERROR); } pDrvCtrl = & drvCtrl [unit]; addr = pDrvCtrl->enpAddr; oldaddr = (ENPDEVICE_OLD *) pDrvCtrl->enpAddr; printf ("enp%d (v%s):\n", unit, (enpNewROM ? "4.x" : "3.x")); for (ix = 0; ix < NELEMENTS(e_message); ix++) { if (enpNewROM) { READLONG ((&addr->enp_stat.e_stat [ix]), &status); } else { READLONG ((&oldaddr->enp_stat.e_stat [ix]), &status); } status = ntohl (status); printf (" %-30.30s %4d\n", e_message [ix], status - pDrvCtrl->enpStat.e_stat [ix]); if (zap) pDrvCtrl->enpStat.e_stat [ix] = status; } return (OK); }#if FALSE/********************************************************************************* enpDumpRing - dump particular ring** RETURNS: N/A*/LOCAL void enpDumpRing (rn, rp) char *rn; /* ring name */ RING32 *rp; /* ring pointer */ { int ix; int temp; printf (" %s: rdidx = 0x%04.4x, wridx = 0x%04.4x, size = 0x%04.4x\n", rn, ntohs (rp->r_rdidx), ntohs (rp->r_wrtidx), ntohs (rp->r_size)); for (ix = 0; ix < 32;) { if ((ix % 6) == 0) printf (" "); READLONG (&rp->r_slot[ix], &temp); printf ("%02.2d:%08.8x ", ix , ntohl (temp)); if ((++ix % 6) == 0) printf ("\n"); } printf ("\n"); }/********************************************************************************* enpDump - dump ring** RETURNS: N/A** NOMANUAL*/void enpDump (unit, ring) int unit; /* interface unit */ BOOL ring; /* true if dump ring structure */ { DRV_CTRL *pDrvCtrl = & drvCtrl[unit]; ENPDEVICE *addr = pDrvCtrl->enpAddr; ENPDEVICE_OLD *oldaddr = (ENPDEVICE_OLD *) pDrvCtrl->enpAddr; int temp; if (enpNewROM) { temp = ntohs (addr->enp_state); printf ("enp%d: is %s\n", unit, temp & S_ENPRUN ? "running" : "down!"); if ((temp & S_ENPRUN) == 0x0) return; printf (" state = 0x%04.4x, mode = 0x%04.4x\n", ntohs (addr->enp_state), ntohs (addr->enp_mode) ); READLONG (&addr->enp_base, &temp); printf (" base = 0x%08.8x\n", ntohl (temp)); printf (" run = 0x%04.4x, ivec = 0x%04.4x\n\n", ntohs (addr->enp_enprun), ntohs (addr->enp_intvector)); if (ring) { enpDumpRing ("toenp", &addr->enp_toenp); enpDumpRing ("hostfree", &addr->enp_hostfree); enpDumpRing ("tohost", &addr->enp_tohost); enpDumpRing ("enpfree", &addr->enp_enpfree); /* enpDumpRing ("rcvdma", &addr->enp_rcvdma); */ /* enpDumpRing ("rcv_d", &addr->enp_rvc_d); */ } } else { temp = ntohs (oldaddr->enp_state); printf ("enp%d: is %s\n", unit, temp & S_ENPRUN ? "running" : "down!"); if ((temp & S_ENPRUN) == 0x0) return; printf (" state = 0x%04.4x, mode = 0x%04.4x\n", ntohs (oldaddr->enp_state), ntohs (oldaddr->enp_mode) ); READLONG (&oldaddr->enp_base, &temp); printf (" base = 0x%08.8x\n", ntohl (temp)); printf (" run = 0x%04.4x, ivec = 0x%04.4x\n\n", ntohs (oldaddr->enp_enprun), ntohs (oldaddr->enp_intvector)); if (ring) { enpDumpRing ("toenp", &oldaddr->enp_toenp); enpDumpRing ("hostfree", &oldaddr->enp_hostfree); enpDumpRing ("tohost", &oldaddr->enp_tohost); enpDumpRing ("enpfree", &oldaddr->enp_enpfree); } } }#endif /* FALSE */#ifdef BSD43_DRIVER#include "sys/socket.h"/********************************************************************************* convertDestAddr - converts socket addr into enet addr and packet type**/static BOOL convertDestAddr ( IDR *pIDR, /* ptr to i/f data record */ SOCK *pDestSktAddr, /* ptr to a generic sock addr */ char *pDestEnetAddr, /* where to write enet addr */ u_short *pPacketType, /* where to write packet type */ MBUF *pMbuf /* ptr to mbuf data */ ) { extern BOOL arpresolve(); /* we call this */ /***** Internet family *****/ { struct in_addr destIPAddr; /* not used */ int trailers; /* not supported */ if (pDestSktAddr->sa_family == AF_INET) { *pPacketType = htons(ETHERTYPE_IP); /* stuff packet type */ destIPAddr = ((struct sockaddr_in *) pDestSktAddr)->sin_addr; if (!arpresolve (pIDR, pMbuf, &destIPAddr, pDestEnetAddr, &trailers)) return (FALSE); /* if not yet resolved */ return (TRUE); } } /***** Generic family *****/ { ENET_HDR *pEnetHdr; if (pDestSktAddr->sa_family == AF_UNSPEC) { pEnetHdr = (ENET_HDR *) pDestSktAddr->sa_data; /* ptr to hdr */ bcopy (pEnetHdr->dst, pDestEnetAddr, 6); /* copy dst addr */ *pPacketType = htons(pEnetHdr->type); /* copy type */ return (TRUE); } } /* Unsupported family */ return (FALSE); } /* End of convertDestAddr() */#endif/* END OF FILE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -