diff --git a/sys/dev/mii/e1000phyreg.h b/sys/dev/mii/e1000phyreg.h new file mode 100644 index 000000000000..9a2301328ffe --- /dev/null +++ b/sys/dev/mii/e1000phyreg.h @@ -0,0 +1,384 @@ +/* $NetBSD: e1000phyreg.h,v 1.1 2018/06/16 17:44:53 jdolecek Exp $ */ +/* $FreeBSD: head/sys/dev/mii/e1000phyreg.h 326022 2017-11-20 19:36:21Z pfg $ */ +/*- + * Principal Author: Parag Patel + * Copyright (c) 2001 + * 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 unmodified, 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * Additional Copyright (c) 2001 by Traakan Software under same licence. + * Secondary Author: Matthew Jacob + */ + +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Derived by information released by Intel under the following license: + * + * Copyright (c) 1999 - 2001, 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 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 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. + * + */ + +/* + * Marvell E1000 PHY registers + */ + +#define E1000_MAX_REG_ADDRESS 0x1F + +#define E1000_CR 0x00 /* control register */ +#define E1000_CR_SPEED_SELECT_MSB 0x0040 +#define E1000_CR_COLL_TEST_ENABLE 0x0080 +#define E1000_CR_FULL_DUPLEX 0x0100 +#define E1000_CR_RESTART_AUTO_NEG 0x0200 +#define E1000_CR_ISOLATE 0x0400 +#define E1000_CR_POWER_DOWN 0x0800 +#define E1000_CR_AUTO_NEG_ENABLE 0x1000 +#define E1000_CR_SPEED_SELECT_LSB 0x2000 +#define E1000_CR_LOOPBACK 0x4000 +#define E1000_CR_RESET 0x8000 + +#define E1000_CR_SPEED_1000 0x0040 +#define E1000_CR_SPEED_100 0x2000 +#define E1000_CR_SPEED_10 0x0000 + +#define E1000_SR 0x01 /* status register */ +#define E1000_SR_EXTENDED 0x0001 +#define E1000_SR_JABBER_DETECT 0x0002 +#define E1000_SR_LINK_STATUS 0x0004 +#define E1000_SR_AUTO_NEG 0x0008 +#define E1000_SR_REMOTE_FAULT 0x0010 +#define E1000_SR_AUTO_NEG_COMPLETE 0x0020 +#define E1000_SR_PREAMBLE_SUPPRESS 0x0040 +#define E1000_SR_EXTENDED_STATUS 0x0100 +#define E1000_SR_100T2 0x0200 +#define E1000_SR_100T2_FD 0x0400 +#define E1000_SR_10T 0x0800 +#define E1000_SR_10T_FD 0x1000 +#define E1000_SR_100TX 0x2000 +#define E1000_SR_100TX_FD 0x4000 +#define E1000_SR_100T4 0x8000 + +#define E1000_ID1 0x02 /* ID register 1 */ +#define E1000_ID2 0x03 /* ID register 2 */ +#define E1000_ID_88E1000 0x01410C50 +#define E1000_ID_88E1000S 0x01410C40 +#define E1000_ID_88E1011 0x01410C20 +#define E1000_ID_MASK 0xFFFFFFF0 + +#define E1000_AR 0x04 /* autonegotiation advertise reg */ +#define E1000_AR_SELECTOR_FIELD 0x0001 +#define E1000_AR_10T 0x0020 +#define E1000_AR_10T_FD 0x0040 +#define E1000_AR_100TX 0x0080 +#define E1000_AR_100TX_FD 0x0100 +#define E1000_AR_100T4 0x0200 +#define E1000_AR_PAUSE 0x0400 +#define E1000_AR_ASM_DIR 0x0800 +#define E1000_AR_REMOTE_FAULT 0x2000 +#define E1000_AR_NEXT_PAGE 0x8000 +#define E1000_AR_SPEED_MASK 0x01E0 + +/* Autonegotiation register bits for fiber cards (Alaska Only!) */ +#define E1000_FA_1000X_FD 0x0020 +#define E1000_FA_1000X 0x0040 +#define E1000_FA_SYM_PAUSE 0x0080 +#define E1000_FA_ASYM_PAUSE 0x0100 +#define E1000_FA_FAULT1 0x1000 +#define E1000_FA_FAULT2 0x2000 +#define E1000_FA_NEXT_PAGE 0x8000 + +#define E1000_LPAR 0x05 /* autoneg link partner abilities reg */ +#define E1000_LPAR_SELECTOR_FIELD 0x0001 +#define E1000_LPAR_10T 0x0020 +#define E1000_LPAR_10T_FD 0x0040 +#define E1000_LPAR_100TX 0x0080 +#define E1000_LPAR_100TX_FD 0x0100 +#define E1000_LPAR_100T4 0x0200 +#define E1000_LPAR_PAUSE 0x0400 +#define E1000_LPAR_ASM_DIR 0x0800 +#define E1000_LPAR_REMOTE_FAULT 0x2000 +#define E1000_LPAR_ACKNOWLEDGE 0x4000 +#define E1000_LPAR_NEXT_PAGE 0x8000 + +/* autoneg link partner ability register bits for fiber cards (Alaska Only!) */ +#define E1000_FPAR_1000X_FD 0x0020 +#define E1000_FPAR_1000X 0x0040 +#define E1000_FPAR_SYM_PAUSE 0x0080 +#define E1000_FPAR_ASYM_PAUSE 0x0100 +#define E1000_FPAR_FAULT1 0x1000 +#define E1000_FPAR_FAULT2 0x2000 +#define E1000_FPAR_ACK 0x4000 +#define E1000_FPAR_NEXT_PAGE 0x8000 + +#define E1000_ER 0x06 /* autoneg expansion reg */ +#define E1000_ER_LP_NWAY 0x0001 +#define E1000_ER_PAGE_RXD 0x0002 +#define E1000_ER_NEXT_PAGE 0x0004 +#define E1000_ER_LP_NEXT_PAGE 0x0008 +#define E1000_ER_PAR_DETECT_FAULT 0x0100 + +#define E1000_NPTX 0x07 /* autoneg next page TX */ +#define E1000_NPTX_MSG_CODE_FIELD 0x0001 +#define E1000_NPTX_TOGGLE 0x0800 +#define E1000_NPTX_ACKNOWLDGE2 0x1000 +#define E1000_NPTX_MSG_PAGE 0x2000 +#define E1000_NPTX_NEXT_PAGE 0x8000 + +#define E1000_RNPR 0x08 /* autoneg link-partner (?) next page */ +#define E1000_RNPR_MSG_CODE_FIELD 0x0001 +#define E1000_RNPR_TOGGLE 0x0800 +#define E1000_RNPR_ACKNOWLDGE2 0x1000 +#define E1000_RNPR_MSG_PAGE 0x2000 +#define E1000_RNPR_ACKNOWLDGE 0x4000 +#define E1000_RNPR_NEXT_PAGE 0x8000 + +#define E1000_1GCR 0x09 /* 1000T (1G) control reg */ +#define E1000_1GCR_ASYM_PAUSE 0x0080 +#define E1000_1GCR_1000T 0x0100 +#define E1000_1GCR_1000T_FD 0x0200 +#define E1000_1GCR_REPEATER_DTE 0x0400 +#define E1000_1GCR_MS_VALUE 0x0800 +#define E1000_1GCR_MS_ENABLE 0x1000 +#define E1000_1GCR_TEST_MODE_NORMAL 0x0000 +#define E1000_1GCR_TEST_MODE_1 0x2000 +#define E1000_1GCR_TEST_MODE_2 0x4000 +#define E1000_1GCR_TEST_MODE_3 0x6000 +#define E1000_1GCR_TEST_MODE_4 0x8000 +#define E1000_1GCR_SPEED_MASK 0x0300 + +#define E1000_1GSR 0x0A /* 1000T (1G) status reg */ +#define E1000_1GSR_IDLE_ERROR_CNT 0x0000 +#define E1000_1GSR_ASYM_PAUSE_DIR 0x0100 +#define E1000_1GSR_LP 0x0400 +#define E1000_1GSR_LP_FD 0x0800 +#define E1000_1GSR_REMOTE_RX_STATUS 0x1000 +#define E1000_1GSR_LOCAL_RX_STATUS 0x2000 +#define E1000_1GSR_MS_CONFIG_RES 0x4000 +#define E1000_1GSR_MS_CONFIG_FAULT 0x8000 + +#define E1000_ESR 0x0F /* IEEE extended status reg */ +#define E1000_ESR_1000T 0x1000 +#define E1000_ESR_1000T_FD 0x2000 +#define E1000_ESR_1000X 0x4000 +#define E1000_ESR_1000X_FD 0x8000 + +#define E1000_TX_POLARITY_MASK 0x0100 +#define E1000_TX_NORMAL_POLARITY 0 + +#define E1000_AUTO_POLARITY_DISABLE 0x0010 + +#define E1000_SCR 0x10 /* special control register */ +#define E1000_SCR_JABBER_DISABLE 0x0001 +#define E1000_SCR_POLARITY_REVERSAL 0x0002 +#define E1000_SCR_SQE_TEST 0x0004 +#define E1000_SCR_INT_FIFO_DISABLE 0x0008 +#define E1000_SCR_CLK125_DISABLE 0x0010 +#define E1000_SCR_MDI_MANUAL_MODE 0x0000 +#define E1000_SCR_MDIX_MANUAL_MODE 0x0020 +#define E1000_SCR_AUTO_X_1000T 0x0040 +#define E1000_SCR_AUTO_X_MODE 0x0060 +#define E1000_SCR_10BT_EXT_ENABLE 0x0080 +#define E1000_SCR_MII_5BIT_ENABLE 0x0100 +#define E1000_SCR_SCRAMBLER_DISABLE 0x0200 +#define E1000_SCR_FORCE_LINK_GOOD 0x0400 +#define E1000_SCR_ASSERT_CRS_ON_TX 0x0800 +#define E1000_SCR_RX_FIFO_DEPTH_6 0x0000 +#define E1000_SCR_RX_FIFO_DEPTH_8 0x1000 +#define E1000_SCR_RX_FIFO_DEPTH_10 0x2000 +#define E1000_SCR_RX_FIFO_DEPTH_12 0x3000 +#define E1000_SCR_TX_FIFO_DEPTH_6 0x0000 +#define E1000_SCR_TX_FIFO_DEPTH_8 0x4000 +#define E1000_SCR_TX_FIFO_DEPTH_10 0x8000 +#define E1000_SCR_TX_FIFO_DEPTH_12 0xC000 + +/* 88E3016 only */ +#define E1000_SCR_AUTO_MDIX 0x0030 +#define E1000_SCR_SIGDET_POLARITY 0x0040 +#define E1000_SCR_EXT_DISTANCE 0x0080 +#define E1000_SCR_FEFI_DISABLE 0x0100 +#define E1000_SCR_NLP_GEN_DISABLE 0x0800 +#define E1000_SCR_LPNP 0x1000 +#define E1000_SCR_NLP_CHK_DISABLE 0x2000 +#define E1000_SCR_EN_DETECT 0x4000 + +#define E1000_SCR_EN_DETECT_MASK 0x0300 + +#define E3000_SCR_SCRAMBLER_DISABLE 0x0200 +#define E3000_SCR_REG8_NEXT_PAGE 0x1000 +#define E3000_SCR_EN_DETECT_MASK 0x4000 + +/* 88E1112 page 1 fiber specific control */ +#define E1000_SCR_FIB_TX_DIS 0x0008 +#define E1000_SCR_FIB_SIGDET_POLARITY 0x0200 +#define E1000_SCR_FIB_FORCE_LINK 0x0400 + +/* 88E1112 page 2 */ +#define E1000_SCR_MODE_MASK 0x0380 +#define E1000_SCR_MODE_AUTO 0x0180 +#define E1000_SCR_MODE_COPPER 0x0280 +#define E1000_SCR_MODE_1000BX 0x0380 + +/* 88E1116 page 0 */ +#define E1000_SCR_POWER_DOWN 0x0004 +/* 88E1116, 88E1149 page 2 */ +#define E1000_SCR_RGMII_POWER_UP 0x0008 + +/* 88E1116, 88E1149 page 3 */ +#define E1000_SCR_LED_STAT0_MASK 0x000F +#define E1000_SCR_LED_STAT1_MASK 0x00F0 +#define E1000_SCR_LED_INIT_MASK 0x0F00 +#define E1000_SCR_LED_LOS_MASK 0xF000 +#define E1000_SCR_LED_STAT0(x) ((x) & E1000_SCR_LED_STAT0_MASK) +#define E1000_SCR_LED_STAT1(x) ((x) & E1000_SCR_LED_STAT1_MASK) +#define E1000_SCR_LED_INIT(x) ((x) & E1000_SCR_LED_INIT_MASK) +#define E1000_SCR_LED_LOS(x) ((x) & E1000_SCR_LED_LOS_MASK) + +#define E1000_SSR 0x11 /* special status register */ +#define E1000_SSR_JABBER 0x0001 +#define E1000_SSR_REV_POLARITY 0x0002 +#define E1000_SSR_MDIX 0x0020 +#define E1000_SSR_LINK 0x0400 +#define E1000_SSR_SPD_DPLX_RESOLVED 0x0800 +#define E1000_SSR_PAGE_RCVD 0x1000 +#define E1000_SSR_DUPLEX 0x2000 +#define E1000_SSR_SPEED 0xC000 +#define E1000_SSR_10MBS 0x0000 +#define E1000_SSR_100MBS 0x4000 +#define E1000_SSR_1000MBS 0x8000 + +#define E1000_IER 0x12 /* interrupt enable reg */ +#define E1000_IER_JABBER 0x0001 +#define E1000_IER_POLARITY_CHANGE 0x0002 +#define E1000_IER_MDIX_CHANGE 0x0040 +#define E1000_IER_FIFO_OVER_UNDERUN 0x0080 +#define E1000_IER_FALSE_CARRIER 0x0100 +#define E1000_IER_SYMBOL_ERROR 0x0200 +#define E1000_IER_LINK_STAT_CHANGE 0x0400 +#define E1000_IER_AUTO_NEG_COMPLETE 0x0800 +#define E1000_IER_PAGE_RECEIVED 0x1000 +#define E1000_IER_DUPLEX_CHANGED 0x2000 +#define E1000_IER_SPEED_CHANGED 0x4000 +#define E1000_IER_AUTO_NEG_ERR 0x8000 + +/* 88E1116, 88E1149 page 3, LED timer control. */ +#define E1000_PULSE_MASK 0x7000 +#define E1000_PULSE_NO_STR 0 /* no pulse stretching */ +#define E1000_PULSE_21MS 1 /* 21 ms to 42 ms */ +#define E1000_PULSE_42MS 2 /* 42 ms to 84 ms */ +#define E1000_PULSE_84MS 3 /* 84 ms to 170 ms */ +#define E1000_PULSE_170MS 4 /* 170 ms to 340 ms */ +#define E1000_PULSE_340MS 5 /* 340 ms to 670 ms */ +#define E1000_PULSE_670MS 6 /* 670 ms to 1300 ms */ +#define E1000_PULSE_1300MS 7 /* 1300 ms to 2700 ms */ +#define E1000_PULSE_DUR(x) ((x) & E1000_PULSE_MASK) + +#define E1000_BLINK_MASK 0x0700 +#define E1000_BLINK_42MS 0 /* 42 ms */ +#define E1000_BLINK_84MS 1 /* 84 ms */ +#define E1000_BLINK_170MS 2 /* 170 ms */ +#define E1000_BLINK_340MS 3 /* 340 ms */ +#define E1000_BLINK_670MS 4 /* 670 ms */ +#define E1000_BLINK_RATE(x) ((x) & E1000_BLINK_MASK) + +#define E1000_ISR 0x13 /* interrupt status reg */ +#define E1000_ISR_JABBER 0x0001 +#define E1000_ISR_POLARITY_CHANGE 0x0002 +#define E1000_ISR_MDIX_CHANGE 0x0040 +#define E1000_ISR_FIFO_OVER_UNDERUN 0x0080 +#define E1000_ISR_FALSE_CARRIER 0x0100 +#define E1000_ISR_SYMBOL_ERROR 0x0200 +#define E1000_ISR_LINK_STAT_CHANGE 0x0400 +#define E1000_ISR_AUTO_NEG_COMPLETE 0x0800 +#define E1000_ISR_PAGE_RECEIVED 0x1000 +#define E1000_ISR_DUPLEX_CHANGED 0x2000 +#define E1000_ISR_SPEED_CHANGED 0x4000 +#define E1000_ISR_AUTO_NEG_ERR 0x8000 + +#define E1000_ESCR 0x14 /* extended special control reg */ +#define E1000_ESCR_FIBER_LOOPBACK 0x4000 +#define E1000_ESCR_DOWN_NO_IDLE 0x8000 +#define E1000_ESCR_TX_CLK_2_5 0x0060 +#define E1000_ESCR_TX_CLK_25 0x0070 +#define E1000_ESCR_TX_CLK_0 0x0000 + +#define E1000_RECR 0x15 /* RX error counter reg */ + +#define E1000_EADR 0x16 /* extended address reg */ + +#define E1000_LCR 0x18 /* LED control reg */ +#define E1000_LCR_LED_TX 0x0001 +#define E1000_LCR_LED_RX 0x0002 +#define E1000_LCR_LED_DUPLEX 0x0004 +#define E1000_LCR_LINK 0x0008 +#define E1000_LCR_BLINK_42MS 0x0000 +#define E1000_LCR_BLINK_84MS 0x0100 +#define E1000_LCR_BLINK_170MS 0x0200 +#define E1000_LCR_BLINK_340MS 0x0300 +#define E1000_LCR_BLINK_670MS 0x0400 +#define E1000_LCR_PULSE_OFF 0x0000 +#define E1000_LCR_PULSE_21_42MS 0x1000 +#define E1000_LCR_PULSE_42_84MS 0x2000 +#define E1000_LCR_PULSE_84_170MS 0x3000 +#define E1000_LCR_PULSE_170_340MS 0x4000 +#define E1000_LCR_PULSE_340_670MS 0x5000 +#define E1000_LCR_PULSE_670_13S 0x6000 +#define E1000_LCR_PULSE_13_26S 0x7000 + +/* The following register is found only on the 88E1011 Alaska PHY */ +#define E1000_ESSR 0x1B /* Extended PHY specific sts */ +#define E1000_ESSR_DIS_FC 0x8000 +#define E1000_ESSR_FIBER_LINK 0x2000 +#define E1000_ESSR_HWCFG_MODE 0x000f +#define E1000_ESSR_GMII_COPPER 0x000f +#define E1000_ESSR_GMII_FIBER 0x0007 +#define E1000_ESSR_TBI_COPPER 0x000d +#define E1000_ESSR_TBI_FIBER 0x0005 +#define E1000_ESSR_RGMII_COPPER 0x000b diff --git a/sys/dev/mii/makphy.c b/sys/dev/mii/makphy.c index f9550e31b272..b3a2a252ac2d 100644 --- a/sys/dev/mii/makphy.c +++ b/sys/dev/mii/makphy.c @@ -1,4 +1,5 @@ -/* $NetBSD: makphy.c,v 1.43 2018/06/13 23:27:48 jdolecek Exp $ */ +/* $NetBSD: makphy.c,v 1.44 2018/06/16 17:44:53 jdolecek Exp $ */ +/* $OpenBSD: eephy.c,v 1.56 2015/03/14 03:38:48 jsg Exp $ */ /*- * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc. @@ -54,12 +55,48 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* + * Principal Author: Parag Patel + * Copyright (c) 2001 + * 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 unmodified, 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * Additonal Copyright (c) 2001 by Traakan Software under same licence. + * Secondary Author: Matthew Jacob + */ /* * Driver for the Marvell 88E1000 ``Alaska'' 10/100/1000 PHY. */ +/* + * Support added for the Marvell 88E1011 (Alaska) 1000/100/10baseTX and + * 1000baseSX PHY. + * Nathan Binkert + */ + #include -__KERNEL_RCSID(0, "$NetBSD: makphy.c,v 1.43 2018/06/13 23:27:48 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: makphy.c,v 1.44 2018/06/16 17:44:53 jdolecek Exp $"); #include #include @@ -75,7 +112,7 @@ __KERNEL_RCSID(0, "$NetBSD: makphy.c,v 1.43 2018/06/13 23:27:48 jdolecek Exp $") #include #include -#include +#include static int makphymatch(device_t, cfdata_t, void *); static void makphyattach(device_t, device_t, void *); @@ -87,11 +124,11 @@ static int makphy_service(struct mii_softc *, struct mii_data *, int); static void makphy_status(struct mii_softc *); static void makphy_reset(struct mii_softc *); -static const struct mii_phy_funcs makphy_funcs = { +static const struct mii_phy_funcs eephy_funcs = { makphy_service, makphy_status, makphy_reset, }; -static const struct mii_phydesc makphys[] = { +static const struct mii_phydesc eephys[] = { { MII_OUI_MARVELL, MII_MODEL_MARVELL_E1000_0, MII_STR_MARVELL_E1000_0 }, @@ -164,7 +201,7 @@ makphymatch(device_t parent, cfdata_t match, void *aux) { struct mii_attach_args *ma = aux; - if (mii_phy_match(ma, makphys) != NULL) + if (mii_phy_match(ma, eephys) != NULL) return (10); return (0); @@ -178,7 +215,7 @@ makphyattach(device_t parent, device_t self, void *aux) struct mii_data *mii = ma->mii_data; const struct mii_phydesc *mpd; - mpd = mii_phy_match(ma, makphys); + mpd = mii_phy_match(ma, eephys); aprint_naive(": Media interface\n"); aprint_normal(": %s, rev. %d\n", mpd->mpd_name, MII_REV(ma->mii_id2)); @@ -188,34 +225,45 @@ makphyattach(device_t parent, device_t self, void *aux) sc->mii_mpd_rev = MII_REV(ma->mii_id2); sc->mii_inst = mii->mii_instance; sc->mii_phy = ma->mii_phyno; - sc->mii_funcs = &makphy_funcs; + sc->mii_funcs = &eephy_funcs; sc->mii_pdata = mii; sc->mii_flags = ma->mii_flags; sc->mii_anegticks = MII_ANEGTICKS; - switch (sc->mii_mpd_model) { - case MII_MODEL_xxMARVELL_E1011: - case MII_MODEL_xxMARVELL_E1112: - if (PHY_READ(sc, MII_MAKPHY_ESSR) & ESSR_FIBER_LINK) - sc->mii_flags |= MIIF_HAVEFIBER; - break; - case MII_MODEL_xxMARVELL_E1149: - case MII_MODEL_xxMARVELL_E1149R: + /* XXX No loopback support yet, although the hardware can do it. */ + sc->mii_flags |= MIIF_NOLOOP; + + /* Make sure page 0 is selected. */ + PHY_WRITE(sc, E1000_EADR, 0); + + /* Switch to copper-only mode if necessary. */ + if (sc->mii_mpd_model == MII_MODEL_MARVELL_E1111 && + (sc->mii_flags & MIIF_HAVEFIBER) == 0) { /* - * Some 88E1149 PHY's page select is initialized to - * point to other bank instead of copper/fiber bank - * which in turn resulted in wrong registers were - * accessed during PHY operation. It is believed that - * page 0 should be used for copper PHY so reinitialize - * MII_MAKPHY_EADR to select default copper PHY. If parent - * device know the type of PHY(either copper or fiber), - * that information should be used to select default - * type of PHY. + * The onboard 88E1111 PHYs on the Sun X4100 M2 come + * up with fiber/copper auto-selection enabled, even + * though the machine only has copper ports. This + * makes the chip autoselect to 1000baseX, and makes + * it impossible to select any other media. So + * disable fiber/copper autoselection. */ - PHY_WRITE(sc, MII_MAKPHY_EADR, 0); - break; - default: - break; + int reg = PHY_READ(sc, E1000_ESSR); + if ((reg & E1000_ESSR_HWCFG_MODE) == E1000_ESSR_RGMII_COPPER) { + reg |= E1000_ESSR_DIS_FC; + PHY_WRITE(sc, E1000_ESSR, reg); + } + } + + /* Switch to fiber-only mode if necessary. */ + if (sc->mii_mpd_model == MII_MODEL_xxMARVELL_E1112 && + sc->mii_flags & MIIF_HAVEFIBER) { + int page = PHY_READ(sc, E1000_EADR); + PHY_WRITE(sc, E1000_EADR, 2); + int reg = PHY_READ(sc, E1000_SCR); + reg &= ~E1000_SCR_MODE_MASK; + reg |= E1000_SCR_MODE_1000BX; + PHY_WRITE(sc, E1000_SCR, reg); + PHY_WRITE(sc, E1000_EADR, page); } PHY_RESET(sc); @@ -236,20 +284,98 @@ makphyattach(device_t parent, device_t self, void *aux) static void makphy_reset(struct mii_softc *sc) { - uint16_t pscr; + int reg, i; - /* Assert CRS on transmit */ - pscr = PHY_READ(sc, MII_MAKPHY_PSCR); - PHY_WRITE(sc, MII_MAKPHY_PSCR, pscr | PSCR_CRS_ON_TX); + reg = PHY_READ(sc, E1000_CR); + reg |= E1000_CR_RESET; + PHY_WRITE(sc, E1000_CR, reg); + + for (i = 0; i < 500; i++) { + DELAY(1); + reg = PHY_READ(sc, E1000_CR); + if (!(reg & E1000_CR_RESET)) + break; + } - mii_phy_reset(sc); + /* + * Initialize PHY Specific Control Register. + */ + reg = PHY_READ(sc, E1000_SCR); + + /* Assert CRS on transmit. */ + reg |= E1000_SCR_ASSERT_CRS_ON_TX; + + /* Enable auto crossover. */ + switch (sc->mii_mpd_model) { + case MII_MODEL_xxMARVELL_E3016: + case MII_MODEL_xxMARVELL_E3082: + /* Bits are in a different position. */ + reg |= (E1000_SCR_AUTO_X_MODE >> 1); + break; + default: + /* Automatic crossover causes problems for 1000baseX. */ + if (sc->mii_flags & MIIF_IS_1000X) + reg &= ~E1000_SCR_AUTO_X_MODE; + else + reg |= E1000_SCR_AUTO_X_MODE; + } + + /* Disable energy detect; only available on some models. */ + switch(sc->mii_mpd_model) { + case MII_MODEL_xxMARVELL_E3016: + reg &= ~E3000_SCR_EN_DETECT_MASK; + break; + case MII_MODEL_MARVELL_E1011: + case MII_MODEL_MARVELL_E1111: + case MII_MODEL_xxMARVELL_E1112: + case MII_MODEL_xxMARVELL_PHYG65G: + reg &= ~E1000_SCR_EN_DETECT_MASK; + break; + } + + /* Enable scrambler if necessary. */ + if (sc->mii_mpd_model == MII_MODEL_xxMARVELL_E3016) + reg &= ~E3000_SCR_SCRAMBLER_DISABLE; + + /* + * Store next page in the Link Partner Next Page register for + * compatibility with 802.3ab. + */ + if (sc->mii_mpd_model == MII_MODEL_xxMARVELL_E3016) + reg |= E3000_SCR_REG8_NEXT_PAGE; + + PHY_WRITE(sc, E1000_SCR, reg); + + /* 25 MHz TX_CLK should always work. */ + reg = PHY_READ(sc, E1000_ESCR); + reg |= E1000_ESCR_TX_CLK_25; + PHY_WRITE(sc, E1000_ESCR, reg); + + /* Configure LEDs if they were left unconfigured. */ + if (sc->mii_mpd_model == MII_MODEL_xxMARVELL_E3016 && + PHY_READ(sc, 0x16) == 0) { + reg = (0x0b << 8) | (0x05 << 4) | 0x04; /* XXX */ + PHY_WRITE(sc, 0x16, reg); + } + + /* + * Do a software reset for these settings to take effect. + * Disable autonegotiation, such that all capabilities get + * advertised when it is switched back on. + */ + reg = PHY_READ(sc, E1000_CR); + reg &= ~E1000_CR_AUTO_NEG_ENABLE; + PHY_WRITE(sc, E1000_CR, reg | E1000_CR_RESET); } static int makphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; - int reg; + int bmcr; + + if (!device_is_active(sc->mii_dev)) + return (ENXIO); switch (cmd) { case MII_POLLSTAT: @@ -266,8 +392,8 @@ makphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) * isolate ourselves. */ if (IFM_INST(ife->ifm_media) != sc->mii_inst) { - reg = PHY_READ(sc, MII_BMCR); - PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO); + bmcr = PHY_READ(sc, E1000_CR); + PHY_WRITE(sc, E1000_CR, bmcr | E1000_CR_ISOLATE); return (0); } @@ -278,14 +404,14 @@ makphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) break; mii_phy_setmedia(sc); + + /* + * If autonegitation is not enabled, we need a + * software reset for the settings to take effect. + */ if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) { - /* - * when not in auto mode, we need to restart nego - * anyway, or a switch from a fixed mode to another - * fixed mode may not be seen by the switch. - */ - PHY_WRITE(sc, MII_BMCR, - PHY_READ(sc, MII_BMCR) | BMCR_STARTNEG); + bmcr = PHY_READ(sc, E1000_CR); + PHY_WRITE(sc, E1000_CR, bmcr | E1000_CR_RESET); } break; @@ -297,12 +423,12 @@ makphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) return (0); if (mii_phy_tick(sc) == EJUSTRETURN) - return (0); + return (0); break; case MII_DOWN: mii_phy_down(sc); - return (0); + return (0); } /* Update the media status. */ @@ -317,65 +443,45 @@ static void makphy_status(struct mii_softc *sc) { struct mii_data *mii = sc->mii_pdata; - struct ifmedia_entry *ife = mii->mii_media.ifm_cur; - int bmcr, pssr, gtsr; + int bmcr, gsr, ssr; mii->mii_media_status = IFM_AVALID; mii->mii_media_active = IFM_ETHER; - pssr = PHY_READ(sc, MII_MAKPHY_PSSR); + bmcr = PHY_READ(sc, E1000_CR); + ssr = PHY_READ(sc, E1000_SSR); - if (pssr & PSSR_LINK) + if (ssr & E1000_SSR_LINK) mii->mii_media_status |= IFM_ACTIVE; - bmcr = PHY_READ(sc, MII_BMCR); - if (bmcr & BMCR_ISO) { + if (bmcr & E1000_CR_LOOPBACK) + mii->mii_media_active |= IFM_LOOP; + + if (!(ssr & E1000_SSR_SPD_DPLX_RESOLVED)) { + /* Erg, still trying, I guess... */ mii->mii_media_active |= IFM_NONE; - mii->mii_media_status = 0; return; } - if (bmcr & BMCR_LOOP) - mii->mii_media_active |= IFM_LOOP; - - if (bmcr & BMCR_AUTOEN) { - /* - * The media status bits are only valid of autonegotiation - * has completed (or it's disabled). - */ - if ((pssr & PSSR_RESOLVED) == 0) { - /* Erg, still trying, I guess... */ - mii->mii_media_active |= IFM_NONE; - return; - } - - switch (PSSR_SPEED_get(pssr)) { - case SPEED_1000: + if (sc->mii_flags & MIIF_IS_1000X) { + mii->mii_media_active |= IFM_1000_SX; + } else { + if (ssr & E1000_SSR_1000MBS) mii->mii_media_active |= IFM_1000_T; - gtsr = PHY_READ(sc, MII_100T2SR); - if (gtsr & GTSR_MS_RES) - mii->mii_media_active |= IFM_ETH_MASTER; - break; - - case SPEED_100: + else if (ssr & E1000_SSR_100MBS) mii->mii_media_active |= IFM_100_TX; - break; - - case SPEED_10: - mii->mii_media_active |= IFM_10_T; - break; - - default: - mii->mii_media_active |= IFM_NONE; - mii->mii_media_status = 0; - return; - } - - if (pssr & PSSR_DUPLEX) - mii->mii_media_active |= - IFM_FDX | mii_phy_flowstatus(sc); else - mii->mii_media_active |= IFM_HDX; - } else - mii->mii_media_active = ife->ifm_media; + mii->mii_media_active |= IFM_10_T; + } + + if (ssr & E1000_SSR_DUPLEX) + mii->mii_media_active |= mii_phy_flowstatus(sc) | IFM_FDX; + else + mii->mii_media_active |= IFM_HDX; + + if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) { + gsr = PHY_READ(sc, E1000_1GSR) | PHY_READ(sc, E1000_1GSR); + if (gsr & E1000_1GSR_MS_CONFIG_RES) + mii->mii_media_active |= IFM_ETH_MASTER; + } } diff --git a/sys/dev/mii/makphyreg.h b/sys/dev/mii/makphyreg.h deleted file mode 100644 index 309c6ca9458c..000000000000 --- a/sys/dev/mii/makphyreg.h +++ /dev/null @@ -1,116 +0,0 @@ -/* $NetBSD: makphyreg.h,v 1.6 2014/05/13 02:53:54 christos Exp $ */ - -/*- - * Copyright (c) 2001 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jason R. Thorpe. - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ - -#ifndef _DEV_MII_MAKPHYREG_H_ -#define _DEV_MII_MAKPHYREG_H_ - -/* - * Marvell 88E1000 ``Alaska'' 10/100/1000 PHY registers. - */ - -#define MII_MAKPHY_PSCR 0x10 /* PHY specific control register */ -#define PSCR_DIS_JABBER (1U << 0) /* disable jabber */ -#define PSCR_POL_REV (1U << 1) /* polarity reversal */ -#define PSCR_SQE_TEST (1U << 2) /* SQE test */ -#define PSCR_MBO (1U << 3) /* must be one */ -#define PSCR_DIS_125CLK (1U << 4) /* 125CLK low */ -#define PSCR_MDI_XOVER_MODE(x) ((x) << 5) /* crossover mode */ -#define PSCR_LOW_10T_THRESH (1U << 7) /* lower 10BASE-T Rx threshold */ -#define PSCR_FORCE_LINK_GOOD (1U << 10) /* force link good */ -#define PSCR_CRS_ON_TX (1U << 11) /* assert CRS on transmit */ -#define PSCR_RX_FIFO(x) ((x) << 12) /* Rx FIFO depth */ -#define PSCR_TX_FIFO(x) ((x) << 14) /* Tx FIFO depth */ - -#define XOVER_MODE_MDI 0 -#define XOVER_MODE_MDIX 1 -#define XOVER_MODE_AUTO 2 - -#define MII_MAKPHY_PSSR 0x11 /* PHY specific status register */ -#define PSSR_JABBER (1U << 0) /* jabber indication */ -#define PSSR_POLARITY (1U << 1) /* polarity indiciation */ -#define PSSR_MDIX (1U << 6) /* 1 = MIDX, 0 = MDI */ -#define PSSR_CABLE_LENGTH_get(x) (((x) >> 7) & 0x3) -#define PSSR_LINK (1U << 10) /* link indication */ -#define PSSR_RESOLVED (1U << 11) /* speed and duplex resolved */ -#define PSSR_PAGE_RECEIVED (1U << 12) /* page received */ -#define PSSR_DUPLEX (1U << 13) /* 1 = FDX */ -#define PSSR_SPEED_get(x) (((x) >> 14) & 0x3) - -#define SPEED_10 0 -#define SPEED_100 1 -#define SPEED_1000 2 -#define SPEED_reserved 3 - -#define MII_MAKPHY_IE 0x12 /* Interrupt enable */ -#define IE_JABBER (1U << 0) /* jabber indication */ -#define IE_POL_CHANGED (1U << 1) /* polarity changed */ -#define IE_MDI_XOVER_CHANGED (1U << 6) /* MDI/MDIX changed */ -#define IE_FIFO_OVER_UNDER (1U << 7) /* FIFO over/underflow */ -#define IE_FALSE_CARRIER (1U << 8) /* false carrier detected */ -#define IE_SYMBOL_ERROR (1U << 9) /* symbol error occurred */ -#define IE_LINK_CHANGED (1U << 10) /* link status changed */ -#define IE_ANEG_COMPLETE (1U << 11) /* autonegotiation completed */ -#define IE_PAGE_RECEIVED (1U << 12) /* page received */ -#define IE_DUPLEX_CHANGED (1U << 13) /* duplex changed */ -#define IE_SPEED_CHANGED (1U << 14) /* speed changed */ -#define IE_ANEG_ERROR (1U << 15) /* autonegotiation error occurred */ - -#define MII_MAKPHY_IS 0x13 /* Interrupt status */ - /* See Interrupt enable bits */ - -#define MII_MAKPHY_EPSC 0x14 /* extended PHY specific control */ -#define EPSC_TX_CLK(x) ((x) << 4) /* transmit clock */ -#define EPSC_TBI_RCLK_DIS (1U << 12) /* TBI RCLK disable */ -#define EPSC_TBI_RX_CLK125_EN (1U << 13) /* TBI RX_CLK125 enable */ -#define EPSC_LINK_DOWN_NO_IDLES (1U << 15) /* 1 = lost lock detect */ - -#define MII_MAKPHY_REC 0x15 /* receive error counter */ - -#define MII_MAKPHY_EADR 0x16 /* extended address register */ - -#define MII_MAKPHY_LEDCTRL 0x18 /* LED control */ -#define LEDCTRL_LED_TX (1U << 0) /* 1 = activ/link, 0 = xmit */ -#define LEDCTRL_LED_RX (1U << 1) /* 1 = activ/link, 1 = recv */ -#define LEDCTRL_LED_DUPLEX (1U << 2) /* 1 = duplex, 0 = dup/coll */ -#define LEDCTRL_LED_LINK (1U << 3) /* 1 = spd/link, 0 = link */ -#define LEDCTRL_BLINK_RATE(x) ((x) << 8) -#define LEDCTRL_PULSE_STRCH(x) ((x) << 12) -#define LEDCTRL_DISABLE (1U << 15) /* disable LED */ - -#define MII_MAKPHY_ESSR 0x1b /* Extended PHY specific status */ -#define ESSR_FIBER_LINK 0x2000 -#define ESSR_GMII_COPPER 0x000f -#define ESSR_GMII_FIBER 0x0007 -#define ESSR_TBI_COPPER 0x000d -#define ESSR_TBI_FIBER 0x0005 - - -#endif /* _DEV_MII_MAKPHYREG_H_ */