On Mon, Jul 26, 2021 at 06:21:46PM +0200, Stefan Sperling wrote:
> This patch implements support for new iwx(4) -63 firmware images
> available in the iwx-firmware-20210512 package (via fw_update).
>
> Please test this patch and report back. If testing works out well
> then I will commit these changes to CVS incrementally. Thanks!
>
> For those testing my iwx Tx agg patch: Please remove that patch first.
> Tx agg will come back later. Getting new firmware images to work is more
> important right now because these images contain fixes for fragattacks.
Several people have reported messages such as:
iwx0: unhandled firmware response 0xc2/0xc rx ring 63[255]
The 0xc2 response is a new notification from firmware (BAR_FRAME_RELEASE).
This updated version of the patch adds support for this feature.
diff 54a415eecf0903b6663209706a0fc6e2e9d40044 refs/heads/iwxfw
blob - 48bf14d7a8a421c6f1bf2b4bfc6c1792396b5400
blob + 0b97503422759e3898791e31f9999f096d6ce9cb
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -232,6 +232,7 @@ const int iwx_mcs2ridx[] = {
};
uint8_t iwx_lookup_cmd_ver(struct iwx_softc *, uint8_t, uint8_t);
+uint8_t iwx_lookup_notif_ver(struct iwx_softc *, uint8_t, uint8_t);
int iwx_is_mimo_ht_plcp(uint8_t);
int iwx_is_mimo_mcs(int);
int iwx_store_cscheme(struct iwx_softc *, uint8_t *, size_t);
@@ -297,6 +298,8 @@ int iwx_nic_rx_init(struct iwx_softc *);
int iwx_nic_init(struct iwx_softc *);
int iwx_enable_txq(struct iwx_softc *, int, int, int, int);
void iwx_post_alive(struct iwx_softc *);
+int iwx_schedule_session_protection(struct iwx_softc *, struct iwx_node *,
+ uint32_t);
void iwx_protect_session(struct iwx_softc *, struct iwx_node *, uint32_t,
uint32_t);
void iwx_unprotect_session(struct iwx_softc *, struct iwx_node *);
@@ -315,6 +318,8 @@ int iwx_ampdu_rx_start(struct ieee80211com *, struct i
void iwx_ampdu_rx_stop(struct ieee80211com *, struct ieee80211_node *,
uint8_t);
void iwx_rx_ba_session_expired(void *);
+void iwx_rx_bar_frame_release(struct iwx_softc *, struct iwx_rx_packet *,
+ struct iwx_rx_data *, struct mbuf_list *);
void iwx_reorder_timer_expired(void *);
void iwx_sta_rx_agg(struct iwx_softc *, struct ieee80211_node *, uint8_t,
uint16_t, uint16_t, int, int);
@@ -356,6 +361,10 @@ void iwx_rx_tx_cmd(struct iwx_softc *, struct
iwx_rx_p
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,
@@ -387,7 +396,16 @@ int iwx_add_sta_cmd(struct iwx_softc *, struct
iwx_nod
int iwx_add_aux_sta(struct iwx_softc *);
int iwx_rm_sta_cmd(struct iwx_softc *, struct iwx_node *);
int iwx_fill_probe_req(struct iwx_softc *, struct iwx_scan_probe_req *);
+int iwx_config_umac_scan_reduced(struct iwx_softc *);
int iwx_config_umac_scan(struct iwx_softc *);
+uint16_t iwx_scan_umac_flags_v2(struct iwx_softc *, int);
+void iwx_scan_umac_dwell_v10(struct iwx_softc *,
+ struct iwx_scan_general_params_v10 *, int);
+void iwx_scan_umac_fill_general_p_v10(struct iwx_softc *,
+ struct iwx_scan_general_params_v10 *, uint16_t, int);
+void iwx_scan_umac_fill_ch_p_v6(struct iwx_softc *,
+ struct iwx_scan_channel_params_v6 *, uint32_t, int, int);
+int iwx_umac_scan_v14(struct iwx_softc *, int);
int iwx_umac_scan(struct iwx_softc *, int);
void iwx_mcc_update(struct iwx_softc *, struct iwx_mcc_chub_notif *);
uint8_t iwx_ridx2rate(struct ieee80211_rateset *, int);
@@ -490,6 +508,21 @@ iwx_lookup_cmd_ver(struct iwx_softc *sc, uint8_t grp,
return IWX_FW_CMD_VER_UNKNOWN;
}
+uint8_t
+iwx_lookup_notif_ver(struct iwx_softc *sc, uint8_t grp, uint8_t cmd)
+{
+ const struct iwx_fw_cmd_version *entry;
+ int i;
+
+ for (i = 0; i < sc->n_cmd_versions; i++) {
+ entry = &sc->cmd_versions[i];
+ if (entry->group == grp && entry->cmd == cmd)
+ return entry->notif_ver;
+ }
+
+ return IWX_FW_CMD_VER_UNKNOWN;
+}
+
int
iwx_is_mimo_ht_plcp(uint8_t ht_plcp)
{
@@ -924,7 +957,7 @@ iwx_firmware_store_section(struct iwx_softc *sc, enum
#define IWX_DEFAULT_SCAN_CHANNELS 40
/* Newer firmware might support more channels. Raise this value if needed. */
-#define IWX_MAX_SCAN_CHANNELS 52 /* as of 8265-34 firmware image */
+#define IWX_MAX_SCAN_CHANNELS 67 /* as of iwx-cc-a0-62 firmware */
struct iwx_tlv_calib_data {
uint32_t ucode_type;
@@ -1304,6 +1337,8 @@ iwx_read_firmware(struct iwx_softc *sc)
break;
case IWX_UCODE_TLV_FW_FSEQ_VERSION:
+ case IWX_UCODE_TLV_PHY_INTEGRATION_VERSION:
+ case IWX_UCODE_TLV_FW_NUM_STATIONS:
break;
/* undocumented TLVs found in iwx-cc-a0-46 image */
@@ -1317,6 +1352,13 @@ iwx_read_firmware(struct iwx_softc *sc)
case 0x1000002:
break;
+ case IWX_UCODE_TLV_TYPE_DEBUG_INFO:
+ case IWX_UCODE_TLV_TYPE_BUFFER_ALLOCATION:
+ case IWX_UCODE_TLV_TYPE_HCMD:
+ case IWX_UCODE_TLV_TYPE_REGIONS:
+ case IWX_UCODE_TLV_TYPE_TRIGGERS:
+ break;
+
default:
err = EINVAL;
goto parse_out;
@@ -2559,6 +2601,23 @@ out:
return err;
}
+int
+iwx_schedule_session_protection(struct iwx_softc *sc, struct iwx_node *in,
+ uint32_t duration)
+{
+ struct iwx_session_prot_cmd cmd = {
+ .id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id,
+ in->in_color)),
+ .action = htole32(IWX_FW_CTXT_ACTION_ADD),
+ .conf_id = htole32(IWX_SESSION_PROTECT_CONF_ASSOC),
+ .duration_tu = htole32(duration * IEEE80211_DUR_TU),
+ };
+ uint32_t cmd_id;
+
+ cmd_id = iwx_cmd_id(IWX_SESSION_PROTECTION_CMD, IWX_MAC_CONF_GROUP, 0);
+ return iwx_send_cmd_pdu(sc, cmd_id, 0, sizeof(cmd), &cmd);
+}
+
void
iwx_protect_session(struct iwx_softc *sc, struct iwx_node *in,
uint32_t duration, uint32_t max_delay)
@@ -2810,6 +2869,41 @@ iwx_rx_ba_session_expired(void *arg)
}
void
+iwx_rx_bar_frame_release(struct iwx_softc *sc, struct iwx_rx_packet *pkt,
+ struct iwx_rx_data *data, struct mbuf_list *ml)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211_node *ni = ic->ic_bss;
+ struct iwx_bar_frame_release *release = (void *)data;
+ struct iwx_reorder_buffer *buf;
+ struct iwx_rxba_data *rxba;
+ unsigned int baid, nssn, sta_id, tid;
+
+ if (iwx_rx_packet_payload_len(pkt) < sizeof(*release))
+ return;
+
+ baid = (le32toh(release->ba_info) & IWX_BAR_FRAME_RELEASE_BAID_MASK) >>
+ IWX_BAR_FRAME_RELEASE_BAID_SHIFT;
+ if (baid == IWX_RX_REORDER_DATA_INVALID_BAID ||
+ baid >= nitems(sc->sc_rxba_data))
+ return;
+
+ rxba = &sc->sc_rxba_data[baid];
+ if (rxba == NULL || rxba->baid == IWX_RX_REORDER_DATA_INVALID_BAID)
+ return;
+
+ tid = le32toh(release->sta_tid) & IWX_BAR_FRAME_RELEASE_TID_MASK;
+ sta_id = (le32toh(release->sta_tid) &
+ IWX_BAR_FRAME_RELEASE_STA_MASK) >> IWX_BAR_FRAME_RELEASE_STA_SHIFT;
+ if (tid != rxba->tid || rxba->sta_id != IWX_STATION_ID)
+ return;
+
+ nssn = le32toh(release->ba_info) & IWX_BAR_FRAME_RELEASE_NSSN_MASK;
+ buf = &rxba->reorder_buf;
+ iwx_release_frames(sc, ni, rxba, buf, nssn, ml);
+}
+
+void
iwx_reorder_timer_expired(void *arg)
{
struct mbuf_list ml = MBUF_LIST_INITIALIZER();
@@ -4416,9 +4510,8 @@ iwx_binding_cmd(struct iwx_softc *sc, struct iwx_node
}
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)
+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;
@@ -4429,8 +4522,13 @@ iwx_phy_ctxt_cmd_uhb(struct iwx_softc *sc, struct iwx_
cmd.id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(ctxt->id,
ctxt->color));
cmd.action = htole32(action);
- cmd.apply_time = htole32(apply_time);
+ 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));
@@ -4440,25 +4538,96 @@ iwx_phy_ctxt_cmd_uhb(struct iwx_softc *sc, struct iwx_
idle_cnt = chains_static;
active_cnt = chains_dynamic;
cmd.rxchain_info = htole32(iwx_fw_valid_rx_ant(sc) <<
- IWX_PHY_RX_CHAIN_VALID_POS);
+ 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);
- cmd.txchain_info = htole32(iwx_fw_valid_tx_ant(sc));
return iwx_send_cmd_pdu(sc, IWX_PHY_CONTEXT_CMD, 0, sizeof(cmd), &cmd);
}
int
-iwx_phy_ctxt_cmd(struct iwx_softc *sc, struct iwx_phy_ctxt *ctxt,
- uint8_t chains_static, uint8_t chains_dynamic, uint32_t action,
- uint32_t apply_time)
+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_v1 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);
+ cmd.apply_time = htole32(apply_time);
+
+ 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);
+ cmd.txchain_info = htole32(iwx_fw_valid_tx_ant(sc));
+
+ return iwx_send_cmd_pdu(sc, IWX_PHY_CONTEXT_CMD, 0, sizeof(cmd), &cmd);
+}
+
+int
+iwx_phy_ctxt_cmd(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_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
* to bump the phy_context_cmd struct, which contains an fw_channel_info
@@ -4466,6 +4635,17 @@ iwx_phy_ctxt_cmd(struct iwx_softc *sc, struct iwx_phy_
* 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);
@@ -4542,15 +4722,24 @@ iwx_send_cmd(struct iwx_softc *sc, struct iwx_host_cmd
desc = &ring->desc[idx];
txdata = &ring->data[idx];
+ /*
+ * XXX Intel inside (tm)
+ * Firmware API versions >= 50 reject old-style commands in
+ * group 0 with a "BAD_COMMAND" firmware error. We must pretend
+ * that such commands were in the LONG_GROUP instead in order
+ * for firmware to accept them.
+ */
+ if (iwx_cmd_groupid(code) == 0) {
+ code = IWX_WIDE_ID(IWX_LONG_GROUP, code);
+ txdata->flags |= IWX_TXDATA_FLAG_CMD_IS_NARROW;
+ } else
+ txdata->flags &= ~IWX_TXDATA_FLAG_CMD_IS_NARROW;
+
group_id = iwx_cmd_groupid(code);
- if (group_id != 0) {
- hdrlen = sizeof(cmd->hdr_wide);
- datasz = sizeof(cmd->data_wide);
- } else {
- hdrlen = sizeof(cmd->hdr);
- datasz = sizeof(cmd->data);
- }
+ hdrlen = sizeof(cmd->hdr_wide);
+ datasz = sizeof(cmd->data_wide);
+
if (paylen > datasz) {
/* Command is too large to fit in pre-allocated space. */
size_t totlen = hdrlen + paylen;
@@ -4583,21 +4772,14 @@ iwx_send_cmd(struct iwx_softc *sc, struct iwx_host_cmd
paddr = txdata->cmd_paddr;
}
- if (group_id != 0) {
- cmd->hdr_wide.opcode = iwx_cmd_opcode(code);
- cmd->hdr_wide.group_id = group_id;
- cmd->hdr_wide.qid = ring->qid;
- cmd->hdr_wide.idx = idx;
- cmd->hdr_wide.length = htole16(paylen);
- cmd->hdr_wide.version = iwx_cmd_version(code);
- data = cmd->data_wide;
- } else {
- cmd->hdr.code = code;
- cmd->hdr.flags = 0;
- cmd->hdr.qid = ring->qid;
- cmd->hdr.idx = idx;
- data = cmd->data;
- }
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->hdr_wide.opcode = iwx_cmd_opcode(code);
+ cmd->hdr_wide.group_id = group_id;
+ cmd->hdr_wide.qid = ring->qid;
+ cmd->hdr_wide.idx = idx;
+ cmd->hdr_wide.length = htole16(paylen);
+ cmd->hdr_wide.version = iwx_cmd_version(code);
+ data = cmd->data_wide;
for (i = 0, off = 0; i < nitems(hcmd->data); i++) {
if (hcmd->len[i] == 0)
@@ -4607,10 +4789,17 @@ iwx_send_cmd(struct iwx_softc *sc, struct iwx_host_cmd
}
KASSERT(off == paylen);
- desc->tbs[0].tb_len = htole16(hdrlen + paylen);
- addr = htole64((uint64_t)paddr);
+ desc->tbs[0].tb_len = htole16(MIN(hdrlen + paylen, IWX_FIRST_TB_SIZE));
+ addr = htole64(paddr);
memcpy(&desc->tbs[0].addr, &addr, sizeof(addr));
- desc->num_tbs = 1;
+ if (hdrlen + paylen > IWX_FIRST_TB_SIZE) {
+ desc->tbs[1].tb_len = htole16(hdrlen + paylen -
+ IWX_FIRST_TB_SIZE);
+ addr = htole64(paddr + IWX_FIRST_TB_SIZE);
+ memcpy(&desc->tbs[1].addr, &addr, sizeof(addr));
+ desc->num_tbs = htole16(2);
+ } else
+ desc->num_tbs = htole16(1);
if (paylen > datasz) {
bus_dmamap_sync(sc->sc_dmat, txdata->map, 0,
@@ -4874,7 +5063,7 @@ iwx_tx(struct iwx_softc *sc, struct mbuf *m, struct ie
* Tx aggregation will require additional queues (one queue per TID
* for which aggregation is enabled) but we do not implement this yet.
*/
- ring = &sc->txq[ac + IWX_DQA_AUX_QUEUE + 1];
+ ring = &sc->txq[ac + sc->first_data_qid];
desc = &ring->desc[ring->cur];
memset(desc, 0, sizeof(*desc));
data = &ring->data[ring->cur];
@@ -5262,7 +5451,16 @@ iwx_add_aux_sta(struct iwx_softc *sc)
struct iwx_add_sta_cmd cmd;
int err, qid = IWX_DQA_AUX_QUEUE;
uint32_t status;
+ uint8_t cmdver;
+ /*
+ * ADD_STA command version >= 12 implies that firmware uses
+ * an internal AUX station for scanning.
+ */
+ cmdver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, IWX_ADD_STA);
+ if (cmdver != IWX_FW_CMD_VER_UNKNOWN && cmdver >= 12)
+ return 0;
+
memset(&cmd, 0, sizeof(cmd));
cmd.sta_id = IWX_AUX_STA_ID;
cmd.station_type = IWX_STA_AUX_ACTIVITY;
@@ -5304,7 +5502,8 @@ iwx_rm_sta_cmd(struct iwx_softc *sc, struct iwx_node *
uint8_t
iwx_umac_scan_fill_channels(struct iwx_softc *sc,
- struct iwx_scan_channel_cfg_umac *chan, int n_ssids, int bgscan)
+ struct iwx_scan_channel_cfg_umac *chan, size_t chan_nitems,
+ int n_ssids, int bgscan)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_channel *c;
@@ -5312,6 +5511,7 @@ iwx_umac_scan_fill_channels(struct iwx_softc *sc,
for (nchan = 0, c = &ic->ic_channels[1];
c <= &ic->ic_channels[IEEE80211_CHAN_MAX] &&
+ nchan < chan_nitems &&
nchan < sc->sc_capa_n_scan_channels;
c++) {
uint8_t channel_num;
@@ -5460,10 +5660,48 @@ iwx_fill_probe_req(struct iwx_softc *sc, struct iwx_sc
}
int
+iwx_config_umac_scan_reduced(struct iwx_softc *sc)
+{
+ struct iwx_scan_config scan_cfg;
+ struct iwx_host_cmd hcmd = {
+ .id = iwx_cmd_id(IWX_SCAN_CFG_CMD, IWX_LONG_GROUP, 0),
+ .len[0] = sizeof(scan_cfg),
+ .data[0] = &scan_cfg,
+ .flags = 0,
+ };
+ int cmdver;
+
+ memset(&scan_cfg, 0, sizeof(scan_cfg));
+
+ /*
+ * ADD_STA command version >= 12 implies that firmware uses
+ * an internal AUX station for scanning.
+ */
+ cmdver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, IWX_ADD_STA);
+ if (cmdver == IWX_FW_CMD_VER_UNKNOWN || cmdver < 12)
+ scan_cfg.bcast_sta_id = IWX_AUX_STA_ID;
+ else {
+ /*
+ * SCAN_CFG version >= 5 implies that the broadcast
+ * STA ID field is deprecated.
+ */
+ cmdver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP,
+ IWX_SCAN_CFG_CMD);
+ if (cmdver == IWX_FW_CMD_VER_UNKNOWN || cmdver < 5)
+ scan_cfg.bcast_sta_id = 0xff;
+ }
+
+ scan_cfg.tx_chains = htole32(iwx_fw_valid_tx_ant(sc));
+ scan_cfg.rx_chains = htole32(iwx_fw_valid_rx_ant(sc));
+
+ return iwx_send_cmd(sc, &hcmd);
+}
+
+int
iwx_config_umac_scan(struct iwx_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
- struct iwx_scan_config *scan_config;
+ struct iwx_scan_config_v2 *scan_config;
int err, nchan;
size_t cmd_size;
struct ieee80211_channel *c;
@@ -5479,6 +5717,9 @@ iwx_config_umac_scan(struct iwx_softc *sc)
IWX_SCAN_CONFIG_RATE_36M | IWX_SCAN_CONFIG_RATE_48M |
IWX_SCAN_CONFIG_RATE_54M);
+ if (isset(sc->sc_ucode_api, IWX_UCODE_TLV_API_REDUCED_SCAN_CONFIG))
+ return iwx_config_umac_scan_reduced(sc);
+
cmd_size = sizeof(*scan_config) + sc->sc_capa_n_scan_channels;
scan_config = malloc(cmd_size, M_DEVBUF, M_WAIT | M_CANFAIL | M_ZERO);
@@ -5589,6 +5830,25 @@ iwx_get_scan_req_umac_data(struct iwx_softc *sc, struc
}
+uint16_t
+iwx_scan_umac_flags_v2(struct iwx_softc *sc, int bgscan)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ uint16_t flags = 0;
+
+ if (ic->ic_des_esslen == 0)
+ flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_FORCE_PASSIVE;
+
+ flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_PASS_ALL;
+ flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_NTFY_ITER_COMPLETE;
+ flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_ADAPTIVE_DWELL;
+
+ return flags;
+}
+
+#define IWX_SCAN_DWELL_ACTIVE 10
+#define IWX_SCAN_DWELL_PASSIVE 110
+
/* adaptive dwell max budget time [TU] for full scan */
#define IWX_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN 300
/* adaptive dwell max budget time [TU] for directed scan */
@@ -5599,8 +5859,145 @@ iwx_get_scan_req_umac_data(struct iwx_softc *sc, struc
#define IWX_SCAN_ADWELL_DEFAULT_LB_N_APS 2
/* adaptive dwell default APs number in social channels (1, 6, 11) */
#define IWX_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL 10
+/* adaptive dwell number of APs override for p2p friendly GO channels */
+#define IWX_SCAN_ADWELL_N_APS_GO_FRIENDLY 10
+/* adaptive dwell number of APs override for social channels */
+#define IWX_SCAN_ADWELL_N_APS_SOCIAL_CHS 2
+void
+iwx_scan_umac_dwell_v10(struct iwx_softc *sc,
+ struct iwx_scan_general_params_v10 *general_params, int bgscan)
+{
+ uint32_t suspend_time, max_out_time;
+ uint8_t active_dwell, passive_dwell;
+
+ active_dwell = IWX_SCAN_DWELL_ACTIVE;
+ passive_dwell = IWX_SCAN_DWELL_PASSIVE;
+
+ general_params->adwell_default_social_chn =
+ IWX_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL;
+ general_params->adwell_default_2g = IWX_SCAN_ADWELL_DEFAULT_LB_N_APS;
+ general_params->adwell_default_5g = IWX_SCAN_ADWELL_DEFAULT_HB_N_APS;
+
+ if (bgscan)
+ general_params->adwell_max_budget =
+ htole16(IWX_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN);
+ else
+ general_params->adwell_max_budget =
+ htole16(IWX_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN);
+
+ general_params->scan_priority = htole32(IWX_SCAN_PRIORITY_EXT_6);
+ if (bgscan) {
+ max_out_time = htole32(120);
+ suspend_time = htole32(120);
+ } else {
+ max_out_time = htole32(0);
+ suspend_time = htole32(0);
+ }
+ general_params->max_out_of_time[IWX_SCAN_LB_LMAC_IDX] =
+ htole32(max_out_time);
+ general_params->suspend_time[IWX_SCAN_LB_LMAC_IDX] =
+ htole32(suspend_time);
+ general_params->max_out_of_time[IWX_SCAN_HB_LMAC_IDX] =
+ htole32(max_out_time);
+ general_params->suspend_time[IWX_SCAN_HB_LMAC_IDX] =
+ htole32(suspend_time);
+
+ general_params->active_dwell[IWX_SCAN_LB_LMAC_IDX] = active_dwell;
+ general_params->passive_dwell[IWX_SCAN_LB_LMAC_IDX] = passive_dwell;
+ general_params->active_dwell[IWX_SCAN_HB_LMAC_IDX] = active_dwell;
+ general_params->passive_dwell[IWX_SCAN_HB_LMAC_IDX] = passive_dwell;
+}
+
+void
+iwx_scan_umac_fill_general_p_v10(struct iwx_softc *sc,
+ struct iwx_scan_general_params_v10 *gp, uint16_t gen_flags, int bgscan)
+{
+ iwx_scan_umac_dwell_v10(sc, gp, bgscan);
+
+ gp->flags = htole16(gen_flags);
+
+ if (gen_flags & IWX_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC1)
+ gp->num_of_fragments[IWX_SCAN_LB_LMAC_IDX] = 3;
+ if (gen_flags & IWX_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC2)
+ gp->num_of_fragments[IWX_SCAN_HB_LMAC_IDX] = 3;
+
+ gp->scan_start_mac_id = 0;
+}
+
+void
+iwx_scan_umac_fill_ch_p_v6(struct iwx_softc *sc,
+ struct iwx_scan_channel_params_v6 *cp, uint32_t channel_cfg_flags,
+ int n_ssid, int bgscan)
+{
+ cp->flags = IWX_SCAN_CHANNEL_FLAG_ENABLE_CHAN_ORDER;
+
+ cp->count = iwx_umac_scan_fill_channels(sc, cp->channel_config,
+ nitems(cp->channel_config), n_ssid, bgscan);
+
+ cp->n_aps_override[0] = IWX_SCAN_ADWELL_N_APS_GO_FRIENDLY;
+ cp->n_aps_override[1] = IWX_SCAN_ADWELL_N_APS_SOCIAL_CHS;
+}
+
int
+iwx_umac_scan_v14(struct iwx_softc *sc, int bgscan)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct iwx_host_cmd hcmd = {
+ .id = iwx_cmd_id(IWX_SCAN_REQ_UMAC, IWX_LONG_GROUP, 0),
+ .len = { 0, },
+ .data = { NULL, },
+ .flags = 0,
+ };
+ struct iwx_scan_req_umac_v14 *cmd;
+ struct iwx_scan_req_params_v14 *scan_p;
+ int err, async = bgscan, n_ssid = 0;
+ uint16_t gen_flags;
+ uint32_t bitmap_ssid = 0;
+
+ cmd = malloc(sizeof(*cmd), M_DEVBUF,
+ (async ? M_NOWAIT : M_WAIT) | M_CANFAIL | M_ZERO);
+ if (cmd == NULL)
+ return ENOMEM;
+
+ scan_p = &cmd->scan_params;
+
+ cmd->ooc_priority = htole32(IWX_SCAN_PRIORITY_EXT_6);
+ cmd->uid = htole32(0);
+
+ gen_flags = iwx_scan_umac_flags_v2(sc, bgscan);
+ iwx_scan_umac_fill_general_p_v10(sc, &scan_p->general_params,
+ gen_flags, bgscan);
+
+ scan_p->periodic_params.schedule[0].interval = htole16(0);
+ scan_p->periodic_params.schedule[0].iter_count = 1;
+
+ err = iwx_fill_probe_req(sc, &scan_p->probe_params.preq);
+ if (err)
+ return err;
+
+ if (ic->ic_des_esslen != 0) {
+ scan_p->probe_params.direct_scan[0].id = IEEE80211_ELEMID_SSID;
+ scan_p->probe_params.direct_scan[0].len = ic->ic_des_esslen;
+ memcpy(scan_p->probe_params.direct_scan[0].ssid,
+ ic->ic_des_essid, ic->ic_des_esslen);
+ bitmap_ssid |= (1 << 0);
+ n_ssid = 1;
+ }
+
+ iwx_scan_umac_fill_ch_p_v6(sc, &scan_p->channel_params, bitmap_ssid,
+ n_ssid, bgscan);
+
+ hcmd.len[0] = sizeof(*cmd);
+ hcmd.data[0] = (void *)cmd;
+ hcmd.flags |= async ? IWX_CMD_ASYNC : 0;
+
+ err = iwx_send_cmd(sc, &hcmd);
+ free(cmd, M_DEVBUF, sizeof(*cmd));
+ return err;
+}
+
+int
iwx_umac_scan(struct iwx_softc *sc, int bgscan)
{
struct ieee80211com *ic = &sc->sc_ic;
@@ -5617,7 +6014,12 @@ iwx_umac_scan(struct iwx_softc *sc, int bgscan)
struct iwx_scan_umac_chan_param *chanparam;
size_t req_len;
int err, async = bgscan;
+ int cmdver;
+ cmdver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, IWX_SCAN_REQ_UMAC);
+ if (cmdver == 14)
+ return iwx_umac_scan_v14(sc, bgscan);
+
req_len = iwx_umac_scan_size(sc);
if ((req_len < IWX_SCAN_REQ_UMAC_SIZE_V1 +
sizeof(struct iwx_scan_req_umac_tail_v1)) ||
@@ -5690,6 +6092,7 @@ iwx_umac_scan(struct iwx_softc *sc, int bgscan)
chanparam = iwx_get_scan_req_umac_chan_param(sc, req);
chanparam->count = iwx_umac_scan_fill_channels(sc,
(struct iwx_scan_channel_cfg_umac *)cmd_data,
+ sc->sc_capa_n_scan_channels,
ic->ic_des_esslen != 0, bgscan);
chanparam->flags = 0;
@@ -6241,19 +6644,31 @@ iwx_scan_abort(struct iwx_softc *sc)
int
iwx_enable_data_tx_queues(struct iwx_softc *sc)
{
- int err, ac;
+ int err, ac, cmdver;
+ /*
+ * ADD_STA command version >= 12 implies that firmware uses
+ * an internal AUX station for scanning. We do not configure
+ * an AUX Tx queue in this case and data queue indices assigned
+ * by firmware shift upwards accordingly.
+ */
+ cmdver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, IWX_ADD_STA);
+ if (cmdver != IWX_FW_CMD_VER_UNKNOWN && cmdver >= 12)
+ sc->first_data_qid = IWX_DQA_CMD_QUEUE + 1;
+ else
+ sc->first_data_qid = IWX_DQA_AUX_QUEUE + 1;
+
for (ac = 0; ac < EDCA_NUM_AC; ac++) {
- int qid = ac + IWX_DQA_AUX_QUEUE + 1;
+ int qid = ac + sc->first_data_qid;
/*
* Regular data frames use the "MGMT" TID and queue.
* Other TIDs and queues are reserved for frame aggregation.
*/
- err = iwx_enable_txq(sc, IWX_STATION_ID, qid, IWX_TID_NON_QOS,
+ err = iwx_enable_txq(sc, IWX_STATION_ID, qid, IWX_MGMT_TID,
IWX_TX_RING_COUNT);
if (err) {
printf("%s: could not enable Tx queue %d (error %d)\n",
- DEVNAME(sc), ac, err);
+ DEVNAME(sc), qid, err);
return err;
}
}
@@ -6302,10 +6717,17 @@ iwx_rs_init(struct iwx_softc *sc, struct iwx_node *in)
struct ieee80211_rateset *rs = &ni->ni_rates;
struct iwx_tlc_config_cmd cfg_cmd;
uint32_t cmd_id;
- int i;
+ int i, cmdver;
+ size_t cmd_size = sizeof(cfg_cmd);
memset(&cfg_cmd, 0, sizeof(cfg_cmd));
+ /* In old versions of the API the struct is 4 bytes smaller */
+ cmdver = iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP,
+ IWX_TLC_MNG_CONFIG_CMD);
+ if (cmdver == IWX_FW_CMD_VER_UNKNOWN || cmdver < 3)
+ cmd_size -= sizeof(uint32_t);
+
for (i = 0; i < rs->rs_nrates; i++) {
uint8_t rval = rs->rs_rates[i] & IEEE80211_RATE_VAL;
int idx = iwx_rs_rval2idx(rval);
@@ -6331,8 +6753,7 @@ iwx_rs_init(struct iwx_softc *sc, struct iwx_node *in)
cfg_cmd.sgi_ch_width_supp = (1 << IWX_TLC_MNG_CH_WIDTH_20MHZ);
cmd_id = iwx_cmd_id(IWX_TLC_MNG_CONFIG_CMD, IWX_DATA_PATH_GROUP, 0);
- return iwx_send_cmd_pdu(sc, cmd_id, IWX_CMD_ASYNC, sizeof(cfg_cmd),
- &cfg_cmd);
+ return iwx_send_cmd_pdu(sc, cmd_id, IWX_CMD_ASYNC, cmd_size, &cfg_cmd);
}
void
@@ -6488,9 +6909,12 @@ iwx_auth(struct iwx_softc *sc)
duration = in->in_ni.ni_intval * 2;
else
duration = IEEE80211_DUR_TU;
- iwx_protect_session(sc, in, duration, in->in_ni.ni_intval / 2);
+ if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_SESSION_PROT_CMD))
+ err = iwx_schedule_session_protection(sc, in, duration);
+ else
+ iwx_protect_session(sc, in, duration, in->in_ni.ni_intval / 2);
- return 0;
+ return err;
rm_sta:
if (generation == sc->sc_generation) {
@@ -8073,6 +8497,19 @@ iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *d
if (!iwx_rx_pkt_valid(pkt))
break;
+ /*
+ * XXX Intel inside (tm)
+ * Any commands in the LONG_GROUP could actually be in the
+ * LEGACY group. Firmware API versions >= 50 reject commands
+ * in group 0, forcing us to use this hack.
+ */
+ if (iwx_cmd_groupid(code) == IWX_LONG_GROUP) {
+ struct iwx_tx_ring *ring = &sc->txq[qid];
+ struct iwx_tx_data *txdata = &ring->data[idx];
+ if (txdata->flags & IWX_TXDATA_FLAG_CMD_IS_NARROW)
+ code = iwx_cmd_opcode(code);
+ }
+
len = sizeof(pkt->len_n_flags) + iwx_rx_packet_len(pkt);
if (len < sizeof(pkt->hdr) ||
len > (IWX_RBUF_SIZE - offset - minsz))
@@ -8124,6 +8561,10 @@ iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *d
break;
}
+ case IWX_BAR_FRAME_RELEASE:
+ iwx_rx_bar_frame_release(sc, pkt, data, ml);
+ break;
+
case IWX_TX_CMD:
iwx_rx_tx_cmd(sc, pkt, data);
break;
@@ -8137,9 +8578,37 @@ iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *d
case IWX_ALIVE: {
struct iwx_alive_resp_v4 *resp4;
+ struct iwx_alive_resp_v5 *resp5;
DPRINTF(("%s: firmware alive\n", __func__));
- if (iwx_rx_packet_payload_len(pkt) == sizeof(*resp4)) {
+ sc->sc_uc.uc_ok = 0;
+
+ /*
+ * For v5 and above, we can check the version, for older
+ * versions we need to check the size.
+ */
+ if (iwx_lookup_notif_ver(sc, IWX_LEGACY_GROUP,
+ IWX_ALIVE) == 5) {
+ SYNC_RESP_STRUCT(resp5, pkt);
+ if (iwx_rx_packet_payload_len(pkt) !=
+ sizeof(*resp5)) {
+ sc->sc_uc.uc_intr = 1;
+ wakeup(&sc->sc_uc);
+ break;
+ }
+ sc->sc_uc.uc_lmac_error_event_table[0] =
le32toh(
+
resp5->lmac_data[0].dbg_ptrs.error_event_table_ptr);
+ sc->sc_uc.uc_lmac_error_event_table[1] =
le32toh(
+
resp5->lmac_data[1].dbg_ptrs.error_event_table_ptr);
+ sc->sc_uc.uc_log_event_table = le32toh(
+
resp5->lmac_data[0].dbg_ptrs.log_event_table_ptr);
+ sc->sched_base = le32toh(
+ resp5->lmac_data[0].dbg_ptrs.scd_base_ptr);
+ sc->sc_uc.uc_umac_error_event_table = le32toh(
+ resp5->umac_data.dbg_ptrs.error_info_addr);
+ if (resp5->status == IWX_ALIVE_STATUS_OK)
+ sc->sc_uc.uc_ok = 1;
+ } else if (iwx_rx_packet_payload_len(pkt) ==
sizeof(*resp4)) {
SYNC_RESP_STRUCT(resp4, pkt);
sc->sc_uc.uc_lmac_error_event_table[0] =
le32toh(
resp4->lmac_data[0].dbg_ptrs.error_event_table_ptr);
@@ -8153,8 +8622,6 @@ iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *d
resp4->umac_data.dbg_ptrs.error_info_addr);
if (resp4->status == IWX_ALIVE_STATUS_OK)
sc->sc_uc.uc_ok = 1;
- else
- sc->sc_uc.uc_ok = 0;
}
sc->sc_uc.uc_intr = 1;
@@ -8189,6 +8656,8 @@ iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *d
break;
}
+ case IWX_WIDE_ID(IWX_MAC_CONF_GROUP,
+ IWX_SESSION_PROTECTION_CMD):
case IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP,
IWX_NVM_GET_INFO):
case IWX_ADD_STA_KEY:
@@ -8288,6 +8757,10 @@ iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *d
break;
}
+ case IWX_WIDE_ID(IWX_MAC_CONF_GROUP,
+ IWX_SESSION_PROTECTION_NOTIF):
+ break;
+
case IWX_WIDE_ID(IWX_SYSTEM_GROUP,
IWX_FSEQ_VER_MISMATCH_NOTIFICATION):
break;
@@ -8844,7 +9317,7 @@ iwx_attach(struct device *parent, struct device *self,
switch (PCI_PRODUCT(pa->pa_id)) {
case PCI_PRODUCT_INTEL_WL_22500_1:
- sc->sc_fwname = "iwx-cc-a0-48";
+ sc->sc_fwname = "iwx-cc-a0-63";
sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
sc->sc_fwdmasegsz = IWX_FWDMASEGSZ_8000;
sc->sc_integrated = 1;
@@ -8862,7 +9335,7 @@ iwx_attach(struct device *parent, struct device *self,
return;
}
- sc->sc_fwname = "iwx-QuZ-a0-hr-b0-48";
+ sc->sc_fwname = "iwx-QuZ-a0-hr-b0-63";
sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
sc->sc_fwdmasegsz = IWX_FWDMASEGSZ_8000;
sc->sc_integrated = 1;
@@ -8873,7 +9346,7 @@ iwx_attach(struct device *parent, struct device *self,
sc->sc_uhb_supported = 0;
break;
case PCI_PRODUCT_INTEL_WL_22500_4:
- sc->sc_fwname = "iwx-Qu-c0-hr-b0-48";
+ sc->sc_fwname = "iwx-Qu-c0-hr-b0-63";
sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
sc->sc_fwdmasegsz = IWX_FWDMASEGSZ_8000;
sc->sc_integrated = 1;
blob - 55422b8d6961837cf9281b56c8671b1aea163b57
blob + d7eda7cb6a3e1a7d8d3b605908a7185a8d8dd245
--- sys/dev/pci/if_iwxreg.h
+++ sys/dev/pci/if_iwxreg.h
@@ -918,11 +918,27 @@ enum msix_ivar_for_cause {
#define IWX_UCODE_TLV_API_NAN2_VER2 31
#define IWX_UCODE_TLV_API_ADAPTIVE_DWELL 32
#define IWX_UCODE_TLV_API_NEW_RX_STATS 35
+#define IWX_UCODE_TLV_API_WOWLAN_KEY_MATERIAL 36
+#define IWX_UCODE_TLV_API_QUOTA_LOW_LATENCY 38
+#define IWX_UCODE_TLV_API_DEPRECATE_TTAK 41
#define IWX_UCODE_TLV_API_ADAPTIVE_DWELL_V2 42
+#define IWX_UCODE_TLV_API_NAN_NOTIF_V2 43
+#define IWX_UCODE_TLV_API_FRAG_EBS 44
+#define IWX_UCODE_TLV_API_REDUCE_TX_POWER 45
+#define IWX_UCODE_TLV_API_SHORT_BEACON_NOTIF 46
#define IWX_UCODE_TLV_API_BEACON_FILTER_V4 47
-#define IWX_UCODE_TLV_API_REGULATORY_NVM_INFO 48
-#define IWX_UCODE_TLV_API_REDUCED_SCAN_CONFIG 56
+#define IWX_UCODE_TLV_API_REGULATORY_NVM_INFO 48
+#define IWX_UCODE_TLV_API_FTM_NEW_RANGE_REQ 49
+#define IWX_UCODE_TLV_API_REDUCED_SCAN_CONFIG 56
+#define IWX_UCODE_TLV_API_SCAN_OFFLOAD_CHANS 50
+#define IWX_UCODE_TLV_API_MBSSID_HE 52
+#define IWX_UCODE_TLV_API_WOWLAN_TCP_SYN_WAKE 53
+#define IWX_UCODE_TLV_API_FTM_RTT_ACCURACY 54
+#define IWX_UCODE_TLV_API_SAR_TABLE_VER 55
+#define IWX_UCODE_TLV_API_REDUCED_SCAN_CONFIG 56
+#define IWX_UCODE_TLV_API_ADWELL_HB_DEF_N_AP 57
#define IWX_UCODE_TLV_API_SCAN_EXT_CHAN_VER 58
+#define IWX_UCODE_TLV_API_BAND_IN_RX_DATA 59
#define IWX_NUM_UCODE_TLV_API 128
#define IWX_UCODE_TLV_API_BITS \
@@ -1013,18 +1029,36 @@ enum msix_ivar_for_cause {
#define IWX_UCODE_TLV_CAPA_GSCAN_SUPPORT 31
#define IWX_UCODE_TLV_CAPA_NAN_SUPPORT 34
#define IWX_UCODE_TLV_CAPA_UMAC_UPLOAD 35
+#define IWM_UCODE_TLV_CAPA_SOC_LATENCY_SUPPORT 37
+#define IWX_UCODE_TLV_CAPA_STA_PM_NOTIF 38
#define IWX_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT 39
#define IWX_UCODE_TLV_CAPA_CDB_SUPPORT 40
-#define IWX_UCODE_TLV_CAPA_TLC_OFFLOAD 43
-#define IWX_UCODE_TLV_CAPA_DYNAMIC_QUOTA 44
+#define IWX_UCODE_TLV_CAPA_D0I3_END_FIRST 41
+#define IWX_UCODE_TLV_CAPA_TLC_OFFLOAD 43
+#define IWX_UCODE_TLV_CAPA_DYNAMIC_QUOTA 44
+#define IWX_UCODE_TLV_CAPA_COEX_SCHEMA_2 45
+#define IWX_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD 46
+#define IWX_UCODE_TLV_CAPA_FTM_CALIBRATED 47
#define IWX_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS 48
+#define IWX_UCODE_TLV_CAPA_CS_MODIFY 49
+#define IWX_UCODE_TLV_CAPA_SET_LTR_GEN2 50
+#define IWX_UCODE_TLV_CAPA_SET_PPAG 52
+#define IWX_UCODE_TLV_CAPA_TAS_CFG 53
+#define IWX_UCODE_TLV_CAPA_SESSION_PROT_CMD 54
+#define IWX_UCODE_TLV_CAPA_PROTECTED_TWT 56
+#define IWX_UCODE_TLV_CAPA_FW_RESET_HANDSHAKE 57
+#define IWX_UCODE_TLV_CAPA_PASSIVE_6GHZ_SCAN 58
+#define IWX_UCODE_TLV_CAPA_PROTECTED_TWT 56
+#define IWX_UCODE_TLV_CAPA_FW_RESET_HANDSHAKE 57
+#define IWX_UCODE_TLV_CAPA_PASSIVE_6GHZ_SCAN 58
#define IWX_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE 64
#define IWX_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS 65
#define IWX_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT 67
#define IWX_UCODE_TLV_CAPA_MULTI_QUEUE_RX_SUPPORT 68
+#define IWX_UCODE_TLV_CAPA_CSA_AND_TBTT_OFFLOAD 70
#define IWX_UCODE_TLV_CAPA_BEACON_ANT_SELECTION 71
#define IWX_UCODE_TLV_CAPA_BEACON_STORING 72
-#define IWX_UCODE_TLV_CAPA_LAR_SUPPORT_V2 73
+#define IWX_UCODE_TLV_CAPA_LAR_SUPPORT_V3 73
#define IWX_UCODE_TLV_CAPA_CT_KILL_BY_FW 74
#define IWX_UCODE_TLV_CAPA_TEMP_THS_REPORT_SUPPORT 75
#define IWX_UCODE_TLV_CAPA_CTDP_SUPPORT 76
@@ -1032,7 +1066,17 @@ enum msix_ivar_for_cause {
#define IWX_UCODE_TLV_CAPA_LMAC_UPLOAD 79
#define IWX_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG 80
#define IWX_UCODE_TLV_CAPA_LQM_SUPPORT 81
+#define IWX_UCODE_TLV_CAPA_TX_POWER_ACK 84
+#define IWX_UCODE_TLV_CAPA_D3_DEBUG 87
#define IWX_UCODE_TLV_CAPA_LED_CMD_SUPPORT 88
+#define IWX_UCODE_TLV_CAPA_MCC_UPDATE_11AX_SUPPORT 89
+#define IWX_UCODE_TLV_CAPA_CSI_REPORTING 90
+#define IWX_UCODE_TLV_CAPA_CSI_REPORTING_V2 91
+#define IWX_UCODE_TLV_CAPA_DBG_SUSPEND_RESUME_CMD_SUPP 92
+#define IWX_UCODE_TLV_CAPA_DBG_BUF_ALLOC_CMD_SUPP 93
+#define IWX_UCODE_TLV_CAPA_MLME_OFFLOAD 96
+#define IWX_UCODE_TLV_CAPA_BIGTK_SUPPORT 100
+#define IWX_UCODE_TLV_CAPA_RFIM_SUPPORT 102
#define IWX_NUM_UCODE_TLV_CAPA 128
@@ -1189,7 +1233,13 @@ struct iwx_ucode_header {
#define IWX_UCODE_TLV_FW_RECOVERY_INFO 57
#define IWX_UCODE_TLV_FW_FMAC_RECOVERY_INFO 59
#define IWX_UCODE_TLV_FW_FSEQ_VERSION 60
+#define IWX_UCODE_TLV_PHY_INTEGRATION_VERSION 61
+#define IWX_UCODE_TLV_PNVM_VERSION 62
+#define IWX_UCODE_TLV_PNVM_SKU 64
+#define IWX_UCODE_TLV_CONST_BASE 0x100
+#define IWX_UCODE_TLV_FW_NUM_STATIONS (IWX_UCODE_TLV_CONST_BASE + 0)
+
#define IWX_UCODE_TLV_DEBUG_BASE 0x1000005
#define IWX_UCODE_TLV_TYPE_DEBUG_INFO (IWX_UCODE_TLV_DEBUG_BASE + 0)
#define IWX_UCODE_TLV_TYPE_BUFFER_ALLOCATION (IWX_UCODE_TLV_DEBUG_BASE + 1)
@@ -1530,6 +1580,8 @@ struct iwx_tx_queue_cfg_rsp {
#define IWX_REPLY_RX_PHY_CMD 0xc0
#define IWX_REPLY_RX_MPDU_CMD 0xc1
+#define IWX_BAR_FRAME_RELEASE 0xc2
+#define IWX_FRAME_RELEASE 0xc3
#define IWX_BA_NOTIF 0xc5
/* Location Aware Regulatory */
@@ -1605,6 +1657,10 @@ struct iwx_tx_queue_cfg_rsp {
#define IWX_INIT_EXTENDED_CFG_CMD 0x03
#define IWX_FW_ERROR_RECOVERY_CMD 0x07
+/* MAC_CONF group subcommand IDs */
+#define IWX_SESSION_PROTECTION_CMD 0x05
+#define IWX_SESSION_PROTECTION_NOTIF 0xfb
+
/* DATA_PATH group subcommand IDs */
#define IWX_DQA_ENABLE_CMD 0x00
#define IWX_TLC_MNG_CONFIG_CMD 0x0f
@@ -1922,6 +1978,19 @@ struct iwx_alive_resp_v4 {
struct iwx_umac_alive umac_data;
} __packed; /* ALIVE_RES_API_S_VER_4 */
+struct iwx_sku_id {
+ uint32_t data[3];
+} __packed; /* SKU_ID_API_S_VER_1 */
+
+struct iwx_alive_resp_v5 {
+ uint16_t status;
+ uint16_t flags;
+ struct iwx_lmac_alive lmac_data[2];
+ struct iwx_umac_alive umac_data;
+ struct iwx_sku_id sku_id;
+} __packed; /* UCODE_ALIVE_NTFY_API_S_VER_5 */
+
+
#define IWX_SOC_CONFIG_CMD_FLAGS_DISCRETE (1 << 0)
#define IWX_SOC_CONFIG_CMD_FLAGS_LOW_LATENCY (1 << 1)
@@ -2722,7 +2791,87 @@ struct iwx_time_event_notif {
uint32_t status;
} __packed; /* IWX_MAC_TIME_EVENT_NTFY_API_S_VER_1 */
+/**
+ * enum iwx_session_prot_conf_id - session protection's configurations
+ * @SESSION_PROTECT_CONF_ASSOC: Start a session protection for association.
+ * The firmware will allocate two events.
+ * Valid for BSS_STA and P2P_STA.
+ * * A rather short event that can't be fragmented and with a very
+ * high priority. If every goes well (99% of the cases) the
+ * association should complete within this first event. During
+ * that event, no other activity will happen in the firmware,
+ * which is why it can't be too long.
+ * The length of this event is hard-coded in the firmware: 300TUs.
+ * * Another event which can be much longer (it's duration is
+ * configurable by the driver) which has a slightly lower
+ * priority and that can be fragmented allowing other activities
+ * to run while this event is running.
+ * The firmware will automatically remove both events once the driver sets
+ * the BSS MAC as associated. Neither of the events will be removed
+ * for the P2P_STA MAC.
+ * Only the duration is configurable for this protection.
+ * @SESSION_PROTECT_CONF_GO_CLIENT_ASSOC: not used
+ * @SESSION_PROTECT_CONF_P2P_DEVICE_DISCOV: Schedule the P2P Device to be in
+ * listen mode. Will be fragmented. Valid only on the P2P Device MAC.
+ * Valid only on the P2P Device MAC. The firmware will take into account
+ * the duration, the interval and the repetition count.
+ * @SESSION_PROTECT_CONF_P2P_GO_NEGOTIATION: Schedule the P2P Device to be be
+ * able to run the GO Negotiation. Will not be fragmented and not
+ * repetitive. Valid only on the P2P Device MAC. Only the duration will
+ * be taken into account.
+ * @SESSION_PROTECT_CONF_MAX_ID: not used
+ */
+enum iwx_session_prot_conf_id {
+ IWX_SESSION_PROTECT_CONF_ASSOC,
+ IWX_SESSION_PROTECT_CONF_GO_CLIENT_ASSOC,
+ IWX_SESSION_PROTECT_CONF_P2P_DEVICE_DISCOV,
+ IWX_SESSION_PROTECT_CONF_P2P_GO_NEGOTIATION,
+ IWX_SESSION_PROTECT_CONF_MAX_ID,
+}; /* SESSION_PROTECTION_CONF_ID_E_VER_1 */
+/**
+ * struct iwx_session_prot_cmd - configure a session protection
+ * @id_and_color: the id and color of the mac for which this session protection
+ * is sent
+ * @action: can be either FW_CTXT_ACTION_ADD or FW_CTXT_ACTION_REMOVE
+ * @conf_id: see &enum iwx_mvm_session_prot_conf_id
+ * @duration_tu: the duration of the whole protection in TUs.
+ * @repetition_count: not used
+ * @interval: not used
+ *
+ * Note: the session protection will always be scheduled to start as
+ * early as possible, but the maximum delay is configuration dependent.
+ * The firmware supports only one concurrent session protection per vif.
+ * Adding a new session protection will remove any currently running session.
+ */
+struct iwx_session_prot_cmd {
+ /* COMMON_INDEX_HDR_API_S_VER_1 hdr */
+ uint32_t id_and_color;
+ uint32_t action;
+ uint32_t conf_id;
+ uint32_t duration_tu;
+ uint32_t repetition_count;
+ uint32_t interval;
+} __packed; /* SESSION_PROTECTION_CMD_API_S_VER_1 */
+
+/**
+ * struct iwx_session_prot_notif - session protection started / ended
+ * @mac_id: the mac id for which the session protection started / ended
+ * @status: 1 means success, 0 means failure
+ * @start: 1 means the session protection started, 0 means it ended
+ * @conf_id: see &enum iwx_mvm_session_prot_conf_id
+ *
+ * Note that any session protection will always get two notifications: start
+ * and end even the firmware could not schedule it.
+ */
+struct iwx_session_prot_notif {
+ uint32_t mac_id;
+ uint32_t status;
+ uint32_t start;
+ uint32_t conf_id;
+} __packed; /* SESSION_PROTECTION_NOTIFICATION_API_S_VER_2 */
+
+
/* Bindings and Time Quota */
/**
@@ -2861,6 +3010,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
@@ -2884,7 +3067,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;
@@ -2898,7 +3081,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;
@@ -3136,7 +3319,44 @@ struct iwx_rx_mpdu_desc {
struct iwx_rx_mpdu_desc_v1 v1;
} __packed;
+struct iwx_frame_release {
+ uint8_t baid;
+ uint8_t reserved;
+ uint16_t nssn;
+};
+
/**
+ * enum iwx_bar_frame_release_sta_tid - STA/TID information for BAR release
+ * @IWX_BAR_FRAME_RELEASE_TID_MASK: TID mask
+ * @IWX_BAR_FRAME_RELEASE_STA_MASK: STA mask
+ */
+#define IWX_BAR_FRAME_RELEASE_TID_MASK 0x0000000f
+#define IWX_BAR_FRAME_RELEASE_STA_MASK 0x000001f0
+#define IWX_BAR_FRAME_RELEASE_STA_SHIFT 4
+
+/**
+ * enum iwx_bar_frame_release_ba_info - BA information for BAR release
+ * @IWL_BAR_FRAME_RELEASE_NSSN_MASK: NSSN mask
+ * @IWL_BAR_FRAME_RELEASE_SN_MASK: SN mask (ignored by driver)
+ * @IWL_BAR_FRAME_RELEASE_BAID_MASK: BAID mask
+ */
+#define IWX_BAR_FRAME_RELEASE_NSSN_MASK 0x00000fff
+#define IWX_BAR_FRAME_RELEASE_SN_MASK 0x00fff000
+#define IWX_BAR_FRAME_RELEASE_SN_SHIFT 12
+#define IWX_BAR_FRAME_RELEASE_BAID_MASK 0x3f000000
+#define IWX_BAR_FRAME_RELEASE_BAID_SHIFT 24
+
+/**
+ * struct iwx_bar_frame_release - frame release from BAR info
+ * @sta_tid: STA & TID information, see &enum iwx_bar_frame_release_sta_tid.
+ * @ba_info: BA information, see &enum iwx_bar_frame_release_ba_info.
+ */
+struct iwx_bar_frame_release {
+ uint32_t sta_tid;
+ uint32_t ba_info;
+} __packed; /* RX_BAR_TO_FRAME_RELEASE_API_S_VER_1 */
+
+/**
* struct iwx_radio_version_notif - information on the radio version
* ( IWX_RADIO_VERSION_NOTIFICATION = 0x68 )
* @radio_flavor:
@@ -4574,6 +4794,8 @@ enum iwx_tlc_mng_ht_rates {
* @sgi_ch_width_supp: bitmap of SGI support per channel width
* use (1 << @enum iwx_tlc_mng_cfg_cw)
* @reserved2: reserved
+ * @max_tx_op: max TXOP in uSecs for all AC (BK, BE, VO, VI),
+ * set zero for no limit.
*/
struct iwx_tlc_config_cmd {
uint8_t sta_id;
@@ -4587,8 +4809,9 @@ struct iwx_tlc_config_cmd {
uint16_t ht_rates[IWX_TLC_NSS_MAX][2];
uint16_t max_mpdu_len;
uint8_t sgi_ch_width_supp;
- uint8_t reserved2[1];
-} __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_2 */
+ uint8_t reserved2;
+ uint32_t max_tx_op;
+} __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_3 */
/**
* @IWX_TLC_NOTIF_FLAG_RATE: last initial rate update
@@ -5315,6 +5538,10 @@ struct iwx_scan_probe_req {
#define IWX_SCAN_CHANNEL_FLAG_EBS (1 << 0)
#define IWX_SCAN_CHANNEL_FLAG_EBS_ACCURATE (1 << 1)
#define IWX_SCAN_CHANNEL_FLAG_CACHE_ADD (1 << 2)
+#define IWX_SCAN_CHANNEL_FLAG_EBS_FRAG (1 << 3)
+#define IWX_SCAN_CHANNEL_FLAG_FORCE_EBS (1 << 4)
+#define IWX_SCAN_CHANNEL_FLAG_ENABLE_CHAN_ORDER (1 << 5)
+#define IWX_SCAN_CHANNEL_FLAG_6G_PSC_NO_FILTER (1 << 6)
/* iwx_scan_channel_opt - CHANNEL_OPTIMIZATION_API_S
* @flags: enum iwx_scan_channel_flags
@@ -5332,6 +5559,17 @@ struct iwx_scan_channel_opt {
#define IWX_SCAN_PRIORITY_MEDIUM 1
#define IWX_SCAN_PRIORITY_HIGH 2
+enum iwx_scan_priority_ext {
+ IWX_SCAN_PRIORITY_EXT_0_LOWEST,
+ IWX_SCAN_PRIORITY_EXT_1,
+ IWX_SCAN_PRIORITY_EXT_2,
+ IWX_SCAN_PRIORITY_EXT_3,
+ IWX_SCAN_PRIORITY_EXT_4,
+ IWX_SCAN_PRIORITY_EXT_5,
+ IWX_SCAN_PRIORITY_EXT_6,
+ IWX_SCAN_PRIORITY_EXT_7_HIGHEST,
+};
+
/**
* iwx_scan_offload_complete - PERIODIC_SCAN_COMPLETE_NTF_API_S_VER_2
* @last_schedule_line: last schedule line executed (fast or regular)
@@ -5501,7 +5739,26 @@ struct iwx_scan_dwell {
#define IWX_SCAN_HB_LMAC_IDX 1 /* high-band */
/**
- * struct iwx_scan_config
+ * struct iwl_scan_config
+ * @enable_cam_mode: whether to enable CAM mode.
+ * @enable_promiscouos_mode: whether to enable promiscouos mode
+ * @bcast_sta_id: the index of the station in the fw. Deprecated starting with
+ * API version 5.
+ * @reserved: reserved
+ * @tx_chains: valid_tx antenna - ANT_* definitions
+ * @rx_chains: valid_rx antenna - ANT_* definitions
+ */
+struct iwx_scan_config {
+ uint8_t enable_cam_mode;
+ uint8_t enable_promiscouos_mode;
+ uint8_t bcast_sta_id;
+ uint8_t reserved;
+ uint32_t tx_chains;
+ uint32_t rx_chains;
+} __packed; /* SCAN_CONFIG_DB_CMD_API_S_5 */
+
+/**
+ * struct iwx_scan_config_v2
* @flags: enum scan_config_flags
* @tx_chains: valid_tx antenna - ANT_* definitions
* @rx_chains: valid_rx antenna - ANT_* definitions
@@ -5518,7 +5775,7 @@ struct iwx_scan_dwell {
* scan_config_channel_flag
* @channel_array: default supported channels
*/
-struct iwx_scan_config {
+struct iwx_scan_config_v2 {
uint32_t flags;
uint32_t tx_chains;
uint32_t rx_chains;
@@ -5819,6 +6076,125 @@ struct iwx_scan_req_umac {
#define IWX_SCAN_REQ_UMAC_SIZE_V1 36
/**
+ * struct iwx_scan_general_params_v10
+ * @flags: &enum iwx_umac_scan_flags
+ * @reserved: reserved for future
+ * @scan_start_mac_id: report the scan start TSF time according to this mac TSF
+ * @active_dwell: dwell time for active scan per LMAC
+ * @adwell_default_2g: adaptive dwell default number of APs
+ * for 2.4GHz channel
+ * @adwell_default_5g: adaptive dwell default number of APs
+ * for 5GHz channels
+ * @adwell_default_social_chn: adaptive dwell default number of
+ * APs per social channel
+ * @reserved1: reserved for future
+ * @adwell_max_budget: the maximal number of TUs that adaptive dwell
+ * can add to the total scan time
+ * @max_out_of_time: max out of serving channel time, per LMAC
+ * @suspend_time: max suspend time, per LMAC
+ * @scan_priority: priority of the request
+ * @passive_dwell: continues dwell time for passive channel
+ * (without adaptive dwell)
+ * @num_of_fragments: number of fragments needed for full fragmented
+ * scan coverage.
+ */
+struct iwx_scan_general_params_v10 {
+ uint16_t flags;
+ uint8_t reserved;
+ uint8_t scan_start_mac_id;
+ uint8_t active_dwell[IWX_SCAN_TWO_LMACS];
+ uint8_t adwell_default_2g;
+ uint8_t adwell_default_5g;
+ uint8_t adwell_default_social_chn;
+ uint8_t reserved1;
+ uint16_t adwell_max_budget;
+ uint32_t max_out_of_time[IWX_SCAN_TWO_LMACS];
+ uint32_t suspend_time[IWX_SCAN_TWO_LMACS];
+ uint32_t scan_priority;
+ uint8_t passive_dwell[IWX_SCAN_TWO_LMACS];
+ uint8_t num_of_fragments[IWX_SCAN_TWO_LMACS];
+} __packed; /* SCAN_GENERAL_PARAMS_API_S_VER_10 */
+
+/**
+ * struct iwx_scan_channel_params_v6
+ * @flags: channel flags &enum iwl_scan_channel_flags
+ * @count: num of channels in scan request
+ * @n_aps_override: override the number of APs the FW uses to calculate dwell
+ * time when adaptive dwell is used.
+ * Channel k will use n_aps_override[i] when BIT(20 + i) is set in
+ * channel_config[k].flags
+ * @channel_config: array of explicit channel configurations
+ * for 2.4Ghz and 5.2Ghz bands
+ */
+struct iwx_scan_channel_params_v6 {
+ uint8_t flags;
+ uint8_t count;
+ uint8_t n_aps_override[2];
+ struct iwx_scan_channel_cfg_umac channel_config[67];
+} __packed; /* SCAN_CHANNEL_PARAMS_API_S_VER_6 */
+
+/**
+ * struct iwx_scan_periodic_parms_v1
+ * @schedule: can scheduling parameter
+ * @delay: initial delay of the periodic scan in seconds
+ * @reserved: reserved for future
+ */
+struct iwx_scan_periodic_parms_v1 {
+ struct iwx_scan_umac_schedule schedule[IWX_MAX_SCHED_SCAN_PLANS];
+ uint16_t delay;
+ uint16_t reserved;
+} __packed; /* SCAN_PERIODIC_PARAMS_API_S_VER_1 */
+
+#define IWX_SCAN_SHORT_SSID_MAX_SIZE 8
+#define IWX_SCAN_BSSID_MAX_SIZE 16
+
+/**
+ * struct iwx_scan_probe_params_v4
+ * @preq: scan probe request params
+ * @short_ssid_num: number of valid short SSIDs in short ssid array
+ * @bssid_num: number of valid bssid in bssids array
+ * @reserved: reserved
+ * @direct_scan: list of ssids
+ * @short_ssid: array of short ssids
+ * @bssid_array: array of bssids
+ */
+struct iwx_scan_probe_params_v4 {
+ struct iwx_scan_probe_req preq;
+ uint8_t short_ssid_num;
+ uint8_t bssid_num;
+ uint16_t reserved;
+ struct iwx_ssid_ie direct_scan[IWX_PROBE_OPTION_MAX];
+ uint32_t short_ssid[IWX_SCAN_SHORT_SSID_MAX_SIZE];
+ uint8_t bssid_array[IWX_SCAN_BSSID_MAX_SIZE][ETHER_ADDR_LEN];
+} __packed; /* SCAN_PROBE_PARAMS_API_S_VER_4 */
+
+/**
+ * struct iwx_scan_req_params_v14
+ * @general_params: &struct iwx_scan_general_params_v10
+ * @channel_params: &struct iwx_scan_channel_params_v6
+ * @periodic_params: &struct iwx_scan_periodic_parms_v1
+ * @probe_params: &struct iwx_scan_probe_params_v4
+ */
+struct iwx_scan_req_params_v14 {
+ struct iwx_scan_general_params_v10 general_params;
+ struct iwx_scan_channel_params_v6 channel_params;
+ struct iwx_scan_periodic_parms_v1 periodic_params;
+ struct iwx_scan_probe_params_v4 probe_params;
+} __packed; /* SCAN_REQUEST_PARAMS_API_S_VER_14 */
+
+/**
+ * struct iwx_scan_req_umac_v14
+ * @uid: scan id, &enum iwl_umac_scan_uid_offsets
+ * @ooc_priority: out of channel priority - &enum iwx_scan_priority
+ * @scan_params: scan parameters
+ */
+struct iwx_scan_req_umac_v14 {
+ uint32_t uid;
+ uint32_t ooc_priority;
+ struct iwx_scan_req_params_v14 scan_params;
+} __packed; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_14 */
+
+/**
* struct iwx_umac_scan_abort
* @uid: scan id, &enum iwx_umac_scan_uid_offsets
* @flags: reserved
@@ -6533,7 +6909,7 @@ struct iwx_cmd_header_wide {
#define IWX_POWER_SCHEME_LP 3
#define IWX_DEF_CMD_PAYLOAD_SIZE 320
-#define IWX_MAX_CMD_PAYLOAD_SIZE ((4096 - 4) - sizeof(struct iwx_cmd_header))
+#define IWX_MAX_CMD_PAYLOAD_SIZE (4096 - sizeof(struct iwx_cmd_header_wide))
#define IWX_CMD_FAILED_MSK 0x40
/**
blob - 928b4d9ec79fed1937e4e147b905cf0da7c36750
blob + 4d297250743b79e9f6bd250041b7ff3b51f43cea
--- sys/dev/pci/if_iwxvar.h
+++ sys/dev/pci/if_iwxvar.h
@@ -123,7 +123,7 @@ struct iwx_tx_radiotap_header {
(1 << IEEE80211_RADIOTAP_RATE) | \
(1 << IEEE80211_RADIOTAP_CHANNEL))
-#define IWX_UCODE_SECT_MAX 42
+#define IWX_UCODE_SECT_MAX 47
#define IWX_FWDMASEGSZ (192*1024)
#define IWX_FWDMASEGSZ_8000 (320*1024)
/* sanity check value */
@@ -236,6 +236,8 @@ struct iwx_tx_data {
bus_addr_t cmd_paddr;
struct mbuf *m;
struct iwx_node *in;
+ int flags;
+#define IWX_TXDATA_FLAG_CMD_IS_NARROW 0x01
};
struct iwx_tx_ring {
@@ -501,6 +503,7 @@ struct iwx_softc {
struct iwx_tx_ring txq[IWX_MAX_QUEUES];
struct iwx_rx_ring rxq;
int qfullmsk;
+ int first_data_qid;
int sc_sf_state;
@@ -536,7 +539,7 @@ struct iwx_softc {
int sc_capa_n_scan_channels;
uint8_t sc_ucode_api[howmany(IWX_NUM_UCODE_TLV_API, NBBY)];
uint8_t sc_enabled_capa[howmany(IWX_NUM_UCODE_TLV_CAPA, NBBY)];
-#define IWX_MAX_FW_CMD_VERSIONS 64
+#define IWX_MAX_FW_CMD_VERSIONS 167
struct iwx_fw_cmd_version cmd_versions[IWX_MAX_FW_CMD_VERSIONS];
int n_cmd_versions;