summaryrefslogtreecommitdiffstats
path: root/sys/dev/pci/if_iwx.c
diff options
context:
space:
mode:
authorstsp <stsp@openbsd.org>2020-06-22 07:39:41 +0000
committerstsp <stsp@openbsd.org>2020-06-22 07:39:41 +0000
commit77bfb901bd2cbaceaa38a1d58d4a669580e3b3ce (patch)
treeff6cde013cd37a36e0624586f8594d5ccd727809 /sys/dev/pci/if_iwx.c
parentDo not copy an SSID into the iwx(4) probe request template. (diff)
downloadwireguard-openbsd-77bfb901bd2cbaceaa38a1d58d4a669580e3b3ce.tar.xz
wireguard-openbsd-77bfb901bd2cbaceaa38a1d58d4a669580e3b3ce.zip
Enable critical temperature detection in iwx(4) firmware.
The driver will turn the device off and print a message to dmesg if the firmware signals critical temperature. It looks like the firmware will also make use of a Tx-backoff mechanism to regulate device temperature.
Diffstat (limited to 'sys/dev/pci/if_iwx.c')
-rw-r--r--sys/dev/pci/if_iwx.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/sys/dev/pci/if_iwx.c b/sys/dev/pci/if_iwx.c
index a44c0a51ed5..2ef3439ebe5 100644
--- a/sys/dev/pci/if_iwx.c
+++ b/sys/dev/pci/if_iwx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwx.c,v 1.32 2020/06/22 07:31:32 stsp Exp $ */
+/* $OpenBSD: if_iwx.c,v 1.33 2020/06/22 07:39:41 stsp Exp $ */
/*
* Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -437,6 +437,7 @@ int iwx_sf_config(struct iwx_softc *, int);
int iwx_send_bt_init_conf(struct iwx_softc *);
int iwx_send_soc_conf(struct iwx_softc *);
int iwx_send_update_mcc_cmd(struct iwx_softc *, const char *);
+int iwx_send_temp_report_ths_cmd(struct iwx_softc *);
int iwx_init_hw(struct iwx_softc *);
int iwx_init(struct ifnet *);
void iwx_start(struct ifnet *);
@@ -6822,6 +6823,29 @@ out:
}
int
+iwx_send_temp_report_ths_cmd(struct iwx_softc *sc)
+{
+ struct iwx_temp_report_ths_cmd cmd;
+ int err;
+
+ /*
+ * In order to give responsibility for critical-temperature-kill
+ * and TX backoff to FW we need to send an empty temperature
+ * reporting command at init time.
+ */
+ memset(&cmd, 0, sizeof(cmd));
+
+ err = iwx_send_cmd_pdu(sc,
+ IWX_WIDE_ID(IWX_PHY_OPS_GROUP, IWX_TEMP_REPORTING_THRESHOLDS_CMD),
+ 0, sizeof(cmd), &cmd);
+ if (err)
+ printf("%s: TEMP_REPORT_THS_CMD command failed (error %d)\n",
+ DEVNAME(sc), err);
+
+ return err;
+}
+
+int
iwx_init_hw(struct iwx_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
@@ -6905,6 +6929,12 @@ iwx_init_hw(struct iwx_softc *sc)
DEVNAME(sc), err);
}
+ if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_CT_KILL_BY_FW)) {
+ err = iwx_send_temp_report_ths_cmd(sc);
+ if (err)
+ goto err;
+ }
+
err = iwx_power_update_device(sc);
if (err) {
printf("%s: could not send power command (error %d)\n",
@@ -7623,8 +7653,22 @@ iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *data, struct mbuf_list *ml)
case IWX_DTS_MEASUREMENT_NOTIFICATION:
case IWX_WIDE_ID(IWX_PHY_OPS_GROUP,
IWX_DTS_MEASUREMENT_NOTIF_WIDE):
+ case IWX_WIDE_ID(IWX_PHY_OPS_GROUP,
+ IWX_TEMP_REPORTING_THRESHOLDS_CMD):
break;
+ case IWX_WIDE_ID(IWX_PHY_OPS_GROUP,
+ IWX_CT_KILL_NOTIFICATION): {
+ struct iwx_ct_kill_notif *notif;
+ SYNC_RESP_STRUCT(notif, pkt);
+ printf("%s: device at critical temperature (%u degC), "
+ "stopping device\n",
+ DEVNAME(sc), le16toh(notif->temperature));
+ sc->sc_flags |= IWX_FLAG_HW_ERR;
+ task_add(systq, &sc->init_task);
+ break;
+ }
+
case IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP,
IWX_NVM_GET_INFO):
case IWX_ADD_STA_KEY: