# HG changeset patch # User ml149210 # Date 1175136553 25200 # Node ID 2f5f98948dcec20a0f7641e5f5e18e8d0b3acf33 # Parent 9e19a8d4a3554ebf73fd09baa559b68addda58de 6490108 ON bge driver support required for Schumacher(CP3010) 6498937 system hang while doing MAX and snoop through bge diff -r 9e19a8d4a355 -r 2f5f98948dce usr/src/uts/common/io/bge/bge.h --- 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 } diff -r 9e19a8d4a355 -r 2f5f98948dce usr/src/uts/common/io/bge/bge_chip2.c --- 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 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 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); diff -r 9e19a8d4a355 -r 2f5f98948dce usr/src/uts/common/io/bge/bge_hw.h --- 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) * diff -r 9e19a8d4a355 -r 2f5f98948dce usr/src/uts/common/io/bge/bge_impl.h --- 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); diff -r 9e19a8d4a355 -r 2f5f98948dce usr/src/uts/common/io/bge/bge_main2.c --- 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: diff -r 9e19a8d4a355 -r 2f5f98948dce usr/src/uts/common/io/bge/bge_recv2.c --- 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); }