Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rtw88: load wowlan firmware if wowlan is supported

Driver used to download normal firmware only,
but some devices support wowlan and require to
download wowlan firmware when system suspends.
So modify rtw_load_firmware() and its callback to
allow driver to download both normal and wowlan firmware.

Signed-off-by: Chin-Yen Lee <timlee@realtek.com>
Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

authored by

Chin-Yen Lee and committed by
Kalle Valo
c8e5695e 78622104

+70 -12
+60 -12
drivers/net/wireless/realtek/rtw88/main.c
··· 793 793 rtw_fw_send_ra_info(rtwdev, si); 794 794 } 795 795 796 + static int rtw_wait_firmware_completion(struct rtw_dev *rtwdev) 797 + { 798 + struct rtw_chip_info *chip = rtwdev->chip; 799 + struct rtw_fw_state *fw; 800 + 801 + fw = &rtwdev->fw; 802 + wait_for_completion(&fw->completion); 803 + if (!fw->firmware) 804 + return -EINVAL; 805 + 806 + if (chip->wow_fw_name) { 807 + fw = &rtwdev->wow_fw; 808 + wait_for_completion(&fw->completion); 809 + if (!fw->firmware) 810 + return -EINVAL; 811 + } 812 + 813 + return 0; 814 + } 815 + 796 816 static int rtw_power_on(struct rtw_dev *rtwdev) 797 817 { 798 818 struct rtw_chip_info *chip = rtwdev->chip; ··· 833 813 goto err; 834 814 } 835 815 836 - wait_for_completion(&fw->completion); 837 - if (!fw->firmware) { 838 - ret = -EINVAL; 839 - rtw_err(rtwdev, "failed to load firmware\n"); 840 - goto err; 816 + ret = rtw_wait_firmware_completion(rtwdev); 817 + if (ret) { 818 + rtw_err(rtwdev, "failed to wait firmware completion\n"); 819 + goto err_off; 841 820 } 842 821 843 822 ret = rtw_download_firmware(rtwdev, fw); ··· 1039 1020 1040 1021 static void rtw_load_firmware_cb(const struct firmware *firmware, void *context) 1041 1022 { 1042 - struct rtw_dev *rtwdev = context; 1043 - struct rtw_fw_state *fw = &rtwdev->fw; 1023 + struct rtw_fw_state *fw = context; 1024 + struct rtw_dev *rtwdev = fw->rtwdev; 1044 1025 const struct rtw_fw_hdr *fw_hdr; 1045 1026 1046 1027 if (!firmware || !firmware->data) { ··· 1062 1043 fw->version, fw->sub_version, fw->sub_index, fw->h2c_version); 1063 1044 } 1064 1045 1065 - static int rtw_load_firmware(struct rtw_dev *rtwdev, const char *fw_name) 1046 + static int rtw_load_firmware(struct rtw_dev *rtwdev, enum rtw_fw_type type) 1066 1047 { 1067 - struct rtw_fw_state *fw = &rtwdev->fw; 1048 + const char *fw_name; 1049 + struct rtw_fw_state *fw; 1068 1050 int ret; 1069 1051 1052 + switch (type) { 1053 + case RTW_WOWLAN_FW: 1054 + fw = &rtwdev->wow_fw; 1055 + fw_name = rtwdev->chip->wow_fw_name; 1056 + break; 1057 + 1058 + case RTW_NORMAL_FW: 1059 + fw = &rtwdev->fw; 1060 + fw_name = rtwdev->chip->fw_name; 1061 + break; 1062 + 1063 + default: 1064 + rtw_warn(rtwdev, "unsupported firmware type\n"); 1065 + return -ENOENT; 1066 + } 1067 + 1068 + fw->rtwdev = rtwdev; 1070 1069 init_completion(&fw->completion); 1071 1070 1072 1071 ret = request_firmware_nowait(THIS_MODULE, true, fw_name, rtwdev->dev, 1073 - GFP_KERNEL, rtwdev, rtw_load_firmware_cb); 1072 + GFP_KERNEL, fw, rtw_load_firmware_cb); 1074 1073 if (ret) { 1075 - rtw_err(rtwdev, "async firmware request failed\n"); 1074 + rtw_err(rtwdev, "failed to async firmware request\n"); 1076 1075 return ret; 1077 1076 } 1078 1077 ··· 1409 1372 BIT_HTC_LOC_CTRL | BIT_APP_PHYSTS | 1410 1373 BIT_AB | BIT_AM | BIT_APM; 1411 1374 1412 - ret = rtw_load_firmware(rtwdev, rtwdev->chip->fw_name); 1375 + ret = rtw_load_firmware(rtwdev, RTW_NORMAL_FW); 1413 1376 if (ret) { 1414 1377 rtw_warn(rtwdev, "no firmware loaded\n"); 1415 1378 return ret; 1416 1379 } 1417 1380 1381 + if (chip->wow_fw_name) { 1382 + ret = rtw_load_firmware(rtwdev, RTW_WOWLAN_FW); 1383 + if (ret) { 1384 + rtw_warn(rtwdev, "no wow firmware loaded\n"); 1385 + return ret; 1386 + } 1387 + } 1418 1388 return 0; 1419 1389 } 1420 1390 EXPORT_SYMBOL(rtw_core_init); ··· 1429 1385 void rtw_core_deinit(struct rtw_dev *rtwdev) 1430 1386 { 1431 1387 struct rtw_fw_state *fw = &rtwdev->fw; 1388 + struct rtw_fw_state *wow_fw = &rtwdev->wow_fw; 1432 1389 struct rtw_rsvd_page *rsvd_pkt, *tmp; 1433 1390 unsigned long flags; 1434 1391 1435 1392 if (fw->firmware) 1436 1393 release_firmware(fw->firmware); 1394 + 1395 + if (wow_fw->firmware) 1396 + release_firmware(wow_fw->firmware); 1437 1397 1438 1398 tasklet_kill(&rtwdev->tx_tasklet); 1439 1399 spin_lock_irqsave(&rtwdev->tx_report.q_lock, flags);
+10
drivers/net/wireless/realtek/rtw88/main.h
··· 193 193 RTK_MAX_RX_QUEUE_NUM 194 194 }; 195 195 196 + enum rtw_fw_type { 197 + RTW_NORMAL_FW = 0x0, 198 + RTW_WOWLAN_FW = 0x1, 199 + }; 200 + 196 201 enum rtw_rate_index { 197 202 RTW_RATEID_BGN_40M_2SS = 0, 198 203 RTW_RATEID_BGN_40M_1SS = 1, ··· 1035 1030 u8 bfer_su_max_num; 1036 1031 u8 bfer_mu_max_num; 1037 1032 1033 + const char *wow_fw_name; 1034 + 1038 1035 /* coex paras */ 1039 1036 u32 coex_para_ver; 1040 1037 u8 bt_desired_ver; ··· 1463 1456 1464 1457 struct rtw_fw_state { 1465 1458 const struct firmware *firmware; 1459 + struct rtw_dev *rtwdev; 1466 1460 struct completion completion; 1467 1461 u16 version; 1468 1462 u8 sub_version; ··· 1587 1579 DECLARE_BITMAP(flags, NUM_OF_RTW_FLAGS); 1588 1580 1589 1581 u8 mp_mode; 1582 + 1583 + struct rtw_fw_state wow_fw; 1590 1584 1591 1585 /* hci related data, must be last */ 1592 1586 u8 priv[0] __aligned(sizeof(void *));