changeset 11968:176a85f50024

6782858 Solaris needs Broadcom 5718 network support
author yong tan - Sun Microsystems - Beijing China <Yong.Tan@Sun.COM>
date Mon, 22 Mar 2010 22:42:59 +0800
parents f91b268929d9
children cdd98a239cd1
files usr/src/pkg/manifests/driver-network-bge.mf usr/src/uts/common/io/bge/bge_chip2.c usr/src/uts/common/io/bge/bge_hw.h usr/src/uts/common/io/bge/bge_impl.h usr/src/uts/common/io/bge/bge_main2.c usr/src/uts/common/io/bge/bge_mii.c
diffstat 6 files changed, 181 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/pkg/manifests/driver-network-bge.mf	Mon Mar 22 08:06:49 2010 -0500
+++ b/usr/src/pkg/manifests/driver-network-bge.mf	Mon Mar 22 22:42:59 2010 +0800
@@ -77,6 +77,7 @@
     alias=pci14e4,16a7 \
     alias=pci14e4,16a8 \
     alias=pci14e4,16c7 \
+    alias=pciex14e4,1656 \
     alias=pciex14e4,165a \
     alias=pciex14e4,165b \
     alias=pciex14e4,1673 \
@@ -109,6 +110,7 @@
     alias=pci14e4,16a7 \
     alias=pci14e4,16a8 \
     alias=pci14e4,16c7 \
+    alias=pciex14e4,1656 \
     alias=pciex14e4,1659 \
     alias=pciex14e4,165a \
     alias=pciex14e4,165b \
--- a/usr/src/uts/common/io/bge/bge_chip2.c	Mon Mar 22 08:06:49 2010 -0500
+++ b/usr/src/uts/common/io/bge/bge_chip2.c	Mon Mar 22 22:42:59 2010 +0800
@@ -239,6 +239,10 @@
 
 	BGE_TRACE(("bge_ind_get32($%p, 0x%lx)", (void *)bgep, regno));
 
+#ifdef __sparc
+	if (DEVICE_5717_SERIES_CHIPSETS(bgep))
+		regno = LE_32(regno);
+#endif
 	pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_RIAAR, regno);
 	val = pci_config_get32(bgep->cfg_handle, PCI_CONF_BGE_RIADR);
 
@@ -260,6 +264,10 @@
 	    (void *)bgep, regno, val));
 
 	val = LE_32(val);
+#ifdef __sparc
+	if (DEVICE_5717_SERIES_CHIPSETS(bgep))
+		regno = LE_32(regno);
+#endif
 	pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_RIAAR, regno);
 	pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_RIADR, val);
 }
@@ -343,13 +351,20 @@
 	 */
 	handle = bgep->cfg_handle;
 
+	/*
+	 * For some chipsets (e.g., BCM5718), if MHCR_ENABLE_ENDIAN_BYTE_SWAP
+	 * has been set in PCI_CONF_COMM already, we need to write the
+	 * byte-swapped value to it. So we just write zero first for simplicity.
+	 */
+	cidp->device = pci_config_get16(handle, PCI_CONF_DEVID);
+	if (DEVICE_5717_SERIES_CHIPSETS(bgep))
+		pci_config_put32(handle, PCI_CONF_BGE_MHCR, 0);
 	mhcr = pci_config_get32(handle, PCI_CONF_BGE_MHCR);
 	cidp->asic_rev = mhcr & MHCR_CHIP_REV_MASK;
 	cidp->businfo = pci_config_get32(handle, PCI_CONF_BGE_PCISTATE);
 	cidp->command = pci_config_get16(handle, PCI_CONF_COMM);
 
 	cidp->vendor = pci_config_get16(handle, PCI_CONF_VENID);
-	cidp->device = pci_config_get16(handle, PCI_CONF_DEVID);
 	cidp->subven = pci_config_get16(handle, PCI_CONF_SUBVENID);
 	cidp->subdev = pci_config_get16(handle, PCI_CONF_SUBSYSID);
 	cidp->revision = pci_config_get8(handle, PCI_CONF_REVID);
@@ -439,6 +454,8 @@
 	mhcr |= MHCR_ENABLE_ENDIAN_WORD_SWAP | MHCR_ENABLE_ENDIAN_BYTE_SWAP;
 #endif	/* _BIG_ENDIAN */
 
