Re: Broadcom Netlink BCM5906M

From: Ayhan Molla <molla5_at_yahoo.com>
Date: Sat, 1 Mar 2008 09:45:59 -0800 (PST)
Thank you very much, it works beautifully now. However I also needed to add the follwing lines to the 
/usr/src/sys/dev/mii/miidevs 
file, I copied them from dragonflyBSD source.

oui BROADCOM2                  0x000af7        Broadcom2 Corporation
oui xxBROADCOM2              0x000af7        Broadcom Corporation

model BROADCOM2 BCM5906        0x0004 BCM5906 10/100/1000baseTX PHY
model xxBROADCOM2 BCM5906      0x0004 BCM5906 10/100/1000baseTX PHY

Thank you very much again.



Thomas Nyström <thn_at_saeab.se> wrote: Ayhan Molla wrote:
> Hi,
> I am having trouble applying the patch for the BCM5906. The patch is
> supposed to work for 7.0-RC1. I have installed 7.0-Release and patch
> didn't work for me.
>  if_bge.c file has changed since RC1 and therefore I wasn't able to
> manually apply the patch.
> 
> Has someone tried to apply the patch for 7.0-Release?

Try the new attached (untested) patch!

/Thomas

-- 
---------------------------------------------------------------
Svensk Aktuell Elektronik AB                     Thomas Nyström
Box 10                                  Phone: +46 73 069 69 30
S-191 21  Sollentuna                        Fax: +46 8 35 92 89
Sweden                                      Email: thn_at_saeab.se
---------------------------------------------------------------
--- ./sys/dev/bge/if_bge.c.70 2008-03-01 15:03:15.000000000 +0100
+++ ./sys/dev/bge/if_bge.c 2008-03-01 15:00:22.000000000 +0100
_at__at_ -195,6 +195,8 _at__at_
  { BCOM_VENDORID, BCOM_DEVICEID_BCM5901 },
  { BCOM_VENDORID, BCOM_DEVICEID_BCM5901A2 },
  { BCOM_VENDORID, BCOM_DEVICEID_BCM5903M },
+ { BCOM_VENDORID, BCOM_DEVICEID_BCM5906 },
+ { BCOM_VENDORID, BCOM_DEVICEID_BCM5906M },
 
  { SK_VENDORID,  SK_DEVICEID_ALTIMA },
 
_at__at_ -271,6 +273,8 _at__at_
  { BGE_CHIPID_BCM5787_A0, "BCM5754/5787 A0" }, 
  { BGE_CHIPID_BCM5787_A1, "BCM5754/5787 A1" },
  { BGE_CHIPID_BCM5787_A2, "BCM5754/5787 A2" },
+ { BGE_CHIPID_BCM5906_A1, "BCM5906 A1" },
+ { BGE_CHIPID_BCM5906_A2, "BCM5906 A2" },
 
  { 0, NULL }
 };
_at__at_ -293,6 +297,7 _at__at_
  { BGE_ASICREV_BCM5755,  "unknown BCM5755" },
  /* 5754 and 5787 share the same ASIC ID */
  { BGE_ASICREV_BCM5787,  "unknown BCM5754/5787" },
+ { BGE_ASICREV_BCM5906,  "unknown BCM5906" },
 
  { 0, NULL }
 };
_at__at_ -305,6 +310,9 _at__at_
 
 const struct bge_revision * bge_lookup_rev(uint32_t);
 const struct bge_vendor * bge_lookup_vendor(uint16_t);
+
+typedef int (*bge_eaddr_fcn_t)(struct bge_softc *, uint8_t[]);
+
 static int bge_probe(device_t);
 static int bge_attach(device_t);
 static int bge_detach(device_t);
_at__at_ -315,6 +323,11 _at__at_
 static int bge_dma_alloc(device_t);
 static void bge_dma_free(struct bge_softc *);
 
+static int bge_get_eaddr_mem(struct bge_softc *, uint8_t[]);
+static int bge_get_eaddr_nvram(struct bge_softc *, uint8_t[]);
+static int bge_get_eaddr_eeprom(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_rxeof(struct bge_softc *);
 
_at__at_ -337,6 +350,9 _at__at_
 static int bge_ifmedia_upd(struct ifnet *);
 static void bge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 
+static uint8_t bge_nvram_getbyte(struct bge_softc *, int, uint8_t *);
+static int bge_read_nvram(struct bge_softc *, caddr_t, int, int);
+
 static uint8_t bge_eeprom_getbyte(struct bge_softc *, int, uint8_t *);
 static int bge_read_eeprom(struct bge_softc *, caddr_t, int, int);
 
_at__at_ -359,6 +375,7 _at__at_
 static int bge_has_eeprom(struct bge_softc *);
 static uint32_t bge_readmem_ind(struct bge_softc *, int);
 static void bge_writemem_ind(struct bge_softc *, int, int);
+static void bge_writembx(struct bge_softc *, int, int);
 #ifdef notdef
 static uint32_t bge_readreg_ind(struct bge_softc *, int);
 #endif
_at__at_ -474,6 +491,10 _at__at_
    return (0);
  }
 #endif
+
+ if (sc->bge_asicrev == BGE_ASICREV_BCM5906)
+  return (0);
+
  return (1);
 }
 
_at__at_ -533,6 +554,15 _at__at_
  CSR_WRITE_4(sc, off, val);
 }
 
+static void
+bge_writembx(struct bge_softc *sc, int off, int val)
+{
+ if (sc->bge_asicrev == BGE_ASICREV_BCM5906)
+  off += BGE_LPMBX_IRQ0_HI - BGE_MBX_IRQ0_HI;
+
+ CSR_WRITE_4(sc, off, val);
+}
+
 /*
  * Map a single buffer address.
  */
_at__at_ -555,6 +585,78 _at__at_
  ctx->bge_busaddr = segs->ds_addr;
 }
 
+static uint8_t
+bge_nvram_getbyte(struct bge_softc *sc, int addr, uint8_t *dest)
+{
+ uint32_t access, byte = 0;
+ int i;
+
+ /* Lock. */
+ 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)
+  return (1);
+
+ /* Enable access. */
+ access = CSR_READ_4(sc, BGE_NVRAM_ACCESS);
+ CSR_WRITE_4(sc, BGE_NVRAM_ACCESS, access | BGE_NVRAMACC_ENABLE);
+
+ CSR_WRITE_4(sc, BGE_NVRAM_ADDR, addr & 0xfffffffc);
+ CSR_WRITE_4(sc, BGE_NVRAM_CMD, BGE_NVRAM_READCMD);
+ for (i = 0; i < BGE_TIMEOUT * 10; i++) {
+  DELAY(10);
+  if (CSR_READ_4(sc, BGE_NVRAM_CMD) & BGE_NVRAMCMD_DONE) {
+   DELAY(10);
+   break;
+  }
+ }
+
+ if (i == BGE_TIMEOUT * 10) {
+  if_printf(sc->bge_ifp, "nvram read timed out\n");
+  return (1);
+ }
+
+ /* Get result. */
+ byte = CSR_READ_4(sc, BGE_NVRAM_RDDATA);
+
+ *dest = (bswap32(byte) >> ((addr % 4) * 8)) & 0xFF;
+
+ /* Disable access. */
+ CSR_WRITE_4(sc, BGE_NVRAM_ACCESS, access);
+
+ /* Unlock. */
+ CSR_WRITE_4(sc, BGE_NVRAM_SWARB, BGE_NVRAMSWARB_CLR1);
+ CSR_READ_4(sc, BGE_NVRAM_SWARB);
+
+ return (0);
+}
+
+/*
+ * Read a sequence of bytes from NVRAM.
+ */
+static int
+bge_read_nvram(struct bge_softc *sc, caddr_t dest, int off, int cnt)
+{
+ int err = 0, i;
+ uint8_t byte = 0;
+
+ if (sc->bge_asicrev != BGE_ASICREV_BCM5906)
+  return (1);
+
+ for (i = 0; i < cnt; i++) {
+  err = bge_nvram_getbyte(sc, off + i, &byte);
+  if (err)
+   break;
+  *(dest + i) = byte;
+ }
+
+ return (err ? 1 : 0);
+}
+
 /*
  * Read a byte of data stored in the EEPROM at address 'addr.' The
  * BCM570x supports both the traditional bitbang interface and an
_at__at_ -659,11 +761,13 _at__at_
  }
 
  if (i == BGE_TIMEOUT) {
-  device_printf(sc->bge_dev, "PHY read timed out\n");
+  device_printf(sc->bge_dev, "PHY read timed out "
+     "(phy %d, reg %d, val 0x%08x)\n", phy, reg, val);
   val = 0;
   goto done;
  }
 
+ DELAY(5);
  val = CSR_READ_4(sc, BGE_MI_COMM);
 
 done:
_at__at_ -687,6 +791,10 _at__at_
 
  sc = device_get_softc(dev);
 
+ if (sc->bge_asicrev == BGE_ASICREV_BCM5906 &&
+     (reg == BRGPHY_MII_1000CTL || reg == BRGPHY_MII_AUXCTL))
+  return(0);
+
  /* Reading with autopolling on may trigger PCI errors */
  autopoll = CSR_READ_4(sc, BGE_MI_MODE);
  if (autopoll & BGE_MIMODE_AUTOPOLL) {
_at__at_ -699,12 +807,17 _at__at_
 
  for (i = 0; i < BGE_TIMEOUT; i++) {
   DELAY(10);
-  if (!(CSR_READ_4(sc, BGE_MI_COMM) & BGE_MICOMM_BUSY))
+  if (!(CSR_READ_4(sc, BGE_MI_COMM) & BGE_MICOMM_BUSY)) {
+   DELAY(5);
+   CSR_READ_4(sc, BGE_MI_COMM); /* dummy read */
    break;
+  }
  }
 
  if (i == BGE_TIMEOUT) {
-  device_printf(sc->bge_dev, "PHY write timed out\n");
+  device_printf(sc->bge_dev,
+     "PHY write timed out (phy %d, reg %d, val %d)\n",
+     phy, reg, val);
   return (0);
  }
 
_at__at_ -887,7 +1000,7 _at__at_
      BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
  sc->bge_std = i - 1;
- CSR_WRITE_4(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
+ bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
 
  return (0);
 }
_at__at_ -934,7 +1047,7 _at__at_
         BGE_RCB_FLAG_USE_EXT_RX_BD);
  CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_MAXLEN_FLAGS, rcb->bge_maxlen_flags);
 
- CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
+ bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
 
  return (0);
 }
_at__at_ -990,17 +1103,17 _at__at_
 
  /* Initialize transmit producer index for host-memory send ring. */
  sc->bge_tx_prodidx = 0;
- CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
+ bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
 
  /* 5700 b2 errata */
  if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
-  CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
+  bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
 
  /* NIC-memory send ring not used; initialize to zero. */
- CSR_WRITE_4(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
+ bge_writembx(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
  /* 5700 b2 errata */
  if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
-  CSR_WRITE_4(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
+  bge_writembx(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
 
  return (0);
 }
_at__at_ -1271,6 +1384,15 _at__at_
  /* Set the timer prescaler (always 66Mhz) */
  CSR_WRITE_4(sc, BGE_MISC_CFG, BGE_32BITTIME_66MHZ);
 
+ if (sc->bge_asicrev == BGE_ASICREV_BCM5906) {
+  DELAY(40); /* XXX */
+
+  /* Put PHY into ready state */
+  BGE_CLRBIT(sc, BGE_MISC_CFG, BGE_MISCCFG_EPHY_IDDQ);
+  CSR_READ_4(sc, BGE_MISC_CFG); /* Flush */
+  DELAY(40);
+ }
+
  return (0);
 }
 
_at__at_ -1307,15 +1429,21 _at__at_
   CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_LEN, 0x2000);
  }
 
+
  /* Configure mbuf pool watermarks */
- if (BGE_IS_5705_PLUS(sc)) {
-  CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);
-  CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x10);
- } else {
+ if (!BGE_IS_5705_PLUS(sc)) {
   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 if (sc->bge_asicrev == 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 {
+  CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);
+  CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x10);
+  CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60);
  }
- CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60);
 
  /* Configure DMA resource watermarks */
  CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_LOWAT, 5);
_at__at_ -1462,15 +1590,15 _at__at_
       BGE_RCB_MAXLEN_FLAGS(sc->bge_return_ring_cnt,
       BGE_RCB_FLAG_RING_DISABLED));
   RCB_WRITE_4(sc, vrcb, bge_nicaddr, 0);
-  CSR_WRITE_4(sc, BGE_MBX_RX_CONS0_LO +
+  bge_writembx(sc, BGE_MBX_RX_CONS0_LO +
       (i * (sizeof(uint64_t))), 0);
   vrcb += sizeof(struct bge_rcb);
  }
 
  /* Initialize RX ring indexes */
- CSR_WRITE_4(sc, BGE_MBX_RX_STD_PROD_LO, 0);
- CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, 0);
- CSR_WRITE_4(sc, BGE_MBX_RX_MINI_PROD_LO, 0);
+ 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
_at__at_ -2230,7 +2358,6 _at__at_
  struct ifnet *ifp;
  struct bge_softc *sc;
  uint32_t hwcfg = 0;
- uint32_t mac_tmp = 0;
  u_char eaddr[ETHER_ADDR_LEN];
  int error, reg, rid, trys;
 
_at__at_ -2283,6 +2410,7 _at__at_
  case BGE_ASICREV_BCM5752:
  case BGE_ASICREV_BCM5755:
  case BGE_ASICREV_BCM5787:
+ case BGE_ASICREV_BCM5906:
   sc->bge_flags |= BGE_FLAG_575X_PLUS;
   /* FALLTHRU */
  case BGE_ASICREV_BCM5705:
_at__at_ -2304,7 +2432,7 _at__at_
   if (sc->bge_asicrev == BGE_ASICREV_BCM5755 ||
       sc->bge_asicrev == BGE_ASICREV_BCM5787)
    sc->bge_flags |= BGE_FLAG_JITTER_BUG;
-  else
+  else if (sc->bge_asicrev != BGE_ASICREV_BCM5906)
    sc->bge_flags |= BGE_FLAG_BER_BUG;
  }
 
_at__at_ -2415,22 +2543,14 _at__at_
  }
 
 #ifdef __sparc64__
- if ((sc->bge_flags & BGE_FLAG_EEPROM) == 0)
+ if (((sc->bge_flags & BGE_FLAG_EEPROM) == 0) &&
+     (sc->bge_asicrev != BGE_ASICREV_BCM5906))
   OF_getetheraddr(dev, eaddr);
  else
 #endif
  {
-  mac_tmp = bge_readmem_ind(sc, 0x0C14);
-  if ((mac_tmp >> 16) == 0x484B) {
-   eaddr[0] = (u_char)(mac_tmp >> 8);
-   eaddr[1] = (u_char)mac_tmp;
-   mac_tmp = bge_readmem_ind(sc, 0x0C18);
-   eaddr[2] = (u_char)(mac_tmp >> 24);
-   eaddr[3] = (u_char)(mac_tmp >> 16);
-   eaddr[4] = (u_char)(mac_tmp >> 8);
-   eaddr[5] = (u_char)mac_tmp;
-  } else if (bge_read_eeprom(sc, eaddr,
-      BGE_EE_MAC_OFFSET + 2, ETHER_ADDR_LEN)) {
+  error = bge_get_eaddr(sc, eaddr);
+  if (error) {
    device_printf(sc->bge_dev,
        "failed to read station address\n");
    error = ENXIO;
_at__at_ -2688,7 +2808,8 _at__at_
 
  dev = sc->bge_dev;
 
- if (BGE_IS_575X_PLUS(sc) && !BGE_IS_5714_FAMILY(sc)) {
+ if (BGE_IS_575X_PLUS(sc) && !BGE_IS_5714_FAMILY(sc) &&
+     (sc->bge_asicrev != BGE_ASICREV_BCM5906)) {
   if (sc->bge_flags & BGE_FLAG_PCIE)
    write_op = bge_writemem_direct;
   else
_at__at_ -2744,6 +2865,17 _at__at_
  /* Issue global reset */
  write_op(sc, BGE_MISC_CFG, reset);
 
+ if (sc->bge_asicrev == BGE_ASICREV_BCM5906) {
+  uint32_t status, ctrl;
+
+  status = CSR_READ_4(sc, BGE_VCPU_STATUS);
+  CSR_WRITE_4(sc, BGE_VCPU_STATUS,
+      status | BGE_VCPU_STATUS_DRV_RESET);
+  ctrl = CSR_READ_4(sc, BGE_VCPU_EXT_CTRL);
+  CSR_WRITE_4(sc, BGE_VCPU_EXT_CTRL,
+      ctrl & ~BGE_VCPU_EXT_CTRL_HALT_CPU);
+ }
+
  DELAY(1000);
 
  /* XXX: Broadcom Linux driver. */
_at__at_ -2788,21 +2920,34 _at__at_
  } else
   CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE);
 
- /*
-  * Poll until we see the 1's complement of the magic number.
-  * This indicates that the firmware initialization is complete.
-  * We expect this to fail if no EEPROM is fitted though.
-  */
- for (i = 0; i < BGE_TIMEOUT; i++) {
-  DELAY(10);
-  val = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM);
-  if (val == ~BGE_MAGIC_NUMBER)
-   break;
- }
+ if (sc->bge_asicrev == BGE_ASICREV_BCM5906) {
+  for (i = 0; i < BGE_TIMEOUT; i++) {
+   val = CSR_READ_4(sc, BGE_VCPU_STATUS);
+   if (val & BGE_VCPU_STATUS_INIT_DONE)
+    break;
+   DELAY(100);
+  }
+  if (i == BGE_TIMEOUT) {
+   device_printf(sc->bge_dev, "reset timed out\n");
+   return (1);
+  }
+ } else {
+  /*
+   * Poll until we see the 1's complement of the magic number.
+   * This indicates that the firmware initialization is complete.
+   * We expect this to fail if no EEPROM is fitted though.
+   */
+  for (i = 0; i < BGE_TIMEOUT; i++) {
+   DELAY(10);
+   val = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM);
+   if (val == ~BGE_MAGIC_NUMBER)
+    break;
+  }
 
- if ((sc->bge_flags & BGE_FLAG_EEPROM) && i == BGE_TIMEOUT)
-  device_printf(sc->bge_dev, "firmware handshake timed out, "
-      "found 0x%08x\n", val);
+  if ((sc->bge_flags & BGE_FLAG_EEPROM) && i == BGE_TIMEOUT)
+   device_printf(sc->bge_dev, "firmware handshake timed out, "
+       "found 0x%08x\n", val);
+ }
 
  /*
   * XXX Wait for the value of the PCISTATE register to
_at__at_ -3022,11 +3167,11 _at__at_
   bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag,
       sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_PREWRITE);
 
- CSR_WRITE_4(sc, BGE_MBX_RX_CONS0_LO, sc->bge_rx_saved_considx);
+ bge_writembx(sc, BGE_MBX_RX_CONS0_LO, sc->bge_rx_saved_considx);
  if (stdcnt)
-  CSR_WRITE_4(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
+  bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
  if (jumbocnt)
-  CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
+  bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
 #ifdef notyet
  /*
   * This register wraps very quickly under heavy packet drops.
_at__at_ -3168,7 +3313,7 _at__at_
   * the status check).  So toggling would probably be a pessimization
   * even with MSI.  It would only be needed for using a task queue.
   */
- CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0);
+ bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
 
  /*
   * Do the mandatory PCI flush as well as get the link status.
_at__at_ -3545,10 +3690,10 _at__at_
   return;
 
  /* Transmit. */
- CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
+ bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
  /* 5700 b2 errata */
  if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
-  CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
+  bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
 
  sc->bge_tx_prodidx = prodidx;
 
_at__at_ -3675,7 +3820,7 _at__at_
  if (ifp->if_capenable & IFCAP_POLLING) {
   BGE_SETBIT(sc, BGE_PCI_MISC_CTL,
       BGE_PCIMISCCTL_MASK_PCI_INTR);
-  CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1);
+  bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
  } else
 #endif
 
_at__at_ -3683,7 +3828,7 _at__at_
  {
  BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_CLEAR_INTA);
  BGE_CLRBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
- CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0);
+ bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
  }
  
  bge_ifmedia_upd_locked(ifp);
_at__at_ -3906,7 +4051,7 _at__at_
     BGE_LOCK(sc);
     BGE_SETBIT(sc, BGE_PCI_MISC_CTL,
         BGE_PCIMISCCTL_MASK_PCI_INTR);
-    CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1);
+    bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
     ifp->if_capenable |= IFCAP_POLLING;
     BGE_UNLOCK(sc);
    } else {
_at__at_ -3915,7 +4060,7 _at__at_
     BGE_LOCK(sc);
     BGE_CLRBIT(sc, BGE_PCI_MISC_CTL,
         BGE_PCIMISCCTL_MASK_PCI_INTR);
-    CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0);
+    bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
     ifp->if_capenable &= ~IFCAP_POLLING;
     BGE_UNLOCK(sc);
    }
_at__at_ -4040,7 +4185,7 _at__at_
 
  /* Disable host interrupts. */
  BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
- CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1);
+ bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
 
  /*
   * Tell firmware we're shutting down.
_at__at_ -4536,3 +4681,64 _at__at_
  return (error);
 }
 #endif
+
+static int
+bge_get_eaddr_mem(struct bge_softc *sc, uint8_t ether_addr[])
+{
+ uint32_t mac_addr;
+ int ret = 1;
+
+ mac_addr = bge_readmem_ind(sc, 0x0c14);
+ if ((mac_addr >> 16) == 0x484b) {
+  ether_addr[0] = (uint8_t)(mac_addr >> 8);
+  ether_addr[1] = (uint8_t)mac_addr;
+  mac_addr = bge_readmem_ind(sc, 0x0c18);
+  ether_addr[2] = (uint8_t)(mac_addr >> 24);
+  ether_addr[3] = (uint8_t)(mac_addr >> 16);
+  ether_addr[4] = (uint8_t)(mac_addr >> 8);
+  ether_addr[5] = (uint8_t)mac_addr;
+  ret = 0;
+ }
+ return ret;
+}
+
+static int
+bge_get_eaddr_nvram(struct bge_softc *sc, uint8_t ether_addr[])
+{
+ int mac_offset = BGE_EE_MAC_OFFSET;
+
+ if (sc->bge_asicrev == BGE_ASICREV_BCM5906)
+  mac_offset = BGE_EE_MAC_OFFSET_5906;
+
+ return bge_read_nvram(sc, ether_addr, mac_offset + 2, ETHER_ADDR_LEN);
+}
+
+static int
+bge_get_eaddr_eeprom(struct bge_softc *sc, uint8_t ether_addr[])
+{
+ if (!(sc->bge_flags & BGE_FLAG_EEPROM))
+  return 1;
+
+ return bge_read_eeprom(sc, ether_addr, BGE_EE_MAC_OFFSET + 2,
+          ETHER_ADDR_LEN);
+}
+
+static int
+bge_get_eaddr(struct bge_softc *sc, uint8_t eaddr[])
+{
+ static const bge_eaddr_fcn_t bge_eaddr_funcs[] = {
+  /* NOTE: Order is critical */
+  bge_get_eaddr_mem,
+  bge_get_eaddr_nvram,
+  bge_get_eaddr_eeprom,
+  NULL
+ };
+ const bge_eaddr_fcn_t *func;
+
+ for (func = bge_eaddr_funcs; *func != NULL; ++func) {
+  if ((*func)(sc, eaddr) == 0)
+   break;
+ }
+ return (*func == NULL ? ENXIO : 0);
+}
+
--- ./sys/dev/bge/if_bgereg.h.orig 2007-05-22 21:22:58.000000000 +0200
+++ ./sys/dev/bge/if_bgereg.h 2008-03-01 14:55:49.000000000 +0100
_at__at_ -283,6 +283,8 _at__at_
 #define BGE_CHIPID_BCM5787_A0  0xb0000000
 #define BGE_CHIPID_BCM5787_A1  0xb0010000
 #define BGE_CHIPID_BCM5787_A2  0xb0020000
+#define BGE_CHIPID_BCM5906_A1  0xc0010000
+#define BGE_CHIPID_BCM5906_A2  0xc0020000
 
 /* shorthand one */
 #define BGE_ASICREV(x)   ((x) >> 28)
_at__at_ -299,6 +301,7 _at__at_
 #define BGE_ASICREV_BCM5755  0x0a
 #define BGE_ASICREV_BCM5754  0x0b
 #define BGE_ASICREV_BCM5787  0x0b
+#define BGE_ASICREV_BCM5906  0x0c
 
 /* chip revisions */
 #define BGE_CHIPREV(x)   ((x) >> 24)
_at__at_ -1438,6 +1441,17 _at__at_
 #define BGE_RXCPUSTAT_MA_REQ_FIFOOFLOW 0x40000000
 #define BGE_RXCPUSTAT_BLOCKING_READ 0x80000000
 
+/*
+ * V? CPU registers
+ */
+#define BGE_VCPU_STATUS   0x5100
+#define BGE_VCPU_EXT_CTRL  0x6890
+
+#define BGE_VCPU_STATUS_INIT_DONE 0x04000000
+#define BGE_VCPU_STATUS_DRV_RESET  0x08000000
+
+#define BGE_VCPU_EXT_CTRL_HALT_CPU 0x00400000
+#define BGE_VCPU_EXT_CTRL_DISABLE_WOL 0x20000000
 
 /*
  * TX CPU registers
_at__at_ -1683,6 +1697,55 _at__at_
 #define BGE_MDI_CTL   0x6844
 #define BGE_EE_DELAY   0x6848
 #define BGE_FASTBOOT_PC   0x6894
+/*
+ * NVRAM Control registers
+ */
+#define BGE_NVRAM_CMD   0x7000
+#define BGE_NVRAM_STAT   0x7004
+#define BGE_NVRAM_WRDATA  0x7008
+#define BGE_NVRAM_ADDR   0x700c
+#define BGE_NVRAM_RDDATA  0x7010
+#define BGE_NVRAM_CFG1   0x7014
+#define BGE_NVRAM_CFG2   0x7018
+#define BGE_NVRAM_CFG3   0x701c
+#define BGE_NVRAM_SWARB   0x7020
+#define BGE_NVRAM_ACCESS  0x7024
+#define BGE_NVRAM_WRITE1  0x7028
+
+#define BGE_NVRAMCMD_RESET  0x00000001
+#define BGE_NVRAMCMD_DONE  0x00000008
+#define BGE_NVRAMCMD_START  0x00000010
+#define BGE_NVRAMCMD_WR   0x00000020 /* 1 = wr, 0 = rd */
+#define BGE_NVRAMCMD_ERASE  0x00000040
+#define BGE_NVRAMCMD_FIRST  0x00000080
+#define BGE_NVRAMCMD_LAST  0x00000100
+
+#define BGE_NVRAM_READCMD \
+ (BGE_NVRAMCMD_FIRST|BGE_NVRAMCMD_LAST| \
+ BGE_NVRAMCMD_START|BGE_NVRAMCMD_DONE)
+#define BGE_NVRAM_WRITECMD \
+ (BGE_NVRAMCMD_FIRST|BGE_NVRAMCMD_LAST| \
+ BGE_NVRAMCMD_START|BGE_NVRAMCMD_DONE|BGE_NVRAMCMD_WR)
+
+#define BGE_NVRAMSWARB_SET0  0x00000001
+#define BGE_NVRAMSWARB_SET1  0x00000002
+#define BGE_NVRAMSWARB_SET2  0x00000003
+#define BGE_NVRAMSWARB_SET3  0x00000004
+#define BGE_NVRAMSWARB_CLR0  0x00000010
+#define BGE_NVRAMSWARB_CLR1  0x00000020
+#define BGE_NVRAMSWARB_CLR2  0x00000040
+#define BGE_NVRAMSWARB_CLR3  0x00000080
+#define BGE_NVRAMSWARB_GNT0  0x00000100
+#define BGE_NVRAMSWARB_GNT1  0x00000200
+#define BGE_NVRAMSWARB_GNT2  0x00000400
+#define BGE_NVRAMSWARB_GNT3  0x00000800
+#define BGE_NVRAMSWARB_REQ0  0x00001000
+#define BGE_NVRAMSWARB_REQ1  0x00002000
+#define BGE_NVRAMSWARB_REQ2  0x00004000
+#define BGE_NVRAMSWARB_REQ3  0x00008000
+
+#define BGE_NVRAMACC_ENABLE  0x00000001
+#define BGE_NVRAMACC_WRENABLE  0x00000002
 
 /* Mode control register */
 #define BGE_MODECTL_INT_SNDCOAL_ONLY 0x00000001
