changeset 3918:2f5f98948dce

6490108 ON bge driver support required for Schumacher(CP3010) 6498937 system hang while doing MAX and snoop through bge
author ml149210
date Wed, 28 Mar 2007 19:49:13 -0700
parents 9e19a8d4a355
children 2dddca2fe7e2
files usr/src/uts/common/io/bge/bge.h 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_recv2.c
diffstat 6 files changed, 175 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/io/bge/bge.h	Wed Mar 28 18:46:25 2007 -0700
+++ b/usr/src/uts/common/io/bge/bge.h	Wed Mar 28 19:49:13 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -130,9 +130,16 @@
 #define	BGE_PP_SPACE_SEEPROM	11		/* SEEPROM (if fitted)	*/
 #define	BGE_PP_SPACE_FLASH	12		/* FLASH (if fitted)    */
 
-#ifndef __sparc
 #define	BGE_IPMI_ASF
-#endif
+#define	BGE_NETCONSOLE
+
+/*
+ * BGE_MAXPKT_RCVED is defined to make sure bge does not stick
+ * in a receiving loop too long. This value is the tuning result
+ * of performance testing on sparc/x86 platforms, with regarding
+ * to throughput/latency/CPU utilization, TCP/UDP
+ */
+#define	BGE_MAXPKT_RCVED	32
 
 #ifdef __cplusplus
 }
--- a/usr/src/uts/common/io/bge/bge_chip2.c	Wed Mar 28 18:46:25 2007 -0700
+++ b/usr/src/uts/common/io/bge/bge_chip2.c	Wed Mar 28 19:49:13 2007 -0700
@@ -34,7 +34,7 @@
  * Future features ... ?
  */
 #define	BGE_CFG_IO8	1	/* 8/16-bit cfg space BIS/BIC	*/
-#define	BGE_IND_IO32	0	/* indirect access code		*/
+#define	BGE_IND_IO32	1	/* indirect access code		*/
 #define	BGE_SEE_IO32	1	/* SEEPROM access code		*/
 #define	BGE_FLASH_IO32	1	/* FLASH access code		*/
 
@@ -160,6 +160,15 @@
 static uint32_t bge_default_jumbo_size	= BGE_JUMBO_BUFF_SIZE;
 
 /*
+ * bge_intr_max_loop controls the maximum loop number within bge_intr.
+ * When loading NIC with heavy network traffic, it is useful.
+ * Increasing this value could have positive effect to throughput,
+ * but it might also increase ticks of a bge ISR stick on CPU, which might
+ * lead to bad UI interactive experience. So tune this with caution.
+ */
+static int bge_intr_max_loop = 1;
+
+/*
  * ========== Low-level chip & ring buffer manipulation ==========
  */
 
@@ -316,38 +325,37 @@
  * it's been thoroughly tested for all access sizes on all supported
  * architectures (SPARC *and* x86!).
  */
-static uint32_t bge_ind_get32(bge_t *bgep, bge_regno_t regno);
+uint32_t bge_ind_get32(bge_t *bgep, bge_regno_t regno);
 #pragma	inline(bge_ind_get32)
 
-static uint32_t
+uint32_t
 bge_ind_get32(bge_t *bgep, bge_regno_t regno)
 {
 	uint32_t val;
 
 	BGE_TRACE(("bge_ind_get32($%p, 0x%lx)", (void *)bgep, regno));
 
-	ASSERT(mutex_owned(bgep->genlock));
-
 	pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_RIAAR, regno);
 	val = pci_config_get32(bgep->cfg_handle, PCI_CONF_BGE_RIADR);
 
 	BGE_DEBUG(("bge_ind_get32($%p, 0x%lx) => 0x%x",
 		(void *)bgep, regno, val));
 
+	val = LE_32(val);
+
 	return (val);
 }
 
-static void bge_ind_put32(bge_t *bgep, bge_regno_t regno, uint32_t val);
+void bge_ind_put32(bge_t *bgep, bge_regno_t regno, uint32_t val);
 #pragma	inline(bge_ind_put32)
 
