sysGei8254xEnd.c
上传用户:dqzhongke1
上传日期:2022-06-26
资源大小:667k
文件大小:52k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* sysGei82543End.c - Intel 82540/82541/82543/82544/82545/82546 END support routine */
  2. /*
  3.  * Copyright (c) 2001-2006 Wind River Systems, Inc.
  4.  *
  5.  * The right to copy, distribute, modify, or otherwise make use
  6.  * of this software may be licensed only pursuant to the terms
  7.  * of an applicable Wind River license agreement.
  8.  */
  9. /*
  10. modification history
  11. --------------------
  12. 01r,06feb06,pmr  HEND support no longer uses this file.
  13. 01q,27sep05,pmr  SPR 112656: fix for non-hEnd support.
  14. 01p,23sep05,agf  remove sysParamsSend;
  15.          componentized and moved to driver configlette
  16. 01o,16aug05,pmr  support for hEnd.
  17. 01n,07jul04,jln  support 82546GB MAC
  18. 01m,04jun04,jln  support 82541 MAC
  19. 01l,07may04,zmm  Fix diab compiler warnings.
  20. 01k,12nov03,sn   Fixed syntax for string spanning multiple lines
  21. 01j,07jul02,jln  add 82544GC device ID (spr#79520)
  22. 01i,21may02,jln  support 82545/82546 fiber-based adapters (spr 78084)
  23. 01h,25apr02,jln  fix short cable errata; support larger EEPROM; add more
  24.                  BSP specific functions; support 82540/82545/82546 chips;
  25.                  change the input argument of sys543IntEnable() and
  26.                  sys543IntDisable() from vector to unit.
  27. 01g,23apr02,pai  Made DEC and GEI END driver config names consistent with
  28.                  other END driver config names.
  29. 01f,05dec01,jln  save pciBus/pciDevice/pciFunc in pci resource table;
  30.                  more comments on PCI to PHY address translation
  31. 01e,19nov01,pai  Pass the correct CSR memory size to sysMmuMapAdd().
  32. 01d,09nov01,pai  Updated documentation and routines for new device discovery
  33.                  algorithm (SPR# 35716).
  34. 01c,16Oct01,jln  added sysGei8254xEndLoad; refined device detecting
  35. 01b,08Aug01,jln  support jumbo frame and 544_based adapter, more comments
  36. 01a,08Jan01,jln  written based on sysNetif.c.
  37. */
  38. /*
  39. This module is the WRS-supplied configuration module for Intel PRO1000
  40. F/T/XF/XT/MT/MF adapters. It has routines for initializing device resources
  41. and provides BSP-specific gei82543End (gei) END driver routines for
  42. Intel 82540/3/4/5/6 Ethernet PCI bus controllers.
  43. The number of supported devices that can be configured for a particular
  44. system is finite and is specified by the GEI_MAX_DEV configuration
  45. constant.  This value, and the internal data structures using it, can be
  46. modified in this file for specific implementations.
  47. SEE ALSO: ifLib,
  48. .I "RS82543GC GIGABIT ETHERNET CONTROLLER NETWORKING SILICON DEVELOPER'S MANUAL"
  49. */
  50. #if defined(INCLUDE_GEI8254X_END)
  51. /* namespace collisions */
  52. #undef INTEL_PCI_VENDOR_ID  /* redefined in gei82543End.h (temporary fix) */
  53. /* includes */
  54. #include <end.h>
  55. #include <drv/end/gei82543End.h>
  56. /* defines */
  57. /* specify the maximum number of physical devices to configure */
  58. #define GEI_MAX_DEV      (4)
  59. /* Default RX descriptor  */
  60. #ifndef GEI_RXDES_NUM
  61. #define GEI_RXDES_NUM              (GEI_DEFAULT_RXDES_NUM)
  62. #endif
  63. /* Default TX descriptor  */
  64. #ifndef GEI_TXDES_NUM
  65. #define GEI_TXDES_NUM              (GEI_DEFAULT_TXDES_NUM)
  66. #endif
  67. /* Default User's flags  */
  68. /* ORed the flag of GEI_END_JUMBO_FRAME_SUPPORT if jumbo frame needed */
  69. #ifndef GEI_USR_FLAG
  70. #define GEI_USR_FLAG        (GEI_END_SET_TIMER | 
  71.                              GEI_END_SET_RX_PRIORITY | 
  72.                              GEI_END_FREE_RESOURCE_DELAY 
  73.                             )
  74. #endif /* GEI_USR_FLAG */
  75. /*
  76.  * If jumbo frame supported, the default 9000 bytes of MTU will be used.
  77.  * Otherwise 1500 bytes MTU for normal frames. User can set up different
  78.  * MTU here for jumbo frames.
  79.  */
  80. #ifndef GEI_JUMBO_MTU_VALUE
  81. #define GEI_JUMBO_MTU_VALUE         (0)  /* Will use default value (9000) */
  82. #endif /* GEI_JUMBO_MTU_VALUE */
  83. /*
  84.  * define the offset value for different arches.
  85.  * For arch like ARM which requires 4-byte alignment for Integer,
  86.  * use offset of 2
  87.  */
  88. #define GEI_X86_OFFSET_VALUE        (0x0)
  89. #define GEI_ARM_OFFSET_VALUE        (0x2)
  90. #ifndef GEI_OFFSET_VALUE
  91. #define GEI_OFFSET_VALUE            GEI_X86_OFFSET_VALUE
  92. #endif /* GEI_OFFSET_VALUE */
  93. /* Assuming 1:1 mapping */
  94. #if (_BYTE_ORDER == _BIG_ENDIAN)
  95. #define GEI_SYS_WRITE_REG(unit, reg, value)     
  96.    ((*(volatile UINT32 *)(PCI_MEMIO2LOCAL(geiResources[(unit)].memBaseLow + reg))) = 
  97.     (LONGSWAP((UINT32)(value))))
  98. #define GEI_SYS_READ_REG(unit, reg)             
  99.    LONGSWAP((*(volatile UINT32 *)(PCI_MEMIO2LOCAL(geiResources[(unit)].memBaseLow + reg))))
  100. #else
  101. #define GEI_SYS_WRITE_REG(unit, reg, value)     
  102.    ((*(volatile UINT32 *)(PCI_MEMIO2LOCAL(geiResources[(unit)].memBaseLow + reg))) = 
  103.     (UINT32)(value))
  104. #define GEI_SYS_READ_REG(unit, reg)             
  105.    (*(volatile UINT32 *)(PCI_MEMIO2LOCAL(geiResources[(unit)].memBaseLow + reg)))
  106. #endif /* _BYTE_ORDER */
  107. /* PCI device ID for Intel 82543/82544 Ethernet */
  108. #define PRO1000_543_PCI_DEVICE_ID_T     (0x1001) /* Copper */
  109. #define PRO1000_543_PCI_DEVICE_ID_FT    (0x1004) /* Fiber / Copper */
  110. #define PRO1000_544_PCI_DEVICE_ID_XT    (0x1008) /* Copper */
  111. #define PRO1000_544_PCI_DEVICE_ID_XF    (0x1009) /* Fiber */
  112. #define PRO1000_544_PCI_DEVICE_ID_GC    (0x100c) /* Copper */
  113. #define PRO1000_540_PCI_DEVICE_ID_XT    (0x100e) /* Copper only */
  114. #define PRO1000_545_PCI_DEVICE_ID_XT    (0x100f) /* Copper */
  115. #define PRO1000_546_PCI_DEVICE_ID_XT    (0x1010) /* Copper - 82546 EB */
  116. #define PRO1000_545_PCI_DEVICE_ID_MF    (0x1011) /* Fiber */
  117. #define PRO1000_546_PCI_DEVICE_ID_MF    (0x1012) /* Fiber */
  118. #define PRO1000_541_PCI_DEVICE_ID_XT    (0x1078) /* Copper */
  119. #define PRO1000_541_PCI_DEVICE_ID_GT    (0x107C) /* Copper */
  120. #define PRO1000_546_PCI_DEVICE_ID_XT2   (0x1079) /* Copper - 82546 GB */
  121. #define PRO1000_572_PCI_DEVICE_ID_EI    (0x107D) /* Copper - 82572EI */
  122. #define PRO1000_573_PCI_DEVICE_ID_E (0x108B) /* Copper - 82573E */
  123. #define PRO1000_573_PCI_DEVICE_ID_IAMT (0x108C) /* Copper - 82573E IAMT */
  124. /* device resources */
  125. #define GEI_MEMSIZE_CSR            (0x20000)     /* 128Kb CSR memory size */
  126. #define GEI_MEMSIZE_FLASH          (0x80000)     /* 512Kb Flash memory size */
  127. #define GEI_EEPROM_SZ_64           (64)          /* 64 WORD */
  128. #define GEI_EEPROM_SZ_256          (256)         /* 256 WORD */
  129. #define GEI0_SHMEM_BASE             NONE
  130. #define GEI0_SHMEM_SIZE             (0)
  131. #define GEI0_RXDES_NUM              GEI_RXDES_NUM
  132. #define GEI0_TXDES_NUM              GEI_TXDES_NUM
  133. #define GEI0_USR_FLAG               GEI_USR_FLAG
  134. #define GEI1_SHMEM_BASE             NONE
  135. #define GEI1_SHMEM_SIZE             (0)
  136. #define GEI1_RXDES_NUM              GEI_RXDES_NUM
  137. #define GEI1_TXDES_NUM              GEI_TXDES_NUM
  138. #define GEI1_USR_FLAG               GEI_USR_FLAG
  139. #define GEI2_SHMEM_BASE             NONE
  140. #define GEI2_SHMEM_SIZE             (0)
  141. #define GEI2_RXDES_NUM              GEI_RXDES_NUM
  142. #define GEI2_TXDES_NUM              GEI_TXDES_NUM
  143. #define GEI2_USR_FLAG               GEI_USR_FLAG
  144. #define GEI3_SHMEM_BASE             NONE
  145. #define GEI3_SHMEM_SIZE             (0)
  146. #define GEI3_RXDES_NUM              GEI_RXDES_NUM
  147. #define GEI3_TXDES_NUM              GEI_TXDES_NUM
  148. #define GEI3_USR_FLAG               GEI_USR_FLAG
  149. /* INTEL 82544 INTERNAL PHY */
  150. #define INTEL_82544PHY_OUI_ID                   (0x5043)
  151. #define INTEL_82544PHY_MODEL                    (0x3)
  152. #define INTEL_82544PHY_PHY_SPEC_CTRL_REG        (0x10)
  153. #define INTEL_82544PHY_PHY_SPEC_STAT_REG        (0x11)
  154. #define INTEL_82544PHY_INT_ENABLE_REG           (0x12)
  155. #define INTEL_82544PHY_INT_STATUS_REG           (0x13)
  156. #define INTEL_82544PHY_EXT_PHY_SPEC_CTRL_REG    (0x14)
  157. #define INTEL_82544PHY_RX_ERROR_COUNTER         (0x15)
  158. #define INTEL_82544PHY_PHY_GLOBAL_STAT          (0x17)
  159. #define INTEL_82544PHY_LED_CTRL_REG             (0x18)
  160. #define INTEL_82544PHY_PSCR_ASSERT_CRS_ON_TX    (0x0800)
  161. #define INTEL_82544PHY_EPSCR_TX_CLK_25          (0x0070)
  162. /* Alaska PHY's information */
  163. #define MARVELL_OUI_ID                  (0x5043)
  164. #define MARVELL_ALASKA_88E1000          (0x5)
  165. #define MARVELL_ALASKA_88E1000S         (0x4)
  166. #define ALASKA_PHY_SPEC_CTRL_REG        (0x10)
  167. #define ALASKA_PHY_SPEC_STAT_REG        (0x11)
  168. #define ALASKA_INT_ENABLE_REG           (0x12)
  169. #define ALASKA_INT_STATUS_REG           (0x13)
  170. #define ALASKA_EXT_PHY_SPEC_CTRL_REG    (0x14)
  171. #define ALASKA_RX_ERROR_COUNTER         (0x15)
  172. #define ALASKA_LED_CTRL_REG             (0x18)
  173. #define ALASKA_PSCR_ASSERT_CRS_ON_TX    (0x0800)
  174. #define ALASKA_EPSCR_TX_CLK_25          (0x0070)
  175. #define ALASKA_PSCR_AUTO_X_1000T        (0x0040)
  176. #define ALASKA_PSCR_AUTO_X_MODE         (0x0060)
  177. #define ALASKA_PSSR_DPLX                (0x2000)
  178. #define ALASKA_PSSR_SPEED               (0xC000)
  179. #define ALASKA_PSSR_10MBS               (0x0000)
  180. #define ALASKA_PSSR_100MBS              (0x4000)
  181. #define ALASKA_PSSR_1000MBS             (0x8000)
  182. #ifndef BOARD_TYPE_UNKNOWN
  183. #define BOARD_TYPE_UNKNOWN (-1)
  184. #endif /* BOARD_TYPE_UNKNOWN */
  185. /* typedefs */
  186. typedef struct pciBoardResource      /* PCI_BOARD_RESOURCE */
  187.     {
  188.     int           pciSysNum;         /* PCI system number */
  189.     UINT32        pciBus;            /* PCI Bus number */
  190.     UINT32        pciDevice;         /* PCI Device number */
  191.     UINT32        pciFunc;           /* PCI Function number */
  192.     UINT32        vendorID;          /* PCI Vendor ID */
  193.     UINT32        deviceID;          /* PCI Device ID */
  194.     UINT8         revisionID;        /* PCI Revision ID */
  195.     UINT32        boardType;         /* BSP-specific board type ID */
  196.     UINT8         irq;               /* Interrupt Request Level */
  197.     UINT32        irqvec;            /* Interrupt Request vector */
  198.     UINT32        bar [6];           /* PCI Base Address Registers */
  199.     void * const  pExtended;         /* pointer to extended device info */
  200.     } PCI_BOARD_RESOURCE;
  201. typedef struct geiResource        /* GEI_RESOURCE */
  202.     {
  203.     BOOL   adr64;                 /* Indicator for 64-bit support */
  204.     UINT32 memBaseLow;            /* Base Address LOW */
  205.     UINT32 memBaseHigh;           /* Base Address HIGH */
  206.     UINT32 flashBase;             /* Base Address for FLASH */
  207.     UINT16 eepromSize;            /* size in unit of word (16 bit) - 64/256 */
  208.     UINT16 eeprom_icw1;           /* EEPROM initialization control word 1 */
  209.     UINT16 eeprom_icw2;           /* EEPROM initialization control word 2 */
  210.     UCHAR  enetAddr[6];           /* MAC address for this adaptor */
  211.     UINT32 shMemBase;             /* Share memory address if any */
  212.     UINT32 shMemSize;             /* Share memory size if any */
  213.     UINT32 rxDesNum;              /* RX descriptor for this unit */
  214.     UINT32 txDesNum;              /* TX descriptor for this unit */
  215.     BOOL   useShortCable;         /* TRUE if short cable used for 82544 */
  216.                                      /* by default is FALSE */
  217.     UINT32 usrFlags;              /* user flags for this unit */
  218.     STATUS iniStatus;             /* initialization perform status */
  219.     } GEI_RESOURCE;
  220. /* This table defined board extended resources */
  221. GEI_RESOURCE geiResources [GEI_MAX_DEV] =
  222.     {
  223.     {FALSE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, GEI_EEPROM_SZ_64, 0, 0, {(UCHAR)NONE},
  224.      (UINT32)GEI0_SHMEM_BASE, GEI0_SHMEM_SIZE, GEI0_RXDES_NUM, GEI0_TXDES_NUM, FALSE,
  225.      GEI0_USR_FLAG, ERROR
  226.     },
  227.     {FALSE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, GEI_EEPROM_SZ_64, 0, 0, {(UCHAR)NONE},
  228.      (UINT32)GEI1_SHMEM_BASE, GEI1_SHMEM_SIZE, GEI1_RXDES_NUM, GEI1_TXDES_NUM, FALSE,
  229.      GEI1_USR_FLAG, ERROR
  230.     },
  231.     {FALSE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, GEI_EEPROM_SZ_64, 0, 0, {(UCHAR)NONE},
  232.      (UINT32)GEI2_SHMEM_BASE, GEI2_SHMEM_SIZE, GEI2_RXDES_NUM, GEI2_TXDES_NUM, FALSE,
  233.      GEI2_USR_FLAG, ERROR
  234.     },
  235.     {FALSE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, GEI_EEPROM_SZ_64, 0, 0, {(UCHAR)NONE},
  236.      (UINT32)GEI3_SHMEM_BASE, GEI3_SHMEM_SIZE, GEI3_RXDES_NUM, GEI3_TXDES_NUM, FALSE,
  237.      GEI3_USR_FLAG, ERROR
  238.     }
  239.     };
  240. /* locals */
  241. LOCAL UINT32 geiUnits = 0;     /* number of GEIs we found */
  242. /* This table defines board PCI resources */
  243. /* This table defines board PCI resources */
  244. LOCAL PCI_BOARD_RESOURCE geiPciResources [GEI_MAX_DEV] =
  245.     {
  246.     {NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT8)NONE, (UINT32)NONE, (UINT8)NONE, (UINT32)NONE,
  247.     {(UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE},
  248.      (void * const)(&geiResources[0])
  249.     },
  250.     {NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT8)NONE, (UINT32)NONE, (UINT8)NONE, (UINT32)NONE,
  251.     {(UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE},
  252.      (void * const)(&geiResources[1])
  253.     },
  254.     {NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT8)NONE, (UINT32)NONE, (UINT8)NONE, (UINT32)NONE,
  255.     {(UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE},
  256.      (void * const)(&geiResources[2])
  257.     },
  258.     {NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT8)NONE, (UINT32)NONE, (UINT8)NONE, (UINT32)NONE,
  259.     {(UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE, (UINT32)NONE},
  260.      (void * const)(&geiResources[3])
  261.     }
  262.     };
  263. /* forward declarations */
  264. LOCAL int       sys543IntEnable  (int unit);
  265. LOCAL int       sys543IntDisable (int unit);
  266. LOCAL int       sys543IntAck     (int unit);
  267. LOCAL STATUS    sys543eepromCheckSum (int unit);
  268. LOCAL UINT16    sys543eepromReadWord (int unit,UINT32);
  269. LOCAL STATUS    sys543EtherAdrGet (int unit);
  270. LOCAL void      sys544PhyPreInit (PHY_INFO *);
  271. LOCAL void      sys543PhySpecRegsInit(PHY_INFO *, UINT8);
  272. LOCAL BOOL      sysGei82546InitTimerSetup (ADAPTOR_INFO * );
  273. LOCAL BOOL      sysGei82546DynaTimerSetup (ADAPTOR_INFO * );
  274. LOCAL UINT32    sysGeiDevToType (UINT32, UINT32, UINT8);
  275. /*****************************************************************************
  276. *
  277. * sys543PciInit - initialize a GEI 8254x PCI ethernet device
  278. *
  279. * This routine performs basic PCI initialization for 8254x ethernet
  280. * devices supported by the gei82543End END driver.  Parameters to this
  281. * routine specify a PCI function, including PCI ID registers, to
  282. * initialize.  If supported,  the device memory and I/O addresses are
  283. * mapped into the local CPU address space and an internal board-specific
  284. * PCI resources table is updated with information on the board type,
  285. * memory address, and IO address.
  286. *
  287. * CAVEATS
  288. * This routine must be performed prior to MMU initialization, usrMmuInit().
  289. * If the number of supported 8254x physical device instances installed
  290. * on the PCI bus exceeds GEI_MAX_DEV, then the extra devices will not be
  291. * initialized in this routine.
  292. *
  293. * RETURNS:
  294. * OK, or ERROR if the specified device is not supported, or if
  295. * the device could not be mapped into the local CPU memory space.
  296. */
  297. STATUS sys543PciInit
  298.     (
  299.     UINT32         pciBus,      /* store a PCI bus number */
  300.     UINT32         pciDevice,   /* store a PCI device number */
  301.     UINT32         pciFunc,     /* store a PCI function number */
  302.     UINT32         vendorId,    /* store a PCI vendor ID */
  303.     UINT32         deviceId,    /* store a PCI device ID */
  304.     UINT8          revisionId,  /* store a PCI revision ID */
  305.     UINT32         boardType,   /* board type */
  306.     int            pciSysNum    /* PCI system number */
  307.     )
  308.     {
  309.     UINT32         memBaseLo;   /* temporary BAR storage */
  310.     UINT32         memBaseHi;
  311.     UINT32         flashBase;
  312.     UINT8          irq;         /* store PCI interrupt line (IRQ) number */
  313.     GEI_RESOURCE * pReso;       /* alias extended resource table */
  314.     /* number of physical units exceeded the number supported ? */
  315.     if (geiUnits >= GEI_MAX_DEV)
  316.         {
  317.         return (ERROR);
  318.         }
  319.     if ((boardType = sysGeiDevToType (vendorId, deviceId, revisionId))
  320.         == BOARD_TYPE_UNKNOWN)
  321.         {
  322.         return (ERROR);
  323.         }
  324.     if (pciSysNum != CDS85XX_PCI_1_BUS && pciSysNum != CDS85XX_PCI_2_BUS && pciSysNum != CDS85XX_PCIEX_BUS)
  325.     {
  326. printf("invalid bus %dn", pciSysNum);
  327.         return ERROR;
  328.      }
  329.     geiPciResources[geiUnits].pciSysNum = pciSysNum;
  330.     /* BAR information will be saved in the extended resource table */
  331.     pReso = (GEI_RESOURCE *)(geiPciResources[geiUnits].pExtended);
  332.     /* Auto Config doesn't work for PCI Express so manually configure */
  333.     if (pciSysNum == CDS85XX_PCIEX_BUS)
  334. {
  335. memBaseLo = CPU_PCI_MEMIO_ADRS3;
  336. pciConfigOutLong  (pciBus, pciDevice, pciFunc, PCI_CFG_BASE_ADDRESS_0, memBaseLo);
  337. irq = PCIEX_XINT1_LVL;
  338. pciConfigOutByte  (pciBus, pciDevice, pciFunc, PCI_CFG_DEV_INT_LINE, irq);
  339. }
  340.     /*
  341.      * BAR0: [32:17]: memory base
  342.      *       [16:4] : read as "0";
  343.      *       [3]    : 0 - device is not prefetchable
  344.      *       [2:1]  : 00b - 32-bit address space, or
  345.      *                01b - 64-bit address space
  346.      *       [0]    : 0 - memory map decoded
  347.      *
  348.      * BAR1: if BAR0[2:1] == 00b, optional flash memory base
  349.      *       if BAR0[2:1] == 01b, high portion of memory base
  350.      *                            for 64-bit address space
  351.      *
  352.      * BAR2: if BAR0[2:1] == 01b, optional flash memory base
  353.      *       if BAR0[2:1] == 00b, behaves as BAR-1 when BAR-0 is
  354.      *                            a 32-bit value
  355.      */
  356.     pciConfigInLong  (pciBus, pciDevice, pciFunc,
  357.                       PCI_CFG_BASE_ADDRESS_0, &memBaseLo);
  358.     pReso->adr64 = ((memBaseLo & BAR0_64_BIT) == BAR0_64_BIT)
  359.                    ? TRUE : FALSE;
  360.     if (pReso->adr64)
  361.         {
  362.         pciConfigInLong  (pciBus, pciDevice, pciFunc,
  363.                           PCI_CFG_BASE_ADDRESS_1, &memBaseHi);
  364.         pciConfigInLong  (pciBus, pciDevice, pciFunc,
  365.                           PCI_CFG_BASE_ADDRESS_2, &flashBase);
  366.         }
  367.     else
  368.         {
  369.         memBaseHi = 0x0;
  370.         pciConfigInLong  (pciBus, pciDevice, pciFunc,
  371.                           PCI_CFG_BASE_ADDRESS_1, &flashBase);
  372.         }
  373.     memBaseLo &= PCI_MEMBASE_MASK;
  374.     flashBase &= PCI_MEMBASE_MASK;
  375.     /* get the device's interrupt line (IRQ) number */
  376.     pciConfigInByte (pciBus, pciDevice, pciFunc,
  377.                      PCI_CFG_DEV_INT_LINE, &irq);
  378.     /* update the board-specific resource tables */
  379.     pReso->memBaseLow  = memBaseLo;
  380.     pReso->memBaseHigh = memBaseHi;
  381.     pReso->flashBase   = flashBase;
  382.     geiPciResources[geiUnits].irq        = irq;
  383.     geiPciResources[geiUnits].irqvec     = irq;
  384.     geiPciResources[geiUnits].vendorID   = vendorId;
  385.     geiPciResources[geiUnits].deviceID   = deviceId;
  386.     geiPciResources[geiUnits].revisionID = revisionId;
  387.     geiPciResources[geiUnits].boardType  = boardType;
  388.    /* the following support legacy interfaces and data structures */
  389.     geiPciResources[geiUnits].pciBus     = pciBus;
  390.     geiPciResources[geiUnits].pciDevice  = pciDevice;
  391.     geiPciResources[geiUnits].pciFunc    = pciFunc;
  392.     /* enable mapped memory and IO decoders */
  393.     pciConfigOutWord (pciBus, pciDevice, pciFunc, PCI_CFG_COMMAND,
  394.                       PCI_CMD_MEM_ENABLE | PCI_CMD_IO_ENABLE |
  395.                       PCI_CMD_MASTER_ENABLE);
  396.     /* disable sleep mode */
  397.     pciConfigOutByte (pciBus, pciDevice, pciFunc, PCI_CFG_MODE,
  398.                       SLEEP_MODE_DIS);
  399.     ++geiUnits;  /* increment number of units initialized */
  400.     return (OK);
  401.     }
  402. /******************************************************************************
  403. *
  404. * sysGei8254xEndLoad - create load string and load a gei driver.
  405. *
  406. * This routine will be invoked by the MUX for the purpose of loading an
  407. * gei82543End (gei) device with initial parameters.  This routine is
  408. * constructed as an interface wrapper for the driver load routine.  Thus,
  409. * the arguments and return values are consistent with any xxxEndLoad()
  410. * routine defined for an END driver and the MUX API.
  411. *
  412. * INTERNAL
  413. * The muxDevLoad() operation calls this routine twice.  A zero length
  414. * <pParamStr> parameter string indicates that this is the first time
  415. * through this routine.  The driver load routine should return the
  416. * driver name in <pParamStr>.
  417. *
  418. * On the second pass though this routine, the initialization parameter
  419. * string is constructed.  Note that on the second pass, the <pParamStr>
  420. * consists of a colon-delimited END device unit number and rudimentary
  421. * initialization string (often empty) constructed from entries in the
  422. * BSP END Device Table such that:
  423. *
  424. *     <pParamStr> = "<unit>:<default initialization string>"
  425. *
  426. * In the process of building the rest of <pParamStr>, the prepended unit
  427. * number must be preserved and passed to the driver load routine.  The
  428. * <default initialization string> portion mentioned above is discarded,
  429. * but future versions of this routine may use it.
  430. *
  431. * The complete gei82543End driver load string has format:
  432. *
  433. *     <unit>:<shMemBase>:<shMemSize>:<rxDesNum>:<txDesNum>:<usrFlags>:
  434. *     <offset>:<mtu>
  435. *
  436. * RETURNS: An END object pointer, or NULL on error, or 0 and the name of the
  437. * device if the <pParamStr> was NULL.
  438. *
  439. * SEE ALSO: gei82543EndLoad()
  440. */
  441. END_OBJ * sysGei8254xEndLoad
  442.     (
  443.     char *    pParamStr,   /* ptr to initialization parameter string */
  444.     void *    unused       /* unused optional argument */
  445.     )
  446.     {
  447.     END_OBJ * pEnd;
  448.     char      paramStr [END_INIT_STR_MAX];
  449.     if (strlen (pParamStr) == 0)
  450.         {
  451.         /* PASS (1)
  452.          * The driver load routine returns the driver name in <pParamStr>.
  453.          */
  454.         pEnd = gei82543EndLoad (pParamStr);
  455. printf("sysGei8254xEndLoad pass 1n");
  456.         }
  457.     else
  458.         {
  459. printf("sysGei8254xEndLoad pass 2n");
  460.         /* PASS (2)
  461.          * The END <unit> number is prepended to <pParamStr>.  Construct
  462.          * the rest of the driver load string based on physical devices
  463.          * discovered in sys543PciInit().  When this routine is called
  464.          * to process a particular END <unit> number, use the END <unit> as
  465.          * an index into the PCI "resources" table to build the driver
  466.          * parameter string.
  467.          */
  468.         GEI_RESOURCE *  pReso;
  469.         char * holder = NULL;
  470.         int    unit   = atoi (strtok_r (pParamStr, ":", &holder));
  471.         /* is there a PCI resource associated with this END unit ? */
  472.         if (unit >= geiUnits)
  473.             {
  474. printf("unit =%d, geiUnits = %dn", unit, geiUnits);
  475.             return NULL;
  476.             }
  477.         pReso = (GEI_RESOURCE *)(geiPciResources[unit].pExtended);
  478.         /* finish off the initialization parameter string */
  479.         sprintf (paramStr,"%d:0x%x:0x%x:0x%x:0x%x:0x%x:%d:%d",
  480.                  unit,                          /* END unit number */
  481.                  pReso->shMemBase,              /* share memory base */
  482.                  pReso->shMemSize,              /* share memory size */
  483.                  pReso->rxDesNum,               /* RX Descriptor Number*/
  484.                  pReso->txDesNum,               /* TX Descriptor Number*/
  485.                  pReso->usrFlags,               /* user's flags */
  486.                  GEI_OFFSET_VALUE,              /* offset value */
  487.                  GEI_JUMBO_MTU_VALUE            /* mtu value */
  488.                 );
  489. printf("%sn", paramStr);
  490.         if ((pEnd = gei82543EndLoad (paramStr)) == (END_OBJ *)NULL)
  491.             {
  492.             printf ("ERROR: sysGei8254xEndLoad fails to load gei %dn", unit);
  493.             }
  494.         }
  495. printf("pEnd = 0x%08xn", pEnd);
  496.     return (pEnd);
  497.     }
  498. /*****************************************************************************
  499. * sys8254xDeviceCheck - check whether a device is 8254x
  500. *
  501. * This function verifies a device is Intel 8254x.
  502. *
  503. * RETURNS: OK
  504. *
  505. * ERRNO: N/A
  506. */
  507. STATUS sys8254xDeviceCheck
  508.     (
  509.     UINT32              pciBus,        /* store a PCI bus number */
  510.     UINT32              pciDevice,     /* store a PCI device number */
  511.     UINT32              pciFunc,       /* store a PCI function number */
  512.     void *              pPciSysNum     /* reserved argument */
  513.     )
  514.     {
  515.     UINT32        boardType;   /* store a BSP-specific board type constant */
  516.     UINT32        vendorId;    /* store a PCI vendor ID */
  517.     UINT32        deviceId;    /* store a PCI device ID */
  518.     UINT8         revisionId;  /* store a PCI revision ID */
  519.     pciConfigInLong (pciBus, pciDevice, pciFunc,
  520.                       PCI_CFG_VENDOR_ID, &vendorId);
  521.     pciConfigInByte (pciBus, pciDevice, pciFunc,
  522.                          PCI_CFG_REVISION, &revisionId);
  523.     deviceId = ((vendorId >> 16) & 0x0000ffff);
  524.     vendorId = (vendorId & 0x0000ffff);
  525.     if ((boardType = sysGeiDevToType (vendorId, deviceId, revisionId))
  526.                   != (UINT32)(BOARD_TYPE_UNKNOWN))
  527.         {
  528.         int pciSysNum = *(int *)pPciSysNum;
  529.         sys543PciInit (pciBus, pciDevice, pciFunc, vendorId,
  530.                         deviceId, revisionId, boardType, pciSysNum);
  531.         }
  532.     return OK;
  533.     }
  534. /*****************************************************************************
  535. *
  536. * sys82543BoardInit - Adaptor initialization for 8254x chip
  537. *
  538. * This routine is expected to perform any adapter-specific or target-specific
  539. * initialization that must be done prior to initializing the 8254x chip.
  540. *
  541. * The 82543 driver calls this routine from the driver load routine before
  542. * any other routines.
  543. *
  544. * RETURNS: OK or ERROR
  545. */
  546. STATUS sys82543BoardInit
  547.     (
  548.     int            unit,      /* unit number */
  549.     ADAPTOR_INFO * pBoard     /* board information for the GEI driver */
  550.     )
  551.     {
  552.     PCI_BOARD_RESOURCE * pRsrc;
  553.     GEI_RESOURCE *       pReso;
  554.     BOOL                 lanB = FALSE;
  555.     int i;
  556.     /* sanity check */
  557.     if (unit >= geiUnits)
  558.         return (ERROR);
  559.     pRsrc = &geiPciResources[unit];
  560.     pReso = (GEI_RESOURCE *)(pRsrc->pExtended);
  561.     if (pRsrc->boardType != PRO1000_543_BOARD &&
  562.         pRsrc->boardType != PRO1000_544_BOARD &&
  563.         pRsrc->boardType != PRO1000_546_BOARD &&
  564.         pRsrc->boardType != PRO1000_573_BOARD)
  565.          return ERROR;
  566.     if (pRsrc->boardType == PRO1000_546_BOARD)
  567.         {
  568.         UINT32 eecd;
  569.         UINT16 devId;
  570.         if (!((eecd = GEI_SYS_READ_REG(unit, INTEL_82543GC_EECD)) & EECD_PRES_BIT))
  571.             {
  572.             printf ("ERROR: gei unit %d eeprom not presentedn", unit);
  573.             return ERROR;
  574.             }
  575.         pReso->eepromSize = (eecd & EECD_SIZE_BIT)? 256 : 64;
  576.         /* detect if this is one of 82546EB dual ports */
  577.         pciConfigInWord (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc,
  578.                           PCI_CFG_DEVICE_ID, &devId);
  579.         if (devId == PRO1000_546_PCI_DEVICE_ID_XT ||
  580.             devId == PRO1000_546_PCI_DEVICE_ID_MF)
  581.         {
  582.             UINT8 headerType;
  583.             pciConfigInByte (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc,
  584.                              PCI_CFG_HEADER_TYPE, &headerType);
  585.             if (headerType == 0x80)
  586.             lanB = (pRsrc->pciFunc == 1)? TRUE : FALSE;
  587.             else if (pRsrc->pciFunc != 0)
  588.             {
  589.                 printf ("Error in detecting 82546 dual port: header type =%2d, "
  590.                          "pci func=%2dn", (UINT32)headerType, (UINT32)(pRsrc->pciFunc));
  591.             }
  592.             }
  593.         }
  594.     /* Reset */
  595.     GEI_SYS_WRITE_REG(unit, INTEL_82543GC_CTRL, CTRL_RST_BIT);
  596.     for (i = 0; i < 10000; i++)
  597.         {
  598.         sysDelay();
  599.         if (!(GEI_SYS_READ_REG(unit, INTEL_82543GC_CTRL) & CTRL_RST_BIT))
  600.             break;
  601.         }
  602.     for (i = 0; i < 50; i++)
  603.         sysDelay();
  604.     /* perform EEPROM checksum */
  605.     if (sys543eepromCheckSum (unit) != OK)
  606.         {
  607.         printf ("ERROR: gei unit=%d, EEPROM checksum error!n", unit);
  608.         }
  609.     /* get the Ethernet Address from eeprom */
  610.     if (sys543EtherAdrGet (unit) == OK)
  611.         {
  612.         if (pRsrc->boardType == PRO1000_546_BOARD && lanB == TRUE)
  613.            {
  614.            int   ix;
  615.        /* update LANB address */
  616.            for (ix = 5; ix >= 0; ix--)
  617.             {
  618.         if (pReso->enetAddr[ix] != 0xff)
  619.             {
  620.                     pReso->enetAddr[ix]++;
  621.                     break;
  622.                     }
  623.                 else
  624.                     pReso->enetAddr[ix] = 0;
  625.                 }
  626.            }
  627.         }
  628.     else
  629.          printf ("ERROR: gei unit=%d, Invalid Ethernet Address!n", unit);
  630.     /* get the initialization control word 1 (ICW1) in EEPROM */
  631.     pReso->eeprom_icw1 = sys543eepromReadWord (unit, EEPROM_ICW1);
  632.     /* get the initialization control word 2 (ICW2) in EEPROM */
  633.     pReso->eeprom_icw2 = sys543eepromReadWord (unit, EEPROM_ICW2);
  634.     /* initializes the board information structure */
  635.     pBoard->boardType   = pRsrc->boardType;
  636.     pBoard->vector      = pRsrc->irq;
  637.     pBoard->regBaseHigh = pReso->memBaseHigh;
  638.     pBoard->regBaseLow  = PCI_MEMIO2LOCAL(pReso->memBaseLow);
  639.     pBoard->flashBase   = PCI_MEMIO2LOCAL(pReso->flashBase);
  640.     pBoard->adr64       = pReso->adr64;
  641.     pBoard->intEnable   = sys543IntEnable;
  642.     pBoard->intDisable  = sys543IntDisable;
  643.     pBoard->intAck      = sys543IntAck;
  644.     /* Intel Copper-based adapter is based on GMII interface */
  645.     pBoard->phyType     = GEI_PHY_GMII_TYPE;
  646.     if (pBoard->boardType == PRO1000_544_BOARD &&
  647.                              geiResources[unit].useShortCable)
  648.         {
  649.         miiPhyOptFuncSet ((FUNCPTR)sys544PhyPreInit);
  650.         }
  651.     pBoard->phySpecInit = sys543PhySpecRegsInit;
  652.     /* BSP specific
  653.      * delayFunc is BSP specific. We prefer a higher time resolution delay
  654.      * delayUnit is the time of ns elapsed when calling delayFunc ().
  655.      */
  656.     pBoard->delayFunc     = (FUNCPTR) sysDelay;
  657.     pBoard->delayUnit     = 720; /* In x86, sysDelay() takes about 720ns */
  658.     /* BSP specific
  659.      * phyDelayRtn is used as a delay function for PHY detection, if not set,
  660.      * taskDelay will be used.
  661.      */
  662.     pBoard->phyDelayRtn = (FUNCPTR) taskDelay;
  663.     pBoard->phyMaxDelay = MII_PHY_DEF_DELAY;
  664.     pBoard->phyDelayParm = 5;
  665.     /* BSP/adapter specific
  666.      * set the PHY address if you know it, otherwise set to zero
  667.      * INTEL 82540/4/5/6-based adapters have a built-in phy with Addr of 1
  668.      */
  669.     pBoard->phyAddr = (pRsrc->boardType == PRO1000_544_BOARD ||
  670.                        pRsrc->boardType == PRO1000_546_BOARD ||
  671.                        pRsrc->boardType == PRO1000_573_BOARD)? 1 : 0;
  672.     /* BSP/adapter specific (for 82540/82545/82546 only)
  673.      * allow users set up the device's internal timer based on their
  674.      * application. sysGeiInitTimerSet() is called when the device
  675.      * starts; sysGeiDynaTimerSet() is called every 2s in tNetTask if
  676.      * GEI_END_SET_TIMER is set.
  677.      */
  678.     if (pRsrc->boardType == PRO1000_546_BOARD)
  679.         {
  680.         pBoard->sysGeiDynaTimerSetup = sysGei82546DynaTimerSetup;
  681.         pBoard->sysGeiInitTimerSetup = sysGei82546InitTimerSetup;
  682.         }
  683.     else
  684.         {
  685.         pBoard->sysGeiDynaTimerSetup   = NULL;         /* default */
  686.         pBoard->sysGeiInitTimerSetup   = NULL;         /* default */
  687.         }
  688.     /* BSP specific
  689.      * call back functions perform system physical memory mapping in the PCI
  690.      * address space. sysLocalToBus converts a system physical memory address
  691.      * into the pci address space. sysBusToLocal converts a pci address which
  692.      * actually reflects a system physical memory back to the system memory
  693.      * address. The sysBusToLocal here in this driver is NOT used for mapping
  694.      * PCI device's memory (e.g. PCI device's control/status registers)
  695.      * to the host address space.
  696.      */
  697.     pBoard->sysLocalToBus = NULL;     /* for 1:1 mapping */
  698.     pBoard->sysBusToLocal = NULL;     /* for 1:1 mapping */
  699.     /* specify the interrupt connect/disconnect routines to be used */
  700.     pBoard->intConnect    = (FUNCPTR) pciIntConnect;
  701.     pBoard->intDisConnect = (FUNCPTR) pciIntDisconnect;
  702.     /* get the ICW1 and ICW2 stored in EEPROM */
  703.     pBoard->eeprom_icw1   = pReso->eeprom_icw1;
  704.     pBoard->eeprom_icw2   = pReso->eeprom_icw2;
  705.     /* copy Ether address */
  706.     memcpy (&pBoard->enetAddr[0], &(pReso->enetAddr[0]),
  707.             ETHER_ADDRESS_SIZE);
  708.     /* we finish adaptor initialization */
  709.     pReso->iniStatus = OK;
  710.     /* enable adaptor interrupt */
  711.     intEnable (pRsrc->irq);
  712.     return (OK);
  713.     }
  714. /*************************************************************************
  715. *
  716. * sysGei82546DynaTimerSetup - setup device internal timer value dynamically
  717. *
  718. * This routine will be called every 2 seconds by default if GEI_END_SET_TIMER
  719. * flag is set. The available timers to adjust include RDTR(unit of ns),
  720. * RADV(unit of us), and ITR(unit of 256ns). Based on CPU's and/or tasks'
  721. * usage on system, user can tune the device's performance dynamically.
  722. * This routine would be called in the tNetTask context, and is only
  723. * available for 82540/82545/82546 MACs. Any timer value greater than
  724. * 0xffff won't be used to change corresponding timer register.
  725. *
  726. * RETURNS: TRUE if timer value should change, or FALSE
  727. */
  728. LOCAL BOOL sysGei82546DynaTimerSetup
  729.     (
  730.     ADAPTOR_INFO * pBoard     /* board information for the GEI driver */
  731.     )
  732.     {
  733.     /* user's specific code to decide what value should be used.
  734.      * For example, depending on
  735.      * 1: CPU usage on system and/or,
  736.      * 2: specific application task's usage and/or,
  737.      * 3: RX/TX packet processing per second, and/or
  738.      * 4: RX/TX interrupt counter per second, and/or
  739.      * 5: RX packet processing for each calling gei82543RxTxIntHandle(),
  740.      * users can choose optimal timer values from a predefined table to
  741.      * reduce interrupt rates. The statistic of 3,4,and 5 items above
  742.      * may be obtained from pBoard->devDrvStat.
  743.      *
  744.      * NOTE:
  745.      * ITR:  Interrupt throttling register (unit of 256ns)
  746.      *       inter-interrupt delay between chip's interrupts
  747.      *
  748.      * RADV: receive interrupt absolute delay timer register (unit of 1.024us)
  749.      *       a RX interrupt will absolutely occur at this defined value
  750.      *       after the first packet is received.
  751.      *
  752.      * RDTR: receive delay timer register (unit of 1.024us)
  753.      *       a RX interrupt will occur if device has not received a subsequent
  754.      *       packet within this defined value.
  755.      */
  756.     /* value > 0xffff would not be used for corresponding timer registers */
  757.     /* pBoard->devTimerUpdate.rdtrVal = 0xffffffff; /@ unit of 1.024ns */
  758.     /* pBoard->devTimerUpdate.radvVal = 0xffffffff; /@ unit of 1.024us */
  759.     /* pBoard->devTimerUpdate.itrVal  = 0xffffffff; /@ unit of 256 ns */
  760.     /* pBoard->devTimerUpdate.watchDogIntVal = 2;   /@ 2 second default */
  761.     /* return TRUE; */
  762.     return FALSE;
  763.     }
  764. /*************************************************************************
  765. *
  766. * sysGei82546InitTimerSetup - initially setup device internal timer value
  767. *
  768. * The device's internal timers include RDTR(unit of ns),
  769. * RADV(unit of us), and ITR(unit of 256ns). The function is
  770. * called before device starts up, and it is only available for
  771. * 82540/82545/82546 MACs. Any timer value greater than 0xffff will
  772. * be discarded.
  773. *
  774. * RETURNS: TRUE if timer value should change, or FALSE
  775. */
  776. LOCAL BOOL sysGei82546InitTimerSetup
  777.     (
  778.     ADAPTOR_INFO * pBoard     /* board information for the GEI driver */
  779.     )
  780.     {
  781.     /* value > 0xffff would not change corresponding timer registers */
  782.     /* pBoard->devTimerUpdate.rdtrVal = 0xffffffff; /@ unit of 1.024ns */
  783.     /* pBoard->devTimerUpdate.radvVal = 0xffffffff; /@ unit of 1.024us */
  784.     /* pBoard->devTimerUpdate.itrVal  = 0xffffffff; /@ unit of 256 ns  */
  785.     /* pBoard->devTimerUpdate.watchDogIntVal = 2;   /@ 2 second default */
  786.     /* return TRUE; */
  787.     return FALSE;
  788.     }
  789. /*************************************************************************
  790. *
  791. * sys543eepromReadBits - read bits from EEPROM
  792. *
  793. * This routine reads bit data from EEPROM
  794. *
  795. * RETURNS: value in WORD size
  796. */
  797. LOCAL UINT16 sys543eepromReadBits
  798.     (
  799.     int      unit,
  800.     int      bitsNum
  801.     )
  802.     {
  803.     int      count;
  804.     UINT32   ix;
  805.     UINT16   val = 0;
  806.     UINT16   reqBit = 0;
  807.     PCI_BOARD_RESOURCE * pRsrc;
  808.     pRsrc = &geiPciResources[unit];
  809.     if (pRsrc->boardType == PRO1000_546_BOARD)
  810.         reqBit = EECD_REQ_BIT;
  811.     for (ix = 0; ix < bitsNum; ix++)
  812.         {
  813.         /* raise the clk */
  814.         GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD,
  815.                                 (EECD_CS_BIT | EECD_SK_BIT | reqBit));
  816.         /* wait 2000ns */
  817.         for (count = 0; count < 3; count++)
  818.              sysDelay ();
  819.         val = ( val << 1) |
  820.           ((GEI_SYS_READ_REG(unit, INTEL_82543GC_EECD) & EECD_DO_BIT)? 1 : 0);
  821.         /* lower the clk */
  822.         GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, (EECD_CS_BIT | reqBit));
  823.         /* wait 2000 ns */
  824.         for (count = 0; count < 3; count++)
  825.              sysDelay ();
  826.         }
  827.     return (val);
  828.     }
  829. /*************************************************************************
  830. *
  831. * sys543eepromWriteBits - write bits out to EEPROM
  832. *
  833. * This routine writes bits out to EEPROM
  834. *
  835. * RETURNS: N/A
  836. */
  837. LOCAL void sys543eepromWriteBits
  838.     (
  839.     int          unit,
  840.     UINT16       value,
  841.     UINT16       bitNum
  842.     )
  843.     {
  844.     int             count;
  845.     volatile UINT16 data;
  846.     UINT16          reqBit = 0;
  847.     PCI_BOARD_RESOURCE * pRsrc;
  848.     pRsrc = &geiPciResources[unit];
  849.     if (pRsrc->boardType == PRO1000_546_BOARD)
  850.         reqBit = EECD_REQ_BIT;
  851.     if (bitNum == 0)
  852.         return;
  853.     while (bitNum--)
  854.         {
  855.         data = (value & (0x1 << bitNum )) ? EECD_DI_BIT : 0;
  856.         data |=  EECD_CS_BIT;
  857.         /* write the data */
  858.         GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, (data | reqBit));
  859.         /* wait 1000ns */
  860.         for (count = 0; count < 2; count++)
  861.             sysDelay ();
  862.         /* raise the clk */
  863.         GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, (data | EECD_SK_BIT | reqBit));
  864.         /* wait 1000ns */
  865.         for (count = 0; count < 2; count++)
  866.             sysDelay ();
  867.         /* lower the clk */
  868.         GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, (data | reqBit));
  869.         /* wait 1000ns */
  870.         for (count = 0; count < 2; count++)
  871.             sysDelay ();
  872.         }
  873.     }
  874. /*
  875.  * For the 82573, forgo the bitbang access methods and just
  876.  * get the controller to read the EEPROM for us.
  877.  */
  878. LOCAL UINT16 sys573eepromReadWord
  879.     (
  880.     int     unit,
  881.     UINT32  index
  882.     )
  883.     {
  884.     int     count;
  885.     UINT16  val;
  886.     UINT32  tmp;
  887.     PCI_BOARD_RESOURCE * pRsrc;
  888.     pRsrc = &geiPciResources[unit];
  889.     tmp = EERD_START_BIT | (index << 2);
  890.     GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EERD, tmp);
  891.     for (count = 0; count < 10000; count++)
  892.         {
  893.         sysDelay();
  894.         if (GEI_SYS_READ_REG(unit, INTEL_82543GC_EERD) & EERD_573_DONE_BIT)
  895.             break;
  896.         }
  897.     if (count == 10000)
  898.         {
  899.         printf("gei%d: EEPROM read timed outn", unit);
  900.         return (0);
  901.         }
  902.     val = (GEI_SYS_READ_REG(unit, INTEL_82543GC_EERD) >> 16) & 0xFFFF;
  903.     return (val);
  904.     }
  905. /*************************************************************************
  906. *
  907. * sys543eepromReadWord - Read a word from EEPROM
  908. *
  909. * RETURNS: value in WORD size
  910. */
  911. LOCAL UINT16 sys543eepromReadWord
  912.     (
  913.     int     unit,
  914.     UINT32  index
  915.     )
  916.     {
  917.     int     count;
  918.     UINT16  val;
  919.     UINT32  tmp;
  920.     PCI_BOARD_RESOURCE * pRsrc;
  921.     pRsrc = &geiPciResources[unit];
  922.     if (pRsrc->boardType == PRO1000_573_BOARD)
  923.         return (sys573eepromReadWord (unit, index));
  924.     if (pRsrc->boardType == PRO1000_546_BOARD)
  925.       {
  926.       int  ix = 0;
  927.       BOOL accessGet = FALSE;
  928.       tmp = GEI_SYS_READ_REG(unit, INTEL_82543GC_EECD);
  929.       tmp |= EECD_REQ_BIT;     /* request EEPROM access */
  930.       GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, tmp);
  931.       do {
  932.          /* wait 2us */
  933.          for (count = 0; count < 3; count++)
  934.               sysDelay ();
  935.          if ((tmp = GEI_SYS_READ_REG(unit, INTEL_82543GC_EECD)) & EECD_GNT_BIT)
  936.          {
  937.              accessGet = TRUE;
  938.              break;
  939.              }
  940.          } while (ix++ < 500000);
  941.       if (!accessGet)
  942.     {
  943.     /* timeout in a second */
  944.         printf ("ERROR: timeout to grant access to gei unit %d EEPROMn", unit);
  945.         return 0;
  946.         }
  947.       }
  948.     if (index >= geiResources[(unit)].eepromSize)
  949.         {
  950.         printf ("ERROR: gei unit %d Invalid index %d to EEPROMn", unit, index);
  951.         return 0;
  952.         }
  953.     tmp = GEI_SYS_READ_REG(unit, INTEL_82543GC_EECD);
  954.     GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, EECD_CS_BIT);
  955.     /* wait 1000ns */
  956.     for (count = 0; count < 2; count++)
  957.          sysDelay ();
  958.     /* write the opcode out */
  959.     sys543eepromWriteBits (unit, EEPROM_READ_OPCODE, EEPROM_CMD_BITS);
  960.     /* write the index out */
  961.     if (geiResources[(unit)].eepromSize == 64)
  962.         sys543eepromWriteBits (unit, index, 6);
  963.     else if (geiResources[(unit)].eepromSize == 256)
  964.         sys543eepromWriteBits (unit, index, 8);
  965.     else /* unsupported, but still try 64 words */
  966.        {
  967.         sys543eepromWriteBits (unit, index, 6);
  968.         printf ("ERROR: gei unit %d unsupported EEPROM sizen", unit);
  969.        }
  970.     GEI_SYS_READ_REG(unit, INTEL_82543GC_EECD);
  971.     /* read the data */
  972.     val = sys543eepromReadBits (unit, EEPROM_DATA_BITS);
  973.     /* clean up access to EEPROM */
  974.     if (pRsrc->boardType == PRO1000_546_BOARD)
  975.        tmp &= ~(EECD_DI_BIT | EECD_DO_BIT | EECD_CS_BIT | EECD_REQ_BIT);
  976.     else
  977.        tmp &= ~(EECD_DI_BIT | EECD_DO_BIT | EECD_CS_BIT);
  978.     GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, tmp);
  979.     return val;
  980.     }
  981. /*************************************************************************
  982. *
  983. * sys543EtherAdrGet - Get Ethernet address from EEPROM
  984. *
  985. * This routine get an Ethernet address from EEPROM
  986. *
  987. * RETURNS: OK or ERROR
  988. */
  989. LOCAL STATUS sys543EtherAdrGet
  990.     (
  991.     int    unit
  992.     )
  993.     {
  994.     UINT32 ix;
  995.     UINT32 count = 0;
  996.     UINT16 val;
  997.     UCHAR  adr [ETHER_ADDRESS_SIZE];
  998.     GEI_RESOURCE * pReso = (GEI_RESOURCE *)(geiPciResources[unit].pExtended);
  999.     for (ix = 0; ix < ETHER_ADDRESS_SIZE / sizeof(UINT16); ix++)
  1000.         {
  1001.         /* get word i from EEPROM */
  1002.         val = sys543eepromReadWord (unit, (UINT16)(EEPROM_IA_ADDRESS + ix));
  1003.         adr [count++] = (UCHAR)val;
  1004.         adr [count++] = (UCHAR) (val >> 8);
  1005.         }
  1006.     memcpy (&(pReso->enetAddr[0]), adr, ETHER_ADDRESS_SIZE);
  1007.     /* check IA is UCAST  */
  1008.     if (adr[0] & 0x1)
  1009.         return (ERROR);
  1010.     return OK;
  1011.     }
  1012. /**************************************************************************
  1013. *
  1014. * sys543eepromCheckSum - calculate checksum
  1015. *
  1016. * This routine perform EEPROM checksum
  1017. *
  1018. * RETURNS: N/A
  1019. */
  1020. LOCAL STATUS sys543eepromCheckSum
  1021.     (
  1022.     int    unit
  1023.     )
  1024.     {
  1025.     UINT16 checkSum = 0 ;
  1026.     UINT32 ix;
  1027.     for (ix = 0; ix < EEPROM_WORD_SIZE; ix++)
  1028.         checkSum += sys543eepromReadWord (unit, ix);
  1029.     if (checkSum == (UINT16)EEPROM_SUM)
  1030.         return OK;
  1031.     return ERROR;
  1032.     }
  1033. /***************************************************************************
  1034. *
  1035. * sys544PhyPreInit -- Init 82544's specific PHY regs before link setup
  1036. *
  1037. * This routine initializes some 82544's PHY regs before set up link
  1038. * Basically, it fixed short cable/backplane problem, Errata 21
  1039. *
  1040. * RETURN: N/A
  1041. */
  1042. LOCAL void sys544PhyPreInit
  1043.     (
  1044.     PHY_INFO * pPhyInfo     /* PHY's info structure pointer */
  1045.     )
  1046.     {
  1047.     UINT16 regVal;          /* register value */
  1048.     UINT16 phyId1;          /* phy Id 1 */
  1049.     UINT16 phyId2;          /* phy ID 2 */
  1050.     UINT32 retVal;          /* return value */
  1051.     UINT32 phyOui = 0;      /* PHY's manufacture ID */
  1052.     UINT32 phyMode;         /* PHY mode number */
  1053.     UINT8  phyAddr;         /* PHY's bus number */
  1054.     phyAddr = pPhyInfo->phyAddr;
  1055.     MII_READ (phyAddr, MII_PHY_ID1_REG, &phyId1, retVal);
  1056.     MII_READ (phyAddr, MII_PHY_ID2_REG, &phyId2, retVal);
  1057.     phyOui =  phyId1 << 6 | phyId2 >> 10;
  1058.     phyMode = (phyId2 & MII_ID2_MODE_MASK) >> 4;
  1059.     if (phyOui == INTEL_82544PHY_OUI_ID && (phyMode == INTEL_82544PHY_MODEL))
  1060.         {
  1061.         regVal = 0x0004;
  1062.         MII_WRITE (phyAddr, 29, 0x4, retVal);
  1063.         MII_READ (phyAddr, 30, &regVal, retVal);
  1064.         regVal |= 0x0200;
  1065.         MII_WRITE (phyAddr, 30, regVal, retVal);
  1066.         }
  1067.     }
  1068. /**************************************************************************
  1069. *
  1070. * sys543PhySpecRegsInit - Initialize PHY specific registers
  1071. *
  1072. * This routine initialize PHY specific registers
  1073. *
  1074. * RETURN: N/A
  1075. */
  1076. LOCAL void sys543PhySpecRegsInit
  1077.     (
  1078.     PHY_INFO * pPhyInfo,    /* PHY's info structure pointer */
  1079.     UINT8      phyAddr      /* PHY's bus number */
  1080.     )
  1081.     {
  1082.     UINT16 regVal;          /* register value */
  1083.     UINT16 phyId1;          /* phy Id 1 */
  1084.     UINT16 phyId2;          /* phy ID 2 */
  1085.     UINT32 retVal;          /* return value */
  1086.     UINT32 phyOui = 0;      /* PHY's manufacture ID */
  1087.     UINT32 phyMode;         /* PHY mode number */
  1088.     /* Intel Pro1000T adaptor uses Alaska transceiver */
  1089.     /* read device ID to check Alaska chip available */
  1090.     MII_READ (phyAddr, MII_PHY_ID1_REG, &phyId1, retVal);
  1091.     MII_READ (phyAddr, MII_PHY_ID2_REG, &phyId2, retVal);
  1092.     phyOui =  phyId1 << 6 | phyId2 >> 10;
  1093.     phyMode = (phyId2 & MII_ID2_MODE_MASK) >> 4;
  1094.     if (phyOui == MARVELL_OUI_ID && (phyMode == MARVELL_ALASKA_88E1000 ||
  1095.                                      phyMode == MARVELL_ALASKA_88E1000S))
  1096.         {
  1097.          /* This is actually a Marvell Alaska 1000T transceiver */
  1098.          /* disable PHY's interrupt */
  1099.          MII_READ (phyAddr, ALASKA_INT_ENABLE_REG, &regVal, retVal);
  1100.          regVal = 0;
  1101.          MII_WRITE (phyAddr, ALASKA_INT_ENABLE_REG, regVal, retVal);
  1102.          /* CRS assert on transmit */
  1103.          MII_READ (phyAddr, ALASKA_PHY_SPEC_CTRL_REG, &regVal, retVal);
  1104.          regVal |= ALASKA_PSCR_ASSERT_CRS_ON_TX;
  1105.          MII_WRITE (phyAddr, ALASKA_PHY_SPEC_CTRL_REG, regVal, retVal);
  1106.         /* set the clock rate when operate in 1000T mode */
  1107.          MII_READ (phyAddr, ALASKA_EXT_PHY_SPEC_CTRL_REG, &regVal, retVal);
  1108.          regVal |= ALASKA_EPSCR_TX_CLK_25;
  1109.          MII_WRITE (phyAddr, ALASKA_EXT_PHY_SPEC_CTRL_REG, regVal, retVal);
  1110.         }
  1111.     else if (phyOui == INTEL_82544PHY_OUI_ID &&
  1112.             (phyMode == INTEL_82544PHY_MODEL))
  1113.         {
  1114.          /* This is INTEL 82544GC/EI internal PHY */
  1115.          /* disable PHY's interrupt */
  1116.          MII_READ (phyAddr, INTEL_82544PHY_INT_ENABLE_REG, &regVal, retVal);
  1117.          regVal = 0;
  1118.          MII_WRITE (phyAddr, INTEL_82544PHY_INT_ENABLE_REG, regVal, retVal);
  1119.          /* CRS assert on transmit */
  1120.          MII_READ (phyAddr, INTEL_82544PHY_PHY_SPEC_CTRL_REG,
  1121.                    &regVal, retVal);
  1122.          regVal |= INTEL_82544PHY_PSCR_ASSERT_CRS_ON_TX;
  1123.          MII_WRITE (phyAddr, INTEL_82544PHY_PHY_SPEC_CTRL_REG,
  1124.                    regVal, retVal);
  1125.         /* set the TX_CLK rate when operate in 1000T mode */
  1126.          MII_READ (phyAddr, INTEL_82544PHY_EXT_PHY_SPEC_CTRL_REG,
  1127.                    &regVal, retVal);
  1128.          regVal |= INTEL_82544PHY_EPSCR_TX_CLK_25;
  1129.          MII_WRITE (phyAddr, INTEL_82544PHY_EXT_PHY_SPEC_CTRL_REG,
  1130.                    regVal, retVal);
  1131.         /* INTEL PHY's bug fixing ... */
  1132.         MII_WRITE (phyAddr, 29, 0x5, retVal);
  1133.         MII_READ (phyAddr, 30, &regVal, retVal);
  1134.         regVal |= 0x100;
  1135.         MII_WRITE (phyAddr, 30, regVal, retVal);
  1136.         }
  1137.      /* other PHYS .... */
  1138.      }
  1139. /*****************************************************************************
  1140. *
  1141. * sys543IntAck - acknowledge an 8254x interrupt
  1142. *
  1143. * This routine performs any 8254x interrupt acknowledge that may be
  1144. * required.  This typically involves an operation to some interrupt
  1145. * control hardware.
  1146. *
  1147. * This routine gets called from the 82543 driver's interrupt handler.
  1148. *
  1149. * This routine assumes that the PCI configuration information has already
  1150. * been setup.
  1151. *
  1152. * RETURNS: OK, or ERROR if the interrupt could not be acknowledged.
  1153. */
  1154. LOCAL STATUS sys543IntAck
  1155.     (
  1156.     int    unit        /* unit number */
  1157.     )
  1158.     {
  1159.     return (OK);
  1160.     }
  1161. /*****************************************************************************
  1162. *
  1163. * sys543IntEnable - enable 8254x chip interrupts
  1164. *
  1165. * This routine enables 8254x interrupts.  This may involve operations on
  1166. * interrupt control hardware.
  1167. *
  1168. * The 8254x driver calls this routine throughout normal operation to terminate
  1169. * critical sections of code.
  1170. *
  1171. * This routine assumes that the PCI configuration information has already
  1172. * been setup.
  1173. *
  1174. * RETURNS: OK, or ERROR if interrupts could not be enabled.
  1175. */
  1176. LOCAL STATUS sys543IntEnable
  1177.     (
  1178.     int    unit        /* unit number */
  1179.     )
  1180.     {
  1181.     return (OK);
  1182.     }
  1183. /*****************************************************************************
  1184. *
  1185. * sys543IntDisable - disable 8254x chip interrupts
  1186. *
  1187. * This routine disables 8254x interrupts.  This may involve operations on
  1188. * interrupt control hardware.
  1189. *
  1190. * The 8254x driver calls this routine throughout normal operation to enter
  1191. * critical sections of code.
  1192. *
  1193. * This routine assumes that the PCI configuration information has already
  1194. * been setup.
  1195. *
  1196. * RETURNS: OK, or ERROR if interrupts could not be disabled.
  1197. */
  1198. LOCAL STATUS sys543IntDisable
  1199.     (
  1200.     int    unit        /* unit number */
  1201.     )
  1202.     {
  1203.     return (OK);
  1204.     }
  1205. /*****************************************************************************
  1206. *
  1207. * sys543Show - shows 8254x chip configuration
  1208. *
  1209. * This routine shows (Intel Pro 1000F/T/XT/XF) adapter configuration
  1210. *
  1211. * RETURNS: N/A
  1212. */
  1213. void sys543Show
  1214.     (
  1215.     int    unit        /* unit number */
  1216.     )
  1217.     {
  1218.     int    ix;
  1219.     PCI_BOARD_RESOURCE * pRsrc;
  1220.     GEI_RESOURCE *       pReso;
  1221.     if (unit >= geiUnits)
  1222.         {
  1223.         printf ("gei device %d is not availablen", unit);
  1224.         return;
  1225.         }
  1226.     pRsrc = &geiPciResources [unit];
  1227.     pReso = (GEI_RESOURCE *)(pRsrc->pExtended);
  1228.     if (pRsrc->boardType == PRO1000_543_BOARD)
  1229.         printf ("********* Intel PRO1000 82543GC Based Adapter ***********n");
  1230.     else if (pRsrc->boardType == PRO1000_544_BOARD)
  1231.         printf ("********* Intel PRO1000 82544GC/EI based Adapter ********n");
  1232.     else if (pRsrc->boardType == PRO1000_546_BOARD)
  1233.         printf ("********* Intel 82540/82541/82545/82546 based Adapter ********n");
  1234.     else
  1235.         printf ("********* UNKNOWN Adaptor ************ n");
  1236.     printf ("  CSR PCI Membase address = 0x%xn", pReso->memBaseLow);
  1237.     printf ("  Flash PCI Membase address = 0x%xn", pReso->flashBase);
  1238.     printf ("  PCI bus no.= 0x%x, device no.= 0x%x, function no.= 0x%xn",
  1239.              pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc);
  1240.     printf ("  IRQ = %dn", pRsrc->irq);
  1241.     if (pReso->iniStatus == ERROR)
  1242.         return;
  1243.     printf ("  Adapter Ethernet Address");
  1244.     for (ix = 0; ix < 6; ix ++)
  1245.         printf (":%2.2X", (UINT32)pReso->enetAddr[ix]);
  1246.     printf ("n");
  1247.     printf ("  EEPROM Initialization Control Word 1 = 0x%4.4Xn",
  1248.             pReso->eeprom_icw1);
  1249.     printf ("  EEPROM Initialization Control Word 2 = 0x%4.4Xn",
  1250.             pReso->eeprom_icw2);
  1251.     printf ("*********************************************n");
  1252.     }
  1253. /*******************************************************************************
  1254. *
  1255. * sysGeiDevToType - convert PCI Vendor and Device IDs to a device type
  1256. *
  1257. * Given <vendorId>, <deviceId>, and <revisionId> values read from PCI Vendor
  1258. * and Device ID registers in PCI configuration space, this routine will
  1259. * attempt to map the IDs to an 8254x device type value.
  1260. *
  1261. * RETURNS:
  1262. * A board type value which will be one of
  1263. *
  1264. * .IP
  1265. * PRO1000_543_BOARD
  1266. * .IP
  1267. * PRO1000_544_BOARD
  1268. * .IP
  1269. * PRO1000_546_BOARD
  1270. * .LP
  1271. *
  1272. * BOARD_TYPE_UNKNOWN will be returned if the Device ID does not map to
  1273. * a supported board type.
  1274. *
  1275. */
  1276. LOCAL UINT32 sysGeiDevToType
  1277.     (
  1278.     UINT32 vendorId,    /* specifies a PCI Vendor ID value */
  1279.     UINT32 deviceId,    /* specifies a PCI Device ID value */
  1280.     UINT8  revisionId   /* specifies a PCI Revision ID value */
  1281.     )
  1282.     {
  1283.     /* At the moment, we are only supporting vendor Intel */
  1284.     if (vendorId == PRO1000_PCI_VENDOR_ID)
  1285.         {
  1286.         switch (deviceId)
  1287.             {
  1288.             case PRO1000_543_PCI_DEVICE_ID_T:
  1289.             case PRO1000_543_PCI_DEVICE_ID_FT:
  1290.                 return (PRO1000_543_BOARD);
  1291.             case PRO1000_544_PCI_DEVICE_ID_XT:
  1292.             case PRO1000_544_PCI_DEVICE_ID_XF:
  1293.             case PRO1000_544_PCI_DEVICE_ID_GC:
  1294.                 return (PRO1000_544_BOARD);
  1295.             case PRO1000_540_PCI_DEVICE_ID_XT:
  1296.             case PRO1000_541_PCI_DEVICE_ID_XT:
  1297.             case PRO1000_541_PCI_DEVICE_ID_GT:
  1298.             case PRO1000_545_PCI_DEVICE_ID_XT:
  1299.             case PRO1000_546_PCI_DEVICE_ID_XT:
  1300.             case PRO1000_546_PCI_DEVICE_ID_XT2:
  1301.             case PRO1000_545_PCI_DEVICE_ID_MF:
  1302.             case PRO1000_546_PCI_DEVICE_ID_MF:
  1303.                 return (PRO1000_546_BOARD);
  1304.             case PRO1000_572_PCI_DEVICE_ID_EI:
  1305.             case PRO1000_573_PCI_DEVICE_ID_E:
  1306.             case PRO1000_573_PCI_DEVICE_ID_IAMT:
  1307.                 return (PRO1000_573_BOARD);
  1308.             }
  1309.         }
  1310.     return ((UINT32)BOARD_TYPE_UNKNOWN);
  1311.     }
  1312. #endif /* INCLUDE_GEI8254X_END */