Pull up the following (via patch), requested by msaitoh in ticket #650:

sys/dev/pci/if_wm.c			1.650, 1.652-1.654
	sys/dev/pci/if_wmreg.h			1.116-1.117

- Set CTRL_ILOS(Invert loss of signal) bit correctly on 82580
  port 1, 2, 3 and newer chips. This change fixes a bug that some
  fiber, serdes or SFP devices don't detect the link status correctly.
- Simplify code by using "struct mii_data *mii" more. No functional
  change.
- MSI-X doesn't use sc->sc_icr variable, so move the code into
  non-MSI-X part. No functional change intended.
- Modify debug printfs a bit.
- Rename macro.
- Use __BIT()
- Fix comment. Add comment.
- KNF.
This commit is contained in:
martin 2020-01-26 11:13:27 +00:00
parent 3ba0477766
commit b6e92bef63
2 changed files with 61 additions and 36 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_wm.c,v 1.645.2.3 2020/01/23 10:10:57 martin Exp $ */
/* $NetBSD: if_wm.c,v 1.645.2.4 2020/01/26 11:13:27 martin Exp $ */
/*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@ -82,7 +82,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.645.2.3 2020/01/23 10:10:57 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.645.2.4 2020/01/26 11:13:27 martin Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@ -2656,10 +2656,11 @@ alloc_retry:
}
}
/* XXX For other than 82580? */
if (sc->sc_type == WM_T_82580) {
wm_nvm_read(sc, NVM_OFF_CFG3_PORTA, 1, &nvmword);
if (nvmword & __BIT(13))
if ((sc->sc_type >= WM_T_82580) && (sc->sc_type <= WM_T_I211)) {
wm_nvm_read(sc,
NVM_OFF_LAN_FUNC_82580(sc->sc_funcid) + NVM_OFF_CFG3_PORTA,
1, &nvmword);
if (nvmword & NVM_CFG3_ILOS)
sc->sc_ctrl |= CTRL_ILOS;
}
@ -6047,8 +6048,7 @@ wm_init_locked(struct ifnet *ifp)
/* Set up the interrupt registers. */
CSR_WRITE(sc, WMREG_IMC, 0xffffffffU);
sc->sc_icr = ICR_TXDW | ICR_LSC | ICR_RXSEQ | ICR_RXDMT0 |
ICR_RXO | ICR_RXT0;
if (wm_is_using_msix(sc)) {
uint32_t mask;
struct wm_queue *wmq;
@ -6088,8 +6088,11 @@ wm_init_locked(struct ifnet *ifp)
CSR_WRITE(sc, WMREG_IMS, ICR_LSC);
break;
}
} else
} else {
sc->sc_icr = ICR_TXDW | ICR_LSC | ICR_RXSEQ | ICR_RXDMT0 |
ICR_RXO | ICR_RXT0;
CSR_WRITE(sc, WMREG_IMS, sc->sc_icr);
}
/* Set up the inter-packet gap. */
CSR_WRITE(sc, WMREG_TIPG, sc->sc_tipg);
@ -9286,7 +9289,7 @@ wm_linkintr_serdes(struct wm_softc *sc, uint32_t icr)
{
struct ifnet *ifp = &sc->sc_ethercom.ec_if;
struct mii_data *mii = &sc->sc_mii;
struct ifmedia_entry *ife = sc->sc_mii.mii_media.ifm_cur;
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint32_t pcs_adv, pcs_lpab, reg;
DPRINTF(WM_DEBUG_LINK, ("%s: %s:\n", device_xname(sc->sc_dev),
@ -9629,11 +9632,12 @@ wm_linkintr_msix(void *arg)
uint32_t reg;
bool has_rxo;
DPRINTF(WM_DEBUG_LINK,
("%s: LINK: got link intr\n", device_xname(sc->sc_dev)));
reg = CSR_READ(sc, WMREG_ICR);
WM_CORE_LOCK(sc);
DPRINTF(WM_DEBUG_LINK,
("%s: LINK: got link intr. ICR = %08x\n",
device_xname(sc->sc_dev), reg));
if (sc->sc_core_stopping)
goto out;
@ -11411,7 +11415,7 @@ wm_gmii_statchg(struct ifnet *ifp)
sc->sc_ctrl |= CTRL_RFCE;
}
if (sc->sc_mii.mii_media_active & IFM_FDX) {
if (mii->mii_media_active & IFM_FDX) {
DPRINTF(WM_DEBUG_LINK,
("%s: LINK: statchg: FDX\n", ifp->if_xname));
sc->sc_tctl |= TCTL_COLD(TX_COLLISION_DISTANCE_FDX);
@ -11426,7 +11430,7 @@ wm_gmii_statchg(struct ifnet *ifp)
CSR_WRITE(sc, (sc->sc_type < WM_T_82543) ? WMREG_OLD_FCRTL
: WMREG_FCRTL, sc->sc_fcrtl);
if (sc->sc_type == WM_T_80003) {
switch (IFM_SUBTYPE(sc->sc_mii.mii_media_active)) {
switch (IFM_SUBTYPE(mii->mii_media_active)) {
case IFM_1000_T:
wm_kmrn_writereg(sc, KUMCTRLSTA_OFFSET_HD_CTRL,
KUMCTRLSTA_HD_CTRL_1000_DEFAULT);
@ -12085,7 +12089,8 @@ wm_tbi_tick(struct wm_softc *sc)
if ((IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO)
&& (++sc->sc_tbi_serdes_ticks
>= sc->sc_tbi_serdes_anegticks)) {
DPRINTF(WM_DEBUG_LINK, ("EXPIRE\n"));
DPRINTF(WM_DEBUG_LINK, ("%s: %s: EXPIRE\n",
device_xname(sc->sc_dev), __func__));
sc->sc_tbi_serdes_ticks = 0;
/*
* Reset the link, and let autonegotiation do
@ -12192,7 +12197,7 @@ wm_serdes_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
{
struct wm_softc *sc = ifp->if_softc;
struct mii_data *mii = &sc->sc_mii;
struct ifmedia_entry *ife = sc->sc_mii.mii_media.ifm_cur;
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint32_t pcs_adv, pcs_lpab, reg;
ifmr->ifm_status = IFM_AVALID;
@ -12310,7 +12315,8 @@ wm_serdes_tick(struct wm_softc *sc)
if ((IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO)
&& (++sc->sc_tbi_serdes_ticks
>= sc->sc_tbi_serdes_anegticks)) {
DPRINTF(WM_DEBUG_LINK, ("EXPIRE\n"));
DPRINTF(WM_DEBUG_LINK, ("%s: %s: EXPIRE\n",
device_xname(sc->sc_dev), __func__));
sc->sc_tbi_serdes_ticks = 0;
/* XXX */
wm_serdes_mediachange(ifp);
@ -12372,6 +12378,7 @@ wm_sfp_get_media_type(struct wm_softc *sc)
}
if (rv != 0)
goto out;
switch (val) {
case SFF_SFP_ID_SFF:
aprint_normal_dev(sc->sc_dev,
@ -12387,9 +12394,8 @@ wm_sfp_get_media_type(struct wm_softc *sc)
}
rv = wm_sfp_read_data_byte(sc, SFF_SFP_ETH_FLAGS_OFF, &val);
if (rv != 0) {
if (rv != 0)
goto out;
}
if ((val & (SFF_SFP_ETH_FLAGS_1000SX | SFF_SFP_ETH_FLAGS_1000LX)) != 0)
mediatype = WM_MEDIATYPE_SERDES;
@ -15461,7 +15467,7 @@ wm_hv_phy_workarounds_ich8lan(struct wm_softc *sc)
if ((rv = wm_set_mdio_slow_mode_hv(sc)) != 0)
return rv;
child = LIST_FIRST(&sc->sc_mii.mii_phys);
child = LIST_FIRST(&mii->mii_phys);
if (child != NULL)
phyrev = child->mii_mpd_rev;
@ -15496,8 +15502,7 @@ wm_hv_phy_workarounds_ich8lan(struct wm_softc *sc)
*/
if ((child != NULL) && (phyrev < 2)) {
PHY_RESET(child);
rv = sc->sc_mii.mii_writereg(dev, 2, MII_BMCR,
0x3140);
rv = mii->mii_writereg(dev, 2, MII_BMCR, 0x3140);
if (rv != 0)
return rv;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_wmreg.h,v 1.115 2019/07/23 09:37:08 msaitoh Exp $ */
/* $NetBSD: if_wmreg.h,v 1.115.2.1 2020/01/26 11:13:28 martin Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@ -435,7 +435,7 @@ struct livengood_tcpip_ctxdesc {
#define CTRL_D_UD_EN (1U << 13) /* Dock/Undock enable */
#define CTRL_D_UD_POL (1U << 14) /* Defined polarity of Dock/Undock indication in SDP[0] */
#define CTRL_F_PHY_R (1U << 15) /* Reset both PHY ports, through PHYRST_N pin */
#define CTRL_EXT_LINK_EN (1U << 16) /* enable link status from external LINK_0 and LINK_1 pins */
#define CTRL_EXTLINK_EN (1U << 16) /* enable link status from external LINK_0 and LINK_1 pins */
#define CTRL_LANPHYPC_OVERRIDE (1U << 16) /* SW control of LANPHYPC */
#define CTRL_LANPHYPC_VALUE (1U << 17) /* SW value of LANPHYPC */
#define CTRL_SWDPINS_SHIFT 18
@ -639,6 +639,14 @@ struct livengood_tcpip_ctxdesc {
#define KUMCTRLSTA_OPMODE_MASK 0x000c
#define KUMCTRLSTA_OPMODE_INBAND_MDIO 0x0004
#define WMREG_CONNSW 0x0034 /* Copper/Fiber Switch Control (>= 82575) */
#define CONNSW_AUTOSENSE_EN __BIT(0) /* Auto Sense Enable */
#define CONNSW_AUTOSENSE_CONF __BIT(1) /* Auto Sense Config Mode */
#define CONNSW_ENRGSRC __BIT(2) /* SerDes Energy Detect Src */
#define CONNSW_SERDESD __BIT(9) /* SerDes Signal Detect Ind. */
#define CONNSW_PHYSD __BIT(10) /* PHY Signal Detect Ind. */
#define CONNSW_PHY_PDN __BIT(11) /* Internal PHY in powerdown */
#define WMREG_VET 0x0038 /* VLAN Ethertype */
#define WMREG_MDPHYA 0x003c /* PHY address - RW */
@ -1153,13 +1161,23 @@ struct livengood_tcpip_ctxdesc {
#define PCS_CFG_PCS_EN __BIT(3)
#define WMREG_PCS_LCTL 0x4208 /* PCS Link Control */
#define PCS_LCTL_FSV_1000 __BIT(2) /* AN Timeout Enable */
#define PCS_LCTL_FDV_FULL __BIT(3) /* AN Timeout Enable */
#define PCS_LCTL_FSD __BIT(4) /* AN Timeout Enable */
#define PCS_LCTL_FORCE_FC __BIT(7) /* AN Timeout Enable */
#define PCS_LCTL_AN_ENABLE __BIT(16) /* AN Timeout Enable */
#define PCS_LCTL_AN_RESTART __BIT(17) /* AN Timeout Enable */
#define PCS_LCTL_AN_TIMEOUT __BIT(18) /* AN Timeout Enable */
#define PCS_LCTL_FLV_LINK_UP __BIT(0) /* Forced Link Value */
#define PCS_LCTL_FSV_MASK __BITS(2, 1) /* Forced Speed Value */
#define PCS_LCTL_FSV_10 0 /* 10Mbps */
#define PCS_LCTL_FSV_100 __BIT(1) /* 100Mbps */
#define PCS_LCTL_FSV_1000 __BIT(2) /* 1Gpbs */
#define PCS_LCTL_FDV_FULL __BIT(3) /* Force Duplex Value */
#define PCS_LCTL_FSD __BIT(4) /* Force Speed and Duplex */
#define PCS_LCTL_FORCE_LINK __BIT(5) /* Force Link */
#define PCS_LCTL_LINK_LATCH_LOW __BIT(6) /* Link Latch Low */
#define PCS_LCTL_FORCE_FC __BIT(7) /* Force Flow Control */
#define PCS_LCTL_AN_ENABLE __BIT(16) /* AN enable */
#define PCS_LCTL_AN_RESTART __BIT(17) /* AN restart */
#define PCS_LCTL_AN_TIMEOUT __BIT(18) /* AN Timeout Enable */
#define PCS_LCTL_AN_SGMII_BYP __BIT(19) /* AN SGMII Bypass */
#define PCS_LCTL_AN_SGMII_TRIG __BIT(20) /* AN SGMII Trigger */
#define PCS_LCTL_FAST_LINKTIMER __BIT(24) /* Fast Link Timer */
#define PCS_LCTL_LINK_OK_FIX_EN __BIT(25) /* Link OK Fix Enable */
#define WMREG_PCS_LSTS 0x420c /* PCS Link Status */
#define PCS_LSTS_LINKOK __BIT(0)
@ -1172,6 +1190,7 @@ struct livengood_tcpip_ctxdesc {
#define WMREG_PCS_ANADV 0x4218 /* AN Advertsement */
#define WMREG_PCS_LPAB 0x421c /* Link Partnet Ability */
#define WMREG_PCS_NPTX 0x4220 /* Next Page Transmit */
#define WMREG_RXCSUM 0x5000 /* Receive Checksum register */
#define RXCSUM_PCSS 0x000000ff /* Packet Checksum Start */
@ -1424,7 +1443,7 @@ struct livengood_tcpip_ctxdesc {
#define NVM_CFG1_LSSID (1U << 1)
#define NVM_CFG1_PME_CLOCK (1U << 2)
#define NVM_CFG1_PM (1U << 3)
#define NVM_CFG1_ILOS (1U << 4)
#define NVM_CFG1_ILOS (1U << 4) /* Invert loss of signal */
#define NVM_CFG1_SWDPIO_SHIFT 5
#define NVM_CFG1_SWDPIO_MASK (0xf << NVM_CFG1_SWDPIO_SHIFT)
#define NVM_CFG1_IPS1 (1U << 8)
@ -1468,9 +1487,10 @@ struct livengood_tcpip_ctxdesc {
#define NVM_3GIO_3_ASPM_MASK (0x3 << 2) /* Active State PM Support */
#define NVM_CFG3_APME (1U << 10)
#define NVM_CFG3_PORTA_EXT_MDIO (1U << 2) /* External MDIO Interface */
#define NVM_CFG3_PORTA_COM_MDIO (1U << 3) /* MDIO Interface is shared */
#define NVM_CFG3_PORTA_EXT_MDIO __BIT(2) /* External MDIO Interface */
#define NVM_CFG3_PORTA_COM_MDIO __BIT(3) /* MDIO Interface is shared */
#define NVM_CFG3_APME __BIT(10) /* APM Enable */
#define NVM_CFG3_ILOS __BIT(13) /* Invert loss of signal */
#define NVM_OFF_MACADDR_82571(x) (3 * (x))