-static void
+void
 bge_ind_put32(bge_t *bgep, bge_regno_t regno, uint32_t val)
 {
 	BGE_TRACE(("bge_ind_put32($%p, 0x%lx, 0x%x)",
 		(void *)bgep, regno, val));
 
-	ASSERT(mutex_owned(bgep->genlock));
-
+	val = LE_32(val);
 	pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_RIAAR, regno);
 	pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_RIADR, val);
 }
@@ -857,7 +865,6 @@
 	pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MWBAR, base);
 }
 
-
 static uint32_t bge_nic_get32(bge_t *bgep, bge_regno_t addr);
 #pragma	inline(bge_nic_get32)
 
@@ -866,7 +873,7 @@
 {
 	uint32_t data;
 
-#ifdef BGE_IPMI_ASF
+#if defined(BGE_IPMI_ASF) && !defined(__sparc)
 	if (bgep->asf_enabled && !bgep->asf_wordswapped) {
 		/* workaround for word swap error */
 		if (addr & 4)
@@ -876,11 +883,15 @@
 	}
 #endif
 
+#ifdef __sparc
+	data = bge_nic_read32(bgep, addr);
+#else
 	bge_nic_setwin(bgep, addr & ~MWBAR_GRANULE_MASK);
 	addr &= MWBAR_GRANULE_MASK;
 	addr += NIC_MEM_WINDOW_OFFSET;
 
 	data = ddi_get32(bgep->io_handle, PIO_ADDR(bgep, addr));
+#endif
 
 	BGE_TRACE(("bge_nic_get32($%p, 0x%lx) = 0x%08x",
 		(void *)bgep, addr, data));
@@ -897,7 +908,7 @@
 	BGE_TRACE(("bge_nic_put32($%p, 0x%lx, 0x%08x)",
 		(void *)bgep, addr, data));
 
-#ifdef BGE_IPMI_ASF
+#if defined(BGE_IPMI_ASF) && !defined(__sparc)
 	if (bgep->asf_enabled && !bgep->asf_wordswapped) {
 		/* workaround for word swap error */
 		if (addr & 4)
@@ -907,14 +918,20 @@
 	}
 #endif
 
+#ifdef __sparc
+	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);
+	pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MWBAR, 0);
+#else
 	bge_nic_setwin(bgep, addr & ~MWBAR_GRANULE_MASK);
 	addr &= MWBAR_GRANULE_MASK;
 	addr += NIC_MEM_WINDOW_OFFSET;
 	ddi_put32(bgep->io_handle, PIO_ADDR(bgep, addr), data);
 	BGE_PCICHK(bgep);
+#endif
 }
 
-
 static uint64_t bge_nic_get64(bge_t *bgep, bge_regno_t addr);
 #pragma	inline(bge_nic_get64)
 
