Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev Fixes the rx stall problem on 82578 by MANY workarou...
details: https://anonhg.NetBSD.org/src/rev/c0c1915d45ed
branches: trunk
changeset: 750795:c0c1915d45ed
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Thu Jan 14 18:56:01 2010 +0000
description:
Fixes the rx stall problem on 82578 by MANY workaround code.
We need more work for 82577.
diffstat:
sys/dev/mii/inbmphyreg.h | 110 ++++++++++
sys/dev/pci/if_wm.c | 489 +++++++++++++++++++++++++++++++++++-----------
sys/dev/pci/if_wmreg.h | 10 +-
sys/dev/pci/if_wmvar.h | 17 +-
4 files changed, 504 insertions(+), 122 deletions(-)
diffs (truncated from 919 to 300 lines):
diff -r 118fd9f5f35b -r c0c1915d45ed sys/dev/mii/inbmphyreg.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/mii/inbmphyreg.h Thu Jan 14 18:56:01 2010 +0000
@@ -0,0 +1,110 @@
+/* $NetBSD: inbmphyreg.h,v 1.1 2010/01/14 18:56:01 msaitoh Exp $ */
+/*******************************************************************************
+Copyright (c) 2001-2005, Intel Corporation
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+
+/*
+ * Copied from the Intel code, and then modified to match NetBSD
+ * style for MII registers more.
+ */
+
+#ifndef _DEV_MII_INBMPHYREG_H_
+#define _DEV_MII_INBMPHYREG_H_
+
+/* Bits...
+ * 15-5: page
+ * 4-0: register offset
+ */
+#define BME1000_PAGE_SHIFT 5
+#define BME1000_REG(page, reg) \
+ (((page) << BME1000_PAGE_SHIFT) | ((reg) & BME1000_MAX_REG_ADDRESS))
+
+#define BME1000_MAX_REG_ADDRESS 0x1f /* 5 bit address bus (0-0x1f) */
+#define BME1000_MAX_MULTI_PAGE_REG 0xf /* Registers equal on all pages */
+
+#define BM_PHY_REG_PAGE(offset) \
+ ((uint16_t)(((offset) >> BME1000_PAGE_SHIFT) & 0xffff))
+#define BM_PHY_REG_NUM(offset) \
+ ((uint16_t)((offset) & BME1000_MAX_REG_ADDRESS) \
+ | (((offset) >> (21 - BME1000_PAGE_SHIFT)) & ~BME1000_MAX_REG_ADDRESS))
+
+/* BME1000 Specific Registers */
+#define BME1000_PHY_SPEC_CTRL BME1000_REG(0, 16) /* PHY Specific Control */
+#define BME1000_PSCR_DISABLE_JABBER 0x0001 /* 1=Disable Jabber */
+#define BME1000_PSCR_POLARITY_REVERSAL_DISABLE 0x0002 /* 1=Polarity Reversal Disabled */
+#define BME1000_PSCR_POWER_DOWN 0x0004 /* 1=Power Down */
+#define BME1000_PSCR_COPPER_TRANSMITER_DISABLE 0x0008 /* 1=Transmitter Disabled */
+#define BME1000_PSCR_CROSSOVER_MODE_MASK 0x0060
+#define BME1000_PSCR_CROSSOVER_MODE_MDI 0x0000 /* 00=Manual MDI configuration */
+#define BME1000_PSCR_CROSSOVER_MODE_MDIX 0x0020 /* 01=Manual MDIX configuration */
+#define BME1000_PSCR_CROSSOVER_MODE_AUTO 0x0060 /* 11=Automatic crossover */
+#define BME1000_PSCR_ENALBE_EXTENDED_DISTANCE 0x0080 /* 1=Enable Extended Distance */
+#define BME1000_PSCR_ENERGY_DETECT_MASK 0x0300
+#define BME1000_PSCR_ENERGY_DETECT_OFF 0x0000 /* 00,01=Off */
+#define BME1000_PSCR_ENERGY_DETECT_RX 0x0200 /* 10=Sense on Rx only (Energy Detect) */
+#define BME1000_PSCR_ENERGY_DETECT_RX_TM 0x0300 /* 11=Sense and Tx NLP */
+#define BME1000_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force Link Good */
+#define BME1000_PSCR_DOWNSHIFT_ENABLE 0x0800 /* 1=Enable Downshift */
+#define BME1000_PSCR_DOWNSHIFT_COUNTER_MASK 0x7000
+#define BME1000_PSCR_DOWNSHIFT_COUNTER_SHIFT 12
+
+#define BME1000_PHY_PAGE_SELECT BME1000_REG(0, 22) /* Page Select */
+
+#define BME1000_BIAS_SETTING 29
+#define BME1000_BIAS_SETTING2 30
+
+#define I82578_ADDR_REG 29
+#define I82577_ADDR_REG 16
+#define I82577_CFG_REG 22
+
+#define HV_OEM_BITS BME1000_REG(0, 25)
+#define HV_OEM_BITS_LPLU (1 << 2)
+#define HV_OEM_BITS_A1KDIS (1 << 6)
+#define HV_OEM_BITS_ANEGNOW (1 << 10)
+
+#define HV_INTC_FC_PAGE_START 768
+#define BM_PORT_CTRL_PAGE 769
+
+#define IGP3_KMRN_DIAG BME1000_REG(770, 19)
+
+#define HV_MUX_DATA_CTRL BME1000_REG(776, 16)
+#define HV_MUX_DATA_CTRL_FORCE_SPEED (1 << 2)
+#define HV_MUX_DATA_CTRL_GEN_TO_MAC (1 << 10)
+
+#define BM_WUC_PAGE 800
+#define BM_WUC BME1000_REG(BM_WUC_PAGE, 1)
+#define BM_WUC_ADDRESS_OPCODE 0x11
+#define BM_WUC_DATA_OPCODE 0x12
+#define BM_WUC_ENABLE_PAGE BM_PORT_CTRL_PAGE
+#define BM_WUC_ENABLE_REG 17
+#define BM_WUC_ENABLE_BIT (1 << 2)
+#define BM_WUC_HOST_WU_BIT (1 << 4)
+
+#endif /* _DEV_MII_INBMPHYREG_H_ */
diff -r 118fd9f5f35b -r c0c1915d45ed sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Thu Jan 14 17:49:31 2010 +0000
+++ b/sys/dev/pci/if_wm.c Thu Jan 14 18:56:01 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.191 2010/01/12 22:26:30 msaitoh Exp $ */
+/* $NetBSD: if_wm.c,v 1.192 2010/01/14 18:56:02 msaitoh Exp $ */
/*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -76,7 +76,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.191 2010/01/12 22:26:30 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.192 2010/01/14 18:56:02 msaitoh Exp $");
#include "bpfilter.h"
#include "rnd.h"
@@ -124,6 +124,7 @@
#include <dev/mii/mii_bitbang.h>
#include <dev/mii/ikphyreg.h>
#include <dev/mii/igphyreg.h>
+#include <dev/mii/inbmphyreg.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
@@ -249,7 +250,9 @@
pci_chipset_tag_t sc_pc;
pcitag_t sc_pcitag;
- wm_chip_type sc_type; /* chip type */
+ wm_chip_type sc_type; /* MAC type */
+ int sc_rev; /* MAC revision */
+ wm_phy_type sc_phytype; /* PHY type */
int sc_flags; /* flags; see below */
int sc_if_flags; /* last if_flags */
int sc_bus_speed; /* PCI/PCIX bus speed */
@@ -366,6 +369,7 @@
#endif
int sc_ich8_flash_base;
int sc_ich8_flash_bank_size;
+ int sc_nvm_k1_enabled;
};
#define WM_RXCHAIN_RESET(sc) \
@@ -520,8 +524,8 @@
static void wm_gmii_i80003_writereg(device_t, int, int, int);
static int wm_gmii_bm_readreg(device_t, int, int);
static void wm_gmii_bm_writereg(device_t, int, int, int);
-static int wm_gmii_kv_readreg(device_t, int, int);
-static void wm_gmii_kv_writereg(device_t, int, int, int);
+static int wm_gmii_hv_readreg(device_t, int, int);
+static void wm_gmii_hv_writereg(device_t, int, int, int);
static void wm_gmii_statchg(device_t);
@@ -562,6 +566,9 @@
static int wm_check_reset_block(struct wm_softc *);
static void wm_get_hw_control(struct wm_softc *);
static int wm_check_for_link(struct wm_softc *);
+static void wm_hv_phy_workaround_ich8lan(struct wm_softc *);
+static void wm_k1_gig_workaround_hv(struct wm_softc *, int);
+static void wm_configure_k1_ich8lan(struct wm_softc *, int);
CFATTACH_DECL_NEW(wm, sizeof(struct wm_softc),
wm_match, wm_attach, NULL, NULL);
@@ -991,18 +998,18 @@
else
sc->sc_dmat = pa->pa_dmat;
- preg = PCI_REVISION(pci_conf_read(pc, pa->pa_tag, PCI_CLASS_REG));
+ sc->sc_rev = PCI_REVISION(pci_conf_read(pc, pa->pa_tag, PCI_CLASS_REG));
aprint_naive(": Ethernet controller\n");
- aprint_normal(": %s, rev. %d\n", wmp->wmp_name, preg);
+ aprint_normal(": %s, rev. %d\n", wmp->wmp_name, sc->sc_rev);
sc->sc_type = wmp->wmp_type;
if (sc->sc_type < WM_T_82543) {
- if (preg < 2) {
+ if (sc->sc_rev < 2) {
aprint_error_dev(sc->sc_dev,
"i82542 must be at least rev. 2\n");
return;
}
- if (preg < 3)
+ if (sc->sc_rev < 3)
sc->sc_type = WM_T_82542_2_0;
}
@@ -1575,6 +1582,18 @@
sc->sc_tdt_reg = WMREG_TDT;
}
+ if (sc->sc_type == WM_T_PCH) {
+ uint16_t val;
+
+ /* Save the NVM K1 bit setting */
+ wm_read_eeprom(sc, EEPROM_OFF_K1_CONFIG, 1, &val);
+
+ if ((val & EEPROM_K1_CONFIG_ENABLE) != 0)
+ sc->sc_nvm_k1_enabled = 1;
+ else
+ sc->sc_nvm_k1_enabled = 0;
+ }
+
/*
* Determine if we're TBI or GMII mode, and initialize the
* media structures accordingly.
@@ -2896,74 +2915,101 @@
}
/*
- * wm_linkintr:
+ * wm_linkintr_gmii:
*
- * Helper; handle link interrupts.
+ * Helper; handle link interrupts for GMII.
*/
static void
-wm_linkintr(struct wm_softc *sc, uint32_t icr)
+wm_linkintr_gmii(struct wm_softc *sc, uint32_t icr)
+{
+
+ DPRINTF(WM_DEBUG_LINK, ("%s: %s:\n", device_xname(sc->sc_dev),
+ __func__));
+
+ if (icr & ICR_LSC) {
+ DPRINTF(WM_DEBUG_LINK,
+ ("%s: LINK: LSC -> mii_tick\n",
+ device_xname(sc->sc_dev)));
+ mii_tick(&sc->sc_mii);
+ if (sc->sc_type == WM_T_82543) {
+ int miistatus, active;
+
+ /*
+ * With 82543, we need to force speed and
+ * duplex on the MAC equal to what the PHY
+ * speed and duplex configuration is.
+ */
+ miistatus = sc->sc_mii.mii_media_status;
+
+ if (miistatus & IFM_ACTIVE) {
+ active = sc->sc_mii.mii_media_active;
+ sc->sc_ctrl &= ~(CTRL_SPEED_MASK | CTRL_FD);
+ switch (IFM_SUBTYPE(active)) {
+ case IFM_10_T:
+ sc->sc_ctrl |= CTRL_SPEED_10;
+ break;
+ case IFM_100_TX:
+ sc->sc_ctrl |= CTRL_SPEED_100;
+ break;
+ case IFM_1000_T:
+ sc->sc_ctrl |= CTRL_SPEED_1000;
+ break;
+ default:
+ /*
+ * fiber?
+ * Shoud not enter here.
+ */
+ printf("unknown media (%x)\n",
+ active);
+ break;
+ }
+ if (active & IFM_FDX)
+ sc->sc_ctrl |= CTRL_FD;
+ CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl);
+ }
+ } else if (sc->sc_type == WM_T_PCH) {
+ wm_k1_gig_workaround_hv(sc,
+ ((sc->sc_mii.mii_media_status & IFM_ACTIVE) != 0));
+ }
+
+ if ((sc->sc_phytype == WMPHY_82578)
+ && (IFM_SUBTYPE(sc->sc_mii.mii_media_active)
+ == IFM_1000_T)) {
+
+ if ((sc->sc_mii.mii_media_status & IFM_ACTIVE) != 0) {
+ printf("XXX link sall wa\n");
+ delay(200*1000); /* XXX too big */
+
+ /* Link stall fix for link up */
+ wm_gmii_hv_writereg(sc->sc_dev, 1,
+ HV_MUX_DATA_CTRL,
+ HV_MUX_DATA_CTRL_GEN_TO_MAC
+ | HV_MUX_DATA_CTRL_FORCE_SPEED);
+ wm_gmii_hv_writereg(sc->sc_dev, 1,
Home |
Main Index |
Thread Index |
Old Index