Hi, With an Intel AX201 Wi-Fi [8086:43f0] subsystem [1a56:1652] pcie card, device fails to load firmware with following error messages: Intel(R) Wireless WiFi driver for Linux iwlwifi 0000:00:14.3: enabling device (0000 -> 0002) iwlwifi 0000:00:14.3: Direct firmware load for (efault)128.ucode failed with error -2 iwlwifi 0000:00:14.3: Direct firmware load for (efault)127.ucode failed with error -2 ... iwlwifi 0000:00:14.3: Direct firmware load for (efault)0.ucode failed with error -2 iwlwifi 0000:00:14.3: no suitable firmware found! iwlwifi 0000:00:14.3: minimum version required: (efault)0 iwlwifi 0000:00:14.3: maximum version supported: (efault)128 This is also reported on some public forums: * https://askubuntu.com/questions/1297311/ubuntu-20-04-wireless-not-working-for-intel-ax1650i-lenovo-thinkpad * https://www.reddit.com/r/pop_os/comments/jxmnre/wifi_and_bluetooth_issues_in_2010/ In drivers/net/wireless/intel/iwlwifi/pcie/drv.c: static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, ... {IWL_PCI_DEVICE(0x43F0, PCI_ANY_ID, iwl_qu_long_latency_trans_cfg)}, ... }; The third argument to IWL_PCI_DEVICE macro will be assigned to driver_data field of struct pci_device_id. However, iwl5100_agn_cfg has type struct iwl_cfg, and yet iwl_qu_long_latency_trans_cfg is typed struct iwl_cfg_trans_params. struct iwl_cfg_trans_params { ... }; struct iwl_cfg { struct iwl_cfg_trans_params trans; const char *name; const char *fw_name_pre; ... }; It's fine to cast a pointer to struct iwl_cfg, but it's not always valid to cast a struct iwl_cfg_trans_params to struct iwl_cfg. In function iwl_pci_probe, it tries to find an alternative cfg by iterating throughout iwl_dev_info_table, but in our case, [8086:43f0] subsystem [1a56:1652], there will be no match in all of the candidates, and iwl_qu_long_latency_trans_cfg will be assigned as the ultimate struct iwl_cfg, which will be certainly wrong when you're trying to dereference anything beyond sizeof(struct iwl_cfg_trans_params), e.g. cfg->fw_name_pre. In this case, ((struct iwl_cfg_trans_params*)&iwl_qu_long_latency_trans_cfg)->name will be "'", and ((struct iwl_cfg_trans_params*)&iwl_qu_long_latency_trans_cfg)->fw_name_pre gives "(efault)", pure garbage data. So is there something missed in the iwl_dev_info_table, or better, just find another solid safe way to handle such trans/cfg mix? Regards, You-Sheng Yang