diff options
author | 2020-06-22 07:39:41 +0000 | |
---|---|---|
committer | 2020-06-22 07:39:41 +0000 | |
commit | 77bfb901bd2cbaceaa38a1d58d4a669580e3b3ce (patch) | |
tree | ff6cde013cd37a36e0624586f8594d5ccd727809 /sys/dev/pci/if_iwx.c | |
parent | Do not copy an SSID into the iwx(4) probe request template. (diff) | |
download | wireguard-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.c | 46 |
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: |