Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Read SFF SFP ROM and configure driver from the v...
details: https://anonhg.NetBSD.org/src/rev/b4fff9476e3e
branches: trunk
changeset: 331968:b4fff9476e3e
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Wed Sep 03 14:30:04 2014 +0000
description:
Read SFF SFP ROM and configure driver from the value.
diffstat:
sys/dev/pci/if_wm.c | 99 +++++++++++++++++++++++++++++++++++++++++++++----
sys/dev/pci/if_wmreg.h | 16 +++++++-
2 files changed, 105 insertions(+), 10 deletions(-)
diffs (172 lines):
diff -r 5bb1df4257a7 -r b4fff9476e3e sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Wed Sep 03 10:00:08 2014 +0000
+++ b/sys/dev/pci/if_wm.c Wed Sep 03 14:30:04 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.294 2014/09/01 16:42:27 msaitoh Exp $ */
+/* $NetBSD: if_wm.c,v 1.295 2014/09/03 14:30:04 msaitoh 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.294 2014/09/01 16:42:27 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.295 2014/09/03 14:30:04 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -624,7 +624,8 @@
static void wm_tbi_set_linkled(struct wm_softc *);
static void wm_tbi_check_link(struct wm_softc *);
/* SFP related */
-static uint32_t wm_get_sfp_media_type(struct wm_softc *);
+static int wm_sfp_read_data_byte(struct wm_softc *, uint16_t, uint8_t *);
+static uint32_t wm_sfp_get_media_type(struct wm_softc *);
/*
* NVM related.
@@ -2075,7 +2076,7 @@
aprint_verbose_dev(sc->sc_dev, "SGMII(I2C)\n");
/*FALLTHROUGH*/
case CTRL_EXT_LINK_MODE_PCIE_SERDES:
- sc->sc_mediatype = wm_get_sfp_media_type(sc);
+ sc->sc_mediatype = wm_sfp_get_media_type(sc);
if (sc->sc_mediatype == WMP_F_UNKNOWN) {
if (link_mode
== CTRL_EXT_LINK_MODE_SGMII) {
@@ -2110,6 +2111,7 @@
break;
case CTRL_EXT_LINK_MODE_GMII:
default:
+ aprint_verbose_dev(sc->sc_dev, "Copper\n");
sc->sc_mediatype = WMP_F_COPPER;
break;
}
@@ -7578,12 +7580,91 @@
}
/* SFP related */
+
+static int
+wm_sfp_read_data_byte(struct wm_softc *sc, uint16_t offset, uint8_t *data)
+{
+ uint32_t i2ccmd;
+ int i;
+
+ i2ccmd = (offset << I2CCMD_REG_ADDR_SHIFT) | I2CCMD_OPCODE_READ;
+ CSR_WRITE(sc, WMREG_I2CCMD, i2ccmd);
+
+ /* Poll the ready bit */
+ for (i = 0; i < I2CCMD_PHY_TIMEOUT; i++) {
+ delay(50);
+ i2ccmd = CSR_READ(sc, WMREG_I2CCMD);
+ if (i2ccmd & I2CCMD_READY)
+ break;
+ }
+ if ((i2ccmd & I2CCMD_READY) == 0)
+ return -1;
+ if ((i2ccmd & I2CCMD_ERROR) != 0)
+ return -1;
+
+ *data = i2ccmd & 0x00ff;
+
+ return 0;
+}
+
static uint32_t
-wm_get_sfp_media_type(struct wm_softc *sc)
-{
-
- /* XXX */
- return WMP_F_SERDES;
+wm_sfp_get_media_type(struct wm_softc *sc)
+{
+ uint32_t ctrl_ext;
+ uint8_t val = 0;
+ int timeout = 3;
+ uint32_t mediatype = WMP_F_UNKNOWN;
+ int rv = -1;
+
+ ctrl_ext = CSR_READ(sc, WMREG_CTRL_EXT);
+ ctrl_ext &= ~CTRL_EXT_SWDPIN(3);
+ CSR_WRITE(sc, WMREG_CTRL_EXT, ctrl_ext | CTRL_EXT_I2C_ENA);
+ CSR_WRITE_FLUSH(sc);
+
+ /* Read SFP module data */
+ while (timeout) {
+ rv = wm_sfp_read_data_byte(sc, SFF_SFP_ID_OFF, &val);
+ if (rv == 0)
+ break;
+ delay(100*1000); /* XXX too big */
+ timeout--;
+ }
+ if (rv != 0)
+ goto out;
+ switch (val) {
+ case SFF_SFP_ID_SFF:
+ aprint_normal_dev(sc->sc_dev,
+ "Module/Connector soldered to board\n");
+ break;
+ case SFF_SFP_ID_SFP:
+ aprint_normal_dev(sc->sc_dev, "SFP\n");
+ break;
+ case SFF_SFP_ID_UNKNOWN:
+ goto out;
+ default:
+ break;
+ }
+
+ rv = wm_sfp_read_data_byte(sc, SFF_SFP_ETH_FLAGS_OFF, &val);
+ if (rv != 0) {
+ goto out;
+ }
+
+ if ((val & (SFF_SFP_ETH_FLAGS_1000SX | SFF_SFP_ETH_FLAGS_1000LX)) != 0)
+ mediatype = WMP_F_SERDES;
+ else if ((val & SFF_SFP_ETH_FLAGS_1000T) != 0){
+ sc->sc_flags |= WM_F_SGMII;
+ mediatype = WMP_F_COPPER;
+ } else if ((val & SFF_SFP_ETH_FLAGS_100FX) != 0){
+ sc->sc_flags |= WM_F_SGMII;
+ mediatype = WMP_F_SERDES;
+ }
+
+out:
+ /* Restore I2C interface setting */
+ CSR_WRITE(sc, WMREG_CTRL_EXT, ctrl_ext);
+
+ return mediatype;
}
/*
* NVM related.
diff -r 5bb1df4257a7 -r b4fff9476e3e sys/dev/pci/if_wmreg.h
--- a/sys/dev/pci/if_wmreg.h Wed Sep 03 10:00:08 2014 +0000
+++ b/sys/dev/pci/if_wmreg.h Wed Sep 03 14:30:04 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wmreg.h,v 1.62 2014/09/01 16:42:27 msaitoh Exp $ */
+/* $NetBSD: if_wmreg.h,v 1.63 2014/09/03 14:30:04 msaitoh Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -1035,6 +1035,20 @@
/* for PCI express Capability registers */
#define WM_PCIE_DCSR2_16MS 0x00000005
+/* SFF SFP ROM data */
+#define SFF_SFP_ID_OFF 0x00
+#define SFF_SFP_ID_UNKNOWN 0x00 /* Unknown */
+#define SFF_SFP_ID_SFF 0x02 /* Module soldered to motherboard */
+#define SFF_SFP_ID_SFP 0x03 /* SFP transceiver */
+
+#define SFF_SFP_ETH_FLAGS_OFF 0x06
+#define SFF_SFP_ETH_FLAGS_1000SX 0x01
+#define SFF_SFP_ETH_FLAGS_1000LX 0x02
+#define SFF_SFP_ETH_FLAGS_1000CX 0x04
+#define SFF_SFP_ETH_FLAGS_1000T 0x08
+#define SFF_SFP_ETH_FLAGS_100FX 0x10
+
+
/* advanced TX descriptor for 82575 and newer */
typedef union nq_txdesc {
struct {
Home |
Main Index |
Thread Index |
Old Index