From 6533df4fe4bcbf5d537b000a200e071476f4476b Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Mon, 15 Jan 2024 14:12:49 -0500 Subject: [PATCH] iaxwifi200 & idualwifi7260: Synchronize with OpenBSD. --- .../network/wlan/iaxwifi200/dev/pci/if_iwx.c | 53 ++++++------------- .../wlan/iaxwifi200/dev/pci/if_iwxreg.h | 3 +- .../wlan/idualwifi7260/dev/pci/if_iwm.c | 36 ++++++++++--- 3 files changed, 47 insertions(+), 45 deletions(-) diff --git a/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/dev/pci/if_iwx.c b/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/dev/pci/if_iwx.c index dd00226952..6ceda4c782 100644 --- a/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/dev/pci/if_iwx.c +++ b/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/dev/pci/if_iwx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwx.c,v 1.176 2023/08/26 09:05:34 stsp Exp $ */ +/* $OpenBSD: if_iwx.c,v 1.180 2023/12/30 16:55:44 stsp Exp $ */ /* * Copyright (c) 2014, 2016 genua gmbh @@ -411,7 +411,6 @@ void iwx_tx_update_byte_tbl(struct iwx_softc *, struct iwx_tx_ring *, int, uint16_t, uint16_t); int iwx_tx(struct iwx_softc *, struct mbuf *, struct ieee80211_node *); int iwx_flush_sta_tids(struct iwx_softc *, int, uint16_t); -int iwx_wait_tx_queues_empty(struct iwx_softc *); int iwx_drain_sta(struct iwx_softc *sc, struct iwx_node *, int); int iwx_flush_sta(struct iwx_softc *, struct iwx_node *); int iwx_beacon_filter_send_cmd(struct iwx_softc *, @@ -6408,10 +6407,7 @@ iwx_flush_sta_tids(struct iwx_softc *sc, int sta_id, uint16_t tids) } resp_len = iwx_rx_packet_payload_len(pkt); - /* Some firmware versions don't provide a response. */ - if (resp_len == 0) - goto out; - else if (resp_len != sizeof(*resp)) { + if (resp_len != sizeof(*resp)) { err = EIO; goto out; } @@ -6452,28 +6448,6 @@ out: #define IWX_FLUSH_WAIT_MS 2000 -int -iwx_wait_tx_queues_empty(struct iwx_softc *sc) -{ - int i, err; - - for (i = 0; i < nitems(sc->txq); i++) { - struct iwx_tx_ring *ring = &sc->txq[i]; - - if (i == IWX_DQA_CMD_QUEUE) - continue; - - while (ring->queued > 0) { - err = tsleep_nsec(ring, 0, "iwxflush", - MSEC_TO_NSEC(IWX_FLUSH_WAIT_MS)); - if (err) - return err; - } - } - - return 0; -} - int iwx_drain_sta(struct iwx_softc *sc, struct iwx_node* in, int drain) { @@ -6531,13 +6505,6 @@ iwx_flush_sta(struct iwx_softc *sc, struct iwx_node *in) goto done; } - err = iwx_wait_tx_queues_empty(sc); - if (err) { - printf("%s: Could not empty Tx queues (error %d)\n", - DEVNAME(sc), err); - goto done; - } - err = iwx_drain_sta(sc, in, 0); done: sc->sc_flags &= ~IWX_FLAG_TXFLUSH; @@ -6998,6 +6965,7 @@ iwx_fill_probe_req(struct iwx_softc *sc, struct iwx_scan_probe_req *preq) return ENOBUFS; frm = ieee80211_add_vhtcaps(frm, ic); remain -= frm - pos; + preq->band_data[1].len = htole16(frm - pos); } } @@ -10148,6 +10116,16 @@ iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *data, struct mbuf_list *ml) case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_RLC_CONFIG_CMD): break; + /* + * Ignore for now. The Linux driver only acts on this request + * with 160Mhz channels in 11ax mode. + */ + case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, + IWX_THERMAL_DUAL_CHAIN_REQUEST): + DPRINTF(("%s: thermal dual-chain request received\n", + DEVNAME(sc))); + break; + /* undocumented notification from iwx-ty-a0-gf-a0-77 image */ case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, 0xf8): break; @@ -10775,7 +10753,7 @@ static const struct iwx_dev_info iwx_dev_info_table[] = { _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY, - IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, + IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, iwx_cfg_so_a0_hr_b0), /* ax101 */ _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, @@ -10792,7 +10770,7 @@ static const struct iwx_dev_info iwx_dev_info_table[] = { _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY, - IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, + IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, iwx_cfg_so_a0_hr_b0), /* AX101 */ _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, @@ -11431,6 +11409,7 @@ iwx_attach(struct device *parent, struct device *self, void *aux) /* Override 802.11 state transition machine. */ sc->sc_newstate = ic->ic_newstate; ic->ic_newstate = iwx_newstate; + ic->ic_updatechan = iwx_updatechan; ic->ic_updateprot = iwx_updateprot; ic->ic_updateslot = iwx_updateslot; ic->ic_updateedca = iwx_updateedca; diff --git a/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/dev/pci/if_iwxreg.h b/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/dev/pci/if_iwxreg.h index 083ffb9e2f..8713b11a6e 100644 --- a/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/dev/pci/if_iwxreg.h +++ b/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/dev/pci/if_iwxreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwxreg.h,v 1.51 2023/03/06 11:18:37 stsp Exp $ */ +/* $OpenBSD: if_iwxreg.h,v 1.52 2023/10/06 15:15:41 stsp Exp $ */ /*- * Based on BSD-licensed source modules in the Linux iwlwifi driver, @@ -2010,6 +2010,7 @@ struct iwx_tx_queue_cfg_rsp { #define IWX_RX_BAID_ALLOCATION_CONFIG_CMD 0x16 #define IWX_SCD_QUEUE_CONFIG_CMD 0x17 #define IWX_RX_NO_DATA_NOTIF 0xf5 +#define IWX_THERMAL_DUAL_CHAIN_REQUEST 0xf6 #define IWX_TLC_MNG_UPDATE_NOTIF 0xf7 /* REGULATORY_AND_NVM group subcommand IDs */ diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/pci/if_iwm.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/pci/if_iwm.c index c59fac975f..42e27d84d6 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/pci/if_iwm.c +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/pci/if_iwm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwm.c,v 1.407 2023/04/14 12:45:10 stsp Exp $ */ +/* $OpenBSD: if_iwm.c,v 1.413 2023/12/20 07:32:05 stsp Exp $ */ /* * Copyright (c) 2014, 2016 genua gmbh @@ -6174,7 +6174,7 @@ uint8_t iwm_get_vht_ctrl_pos(struct ieee80211com *ic, struct ieee80211_channel *chan) { int center_idx = ic->ic_bss->ni_vht_chan_center_freq_idx0; - int primary_idx = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan); + int primary_idx = ic->ic_bss->ni_primary_chan; /* * The FW is expected to check the control channel position only * when in HT/VHT and the channel width is not 20MHz. Return @@ -6754,7 +6754,12 @@ iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac) * client mode; the firmware's station table contains only one entry * which represents our access point. */ - if (isset(sc->sc_enabled_capa, IWM_UCODE_TLV_CAPA_DQA_SUPPORT)) + if (ic->ic_opmode == IEEE80211_M_MONITOR) { + if (isset(sc->sc_enabled_capa, IWM_UCODE_TLV_CAPA_DQA_SUPPORT)) + qid = IWM_DQA_INJECT_MONITOR_QUEUE; + else + qid = IWM_AUX_QUEUE; + } else if (isset(sc->sc_enabled_capa, IWM_UCODE_TLV_CAPA_DQA_SUPPORT)) qid = IWM_DQA_MIN_MGMT_QUEUE + ac; else qid = ac; @@ -6826,7 +6831,8 @@ iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac) #endif totlen = m->m_pkthdr.len; - if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { + if (ic->ic_opmode != IEEE80211_M_MONITOR && + (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)) { k = ieee80211_get_txkey(ic, wh, ni); if ((k->k_flags & IEEE80211_KEY_GROUP) || (k->k_cipher != IEEE80211_CIPHER_CCMP)) { @@ -6853,7 +6859,10 @@ iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac) (ic->ic_flags & IEEE80211_F_USEPROT))) flags |= IWM_TX_CMD_FLG_PROT_REQUIRE; - tx->sta_id = IWM_STATION_ID; + if (ic->ic_opmode == IEEE80211_M_MONITOR) + tx->sta_id = IWM_MONITOR_STA_ID; + else + tx->sta_id = IWM_STATION_ID; if (type == IEEE80211_FC0_TYPE_MGT) { if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ || @@ -7715,6 +7724,7 @@ iwm_fill_probe_req(struct iwm_softc *sc, struct iwm_scan_probe_req *preq) return ENOBUFS; frm = ieee80211_add_vhtcaps(frm, ic); remain -= frm - pos; + preq->band_data[1].len = htole16(frm - pos); } } @@ -8594,7 +8604,7 @@ iwm_bgscan_done(struct ieee80211com *ic, free(sc->bgscan_unref_arg, M_DEVBUF, sc->bgscan_unref_arg_size); sc->bgscan_unref_arg = arg; sc->bgscan_unref_arg_size = arg_size; - iwm_add_task(sc, sc->sc_nswq, &sc->bgscan_done_task); + iwm_add_task(sc, systq, &sc->bgscan_done_task); } void @@ -9217,6 +9227,9 @@ iwm_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni, return; } + if ((sc->sc_flags & IWM_FLAG_STA_ACTIVE) == 0) + return; + if (!isset(sc->sc_ucode_api, IWM_UCODE_TLV_API_TKIP_MIC_KEYS)) return iwm_delete_key_v1(ic, ni, k); @@ -9302,8 +9315,17 @@ iwm_set_rate_table_vht(struct iwm_node *in, struct iwm_lq_cmd *lqcmd) if (i < 2 && in->in_phyctxt->vht_chan_width >= IEEE80211_VHTOP0_CHAN_WIDTH_80) tab |= IWM_RATE_MCS_CHAN_WIDTH_80; - else + else if (in->in_phyctxt->sco == + IEEE80211_HTOP0_SCO_SCA || + in->in_phyctxt->sco == + IEEE80211_HTOP0_SCO_SCB) tab |= IWM_RATE_MCS_CHAN_WIDTH_40; + else { + /* no 40 MHz, fall back on MCS 8 */ + tab &= ~IWM_RATE_VHT_MCS_RATE_CODE_MSK; + tab |= 8; + } + tab |= IWM_RATE_MCS_RTS_REQUIRED_MSK; if (i < 4) { if (ieee80211_ra_vht_use_sgi(ni))