+	if (DEVICE_5717_SERIES_CHIPSETS(bgep))
+		pci_config_put32(handle, PCI_CONF_BGE_MHCR, 0);
 	pci_config_put32(handle, PCI_CONF_BGE_MHCR, mhcr);
 
 #ifdef BGE_IPMI_ASF
@@ -609,7 +626,8 @@
 	uint64_t regval;
 
 #ifdef	__amd64
-	if (DEVICE_5723_SERIES_CHIPSETS(bgep) || bge_get_em64t_type()) {
+	if (DEVICE_5723_SERIES_CHIPSETS(bgep) || bge_get_em64t_type() ||
+	    DEVICE_5717_SERIES_CHIPSETS(bgep)) {
 		regval = ddi_get32(bgep->io_handle, PIO_ADDR(bgep, regno + 4));
 		regval <<= 32;
 		regval |= ddi_get32(bgep->io_handle, PIO_ADDR(bgep, regno));
@@ -617,7 +635,8 @@
 		regval = ddi_get64(bgep->io_handle, PIO_ADDR(bgep, regno));
 	}
 #elif defined(__sparc)
-	if (DEVICE_5723_SERIES_CHIPSETS(bgep)) {
+	if (DEVICE_5723_SERIES_CHIPSETS(bgep) ||
+	    DEVICE_5717_SERIES_CHIPSETS(bgep)) {
 		regval = ddi_get32(bgep->io_handle, PIO_ADDR(bgep, regno));
 		regval <<= 32;
 		regval |= ddi_get32(bgep->io_handle, PIO_ADDR(bgep, regno + 4));
@@ -652,7 +671,8 @@
 #endif	/* _LITTLE_ENDIAN */
 
 #ifdef	__amd64
-	if (DEVICE_5723_SERIES_CHIPSETS(bgep) || bge_get_em64t_type()) {
+	if (DEVICE_5723_SERIES_CHIPSETS(bgep) || bge_get_em64t_type() ||
+	    DEVICE_5717_SERIES_CHIPSETS(bgep)) {
 		ddi_put32(bgep->io_handle,
 		    PIO_ADDR(bgep, regno), (uint32_t)data);
 		BGE_PCICHK(bgep);
@@ -663,7 +683,8 @@
 		ddi_put64(bgep->io_handle, PIO_ADDR(bgep, regno), data);
 	}
 #elif defined(__sparc)
-	if (DEVICE_5723_SERIES_CHIPSETS(bgep)) {
+	if (DEVICE_5723_SERIES_CHIPSETS(bgep) ||
+	    DEVICE_5717_SERIES_CHIPSETS(bgep)) {
 		ddi_put32(bgep->io_handle,
 		    PIO_ADDR(bgep, regno + 4), (uint32_t)data);
 		BGE_PCICHK(bgep);
@@ -750,6 +771,9 @@
 #endif	/* _BIG_ENDIAN */
 	BGE_PCICHK(bgep);
 
+	BGE_DEBUG(("bge_mbx_get($%p, 0x%lx) => 0x%08x",
+	    (void *)bgep, regno, val32));
+
 	return (val32);
 }
 
@@ -817,6 +841,10 @@
 		bgep->lastWriteZeroData = ((base == (bge_regno_t)0) ?
 		    B_TRUE : B_FALSE);
 	}
+#ifdef __sparc
+	if (DEVICE_5717_SERIES_CHIPSETS(bgep))
+		base = LE_32(base);
+#endif
 	pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MWBAR, base);
 }
 
@@ -874,6 +902,8 @@
 #endif
 
 #ifdef __sparc
+	if (DEVICE_5717_SERIES_CHIPSETS(bgep))
+		addr = LE_32(addr);
 	pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MWBAR, addr);
 	data = LE_32(data);
 	pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MWDAR, data);
@@ -900,22 +930,24 @@
 	addr += NIC_MEM_WINDOW_OFFSET;
 
 #ifdef	__amd64
-		if (DEVICE_5723_SERIES_CHIPSETS(bgep) || bge_get_em64t_type()) {
-			data = ddi_get32(bgep->io_handle, PIO_ADDR(bgep, addr));
-			data <<= 32;
-			data |= ddi_get32(bgep->io_handle,
-			    PIO_ADDR(bgep, addr + 4));
-		} else {
+	if (DEVICE_5723_SERIES_CHIPSETS(bgep) || bge_get_em64t_type() ||
+	    DEVICE_5717_SERIES_CHIPSETS(bgep)) {
+		data = ddi_get32(bgep->io_handle,
+		    PIO_ADDR(bgep, addr + 4));
+		data <<= 32;
+		data |= ddi_get32(bgep->io_handle, PIO_ADDR(bgep, addr));
+	} else {
 			data = ddi_get64(bgep->io_handle, PIO_ADDR(bgep, addr));
-		}
+	}
 #elif defined(__sparc)
