summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2021-07-29 11:56:54 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2021-07-29 11:56:54 +0000
commit7fba5538266a3d08fbea2c38469b9012ec123dff (patch)
tree2b2260b01a8ec95686621bdd6a225be60963992d /sys
parentd648c3626c78c3e67f53694d560968637c6c07c4 (diff)
Handle iwx(4) PHY context command version 3.
ok kevlo@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/if_iwx.c96
-rw-r--r--sys/dev/pci/if_iwxreg.h40
2 files changed, 130 insertions, 6 deletions
diff --git a/sys/dev/pci/if_iwx.c b/sys/dev/pci/if_iwx.c
index fa02c31ef57..81627b46d19 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.78 2021/07/29 11:56:21 stsp Exp $ */
+/* $OpenBSD: if_iwx.c,v 1.79 2021/07/29 11:56:53 stsp Exp $ */
/*
* Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -357,6 +357,10 @@ void iwx_rx_tx_cmd(struct iwx_softc *, struct iwx_rx_packet *,
void iwx_rx_bmiss(struct iwx_softc *, struct iwx_rx_packet *,
struct iwx_rx_data *);
int iwx_binding_cmd(struct iwx_softc *, struct iwx_node *, uint32_t);
+int iwx_phy_ctxt_cmd_uhb_v3(struct iwx_softc *, struct iwx_phy_ctxt *, uint8_t,
+ uint8_t, uint32_t);
+int iwx_phy_ctxt_cmd_v3(struct iwx_softc *, struct iwx_phy_ctxt *, uint8_t,
+ uint8_t, uint32_t);
int iwx_phy_ctxt_cmd_uhb(struct iwx_softc *, struct iwx_phy_ctxt *, uint8_t,
uint8_t, uint32_t, uint32_t);
int iwx_phy_ctxt_cmd(struct iwx_softc *, struct iwx_phy_ctxt *, uint8_t,
@@ -4441,12 +4445,86 @@ iwx_binding_cmd(struct iwx_softc *sc, struct iwx_node *in, uint32_t action)
}
int
+iwx_phy_ctxt_cmd_uhb_v3(struct iwx_softc *sc, struct iwx_phy_ctxt *ctxt,
+ uint8_t chains_static, uint8_t chains_dynamic, uint32_t action)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct iwx_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(IWX_FW_CMD_ID_AND_COLOR(ctxt->id,
+ ctxt->color));
+ cmd.action = htole32(action);
+
+ if (IEEE80211_IS_CHAN_2GHZ(ctxt->channel) ||
+ !isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_CDB_SUPPORT))
+ cmd.lmac_id = htole32(IWX_LMAC_24G_INDEX);
+ else
+ cmd.lmac_id = htole32(IWX_LMAC_5G_INDEX);
+
+ cmd.ci.band = IEEE80211_IS_CHAN_2GHZ(chan) ?
+ IWX_PHY_BAND_24 : IWX_PHY_BAND_5;
+ cmd.ci.channel = htole32(ieee80211_chan2ieee(ic, chan));
+ cmd.ci.width = IWX_PHY_VHT_CHANNEL_MODE20;
+ cmd.ci.ctrl_pos = IWX_PHY_VHT_CTRL_POS_1_BELOW;
+
+ idle_cnt = chains_static;
+ active_cnt = chains_dynamic;
+ cmd.rxchain_info = htole32(iwx_fw_valid_rx_ant(sc) <<
+ IWX_PHY_RX_CHAIN_VALID_POS);
+ cmd.rxchain_info |= htole32(idle_cnt << IWX_PHY_RX_CHAIN_CNT_POS);
+ cmd.rxchain_info |= htole32(active_cnt <<
+ IWX_PHY_RX_CHAIN_MIMO_CNT_POS);
+
+ return iwx_send_cmd_pdu(sc, IWX_PHY_CONTEXT_CMD, 0, sizeof(cmd), &cmd);
+}
+
+int
+iwx_phy_ctxt_cmd_v3(struct iwx_softc *sc, struct iwx_phy_ctxt *ctxt,
+ uint8_t chains_static, uint8_t chains_dynamic, uint32_t action)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct iwx_phy_context_cmd cmd;
+ uint8_t active_cnt, idle_cnt;
+ struct ieee80211_channel *chan = ctxt->channel;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(ctxt->id,
+ ctxt->color));
+ cmd.action = htole32(action);
+
+ if (IEEE80211_IS_CHAN_2GHZ(ctxt->channel) ||
+ !isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_CDB_SUPPORT))
+ cmd.lmac_id = htole32(IWX_LMAC_24G_INDEX);
+ else
+ cmd.lmac_id = htole32(IWX_LMAC_5G_INDEX);
+
+ cmd.ci.band = IEEE80211_IS_CHAN_2GHZ(chan) ?
+ IWX_PHY_BAND_24 : IWX_PHY_BAND_5;
+ cmd.ci.channel = ieee80211_chan2ieee(ic, chan);
+ cmd.ci.width = IWX_PHY_VHT_CHANNEL_MODE20;
+ cmd.ci.ctrl_pos = IWX_PHY_VHT_CTRL_POS_1_BELOW;
+
+ idle_cnt = chains_static;
+ active_cnt = chains_dynamic;
+ cmd.rxchain_info = htole32(iwx_fw_valid_rx_ant(sc) <<
+ IWX_PHY_RX_CHAIN_VALID_POS);
+ cmd.rxchain_info |= htole32(idle_cnt << IWX_PHY_RX_CHAIN_CNT_POS);
+ cmd.rxchain_info |= htole32(active_cnt <<
+ IWX_PHY_RX_CHAIN_MIMO_CNT_POS);
+
+ return iwx_send_cmd_pdu(sc, IWX_PHY_CONTEXT_CMD, 0, sizeof(cmd), &cmd);
+}
+
+int
iwx_phy_ctxt_cmd_uhb(struct iwx_softc *sc, struct iwx_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 iwx_phy_context_cmd_uhb cmd;
+ struct iwx_phy_context_cmd_uhb_v1 cmd;
uint8_t active_cnt, idle_cnt;
struct ieee80211_channel *chan = ctxt->channel;
@@ -4480,9 +4558,10 @@ iwx_phy_ctxt_cmd(struct iwx_softc *sc, struct iwx_phy_ctxt *ctxt,
uint32_t apply_time)
{
struct ieee80211com *ic = &sc->sc_ic;
- struct iwx_phy_context_cmd cmd;
+ struct iwx_phy_context_cmd_v1 cmd;
uint8_t active_cnt, idle_cnt;
struct ieee80211_channel *chan = ctxt->channel;
+ int cmdver;
/*
* Intel increased the size of the fw_channel_info struct and neglected
@@ -4491,6 +4570,17 @@ iwx_phy_ctxt_cmd(struct iwx_softc *sc, struct iwx_phy_ctxt *ctxt,
* To keep things simple we use a separate function to handle the larger
* variant of the phy context command.
*/
+ cmdver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, IWX_PHY_CONTEXT_CMD);
+ if (cmdver == 3) {
+ /* Version 3 differs in the "data" portion of the command. */
+ if (isset(sc->sc_enabled_capa,
+ IWX_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS)) {
+ return iwx_phy_ctxt_cmd_uhb_v3(sc, ctxt, chains_static,
+ chains_dynamic, action);
+ }
+ return iwx_phy_ctxt_cmd_v3(sc, ctxt, chains_static,
+ chains_dynamic, action);
+ }
if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS))
return iwx_phy_ctxt_cmd_uhb(sc, ctxt, chains_static,
chains_dynamic, action, apply_time);
diff --git a/sys/dev/pci/if_iwxreg.h b/sys/dev/pci/if_iwxreg.h
index fc05171a70e..26231b92db5 100644
--- a/sys/dev/pci/if_iwxreg.h
+++ b/sys/dev/pci/if_iwxreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwxreg.h,v 1.23 2021/07/29 11:53:46 stsp Exp $ */
+/* $OpenBSD: if_iwxreg.h,v 1.24 2021/07/29 11:56:53 stsp Exp $ */
/*-
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
@@ -2924,6 +2924,40 @@ struct iwx_fw_channel_info {
/* TODO: fix the value, make it depend on firmware at runtime? */
#define IWX_NUM_PHY_CTX 3
+/**
+ * struct iwl_phy_context_cmd - config of the PHY context
+ * ( IWX_PHY_CONTEXT_CMD = 0x8 )
+ * @id_and_color: ID and color of the relevant Binding
+ * @action: action to perform, one of IWX_FW_CTXT_ACTION_*
+ * @lmac_id: the lmac id the phy context belongs to
+ * @ci: channel info
+ * @rxchain_info: ???
+ * @dsp_cfg_flags: set to 0
+ * @reserved: reserved to align to 64 bit
+ */
+struct iwx_phy_context_cmd_uhb {
+ /* COMMON_INDEX_HDR_API_S_VER_1 */
+ uint32_t id_and_color;
+ uint32_t action;
+ /* PHY_CONTEXT_DATA_API_S_VER_3 */
+ struct iwx_fw_channel_info ci;
+ uint32_t lmac_id;
+ uint32_t rxchain_info;
+ uint32_t dsp_cfg_flags;
+ uint32_t reserved;
+} __packed; /* PHY_CONTEXT_CMD_API_VER_3 */
+struct iwx_phy_context_cmd {
+ /* COMMON_INDEX_HDR_API_S_VER_1 */
+ uint32_t id_and_color;
+ uint32_t action;
+ /* PHY_CONTEXT_DATA_API_S_VER_3 */
+ struct iwx_fw_channel_info_v1 ci;
+ uint32_t lmac_id;
+ uint32_t rxchain_info;
+ uint32_t dsp_cfg_flags;
+ uint32_t reserved;
+} __packed; /* PHY_CONTEXT_CMD_API_VER_3 */
+
/* TODO: complete missing documentation */
/**
* struct iwx_phy_context_cmd - config of the PHY context
@@ -2947,7 +2981,7 @@ struct iwx_fw_channel_info {
* magic with pointers to struct members instead.)
*/
/* This version must be used if IWX_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS is set: */
-struct iwx_phy_context_cmd_uhb {
+struct iwx_phy_context_cmd_uhb_v1 {
/* COMMON_INDEX_HDR_API_S_VER_1 */
uint32_t id_and_color;
uint32_t action;
@@ -2961,7 +2995,7 @@ struct iwx_phy_context_cmd_uhb {
uint32_t dsp_cfg_flags;
} __packed; /* IWX_PHY_CONTEXT_CMD_API_VER_1 */
/* This version must be used otherwise: */
-struct iwx_phy_context_cmd {
+struct iwx_phy_context_cmd_v1 {
/* COMMON_INDEX_HDR_API_S_VER_1 */
uint32_t id_and_color;
uint32_t action;