opensubscriber
   Find in this group all groups
 
Unknown more information…

f : freebsd-net@freebsd.org 2 March 2008 • 3:50AM -0500

Re: kern/118975: [bge] [patch] Broadcom 5906 not handled by FreeBSD
by Thomas Nyström

REPLY TO AUTHOR
 
REPLY TO GROUP






The following reply was made to PR kern/118975; it has been noted by GNATS.

From: =?ISO-8859-1?Q?Thomas_Nystr=F6m?= <thn@saea...>
To: bug-followup@Free..., thn@saea...
Cc:  
Subject: Re: kern/118975: [bge] [patch] Broadcom 5906 not handled by FreeBSD
Date: Sat, 01 Mar 2008 20:35:04 +0100

This is a multi-part message in MIME format.
--------------000103070907090204020108
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Updated patch for 7.0-RELEASE (and probably -CURRENT).

/thn


--------------000103070907090204020108
Content-Type: text/plain;
  name="broadcom5906-70.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
  filename="broadcom5906-70.diff"

--- ./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
@@ -195,6 +195,8 @@
   { 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 },
  
@@ -271,6 +273,8 @@
   { 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 }
  };
@@ -293,6 +297,7 @@
   { 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 }
  };
@@ -305,6 +310,9 @@
  
  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);
@@ -315,6 +323,11 @@
  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 *);
  
@@ -337,6 +350,9 @@
  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);
  
@@ -359,6 +375,7 @@
  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
@@ -474,6 +491,10 @@
   return (0);
   }
  #endif
+
+ if (sc->bge_asicrev == BGE_ASICREV_BCM5906)
+ return (0);
+
   return (1);
  }
  
@@ -533,6 +554,15 @@
   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.
   */
@@ -555,6 +585,78 @@
   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
@@ -659,11 +761,13 @@
   }
  
   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:
@@ -687,6 +791,10 @@
  
   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) {
@@ -699,12 +807,17 @@
  
   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);
   }
  
@@ -887,7 +1000,7 @@
       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);
  }
@@ -934,7 +1047,7 @@
       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);
  }
@@ -990,17 +1103,17 @@
  
   /* 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);
  }
@@ -1271,6 +1384,15 @@
   /* 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);
  }
  
@@ -1307,15 +1429,21 @@
   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);
@@ -1462,15 +1590,15 @@
       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
@@ -2230,7 +2358,6 @@
   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;
  
@@ -2283,6 +2410,7 @@
   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:
@@ -2304,7 +2432,7 @@
   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;
   }
  
@@ -2415,22 +2543,14 @@
   }
  
  #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;
@@ -2688,7 +2808,8 @@
  
   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
@@ -2744,6 +2865,17 @@
   /* 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. */
@@ -2788,21 +2920,34 @@
   } 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
@@ -3022,11 +3167,11 @@
   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.
@@ -3168,7 +3313,7 @@
   * 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.
@@ -3545,10 +3690,10 @@
   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;
  
@@ -3675,7 +3820,7 @@
   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
  
@@ -3683,7 +3828,7 @@
   {
   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);
@@ -3906,7 +4051,7 @@
   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 {
@@ -3915,7 +4060,7 @@
   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);
   }
@@ -4040,7 +4185,7 @@
  
   /* 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.
@@ -4536,3 +4681,64 @@
   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
@@ -283,6 +283,8 @@
  #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)
@@ -299,6 +301,7 @@
  #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)
@@ -1438,6 +1441,17 @@
  #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
@@ -1683,6 +1697,55 @@
  #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
@@ -1711,6 +1774,7 @@
  /* 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)
  
@@ -2037,6 +2101,8 @@
  #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.
@@ -2090,6 +2156,7 @@
   * Offset of MAC address inside EEPROM.
   */
  #define BGE_EE_MAC_OFFSET 0x7C
+#define BGE_EE_MAC_OFFSET_5906 0x10
  #define BGE_EE_HWCFG_OFFSET 0xC8
  
  #define BGE_HWCFG_VOLTAGE 0x00000003
@@ -2474,6 +2541,7 @@
  #define BGE_FLAG_BER_BUG 0x02000000
  #define BGE_FLAG_ADJUST_TRIM 0x04000000
  #define BGE_FLAG_CRC_BUG 0x08000000
+#define BGE_FLAG_NO_EEPROM 0x10000000
   uint32_t bge_chipid;
   uint8_t bge_asicrev;
   uint8_t bge_chiprev;
--- ./sys/dev/mii/brgphy.c.70 2008-03-01 14:54:58.000000000 +0100
+++ ./sys/dev/mii/brgphy.c 2008-03-01 14:55:49.000000000 +0100
@@ -131,6 +131,7 @@
   MII_PHY_DESC(xxBROADCOM_ALT1, BCM5755),
   MII_PHY_DESC(xxBROADCOM_ALT1, BCM5787),
   MII_PHY_DESC(xxBROADCOM_ALT1, BCM5708S),
+ MII_PHY_DESC(BROADCOM2, BCM5906),
   MII_PHY_END
  };
  
@@ -186,6 +187,7 @@
   /* Handle any special cases based on the PHY ID */
   switch (bsc->mii_oui) {
   case MII_OUI_BROADCOM:
+ case MII_OUI_BROADCOM2:
   break;
   case MII_OUI_xxBROADCOM:
   switch (bsc->mii_model) {
@@ -226,12 +228,14 @@
   bce_sc = ifp->if_softc;
   }
  
- /* Todo: Need to add additional controllers such as 5906 & 5787F */
+ /* Todo: Need to add additional controllers such as 5787F */
   /* The 590x chips are 10/100 only. */
   if (bge_sc &&
       pci_get_vendor(bge_sc->bge_dev) == BCOM_VENDORID &&
       (pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5901 ||
-     pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5901A2)) {
+      pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5901A2 ||
+      pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5906 ||
+      pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5906M)) {
   fast_ether = 1;
   sc->mii_anegticks = MII_ANEGTICKS;
   }
@@ -930,6 +934,11 @@
       PHY_READ(sc, BRGPHY_MII_PHY_EXTCTL) &
       ~BRGPHY_PHY_EXTCTL_3_LED);
   }
+
+ /* Adjust output voltage (From Linux driver) */
+ if (bge_sc->bge_asicrev == BGE_ASICREV_BCM5906)
+ PHY_WRITE(sc, BRGPHY_MII_EPHY_PTEST, 0x12);
+
   /* Handle any bce (NetXtreme II) workarounds. */
   } else if (bce_sc) {
  
--- ./sys/dev/mii/brgphyreg.h.70 2008-03-01 14:55:05.000000000 +0100
+++ ./sys/dev/mii/brgphyreg.h 2008-03-01 14:55:49.000000000 +0100
@@ -161,6 +161,7 @@
  #define BRGPHY_MII_DSP_RW_PORT 0x15 /* DSP coefficient r/w port */
  
  #define BRGPHY_MII_DSP_ADDR_REG 0x17 /* DSP coefficient addr register */
+#define BRGPHY_MII_EPHY_PTEST 0x17 /* 5906 PHY register */
  
  #define BRGPHY_DSP_TAP_NUMBER_MASK 0x00
  #define BRGPHY_DSP_AGC_A 0x00
--- ./sys/dev/mii/miidevs.orig 2007-11-05 02:42:02.000000000 +0100
+++ ./sys/dev/mii/miidevs 2008-03-01 14:55:49.000000000 +0100
@@ -52,6 +52,7 @@
  oui ALTIMA 0x0010a9 Altima Communications
  oui AMD 0x00001a Advanced Micro Devices
  oui BROADCOM 0x001018 Broadcom Corporation
+oui BROADCOM2 0x000af7 Broadcom Corporation
  oui CICADA 0x0003F1 Cicada Semiconductor
  oui DAVICOM 0x00606e Davicom Semiconductor
  oui ICPLUS 0x0090c3 IC Plus Corp.
@@ -135,6 +136,7 @@
  model xxBROADCOM_ALT1 BCM5755 0x000c BCM5755 10/100/1000baseTX PHY
  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/100baseTX PHY
  
  /* Cicada Semiconductor PHYs (now owned by Vitesse?) */
  model CICADA CS8201 0x0001 Cicada CS8201 10/100/1000TX PHY

--------------000103070907090204020108--
_______________________________________________
freebsd-net@free... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscribe@free..."

Bookmark with:

Delicious   Digg   reddit   Facebook   StumbleUpon

Related Messages

opensubscriber is not affiliated with the authors of this message nor responsible for its content.