DaemonForums  

Go Back   DaemonForums > FreeBSD > FreeBSD General

FreeBSD General Other questions regarding FreeBSD which do not fit in any of the categories below.

Reply
 
Thread Tools Display Modes
  #1   (View Single Post)  
Old 25th May 2009
syrushcw syrushcw is offline
Port Guard
 
Join Date: May 2008
Posts: 17
Default Broadcom NIC

I got a new laptop with a Broadcom NIC that I can't get to work. I've never had to edit driver files in BSD so IDK what to do. I know I have to edit the bge(4) file with the following patch.

Code:
****************   PATCH FOR FreeBSD 7.0RC1 AND -CURRENT   ****************
diff --strip-trailing-cr -ur ../src.70.orig/sys/dev/bge/if_bge.c ./sys/dev/bge/if_bge.c
--- ../src.70.orig/sys/dev/bge/if_bge.c	2007-11-26 18:33:28.000000000 +0100
+++ ./sys/dev/bge/if_bge.c	2007-12-23 13:57:17.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);
 }
 
@@ -1309,13 +1431,18 @@
 
 	/* 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 {
 		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 +1589,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 +2357,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 +2409,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 +2431,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 +2542,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 +2807,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 +2864,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 +2919,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 +3166,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 +3312,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 +3689,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 +3819,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 +3827,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 +4050,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 +4059,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 +4184,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 +4680,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);
+}
+
diff --strip-trailing-cr -ur ../src.70.orig/sys/dev/bge/if_bgereg.h ./sys/dev/bge/if_bgereg.h
--- ../src.70.orig/sys/dev/bge/if_bgereg.h	2007-05-22 21:22:58.000000000 +0200
+++ ./sys/dev/bge/if_bgereg.h	2007-12-23 01:10:59.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;
diff --strip-trailing-cr -ur ../src.70.orig/sys/dev/mii/brgphy.c ./sys/dev/mii/brgphy.c
--- ../src.70.orig/sys/dev/mii/brgphy.c	2007-06-08 04:34:44.000000000 +0200
+++ ./sys/dev/mii/brgphy.c	2007-12-23 13:55:37.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) {
 
diff --strip-trailing-cr -ur ../src.70.orig/sys/dev/mii/brgphyreg.h ./sys/dev/mii/brgphyreg.h
--- ../src.70.orig/sys/dev/mii/brgphyreg.h	2007-06-07 04:21:38.000000000 +0200
+++ ./sys/dev/mii/brgphyreg.h	2007-12-23 02:25:32.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
diff --strip-trailing-cr -ur ../src.70.orig/sys/dev/mii/miidevs ./sys/dev/mii/miidevs
--- ../src.70.orig/sys/dev/mii/miidevs	2007-11-05 02:42:02.000000000 +0100
+++ ./sys/dev/mii/miidevs	2007-12-23 02:24:23.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
****************   END OF PATCH FOR FreeBSD 7.0RC1 AND -CURRENT   ****************
(it wouldn't let me post the whole patch)

I grep the bge file but all I find is one manpage
/usr/share/man/man4/if_bge.4.gz

I'm using 7.2 can someone point me in the right way? Thanks
Reply With Quote
  #2   (View Single Post)  
Old 30th May 2009
Business_woman's Avatar
Business_woman Business_woman is offline
lieutenant
 
Join Date: May 2008
Posts: 45
Default

That should not be necessary. What broadcom chips are you running?
__________________
I like cookies...
Reply With Quote
  #3   (View Single Post)  
Old 30th May 2009
Calderon's Avatar
Calderon Calderon is offline
Real Name: Patrick Lindholm
Fdisk Soldier
 
Join Date: May 2008
Location: Finland
Posts: 60
Default

Code:
****************   PATCH FOR FreeBSD 7.0RC1 AND -CURRENT   ****************
?

Code:
patch < /path/to/patch
Reply With Quote
  #4   (View Single Post)  
Old 2nd June 2009
BSDKaffee's Avatar
BSDKaffee BSDKaffee is offline
Real Name: Jason Hale
Coffee Addict
 
Join Date: May 2008
Location: Wintersville, Ohio
Posts: 212
Default

Quote:
Originally Posted by syrushcw View Post
I got a new laptop with a Broadcom NIC that I can't get to work. I've never had to edit driver files in BSD so IDK what to do. I know I have to edit the bge(4) file with the following patch.
That is an old patch. If you are running FreeBSD 7.2, then that code is already in there. Tell us what the model number of the chipset is and maybe we can help.

Quote:
Originally Posted by syrushcw View Post
I grep the bge file but all I find is one manpage
/usr/share/man/man4/if_bge.4.gzp
Do you have the kernel sources installed? That file should be in /usr/src/sys/dev/bge
Reply With Quote
  #5   (View Single Post)  
Old 2nd June 2009
syrushcw syrushcw is offline
Port Guard
 
Join Date: May 2008
Posts: 17
Default

I do have kernel sources installed its a Broadcom NetLink (TM) Gigabit Ethernet
Reply With Quote
  #6   (View Single Post)  
Old 4th June 2009
BSDKaffee's Avatar
BSDKaffee BSDKaffee is offline
Real Name: Jason Hale
Coffee Addict
 
Join Date: May 2008
Location: Wintersville, Ohio
Posts: 212
Default

What is the actual model number of the chipset? E.g.: BCM5788.
Reply With Quote
Reply

Tags
bge, broadcom

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Lagg failover on FreeBSD 7.0 Dell 1950/Broadcom 5708 NICs rfranzke FreeBSD General 4 14th September 2010 08:06 PM
Broadcom BCM5906M 10/100 Ethernet Driver? revzalot Solaris 0 15th June 2009 05:47 PM
broadcom 4312 jaideep_jdof OpenBSD General 1 18th November 2008 11:45 AM
broadcom ethernet jaideep_jdof NetBSD General 0 16th November 2008 05:33 PM
Freebsd broadcom driver jaideep_jdof FreeBSD Ports and Packages 9 10th November 2008 06:25 PM


All times are GMT. The time now is 06:16 AM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Content copyright © 2007-2010, the authors
Daemon image copyright ©1988, Marshall Kirk McKusick