-		if (DEVICE_5723_SERIES_CHIPSETS(bgep)) {
-			data = ddi_get32(bgep->io_handle, PIO_ADDR(bgep, addr));
-			data <<= 32;
-			data |= ddi_get32(bgep->io_handle,
-			    PIO_ADDR(bgep, addr + 4));
-		} else {
-			data = ddi_get64(bgep->io_handle, PIO_ADDR(bgep, addr));
+	if (DEVICE_5723_SERIES_CHIPSETS(bgep) ||
+	    DEVICE_5717_SERIES_CHIPSETS(bgep)) {
+		data = ddi_get32(bgep->io_handle, PIO_ADDR(bgep, addr));
+		data <<= 32;
+		data |= ddi_get32(bgep->io_handle,
+		    PIO_ADDR(bgep, addr + 4));
+	} else {
+		data = ddi_get64(bgep->io_handle, PIO_ADDR(bgep, addr));
 		}
 #else
 		data = ddi_get64(bgep->io_handle, PIO_ADDR(bgep, addr));
@@ -941,17 +973,19 @@
 	addr += NIC_MEM_WINDOW_OFFSET;
 
 #ifdef	__amd64
-	if (DEVICE_5723_SERIES_CHIPSETS(bgep) || bge_get_em64t_type()) {
+	if (DEVICE_5723_SERIES_CHIPSETS(bgep) || bge_get_em64t_type() ||
+	    DEVICE_5717_SERIES_CHIPSETS(bgep)) {
 		ddi_put32(bgep->io_handle,
-		    PIO_ADDR(bgep, addr), (uint32_t)data);
+		    PIO_ADDR(bgep, addr + 4), (uint32_t)data);
 		BGE_PCICHK(bgep);
 		ddi_put32(bgep->io_handle,
-		    PIO_ADDR(bgep, addr + 4), (uint32_t)(data >> 32));
+		    PIO_ADDR(bgep, addr), (uint32_t)(data >> 32));
 	} else {
 		ddi_put64(bgep->io_handle, PIO_ADDR(bgep, addr), data);
 	}
 #elif defined(__sparc)
