summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2021-07-07 08:21:32 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2021-07-07 08:21:32 +0000
commit216dddbeb2e2a738c6c824f9cb26d2ca433580b0 (patch)
tree807263b948eabe511e3938138d141725e35e4c66 /sys/dev
parentff1233aecc535e9bf64ee51400c84d5ed4733d5b (diff)
Support the larger phy context command required by newer iwm(4) firmware.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/if_iwm.c49
-rw-r--r--sys/dev/pci/if_iwmreg.h48
2 files changed, 92 insertions, 5 deletions
diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c
index ed8f3c7ae91..ac4d3526290 100644
--- a/sys/dev/pci/if_iwm.c
+++ b/sys/dev/pci/if_iwm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwm.c,v 1.335 2021/07/07 08:13:37 stsp Exp $ */
+/* $OpenBSD: if_iwm.c,v 1.336 2021/07/07 08:21:31 stsp Exp $ */
/*
* Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -402,6 +402,8 @@ void iwm_rx_compressed_ba(struct iwm_softc *, struct iwm_rx_packet *,
void iwm_rx_bmiss(struct iwm_softc *, struct iwm_rx_packet *,
struct iwm_rx_data *);
int iwm_binding_cmd(struct iwm_softc *, struct iwm_node *, uint32_t);
+int iwm_phy_ctxt_cmd_uhb(struct iwm_softc *, struct iwm_phy_ctxt *, uint8_t,
+ uint8_t, uint32_t, uint32_t);
void iwm_phy_ctxt_cmd_hdr(struct iwm_softc *, struct iwm_phy_ctxt *,
struct iwm_phy_context_cmd *, uint32_t, uint32_t);
void iwm_phy_ctxt_cmd_data(struct iwm_softc *, struct iwm_phy_context_cmd *,
@@ -5743,12 +5745,57 @@ iwm_phy_ctxt_cmd_data(struct iwm_softc *sc, struct iwm_phy_context_cmd *cmd,
}
int
+iwm_phy_ctxt_cmd_uhb(struct iwm_softc *sc, struct iwm_phy_ctxt *ctxt,
+ uint8_t chains_static, uint8_t chains_dynamic, uint32_t action,
+ uint32_t apply_time)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct iwm_phy_context_cmd_uhb cmd;
+ uint8_t active_cnt, idle_cnt;
+ struct ieee80211_channel *chan = ctxt->channel;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(ctxt->id,
+ ctxt->color));
+ cmd.action = htole32(action);
+ cmd.apply_time = htole32(apply_time);
+
+ cmd.ci.band = IEEE80211_IS_CHAN_2GHZ(chan) ?
+ IWM_PHY_BAND_24 : IWM_PHY_BAND_5;
+ cmd.ci.channel = htole32(ieee80211_chan2ieee(ic, chan));
+ cmd.ci.width = IWM_PHY_VHT_CHANNEL_MODE20;
+ cmd.ci.ctrl_pos = IWM_PHY_VHT_CTRL_POS_1_BELOW;
+
+ idle_cnt = chains_static;
+ active_cnt = chains_dynamic;
+ cmd.rxchain_info = htole32(iwm_fw_valid_rx_ant(sc) <<
+ IWM_PHY_RX_CHAIN_VALID_POS);
+ cmd.rxchain_info |= htole32(idle_cnt << IWM_PHY_RX_CHAIN_CNT_POS);
+ cmd.rxchain_info |= htole32(active_cnt <<
+ IWM_PHY_RX_CHAIN_MIMO_CNT_POS);
+ cmd.txchain_info = htole32(iwm_fw_valid_tx_ant(sc));
+
+ return iwm_send_cmd_pdu(sc, IWM_PHY_CONTEXT_CMD, 0, sizeof(cmd), &cmd);
+}
+
+int
iwm_phy_ctxt_cmd(struct iwm_softc *sc, struct iwm_phy_ctxt *ctxt,
uint8_t chains_static, uint8_t chains_dynamic, uint32_t action,
uint32_t apply_time)
{
struct iwm_phy_context_cmd cmd;
+ /*
+ * Intel increased the size of the fw_channel_info struct and neglected
+ * to bump the phy_context_cmd struct, which contains an fw_channel_info
+ * member in the middle.
+ * To keep things simple we use a separate function to handle the larger
+ * variant of the phy context command.
+ */
+ if (isset(sc->sc_enabled_capa, IWM_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS))
+ return iwm_phy_ctxt_cmd_uhb(sc, ctxt, chains_static,
+ chains_dynamic, action, apply_time);
+
iwm_phy_ctxt_cmd_hdr(sc, ctxt, &cmd, action, apply_time);
iwm_phy_ctxt_cmd_data(sc, &cmd, ctxt->channel,
diff --git a/sys/dev/pci/if_iwmreg.h b/sys/dev/pci/if_iwmreg.h
index e2348d4a489..c396eeca999 100644
--- a/sys/dev/pci/if_iwmreg.h
+++ b/sys/dev/pci/if_iwmreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwmreg.h,v 1.55 2021/07/07 08:13:37 stsp Exp $ */
+/* $OpenBSD: if_iwmreg.h,v 1.56 2021/07/07 08:21:31 stsp Exp $ */
/******************************************************************************
*
@@ -917,6 +917,7 @@ enum msix_ivar_for_cause {
#define IWM_UCODE_TLV_CAPA_NAN_SUPPORT 34
#define IWM_UCODE_TLV_CAPA_UMAC_UPLOAD 35
#define IWM_UCODE_TLV_CAPA_DYNAMIC_QUOTA 44
+#define IWM_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS 48
#define IWM_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE 64
#define IWM_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS 65
#define IWM_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT 67
@@ -2966,12 +2967,29 @@ struct iwm_time_quota_cmd {
* @width: PHY_[VHT|LEGACY]_CHANNEL_*
* @ctrl channel: PHY_[VHT|LEGACY]_CTRL_*
*/
-struct iwm_fw_channel_info {
+struct iwm_fw_channel_info_v1 {
uint8_t band;
uint8_t channel;
uint8_t width;
uint8_t ctrl_pos;
-} __packed;
+} __packed; /* CHANNEL_CONFIG_API_S_VER_1 */
+
+/*
+ * struct iwm_fw_channel_info - channel information
+ *
+ * @channel: channel number
+ * @band: PHY_BAND_*
+ * @width: PHY_[VHT|LEGACY]_CHANNEL_*
+ * @ctrl channel: PHY_[VHT|LEGACY]_CTRL_*
+ * @reserved: for future use and alignment
+ */
+struct iwm_fw_channel_info {
+ uint32_t channel;
+ uint8_t band;
+ uint8_t width;
+ uint8_t ctrl_pos;
+ uint8_t reserved;
+} __packed; /* CHANNEL_CONFIG_API_S_VER_2 */
#define IWM_PHY_RX_CHAIN_DRIVER_FORCE_POS (0)
#define IWM_PHY_RX_CHAIN_DRIVER_FORCE_MSK \
@@ -3013,7 +3031,15 @@ struct iwm_fw_channel_info {
* @acquisition_data: ???
* @dsp_cfg_flags: set to 0
*/
-struct iwm_phy_context_cmd {
+/*
+ * XXX Intel forgot to bump the PHY_CONTEXT command API when they increased
+ * the size of fw_channel_info from v1 to v2.
+ * To keep things simple we define two versions of this struct, and both
+ * are labled as CMD_API_VER_1. (The Linux iwlwifi driver performs dark
+ * magic with pointers to struct members instead.)
+ */
+/* This version must be used if IWM_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS is set: */
+struct iwm_phy_context_cmd_uhb {
/* COMMON_INDEX_HDR_API_S_VER_1 */
uint32_t id_and_color;
uint32_t action;
@@ -3026,6 +3052,20 @@ struct iwm_phy_context_cmd {
uint32_t acquisition_data;
uint32_t dsp_cfg_flags;
} __packed; /* IWM_PHY_CONTEXT_CMD_API_VER_1 */
+/* This version must be used otherwise: */
+struct iwm_phy_context_cmd {
+ /* COMMON_INDEX_HDR_API_S_VER_1 */
+ uint32_t id_and_color;
+ uint32_t action;
+ /* IWM_PHY_CONTEXT_DATA_API_S_VER_1 */
+ uint32_t apply_time;
+ uint32_t tx_param_color;
+ struct iwm_fw_channel_info_v1 ci;
+ uint32_t txchain_info;
+ uint32_t rxchain_info;
+ uint32_t acquisition_data;
+ uint32_t dsp_cfg_flags;
+} __packed; /* IWM_PHY_CONTEXT_CMD_API_VER_1 */
#define IWM_RX_INFO_PHY_CNT 8
#define IWM_RX_INFO_ENERGY_ANT_ABC_IDX 1