From: Mark Kettenis Subject: Re: iwx: support MCC update response version 4 To: Stefan Sperling Cc: tech@openbsd.org Date: Mon, 02 Mar 2026 21:24:37 +0100 > Date: Mon, 2 Mar 2026 14:59:32 +0100 > From: Stefan Sperling > > 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? Doesn't break MA and looks fine to me. ok kettenis@ > 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 > >