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

VxWorks

开发平台:

C/C++

  1. /* ixEthAccSysEnd.c - Intel IXDP425 ixEth Init Module */
  2. /* Copyright 2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01l,22oct02,jb  Changing Autonegotiate message
  8. 01k,07oct02,jb  Fix numbering
  9. 01j,07oct02,jb  Fix naming
  10. 01i,07oct02,jb  fix IP address
  11. 01h,23sep02,jb  Adding default IP addresses from config.h
  12. 01g,05sep02,jb  Changes to support Gold release of Intel Lib
  13. 01f,19aug02,jb  Fix double inclusion
  14. 01e,01aug02,jb  Continued developement
  15. 01d,31jul02,jb  Fixing name errors
  16. 01c,17jul02,jb  Renamed file, renaming bsp specific routines to segregate Intel
  17.                  library
  18. 01b,10jun02,jb  Modifying to integrate ixEth
  19. 01a,27may02,jb  Initial version from Intel
  20. */
  21. /*
  22. DESCRIPTION
  23. This file contains the board-specific routines for Ethernet adapter
  24. initialisation of Intel ixEthAcc devices.
  25. */
  26. #include <stddef.h>
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include "vxWorks.h"
  30. #include "sysLib.h"
  31. #include "ctype.h"
  32. #include "end.h" /* Common END structures. */
  33. #include "endLib.h"
  34. #include "inetLib.h"
  35. #undef ETHER_MAP_IP_MULTICAST
  36. #include "etherMultiLib.h" /* multicast stuff. */
  37. #include "ipProto.h"                    /* IP prototypes */
  38. #include "logLib.h"
  39. #include "net/mbuf.h"
  40. #include "net/unixLib.h"
  41. #include "net/protosw.h"
  42. #include "net/systm.h"
  43. #include "net/if_subr.h"
  44. #include "net/route.h"
  45. #include <inetLib.h>
  46. #include <ipProto.h>
  47. #include <netinet/in.h>
  48. #include <netinet/ip.h>
  49. #include <netinet/if_ether.h>
  50. #include "sys/socket.h"
  51. #include "sys/ioctl.h"
  52. #include "sys/times.h"
  53. #undef FORCE_CODELETS
  54. #include "IxTypes.h"
  55. #include "IxEthAcc.h"
  56. #include "IxQMgr.h"
  57. #include "IxNpeDl.h"
  58. #include "IxNpeMh.h"
  59. #ifndef FORCE_CODELETS
  60.     #include "IxNpeMicrocode.h"
  61. #endif /* FORCE_CODELETS */
  62. #include "IxOsServices.h"
  63. #include "IxEthAcc.h"
  64. #include "ixp425.h" /* Chip level definitions required */
  65. #include "ixdp425.h"
  66. #include "config.h"
  67. #ifdef INCLUDE_IXETHACCEND
  68. /* DEBUG MACROS */
  69. #define SYS_END_DEBUG
  70. #ifdef SYS_END_DEBUG
  71.     #define DRV_LOG printf
  72. #else
  73.     #define DRV_LOG
  74. #endif /* SYS_END_DEBUG */
  75. #ifndef END_LD_STR_SIZE
  76. #define      END_LD_STR_SIZE 80
  77. #endif
  78. /**< Max number of NPE uCode versions */
  79. #define IX_ETHACC_CODELET_NPE_LIST 20
  80. /**< Location of NPE image to download */
  81. #define IX_ETHACC_CODELET_NPE_IMG IX_NPEDL_MicrocodeImage 
  82. #ifdef FORCE_CODELETS
  83. IMPORT unsigned IX_NPEDL_MicrocodeImage[];
  84. #endif
  85. #define NUM_ELEM(vector) (sizeof (vector) / sizeof ((vector)[0]))
  86. /* Imports from Monsoon */
  87. struct
  88.     {
  89.     int number; const char *string;
  90.     } ixIpProtoValues[] = 
  91.     {
  92.     {IPPROTO_IP,            "IP"},
  93.     {IPPROTO_TCP,           "TCP"},
  94.     {IPPROTO_UDP,           "UDP"},
  95.     {IPPROTO_ICMP,          "ICMP"},
  96.     {IPPROTO_IGMP,          "IGMP"}
  97.     };
  98. /* These are to simplify includes */
  99. #define IX_ETH_ACC_MII_STAT_REG          0x1 /* Status Register */
  100. #define IX_ETH_ACC_MII_STAT2_REG    0x11 /* Status Register 2*/
  101. #define IX_ETH_ACC_MII_SR_AUTO_NEG      0x0020 /* auto negotiation complete */
  102. #define IX_ETH_ACC_MII_SR2_FD           0x0200
  103. IMPORT END_OBJ*     ixEthAccEndLoad (char *, void *);
  104. IMPORT END_TBL_ENTRY    endDevTbl[];
  105. unsigned char sysIxEthAccEndEnetAddr[6] = { 0x00, 0x02,0xb3,0x3c,0x16,0x95};
  106. #if defined(IXDP_ETHACC_IP0_DEFAULT) && defined(IXDP_ETHACC_IP1_DEFAULT)
  107. LOCAL char *sysIxEthAccEndIpAddr[IX_ETH_ACC_NUMBER_OF_PORTS] =
  108.     {
  109.     IXDP_ETHACC_IP0_DEFAULT,
  110.     IXDP_ETHACC_IP1_DEFAULT
  111.     };
  112. #endif
  113. LOCAL char      ixpEndLoadStr[IX_ETH_ACC_NUMBER_OF_PORTS][END_LD_STR_SIZE] = 
  114.     {
  115.     { "0:"},
  116.     { "0:"},
  117.     };
  118. typedef struct _IXDP_ETHACC_PHY_CONF
  119.     {
  120.     BOOL speed100;  /**< 100 Mbits */
  121.     BOOL fullDuplex;    /**< Full Duplex */
  122.     BOOL autonegotiate; /**< Autonegotiation */
  123.     } IXDP_ETHACC_PHY_CONF;
  124. PRIVATE IXDP_ETHACC_PHY_CONF ixdp425phyConf = 
  125.     {
  126.     TRUE,   /* 100 Mbits */
  127.     TRUE,   /* Full duplex */
  128.     TRUE    /* Autonegotiate */
  129.     };
  130. #ifdef IXDP_ETHACC_USE_NVRAM_MAC
  131.     static UCHAR ixdp425IntelMacPrefix[6] = 
  132.         {
  133.         0x00,
  134.         0xe0,
  135.         0x42,
  136.         0x00,
  137.         0x00,
  138.         0x00,
  139.         };
  140.     static UINT32 nvRamNpeMacAddr[IX_ETH_ACC_NUMBER_OF_PORTS] =
  141.     {
  142.         NV_MAC_ADRS_NPE1,
  143.         NV_MAC_ADRS_NPE2,
  144.     };
  145. #endif /* IXDP_ETHACC_USE_NVRAM_MAC */
  146. void ixEthernetHdrDump(const char * const mData);
  147. void ixIpHdrDump(const char * const mData);
  148. IxEthAccStatus ixEthAccMiiReadRtn (UINT8, UINT8, UINT16 *);
  149. extern void sysMicroDelay(int microseconds);
  150. BOOL ixdp425EthLibInitialised = FALSE;
  151. #if (BOARD_TYPE==CPF425O)
  152. UINT32 ixEthAccPhyAddresses[IX_ETH_ACC_NUMBER_OF_PORTS]={4,5};
  153. #elif (BOARD_TYPE==CPF425C)
  154. UINT32 ixEthAccPhyAddresses[IX_ETH_ACC_NUMBER_OF_PORTS]={1,0};
  155. #else
  156. #error "Unsupported embedway board"
  157. #endif
  158. PRIVATE BOOL phyPresent[IXP425_ETH_ACC_MII_MAX_ADDR];
  159. PRIVATE char ixnpeMaddrStr[IX_ETH_ACC_NUMBER_OF_PORTS][64];
  160. #ifdef FORCE_CODELETS
  161. /* Do Not call this routine - It is used to force code inclusion */
  162. PRIVATE void ixdp425ForceCodlets()
  163.     {
  164.     ixEthAccCodeletInit();
  165.     }
  166. #endif /* FORCE_CODELETS */
  167. PRIVATE IX_STATUS ixdp425EthAccPhyInit(int port)
  168.     {
  169.     UINT16 regval;
  170.     UINT32 phyAddr;
  171.     UINT32 timeout;
  172.     UINT32 i;
  173. #if BOARD_TYPE==CPF425O
  174.     if (port == 0)
  175.         return IX_SUCCESS;
  176. #endif
  177.     if (ixEthAccMiiPhyScan(phyPresent) == ERROR)
  178.         {
  179.         return(IX_FAIL);
  180.         }
  181.      else
  182.         {
  183.  for (i = 0; i < IX_ETH_ACC_NUMBER_OF_PORTS; i++)
  184.   {
  185.   phyAddr = ixEthAccPhyAddresses[i];
  186.   if (phyPresent[phyAddr] == 0)
  187. return(IX_FAIL);
  188.   }
  189.         }
  190.     /* Reset each phy */
  191.     for (i=0; i<IX_ETH_ACC_NUMBER_OF_PORTS; i++)
  192.         {
  193.         if (i != port || ixEthAccPhyAddresses[i] == 0xffffffff)
  194.             continue;
  195.         ixEthAccMiiPhyReset(ixEthAccPhyAddresses[i]);
  196.         }
  197.     /* Set each phy properties */
  198.     for (i=0; i<IX_ETH_ACC_NUMBER_OF_PORTS; i++)
  199.         {
  200.         if (i != port || ixEthAccPhyAddresses[i] == 0xffffffff)
  201.             continue;
  202.         ixEthAccMiiPhyConfig(ixEthAccPhyAddresses[i],
  203.                              ixdp425phyConf.speed100, 
  204.                              ixdp425phyConf.fullDuplex, 
  205.                              ixdp425phyConf.autonegotiate);
  206.         if ((ixdp425phyConf.autonegotiate) && (port ==1))
  207.             {
  208.             /* We need to delay here until Autonegotiate is complete */
  209.             for ( timeout = 10; timeout; timeout-- )
  210.                 {
  211.                 /* A short delay */
  212.                 sysMicroDelay(50);
  213.                 /* Must do this read twice */
  214.                 ixEthAccMiiReadRtn(ixEthAccPhyAddresses[i],  IX_ETH_ACC_MII_STAT_REG, &regval);
  215.                 ixEthAccMiiReadRtn(ixEthAccPhyAddresses[i],  IX_ETH_ACC_MII_STAT_REG, &regval);
  216.                 if ((regval & IX_ETH_ACC_MII_SR_AUTO_NEG) != 0)
  217.                     break;
  218.                 }
  219.             /* If connect failed, then report it */
  220.             if ( (regval & IX_ETH_ACC_MII_SR_AUTO_NEG) == 0 )
  221.                 {
  222.                 printf("nixe ETH PHY %d Autonegotiate incompleten"
  223.                        , ixEthAccPhyAddresses[i]
  224.                       ); 
  225. #if 0
  226. /* allow autonegotiate for later */
  227.                 ixEthAccPhyAddresses[i] = 0xffffffff;
  228. #endif
  229.                 }
  230.             }
  231.         }
  232.     /* Set the MAC to the same duplex mode as the phy */
  233.     for (i=0; i<IX_ETH_ACC_NUMBER_OF_PORTS; i++)
  234.         {
  235.         if (i != port || ixEthAccPhyAddresses[i] == 0xffffffff)
  236.             continue;
  237.         if (ixdp425phyConf.fullDuplex)
  238.             {
  239.             ixEthAccPortDuplexModeSet (ixEthAccPhyAddresses[i], IX_ETH_ACC_FULL_DUPLEX);
  240.             }
  241.         else
  242.             {
  243.             ixEthAccPortDuplexModeSet (ixEthAccPhyAddresses[i], IX_ETH_ACC_HALF_DUPLEX);
  244.             }
  245.         /* Do a read status to add a delay. Must do this read twice */
  246.         ixEthAccMiiReadRtn(ixEthAccPhyAddresses[i],  IX_ETH_ACC_MII_STAT_REG, &regval);
  247.         ixEthAccMiiReadRtn(ixEthAccPhyAddresses[i],  IX_ETH_ACC_MII_STAT_REG, &regval);
  248. #ifdef SYS_END_DEBUG
  249.         printf("nixe ETH PHY %d configuration:n"
  250.                , ixEthAccPhyAddresses[i]
  251.               ); 
  252.         ixEthAccMiiShow(ixEthAccPhyAddresses[i]);
  253. #endif /* SYS_END_DEBUG */
  254.         }
  255.     return(IX_SUCCESS);
  256.     }
  257. /**
  258.  * @fn IX_STATUS ixdp425EthAccNpeInit(IxNpeDlNpeId npeId)
  259.  *
  260.  * @param npeId - ID of ixe to initialise
  261.  *
  262.  * Download microcode to the IXE. This function always downloads the latest
  263.  * version of NPE microcode available.
  264.  *
  265.  * @return IX_SUCCESS - NPE successfuly initialised
  266.  * @return IX_FAIL - Error initialising NPE
  267.  */
  268. PRIVATE IX_STATUS ixdp425EthAccNpeInit(IxNpeDlNpeId npeId)
  269.     {
  270.     IxNpeDlVersionId npeIdList[IX_ETHACC_CODELET_NPE_LIST];
  271.     UINT32 npeListSize = IX_ETHACC_CODELET_NPE_LIST;
  272.     IxNpeDlVersionId tmpIdList = {0, 0, 0, 0};
  273.     int i;
  274.     tmpIdList.npeId = npeId;
  275.     /* Stop the NPE before attempting a download */
  276.     if (ixNpeDlNpeStopAndReset(npeId) != IX_SUCCESS)
  277.         {
  278.         printf("ixe %d stop and reset failedn"
  279.                , (int)npeId
  280.               );
  281.         return(IX_FAIL);
  282.         }
  283.     /* Get the latest version of NPE code available */
  284.     ixNpeDlAvailableVersionsListGet(npeIdList, &npeListSize);
  285.     for (i = 0; i < npeListSize; i++)
  286.         {
  287.         if (npeIdList[i].npeId == npeId)
  288.             {
  289.             if (npeIdList[i].major >= tmpIdList.major)
  290.                 {
  291.                 tmpIdList.major = npeIdList[i].major;
  292.                 if (npeIdList[i].minor >= tmpIdList.minor)
  293.                     {
  294.                     tmpIdList.minor = npeIdList[i].minor;
  295.                     tmpIdList.buildId = npeIdList[i].buildId;
  296.                     }
  297.                 }
  298.             }
  299.         }
  300. #ifdef SYS_END_DEBUG
  301.     printf("ixe %d Version informationn", tmpIdList.npeId - 1);
  302.     printf("Major ID:t 0x%xn", tmpIdList.major);
  303.     printf("Minor ID:t 0x%xn", tmpIdList.minor);
  304.     printf("Build ID:t 0x%xn", tmpIdList.buildId);
  305. #endif /* SYS_END_DEBUG */
  306.     /* Download NPE code */
  307.     if (ixNpeDlVersionDownload(&tmpIdList, TRUE) != IX_SUCCESS)
  308.         {
  309.         printf("ixe %d download failedn"
  310.                , tmpIdList.npeId
  311.               );
  312.         return(IX_FAIL);
  313.         }
  314.     return(IX_SUCCESS);
  315.     }
  316. /**
  317.  * @fn IX_STATUS ixdp425EthAccMacSet()
  318.  *
  319.  * Set the MAC address for available Ports on the board.
  320.  * It is assumed that the MAC addresses are stored in non-volatile storage.
  321.  *
  322.  * @return IX_SUCCESS - MAC address successfuly set
  323.  * @return IX_FAIL - Error setting MAC address
  324.  */
  325. PRIVATE IX_STATUS ixdp425EthAccMacSet(int port)
  326.     {
  327.     IxEthAccMacAddr npeMacAddr;
  328. #ifdef IXDP_ETHACC_USE_NVRAM_MAC
  329.     if (sysNvRamGet((UINT8 *)&npeMacAddr.macAddress, 
  330.                     IX_IEEE803_MAC_ADDRESS_SIZE, 
  331.                     nvRamNpeMacAddr[port]) == ERROR)
  332.         {
  333.         printf("ixe %d - Unable to read MAC address from non-volatile storage!n"
  334.                , port
  335.               );
  336.         return(IX_FAIL);
  337.         }
  338.     /* Check for a valid MAC address - Only compare first three bytes */
  339.     if ( bcmp( (char *)&npeMacAddr.macAddress, ixdp425IntelMacPrefix, 3) )
  340.         {
  341.         /* Don't have a valid MAC in NVRAM so we fall back to Intel's base addresses */
  342.         bcopy ((char *)sysIxEthAccEndEnetAddr, (char *)npeMacAddr.macAddress, 6);
  343.         npeMacAddr.macAddress[5] += port;
  344.         printf("ixe ETH PHY %d Hard Coded MAC address is: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2xn"
  345.            , port
  346.            ,npeMacAddr.macAddress[0], npeMacAddr.macAddress[1]
  347.            ,npeMacAddr.macAddress[2], npeMacAddr.macAddress[3]
  348.            ,npeMacAddr.macAddress[4], npeMacAddr.macAddress[5]);
  349.         }
  350.     else
  351.         {
  352. #ifdef SYS_END_DEBUG
  353.         printf("ixe ETH PHY %d MAC address is: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2xn"
  354.            , port
  355.            ,npeMacAddr.macAddress[0], npeMacAddr.macAddress[1]
  356.            ,npeMacAddr.macAddress[2], npeMacAddr.macAddress[3]
  357.            ,npeMacAddr.macAddress[4], npeMacAddr.macAddress[5]);
  358. #endif /* SYS_END_DEBUG */
  359.         }
  360. #else /* Hard encoded MAC */
  361.     bcopy ((char *)sysIxEthAccEndEnetAddr, (char *)npeMacAddr.macAddress, 6);
  362.     npeMacAddr.macAddress[5] += port;
  363.     printf("ixe ETH PHY %d Hard Coded MAC address is: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2xn"
  364.            , port
  365.            ,npeMacAddr.macAddress[0], npeMacAddr.macAddress[1]
  366.            ,npeMacAddr.macAddress[2], npeMacAddr.macAddress[3]
  367.            ,npeMacAddr.macAddress[4], npeMacAddr.macAddress[5]);
  368. #endif 
  369.     if (ixEthAccPortUnicastMacAddressSet(port, &npeMacAddr) != IX_ETH_ACC_SUCCESS)
  370.         {
  371.         return(IX_FAIL);
  372.         }
  373.     return(IX_SUCCESS);
  374.     }
  375. /**
  376.  * @fn IX_STATUS ixdp425EthAccStartDispatch()
  377.  *
  378.  * @param BOOL interruptMode - start in interrupt or polled mode
  379.  *
  380.  * This function starts the Queue manager dispatch timer.
  381.  * 
  382.  * @return IX_SUCCESS - Dispatch timer successfully started
  383.  * @return IX_FAIL - Error starting dispatch timer
  384.  */
  385. PRIVATE IX_STATUS ixdp425EthAccStartDispatch(BOOL interruptMode)
  386.     {
  387.     if (interruptMode)   /* Interrupt mode */
  388.         {
  389.         /* 
  390.          * Hook the QM QLOW dispatcher to the interrupt controller. 
  391.          * The ethernet NPEs use queues 24 through 27.
  392.          */
  393.         if (ixOsServIntBind(IXP425_INT_LVL_QM1,
  394.                             (VOIDFUNCPTR)ixQMgrDispatcherLoopRun,
  395.                             (void *)IX_QMGR_QUELOW_GROUP) != IX_SUCCESS)
  396.             {
  397.             printf("ixe Ethernet Lib - Failed to bind to QM1 interruptn"
  398.                   );
  399.             return(IX_FAIL);
  400.             }
  401.         }
  402.     else    /* Polled mode */
  403.         {
  404.         return(IX_FAIL);
  405.         }
  406.     return(IX_SUCCESS);
  407.     }
  408. IX_STATUS ixdp425EthLibInit()
  409.     {  
  410.     UINT32 i;
  411.     if (ixdp425EthLibInitialised)
  412.         {
  413.         printf("ixe Ethernet Lib - Ethernet codelet already initialisedn");
  414.         return(IX_SUCCESS);
  415.         }
  416.     /* Initialise Queue Manager */
  417. #ifdef SYS_END_DEBUG
  418.     DRV_LOG("ixdp425EthLibInit: Initialising Queue Manager...n");
  419. #endif /* SYS_END_DEBUG */
  420.     if (ixQMgrInit() != IX_SUCCESS)
  421.         {
  422.         printf("ixdp425EthLibInit: Error initialising Intel queue manager!n");
  423.         return(IX_FAIL);
  424.         }
  425.     /* Start the Queue Manager dispatcher loop */
  426.     if (ixdp425EthAccStartDispatch(TRUE) != IX_SUCCESS)
  427.         {
  428.         printf("ixdp425EthLibInit: Error starting Intel queue manager dispatch loop!n");
  429.         return(IX_FAIL);
  430.         }
  431.     /* Initialise ixes */
  432. #ifdef SYS_END_DEBUG
  433.     DRV_LOG("ixdp425EthLibInit: Initialising ixes...n");
  434. #endif /* SYS_END_DEBUG */
  435.     if (ixdp425EthAccNpeInit(IX_NPEDL_NPEID_NPEB) != IX_SUCCESS)
  436.         {
  437.         printf("ixdp425EthLibInit: Error initialising ixe 0!n");
  438.         return(IX_FAIL);
  439.         }
  440.     if (ixdp425EthAccNpeInit(IX_NPEDL_NPEID_NPEC) != IX_SUCCESS)
  441.         {
  442.         printf("ixdp425EthLibInit: Error initialising ixe 1!n");
  443.         return(IX_FAIL);
  444.         }
  445.     /* Initialise NPE Message handler */
  446. #ifdef SYS_END_DEBUG
  447.     DRV_LOG("nixdp425EthLibInit: Starting ixe message handler...n");
  448. #endif /* SYS_END_DEBUG */
  449.     if (ixNpeMhInitialize(IX_NPEMH_NPEINTERRUPTS_YES) != IX_SUCCESS)
  450.         {
  451.         printf("ixdp425EthLibInit: Error initialising ixe Message handler!n");
  452.         return(IX_FAIL);
  453.         }
  454.     /* Start NPEs */
  455. #ifdef SYS_END_DEBUG
  456.     DRV_LOG("ixdp425EthLibInit: Starting ixes...n");
  457. #endif /* SYS_END_DEBUG */
  458.     if (ixNpeDlNpeExecutionStart(IX_NPEDL_NPEID_NPEB) != IX_SUCCESS)
  459.         {
  460.         printf("ixdp425EthLibInit: Error starting ixe 0!n");
  461.         return(IX_FAIL);
  462.         }
  463.     if (ixNpeDlNpeExecutionStart(IX_NPEDL_NPEID_NPEC) != IX_SUCCESS)
  464.         {
  465.         printf("ixdp425EthLibInit: Error starting ixe 1!n");
  466.         return(IX_FAIL);
  467.         }
  468.     /***********************************************************************
  469.      *
  470.      * System initialisation done. Now initialise Ethernet Access components. 
  471.      *
  472.      ***********************************************************************/
  473.     if (ixEthAccInit() != IX_ETH_ACC_SUCCESS)
  474.         {
  475.         printf("ixdp425EthLibInit: Error initialising ixe Ethernet access driver!n");
  476.         return(IX_FAIL);
  477.         }
  478.     ixdp425EthLibInitialised = TRUE;
  479.     return(IX_SUCCESS);
  480.     }
  481. IX_STATUS ixdp425EthPhysInit(int port)
  482.     {  
  483.     /* Initialise Ethernet ports */
  484.     if (ixEthAccPortInit(port) != IX_ETH_ACC_SUCCESS)
  485.         {
  486.         printf("Error initialising ixe Ethernet port %d!n" , port);
  487.         return(IX_FAIL);
  488.         }
  489.     /* Find and initialise all available PHYs */
  490.     if (ixdp425EthAccPhyInit(port) != IX_SUCCESS)
  491.         {
  492.         printf("Error initialising PNE Ethernet phy %d!n" , port);
  493.         return(IX_FAIL);
  494.         }
  495.     /* Program MAC addresses for available PHYs */
  496.     if (ixdp425EthAccMacSet(port) != IX_SUCCESS)
  497.         {
  498.         printf("Error programming MAC address for Ethernet phy %d!n" , port);
  499.         return(IX_FAIL);
  500.         }
  501.     if (ixEthAccPortTxFrameAppendFCSEnable(port) != IX_ETH_ACC_SUCCESS)
  502.         {
  503.         printf("Error setting ixEthAccPortTxFrameAppendFCSEnable mode for port %dn" , port);
  504.         return(IX_FAIL);
  505.         }
  506.     if (ixEthAccPortRxFrameAppendFCSDisable(port) != IX_ETH_ACC_SUCCESS)
  507.         {
  508.         printf("Error setting ixEthAccPortRxFrameAppendFCSDisable mode for port %dn" , port);
  509.         return(IX_FAIL);
  510.         }
  511.     /* Set scheduling discipline */
  512.     ixEthAccTxSchedulingDisciplineSet(port, FIFO_NO_PRIORITY);
  513.     return(IX_SUCCESS);
  514.     }
  515. STATUS ixdp425EthEndMuxInit()
  516.     {
  517.     END_TBL_ENTRY     *pDevTbl;
  518.     UINT32 i;
  519.     for ( pDevTbl = endDevTbl; pDevTbl->endLoadFunc != END_TBL_END; pDevTbl++ )
  520.         ; /* Do nothing as we just want the increment */
  521.     /* TODO - How to we tie phys ports to ixe's ?????? */
  522.     for (i=0; i<IX_ETH_ACC_NUMBER_OF_PORTS; i++)
  523.         {
  524. #ifndef INCLUDE_IXETHACC_PORT0_END
  525.         if ( i == 0 )
  526.             continue;
  527. #endif
  528. #ifndef INCLUDE_IXETHACC_PORT1_END
  529.         if ( i == 1 )
  530.             continue;
  531. #endif
  532.         /* Fill in the endDev entry for this device */
  533.         pDevTbl->unit = i;
  534.         pDevTbl->endLoadFunc = ixEthAccEndLoad;
  535.         pDevTbl->endLoadString = ixpEndLoadStr[i];
  536.         pDevTbl->endLoan = 1;
  537.         pDevTbl->pBSP = NULL;
  538.         pDevTbl->processed = FALSE;
  539.         pDevTbl++;
  540.         }
  541.     return OK;
  542.     }
  543. STATUS ixdp425EthEndStartUp()
  544.     {
  545.     END_TBL_ENTRY     *pDevTbl;
  546.     END_OBJ *         pCookie = NULL;
  547.     UINT32 ixdp425EthEndMask;
  548.     UINT8 nvImage[NV_RAM_IF_SIZE+1];
  549.     UINT8 inetAddr[INET_ADDR_LEN];
  550.     UINT8 nameAndUnit[32];
  551.     UINT8 pNetDev[32];
  552.     char *colon;
  553.     int n = 0,index,ipaddrOk;
  554.     sysNvRamGet(nvImage, NV_RAM_IF_SIZE, NV_RAM_IF_START_OFFSET);
  555.     for ( pDevTbl = endDevTbl
  556.             ; pDevTbl->endLoadFunc != END_TBL_END && n < IX_ETH_ACC_NUMBER_OF_PORTS
  557.             ; pDevTbl++ )
  558.         {
  559.         if ( pDevTbl->endLoadFunc != ixEthAccEndLoad )
  560.             continue;
  561.         if ( pDevTbl->processed == FALSE )
  562.             {
  563.             /* Add in mux END */
  564.             pCookie = muxDevLoad (pDevTbl->unit,
  565.                                   pDevTbl->endLoadFunc,
  566.                                   pDevTbl->endLoadString,
  567.                                   pDevTbl->endLoan, 
  568.                                   pDevTbl->pBSP);
  569.             if (pCookie == NULL)
  570.                 {
  571.                 printf("ixdp425EthEndStartUp: muxDevLoad failed for ixp device entry %d!n"
  572.                        , n
  573.                       );
  574.                 n++;
  575.                 continue;
  576.                 }
  577.              else
  578.                 {
  579.                 /* Start END */
  580.                 if (muxDevStart(pCookie) == ERROR)
  581.                     {
  582.                     printf("ixdp425EthEndStartUp: muxDevStart failed for ixp device entry %d!n"
  583.                            , n
  584.                           );
  585.                     n++;
  586.                     continue;
  587.                     }
  588.                 }
  589.             }
  590.         ipaddrOk = 1;
  591.         /* If the EthAccEnd interface is not already attached, we should bring it up here
  592.           and assign an IP address*/
  593.         sprintf(pNetDev,"%s","ixe");
  594.         sprintf(nameAndUnit,"%s%d","ixe", n);
  595.         /* need to figure out if this has been configured already */
  596.         if (ifAddrGet(nameAndUnit,inetAddr) == ERROR)
  597.             {
  598.             if (ipAttach(n, pNetDev) != OK)
  599.                 {
  600.                 printf ("ixdp425EthEndStartUp: Failed to attach to device %s, unit: %d", pNetDev,n);
  601.                 }
  602.              else
  603.                 {
  604.                 /* See if an address is in nvram */
  605.                 /* Get IP address */
  606.                 index = NV_IP_ADRS_NPE1 + n*SIZE_OF_IP_ADDRESS - NV_RAM_IF_START_OFFSET;
  607.                 memcpy(inetAddr, &nvImage[index],SIZE_OF_IP_ADDRESS);
  608.                 inetAddr[SIZE_OF_IP_ADDRESS]=0;
  609. hardCodedRetry:
  610.                 /* See if there is a mask */
  611.                 if ( (colon = strchr(inetAddr, ':')) )
  612.                     {
  613.                     *colon = 0;
  614.                     colon++;
  615.                     for(index = 0; index < 6; index++)
  616.                         {
  617.                         if( isxdigit(colon[index] == 0 ) )
  618.                             {
  619.                             printf("ixdp425EthEndStartUp: Invalid Mask for ixe%d IP: %s:%s Discarding Maskn"
  620.                                 ,n,inetAddr, colon);
  621.                             colon = NULL;
  622.                             break;
  623.                             }
  624.                         }
  625.                     if(colon != NULL)
  626.                         {
  627.                         sscanf(colon, "%x", &ixdp425EthEndMask);
  628.                         }
  629.                     }
  630.                 /* Check to see if its a valid IP address */
  631.                 for(index = 0; index < SIZE_OF_IP_ADDRESS; )
  632.                     {
  633.                     if ( !isdigit(inetAddr[index]) && inetAddr[index] != '.' )
  634.                         {
  635. #if defined(IXDP_ETHACC_IP0_DEFAULT) && defined(IXDP_ETHACC_IP1_DEFAULT)
  636.                         printf("ixdp425EthEndStartUp: Forcing Hard Coded IP Address for ixe%dn",n);
  637.                         sprintf(inetAddr, "%s", sysIxEthAccEndIpAddr[n]);
  638.                         goto hardCodedRetry;
  639. #else
  640.                         ipaddrOk = 0;
  641.                         printf("ixdp425EthEndStartUp: Invalid Address for ixe%d IP: %s Ignoringn",n,inetAddr);
  642.                         break;
  643. #endif
  644.                         }
  645.                     if ( inetAddr[++index] == 0 )
  646.                         break;
  647.                     }
  648.                 if ( ipaddrOk )
  649.                     {
  650.                     ifAddrSet(nameAndUnit, inetAddr);
  651.                     if( colon != NULL )
  652.                         {
  653.                         ifMaskSet(nameAndUnit, ixdp425EthEndMask);
  654.                         printf("ixdp425EthEndStartUp: ixe%d: IP Addr set to %s:%xn"
  655.                                 ,n, inetAddr, ixdp425EthEndMask);
  656.                         }
  657.                     else
  658.                         {
  659.                         printf("ixdp425EthEndStartUp: ixe%d: IP Addr set to %sn",n, inetAddr);
  660.                         }
  661.                     }
  662.                 }
  663.             }
  664.         n++;
  665.         }
  666.     return OK;
  667.     }
  668. const char *ixIpProtoStrGet (const UINT8 ipProto)
  669.     {
  670.     UINT32 index;
  671.     for (index = 0 ; index < NUM_ELEM(ixIpProtoValues) ; index++)
  672.         {
  673.         if (ixIpProtoValues[index].number == ipProto)
  674.             {
  675.             return ixIpProtoValues[index].string;
  676.             }
  677.         }
  678.     return "Unknown IP protocol";
  679.     }
  680. struct
  681.     {
  682.     int number; const char *string;
  683.     } ixEtherTypeValues[] = 
  684.     {
  685.     {ETHERTYPE_PUP,         "PUP"},
  686.     {ETHERTYPE_IP,          "IP"},
  687.     {ETHERTYPE_ARP,         "ARP"},
  688.     {ETHERTYPE_REVARP,      "Reverse ARP"}
  689.     };
  690. const char *ixEthernetTypeStrGet (const UINT16 etherType)
  691.     {
  692.     UINT32 index;
  693.     for (index = 0 ; index < NUM_ELEM(ixEtherTypeValues) ; index++)
  694.         {
  695.         if (ixEtherTypeValues[index].number == etherType)
  696.             {
  697.             return ixEtherTypeValues[index].string;
  698.             }
  699.         }
  700.     return "Unknown Ethernet Type";
  701.     }
  702. void dumpMbufPtr(IX_MBUF *mBufPtr)
  703.     {
  704.     UINT32 j,k;
  705.     logMsg("m_len:        %d",mBufPtr->m_len,0,0,0,0,0);
  706.     logMsg("m_pkthdr.len: %d", mBufPtr->m_pkthdr.len,0,0,0,0,0);
  707.     logMsg("m_next        0x%x",(UINT32)mBufPtr->m_next,0,0,0,0,0);
  708.     logMsg("m_type        0x%x", mBufPtr->m_type,0,0,0,0,0);
  709.     logMsg("data: ",0,0,0,0,0,0);
  710.     for (j=0;j<mBufPtr->m_len/16;j++)
  711.         {
  712.         for (k=0;k<16;k++)
  713.             {
  714.             logMsg("0x%x ",mBufPtr->m_data[j*16 + k],0,0,0,0,0);
  715.             }
  716.         }
  717.     ixEthernetHdrDump(mBufPtr->m_data);
  718.     }
  719. /******************************************************************************
  720.  *
  721.  * This function can be used to output the Ethernet headers of messages. The
  722.  * inputted mData pointer is assumed to point to the start of the Ethernet 
  723.  * header
  724.  *
  725.  *****************************************************************************/
  726. void ixEthernetHdrDump(const char * const mData)
  727.     {
  728.     static unsigned char *etherSrcAddr = NULL;
  729.     static unsigned char *etherDstAddr = NULL;
  730.     static unsigned etherType = 0;
  731.     const char *etherTypeStr = NULL;
  732.     BOOL nonIpHdrDetected;
  733.     if ( (mData == NULL) )
  734.         {
  735.         logMsg("ERROR: RNDIS detected NULL pointer in ixEthernetDump",
  736.                0,0,0,0,0,0);
  737.         return;
  738.         }
  739.     logMsg("*** Ethernet Header ***n", 0, 0, 0, 0, 0, 0);
  740.     etherDstAddr = ((struct ether_header *) mData)->ether_dhost;
  741.     etherSrcAddr = ((struct ether_header *) mData)->ether_shost;
  742.     etherType = ntohs(((struct ether_header *) mData)->ether_type);
  743.     if (etherType != ETHERTYPE_IP)
  744.         {
  745.         nonIpHdrDetected = TRUE;
  746.         logMsg("[this is non-IP data]n", 0, 0, 0, 0, 0, 0);
  747.         }
  748.      else
  749.         {
  750.         nonIpHdrDetected = FALSE;
  751.         logMsg("[this is IP data]n", 0, 0, 0, 0, 0 ,0);
  752.         }
  753.     etherTypeStr = ixEthernetTypeStrGet((const UINT16)etherType);
  754.     logMsg("Ethernet Dst MAC: 0x%02x:%02x:%02x:%02x:%02x:%02xn",
  755.            etherDstAddr[0],
  756.            etherDstAddr[1],
  757.            etherDstAddr[2], 
  758.            etherDstAddr[3], 
  759.            etherDstAddr[4], 
  760.            etherDstAddr[5] );
  761.     logMsg("Ethernet Src MAC: 0x%02x:%02x:%02x:%02x:%02x:%02xn",
  762.            etherSrcAddr[0],
  763.            etherSrcAddr[1],
  764.            etherSrcAddr[2], 
  765.            etherSrcAddr[3], 
  766.            etherSrcAddr[4], 
  767.            etherSrcAddr[5] );
  768.     logMsg("Ethernet Type (%X): %sn", etherType, (int)etherTypeStr, 0, 0, 0, 0);
  769.     if (!nonIpHdrDetected)
  770.         {
  771.         ixIpHdrDump(mData + 14 );
  772.         }
  773.     }
  774. /******************************************************************************
  775.  *
  776.  * This function can be used to output the IP headers of messages. The inputted
  777.  * mData pointer is assumed to point to the start of the IP header
  778.  *
  779.  *****************************************************************************/
  780. void ixIpHdrDump(const char * const mData)
  781.     {
  782.     static struct in_addr srcAddr;
  783.     static struct in_addr dstAddr;
  784.     static char ipAddrStr[INET_ADDR_LEN];
  785.     if (mData == NULL)
  786.         {
  787.         logMsg("ERROR: RNDIS detected NULL pointer in ixIpHdrDumpn",
  788.                0,0,0,0,0,0);
  789.         return;
  790.         }
  791.     /*
  792.      * Check for a non word aligned header
  793.      */
  794.     if (((UINT32) mData) % 4 == 0)
  795.         {
  796.         logMsg("*** IP Header ***n", 0, 0, 0, 0, 0, 0);
  797.         }
  798.      else
  799.         {
  800.         logMsg("*** IP Header *** WARNING: THIS IS NOT WORD ALIGNEDn", 0, 0, 0, 0, 0, 0);
  801.         }
  802.     logMsg("Total Length: %u 0x%08Xn",
  803.            ntohs(((struct ip *) mData)->ip_len),(((struct ip *) mData)->ip_len) , 0, 0, 0, 0);
  804.     logMsg("Protocol: %sn",
  805.            (int)ixIpProtoStrGet(((struct ip *) mData)->ip_p), 0, 0, 0, 0, 0);
  806.     /*
  807.      * Potential for the source IP address to be on a half word
  808.      * boundary. E.g. If the RNDIS header is word aligned (44 bytes 
  809.      * long), the Ethernet header follows directly (14 bytes), and
  810.      * then the IP header is directly after that, then the IP 
  811.      * will be on a half word boundary... This may have performance
  812.      * impacts on the system.
  813.      */
  814.     memcpy(&(srcAddr.s_addr),
  815.            &(((struct ip *)mData)->ip_src.s_addr),
  816.            sizeof (UINT32));
  817.     memcpy( &(dstAddr.s_addr),
  818.             &(((struct ip *)mData)->ip_dst.s_addr),
  819.             sizeof (UINT32));
  820.     /*
  821.      * Get the IP addresses in string dotted decimal format
  822.      */
  823.     inet_ntoa_b(srcAddr, ipAddrStr);
  824.     logMsg("Src Addr: %sn", (int)ipAddrStr, 0, 0, 0, 0, 0);
  825.     inet_ntoa_b(dstAddr, ipAddrStr);
  826.     logMsg("Dst Addr: %sn", (int)ipAddrStr, 0, 0, 0, 0, 0);
  827.     }
  828. #endif /* INCLUDE_IXETHACCEND */