@@ -2512,6 +2529,15 @@
 	switch (regno) {
 	case FTQ_RESET_REG:
 		/*
+		 * For Schumacher's bugfix CR6490108
+		 */
+#ifdef BGE_IPMI_ASF
+#ifdef BGE_NETCONSOLE
+		if (bgep->asf_enabled)
+			return (B_TRUE);
+#endif
+#endif
+		/*
 		 * Not quite like the others; it doesn't
 		 * have an <enable> bit, but instead we
 		 * have to set and then clear all the bits
@@ -2555,6 +2581,12 @@
 
 	switch (regno) {
 	case FTQ_RESET_REG:
+#ifdef BGE_IPMI_ASF
+#ifdef BGE_NETCONSOLE
+		if (bgep->asf_enabled)
+			return (B_TRUE);
+#endif
+#endif
 		/*
 		 * Not quite like the others; it doesn't
 		 * have an <enable> bit, but instead we
@@ -3031,6 +3063,19 @@
 
 #ifdef BGE_IPMI_ASF
 	if (bgep->asf_enabled) {
+#ifdef __sparc
+		mhcr = MHCR_ENABLE_INDIRECT_ACCESS |
+			MHCR_ENABLE_TAGGED_STATUS_MODE |
+			MHCR_MASK_INTERRUPT_MODE |
+			MHCR_MASK_PCI_INT_OUTPUT |
+			MHCR_CLEAR_INTERRUPT_INTA |
+			MHCR_ENABLE_ENDIAN_WORD_SWAP |
+			MHCR_ENABLE_ENDIAN_BYTE_SWAP;
+		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) |
+			MEMORY_ARBITER_ENABLE);
+#endif
 		if (asf_mode == ASF_MODE_INIT) {
 			bge_asf_pre_reset_operations(bgep, BGE_INIT_RESET);
 		} else if (asf_mode == ASF_MODE_SHUTDOWN) {
@@ -3129,31 +3174,52 @@
 
 #ifdef BGE_IPMI_ASF
 	if (bgep->asf_enabled) {
-		if (asf_mode != ASF_MODE_NONE) {
-			/* Wait for NVRAM init */
-			i = 0;
-			drv_usecwait(5000);
-			mailbox = bge_nic_get32(bgep, BGE_FIRMWARE_MAILBOX);
-			while ((mailbox != (uint32_t)
-				~BGE_MAGIC_NUM_FIRMWARE_INIT_DONE) &&
-				(i < 10000)) {
-				drv_usecwait(100);
-				mailbox = bge_nic_get32(bgep,
-					BGE_FIRMWARE_MAILBOX);
-				i++;
-			}
-			if (!bgep->asf_newhandshake) {
-				if ((asf_mode == ASF_MODE_INIT) ||
-					(asf_mode == ASF_MODE_POST_INIT)) {
-
-					bge_asf_post_reset_old_mode(bgep,
-						BGE_INIT_RESET);
-				} else {
-					bge_asf_post_reset_old_mode(bgep,
-						BGE_SHUTDOWN_RESET);
-				}
+#ifdef __sparc
+		bge_reg_put32(bgep, MEMORY_ARBITER_MODE_REG,
+			MEMORY_ARBITER_ENABLE |
+			bge_reg_get32(bgep, MEMORY_ARBITER_MODE_REG));
+#endif
+
+#ifdef  BGE_NETCONSOLE
+		if (!bgep->asf_newhandshake) {
+			if ((asf_mode == ASF_MODE_INIT) ||
+			(asf_mode == ASF_MODE_POST_INIT)) {
+				bge_asf_post_reset_old_mode(bgep,
+					BGE_INIT_RESET);
+			} else {
+				bge_asf_post_reset_old_mode(bgep,
+					BGE_SHUTDOWN_RESET);
 			}
 		}
+#endif
+
+		/* Wait for NVRAM init */
+		i = 0;
+		drv_usecwait(5000);
+		mailbox = bge_nic_get32(bgep, BGE_FIRMWARE_MAILBOX);
+
+		while ((mailbox != (uint32_t)
+			~BGE_MAGIC_NUM_FIRMWARE_INIT_DONE) &&
+			(i < 10000)) {
+			drv_usecwait(100);
+			mailbox = bge_nic_get32(bgep,
+				BGE_FIRMWARE_MAILBOX);
+			i++;
+		}
+
+#ifndef BGE_NETCONSOLE
+		if (!bgep->asf_newhandshake) {
+			if ((asf_mode == ASF_MODE_INIT) ||
+				(asf_mode == ASF_MODE_POST_INIT)) {
+
+				bge_asf_post_reset_old_mode(bgep,
+					BGE_INIT_RESET);
+			} else {
+				bge_asf_post_reset_old_mode(bgep,
+					BGE_SHUTDOWN_RESET);
+			}
+		}
+#endif
 	}
 #endif
 	/*
@@ -3842,7 +3908,7 @@
 	uint64_t flags;
 	uint32_t regval;
 	uint_t result;
-	int retval;
+	int retval, loop_cnt = 0;
 
 	BGE_TRACE(("bge_intr($%p) ($%p)", arg1, arg2));
 
@@ -3904,7 +3970,7 @@
 	 */
 	bgep->missed_dmas += 1;
 	bsp = DMA_VPTR(bgep->status_block);
-	for (;;) {
+	for (loop_cnt = 0; loop_cnt < bge_intr_max_loop; loop_cnt++) {
 		if (bgep->bge_chip_state != BGE_CHIP_RUNNING) {
 			/*
 			 * bge_chip_stop() may have freed dma area etc
@@ -4257,7 +4323,9 @@
 	if (dogval < bge_watchdog_count)
 		return (B_FALSE);
 
+#if !defined(BGE_NETCONSOLE)
 	BGE_REPORT((bgep, "Tx stall detected, watchdog code 0x%x", dogval));
+#endif
 	bge_fm_ereport(bgep, DDI_FM_DEVICE_STALL);
 	return (B_TRUE);
 }
@@ -5087,6 +5155,8 @@
 		/*
 		 * Reset and reinitialise the 570x hardware
 		 */
+		bgep->bge_chip_state = BGE_CHIP_FAULT;
+		ddi_trigger_softintr(bgep->factotum_id);
 		(void) bge_restart(bgep, cmd == BGE_HARD_RESET);
 		return (IOC_ACK);
 	}
@@ -5299,6 +5369,7 @@
 {
 	uint32_t data;
 
+#ifndef __sparc
 	if (!bgep->asf_wordswapped) {
 		/* a workaround word swap error */
 		if (addr & 4)
@@ -5306,15 +5377,16 @@
 		else
 			addr = addr + 4;
 	}
+#endif
 
 	pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MWBAR, addr);
 	data = pci_config_get32(bgep->cfg_handle, PCI_CONF_BGE_MWDAR);
 	pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MWBAR, 0);
 
+	data = LE_32(data);
 	return (data);
 }
 
-
 void
 bge_asf_update_status(bge_t *bgep)
 {
@@ -5380,6 +5452,7 @@
 	uint32_t nicsig;
 	uint32_t niccfg;
 
+	bgep->asf_enabled = B_FALSE;
 	nicsig = bge_nic_read32(bgep, BGE_NIC_DATA_SIG_ADDR);
 	if (nicsig == BGE_NIC_DATA_SIG) {
 		niccfg = bge_nic_read32(bgep, BGE_NIC_DATA_NIC_CFG_ADDR);
--- a/usr/src/uts/common/io/bge/bge_hw.h	Wed Mar 28 18:46:25 2007 -0700
+++ b/usr/src/uts/common/io/bge/bge_hw.h	Wed Mar 28 19:49:13 2007 -0700
@@ -545,6 +545,12 @@
 #define	COALESCE_NOW			0x00000008
 
 /*
+ * Memory Arbiter Mode Register
+ * (MEMORY_ARBITER_MODE_REG, 0x4000)
+ */
+#define	MEMORY_ARBITER_ENABLE		0x00000002
+
+/*
  * Buffer Manager Mode Register
  * (BUFFER_MANAGER_MODE_REG, 0x4400)
  *
--- a/usr/src/uts/common/io/bge/bge_impl.h	Wed Mar 28 18:46:25 2007 -0700
+++ b/usr/src/uts/common/io/bge/bge_impl.h	Wed Mar 28 19:49:13 2007 -0700
@@ -1211,6 +1211,10 @@
 void bge_nic_put32(bge_t *bgep, bge_regno_t addr, uint32_t data);
 #pragma	inline(bge_nic_put32)
 uint32_t bge_nic_read32(bge_t *bgep, bge_regno_t addr);
+void bge_ind_put32(bge_t *bgep, bge_regno_t regno, uint32_t val);
+#pragma inline(bge_ind_put32)
+uint32_t bge_ind_get32(bge_t *bgep, bge_regno_t regno);
+#pragma inline(bge_ind_get32)
 void bge_asf_update_status(bge_t *bgep);
 void bge_asf_heartbeat(void *bgep);
 void bge_asf_stop_timer(bge_t *bgep);
--- a/usr/src/uts/common/io/bge/bge_main2.c	Wed Mar 28 18:46:25 2007 -0700
+++ b/usr/src/uts/common/io/bge/bge_main2.c	Wed Mar 28 19:49:13 2007 -0700
@@ -2509,6 +2509,12 @@
 	int intr_types;
 #ifdef BGE_IPMI_ASF
 	uint32_t mhcrValue;
+#ifdef __sparc
+	uint16_t value16;
+#endif
+#ifdef BGE_NETCONSOLE
+	int retval;
+#endif
 #endif
 
 	instance = ddi_get_instance(devinfo);
@@ -2578,7 +2584,24 @@
 	 */
 	err = pci_config_setup(devinfo, &bgep->cfg_handle);
 #ifdef BGE_IPMI_ASF
+#ifdef __sparc
+	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);
+	mhcrValue = MHCR_ENABLE_INDIRECT_ACCESS |
+		MHCR_ENABLE_TAGGED_STATUS_MODE |
+		MHCR_MASK_INTERRUPT_MODE |
+		MHCR_MASK_PCI_INT_OUTPUT |
+		MHCR_CLEAR_INTERRUPT_INTA |
+		MHCR_ENABLE_ENDIAN_WORD_SWAP |
+		MHCR_ENABLE_ENDIAN_BYTE_SWAP;
+	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) |
+		MEMORY_ARBITER_ENABLE);
+#else
 	mhcrValue = pci_config_get32(bgep->cfg_handle, PCI_CONF_BGE_MHCR);
