📄 smnetlib.c
字号:
== NULL) || (smNetProbe ((void *)&pPktCpuDesc->status, maxTicsWait, TRUE, SM_CPU_ATTACHED) != OK)) { printf ("smNetAttach2: Error: SM probe 4 time out\n"); } else { /* if sequential addressing - can calculate hw address */ CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ tmp = pSmPktHdr->reserved1; /* PCI bug [SPR 68844] */ if (pSmPktHdr->reserved1 != 0) { xs->xs_ac.ac_if.if_resolve = smNetAddrResolve; } cont = TRUE; } } else cont = TRUE; if (cont) { /* * finish attachment by setting current receive state in * SM_SOFTC and connecting the SM interrupt service routine */ xs->taskRecvActive = FALSE; if (smUtilIntConnect (LOW_PRIORITY, (FUNCPTR) smNetIntr, intType, intType, intArg1, intArg2, intArg3) == OK) { return (OK); } } /* clean up before taking error exit */ if_dettach (&xs->xs_if); } (void) free ((caddr_t) xs); return (ERROR); }/******************************************************************************** smNetAttach - attach the shared memory network interface** This routine attaches the shared memory interface to the network. It is* called once by each CPU on the shared memory network. The <unit> parameter* specifies the backplane unit number.** The <pAnchor> parameter is the local address by which the local CPU may* access the shared memory anchor.** The <maxInputPkts> parameter specifies the maximum number of incoming* shared memory packets which may be queued to this CPU at one time.** The <intType>, <intArg1>, <intArg2>, and <intArg3> parameters allow a* CPU to announce the method by which it is to be notified of input packets* which have been queued to it.** RETURNS: OK, or ERROR if the shared memory interface cannot be attached.** NOMANUAL*/STATUS smNetAttach ( int unit, /* interface unit number */ SM_ANCHOR * pAnchor, /* addr of anchor */ int maxInputPkts, /* max queued packets */ int intType, /* interrupt method */ int intArg1, /* interrupt argument #1 */ int intArg2, /* interrupt argument #2 */ int intArg3 /* interrupt argument #3 */ ) { return (smNetAttach2 (unit, pAnchor, maxInputPkts, intType, intArg1, intArg2, intArg3, 0, 0)); }/******************************************************************************** smNetIntr - VxWorks interrupt service routine** This routine is the interrupt service routine for shared memory input* packets. It processes the interrupt (if appropriate) then notifies the* interface of the incomming packet by calling smIfInput via the netTask.** RETURNS: N/A** NOMANUAL*/LOCAL void smNetIntr ( int intType /* interrupt type */ ) { SM_SOFTC * xs; /* softc pointer */ int ix; /* unit */ /* check all SM interfaces for incoming packets */ for (ix = 0; ix < NSM; ix++) { if (((xs = sm_softc [ix]) != NULL) && (xs->smPktDesc.status == SM_CPU_ATTACHED) && (smIfInputCount (xs, xs->smPktDesc.smDesc.cpuNum) > 0)) { if (!xs->taskRecvActive) { xs->taskRecvActive = TRUE; (void) netJobAdd ((FUNCPTR) smIfInput, (int) xs, 0, 0, 0, 0); } } /* if bus interrupt, acknowledge it */ if ((xs != NULL) && (intType == SM_INT_BUS)) sysBusIntAck (xs->smPktDesc.smDesc.intArg1); } }/******************************************************************************** smNetPulse - continually pulse the shared memory heartbeat** This routine maintains the shared memory heart beat by incrementing * the heartbeat count and then re-scheduling itself to run again * after a "beat" has passed.** RETURNS: N/A** NOMANUAL*/LOCAL void smNetPulse ( SM_PKT_MEM_HDR * pSmPktHdr /* pointer to heartbeat */ ) { smPktBeat (pSmPktHdr); (void) wdStart ((WDOG_ID) pSmPktHdr->reserved2, (int) sysClkRateGet (), (FUNCPTR) smNetPulse, (int) pSmPktHdr); }/******************************************************************************** smNetProbe - probe a shared memory location** This routine probes a shared memory location. If the location can be* accessed and the value there is neither zero nor 0xffffffff, OK is returned.* The probe is repeated periodically until the above conditions are met or* until a maximum number of probes has been attempted. If the maximum number* of probes is exceeded, ERROR is returned.** RETURNS: OK if successful probe, otherwise ERROR** NOMANUAL*/LOCAL STATUS smNetProbe ( void * ptr, /* location to probe */ UINT maxTicsWait, /* max system clock ticks period to wait */ BOOL tstEqVal, /* TRUE: test probe value == val */ int val /* specific value for operation */ ) { int probeVal; /* value read during probe */ UINT tics; /* SM probe delay period */ int chkVal = htonl (val); char * cp = (char *)ptr; tics = smUtilProcNumGet (); tics <<= 1; do { smUtilDelay (NULL, tics); if (smUtilMemProbe (cp, READ, 4, (char *)&probeVal) == OK) { if (tstEqVal) { if (probeVal == chkVal) { return (OK); } } else if ((probeVal != (int)~0) && (probeVal != 0)) { return (OK); } } tics <<= 1; } while ((tics < maxTicsWait) && (tics != 0)); return (ERROR); }/******************************************************************************** loanBuild - build an mbuf cluster with a shared memory buffer** This routine calls build cluster to build an mbuf cluster from a shared* memory packet.** RETURNS: pointer to the cluster if successful, otherwise NULL** NOMANUAL*/struct mbuf * loanBuild ( SM_SOFTC * xs, /* softc pointer */ SM_PKT volatile * pPkt, /* shared memory packet */ u_char * pData, /* pointer to data */ int len /* length of packet */ ) { int tmp; /* temp storage */ pPkt->header.type = 0; CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ tmp = pPkt->header.nBytes; /* BRIDGE FLUSH [SPR 68334] */ return (build_cluster (pData, len, &xs->xs_if, MC_BACKPLANE, (u_char *)&(pPkt->header.type), (FUNCPTR)smIfLoanReturn, (int) xs, (int) pPkt, 0)); }/******************************************************************************** smNetInetGet - get address associated with a shared memory network interface** This routine returns the IP address in <smInet> for the CPU* specified by <cpuNum> on the shared memory network specified by <smName>.* If <cpuNum> is NONE (-1), this routine returns information about the local* (calling) CPU.** This routine can only be called after a call to smNetAttach(). It will* block if the shared memory region has not yet been initialized.** This routine is only applicable if sequential addressing is being used* over the backplane.** RETURNS: OK, or ERROR if the Internet address cannot be found.** NOMANUAL*/STATUS smNetInetGet ( char * smName, /* device name */ char * smInet, /* return inet */ int cpuNum /* cpu number */ ) { SM_SOFTC * xs; /* softc pointer */ SM_ANCHOR volatile * pAnchor; /* ptr to anchor */ SM_PKT_MEM_HDR volatile * pSmPktHdr; /* packet header */ struct in_addr smAddr; /* address */ int tmp; /* temp storage */ if ((xs = (SM_SOFTC *) ifunit (smName)) == NULL) { printf ("smNetInetGet:%s not attached\n", smName); return (ERROR); } pAnchor = (SM_ANCHOR volatile *) xs->smPktDesc.smDesc.anchorLocalAdrs; if (smIsAlive ((SM_ANCHOR *)pAnchor, (int *)&pAnchor->smPktHeader, xs->smPktDesc.smDesc.base, 0, 0) == FALSE) { return (ERROR); } pSmPktHdr = SM_OFFSET_TO_LOCAL (ntohl (pAnchor->smPktHeader), xs->smPktDesc.smDesc.base, SM_PKT_MEM_HDR volatile *); CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ tmp = pSmPktHdr->reserved1; /* PCI bug [SPR 68844] */ if (pSmPktHdr->reserved1 == 0) { /* no sequential addressing */ return (ERROR); } if (cpuNum == NONE) { cpuNum = xs->smPktDesc.smDesc.cpuNum; } smAddr.s_addr = htonl (ntohl (pSmPktHdr->reserved1) + cpuNum); inet_ntoa_b (smAddr, smInet); return (OK); }/******************************************************************************** smNetAddrResolve - resolve an Ethernet address** This routine converts a destination IP address into a destination* Ethernet address. It only resolves the address if sequential addressing* is being used and the destination is attached to shared memory.** RETURNS: OK if successful, otherwise ERROR.** NOMANUAL*/LOCAL STATUS smNetAddrResolve ( struct ifnet * pIf, /* ifnet pointer */ struct in_addr * pIpDest, /* dest ip address */ u_char * pHwDest, /* return hardware address */ int * usetrailers /* not used */ ) { SM_PKT_CPU_DESC volatile * pPktCpuDesc; u_long dstHostAddr; int destCpu; int tmp; /* temp storage */ SM_SOFTC * xs = sm_softc [pIf->if_unit]; /*softc pointer*/ if (xs->masterAddr == 0) return (ERROR); /* sequential addressing not enabled */ dstHostAddr = pIpDest->s_addr & 0x00ffffff; destCpu = dstHostAddr - xs->masterAddr; if ((destCpu < 0) || (destCpu >= xs->smPktDesc.smDesc.maxCpus)) return (ERROR); pPktCpuDesc = &((xs->smPktDesc.cpuLocalAdrs) [destCpu]); CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ tmp = pPktCpuDesc->status; /* PCI bug [SPR 68844] */ if (pPktCpuDesc->status != SM_CPU_ATTACHED) return (ERROR); /* * Synthesize SM physical (MAC) address. * * Under IPv4, SM ethernet physical addresses (EUI-48) consist of 48 bits: * { 0x00, 0x02, 0xE2, hostIpAdrs[3], hostIpAdrs[4], hostIpAdrs[5] } * * Under IPv6 (EUI-64) the 64-bit format is: * { 0x00, 0x02, 0xE2, 0xFF, 0xFE, * hostIpAdrs[3], hostIpAdrs[4], hostIpAdrs[5] } * * XXXmas: FUTURE: The most significant 24 bits are the vendor ID. Wind * River's vendor ID is 0x00 0x40 0x47, not 0x00 0x02 0xE2! Must be * changed in next major release. */ pHwDest [0] = 0x00; pHwDest [1] = 0x02; pHwDest [2] = 0xE2; pHwDest [3] = (u_char)((dstHostAddr >> 16) & 0xff); pHwDest [4] = (u_char)((dstHostAddr >> 8) & 0xff); pHwDest [5] = (u_char)(dstHostAddr & 0xff); /* entered into arp table for efficency */ arpCmd ((int)SIOCSARP, pIpDest, pHwDest, NULL); *usetrailers = 0; return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -