📄 if_ex.c
字号:
(FUNCPTR) exRecvAndHang, unit, pMsg->mb_er.er_blks[0].bb_len, pMsg->mb_rply, 0, 0 ); break; case LLRTRANSMIT:#ifdef EX_DEBUG if ((pDrvCtrl->flags & EX_XPENDING) == 0) panic ("exxmit: no xmit pending");#endif /* EX_DEBUG */ pDrvCtrl->flags &= ~EX_XPENDING; if (pMsg->mb_rply == LL_OK) ; else if (pMsg->mb_rply & LLXM_1RTRY) { pDrvCtrl->idr.ac_if.if_collisions++; } else if (pMsg->mb_rply & LLXM_RTRYS) { pDrvCtrl->idr.ac_if.if_collisions += 2; /* guess */ } else if (pMsg->mb_rply & LLXM_ERROR) { pDrvCtrl->idr.ac_if.if_oerrors++; pDrvCtrl->idr.ac_if.if_opackets--;#ifdef EX_DEBUG logMsg ("ex%d: transmit error=%#x\n", unit, pMsg->mb_rply, 0, 0, 0, 0);#endif } if (pDrvCtrl->idr.ac_if.if_snd.ifq_head != NULL)#ifdef BSD43_DRIVER (void)netJobAdd ( (FUNCPTR)exStart, unit, 0, 0, 0, 0);#else (void)netJobAdd ( (FUNCPTR)exStart, (int)pDrvCtrl, 0, 0, 0, 0);#endif break; case LLNET_STSTCS: pDrvCtrl->idr.ac_if.if_ierrors = pDrvCtrl->pStatArray->sa_crc; pDrvCtrl->flags &= ~EX_STATPENDING; break; case LLNET_ADDRS: /* Copy the enet addr from the message to our IDR */ bcopy ( (caddr_t) pMsg->mb_na.na_addrs, (caddr_t) pDrvCtrl->idr.ac_enaddr, sizeof (pDrvCtrl->idr.ac_enaddr) ); break; case LLNET_RECV: case LLNET_MODE: break; } if (sysBus == MULTI_BUS) pDrvCtrl->pDev->bus.multi.xd_porta = 7; /* ack the interrupt */ pMsg->mb_length = MBDATALEN; exGiveRequest (pMsg, pDrvCtrl->pDev); pMsg = pDrvCtrl->pX2HNext = pDrvCtrl->pX2HNext->mb_next; } }/********************************************************************************* exMsgBlkGet - get a request buffer** Fill in standard values, advance pointer.*/LOCAL EX_MSG *exMsgBlkGet ( DRV_CTRL *pDrvCtrl ) { EX_MSG *pMsg; pMsg = pDrvCtrl->pH2XNext;#ifdef EX_DEBUG if ((pMsg->mb_status & MH_OWNER) == MH_EXOS) panic ("ex: EXOS owns message buffer");#endif /* EX_DEBUG */ pMsg->mb_1rsrv = 0; pMsg->mb_length = MBDATALEN; pDrvCtrl->pH2XNext = pDrvCtrl->pH2XNext->mb_next; return (pMsg); }/********************************************************************************* exRecvAndHang - receive packet and post another receive request*/LOCAL void exRecvAndHang ( int unit, int len, int status ) { exRecv (unit, len, status); exRxRqst (unit); }/********************************************************************************* exRecv - process Ethernet receive completion** If input error just drop packet.* Otherwise purge input buffered data path and examine* packet to determine type. If can't determine length* from type, then have to drop packet. Otherwise decapsulate* packet based on type and pass to type-specific higher-level* input routine.*/LOCAL void exRecv ( int unit, int len, int status ) { DRV_CTRL *pDrvCtrl; struct ether_header *eh; MBUF *pMbuf; u_char *pData; pDrvCtrl = & drvCtrl [unit]; if (status != LL_OK) { pDrvCtrl->idr.ac_if.if_ierrors++;#ifdef EX_DEBUG printErr ("ex%d: receive error=%b\n", unit, status, RECV_BITS);#endif return; } /* get input packet length and ptr to packet */ len -= 4; /* subtract FCS */ eh = (struct ether_header *)(pDrvCtrl->pReadBuf); pDrvCtrl->idr.ac_if.if_ipackets++; /* call input hook if any */ if ( etherInputHookRtn != NULL ) { if ( (* etherInputHookRtn)(&pDrvCtrl->idr.ac_if, (char *) eh, len) ) return; /* input hook has already processed this packet */ } /* Subtract header size from length */ len -= SIZEOF_ETHERHEADER; /* Get pointer to packet data */ pData = ((u_char *) eh) + (SIZEOF_ETHERHEADER); pMbuf = copy_to_mbufs (pData, len, 0, & pDrvCtrl->idr.ac_if); if (pMbuf == NULL) /* no room at the inn */ { pDrvCtrl->idr.ac_if.if_ierrors++; return; }#ifdef BSD43_DRIVER do_protocol_with_type (ntohs(eh->ether_type), pMbuf, &pDrvCtrl->idr, len);#else do_protocol (eh, pMbuf, &pDrvCtrl->idr, len);#endif }/********************************************************************************* exRxRqst - send receive request to EXOS** Called by exIntr, with interrupts disabled in both cases.*/LOCAL void exRxRqst ( int unit ) { DRV_CTRL *pDrvCtrl; EX_MSG *pMsg; pDrvCtrl = & drvCtrl [unit]; pMsg = exMsgBlkGet(pDrvCtrl); pMsg->mb_rqst = LLRECEIVE; pMsg->mb_er.er_nblock = 1; pMsg->mb_er.er_blks[0].bb_len = EXMAXRBUF;#if (CPU_FAMILY == SPARC) { ULONG blockAddr; blockAddr = (ULONG) exHostAdrs ((char *) pDrvCtrl->pReadBuf); pMsg->mb_er.er_blks[0].bb_addr[0] = blockAddr >> 16; pMsg->mb_er.er_blks[0].bb_addr[1] = blockAddr & 0xffff; }#else *(char **)pMsg->mb_er.er_blks[0].bb_addr = exHostAdrs ((char *) pDrvCtrl->pReadBuf);#endif /* CPU_FAMILY == SPARC */ exGiveRequest (pMsg, pDrvCtrl->pDev); }#ifdef BSD43_DRIVER/********************************************************************************* exOutput - the output routine*/LOCAL int exOutput ( IDR *pIDR, MBUF *pMbuf, SOCK *pDest ) { return (ether_output ((IFNET*)pIDR, pMbuf, pDest, (FUNCPTR) exStart, pIDR)); }#endif/********************************************************************************* exIoctl - process an ioctl request*/LOCAL int exIoctl ( IDR *pIDR, int cmd, caddr_t data ) { int ret; ret = 0; switch (cmd) { case SIOCSIFADDR: ((struct arpcom *)pIDR)->ac_ipaddr = IA_SIN (data)->sin_addr; arpwhohas (pIDR, &IA_SIN (data)->sin_addr); break; case SIOCSIFFLAGS: /* Flags are set outside this module. No additional work to do. */ break; default: ret = EINVAL; } return (ret); }/********************************************************************************* exHostAdrs - get host address as required by EXOS board** This routine converts the specified local address into the form* that the EXOS board wants to see it, namely converted into* the proper vme address space and, in the VME version, with the* address modifier in the upper byte.** RETURNS: proper EXOS access address or ERROR.*/LOCAL char *exHostAdrs ( char *localAdrs ) { char *busAdrs; if (sysLocalToBusAdrs (exBusAdrsSpace, localAdrs, &busAdrs) != OK) {#ifdef EX_DEBUG printErr ("ex: no bus access to local address 0x%x (AM=0x%x)\n", localAdrs, exBusAdrsSpace);#endif return ((char*)ERROR); } if (sysBus == VME_BUS && !exBit32) { /* EXOS 202 (VME version) requires AM code in upper byte */ busAdrs = (char *) ((int) busAdrs | (exBusAdrsSpace << 24)); } return (busAdrs); }/********************************************************************************* exGiveRequest - give request buffer to EXOS*/LOCAL void exGiveRequest ( EX_MSG *pMsg, /* pointer to msg buffer to give to EXOS */ DEV_CTRL *pDev /* device address */ ) { pMsg->mb_status |= MH_EXOS; /* give request to EXOS */ if (sysBus == VME_BUS) pDev->bus.vme.xd_portb = EX_NTRUPT; else pDev->bus.multi.xd_portb = EX_NTRUPT; }/* END OF FILE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -