[BACK]Return to if_bge.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / pci

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/dev/pci/if_bge.c between version 1.200 and 1.200.2.2

version 1.200, 2012/02/02 19:43:05 version 1.200.2.2, 2013/09/07 16:39:32
Line 51 
Line 51 
 /*  /*
  * The Broadcom BCM5700 is based on technology originally developed by   * The Broadcom BCM5700 is based on technology originally developed by
  * Alteon Networks as part of the Tigon I and Tigon II gigabit ethernet   * Alteon Networks as part of the Tigon I and Tigon II gigabit ethernet
  * MAC chips. The BCM5700, sometimes refered to as the Tigon III, has   * MAC chips. The BCM5700, sometimes referred to as the Tigon III, has
  * two on-board MIPS R4000 CPUs and can have as much as 16MB of external   * two on-board MIPS R4000 CPUs and can have as much as 16MB of external
  * SSRAM. The BCM5700 supports TCP, UDP and IP checksum offload, jumbo   * SSRAM. The BCM5700 supports TCP, UDP and IP checksum offload, jumbo
  * frames, highly configurable RX filtering, and 16 RX and TX queues   * frames, highly configurable RX filtering, and 16 RX and TX queues
Line 108  __KERNEL_RCSID(0, "$NetBSD$");
Line 108  __KERNEL_RCSID(0, "$NetBSD$");
 #include <netinet/ip.h>  #include <netinet/ip.h>
 #endif  #endif
   
 /* Headers for TCP  Segmentation Offload (TSO) */  /* Headers for TCP Segmentation Offload (TSO) */
 #include <netinet/in_systm.h>           /* n_time for <netinet/ip.h>... */  #include <netinet/in_systm.h>           /* n_time for <netinet/ip.h>... */
 #include <netinet/in.h>                 /* ip_{src,dst}, for <netinet/ip.h> */  #include <netinet/in.h>                 /* ip_{src,dst}, for <netinet/ip.h> */
 #include <netinet/ip.h>                 /* for struct ip */  #include <netinet/ip.h>                 /* for struct ip */
Line 184  static int bge_rxthresh_nodenum;
Line 184  static int bge_rxthresh_nodenum;
   
 typedef int (*bge_eaddr_fcn_t)(struct bge_softc *, uint8_t[]);  typedef int (*bge_eaddr_fcn_t)(struct bge_softc *, uint8_t[]);
   
   static uint32_t bge_chipid(const struct pci_attach_args *);
 static int bge_probe(device_t, cfdata_t, void *);  static int bge_probe(device_t, cfdata_t, void *);
 static void bge_attach(device_t, device_t, void *);  static void bge_attach(device_t, device_t, void *);
   static int bge_detach(device_t, int);
 static void bge_release_resources(struct bge_softc *);  static void bge_release_resources(struct bge_softc *);
   
 static int bge_get_eaddr_fw(struct bge_softc *, uint8_t[]);  static int bge_get_eaddr_fw(struct bge_softc *, uint8_t[]);
Line 195  static int bge_get_eaddr_eeprom(struct b
Line 197  static int bge_get_eaddr_eeprom(struct b
 static int bge_get_eaddr(struct bge_softc *, uint8_t[]);  static int bge_get_eaddr(struct bge_softc *, uint8_t[]);
   
 static void bge_txeof(struct bge_softc *);  static void bge_txeof(struct bge_softc *);
   static void bge_rxcsum(struct bge_softc *, struct bge_rx_bd *, struct mbuf *);
 static void bge_rxeof(struct bge_softc *);  static void bge_rxeof(struct bge_softc *);
   
 static void bge_asf_driver_up (struct bge_softc *);  static void bge_asf_driver_up (struct bge_softc *);
Line 239  static int bge_init_tx_ring(struct bge_s
Line 242  static int bge_init_tx_ring(struct bge_s
   
 static int bge_chipinit(struct bge_softc *);  static int bge_chipinit(struct bge_softc *);
 static int bge_blockinit(struct bge_softc *);  static int bge_blockinit(struct bge_softc *);
 static int bge_setpowerstate(struct bge_softc *, int);  static int bge_phy_addr(struct bge_softc *);
 static uint32_t bge_readmem_ind(struct bge_softc *, int);  static uint32_t bge_readmem_ind(struct bge_softc *, int);
 static void bge_writemem_ind(struct bge_softc *, int, int);  static void bge_writemem_ind(struct bge_softc *, int, int);
 static void bge_writembx(struct bge_softc *, int, int);  static void bge_writembx(struct bge_softc *, int, int);
   static void bge_writembx_flush(struct bge_softc *, int, int);
 static void bge_writemem_direct(struct bge_softc *, int, int);  static void bge_writemem_direct(struct bge_softc *, int, int);
 static void bge_writereg_ind(struct bge_softc *, int, int);  static void bge_writereg_ind(struct bge_softc *, int, int);
 static void bge_set_max_readrq(struct bge_softc *);  static void bge_set_max_readrq(struct bge_softc *);
Line 251  static int bge_miibus_readreg(device_t, 
Line 255  static int bge_miibus_readreg(device_t, 
 static void bge_miibus_writereg(device_t, int, int, int);  static void bge_miibus_writereg(device_t, int, int, int);
 static void bge_miibus_statchg(device_t);  static void bge_miibus_statchg(device_t);
   
 #define BGE_RESET_START 1  #define BGE_RESET_SHUTDOWN      0
 #define BGE_RESET_STOP  2  #define BGE_RESET_START         1
   #define BGE_RESET_SUSPEND       2
 static void bge_sig_post_reset(struct bge_softc *, int);  static void bge_sig_post_reset(struct bge_softc *, int);
 static void bge_sig_legacy(struct bge_softc *, int);  static void bge_sig_legacy(struct bge_softc *, int);
 static void bge_sig_pre_reset(struct bge_softc *, int);  static void bge_sig_pre_reset(struct bge_softc *, int);
   static void bge_wait_for_event_ack(struct bge_softc *);
 static void bge_stop_fw(struct bge_softc *);  static void bge_stop_fw(struct bge_softc *);
 static int bge_reset(struct bge_softc *);  static int bge_reset(struct bge_softc *);
 static void bge_link_upd(struct bge_softc *);  static void bge_link_upd(struct bge_softc *);
 static void sysctl_bge_init(struct bge_softc *);  static void bge_sysctl_init(struct bge_softc *);
 static int sysctl_bge_verify(SYSCTLFN_PROTO);  static int bge_sysctl_verify(SYSCTLFN_PROTO);
   
   static void bge_ape_lock_init(struct bge_softc *);
   static void bge_ape_read_fw_ver(struct bge_softc *);
   static int bge_ape_lock(struct bge_softc *, int);
   static void bge_ape_unlock(struct bge_softc *, int);
   static void bge_ape_send_event(struct bge_softc *, uint32_t);
   static void bge_ape_driver_state_change(struct bge_softc *, int);
   
 #ifdef BGE_DEBUG  #ifdef BGE_DEBUG
 #define DPRINTF(x)      if (bgedebug) printf x  #define DPRINTF(x)      if (bgedebug) printf x
Line 313  static const struct bge_product {
Line 326  static const struct bge_product {
           "Altima AC1001 Gigabit Ethernet",            "Altima AC1001 Gigabit Ethernet",
            },             },
         { PCI_VENDOR_ALTIMA,          { PCI_VENDOR_ALTIMA,
             PCI_PRODUCT_ALTIMA_AC1003,
             "Altima AC1003 Gigabit Ethernet",
              },
           { PCI_VENDOR_ALTIMA,
           PCI_PRODUCT_ALTIMA_AC9100,            PCI_PRODUCT_ALTIMA_AC9100,
           "Altima AC9100 Gigabit Ethernet",            "Altima AC9100 Gigabit Ethernet",
           },            },
           { PCI_VENDOR_APPLE,
             PCI_PRODUCT_APPLE_BCM5701,
             "APPLE BCM5701 Gigabit Ethernet",
             },
         { PCI_VENDOR_BROADCOM,          { PCI_VENDOR_BROADCOM,
           PCI_PRODUCT_BROADCOM_BCM5700,            PCI_PRODUCT_BROADCOM_BCM5700,
           "Broadcom BCM5700 Gigabit Ethernet",            "Broadcom BCM5700 Gigabit Ethernet",
Line 396  static const struct bge_product {
Line 417  static const struct bge_product {
           "Broadcom BCM5718 Gigabit Ethernet",            "Broadcom BCM5718 Gigabit Ethernet",
           },            },
         { PCI_VENDOR_BROADCOM,          { PCI_VENDOR_BROADCOM,
             PCI_PRODUCT_BROADCOM_BCM5719,
             "Broadcom BCM5719 Gigabit Ethernet",
             },
           { PCI_VENDOR_BROADCOM,
           PCI_PRODUCT_BROADCOM_BCM5720,            PCI_PRODUCT_BROADCOM_BCM5720,
           "Broadcom BCM5720 Gigabit Ethernet",            "Broadcom BCM5720 Gigabit Ethernet",
           },            },
Line 516  static const struct bge_product {
Line 541  static const struct bge_product {
           "BCM5784M NetLink 1000baseT Ethernet",            "BCM5784M NetLink 1000baseT Ethernet",
         },          },
         { PCI_VENDOR_BROADCOM,          { PCI_VENDOR_BROADCOM,
             PCI_PRODUCT_BROADCOM_BCM5785F,
             "BCM5785F NetLink 10/100 Ethernet",
           },
           { PCI_VENDOR_BROADCOM,
             PCI_PRODUCT_BROADCOM_BCM5785G,
             "BCM5785G NetLink 1000baseT Ethernet",
           },
           { PCI_VENDOR_BROADCOM,
           PCI_PRODUCT_BROADCOM_BCM5786,            PCI_PRODUCT_BROADCOM_BCM5786,
           "Broadcom BCM5786 Gigabit Ethernet",            "Broadcom BCM5786 Gigabit Ethernet",
         },          },
Line 524  static const struct bge_product {
Line 557  static const struct bge_product {
           "Broadcom BCM5787 Gigabit Ethernet",            "Broadcom BCM5787 Gigabit Ethernet",
         },          },
         { PCI_VENDOR_BROADCOM,          { PCI_VENDOR_BROADCOM,
             PCI_PRODUCT_BROADCOM_BCM5787F,
             "Broadcom BCM5787F 10/100 Ethernet",
           },
           { PCI_VENDOR_BROADCOM,
           PCI_PRODUCT_BROADCOM_BCM5787M,            PCI_PRODUCT_BROADCOM_BCM5787M,
           "Broadcom BCM5787M Gigabit Ethernet",            "Broadcom BCM5787M Gigabit Ethernet",
         },          },
Line 564  static const struct bge_product {
Line 601  static const struct bge_product {
           "Broadcom BCM57761 Fast Ethernet",            "Broadcom BCM57761 Fast Ethernet",
           },            },
         { PCI_VENDOR_BROADCOM,          { PCI_VENDOR_BROADCOM,
             PCI_PRODUCT_BROADCOM_BCM57762,
             "Broadcom BCM57762 Gigabit Ethernet",
             },
           { PCI_VENDOR_BROADCOM,
           PCI_PRODUCT_BROADCOM_BCM57765,            PCI_PRODUCT_BROADCOM_BCM57765,
           "Broadcom BCM57765 Fast Ethernet",            "Broadcom BCM57765 Fast Ethernet",
           },            },
         { PCI_VENDOR_BROADCOM,          { PCI_VENDOR_BROADCOM,
             PCI_PRODUCT_BROADCOM_BCM57766,
             "Broadcom BCM57766 Fast Ethernet",
             },
           { PCI_VENDOR_BROADCOM,
           PCI_PRODUCT_BROADCOM_BCM57780,            PCI_PRODUCT_BROADCOM_BCM57780,
           "Broadcom BCM57780 Fast Ethernet",            "Broadcom BCM57780 Fast Ethernet",
           },            },
Line 576  static const struct bge_product {
Line 621  static const struct bge_product {
           "Broadcom BCM57781 Fast Ethernet",            "Broadcom BCM57781 Fast Ethernet",
           },            },
         { PCI_VENDOR_BROADCOM,          { PCI_VENDOR_BROADCOM,
             PCI_PRODUCT_BROADCOM_BCM57782,
             "Broadcom BCM57782 Fast Ethernet",
             },
           { PCI_VENDOR_BROADCOM,
           PCI_PRODUCT_BROADCOM_BCM57785,            PCI_PRODUCT_BROADCOM_BCM57785,
           "Broadcom BCM57785 Fast Ethernet",            "Broadcom BCM57785 Fast Ethernet",
           },            },
         { PCI_VENDOR_BROADCOM,          { PCI_VENDOR_BROADCOM,
             PCI_PRODUCT_BROADCOM_BCM57786,
             "Broadcom BCM57786 Fast Ethernet",
             },
           { PCI_VENDOR_BROADCOM,
           PCI_PRODUCT_BROADCOM_BCM57788,            PCI_PRODUCT_BROADCOM_BCM57788,
           "Broadcom BCM57788 Fast Ethernet",            "Broadcom BCM57788 Fast Ethernet",
           },            },
Line 620  static const struct bge_product {
Line 673  static const struct bge_product {
           NULL },            NULL },
 };  };
   
 /*  #define BGE_IS_JUMBO_CAPABLE(sc)        ((sc)->bge_flags & BGE_JUMBO_CAPABLE)
  * XXX: how to handle variants based on 5750 and derivatives:  
  * 5750 5751, 5721, possibly 5714, 5752, and 5708?, which  
  * in general behave like a 5705, except with additional quirks.  
  * This driver's current handling of the 5721 is wrong;  
  * how we map ASIC revision to "quirks" needs more thought.  
  * (defined here until the thought is done).  
  */  
 #define BGE_IS_5700_FAMILY(sc)          ((sc)->bge_flags & BGE_5700_FAMILY)  #define BGE_IS_5700_FAMILY(sc)          ((sc)->bge_flags & BGE_5700_FAMILY)
   #define BGE_IS_5705_PLUS(sc)            ((sc)->bge_flags & BGE_5705_PLUS)
 #define BGE_IS_5714_FAMILY(sc)          ((sc)->bge_flags & BGE_5714_FAMILY)  #define BGE_IS_5714_FAMILY(sc)          ((sc)->bge_flags & BGE_5714_FAMILY)
 #define BGE_IS_5705_PLUS(sc)    ((sc)->bge_flags & BGE_5705_PLUS)  #define BGE_IS_575X_PLUS(sc)            ((sc)->bge_flags & BGE_575X_PLUS)
 #define BGE_IS_5750_OR_BEYOND(sc)       ((sc)->bge_flags & BGE_5750_PLUS)  #define BGE_IS_5755_PLUS(sc)            ((sc)->bge_flags & BGE_5755_PLUS)
 #define BGE_IS_5755_PLUS(sc)    ((sc)->bge_flags & BGE_5755_PLUS)  #define BGE_IS_57765_FAMILY(sc)         ((sc)->bge_flags & BGE_57765_FAMILY)
 #define BGE_IS_JUMBO_CAPABLE(sc)        ((sc)->bge_flags & BGE_JUMBO_CAPABLE)  #define BGE_IS_57765_PLUS(sc)           ((sc)->bge_flags & BGE_57765_PLUS)
   #define BGE_IS_5717_PLUS(sc)            ((sc)->bge_flags & BGE_5717_PLUS)
   
 static const struct bge_revision {  static const struct bge_revision {
         uint32_t                br_chipid;          uint32_t                br_chipid;
Line 645  static const struct bge_revision {
Line 693  static const struct bge_revision {
         { BGE_CHIPID_BCM5700_B1, "BCM5700 B1" },          { BGE_CHIPID_BCM5700_B1, "BCM5700 B1" },
         { BGE_CHIPID_BCM5700_B2, "BCM5700 B2" },          { BGE_CHIPID_BCM5700_B2, "BCM5700 B2" },
         { BGE_CHIPID_BCM5700_B3, "BCM5700 B3" },          { BGE_CHIPID_BCM5700_B3, "BCM5700 B3" },
         /* This is treated like a BCM5700 Bx */  
         { BGE_CHIPID_BCM5700_ALTIMA, "BCM5700 Altima" },          { BGE_CHIPID_BCM5700_ALTIMA, "BCM5700 Altima" },
         { BGE_CHIPID_BCM5700_C0, "BCM5700 C0" },          { BGE_CHIPID_BCM5700_C0, "BCM5700 C0" },
         { BGE_CHIPID_BCM5701_A0, "BCM5701 A0" },          { BGE_CHIPID_BCM5701_A0, "BCM5701 A0" },
Line 683  static const struct bge_revision {
Line 730  static const struct bge_revision {
         { BGE_CHIPID_BCM5715_A0, "BCM5715 A0" },          { BGE_CHIPID_BCM5715_A0, "BCM5715 A0" },
         { BGE_CHIPID_BCM5715_A1, "BCM5715 A1" },          { BGE_CHIPID_BCM5715_A1, "BCM5715 A1" },
         { BGE_CHIPID_BCM5715_A3, "BCM5715 A3" },          { BGE_CHIPID_BCM5715_A3, "BCM5715 A3" },
           { BGE_CHIPID_BCM5717_A0, "BCM5717 A0" },
           { BGE_CHIPID_BCM5717_B0, "BCM5717 B0" },
           { BGE_CHIPID_BCM5719_A0, "BCM5719 A0" },
           { BGE_CHIPID_BCM5720_A0, "BCM5720 A0" },
         { BGE_CHIPID_BCM5755_A0, "BCM5755 A0" },          { BGE_CHIPID_BCM5755_A0, "BCM5755 A0" },
         { BGE_CHIPID_BCM5755_A1, "BCM5755 A1" },          { BGE_CHIPID_BCM5755_A1, "BCM5755 A1" },
         { BGE_CHIPID_BCM5755_A2, "BCM5755 A2" },          { BGE_CHIPID_BCM5755_A2, "BCM5755 A2" },
Line 695  static const struct bge_revision {
Line 746  static const struct bge_revision {
         { BGE_CHIPID_BCM5787_A0, "BCM5754/5787 A0" },          { BGE_CHIPID_BCM5787_A0, "BCM5754/5787 A0" },
         { BGE_CHIPID_BCM5787_A1, "BCM5754/5787 A1" },          { BGE_CHIPID_BCM5787_A1, "BCM5754/5787 A1" },
         { BGE_CHIPID_BCM5787_A2, "BCM5754/5787 A2" },          { BGE_CHIPID_BCM5787_A2, "BCM5754/5787 A2" },
           { BGE_CHIPID_BCM5906_A0, "BCM5906 A0" },
         { BGE_CHIPID_BCM5906_A1, "BCM5906 A1" },          { BGE_CHIPID_BCM5906_A1, "BCM5906 A1" },
         { BGE_CHIPID_BCM5906_A2, "BCM5906 A2" },          { BGE_CHIPID_BCM5906_A2, "BCM5906 A2" },
           { BGE_CHIPID_BCM57765_A0, "BCM57765 A0" },
           { BGE_CHIPID_BCM57765_B0, "BCM57765 B0" },
         { BGE_CHIPID_BCM57780_A0, "BCM57780 A0" },          { BGE_CHIPID_BCM57780_A0, "BCM57780 A0" },
         { BGE_CHIPID_BCM57780_A1, "BCM57780 A1" },          { BGE_CHIPID_BCM57780_A1, "BCM57780 A1" },
   
Line 714  static const struct bge_revision bge_maj
Line 768  static const struct bge_revision bge_maj
         { BGE_ASICREV_BCM5704, "unknown BCM5704" },          { BGE_ASICREV_BCM5704, "unknown BCM5704" },
         { BGE_ASICREV_BCM5705, "unknown BCM5705" },          { BGE_ASICREV_BCM5705, "unknown BCM5705" },
         { BGE_ASICREV_BCM5750, "unknown BCM5750" },          { BGE_ASICREV_BCM5750, "unknown BCM5750" },
           { BGE_ASICREV_BCM5714, "unknown BCM5714" },
         { BGE_ASICREV_BCM5714_A0, "unknown BCM5714" },          { BGE_ASICREV_BCM5714_A0, "unknown BCM5714" },
         { BGE_ASICREV_BCM5752, "unknown BCM5752" },          { BGE_ASICREV_BCM5752, "unknown BCM5752" },
         { BGE_ASICREV_BCM5780, "unknown BCM5780" },          { BGE_ASICREV_BCM5780, "unknown BCM5780" },
         { BGE_ASICREV_BCM5714, "unknown BCM5714" },  
         { BGE_ASICREV_BCM5755, "unknown BCM5755" },          { BGE_ASICREV_BCM5755, "unknown BCM5755" },
         { BGE_ASICREV_BCM5761, "unknown BCM5761" },          { BGE_ASICREV_BCM5761, "unknown BCM5761" },
         { BGE_ASICREV_BCM5784, "unknown BCM5784" },          { BGE_ASICREV_BCM5784, "unknown BCM5784" },
Line 725  static const struct bge_revision bge_maj
Line 779  static const struct bge_revision bge_maj
         /* 5754 and 5787 share the same ASIC ID */          /* 5754 and 5787 share the same ASIC ID */
         { BGE_ASICREV_BCM5787, "unknown BCM5754/5787" },          { BGE_ASICREV_BCM5787, "unknown BCM5754/5787" },
         { BGE_ASICREV_BCM5906, "unknown BCM5906" },          { BGE_ASICREV_BCM5906, "unknown BCM5906" },
           { BGE_ASICREV_BCM57765, "unknown BCM57765" },
           { BGE_ASICREV_BCM57766, "unknown BCM57766" },
         { BGE_ASICREV_BCM57780, "unknown BCM57780" },          { BGE_ASICREV_BCM57780, "unknown BCM57780" },
         { BGE_ASICREV_BCM5717, "unknown BCM5717" },          { BGE_ASICREV_BCM5717, "unknown BCM5717" },
         { BGE_ASICREV_BCM57765, "unknown BCM57765" },          { BGE_ASICREV_BCM5719, "unknown BCM5719" },
           { BGE_ASICREV_BCM5720, "unknown BCM5720" },
   
         { 0, NULL }          { 0, NULL }
 };  };
   
 static int bge_allow_asf = 1;  static int bge_allow_asf = 1;
   
 CFATTACH_DECL_NEW(bge, sizeof(struct bge_softc),  CFATTACH_DECL3_NEW(bge, sizeof(struct bge_softc),
     bge_probe, bge_attach, NULL, NULL);      bge_probe, bge_attach, bge_detach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN);
   
 static uint32_t  static uint32_t
 bge_readmem_ind(struct bge_softc *sc, int off)  bge_readmem_ind(struct bge_softc *sc, int off)
 {  {
         pcireg_t val;          pcireg_t val;
   
           if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906 &&
               off >= BGE_STATS_BLOCK && off < BGE_SEND_RING_1_TO_4)
                   return 0;
   
         pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_BASEADDR, off);          pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_BASEADDR, off);
         val = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_DATA);          val = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_DATA);
           pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_BASEADDR, 0);
         return val;          return val;
 }  }
   
 static void  static void
 bge_writemem_ind(struct bge_softc *sc, int off, int val)  bge_writemem_ind(struct bge_softc *sc, int off, int val)
 {  {
   
         pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_BASEADDR, off);          pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_BASEADDR, off);
         pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_DATA, val);          pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_DATA, val);
           pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_BASEADDR, 0);
 }  }
   
 /*  /*
Line 764  bge_set_max_readrq(struct bge_softc *sc)
Line 828  bge_set_max_readrq(struct bge_softc *sc)
   
         val = pci_conf_read(sc->sc_pc, sc->sc_pcitag, sc->bge_pciecap          val = pci_conf_read(sc->sc_pc, sc->sc_pcitag, sc->bge_pciecap
             + PCI_PCIE_DCSR);              + PCI_PCIE_DCSR);
         if ((val & PCI_PCIE_DCSR_MAX_READ_REQ) !=          val &= ~PCI_PCIE_DCSR_MAX_READ_REQ;
             BGE_PCIE_DEVCTL_MAX_READRQ_4096) {          switch (sc->bge_expmrq) {
                 aprint_verbose_dev(sc->bge_dev,          case 2048:
                     "adjust device control 0x%04x ", val);                  val |= BGE_PCIE_DEVCTL_MAX_READRQ_2048;
                 val &= ~PCI_PCIE_DCSR_MAX_READ_REQ;                  break;
           case 4096:
                 val |= BGE_PCIE_DEVCTL_MAX_READRQ_4096;                  val |= BGE_PCIE_DEVCTL_MAX_READRQ_4096;
                 pci_conf_write(sc->sc_pc, sc->sc_pcitag, sc->bge_pciecap                  break;
                     + PCI_PCIE_DCSR, val);          default:
                 aprint_verbose("-> 0x%04x\n", val);                  panic("incorrect expmrq value(%d)", sc->bge_expmrq);
                   break;
         }          }
           pci_conf_write(sc->sc_pc, sc->sc_pcitag, sc->bge_pciecap
               + PCI_PCIE_DCSR, val);
 }  }
   
 #ifdef notdef  #ifdef notdef
Line 807  bge_writembx(struct bge_softc *sc, int o
Line 875  bge_writembx(struct bge_softc *sc, int o
         CSR_WRITE_4(sc, off, val);          CSR_WRITE_4(sc, off, val);
 }  }
   
   static void
   bge_writembx_flush(struct bge_softc *sc, int off, int val)
   {
           if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906)
                   off += BGE_LPMBX_IRQ0_HI - BGE_MBX_IRQ0_HI;
   
           CSR_WRITE_4_FLUSH(sc, off, val);
   }
   
   /*
    * Clear all stale locks and select the lock for this driver instance.
    */
   void
   bge_ape_lock_init(struct bge_softc *sc)
   {
           struct pci_attach_args *pa = &(sc->bge_pa);
           uint32_t bit, regbase;
           int i;
   
           if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5761)
                   regbase = BGE_APE_LOCK_GRANT;
           else
                   regbase = BGE_APE_PER_LOCK_GRANT;
   
           /* Clear any stale locks. */
           for (i = BGE_APE_LOCK_PHY0; i <= BGE_APE_LOCK_GPIO; i++) {
                   switch (i) {
                   case BGE_APE_LOCK_PHY0:
                   case BGE_APE_LOCK_PHY1:
                   case BGE_APE_LOCK_PHY2:
                   case BGE_APE_LOCK_PHY3:
                           bit = BGE_APE_LOCK_GRANT_DRIVER0;
                           break;
                   default:
                           if (pa->pa_function == 0)
                                   bit = BGE_APE_LOCK_GRANT_DRIVER0;
                           else
                                   bit = (1 << pa->pa_function);
                   }
                   APE_WRITE_4(sc, regbase + 4 * i, bit);
           }
   
           /* Select the PHY lock based on the device's function number. */
           switch (pa->pa_function) {
           case 0:
                   sc->bge_phy_ape_lock = BGE_APE_LOCK_PHY0;
                   break;
           case 1:
                   sc->bge_phy_ape_lock = BGE_APE_LOCK_PHY1;
                   break;
           case 2:
                   sc->bge_phy_ape_lock = BGE_APE_LOCK_PHY2;
                   break;
           case 3:
                   sc->bge_phy_ape_lock = BGE_APE_LOCK_PHY3;
                   break;
           default:
                   printf("%s: PHY lock not supported on function\n",
                       device_xname(sc->bge_dev));
                   break;
           }
   }
   
   /*
    * Check for APE firmware, set flags, and print version info.
    */
   void
   bge_ape_read_fw_ver(struct bge_softc *sc)
   {
           const char *fwtype;
           uint32_t apedata, features;
   
           /* Check for a valid APE signature in shared memory. */
           apedata = APE_READ_4(sc, BGE_APE_SEG_SIG);
           if (apedata != BGE_APE_SEG_SIG_MAGIC) {
                   sc->bge_mfw_flags &= ~ BGE_MFW_ON_APE;
                   return;
           }
   
           /* Check if APE firmware is running. */
           apedata = APE_READ_4(sc, BGE_APE_FW_STATUS);
           if ((apedata & BGE_APE_FW_STATUS_READY) == 0) {
                   printf("%s: APE signature found but FW status not ready! "
                       "0x%08x\n", device_xname(sc->bge_dev), apedata);
                   return;
           }
   
           sc->bge_mfw_flags |= BGE_MFW_ON_APE;
   
           /* Fetch the APE firwmare type and version. */
           apedata = APE_READ_4(sc, BGE_APE_FW_VERSION);
           features = APE_READ_4(sc, BGE_APE_FW_FEATURES);
           if ((features & BGE_APE_FW_FEATURE_NCSI) != 0) {
                   sc->bge_mfw_flags |= BGE_MFW_TYPE_NCSI;
                   fwtype = "NCSI";
           } else if ((features & BGE_APE_FW_FEATURE_DASH) != 0) {
                   sc->bge_mfw_flags |= BGE_MFW_TYPE_DASH;
                   fwtype = "DASH";
           } else
                   fwtype = "UNKN";
   
           /* Print the APE firmware version. */
           printf(", APE firmware %s %d.%d.%d.%d", fwtype,
               (apedata & BGE_APE_FW_VERSION_MAJMSK) >> BGE_APE_FW_VERSION_MAJSFT,
               (apedata & BGE_APE_FW_VERSION_MINMSK) >> BGE_APE_FW_VERSION_MINSFT,
               (apedata & BGE_APE_FW_VERSION_REVMSK) >> BGE_APE_FW_VERSION_REVSFT,
               (apedata & BGE_APE_FW_VERSION_BLDMSK));
   }
   
   int
   bge_ape_lock(struct bge_softc *sc, int locknum)
   {
           struct pci_attach_args *pa = &(sc->bge_pa);
           uint32_t bit, gnt, req, status;
           int i, off;
   
           if ((sc->bge_mfw_flags & BGE_MFW_ON_APE) == 0)
                   return (0);
   
           /* Lock request/grant registers have different bases. */
           if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5761) {
                   req = BGE_APE_LOCK_REQ;
                   gnt = BGE_APE_LOCK_GRANT;
           } else {
                   req = BGE_APE_PER_LOCK_REQ;
                   gnt = BGE_APE_PER_LOCK_GRANT;
           }
   
           off = 4 * locknum;
   
           switch (locknum) {
           case BGE_APE_LOCK_GPIO:
                   /* Lock required when using GPIO. */
                   if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5761)
                           return (0);
                   if (pa->pa_function == 0)
                           bit = BGE_APE_LOCK_REQ_DRIVER0;
                   else
                           bit = (1 << pa->pa_function);
                   break;
           case BGE_APE_LOCK_GRC:
                   /* Lock required to reset the device. */
                   if (pa->pa_function == 0)
                           bit = BGE_APE_LOCK_REQ_DRIVER0;
                   else
                           bit = (1 << pa->pa_function);
                   break;
           case BGE_APE_LOCK_MEM:
                   /* Lock required when accessing certain APE memory. */
                   if (pa->pa_function == 0)
                           bit = BGE_APE_LOCK_REQ_DRIVER0;
                   else
                           bit = (1 << pa->pa_function);
                   break;
           case BGE_APE_LOCK_PHY0:
           case BGE_APE_LOCK_PHY1:
           case BGE_APE_LOCK_PHY2:
           case BGE_APE_LOCK_PHY3:
                   /* Lock required when accessing PHYs. */
                   bit = BGE_APE_LOCK_REQ_DRIVER0;
                   break;
           default:
                   return (EINVAL);
           }
   
           /* Request a lock. */
           APE_WRITE_4_FLUSH(sc, req + off, bit);
   
           /* Wait up to 1 second to acquire lock. */
           for (i = 0; i < 20000; i++) {
                   status = APE_READ_4(sc, gnt + off);
                   if (status == bit)
                           break;
                   DELAY(50);
           }
   
           /* Handle any errors. */
           if (status != bit) {
                   printf("%s: APE lock %d request failed! "
                       "request = 0x%04x[0x%04x], status = 0x%04x[0x%04x]\n",
                       device_xname(sc->bge_dev),
                       locknum, req + off, bit & 0xFFFF, gnt + off,
                       status & 0xFFFF);
                   /* Revoke the lock request. */
                   APE_WRITE_4(sc, gnt + off, bit);
                   return (EBUSY);
           }
   
           return (0);
   }
   
   void
   bge_ape_unlock(struct bge_softc *sc, int locknum)
   {
           struct pci_attach_args *pa = &(sc->bge_pa);
           uint32_t bit, gnt;
           int off;
   
           if ((sc->bge_mfw_flags & BGE_MFW_ON_APE) == 0)
                   return;
   
           if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5761)
                   gnt = BGE_APE_LOCK_GRANT;
           else
                   gnt = BGE_APE_PER_LOCK_GRANT;
   
           off = 4 * locknum;
   
           switch (locknum) {
           case BGE_APE_LOCK_GPIO:
                   if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5761)
                           return;
                   if (pa->pa_function == 0)
                           bit = BGE_APE_LOCK_GRANT_DRIVER0;
                   else
                           bit = (1 << pa->pa_function);
                   break;
           case BGE_APE_LOCK_GRC:
                   if (pa->pa_function == 0)
                           bit = BGE_APE_LOCK_GRANT_DRIVER0;
                   else
                           bit = (1 << pa->pa_function);
                   break;
           case BGE_APE_LOCK_MEM:
                   if (pa->pa_function == 0)
                           bit = BGE_APE_LOCK_GRANT_DRIVER0;
                   else
                           bit = (1 << pa->pa_function);
                   break;
           case BGE_APE_LOCK_PHY0:
           case BGE_APE_LOCK_PHY1:
           case BGE_APE_LOCK_PHY2:
           case BGE_APE_LOCK_PHY3:
                   bit = BGE_APE_LOCK_GRANT_DRIVER0;
                   break;
           default:
                   return;
           }
   
           /* Write and flush for consecutive bge_ape_lock() */
           APE_WRITE_4_FLUSH(sc, gnt + off, bit);
   }
   
   /*
    * Send an event to the APE firmware.
    */
   void
   bge_ape_send_event(struct bge_softc *sc, uint32_t event)
   {
           uint32_t apedata;
           int i;
   
           /* NCSI does not support APE events. */
           if ((sc->bge_mfw_flags & BGE_MFW_ON_APE) == 0)
                   return;
   
           /* Wait up to 1ms for APE to service previous event. */
           for (i = 10; i > 0; i--) {
                   if (bge_ape_lock(sc, BGE_APE_LOCK_MEM) != 0)
                           break;
                   apedata = APE_READ_4(sc, BGE_APE_EVENT_STATUS);
                   if ((apedata & BGE_APE_EVENT_STATUS_EVENT_PENDING) == 0) {
                           APE_WRITE_4(sc, BGE_APE_EVENT_STATUS, event |
                               BGE_APE_EVENT_STATUS_EVENT_PENDING);
                           bge_ape_unlock(sc, BGE_APE_LOCK_MEM);
                           APE_WRITE_4(sc, BGE_APE_EVENT, BGE_APE_EVENT_1);
                           break;
                   }
                   bge_ape_unlock(sc, BGE_APE_LOCK_MEM);
                   DELAY(100);
           }
           if (i == 0) {
                   printf("%s: APE event 0x%08x send timed out\n",
                       device_xname(sc->bge_dev), event);
           }
   }
   
   void
   bge_ape_driver_state_change(struct bge_softc *sc, int kind)
   {
           uint32_t apedata, event;
   
           if ((sc->bge_mfw_flags & BGE_MFW_ON_APE) == 0)
                   return;
   
           switch (kind) {
           case BGE_RESET_START:
                   /* If this is the first load, clear the load counter. */
                   apedata = APE_READ_4(sc, BGE_APE_HOST_SEG_SIG);
                   if (apedata != BGE_APE_HOST_SEG_SIG_MAGIC)
                           APE_WRITE_4(sc, BGE_APE_HOST_INIT_COUNT, 0);
                   else {
                           apedata = APE_READ_4(sc, BGE_APE_HOST_INIT_COUNT);
                           APE_WRITE_4(sc, BGE_APE_HOST_INIT_COUNT, ++apedata);
                   }
                   APE_WRITE_4(sc, BGE_APE_HOST_SEG_SIG,
                       BGE_APE_HOST_SEG_SIG_MAGIC);
                   APE_WRITE_4(sc, BGE_APE_HOST_SEG_LEN,
                       BGE_APE_HOST_SEG_LEN_MAGIC);
   
                   /* Add some version info if bge(4) supports it. */
                   APE_WRITE_4(sc, BGE_APE_HOST_DRIVER_ID,
                       BGE_APE_HOST_DRIVER_ID_MAGIC(1, 0));
                   APE_WRITE_4(sc, BGE_APE_HOST_BEHAVIOR,
                       BGE_APE_HOST_BEHAV_NO_PHYLOCK);
                   APE_WRITE_4(sc, BGE_APE_HOST_HEARTBEAT_INT_MS,
                       BGE_APE_HOST_HEARTBEAT_INT_DISABLE);
                   APE_WRITE_4(sc, BGE_APE_HOST_DRVR_STATE,
                       BGE_APE_HOST_DRVR_STATE_START);
                   event = BGE_APE_EVENT_STATUS_STATE_START;
                   break;
           case BGE_RESET_SHUTDOWN:
                   APE_WRITE_4(sc, BGE_APE_HOST_DRVR_STATE,
                       BGE_APE_HOST_DRVR_STATE_UNLOAD);
                   event = BGE_APE_EVENT_STATUS_STATE_UNLOAD;
                   break;
           case BGE_RESET_SUSPEND:
                   event = BGE_APE_EVENT_STATUS_STATE_SUSPEND;
                   break;
           default:
                   return;
           }
   
           bge_ape_send_event(sc, event | BGE_APE_EVENT_STATUS_DRIVER_EVNT |
               BGE_APE_EVENT_STATUS_STATE_CHNGE);
   }
   
 static uint8_t  static uint8_t
 bge_nvram_getbyte(struct bge_softc *sc, int addr, uint8_t *dest)  bge_nvram_getbyte(struct bge_softc *sc, int addr, uint8_t *dest)
 {  {
Line 851  bge_nvram_getbyte(struct bge_softc *sc, 
Line 1246  bge_nvram_getbyte(struct bge_softc *sc, 
         CSR_WRITE_4(sc, BGE_NVRAM_ACCESS, access);          CSR_WRITE_4(sc, BGE_NVRAM_ACCESS, access);
   
         /* Unlock. */          /* Unlock. */
         CSR_WRITE_4(sc, BGE_NVRAM_SWARB, BGE_NVRAMSWARB_CLR1);          CSR_WRITE_4_FLUSH(sc, BGE_NVRAM_SWARB, BGE_NVRAMSWARB_CLR1);
         CSR_READ_4(sc, BGE_NVRAM_SWARB);  
   
         return 0;          return 0;
 }  }
Line 863  bge_nvram_getbyte(struct bge_softc *sc, 
Line 1257  bge_nvram_getbyte(struct bge_softc *sc, 
 static int  static int
 bge_read_nvram(struct bge_softc *sc, uint8_t *dest, int off, int cnt)  bge_read_nvram(struct bge_softc *sc, uint8_t *dest, int off, int cnt)
 {  {
         int err = 0, i;          int error = 0, i;
         uint8_t byte = 0;          uint8_t byte = 0;
   
         if (BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5906)          if (BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5906)
                 return 1;                  return 1;
   
         for (i = 0; i < cnt; i++) {          for (i = 0; i < cnt; i++) {
                 err = bge_nvram_getbyte(sc, off + i, &byte);                  error = bge_nvram_getbyte(sc, off + i, &byte);
                 if (err)                  if (error)
                         break;                          break;
                 *(dest + i) = byte;                  *(dest + i) = byte;
         }          }
   
         return (err ? 1 : 0);          return (error ? 1 : 0);
 }  }
   
 /*  /*
Line 931  bge_eeprom_getbyte(struct bge_softc *sc,
Line 1325  bge_eeprom_getbyte(struct bge_softc *sc,
 static int  static int
 bge_read_eeprom(struct bge_softc *sc, void *destv, int off, int cnt)  bge_read_eeprom(struct bge_softc *sc, void *destv, int off, int cnt)
 {  {
         int err = 0, i;          int error = 0, i;
         uint8_t byte = 0;          uint8_t byte = 0;
         char *dest = destv;          char *dest = destv;
   
         for (i = 0; i < cnt; i++) {          for (i = 0; i < cnt; i++) {
                 err = bge_eeprom_getbyte(sc, off + i, &byte);                  error = bge_eeprom_getbyte(sc, off + i, &byte);
                 if (err)                  if (error)
                         break;                          break;
                 *(dest + i) = byte;                  *(dest + i) = byte;
         }          }
   
         return (err ? 1 : 0);          return (error ? 1 : 0);
 }  }
   
 static int  static int
Line 953  bge_miibus_readreg(device_t dev, int phy
Line 1347  bge_miibus_readreg(device_t dev, int phy
         uint32_t autopoll;          uint32_t autopoll;
         int i;          int i;
   
         /*          if (bge_ape_lock(sc, sc->bge_phy_ape_lock) != 0)
          * Broadcom's own driver always assumes the internal  
          * PHY is at GMII address 1. On some chips, the PHY responds  
          * to accesses at all addresses, which could cause us to  
          * bogusly attach the PHY 32 times at probe type. Always  
          * restricting the lookup to address 1 is simpler than  
          * trying to figure out which chips revisions should be  
          * special-cased.  
          */  
         if (phy != 1)  
                 return 0;                  return 0;
   
         /* Reading with autopolling on may trigger PCI errors */          /* Reading with autopolling on may trigger PCI errors */
         autopoll = CSR_READ_4(sc, BGE_MI_MODE);          autopoll = CSR_READ_4(sc, BGE_MI_MODE);
         if (autopoll & BGE_MIMODE_AUTOPOLL) {          if (autopoll & BGE_MIMODE_AUTOPOLL) {
                 BGE_STS_CLRBIT(sc, BGE_STS_AUTOPOLL);                  BGE_STS_CLRBIT(sc, BGE_STS_AUTOPOLL);
                 BGE_CLRBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);                  BGE_CLRBIT_FLUSH(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);
                 DELAY(40);                  DELAY(80);
         }          }
   
         CSR_WRITE_4(sc, BGE_MI_COMM, BGE_MICMD_READ | BGE_MICOMM_BUSY |          CSR_WRITE_4_FLUSH(sc, BGE_MI_COMM, BGE_MICMD_READ | BGE_MICOMM_BUSY |
             BGE_MIPHY(phy) | BGE_MIREG(reg));              BGE_MIPHY(phy) | BGE_MIREG(reg));
   
         for (i = 0; i < BGE_TIMEOUT; i++) {          for (i = 0; i < BGE_TIMEOUT; i++) {
                   delay(10);
                 val = CSR_READ_4(sc, BGE_MI_COMM);                  val = CSR_READ_4(sc, BGE_MI_COMM);
                 if (!(val & BGE_MICOMM_BUSY))                  if (!(val & BGE_MICOMM_BUSY)) {
                           DELAY(5);
                           val = CSR_READ_4(sc, BGE_MI_COMM);
                         break;                          break;
                 delay(10);                  }
         }          }
   
         if (i == BGE_TIMEOUT) {          if (i == BGE_TIMEOUT) {
Line 989  bge_miibus_readreg(device_t dev, int phy
Line 1377  bge_miibus_readreg(device_t dev, int phy
                 goto done;                  goto done;
         }          }
   
         val = CSR_READ_4(sc, BGE_MI_COMM);  
   
 done:  done:
         if (autopoll & BGE_MIMODE_AUTOPOLL) {          if (autopoll & BGE_MIMODE_AUTOPOLL) {
                 BGE_STS_SETBIT(sc, BGE_STS_AUTOPOLL);                  BGE_STS_SETBIT(sc, BGE_STS_AUTOPOLL);
                 BGE_SETBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);                  BGE_SETBIT_FLUSH(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);
                 DELAY(40);                  DELAY(80);
         }          }
   
           bge_ape_unlock(sc, sc->bge_phy_ape_lock);
   
         if (val & BGE_MICOMM_READFAIL)          if (val & BGE_MICOMM_READFAIL)
                 return 0;                  return 0;
   
Line 1011  bge_miibus_writereg(device_t dev, int ph
Line 1399  bge_miibus_writereg(device_t dev, int ph
         uint32_t autopoll;          uint32_t autopoll;
         int i;          int i;
   
         if (phy!=1) {          if (bge_ape_lock(sc, sc->bge_phy_ape_lock) != 0)
                 return;                  return;
         }  
   
         if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906 &&          if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906 &&
             (reg == BRGPHY_MII_1000CTL || reg == BRGPHY_MII_AUXCTL)) {              (reg == BRGPHY_MII_1000CTL || reg == BRGPHY_MII_AUXCTL))
                 return;                  return;
         }  
   
         /* Reading with autopolling on may trigger PCI errors */          /* Reading with autopolling on may trigger PCI errors */
         autopoll = CSR_READ_4(sc, BGE_MI_MODE);          autopoll = CSR_READ_4(sc, BGE_MI_MODE);
         if (autopoll & BGE_MIMODE_AUTOPOLL) {          if (autopoll & BGE_MIMODE_AUTOPOLL) {
                 delay(40);  
                 BGE_STS_CLRBIT(sc, BGE_STS_AUTOPOLL);                  BGE_STS_CLRBIT(sc, BGE_STS_AUTOPOLL);
                 BGE_CLRBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);                  BGE_CLRBIT_FLUSH(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);
                 delay(10); /* 40 usec is supposed to be adequate */                  DELAY(80);
         }          }
   
         CSR_WRITE_4(sc, BGE_MI_COMM, BGE_MICMD_WRITE | BGE_MICOMM_BUSY |          CSR_WRITE_4_FLUSH(sc, BGE_MI_COMM, BGE_MICMD_WRITE | BGE_MICOMM_BUSY |
             BGE_MIPHY(phy) | BGE_MIREG(reg) | val);              BGE_MIPHY(phy) | BGE_MIREG(reg) | val);
   
         for (i = 0; i < BGE_TIMEOUT; i++) {          for (i = 0; i < BGE_TIMEOUT; i++) {
Line 1043  bge_miibus_writereg(device_t dev, int ph
Line 1428  bge_miibus_writereg(device_t dev, int ph
   
         if (autopoll & BGE_MIMODE_AUTOPOLL) {          if (autopoll & BGE_MIMODE_AUTOPOLL) {
                 BGE_STS_SETBIT(sc, BGE_STS_AUTOPOLL);                  BGE_STS_SETBIT(sc, BGE_STS_AUTOPOLL);
                 BGE_SETBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);                  BGE_SETBIT_FLUSH(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);
                 delay(40);                  delay(80);
         }          }
   
           bge_ape_unlock(sc, sc->bge_phy_ape_lock);
   
         if (i == BGE_TIMEOUT)          if (i == BGE_TIMEOUT)
                 aprint_error_dev(sc->bge_dev, "PHY read timed out\n");                  aprint_error_dev(sc->bge_dev, "PHY read timed out\n");
 }  }
Line 1056  bge_miibus_statchg(device_t dev)
Line 1443  bge_miibus_statchg(device_t dev)
 {  {
         struct bge_softc *sc = device_private(dev);          struct bge_softc *sc = device_private(dev);
         struct mii_data *mii = &sc->bge_mii;          struct mii_data *mii = &sc->bge_mii;
           uint32_t mac_mode, rx_mode, tx_mode;
   
         /*          /*
          * Get flow control negotiation result.           * Get flow control negotiation result.
          */           */
         if (IFM_SUBTYPE(mii->mii_media.ifm_cur->ifm_media) == IFM_AUTO &&          if (IFM_SUBTYPE(mii->mii_media.ifm_cur->ifm_media) == IFM_AUTO &&
             (mii->mii_media_active & IFM_ETH_FMASK) != sc->bge_flowflags) {              (mii->mii_media_active & IFM_ETH_FMASK) != sc->bge_flowflags)
                 sc->bge_flowflags = mii->mii_media_active & IFM_ETH_FMASK;                  sc->bge_flowflags = mii->mii_media_active & IFM_ETH_FMASK;
                 mii->mii_media_active &= ~IFM_ETH_FMASK;  
         }  
   
         BGE_CLRBIT(sc, BGE_MAC_MODE, BGE_MACMODE_PORTMODE);          if (!BGE_STS_BIT(sc, BGE_STS_LINK) &&
               mii->mii_media_status & IFM_ACTIVE &&
               IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)
                   BGE_STS_SETBIT(sc, BGE_STS_LINK);
           else if (BGE_STS_BIT(sc, BGE_STS_LINK) &&
               (!(mii->mii_media_status & IFM_ACTIVE) ||
               IFM_SUBTYPE(mii->mii_media_active) == IFM_NONE))
                   BGE_STS_CLRBIT(sc, BGE_STS_LINK);
   
           if (!BGE_STS_BIT(sc, BGE_STS_LINK))
                   return;
   
           /* Set the port mode (MII/GMII) to match the link speed. */
           mac_mode = CSR_READ_4(sc, BGE_MAC_MODE) &
               ~(BGE_MACMODE_PORTMODE | BGE_MACMODE_HALF_DUPLEX);
           tx_mode = CSR_READ_4(sc, BGE_TX_MODE);
           rx_mode = CSR_READ_4(sc, BGE_RX_MODE);
         if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||          if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
             IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX)              IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX)
                 BGE_SETBIT(sc, BGE_MAC_MODE, BGE_PORTMODE_GMII);                  mac_mode |= BGE_PORTMODE_GMII;
         else  
                 BGE_SETBIT(sc, BGE_MAC_MODE, BGE_PORTMODE_MII);  
   
         if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)  
                 BGE_CLRBIT(sc, BGE_MAC_MODE, BGE_MACMODE_HALF_DUPLEX);  
         else          else
                 BGE_SETBIT(sc, BGE_MAC_MODE, BGE_MACMODE_HALF_DUPLEX);                  mac_mode |= BGE_PORTMODE_MII;
   
         /*          tx_mode &= ~BGE_TXMODE_FLOWCTL_ENABLE;
          * 802.3x flow control          rx_mode &= ~BGE_RXMODE_FLOWCTL_ENABLE;
          */          if ((mii->mii_media_active & IFM_FDX) != 0) {
         if (sc->bge_flowflags & IFM_ETH_RXPAUSE)                  if (sc->bge_flowflags & IFM_ETH_TXPAUSE)
                 BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_FLOWCTL_ENABLE);                          tx_mode |= BGE_TXMODE_FLOWCTL_ENABLE;
         else                  if (sc->bge_flowflags & IFM_ETH_RXPAUSE)
                 BGE_CLRBIT(sc, BGE_RX_MODE, BGE_RXMODE_FLOWCTL_ENABLE);                          rx_mode |= BGE_RXMODE_FLOWCTL_ENABLE;
           } else
                   mac_mode |= BGE_MACMODE_HALF_DUPLEX;
   
         if (sc->bge_flowflags & IFM_ETH_TXPAUSE)          CSR_WRITE_4_FLUSH(sc, BGE_MAC_MODE, mac_mode);
                 BGE_SETBIT(sc, BGE_TX_MODE, BGE_TXMODE_FLOWCTL_ENABLE);          DELAY(40);
         else          CSR_WRITE_4(sc, BGE_TX_MODE, tx_mode);
                 BGE_CLRBIT(sc, BGE_TX_MODE, BGE_TXMODE_FLOWCTL_ENABLE);          CSR_WRITE_4(sc, BGE_RX_MODE, rx_mode);
 }  }
   
 /*  /*
Line 1113  bge_set_thresh(struct ifnet *ifp, int lv
Line 1512  bge_set_thresh(struct ifnet *ifp, int lv
         sc->bge_rx_max_coal_bds = bge_rx_threshes[lvl].rx_max_bds;          sc->bge_rx_max_coal_bds = bge_rx_threshes[lvl].rx_max_bds;
         sc->bge_pending_rxintr_change = 1;          sc->bge_pending_rxintr_change = 1;
         splx(s);          splx(s);
   
          return;  
 }  }
   
   
Line 1490  bge_init_rx_ring_jumbo(struct bge_softc 
Line 1887  bge_init_rx_ring_jumbo(struct bge_softc 
         for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) {          for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) {
                 if (bge_newbuf_jumbo(sc, i, NULL) == ENOBUFS)                  if (bge_newbuf_jumbo(sc, i, NULL) == ENOBUFS)
                         return ENOBUFS;                          return ENOBUFS;
         };          }
   
         sc->bge_jumbo = i - 1;          sc->bge_jumbo = i - 1;
         sc->bge_flags |= BGE_JUMBO_RXRING_VALID;          sc->bge_flags |= BGE_JUMBO_RXRING_VALID;
Line 1527  bge_free_rx_ring_jumbo(struct bge_softc 
Line 1924  bge_free_rx_ring_jumbo(struct bge_softc 
 static void  static void
 bge_free_tx_ring(struct bge_softc *sc)  bge_free_tx_ring(struct bge_softc *sc)
 {  {
         int i, freed;          int i;
         struct txdmamap_pool_entry *dma;          struct txdmamap_pool_entry *dma;
   
         if (!(sc->bge_flags & BGE_TXRING_VALID))          if (!(sc->bge_flags & BGE_TXRING_VALID))
                 return;                  return;
   
         freed = 0;  
   
         for (i = 0; i < BGE_TX_RING_CNT; i++) {          for (i = 0; i < BGE_TX_RING_CNT; i++) {
                 if (sc->bge_cdata.bge_tx_chain[i] != NULL) {                  if (sc->bge_cdata.bge_tx_chain[i] != NULL) {
                         freed++;  
                         m_freem(sc->bge_cdata.bge_tx_chain[i]);                          m_freem(sc->bge_cdata.bge_tx_chain[i]);
                         sc->bge_cdata.bge_tx_chain[i] = NULL;                          sc->bge_cdata.bge_tx_chain[i] = NULL;
                         SLIST_INSERT_HEAD(&sc->txdma_list, sc->txdma[i],                          SLIST_INSERT_HEAD(&sc->txdma_list, sc->txdma[i],
Line 1560  bge_free_tx_ring(struct bge_softc *sc)
Line 1954  bge_free_tx_ring(struct bge_softc *sc)
 static int  static int
 bge_init_tx_ring(struct bge_softc *sc)  bge_init_tx_ring(struct bge_softc *sc)
 {  {
           struct ifnet *ifp = &sc->ethercom.ec_if;
         int i;          int i;
         bus_dmamap_t dmamap;          bus_dmamap_t dmamap;
           bus_size_t maxsegsz;
         struct txdmamap_pool_entry *dma;          struct txdmamap_pool_entry *dma;
   
         if (sc->bge_flags & BGE_TXRING_VALID)          if (sc->bge_flags & BGE_TXRING_VALID)
Line 1583  bge_init_tx_ring(struct bge_softc *sc)
Line 1979  bge_init_tx_ring(struct bge_softc *sc)
         if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5700_BX)          if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5700_BX)
                 bge_writembx(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);                  bge_writembx(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
   
           /* Limit DMA segment size for some chips */
           if ((BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57766) &&
               (ifp->if_mtu <= ETHERMTU))
                   maxsegsz = 2048;
           else if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719)
                   maxsegsz = 4096;
           else
                   maxsegsz = ETHER_MAX_LEN_JUMBO;
         SLIST_INIT(&sc->txdma_list);          SLIST_INIT(&sc->txdma_list);
         for (i = 0; i < BGE_RSLOTS; i++) {          for (i = 0; i < BGE_TX_RING_CNT; i++) {
                 if (bus_dmamap_create(sc->bge_dmatag, BGE_TXDMA_MAX,                  if (bus_dmamap_create(sc->bge_dmatag, BGE_TXDMA_MAX,
                     BGE_NTXSEG, ETHER_MAX_LEN_JUMBO, 0, BUS_DMA_NOWAIT,                      BGE_NTXSEG, maxsegsz, 0, BUS_DMA_NOWAIT,
                     &dmamap))                      &dmamap))
                         return ENOBUFS;                          return ENOBUFS;
                 if (dmamap == NULL)                  if (dmamap == NULL)
Line 1660  bge_setmulti(struct bge_softc *sc)
Line 2064  bge_setmulti(struct bge_softc *sc)
 static void  static void
 bge_sig_pre_reset(struct bge_softc *sc, int type)  bge_sig_pre_reset(struct bge_softc *sc, int type)
 {  {
   
         /*          /*
          * Some chips don't like this so only do this if ASF is enabled           * Some chips don't like this so only do this if ASF is enabled
          */           */
         if (sc->bge_asf_mode)          if (sc->bge_asf_mode)
                 bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);                  bge_writemem_ind(sc, BGE_SRAM_FW_MB, BGE_SRAM_FW_MB_MAGIC);
   
         if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) {          if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) {
                 switch (type) {                  switch (type) {
                 case BGE_RESET_START:                  case BGE_RESET_START:
                         bge_writemem_ind(sc, BGE_SDI_STATUS, 0x1); /* START */                          bge_writemem_ind(sc, BGE_SRAM_FW_DRV_STATE_MB,
                               BGE_FW_DRV_STATE_START);
                         break;                          break;
                 case BGE_RESET_STOP:                  case BGE_RESET_SHUTDOWN:
                         bge_writemem_ind(sc, BGE_SDI_STATUS, 0x2); /* UNLOAD */                          bge_writemem_ind(sc, BGE_SRAM_FW_DRV_STATE_MB,
                               BGE_FW_DRV_STATE_UNLOAD);
                           break;
                   case BGE_RESET_SUSPEND:
                           bge_writemem_ind(sc, BGE_SRAM_FW_DRV_STATE_MB,
                               BGE_FW_DRV_STATE_SUSPEND);
                         break;                          break;
                 }                  }
         }          }
   
           if (type == BGE_RESET_START || type == BGE_RESET_SUSPEND)
                   bge_ape_driver_state_change(sc, type);
 }  }
   
 static void  static void
Line 1685  bge_sig_post_reset(struct bge_softc *sc,
Line 2099  bge_sig_post_reset(struct bge_softc *sc,
         if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) {          if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) {
                 switch (type) {                  switch (type) {
                 case BGE_RESET_START:                  case BGE_RESET_START:
                         bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000001);                          bge_writemem_ind(sc, BGE_SRAM_FW_DRV_STATE_MB,
                               BGE_FW_DRV_STATE_START_DONE);
                         /* START DONE */                          /* START DONE */
                         break;                          break;
                 case BGE_RESET_STOP:                  case BGE_RESET_SHUTDOWN:
                         bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000002);                          bge_writemem_ind(sc, BGE_SRAM_FW_DRV_STATE_MB,
                               BGE_FW_DRV_STATE_UNLOAD_DONE);
                         break;                          break;
                 }                  }
         }          }
   
           if (type == BGE_RESET_SHUTDOWN)
                   bge_ape_driver_state_change(sc, type);
 }  }
   
 static void  static void
Line 1702  bge_sig_legacy(struct bge_softc *sc, int
Line 2121  bge_sig_legacy(struct bge_softc *sc, int
         if (sc->bge_asf_mode) {          if (sc->bge_asf_mode) {
                 switch (type) {                  switch (type) {
                 case BGE_RESET_START:                  case BGE_RESET_START:
                         bge_writemem_ind(sc, BGE_SDI_STATUS, 0x1); /* START */                          bge_writemem_ind(sc, BGE_SRAM_FW_DRV_STATE_MB,
                               BGE_FW_DRV_STATE_START);
                         break;                          break;
                 case BGE_RESET_STOP:                  case BGE_RESET_SHUTDOWN:
                         bge_writemem_ind(sc, BGE_SDI_STATUS, 0x2); /* UNLOAD */                          bge_writemem_ind(sc, BGE_SRAM_FW_DRV_STATE_MB,
                               BGE_FW_DRV_STATE_UNLOAD);
                         break;                          break;
                 }                  }
         }          }
 }  }
   
 static void  static void
 bge_stop_fw(struct bge_softc *sc)  bge_wait_for_event_ack(struct bge_softc *sc)
 {  {
         int i;          int i;
   
           /* wait up to 2500usec */
           for (i = 0; i < 250; i++) {
                   if (!(CSR_READ_4(sc, BGE_RX_CPU_EVENT) &
                           BGE_RX_CPU_DRV_EVENT))
                           break;
                   DELAY(10);
           }
   }
   
   static void
   bge_stop_fw(struct bge_softc *sc)
   {
   
         if (sc->bge_asf_mode) {          if (sc->bge_asf_mode) {
                 bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM_FW, BGE_FW_PAUSE);                  bge_wait_for_event_ack(sc);
                 CSR_WRITE_4(sc, BGE_CPU_EVENT,  
                     CSR_READ_4(sc, BGE_CPU_EVENT) | (1 << 14));  
   
                 for (i = 0; i < 100; i++) {                  bge_writemem_ind(sc, BGE_SRAM_FW_CMD_MB, BGE_FW_CMD_PAUSE);
                         if (!(CSR_READ_4(sc, BGE_CPU_EVENT) & (1 << 14)))                  CSR_WRITE_4_FLUSH(sc, BGE_RX_CPU_EVENT,
                                 break;                      CSR_READ_4(sc, BGE_RX_CPU_EVENT) | BGE_RX_CPU_DRV_EVENT);
                         DELAY(10);  
                 }                  bge_wait_for_event_ack(sc);
         }          }
 }  }
   
Line 1755  bge_poll_fw(struct bge_softc *sc)
Line 2187  bge_poll_fw(struct bge_softc *sc)
                  * XXX 1000ms for Flash and 10000ms for SEEPROM.                   * XXX 1000ms for Flash and 10000ms for SEEPROM.
                  */                   */
                 for (i = 0; i < BGE_TIMEOUT; i++) {                  for (i = 0; i < BGE_TIMEOUT; i++) {
                         val = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM);                          val = bge_readmem_ind(sc, BGE_SRAM_FW_MB);
                         if (val == ~BGE_MAGIC_NUMBER)                          if (val == ~BGE_SRAM_FW_MB_MAGIC)
                                 break;                                  break;
                         DELAY(10);                          DELAY(10);
                 }                  }
Line 1768  bge_poll_fw(struct bge_softc *sc)
Line 2200  bge_poll_fw(struct bge_softc *sc)
                 }                  }
         }          }
   
           if (sc->bge_chipid == BGE_CHIPID_BCM57765_A0) {
                   /* tg3 says we have to wait extra time */
                   delay(10 * 1000);
           }
   
         return 0;          return 0;
 }  }
   
   int
   bge_phy_addr(struct bge_softc *sc)
   {
           struct pci_attach_args *pa = &(sc->bge_pa);
           int phy_addr = 1;
   
           /*
            * PHY address mapping for various devices.
            *
            *          | F0 Cu | F0 Sr | F1 Cu | F1 Sr |
            * ---------+-------+-------+-------+-------+
            * BCM57XX  |   1   |   X   |   X   |   X   |
            * BCM5704  |   1   |   X   |   1   |   X   |
            * BCM5717  |   1   |   8   |   2   |   9   |
            * BCM5719  |   1   |   8   |   2   |   9   |
            * BCM5720  |   1   |   8   |   2   |   9   |
            *
            *          | F2 Cu | F2 Sr | F3 Cu | F3 Sr |
            * ---------+-------+-------+-------+-------+
            * BCM57XX  |   X   |   X   |   X   |   X   |
            * BCM5704  |   X   |   X   |   X   |   X   |
            * BCM5717  |   X   |   X   |   X   |   X   |
            * BCM5719  |   3   |   10  |   4   |   11  |
            * BCM5720  |   X   |   X   |   X   |   X   |
            *
            * Other addresses may respond but they are not
            * IEEE compliant PHYs and should be ignored.
            */
           switch (BGE_ASICREV(sc->bge_chipid)) {
           case BGE_ASICREV_BCM5717:
           case BGE_ASICREV_BCM5719:
           case BGE_ASICREV_BCM5720:
                   phy_addr = pa->pa_function;
                   if (sc->bge_chipid != BGE_CHIPID_BCM5717_A0) {
                           phy_addr += (CSR_READ_4(sc, BGE_SGDIG_STS) &
                               BGE_SGDIGSTS_IS_SERDES) ? 8 : 1;
                   } else {
                           phy_addr += (CSR_READ_4(sc, BGE_CPMU_PHY_STRAP) &
                               BGE_CPMU_PHY_STRAP_IS_SERDES) ? 8 : 1;
                   }
           }
   
           return phy_addr;
   }
   
 /*  /*
  * Do endian, PCI and DMA initialization. Also check the on-board ROM   * Do endian, PCI and DMA initialization. Also check the on-board ROM
  * self-test results.   * self-test results.
Line 1778  bge_poll_fw(struct bge_softc *sc)
Line 2260  bge_poll_fw(struct bge_softc *sc)
 static int  static int
 bge_chipinit(struct bge_softc *sc)  bge_chipinit(struct bge_softc *sc)
 {  {
           uint32_t dma_rw_ctl, mode_ctl, reg;
         int i;          int i;
         uint32_t dma_rw_ctl;  
   
         /* Set endianness before we access any non-PCI registers. */          /* Set endianness before we access any non-PCI registers. */
         pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MISC_CTL,          pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MISC_CTL,
             BGE_INIT);              BGE_INIT);
   
         /* Set power state to D0. */  
         bge_setpowerstate(sc, 0);  
   
         /* Clear the MAC control register */  
         CSR_WRITE_4(sc, BGE_MAC_MODE, 0);  
   
         /*          /*
          * Clear the MAC statistics block in the NIC's           * Clear the MAC statistics block in the NIC's
          * internal memory.           * internal memory.
Line 1803  bge_chipinit(struct bge_softc *sc)
Line 2279  bge_chipinit(struct bge_softc *sc)
             i < BGE_STATUS_BLOCK_END + 1; i += sizeof(uint32_t))              i < BGE_STATUS_BLOCK_END + 1; i += sizeof(uint32_t))
                 BGE_MEMWIN_WRITE(sc->sc_pc, sc->sc_pcitag, i, 0);                  BGE_MEMWIN_WRITE(sc->sc_pc, sc->sc_pcitag, i, 0);
   
           /* 5717 workaround from tg3 */
           if (sc->bge_chipid == BGE_CHIPID_BCM5717_A0) {
                   /* Save */
                   mode_ctl = CSR_READ_4(sc, BGE_MODE_CTL);
   
                   /* Temporary modify MODE_CTL to control TLP */
                   reg = mode_ctl & ~BGE_MODECTL_PCIE_TLPADDRMASK;
                   CSR_WRITE_4(sc, BGE_MODE_CTL, reg | BGE_MODECTL_PCIE_TLPADDR1);
   
                   /* Control TLP */
                   reg = CSR_READ_4(sc, BGE_TLP_CONTROL_REG +
                       BGE_TLP_PHYCTL1);
                   CSR_WRITE_4(sc, BGE_TLP_CONTROL_REG + BGE_TLP_PHYCTL1,
                       reg | BGE_TLP_PHYCTL1_EN_L1PLLPD);
   
                   /* Restore */
                   CSR_WRITE_4(sc, BGE_MODE_CTL, mode_ctl);
           }
   
           if (BGE_IS_57765_FAMILY(sc)) {
                   if (sc->bge_chipid == BGE_CHIPID_BCM57765_A0) {
                           /* Save */
                           mode_ctl = CSR_READ_4(sc, BGE_MODE_CTL);
   
                           /* Temporary modify MODE_CTL to control TLP */
                           reg = mode_ctl & ~BGE_MODECTL_PCIE_TLPADDRMASK;
                           CSR_WRITE_4(sc, BGE_MODE_CTL,
                               reg | BGE_MODECTL_PCIE_TLPADDR1);
   
                           /* Control TLP */
                           reg = CSR_READ_4(sc, BGE_TLP_CONTROL_REG +
                               BGE_TLP_PHYCTL5);
                           CSR_WRITE_4(sc, BGE_TLP_CONTROL_REG + BGE_TLP_PHYCTL5,
                               reg | BGE_TLP_PHYCTL5_DIS_L2CLKREQ);
   
                           /* Restore */
                           CSR_WRITE_4(sc, BGE_MODE_CTL, mode_ctl);
                   }
                   if (BGE_CHIPREV(sc->bge_chipid) != BGE_CHIPREV_57765_AX) {
                           reg = CSR_READ_4(sc, BGE_CPMU_PADRNG_CTL);
                           CSR_WRITE_4(sc, BGE_CPMU_PADRNG_CTL,
                               reg | BGE_CPMU_PADRNG_CTL_RDIV2);
   
                           /* Save */
                           mode_ctl = CSR_READ_4(sc, BGE_MODE_CTL);
   
                           /* Temporary modify MODE_CTL to control TLP */
                           reg = mode_ctl & ~BGE_MODECTL_PCIE_TLPADDRMASK;
                           CSR_WRITE_4(sc, BGE_MODE_CTL,
                               reg | BGE_MODECTL_PCIE_TLPADDR0);
   
                           /* Control TLP */
                           reg = CSR_READ_4(sc, BGE_TLP_CONTROL_REG +
                               BGE_TLP_FTSMAX);
                           reg &= ~BGE_TLP_FTSMAX_MSK;
                           CSR_WRITE_4(sc, BGE_TLP_CONTROL_REG + BGE_TLP_FTSMAX,
                               reg | BGE_TLP_FTSMAX_VAL);
   
                           /* Restore */
                           CSR_WRITE_4(sc, BGE_MODE_CTL, mode_ctl);
                   }
   
                   reg = CSR_READ_4(sc, BGE_CPMU_LSPD_10MB_CLK);
                   reg &= ~BGE_CPMU_LSPD_10MB_MACCLK_MASK;
                   reg |= BGE_CPMU_LSPD_10MB_MACCLK_6_25;
                   CSR_WRITE_4(sc, BGE_CPMU_LSPD_10MB_CLK, reg);
           }
   
         /* Set up the PCI DMA control register. */          /* Set up the PCI DMA control register. */
         dma_rw_ctl = BGE_PCI_READ_CMD | BGE_PCI_WRITE_CMD;          dma_rw_ctl = BGE_PCI_READ_CMD | BGE_PCI_WRITE_CMD;
         if (sc->bge_flags & BGE_PCIE) {          if (sc->bge_flags & BGE_PCIE) {
                 /* Read watermark not used, 128 bytes for write. */                  /* Read watermark not used, 128 bytes for write. */
                 DPRINTFN(4, ("(%s: PCI-Express DMA setting)\n",                  DPRINTFN(4, ("(%s: PCI-Express DMA setting)\n",
                     device_xname(sc->bge_dev)));                      device_xname(sc->bge_dev)));
                 dma_rw_ctl |= (0x3 << BGE_PCIDMARWCTL_WR_WAT_SHIFT);                  if (sc->bge_mps >= 256)
                           dma_rw_ctl |= BGE_PCIDMARWCTL_WR_WAT_SHIFT(7);
                   else
                           dma_rw_ctl |= BGE_PCIDMARWCTL_WR_WAT_SHIFT(3);
         } else if (sc->bge_flags & BGE_PCIX) {          } else if (sc->bge_flags & BGE_PCIX) {
                 DPRINTFN(4, ("(:%s: PCI-X DMA setting)\n",                  DPRINTFN(4, ("(:%s: PCI-X DMA setting)\n",
                     device_xname(sc->bge_dev)));                      device_xname(sc->bge_dev)));
                 /* PCI-X bus */                  /* PCI-X bus */
                 if (BGE_IS_5714_FAMILY(sc)) {                  if (BGE_IS_5714_FAMILY(sc)) {
                         /* 256 bytes for read and write. */                          /* 256 bytes for read and write. */
                         dma_rw_ctl |= (0x02 << BGE_PCIDMARWCTL_RD_WAT_SHIFT) |                          dma_rw_ctl |= BGE_PCIDMARWCTL_RD_WAT_SHIFT(2) |
                             (0x02 << BGE_PCIDMARWCTL_WR_WAT_SHIFT);                              BGE_PCIDMARWCTL_WR_WAT_SHIFT(2);
   
                         if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5780)                          if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5780)
                                 dma_rw_ctl |= BGE_PCIDMARWCTL_ONEDMA_ATONCE_GLOBAL;                                  dma_rw_ctl |= BGE_PCIDMARWCTL_ONEDMA_ATONCE_GLOBAL;
Line 1825  bge_chipinit(struct bge_softc *sc)
Line 2372  bge_chipinit(struct bge_softc *sc)
                                 dma_rw_ctl |= BGE_PCIDMARWCTL_ONEDMA_ATONCE_LOCAL;                                  dma_rw_ctl |= BGE_PCIDMARWCTL_ONEDMA_ATONCE_LOCAL;
                 } else if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704) {                  } else if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704) {
                         /* 1536 bytes for read, 384 bytes for write. */                          /* 1536 bytes for read, 384 bytes for write. */
                         dma_rw_ctl |=                          dma_rw_ctl |= BGE_PCIDMARWCTL_RD_WAT_SHIFT(7) |
                           (0x7 << BGE_PCIDMARWCTL_RD_WAT_SHIFT) |                              BGE_PCIDMARWCTL_WR_WAT_SHIFT(3);
                           (0x3 << BGE_PCIDMARWCTL_WR_WAT_SHIFT);  
                 } else {                  } else {
                         /* 384 bytes for read and write. */                          /* 384 bytes for read and write. */
                         dma_rw_ctl |= (0x03 << BGE_PCIDMARWCTL_RD_WAT_SHIFT) |                          dma_rw_ctl |= BGE_PCIDMARWCTL_RD_WAT_SHIFT(3) |
                             (0x03 << BGE_PCIDMARWCTL_WR_WAT_SHIFT) |                              BGE_PCIDMARWCTL_WR_WAT_SHIFT(3) |
                             (0x0F);                              (0x0F);
                 }                  }
   
Line 1852  bge_chipinit(struct bge_softc *sc)
Line 2398  bge_chipinit(struct bge_softc *sc)
                 /* Conventional PCI bus: 256 bytes for read and write. */                  /* Conventional PCI bus: 256 bytes for read and write. */
                 DPRINTFN(4, ("(%s: PCI 2.2 DMA setting)\n",                  DPRINTFN(4, ("(%s: PCI 2.2 DMA setting)\n",
                     device_xname(sc->bge_dev)));                      device_xname(sc->bge_dev)));
                 dma_rw_ctl |= (0x7 << BGE_PCIDMARWCTL_RD_WAT_SHIFT) |                  dma_rw_ctl |= BGE_PCIDMARWCTL_RD_WAT_SHIFT(7) |
                    (0x7 << BGE_PCIDMARWCTL_WR_WAT_SHIFT);                      BGE_PCIDMARWCTL_WR_WAT_SHIFT(7);
   
                 if (BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5705 &&                  if (BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5705 &&
                     BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5750)                      BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5750)
                         dma_rw_ctl |= 0x0F;                          dma_rw_ctl |= 0x0F;
Line 1868  bge_chipinit(struct bge_softc *sc)
Line 2415  bge_chipinit(struct bge_softc *sc)
             BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704)              BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704)
                 dma_rw_ctl &= ~BGE_PCIDMARWCTL_MINDMA;                  dma_rw_ctl &= ~BGE_PCIDMARWCTL_MINDMA;
   
           if (BGE_IS_57765_PLUS(sc)) {
                   dma_rw_ctl &= ~BGE_PCIDMARWCTL_DIS_CACHE_ALIGNMENT;
                   if (sc->bge_chipid == BGE_CHIPID_BCM57765_A0)
                           dma_rw_ctl &= ~BGE_PCIDMARWCTL_CRDRDR_RDMA_MRRS_MSK;
   
                   /*
                    * Enable HW workaround for controllers that misinterpret
                    * a status tag update and leave interrupts permanently
                    * disabled.
                    */
                   if (!BGE_IS_57765_FAMILY(sc) &&
                       BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5717)
                           dma_rw_ctl |= BGE_PCIDMARWCTL_TAGGED_STATUS_WA;
           }
   
         pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_DMA_RW_CTL,          pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_DMA_RW_CTL,
             dma_rw_ctl);              dma_rw_ctl);
   
         /*          /*
          * Set up general mode register.           * Set up general mode register.
          */           */
         CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS |          mode_ctl = BGE_DMA_SWAP_OPTIONS;
             BGE_MODECTL_MAC_ATTN_INTR | BGE_MODECTL_HOST_SEND_BDS |          if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5720) {
             BGE_MODECTL_TX_NO_PHDR_CSUM);                  /* Retain Host-2-BMC settings written by APE firmware. */
                   mode_ctl |= CSR_READ_4(sc, BGE_MODE_CTL) &
                       (BGE_MODECTL_BYTESWAP_B2HRX_DATA |
                       BGE_MODECTL_WORDSWAP_B2HRX_DATA |
                       BGE_MODECTL_B2HRX_ENABLE | BGE_MODECTL_HTX2B_ENABLE);
           }
           mode_ctl |= BGE_MODECTL_MAC_ATTN_INTR | BGE_MODECTL_HOST_SEND_BDS |
               BGE_MODECTL_TX_NO_PHDR_CSUM;
   
         /*          /*
          * BCM5701 B5 have a bug causing data corruption when using           * BCM5701 B5 have a bug causing data corruption when using
Line 1886  bge_chipinit(struct bge_softc *sc)
Line 2455  bge_chipinit(struct bge_softc *sc)
          */           */
         if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5701 &&          if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5701 &&
             sc->bge_chipid == BGE_CHIPID_BCM5701_B5)              sc->bge_chipid == BGE_CHIPID_BCM5701_B5)
                 BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_FORCE_PCI32);                  mode_ctl |= BGE_MODECTL_FORCE_PCI32;
   
         /*          /*
          * Tell the firmware the driver is running           * Tell the firmware the driver is running
          */           */
         if (sc->bge_asf_mode & ASF_STACKUP)          if (sc->bge_asf_mode & ASF_STACKUP)
                 BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);                  mode_ctl |= BGE_MODECTL_STACKUP;
   
           CSR_WRITE_4(sc, BGE_MODE_CTL, mode_ctl);
   
         /*          /*
          * Disable memory write invalidate.  Apparently it is not supported           * Disable memory write invalidate.  Apparently it is not supported
Line 1912  bge_chipinit(struct bge_softc *sc)
Line 2483  bge_chipinit(struct bge_softc *sc)
 #endif  #endif
   
         /* Set the timer prescaler (always 66MHz) */          /* Set the timer prescaler (always 66MHz) */
         CSR_WRITE_4(sc, BGE_MISC_CFG, 65 << 1/*BGE_32BITTIME_66MHZ*/);          CSR_WRITE_4(sc, BGE_MISC_CFG, BGE_32BITTIME_66MHZ);
   
         if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906) {          if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906) {
                 DELAY(40);      /* XXX */                  DELAY(40);      /* XXX */
   
                 /* Put PHY into ready state */                  /* Put PHY into ready state */
                 BGE_CLRBIT(sc, BGE_MISC_CFG, BGE_MISCCFG_EPHY_IDDQ);                  BGE_CLRBIT_FLUSH(sc, BGE_MISC_CFG, BGE_MISCCFG_EPHY_IDDQ);
                 CSR_READ_4(sc, BGE_MISC_CFG); /* Flush */  
                 DELAY(40);                  DELAY(40);
         }          }
   
Line 1931  bge_blockinit(struct bge_softc *sc)
Line 2501  bge_blockinit(struct bge_softc *sc)
 {  {
         volatile struct bge_rcb  *rcb;          volatile struct bge_rcb  *rcb;
         bus_size_t rcb_addr;          bus_size_t rcb_addr;
         int i;  
         struct ifnet *ifp = &sc->ethercom.ec_if;          struct ifnet *ifp = &sc->ethercom.ec_if;
         bge_hostaddr taddr;          bge_hostaddr taddr;
         uint32_t val;          uint32_t        dmactl, val;
           int             i, limit;
   
         /*          /*
          * Initialize the memory window pointer register so that           * Initialize the memory window pointer register so that
Line 1942  bge_blockinit(struct bge_softc *sc)
Line 2512  bge_blockinit(struct bge_softc *sc)
          * allow us to set up the TX send ring RCBs and the RX return           * allow us to set up the TX send ring RCBs and the RX return
          * ring RCBs, plus other things which live in NIC memory.           * ring RCBs, plus other things which live in NIC memory.
          */           */
   
         pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_BASEADDR, 0);          pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_BASEADDR, 0);
   
         /* Step 33: Configure mbuf memory pool */          if (!BGE_IS_5705_PLUS(sc)) {
         if (BGE_IS_5700_FAMILY(sc)) {                  /* 57XX step 33 */
                   /* Configure mbuf memory pool */
                 CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_BASEADDR,                  CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_BASEADDR,
                     BGE_BUFFPOOL_1);                      BGE_BUFFPOOL_1);
   
Line 1955  bge_blockinit(struct bge_softc *sc)
Line 2525  bge_blockinit(struct bge_softc *sc)
                 else                  else
                         CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_LEN, 0x18000);                          CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_LEN, 0x18000);
   
                   /* 57XX step 34 */
                 /* Configure DMA resource pool */                  /* Configure DMA resource pool */
                 CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_BASEADDR,                  CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_BASEADDR,
                     BGE_DMA_DESCRIPTORS);                      BGE_DMA_DESCRIPTORS);
                 CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_LEN, 0x2000);                  CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_LEN, 0x2000);
         }          }
   
         /* Step 35: Configure mbuf pool watermarks */          /* 5718 step 11, 57XX step 35 */
 #ifdef ORIG_WPAUL_VALUES          /*
         CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 24);           * Configure mbuf pool watermarks. New broadcom docs strongly
         CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 24);           * recommend these.
         CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 48);           */
 #else          if (BGE_IS_5717_PLUS(sc)) {
                   CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);
                   CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x2a);
                   CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0xa0);
           } else if (BGE_IS_5705_PLUS(sc)) {
                   CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);
   
         /* new broadcom docs strongly recommend these: */                  if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906) {
         if (!BGE_IS_5705_PLUS(sc)) {                          CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x04);
                 if (ifp->if_mtu > ETHER_MAX_LEN) {                          CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x10);
                         CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x50);  
                         CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x20);  
                         CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60);  
                 } else {                  } else {
                         CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 304);                          CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x10);
                         CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 152);                          CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60);
                         CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 380);  
                 }                  }
         } else if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906) {  
                 CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);  
                 CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x04);  
                 CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x10);  
         } else {          } else {
                 CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);                  CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x50);
                 CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x10);                  CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x20);
                 CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60);                  CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60);
         }          }
 #endif  
   
         /* Step 36: Configure DMA resource watermarks */          /* 57XX step 36 */
           /* Configure DMA resource watermarks */
         CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_LOWAT, 5);          CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_LOWAT, 5);
         CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_HIWAT, 10);          CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_HIWAT, 10);
   
         /* Step 38: Enable buffer manager */          /* 5718 step 13, 57XX step 38 */
         CSR_WRITE_4(sc, BGE_BMAN_MODE,          /* Enable buffer manager */
             BGE_BMANMODE_ENABLE | BGE_BMANMODE_LOMBUF_ATTN);          val = BGE_BMANMODE_ENABLE | BGE_BMANMODE_ATTN;
           /*
            * Change the arbitration algorithm of TXMBUF read request to
            * round-robin instead of priority based for BCM5719.  When
            * TXFIFO is almost empty, RDMA will hold its request until
            * TXFIFO is not almost empty.
            */
           if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719)
                   val |= BGE_BMANMODE_NO_TX_UNDERRUN;
           if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 ||
                   sc->bge_chipid == BGE_CHIPID_BCM5719_A0 ||
                   sc->bge_chipid == BGE_CHIPID_BCM5720_A0)
                   val |= BGE_BMANMODE_LOMBUF_ATTN;
           CSR_WRITE_4(sc, BGE_BMAN_MODE, val);
   
         /* Step 39: Poll for buffer manager start indication */          /* 57XX step 39 */
           /* Poll for buffer manager start indication */
         for (i = 0; i < BGE_TIMEOUT * 2; i++) {          for (i = 0; i < BGE_TIMEOUT * 2; i++) {
                   DELAY(10);
                 if (CSR_READ_4(sc, BGE_BMAN_MODE) & BGE_BMANMODE_ENABLE)                  if (CSR_READ_4(sc, BGE_BMAN_MODE) & BGE_BMANMODE_ENABLE)
                         break;                          break;
                 DELAY(10);  
         }          }
   
         if (i == BGE_TIMEOUT * 2) {          if (i == BGE_TIMEOUT * 2) {
Line 2011  bge_blockinit(struct bge_softc *sc)
Line 2593  bge_blockinit(struct bge_softc *sc)
                 return ENXIO;                  return ENXIO;
         }          }
   
         /* Step 40: Enable flow-through queues */          /* 57XX step 40 */
           /* Enable flow-through queues */
         CSR_WRITE_4(sc, BGE_FTQ_RESET, 0xFFFFFFFF);          CSR_WRITE_4(sc, BGE_FTQ_RESET, 0xFFFFFFFF);
         CSR_WRITE_4(sc, BGE_FTQ_RESET, 0);          CSR_WRITE_4(sc, BGE_FTQ_RESET, 0);
   
Line 2028  bge_blockinit(struct bge_softc *sc)
Line 2611  bge_blockinit(struct bge_softc *sc)
                 return ENXIO;                  return ENXIO;
         }          }
   
         /* Step 41: Initialize the standard RX ring control block */          /*
            * Summary of rings supported by the controller:
            *
            * Standard Receive Producer Ring
            * - This ring is used to feed receive buffers for "standard"
            *   sized frames (typically 1536 bytes) to the controller.
            *
            * Jumbo Receive Producer Ring
            * - This ring is used to feed receive buffers for jumbo sized
            *   frames (i.e. anything bigger than the "standard" frames)
            *   to the controller.
            *
            * Mini Receive Producer Ring
            * - This ring is used to feed receive buffers for "mini"
            *   sized frames to the controller.
            * - This feature required external memory for the controller
            *   but was never used in a production system.  Should always
            *   be disabled.
            *
            * Receive Return Ring
            * - After the controller has placed an incoming frame into a
            *   receive buffer that buffer is moved into a receive return
            *   ring.  The driver is then responsible to passing the
            *   buffer up to the stack.  Many versions of the controller
            *   support multiple RR rings.
            *
            * Send Ring
            * - This ring is used for outgoing frames.  Many versions of
            *   the controller support multiple send rings.
            */
   
           /* 5718 step 15, 57XX step 41 */
           /* Initialize the standard RX ring control block */
         rcb = &sc->bge_rdata->bge_info.bge_std_rx_rcb;          rcb = &sc->bge_rdata->bge_info.bge_std_rx_rcb;
         BGE_HOSTADDR(rcb->bge_hostaddr, BGE_RING_DMA_ADDR(sc, bge_rx_std_ring));          BGE_HOSTADDR(rcb->bge_hostaddr, BGE_RING_DMA_ADDR(sc, bge_rx_std_ring));
         if (BGE_IS_5705_PLUS(sc))          /* 5718 step 16 */
           if (BGE_IS_57765_PLUS(sc)) {
                   /*
                    * Bits 31-16: Programmable ring size (2048, 1024, 512, .., 32)
                    * Bits 15-2 : Maximum RX frame size
                    * Bit 1     : 1 = Ring Disabled, 0 = Ring ENabled
                    * Bit 0     : Reserved
                    */
                   rcb->bge_maxlen_flags =
                       BGE_RCB_MAXLEN_FLAGS(512, BGE_MAX_FRAMELEN << 2);
           } else if (BGE_IS_5705_PLUS(sc)) {
                   /*
                    * Bits 31-16: Programmable ring size (512, 256, 128, 64, 32)
                    * Bits 15-2 : Reserved (should be 0)
                    * Bit 1     : 1 = Ring Disabled, 0 = Ring Enabled
                    * Bit 0     : Reserved
                    */
                 rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(512, 0);                  rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(512, 0);
         else          } else {
                   /*
                    * Ring size is always XXX entries
                    * Bits 31-16: Maximum RX frame size
                    * Bits 15-2 : Reserved (should be 0)
                    * Bit 1     : 1 = Ring Disabled, 0 = Ring Enabled
                    * Bit 0     : Reserved
                    */
                 rcb->bge_maxlen_flags =                  rcb->bge_maxlen_flags =
                     BGE_RCB_MAXLEN_FLAGS(BGE_MAX_FRAMELEN, 0);                      BGE_RCB_MAXLEN_FLAGS(BGE_MAX_FRAMELEN, 0);
         rcb->bge_nicaddr = BGE_STD_RX_RINGS;          }
           if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 ||
               BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719 ||
               BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5720)
                   rcb->bge_nicaddr = BGE_STD_RX_RINGS_5717;
           else
                   rcb->bge_nicaddr = BGE_STD_RX_RINGS;
           /* Write the standard receive producer ring control block. */
         CSR_WRITE_4(sc, BGE_RX_STD_RCB_HADDR_HI, rcb->bge_hostaddr.bge_addr_hi);          CSR_WRITE_4(sc, BGE_RX_STD_RCB_HADDR_HI, rcb->bge_hostaddr.bge_addr_hi);
         CSR_WRITE_4(sc, BGE_RX_STD_RCB_HADDR_LO, rcb->bge_hostaddr.bge_addr_lo);          CSR_WRITE_4(sc, BGE_RX_STD_RCB_HADDR_LO, rcb->bge_hostaddr.bge_addr_lo);
         CSR_WRITE_4(sc, BGE_RX_STD_RCB_MAXLEN_FLAGS, rcb->bge_maxlen_flags);          CSR_WRITE_4(sc, BGE_RX_STD_RCB_MAXLEN_FLAGS, rcb->bge_maxlen_flags);
         CSR_WRITE_4(sc, BGE_RX_STD_RCB_NICADDR, rcb->bge_nicaddr);          CSR_WRITE_4(sc, BGE_RX_STD_RCB_NICADDR, rcb->bge_nicaddr);
   
           /* Reset the standard receive producer ring producer index. */
           bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, 0);
   
           /* 57XX step 42 */
         /*          /*
          * Step 42: Initialize the jumbo RX ring control block           * Initialize the jumbo RX ring control block
          * We set the 'ring disabled' bit in the flags           * We set the 'ring disabled' bit in the flags
          * field until we're actually ready to start           * field until we're actually ready to start
          * using this ring (i.e. once we set the MTU           * using this ring (i.e. once we set the MTU
Line 2053  bge_blockinit(struct bge_softc *sc)
Line 2702  bge_blockinit(struct bge_softc *sc)
                 rcb = &sc->bge_rdata->bge_info.bge_jumbo_rx_rcb;                  rcb = &sc->bge_rdata->bge_info.bge_jumbo_rx_rcb;
                 BGE_HOSTADDR(rcb->bge_hostaddr,                  BGE_HOSTADDR(rcb->bge_hostaddr,
                     BGE_RING_DMA_ADDR(sc, bge_rx_jumbo_ring));                      BGE_RING_DMA_ADDR(sc, bge_rx_jumbo_ring));
                 rcb->bge_maxlen_flags =                  rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(0,
                     BGE_RCB_MAXLEN_FLAGS(BGE_MAX_FRAMELEN,                      BGE_RCB_FLAG_USE_EXT_RX_BD | BGE_RCB_FLAG_RING_DISABLED);
                         BGE_RCB_FLAG_RING_DISABLED);                  if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 ||
                 rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS;                      BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719 ||
                       BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5720)
                           rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS_5717;
                   else
                           rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS;
                 CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_HADDR_HI,                  CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_HADDR_HI,
                     rcb->bge_hostaddr.bge_addr_hi);                      rcb->bge_hostaddr.bge_addr_hi);
                 CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_HADDR_LO,                  CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_HADDR_LO,
                     rcb->bge_hostaddr.bge_addr_lo);                      rcb->bge_hostaddr.bge_addr_lo);
                   /* Program the jumbo receive producer ring RCB parameters. */
                 CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_MAXLEN_FLAGS,                  CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_MAXLEN_FLAGS,
                     rcb->bge_maxlen_flags);                      rcb->bge_maxlen_flags);
                 CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_NICADDR, rcb->bge_nicaddr);                  CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_NICADDR, rcb->bge_nicaddr);
                   /* Reset the jumbo receive producer ring producer index. */
                   bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, 0);
           }
   
           /* 57XX step 43 */
           /* Disable the mini receive producer ring RCB. */
           if (BGE_IS_5700_FAMILY(sc)) {
                 /* Set up dummy disabled mini ring RCB */                  /* Set up dummy disabled mini ring RCB */
                 rcb = &sc->bge_rdata->bge_info.bge_mini_rx_rcb;                  rcb = &sc->bge_rdata->bge_info.bge_mini_rx_rcb;
                 rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(0,                  rcb->bge_maxlen_flags =
                     BGE_RCB_FLAG_RING_DISABLED);                      BGE_RCB_MAXLEN_FLAGS(0, BGE_RCB_FLAG_RING_DISABLED);
                 CSR_WRITE_4(sc, BGE_RX_MINI_RCB_MAXLEN_FLAGS,                  CSR_WRITE_4(sc, BGE_RX_MINI_RCB_MAXLEN_FLAGS,
                     rcb->bge_maxlen_flags);                      rcb->bge_maxlen_flags);
                   /* Reset the mini receive producer ring producer index. */
                   bge_writembx(sc, BGE_MBX_RX_MINI_PROD_LO, 0);
   
                 bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,                  bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
                     offsetof(struct bge_ring_data, bge_info),                      offsetof(struct bge_ring_data, bge_info),
Line 2078  bge_blockinit(struct bge_softc *sc)
Line 2740  bge_blockinit(struct bge_softc *sc)
                     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);                      BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
         }          }
   
         /*          /* Choose de-pipeline mode for BCM5906 A0, A1 and A2. */
           if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906) {
                   if (sc->bge_chipid == BGE_CHIPID_BCM5906_A0 ||
                       sc->bge_chipid == BGE_CHIPID_BCM5906_A1 ||
                       sc->bge_chipid == BGE_CHIPID_BCM5906_A2)
                           CSR_WRITE_4(sc, BGE_ISO_PKT_TX,
                               (CSR_READ_4(sc, BGE_ISO_PKT_TX) & ~3) | 2);
           }
           /* 5718 step 14, 57XX step 44 */
           /*
            * The BD ring replenish thresholds control how often the
            * hardware fetches new BD's from the producer rings in host
            * memory.  Setting the value too low on a busy system can
            * starve the hardware and recue the throughpout.
            *
          * Set the BD ring replenish thresholds. The recommended           * Set the BD ring replenish thresholds. The recommended
          * values are 1/8th the number of descriptors allocated to           * values are 1/8th the number of descriptors allocated to
          * each ring.           * each ring, but since we try to avoid filling the entire
          */           * ring we set these to the minimal value of 8.  This needs to
         i = BGE_STD_RX_RING_CNT / 8;           * be done on several of the supported chip revisions anyway,
            * to work around HW bugs.
         /*  
          * Use a value of 8 for the following chips to workaround HW errata.  
          * Some of these chips have been added based on empirical  
          * evidence (they don't work unless this is done).  
          */           */
         if (BGE_IS_5705_PLUS(sc))          CSR_WRITE_4(sc, BGE_RBDI_STD_REPL_THRESH, 8);
                 i = 8;          if (BGE_IS_JUMBO_CAPABLE(sc))
                   CSR_WRITE_4(sc, BGE_RBDI_JUMBO_REPL_THRESH, 8);
         CSR_WRITE_4(sc, BGE_RBDI_STD_REPL_THRESH, i);  
         CSR_WRITE_4(sc, BGE_RBDI_JUMBO_REPL_THRESH, BGE_JUMBO_RX_RING_CNT / 8);  
   
         if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 ||          /* 5718 step 18 */
             BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57765) {          if (BGE_IS_5717_PLUS(sc)) {
                 CSR_WRITE_4(sc, BGE_STD_REPL_LWM, 4);                  CSR_WRITE_4(sc, BGE_STD_REPL_LWM, 4);
                 CSR_WRITE_4(sc, BGE_JUMBO_REPL_LWM, 4);                  CSR_WRITE_4(sc, BGE_JUMBO_REPL_LWM, 4);
         }          }
   
           /* 57XX step 45 */
         /*          /*
          * Disable all unused send rings by setting the 'ring disabled'           * Disable all send rings by setting the 'ring disabled' bit
          * bit in the flags field of all the TX send ring control blocks.           * in the flags field of all the TX send ring control blocks,
          * These are located in NIC memory.           * located in NIC memory.
          */           */
           if (BGE_IS_5700_FAMILY(sc)) {
                   /* 5700 to 5704 had 16 send rings. */
                   limit = BGE_TX_RINGS_EXTSSRAM_MAX;
           } else if (BGE_IS_5717_PLUS(sc)) {
                   limit = BGE_TX_RINGS_5717_MAX;
           } else if (BGE_IS_57765_FAMILY(sc)) {
                   limit = BGE_TX_RINGS_57765_MAX;
           } else
                   limit = 1;
         rcb_addr = BGE_MEMWIN_START + BGE_SEND_RING_RCB;          rcb_addr = BGE_MEMWIN_START + BGE_SEND_RING_RCB;
         for (i = 0; i < BGE_TX_RINGS_EXTSSRAM_MAX; i++) {          for (i = 0; i < limit; i++) {
                 RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,                  RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,
                     BGE_RCB_MAXLEN_FLAGS(0, BGE_RCB_FLAG_RING_DISABLED));                      BGE_RCB_MAXLEN_FLAGS(0, BGE_RCB_FLAG_RING_DISABLED));
                 RCB_WRITE_4(sc, rcb_addr, bge_nicaddr, 0);                  RCB_WRITE_4(sc, rcb_addr, bge_nicaddr, 0);
                 rcb_addr += sizeof(struct bge_rcb);                  rcb_addr += sizeof(struct bge_rcb);
         }          }
   
         /* Configure TX RCB 0 (we use only the first ring) */          /* 57XX step 46 and 47 */
           /* Configure send ring RCB 0 (we use only the first ring) */
         rcb_addr = BGE_MEMWIN_START + BGE_SEND_RING_RCB;          rcb_addr = BGE_MEMWIN_START + BGE_SEND_RING_RCB;
         BGE_HOSTADDR(taddr, BGE_RING_DMA_ADDR(sc, bge_tx_ring));          BGE_HOSTADDR(taddr, BGE_RING_DMA_ADDR(sc, bge_tx_ring));
         RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_hi, taddr.bge_addr_hi);          RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_hi, taddr.bge_addr_hi);
         RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_lo, taddr.bge_addr_lo);          RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_lo, taddr.bge_addr_lo);
         RCB_WRITE_4(sc, rcb_addr, bge_nicaddr,          if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 ||
               BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719 ||
               BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5720)
                   RCB_WRITE_4(sc, rcb_addr, bge_nicaddr, BGE_SEND_RING_5717);
           else
                   RCB_WRITE_4(sc, rcb_addr, bge_nicaddr,
                     BGE_NIC_TXRING_ADDR(0, BGE_TX_RING_CNT));                      BGE_NIC_TXRING_ADDR(0, BGE_TX_RING_CNT));
         if (BGE_IS_5700_FAMILY(sc))          RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,
                 RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,              BGE_RCB_MAXLEN_FLAGS(BGE_TX_RING_CNT, 0));
                     BGE_RCB_MAXLEN_FLAGS(BGE_TX_RING_CNT, 0));  
   
         /* Disable all unused RX return rings */          /* 57XX step 48 */
           /*
            * Disable all receive return rings by setting the
            * 'ring diabled' bit in the flags field of all the receive
            * return ring control blocks, located in NIC memory.
            */
           if (BGE_IS_5717_PLUS(sc)) {
                   /* Should be 17, use 16 until we get an SRAM map. */
                   limit = 16;
           } else if (BGE_IS_5700_FAMILY(sc))
                   limit = BGE_RX_RINGS_MAX;
           else if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755 ||
               BGE_IS_57765_FAMILY(sc))
                   limit = 4;
           else
                   limit = 1;
           /* Disable all receive return rings */
         rcb_addr = BGE_MEMWIN_START + BGE_RX_RETURN_RING_RCB;          rcb_addr = BGE_MEMWIN_START + BGE_RX_RETURN_RING_RCB;
         for (i = 0; i < BGE_RX_RINGS_MAX; i++) {          for (i = 0; i < limit; i++) {
                 RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_hi, 0);                  RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_hi, 0);
                 RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_lo, 0);                  RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_lo, 0);
                 RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,                  RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,
Line 2140  bge_blockinit(struct bge_softc *sc)
Line 2841  bge_blockinit(struct bge_softc *sc)
                 rcb_addr += sizeof(struct bge_rcb);                  rcb_addr += sizeof(struct bge_rcb);
         }          }
   
         /* Initialize RX ring indexes */          /* 57XX step 49 */
         bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, 0);  
         bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, 0);  
         bge_writembx(sc, BGE_MBX_RX_MINI_PROD_LO, 0);  
   
         /*          /*
          * Set up RX return ring 0           * Set up receive return ring 0.  Note that the NIC address
          * Note that the NIC address for RX return rings is 0x00000000.           * for RX return rings is 0x0.  The return rings live entirely
          * The return rings live entirely within the host, so the           * within the host, so the nicaddr field in the RCB isn't used.
          * nicaddr field in the RCB isn't used.  
          */           */
         rcb_addr = BGE_MEMWIN_START + BGE_RX_RETURN_RING_RCB;          rcb_addr = BGE_MEMWIN_START + BGE_RX_RETURN_RING_RCB;
         BGE_HOSTADDR(taddr, BGE_RING_DMA_ADDR(sc, bge_rx_return_ring));          BGE_HOSTADDR(taddr, BGE_RING_DMA_ADDR(sc, bge_rx_return_ring));
Line 2159  bge_blockinit(struct bge_softc *sc)
Line 2855  bge_blockinit(struct bge_softc *sc)
         RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,          RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,
             BGE_RCB_MAXLEN_FLAGS(sc->bge_return_ring_cnt, 0));              BGE_RCB_MAXLEN_FLAGS(sc->bge_return_ring_cnt, 0));
   
           /* 5718 step 24, 57XX step 53 */
         /* Set random backoff seed for TX */          /* Set random backoff seed for TX */
         CSR_WRITE_4(sc, BGE_TX_RANDOM_BACKOFF,          CSR_WRITE_4(sc, BGE_TX_RANDOM_BACKOFF,
             CLLADDR(ifp->if_sadl)[0] + CLLADDR(ifp->if_sadl)[1] +              (CLLADDR(ifp->if_sadl)[0] + CLLADDR(ifp->if_sadl)[1] +
             CLLADDR(ifp->if_sadl)[2] + CLLADDR(ifp->if_sadl)[3] +                  CLLADDR(ifp->if_sadl)[2] + CLLADDR(ifp->if_sadl)[3] +
             CLLADDR(ifp->if_sadl)[4] + CLLADDR(ifp->if_sadl)[5] +                  CLLADDR(ifp->if_sadl)[4] + CLLADDR(ifp->if_sadl)[5]) &
             BGE_TX_BACKOFF_SEED_MASK);              BGE_TX_BACKOFF_SEED_MASK);
   
           /* 5718 step 26, 57XX step 55 */
         /* Set inter-packet gap */          /* Set inter-packet gap */
         CSR_WRITE_4(sc, BGE_TX_LENGTHS, 0x2620);          val = 0x2620;
           if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5720)
                   val |= CSR_READ_4(sc, BGE_TX_LENGTHS) &
                       (BGE_TXLEN_JMB_FRM_LEN_MSK | BGE_TXLEN_CNT_DN_VAL_MSK);
           CSR_WRITE_4(sc, BGE_TX_LENGTHS, val);
   
           /* 5718 step 27, 57XX step 56 */
         /*          /*
          * Specify which ring to use for packets that don't match           * Specify which ring to use for packets that don't match
          * any RX rules.           * any RX rules.
          */           */
         CSR_WRITE_4(sc, BGE_RX_RULES_CFG, 0x08);          CSR_WRITE_4(sc, BGE_RX_RULES_CFG, 0x08);
   
           /* 5718 step 28, 57XX step 57 */
         /*          /*
          * Configure number of RX lists. One interrupt distribution           * Configure number of RX lists. One interrupt distribution
          * list, sixteen active lists, one bad frames class.           * list, sixteen active lists, one bad frames class.
          */           */
         CSR_WRITE_4(sc, BGE_RXLP_CFG, 0x181);          CSR_WRITE_4(sc, BGE_RXLP_CFG, 0x181);
   
           /* 5718 step 29, 57XX step 58 */
         /* Inialize RX list placement stats mask. */          /* Inialize RX list placement stats mask. */
         CSR_WRITE_4(sc, BGE_RXLP_STATS_ENABLE_MASK, 0x007FFFFF);          if (BGE_IS_575X_PLUS(sc)) {
                   val = CSR_READ_4(sc, BGE_RXLP_STATS_ENABLE_MASK);
                   val &= ~BGE_RXLPSTATCONTROL_DACK_FIX;
                   CSR_WRITE_4(sc, BGE_RXLP_STATS_ENABLE_MASK, val);
           } else
                   CSR_WRITE_4(sc, BGE_RXLP_STATS_ENABLE_MASK, 0x007FFFFF);
   
           /* 5718 step 30, 57XX step 59 */
         CSR_WRITE_4(sc, BGE_RXLP_STATS_CTL, 0x1);          CSR_WRITE_4(sc, BGE_RXLP_STATS_CTL, 0x1);
   
           /* 5718 step 33, 57XX step 62 */
         /* Disable host coalescing until we get it set up */          /* Disable host coalescing until we get it set up */
         CSR_WRITE_4(sc, BGE_HCC_MODE, 0x00000000);          CSR_WRITE_4(sc, BGE_HCC_MODE, 0x00000000);
   
           /* 5718 step 34, 57XX step 63 */
         /* Poll to make sure it's shut down. */          /* Poll to make sure it's shut down. */
         for (i = 0; i < BGE_TIMEOUT * 2; i++) {          for (i = 0; i < BGE_TIMEOUT * 2; i++) {
                   DELAY(10);
                 if (!(CSR_READ_4(sc, BGE_HCC_MODE) & BGE_HCCMODE_ENABLE))                  if (!(CSR_READ_4(sc, BGE_HCC_MODE) & BGE_HCCMODE_ENABLE))
                         break;                          break;
                 DELAY(10);  
         }          }
   
         if (i == BGE_TIMEOUT * 2) {          if (i == BGE_TIMEOUT * 2) {
Line 2201  bge_blockinit(struct bge_softc *sc)
Line 2915  bge_blockinit(struct bge_softc *sc)
                 return ENXIO;                  return ENXIO;
         }          }
   
           /* 5718 step 35, 36, 37 */
         /* Set up host coalescing defaults */          /* Set up host coalescing defaults */
         CSR_WRITE_4(sc, BGE_HCC_RX_COAL_TICKS, sc->bge_rx_coal_ticks);          CSR_WRITE_4(sc, BGE_HCC_RX_COAL_TICKS, sc->bge_rx_coal_ticks);
         CSR_WRITE_4(sc, BGE_HCC_TX_COAL_TICKS, sc->bge_tx_coal_ticks);          CSR_WRITE_4(sc, BGE_HCC_TX_COAL_TICKS, sc->bge_tx_coal_ticks);
         CSR_WRITE_4(sc, BGE_HCC_RX_MAX_COAL_BDS, sc->bge_rx_max_coal_bds);          CSR_WRITE_4(sc, BGE_HCC_RX_MAX_COAL_BDS, sc->bge_rx_max_coal_bds);
         CSR_WRITE_4(sc, BGE_HCC_TX_MAX_COAL_BDS, sc->bge_tx_max_coal_bds);          CSR_WRITE_4(sc, BGE_HCC_TX_MAX_COAL_BDS, sc->bge_tx_max_coal_bds);
         if (BGE_IS_5700_FAMILY(sc)) {          if (!(BGE_IS_5705_PLUS(sc))) {
                 CSR_WRITE_4(sc, BGE_HCC_RX_COAL_TICKS_INT, 0);                  CSR_WRITE_4(sc, BGE_HCC_RX_COAL_TICKS_INT, 0);
                 CSR_WRITE_4(sc, BGE_HCC_TX_COAL_TICKS_INT, 0);                  CSR_WRITE_4(sc, BGE_HCC_TX_COAL_TICKS_INT, 0);
         }          }
Line 2222  bge_blockinit(struct bge_softc *sc)
Line 2937  bge_blockinit(struct bge_softc *sc)
                 CSR_WRITE_4(sc, BGE_HCC_STATS_ADDR_LO, taddr.bge_addr_lo);                  CSR_WRITE_4(sc, BGE_HCC_STATS_ADDR_LO, taddr.bge_addr_lo);
         }          }
   
           /* 5718 step 38 */
         /* Set up address of status block */          /* Set up address of status block */
         BGE_HOSTADDR(taddr, BGE_RING_DMA_ADDR(sc, bge_status_block));          BGE_HOSTADDR(taddr, BGE_RING_DMA_ADDR(sc, bge_status_block));
         CSR_WRITE_4(sc, BGE_HCC_STATUSBLK_BASEADDR, BGE_STATUS_BLOCK);          CSR_WRITE_4(sc, BGE_HCC_STATUSBLK_BASEADDR, BGE_STATUS_BLOCK);
Line 2230  bge_blockinit(struct bge_softc *sc)
Line 2946  bge_blockinit(struct bge_softc *sc)
         sc->bge_rdata->bge_status_block.bge_idx[0].bge_rx_prod_idx = 0;          sc->bge_rdata->bge_status_block.bge_idx[0].bge_rx_prod_idx = 0;
         sc->bge_rdata->bge_status_block.bge_idx[0].bge_tx_cons_idx = 0;          sc->bge_rdata->bge_status_block.bge_idx[0].bge_tx_cons_idx = 0;
   
           /* Set up status block size. */
           if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700 &&
               sc->bge_chipid != BGE_CHIPID_BCM5700_C0) {
                   val = BGE_STATBLKSZ_FULL;
                   bzero(&sc->bge_rdata->bge_status_block, BGE_STATUS_BLK_SZ);
           } else {
                   val = BGE_STATBLKSZ_32BYTE;
                   bzero(&sc->bge_rdata->bge_status_block, 32);
           }
   
           /* 5718 step 39, 57XX step 73 */
         /* Turn on host coalescing state machine */          /* Turn on host coalescing state machine */
         CSR_WRITE_4(sc, BGE_HCC_MODE, BGE_HCCMODE_ENABLE);          CSR_WRITE_4(sc, BGE_HCC_MODE, val | BGE_HCCMODE_ENABLE);
   
           /* 5718 step 40, 57XX step 74 */
         /* Turn on RX BD completion state machine and enable attentions */          /* Turn on RX BD completion state machine and enable attentions */
         CSR_WRITE_4(sc, BGE_RBDC_MODE,          CSR_WRITE_4(sc, BGE_RBDC_MODE,
             BGE_RBDCMODE_ENABLE | BGE_RBDCMODE_ATTN);              BGE_RBDCMODE_ENABLE | BGE_RBDCMODE_ATTN);
   
           /* 5718 step 41, 57XX step 75 */
         /* Turn on RX list placement state machine */          /* Turn on RX list placement state machine */
         CSR_WRITE_4(sc, BGE_RXLP_MODE, BGE_RXLPMODE_ENABLE);          CSR_WRITE_4(sc, BGE_RXLP_MODE, BGE_RXLPMODE_ENABLE);
   
           /* 57XX step 76 */
         /* Turn on RX list selector state machine. */          /* Turn on RX list selector state machine. */
         if (BGE_IS_5700_FAMILY(sc))          if (!(BGE_IS_5705_PLUS(sc)))
                 CSR_WRITE_4(sc, BGE_RXLS_MODE, BGE_RXLSMODE_ENABLE);                  CSR_WRITE_4(sc, BGE_RXLS_MODE, BGE_RXLSMODE_ENABLE);
   
         val = BGE_MACMODE_TXDMA_ENB | BGE_MACMODE_RXDMA_ENB |          val = BGE_MACMODE_TXDMA_ENB | BGE_MACMODE_RXDMA_ENB |
Line 2256  bge_blockinit(struct bge_softc *sc)
Line 2986  bge_blockinit(struct bge_softc *sc)
         else          else
                 val |= BGE_PORTMODE_MII;                  val |= BGE_PORTMODE_MII;
   
           /* 5718 step 42 and 43, 57XX step 77 and 78 */
           /* Allow APE to send/receive frames. */
           if ((sc->bge_mfw_flags & BGE_MFW_ON_APE) != 0)
                   val |= BGE_MACMODE_APE_RX_EN | BGE_MACMODE_APE_TX_EN;
   
         /* Turn on DMA, clear stats */          /* Turn on DMA, clear stats */
         CSR_WRITE_4(sc, BGE_MAC_MODE, val);          CSR_WRITE_4_FLUSH(sc, BGE_MAC_MODE, val);
           /* 5718 step 44 */
           DELAY(40);
   
           /* 5718 step 45, 57XX step 79 */
         /* Set misc. local control, enable interrupts on attentions */          /* Set misc. local control, enable interrupts on attentions */
         sc->bge_local_ctrl_reg = BGE_MLC_INTR_ONATTN | BGE_MLC_AUTO_EEPROM;          BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_INTR_ONATTN);
           if (BGE_IS_5717_PLUS(sc)) {
 #ifdef notdef                  CSR_READ_4(sc, BGE_MISC_LOCAL_CTL); /* Flush */
         /* Assert GPIO pins for PHY reset */                  /* 5718 step 46 */
         BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_MISCIO_OUT0|                  DELAY(100);
             BGE_MLC_MISCIO_OUT1|BGE_MLC_MISCIO_OUT2);  
         BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_MISCIO_OUTEN0|  
             BGE_MLC_MISCIO_OUTEN1|BGE_MLC_MISCIO_OUTEN2);  
 #endif  
   
 #if defined(not_quite_yet)  
         /* Linux driver enables enable gpio pin #1 on 5700s */  
         if (sc->bge_chipid == BGE_CHIPID_BCM5700) {  
                 sc->bge_local_ctrl_reg |=  
                   (BGE_MLC_MISCIO_OUT1|BGE_MLC_MISCIO_OUTEN1);  
         }          }
 #endif  
         CSR_WRITE_4(sc, BGE_MISC_LOCAL_CTL, sc->bge_local_ctrl_reg);  
   
           /* 57XX step 81 */
         /* Turn on DMA completion state machine */          /* Turn on DMA completion state machine */
         if (BGE_IS_5700_FAMILY(sc))          if (!(BGE_IS_5705_PLUS(sc)))
                 CSR_WRITE_4(sc, BGE_DMAC_MODE, BGE_DMACMODE_ENABLE);                  CSR_WRITE_4(sc, BGE_DMAC_MODE, BGE_DMACMODE_ENABLE);
   
           /* 5718 step 47, 57XX step 82 */
           val = BGE_WDMAMODE_ENABLE | BGE_WDMAMODE_ALL_ATTNS;
   
           /* 5718 step 48 */
           /* Enable host coalescing bug fix. */
           if (BGE_IS_5755_PLUS(sc))
                   val |= BGE_WDMAMODE_STATUS_TAG_FIX;
   
           if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5785)
                   val |= BGE_WDMAMODE_BURST_ALL_DATA;
   
         /* Turn on write DMA state machine */          /* Turn on write DMA state machine */
         {          CSR_WRITE_4_FLUSH(sc, BGE_WDMA_MODE, val);
                 uint32_t bge_wdma_mode =          /* 5718 step 49 */
                         BGE_WDMAMODE_ENABLE|BGE_WDMAMODE_ALL_ATTNS;          DELAY(40);
   
                 /* Enable host coalescing bug fix; see Linux tg3.c */  
                 if (BGE_IS_5755_PLUS(sc))  
                         bge_wdma_mode |= BGE_WDMAMODE_STATUS_TAG_FIX;  
   
                 CSR_WRITE_4(sc, BGE_WDMA_MODE, bge_wdma_mode);          val = BGE_RDMAMODE_ENABLE | BGE_RDMAMODE_ALL_ATTNS;
         }  
   
         /* Turn on read DMA state machine */          if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717)
         {                  val |= BGE_RDMAMODE_MULT_DMA_RD_DIS;
                 uint32_t dma_read_modebits;  
   
                 dma_read_modebits =          if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5784 ||
                   BGE_RDMAMODE_ENABLE | BGE_RDMAMODE_ALL_ATTNS;              BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5785 ||
               BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57780)
                   val |= BGE_RDMAMODE_BD_SBD_CRPT_ATTN |
                       BGE_RDMAMODE_MBUF_RBD_CRPT_ATTN |
                       BGE_RDMAMODE_MBUF_SBD_CRPT_ATTN;
   
                 if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5784 ||          if (sc->bge_flags & BGE_PCIE)
                     BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5785 ||                  val |= BGE_RDMAMODE_FIFO_LONG_BURST;
                     BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57780)          if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57766) {
                         dma_read_modebits |= BGE_RDMAMODE_BD_SBD_CRPT_ATTN |                  if (ifp->if_mtu <= ETHERMTU)
                             BGE_RDMAMODE_MBUF_RBD_CRPT_ATTN |                          val |= BGE_RDMAMODE_JMB_2K_MMRR;
                             BGE_RDMAMODE_MBUF_SBD_CRPT_ATTN;          }
           if (sc->bge_flags & BGE_TSO)
                   val |= BGE_RDMAMODE_TSO4_ENABLE;
   
                 if (sc->bge_flags & BGE_PCIE)          if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5720) {
                         dma_read_modebits |= BGE_RDMA_MODE_FIFO_LONG_BURST;                  val |= CSR_READ_4(sc, BGE_RDMA_MODE) &
                 if (sc->bge_flags & BGE_TSO)                      BGE_RDMAMODE_H2BNC_VLAN_DET;
                         dma_read_modebits |= BGE_RDMAMODE_TSO4_ENABLE;                  /*
                 CSR_WRITE_4(sc, BGE_RDMA_MODE, dma_read_modebits);                   * Allow multiple outstanding read requests from
                 delay(40);                   * non-LSO read DMA engine.
                    */
                   val &= ~BGE_RDMAMODE_MULT_DMA_RD_DIS;
           }
   
           if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5761 ||
               BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5784 ||
               BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5785 ||
               BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57780 ||
               BGE_IS_57765_PLUS(sc)) {
                   dmactl = CSR_READ_4(sc, BGE_RDMA_RSRVCTRL);
                   /*
                    * Adjust tx margin to prevent TX data corruption and
                    * fix internal FIFO overflow.
                    */
                   if (sc->bge_chipid == BGE_CHIPID_BCM5719_A0) {
                           dmactl &= ~(BGE_RDMA_RSRVCTRL_FIFO_LWM_MASK |
                               BGE_RDMA_RSRVCTRL_FIFO_HWM_MASK |
                               BGE_RDMA_RSRVCTRL_TXMRGN_MASK);
                           dmactl |= BGE_RDMA_RSRVCTRL_FIFO_LWM_1_5K |
                               BGE_RDMA_RSRVCTRL_FIFO_HWM_1_5K |
                               BGE_RDMA_RSRVCTRL_TXMRGN_320B;
                   }
                   /*
                    * Enable fix for read DMA FIFO overruns.
                    * The fix is to limit the number of RX BDs
                    * the hardware would fetch at a fime.
                    */
                   CSR_WRITE_4(sc, BGE_RDMA_RSRVCTRL, dmactl |
                       BGE_RDMA_RSRVCTRL_FIFO_OFLW_FIX);
           }
   
           if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719) {
                   CSR_WRITE_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL,
                       CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL) |
                       BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K |
                       BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K);
           } else if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5720) {
                   /*
                    * Allow 4KB burst length reads for non-LSO frames.
                    * Enable 512B burst length reads for buffer descriptors.
                    */
                   CSR_WRITE_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL,
                       CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL) |
                       BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_512 |
                       BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K);
         }          }
   
           /* Turn on read DMA state machine */
           CSR_WRITE_4_FLUSH(sc, BGE_RDMA_MODE, val);
           /* 5718 step 52 */
           delay(40);
   
           /* 5718 step 56, 57XX step 84 */
         /* Turn on RX data completion state machine */          /* Turn on RX data completion state machine */
         CSR_WRITE_4(sc, BGE_RDC_MODE, BGE_RDCMODE_ENABLE);          CSR_WRITE_4(sc, BGE_RDC_MODE, BGE_RDCMODE_ENABLE);
   
         /* Turn on RX BD initiator state machine */  
         CSR_WRITE_4(sc, BGE_RBDI_MODE, BGE_RBDIMODE_ENABLE);  
   
         /* Turn on RX data and RX BD initiator state machine */          /* Turn on RX data and RX BD initiator state machine */
         CSR_WRITE_4(sc, BGE_RDBDI_MODE, BGE_RDBDIMODE_ENABLE);          CSR_WRITE_4(sc, BGE_RDBDI_MODE, BGE_RDBDIMODE_ENABLE);
   
           /* 57XX step 85 */
         /* Turn on Mbuf cluster free state machine */          /* Turn on Mbuf cluster free state machine */
         if (BGE_IS_5700_FAMILY(sc))          if (!BGE_IS_5705_PLUS(sc))
                 CSR_WRITE_4(sc, BGE_MBCF_MODE, BGE_MBCFMODE_ENABLE);                  CSR_WRITE_4(sc, BGE_MBCF_MODE, BGE_MBCFMODE_ENABLE);
   
         /* Turn on send BD completion state machine */          /* 5718 step 57, 57XX step 86 */
         CSR_WRITE_4(sc, BGE_SBDC_MODE, BGE_SBDCMODE_ENABLE);  
   
         /* Turn on send data completion state machine */          /* Turn on send data completion state machine */
         val = BGE_SDCMODE_ENABLE;          val = BGE_SDCMODE_ENABLE;
         if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5761)          if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5761)
                 val |= BGE_SDCMODE_CDELAY;                  val |= BGE_SDCMODE_CDELAY;
         CSR_WRITE_4(sc, BGE_SDC_MODE, val);          CSR_WRITE_4(sc, BGE_SDC_MODE, val);
   
           /* 5718 step 58 */
           /* Turn on send BD completion state machine */
           CSR_WRITE_4(sc, BGE_SBDC_MODE, BGE_SBDCMODE_ENABLE);
   
           /* 57XX step 88 */
           /* Turn on RX BD initiator state machine */
           CSR_WRITE_4(sc, BGE_RBDI_MODE, BGE_RBDIMODE_ENABLE);
   
           /* 5718 step 60, 57XX step 90 */
         /* Turn on send data initiator state machine */          /* Turn on send data initiator state machine */
         if (sc->bge_flags & BGE_TSO) {          if (sc->bge_flags & BGE_TSO) {
                 /* XXX: magic value from Linux driver */                  /* XXX: magic value from Linux driver */
                 CSR_WRITE_4(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE | 0x08);                  CSR_WRITE_4(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE |
                       BGE_SDIMODE_HW_LSO_PRE_DMA);
         } else          } else
                 CSR_WRITE_4(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE);                  CSR_WRITE_4(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE);
   
           /* 5718 step 61, 57XX step 91 */
         /* Turn on send BD initiator state machine */          /* Turn on send BD initiator state machine */
         CSR_WRITE_4(sc, BGE_SBDI_MODE, BGE_SBDIMODE_ENABLE);          CSR_WRITE_4(sc, BGE_SBDI_MODE, BGE_SBDIMODE_ENABLE);
   
           /* 5718 step 62, 57XX step 92 */
         /* Turn on send BD selector state machine */          /* Turn on send BD selector state machine */
         CSR_WRITE_4(sc, BGE_SRS_MODE, BGE_SRSMODE_ENABLE);          CSR_WRITE_4(sc, BGE_SRS_MODE, BGE_SRSMODE_ENABLE);
   
           /* 5718 step 31, 57XX step 60 */
         CSR_WRITE_4(sc, BGE_SDI_STATS_ENABLE_MASK, 0x007FFFFF);          CSR_WRITE_4(sc, BGE_SDI_STATS_ENABLE_MASK, 0x007FFFFF);
           /* 5718 step 32, 57XX step 61 */
         CSR_WRITE_4(sc, BGE_SDI_STATS_CTL,          CSR_WRITE_4(sc, BGE_SDI_STATS_CTL,
             BGE_SDISTATSCTL_ENABLE | BGE_SDISTATSCTL_FASTER);              BGE_SDISTATSCTL_ENABLE | BGE_SDISTATSCTL_FASTER);
   
Line 2362  bge_blockinit(struct bge_softc *sc)
Line 3161  bge_blockinit(struct bge_softc *sc)
             BGE_MACSTAT_LINK_CHANGED);              BGE_MACSTAT_LINK_CHANGED);
         CSR_WRITE_4(sc, BGE_MI_STS, 0);          CSR_WRITE_4(sc, BGE_MI_STS, 0);
   
         /* Enable PHY auto polling (for MII/GMII only) */          /*
            * Enable attention when the link has changed state for
            * devices that use auto polling.
            */
         if (sc->bge_flags & BGE_PHY_FIBER_TBI) {          if (sc->bge_flags & BGE_PHY_FIBER_TBI) {
                 CSR_WRITE_4(sc, BGE_MI_STS, BGE_MISTS_LINK);                  CSR_WRITE_4(sc, BGE_MI_STS, BGE_MISTS_LINK);
         } else {          } else {
                   /* 5718 step 68 */
                 BGE_STS_SETBIT(sc, BGE_STS_AUTOPOLL);                  BGE_STS_SETBIT(sc, BGE_STS_AUTOPOLL);
                   /* 5718 step 69 (optionally) */
                 BGE_SETBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL | (10 << 16));                  BGE_SETBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL | (10 << 16));
                 if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700)                  if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700)
                         CSR_WRITE_4(sc, BGE_MAC_EVT_ENB,                          CSR_WRITE_4(sc, BGE_MAC_EVT_ENB,
Line 2422  bge_lookup(const struct pci_attach_args 
Line 3226  bge_lookup(const struct pci_attach_args 
         return NULL;          return NULL;
 }  }
   
 static int  static uint32_t
 bge_setpowerstate(struct bge_softc *sc, int powerlevel)  bge_chipid(const struct pci_attach_args *pa)
 {  {
 #ifdef NOTYET          uint32_t id;
         uint32_t pm_ctl = 0;  
   
         /* XXX FIXME: make sure indirect accesses enabled? */          id = pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_MISC_CTL)
         pm_ctl = pci_conf_read(sc->bge_dev, BGE_PCI_MISC_CTL, 4);                  >> BGE_PCIMISCCTL_ASICREV_SHIFT;
         pm_ctl |= BGE_PCIMISCCTL_INDIRECT_ACCESS;  
         pci_write_config(sc->bge_dev, BGE_PCI_MISC_CTL, pm_ctl, 4);  
   
         /* clear the PME_assert bit and power state bits, enable PME */  
         pm_ctl = pci_conf_read(sc->bge_dev, BGE_PCI_PWRMGMT_CMD, 2);  
         pm_ctl &= ~PCIM_PSTAT_DMASK;  
         pm_ctl |= (1 << 8);  
   
         if (powerlevel == 0) {  
                 pm_ctl |= PCIM_PSTAT_D0;  
                 pci_write_config(sc->bge_dev, BGE_PCI_PWRMGMT_CMD,  
                     pm_ctl, 2);  
                 DELAY(10000);  
                 CSR_WRITE_4(sc, BGE_MISC_LOCAL_CTL, sc->bge_local_ctrl_reg);  
                 DELAY(10000);  
   
 #ifdef NOTYET          if (BGE_ASICREV(id) == BGE_ASICREV_USE_PRODID_REG) {
                 /* XXX FIXME: write 0x02 to phy aux_Ctrl reg */                  switch (PCI_PRODUCT(pa->pa_id)) {
                 bge_miibus_writereg(sc->bge_dev, 1, 0x18, 0x02);                  case PCI_PRODUCT_BROADCOM_BCM5717:
 #endif                  case PCI_PRODUCT_BROADCOM_BCM5718:
                 DELAY(40); DELAY(40); DELAY(40);                  case PCI_PRODUCT_BROADCOM_BCM5719:
                 DELAY(10000);   /* above not quite adequate on 5700 */                  case PCI_PRODUCT_BROADCOM_BCM5720:
                 return 0;                  case PCI_PRODUCT_BROADCOM_BCM5724: /* ??? */
                           id = pci_conf_read(pa->pa_pc, pa->pa_tag,
                               BGE_PCI_GEN2_PRODID_ASICREV);
                           break;
                   case PCI_PRODUCT_BROADCOM_BCM57761:
                   case PCI_PRODUCT_BROADCOM_BCM57762:
                   case PCI_PRODUCT_BROADCOM_BCM57765:
                   case PCI_PRODUCT_BROADCOM_BCM57766:
                   case PCI_PRODUCT_BROADCOM_BCM57781:
                   case PCI_PRODUCT_BROADCOM_BCM57785:
                   case PCI_PRODUCT_BROADCOM_BCM57791:
                   case PCI_PRODUCT_BROADCOM_BCM57795:
                           id = pci_conf_read(pa->pa_pc, pa->pa_tag,
                               BGE_PCI_GEN15_PRODID_ASICREV);
                           break;
                   default:
                           id = pci_conf_read(pa->pa_pc, pa->pa_tag,
                               BGE_PCI_PRODID_ASICREV);
                           break;
                   }
         }          }
   
           return id;
         /*  
          * Entering ACPI power states D1-D3 is achieved by wiggling  
          * GMII gpio pins. Example code assumes all hardware vendors  
          * followed Broadcom's sample pcb layout. Until we verify that  
          * for all supported OEM cards, states D1-D3 are  unsupported.  
          */  
         aprint_error_dev(sc->bge_dev,  
             "power state %d unimplemented; check GPIO pins\n",  
             powerlevel);  
 #endif  
         return EOPNOTSUPP;  
 }  }
   
   
 /*  /*
  * Probe for a Broadcom chip. Check the PCI vendor and device IDs   * Probe for a Broadcom chip. Check the PCI vendor and device IDs
  * against our list and return its name if we find a match. Note   * against our list and return its name if we find a match. Note
Line 2500  bge_attach(device_t parent, device_t sel
Line 3295  bge_attach(device_t parent, device_t sel
         pci_chipset_tag_t       pc;          pci_chipset_tag_t       pc;
         pci_intr_handle_t       ih;          pci_intr_handle_t       ih;
         const char              *intrstr = NULL;          const char              *intrstr = NULL;
         bus_dma_segment_t       seg;          uint32_t                hwcfg, hwcfg2, hwcfg3, hwcfg4;
         int                     rseg;  
         uint32_t                hwcfg = 0;  
         uint32_t                command;          uint32_t                command;
         struct ifnet            *ifp;          struct ifnet            *ifp;
         uint32_t                misccfg;          uint32_t                misccfg, mimode;
         void *                  kva;          void *                  kva;
         u_char                  eaddr[ETHER_ADDR_LEN];          u_char                  eaddr[ETHER_ADDR_LEN];
         pcireg_t                memtype, subid;          pcireg_t                memtype, subid, reg;
         bus_addr_t              memaddr;          bus_addr_t              memaddr;
         bus_size_t              memsize;  
         uint32_t                pm_ctl;          uint32_t                pm_ctl;
         bool                    no_seeprom;          bool                    no_seeprom;
           int                     capmask;
   
         bp = bge_lookup(pa);          bp = bge_lookup(pa);
         KASSERT(bp != NULL);          KASSERT(bp != NULL);
Line 2521  bge_attach(device_t parent, device_t sel
Line 3314  bge_attach(device_t parent, device_t sel
         sc->sc_pcitag = pa->pa_tag;          sc->sc_pcitag = pa->pa_tag;
         sc->bge_dev = self;          sc->bge_dev = self;
   
           sc->bge_pa = *pa;
         pc = sc->sc_pc;          pc = sc->sc_pc;
         subid = pci_conf_read(pc, sc->sc_pcitag, PCI_SUBSYS_ID_REG);          subid = pci_conf_read(pc, sc->sc_pcitag, PCI_SUBSYS_ID_REG);
   
Line 2549  bge_attach(device_t parent, device_t sel
Line 3343  bge_attach(device_t parent, device_t sel
         case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:          case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
                 if (pci_mapreg_map(pa, BGE_PCI_BAR0,                  if (pci_mapreg_map(pa, BGE_PCI_BAR0,
                     memtype, 0, &sc->bge_btag, &sc->bge_bhandle,                      memtype, 0, &sc->bge_btag, &sc->bge_bhandle,
                     &memaddr, &memsize) == 0)                      &memaddr, &sc->bge_bsize) == 0)
                         break;                          break;
         default:          default:
                 aprint_error_dev(sc->bge_dev, "can't find mem space\n");                  aprint_error_dev(sc->bge_dev, "can't find mem space\n");
Line 2571  bge_attach(device_t parent, device_t sel
Line 3365  bge_attach(device_t parent, device_t sel
         if (sc->bge_intrhand == NULL) {          if (sc->bge_intrhand == NULL) {
                 aprint_error_dev(sc->bge_dev,                  aprint_error_dev(sc->bge_dev,
                     "couldn't establish interrupt%s%s\n",                      "couldn't establish interrupt%s%s\n",
                     intrstr ? " at " : "", intrstr ? intrstr : "");                      intrstr ? " at " : "", intrstr ? intrstr : "");
                 return;                  return;
         }  
         aprint_normal_dev(sc->bge_dev, "interrupting at %s\n", intrstr);  
   
         /*  
          * Kludge for 5700 Bx bug: a hardware bug (PCIX byte enable?)  
          * can clobber the chip's PCI config-space power control registers,  
          * leaving the card in D3 powersave state.  
          * We do not have memory-mapped registers in this state,  
          * so force device into D0 state before starting initialization.  
          */  
         pm_ctl = pci_conf_read(pc, sc->sc_pcitag, BGE_PCI_PWRMGMT_CMD);  
         pm_ctl &= ~(PCI_PWR_D0|PCI_PWR_D1|PCI_PWR_D2|PCI_PWR_D3);  
         pm_ctl |= (1 << 8) | PCI_PWR_D0 ; /* D0 state */  
         pci_conf_write(pc, sc->sc_pcitag, BGE_PCI_PWRMGMT_CMD, pm_ctl);  
         DELAY(1000);    /* 27 usec is allegedly sufficent */  
   
         /*  
          * Save ASIC rev.  
          */  
         sc->bge_chipid =  
             pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_MISC_CTL)  
                 >> BGE_PCIMISCCTL_ASICREV_SHIFT;  
   
         if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_USE_PRODID_REG) {  
                 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5717 ||  
                     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5718 ||  
                     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5724)  
                         sc->bge_chipid = pci_conf_read(pc, pa->pa_tag,  
                             BGE_PCI_GEN2_PRODID_ASICREV);  
                 else if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM57761 ||  
                          PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM57765 ||  
                          PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM57781 ||  
                          PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM57785 ||  
                          PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM57791 ||  
                          PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM57795)  
                         sc->bge_chipid = pci_conf_read(pc, pa->pa_tag,  
                             BGE_PCI_GEN15_PRODID_ASICREV);  
                 else  
                         sc->bge_chipid = pci_conf_read(pc, pa->pa_tag,  
                             BGE_PCI_PRODID_ASICREV);  
         }          }
           aprint_normal_dev(sc->bge_dev, "interrupting at %s\n", intrstr);
   
           /* Save various chip information. */
           sc->bge_chipid = bge_chipid(pa);
           sc->bge_phy_addr = bge_phy_addr(sc);
   
         if ((pci_get_capability(sc->sc_pc, sc->sc_pcitag, PCI_CAP_PCIEXPRESS,          if ((pci_get_capability(sc->sc_pc, sc->sc_pcitag, PCI_CAP_PCIEXPRESS,
                 &sc->bge_pciecap, NULL) != 0)                  &sc->bge_pciecap, NULL) != 0)
             || (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5785)) {              || (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5785)) {
                 /* PCIe */                  /* PCIe */
                 sc->bge_flags |= BGE_PCIE;                  sc->bge_flags |= BGE_PCIE;
                   /* Extract supported maximum payload size. */
                   reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
                       sc->bge_pciecap + PCI_PCIE_DCAP);
                   sc->bge_mps = 128 << (reg & PCI_PCIE_DCAP_MAX_PAYLOAD);
                   if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719 ||
                       BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5720)
                           sc->bge_expmrq = 2048;
                   else
                           sc->bge_expmrq = 4096;
                 bge_set_max_readrq(sc);                  bge_set_max_readrq(sc);
         } else if ((pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_PCISTATE) &          } else if ((pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_PCISTATE) &
                 BGE_PCISTATE_PCI_BUSMODE) == 0) {                  BGE_PCISTATE_PCI_BUSMODE) == 0) {
Line 2631  bge_attach(device_t parent, device_t sel
Line 3399  bge_attach(device_t parent, device_t sel
                             "unable to find PCIX capability\n");                              "unable to find PCIX capability\n");
         }          }
   
         /* chipid */          if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5700_BX) {
         if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700 ||                  /*
             BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5701 ||                   * Kludge for 5700 Bx bug: a hardware bug (PCIX byte enable?)
             BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5703 ||                   * can clobber the chip's PCI config-space power control
             BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704)                   * registers, leaving the card in D3 powersave state. We do
                 sc->bge_flags |= BGE_5700_FAMILY;                   * not have memory-mapped registers in this state, so force
                    * device into D0 state before starting initialization.
                    */
                   pm_ctl = pci_conf_read(pc, sc->sc_pcitag, BGE_PCI_PWRMGMT_CMD);
                   pm_ctl &= ~(PCI_PWR_D0|PCI_PWR_D1|PCI_PWR_D2|PCI_PWR_D3);
                   pm_ctl |= (1 << 8) | PCI_PWR_D0 ; /* D0 state */
                   pci_conf_write(pc, sc->sc_pcitag, BGE_PCI_PWRMGMT_CMD, pm_ctl);
                   DELAY(1000);    /* 27 usec is allegedly sufficent */
           }
   
           /* Save chipset family. */
           switch (BGE_ASICREV(sc->bge_chipid)) {
           case BGE_ASICREV_BCM5717:
           case BGE_ASICREV_BCM5719:
           case BGE_ASICREV_BCM5720:
                   sc->bge_flags |= BGE_5717_PLUS;
                   /* FALLTHROUGH */
           case BGE_ASICREV_BCM57765:
           case BGE_ASICREV_BCM57766:
                   if (!BGE_IS_5717_PLUS(sc))
                           sc->bge_flags |= BGE_57765_FAMILY;
                   sc->bge_flags |= BGE_57765_PLUS | BGE_5755_PLUS |
                       BGE_575X_PLUS | BGE_5705_PLUS | BGE_JUMBO_CAPABLE;
                   /* Jumbo frame on BCM5719 A0 does not work. */
                   if ((BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719) &&
                       (sc->bge_chipid == BGE_CHIPID_BCM5719_A0))
                           sc->bge_flags &= ~BGE_JUMBO_CAPABLE;
                   break;
           case BGE_ASICREV_BCM5755:
           case BGE_ASICREV_BCM5761:
           case BGE_ASICREV_BCM5784:
           case BGE_ASICREV_BCM5785:
           case BGE_ASICREV_BCM5787:
           case BGE_ASICREV_BCM57780:
                   sc->bge_flags |= BGE_5755_PLUS | BGE_575X_PLUS | BGE_5705_PLUS;
                   break;
           case BGE_ASICREV_BCM5700:
           case BGE_ASICREV_BCM5701:
           case BGE_ASICREV_BCM5703:
           case BGE_ASICREV_BCM5704:
                   sc->bge_flags |= BGE_5700_FAMILY | BGE_JUMBO_CAPABLE;
                   break;
           case BGE_ASICREV_BCM5714_A0:
           case BGE_ASICREV_BCM5780:
           case BGE_ASICREV_BCM5714:
                   sc->bge_flags |= BGE_5714_FAMILY | BGE_JUMBO_CAPABLE;
                   /* FALLTHROUGH */
           case BGE_ASICREV_BCM5750:
           case BGE_ASICREV_BCM5752:
           case BGE_ASICREV_BCM5906:
                   sc->bge_flags |= BGE_575X_PLUS;
                   /* FALLTHROUGH */
           case BGE_ASICREV_BCM5705:
                   sc->bge_flags |= BGE_5705_PLUS;
                   break;
           }
   
         if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5714_A0 ||          /* Identify chips with APE processor. */
             BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5780 ||          switch (BGE_ASICREV(sc->bge_chipid)) {
             BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5714)          case BGE_ASICREV_BCM5717:
                 sc->bge_flags |= BGE_5714_FAMILY;          case BGE_ASICREV_BCM5719:
           case BGE_ASICREV_BCM5720:
           case BGE_ASICREV_BCM5761:
                   sc->bge_flags |= BGE_APE;
                   break;
           }
   
         /* Intentionally exclude BGE_ASICREV_BCM5906 */          /* Chips with APE need BAR2 access for APE registers/memory. */
         if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 ||          if ((sc->bge_flags & BGE_APE) != 0) {
             BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755 ||                  memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BGE_PCI_BAR2);
             BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5761 ||                  if (pci_mapreg_map(pa, BGE_PCI_BAR2, memtype, 0,
                           &sc->bge_apetag, &sc->bge_apehandle, NULL,
                           &sc->bge_apesize)) {
                           aprint_error_dev(sc->bge_dev,
                               "couldn't map BAR2 memory\n");
                           return;
                   }
   
                   /* Enable APE register/memory access by host driver. */
                   reg = pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_PCISTATE);
                   reg |= BGE_PCISTATE_ALLOW_APE_CTLSPC_WR |
                       BGE_PCISTATE_ALLOW_APE_SHMEM_WR |
                       BGE_PCISTATE_ALLOW_APE_PSPACE_WR;
                   pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_PCISTATE, reg);
   
                   bge_ape_lock_init(sc);
                   bge_ape_read_fw_ver(sc);
           }
   
           /* Identify the chips that use an CPMU. */
           if (BGE_IS_5717_PLUS(sc) ||
             BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5784 ||              BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5784 ||
               BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5761 ||
             BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5785 ||              BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5785 ||
             BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5787 ||  
             BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57765 ||  
             BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57780)              BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57780)
                 sc->bge_flags |= BGE_5755_PLUS;                  sc->bge_flags |= BGE_CPMU_PRESENT;
   
         if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750 ||          /* Set MI_MODE */
             BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5752 ||          mimode = BGE_MIMODE_PHYADDR(sc->bge_phy_addr);
             BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906 ||          if ((sc->bge_flags & BGE_CPMU_PRESENT) != 0)
             BGE_IS_5755_PLUS(sc) ||                  mimode |= BGE_MIMODE_500KHZ_CONST;
             BGE_IS_5714_FAMILY(sc))          else
                 sc->bge_flags |= BGE_5750_PLUS;                  mimode |= BGE_MIMODE_BASE;
           CSR_WRITE_4(sc, BGE_MI_MODE, mimode);
         if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5705 ||  
             BGE_IS_5750_OR_BEYOND(sc))  
                 sc->bge_flags |= BGE_5705_PLUS;  
   
         /*          /*
          * When using the BCM5701 in PCI-X mode, data corruption has           * When using the BCM5701 in PCI-X mode, data corruption has
Line 2680  bge_attach(device_t parent, device_t sel
Line 3524  bge_attach(device_t parent, device_t sel
         if (BGE_IS_5700_FAMILY(sc))          if (BGE_IS_5700_FAMILY(sc))
                 sc->bge_flags |= BGE_JUMBO_CAPABLE;                  sc->bge_flags |= BGE_JUMBO_CAPABLE;
   
         if ((BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700 ||  
             BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5701) &&  
             PCI_VENDOR(subid) == PCI_VENDOR_DELL)  
                 sc->bge_flags |= BGE_NO_3LED;  
   
         misccfg = CSR_READ_4(sc, BGE_MISC_CFG);          misccfg = CSR_READ_4(sc, BGE_MISC_CFG);
         misccfg &= BGE_MISCCFG_BOARD_ID_MASK;          misccfg &= BGE_MISCCFG_BOARD_ID_MASK;
   
Line 2715  bge_attach(device_t parent, device_t sel
Line 3554  bge_attach(device_t parent, device_t sel
                         sc->bge_flags |= BGE_TSO;                          sc->bge_flags |= BGE_TSO;
         }          }
   
           capmask = 0xffffffff; /* XXX BMSR_DEFCAPMASK */
         if ((BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5703 &&          if ((BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5703 &&
              (misccfg == 0x4000 || misccfg == 0x8000)) ||               (misccfg == 0x4000 || misccfg == 0x8000)) ||
             (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5705 &&              (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5705 &&
Line 2727  bge_attach(device_t parent, device_t sel
Line 3567  bge_attach(device_t parent, device_t sel
               PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5753F ||                PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5753F ||
               PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5787F)) ||                PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5787F)) ||
             PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM57790 ||              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM57790 ||
             BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906)              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM57791 ||
                 sc->bge_flags |= BGE_10_100_ONLY;              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM57795 ||
               BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906) {
                   capmask &= ~BMSR_EXTSTAT;
                   sc->bge_flags |= BGE_PHY_NO_WIRESPEED;
           }
   
         if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700 ||          if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700 ||
             (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5705 &&              (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5705 &&
              (sc->bge_chipid != BGE_CHIPID_BCM5705_A0 &&               (sc->bge_chipid != BGE_CHIPID_BCM5705_A0 &&
               sc->bge_chipid != BGE_CHIPID_BCM5705_A1)) ||                   sc->bge_chipid != BGE_CHIPID_BCM5705_A1)))
             BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906)                  sc->bge_flags |= BGE_PHY_NO_WIRESPEED;
                 sc->bge_flags |= BGE_NO_ETH_WIRE_SPEED;  
   
           /* Set various PHY bug flags. */
         if (sc->bge_chipid == BGE_CHIPID_BCM5701_A0 ||          if (sc->bge_chipid == BGE_CHIPID_BCM5701_A0 ||
             sc->bge_chipid == BGE_CHIPID_BCM5701_B0)              sc->bge_chipid == BGE_CHIPID_BCM5701_B0)
                 sc->bge_flags |= BGE_PHY_CRC_BUG;                  sc->bge_flags |= BGE_PHY_CRC_BUG;
Line 2745  bge_attach(device_t parent, device_t sel
Line 3589  bge_attach(device_t parent, device_t sel
                 sc->bge_flags |= BGE_PHY_ADC_BUG;                  sc->bge_flags |= BGE_PHY_ADC_BUG;
         if (sc->bge_chipid == BGE_CHIPID_BCM5704_A0)          if (sc->bge_chipid == BGE_CHIPID_BCM5704_A0)
                 sc->bge_flags |= BGE_PHY_5704_A0_BUG;                  sc->bge_flags |= BGE_PHY_5704_A0_BUG;
           if ((BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700 ||
               BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5701) &&
               PCI_VENDOR(subid) == PCI_VENDOR_DELL)
                   sc->bge_flags |= BGE_PHY_NO_3LED;
         if (BGE_IS_5705_PLUS(sc) &&          if (BGE_IS_5705_PLUS(sc) &&
             BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5906 &&              BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5906 &&
             BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5717 &&  
             BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5785 &&              BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5785 &&
             BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM57765 &&              BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM57780 &&
             BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM57780) {              !BGE_IS_57765_PLUS(sc)) {
                 if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755 ||                  if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755 ||
                     BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5761 ||                      BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5761 ||
                     BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5784 ||                      BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5784 ||
Line 2761  bge_attach(device_t parent, device_t sel
Line 3607  bge_attach(device_t parent, device_t sel
                                 sc->bge_flags |= BGE_PHY_JITTER_BUG;                                  sc->bge_flags |= BGE_PHY_JITTER_BUG;
                         if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5755M)                          if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5755M)
                                 sc->bge_flags |= BGE_PHY_ADJUST_TRIM;                                  sc->bge_flags |= BGE_PHY_ADJUST_TRIM;
                 } else if (BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5906)                  } else
                         sc->bge_flags |= BGE_PHY_BER_BUG;                          sc->bge_flags |= BGE_PHY_BER_BUG;
         }          }
   
Line 2773  bge_attach(device_t parent, device_t sel
Line 3619  bge_attach(device_t parent, device_t sel
              "without-seeprom", &no_seeprom) && no_seeprom)               "without-seeprom", &no_seeprom) && no_seeprom)
                 sc->bge_flags |= BGE_NO_EEPROM;                  sc->bge_flags |= BGE_NO_EEPROM;
   
           else if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906)
                   sc->bge_flags |= BGE_NO_EEPROM;
   
         /* Now check the 'ROM failed' bit on the RX CPU */          /* Now check the 'ROM failed' bit on the RX CPU */
         else if (CSR_READ_4(sc, BGE_RXCPU_MODE) & BGE_RXCPUMODE_ROMFAIL)          else if (CSR_READ_4(sc, BGE_RXCPU_MODE) & BGE_RXCPUMODE_ROMFAIL)
                 sc->bge_flags |= BGE_NO_EEPROM;                  sc->bge_flags |= BGE_NO_EEPROM;
   
         /* Try to reset the chip. */  
         DPRINTFN(5, ("bge_reset\n"));  
         bge_reset(sc);  
   
         sc->bge_asf_mode = 0;          sc->bge_asf_mode = 0;
         if (bge_allow_asf && (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_SIG)          /* No ASF if APE present. */
             == BGE_MAGIC_NUMBER)) {          if ((sc->bge_flags & BGE_APE) == 0) {
                 if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_NICCFG)                  if (bge_allow_asf && (bge_readmem_ind(sc, BGE_SRAM_DATA_SIG) ==
                     & BGE_HWCFG_ASF) {                          BGE_SRAM_DATA_SIG_MAGIC)) {
                         sc->bge_asf_mode |= ASF_ENABLE;                          if (bge_readmem_ind(sc, BGE_SRAM_DATA_CFG) &
                         sc->bge_asf_mode |= ASF_STACKUP;                              BGE_HWCFG_ASF) {
                         if (BGE_IS_5750_OR_BEYOND(sc)) {                                  sc->bge_asf_mode |= ASF_ENABLE;
                                 sc->bge_asf_mode |= ASF_NEW_HANDSHAKE;                                  sc->bge_asf_mode |= ASF_STACKUP;
                                   if (BGE_IS_575X_PLUS(sc))
                                           sc->bge_asf_mode |= ASF_NEW_HANDSHAKE;
                         }                          }
                 }                  }
         }          }
   
         /* Try to reset the chip again the nice way. */          /*
            * Reset NVRAM before bge_reset(). It's required to acquire NVRAM
            * lock in bge_reset().
            */
           CSR_WRITE_4(sc, BGE_EE_ADDR,
               BGE_EEADDR_RESET | BGE_EEHALFCLK(BGE_HALFCLK_384SCL));
           delay(1000);
           BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_AUTO_EEPROM);
   
         bge_stop_fw(sc);          bge_stop_fw(sc);
         bge_sig_pre_reset(sc, BGE_RESET_STOP);          bge_sig_pre_reset(sc, BGE_RESET_START);
         if (bge_reset(sc))          if (bge_reset(sc))
                 aprint_error_dev(sc->bge_dev, "chip reset failed\n");                  aprint_error_dev(sc->bge_dev, "chip reset failed\n");
   
         bge_sig_legacy(sc, BGE_RESET_STOP);          /*
         bge_sig_post_reset(sc, BGE_RESET_STOP);           * Read the hardware config word in the first 32k of NIC internal
            * memory, or fall back to the config word in the EEPROM.
            * Note: on some BCM5700 cards, this value appears to be unset.
            */
           hwcfg = hwcfg2 = hwcfg3 = hwcfg4 = 0;
           if (bge_readmem_ind(sc, BGE_SRAM_DATA_SIG) ==
               BGE_SRAM_DATA_SIG_MAGIC) {
                   uint32_t tmp;
   
                   hwcfg = bge_readmem_ind(sc, BGE_SRAM_DATA_CFG);
                   tmp = bge_readmem_ind(sc, BGE_SRAM_DATA_VER) >>
                       BGE_SRAM_DATA_VER_SHIFT;
                   if ((0 < tmp) && (tmp < 0x100))
                           hwcfg2 = bge_readmem_ind(sc, BGE_SRAM_DATA_CFG_2);
                   if (sc->bge_flags & BGE_PCIE)
                           hwcfg3 = bge_readmem_ind(sc, BGE_SRAM_DATA_CFG_3);
                   if (BGE_ASICREV(sc->bge_chipid == BGE_ASICREV_BCM5785))
                           hwcfg4 = bge_readmem_ind(sc, BGE_SRAM_DATA_CFG_4);
           } else if (!(sc->bge_flags & BGE_NO_EEPROM)) {
                   bge_read_eeprom(sc, (void *)&hwcfg,
                       BGE_EE_HWCFG_OFFSET, sizeof(hwcfg));
                   hwcfg = be32toh(hwcfg);
           }
           aprint_normal_dev(sc->bge_dev, "HW config %08x, %08x, %08x, %08x\n",
               hwcfg, hwcfg2, hwcfg3, hwcfg4);
   
           bge_sig_legacy(sc, BGE_RESET_START);
           bge_sig_post_reset(sc, BGE_RESET_START);
   
         if (bge_chipinit(sc)) {          if (bge_chipinit(sc)) {
                 aprint_error_dev(sc->bge_dev, "chip initialization failed\n");                  aprint_error_dev(sc->bge_dev, "chip initialization failed\n");
Line 2810  bge_attach(device_t parent, device_t sel
Line 3692  bge_attach(device_t parent, device_t sel
         }          }
   
         /*          /*
          * Get station address from the EEPROM           * Get station address from the EEPROM.
          */           */
         if (bge_get_eaddr(sc, eaddr)) {          if (bge_get_eaddr(sc, eaddr)) {
                 aprint_error_dev(sc->bge_dev,                  aprint_error_dev(sc->bge_dev,
Line 2837  bge_attach(device_t parent, device_t sel
Line 3719  bge_attach(device_t parent, device_t sel
                 sc->bge_dmatag = pa->pa_dmat;                  sc->bge_dmatag = pa->pa_dmat;
         DPRINTFN(5, ("bus_dmamem_alloc\n"));          DPRINTFN(5, ("bus_dmamem_alloc\n"));
         if (bus_dmamem_alloc(sc->bge_dmatag, sizeof(struct bge_ring_data),          if (bus_dmamem_alloc(sc->bge_dmatag, sizeof(struct bge_ring_data),
                              PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {                               PAGE_SIZE, 0, &sc->bge_ring_seg, 1,
                   &sc->bge_ring_rseg, BUS_DMA_NOWAIT)) {
                 aprint_error_dev(sc->bge_dev, "can't alloc rx buffers\n");                  aprint_error_dev(sc->bge_dev, "can't alloc rx buffers\n");
                 return;                  return;
         }          }
         DPRINTFN(5, ("bus_dmamem_map\n"));          DPRINTFN(5, ("bus_dmamem_map\n"));
         if (bus_dmamem_map(sc->bge_dmatag, &seg, rseg,          if (bus_dmamem_map(sc->bge_dmatag, &sc->bge_ring_seg,
                            sizeof(struct bge_ring_data), &kva,                  sc->bge_ring_rseg, sizeof(struct bge_ring_data), &kva,
                            BUS_DMA_NOWAIT)) {                             BUS_DMA_NOWAIT)) {
                 aprint_error_dev(sc->bge_dev,                  aprint_error_dev(sc->bge_dev,
                     "can't map DMA buffers (%zu bytes)\n",                      "can't map DMA buffers (%zu bytes)\n",
                     sizeof(struct bge_ring_data));                      sizeof(struct bge_ring_data));
                 bus_dmamem_free(sc->bge_dmatag, &seg, rseg);                  bus_dmamem_free(sc->bge_dmatag, &sc->bge_ring_seg,
                       sc->bge_ring_rseg);
                 return;                  return;
         }          }
         DPRINTFN(5, ("bus_dmamem_create\n"));          DPRINTFN(5, ("bus_dmamem_create\n"));
Line 2858  bge_attach(device_t parent, device_t sel
Line 3742  bge_attach(device_t parent, device_t sel
                 aprint_error_dev(sc->bge_dev, "can't create DMA map\n");                  aprint_error_dev(sc->bge_dev, "can't create DMA map\n");
                 bus_dmamem_unmap(sc->bge_dmatag, kva,                  bus_dmamem_unmap(sc->bge_dmatag, kva,
                                  sizeof(struct bge_ring_data));                                   sizeof(struct bge_ring_data));
                 bus_dmamem_free(sc->bge_dmatag, &seg, rseg);                  bus_dmamem_free(sc->bge_dmatag, &sc->bge_ring_seg,
                       sc->bge_ring_rseg);
                 return;                  return;
         }          }
         DPRINTFN(5, ("bus_dmamem_load\n"));          DPRINTFN(5, ("bus_dmamem_load\n"));
Line 2868  bge_attach(device_t parent, device_t sel
Line 3753  bge_attach(device_t parent, device_t sel
                 bus_dmamap_destroy(sc->bge_dmatag, sc->bge_ring_map);                  bus_dmamap_destroy(sc->bge_dmatag, sc->bge_ring_map);
                 bus_dmamem_unmap(sc->bge_dmatag, kva,                  bus_dmamem_unmap(sc->bge_dmatag, kva,
                                  sizeof(struct bge_ring_data));                                   sizeof(struct bge_ring_data));
                 bus_dmamem_free(sc->bge_dmatag, &seg, rseg);                  bus_dmamem_free(sc->bge_dmatag, &sc->bge_ring_seg,
                       sc->bge_ring_rseg);
                 return;                  return;
         }          }
   
Line 2890  bge_attach(device_t parent, device_t sel
Line 3776  bge_attach(device_t parent, device_t sel
         sc->bge_stat_ticks = BGE_TICKS_PER_SEC;          sc->bge_stat_ticks = BGE_TICKS_PER_SEC;
         sc->bge_rx_coal_ticks = 150;          sc->bge_rx_coal_ticks = 150;
         sc->bge_rx_max_coal_bds = 64;          sc->bge_rx_max_coal_bds = 64;
 #ifdef ORIG_WPAUL_VALUES  
         sc->bge_tx_coal_ticks = 150;  
         sc->bge_tx_max_coal_bds = 128;  
 #else  
         sc->bge_tx_coal_ticks = 300;          sc->bge_tx_coal_ticks = 300;
         sc->bge_tx_max_coal_bds = 400;          sc->bge_tx_max_coal_bds = 400;
 #endif  
         if (BGE_IS_5705_PLUS(sc)) {          if (BGE_IS_5705_PLUS(sc)) {
                 sc->bge_tx_coal_ticks = (12 * 5);                  sc->bge_tx_coal_ticks = (12 * 5);
                 sc->bge_tx_max_coal_bds = (12 * 5);                  sc->bge_tx_max_coal_bds = (12 * 5);
Line 2904  bge_attach(device_t parent, device_t sel
Line 3785  bge_attach(device_t parent, device_t sel
                             "setting short Tx thresholds\n");                              "setting short Tx thresholds\n");
         }          }
   
         if (BGE_IS_5705_PLUS(sc))          if (BGE_IS_5717_PLUS(sc))
                   sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT;
           else if (BGE_IS_5705_PLUS(sc))
                 sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT_5705;                  sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT_5705;
         else          else
                 sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT;                  sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT;
Line 2947  bge_attach(device_t parent, device_t sel
Line 3830  bge_attach(device_t parent, device_t sel
         sc->bge_mii.mii_statchg = bge_miibus_statchg;          sc->bge_mii.mii_statchg = bge_miibus_statchg;
   
         /*          /*
          * Figure out what sort of media we have by checking the           * Figure out what sort of media we have by checking the hardware
          * hardware config word in the first 32k of NIC internal memory,           * config word.  Note: on some BCM5700 cards, this value appears to be
          * or fall back to the config word in the EEPROM. Note: on some BCM5700           * unset. If that's the case, we have to rely on identifying the NIC
          * cards, this value appears to be unset. If that's the           * by its PCI subsystem ID, as we do below for the SysKonnect SK-9D41.
          * case, we have to rely on identifying the NIC by its PCI           * The SysKonnect SK-9D41 is a 1000baseSX card.
          * subsystem ID, as we do below for the SysKonnect SK-9D41.  
          */           */
         if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_SIG) == BGE_MAGIC_NUMBER) {  
                 hwcfg = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_NICCFG);  
         } else if (!(sc->bge_flags & BGE_NO_EEPROM)) {  
                 bge_read_eeprom(sc, (void *)&hwcfg,  
                     BGE_EE_HWCFG_OFFSET, sizeof(hwcfg));  
                 hwcfg = be32toh(hwcfg);  
         }  
         /* The SysKonnect SK-9D41 is a 1000baseSX card. */  
         if (PCI_PRODUCT(pa->pa_id) == SK_SUBSYSID_9D41 ||          if (PCI_PRODUCT(pa->pa_id) == SK_SUBSYSID_9D41 ||
             (hwcfg & BGE_HWCFG_MEDIA) == BGE_MEDIA_FIBER) {              (hwcfg & BGE_HWCFG_MEDIA) == BGE_MEDIA_FIBER) {
                 if (BGE_IS_5714_FAMILY(sc))                  if (BGE_IS_5714_FAMILY(sc))
Line 2998  bge_attach(device_t parent, device_t sel
Line 3872  bge_attach(device_t parent, device_t sel
   
                 ifmedia_init(&sc->bge_mii.mii_media, 0, bge_ifmedia_upd,                  ifmedia_init(&sc->bge_mii.mii_media, 0, bge_ifmedia_upd,
                              bge_ifmedia_sts);                               bge_ifmedia_sts);
                 mii_attach(sc->bge_dev, &sc->bge_mii, 0xffffffff,                  mii_attach(sc->bge_dev, &sc->bge_mii, capmask,
                            MII_PHY_ANY, MII_OFFSET_ANY,                             sc->bge_phy_addr, MII_OFFSET_ANY,
                            MIIF_FORCEANEG|MIIF_DOPAUSE);                             MIIF_DOPAUSE);
   
                 if (LIST_EMPTY(&sc->bge_mii.mii_phys)) {                  if (LIST_EMPTY(&sc->bge_mii.mii_phys)) {
                         aprint_error_dev(sc->bge_dev, "no PHY found!\n");                          aprint_error_dev(sc->bge_dev, "no PHY found!\n");
Line 3056  bge_attach(device_t parent, device_t sel
Line 3930  bge_attach(device_t parent, device_t sel
         else          else
                 aprint_error_dev(self, "couldn't establish power handler\n");                  aprint_error_dev(self, "couldn't establish power handler\n");
   
         sysctl_bge_init(sc);          bge_sysctl_init(sc);
   
 #ifdef BGE_DEBUG  #ifdef BGE_DEBUG
         bge_debug_info(sc);          bge_debug_info(sc);
 #endif  #endif
 }  }
   
   /*
    * Stop all chip I/O so that the kernel's probe routines don't
    * get confused by errant DMAs when rebooting.
    */
   static int
   bge_detach(device_t self, int flags __unused)
   {
           struct bge_softc *sc = device_private(self);
           struct ifnet *ifp = &sc->ethercom.ec_if;
           int s;
   
           s = splnet();
           /* Stop the interface. Callouts are stopped in it. */
           bge_stop(ifp, 1);
           splx(s);
   
           mii_detach(&sc->bge_mii, MII_PHY_ANY, MII_OFFSET_ANY);
   
           /* Delete all remaining media. */
           ifmedia_delete_instance(&sc->bge_mii.mii_media, IFM_INST_ANY);
   
           ether_ifdetach(ifp);
           if_detach(ifp);
   
           bge_release_resources(sc);
   
           return 0;
   }
   
 static void  static void
 bge_release_resources(struct bge_softc *sc)  bge_release_resources(struct bge_softc *sc)
 {  {
         if (sc->bge_vpd_prodname != NULL)  
                 free(sc->bge_vpd_prodname, M_DEVBUF);  
   
         if (sc->bge_vpd_readonly != NULL)          /* Disestablish the interrupt handler */
                 free(sc->bge_vpd_readonly, M_DEVBUF);          if (sc->bge_intrhand != NULL) {
                   pci_intr_disestablish(sc->sc_pc, sc->bge_intrhand);
                   sc->bge_intrhand = NULL;
           }
   
           if (sc->bge_dmatag != NULL) {
                   bus_dmamap_unload(sc->bge_dmatag, sc->bge_ring_map);
                   bus_dmamap_destroy(sc->bge_dmatag, sc->bge_ring_map);
                   bus_dmamem_unmap(sc->bge_dmatag, (void *)sc->bge_rdata,
                       sizeof(struct bge_ring_data));
                   bus_dmamem_free(sc->bge_dmatag, &sc->bge_ring_seg, sc->bge_ring_rseg);
           }
   
           /* Unmap the device registers */
           if (sc->bge_bsize != 0) {
                   bus_space_unmap(sc->bge_btag, sc->bge_bhandle, sc->bge_bsize);
                   sc->bge_bsize = 0;
           }
   
           /* Unmap the APE registers */
           if (sc->bge_apesize != 0) {
                   bus_space_unmap(sc->bge_apetag, sc->bge_apehandle,
                       sc->bge_apesize);
                   sc->bge_apesize = 0;
           }
 }  }
   
 static int  static int
 bge_reset(struct bge_softc *sc)  bge_reset(struct bge_softc *sc)
 {  {
         uint32_t cachesize, command, pcistate, marbmode;          uint32_t cachesize, command;
 #if 0          uint32_t reset, mac_mode, mac_mode_mask;
         uint32_t new_pcistate;  
 #endif  
         pcireg_t devctl, reg;          pcireg_t devctl, reg;
         int i, val;          int i, val;
         void (*write_op)(struct bge_softc *, int, int);          void (*write_op)(struct bge_softc *, int, int);
   
         if (BGE_IS_5750_OR_BEYOND(sc) && !BGE_IS_5714_FAMILY(sc)          /* Make mask for BGE_MAC_MODE register. */
             && (BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5906)) {          mac_mode_mask = BGE_MACMODE_HALF_DUPLEX | BGE_MACMODE_PORTMODE;
           if ((sc->bge_mfw_flags & BGE_MFW_ON_APE) != 0)
                   mac_mode_mask |= BGE_MACMODE_APE_RX_EN | BGE_MACMODE_APE_TX_EN;
           /* Keep mac_mode_mask's bits of BGE_MAC_MODE register into mac_mode */
           mac_mode = CSR_READ_4(sc, BGE_MAC_MODE) & mac_mode_mask;
   
           if (BGE_IS_575X_PLUS(sc) && !BGE_IS_5714_FAMILY(sc) &&
               (BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5906)) {
                 if (sc->bge_flags & BGE_PCIE)                  if (sc->bge_flags & BGE_PCIE)
                         write_op = bge_writemem_direct;                          write_op = bge_writemem_direct;
                 else                  else
Line 3093  bge_reset(struct bge_softc *sc)
Line 4023  bge_reset(struct bge_softc *sc)
         } else          } else
                 write_op = bge_writereg_ind;                  write_op = bge_writereg_ind;
   
           /* 57XX step 4 */
           /* Acquire the NVM lock */
           if ((sc->bge_flags & BGE_NO_EEPROM) == 0 &&
               BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5700 &&
               BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5701) {
                   CSR_WRITE_4(sc, BGE_NVRAM_SWARB, BGE_NVRAMSWARB_SET1);
                   for (i = 0; i < 8000; i++) {
                           if (CSR_READ_4(sc, BGE_NVRAM_SWARB) &
                               BGE_NVRAMSWARB_GNT1)
                                   break;
                           DELAY(20);
                   }
                   if (i == 8000) {
                           printf("%s: NVRAM lock timedout!\n",
                               device_xname(sc->bge_dev));
                   }
           }
   
           /* Take APE lock when performing reset. */
           bge_ape_lock(sc, BGE_APE_LOCK_GRC);
   
           /* 57XX step 3 */
         /* Save some important PCI state. */          /* Save some important PCI state. */
         cachesize = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CACHESZ);          cachesize = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CACHESZ);
           /* 5718 reset step 3 */
         command = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CMD);          command = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CMD);
         pcistate = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_PCISTATE);  
   
         /* Step 5a: Enable memory arbiter. */          /* 5718 reset step 5, 57XX step 5b-5d */
         marbmode = 0;  
         if (BGE_IS_5714_FAMILY(sc))  
                 marbmode = CSR_READ_4(sc, BGE_MARB_MODE);  
         CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE | marbmode);  
   
         /* Step 5b-5d: */  
         pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MISC_CTL,          pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MISC_CTL,
             BGE_PCIMISCCTL_INDIRECT_ACCESS | BGE_PCIMISCCTL_MASK_PCI_INTR |              BGE_PCIMISCCTL_INDIRECT_ACCESS | BGE_PCIMISCCTL_MASK_PCI_INTR |
             BGE_HIF_SWAP_OPTIONS | BGE_PCIMISCCTL_PCISTATE_RW);              BGE_HIF_SWAP_OPTIONS | BGE_PCIMISCCTL_PCISTATE_RW);
Line 3114  bge_reset(struct bge_softc *sc)
Line 4060  bge_reset(struct bge_softc *sc)
             BGE_IS_5755_PLUS(sc))              BGE_IS_5755_PLUS(sc))
                 CSR_WRITE_4(sc, BGE_FASTBOOT_PC, 0);                  CSR_WRITE_4(sc, BGE_FASTBOOT_PC, 0);
   
           /* 5718 reset step 2, 57XX step 6 */
         /*          /*
          * Step 6: Write the magic number to SRAM at offset 0xB50.           * Write the magic number to SRAM at offset 0xB50.
          * When firmware finishes its initialization it will           * When firmware finishes its initialization it will
          * write ~BGE_MAGIC_NUMBER to the same location.           * write ~BGE_MAGIC_NUMBER to the same location.
          */           */
         bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);          bge_writemem_ind(sc, BGE_SRAM_FW_MB, BGE_SRAM_FW_MB_MAGIC);
   
         /* Step 7: */          /* 5718 reset step 6, 57XX step 7 */
         val = BGE_MISCCFG_RESET_CORE_CLOCKS | (65<<1);          reset = BGE_MISCCFG_RESET_CORE_CLOCKS | BGE_32BITTIME_66MHZ;
         /*          /*
          * XXX: from FreeBSD/Linux; no documentation           * XXX: from FreeBSD/Linux; no documentation
          */           */
         if (sc->bge_flags & BGE_PCIE) {          if (sc->bge_flags & BGE_PCIE) {
                 if (CSR_READ_4(sc, BGE_PCIE_CTL1) == 0x60)                  if (BGE_ASICREV(sc->bge_chipid != BGE_ASICREV_BCM5785) &&
                       !BGE_IS_57765_PLUS(sc) &&
                       (CSR_READ_4(sc, BGE_PHY_TEST_CTRL_REG) ==
                           (BGE_PHY_PCIE_LTASS_MODE | BGE_PHY_PCIE_SCRAM_MODE))) {
                         /* PCI Express 1.0 system */                          /* PCI Express 1.0 system */
                         CSR_WRITE_4(sc, BGE_PCIE_CTL1, 0x20);                          CSR_WRITE_4(sc, BGE_PHY_TEST_CTRL_REG,
                               BGE_PHY_PCIE_SCRAM_MODE);
                   }
                 if (sc->bge_chipid != BGE_CHIPID_BCM5750_A0) {                  if (sc->bge_chipid != BGE_CHIPID_BCM5750_A0) {
                         /*                          /*
                          * Prevent PCI Express link training                           * Prevent PCI Express link training
                          * during global reset.                           * during global reset.
                          */                           */
                         CSR_WRITE_4(sc, BGE_MISC_CFG, 1 << 29);                          CSR_WRITE_4(sc, BGE_MISC_CFG, 1 << 29);
                         val |= (1<<29);                          reset |= (1 << 29);
                 }                  }
         }          }
   
Line 3153  bge_reset(struct bge_softc *sc)
Line 4105  bge_reset(struct bge_softc *sc)
          * Set GPHY Power Down Override to leave GPHY           * Set GPHY Power Down Override to leave GPHY
          * powered up in D0 uninitialized.           * powered up in D0 uninitialized.
          */           */
         if (BGE_IS_5705_PLUS(sc))          if (BGE_IS_5705_PLUS(sc) &&
                 val |= BGE_MISCCFG_KEEP_GPHY_POWER;              (sc->bge_flags & BGE_CPMU_PRESENT) == 0)
                   reset |= BGE_MISCCFG_GPHY_PD_OVERRIDE;
         /* XXX 5721, 5751 and 5752 */  
         if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750)  
                 val |= BGE_MISCCFG_GRC_RESET_DISABLE;  
   
         /* Issue global reset */          /* Issue global reset */
         write_op(sc, BGE_MISC_CFG, val);          write_op(sc, BGE_MISC_CFG, reset);
   
         /* Step 8: wait for complete */          /* 5718 reset step 7, 57XX step 8 */
         if (sc->bge_flags & BGE_PCIE)          if (sc->bge_flags & BGE_PCIE)
                 delay(100*1000); /* too big */                  delay(100*1000); /* too big */
         else          else
                 delay(100);                  delay(1000);
   
         /* From Linux: dummy read to flush PCI posted writes */  
         reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CMD);  
   
         /* Step 9-10: Reset some of the PCI state that got zapped by reset */  
         pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MISC_CTL,  
             BGE_PCIMISCCTL_INDIRECT_ACCESS | BGE_PCIMISCCTL_MASK_PCI_INTR |  
             BGE_HIF_SWAP_OPTIONS | BGE_PCIMISCCTL_PCISTATE_RW  
                 | BGE_PCIMISCCTL_CLOCKCTL_RW);  
         pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CMD, command);  
         write_op(sc, BGE_MISC_CFG, (65 << 1));  
   
         /* Step 11: disable PCI-X Relaxed Ordering. */  
         if (sc->bge_flags & BGE_PCIX) {  
                 reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, sc->bge_pcixcap  
                     + PCI_PCIX_CMD);  
                 pci_conf_write(sc->sc_pc, sc->sc_pcitag, sc->bge_pcixcap  
                     + PCI_PCIX_CMD, reg & ~PCI_PCIX_CMD_RELAXED_ORDER);  
         }  
   
         if (sc->bge_flags & BGE_PCIE) {          if (sc->bge_flags & BGE_PCIE) {
                 if (sc->bge_chipid == BGE_CHIPID_BCM5750_A0) {                  if (sc->bge_chipid == BGE_CHIPID_BCM5750_A0) {
Line 3201  bge_reset(struct bge_softc *sc)
Line 4131  bge_reset(struct bge_softc *sc)
                 devctl = pci_conf_read(sc->sc_pc, sc->sc_pcitag,                  devctl = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
                     sc->bge_pciecap + PCI_PCIE_DCSR);                      sc->bge_pciecap + PCI_PCIE_DCSR);
                 /* Clear enable no snoop and disable relaxed ordering. */                  /* Clear enable no snoop and disable relaxed ordering. */
                 devctl &= ~(0x0010 | PCI_PCIE_DCSR_ENA_NO_SNOOP);                  devctl &= ~(PCI_PCIE_DCSR_ENA_RELAX_ORD |
                 /* Set PCIE max payload size to 128. */                      PCI_PCIE_DCSR_ENA_NO_SNOOP);
                 devctl &= ~(0x00e0);  
                   /* Set PCIE max payload size to 128 for older PCIe devices */
                   if ((sc->bge_flags & BGE_CPMU_PRESENT) == 0)
                           devctl &= ~(0x00e0);
                 /* Clear device status register. Write 1b to clear */                  /* Clear device status register. Write 1b to clear */
                 devctl |= PCI_PCIE_DCSR_URD | PCI_PCIE_DCSR_FED                  devctl |= PCI_PCIE_DCSR_URD | PCI_PCIE_DCSR_FED
                     | PCI_PCIE_DCSR_NFED | PCI_PCIE_DCSR_CED;                      | PCI_PCIE_DCSR_NFED | PCI_PCIE_DCSR_CED;
                 pci_conf_write(sc->sc_pc, sc->sc_pcitag,                  pci_conf_write(sc->sc_pc, sc->sc_pcitag,
                     sc->bge_pciecap + PCI_PCIE_DCSR, devctl);                      sc->bge_pciecap + PCI_PCIE_DCSR, devctl);
                   bge_set_max_readrq(sc);
         }          }
   
         /* Step 12: Enable memory arbiter. */          /* From Linux: dummy read to flush PCI posted writes */
         marbmode = 0;          reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CMD);
         if (BGE_IS_5714_FAMILY(sc))  
                 marbmode = CSR_READ_4(sc, BGE_MARB_MODE);  
         CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE | marbmode);  
   
         /* Step 17: Poll until the firmware initialization is complete */          /*
         bge_poll_fw(sc);           * Reset some of the PCI state that got zapped by reset
            * To modify the PCISTATE register, BGE_PCIMISCCTL_PCISTATE_RW must be
            * set, too.
            */
           pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MISC_CTL,
               BGE_PCIMISCCTL_INDIRECT_ACCESS | BGE_PCIMISCCTL_MASK_PCI_INTR |
               BGE_HIF_SWAP_OPTIONS | BGE_PCIMISCCTL_PCISTATE_RW);
           val = BGE_PCISTATE_ROM_ENABLE | BGE_PCISTATE_ROM_RETRY_ENABLE;
           if (sc->bge_chipid == BGE_CHIPID_BCM5704_A0 &&
               (sc->bge_flags & BGE_PCIX) != 0)
                   val |= BGE_PCISTATE_RETRY_SAME_DMA;
           if ((sc->bge_mfw_flags & BGE_MFW_ON_APE) != 0)
                   val |= BGE_PCISTATE_ALLOW_APE_CTLSPC_WR |
                       BGE_PCISTATE_ALLOW_APE_SHMEM_WR |
                       BGE_PCISTATE_ALLOW_APE_PSPACE_WR;
           pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_PCISTATE, val);
           pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CACHESZ, cachesize);
           pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CMD, command);
   
           /* Step 11: disable PCI-X Relaxed Ordering. */
           if (sc->bge_flags & BGE_PCIX) {
                   reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, sc->bge_pcixcap
                       + PCI_PCIX_CMD);
                   pci_conf_write(sc->sc_pc, sc->sc_pcitag, sc->bge_pcixcap
                       + PCI_PCIX_CMD, reg & ~PCI_PCIX_CMD_RELAXED_ORDER);
           }
   
           /* 5718 reset step 10, 57XX step 12 */
           /* Enable memory arbiter. */
           if (BGE_IS_5714_FAMILY(sc)) {
                   val = CSR_READ_4(sc, BGE_MARB_MODE);
                   CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE | val);
           } else
                   CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE);
   
         /* XXX 5721, 5751 and 5752 */          /* XXX 5721, 5751 and 5752 */
         if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750) {          if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750) {
Line 3228  bge_reset(struct bge_softc *sc)
Line 4192  bge_reset(struct bge_softc *sc)
                 BGE_SETBIT(sc, BGE_TLP_CONTROL_REG, BGE_TLP_DATA_FIFO_PROTECT);                  BGE_SETBIT(sc, BGE_TLP_CONTROL_REG, BGE_TLP_DATA_FIFO_PROTECT);
         }          }
   
         /*          /* 5718 reset step 13, 57XX step 17 */
          * Step 18: wirte mac mode          /* Poll until the firmware initialization is complete */
          * XXX Write 0x0c for 5703S and 5704S          bge_poll_fw(sc);
          */  
         CSR_WRITE_4(sc, BGE_MAC_MODE, 0);  
   
           /* 5718 reset step 12, 57XX step 15 and 16 */
           /* Fix up byte swapping */
           CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS);
   
         /* Step 21: 5822 B0 errata */          /* 57XX step 21 */
         if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5704_BX) {          if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5704_BX) {
                 pcireg_t msidata;                  pcireg_t msidata;
   
                 msidata = pci_conf_read(sc->sc_pc, sc->sc_pcitag,                  msidata = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
                     BGE_PCI_MSI_DATA);                      BGE_PCI_MSI_DATA);
                 msidata |= ((1 << 13 | 1 << 12 | 1 << 10) << 16);                  msidata |= ((1 << 13 | 1 << 12 | 1 << 10) << 16);
Line 3246  bge_reset(struct bge_softc *sc)
Line 4211  bge_reset(struct bge_softc *sc)
                     msidata);                      msidata);
         }          }
   
         /* Step 23: restore cache line size */          /* 57XX step 18 */
         pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CACHESZ, cachesize);          /* Write mac mode. */
           val = CSR_READ_4(sc, BGE_MAC_MODE);
 #if 0          /* Restore mac_mode_mask's bits using mac_mode */
         /*          val = (val & ~mac_mode_mask) | mac_mode;
          * XXX Wait for the value of the PCISTATE register to          CSR_WRITE_4_FLUSH(sc, BGE_MAC_MODE, val);
          * return to its original pre-reset state. This is a          DELAY(40);
          * fairly good indicator of reset completion. If we don't  
          * wait for the reset to fully complete, trying to read  
          * from the device's non-PCI registers may yield garbage  
          * results.  
          */  
         for (i = 0; i < BGE_TIMEOUT; i++) {  
                 new_pcistate = pci_conf_read(sc->sc_pc, sc->sc_pcitag,  
                     BGE_PCI_PCISTATE);  
                 if ((new_pcistate & ~BGE_PCISTATE_RESERVED) ==  
                     (pcistate & ~BGE_PCISTATE_RESERVED))  
                         break;  
                 DELAY(10);  
         }  
         if ((new_pcistate & ~BGE_PCISTATE_RESERVED) !=  
             (pcistate & ~BGE_PCISTATE_RESERVED)) {  
                 aprint_error_dev(sc->bge_dev, "pcistate failed to revert\n");  
         }  
 #endif  
   
         /* Step 28: Fix up byte swapping */  
         CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS);  
   
         /* Tell the ASF firmware we are up */          bge_ape_unlock(sc, BGE_APE_LOCK_GRC);
         if (sc->bge_asf_mode & ASF_STACKUP)  
                 BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);  
   
         /*          /*
          * The 5704 in TBI mode apparently needs some special           * The 5704 in TBI mode apparently needs some special
Line 3294  bge_reset(struct bge_softc *sc)
Line 4236  bge_reset(struct bge_softc *sc)
         }          }
   
         if (sc->bge_flags & BGE_PCIE &&          if (sc->bge_flags & BGE_PCIE &&
               !BGE_IS_57765_PLUS(sc) &&
             sc->bge_chipid != BGE_CHIPID_BCM5750_A0 &&              sc->bge_chipid != BGE_CHIPID_BCM5750_A0 &&
             BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5717 &&              BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5785) {
             BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5785 &&  
             BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM57765) {  
                 uint32_t v;                  uint32_t v;
   
                 /* Enable PCI Express bug fix */                  /* Enable PCI Express bug fix */
                 v = CSR_READ_4(sc, 0x7c00);                  v = CSR_READ_4(sc, BGE_TLP_CONTROL_REG);
                 CSR_WRITE_4(sc, 0x7c00, v | (1<<25));                  CSR_WRITE_4(sc, BGE_TLP_CONTROL_REG,
                       v | BGE_TLP_DATA_FIFO_PROTECT);
         }          }
         DELAY(10000);  
           if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5720)
                   BGE_CLRBIT(sc, BGE_CPMU_CLCK_ORIDE,
                       CPMU_CLCK_ORIDE_MAC_ORIDE_EN);
   
         return 0;          return 0;
 }  }
Line 3444  bge_rxeof(struct bge_softc *sc)
Line 4389  bge_rxeof(struct bge_softc *sc)
                  */                   */
                 bpf_mtap(ifp, m);                  bpf_mtap(ifp, m);
   
                 m->m_pkthdr.csum_flags = M_CSUM_IPv4;                  bge_rxcsum(sc, cur_rx, m);
   
                 if ((cur_rx->bge_ip_csum ^ 0xffff) != 0)  
                         m->m_pkthdr.csum_flags |= M_CSUM_IPv4_BAD;  
                 /*  
                  * Rx transport checksum-offload may also  
                  * have bugs with packets which, when transmitted,  
                  * were `runts' requiring padding.  
                  */  
                 if (cur_rx->bge_flags & BGE_RXBDFLAG_TCP_UDP_CSUM &&  
                     (/* (sc->_bge_quirks & BGE_QUIRK_SHORT_CKSUM_BUG) == 0 ||*/  
                      m->m_pkthdr.len >= ETHER_MIN_NOPAD)) {  
                         m->m_pkthdr.csum_data =  
                             cur_rx->bge_tcp_udp_csum;  
                         m->m_pkthdr.csum_flags |=  
                             (M_CSUM_TCPv4|M_CSUM_UDPv4|  
                              M_CSUM_DATA);  
                 }  
   
                 /*                  /*
                  * If we received a packet with a vlan tag, pass it                   * If we received a packet with a vlan tag, pass it
Line 3483  bge_rxeof(struct bge_softc *sc)
Line 4411  bge_rxeof(struct bge_softc *sc)
 }  }
   
 static void  static void
   bge_rxcsum(struct bge_softc *sc, struct bge_rx_bd *cur_rx, struct mbuf *m)
   {
   
           if (BGE_IS_57765_PLUS(sc)) {
                   if ((cur_rx->bge_flags & BGE_RXBDFLAG_IPV6) == 0) {
                           if ((cur_rx->bge_flags & BGE_RXBDFLAG_IP_CSUM) != 0)
                                   m->m_pkthdr.csum_flags = M_CSUM_IPv4;
                           if ((cur_rx->bge_error_flag &
                                   BGE_RXERRFLAG_IP_CSUM_NOK) != 0)
                                   m->m_pkthdr.csum_flags |= M_CSUM_IPv4_BAD;
                           if (cur_rx->bge_flags & BGE_RXBDFLAG_TCP_UDP_CSUM) {
                                   m->m_pkthdr.csum_data =
                                       cur_rx->bge_tcp_udp_csum;
                                   m->m_pkthdr.csum_flags |=
                                       (M_CSUM_TCPv4|M_CSUM_UDPv4|
                                           M_CSUM_DATA);
                           }
                   }
           } else {
                   if ((cur_rx->bge_flags & BGE_RXBDFLAG_IP_CSUM) != 0)
                           m->m_pkthdr.csum_flags = M_CSUM_IPv4;
                   if ((cur_rx->bge_ip_csum ^ 0xffff) != 0)
                           m->m_pkthdr.csum_flags |= M_CSUM_IPv4_BAD;
                   /*
                    * Rx transport checksum-offload may also
                    * have bugs with packets which, when transmitted,
                    * were `runts' requiring padding.
                    */
                   if (cur_rx->bge_flags & BGE_RXBDFLAG_TCP_UDP_CSUM &&
                       (/* (sc->_bge_quirks & BGE_QUIRK_SHORT_CKSUM_BUG) == 0 ||*/
                               m->m_pkthdr.len >= ETHER_MIN_NOPAD)) {
                           m->m_pkthdr.csum_data =
                               cur_rx->bge_tcp_udp_csum;
                           m->m_pkthdr.csum_flags |=
                               (M_CSUM_TCPv4|M_CSUM_UDPv4|
                                   M_CSUM_DATA);
                   }
           }
   }
   
   static void
 bge_txeof(struct bge_softc *sc)  bge_txeof(struct bge_softc *sc)
 {  {
         struct bge_tx_bd *cur_tx = NULL;          struct bge_tx_bd *cur_tx = NULL;
Line 3560  bge_intr(void *xsc)
Line 4529  bge_intr(void *xsc)
         struct bge_softc *sc;          struct bge_softc *sc;
         struct ifnet *ifp;          struct ifnet *ifp;
         uint32_t statusword;          uint32_t statusword;
           uint32_t intrmask = BGE_PCISTATE_INTR_NOT_ACTIVE;
   
         sc = xsc;          sc = xsc;
         ifp = &sc->ethercom.ec_if;          ifp = &sc->ethercom.ec_if;
   
           /* 5717 and newer chips have no BGE_PCISTATE_INTR_NOT_ACTIVE bit */
           if (BGE_IS_5717_PLUS(sc))
                   intrmask = 0;
   
         /* It is possible for the interrupt to arrive before          /* It is possible for the interrupt to arrive before
          * the status block is updated prior to the interrupt.           * the status block is updated prior to the interrupt.
          * Reading the PCI State register will confirm whether the           * Reading the PCI State register will confirm whether the
Line 3571  bge_intr(void *xsc)
Line 4545  bge_intr(void *xsc)
          */           */
   
         /* read status word from status block */          /* read status word from status block */
           bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
               offsetof(struct bge_ring_data, bge_status_block),
               sizeof (struct bge_status_block),
               BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
         statusword = sc->bge_rdata->bge_status_block.bge_status;          statusword = sc->bge_rdata->bge_status_block.bge_status;
   
         if ((statusword & BGE_STATFLAG_UPDATED) ||          if ((statusword & BGE_STATFLAG_UPDATED) ||
             (!(CSR_READ_4(sc, BGE_PCI_PCISTATE) & BGE_PCISTATE_INTR_NOT_ACTIVE))) {              (~CSR_READ_4(sc, BGE_PCI_PCISTATE) & intrmask)) {
                 /* Ack interrupt and stop others from occuring. */                  /* Ack interrupt and stop others from occuring. */
                 bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);                  bge_writembx_flush(sc, BGE_MBX_IRQ0_LO, 1);
   
                 BGE_EVCNT_INCR(sc->bge_ev_intr);                  BGE_EVCNT_INCR(sc->bge_ev_intr);
   
Line 3614  bge_intr(void *xsc)
Line 4592  bge_intr(void *xsc)
                 bge_handle_events(sc);                  bge_handle_events(sc);
   
                 /* Re-enable interrupts. */                  /* Re-enable interrupts. */
                 bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);                  bge_writembx_flush(sc, BGE_MBX_IRQ0_LO, 0);
   
                 if (ifp->if_flags & IFF_RUNNING && !IFQ_IS_EMPTY(&ifp->if_snd))                  if (ifp->if_flags & IFF_RUNNING && !IFQ_IS_EMPTY(&ifp->if_snd))
                         bge_start(ifp);                          bge_start(ifp);
Line 3633  bge_asf_driver_up(struct bge_softc *sc)
Line 4611  bge_asf_driver_up(struct bge_softc *sc)
                         sc->bge_asf_count --;                          sc->bge_asf_count --;
                 else {                  else {
                         sc->bge_asf_count = 2;                          sc->bge_asf_count = 2;
                         bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM_FW,  
                             BGE_FW_DRV_ALIVE);                          bge_wait_for_event_ack(sc);
                         bge_writemem_ind(sc, BGE_SOFTWARE_GENNCOMM_FW_LEN, 4);  
                         bge_writemem_ind(sc, BGE_SOFTWARE_GENNCOMM_FW_DATA, 3);                          bge_writemem_ind(sc, BGE_SRAM_FW_CMD_MB,
                         CSR_WRITE_4(sc, BGE_CPU_EVENT,                              BGE_FW_CMD_DRV_ALIVE);
                             CSR_READ_4(sc, BGE_CPU_EVENT) | (1 << 14));                          bge_writemem_ind(sc, BGE_SRAM_FW_CMD_LEN_MB, 4);
                           bge_writemem_ind(sc, BGE_SRAM_FW_CMD_DATA_MB,
                               BGE_FW_HB_TIMEOUT_SEC);
                           CSR_WRITE_4_FLUSH(sc, BGE_RX_CPU_EVENT,
                               CSR_READ_4(sc, BGE_RX_CPU_EVENT) |
                               BGE_RX_CPU_DRV_EVENT);
                 }                  }
         }          }
 }  }
Line 3675  bge_tick(void *xsc)
Line 4658  bge_tick(void *xsc)
                         mii_tick(mii);                          mii_tick(mii);
         }          }
   
           bge_asf_driver_up(sc);
   
         callout_reset(&sc->bge_timeout, hz, bge_tick, sc);          callout_reset(&sc->bge_timeout, hz, bge_tick, sc);
   
         splx(s);          splx(s);
Line 3807  bge_compact_dma_runt(struct mbuf *pkt)
Line 4792  bge_compact_dma_runt(struct mbuf *pkt)
                 int shortfall = 8 - mlen ;                  int shortfall = 8 - mlen ;
   
                 totlen += mlen;                  totlen += mlen;
                 if (mlen == 0) {                  if (mlen == 0)
                         continue;                          continue;
                 }  
                 if (mlen >= 8)                  if (mlen >= 8)
                         continue;                          continue;
   
Line 3904  bge_compact_dma_runt(struct mbuf *pkt)
Line 4888  bge_compact_dma_runt(struct mbuf *pkt)
 }  }
   
 /*  /*
  * Encapsulate an mbuf chain in the tx ring  by coupling the mbuf data   * Encapsulate an mbuf chain in the tx ring by coupling the mbuf data
  * pointers to descriptors.   * pointers to descriptors.
  */   */
 static int  static int
Line 4056  doit:
Line 5040  doit:
                                            - sizeof(struct tcphdr)                                             - sizeof(struct tcphdr)
                                            - sizeof(struct ip)) >> 2;                                             - sizeof(struct ip)) >> 2;
                 }                  }
                 if (BGE_IS_5750_OR_BEYOND(sc)) {                  if (BGE_IS_575X_PLUS(sc)) {
                         th->th_sum = 0;                          th->th_sum = 0;
                         csum_flags &= ~(BGE_TXBDFLAG_TCP_UDP_CSUM);                          csum_flags &= ~(BGE_TXBDFLAG_TCP_UDP_CSUM);
                 } else {                  } else {
Line 4140  doit:
Line 5124  doit:
                  * of TSO flags and segsize.                   * of TSO flags and segsize.
                  */                   */
                 if (use_tso) {                  if (use_tso) {
                         if (BGE_IS_5750_OR_BEYOND(sc) || i == 0) {                          if (BGE_IS_575X_PLUS(sc) || i == 0) {
                                 f->bge_rsvd = maxsegsize;                                  f->bge_rsvd = maxsegsize;
                                 f->bge_flags = csum_flags | txbd_tso_flags;                                  f->bge_flags = csum_flags | txbd_tso_flags;
                         } else {                          } else {
Line 4280  bge_init(struct ifnet *ifp)
Line 5264  bge_init(struct ifnet *ifp)
 {  {
         struct bge_softc *sc = ifp->if_softc;          struct bge_softc *sc = ifp->if_softc;
         const uint16_t *m;          const uint16_t *m;
           uint32_t mode, reg;
         int s, error = 0;          int s, error = 0;
   
         s = splnet();          s = splnet();
Line 4311  bge_init(struct ifnet *ifp)
Line 5296  bge_init(struct ifnet *ifp)
   
         ifp = &sc->ethercom.ec_if;          ifp = &sc->ethercom.ec_if;
   
           /* 5718 step 25, 57XX step 54 */
         /* Specify MTU. */          /* Specify MTU. */
         CSR_WRITE_4(sc, BGE_RX_MTU, ifp->if_mtu +          CSR_WRITE_4(sc, BGE_RX_MTU, ifp->if_mtu +
             ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN);              ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN);
   
           /* 5718 step 23 */
         /* Load our MAC address. */          /* Load our MAC address. */
         m = (const uint16_t *)&(CLLADDR(ifp->if_sadl)[0]);          m = (const uint16_t *)&(CLLADDR(ifp->if_sadl)[0]);
         CSR_WRITE_4(sc, BGE_MAC_ADDR1_LO, htons(m[0]));          CSR_WRITE_4(sc, BGE_MAC_ADDR1_LO, htons(m[0]));
Line 4360  bge_init(struct ifnet *ifp)
Line 5347  bge_init(struct ifnet *ifp)
         /* Init TX ring. */          /* Init TX ring. */
         bge_init_tx_ring(sc);          bge_init_tx_ring(sc);
   
           /* 5718 step 63, 57XX step 94 */
           /* Enable TX MAC state machine lockup fix. */
           mode = CSR_READ_4(sc, BGE_TX_MODE);
           if (BGE_IS_5755_PLUS(sc) ||
               BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906)
                   mode |= BGE_TXMODE_MBUF_LOCKUP_FIX;
           if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5720) {
                   mode &= ~(BGE_TXMODE_JMB_FRM_LEN | BGE_TXMODE_CNT_DN_MODE);
                   mode |= CSR_READ_4(sc, BGE_TX_MODE) &
                       (BGE_TXMODE_JMB_FRM_LEN | BGE_TXMODE_CNT_DN_MODE);
           }
   
         /* Turn on transmitter */          /* Turn on transmitter */
         BGE_SETBIT(sc, BGE_TX_MODE, BGE_TXMODE_ENABLE);          CSR_WRITE_4_FLUSH(sc, BGE_TX_MODE, mode | BGE_TXMODE_ENABLE);
           /* 5718 step 64 */
           DELAY(100);
   
           /* 5718 step 65, 57XX step 95 */
         /* Turn on receiver */          /* Turn on receiver */
         BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_ENABLE);          mode = CSR_READ_4(sc, BGE_RX_MODE);
           if (BGE_IS_5755_PLUS(sc))
                   mode |= BGE_RXMODE_IPV6_ENABLE;
           CSR_WRITE_4_FLUSH(sc, BGE_RX_MODE, mode | BGE_RXMODE_ENABLE);
           /* 5718 step 66 */
           DELAY(10);
   
         CSR_WRITE_4(sc, BGE_MAX_RX_FRAME_LOWAT, 2);          /* 5718 step 12, 57XX step 37 */
           /*
            * XXX Doucments of 5718 series and 577xx say the recommended value
            * is 1, but tg3 set 1 only on 57765 series.
            */
           if (BGE_IS_57765_PLUS(sc))
                   reg = 1;
           else
                   reg = 2;
           CSR_WRITE_4_FLUSH(sc, BGE_MAX_RX_FRAME_LOWAT, reg);
   
         /* Tell firmware we're alive. */          /* Tell firmware we're alive. */
         BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);          BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
Line 4374  bge_init(struct ifnet *ifp)
Line 5390  bge_init(struct ifnet *ifp)
         /* Enable host interrupts. */          /* Enable host interrupts. */
         BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_CLEAR_INTA);          BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_CLEAR_INTA);
         BGE_CLRBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);          BGE_CLRBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
         bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);          bge_writembx_flush(sc, BGE_MBX_IRQ0_LO, 0);
   
         if ((error = bge_ifmedia_upd(ifp)) != 0)          if ((error = bge_ifmedia_upd(ifp)) != 0)
                 goto out;                  goto out;
Line 4422  bge_ifmedia_upd(struct ifnet *ifp)
Line 5438  bge_ifmedia_upd(struct ifnet *ifp)
                                         sgdig |= BGE_SGDIGCFG_AUTO |                                          sgdig |= BGE_SGDIGCFG_AUTO |
                                             BGE_SGDIGCFG_PAUSE_CAP |                                              BGE_SGDIGCFG_PAUSE_CAP |
                                             BGE_SGDIGCFG_ASYM_PAUSE;                                              BGE_SGDIGCFG_ASYM_PAUSE;
                                         CSR_WRITE_4(sc, BGE_SGDIG_CFG,                                          CSR_WRITE_4_FLUSH(sc, BGE_SGDIG_CFG,
                                             sgdig | BGE_SGDIGCFG_SEND);                                              sgdig | BGE_SGDIGCFG_SEND);
                                         DELAY(5);                                          DELAY(5);
                                         CSR_WRITE_4(sc, BGE_SGDIG_CFG, sgdig);                                          CSR_WRITE_4_FLUSH(sc, BGE_SGDIG_CFG,
                                               sgdig);
                                 }                                  }
                         }                          }
                         break;                          break;
Line 4437  bge_ifmedia_upd(struct ifnet *ifp)
Line 5454  bge_ifmedia_upd(struct ifnet *ifp)
                                 BGE_SETBIT(sc, BGE_MAC_MODE,                                  BGE_SETBIT(sc, BGE_MAC_MODE,
                                     BGE_MACMODE_HALF_DUPLEX);                                      BGE_MACMODE_HALF_DUPLEX);
                         }                          }
                           DELAY(40);
                         break;                          break;
                 default:                  default:
                         return EINVAL;                          return EINVAL;
Line 4598  bge_stop_block(struct bge_softc *sc, bus
Line 5616  bge_stop_block(struct bge_softc *sc, bus
 {  {
         int i;          int i;
   
         BGE_CLRBIT(sc, reg, bit);          BGE_CLRBIT_FLUSH(sc, reg, bit);
   
         for (i = 0; i < 1000; i++) {          for (i = 0; i < 1000; i++) {
                   delay(100);
                 if ((CSR_READ_4(sc, reg) & bit) == 0)                  if ((CSR_READ_4(sc, reg) & bit) == 0)
                         return;                          return;
                 delay(100);  
         }          }
   
         /*          /*
Line 4627  bge_stop(struct ifnet *ifp, int disable)
Line 5645  bge_stop(struct ifnet *ifp, int disable)
   
         callout_stop(&sc->bge_timeout);          callout_stop(&sc->bge_timeout);
   
           /* Disable host interrupts. */
           BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
           bge_writembx_flush(sc, BGE_MBX_IRQ0_LO, 1);
   
         /*          /*
          * Tell firmware we're shutting down.           * Tell firmware we're shutting down.
          */           */
         bge_stop_fw(sc);          bge_stop_fw(sc);
         bge_sig_pre_reset(sc, BGE_RESET_STOP);          bge_sig_pre_reset(sc, BGE_RESET_SHUTDOWN);
   
         /* Disable host interrupts. */  
         BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);  
         bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);  
   
         /*          /*
          * Disable all of the receiver blocks           * Disable all of the receiver blocks.
          */           */
         bge_stop_block(sc, BGE_RX_MODE, BGE_RXMODE_ENABLE);          bge_stop_block(sc, BGE_RX_MODE, BGE_RXMODE_ENABLE);
         bge_stop_block(sc, BGE_RBDI_MODE, BGE_RBDIMODE_ENABLE);          bge_stop_block(sc, BGE_RBDI_MODE, BGE_RBDIMODE_ENABLE);
Line 4650  bge_stop(struct ifnet *ifp, int disable)
Line 5668  bge_stop(struct ifnet *ifp, int disable)
         bge_stop_block(sc, BGE_RBDC_MODE, BGE_RBDCMODE_ENABLE);          bge_stop_block(sc, BGE_RBDC_MODE, BGE_RBDCMODE_ENABLE);
   
         /*          /*
          * Disable all of the transmit blocks           * Disable all of the transmit blocks.
          */           */
         bge_stop_block(sc, BGE_SRS_MODE, BGE_SRSMODE_ENABLE);          bge_stop_block(sc, BGE_SRS_MODE, BGE_SRSMODE_ENABLE);
         bge_stop_block(sc, BGE_SBDI_MODE, BGE_SBDIMODE_ENABLE);          bge_stop_block(sc, BGE_SBDI_MODE, BGE_SBDIMODE_ENABLE);
Line 4661  bge_stop(struct ifnet *ifp, int disable)
Line 5679  bge_stop(struct ifnet *ifp, int disable)
                 bge_stop_block(sc, BGE_DMAC_MODE, BGE_DMACMODE_ENABLE);                  bge_stop_block(sc, BGE_DMAC_MODE, BGE_DMACMODE_ENABLE);
         bge_stop_block(sc, BGE_SBDC_MODE, BGE_SBDCMODE_ENABLE);          bge_stop_block(sc, BGE_SBDC_MODE, BGE_SBDCMODE_ENABLE);
   
           BGE_CLRBIT_FLUSH(sc, BGE_MAC_MODE, BGE_MACMODE_TXDMA_ENB);
           delay(40);
   
           bge_stop_block(sc, BGE_TX_MODE, BGE_TXMODE_ENABLE);
   
         /*          /*
          * Shut down all of the memory managers and related           * Shut down all of the memory managers and related
          * state machines.           * state machines.
          */           */
           /* 5718 step 5a,5b */
         bge_stop_block(sc, BGE_HCC_MODE, BGE_HCCMODE_ENABLE);          bge_stop_block(sc, BGE_HCC_MODE, BGE_HCCMODE_ENABLE);
         bge_stop_block(sc, BGE_WDMA_MODE, BGE_WDMAMODE_ENABLE);          bge_stop_block(sc, BGE_WDMA_MODE, BGE_WDMAMODE_ENABLE);
         if (BGE_IS_5700_FAMILY(sc))          if (BGE_IS_5700_FAMILY(sc))
                 bge_stop_block(sc, BGE_MBCF_MODE, BGE_MBCFMODE_ENABLE);                  bge_stop_block(sc, BGE_MBCF_MODE, BGE_MBCFMODE_ENABLE);
   
           /* 5718 step 5c,5d */
         CSR_WRITE_4(sc, BGE_FTQ_RESET, 0xFFFFFFFF);          CSR_WRITE_4(sc, BGE_FTQ_RESET, 0xFFFFFFFF);
         CSR_WRITE_4(sc, BGE_FTQ_RESET, 0);          CSR_WRITE_4(sc, BGE_FTQ_RESET, 0);
   
Line 4679  bge_stop(struct ifnet *ifp, int disable)
Line 5704  bge_stop(struct ifnet *ifp, int disable)
         }          }
   
         bge_reset(sc);          bge_reset(sc);
         bge_sig_legacy(sc, BGE_RESET_STOP);          bge_sig_legacy(sc, BGE_RESET_SHUTDOWN);
         bge_sig_post_reset(sc, BGE_RESET_STOP);          bge_sig_post_reset(sc, BGE_RESET_SHUTDOWN);
   
         /*          /*
          * Keep the ASF firmware running if up.           * Keep the ASF firmware running if up.
Line 4754  bge_link_upd(struct bge_softc *sc)
Line 5779  bge_link_upd(struct bge_softc *sc)
                         /* Clear the interrupt */                          /* Clear the interrupt */
                         CSR_WRITE_4(sc, BGE_MAC_EVT_ENB,                          CSR_WRITE_4(sc, BGE_MAC_EVT_ENB,
                             BGE_EVTENB_MI_INTERRUPT);                              BGE_EVTENB_MI_INTERRUPT);
                         bge_miibus_readreg(sc->bge_dev, 1, BRGPHY_MII_ISR);                          bge_miibus_readreg(sc->bge_dev, sc->bge_phy_addr,
                         bge_miibus_writereg(sc->bge_dev, 1, BRGPHY_MII_IMR,                              BRGPHY_MII_ISR);
                             BRGPHY_INTRS);                          bge_miibus_writereg(sc->bge_dev, sc->bge_phy_addr,
                               BRGPHY_MII_IMR, BRGPHY_INTRS);
                 }                  }
                 return;                  return;
         }          }
Line 4766  bge_link_upd(struct bge_softc *sc)
Line 5792  bge_link_upd(struct bge_softc *sc)
                 if (status & BGE_MACSTAT_TBI_PCS_SYNCHED) {                  if (status & BGE_MACSTAT_TBI_PCS_SYNCHED) {
                         if (!BGE_STS_BIT(sc, BGE_STS_LINK)) {                          if (!BGE_STS_BIT(sc, BGE_STS_LINK)) {
                                 BGE_STS_SETBIT(sc, BGE_STS_LINK);                                  BGE_STS_SETBIT(sc, BGE_STS_LINK);
                                 if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704)                                  if (BGE_ASICREV(sc->bge_chipid)
                                       == BGE_ASICREV_BCM5704) {
                                         BGE_CLRBIT(sc, BGE_MAC_MODE,                                          BGE_CLRBIT(sc, BGE_MAC_MODE,
                                             BGE_MACMODE_TBI_SEND_CFGS);                                              BGE_MACMODE_TBI_SEND_CFGS);
                                           DELAY(40);
                                   }
                                 CSR_WRITE_4(sc, BGE_MAC_STS, 0xFFFFFFFF);                                  CSR_WRITE_4(sc, BGE_MAC_STS, 0xFFFFFFFF);
                                 if_link_state_change(ifp, LINK_STATE_UP);                                  if_link_state_change(ifp, LINK_STATE_UP);
                         }                          }
Line 4776  bge_link_upd(struct bge_softc *sc)
Line 5805  bge_link_upd(struct bge_softc *sc)
                         BGE_STS_CLRBIT(sc, BGE_STS_LINK);                          BGE_STS_CLRBIT(sc, BGE_STS_LINK);
                         if_link_state_change(ifp, LINK_STATE_DOWN);                          if_link_state_change(ifp, LINK_STATE_DOWN);
                 }                  }
         /*  
          * Discard link events for MII/GMII cards if MI auto-polling disabled.  
          * This should not happen since mii callouts are locked now, but  
          * we keep this check for debug.  
          */  
         } else if (BGE_STS_BIT(sc, BGE_STS_AUTOPOLL)) {          } else if (BGE_STS_BIT(sc, BGE_STS_AUTOPOLL)) {
                 /*                  /*
                  * Some broken BCM chips have BGE_STATFLAG_LINKSTATE_CHANGED                   * Some broken BCM chips have BGE_STATFLAG_LINKSTATE_CHANGED
Line 4802  bge_link_upd(struct bge_softc *sc)
Line 5826  bge_link_upd(struct bge_softc *sc)
                             IFM_SUBTYPE(mii->mii_media_active) == IFM_NONE))                              IFM_SUBTYPE(mii->mii_media_active) == IFM_NONE))
                                 BGE_STS_CLRBIT(sc, BGE_STS_LINK);                                  BGE_STS_CLRBIT(sc, BGE_STS_LINK);
                 }                  }
           } else {
                   /*
                    * For controllers that call mii_tick, we have to poll
                    * link status.
                    */
                   mii_pollstat(mii);
         }          }
   
         /* Clear the attention */          /* Clear the attention */
Line 4811  bge_link_upd(struct bge_softc *sc)
Line 5841  bge_link_upd(struct bge_softc *sc)
 }  }
   
 static int  static int
 sysctl_bge_verify(SYSCTLFN_ARGS)  bge_sysctl_verify(SYSCTLFN_ARGS)
 {  {
         int error, t;          int error, t;
         struct sysctlnode node;          struct sysctlnode node;
Line 4844  sysctl_bge_verify(SYSCTLFN_ARGS)
Line 5874  sysctl_bge_verify(SYSCTLFN_ARGS)
  * Set up sysctl(3) MIB, hw.bge.*.   * Set up sysctl(3) MIB, hw.bge.*.
  */   */
 static void  static void
 sysctl_bge_init(struct bge_softc *sc)  bge_sysctl_init(struct bge_softc *sc)
 {  {
         int rc, bge_root_num;          int rc, bge_root_num;
         const struct sysctlnode *node;          const struct sysctlnode *node;
Line 4852  sysctl_bge_init(struct bge_softc *sc)
Line 5882  sysctl_bge_init(struct bge_softc *sc)
         if ((rc = sysctl_createv(&sc->bge_log, 0, NULL, NULL,          if ((rc = sysctl_createv(&sc->bge_log, 0, NULL, NULL,
             CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,              CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
             NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0) {              NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0) {
                 goto err;                  goto out;
         }          }
   
         if ((rc = sysctl_createv(&sc->bge_log, 0, NULL, &node,          if ((rc = sysctl_createv(&sc->bge_log, 0, NULL, &node,
             0, CTLTYPE_NODE, "bge",              0, CTLTYPE_NODE, "bge",
             SYSCTL_DESCR("BGE interface controls"),              SYSCTL_DESCR("BGE interface controls"),
             NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0) {              NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0) {
                 goto err;                  goto out;
         }          }
   
         bge_root_num = node->sysctl_num;          bge_root_num = node->sysctl_num;
Line 4869  sysctl_bge_init(struct bge_softc *sc)
Line 5899  sysctl_bge_init(struct bge_softc *sc)
             CTLFLAG_READWRITE,              CTLFLAG_READWRITE,
             CTLTYPE_INT, "rx_lvl",              CTLTYPE_INT, "rx_lvl",
             SYSCTL_DESCR("BGE receive interrupt mitigation level"),              SYSCTL_DESCR("BGE receive interrupt mitigation level"),
             sysctl_bge_verify, 0,              bge_sysctl_verify, 0,
             &bge_rx_thresh_lvl,              &bge_rx_thresh_lvl,
             0, CTL_HW, bge_root_num, CTL_CREATE,              0, CTL_HW, bge_root_num, CTL_CREATE,
             CTL_EOL)) != 0) {              CTL_EOL)) != 0) {
                 goto err;                  goto out;
         }          }
   
         bge_rxthresh_nodenum = node->sysctl_num;          bge_rxthresh_nodenum = node->sysctl_num;
   
         return;          return;
   
 err:  out:
         aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);          aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
 }  }
   
Line 4890  bge_debug_info(struct bge_softc *sc)
Line 5920  bge_debug_info(struct bge_softc *sc)
 {  {
   
         printf("Hardware Flags:\n");          printf("Hardware Flags:\n");
           if (BGE_IS_57765_PLUS(sc))
                   printf(" - 57765 Plus\n");
           if (BGE_IS_5717_PLUS(sc))
                   printf(" - 5717 Plus\n");
         if (BGE_IS_5755_PLUS(sc))          if (BGE_IS_5755_PLUS(sc))
                 printf(" - 5755 Plus\n");                  printf(" - 5755 Plus\n");
         if (BGE_IS_5750_OR_BEYOND(sc))          if (BGE_IS_575X_PLUS(sc))
                 printf(" - 5750 Plus\n");                  printf(" - 575X Plus\n");
         if (BGE_IS_5705_PLUS(sc))          if (BGE_IS_5705_PLUS(sc))
                 printf(" - 5705 Plus\n");                  printf(" - 5705 Plus\n");
         if (BGE_IS_5714_FAMILY(sc))          if (BGE_IS_5714_FAMILY(sc))
Line 4910  bge_debug_info(struct bge_softc *sc)
Line 5944  bge_debug_info(struct bge_softc *sc)
                 printf(" - PCI-X Bus\n");                  printf(" - PCI-X Bus\n");
         if (sc->bge_flags & BGE_PCIE)          if (sc->bge_flags & BGE_PCIE)
                 printf(" - PCI Express Bus\n");                  printf(" - PCI Express Bus\n");
         if (sc->bge_flags & BGE_NO_3LED)  
                 printf(" - No 3 LEDs\n");  
         if (sc->bge_flags & BGE_RX_ALIGNBUG)          if (sc->bge_flags & BGE_RX_ALIGNBUG)
                 printf(" - RX Alignment Bug\n");                  printf(" - RX Alignment Bug\n");
           if (sc->bge_flags & BGE_APE)
                   printf(" - APE\n");
           if (sc->bge_flags & BGE_CPMU_PRESENT)
                   printf(" - CPMU\n");
         if (sc->bge_flags & BGE_TSO)          if (sc->bge_flags & BGE_TSO)
                 printf(" - TSO\n");                  printf(" - TSO\n");
   
           if (sc->bge_flags & BGE_PHY_NO_3LED)
                   printf(" - No 3 LEDs\n");
           if (sc->bge_flags & BGE_PHY_CRC_BUG)
                   printf(" - CRC bug\n");
           if (sc->bge_flags & BGE_PHY_ADC_BUG)
                   printf(" - ADC bug\n");
           if (sc->bge_flags & BGE_PHY_5704_A0_BUG)
                   printf(" - 5704 A0 bug\n");
           if (sc->bge_flags & BGE_PHY_JITTER_BUG)
                   printf(" - jitter bug\n");
           if (sc->bge_flags & BGE_PHY_BER_BUG)
                   printf(" - BER bug\n");
           if (sc->bge_flags & BGE_PHY_ADJUST_TRIM)
                   printf(" - adjust trim\n");
           if (sc->bge_flags & BGE_PHY_NO_WIRESPEED)
                   printf(" - no wirespeed\n");
 }  }
 #endif /* BGE_DEBUG */  #endif /* BGE_DEBUG */
   
Line 4945  bge_get_eaddr_mem(struct bge_softc *sc, 
Line 5998  bge_get_eaddr_mem(struct bge_softc *sc, 
 {  {
         uint32_t mac_addr;          uint32_t mac_addr;
   
         mac_addr = bge_readmem_ind(sc, 0x0c14);          mac_addr = bge_readmem_ind(sc, BGE_SRAM_MAC_ADDR_HIGH_MB);
         if ((mac_addr >> 16) == 0x484b) {          if ((mac_addr >> 16) == 0x484b) {
                 ether_addr[0] = (uint8_t)(mac_addr >> 8);                  ether_addr[0] = (uint8_t)(mac_addr >> 8);
                 ether_addr[1] = (uint8_t)mac_addr;                  ether_addr[1] = (uint8_t)mac_addr;
                 mac_addr = bge_readmem_ind(sc, 0x0c18);                  mac_addr = bge_readmem_ind(sc, BGE_SRAM_MAC_ADDR_LOW_MB);
                 ether_addr[2] = (uint8_t)(mac_addr >> 24);                  ether_addr[2] = (uint8_t)(mac_addr >> 24);
                 ether_addr[3] = (uint8_t)(mac_addr >> 16);                  ether_addr[3] = (uint8_t)(mac_addr >> 16);
                 ether_addr[4] = (uint8_t)(mac_addr >> 8);                  ether_addr[4] = (uint8_t)(mac_addr >> 8);

Legend:
Removed from v.1.200  
changed lines
  Added in v.1.200.2.2

CVSweb <webmaster@jp.NetBSD.org>