diff options
author | Stefan Sperling <stsp@cvs.openbsd.org> | 2021-07-07 08:21:32 +0000 |
---|---|---|
committer | Stefan Sperling <stsp@cvs.openbsd.org> | 2021-07-07 08:21:32 +0000 |
commit | 216dddbeb2e2a738c6c824f9cb26d2ca433580b0 (patch) | |
tree | 807263b948eabe511e3938138d141725e35e4c66 /sys/dev | |
parent | ff1233aecc535e9bf64ee51400c84d5ed4733d5b (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.c | 49 | ||||
-rw-r--r-- | sys/dev/pci/if_iwmreg.h | 48 |
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 |