📄 if_ex.c
字号:
pMsg = exMsgBlkGet (pDrvCtrl); pMsg->mb_rqst = LLNET_ADDRS; pMsg->mb_na.na_mask = READ_OBJ; pMsg->mb_na.na_slot = PHYSSLOT; exGiveRequest (pMsg, pDrvCtrl->pDev); for ( loopy = 10; ; loopy-- ) { taskDelay (10); if ( *(long *)pDrvCtrl->idr.ac_enaddr ) /* check 'sync flag' */ break; if ( loopy < 0 ) /* if reached retry limit */ return (ERROR); } /* Enable the EXOS board onto the Ethernet, using NET_MODE command */ pMsg = exMsgBlkGet (pDrvCtrl); pMsg->mb_rqst = LLNET_MODE; pMsg->mb_nm.nm_mask = WRITE_OBJ; pMsg->mb_nm.nm_optn = 0; pMsg->mb_nm.nm_mode = MODE_PERF; exGiveRequest (pMsg, pDrvCtrl->pDev); exRxRqst (unit); /* post a receive request */ /* Set flags */ pDrvCtrl->attached = TRUE; pDrvCtrl->idr.ac_if.if_flags |= ( IFF_RUNNING | IFF_UP | IFF_NOTRAILERS ); pDrvCtrl->flags = EX_RUNNING; return (OK); }/********************************************************************************* exReset - reset the EXOS board and bring down interface*/LOCAL void exReset ( int unit ) { int temp; DRV_CTRL *pDrvCtrl; /* Sanity check the unit number */ if (unit < 0 || unit >= MAX_UNITS) return; pDrvCtrl = & drvCtrl [unit]; pDrvCtrl->idr.ac_if.if_flags = 0; pDrvCtrl->flags &= ~EX_RUNNING; if (sysBus == VME_BUS) pDrvCtrl->pDev->bus.vme.xd_porta = EX_RESET; else temp = pDrvCtrl->pDev->bus.multi.xd_porta; /* access location */ }/********************************************************************************* exConfig - configure EXOS board** Reset, test, and configure EXOS.*/LOCAL STATUS exConfig ( int unit, int itype /* interrupt type */ ) { char val; /* sizeof xd_porta */ int ix; u_long shiftreg; DRV_CTRL *pDrvCtrl; DEV_CTRL *pDev; CFG_MSG *pCfgMsg; pDrvCtrl = & drvCtrl [unit]; pDev = pDrvCtrl->pDev; pCfgMsg = pDrvCtrl->pCfgMsg; /* Reset EXOS via probe (in case board doesn't exist) */ if (sysBus == VME_BUS) { val = EX_RESET; if (vxMemProbe ((char *)&pDev->bus.vme.xd_porta, O_WRONLY, sizeof (pDev->bus.vme.xd_porta), &val) == ERROR) { errnoSet (S_iosLib_CONTROLLER_NOT_PRESENT); return (ERROR); } } else { if (vxMemProbe ((char *)&pDev->bus.multi.xd_porta, O_RDONLY, sizeof (pDev->bus.multi.xd_porta), &val) == ERROR) { errnoSet (S_iosLib_CONTROLLER_NOT_PRESENT); return (ERROR); } } /* wait for test to complete (10 secs max) */ for (ix = 10 * sysClkRateGet (); ix > 0; ix--) { if (sysBus == VME_BUS) { if ((pDev->bus.vme.xd_portb & EX_TESTOK) != 0) break; } else { if ((pDev->bus.multi.xd_portb & EX_TESTOK) != 0) break; } taskDelay (1); } if (ix == 0) {#ifdef EX_DEBUG printErr ("ex%d: self-test failed.\n", unit);#endif errnoSet (S_ioLib_DEVICE_ERROR); return (ERROR); } /* Write address modifier to Port C on EXOS 302 (after reset). */ if (sysBus == VME_BUS && exBit32) pDrvCtrl->pDev->bus.vme.xd_portc = exBusAdrsSpace; /* Set up configuration message. */ pCfgMsg->cm_1rsrv = 1; pCfgMsg->cm_cc = 0xFF; pCfgMsg->cm_opmode = 0; /* link-level controller mode */ pCfgMsg->cm_dfo = 0x0101; /* enable host data order conversion */ pCfgMsg->cm_dcn1 = 1; pCfgMsg->cm_2rsrv[0] = 0; pCfgMsg->cm_2rsrv[1] = 0; pCfgMsg->cm_ham = 3; /* absolute address mode */ pCfgMsg->cm_3rsrv = 0; pCfgMsg->cm_mapsiz = 0; pCfgMsg->cm_byteptrn[0] = 0x01; /* EXOS deduces data order of host */ pCfgMsg->cm_byteptrn[1] = 0x03; /* by looking at this pattern */ pCfgMsg->cm_byteptrn[2] = 0x07; pCfgMsg->cm_byteptrn[3] = 0x0F; pCfgMsg->cm_wordptrn[0] = 0x0103; pCfgMsg->cm_wordptrn[1] = 0x070F; pCfgMsg->cm_lwordptrn = 0x0103070F; for (ix = 0; ix < 20; ix++) pCfgMsg->cm_rsrvd[ix] = 0; pCfgMsg->cm_mba = 0xFFFFFFFF; pCfgMsg->cm_nproc = 0xFF; pCfgMsg->cm_nmbox = 0xFF; pCfgMsg->cm_nmcast = 0xFF; pCfgMsg->cm_nhost = 1; pCfgMsg->cm_h2xba = (u_long) exHostAdrs ( (char *) pCfgMsg ); pCfgMsg->cm_h2xhdr = (u_short) ( (int)(pDrvCtrl->pH2XHdr) - (int)pCfgMsg ); pCfgMsg->cm_h2xtyp = 0; /* should never wait for rqst buffer */ pCfgMsg->cm_x2hba = pCfgMsg->cm_h2xba; pCfgMsg->cm_x2hhdr = (u_short) ( (int)(pDrvCtrl->pX2HHdr) - (int)pCfgMsg ); pCfgMsg->cm_x2htyp = itype; /* 0=none, 4=vectored, 3=level */ if (sysBus == VME_BUS) pCfgMsg->cm_x2haddr = pDrvCtrl->ivec; /* * Write config msg address to EXOS and wait for * configuration to complete (guaranteed response within 2 seconds). */ shiftreg = (u_long)0x0000FFFF; for (ix = 0; ix < 8; ix++) { if (ix == 4) shiftreg = (u_long) exHostAdrs ((char *)pCfgMsg); if (sysBus == VME_BUS) { while (pDev->bus.vme.xd_portb & EX_UNREADY) ; pDev->bus.vme.xd_portb = (u_char)(shiftreg & 0xFF); } else { while (pDev->bus.multi.xd_portb & EX_UNREADY) ; pDev->bus.multi.xd_portb = (u_char)(shiftreg & 0xFF); } shiftreg >>= 8; } for (ix = 3 * sysClkRateGet (); (pCfgMsg->cm_cc == 0xFF) && ix; --ix) taskDelay (1); if (pCfgMsg->cm_cc) {#ifdef EX_DEBUG printErr ( "ex%d: configuration failed; cc=0x%x\n", unit, pCfgMsg->cm_cc );#endif errnoSet (S_ioLib_DEVICE_ERROR); return (ERROR); } return (OK); }/********************************************************************************* exStart - start or re-start output on interface** Get another datagram to send off of the interface queue,* and map it to the interface before starting the output.* This routine is called by exOutput(), and exIntr().* In all cases, interrupts by EXOS are disabled.*/#ifdef BSD43_DRIVERLOCAL void exStart ( int unit ) { DRV_CTRL *pDrvCtrl;#elseLOCAL void exStart ( DRV_CTRL * pDrvCtrl ) {#endif EX_MSG *pMsg; MBUF *pMbuf; int len; int s;#ifdef BSD43_DRIVER pDrvCtrl = & drvCtrl [unit];#endif s = splnet (); if ((pDrvCtrl->flags & EX_XPENDING) == 0 && pDrvCtrl->idr.ac_if.if_snd.ifq_head != NULL) { IF_DEQUEUE(&pDrvCtrl->idr.ac_if.if_snd, pMbuf); /* copy packet to write buffer */ copy_from_mbufs (pDrvCtrl->pWriteBuf, pMbuf, len); /* Adjust length to ensure minimum packet size */ len = max (ETHERSMALL, len); /* Place a transmit request. */#if (CPU_FAMILY == SPARC) { ULONG blockAddr; pMsg = exMsgBlkGet (pDrvCtrl); pMsg->mb_rqst = LLRTRANSMIT; pMsg->mb_et.et_nblock = 1; pMsg->mb_et.et_blks[0].bb_len = (u_short)len; blockAddr = (ULONG) exHostAdrs ((char *) pDrvCtrl->pWriteBuf); pMsg->mb_et.et_blks[0].bb_addr[0] = blockAddr >> 16; pMsg->mb_et.et_blks[0].bb_addr[1] = blockAddr & 0xffff; }#else /* CPU_FAMILY == SPARC */ pMsg = exMsgBlkGet (pDrvCtrl); pMsg->mb_rqst = LLRTRANSMIT; pMsg->mb_et.et_nblock = 1; pMsg->mb_et.et_blks[0].bb_len = (u_short)len; *(char **)pMsg->mb_et.et_blks[0].bb_addr = exHostAdrs ((char *) pDrvCtrl->pWriteBuf);#endif /* CPU_FAMILY == SPARC */ pDrvCtrl->flags |= EX_XPENDING; /* indicate that xmit in progress */ exGiveRequest (pMsg, pDrvCtrl->pDev);#ifndef BSD43_DRIVER /* BSD 4.4 ether_output() doesn't bump statistic. */ pDrvCtrl->idr.ac_if.if_opackets++;#endif } splx (s); }/********************************************************************************* exIntr - interrupt handler** This routine is called at interrupt level in response to an interrupt from* the controller.*/LOCAL void exIntr ( int unit ) { DRV_CTRL *pDrvCtrl; EX_MSG *pMsg; pDrvCtrl = & drvCtrl [unit]; pMsg = pDrvCtrl->pX2HNext; sysBusIntAck (pDrvCtrl->ilevel); /* acknowledge interrupt */ while ((pMsg->mb_status & MH_OWNER) == MH_HOST) { switch (pMsg->mb_rqst) { case LLRECEIVE: (void) netJobAdd (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -