summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2019-04-10 09:55:03 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2019-04-10 09:55:03 +0000
commitede166c3581794ee7e7d568b025363fd37c6046d (patch)
tree77f14f05619b39a01c603d681ec09a92ceb2336f /sys/dev
parent579c07513bb9e4718897ec05bd7bc43dff9b9d31 (diff)
add support for SIOCGIFSFFPAGE so userland can read sfp module info
access to the ioctl is serialised by a per ifp rwlock so userland reads of different pages in the same device address do not confuse each other. this was pretty straightforward because a lot of the plumbing for accessing the i2c bus was already in place.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/if_ix.c58
-rw-r--r--sys/dev/pci/if_ix.h3
-rw-r--r--sys/dev/pci/ixgbe_type.h6
3 files changed, 64 insertions, 3 deletions
diff --git a/sys/dev/pci/if_ix.c b/sys/dev/pci/if_ix.c
index c8cef1c6390..e29fc0aa07f 100644
--- a/sys/dev/pci/if_ix.c
+++ b/sys/dev/pci/if_ix.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ix.c,v 1.156 2019/03/01 06:15:59 dlg Exp $ */
+/* $OpenBSD: if_ix.c,v 1.157 2019/04/10 09:55:02 dlg Exp $ */
/******************************************************************************
@@ -96,6 +96,7 @@ int ixgbe_detach(struct device *, int);
void ixgbe_start(struct ifqueue *);
int ixgbe_ioctl(struct ifnet *, u_long, caddr_t);
int ixgbe_rxrinfo(struct ix_softc *, struct if_rxrinfo *);
+int ixgbe_get_sffpage(struct ix_softc *, struct if_sffpage *);
void ixgbe_watchdog(struct ifnet *);
void ixgbe_init(void *);
void ixgbe_stop(void *);
@@ -225,6 +226,8 @@ ixgbe_attach(struct device *parent, struct device *self, void *aux)
sc->osdep.os_sc = sc;
sc->osdep.os_pa = *pa;
+ rw_init(&sc->sfflock, "ixsff");
+
/* Set up the timer callout */
timeout_set(&sc->timer, ixgbe_local_timer, sc);
timeout_set(&sc->rx_refill, ixgbe_rxrefill, sc);
@@ -498,6 +501,15 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data)
error = ixgbe_rxrinfo(sc, (struct if_rxrinfo *)ifr->ifr_data);
break;
+ case SIOCGIFSFFPAGE:
+ error = rw_enter(&sc->sfflock, RW_WRITE|RW_INTR);
+ if (error != 0)
+ break;
+
+ error = ixgbe_get_sffpage(sc, (struct if_sffpage *)data);
+ rw_exit(&sc->sfflock);
+ break;
+
default:
error = ether_ioctl(ifp, &sc->arpcom, command, data);
}
@@ -516,6 +528,50 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data)
}
int
+ixgbe_get_sffpage(struct ix_softc *sc, struct if_sffpage *sff)
+{
+ struct ixgbe_hw *hw = &sc->hw;
+ uint32_t swfw_mask = hw->phy.phy_semaphore_mask;
+ uint8_t page;
+ size_t i;
+ int error = EIO;
+
+ if (hw->phy.type == ixgbe_phy_fw)
+ return (ENODEV);
+
+ if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
+ return (EBUSY); /* XXX */
+
+ if (sff->sff_addr == IFSFF_ADDR_EEPROM) {
+ if (hw->phy.ops.read_i2c_byte_unlocked(hw, 127,
+ IFSFF_ADDR_EEPROM, &page))
+ goto error;
+ if (page != sff->sff_page &&
+ hw->phy.ops.write_i2c_byte_unlocked(hw, 127,
+ IFSFF_ADDR_EEPROM, sff->sff_page))
+ goto error;
+ }
+
+ for (i = 0; i < sizeof(sff->sff_data); i++) {
+ if (hw->phy.ops.read_i2c_byte_unlocked(hw, i,
+ sff->sff_addr, &sff->sff_data[i]))
+ goto error;
+ }
+
+ if (sff->sff_addr == IFSFF_ADDR_EEPROM) {
+ if (page != sff->sff_page &&
+ hw->phy.ops.write_i2c_byte_unlocked(hw, 127,
+ IFSFF_ADDR_EEPROM, page))
+ goto error;
+ }
+
+ error = 0;
+error:
+ hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+ return (error);
+}
+
+int
ixgbe_rxrinfo(struct ix_softc *sc, struct if_rxrinfo *ifri)
{
struct if_rxring_info *ifr, ifr1;
diff --git a/sys/dev/pci/if_ix.h b/sys/dev/pci/if_ix.h
index fff1967133b..753a2bfb78a 100644
--- a/sys/dev/pci/if_ix.h
+++ b/sys/dev/pci/if_ix.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ix.h,v 1.33 2019/02/21 03:16:47 dlg Exp $ */
+/* $OpenBSD: if_ix.h,v 1.34 2019/04/10 09:55:02 dlg Exp $ */
/******************************************************************************
@@ -251,6 +251,7 @@ struct ix_softc {
uint32_t link_speed;
bool link_up;
uint32_t linkvec;
+ struct rwlock sfflock;
/* Mbuf cluster size */
uint32_t rx_mbuf_sz;
diff --git a/sys/dev/pci/ixgbe_type.h b/sys/dev/pci/ixgbe_type.h
index aeea522f457..ce851315392 100644
--- a/sys/dev/pci/ixgbe_type.h
+++ b/sys/dev/pci/ixgbe_type.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ixgbe_type.h,v 1.31 2016/11/18 14:16:10 mikeb Exp $ */
+/* $OpenBSD: ixgbe_type.h,v 1.32 2019/04/10 09:55:02 dlg Exp $ */
/******************************************************************************
@@ -3142,7 +3142,9 @@ enum ixgbe_phy_type {
ixgbe_phy_aq,
ixgbe_phy_x550em_kr,
ixgbe_phy_x550em_kx4,
+ ixgbe_phy_x550em_xfi,
ixgbe_phy_x550em_ext_t,
+ ixgbe_phy_ext_1g_t,
ixgbe_phy_cu_unknown,
ixgbe_phy_qt,
ixgbe_phy_xaui,
@@ -3160,6 +3162,8 @@ enum ixgbe_phy_type {
ixgbe_phy_qsfp_intel,
ixgbe_phy_qsfp_unknown,
ixgbe_phy_sfp_unsupported, /*Enforce bit set with unsupported module*/
+ ixgbe_phy_sgmii,
+ ixgbe_phy_fw,
ixgbe_phy_generic
};