_at__at_ -1711,6 +1774,7 _at__at_
 /* Misc. config register */
 #define BGE_MISCCFG_RESET_CORE_CLOCKS 0x00000001
 #define BGE_MISCCFG_TIMER_PRESCALER 0x000000FE
+#define BGE_MISCCFG_EPHY_IDDQ  0x00200000
 
 #define BGE_32BITTIME_66MHZ  (0x41 << 1)
 
_at__at_ -2037,6 +2101,8 _at__at_
 #define BCOM_DEVICEID_BCM5901  0x170D
 #define BCOM_DEVICEID_BCM5901A2  0x170E
 #define BCOM_DEVICEID_BCM5903M  0x16FF
+#define BCOM_DEVICEID_BCM5906  0x1712
+#define BCOM_DEVICEID_BCM5906M  0x1713
 
 /*
  * Alteon AceNIC PCI vendor/device ID.

=== message truncated ===

       
---------------------------------
Be a better friend, newshound, and know-it-all with Yahoo! Mobile.  Try it now.
--- /usr/src/sys/dev/mii/miidevs	2007-11-05 01:42:02.000000000 +0000
+++ /usr/src/sys/dev/mii/miidevs	2008-02-29 19:31:15.000000000 +0000
_at__at_ -52,6 +52,7 _at__at_
 oui ALTIMA			0x0010a9	Altima Communications
 oui AMD			0x00001a	Advanced Micro Devices
 oui BROADCOM			0x001018	Broadcom Corporation
+oui BROADCOM2	                0x000af7 	Broadcom2 Corporation
 oui CICADA			0x0003F1	Cicada Semiconductor
 oui DAVICOM			0x00606e	Davicom Semiconductor
 oui ICPLUS			0x0090c3	IC Plus Corp.
_at__at_ -80,6 +81,7 _at__at_
 /* some vendors have the bits swapped within bytes
 	(ie, ordered as on the wire) */
 oui xxALTIMA			0x000895	Altima Communications
+oui xxBROADCOM2	                0x000af7 	Broadcom Corporation
 oui xxBROADCOM			0x000818	Broadcom Corporation
 oui xxBROADCOM_ALT1		0x0050ef	Broadcom Corporation
 oui xxICS			0x00057d	Integrated Circuit Systems
_at__at_ -136,6 +138,8 _at__at_
 model xxBROADCOM_ALT1 BCM5787	0x000e BCM5787 10/100/1000baseTX PHY
 model xxBROADCOM_ALT1 BCM5708S	0x0015 BCM5708S 1000/2500BaseSX PHY
 
+model BROADCOM2 BCM5906	0x0004 BCM5906 10/100/1000baseTX PHY 
+model xxBROADCOM2 BCM5906	0x0004 BCM5906 10/100/1000baseTX PHY 
 /* Cicada Semiconductor PHYs (now owned by Vitesse?) */
 model CICADA CS8201		0x0001 Cicada CS8201 10/100/1000TX PHY
 model CICADA CS8201A		0x0020 Cicada CS8201 10/100/1000TX PHY
Received on Sat Mar 01 2008 - 16:46:00 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:28 UTC