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; >