-	if (DEVICE_5723_SERIES_CHIPSETS(bgep)) {
+	if (DEVICE_5723_SERIES_CHIPSETS(bgep) ||
+	    DEVICE_5717_SERIES_CHIPSETS(bgep)) {
 		ddi_put32(bgep->io_handle,
 		    PIO_ADDR(bgep, addr + 4), (uint32_t)data);
 		BGE_PCICHK(bgep);
@@ -991,13 +1025,14 @@
 
 	p = (void *)rcbp;
 #ifdef	__amd64
-	if (DEVICE_5723_SERIES_CHIPSETS(bgep) || bge_get_em64t_type()) {
+	if (DEVICE_5723_SERIES_CHIPSETS(bgep) || bge_get_em64t_type() ||
+	    DEVICE_5717_SERIES_CHIPSETS(bgep)) {
 		ddi_put32(bgep->io_handle, PIO_ADDR(bgep, addr),
 		    (uint32_t)(*p));
 		ddi_put32(bgep->io_handle, PIO_ADDR(bgep, addr + 4),
-		    (uint32_t)(*p >> 32));
+		    (uint32_t)(*p++ >> 32));
 		ddi_put32(bgep->io_handle, PIO_ADDR(bgep, addr + 8),
-		    (uint32_t)(*(p + 1)));
+		    (uint32_t)(*p));
 		ddi_put32(bgep->io_handle, PIO_ADDR(bgep, addr + 12),
 		    (uint32_t)(*p >> 32));
 
@@ -1006,13 +1041,14 @@
 		ddi_put64(bgep->io_handle, PIO_ADDR(bgep, addr+8), *p);
 	}
 #elif defined(__sparc)
-	if (DEVICE_5723_SERIES_CHIPSETS(bgep)) {
+	if (DEVICE_5723_SERIES_CHIPSETS(bgep) ||
+	    DEVICE_5717_SERIES_CHIPSETS(bgep)) {
 		ddi_put32(bgep->io_handle, PIO_ADDR(bgep, addr + 4),
 		    (uint32_t)(*p));
 		ddi_put32(bgep->io_handle, PIO_ADDR(bgep, addr),
-		    (uint32_t)(*p >> 32));
+		    (uint32_t)(*p++ >> 32));
 		ddi_put32(bgep->io_handle, PIO_ADDR(bgep, addr + 12),
-		    (uint32_t)(*(p + 1)));
+		    (uint32_t)(*p));
 		ddi_put32(bgep->io_handle, PIO_ADDR(bgep, addr + 8),
 		    (uint32_t)(*p >> 32));
 	} else {
@@ -1680,6 +1716,7 @@
 		case BGE_FLASH_READ:
 			if (DEVICE_5721_SERIES_CHIPSETS(bgep) ||
 			    DEVICE_5723_SERIES_CHIPSETS(bgep) ||
+			    DEVICE_5717_SERIES_CHIPSETS(bgep) ||
 			    DEVICE_5714_SERIES_CHIPSETS(bgep)) {
 				bge_reg_set32(bgep, NVM_ACCESS_REG,
 				    NVM_ACCESS_ENABLE);
@@ -1688,6 +1725,7 @@
 			    NVM_FLASH_CMD_RD, addr, dp);
 			if (DEVICE_5721_SERIES_CHIPSETS(bgep) ||
 			    DEVICE_5723_SERIES_CHIPSETS(bgep) ||
+			    DEVICE_5717_SERIES_CHIPSETS(bgep) ||
 			    DEVICE_5714_SERIES_CHIPSETS(bgep)) {
 				bge_reg_clr32(bgep, NVM_ACCESS_REG,
 				    NVM_ACCESS_ENABLE);
@@ -1697,6 +1735,7 @@
 		case BGE_FLASH_WRITE:
 			if (DEVICE_5721_SERIES_CHIPSETS(bgep) ||
 			    DEVICE_5723_SERIES_CHIPSETS(bgep) ||
+			    DEVICE_5717_SERIES_CHIPSETS(bgep) ||
 			    DEVICE_5714_SERIES_CHIPSETS(bgep)) {
 				bge_reg_set32(bgep, NVM_ACCESS_REG,
 				    NVM_WRITE_ENABLE|NVM_ACCESS_ENABLE);
@@ -1707,6 +1746,7 @@
 			bge_nvmem_protect(bgep, B_TRUE);
 			if (DEVICE_5721_SERIES_CHIPSETS(bgep) ||
 			    DEVICE_5723_SERIES_CHIPSETS(bgep) ||
+			    DEVICE_5717_SERIES_CHIPSETS(bgep) ||
 			    DEVICE_5714_SERIES_CHIPSETS(bgep)) {
 				bge_reg_clr32(bgep, NVM_ACCESS_REG,
 				    NVM_WRITE_ENABLE|NVM_ACCESS_ENABLE);
@@ -1851,6 +1891,7 @@
 	case DEVICE_ID_5705M:
 	case DEVICE_ID_5705C:
 	case DEVICE_ID_5705_2:
+	case DEVICE_ID_5718:
 	case DEVICE_ID_5780:
 	case DEVICE_ID_5782:
 	case DEVICE_ID_5785:
@@ -1967,6 +2008,7 @@
 	cidp->rx_count_norm = bge_rx_count_norm;
 	cidp->tx_ticks_norm = bge_tx_ticks_norm;
 	cidp->tx_count_norm = bge_tx_count_norm;
+	cidp->mask_pci_int = MHCR_MASK_PCI_INT_OUTPUT;
 
 	if (cidp->rx_rings == 0 || cidp->rx_rings > BGE_RECV_RINGS_MAX)
 		cidp->rx_rings = BGE_RECV_RINGS_DEFAULT;
@@ -1976,6 +2018,28 @@
 	cidp->msi_enabled = B_FALSE;
 
 	switch (cidp->device) {
+	case DEVICE_ID_5718:
+		cidp->chip_label = 5718;
+		cidp->msi_enabled = bge_enable_msi;
+#ifdef __sparc
+		cidp->mask_pci_int = LE_32(MHCR_MASK_PCI_INT_OUTPUT);
+#endif
+		cidp->bge_dma_rwctrl = LE_32(PDRWCR_VAR_5717);
+		cidp->pci_type = BGE_PCI_E;
+		cidp->mbuf_lo_water_rdma = RDMA_MBUF_LOWAT_5705;
+		cidp->mbuf_lo_water_rmac = MAC_RX_MBUF_LOWAT_5717;
+		cidp->mbuf_hi_water = MBUF_HIWAT_5717;
+		cidp->mbuf_base = bge_mbuf_pool_base_5705;
+		cidp->mbuf_length = bge_mbuf_pool_len_5705;
+		cidp->recv_slots = BGE_RECV_SLOTS_5705;
+		cidp->bge_mlcr_default = MLCR_DEFAULT_5717;
+		cidp->rx_rings = BGE_RECV_RINGS_MAX_5705;
+		cidp->tx_rings = BGE_SEND_RINGS_MAX_5705;
+		cidp->flags |= CHIP_FLAG_NO_JUMBO;
+		cidp->statistic_type = BGE_STAT_REG;
+		dev_ok = B_TRUE;
+		break;
+
 	case DEVICE_ID_5700:
 	case DEVICE_ID_5700x:
 		cidp->chip_label = 5700;
@@ -2583,6 +2647,7 @@
 		 * See:P500 of 57xx-PG102-RDS.pdf.
 		 */
 		if (DEVICE_5705_SERIES_CHIPSETS(bgep)||
+		    DEVICE_5717_SERIES_CHIPSETS(bgep)||
 		    DEVICE_5721_SERIES_CHIPSETS(bgep)||
 		    DEVICE_5723_SERIES_CHIPSETS(bgep)||
 		    DEVICE_5714_SERIES_CHIPSETS(bgep)||
@@ -3325,6 +3390,9 @@
 			MHCR_CLEAR_INTERRUPT_INTA |
 			MHCR_ENABLE_ENDIAN_WORD_SWAP |
 			MHCR_ENABLE_ENDIAN_BYTE_SWAP;
+		if (DEVICE_5717_SERIES_CHIPSETS(bgep))
+			pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MHCR,
+					0);
 		pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MHCR, mhcr);
 		bge_reg_put32(bgep, MEMORY_ARBITER_MODE_REG,
 			bge_reg_get32(bgep, MEMORY_ARBITER_MODE_REG) |
@@ -3359,6 +3427,8 @@
 #ifdef  _BIG_ENDIAN
 	mhcr |= MHCR_ENABLE_ENDIAN_WORD_SWAP | MHCR_ENABLE_ENDIAN_BYTE_SWAP;
 #endif  /* _BIG_ENDIAN */
+	if (DEVICE_5717_SERIES_CHIPSETS(bgep))
+		pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MHCR, 0);
 	pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MHCR, mhcr);
 #ifdef BGE_IPMI_ASF
 	if (bgep->asf_enabled)
@@ -3617,6 +3687,7 @@
 	uint32_t stats_mask;
 	uint32_t dma_wrprio;
 	uint64_t ring;
+	uint32_t regval;
 	int retval = DDI_SUCCESS;
 
 	BGE_TRACE(("bge_chip_start($%p)",
@@ -3676,7 +3747,9 @@
 	 * into bits 7-1.  Don't set bit 0, 'cos that's the RESET bit
 	 * for the whole chip!
 	 */
-	bge_reg_put32(bgep, MISC_CONFIG_REG, MISC_CONFIG_DEFAULT);
+	regval = bge_reg_get32(bgep, MISC_CONFIG_REG);
+	regval = (regval & 0xffffff00) | MISC_CONFIG_DEFAULT;
+	bge_reg_put32(bgep, MISC_CONFIG_REG, regval);
 
 	if (DEVICE_5906_SERIES_CHIPSETS(bgep)) {
 		drv_usecwait(40);
@@ -3739,8 +3812,18 @@
 	/*
 	 * Steps 37-39: initialise Receive Buffer (Producer) RCBs
 	 */
-	bge_reg_putrcb(bgep, STD_RCV_BD_RING_RCB_REG,
-	    &bgep->buff[BGE_STD_BUFF_RING].hw_rcb);
+	if (DEVICE_5717_SERIES_CHIPSETS(bgep)) {
+		buff_ring_t *brp = &bgep->buff[BGE_STD_BUFF_RING];
+		bge_reg_put64(bgep, STD_RCV_BD_RING_RCB_REG,
+		    brp->desc.cookie.dmac_laddress);
+		bge_reg_put32(bgep, STD_RCV_BD_RING_RCB_REG + 8,
+		    (brp->desc.nslots) << 16 | brp->buf[0].size << 2);
+		bge_reg_put32(bgep, STD_RCV_BD_RING_RCB_REG + 0xc,
+		    NIC_MEM_SHADOW_BUFF_STD_5717);
+	} else
+		bge_reg_putrcb(bgep, STD_RCV_BD_RING_RCB_REG,
+		    &bgep->buff[BGE_STD_BUFF_RING].hw_rcb);
+
 	if (DEVICE_5704_SERIES_CHIPSETS(bgep)) {
 		bge_reg_putrcb(bgep, JUMBO_RCV_BD_RING_RCB_REG,
 		    &bgep->buff[BGE_JUMBO_BUFF_RING].hw_rcb);
@@ -3915,6 +3998,8 @@
 		coalmode = COALESCE_64_BYTE_STATUS;
 	else
 		coalmode = 0;
+	if (DEVICE_5717_SERIES_CHIPSETS(bgep))
+		coalmode = COALESCE_CLR_TICKS_RX;
 	if (!bge_chip_enable_engine(bgep, HOST_COALESCE_MODE_REG, coalmode))
 		retval = DDI_FAILURE;
 	if (!bge_chip_enable_engine(bgep, RCV_BD_COMPLETION_MODE_REG,
@@ -3971,13 +4056,16 @@
 	if ((MHCR_CHIP_ASIC_REV(bgep->chipid.asic_rev) ==
 	    MHCR_CHIP_ASIC_REV_5755) ||
 	    (MHCR_CHIP_ASIC_REV(bgep->chipid.asic_rev) ==
+	    MHCR_CHIP_ASIC_REV_5723) ||
+	    (MHCR_CHIP_ASIC_REV(bgep->chipid.asic_rev) ==
 	    MHCR_CHIP_ASIC_REV_5906)) {
 		dma_wrprio |= DMA_STATUS_TAG_FIX_CQ12384;
 	}
 	if (!bge_chip_enable_engine(bgep, WRITE_DMA_MODE_REG,
 	    dma_wrprio))
 		retval = DDI_FAILURE;
-	if (DEVICE_5723_SERIES_CHIPSETS(bgep))
+	if (DEVICE_5723_SERIES_CHIPSETS(bgep) ||
+	    DEVICE_5717_SERIES_CHIPSETS(bgep))
 		bge_dma_rdprio = 0;
 	if (!bge_chip_enable_engine(bgep, READ_DMA_MODE_REG,
 	    (bge_dma_rdprio << DMA_PRIORITY_SHIFT) | ALL_DMA_ATTN_BITS))
@@ -4115,7 +4203,7 @@
 	 */
 	if (bgep->intr_type == DDI_INTR_TYPE_FIXED)
 		bge_cfg_clr32(bgep, PCI_CONF_BGE_MHCR,
-		    MHCR_MASK_PCI_INT_OUTPUT);
+		    bgep->chipid.mask_pci_int);
 
 	/*
 	 * All done!
@@ -4217,7 +4305,8 @@
 		 * bit is *zero* when the interrupt is asserted.
 		 */
 		regval = bge_reg_get32(bgep, MISC_LOCAL_CONTROL_REG);
-		if (regval & MLCR_INTA_STATE) {
+		if (!(DEVICE_5717_SERIES_CHIPSETS(bgep)) &&
+		    (regval & MLCR_INTA_STATE)) {
 			if (bge_check_acc_handle(bgep, bgep->io_handle)
 			    != DDI_FM_OK)
 				goto chip_stop;
@@ -4229,7 +4318,7 @@
 		 * Block further PCI interrupts ...
 		 */
 		bge_reg_set32(bgep, PCI_CONF_BGE_MHCR,
-		    MHCR_MASK_PCI_INT_OUTPUT);
+		    bgep->chipid.mask_pci_int);
 
 	} else {
 		/*
@@ -4364,7 +4453,7 @@
 	 */
 	if (bgep->intr_type == DDI_INTR_TYPE_FIXED) {
 		bge_reg_clr32(bgep, PCI_CONF_BGE_MHCR,
-		    MHCR_MASK_PCI_INT_OUTPUT);
+		    bgep->chipid.mask_pci_int);
 		if (bge_check_acc_handle(bgep, bgep->cfg_handle) !=
 		    DDI_FM_OK)
 			goto chip_stop;
@@ -5671,6 +5760,9 @@
 		else
 			addr = addr + 4;
 	}
+#else
+	if (DEVICE_5717_SERIES_CHIPSETS(bgep))
+		addr = LE_32(addr);
 #endif
 
 	pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MWBAR, addr);
@@ -5678,6 +5770,10 @@
 	pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MWBAR, 0);
 
 	data = LE_32(data);
+
+	BGE_DEBUG(("bge_nic_read32($%p, 0x%x) => 0x%x",
+	    (void *)bgep, addr, data));
+
 	return (data);
 }
 
--- a/usr/src/uts/common/io/bge/bge_hw.h	Mon Mar 22 08:06:49 2010 -0500
+++ b/usr/src/uts/common/io/bge/bge_hw.h	Mon Mar 22 22:42:59 2010 +0800
@@ -64,6 +64,7 @@
 #define	DEVICE_ID_5704			0x1649
 #define	DEVICE_ID_5705C			0x1653
 #define	DEVICE_ID_5705_2		0x1654
+#define	DEVICE_ID_5718			0x1656
 #define	DEVICE_ID_5705M			0x165d
 #define	DEVICE_ID_5705MA3		0x165e
 #define	DEVICE_ID_5705F			0x166e
@@ -183,6 +184,9 @@
 		(bgep->chipid.device == DEVICE_ID_5752M) ||\
 		(bgep->chipid.device == DEVICE_ID_5789))
 
+#define	DEVICE_5717_SERIES_CHIPSETS(bgep) \
+		(bgep->chipid.device == DEVICE_ID_5718)
+
 #define	DEVICE_5723_SERIES_CHIPSETS(bgep) \
 		((bgep->chipid.device == DEVICE_ID_5723) ||\
 		(bgep->chipid.device == DEVICE_ID_5761) ||\
@@ -356,6 +360,7 @@
 #define	PDRWCR_VAR_5721			0x76180000
 #define	PDRWCR_VAR_5714			0x76148000	/* OR of above	*/
 #define	PDRWCR_VAR_5715			0x76144000	/* OR of above	*/
+#define	PDRWCR_VAR_5717			0x00380000
 
 /*
  * PCI State Register, in PCI config space
@@ -487,6 +492,7 @@
 #define	NIC_MEM_SHADOW_SEND_7_8		0x7000		/* bogus	*/
 #define	NIC_MEM_SHADOW_SEND_9_16	0x8000		/* bogus	*/
 #define	NIC_MEM_SHADOW_BUFF_STD		0x6000
+#define	NIC_MEM_SHADOW_BUFF_STD_5717		0x40000
 #define	NIC_MEM_SHADOW_BUFF_JUMBO	0x7000
 #define	NIC_MEM_SHADOW_BUFF_MINI	0x8000		/* bogus	*/
 #define	NIC_MEM_SHADOW_SEND_RING(ring, nslots)	(0x4000 + 4*(ring)*(nslots))
@@ -960,6 +966,12 @@
 #define	SERDES_STATUS_RXSTAT		0x000000ff
 
 /*
+ * SGMII Status Register (5717/5718 only)
+ */
+#define	SGMII_STATUS_REG	0x5B4
+#define	MEDIA_SELECTION_MODE	0x00000100
+
+/*
  * Statistic Registers (5705/5788/5721/5751/5752/5714/5715 only)
  */
 #define	STAT_IFHCOUT_OCTETS_REG		0x0800
@@ -1052,6 +1064,12 @@
 #define	JUMBO_RCV_BD_REPLENISH_DEFAULT	0x00000020	/* 32	*/
 
 /*
+ * CPMU registers (5717/5718 only)
+ */
+#define	CPMU_STATUS_REG	0x362c
+#define	CPMU_STATUS_FUN_NUM	0x20000000
+
+/*
  * Host Coalescing Engine Control Registers
  */
 #define	RCV_COALESCE_TICKS_REG		0x3c08
@@ -1112,12 +1130,14 @@
 #define	MAC_RX_MBUF_LOWAT_DEFAULT	0x00000020
 #define	MAC_RX_MBUF_LOWAT_5705		0x00000010
 #define	MAC_RX_MBUF_LOWAT_5906		0x00000004
+#define	MAC_RX_MBUF_LOWAT_5717		0x0000002a
 #define	MAC_RX_MBUF_LOWAT_JUMBO		0x00000098
 #define	MAC_RX_MBUF_LOWAT_5714_JUMBO	0x0000004b
 #define	MBUF_HIWAT_REG			0x4418
 #define	MBUF_HIWAT_DEFAULT		0x00000060
 #define	MBUF_HIWAT_5705			0x00000060
 #define	MBUF_HIWAT_5906			0x00000010
+#define	MBUF_HIWAT_5717			0x000000a0
 #define	MBUF_HIWAT_JUMBO		0x0000017c
 #define	MBUF_HIWAT_5714_JUMBO		0x00000096
 
@@ -1269,6 +1289,7 @@
  */
 #define	MLCR_DEFAULT			0x0101c000
 #define	MLCR_DEFAULT_5714		0x1901c000
+#define	MLCR_DEFAULT_5717		0x01000000
 
 /*
  * Serial EEPROM Data/Address Registers (auto-access mode)
--- a/usr/src/uts/common/io/bge/bge_impl.h	Mon Mar 22 08:06:49 2010 -0500
+++ b/usr/src/uts/common/io/bge/bge_impl.h	Mon Mar 22 22:42:59 2010 +0800
@@ -638,6 +638,7 @@
 	uint32_t		rx_count_norm;
 	uint32_t		tx_ticks_norm;
 	uint32_t		tx_count_norm;
+	uint32_t		mask_pci_int;
 } chip_id_t;
 
 #define	CHIP_FLAG_SUPPORTED	0x80
--- a/usr/src/uts/common/io/bge/bge_main2.c	Mon Mar 22 08:06:49 2010 -0500
+++ b/usr/src/uts/common/io/bge/bge_main2.c	Mon Mar 22 22:42:59 2010 +0800
@@ -3188,6 +3188,13 @@
 	err = pci_config_setup(devinfo, &bgep->cfg_handle);
 #ifdef BGE_IPMI_ASF
 #ifdef __sparc
+	/*
+	 * We need to determine the type of chipset for accessing some configure
+	 * registers. (This information will be used by bge_ind_put32,
+	 * bge_ind_get32 and bge_nic_read32)
+	 */
+	bgep->chipid.device = pci_config_get16(bgep->cfg_handle,
+	    PCI_CONF_DEVID);
 	value16 = pci_config_get16(bgep->cfg_handle, PCI_CONF_COMM);
 	value16 = value16 | (PCI_COMM_MAE | PCI_COMM_ME);
 	pci_config_put16(bgep->cfg_handle, PCI_CONF_COMM, value16);
@@ -3198,6 +3205,13 @@
 	    MHCR_CLEAR_INTERRUPT_INTA |
 	    MHCR_ENABLE_ENDIAN_WORD_SWAP |
 	    MHCR_ENABLE_ENDIAN_BYTE_SWAP;
+	/*
+	 * For some chipsets (e.g., BCM5718), if MHCR_ENABLE_ENDIAN_BYTE_SWAP
+	 * has been set in PCI_CONF_COMM already, we need to write the
+	 * byte-swapped value to it. So we just write zero first for simplicity.
+	 */
+	if (DEVICE_5717_SERIES_CHIPSETS(bgep))
+		pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MHCR, 0);
 	pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MHCR, mhcrValue);
 	bge_ind_put32(bgep, MEMORY_ARBITER_MODE_REG,
 	    bge_ind_get32(bgep, MEMORY_ARBITER_MODE_REG) |
--- a/usr/src/uts/common/io/bge/bge_mii.c	Mon Mar 22 08:06:49 2010 -0500
+++ b/usr/src/uts/common/io/bge/bge_mii.c	Mon Mar 22 22:42:59 2010 +0800
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -1503,6 +1503,15 @@
 	 * BCM800x PHY.
 	 */
 	bgep->phy_mii_addr = 1;
+	if (DEVICE_5717_SERIES_CHIPSETS(bgep)) {
+		int regval = bge_reg_get32(bgep, CPMU_STATUS_REG);
+		if (regval & CPMU_STATUS_FUN_NUM)
+			bgep->phy_mii_addr += 1;
+		regval = bge_reg_get32(bgep, SGMII_STATUS_REG);
+		if (regval & MEDIA_SELECTION_MODE)
+			bgep->phy_mii_addr += 7;
+	}
+
 	if (bge_phy_probe(bgep)) {
 		bgep->chipid.flags &= ~CHIP_FLAG_SERDES;
 		bgep->physops = &copper_ops;