From: Peter Hessler Subject: Re: iwx: support MCC update response version 4 To: tech@openbsd.org Date: Mon, 2 Mar 2026 22:23:47 +0100 WORKSFORME, OK On 2026 Mar 02 (Mon) at 14:59:32 +0100 (+0100), Stefan Sperling wrote: :Add support for MCC update response version 4. :We receive this version on firmware for BZ devices. : :This notification provides an updated list of channels the firmware :consideres valid. And it tells us which country code firmware has :detected during scans. : :As with earlier versions of this command, we do update the channel map :but we don't do anything with the country code. We always run firmware :in the "world" regulatory domain. : :ok? : :M sys/dev/pci/if_iwx.c | 55+ 16- :M sys/dev/pci/if_iwxreg.h | 28+ 0- : :2 files changed, 83 insertions(+), 16 deletions(-) : :commit - 113cb9a5d6155149dad7584530c6b03a26fa6b67 :commit + 1c2d536d6cc6469071ec899f540dc8c94a45e0c3 :blob - 0c5699264df1312403e63d66e1f41a25b4837ca8 :blob + d51929b47f482a5fcae2c9c97d06ed79c2817f67 :--- sys/dev/pci/if_iwx.c :+++ sys/dev/pci/if_iwx.c :@@ -9731,10 +9731,17 @@ iwx_send_update_mcc_cmd(struct iwx_softc *sc, const ch : .data = { &mcc_cmd }, : }; : struct iwx_rx_packet *pkt; :- struct iwx_mcc_update_resp *resp; : size_t resp_len; :- int err; :+ int err, resp_version; : :+ resp_version = iwx_lookup_notif_ver(sc, IWX_LONG_GROUP, :+ IWX_MCC_UPDATE_CMD); :+ if (resp_version >= 8) { :+ printf("%s: unsupported MCC update command response " :+ "version %u\n", DEVNAME(sc), resp_version); :+ return ENOTSUP; :+ } :+ : memset(&mcc_cmd, 0, sizeof(mcc_cmd)); : mcc_cmd.mcc = htole16(alpha2[0] << 8 | alpha2[1]); : if (isset(sc->sc_ucode_api, IWX_UCODE_TLV_API_WIFI_MCC_UPDATE) || :@@ -9757,24 +9764,56 @@ iwx_send_update_mcc_cmd(struct iwx_softc *sc, const ch : } : : resp_len = iwx_rx_packet_payload_len(pkt); :- if (resp_len < sizeof(*resp)) { :- err = EIO; :- goto out; :- } : :- resp = (void *)pkt->data; :- if (resp_len != sizeof(*resp) + :- resp->n_channels * sizeof(resp->channels[0])) { :- err = EIO; :- goto out; :- } : :- DPRINTF(("MCC status=0x%x mcc=0x%x cap=0x%x time=0x%x geo_info=0x%x source_id=0x%d n_channels=%u\n", :- resp->status, resp->mcc, resp->cap, resp->time, resp->geo_info, resp->source_id, resp->n_channels)); :+ if (isset(sc->sc_enabled_capa, :+ IWX_UCODE_TLV_CAPA_MCC_UPDATE_11AX_SUPPORT)) { :+ struct iwx_mcc_update_resp_v4 *resp; : :- /* Update channel map for net80211 and our scan configuration. */ :- iwx_init_channel_map(sc, NULL, resp->channels, resp->n_channels); :+ if (resp_len < sizeof(*resp)) { :+ err = EIO; :+ goto out; :+ } : :+ resp = (void *)pkt->data; :+ if (resp_len != sizeof(*resp) + :+ resp->n_channels * sizeof(resp->channels[0])) { :+ err = EIO; :+ goto out; :+ } :+ :+ DPRINTF(("MCC status=0x%x mcc=0x%x cap=0x%x time=0x%x " :+ "geo_info=0x%x source_id=0x%d n_channels=%u\n", :+ resp->status, resp->mcc, resp->cap, resp->time, :+ resp->geo_info, resp->source_id, resp->n_channels)); :+ :+ /* Update channel map and our scan configuration. */ :+ iwx_init_channel_map(sc, NULL, resp->channels, :+ resp->n_channels); :+ } else { :+ struct iwx_mcc_update_resp *resp; :+ :+ if (resp_len < sizeof(*resp)) { :+ err = EIO; :+ goto out; :+ } :+ resp = (void *)pkt->data; :+ if (resp_len != sizeof(*resp) + :+ resp->n_channels * sizeof(resp->channels[0])) { :+ err = EIO; :+ goto out; :+ } :+ :+ DPRINTF(("MCC status=0x%x mcc=0x%x cap=0x%x time=0x%x " :+ "geo_info=0x%x source_id=0x%d n_channels=%u\n", :+ resp->status, resp->mcc, resp->cap, resp->time, :+ resp->geo_info, resp->source_id, resp->n_channels)); :+ :+ /* Update channel map and our scan configuration. */ :+ iwx_init_channel_map(sc, NULL, resp->channels, :+ resp->n_channels); :+ } :+ : out: : iwx_free_resp(sc, &hcmd); : :blob - fb40a1894862858f4e5baae506e0cae732e4cce7 :blob + d80e0fdff2017b0aac4512d5367ed3ee8eb93e29 :--- sys/dev/pci/if_iwxreg.h :+++ sys/dev/pci/if_iwxreg.h :@@ -8516,6 +8516,34 @@ struct iwx_mcc_update_resp_v3 { : } __packed; /* LAR_UPDATE_MCC_CMD_RESP_S_VER_3 */ : : /** :+ * struct iwx_mcc_update_resp_v4 - response to MCC_UPDATE_CMD. :+ * Contains the new channel control profile map, if changed, and the new MCC :+ * (mobile country code). :+ * The new MCC may be different than what was requested in MCC_UPDATE_CMD. :+ * @status: see &enum iwx_mcc_update_status :+ * @mcc: the new applied MCC :+ * @cap: capabilities for all channels which matches the MCC :+ * @time: time elapsed from the MCC test start (in units of 30 seconds) :+ * @geo_info: geographic specific profile information :+ * see &enum iwl_geo_information. :+ * @source_id: the MCC source, see iwl_mcc_source :+ * @reserved: for four bytes alignment. :+ * @n_channels: number of channels in @channels_data. :+ * @channels: channel control data map, DWORD for each channel. Only the first :+ * 16bits are used. :+ */ :+struct iwx_mcc_update_resp_v4 { :+ uint32_t status; :+ uint16_t mcc; :+ uint16_t cap; :+ uint16_t time; :+ uint16_t geo_info; :+ uint8_t source_id; :+ uint8_t reserved[3]; :+ uint32_t n_channels; :+ uint32_t channels[]; :+} __packed; /* LAR_UPDATE_MCC_CMD_RESP_S_VER_4 */ :+/** : * geographic information. : * @GEO_NO_INFO: no special info for this geo profile. : * @GEO_WMM_ETSI_5GHZ_INFO: this geo profile limits the WMM params : -- If you ever want to get anywhere in politics, my boy, you're going to have to get a toehold in the public eye.