+#endif
 	if (mhcrValue & MHCR_ENABLE_ENDIAN_WORD_SWAP) {
 		bgep->asf_wordswapped = B_TRUE;
 	} else {
@@ -2776,7 +2799,11 @@
 	 * filtering, promiscuity, loopback mode.
 	 */
 #ifdef BGE_IPMI_ASF
+#ifdef BGE_NETCONSOLE
+	if (bge_reset(bgep, ASF_MODE_INIT) != DDI_SUCCESS) {
+#else
 	if (bge_reset(bgep, ASF_MODE_SHUTDOWN) != DDI_SUCCESS) {
+#endif
 #else
 	if (bge_reset(bgep) != DDI_SUCCESS) {
 #endif
@@ -2875,6 +2902,17 @@
 
 	bgep->progress |= PROGRESS_READY;
 	ASSERT(bgep->bge_guard == BGE_GUARD);
+#ifdef BGE_IPMI_ASF
+#ifdef BGE_NETCONSOLE
+	if (bgep->asf_enabled) {
+		mutex_enter(bgep->genlock);
+		retval = bge_chip_start(bgep, B_TRUE);
+		mutex_exit(bgep->genlock);
+		if (retval != DDI_SUCCESS)
+			goto attach_fail;
+	}
+#endif
+#endif
 	return (DDI_SUCCESS);
 
 attach_fail:
--- a/usr/src/uts/common/io/bge/bge_recv2.c	Wed Mar 28 18:46:25 2007 -0700
+++ b/usr/src/uts/common/io/bge/bge_recv2.c	Wed Mar 28 19:49:13 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -284,6 +284,7 @@
 	mblk_t *head;
 	mblk_t **tail;
 	mblk_t *mp;
+	int recv_cnt = 0;
 
 	ASSERT(mutex_owned(rrp->rx_lock));
 
@@ -310,10 +311,12 @@
 	tail = &head;
 	slot = rrp->rx_next;
 
-	while (slot != *rrp->prod_index_p) {	/* Note: volatile	*/
+	while ((slot != *rrp->prod_index_p) && /* Note: volatile	*/
+		(recv_cnt < BGE_MAXPKT_RCVED)) {
 		if ((mp = bge_receive_packet(bgep, &hw_rbd_p[slot])) != NULL) {
 			*tail = mp;
 			tail = &mp->b_next;
+			recv_cnt++;
 		}
 		rrp->rx_next = slot = NEXT(slot, rrp->desc.nslots);
 	}