Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci support internal PHY temperature sensor
details: https://anonhg.NetBSD.org/src/rev/36cc60ccab3f
branches: trunk
changeset: 467189:36cc60ccab3f
user: ryo <ryo%NetBSD.org@localhost>
date: Fri Jan 17 05:22:42 2020 +0000
description:
support internal PHY temperature sensor
diffstat:
sys/dev/pci/files.pci | 4 +-
sys/dev/pci/if_aq.c | 161 +++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 148 insertions(+), 17 deletions(-)
diffs (truncated from 339 to 300 lines):
diff -r f26fb46a811d -r 36cc60ccab3f sys/dev/pci/files.pci
--- a/sys/dev/pci/files.pci Fri Jan 17 05:20:21 2020 +0000
+++ b/sys/dev/pci/files.pci Fri Jan 17 05:22:42 2020 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.pci,v 1.420 2020/01/16 07:11:50 yamaguchi Exp $
+# $NetBSD: files.pci,v 1.421 2020/01/17 05:22:42 ryo Exp $
#
# Config file and device description for machine-independent PCI code.
# Included by ports that need it. Requires that the SCSI files be
@@ -168,7 +168,7 @@
file dev/pci/mpii.c mpii
# Aquantia/Atlantic 10-Gigabit Ethernet
-device aq: ether, ifnet, arp
+device aq: ether, ifnet, arp, sysmon_envsys
attach aq at pci
file dev/pci/if_aq.c aq
defflag opt_if_aq.h AQ_EVENT_COUNTERS
diff -r f26fb46a811d -r 36cc60ccab3f sys/dev/pci/if_aq.c
--- a/sys/dev/pci/if_aq.c Fri Jan 17 05:20:21 2020 +0000
+++ b/sys/dev/pci/if_aq.c Fri Jan 17 05:22:42 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_aq.c,v 1.3 2020/01/17 05:16:33 ryo Exp $ */
+/* $NetBSD: if_aq.c,v 1.4 2020/01/17 05:22:42 ryo Exp $ */
/**
* aQuantia Corporation Network Driver
@@ -62,10 +62,11 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_aq.c,v 1.3 2020/01/17 05:16:33 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_aq.c,v 1.4 2020/01/17 05:22:42 ryo Exp $");
#ifdef _KERNEL_OPT
#include "opt_if_aq.h"
+#include "sysmon_envsys.h"
#endif
#include <sys/param.h>
@@ -87,6 +88,7 @@
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcidevs.h>
+#include <dev/sysmon/sysmonvar.h>
/* driver configuration */
#define CONFIG_INTR_MODERATION_ENABLE true /* delayed interrupt */
@@ -710,11 +712,14 @@
typedef struct fw2x_mailbox { /* struct fwHostInterface */
aq_mailbox_header_t header;
fw2x_msm_statistics_t msm; /* msmStatistics_t msm; */
- uint16_t phy_h_bit;
- uint16_t phy_fault_code;
- int16_t phy_temperature;
- uint8_t cable_len;
- uint8_t reserved1;
+
+ uint32_t phy_info1;
+#define PHYINFO1_FAULT_CODE __BITS(31,16)
+#define PHYINFO1_PHY_H_BIT __BITS(0,15)
+ uint32_t phy_info2;
+#define PHYINFO2_TEMPERATURE __BITS(15,0)
+#define PHYINFO2_CABLE_LEN __BITS(23,16)
+
fw2x_phy_cable_diag_data_t diag_data;
uint32_t reserved[8];
@@ -907,6 +912,9 @@
int (*get_mode)(struct aq_softc *, aq_hw_fw_mpi_state_t *,
aq_link_speed_t *, aq_link_fc_t *, aq_link_eee_t *);
int (*get_stats)(struct aq_softc *, aq_hw_stats_s_t *);
+#if NSYSMON_ENVSYS > 0
+ int (*get_temperature)(struct aq_softc *, uint32_t *);
+#endif
};
#ifdef AQ_EVENT_COUNTERS
@@ -933,6 +941,11 @@
#define AQ_LOCK(sc) mutex_enter(&(sc)->sc_mutex);
#define AQ_UNLOCK(sc) mutex_exit(&(sc)->sc_mutex);
+/* lock for FW2X_MPI_{CONTROL,STATE]_REG read-modify-write */
+#define AQ_MPI_LOCK(sc) mutex_enter(&(sc)->sc_mpi_mutex);
+#define AQ_MPI_UNLOCK(sc) mutex_exit(&(sc)->sc_mpi_mutex);
+
+
struct aq_softc {
device_t sc_dev;
@@ -951,6 +964,11 @@
bool sc_poll_linkstat;
bool sc_detect_linkstat;
+#if NSYSMON_ENVSYS > 0
+ struct sysmon_envsys *sc_sme;
+ envsys_data_t sc_sensor_temp;
+#endif
+
callout_t sc_tick_ch;
int sc_nintrs;
@@ -965,6 +983,7 @@
uint16_t sc_revision;
kmutex_t sc_mutex;
+ kmutex_t sc_mpi_mutex;
struct aq_firmware_ops *sc_fw_ops;
uint64_t sc_fw_caps;
@@ -1063,6 +1082,9 @@
static void aq_initmedia(struct aq_softc *);
static void aq_enable_intr(struct aq_softc *, bool, bool);
+#if NSYSMON_ENVSYS > 0
+static void aq_temp_refresh(struct sysmon_envsys *, envsys_data_t *);
+#endif
static void aq_tick(void *);
static int aq_legacy_intr(void *);
static int aq_link_intr(void *);
@@ -1099,19 +1121,28 @@
static int fw2x_get_mode(struct aq_softc *, aq_hw_fw_mpi_state_t *,
aq_link_speed_t *, aq_link_fc_t *, aq_link_eee_t *);
static int fw2x_get_stats(struct aq_softc *, aq_hw_stats_s_t *);
+#if NSYSMON_ENVSYS > 0
+static int fw2x_get_temperature(struct aq_softc *, uint32_t *);
+#endif
static struct aq_firmware_ops aq_fw1x_ops = {
.reset = fw1x_reset,
.set_mode = fw1x_set_mode,
.get_mode = fw1x_get_mode,
- .get_stats = fw1x_get_stats
+ .get_stats = fw1x_get_stats,
+#if NSYSMON_ENVSYS > 0
+ .get_temperature = NULL
+#endif
};
static struct aq_firmware_ops aq_fw2x_ops = {
.reset = fw2x_reset,
.set_mode = fw2x_set_mode,
.get_mode = fw2x_get_mode,
- .get_stats = fw2x_get_stats
+ .get_stats = fw2x_get_stats,
+#if NSYSMON_ENVSYS > 0
+ .get_temperature = fw2x_get_temperature
+#endif
};
CFATTACH_DECL3_NEW(aq, sizeof(struct aq_softc),
@@ -1216,6 +1247,7 @@
sc->sc_dev = self;
mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_NET);
+ mutex_init(&sc->sc_mpi_mutex, MUTEX_DEFAULT, IPL_NET);
sc->sc_pc = pc = pa->pa_pc;
sc->sc_pcitag = tag = pa->pa_tag;
@@ -1433,6 +1465,31 @@
/* update media */
aq_ifmedia_change(ifp);
+#if NSYSMON_ENVSYS > 0
+ /* temperature monitoring */
+ if (sc->sc_fw_ops != NULL && sc->sc_fw_ops->get_temperature != NULL &&
+ (sc->sc_fw_caps & FW2X_CTRL_TEMPERATURE) != 0) {
+
+ sc->sc_sme = sysmon_envsys_create();
+ sc->sc_sme->sme_name = device_xname(self);
+ sc->sc_sme->sme_cookie = sc;
+ sc->sc_sme->sme_flags = 0;
+ sc->sc_sme->sme_refresh = aq_temp_refresh;
+ sc->sc_sensor_temp.units = ENVSYS_STEMP;
+ sc->sc_sensor_temp.state = ENVSYS_SINVALID;
+ snprintf(sc->sc_sensor_temp.desc, ENVSYS_DESCLEN, "PHY");
+
+ sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_sensor_temp);
+ sysmon_envsys_register(sc->sc_sme);
+
+ /*
+ * for unknown reasons, the first call of fw2x_get_temperature()
+ * will always fail (firmware matter?), so run once now.
+ */
+ aq_temp_refresh(sc->sc_sme, &sc->sc_sensor_temp);
+ }
+#endif
+
#ifdef AQ_EVENT_COUNTERS
/* get starting statistics values */
if (sc->sc_fw_ops != NULL && sc->sc_fw_ops->get_stats != NULL &&
@@ -1507,6 +1564,14 @@
callout_stop(&sc->sc_tick_ch);
+#if NSYSMON_ENVSYS > 0
+ if (sc->sc_sme != NULL) {
+ /* all sensors associated with this will also be detached */
+ sysmon_envsys_unregister(sc->sc_sme);
+ sc->sc_sme = NULL;
+ }
+#endif
+
#ifdef AQ_EVENT_COUNTERS
AQ_EVCNT_DETACH(sc, uprc);
AQ_EVCNT_DETACH(sc, mprc);
@@ -1528,6 +1593,7 @@
AQ_EVCNT_DETACH(sc, cprc);
#endif
+ mutex_destroy(&sc->sc_mpi_mutex);
mutex_destroy(&sc->sc_mutex);
return 0;
@@ -2216,7 +2282,12 @@
fw2x_set_mode(struct aq_softc *sc, aq_hw_fw_mpi_state_t mode,
aq_link_speed_t speed, aq_link_fc_t fc, aq_link_eee_t eee)
{
- uint64_t mpi_ctrl = AQ_READ64_REG(sc, FW2X_MPI_CONTROL_REG);
+ uint64_t mpi_ctrl;
+ int error = 0;
+
+ AQ_MPI_LOCK(sc);
+
+ mpi_ctrl = AQ_READ64_REG(sc, FW2X_MPI_CONTROL_REG);
switch (mode) {
case MPI_INIT:
@@ -2250,11 +2321,14 @@
break;
default:
device_printf(sc->sc_dev, "fw2x> unknown MPI state %d\n", mode);
- return EINVAL;
+ error = EINVAL;
+ goto failure;
}
-
AQ_WRITE64_REG(sc, FW2X_MPI_CONTROL_REG, mpi_ctrl);
- return 0;
+
+ failure:
+ AQ_MPI_UNLOCK(sc);
+ return error;
}
static int
@@ -2344,12 +2418,13 @@
{
int error;
+ AQ_MPI_LOCK(sc);
/* Say to F/W to update the statistics */
error = toggle_mpi_ctrl_and_wait(sc, FW2X_CTRL_STATISTICS, 1, 25);
if (error != 0) {
device_printf(sc->sc_dev,
"fw2x> statistics update error %d\n", error);
- return error;
+ goto failure;
}
CTASSERT(sizeof(fw2x_msm_statistics_t) <= sizeof(struct aq_hw_stats_s));
@@ -2359,13 +2434,49 @@
if (error != 0) {
device_printf(sc->sc_dev,
"fw2x> download statistics data FAILED, error %d", error);
- return error;
+ goto failure;
}
stats->dpc = AQ_READ_REG(sc, RX_DMA_DROP_PKT_CNT_REG);
stats->cprc = AQ_READ_REG(sc, RX_DMA_COALESCED_PKT_CNT_REG);
+ failure:
+ AQ_MPI_UNLOCK(sc);
+ return error;
+}
+
+#if NSYSMON_ENVSYS > 0
+static int
+fw2x_get_temperature(struct aq_softc *sc, uint32_t *temp)
+{
+ int error;
+ uint32_t value, celsius;
+
+ AQ_MPI_LOCK(sc);
+
+ /* Say to F/W to update the temperature */
+ error = toggle_mpi_ctrl_and_wait(sc, FW2X_CTRL_TEMPERATURE, 1, 25);
+ if (error != 0)
+ goto failure;
+
+ error = aq_fw_downld_dwords(sc,
+ sc->sc_mbox_addr + offsetof(fw2x_mailbox_t, phy_info2),
+ &value, sizeof(value) / sizeof(uint32_t));
+ if (error != 0)
+ goto failure;
+
+ /* 1/256 decrees C to microkelvin */
+ celsius = __SHIFTOUT(value, PHYINFO2_TEMPERATURE);
+ if (celsius == 0) {
+ error = EIO;
Home |
Main Index |
Thread Index |
Old Index