On 2025/07/18 14:54, Stuart Henderson wrote:
> On 2025/07/18 03:33, Prateek Kumar wrote:
oops, I missed stsp's earlier reply, which is more likely to be correct
wrt rf_id values.
> > iwx0: using firmware iwx-QuZ-a0-hr-b0-77
>
> > [ 3.571806] iwlwifi 0000:00:14.3: PCI dev a0f0/0264, rev=0x351,
> > rfid=0x108110
> > [ 3.571813] iwlwifi 0000:00:14.3: Detected Intel(R) Wireless-AC 9461
> > [ 3.577698] iwlwifi 0000:00:14.3: TLV_FW_FSEQ_VERSION: FSEQ Version:
> > 89.3.35.37
> > [ 3.578120] iwlwifi 0000:00:14.3: loaded firmware version
> > 77.f31a351f.0 QuZ-a0-jf-b0-77.ucode op_mode iwlmvm
>
> so decoding from the fw name, the MAC is QuZ, stepping a0, RF chip
> is jf (but we misdetect as hr) stepping b0.
>
> linux iwlwifi builds up the firmware filename piece by piece.
>
> iwx does not but instead has hardcoded filenames. There's one match
> table (which does look at rf though doesn't include any QuZ jf) and
> also does some other detection mostly(?) based on the MAC id/revision
> and currently not looking at rf id.
>
> > >Fix:
> > The iwx driver code configures the device and sets the fwname
> > based on its pci id and hardware parameters. For this particular
> > wireless device, the rest of the configuration is fine but the
> > fwname is set incorrectly (i.e. different from what iwlwifi sets).
> >
> > As a workaround to gain connectivity initially, the QuZ-a0-hr-b0-77
> > firmware file in /etc/firmware can be replaced with the correct one
> > under the same name:
> > # cd /etc/firmware
> > # mv iwx-QuZ-a0-hr-b0-77 iwx-QuZ-a0-hr-b0-77.bak
> > # ln iwx-QuZ-a0-jf-b0-77 iwx-QuZ-a0-hr-b0-77
> >
> > The patch given below fixes the logic that sets the correct fwname
> > for this wireless device. The driver with this patch applied works
> > as expected:
> > iwx0 at pci0 dev 20 function 3 "Intel Wi-Fi 6 AX201" rev 0x20, msix
> > iwx0: hw rev 0x350, fw 77.206b0184.0, address 80:b6:55:ce:45:6e
> > iwx0: using firmware iwx-QuZ-a0-jf-b0-77
>
> > Index: if_iwx.c
> > ===================================================================
> > RCS file: /cvs/src/sys/dev/pci/if_iwx.c,v
> > retrieving revision 1.191
> > diff -u -p -u -p -r1.191 if_iwx.c
> > --- if_iwx.c 29 Jun 2025 19:32:08 -0000 1.191
> > +++ if_iwx.c 17 Jul 2025 15:22:57 -0000
> > @@ -11487,12 +11487,7 @@ iwx_attach(struct device *parent, struct
> > sc->sc_uhb_supported = 0;
> > break;
> > case PCI_PRODUCT_INTEL_WL_22500_3:
> > - if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0)
> > - sc->sc_fwname = IWX_QU_C_HR_B_FW;
> > - else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ)
> > - sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
> > - else
> > - sc->sc_fwname = IWX_QU_B_HR_B_FW;
> > + sc->sc_fwname = IWX_QUZ_A_JF_B_FW;
> > sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
> > sc->sc_integrated = 1;
> > sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_200;
>
> That doesn't seem like a commitable fix, it's likely to fix some
> devices at the expense of breaking others.
>
> Wonder if this might do the trick, though a bigger change of building
> up the firmware filename from pieces would seem likely to give correct
> results more often, and probably end up less complicated.
>
> Index: if_iwx.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/if_iwx.c,v
> diff -u -p -r1.191 if_iwx.c
> --- if_iwx.c 29 Jun 2025 19:32:08 -0000 1.191
> +++ if_iwx.c 18 Jul 2025 13:49:59 -0000
> @@ -11247,15 +11247,16 @@ iwx_preinit(struct iwx_softc *sc)
> /* Print version info and MAC address on first successful fw load. */
> sc->attached = 1;
> if (sc->sc_pnvm_ver) {
> - printf("%s: hw rev 0x%x, fw %s, pnvm %08x, "
> + printf("%s: hw rev 0x%x, rf 0x%x, fw %s, pnvm %08x, "
> "address %s\n",
> DEVNAME(sc), sc->sc_hw_rev & IWX_CSR_HW_REV_TYPE_MSK,
> - sc->sc_fwver, sc->sc_pnvm_ver,
> + sc->sc_hw_rf_id, sc->sc_fwver, sc->sc_pnvm_ver,
> ether_sprintf(sc->sc_nvm.hw_addr));
> } else {
> - printf("%s: hw rev 0x%x, fw %s, address %s\n",
> + printf("%s: hw rev 0x%x, rf 0x%x, fw %s, address %s\n",
> DEVNAME(sc), sc->sc_hw_rev & IWX_CSR_HW_REV_TYPE_MSK,
> - sc->sc_fwver, ether_sprintf(sc->sc_nvm.hw_addr));
> + sc->sc_hw_rf_id, sc->sc_fwver,
> + ether_sprintf(sc->sc_nvm.hw_addr));
> }
>
> if (sc->sc_nvm.sku_cap_11n_enable)
> @@ -11477,7 +11478,10 @@ iwx_attach(struct device *parent, struct
> printf("%s: unsupported AX201 adapter\n", DEVNAME(sc));
> return;
> }
> - sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
> + if (sc->sc_hw_rf_id == IWX_CFG_RF_ID_JF)
> + sc->sc_fwname = IWX_QUZ_A_JF_B_FW;
> + else
> + sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
> sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
> sc->sc_integrated = 1;
> sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_200;
> @@ -11490,7 +11494,10 @@ iwx_attach(struct device *parent, struct
> if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0)
> sc->sc_fwname = IWX_QU_C_HR_B_FW;
> else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ)
> - sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
> + if (sc->sc_hw_rf_id == IWX_CFG_RF_ID_JF)
> + sc->sc_fwname = IWX_QUZ_A_JF_B_FW;
> + else
> + sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
> else
> sc->sc_fwname = IWX_QU_B_HR_B_FW;
> sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
> @@ -11507,7 +11514,10 @@ iwx_attach(struct device *parent, struct
> if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0)
> sc->sc_fwname = IWX_QU_C_HR_B_FW;
> else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ)
> - sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
> + if (sc->sc_hw_rf_id == IWX_CFG_RF_ID_JF)
> + sc->sc_fwname = IWX_QUZ_A_JF_B_FW;
> + else
> + sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
> else
> sc->sc_fwname = IWX_QU_B_HR_B_FW;
> sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
> @@ -11522,7 +11532,10 @@ iwx_attach(struct device *parent, struct
> if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0)
> sc->sc_fwname = IWX_QU_C_HR_B_FW;
> else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ)
> - sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
> + if (sc->sc_hw_rf_id == IWX_CFG_RF_ID_JF)
> + sc->sc_fwname = IWX_QUZ_A_JF_B_FW;
> + else
> + sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
> else
> sc->sc_fwname = IWX_QU_B_HR_B_FW;
> sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
>