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

From: Benjamin Close <[EMAIL PROTECTED]>
To: [EMAIL PROTECTED]
Cc: =?ISO-8859-1?Q?Thomas_Nystr=F6m?= <[EMAIL PROTECTED]>, [EMAIL PROTECTED]
Subject: Re: kern/118975: [bge] [patch] Broadcom 5906 not handled by FreeBSD
Date: Tue, 01 Apr 2008 23:29:49 +1030

 This is a multi-part message in MIME format.
 --------------030107050408040208070301
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 8bit
 
 Thomas Nyström wrote:
 > Benjamin Close skrev:
 >> Hi Thomas,
 >>    Are you able to attach a recent patch rather than inling it - I'll 
 >> see what I can do to test/get it merged.
 >
 > Hi Benjamin!
 >
 > I tried to attach the updated patch the last time but it seems that
 > something got wrong...
 >
 > I have now put both patches here: http://ture.saeab.se/bcm5906/
 > One for 6.3R and one for 7.0R. Last time I checked the 7.0R also
 > applied to -CURRENT without problem.
 >
 > Currently my machine with 5906 is running 6.3R but I will arrange so
 > it also could run -CURRENT.
 >
 > /Thomas
 >
 Hi John,
    Are you the current maintainer of bge(4)?
 
 The patch put together by Thomas (cc'd) adds 5906 chipset support for 
 the driver and works very well (sending this email via the patched 
 driver). Any chance of committing - or happy for me to commit? (Patch 
 against -current attached)
 
 Cheers,
     Benjamin
 
 --------------030107050408040208070301
 Content-Type: text/plain;
  name="20080325-5906.diff"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="20080325-5906.diff"
 
 Index: dev/bge/if_bge.c
 ===================================================================
 RCS file: /devel/FreeBSD/ncvs/src/sys/dev/bge/if_bge.c,v
 retrieving revision 1.204
 diff -u -r1.204 if_bge.c
 --- dev/bge/if_bge.c   11 Mar 2008 15:05:54 -0000      1.204
 +++ dev/bge/if_bge.c   25 Mar 2008 02:44:25 -0000
 @@ -196,6 +196,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 },
  
 @@ -273,6 +275,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 }
  };
 @@ -295,6 +299,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 }
  };
 @@ -307,6 +312,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);
 @@ -317,6 +325,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 *);
  
 @@ -339,6 +352,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);
  
 @@ -361,6 +377,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
 @@ -476,6 +493,10 @@
                        return (0);
        }
  #endif
 +
 +      if (sc->bge_asicrev == BGE_ASICREV_BCM5906)
 +              return (0);
 +
        return (1);
  }
  
 @@ -535,6 +556,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.
   */
 @@ -557,6 +587,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
 @@ -661,11 +763,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:
 @@ -689,6 +793,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) {
 @@ -701,12 +809,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);
        }
  
 @@ -889,7 +1002,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);
  }
 @@ -936,7 +1049,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);
  }
 @@ -992,17 +1105,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);
  }
 @@ -1273,6 +1386,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);
  }
  
 @@ -1309,15 +1431,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);
 @@ -1464,15 +1592,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
 @@ -2232,7 +2360,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;
  
 @@ -2294,6 +2421,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:
 @@ -2316,7 +2444,7 @@
                    sc->bge_asicrev == BGE_ASICREV_BCM5787) {
                        if (sc->bge_chipid != BGE_CHIPID_BCM5722_A0)
                                sc->bge_flags |= BGE_FLAG_JITTER_BUG;
 -              } else
 +              } else if (sc->bge_asicrev != BGE_ASICREV_BCM5906)
                        sc->bge_flags |= BGE_FLAG_BER_BUG;
        }
  
 @@ -2427,22 +2555,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;
 @@ -2700,7 +2820,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
 @@ -2756,6 +2877,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. */
 @@ -2800,21 +2932,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
 @@ -3034,11 +3179,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.
 @@ -3180,7 +3325,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.
 @@ -3557,10 +3702,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;
  
 @@ -3687,7 +3832,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
  
 @@ -3695,7 +3840,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);
 @@ -3918,7 +4063,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 {
 @@ -3927,7 +4072,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);
                        }
 @@ -4052,7 +4197,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.
 @@ -4548,3 +4693,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);
 +}
 +
 Index: dev/bge/if_bgereg.h
 ===================================================================
 RCS file: /devel/FreeBSD/ncvs/src/sys/dev/bge/if_bgereg.h,v
 retrieving revision 1.77
 diff -u -r1.77 if_bgereg.h
 --- dev/bge/if_bgereg.h        6 Mar 2008 21:48:34 -0000       1.77
 +++ dev/bge/if_bgereg.h        25 Mar 2008 02:41:09 -0000
 @@ -284,6 +284,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)
 @@ -300,6 +302,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)
 @@ -1439,6 +1442,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
 @@ -1684,6 +1698,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
 @@ -1712,6 +1775,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)
  
 @@ -2039,6 +2103,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.
 @@ -2092,6 +2158,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
 @@ -2477,6 +2544,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;
 Index: dev/mii/brgphy.c
 ===================================================================
 RCS file: /devel/FreeBSD/ncvs/src/sys/dev/mii/brgphy.c,v
 retrieving revision 1.73
 diff -u -r1.73 brgphy.c
 --- dev/mii/brgphy.c   6 Mar 2008 21:42:48 -0000       1.73
 +++ dev/mii/brgphy.c   25 Mar 2008 02:47:22 -0000
 @@ -134,6 +134,7 @@
        MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709CAX),
        MII_PHY_DESC(xxBROADCOM_ALT1, BCM5722),
        MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709C),
 +      MII_PHY_DESC(BROADCOM2, BCM5906),
        MII_PHY_END
  };
  
 @@ -189,6 +190,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) {
 @@ -229,12 +231,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;
        }
 @@ -927,6 +931,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) {
  
 Index: dev/mii/brgphyreg.h
 ===================================================================
 RCS file: /devel/FreeBSD/ncvs/src/sys/dev/mii/brgphyreg.h,v
 retrieving revision 1.10
 diff -u -r1.10 brgphyreg.h
 --- dev/mii/brgphyreg.h        7 Jun 2007 02:21:38 -0000       1.10
 +++ dev/mii/brgphyreg.h        25 Mar 2008 02:41:09 -0000
 @@ -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
 Index: dev/mii/miidevs
 ===================================================================
 RCS file: /devel/FreeBSD/ncvs/src/sys/dev/mii/miidevs,v
 retrieving revision 1.51
 diff -u -r1.51 miidevs
 --- dev/mii/miidevs    6 Mar 2008 21:42:48 -0000       1.51
 +++ dev/mii/miidevs    25 Mar 2008 02:43:03 -0000
 @@ -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.
 @@ -138,6 +139,7 @@
  model xxBROADCOM_ALT1 BCM5709CAX      0x002c BCM5709C(AX) 10/100/1000baseTX 
PHY
  model xxBROADCOM_ALT1 BCM5722 0x002d BCM5722 10/100/1000baseTX PHY
  model xxBROADCOM_ALT1 BCM5709C        0x003c BCM5709C 10/100/1000baseTX 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
 
 --------------030107050408040208070301--
_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to