smNetLib.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:25k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* smNetLib.c - VxWorks interface to shared memory network (backplane) driver*/
  2. /* Copyright 1984-2002 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01v,05apr02,mas  added volatile pointers and bridge flushing reads (SPRs 68334,
  7.  68844)
  8. 01u,13feb02,mas  fixed staged delay/check for slave node startup (SPR 73163)
  9. 01t,24oct01,mas  fixed diab warnings (SPR 71120); doc update (SPR 71149)
  10. 01s,02oct01,mas  added staged delay/check for slave node startup in new
  11.  smNetAttach2() routine (SPR 4547)
  12. 01r,15may95,vin  fixed parameter to build_cluster().
  13. 01q,30sep93,rrr  Added missing 01p modhist.
  14. 01p,30sep93,rrr  Fixed smNetIntr from using an uninialized variable if
  15.                  intType==SM_INT_BUS.
  16. 01o,21nov92,jdi  documentation cleanup.
  17. 01n,13oct92,jcf  added a hack to protect from bus error during attach.
  18. 01m,20oct92,pme  made smNetInit return ERROR instead of disabling data cache
  19.  if cache coherent buffer cannot be allocated.
  20. 01l,09sep92,gae  doc tweaks.
  21. 01k,31jul92,dnw  Changed to new cacheLib.
  22. 01j,27jul92,elh  Moved smNetShow to smNetShow.c
  23. 01i,26jul92,gae  fixed number of parameters to logMsg().
  24. 01h,24jul92,elh  added caching, ripple effect of moving heartbeat.
  25. 01g,15jun92,elh  changed parameter to smNetInetGet.
  26. 01f,02jun92,elh  the tree shuffle
  27.   -changed includes to have absolute path from h/
  28. 01e,27may92,elh  Incorperated the changes caused from restructuring the
  29.  shared memory libraries.
  30. 01d,17may92,elh  renamed from smVxLib to smNetLib
  31. 01c,01may92,elh  added mask, if_resolve hook and smNetAddrResolve.
  32. 01b,12apr92,elh  added support for sequential addressing.
  33. 01a,17nov90,elh  written.
  34. */
  35. /*
  36. DESCRIPTION
  37. This library implements the VxWorks-specific portions of the shared memory
  38. network interface driver.  It provides the interface between VxWorks and
  39. the network driver modules (e.g., how the OS initializes and attaches
  40. the driver, interrupt handling, etc.), as well as VxWorks-dependent
  41. system calls.  
  42. There are no user-callable routines.
  43. The backplane master initializes the backplane shared memory and network
  44. structures by first calling smNetInit().  Once the backplane has been
  45. initialized, all processors can be attached to the shared memory network via
  46. the smNetAttach() routine.  Both smNetInit() and smNetAttach() are called
  47. automatically during system initialization when backplane parameters are
  48. specified in the boot line.
  49. For detailed information refer to 
  50. tb VxWorks Network Programmer's Guide: Data Link Layer Network Compnents.
  51. INTERNAL
  52. This file used to correspond to the smNetLib for SunOS.  SunOS is no longer
  53. supported. 
  54. The smNetInetGet() routine gets the Internet address associated with a
  55. backplane interface.
  56. Refer to if_sm.c for more information about the layering of backplane modules.
  57. INCLUDE FILES: smNetLib.h, smPktLib.h, smUtilLib.h
  58. SEE ALSO: ifLib, if_sm,
  59. tb VxWorks Network Programmer's Guide
  60. NOROUTINES
  61. */
  62. /* includes */
  63. #include "vxWorks.h"
  64. #include "net/if.h"
  65. #include "netinet/if_ether.h"
  66. #include "net/mbuf.h"
  67. #include "arpLib.h"
  68. #include "wdLib.h"
  69. #include "sysLib.h"
  70. #include "iv.h"
  71. #include "vxLib.h"
  72. #include "taskLib.h"
  73. #include "stdlib.h"
  74. #include "intLib.h"
  75. #include "stdio.h"
  76. #include "logLib.h"
  77. #include "netLib.h"
  78. #include "cacheLib.h"
  79. #include "drv/netif/if_sm.h"
  80. #include "drv/netif/smNetLib.h"
  81. #include "smPktLib.h"
  82. #include "smUtilLib.h"
  83. /* globals */
  84. int smNetVerbose = FALSE; /* debug aide */
  85. int  smNetMaxBytesDefault  = DEFAULT_PKT_SIZE; /* packet size */
  86. int smNetLoanNum = 0; /* buffers to loan */
  87. SM_SOFTC * sm_softc [NSM] = { NULL }; /* soft_c structures */
  88. /* forward declarations */
  89. LOCAL STATUS    smNetAddrResolve (struct ifnet * pIf, struct in_addr * pIpDest,
  90.  u_char * pHwDest, int * usetrailers);
  91. LOCAL void smNetIntr (int intType);
  92. LOCAL void smNetPulse (SM_PKT_MEM_HDR * pSmPktHdr);
  93. LOCAL STATUS smNetProbe
  94.     (
  95.     void * ptr, /* location to probe */
  96.     UINT   maxTicsWait, /* max system clock ticks period to wait */
  97.     BOOL   tstEqVal, /* TRUE: test probe value == val */
  98.     int    val /* specific value for operation */
  99.     );
  100. /* externs */
  101. IMPORT void if_dettach (struct ifnet *);
  102. /******************************************************************************
  103. *
  104. * smNetInit - initialize the shared memory network driver
  105. *
  106. * This routine is called once by the backplane master.  It sets up and 
  107. * initializes the shared memory region of the shared memory network and 
  108. * starts the shared memory heartbeat.  
  109. *
  110. * The <pAnchor> parameter is the local memory address by which the master
  111. * CPU accesses the shared memory anchor.  <pMem> contains either the local
  112. * address of shared memory or the value NONE (-1), which implies that shared
  113. * memory is to be allocated dynamically.  <memSize> is the size, in bytes,
  114. * of the shared memory region.
  115. *
  116. * The <tasType> parameter specifies the test-and-set operation to be used to
  117. * obtain exclusive access to the shared data structures.  It is preferable
  118. * to use a genuine test-and-set instruction, if the hardware permits it.  In
  119. * this case, <tasType> should be SM_TAS_HARD.  If any of the CPUs on the
  120. * backplane network do not support the test-and-set instruction, <tasType>
  121. * should be SM_TAS_SOFT.
  122. *
  123. * The <maxCpus> parameter specifies the maximum number of CPUs that may
  124. * use the shared memory region.
  125. *
  126. * The <maxPktBytes> parameter specifies the size, in bytes, of the data
  127. * buffer in shared memory packets.  This is the largest amount of data
  128. * that may be sent in a single packet.  If this value is not an exact
  129. * multiple of 4 bytes, it will be rounded up to the next multiple of 4.
  130. *
  131. * The <startAddr> parameter is only applicable if sequential addressing is
  132. * desired.  If <startAddr> is non-zero, it specifies the starting address to
  133. * use for sequential addressing on the backplane.  If <startAddr> is zero,
  134. * sequential addressing is disabled.
  135. *
  136. * RETURNS: OK, or ERROR if the shared memory network cannot be initialized.
  137. *
  138. * NOMANUAL
  139. */
  140. STATUS smNetInit
  141.     (
  142.     SM_ANCHOR * pAnchor, /* local addr of anchor */
  143.     char * pMem, /* local addr of shared memory */
  144.     int memSize, /* size of shared memory */
  145.     BOOL tasType, /* TRUE = hardware supports TAS */
  146.     int cpuMax, /* max numbers of cpus */
  147.     int maxPktBytes,  /* size of data packets */
  148.     u_long startAddr  /* beginning address */
  149.     )
  150.     {
  151.     SM_ANCHOR volatile * pAnchorv = (SM_ANCHOR volatile *) pAnchor;
  152.     SM_PKT_MEM_HDR volatile * pSmPktHdr;   /* packet header */
  153.     WDOG_ID beatWd;
  154.     BOOL malloced = FALSE; /* malloced memory here! */
  155.     /* validate parameters */
  156.     if ((pAnchor == NULL) || (pMem == NULL))
  157. {
  158. logMsg ("smNetInit: invalid %sn", (pAnchor == NULL) ?
  159. (int) "pAnchor" : (int) "pMem", 0, 0, 0, 0, 0);
  160. return (ERROR);
  161. }
  162.     if (sysProcNumGet () != SM_MASTER)
  163. {
  164. logMsg ("smNetInit:called by cpu [%d] non-mastern", sysProcNumGet(),
  165. 0, 0, 0, 0, 0);
  166. return (ERROR);
  167. }
  168.     maxPktBytes = (maxPktBytes == 0) ?  smNetMaxBytesDefault : maxPktBytes;
  169.     if ((startAddr != 0) && (smNetVerbose))
  170. logMsg ("smNetInit:sequential addressing activated (0x%x) n", 
  171. startAddr, 0, 0, 0, 0, 0);
  172.     if (pMem == (char *) NONE)  /* allocate the shared memory */
  173. {
  174. if (!CACHE_DMA_IS_WRITE_COHERENT () || !CACHE_DMA_IS_READ_COHERENT ())
  175.     {
  176.     logMsg ("smNetInit - cache coherent buffer not available. Giving up. n", 0, 0, 0, 0, 0, 0);
  177.     return (ERROR);
  178.     }
  179.      if ((pMem = (char *) cacheDmaMalloc (memSize)) == NULL)
  180.          return (ERROR);
  181.      malloced = TRUE;
  182.         }
  183.     else
  184. {
  185.      if (pMem == (char *) pAnchor)
  186.     {
  187.     pMem    +=  sizeof (SM_ANCHOR);
  188.     memSize -=  sizeof (SM_ANCHOR);
  189.     }
  190. }
  191.     if (smNetVerbose)
  192. logMsg ("smNetInit: anchor:[0x%x] memory:[0x%x] size:%d n",
  193. (int) pAnchor, (int) pMem, memSize, 0, 0, 0);
  194.     /* set up shared memory region */
  195.     if ((smPktSetup (pAnchor, pMem, memSize, tasType, cpuMax,
  196.      maxPktBytes + SIZEOF_ETHERHEADER) == OK) &&
  197.   ((beatWd = wdCreate ()) != NULL))
  198. {
  199.         pSmPktHdr = SM_OFFSET_TO_LOCAL(ntohl (pAnchorv->smPktHeader),
  200.        (int)pAnchor, SM_PKT_MEM_HDR volatile *);
  201.      pSmPktHdr->reserved1 = htonl (startAddr);
  202.         pSmPktHdr->reserved2 = (int) beatWd;
  203.         CACHE_PIPE_FLUSH ();                  /* CACHE FLUSH   [SPR 68334] */
  204.         maxPktBytes = pSmPktHdr->maxPktBytes; /* BRIDGE FLUSH  [SPR 68334] */
  205.         /* start heartbeat */
  206.         smNetPulse ((SM_PKT_MEM_HDR *)pSmPktHdr);
  207. return (OK);
  208. }
  209.     if (malloced)
  210. (void) free (pMem);
  211.     return (ERROR);
  212.     }
  213. /******************************************************************************
  214. *
  215. * smNetAttach2 - attach the shared memory network interface
  216. *
  217. * This routine attaches the shared memory interface to the network.  It is
  218. * called once by each CPU on the shared memory network.  The <unit> parameter
  219. * specifies the backplane unit number.
  220. *
  221. * The <pAnchor> parameter is the local address by which the local CPU may
  222. * access the shared memory anchor.
  223. *
  224. * The <maxInputPkts> parameter specifies the maximum number of incoming
  225. * shared memory packets which may be queued to this CPU at one time.
  226. *
  227. * The <intType>, <intArg1>, <intArg2>, and <intArg3> parameters allow a
  228. * CPU to announce the method by which it is to be notified of input packets
  229. * which have been queued to it.
  230. *
  231. * The <masterCpu> parameter specifies the CPU number of the shared memory
  232. * master node.
  233. *
  234. * The <maxTicsWait> parameter sets the maximum wait interval allowed during
  235. * probing of shared memory locations prior to attaching.  If equal to zero,
  236. * a default value of 3000 is used.
  237. *
  238. * RETURNS: OK, or ERROR if the shared memory interface cannot be attached.
  239. *
  240. * INTERNAL
  241. * The delayed start for slave processors used below is required.  The anchor
  242. * may not yet be mapped to the bus.  So, probing of shared memory locations is
  243. * used to overcome Bus Errors which occur on many boards if the slave accesses
  244. * shared memory (SM) before the master has finished initializing it.  The code
  245. * here simply delays access to the SM region until the SM master has finished
  246. * initializing it.
  247. *
  248. * The method used is to repetitively probe key locations in the SM region
  249. * after delay periods until valid values are detected or a time-out occurs.
  250. * The initial delay period is set based on processor number.  (The master
  251. * processor does not delay.)  If the first probe of a location fails, an
  252. * exponential increase in delay period is used to reduce bus contention on
  253. * subsequent probes.
  254. *
  255. * This method is no better than receiving raw BERRs and does reduce bus
  256. * contention and the number of BERRs.
  257. *
  258. * NOMANUAL
  259. */
  260. STATUS smNetAttach2
  261.     (
  262.     int unit, /* interface unit number */
  263.     SM_ANCHOR * pAnchor, /* addr of anchor */
  264.     int maxInputPkts, /* max queued packets */
  265.     int intType, /* interrupt method */
  266.     int intArg1, /* interrupt argument #1 */
  267.     int intArg2, /* interrupt argument #2 */
  268.     int intArg3,  /* interrupt argument #3 */
  269.     int masterCpu, /* master CPU number */
  270.     int maxTicsWait /* max clock ticks to wait */
  271.     )
  272.     {
  273.     SM_SOFTC * xs; /* softc pointer */
  274.     SM_ANCHOR volatile * pAnchorv = (SM_ANCHOR volatile *) pAnchor;
  275.     SM_PKT_MEM_HDR volatile * pSmPktHdr; /* SM packet header */
  276.     SM_PKT_CPU_DESC volatile * pPktCpuDesc;
  277.     int tmp; /* temp storage */
  278.     BOOL cont = FALSE;
  279.     if (unit >= NSM)
  280.         {
  281. return (ERROR);
  282.         }
  283.     if ((xs = (SM_SOFTC *) calloc (sizeof (SM_SOFTC), 1)) == NULL)
  284.         {
  285.      return (ERROR);
  286.         }
  287.     if (maxTicsWait == 0)
  288.         {
  289.         maxTicsWait = 3000;
  290.         }
  291.     sm_softc [unit] = xs;
  292.     if (smIfAttach (unit, pAnchor, maxInputPkts, intType, intArg1, intArg2,
  293.     intArg3, sysClkRateGet (), smNetLoanNum) == OK)
  294.      {
  295.         /*
  296.          * If we are on master CPU, do not delay in probing shared memory,
  297.          * else, use delayed probe of key locations to wait for master to
  298.          * finish initialization of shared memory.  Slaves must wait because
  299.          * all subsequent steps assume that the master has completed its
  300.          * initialization of shared memory.
  301.          */
  302.         if (smUtilProcNumGet () != masterCpu)
  303.             {
  304.             /* First wait for valid anchor region */
  305.             if (smNetProbe (pAnchor, maxTicsWait, TRUE, SM_READY) == ERROR)
  306.                 {
  307.                 printf ("smNetAttach2: Error: SM probe 1 time outn");
  308.                 }
  309.             /* Now wait for valid SM packet memory header area */
  310.             else if (smNetProbe ((void *)&pAnchorv->smPktHeader,
  311.                                  maxTicsWait, FALSE, 0) == ERROR)
  312.                 {
  313.                 printf ("smNetAttach2: Error: SM probe 2 time outn");
  314.                 }
  315.             /*
  316.              * Wait for master to finish initializing packet memory header
  317.              * before continuing.
  318.              */
  319.             else if (((pSmPktHdr =
  320.                        SM_OFFSET_TO_LOCAL (ntohl (pAnchorv->smPktHeader),
  321.                                            (unsigned)pAnchor,
  322.                                            SM_PKT_MEM_HDR volatile *))
  323.                                  == NULL) ||
  324.                      (smNetProbe ((void *)&pSmPktHdr->pktCpuTbl,
  325.                                   maxTicsWait, FALSE, 0) != OK))
  326.                 {
  327.                 printf ("smNetAttach2: Error: SM probe 3 time outn");
  328.                 }
  329.             /* Finally, wait for master to attach to SM backplane network */
  330.             else if (((pPktCpuDesc =
  331.                        SM_OFFSET_TO_LOCAL (ntohl (pSmPktHdr->pktCpuTbl),
  332.                                            (unsigned)pAnchor,
  333.                                            SM_PKT_CPU_DESC volatile *))
  334.                                  == NULL) ||
  335.                      (smNetProbe ((void *)&pPktCpuDesc->status,
  336.                                   maxTicsWait, TRUE, SM_CPU_ATTACHED) != OK))
  337.                 {
  338.                 printf ("smNetAttach2: Error: SM probe 4 time outn");
  339.                 }
  340.             else
  341.                 {
  342.                 /* if sequential addressing - can calculate hw address */
  343.                 CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */
  344.                 tmp = pSmPktHdr->reserved1;     /* PCI bug       [SPR 68844] */
  345.                 if (pSmPktHdr->reserved1 != 0)
  346.                     {
  347.                     xs->xs_ac.ac_if.if_resolve = smNetAddrResolve;
  348.                     }
  349.                 cont = TRUE;
  350.                 }
  351.             }
  352.         else
  353.             cont = TRUE;
  354.         if (cont)
  355.             {
  356.             /*
  357.              * finish attachment by setting current receive state in
  358.              * SM_SOFTC and connecting the SM interrupt service routine
  359.              */
  360.             xs->taskRecvActive = FALSE;
  361.             if (smUtilIntConnect (LOW_PRIORITY, (FUNCPTR) smNetIntr, intType,
  362.                                   intType, intArg1, intArg2, intArg3) == OK)
  363.                 {
  364.                 return (OK);
  365.                 }
  366.             }
  367.         /* clean up before taking error exit */
  368. if_dettach (&xs->xs_if);
  369. }
  370.     (void) free ((caddr_t) xs);
  371.     return (ERROR);
  372.     }
  373. /******************************************************************************
  374. *
  375. * smNetAttach - attach the shared memory network interface
  376. *
  377. * This routine attaches the shared memory interface to the network.  It is
  378. * called once by each CPU on the shared memory network.  The <unit> parameter
  379. * specifies the backplane unit number.
  380. *
  381. * The <pAnchor> parameter is the local address by which the local CPU may
  382. * access the shared memory anchor.
  383. *
  384. * The <maxInputPkts> parameter specifies the maximum number of incoming
  385. * shared memory packets which may be queued to this CPU at one time.
  386. *
  387. * The <intType>, <intArg1>, <intArg2>, and <intArg3> parameters allow a
  388. * CPU to announce the method by which it is to be notified of input packets
  389. * which have been queued to it.
  390. *
  391. * RETURNS: OK, or ERROR if the shared memory interface cannot be attached.
  392. *
  393. * NOMANUAL
  394. */
  395. STATUS smNetAttach
  396.     (
  397.     int unit, /* interface unit number */
  398.     SM_ANCHOR * pAnchor, /* addr of anchor */
  399.     int maxInputPkts, /* max queued packets */
  400.     int intType, /* interrupt method */
  401.     int intArg1, /* interrupt argument #1 */
  402.     int intArg2, /* interrupt argument #2 */
  403.     int intArg3  /* interrupt argument #3 */
  404.     )
  405.     {
  406.     return (smNetAttach2 (unit, pAnchor, maxInputPkts, intType, intArg1,
  407.                           intArg2, intArg3, 0, 0));
  408.     }
  409. /******************************************************************************
  410. *
  411. * smNetIntr - VxWorks interrupt service routine
  412. *
  413. * This routine is the interrupt service routine for shared memory input
  414. * packets.  It processes the interrupt (if appropriate) then notifies the
  415. * interface of the incomming packet by calling smIfInput via the netTask.
  416. *
  417. * RETURNS: N/A
  418. *
  419. * NOMANUAL
  420. */
  421. LOCAL void smNetIntr
  422.     (
  423.     int  intType  /* interrupt type */
  424.     )
  425.     {
  426.     SM_SOFTC * xs; /* softc pointer */
  427.     int ix; /* unit */
  428.     /* check all SM interfaces for incoming packets */
  429.     for (ix = 0; ix < NSM; ix++)
  430. {
  431. if (((xs = sm_softc [ix]) != NULL) &&
  432.     (xs->smPktDesc.status == SM_CPU_ATTACHED) &&
  433.     (smIfInputCount (xs, xs->smPktDesc.smDesc.cpuNum) > 0))
  434.     {
  435.     if (!xs->taskRecvActive)
  436. {
  437. xs->taskRecvActive = TRUE;
  438.      (void) netJobAdd ((FUNCPTR) smIfInput, (int) xs, 0, 0, 0, 0);
  439. }
  440.     }
  441. /* if bus interrupt, acknowledge it */
  442. if ((xs != NULL) && (intType == SM_INT_BUS))
  443.     sysBusIntAck (xs->smPktDesc.smDesc.intArg1);
  444. }
  445.     }
  446. /******************************************************************************
  447. *
  448. * smNetPulse - continually pulse the shared memory heartbeat
  449. *
  450. * This routine maintains the shared memory heart beat by incrementing 
  451. * the heartbeat count and then re-scheduling itself to run again 
  452. * after a "beat" has passed.
  453. *
  454. * RETURNS: N/A
  455. *
  456. * NOMANUAL
  457. */
  458. LOCAL void smNetPulse
  459.     (
  460.     SM_PKT_MEM_HDR * pSmPktHdr /* pointer to heartbeat */
  461.     )
  462.     {
  463.     smPktBeat (pSmPktHdr);
  464.     (void) wdStart ((WDOG_ID) pSmPktHdr->reserved2, (int) sysClkRateGet (),
  465.           (FUNCPTR) smNetPulse, (int) pSmPktHdr);
  466.     }
  467. /******************************************************************************
  468. *
  469. * smNetProbe - probe a shared memory location
  470. *
  471. * This routine probes a shared memory location.  If the location can be
  472. * accessed and the value there is neither zero nor 0xffffffff, OK is returned.
  473. * The probe is repeated periodically until the above conditions are met or
  474. * until a maximum number of probes has been attempted.  If the maximum number
  475. * of probes is exceeded, ERROR is returned.
  476. *
  477. * RETURNS: OK if successful probe, otherwise ERROR
  478. *
  479. * NOMANUAL
  480. */
  481. LOCAL STATUS smNetProbe
  482.     (
  483.     void * ptr, /* location to probe */
  484.     UINT maxTicsWait, /* max system clock ticks period to wait */
  485.     BOOL tstEqVal, /* TRUE: test probe value == val */
  486.     int val /* specific value for operation */
  487.     )
  488.     {
  489.     int probeVal; /* value read during probe */
  490.     UINT tics; /* SM probe delay period */
  491.     int chkVal = htonl (val);
  492.     char * cp     = (char *)ptr;
  493.     tics = smUtilProcNumGet ();
  494.     tics <<= 1;
  495.     do
  496.         {
  497.         smUtilDelay (NULL, tics);
  498.         if (smUtilMemProbe (cp, READ, 4, (char *)&probeVal) == OK)
  499.             {
  500.             if (tstEqVal)
  501.                 {
  502.                 if (probeVal == chkVal)
  503.                     {
  504.                     return (OK);
  505.                     }
  506.                 }
  507.             else if ((probeVal != (int)~0) && (probeVal != 0))
  508.                 {
  509.                 return (OK);
  510.                 }
  511.             }
  512.         tics <<= 1;
  513.         } while ((tics < maxTicsWait) && (tics != 0));
  514.     return (ERROR);
  515.     }
  516. /******************************************************************************
  517. *
  518. * loanBuild - build an mbuf cluster with a shared memory buffer
  519. *
  520. * This routine calls build cluster to build an mbuf cluster from a shared
  521. * memory packet.
  522. *
  523. * RETURNS: pointer to the cluster if successful, otherwise NULL
  524. *
  525. * NOMANUAL
  526. */
  527. struct mbuf * loanBuild
  528.     (
  529.     SM_SOFTC * xs, /* softc pointer */
  530.     SM_PKT volatile * pPkt, /* shared memory packet */
  531.     u_char * pData, /* pointer to data */
  532.     int len /* length of packet */
  533.     )
  534.     {
  535.     int tmp; /* temp storage */
  536.     pPkt->header.type = 0;
  537.     CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */
  538.     tmp = pPkt->header.nBytes;      /* BRIDGE FLUSH  [SPR 68334] */
  539.     return (build_cluster (pData, len, &xs->xs_if, MC_BACKPLANE,
  540.    (u_char *)&(pPkt->header.type),
  541.    (FUNCPTR)smIfLoanReturn, (int) xs, (int) pPkt, 0));
  542.     }
  543. /******************************************************************************
  544. *
  545. * smNetInetGet - get address associated with a shared memory network interface
  546. *
  547. * This routine returns the IP address in <smInet> for the CPU
  548. * specified by <cpuNum> on the shared memory network specified by <smName>.
  549. * If <cpuNum> is NONE (-1), this routine returns information about the local
  550. * (calling) CPU.
  551. *
  552. * This routine can only be called after a call to smNetAttach().  It will
  553. * block if the shared memory region has not yet been initialized.
  554. *
  555. * This routine is only applicable if sequential addressing is being used
  556. * over the backplane.
  557. *
  558. * RETURNS: OK, or ERROR if the Internet address cannot be found.
  559. *
  560. * NOMANUAL
  561. */
  562. STATUS smNetInetGet
  563.     (
  564.     char * smName,  /* device name */
  565.     char * smInet, /* return inet */
  566.     int cpuNum /* cpu number */
  567.     )
  568.     {
  569.     SM_SOFTC * xs; /* softc pointer */
  570.     SM_ANCHOR volatile * pAnchor; /* ptr to anchor */
  571.     SM_PKT_MEM_HDR volatile * pSmPktHdr; /* packet header */
  572.     struct in_addr smAddr; /* address */
  573.     int tmp; /* temp storage */
  574.     if ((xs = (SM_SOFTC *) ifunit (smName)) == NULL)
  575. {
  576. printf ("smNetInetGet:%s not attachedn", smName);
  577. return (ERROR);
  578. }
  579.     pAnchor = (SM_ANCHOR volatile *) xs->smPktDesc.smDesc.anchorLocalAdrs;
  580.     if (smIsAlive ((SM_ANCHOR *)pAnchor, (int *)&pAnchor->smPktHeader,
  581.                    xs->smPktDesc.smDesc.base, 0, 0) == FALSE)
  582.         {
  583. return (ERROR);
  584.         }
  585.     pSmPktHdr = SM_OFFSET_TO_LOCAL (ntohl (pAnchor->smPktHeader),
  586.     xs->smPktDesc.smDesc.base,
  587.     SM_PKT_MEM_HDR volatile *);
  588.     CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */
  589.     tmp = pSmPktHdr->reserved1;     /* PCI bug       [SPR 68844] */
  590.     if (pSmPktHdr->reserved1 == 0)
  591.         {
  592.         /* no sequential addressing */
  593. return (ERROR);
  594.         }
  595.     if (cpuNum == NONE)
  596.         {
  597. cpuNum = xs->smPktDesc.smDesc.cpuNum;
  598.         }
  599.     smAddr.s_addr = htonl (ntohl (pSmPktHdr->reserved1) + cpuNum);
  600.     inet_ntoa_b (smAddr, smInet);
  601.     return (OK);
  602.     }
  603. /******************************************************************************
  604. *
  605. * smNetAddrResolve - resolve an Ethernet address
  606. *
  607. * This routine converts a destination IP address into a destination
  608. * Ethernet address.  It only resolves the address if sequential addressing
  609. * is being used and the destination is attached to shared memory.
  610. *
  611. * RETURNS: OK if successful, otherwise ERROR.
  612. *
  613. * NOMANUAL
  614. */
  615. LOCAL STATUS smNetAddrResolve
  616.     (
  617.     struct ifnet *   pIf, /* ifnet pointer */
  618.     struct in_addr * pIpDest, /* dest ip address */
  619.     u_char *      pHwDest, /* return hardware address */
  620.     int *      usetrailers /* not used */
  621.     )
  622.     {
  623.     SM_PKT_CPU_DESC volatile * pPktCpuDesc;
  624.     u_long dstHostAddr;
  625.     int destCpu;
  626.     int tmp;            /* temp storage */
  627.     SM_SOFTC * xs = sm_softc [pIf->if_unit]; /*softc pointer*/
  628.     if (xs->masterAddr == 0)
  629. return (ERROR); /* sequential addressing not enabled */
  630.     dstHostAddr = pIpDest->s_addr & 0x00ffffff;
  631.     destCpu = dstHostAddr - xs->masterAddr;
  632.     if ((destCpu < 0) || (destCpu >= xs->smPktDesc.smDesc.maxCpus))
  633.         return (ERROR);
  634.     pPktCpuDesc = &((xs->smPktDesc.cpuLocalAdrs) [destCpu]);
  635.     CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */
  636.     tmp = pPktCpuDesc->status;      /* PCI bug       [SPR 68844] */
  637.     if (pPktCpuDesc->status != SM_CPU_ATTACHED)
  638. return (ERROR);
  639.     /*
  640.      * Synthesize SM physical (MAC) address.
  641.      *
  642.      * Under IPv4, SM ethernet physical addresses (EUI-48) consist of 48 bits:
  643.      * { 0x00, 0x02, 0xE2, hostIpAdrs[3], hostIpAdrs[4], hostIpAdrs[5] }
  644.      *
  645.      * Under IPv6 (EUI-64) the 64-bit format is:
  646.      * { 0x00, 0x02, 0xE2, 0xFF, 0xFE,
  647.      *   hostIpAdrs[3], hostIpAdrs[4], hostIpAdrs[5] }
  648.      *
  649.      * XXXmas: FUTURE: The most significant 24 bits are the vendor ID.  Wind
  650.      * River's vendor ID is 0x00 0x40 0x47, not 0x00 0x02 0xE2!  Must be
  651.      * changed in next major release.
  652.      */
  653.     pHwDest [0] = 0x00;
  654.     pHwDest [1] = 0x02;
  655.     pHwDest [2] = 0xE2;
  656.     pHwDest [3] = (u_char)((dstHostAddr >> 16) & 0xff);
  657.     pHwDest [4] = (u_char)((dstHostAddr >> 8) & 0xff);
  658.     pHwDest [5] = (u_char)(dstHostAddr & 0xff);
  659.     /* entered into arp table for efficency */
  660.     arpCmd ((int)SIOCSARP, pIpDest, pHwDest, NULL);
  661.     *usetrailers = 0;
  662.     return (OK);
  663.     }