diff --git a/lib/functions/compilation/patch/drivers_network.sh b/lib/functions/compilation/patch/drivers_network.sh index bf3508541b..95b83598e0 100644 --- a/lib/functions/compilation/patch/drivers_network.sh +++ b/lib/functions/compilation/patch/drivers_network.sh @@ -406,21 +406,11 @@ driver_rtw88() { return 0 fi - # Upstream wireless RTW88 drivers - if [[ "$version" == "6.1" || "$version" == "6.2" || "$version" == "6.3" ]] && [ $EXTRAWIFI == yes ]; then + # Upstream wireless RTW88 drivers (wireless-next-2023-06-22) + if [[ "$version" == "6.1" || "$version" == "6.2" || "$version" == "6.3" || "$version" == "6.4" ]] && [ $EXTRAWIFI == yes ]; then display_alert "Adding" "Upstream wireless RTW88 drivers" "info" process_patch_file "${SRC}/patch/misc/rtw88/${version}/001-rtw88-linux-next.patch" "applying" process_patch_file "${SRC}/patch/misc/rtw88/${version}/002-rtw88-linux-next.patch" "applying" - process_patch_file "${SRC}/patch/misc/rtw88/${version}/003-rtw88-add-missing-unwind-goto-for_rtw_download_firmware.patch" "applying" - process_patch_file "${SRC}/patch/misc/rtw88/${version}/004-rtw88-fix-action-frame-transmission-fail-before-association.patch" "applying" - process_patch_file "${SRC}/patch/misc/rtw88/hack/001-revert-rtw88-sdio-size-and-timout-to-rfc-v1.patch" "applying" - process_patch_file "${SRC}/patch/misc/rtw88/hack/002-rtw88-usb-make-work-queues-high-priority.patch" "applying" - fi - if [[ "$version" == "6.4" ]] && [ $EXTRAWIFI == yes ]; then - display_alert "Adding" "Upstream wireless RTW88 drivers" "info" - process_patch_file "${SRC}/patch/misc/rtw88/${version}/001-rtw88-add-support-for-the-RTL8723DS-SDIO-wifi-chip.patch" "applying" - process_patch_file "${SRC}/patch/misc/rtw88/${version}/002-rtw88-add-missing-unwind-goto-for_rtw_download_firmware.patch" "applying" - process_patch_file "${SRC}/patch/misc/rtw88/${version}/003-rtw88-fix-action-frame-transmission-fail-before-association.patch" "applying" process_patch_file "${SRC}/patch/misc/rtw88/hack/001-revert-rtw88-sdio-size-and-timout-to-rfc-v1.patch" "applying" process_patch_file "${SRC}/patch/misc/rtw88/hack/002-rtw88-usb-make-work-queues-high-priority.patch" "applying" fi diff --git a/patch/misc/rtw88/6.1/001-rtw88-linux-next.patch b/patch/misc/rtw88/6.1/001-rtw88-linux-next.patch index 4a9cedac31..a1b05e8526 100644 --- a/patch/misc/rtw88/6.1/001-rtw88-linux-next.patch +++ b/patch/misc/rtw88/6.1/001-rtw88-linux-next.patch @@ -1,6 +1,6 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/bf.c b/drivers/net/wireless/realtek/rtw88/bf.c ---- a/drivers/net/wireless/realtek/rtw88/bf.c 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/bf.c 2023-06-10 16:36:07.000000000 -0400 +--- a/drivers/net/wireless/realtek/rtw88/bf.c 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/bf.c 2023-06-22 13:52:09.000000000 -0400 @@ -49,19 +49,23 @@ sta = ieee80211_find_sta(vif, bssid); @@ -47,8 +47,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/bf.c b/drivers/net/wireless/real void rtw_bf_init_bfer_entry_mu(struct rtw_dev *rtwdev, diff -Naur a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c ---- a/drivers/net/wireless/realtek/rtw88/coex.c 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/coex.c 2023-06-10 16:36:07.000000000 -0400 +--- a/drivers/net/wireless/realtek/rtw88/coex.c 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/coex.c 2023-06-22 13:52:09.000000000 -0400 @@ -633,7 +633,7 @@ struct rtw_coex *coex = &rtwdev->coex; struct sk_buff *skb_resp = NULL; @@ -67,8 +67,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/re } diff -Naur a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c ---- a/drivers/net/wireless/realtek/rtw88/debug.c 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/debug.c 2023-06-10 16:36:07.000000000 -0400 +--- a/drivers/net/wireless/realtek/rtw88/debug.c 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/debug.c 2023-06-22 13:52:09.000000000 -0400 @@ -144,7 +144,9 @@ addr = debugfs_priv->rf_addr; mask = debugfs_priv->rf_mask; @@ -79,7 +79,96 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/r seq_printf(m, "rf_read path:%d addr:0x%08x mask:0x%08x val=0x%08x\n", path, addr, mask, val); -@@ -390,7 +392,9 @@ +@@ -181,8 +183,8 @@ + + tmp_len = (count > size - 1 ? size - 1 : count); + +- if (!buffer || copy_from_user(tmp, buffer, tmp_len)) +- return count; ++ if (copy_from_user(tmp, buffer, tmp_len)) ++ return -EFAULT; + + tmp[tmp_len] = '\0'; + +@@ -199,13 +201,16 @@ + char tmp[32 + 1]; + u32 addr, len; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); ++ if (ret) ++ return ret; + + num = sscanf(tmp, "%x %x", &addr, &len); + + if (num != 2) +- return count; ++ return -EINVAL; + + if (len != 1 && len != 2 && len != 4) { + rtw_warn(rtwdev, "read reg setting wrong len\n"); +@@ -286,8 +291,11 @@ + char tmp[32 + 1]; + u32 offset, page_num; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); ++ if (ret) ++ return ret; + + num = sscanf(tmp, "%d %d", &offset, &page_num); + +@@ -312,8 +320,11 @@ + char tmp[32 + 1]; + u32 input; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ if (ret) ++ return ret; + + num = kstrtoint(tmp, 0, &input); + +@@ -336,14 +347,17 @@ + char tmp[32 + 1]; + u32 addr, val, len; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ if (ret) ++ return ret; + + /* write BB/MAC register */ + num = sscanf(tmp, "%x %x %x", &addr, &val, &len); + + if (num != 3) +- return count; ++ return -EINVAL; + + switch (len) { + case 1: +@@ -379,8 +393,11 @@ + char tmp[32 + 1]; + u8 param[8]; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ if (ret) ++ return ret; + + num = sscanf(tmp, "%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx", + ¶m[0], ¶m[1], ¶m[2], ¶m[3], +@@ -390,7 +407,9 @@ return -EINVAL; } @@ -89,8 +178,23 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/r return count; } -@@ -414,7 +418,9 @@ - return count; +@@ -404,17 +423,22 @@ + char tmp[32 + 1]; + u32 path, addr, mask, val; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 4); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 4); ++ if (ret) ++ return ret; + + num = sscanf(tmp, "%x %x %x %x", &path, &addr, &mask, &val); + + if (num != 4) { + rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); +- return count; ++ return -EINVAL; } + mutex_lock(&rtwdev->mutex); @@ -99,7 +203,38 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/r rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, "write_rf path:%d addr:0x%08x mask:0x%08x, val:0x%08x\n", path, addr, mask, val); -@@ -519,6 +525,8 @@ +@@ -432,14 +456,17 @@ + char tmp[32 + 1]; + u32 path, addr, mask; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ if (ret) ++ return ret; + + num = sscanf(tmp, "%x %x %x", &path, &addr, &mask); + + if (num != 3) { + rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); +- return count; ++ return -EINVAL; + } + + debugfs_priv->rf_path = path; +@@ -461,7 +488,9 @@ + char tmp[32 + 1]; + int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ if (ret) ++ return ret; + + ret = kstrtou8(tmp, 0, &fix_rate); + if (ret) { +@@ -519,6 +548,8 @@ u32 addr, offset, data; u8 path; @@ -108,7 +243,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/r for (path = 0; path < rtwdev->hal.rf_path_num; path++) { seq_printf(m, "RF path:%d\n", path); for (addr = 0; addr < 0x100; addr += 4) { -@@ -533,6 +541,8 @@ +@@ -533,6 +564,8 @@ seq_puts(m, "\n"); } @@ -117,7 +252,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/r return 0; } -@@ -831,7 +841,9 @@ +@@ -831,7 +864,9 @@ struct rtw_debugfs_priv *debugfs_priv = m->private; struct rtw_dev *rtwdev = debugfs_priv->rtwdev; @@ -127,7 +262,29 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/r return 0; } -@@ -1026,6 +1038,8 @@ +@@ -848,7 +883,9 @@ + bool enable; + int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ if (ret) ++ return ret; + + ret = kstrtobool(tmp, &enable); + if (ret) { +@@ -918,7 +955,9 @@ + bool input; + int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ if (ret) ++ return ret; + + ret = kstrtobool(tmp, &input); + if (ret) +@@ -1026,6 +1065,8 @@ dm_info->dm_flags & BIT(RTW_DM_CAP_TXGAPK) ? '-' : '+', rtw_dm_cap_strs[RTW_DM_CAP_TXGAPK]); @@ -136,7 +293,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/r for (path = 0; path < rtwdev->hal.rf_path_num; path++) { val = rtw_read_rf(rtwdev, path, RF_GAINTX, RFREG_MASK); seq_printf(m, "path %d:\n0x%x = 0x%x\n", path, RF_GAINTX, val); -@@ -1035,6 +1049,7 @@ +@@ -1035,6 +1076,7 @@ txgapk->rf3f_fs[path][i], i); seq_puts(m, "\n"); } @@ -145,8 +302,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/r static int rtw_debugfs_get_dm_cap(struct seq_file *m, void *v) diff -Naur a/drivers/net/wireless/realtek/rtw88/debug.h b/drivers/net/wireless/realtek/rtw88/debug.h ---- a/drivers/net/wireless/realtek/rtw88/debug.h 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/debug.h 2023-06-10 16:36:07.000000000 -0400 +--- a/drivers/net/wireless/realtek/rtw88/debug.h 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/debug.h 2023-06-22 13:52:09.000000000 -0400 @@ -24,6 +24,7 @@ RTW_DBG_ADAPTIVITY = 0x00008000, RTW_DBG_HW_SCAN = 0x00010000, @@ -156,9 +313,63 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/debug.h b/drivers/net/wireless/r RTW_DBG_ALL = 0xffffffff }; diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c ---- a/drivers/net/wireless/realtek/rtw88/fw.c 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/fw.c 2023-06-10 16:36:07.000000000 -0400 -@@ -311,10 +311,10 @@ +--- a/drivers/net/wireless/realtek/rtw88/fw.c 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/fw.c 2023-06-22 13:52:09.000000000 -0400 +@@ -308,13 +308,64 @@ + } + EXPORT_SYMBOL(rtw_fw_c2h_cmd_isr); + ++static void rtw_fw_send_h2c_command_register(struct rtw_dev *rtwdev, ++ struct rtw_h2c_register *h2c) ++{ ++ u32 box_reg, box_ex_reg; ++ u8 box_state, box; ++ int ret; ++ ++ rtw_dbg(rtwdev, RTW_DBG_FW, "send H2C content %08x %08x\n", h2c->w0, ++ h2c->w1); ++ ++ lockdep_assert_held(&rtwdev->mutex); ++ ++ box = rtwdev->h2c.last_box_num; ++ switch (box) { ++ case 0: ++ box_reg = REG_HMEBOX0; ++ box_ex_reg = REG_HMEBOX0_EX; ++ break; ++ case 1: ++ box_reg = REG_HMEBOX1; ++ box_ex_reg = REG_HMEBOX1_EX; ++ break; ++ case 2: ++ box_reg = REG_HMEBOX2; ++ box_ex_reg = REG_HMEBOX2_EX; ++ break; ++ case 3: ++ box_reg = REG_HMEBOX3; ++ box_ex_reg = REG_HMEBOX3_EX; ++ break; ++ default: ++ WARN(1, "invalid h2c mail box number\n"); ++ return; ++ } ++ ++ ret = read_poll_timeout_atomic(rtw_read8, box_state, ++ !((box_state >> box) & 0x1), 100, 3000, ++ false, rtwdev, REG_HMETFR); ++ ++ if (ret) { ++ rtw_err(rtwdev, "failed to send h2c command\n"); ++ return; ++ } ++ ++ rtw_write32(rtwdev, box_ex_reg, h2c->w1); ++ rtw_write32(rtwdev, box_reg, h2c->w0); ++ ++ if (++rtwdev->h2c.last_box_num >= 4) ++ rtwdev->h2c.last_box_num = 0; ++} ++ static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev, u8 *h2c) { @@ -170,7 +381,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real int ret; rtw_dbg(rtwdev, RTW_DBG_FW, -@@ -322,7 +322,7 @@ +@@ -322,7 +373,7 @@ h2c[3], h2c[2], h2c[1], h2c[0], h2c[7], h2c[6], h2c[5], h2c[4]); @@ -179,7 +390,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real box = rtwdev->h2c.last_box_num; switch (box) { -@@ -344,7 +344,7 @@ +@@ -344,7 +395,7 @@ break; default: WARN(1, "invalid h2c mail box number\n"); @@ -188,7 +399,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real } ret = read_poll_timeout_atomic(rtw_read8, box_state, -@@ -353,19 +353,14 @@ +@@ -353,19 +404,14 @@ if (ret) { rtw_err(rtwdev, "failed to send h2c command\n"); @@ -211,7 +422,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real } void rtw_fw_h2c_cmd_dbg(struct rtw_dev *rtwdev, u8 *h2c) -@@ -377,15 +372,13 @@ +@@ -377,15 +423,13 @@ { int ret; @@ -228,7 +439,31 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real } void -@@ -824,6 +817,16 @@ +@@ -475,6 +519,23 @@ + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); + } + ++void rtw_fw_default_port(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif) ++{ ++ struct rtw_h2c_register h2c = {}; ++ ++ if (rtwvif->net_type != RTW_NET_MGD_LINKED) ++ return; ++ ++ /* Leave LPS before default port H2C so FW timer is correct */ ++ rtw_leave_lps(rtwdev); ++ ++ h2c.w0 = u32_encode_bits(H2C_CMD_DEFAULT_PORT, RTW_H2C_W0_CMDID) | ++ u32_encode_bits(rtwvif->port, RTW_H2C_DEFAULT_PORT_W0_PORTID) | ++ u32_encode_bits(rtwvif->mac_id, RTW_H2C_DEFAULT_PORT_W0_MACID); ++ ++ rtw_fw_send_h2c_command_register(rtwdev, &h2c); ++} ++ + void rtw_fw_wl_ch_info(struct rtw_dev *rtwdev, u8 link, u8 ch, u8 bw) + { + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; +@@ -824,6 +885,16 @@ rtw_fw_send_h2c_command(rtwdev, h2c_pkt); } @@ -245,7 +480,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real void rtw_fw_set_pg_info(struct rtw_dev *rtwdev) { struct rtw_lps_conf *conf = &rtwdev->lps_conf; -@@ -1390,6 +1393,10 @@ +@@ -1390,6 +1461,10 @@ struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; struct rtw_rsvd_page *rsvd_pkt; @@ -256,7 +491,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real list_for_each_entry(rsvd_pkt, &rtwvif->rsvd_page_list, vif_list) { if (rsvd_pkt->type == RSVD_BEACON) list_add(&rsvd_pkt->build_list, -@@ -1611,6 +1618,7 @@ +@@ -1611,6 +1686,7 @@ mutex_lock(&rtwdev->mutex); rtw_fw_download_rsvd_page(rtwdev); @@ -264,7 +499,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real mutex_unlock(&rtwdev->mutex); } -@@ -2152,11 +2160,19 @@ +@@ -2152,11 +2228,19 @@ } rtw_fw_set_scan_offload(rtwdev, &cs_option, rtwvif, &chan_list); out: @@ -285,7 +520,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD)) return; -@@ -2241,6 +2257,7 @@ +@@ -2241,6 +2325,7 @@ if (rtw_is_op_chan(rtwdev, chan)) { rtw_store_op_chan(rtwdev, false); ieee80211_wake_queues(rtwdev->hw); @@ -293,7 +528,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real } } else if (id == RTW_SCAN_NOTIFY_ID_PRESWITCH) { if (IS_CH_5G_BAND(chan)) { -@@ -2259,8 +2276,10 @@ +@@ -2259,8 +2344,10 @@ * if next channel is non-op channel. */ if (!rtw_is_op_chan(rtwdev, chan) && @@ -306,12 +541,23 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real rtw_dbg(rtwdev, RTW_DBG_HW_SCAN, diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h ---- a/drivers/net/wireless/realtek/rtw88/fw.h 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/fw.h 2023-06-10 16:36:07.000000000 -0400 -@@ -81,6 +81,11 @@ +--- a/drivers/net/wireless/realtek/rtw88/fw.h 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/fw.h 2023-06-22 13:52:09.000000000 -0400 +@@ -81,6 +81,22 @@ u8 option; } __packed; ++struct rtw_h2c_register { ++ u32 w0; ++ u32 w1; ++} __packed; ++ ++#define RTW_H2C_W0_CMDID GENMASK(7, 0) ++ ++/* H2C_CMD_DEFAULT_PORT command */ ++#define RTW_H2C_DEFAULT_PORT_W0_PORTID GENMASK(15, 8) ++#define RTW_H2C_DEFAULT_PORT_W0_MACID GENMASK(23, 16) ++ +struct rtw_h2c_cmd { + __le32 msg; + __le32 msg_ext; @@ -320,7 +566,15 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/real enum rtw_rsvd_packet_type { RSVD_BEACON, RSVD_DUMMY, -@@ -550,6 +555,8 @@ +@@ -525,6 +541,7 @@ + #define H2C_CMD_MEDIA_STATUS_RPT 0x01 + #define H2C_CMD_SET_PWR_MODE 0x20 + #define H2C_CMD_LPS_PG_INFO 0x2b ++#define H2C_CMD_DEFAULT_PORT 0x2c + #define H2C_CMD_RA_INFO 0x40 + #define H2C_CMD_RSSI_MONITOR 0x42 + #define H2C_CMD_BCN_FILTER_OFFLOAD_P0 0x56 +@@ -550,6 +567,8 @@ #define H2C_CMD_AOAC_GLOBAL_INFO 0x82 #define H2C_CMD_NLO_INFO 0x8C @@ -329,7 +583,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/real #define SET_H2C_CMD_ID_CLASS(h2c_pkt, value) \ le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(7, 0)) -@@ -749,6 +756,9 @@ +@@ -749,6 +768,9 @@ #define SET_NLO_LOC_NLO_INFO(h2c_pkt, value) \ le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16)) @@ -339,7 +593,15 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/real #define GET_FW_DUMP_LEN(_header) \ le32_get_bits(*((__le32 *)(_header) + 0x00), GENMASK(15, 0)) #define GET_FW_DUMP_SEQ(_header) \ -@@ -838,6 +848,7 @@ +@@ -791,6 +813,7 @@ + void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb); + void rtw_fw_send_general_info(struct rtw_dev *rtwdev); + void rtw_fw_send_phydm_info(struct rtw_dev *rtwdev); ++void rtw_fw_default_port(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif); + + void rtw_fw_do_iqk(struct rtw_dev *rtwdev, struct rtw_iqk_para *para); + void rtw_fw_inform_rfk_status(struct rtw_dev *rtwdev, bool start); +@@ -838,6 +861,7 @@ u8 group_key_enc); void rtw_fw_set_nlo_info(struct rtw_dev *rtwdev, bool enable); @@ -347,7 +609,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/real void rtw_fw_update_pkt_probe_req(struct rtw_dev *rtwdev, struct cfg80211_ssid *ssid); void rtw_fw_channel_switch(struct rtw_dev *rtwdev, bool enable); -@@ -857,5 +868,5 @@ +@@ -857,5 +881,5 @@ bool enable); void rtw_hw_scan_status_report(struct rtw_dev *rtwdev, struct sk_buff *skb); void rtw_hw_scan_chan_switch(struct rtw_dev *rtwdev, struct sk_buff *skb); @@ -355,8 +617,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/real +void rtw_hw_scan_abort(struct rtw_dev *rtwdev); #endif diff -Naur a/drivers/net/wireless/realtek/rtw88/hci.h b/drivers/net/wireless/realtek/rtw88/hci.h ---- a/drivers/net/wireless/realtek/rtw88/hci.h 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/hci.h 2023-06-10 16:36:07.000000000 -0400 +--- a/drivers/net/wireless/realtek/rtw88/hci.h 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/hci.h 2023-06-22 13:52:09.000000000 -0400 @@ -166,12 +166,11 @@ rtw_read_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, u32 addr, u32 mask) @@ -386,8 +648,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/hci.h b/drivers/net/wireless/rea static inline u32 diff -Naur a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig ---- a/drivers/net/wireless/realtek/rtw88/Kconfig 2023-06-09 04:34:30.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/Kconfig 2023-06-11 07:10:49.401245393 -0400 +--- a/drivers/net/wireless/realtek/rtw88/Kconfig 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/Kconfig 2023-06-22 13:52:09.000000000 -0400 @@ -16,6 +16,12 @@ config RTW88_PCI tristate @@ -518,9 +780,22 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/r bool "Realtek rtw88 debug support" depends on RTW88_CORE diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c ---- a/drivers/net/wireless/realtek/rtw88/mac80211.c 2023-06-14 05:15:34.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c 2023-06-14 07:42:56.191262408 -0400 -@@ -146,25 +146,30 @@ +--- a/drivers/net/wireless/realtek/rtw88/mac80211.c 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/mac80211.c 2023-06-22 13:52:09.000000000 -0400 +@@ -43,7 +43,11 @@ + list_add_tail(&rtwtxq->list, &rtwdev->txqs); + spin_unlock_bh(&rtwdev->txq_lock); + +- queue_work(rtwdev->tx_wq, &rtwdev->tx_work); ++ /* ensure to dequeue EAPOL (4/4) at the right time */ ++ if (txq->ac == IEEE80211_AC_VO) ++ __rtw_tx_work(rtwdev); ++ else ++ queue_work(rtwdev->tx_wq, &rtwdev->tx_work); + } + + static int rtw_ops_start(struct ieee80211_hw *hw) +@@ -146,25 +150,32 @@ struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; enum rtw_net_type net_type; u32 config = 0; @@ -545,8 +820,10 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles mutex_lock(&rtwdev->mutex); + port = find_first_zero_bit(rtwdev->hw_port, RTW_PORT_NUM); -+ if (port >= RTW_PORT_NUM) ++ if (port >= RTW_PORT_NUM) { ++ mutex_unlock(&rtwdev->mutex); + return -EINVAL; ++ } + set_bit(port, rtwdev->hw_port); + + rtwvif->port = port; @@ -554,7 +831,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles rtw_leave_lps_deep(rtwdev); switch (vif->type) { -@@ -186,6 +191,7 @@ +@@ -186,6 +197,7 @@ break; default: WARN_ON(1); @@ -562,7 +839,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles mutex_unlock(&rtwdev->mutex); return -EINVAL; } -@@ -197,6 +203,7 @@ +@@ -197,6 +209,7 @@ rtwvif->bcn_ctrl = bcn_ctrl; config |= PORT_SET_BCN_CTRL; rtw_vif_port_config(rtwdev, rtwvif, config); @@ -570,7 +847,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles rtw_recalc_lps(rtwdev, vif); mutex_unlock(&rtwdev->mutex); -@@ -228,6 +235,7 @@ +@@ -228,6 +241,7 @@ rtwvif->bcn_ctrl = 0; config |= PORT_SET_BCN_CTRL; rtw_vif_port_config(rtwdev, rtwvif, config); @@ -578,16 +855,25 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles rtw_recalc_lps(rtwdev, NULL); mutex_unlock(&rtwdev->mutex); -@@ -378,7 +386,7 @@ +@@ -368,6 +382,7 @@ + + rtw_fw_download_rsvd_page(rtwdev); + rtw_send_rsvd_page_h2c(rtwdev); ++ rtw_fw_default_port(rtwdev, rtwvif); + rtw_coex_media_status_notify(rtwdev, vif->cfg.assoc); + if (rtw_bf_support) + rtw_bf_assoc(rtwdev, vif, conf); +@@ -378,7 +393,8 @@ * when disconnected by peer */ if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) - rtw_hw_scan_abort(rtwdev, vif); + rtw_hw_scan_abort(rtwdev); ++ } config |= PORT_SET_NET_TYPE; -@@ -388,7 +396,7 @@ +@@ -388,7 +404,7 @@ if (changed & BSS_CHANGED_BSSID) { ether_addr_copy(rtwvif->bssid, conf->bssid); config |= PORT_SET_BSSID; @@ -596,7 +882,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles rtw_clear_op_chan(rtwdev); else rtw_store_op_chan(rtwdev, true); -@@ -402,6 +410,7 @@ +@@ -402,6 +418,7 @@ if (changed & BSS_CHANGED_BEACON) { rtw_set_dtim_period(rtwdev, conf->dtim_period); rtw_fw_download_rsvd_page(rtwdev); @@ -604,10 +890,11 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles } if (changed & BSS_CHANGED_BEACON_ENABLED) { -@@ -437,12 +446,27 @@ +@@ -437,12 +454,29 @@ const struct rtw_chip_info *chip = rtwdev->chip; mutex_lock(&rtwdev->mutex); ++ rtw_write32_set(rtwdev, REG_TCR, BIT_TCR_UPDATE_HGQMD); + rtwdev->ap_active = true; + rtw_store_op_chan(rtwdev, true); chip->ops->phy_calibration(rtwdev); @@ -623,6 +910,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles + struct rtw_dev *rtwdev = hw->priv; + + mutex_lock(&rtwdev->mutex); ++ rtw_write32_clr(rtwdev, REG_TCR, BIT_TCR_UPDATE_HGQMD); + rtwdev->ap_active = false; + if (!rtw_core_check_sta_active(rtwdev)) + rtw_clear_op_chan(rtwdev); @@ -632,7 +920,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles static int rtw_ops_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, unsigned int link_id, u16 ac, -@@ -483,8 +507,8 @@ +@@ -483,8 +517,8 @@ { struct rtw_dev *rtwdev = hw->priv; @@ -642,7 +930,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles rtw_sta_remove(rtwdev, sta, true); mutex_unlock(&rtwdev->mutex); -@@ -733,7 +757,7 @@ +@@ -733,7 +767,7 @@ br_data.rtwdev = rtwdev; br_data.vif = vif; br_data.mask = mask; @@ -651,7 +939,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles } static int rtw_ops_set_bitrate_mask(struct ieee80211_hw *hw, -@@ -742,7 +766,9 @@ +@@ -742,7 +776,9 @@ { struct rtw_dev *rtwdev = hw->priv; @@ -661,7 +949,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles return 0; } -@@ -843,7 +869,7 @@ +@@ -843,7 +879,7 @@ rtw_hw_scan_start(rtwdev, vif, req); ret = rtw_hw_scan_offload(rtwdev, vif, true); if (ret) { @@ -670,7 +958,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles rtw_err(rtwdev, "HW scan failed with status: %d\n", ret); } mutex_unlock(&rtwdev->mutex); -@@ -863,7 +889,7 @@ +@@ -863,7 +899,7 @@ return; mutex_lock(&rtwdev->mutex); @@ -679,7 +967,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles mutex_unlock(&rtwdev->mutex); } -@@ -902,6 +928,7 @@ +@@ -902,6 +938,7 @@ .configure_filter = rtw_ops_configure_filter, .bss_info_changed = rtw_ops_bss_info_changed, .start_ap = rtw_ops_start_ap, @@ -688,8 +976,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles .sta_add = rtw_ops_sta_add, .sta_remove = rtw_ops_sta_remove, diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c ---- a/drivers/net/wireless/realtek/rtw88/mac.c 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/mac.c 2023-06-10 16:36:07.000000000 -0400 +--- a/drivers/net/wireless/realtek/rtw88/mac.c 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/mac.c 2023-06-22 13:52:09.000000000 -0400 @@ -7,6 +7,7 @@ #include "reg.h" #include "fw.h" @@ -800,7 +1088,20 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/rea /* Disable beacon related functions */ tmp = rtw_read8(rtwdev, REG_BCN_CTRL); bckp[bckp_idx].len = 1; -@@ -918,7 +956,8 @@ +@@ -756,8 +794,10 @@ + + wlan_cpu_enable(rtwdev, true); + +- if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) +- return -EBUSY; ++ if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) { ++ ret = -EBUSY; ++ goto dlfw_fail; ++ } + + ret = download_firmware_validate(rtwdev); + if (ret) +@@ -918,7 +958,8 @@ return ret; } @@ -810,7 +1111,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/rea { if (rtw_chip_wcpu_11n(rtwdev)) return __rtw_download_firmware_legacy(rtwdev, fw); -@@ -926,6 +965,21 @@ +@@ -926,6 +967,21 @@ return __rtw_download_firmware(rtwdev, fw); } @@ -832,7 +1133,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/rea static u32 get_priority_queues(struct rtw_dev *rtwdev, u32 queues) { const struct rtw_rqpn *rqpn = rtwdev->fifo.rqpn; -@@ -1026,6 +1080,9 @@ +@@ -1026,6 +1082,9 @@ else return -EINVAL; break; @@ -842,7 +1143,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/rea default: return -EINVAL; } -@@ -1044,6 +1101,13 @@ +@@ -1044,6 +1103,13 @@ if (rtw_chip_wcpu_11ac(rtwdev)) rtw_write32(rtwdev, REG_H2CQ_CSR, BIT_H2CQ_FULL); @@ -856,7 +1157,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/rea return 0; } -@@ -1055,7 +1119,7 @@ +@@ -1055,7 +1121,7 @@ u8 csi_buf_pg_num = chip->csi_buf_pg_num; /* config rsvd page num */ @@ -865,7 +1166,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/rea fifo->txff_pg_num = chip->txff_size >> 7; if (rtw_chip_wcpu_11n(rtwdev)) fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num; -@@ -1185,6 +1249,9 @@ +@@ -1185,6 +1251,9 @@ else return -EINVAL; break; @@ -876,8 +1177,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/rea return -EINVAL; } diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.h b/drivers/net/wireless/realtek/rtw88/mac.h ---- a/drivers/net/wireless/realtek/rtw88/mac.h 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/mac.h 2023-06-10 16:36:07.000000000 -0400 +--- a/drivers/net/wireless/realtek/rtw88/mac.h 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/mac.h 2023-06-22 13:52:09.000000000 -0400 @@ -7,7 +7,6 @@ #define RTW_HW_PORT_NUM 5 @@ -887,8 +1188,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.h b/drivers/net/wireless/rea #define C2H_PKT_BUF 256 #define REPORT_BUF 128 diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c ---- a/drivers/net/wireless/realtek/rtw88/main.c 2023-06-14 05:15:34.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/main.c 2023-06-14 07:26:51.631508167 -0400 +--- a/drivers/net/wireless/realtek/rtw88/main.c 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/main.c 2023-06-22 13:52:09.000000000 -0400 @@ -18,6 +18,7 @@ #include "debug.h" #include "bf.h" @@ -946,7 +1247,23 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re rtw_enter_lps(rtwdev, data.rtwvif->port); rtwdev->watch_dog_cnt++; -@@ -622,6 +645,7 @@ +@@ -311,12 +334,15 @@ + struct ieee80211_vif *vif) + { + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; ++ struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + int i; + + si->mac_id = rtw_acquire_macid(rtwdev); + if (si->mac_id >= RTW_MAX_MAC_ID_NUM) + return -ENOSPC; + ++ if (vif->type == NL80211_IFTYPE_STATION && vif->cfg.assoc == 0) ++ rtwvif->mac_id = si->mac_id; + si->rtwdev = rtwdev; + si->sta = sta; + si->vif = vif; +@@ -622,6 +648,7 @@ rcu_read_unlock(); rtw_iterate_stas_atomic(rtwdev, rtw_reset_sta_iter, rtwdev); rtw_iterate_vifs_atomic(rtwdev, rtw_reset_vif_iter, rtwdev); @@ -954,7 +1271,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re rtw_enter_ips(rtwdev); } -@@ -841,6 +865,9 @@ +@@ -841,6 +868,9 @@ rtw_update_channel(rtwdev, center_chan, primary_chan, band, bandwidth); @@ -964,7 +1281,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re chip->ops->set_channel(rtwdev, center_chan, bandwidth, hal->current_primary_channel_index); -@@ -1746,7 +1773,8 @@ +@@ -1746,7 +1776,8 @@ update_firmware_info(rtwdev, fw); complete_all(&fw->completion); @@ -974,7 +1291,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re fw->version, fw->sub_version, fw->sub_index, fw->h2c_version); } -@@ -1772,6 +1800,7 @@ +@@ -1772,6 +1803,7 @@ return -ENOENT; } @@ -982,7 +1299,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re fw->rtwdev = rtwdev; init_completion(&fw->completion); -@@ -1796,6 +1825,14 @@ +@@ -1796,6 +1828,14 @@ rtwdev->hci.rpwm_addr = 0x03d9; rtwdev->hci.cpwm_addr = 0x03da; break; @@ -997,7 +1314,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re default: rtw_err(rtwdev, "unsupported hci type\n"); return -EINVAL; -@@ -1986,7 +2023,7 @@ +@@ -1986,7 +2026,7 @@ if (!rfe_def) return -ENODEV; @@ -1006,7 +1323,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re rtw_phy_init_tx_power(rtwdev); if (rfe_def->agc_btg_tbl) -@@ -2080,13 +2117,10 @@ +@@ -2080,13 +2120,10 @@ skb_queue_head_init(&rtwdev->coex.queue); skb_queue_head_init(&rtwdev->tx_report.queue); @@ -1020,7 +1337,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re mutex_init(&rtwdev->hal.tx_power_mutex); init_waitqueue_head(&rtwdev->coex.wait); -@@ -2158,7 +2192,6 @@ +@@ -2158,7 +2195,6 @@ } mutex_destroy(&rtwdev->mutex); @@ -1028,7 +1345,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re mutex_destroy(&rtwdev->hal.tx_power_mutex); } EXPORT_SYMBOL(rtw_core_deinit); -@@ -2169,9 +2202,11 @@ +@@ -2169,9 +2205,11 @@ int max_tx_headroom = 0; int ret; @@ -1041,7 +1358,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re hw->extra_tx_headroom = max_tx_headroom; hw->queues = IEEE80211_NUM_ACS; hw->txq_data_size = sizeof(struct rtw_txq); -@@ -2205,6 +2240,11 @@ +@@ -2205,6 +2243,11 @@ hw->wiphy->max_scan_ssids = RTW_SCAN_MAX_SSIDS; hw->wiphy->max_scan_ie_len = rtw_get_max_scan_ie_len(rtwdev); @@ -1053,7 +1370,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_SCAN_RANDOM_SN); wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL); -@@ -2254,6 +2294,121 @@ +@@ -2254,6 +2297,129 @@ } EXPORT_SYMBOL(rtw_unregister_hw); @@ -1103,6 +1420,9 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re + rtw_dbg(rtwdev, RTW_DBG_STATE, "AP port switch from %d -> %d\n", + rtwvif_ap->port, rtwvif_target->port); + ++ /* Leave LPS so the value swapped are not in PS mode */ ++ rtw_leave_lps(rtwdev); ++ + reg1 = &rtwvif_ap->conf->net_type; + reg2 = &rtwvif_target->conf->net_type; + rtw_swap_reg_mask(rtwdev, reg1, reg2); @@ -1121,6 +1441,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re + + swap(rtwvif_target->port, rtwvif_ap->port); + swap(rtwvif_target->conf, rtwvif_ap->conf); ++ ++ rtw_fw_default_port(rtwdev, rtwvif_target); +} + +void rtw_core_port_switch(struct rtw_dev *rtwdev, struct ieee80211_vif *vif) @@ -1166,18 +1488,21 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re + if (!rtwdev->ap_active) + return; + -+ if (enable) ++ if (enable) { + rtw_write32_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); -+ else ++ rtw_write32_clr(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); ++ } else { + rtw_write32_clr(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); ++ rtw_write32_set(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); ++ } +} + MODULE_AUTHOR("Realtek Corporation"); MODULE_DESCRIPTION("Realtek 802.11ac wireless core module"); MODULE_LICENSE("Dual BSD/GPL"); diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h ---- a/drivers/net/wireless/realtek/rtw88/main.h 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/main.h 2023-06-10 16:36:07.000000000 -0400 +--- a/drivers/net/wireless/realtek/rtw88/main.h 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/main.h 2023-06-22 13:52:09.000000000 -0400 @@ -88,7 +88,7 @@ RTW_BAND_60G = BIT(NL80211_BAND_60GHZ), }; @@ -1203,7 +1528,15 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re enum rtw_wow_flags { RTW_WOW_FLAG_EN_MAGIC_PKT, RTW_WOW_FLAG_EN_REKEY_PKT, -@@ -874,6 +883,10 @@ +@@ -794,6 +803,7 @@ + struct rtw_vif { + enum rtw_net_type net_type; + u16 aid; ++ u8 mac_id; /* for STA mode only */ + u8 mac_addr[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + u8 port; +@@ -874,6 +884,10 @@ bool is_tx2_path); void (*config_txrx_mode)(struct rtw_dev *rtwdev, u8 tx_path, u8 rx_path, bool is_tx2_path); @@ -1214,7 +1547,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re /* for coex */ void (*coex_set_init)(struct rtw_dev *rtwdev); -@@ -1167,6 +1180,7 @@ +@@ -1167,6 +1181,7 @@ u32 txff_size; u32 rxff_size; u32 fw_rxff_size; @@ -1222,7 +1555,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re u8 band; u8 page_size; u8 csi_buf_pg_num; -@@ -1504,8 +1518,6 @@ +@@ -1504,8 +1519,6 @@ }; struct rtw_coex { @@ -1231,7 +1564,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re struct sk_buff_head queue; wait_queue_head_t wait; -@@ -1854,6 +1866,7 @@ +@@ -1854,6 +1867,7 @@ u16 h2c_version; u32 feature; u32 feature_ext; @@ -1239,7 +1572,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re }; enum rtw_sar_sources { -@@ -1871,7 +1884,7 @@ +@@ -1871,7 +1885,7 @@ RTW_SAR_BAND_NR, }; @@ -1248,7 +1581,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re * which might not re-use same format with array common. */ union rtw_sar_cfg { -@@ -1890,7 +1903,9 @@ +@@ -1890,7 +1904,9 @@ u8 cut_version; u8 mp_chip; u8 oem_id; @@ -1258,7 +1591,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re u8 ps_mode; u8 current_channel; -@@ -1997,9 +2012,6 @@ +@@ -1997,9 +2013,6 @@ /* ensures exclusive access from mac80211 callbacks */ struct mutex mutex; @@ -1268,7 +1601,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re /* watch dog every 2 sec */ struct delayed_work watch_dog_work; u32 watch_dog_cnt; -@@ -2023,10 +2035,8 @@ +@@ -2023,10 +2036,8 @@ struct rtw_tx_report tx_report; struct { @@ -1280,7 +1613,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re u32 seq; } h2c; -@@ -2041,6 +2051,7 @@ +@@ -2041,6 +2052,7 @@ u8 sta_cnt; u32 rts_threshold; @@ -1288,7 +1621,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re DECLARE_BITMAP(mac_id_map, RTW_MAX_MAC_ID_NUM); DECLARE_BITMAP(flags, NUM_OF_RTW_FLAGS); -@@ -2052,6 +2063,7 @@ +@@ -2052,6 +2064,7 @@ bool need_rfk; struct completion fw_scan_density; @@ -1296,7 +1629,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re /* hci related data, must be last */ u8 priv[] __aligned(sizeof(void *)); -@@ -2193,4 +2205,7 @@ +@@ -2193,4 +2206,7 @@ void rtw_update_channel(struct rtw_dev *rtwdev, u8 center_channel, u8 primary_channel, enum rtw_supported_band band, enum rtw_bandwidth bandwidth); @@ -1305,8 +1638,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re +void rtw_core_enable_beacon(struct rtw_dev *rtwdev, bool enable); #endif diff -Naur a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile ---- a/drivers/net/wireless/realtek/rtw88/Makefile 2023-06-09 04:34:30.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/Makefile 2023-06-11 07:10:49.401245393 -0400 +--- a/drivers/net/wireless/realtek/rtw88/Makefile 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/Makefile 2023-06-22 13:52:09.000000000 -0400 @@ -26,23 +26,53 @@ obj-$(CONFIG_RTW88_8822BE) += rtw88_8822be.o rtw88_8822be-objs := rtw8822be.o @@ -1362,8 +1695,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/ +obj-$(CONFIG_RTW88_USB) += rtw88_usb.o +rtw88_usb-objs := usb.o diff -Naur a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c ---- a/drivers/net/wireless/realtek/rtw88/pci.c 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/pci.c 2023-06-10 16:36:07.000000000 -0400 +--- a/drivers/net/wireless/realtek/rtw88/pci.c 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/pci.c 2023-06-22 13:52:09.000000000 -0400 @@ -30,7 +30,8 @@ [RTW_TX_QUEUE_H2C] = RTK_PCI_TXBD_IDX_H2CQ, }; @@ -1445,7 +1778,19 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/rea static void rtw_pci_release_rsvd_page(struct rtw_pci *rtwpci, struct rtw_pci_tx_ring *ring) { -@@ -797,13 +760,14 @@ +@@ -775,8 +738,9 @@ + u8 q; + + for (q = 0; q < RTK_MAX_TX_QUEUE_NUM; q++) { +- /* It may be not necessary to flush BCN and H2C tx queues. */ +- if (q == RTW_TX_QUEUE_BCN || q == RTW_TX_QUEUE_H2C) ++ /* Unnecessary to flush BCN, H2C and HI tx queues. */ ++ if (q == RTW_TX_QUEUE_BCN || q == RTW_TX_QUEUE_H2C || ++ q == RTW_TX_QUEUE_HI0) + continue; + + if (pci_queues & BIT(q)) +@@ -797,13 +761,14 @@ } else { for (i = 0; i < rtwdev->hw->queues; i++) if (queues & BIT(i)) @@ -1462,7 +1807,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/rea { struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; struct rtw_pci_tx_ring *ring; -@@ -822,7 +786,7 @@ +@@ -822,7 +787,7 @@ static void rtw_pci_tx_kick_off(struct rtw_dev *rtwdev) { struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; @@ -1471,7 +1816,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/rea for (queue = 0; queue < RTK_MAX_TX_QUEUE_NUM; queue++) if (test_and_clear_bit(queue, rtwpci->tx_queued)) -@@ -831,7 +795,8 @@ +@@ -831,7 +796,8 @@ static int rtw_pci_tx_write_data(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, @@ -1481,7 +1826,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/rea { struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; const struct rtw_chip_info *chip = rtwdev->chip; -@@ -949,9 +914,9 @@ +@@ -949,9 +915,9 @@ struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb) { @@ -1492,7 +1837,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/rea int ret; ret = rtw_pci_tx_write_data(rtwdev, pkt_info, skb, queue); -@@ -1580,7 +1545,6 @@ +@@ -1580,7 +1546,6 @@ static void rtw_pci_declaim(struct rtw_dev *rtwdev, struct pci_dev *pdev) { @@ -1501,8 +1846,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/rea } diff -Naur a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c ---- a/drivers/net/wireless/realtek/rtw88/phy.c 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/phy.c 2023-06-10 16:36:07.000000000 -0400 +--- a/drivers/net/wireless/realtek/rtw88/phy.c 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/phy.c 2023-06-22 13:52:09.000000000 -0400 @@ -300,7 +300,7 @@ data.rtwdev = rtwdev; @@ -1531,20 +1876,30 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/rea } diff -Naur a/drivers/net/wireless/realtek/rtw88/ps.c b/drivers/net/wireless/realtek/rtw88/ps.c ---- a/drivers/net/wireless/realtek/rtw88/ps.c 2023-06-14 05:15:34.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/ps.c 2023-06-14 08:12:36.716520345 -0400 -@@ -61,7 +61,7 @@ +--- a/drivers/net/wireless/realtek/rtw88/ps.c 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/ps.c 2023-06-22 13:52:09.000000000 -0400 +@@ -18,6 +18,7 @@ + if (ret) + rtw_err(rtwdev, "leave idle state failed\n"); + ++ rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); + rtw_set_channel(rtwdev); + + return ret; +@@ -61,9 +62,7 @@ return ret; } - rtw_iterate_vifs_atomic(rtwdev, rtw_restore_port_cfg_iter, rtwdev); +- +- rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); + rtw_iterate_vifs(rtwdev, rtw_restore_port_cfg_iter, rtwdev); - rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); - + return 0; + } diff -Naur a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h ---- a/drivers/net/wireless/realtek/rtw88/reg.h 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/reg.h 2023-06-10 16:36:07.000000000 -0400 +--- a/drivers/net/wireless/realtek/rtw88/reg.h 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/reg.h 2023-06-22 13:52:09.000000000 -0400 @@ -87,6 +87,7 @@ #define BIT_LTE_MUX_CTRL_PATH BIT(26) #define REG_HCI_OPT_CTRL 0x0074 @@ -1583,9 +1938,25 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/rea #define REG_RXPKTNUM 0x02B0 #define REG_INT_MIG 0x0304 +@@ -365,6 +378,7 @@ + #define BIT_SIFS_BK_EN BIT(12) + #define REG_TXPAUSE 0x0522 + #define BIT_AC_QUEUE GENMASK(7, 0) ++#define BIT_HIGH_QUEUE BIT(5) + #define REG_RD_CTRL 0x0524 + #define BIT_EDCCA_MSK_CNTDOWN_EN BIT(11) + #define BIT_DIS_TXOP_CFE BIT(10) +@@ -397,6 +411,7 @@ + #define REG_TCR 0x0604 + #define BIT_PWRMGT_HWDATA_EN BIT(7) + #define BIT_TCR_UPDATE_TIMIE BIT(5) ++#define BIT_TCR_UPDATE_HGQMD BIT(4) + #define REG_RCR 0x0608 + #define BIT_APP_FCS BIT(31) + #define BIT_APP_MIC BIT(30) diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c ---- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c 2023-06-09 04:34:30.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c 2023-06-11 07:10:49.400245409 -0400 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c 2023-06-22 13:52:09.000000000 -0400 @@ -210,6 +210,18 @@ ether_addr_copy(efuse->addr, map->e.mac_addr); } @@ -1618,7 +1989,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireles default: /* unsupported now */ return -ENOTSUPP; -@@ -1945,6 +1963,24 @@ +@@ -1945,6 +1963,26 @@ dm_info->pwr_trk_triggered = false; } @@ -1629,21 +2000,23 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireles + size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */ + __le16 chksum = 0; + __le16 *data = (__le16 *)(txdesc); ++ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc; + -+ SET_TX_DESC_TXDESC_CHECKSUM(txdesc, 0x0000); ++ le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM); + + while (words--) + chksum ^= *data++; + + chksum = ~chksum; + -+ SET_TX_DESC_TXDESC_CHECKSUM(txdesc, __le16_to_cpu(chksum)); ++ le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum), ++ RTW_TX_DESC_W7_TXDESC_CHECKSUM); +} + static struct rtw_chip_ops rtw8723d_ops = { .phy_set_param = rtw8723d_phy_set_param, .read_efuse = rtw8723d_read_efuse, -@@ -1965,6 +2001,7 @@ +@@ -1965,6 +2003,7 @@ .config_bfee = NULL, .set_gid_table = NULL, .cfg_csi_rate = NULL, @@ -1651,7 +2024,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireles .coex_set_init = rtw8723d_coex_cfg_init, .coex_set_ant_switch = NULL, -@@ -2715,6 +2752,7 @@ +@@ -2715,6 +2754,7 @@ .ptct_efuse_size = 96 + 1, .txff_size = 32768, .rxff_size = 16384, @@ -1660,8 +2033,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireles .is_pwr_by_rate_dec = true, .max_power_index = 0x3f, diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8723d.h b/drivers/net/wireless/realtek/rtw88/rtw8723d.h ---- a/drivers/net/wireless/realtek/rtw88/rtw8723d.h 2023-06-09 04:34:30.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h 2023-06-11 07:10:49.400245409 -0400 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.h 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h 2023-06-22 13:52:09.000000000 -0400 @@ -41,6 +41,19 @@ u8 sub_device_id[2]; }; @@ -1696,8 +2069,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8723d.h b/drivers/net/wireles extern const struct rtw_chip_info rtw8723d_hw_spec; diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c ---- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c 2023-06-10 16:36:07.000000000 -0400 +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c 2023-06-22 13:52:09.000000000 -0400 @@ -26,6 +26,18 @@ ether_addr_copy(efuse->addr, map->e.mac_addr); } @@ -1812,8 +2185,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireles .is_pwr_by_rate_dec = true, .max_power_index = 0x3f, diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8821c.h b/drivers/net/wireless/realtek/rtw88/rtw8821c.h ---- a/drivers/net/wireless/realtek/rtw88/rtw8821c.h 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.h 2023-06-10 16:36:07.000000000 -0400 +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.h 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.h 2023-06-22 13:52:09.000000000 -0400 @@ -9,6 +9,26 @@ #define RCR_VHT_ACK BIT(26) @@ -1863,8 +2236,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8821c.h b/drivers/net/wireles }; diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c ---- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c 2023-06-10 16:36:07.000000000 -0400 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c 2023-06-22 13:52:09.000000000 -0400 @@ -26,6 +26,18 @@ ether_addr_copy(efuse->addr, map->e.mac_addr); } @@ -1930,8 +2303,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireles .is_pwr_by_rate_dec = true, .max_power_index = 0x3f, diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822b.h b/drivers/net/wireless/realtek/rtw88/rtw8822b.h ---- a/drivers/net/wireless/realtek/rtw88/rtw8822b.h 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.h 2023-06-10 16:36:07.000000000 -0400 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.h 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.h 2023-06-22 13:52:09.000000000 -0400 @@ -65,6 +65,11 @@ u8 res7; }; @@ -1956,8 +2329,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822b.h b/drivers/net/wireles }; diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c ---- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c 2023-06-10 16:36:07.000000000 -0400 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c 2023-06-22 13:52:09.000000000 -0400 @@ -29,6 +29,18 @@ ether_addr_copy(efuse->addr, map->e.mac_addr); } @@ -2035,8 +2408,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireles .is_pwr_by_rate_dec = false, .max_power_index = 0x7f, diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822c.h b/drivers/net/wireless/realtek/rtw88/rtw8822c.h ---- a/drivers/net/wireless/realtek/rtw88/rtw8822c.h 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.h 2023-06-10 16:36:07.000000000 -0400 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.h 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.h 2023-06-22 13:52:09.000000000 -0400 @@ -16,6 +16,11 @@ u8 res2[0x3d]; }; @@ -2061,9 +2434,126 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822c.h b/drivers/net/wireles }; diff -Naur a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c ---- a/drivers/net/wireless/realtek/rtw88/tx.c 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/tx.c 2023-06-10 16:36:07.000000000 -0400 -@@ -682,3 +682,44 @@ +--- a/drivers/net/wireless/realtek/rtw88/tx.c 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/tx.c 2023-06-22 13:52:09.000000000 -0400 +@@ -34,43 +34,57 @@ + + void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb) + { +- __le32 *txdesc = (__le32 *)skb->data; ++ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data; ++ bool more_data = false; ++ ++ if (pkt_info->qsel == TX_DESC_QSEL_HIGH) ++ more_data = true; ++ ++ tx_desc->w0 = le32_encode_bits(pkt_info->tx_pkt_size, RTW_TX_DESC_W0_TXPKTSIZE) | ++ le32_encode_bits(pkt_info->offset, RTW_TX_DESC_W0_OFFSET) | ++ le32_encode_bits(pkt_info->bmc, RTW_TX_DESC_W0_BMC) | ++ le32_encode_bits(pkt_info->ls, RTW_TX_DESC_W0_LS) | ++ le32_encode_bits(pkt_info->dis_qselseq, RTW_TX_DESC_W0_DISQSELSEQ); ++ ++ tx_desc->w1 = le32_encode_bits(pkt_info->qsel, RTW_TX_DESC_W1_QSEL) | ++ le32_encode_bits(pkt_info->rate_id, RTW_TX_DESC_W1_RATE_ID) | ++ le32_encode_bits(pkt_info->sec_type, RTW_TX_DESC_W1_SEC_TYPE) | ++ le32_encode_bits(pkt_info->pkt_offset, RTW_TX_DESC_W1_PKT_OFFSET) | ++ le32_encode_bits(more_data, RTW_TX_DESC_W1_MORE_DATA); ++ ++ tx_desc->w2 = le32_encode_bits(pkt_info->ampdu_en, RTW_TX_DESC_W2_AGG_EN) | ++ le32_encode_bits(pkt_info->report, RTW_TX_DESC_W2_SPE_RPT) | ++ le32_encode_bits(pkt_info->ampdu_density, RTW_TX_DESC_W2_AMPDU_DEN) | ++ le32_encode_bits(pkt_info->bt_null, RTW_TX_DESC_W2_BT_NULL); ++ ++ tx_desc->w3 = le32_encode_bits(pkt_info->hw_ssn_sel, RTW_TX_DESC_W3_HW_SSN_SEL) | ++ le32_encode_bits(pkt_info->use_rate, RTW_TX_DESC_W3_USE_RATE) | ++ le32_encode_bits(pkt_info->dis_rate_fallback, RTW_TX_DESC_W3_DISDATAFB) | ++ le32_encode_bits(pkt_info->rts, RTW_TX_DESC_W3_USE_RTS) | ++ le32_encode_bits(pkt_info->nav_use_hdr, RTW_TX_DESC_W3_NAVUSEHDR) | ++ le32_encode_bits(pkt_info->ampdu_factor, RTW_TX_DESC_W3_MAX_AGG_NUM); ++ ++ tx_desc->w4 = le32_encode_bits(pkt_info->rate, RTW_TX_DESC_W4_DATARATE); ++ ++ tx_desc->w5 = le32_encode_bits(pkt_info->short_gi, RTW_TX_DESC_W5_DATA_SHORT) | ++ le32_encode_bits(pkt_info->bw, RTW_TX_DESC_W5_DATA_BW) | ++ le32_encode_bits(pkt_info->ldpc, RTW_TX_DESC_W5_DATA_LDPC) | ++ le32_encode_bits(pkt_info->stbc, RTW_TX_DESC_W5_DATA_STBC); ++ ++ tx_desc->w6 = le32_encode_bits(pkt_info->sn, RTW_TX_DESC_W6_SW_DEFINE); ++ ++ tx_desc->w8 = le32_encode_bits(pkt_info->en_hwseq, RTW_TX_DESC_W8_EN_HWSEQ); ++ ++ tx_desc->w9 = le32_encode_bits(pkt_info->seq, RTW_TX_DESC_W9_SW_SEQ); + +- SET_TX_DESC_TXPKTSIZE(txdesc, pkt_info->tx_pkt_size); +- SET_TX_DESC_OFFSET(txdesc, pkt_info->offset); +- SET_TX_DESC_PKT_OFFSET(txdesc, pkt_info->pkt_offset); +- SET_TX_DESC_QSEL(txdesc, pkt_info->qsel); +- SET_TX_DESC_BMC(txdesc, pkt_info->bmc); +- SET_TX_DESC_RATE_ID(txdesc, pkt_info->rate_id); +- SET_TX_DESC_DATARATE(txdesc, pkt_info->rate); +- SET_TX_DESC_DISDATAFB(txdesc, pkt_info->dis_rate_fallback); +- SET_TX_DESC_USE_RATE(txdesc, pkt_info->use_rate); +- SET_TX_DESC_SEC_TYPE(txdesc, pkt_info->sec_type); +- SET_TX_DESC_DATA_BW(txdesc, pkt_info->bw); +- SET_TX_DESC_SW_SEQ(txdesc, pkt_info->seq); +- SET_TX_DESC_MAX_AGG_NUM(txdesc, pkt_info->ampdu_factor); +- SET_TX_DESC_AMPDU_DENSITY(txdesc, pkt_info->ampdu_density); +- SET_TX_DESC_DATA_STBC(txdesc, pkt_info->stbc); +- SET_TX_DESC_DATA_LDPC(txdesc, pkt_info->ldpc); +- SET_TX_DESC_AGG_EN(txdesc, pkt_info->ampdu_en); +- SET_TX_DESC_LS(txdesc, pkt_info->ls); +- SET_TX_DESC_DATA_SHORT(txdesc, pkt_info->short_gi); +- SET_TX_DESC_SPE_RPT(txdesc, pkt_info->report); +- SET_TX_DESC_SW_DEFINE(txdesc, pkt_info->sn); +- SET_TX_DESC_USE_RTS(txdesc, pkt_info->rts); + if (pkt_info->rts) { +- SET_TX_DESC_RTSRATE(txdesc, DESC_RATE24M); +- SET_TX_DESC_DATA_RTS_SHORT(txdesc, 1); +- } +- SET_TX_DESC_DISQSELSEQ(txdesc, pkt_info->dis_qselseq); +- SET_TX_DESC_EN_HWSEQ(txdesc, pkt_info->en_hwseq); +- SET_TX_DESC_HW_SSN_SEL(txdesc, pkt_info->hw_ssn_sel); +- SET_TX_DESC_NAVUSEHDR(txdesc, pkt_info->nav_use_hdr); +- SET_TX_DESC_BT_NULL(txdesc, pkt_info->bt_null); +- if (pkt_info->tim_offset) { +- SET_TX_DESC_TIM_EN(txdesc, 1); +- SET_TX_DESC_TIM_OFFSET(txdesc, pkt_info->tim_offset); ++ tx_desc->w4 |= le32_encode_bits(DESC_RATE24M, RTW_TX_DESC_W4_RTSRATE); ++ tx_desc->w5 |= le32_encode_bits(1, RTW_TX_DESC_W5_DATA_RTS_SHORT); + } ++ ++ if (pkt_info->tim_offset) ++ tx_desc->w9 |= le32_encode_bits(1, RTW_TX_DESC_W9_TIM_EN) | ++ le32_encode_bits(pkt_info->tim_offset, RTW_TX_DESC_W9_TIM_OFFSET); + } + EXPORT_SYMBOL(rtw_tx_fill_tx_desc); + +@@ -635,9 +649,8 @@ + rcu_read_unlock(); + } + +-void rtw_tx_work(struct work_struct *w) ++void __rtw_tx_work(struct rtw_dev *rtwdev) + { +- struct rtw_dev *rtwdev = container_of(w, struct rtw_dev, tx_work); + struct rtw_txq *rtwtxq, *tmp; + + spin_lock_bh(&rtwdev->txq_lock); +@@ -658,6 +671,13 @@ + spin_unlock_bh(&rtwdev->txq_lock); + } + ++void rtw_tx_work(struct work_struct *w) ++{ ++ struct rtw_dev *rtwdev = container_of(w, struct rtw_dev, tx_work); ++ ++ __rtw_tx_work(rtwdev); ++} ++ + void rtw_txq_init(struct rtw_dev *rtwdev, struct ieee80211_txq *txq) + { + struct rtw_txq *rtwtxq; +@@ -682,3 +702,44 @@ list_del_init(&rtwtxq->list); spin_unlock_bh(&rtwdev->txq_lock); } @@ -2109,24 +2599,133 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/real +} +EXPORT_SYMBOL(rtw_tx_queue_mapping); diff -Naur a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/realtek/rtw88/tx.h ---- a/drivers/net/wireless/realtek/rtw88/tx.h 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/tx.h 2023-06-10 16:36:07.000000000 -0400 -@@ -71,6 +71,14 @@ - le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(15)) - #define SET_TX_DESC_BT_NULL(txdesc, value) \ - le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(23)) -+#define SET_TX_DESC_TXDESC_CHECKSUM(txdesc, value) \ -+ le32p_replace_bits((__le32 *)(txdesc) + 0x07, value, GENMASK(15, 0)) -+#define SET_TX_DESC_DMA_TXAGG_NUM(txdesc, value) \ -+ le32p_replace_bits((__le32 *)(txdesc) + 0x07, value, GENMASK(31, 24)) -+#define GET_TX_DESC_PKT_OFFSET(txdesc) \ -+ le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(28, 24)) -+#define GET_TX_DESC_QSEL(txdesc) \ -+ le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(12, 8)) +--- a/drivers/net/wireless/realtek/rtw88/tx.h 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/tx.h 2023-06-22 13:52:09.000000000 -0400 +@@ -9,68 +9,53 @@ + + #define RTW_TX_PROBE_TIMEOUT msecs_to_jiffies(500) + +-#define SET_TX_DESC_TXPKTSIZE(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, GENMASK(15, 0)) +-#define SET_TX_DESC_OFFSET(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, GENMASK(23, 16)) +-#define SET_TX_DESC_PKT_OFFSET(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x01, value, GENMASK(28, 24)) +-#define SET_TX_DESC_QSEL(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x01, value, GENMASK(12, 8)) +-#define SET_TX_DESC_BMC(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, BIT(24)) +-#define SET_TX_DESC_RATE_ID(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x01, value, GENMASK(20, 16)) +-#define SET_TX_DESC_DATARATE(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x04, value, GENMASK(6, 0)) +-#define SET_TX_DESC_DISDATAFB(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(10)) +-#define SET_TX_DESC_USE_RATE(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(8)) +-#define SET_TX_DESC_SEC_TYPE(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x01, value, GENMASK(23, 22)) +-#define SET_TX_DESC_DATA_BW(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, GENMASK(6, 5)) +-#define SET_TX_DESC_SW_SEQ(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x09, value, GENMASK(23, 12)) +-#define SET_TX_DESC_TIM_EN(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x09, value, BIT(7)) +-#define SET_TX_DESC_TIM_OFFSET(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x09, value, GENMASK(6, 0)) +-#define SET_TX_DESC_MAX_AGG_NUM(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, GENMASK(21, 17)) +-#define SET_TX_DESC_USE_RTS(tx_desc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(12)) +-#define SET_TX_DESC_RTSRATE(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x04, value, GENMASK(28, 24)) +-#define SET_TX_DESC_DATA_RTS_SHORT(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, BIT(12)) +-#define SET_TX_DESC_AMPDU_DENSITY(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, GENMASK(22, 20)) +-#define SET_TX_DESC_DATA_STBC(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, GENMASK(9, 8)) +-#define SET_TX_DESC_DATA_LDPC(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, BIT(7)) +-#define SET_TX_DESC_AGG_EN(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(12)) +-#define SET_TX_DESC_LS(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, BIT(26)) +-#define SET_TX_DESC_DATA_SHORT(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, BIT(4)) +-#define SET_TX_DESC_SPE_RPT(tx_desc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(19)) +-#define SET_TX_DESC_SW_DEFINE(tx_desc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x06, value, GENMASK(11, 0)) +-#define SET_TX_DESC_DISQSELSEQ(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, BIT(31)) +-#define SET_TX_DESC_EN_HWSEQ(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x08, value, BIT(15)) +-#define SET_TX_DESC_HW_SSN_SEL(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, GENMASK(7, 6)) +-#define SET_TX_DESC_NAVUSEHDR(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(15)) +-#define SET_TX_DESC_BT_NULL(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(23)) ++struct rtw_tx_desc { ++ __le32 w0; ++ __le32 w1; ++ __le32 w2; ++ __le32 w3; ++ __le32 w4; ++ __le32 w5; ++ __le32 w6; ++ __le32 w7; ++ __le32 w8; ++ __le32 w9; ++} __packed; ++ ++#define RTW_TX_DESC_W0_TXPKTSIZE GENMASK(15, 0) ++#define RTW_TX_DESC_W0_OFFSET GENMASK(23, 16) ++#define RTW_TX_DESC_W0_BMC BIT(24) ++#define RTW_TX_DESC_W0_LS BIT(26) ++#define RTW_TX_DESC_W0_DISQSELSEQ BIT(31) ++#define RTW_TX_DESC_W1_QSEL GENMASK(12, 8) ++#define RTW_TX_DESC_W1_RATE_ID GENMASK(20, 16) ++#define RTW_TX_DESC_W1_SEC_TYPE GENMASK(23, 22) ++#define RTW_TX_DESC_W1_PKT_OFFSET GENMASK(28, 24) ++#define RTW_TX_DESC_W1_MORE_DATA BIT(29) ++#define RTW_TX_DESC_W2_AGG_EN BIT(12) ++#define RTW_TX_DESC_W2_SPE_RPT BIT(19) ++#define RTW_TX_DESC_W2_AMPDU_DEN GENMASK(22, 20) ++#define RTW_TX_DESC_W2_BT_NULL BIT(23) ++#define RTW_TX_DESC_W3_HW_SSN_SEL GENMASK(7, 6) ++#define RTW_TX_DESC_W3_USE_RATE BIT(8) ++#define RTW_TX_DESC_W3_DISDATAFB BIT(10) ++#define RTW_TX_DESC_W3_USE_RTS BIT(12) ++#define RTW_TX_DESC_W3_NAVUSEHDR BIT(15) ++#define RTW_TX_DESC_W3_MAX_AGG_NUM GENMASK(21, 17) ++#define RTW_TX_DESC_W4_DATARATE GENMASK(6, 0) ++#define RTW_TX_DESC_W4_RTSRATE GENMASK(28, 24) ++#define RTW_TX_DESC_W5_DATA_SHORT BIT(4) ++#define RTW_TX_DESC_W5_DATA_BW GENMASK(6, 5) ++#define RTW_TX_DESC_W5_DATA_LDPC BIT(7) ++#define RTW_TX_DESC_W5_DATA_STBC GENMASK(9, 8) ++#define RTW_TX_DESC_W5_DATA_RTS_SHORT BIT(12) ++#define RTW_TX_DESC_W6_SW_DEFINE GENMASK(11, 0) ++#define RTW_TX_DESC_W7_TXDESC_CHECKSUM GENMASK(15, 0) ++#define RTW_TX_DESC_W7_DMA_TXAGG_NUM GENMASK(31, 24) ++#define RTW_TX_DESC_W8_EN_HWSEQ BIT(15) ++#define RTW_TX_DESC_W9_SW_SEQ GENMASK(23, 12) ++#define RTW_TX_DESC_W9_TIM_EN BIT(7) ++#define RTW_TX_DESC_W9_TIM_OFFSET GENMASK(6, 0) enum rtw_tx_desc_queue_select { TX_DESC_QSEL_TID0 = 0, -@@ -123,4 +131,30 @@ +@@ -103,6 +88,7 @@ + void rtw_txq_init(struct rtw_dev *rtwdev, struct ieee80211_txq *txq); + void rtw_txq_cleanup(struct rtw_dev *rtwdev, struct ieee80211_txq *txq); + void rtw_tx_work(struct work_struct *w); ++void __rtw_tx_work(struct rtw_dev *rtwdev); + void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct ieee80211_sta *sta, +@@ -123,4 +109,32 @@ struct rtw_tx_pkt_info *pkt_info, u8 *buf, u32 size); @@ -2138,13 +2737,15 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/real +{ + __le16 chksum = 0; + __le16 *data = (__le16 *)(txdesc); ++ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc; + -+ SET_TX_DESC_TXDESC_CHECKSUM(txdesc, 0x0000); ++ le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM); + + while (words--) + chksum ^= *data++; + -+ SET_TX_DESC_TXDESC_CHECKSUM(txdesc, __le16_to_cpu(chksum)); ++ le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum), ++ RTW_TX_DESC_W7_TXDESC_CHECKSUM); +} + +static inline void rtw_tx_fill_txdesc_checksum(struct rtw_dev *rtwdev, @@ -2158,8 +2759,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/real + #endif diff -Naur a/drivers/net/wireless/realtek/rtw88/util.c b/drivers/net/wireless/realtek/rtw88/util.c ---- a/drivers/net/wireless/realtek/rtw88/util.c 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/util.c 2023-06-10 16:36:07.000000000 -0400 +--- a/drivers/net/wireless/realtek/rtw88/util.c 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/util.c 2023-06-22 13:52:09.000000000 -0400 @@ -105,3 +105,106 @@ *mcs = rate - DESC_RATEMCS0; } @@ -2268,8 +2869,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/util.c b/drivers/net/wireless/re + } +} diff -Naur a/drivers/net/wireless/realtek/rtw88/util.h b/drivers/net/wireless/realtek/rtw88/util.h ---- a/drivers/net/wireless/realtek/rtw88/util.h 2023-06-05 03:26:22.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/util.h 2023-06-10 16:36:07.000000000 -0400 +--- a/drivers/net/wireless/realtek/rtw88/util.h 2023-06-21 10:01:03.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/util.h 2023-06-22 13:52:09.000000000 -0400 @@ -7,9 +7,6 @@ struct rtw_dev; diff --git a/patch/misc/rtw88/6.1/002-rtw88-linux-next.patch b/patch/misc/rtw88/6.1/002-rtw88-linux-next.patch index 21ac7ba7cc..057082b611 100644 --- a/patch/misc/rtw88/6.1/002-rtw88-linux-next.patch +++ b/patch/misc/rtw88/6.1/002-rtw88-linux-next.patch @@ -1,5 +1,5 @@ ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723ds.c 2023-06-11 07:10:49.401245393 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723ds.c 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) Martin Blumenstingl @@ -42,8 +42,8 @@ +MODULE_AUTHOR("Martin Blumenstingl "); +MODULE_DESCRIPTION("Realtek 802.11n wireless 8723ds driver"); +MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723du.c 2023-06-10 16:36:07.000000000 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723du.c 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation @@ -81,8 +81,8 @@ +MODULE_AUTHOR("Hans Ulli Kroll "); +MODULE_DESCRIPTION("Realtek 802.11n wireless 8723du driver"); +MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821cs.c 2023-06-10 16:36:07.000000000 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821cs.c 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) Martin Blumenstingl @@ -120,8 +120,8 @@ +MODULE_AUTHOR("Martin Blumenstingl "); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821cs driver"); +MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821cu.c 2023-06-10 16:36:07.000000000 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821cu.c 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation @@ -173,8 +173,8 @@ +MODULE_AUTHOR("Hans Ulli Kroll "); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821cu driver"); +MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822bs.c 2023-06-10 16:36:07.000000000 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822bs.c 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) Jernej Skrabec @@ -212,8 +212,8 @@ +MODULE_AUTHOR("Jernej Skrabec "); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822bs driver"); +MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822bu.c 2023-06-10 16:36:07.000000000 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822bu.c 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation @@ -305,8 +305,8 @@ +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822bu driver"); +MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822cs.c 2023-06-10 16:36:07.000000000 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822cs.c 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) Martin Blumenstingl @@ -344,8 +344,8 @@ +MODULE_AUTHOR("Martin Blumenstingl "); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822cs driver"); +MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822cu.c 2023-06-10 16:36:07.000000000 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822cu.c 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation @@ -391,8 +391,8 @@ +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822cu driver"); +MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/sdio.c 2023-06-11 07:10:49.399245425 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/sdio.c 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,1404 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright (C) 2021 Martin Blumenstingl @@ -1798,8 +1798,8 @@ +MODULE_AUTHOR("Jernej Skrabec"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless SDIO driver"); +MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/sdio.h 2023-06-10 16:36:07.000000000 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/sdio.h 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,178 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright (C) 2021 Martin Blumenstingl @@ -1979,9 +1979,9 @@ +} + +#endif ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/usb.c 2023-06-10 16:36:07.000000000 -0400 -@@ -0,0 +1,924 @@ +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/usb.c 2023-06-22 13:52:09.000000000 -0400 +@@ -0,0 +1,931 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ @@ -2008,11 +2008,12 @@ +static void rtw_usb_fill_tx_checksum(struct rtw_usb *rtwusb, + struct sk_buff *skb, int agg_num) +{ ++ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data; + struct rtw_dev *rtwdev = rtwusb->rtwdev; + struct rtw_tx_pkt_info pkt_info; + -+ SET_TX_DESC_DMA_TXAGG_NUM(skb->data, agg_num); -+ pkt_info.pkt_offset = GET_TX_DESC_PKT_OFFSET(skb->data); ++ le32p_replace_bits(&tx_desc->w7, agg_num, RTW_TX_DESC_W7_DMA_TXAGG_NUM); ++ pkt_info.pkt_offset = le32_get_bits(tx_desc->w1, RTW_TX_DESC_W1_PKT_OFFSET); + rtw_tx_fill_txdesc_checksum(rtwdev, &pkt_info, skb->data); +} + @@ -2290,11 +2291,13 @@ +static bool rtw_usb_tx_agg_skb(struct rtw_usb *rtwusb, struct sk_buff_head *list) +{ + struct rtw_dev *rtwdev = rtwusb->rtwdev; ++ struct rtw_tx_desc *tx_desc; + struct rtw_usb_txcb *txcb; + struct sk_buff *skb_head; + struct sk_buff *skb_iter; + int agg_num = 0; + unsigned int align_next = 0; ++ u8 qsel; + + if (skb_queue_empty(list)) + return false; @@ -2347,9 +2350,10 @@ + +queue: + skb_queue_tail(&txcb->tx_ack_queue, skb_head); ++ tx_desc = (struct rtw_tx_desc *)skb_head->data; ++ qsel = le32_get_bits(tx_desc->w1, RTW_TX_DESC_W1_QSEL); + -+ rtw_usb_write_port(rtwdev, GET_TX_DESC_QSEL(skb_head->data), skb_head, -+ rtw_usb_write_port_tx_complete, txcb); ++ rtw_usb_write_port(rtwdev, qsel, skb_head, rtw_usb_write_port_tx_complete, txcb); + + return true; +} @@ -2449,6 +2453,9 @@ + + if (unlikely(ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))) + qsel = TX_DESC_QSEL_MGMT; ++ else if (is_broadcast_ether_addr(hdr->addr1) || ++ is_multicast_ether_addr(hdr->addr1)) ++ qsel = TX_DESC_QSEL_HIGH; + else if (skb_get_queue_mapping(skb) <= IEEE80211_AC_BK) + qsel = skb->priority; + else @@ -2519,7 +2526,7 @@ + } + + if (skb_queue_len(&rtwusb->rx_queue) >= RTW_USB_MAX_RXQ_LEN) { -+ rtw_err(rtwdev, "failed to get rx_queue, overflow\n"); ++ dev_dbg_ratelimited(rtwdev->dev, "failed to get rx_queue, overflow\n"); + dev_kfree_skb_any(skb); + continue; + } @@ -2906,8 +2913,8 @@ +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless USB driver"); +MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/usb.h 2023-06-10 16:36:07.000000000 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/usb.h 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,107 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation diff --git a/patch/misc/rtw88/6.1/003-rtw88-add-missing-unwind-goto-for_rtw_download_firmware.patch b/patch/misc/rtw88/6.1/003-rtw88-add-missing-unwind-goto-for_rtw_download_firmware.patch deleted file mode 100644 index e1d032bbf2..0000000000 --- a/patch/misc/rtw88/6.1/003-rtw88-add-missing-unwind-goto-for_rtw_download_firmware.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Ping-Ke Shih @ 2023-06-07 1:27 UTC (permalink / raw) - To: tony0620emma, kvalo; +Cc: s.hauer, dan.carpenter, lkp, linux-wireless - -This flaw is detected by smatch: - drivers/net/wireless/realtek/rtw88/mac.c:748 __rtw_download_firmware() - warn: missing unwind goto? - -Though most things of dlfw_fail have been done by -download_firmware_end_flow() and wlan_cpu_enable(), an exception is that -download_firmware_end_flow() clear BIT_MCUFWDL_EN bit conditionally. -So, make this change to clear the bit. - -diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c -index a168f36c38ece..298663b035808 100644 ---- a/drivers/net/wireless/realtek/rtw88/mac.c -+++ b/drivers/net/wireless/realtek/rtw88/mac.c -@@ -794,8 +794,10 @@ static int __rtw_download_firmware(struct rtw_dev *rtwdev, - - wlan_cpu_enable(rtwdev, true); - -- if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) -- return -EBUSY; -+ if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) { -+ ret = -EBUSY; -+ goto dlfw_fail; -+ } - - ret = download_firmware_validate(rtwdev); - if (ret) --- -2.25.1 diff --git a/patch/misc/rtw88/6.1/004-rtw88-fix-action-frame-transmission-fail-before-association.patch b/patch/misc/rtw88/6.1/004-rtw88-fix-action-frame-transmission-fail-before-association.patch deleted file mode 100644 index a41e6fb153..0000000000 --- a/patch/misc/rtw88/6.1/004-rtw88-fix-action-frame-transmission-fail-before-association.patch +++ /dev/null @@ -1,41 +0,0 @@ -From: Ping-Ke Shih @ 2023-06-15 11:43 UTC (permalink / raw) - To: tony0620emma, kvalo; +Cc: phhuang, linux-wireless - -From: Po-Hao Huang - -For combo chips, antennas were controlled by bluetooth only during -power on. If WiFi wish to do transmission, notification to the coexistence -module are required. Previously we only do this before authentication. -To allow transmission before auth, such as management TX, now we start -the initiation of coexistence earlier so antennas are shared between -WiFi and bluetooth after set_channel(), and frames could then be sent. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih ---- - drivers/net/wireless/realtek/rtw88/ps.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/drivers/net/wireless/realtek/rtw88/ps.c b/drivers/net/wireless/realtek/rtw88/ps.c -index 53933fb38a330..43e80a3a8136d 100644 ---- a/drivers/net/wireless/realtek/rtw88/ps.c -+++ b/drivers/net/wireless/realtek/rtw88/ps.c -@@ -18,6 +18,7 @@ static int rtw_ips_pwr_up(struct rtw_dev *rtwdev) - if (ret) - rtw_err(rtwdev, "leave idle state failed\n"); - -+ rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); - rtw_set_channel(rtwdev); - - return ret; -@@ -63,8 +64,6 @@ int rtw_leave_ips(struct rtw_dev *rtwdev) - - rtw_iterate_vifs(rtwdev, rtw_restore_port_cfg_iter, rtwdev); - -- rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); -- - return 0; - } - --- -2.25.1 diff --git a/patch/misc/rtw88/6.2/001-rtw88-linux-next.patch b/patch/misc/rtw88/6.2/001-rtw88-linux-next.patch index 5c74647e7b..58708fdc9d 100644 --- a/patch/misc/rtw88/6.2/001-rtw88-linux-next.patch +++ b/patch/misc/rtw88/6.2/001-rtw88-linux-next.patch @@ -1,6 +1,6 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/bf.c b/drivers/net/wireless/realtek/rtw88/bf.c --- a/drivers/net/wireless/realtek/rtw88/bf.c 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/bf.c 2023-06-12 05:02:33.131048274 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/bf.c 2023-06-22 13:52:09.000000000 -0400 @@ -49,19 +49,23 @@ sta = ieee80211_find_sta(vif, bssid); @@ -46,9 +46,174 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/bf.c b/drivers/net/wireless/real } void rtw_bf_init_bfer_entry_mu(struct rtw_dev *rtwdev, +diff -Naur a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c +--- a/drivers/net/wireless/realtek/rtw88/debug.c 2023-05-17 07:59:13.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/debug.c 2023-06-22 13:52:09.000000000 -0400 +@@ -183,8 +183,8 @@ + + tmp_len = (count > size - 1 ? size - 1 : count); + +- if (!buffer || copy_from_user(tmp, buffer, tmp_len)) +- return count; ++ if (copy_from_user(tmp, buffer, tmp_len)) ++ return -EFAULT; + + tmp[tmp_len] = '\0'; + +@@ -201,13 +201,16 @@ + char tmp[32 + 1]; + u32 addr, len; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); ++ if (ret) ++ return ret; + + num = sscanf(tmp, "%x %x", &addr, &len); + + if (num != 2) +- return count; ++ return -EINVAL; + + if (len != 1 && len != 2 && len != 4) { + rtw_warn(rtwdev, "read reg setting wrong len\n"); +@@ -288,8 +291,11 @@ + char tmp[32 + 1]; + u32 offset, page_num; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); ++ if (ret) ++ return ret; + + num = sscanf(tmp, "%d %d", &offset, &page_num); + +@@ -314,8 +320,11 @@ + char tmp[32 + 1]; + u32 input; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ if (ret) ++ return ret; + + num = kstrtoint(tmp, 0, &input); + +@@ -338,14 +347,17 @@ + char tmp[32 + 1]; + u32 addr, val, len; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ if (ret) ++ return ret; + + /* write BB/MAC register */ + num = sscanf(tmp, "%x %x %x", &addr, &val, &len); + + if (num != 3) +- return count; ++ return -EINVAL; + + switch (len) { + case 1: +@@ -381,8 +393,11 @@ + char tmp[32 + 1]; + u8 param[8]; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ if (ret) ++ return ret; + + num = sscanf(tmp, "%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx", + ¶m[0], ¶m[1], ¶m[2], ¶m[3], +@@ -408,14 +423,17 @@ + char tmp[32 + 1]; + u32 path, addr, mask, val; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 4); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 4); ++ if (ret) ++ return ret; + + num = sscanf(tmp, "%x %x %x %x", &path, &addr, &mask, &val); + + if (num != 4) { + rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); +- return count; ++ return -EINVAL; + } + + mutex_lock(&rtwdev->mutex); +@@ -438,14 +456,17 @@ + char tmp[32 + 1]; + u32 path, addr, mask; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ if (ret) ++ return ret; + + num = sscanf(tmp, "%x %x %x", &path, &addr, &mask); + + if (num != 3) { + rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); +- return count; ++ return -EINVAL; + } + + debugfs_priv->rf_path = path; +@@ -467,7 +488,9 @@ + char tmp[32 + 1]; + int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ if (ret) ++ return ret; + + ret = kstrtou8(tmp, 0, &fix_rate); + if (ret) { +@@ -860,7 +883,9 @@ + bool enable; + int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ if (ret) ++ return ret; + + ret = kstrtobool(tmp, &enable); + if (ret) { +@@ -930,7 +955,9 @@ + bool input; + int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ if (ret) ++ return ret; + + ret = kstrtobool(tmp, &input); + if (ret) diff -Naur a/drivers/net/wireless/realtek/rtw88/debug.h b/drivers/net/wireless/realtek/rtw88/debug.h --- a/drivers/net/wireless/realtek/rtw88/debug.h 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/debug.h 2023-06-12 05:02:33.132048259 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/debug.h 2023-06-22 13:52:09.000000000 -0400 @@ -24,6 +24,7 @@ RTW_DBG_ADAPTIVITY = 0x00008000, RTW_DBG_HW_SCAN = 0x00010000, @@ -59,8 +224,90 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/debug.h b/drivers/net/wireless/r }; diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c --- a/drivers/net/wireless/realtek/rtw88/fw.c 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/fw.c 2023-06-12 05:02:33.132048259 -0400 -@@ -1393,6 +1393,10 @@ ++++ b/drivers/net/wireless/realtek/rtw88/fw.c 2023-06-22 13:52:09.000000000 -0400 +@@ -308,6 +308,57 @@ + } + EXPORT_SYMBOL(rtw_fw_c2h_cmd_isr); + ++static void rtw_fw_send_h2c_command_register(struct rtw_dev *rtwdev, ++ struct rtw_h2c_register *h2c) ++{ ++ u32 box_reg, box_ex_reg; ++ u8 box_state, box; ++ int ret; ++ ++ rtw_dbg(rtwdev, RTW_DBG_FW, "send H2C content %08x %08x\n", h2c->w0, ++ h2c->w1); ++ ++ lockdep_assert_held(&rtwdev->mutex); ++ ++ box = rtwdev->h2c.last_box_num; ++ switch (box) { ++ case 0: ++ box_reg = REG_HMEBOX0; ++ box_ex_reg = REG_HMEBOX0_EX; ++ break; ++ case 1: ++ box_reg = REG_HMEBOX1; ++ box_ex_reg = REG_HMEBOX1_EX; ++ break; ++ case 2: ++ box_reg = REG_HMEBOX2; ++ box_ex_reg = REG_HMEBOX2_EX; ++ break; ++ case 3: ++ box_reg = REG_HMEBOX3; ++ box_ex_reg = REG_HMEBOX3_EX; ++ break; ++ default: ++ WARN(1, "invalid h2c mail box number\n"); ++ return; ++ } ++ ++ ret = read_poll_timeout_atomic(rtw_read8, box_state, ++ !((box_state >> box) & 0x1), 100, 3000, ++ false, rtwdev, REG_HMETFR); ++ ++ if (ret) { ++ rtw_err(rtwdev, "failed to send h2c command\n"); ++ return; ++ } ++ ++ rtw_write32(rtwdev, box_ex_reg, h2c->w1); ++ rtw_write32(rtwdev, box_reg, h2c->w0); ++ ++ if (++rtwdev->h2c.last_box_num >= 4) ++ rtwdev->h2c.last_box_num = 0; ++} ++ + static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev, + u8 *h2c) + { +@@ -468,6 +519,23 @@ + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); + } + ++void rtw_fw_default_port(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif) ++{ ++ struct rtw_h2c_register h2c = {}; ++ ++ if (rtwvif->net_type != RTW_NET_MGD_LINKED) ++ return; ++ ++ /* Leave LPS before default port H2C so FW timer is correct */ ++ rtw_leave_lps(rtwdev); ++ ++ h2c.w0 = u32_encode_bits(H2C_CMD_DEFAULT_PORT, RTW_H2C_W0_CMDID) | ++ u32_encode_bits(rtwvif->port, RTW_H2C_DEFAULT_PORT_W0_PORTID) | ++ u32_encode_bits(rtwvif->mac_id, RTW_H2C_DEFAULT_PORT_W0_MACID); ++ ++ rtw_fw_send_h2c_command_register(rtwdev, &h2c); ++} ++ + void rtw_fw_wl_ch_info(struct rtw_dev *rtwdev, u8 link, u8 ch, u8 bw) + { + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; +@@ -1393,6 +1461,10 @@ struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; struct rtw_rsvd_page *rsvd_pkt; @@ -71,7 +318,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real list_for_each_entry(rsvd_pkt, &rtwvif->rsvd_page_list, vif_list) { if (rsvd_pkt->type == RSVD_BEACON) list_add(&rsvd_pkt->build_list, -@@ -1614,6 +1618,7 @@ +@@ -1614,6 +1686,7 @@ mutex_lock(&rtwdev->mutex); rtw_fw_download_rsvd_page(rtwdev); @@ -79,7 +326,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real mutex_unlock(&rtwdev->mutex); } -@@ -2155,11 +2160,19 @@ +@@ -2155,11 +2228,19 @@ } rtw_fw_set_scan_offload(rtwdev, &cs_option, rtwvif, &chan_list); out: @@ -100,7 +347,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD)) return; -@@ -2244,6 +2257,7 @@ +@@ -2244,6 +2325,7 @@ if (rtw_is_op_chan(rtwdev, chan)) { rtw_store_op_chan(rtwdev, false); ieee80211_wake_queues(rtwdev->hw); @@ -108,7 +355,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real } } else if (id == RTW_SCAN_NOTIFY_ID_PRESWITCH) { if (IS_CH_5G_BAND(chan)) { -@@ -2262,8 +2276,10 @@ +@@ -2262,8 +2344,10 @@ * if next channel is non-op channel. */ if (!rtw_is_op_chan(rtwdev, chan) && @@ -122,8 +369,42 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real rtw_dbg(rtwdev, RTW_DBG_HW_SCAN, diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h --- a/drivers/net/wireless/realtek/rtw88/fw.h 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/fw.h 2023-06-12 05:02:33.132048259 -0400 -@@ -868,5 +868,5 @@ ++++ b/drivers/net/wireless/realtek/rtw88/fw.h 2023-06-22 13:52:09.000000000 -0400 +@@ -81,6 +81,17 @@ + u8 option; + } __packed; + ++struct rtw_h2c_register { ++ u32 w0; ++ u32 w1; ++} __packed; ++ ++#define RTW_H2C_W0_CMDID GENMASK(7, 0) ++ ++/* H2C_CMD_DEFAULT_PORT command */ ++#define RTW_H2C_DEFAULT_PORT_W0_PORTID GENMASK(15, 8) ++#define RTW_H2C_DEFAULT_PORT_W0_MACID GENMASK(23, 16) ++ + struct rtw_h2c_cmd { + __le32 msg; + __le32 msg_ext; +@@ -530,6 +541,7 @@ + #define H2C_CMD_MEDIA_STATUS_RPT 0x01 + #define H2C_CMD_SET_PWR_MODE 0x20 + #define H2C_CMD_LPS_PG_INFO 0x2b ++#define H2C_CMD_DEFAULT_PORT 0x2c + #define H2C_CMD_RA_INFO 0x40 + #define H2C_CMD_RSSI_MONITOR 0x42 + #define H2C_CMD_BCN_FILTER_OFFLOAD_P0 0x56 +@@ -801,6 +813,7 @@ + void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb); + void rtw_fw_send_general_info(struct rtw_dev *rtwdev); + void rtw_fw_send_phydm_info(struct rtw_dev *rtwdev); ++void rtw_fw_default_port(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif); + + void rtw_fw_do_iqk(struct rtw_dev *rtwdev, struct rtw_iqk_para *para); + void rtw_fw_inform_rfk_status(struct rtw_dev *rtwdev, bool start); +@@ -868,5 +881,5 @@ bool enable); void rtw_hw_scan_status_report(struct rtw_dev *rtwdev, struct sk_buff *skb); void rtw_hw_scan_chan_switch(struct rtw_dev *rtwdev, struct sk_buff *skb); @@ -132,7 +413,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/real #endif diff -Naur a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig --- a/drivers/net/wireless/realtek/rtw88/Kconfig 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/Kconfig 2023-06-12 05:04:19.622514805 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/Kconfig 2023-06-22 13:52:09.000000000 -0400 @@ -16,6 +16,9 @@ config RTW88_PCI tristate @@ -217,8 +498,21 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/r depends on USB diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c --- a/drivers/net/wireless/realtek/rtw88/mac80211.c 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c 2023-06-12 05:02:33.132048259 -0400 -@@ -88,15 +88,6 @@ ++++ b/drivers/net/wireless/realtek/rtw88/mac80211.c 2023-06-22 13:52:09.000000000 -0400 +@@ -43,7 +43,11 @@ + list_add_tail(&rtwtxq->list, &rtwdev->txqs); + spin_unlock_bh(&rtwdev->txq_lock); + +- queue_work(rtwdev->tx_wq, &rtwdev->tx_work); ++ /* ensure to dequeue EAPOL (4/4) at the right time */ ++ if (txq->ac == IEEE80211_AC_VO) ++ __rtw_tx_work(rtwdev); ++ else ++ queue_work(rtwdev->tx_wq, &rtwdev->tx_work); + } + + static int rtw_ops_start(struct ieee80211_hw *hw) +@@ -88,15 +92,6 @@ } } @@ -234,7 +528,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles if (changed & IEEE80211_CONF_CHANGE_CHANNEL) rtw_set_channel(rtwdev); -@@ -155,25 +146,30 @@ +@@ -155,25 +150,32 @@ struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; enum rtw_net_type net_type; u32 config = 0; @@ -259,8 +553,10 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles mutex_lock(&rtwdev->mutex); + port = find_first_zero_bit(rtwdev->hw_port, RTW_PORT_NUM); -+ if (port >= RTW_PORT_NUM) ++ if (port >= RTW_PORT_NUM) { ++ mutex_unlock(&rtwdev->mutex); + return -EINVAL; ++ } + set_bit(port, rtwdev->hw_port); + + rtwvif->port = port; @@ -268,7 +564,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles rtw_leave_lps_deep(rtwdev); switch (vif->type) { -@@ -195,6 +191,7 @@ +@@ -195,6 +197,7 @@ break; default: WARN_ON(1); @@ -276,7 +572,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles mutex_unlock(&rtwdev->mutex); return -EINVAL; } -@@ -206,6 +203,8 @@ +@@ -206,6 +209,8 @@ rtwvif->bcn_ctrl = bcn_ctrl; config |= PORT_SET_BCN_CTRL; rtw_vif_port_config(rtwdev, rtwvif, config); @@ -285,7 +581,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles mutex_unlock(&rtwdev->mutex); -@@ -236,6 +235,8 @@ +@@ -236,6 +241,8 @@ rtwvif->bcn_ctrl = 0; config |= PORT_SET_BCN_CTRL; rtw_vif_port_config(rtwdev, rtwvif, config); @@ -294,7 +590,15 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles mutex_unlock(&rtwdev->mutex); } -@@ -385,7 +386,8 @@ +@@ -375,6 +382,7 @@ + + rtw_fw_download_rsvd_page(rtwdev); + rtw_send_rsvd_page_h2c(rtwdev); ++ rtw_fw_default_port(rtwdev, rtwvif); + rtw_coex_media_status_notify(rtwdev, vif->cfg.assoc); + if (rtw_bf_support) + rtw_bf_assoc(rtwdev, vif, conf); +@@ -385,7 +393,8 @@ * when disconnected by peer */ if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) @@ -304,7 +608,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles } config |= PORT_SET_NET_TYPE; -@@ -395,7 +397,7 @@ +@@ -395,7 +404,7 @@ if (changed & BSS_CHANGED_BSSID) { ether_addr_copy(rtwvif->bssid, conf->bssid); config |= PORT_SET_BSSID; @@ -313,7 +617,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles rtw_clear_op_chan(rtwdev); else rtw_store_op_chan(rtwdev, true); -@@ -409,6 +411,7 @@ +@@ -409,6 +418,7 @@ if (changed & BSS_CHANGED_BEACON) { rtw_set_dtim_period(rtwdev, conf->dtim_period); rtw_fw_download_rsvd_page(rtwdev); @@ -321,7 +625,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles } if (changed & BSS_CHANGED_BEACON_ENABLED) { -@@ -428,6 +431,9 @@ +@@ -428,6 +438,9 @@ if (changed & BSS_CHANGED_ERP_SLOT) rtw_conf_tx(rtwdev, rtwvif); @@ -331,10 +635,11 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles rtw_vif_port_config(rtwdev, rtwvif, config); mutex_unlock(&rtwdev->mutex); -@@ -441,12 +447,27 @@ +@@ -441,12 +454,29 @@ const struct rtw_chip_info *chip = rtwdev->chip; mutex_lock(&rtwdev->mutex); ++ rtw_write32_set(rtwdev, REG_TCR, BIT_TCR_UPDATE_HGQMD); + rtwdev->ap_active = true; + rtw_store_op_chan(rtwdev, true); chip->ops->phy_calibration(rtwdev); @@ -350,6 +655,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles + struct rtw_dev *rtwdev = hw->priv; + + mutex_lock(&rtwdev->mutex); ++ rtw_write32_clr(rtwdev, REG_TCR, BIT_TCR_UPDATE_HGQMD); + rtwdev->ap_active = false; + if (!rtw_core_check_sta_active(rtwdev)) + rtw_clear_op_chan(rtwdev); @@ -359,7 +665,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles static int rtw_ops_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, unsigned int link_id, u16 ac, -@@ -849,7 +870,7 @@ +@@ -849,7 +879,7 @@ rtw_hw_scan_start(rtwdev, vif, req); ret = rtw_hw_scan_offload(rtwdev, vif, true); if (ret) { @@ -368,7 +674,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles rtw_err(rtwdev, "HW scan failed with status: %d\n", ret); } mutex_unlock(&rtwdev->mutex); -@@ -869,7 +890,7 @@ +@@ -869,7 +899,7 @@ return; mutex_lock(&rtwdev->mutex); @@ -377,7 +683,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles mutex_unlock(&rtwdev->mutex); } -@@ -893,7 +914,7 @@ +@@ -893,7 +923,7 @@ struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; if (changed & IEEE80211_RC_BW_CHANGED) @@ -386,7 +692,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles } const struct ieee80211_ops rtw_ops = { -@@ -908,6 +929,7 @@ +@@ -908,6 +938,7 @@ .configure_filter = rtw_ops_configure_filter, .bss_info_changed = rtw_ops_bss_info_changed, .start_ap = rtw_ops_start_ap, @@ -396,7 +702,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles .sta_remove = rtw_ops_sta_remove, diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c --- a/drivers/net/wireless/realtek/rtw88/mac.c 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/mac.c 2023-06-12 05:02:33.132048259 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/mac.c 2023-06-22 13:52:09.000000000 -0400 @@ -7,6 +7,7 @@ #include "reg.h" #include "fw.h" @@ -507,7 +813,20 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/rea /* Disable beacon related functions */ tmp = rtw_read8(rtwdev, REG_BCN_CTRL); bckp[bckp_idx].len = 1; -@@ -1042,6 +1080,9 @@ +@@ -756,8 +794,10 @@ + + wlan_cpu_enable(rtwdev, true); + +- if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) +- return -EBUSY; ++ if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) { ++ ret = -EBUSY; ++ goto dlfw_fail; ++ } + + ret = download_firmware_validate(rtwdev); + if (ret) +@@ -1042,6 +1082,9 @@ else return -EINVAL; break; @@ -517,7 +836,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/rea default: return -EINVAL; } -@@ -1060,8 +1101,12 @@ +@@ -1060,8 +1103,12 @@ if (rtw_chip_wcpu_11ac(rtwdev)) rtw_write32(rtwdev, REG_H2CQ_CSR, BIT_H2CQ_FULL); @@ -531,7 +850,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/rea return 0; } -@@ -1074,7 +1119,7 @@ +@@ -1074,7 +1121,7 @@ u8 csi_buf_pg_num = chip->csi_buf_pg_num; /* config rsvd page num */ @@ -540,7 +859,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/rea fifo->txff_pg_num = chip->txff_size >> 7; if (rtw_chip_wcpu_11n(rtwdev)) fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num; -@@ -1204,6 +1249,9 @@ +@@ -1204,6 +1251,9 @@ else return -EINVAL; break; @@ -552,7 +871,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/rea } diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.h b/drivers/net/wireless/realtek/rtw88/mac.h --- a/drivers/net/wireless/realtek/rtw88/mac.h 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/mac.h 2023-06-12 05:02:33.132048259 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/mac.h 2023-06-22 13:52:09.000000000 -0400 @@ -7,7 +7,6 @@ #define RTW_HW_PORT_NUM 5 @@ -563,7 +882,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.h b/drivers/net/wireless/rea #define REPORT_BUF 128 diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c --- a/drivers/net/wireless/realtek/rtw88/main.c 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/main.c 2023-06-12 05:02:33.133048245 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/main.c 2023-06-22 13:52:09.000000000 -0400 @@ -18,6 +18,7 @@ #include "debug.h" #include "bf.h" @@ -616,7 +935,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re rtw_enter_lps(rtwdev, data.rtwvif->port); rtwdev->watch_dog_cnt++; -@@ -298,6 +319,17 @@ +@@ -298,22 +319,38 @@ return mac_id; } @@ -634,10 +953,16 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta, struct ieee80211_vif *vif) { -@@ -308,12 +340,14 @@ + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; ++ struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + int i; + + si->mac_id = rtw_acquire_macid(rtwdev); if (si->mac_id >= RTW_MAX_MAC_ID_NUM) return -ENOSPC; ++ if (vif->type == NL80211_IFTYPE_STATION && vif->cfg.assoc == 0) ++ rtwvif->mac_id = si->mac_id; + si->rtwdev = rtwdev; si->sta = sta; si->vif = vif; @@ -649,7 +974,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re rtw_update_sta_info(rtwdev, si, true); rtw_fw_media_status_report(rtwdev, si->mac_id, true); -@@ -332,6 +366,8 @@ +@@ -332,6 +369,8 @@ struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; int i; @@ -658,7 +983,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re rtw_release_macid(rtwdev, si->mac_id); if (fw_exist) rtw_fw_media_status_report(rtwdev, si->mac_id, false); -@@ -609,6 +645,7 @@ +@@ -609,6 +648,7 @@ rcu_read_unlock(); rtw_iterate_stas_atomic(rtwdev, rtw_reset_sta_iter, rtwdev); rtw_iterate_vifs_atomic(rtwdev, rtw_reset_vif_iter, rtwdev); @@ -666,7 +991,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re rtw_enter_ips(rtwdev); } -@@ -828,6 +865,9 @@ +@@ -828,6 +868,9 @@ rtw_update_channel(rtwdev, center_chan, primary_chan, band, bandwidth); @@ -676,7 +1001,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re chip->ops->set_channel(rtwdev, center_chan, bandwidth, hal->current_primary_channel_index); -@@ -1785,6 +1825,10 @@ +@@ -1785,6 +1828,10 @@ rtwdev->hci.rpwm_addr = 0x03d9; rtwdev->hci.cpwm_addr = 0x03da; break; @@ -687,7 +1012,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re case RTW_HCI_TYPE_USB: rtwdev->hci.rpwm_addr = 0xfe58; rtwdev->hci.cpwm_addr = 0xfe57; -@@ -1979,7 +2023,7 @@ +@@ -1979,7 +2026,7 @@ if (!rfe_def) return -ENODEV; @@ -696,7 +1021,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re rtw_phy_init_tx_power(rtwdev); if (rfe_def->agc_btg_tbl) -@@ -2158,9 +2202,11 @@ +@@ -2158,9 +2205,11 @@ int max_tx_headroom = 0; int ret; @@ -709,7 +1034,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re hw->extra_tx_headroom = max_tx_headroom; hw->queues = IEEE80211_NUM_ACS; hw->txq_data_size = sizeof(struct rtw_txq); -@@ -2194,6 +2240,11 @@ +@@ -2194,6 +2243,11 @@ hw->wiphy->max_scan_ssids = RTW_SCAN_MAX_SSIDS; hw->wiphy->max_scan_ie_len = rtw_get_max_scan_ie_len(rtwdev); @@ -721,7 +1046,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_SCAN_RANDOM_SN); wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL); -@@ -2243,6 +2294,121 @@ +@@ -2243,6 +2297,129 @@ } EXPORT_SYMBOL(rtw_unregister_hw); @@ -771,6 +1096,9 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re + rtw_dbg(rtwdev, RTW_DBG_STATE, "AP port switch from %d -> %d\n", + rtwvif_ap->port, rtwvif_target->port); + ++ /* Leave LPS so the value swapped are not in PS mode */ ++ rtw_leave_lps(rtwdev); ++ + reg1 = &rtwvif_ap->conf->net_type; + reg2 = &rtwvif_target->conf->net_type; + rtw_swap_reg_mask(rtwdev, reg1, reg2); @@ -789,6 +1117,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re + + swap(rtwvif_target->port, rtwvif_ap->port); + swap(rtwvif_target->conf, rtwvif_ap->conf); ++ ++ rtw_fw_default_port(rtwdev, rtwvif_target); +} + +void rtw_core_port_switch(struct rtw_dev *rtwdev, struct ieee80211_vif *vif) @@ -834,10 +1164,13 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re + if (!rtwdev->ap_active) + return; + -+ if (enable) ++ if (enable) { + rtw_write32_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); -+ else ++ rtw_write32_clr(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); ++ } else { + rtw_write32_clr(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); ++ rtw_write32_set(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); ++ } +} + MODULE_AUTHOR("Realtek Corporation"); @@ -845,7 +1178,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re MODULE_LICENSE("Dual BSD/GPL"); diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h --- a/drivers/net/wireless/realtek/rtw88/main.h 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/main.h 2023-06-12 05:02:33.133048245 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/main.h 2023-06-22 13:52:09.000000000 -0400 @@ -88,7 +88,7 @@ RTW_BAND_60G = BIT(NL80211_BAND_60GHZ), }; @@ -888,7 +1221,15 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re }; enum rtw_bfee_role { -@@ -1168,6 +1180,7 @@ +@@ -791,6 +803,7 @@ + struct rtw_vif { + enum rtw_net_type net_type; + u16 aid; ++ u8 mac_id; /* for STA mode only */ + u8 mac_addr[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + u8 port; +@@ -1168,6 +1181,7 @@ u32 txff_size; u32 rxff_size; u32 fw_rxff_size; @@ -896,7 +1237,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re u8 band; u8 page_size; u8 csi_buf_pg_num; -@@ -1871,7 +1884,7 @@ +@@ -1871,7 +1885,7 @@ RTW_SAR_BAND_NR, }; @@ -905,7 +1246,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re * which might not re-use same format with array common. */ union rtw_sar_cfg { -@@ -1890,7 +1903,9 @@ +@@ -1890,7 +1904,9 @@ u8 cut_version; u8 mp_chip; u8 oem_id; @@ -915,7 +1256,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re u8 ps_mode; u8 current_channel; -@@ -2020,7 +2035,7 @@ +@@ -2020,7 +2036,7 @@ struct rtw_tx_report tx_report; struct { @@ -924,7 +1265,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re u8 last_box_num; u32 seq; } h2c; -@@ -2036,6 +2051,7 @@ +@@ -2036,6 +2052,7 @@ u8 sta_cnt; u32 rts_threshold; @@ -932,7 +1273,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re DECLARE_BITMAP(mac_id_map, RTW_MAX_MAC_ID_NUM); DECLARE_BITMAP(flags, NUM_OF_RTW_FLAGS); -@@ -2047,6 +2063,7 @@ +@@ -2047,6 +2064,7 @@ bool need_rfk; struct completion fw_scan_density; @@ -940,7 +1281,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re /* hci related data, must be last */ u8 priv[] __aligned(sizeof(void *)); -@@ -2188,4 +2205,7 @@ +@@ -2188,4 +2206,7 @@ void rtw_update_channel(struct rtw_dev *rtwdev, u8 center_channel, u8 primary_channel, enum rtw_supported_band band, enum rtw_bandwidth bandwidth); @@ -950,7 +1291,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re #endif diff -Naur a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile --- a/drivers/net/wireless/realtek/rtw88/Makefile 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/Makefile 2023-06-12 05:04:19.622514805 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/Makefile 2023-06-22 13:52:09.000000000 -0400 @@ -26,6 +26,9 @@ obj-$(CONFIG_RTW88_8822BE) += rtw88_8822be.o rtw88_8822be-objs := rtw8822be.o @@ -1001,7 +1342,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/ rtw88_usb-objs := usb.o diff -Naur a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c --- a/drivers/net/wireless/realtek/rtw88/pci.c 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/pci.c 2023-06-12 05:02:33.133048245 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/pci.c 2023-06-22 13:52:09.000000000 -0400 @@ -30,7 +30,8 @@ [RTW_TX_QUEUE_H2C] = RTK_PCI_TXBD_IDX_H2CQ, }; @@ -1083,7 +1424,19 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/rea static void rtw_pci_release_rsvd_page(struct rtw_pci *rtwpci, struct rtw_pci_tx_ring *ring) { -@@ -797,13 +760,14 @@ +@@ -775,8 +738,9 @@ + u8 q; + + for (q = 0; q < RTK_MAX_TX_QUEUE_NUM; q++) { +- /* It may be not necessary to flush BCN and H2C tx queues. */ +- if (q == RTW_TX_QUEUE_BCN || q == RTW_TX_QUEUE_H2C) ++ /* Unnecessary to flush BCN, H2C and HI tx queues. */ ++ if (q == RTW_TX_QUEUE_BCN || q == RTW_TX_QUEUE_H2C || ++ q == RTW_TX_QUEUE_HI0) + continue; + + if (pci_queues & BIT(q)) +@@ -797,13 +761,14 @@ } else { for (i = 0; i < rtwdev->hw->queues; i++) if (queues & BIT(i)) @@ -1100,7 +1453,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/rea { struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; struct rtw_pci_tx_ring *ring; -@@ -822,7 +786,7 @@ +@@ -822,7 +787,7 @@ static void rtw_pci_tx_kick_off(struct rtw_dev *rtwdev) { struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; @@ -1109,7 +1462,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/rea for (queue = 0; queue < RTK_MAX_TX_QUEUE_NUM; queue++) if (test_and_clear_bit(queue, rtwpci->tx_queued)) -@@ -831,7 +795,8 @@ +@@ -831,7 +796,8 @@ static int rtw_pci_tx_write_data(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, @@ -1119,7 +1472,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/rea { struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; const struct rtw_chip_info *chip = rtwdev->chip; -@@ -949,9 +914,9 @@ +@@ -949,9 +915,9 @@ struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb) { @@ -1130,7 +1483,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/rea int ret; ret = rtw_pci_tx_write_data(rtwdev, pkt_info, skb, queue); -@@ -1580,7 +1545,6 @@ +@@ -1580,7 +1546,6 @@ static void rtw_pci_declaim(struct rtw_dev *rtwdev, struct pci_dev *pdev) { @@ -1140,8 +1493,25 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/rea diff -Naur a/drivers/net/wireless/realtek/rtw88/ps.c b/drivers/net/wireless/realtek/rtw88/ps.c --- a/drivers/net/wireless/realtek/rtw88/ps.c 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/ps.c 2023-06-12 05:02:33.133048245 -0400 -@@ -299,3 +299,46 @@ ++++ b/drivers/net/wireless/realtek/rtw88/ps.c 2023-06-22 13:52:09.000000000 -0400 +@@ -18,6 +18,7 @@ + if (ret) + rtw_err(rtwdev, "leave idle state failed\n"); + ++ rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); + rtw_set_channel(rtwdev); + + return ret; +@@ -63,8 +64,6 @@ + + rtw_iterate_vifs(rtwdev, rtw_restore_port_cfg_iter, rtwdev); + +- rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); +- + return 0; + } + +@@ -299,3 +298,46 @@ __rtw_leave_lps_deep(rtwdev); } @@ -1190,7 +1560,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/ps.c b/drivers/net/wireless/real +} diff -Naur a/drivers/net/wireless/realtek/rtw88/ps.h b/drivers/net/wireless/realtek/rtw88/ps.h --- a/drivers/net/wireless/realtek/rtw88/ps.h 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/ps.h 2023-06-12 05:02:33.133048245 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/ps.h 2023-06-22 13:52:09.000000000 -0400 @@ -23,4 +23,6 @@ void rtw_leave_lps(struct rtw_dev *rtwdev); void rtw_leave_lps_deep(struct rtw_dev *rtwdev); @@ -1200,7 +1570,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/ps.h b/drivers/net/wireless/real #endif diff -Naur a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h --- a/drivers/net/wireless/realtek/rtw88/reg.h 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/reg.h 2023-06-12 05:02:33.133048245 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/reg.h 2023-06-22 13:52:09.000000000 -0400 @@ -87,6 +87,7 @@ #define BIT_LTE_MUX_CTRL_PATH BIT(26) #define REG_HCI_OPT_CTRL 0x0074 @@ -1238,9 +1608,25 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/rea #define REG_RXPKTNUM 0x02B0 #define REG_INT_MIG 0x0304 +@@ -366,6 +378,7 @@ + #define BIT_SIFS_BK_EN BIT(12) + #define REG_TXPAUSE 0x0522 + #define BIT_AC_QUEUE GENMASK(7, 0) ++#define BIT_HIGH_QUEUE BIT(5) + #define REG_RD_CTRL 0x0524 + #define BIT_EDCCA_MSK_CNTDOWN_EN BIT(11) + #define BIT_DIS_TXOP_CFE BIT(10) +@@ -398,6 +411,7 @@ + #define REG_TCR 0x0604 + #define BIT_PWRMGT_HWDATA_EN BIT(7) + #define BIT_TCR_UPDATE_TIMIE BIT(5) ++#define BIT_TCR_UPDATE_HGQMD BIT(4) + #define REG_RCR 0x0608 + #define BIT_APP_FCS BIT(31) + #define BIT_APP_MIC BIT(30) diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c --- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c 2023-06-12 05:04:19.621514820 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c 2023-06-22 13:52:09.000000000 -0400 @@ -216,6 +216,12 @@ ether_addr_copy(efuse->addr, map->u.mac_addr); } @@ -1264,7 +1650,27 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireles default: /* unsupported now */ return -ENOTSUPP; -@@ -2743,6 +2752,7 @@ +@@ -1961,15 +1970,17 @@ + size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */ + __le16 chksum = 0; + __le16 *data = (__le16 *)(txdesc); ++ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc; + +- SET_TX_DESC_TXDESC_CHECKSUM(txdesc, 0x0000); ++ le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM); + + while (words--) + chksum ^= *data++; + + chksum = ~chksum; + +- SET_TX_DESC_TXDESC_CHECKSUM(txdesc, __le16_to_cpu(chksum)); ++ le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum), ++ RTW_TX_DESC_W7_TXDESC_CHECKSUM); + } + + static struct rtw_chip_ops rtw8723d_ops = { +@@ -2743,6 +2754,7 @@ .ptct_efuse_size = 96 + 1, .txff_size = 32768, .rxff_size = 16384, @@ -1274,7 +1680,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireles .max_power_index = 0x3f, diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8723d.h b/drivers/net/wireless/realtek/rtw88/rtw8723d.h --- a/drivers/net/wireless/realtek/rtw88/rtw8723d.h 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h 2023-06-12 05:04:19.621514820 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h 2023-06-22 13:52:09.000000000 -0400 @@ -49,6 +49,11 @@ u8 mac_addr[ETH_ALEN]; /* 0x107 */ }; @@ -1297,7 +1703,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8723d.h b/drivers/net/wireles diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c --- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c 2023-06-12 05:02:33.134048230 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c 2023-06-22 13:52:09.000000000 -0400 @@ -32,6 +32,12 @@ ether_addr_copy(efuse->addr, map->u.mac_addr); } @@ -1382,7 +1788,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireles .max_power_index = 0x3f, diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8821c.h b/drivers/net/wireless/realtek/rtw88/rtw8821c.h --- a/drivers/net/wireless/realtek/rtw88/rtw8821c.h 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.h 2023-06-12 05:02:33.134048230 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.h 2023-06-22 13:52:09.000000000 -0400 @@ -65,6 +65,11 @@ u8 res7; }; @@ -1405,7 +1811,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8821c.h b/drivers/net/wireles diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c --- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c 2023-06-12 05:02:33.135048216 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c 2023-06-22 13:52:09.000000000 -0400 @@ -32,6 +32,12 @@ ether_addr_copy(efuse->addr, map->u.mac_addr); } @@ -1439,7 +1845,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireles .max_power_index = 0x3f, diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822b.h b/drivers/net/wireless/realtek/rtw88/rtw8822b.h --- a/drivers/net/wireless/realtek/rtw88/rtw8822b.h 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.h 2023-06-12 05:02:33.135048216 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.h 2023-06-22 13:52:09.000000000 -0400 @@ -65,6 +65,11 @@ u8 res7; }; @@ -1465,7 +1871,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822b.h b/drivers/net/wireles diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c --- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c 2023-06-12 05:02:33.137048187 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c 2023-06-22 13:52:09.000000000 -0400 @@ -35,6 +35,12 @@ ether_addr_copy(efuse->addr, map->u.mac_addr); } @@ -1499,7 +1905,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireles .max_power_index = 0x7f, diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822c.h b/drivers/net/wireless/realtek/rtw88/rtw8822c.h --- a/drivers/net/wireless/realtek/rtw88/rtw8822c.h 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.h 2023-06-12 05:02:33.137048187 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.h 2023-06-22 13:52:09.000000000 -0400 @@ -16,6 +16,11 @@ u8 res2[0x3d]; }; @@ -1525,8 +1931,125 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822c.h b/drivers/net/wireles diff -Naur a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c --- a/drivers/net/wireless/realtek/rtw88/tx.c 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/tx.c 2023-06-12 05:02:33.140048143 -0400 -@@ -682,3 +682,44 @@ ++++ b/drivers/net/wireless/realtek/rtw88/tx.c 2023-06-22 13:52:09.000000000 -0400 +@@ -34,43 +34,57 @@ + + void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb) + { +- __le32 *txdesc = (__le32 *)skb->data; ++ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data; ++ bool more_data = false; ++ ++ if (pkt_info->qsel == TX_DESC_QSEL_HIGH) ++ more_data = true; ++ ++ tx_desc->w0 = le32_encode_bits(pkt_info->tx_pkt_size, RTW_TX_DESC_W0_TXPKTSIZE) | ++ le32_encode_bits(pkt_info->offset, RTW_TX_DESC_W0_OFFSET) | ++ le32_encode_bits(pkt_info->bmc, RTW_TX_DESC_W0_BMC) | ++ le32_encode_bits(pkt_info->ls, RTW_TX_DESC_W0_LS) | ++ le32_encode_bits(pkt_info->dis_qselseq, RTW_TX_DESC_W0_DISQSELSEQ); ++ ++ tx_desc->w1 = le32_encode_bits(pkt_info->qsel, RTW_TX_DESC_W1_QSEL) | ++ le32_encode_bits(pkt_info->rate_id, RTW_TX_DESC_W1_RATE_ID) | ++ le32_encode_bits(pkt_info->sec_type, RTW_TX_DESC_W1_SEC_TYPE) | ++ le32_encode_bits(pkt_info->pkt_offset, RTW_TX_DESC_W1_PKT_OFFSET) | ++ le32_encode_bits(more_data, RTW_TX_DESC_W1_MORE_DATA); ++ ++ tx_desc->w2 = le32_encode_bits(pkt_info->ampdu_en, RTW_TX_DESC_W2_AGG_EN) | ++ le32_encode_bits(pkt_info->report, RTW_TX_DESC_W2_SPE_RPT) | ++ le32_encode_bits(pkt_info->ampdu_density, RTW_TX_DESC_W2_AMPDU_DEN) | ++ le32_encode_bits(pkt_info->bt_null, RTW_TX_DESC_W2_BT_NULL); ++ ++ tx_desc->w3 = le32_encode_bits(pkt_info->hw_ssn_sel, RTW_TX_DESC_W3_HW_SSN_SEL) | ++ le32_encode_bits(pkt_info->use_rate, RTW_TX_DESC_W3_USE_RATE) | ++ le32_encode_bits(pkt_info->dis_rate_fallback, RTW_TX_DESC_W3_DISDATAFB) | ++ le32_encode_bits(pkt_info->rts, RTW_TX_DESC_W3_USE_RTS) | ++ le32_encode_bits(pkt_info->nav_use_hdr, RTW_TX_DESC_W3_NAVUSEHDR) | ++ le32_encode_bits(pkt_info->ampdu_factor, RTW_TX_DESC_W3_MAX_AGG_NUM); ++ ++ tx_desc->w4 = le32_encode_bits(pkt_info->rate, RTW_TX_DESC_W4_DATARATE); ++ ++ tx_desc->w5 = le32_encode_bits(pkt_info->short_gi, RTW_TX_DESC_W5_DATA_SHORT) | ++ le32_encode_bits(pkt_info->bw, RTW_TX_DESC_W5_DATA_BW) | ++ le32_encode_bits(pkt_info->ldpc, RTW_TX_DESC_W5_DATA_LDPC) | ++ le32_encode_bits(pkt_info->stbc, RTW_TX_DESC_W5_DATA_STBC); ++ ++ tx_desc->w6 = le32_encode_bits(pkt_info->sn, RTW_TX_DESC_W6_SW_DEFINE); ++ ++ tx_desc->w8 = le32_encode_bits(pkt_info->en_hwseq, RTW_TX_DESC_W8_EN_HWSEQ); ++ ++ tx_desc->w9 = le32_encode_bits(pkt_info->seq, RTW_TX_DESC_W9_SW_SEQ); + +- SET_TX_DESC_TXPKTSIZE(txdesc, pkt_info->tx_pkt_size); +- SET_TX_DESC_OFFSET(txdesc, pkt_info->offset); +- SET_TX_DESC_PKT_OFFSET(txdesc, pkt_info->pkt_offset); +- SET_TX_DESC_QSEL(txdesc, pkt_info->qsel); +- SET_TX_DESC_BMC(txdesc, pkt_info->bmc); +- SET_TX_DESC_RATE_ID(txdesc, pkt_info->rate_id); +- SET_TX_DESC_DATARATE(txdesc, pkt_info->rate); +- SET_TX_DESC_DISDATAFB(txdesc, pkt_info->dis_rate_fallback); +- SET_TX_DESC_USE_RATE(txdesc, pkt_info->use_rate); +- SET_TX_DESC_SEC_TYPE(txdesc, pkt_info->sec_type); +- SET_TX_DESC_DATA_BW(txdesc, pkt_info->bw); +- SET_TX_DESC_SW_SEQ(txdesc, pkt_info->seq); +- SET_TX_DESC_MAX_AGG_NUM(txdesc, pkt_info->ampdu_factor); +- SET_TX_DESC_AMPDU_DENSITY(txdesc, pkt_info->ampdu_density); +- SET_TX_DESC_DATA_STBC(txdesc, pkt_info->stbc); +- SET_TX_DESC_DATA_LDPC(txdesc, pkt_info->ldpc); +- SET_TX_DESC_AGG_EN(txdesc, pkt_info->ampdu_en); +- SET_TX_DESC_LS(txdesc, pkt_info->ls); +- SET_TX_DESC_DATA_SHORT(txdesc, pkt_info->short_gi); +- SET_TX_DESC_SPE_RPT(txdesc, pkt_info->report); +- SET_TX_DESC_SW_DEFINE(txdesc, pkt_info->sn); +- SET_TX_DESC_USE_RTS(txdesc, pkt_info->rts); + if (pkt_info->rts) { +- SET_TX_DESC_RTSRATE(txdesc, DESC_RATE24M); +- SET_TX_DESC_DATA_RTS_SHORT(txdesc, 1); +- } +- SET_TX_DESC_DISQSELSEQ(txdesc, pkt_info->dis_qselseq); +- SET_TX_DESC_EN_HWSEQ(txdesc, pkt_info->en_hwseq); +- SET_TX_DESC_HW_SSN_SEL(txdesc, pkt_info->hw_ssn_sel); +- SET_TX_DESC_NAVUSEHDR(txdesc, pkt_info->nav_use_hdr); +- SET_TX_DESC_BT_NULL(txdesc, pkt_info->bt_null); +- if (pkt_info->tim_offset) { +- SET_TX_DESC_TIM_EN(txdesc, 1); +- SET_TX_DESC_TIM_OFFSET(txdesc, pkt_info->tim_offset); ++ tx_desc->w4 |= le32_encode_bits(DESC_RATE24M, RTW_TX_DESC_W4_RTSRATE); ++ tx_desc->w5 |= le32_encode_bits(1, RTW_TX_DESC_W5_DATA_RTS_SHORT); + } ++ ++ if (pkt_info->tim_offset) ++ tx_desc->w9 |= le32_encode_bits(1, RTW_TX_DESC_W9_TIM_EN) | ++ le32_encode_bits(pkt_info->tim_offset, RTW_TX_DESC_W9_TIM_OFFSET); + } + EXPORT_SYMBOL(rtw_tx_fill_tx_desc); + +@@ -635,9 +649,8 @@ + rcu_read_unlock(); + } + +-void rtw_tx_work(struct work_struct *w) ++void __rtw_tx_work(struct rtw_dev *rtwdev) + { +- struct rtw_dev *rtwdev = container_of(w, struct rtw_dev, tx_work); + struct rtw_txq *rtwtxq, *tmp; + + spin_lock_bh(&rtwdev->txq_lock); +@@ -658,6 +671,13 @@ + spin_unlock_bh(&rtwdev->txq_lock); + } + ++void rtw_tx_work(struct work_struct *w) ++{ ++ struct rtw_dev *rtwdev = container_of(w, struct rtw_dev, tx_work); ++ ++ __rtw_tx_work(rtwdev); ++} ++ + void rtw_txq_init(struct rtw_dev *rtwdev, struct ieee80211_txq *txq) + { + struct rtw_txq *rtwtxq; +@@ -682,3 +702,44 @@ list_del_init(&rtwtxq->list); spin_unlock_bh(&rtwdev->txq_lock); } @@ -1573,8 +2096,140 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/real +EXPORT_SYMBOL(rtw_tx_queue_mapping); diff -Naur a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/realtek/rtw88/tx.h --- a/drivers/net/wireless/realtek/rtw88/tx.h 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/tx.h 2023-06-12 05:02:33.140048143 -0400 -@@ -131,6 +131,9 @@ ++++ b/drivers/net/wireless/realtek/rtw88/tx.h 2023-06-22 13:52:09.000000000 -0400 +@@ -9,76 +9,53 @@ + + #define RTW_TX_PROBE_TIMEOUT msecs_to_jiffies(500) + +-#define SET_TX_DESC_TXPKTSIZE(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, GENMASK(15, 0)) +-#define SET_TX_DESC_OFFSET(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, GENMASK(23, 16)) +-#define SET_TX_DESC_PKT_OFFSET(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x01, value, GENMASK(28, 24)) +-#define SET_TX_DESC_QSEL(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x01, value, GENMASK(12, 8)) +-#define SET_TX_DESC_BMC(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, BIT(24)) +-#define SET_TX_DESC_RATE_ID(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x01, value, GENMASK(20, 16)) +-#define SET_TX_DESC_DATARATE(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x04, value, GENMASK(6, 0)) +-#define SET_TX_DESC_DISDATAFB(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(10)) +-#define SET_TX_DESC_USE_RATE(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(8)) +-#define SET_TX_DESC_SEC_TYPE(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x01, value, GENMASK(23, 22)) +-#define SET_TX_DESC_DATA_BW(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, GENMASK(6, 5)) +-#define SET_TX_DESC_SW_SEQ(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x09, value, GENMASK(23, 12)) +-#define SET_TX_DESC_TIM_EN(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x09, value, BIT(7)) +-#define SET_TX_DESC_TIM_OFFSET(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x09, value, GENMASK(6, 0)) +-#define SET_TX_DESC_MAX_AGG_NUM(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, GENMASK(21, 17)) +-#define SET_TX_DESC_USE_RTS(tx_desc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(12)) +-#define SET_TX_DESC_RTSRATE(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x04, value, GENMASK(28, 24)) +-#define SET_TX_DESC_DATA_RTS_SHORT(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, BIT(12)) +-#define SET_TX_DESC_AMPDU_DENSITY(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, GENMASK(22, 20)) +-#define SET_TX_DESC_DATA_STBC(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, GENMASK(9, 8)) +-#define SET_TX_DESC_DATA_LDPC(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, BIT(7)) +-#define SET_TX_DESC_AGG_EN(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(12)) +-#define SET_TX_DESC_LS(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, BIT(26)) +-#define SET_TX_DESC_DATA_SHORT(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, BIT(4)) +-#define SET_TX_DESC_SPE_RPT(tx_desc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(19)) +-#define SET_TX_DESC_SW_DEFINE(tx_desc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x06, value, GENMASK(11, 0)) +-#define SET_TX_DESC_DISQSELSEQ(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, BIT(31)) +-#define SET_TX_DESC_EN_HWSEQ(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x08, value, BIT(15)) +-#define SET_TX_DESC_HW_SSN_SEL(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, GENMASK(7, 6)) +-#define SET_TX_DESC_NAVUSEHDR(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(15)) +-#define SET_TX_DESC_BT_NULL(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(23)) +-#define SET_TX_DESC_TXDESC_CHECKSUM(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x07, value, GENMASK(15, 0)) +-#define SET_TX_DESC_DMA_TXAGG_NUM(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x07, value, GENMASK(31, 24)) +-#define GET_TX_DESC_PKT_OFFSET(txdesc) \ +- le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(28, 24)) +-#define GET_TX_DESC_QSEL(txdesc) \ +- le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(12, 8)) ++struct rtw_tx_desc { ++ __le32 w0; ++ __le32 w1; ++ __le32 w2; ++ __le32 w3; ++ __le32 w4; ++ __le32 w5; ++ __le32 w6; ++ __le32 w7; ++ __le32 w8; ++ __le32 w9; ++} __packed; ++ ++#define RTW_TX_DESC_W0_TXPKTSIZE GENMASK(15, 0) ++#define RTW_TX_DESC_W0_OFFSET GENMASK(23, 16) ++#define RTW_TX_DESC_W0_BMC BIT(24) ++#define RTW_TX_DESC_W0_LS BIT(26) ++#define RTW_TX_DESC_W0_DISQSELSEQ BIT(31) ++#define RTW_TX_DESC_W1_QSEL GENMASK(12, 8) ++#define RTW_TX_DESC_W1_RATE_ID GENMASK(20, 16) ++#define RTW_TX_DESC_W1_SEC_TYPE GENMASK(23, 22) ++#define RTW_TX_DESC_W1_PKT_OFFSET GENMASK(28, 24) ++#define RTW_TX_DESC_W1_MORE_DATA BIT(29) ++#define RTW_TX_DESC_W2_AGG_EN BIT(12) ++#define RTW_TX_DESC_W2_SPE_RPT BIT(19) ++#define RTW_TX_DESC_W2_AMPDU_DEN GENMASK(22, 20) ++#define RTW_TX_DESC_W2_BT_NULL BIT(23) ++#define RTW_TX_DESC_W3_HW_SSN_SEL GENMASK(7, 6) ++#define RTW_TX_DESC_W3_USE_RATE BIT(8) ++#define RTW_TX_DESC_W3_DISDATAFB BIT(10) ++#define RTW_TX_DESC_W3_USE_RTS BIT(12) ++#define RTW_TX_DESC_W3_NAVUSEHDR BIT(15) ++#define RTW_TX_DESC_W3_MAX_AGG_NUM GENMASK(21, 17) ++#define RTW_TX_DESC_W4_DATARATE GENMASK(6, 0) ++#define RTW_TX_DESC_W4_RTSRATE GENMASK(28, 24) ++#define RTW_TX_DESC_W5_DATA_SHORT BIT(4) ++#define RTW_TX_DESC_W5_DATA_BW GENMASK(6, 5) ++#define RTW_TX_DESC_W5_DATA_LDPC BIT(7) ++#define RTW_TX_DESC_W5_DATA_STBC GENMASK(9, 8) ++#define RTW_TX_DESC_W5_DATA_RTS_SHORT BIT(12) ++#define RTW_TX_DESC_W6_SW_DEFINE GENMASK(11, 0) ++#define RTW_TX_DESC_W7_TXDESC_CHECKSUM GENMASK(15, 0) ++#define RTW_TX_DESC_W7_DMA_TXAGG_NUM GENMASK(31, 24) ++#define RTW_TX_DESC_W8_EN_HWSEQ BIT(15) ++#define RTW_TX_DESC_W9_SW_SEQ GENMASK(23, 12) ++#define RTW_TX_DESC_W9_TIM_EN BIT(7) ++#define RTW_TX_DESC_W9_TIM_OFFSET GENMASK(6, 0) + + enum rtw_tx_desc_queue_select { + TX_DESC_QSEL_TID0 = 0, +@@ -111,6 +88,7 @@ + void rtw_txq_init(struct rtw_dev *rtwdev, struct ieee80211_txq *txq); + void rtw_txq_cleanup(struct rtw_dev *rtwdev, struct ieee80211_txq *txq); + void rtw_tx_work(struct work_struct *w); ++void __rtw_tx_work(struct rtw_dev *rtwdev); + void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct ieee80211_sta *sta, +@@ -131,18 +109,23 @@ struct rtw_tx_pkt_info *pkt_info, u8 *buf, u32 size); @@ -1584,10 +2239,87 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/real static inline void fill_txdesc_checksum_common(u8 *txdesc, size_t words) { + __le16 chksum = 0; + __le16 *data = (__le16 *)(txdesc); ++ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc; + +- SET_TX_DESC_TXDESC_CHECKSUM(txdesc, 0x0000); ++ le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM); + + while (words--) + chksum ^= *data++; + +- SET_TX_DESC_TXDESC_CHECKSUM(txdesc, __le16_to_cpu(chksum)); ++ le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum), ++ RTW_TX_DESC_W7_TXDESC_CHECKSUM); + } + + static inline void rtw_tx_fill_txdesc_checksum(struct rtw_dev *rtwdev, diff -Naur a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c --- a/drivers/net/wireless/realtek/rtw88/usb.c 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/usb.c 2023-06-12 05:02:33.140048143 -0400 -@@ -804,6 +804,7 @@ ++++ b/drivers/net/wireless/realtek/rtw88/usb.c 2023-06-22 13:52:09.000000000 -0400 +@@ -24,11 +24,12 @@ + static void rtw_usb_fill_tx_checksum(struct rtw_usb *rtwusb, + struct sk_buff *skb, int agg_num) + { ++ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data; + struct rtw_dev *rtwdev = rtwusb->rtwdev; + struct rtw_tx_pkt_info pkt_info; + +- SET_TX_DESC_DMA_TXAGG_NUM(skb->data, agg_num); +- pkt_info.pkt_offset = GET_TX_DESC_PKT_OFFSET(skb->data); ++ le32p_replace_bits(&tx_desc->w7, agg_num, RTW_TX_DESC_W7_DMA_TXAGG_NUM); ++ pkt_info.pkt_offset = le32_get_bits(tx_desc->w1, RTW_TX_DESC_W1_PKT_OFFSET); + rtw_tx_fill_txdesc_checksum(rtwdev, &pkt_info, skb->data); + } + +@@ -306,11 +307,13 @@ + static bool rtw_usb_tx_agg_skb(struct rtw_usb *rtwusb, struct sk_buff_head *list) + { + struct rtw_dev *rtwdev = rtwusb->rtwdev; ++ struct rtw_tx_desc *tx_desc; + struct rtw_usb_txcb *txcb; + struct sk_buff *skb_head; + struct sk_buff *skb_iter; + int agg_num = 0; + unsigned int align_next = 0; ++ u8 qsel; + + if (skb_queue_empty(list)) + return false; +@@ -363,9 +366,10 @@ + + queue: + skb_queue_tail(&txcb->tx_ack_queue, skb_head); ++ tx_desc = (struct rtw_tx_desc *)skb_head->data; ++ qsel = le32_get_bits(tx_desc->w1, RTW_TX_DESC_W1_QSEL); + +- rtw_usb_write_port(rtwdev, GET_TX_DESC_QSEL(skb_head->data), skb_head, +- rtw_usb_write_port_tx_complete, txcb); ++ rtw_usb_write_port(rtwdev, qsel, skb_head, rtw_usb_write_port_tx_complete, txcb); + + return true; + } +@@ -465,6 +469,9 @@ + + if (unlikely(ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))) + qsel = TX_DESC_QSEL_MGMT; ++ else if (is_broadcast_ether_addr(hdr->addr1) || ++ is_multicast_ether_addr(hdr->addr1)) ++ qsel = TX_DESC_QSEL_HIGH; + else if (skb_get_queue_mapping(skb) <= IEEE80211_AC_BK) + qsel = skb->priority; + else +@@ -535,7 +542,7 @@ + } + + if (skb_queue_len(&rtwusb->rx_queue) >= RTW_USB_MAX_RXQ_LEN) { +- rtw_err(rtwdev, "failed to get rx_queue, overflow\n"); ++ dev_dbg_ratelimited(rtwdev->dev, "failed to get rx_queue, overflow\n"); + dev_kfree_skb_any(skb); + continue; + } +@@ -804,6 +811,7 @@ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); usb_put_dev(rtwusb->udev); @@ -1595,7 +2327,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/rea usb_set_intfdata(intf, NULL); } -@@ -832,7 +833,7 @@ +@@ -832,7 +840,7 @@ ret = rtw_usb_alloc_rx_bufs(rtwusb); if (ret) @@ -1606,7 +2338,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/rea if (ret) diff -Naur a/drivers/net/wireless/realtek/rtw88/usb.h b/drivers/net/wireless/realtek/rtw88/usb.h --- a/drivers/net/wireless/realtek/rtw88/usb.h 2023-05-17 07:59:13.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/usb.h 2023-06-12 05:02:33.140048143 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/usb.h 2023-06-22 13:52:09.000000000 -0400 @@ -78,7 +78,7 @@ u8 pipe_interrupt; u8 pipe_in; diff --git a/patch/misc/rtw88/6.2/002-rtw88-linux-next.patch b/patch/misc/rtw88/6.2/002-rtw88-linux-next.patch index 0ea6905d63..f29e5a96f2 100644 --- a/patch/misc/rtw88/6.2/002-rtw88-linux-next.patch +++ b/patch/misc/rtw88/6.2/002-rtw88-linux-next.patch @@ -1,5 +1,5 @@ ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723ds.c 2023-06-12 05:04:19.622514805 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723ds.c 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) Martin Blumenstingl @@ -42,8 +42,8 @@ +MODULE_AUTHOR("Martin Blumenstingl "); +MODULE_DESCRIPTION("Realtek 802.11n wireless 8723ds driver"); +MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821cs.c 2023-06-12 05:02:33.135048216 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821cs.c 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) Martin Blumenstingl @@ -81,8 +81,8 @@ +MODULE_AUTHOR("Martin Blumenstingl "); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821cs driver"); +MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822bs.c 2023-06-12 05:02:33.136048201 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822bs.c 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) Jernej Skrabec @@ -120,8 +120,8 @@ +MODULE_AUTHOR("Jernej Skrabec "); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822bs driver"); +MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822cs.c 2023-06-12 05:02:33.139048158 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822cs.c 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) Martin Blumenstingl @@ -159,8 +159,8 @@ +MODULE_AUTHOR("Martin Blumenstingl "); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822cs driver"); +MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/sdio.c 2023-06-12 05:04:19.620514834 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/sdio.c 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,1404 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright (C) 2021 Martin Blumenstingl @@ -1566,8 +1566,8 @@ +MODULE_AUTHOR("Jernej Skrabec"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless SDIO driver"); +MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/sdio.h 2023-06-12 05:02:33.140048143 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/sdio.h 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,178 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright (C) 2021 Martin Blumenstingl diff --git a/patch/misc/rtw88/6.2/003-rtw88-add-missing-unwind-goto-for_rtw_download_firmware.patch b/patch/misc/rtw88/6.2/003-rtw88-add-missing-unwind-goto-for_rtw_download_firmware.patch deleted file mode 100644 index e1d032bbf2..0000000000 --- a/patch/misc/rtw88/6.2/003-rtw88-add-missing-unwind-goto-for_rtw_download_firmware.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Ping-Ke Shih @ 2023-06-07 1:27 UTC (permalink / raw) - To: tony0620emma, kvalo; +Cc: s.hauer, dan.carpenter, lkp, linux-wireless - -This flaw is detected by smatch: - drivers/net/wireless/realtek/rtw88/mac.c:748 __rtw_download_firmware() - warn: missing unwind goto? - -Though most things of dlfw_fail have been done by -download_firmware_end_flow() and wlan_cpu_enable(), an exception is that -download_firmware_end_flow() clear BIT_MCUFWDL_EN bit conditionally. -So, make this change to clear the bit. - -diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c -index a168f36c38ece..298663b035808 100644 ---- a/drivers/net/wireless/realtek/rtw88/mac.c -+++ b/drivers/net/wireless/realtek/rtw88/mac.c -@@ -794,8 +794,10 @@ static int __rtw_download_firmware(struct rtw_dev *rtwdev, - - wlan_cpu_enable(rtwdev, true); - -- if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) -- return -EBUSY; -+ if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) { -+ ret = -EBUSY; -+ goto dlfw_fail; -+ } - - ret = download_firmware_validate(rtwdev); - if (ret) --- -2.25.1 diff --git a/patch/misc/rtw88/6.2/004-rtw88-fix-action-frame-transmission-fail-before-association.patch b/patch/misc/rtw88/6.2/004-rtw88-fix-action-frame-transmission-fail-before-association.patch deleted file mode 100644 index a41e6fb153..0000000000 --- a/patch/misc/rtw88/6.2/004-rtw88-fix-action-frame-transmission-fail-before-association.patch +++ /dev/null @@ -1,41 +0,0 @@ -From: Ping-Ke Shih @ 2023-06-15 11:43 UTC (permalink / raw) - To: tony0620emma, kvalo; +Cc: phhuang, linux-wireless - -From: Po-Hao Huang - -For combo chips, antennas were controlled by bluetooth only during -power on. If WiFi wish to do transmission, notification to the coexistence -module are required. Previously we only do this before authentication. -To allow transmission before auth, such as management TX, now we start -the initiation of coexistence earlier so antennas are shared between -WiFi and bluetooth after set_channel(), and frames could then be sent. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih ---- - drivers/net/wireless/realtek/rtw88/ps.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/drivers/net/wireless/realtek/rtw88/ps.c b/drivers/net/wireless/realtek/rtw88/ps.c -index 53933fb38a330..43e80a3a8136d 100644 ---- a/drivers/net/wireless/realtek/rtw88/ps.c -+++ b/drivers/net/wireless/realtek/rtw88/ps.c -@@ -18,6 +18,7 @@ static int rtw_ips_pwr_up(struct rtw_dev *rtwdev) - if (ret) - rtw_err(rtwdev, "leave idle state failed\n"); - -+ rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); - rtw_set_channel(rtwdev); - - return ret; -@@ -63,8 +64,6 @@ int rtw_leave_ips(struct rtw_dev *rtwdev) - - rtw_iterate_vifs(rtwdev, rtw_restore_port_cfg_iter, rtwdev); - -- rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); -- - return 0; - } - --- -2.25.1 diff --git a/patch/misc/rtw88/6.3/001-rtw88-linux-next.patch b/patch/misc/rtw88/6.3/001-rtw88-linux-next.patch index 78ae7a7762..34067bab8a 100644 --- a/patch/misc/rtw88/6.3/001-rtw88-linux-next.patch +++ b/patch/misc/rtw88/6.3/001-rtw88-linux-next.patch @@ -1,6 +1,171 @@ +diff -Naur a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c +--- a/drivers/net/wireless/realtek/rtw88/debug.c 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/debug.c 2023-06-22 13:52:09.000000000 -0400 +@@ -183,8 +183,8 @@ + + tmp_len = (count > size - 1 ? size - 1 : count); + +- if (!buffer || copy_from_user(tmp, buffer, tmp_len)) +- return count; ++ if (copy_from_user(tmp, buffer, tmp_len)) ++ return -EFAULT; + + tmp[tmp_len] = '\0'; + +@@ -201,13 +201,16 @@ + char tmp[32 + 1]; + u32 addr, len; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); ++ if (ret) ++ return ret; + + num = sscanf(tmp, "%x %x", &addr, &len); + + if (num != 2) +- return count; ++ return -EINVAL; + + if (len != 1 && len != 2 && len != 4) { + rtw_warn(rtwdev, "read reg setting wrong len\n"); +@@ -288,8 +291,11 @@ + char tmp[32 + 1]; + u32 offset, page_num; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); ++ if (ret) ++ return ret; + + num = sscanf(tmp, "%d %d", &offset, &page_num); + +@@ -314,8 +320,11 @@ + char tmp[32 + 1]; + u32 input; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ if (ret) ++ return ret; + + num = kstrtoint(tmp, 0, &input); + +@@ -338,14 +347,17 @@ + char tmp[32 + 1]; + u32 addr, val, len; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ if (ret) ++ return ret; + + /* write BB/MAC register */ + num = sscanf(tmp, "%x %x %x", &addr, &val, &len); + + if (num != 3) +- return count; ++ return -EINVAL; + + switch (len) { + case 1: +@@ -381,8 +393,11 @@ + char tmp[32 + 1]; + u8 param[8]; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ if (ret) ++ return ret; + + num = sscanf(tmp, "%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx", + ¶m[0], ¶m[1], ¶m[2], ¶m[3], +@@ -408,14 +423,17 @@ + char tmp[32 + 1]; + u32 path, addr, mask, val; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 4); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 4); ++ if (ret) ++ return ret; + + num = sscanf(tmp, "%x %x %x %x", &path, &addr, &mask, &val); + + if (num != 4) { + rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); +- return count; ++ return -EINVAL; + } + + mutex_lock(&rtwdev->mutex); +@@ -438,14 +456,17 @@ + char tmp[32 + 1]; + u32 path, addr, mask; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ if (ret) ++ return ret; + + num = sscanf(tmp, "%x %x %x", &path, &addr, &mask); + + if (num != 3) { + rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); +- return count; ++ return -EINVAL; + } + + debugfs_priv->rf_path = path; +@@ -467,7 +488,9 @@ + char tmp[32 + 1]; + int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ if (ret) ++ return ret; + + ret = kstrtou8(tmp, 0, &fix_rate); + if (ret) { +@@ -860,7 +883,9 @@ + bool enable; + int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ if (ret) ++ return ret; + + ret = kstrtobool(tmp, &enable); + if (ret) { +@@ -930,7 +955,9 @@ + bool input; + int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ if (ret) ++ return ret; + + ret = kstrtobool(tmp, &input); + if (ret) diff -Naur a/drivers/net/wireless/realtek/rtw88/debug.h b/drivers/net/wireless/realtek/rtw88/debug.h ---- a/drivers/net/wireless/realtek/rtw88/debug.h 2023-06-09 04:48:26.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/debug.h 2023-06-11 07:25:27.482597275 -0400 +--- a/drivers/net/wireless/realtek/rtw88/debug.h 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/debug.h 2023-06-22 13:52:09.000000000 -0400 @@ -24,6 +24,7 @@ RTW_DBG_ADAPTIVITY = 0x00008000, RTW_DBG_HW_SCAN = 0x00010000, @@ -10,9 +175,91 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/debug.h b/drivers/net/wireless/r RTW_DBG_ALL = 0xffffffff }; diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c ---- a/drivers/net/wireless/realtek/rtw88/fw.c 2023-06-09 04:48:26.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/fw.c 2023-06-11 07:25:27.485597229 -0400 -@@ -1393,6 +1393,10 @@ +--- a/drivers/net/wireless/realtek/rtw88/fw.c 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/fw.c 2023-06-22 13:52:09.000000000 -0400 +@@ -308,6 +308,57 @@ + } + EXPORT_SYMBOL(rtw_fw_c2h_cmd_isr); + ++static void rtw_fw_send_h2c_command_register(struct rtw_dev *rtwdev, ++ struct rtw_h2c_register *h2c) ++{ ++ u32 box_reg, box_ex_reg; ++ u8 box_state, box; ++ int ret; ++ ++ rtw_dbg(rtwdev, RTW_DBG_FW, "send H2C content %08x %08x\n", h2c->w0, ++ h2c->w1); ++ ++ lockdep_assert_held(&rtwdev->mutex); ++ ++ box = rtwdev->h2c.last_box_num; ++ switch (box) { ++ case 0: ++ box_reg = REG_HMEBOX0; ++ box_ex_reg = REG_HMEBOX0_EX; ++ break; ++ case 1: ++ box_reg = REG_HMEBOX1; ++ box_ex_reg = REG_HMEBOX1_EX; ++ break; ++ case 2: ++ box_reg = REG_HMEBOX2; ++ box_ex_reg = REG_HMEBOX2_EX; ++ break; ++ case 3: ++ box_reg = REG_HMEBOX3; ++ box_ex_reg = REG_HMEBOX3_EX; ++ break; ++ default: ++ WARN(1, "invalid h2c mail box number\n"); ++ return; ++ } ++ ++ ret = read_poll_timeout_atomic(rtw_read8, box_state, ++ !((box_state >> box) & 0x1), 100, 3000, ++ false, rtwdev, REG_HMETFR); ++ ++ if (ret) { ++ rtw_err(rtwdev, "failed to send h2c command\n"); ++ return; ++ } ++ ++ rtw_write32(rtwdev, box_ex_reg, h2c->w1); ++ rtw_write32(rtwdev, box_reg, h2c->w0); ++ ++ if (++rtwdev->h2c.last_box_num >= 4) ++ rtwdev->h2c.last_box_num = 0; ++} ++ + static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev, + u8 *h2c) + { +@@ -468,6 +519,23 @@ + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); + } + ++void rtw_fw_default_port(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif) ++{ ++ struct rtw_h2c_register h2c = {}; ++ ++ if (rtwvif->net_type != RTW_NET_MGD_LINKED) ++ return; ++ ++ /* Leave LPS before default port H2C so FW timer is correct */ ++ rtw_leave_lps(rtwdev); ++ ++ h2c.w0 = u32_encode_bits(H2C_CMD_DEFAULT_PORT, RTW_H2C_W0_CMDID) | ++ u32_encode_bits(rtwvif->port, RTW_H2C_DEFAULT_PORT_W0_PORTID) | ++ u32_encode_bits(rtwvif->mac_id, RTW_H2C_DEFAULT_PORT_W0_MACID); ++ ++ rtw_fw_send_h2c_command_register(rtwdev, &h2c); ++} ++ + void rtw_fw_wl_ch_info(struct rtw_dev *rtwdev, u8 link, u8 ch, u8 bw) + { + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; +@@ -1393,6 +1461,10 @@ struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; struct rtw_rsvd_page *rsvd_pkt; @@ -23,7 +270,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real list_for_each_entry(rsvd_pkt, &rtwvif->rsvd_page_list, vif_list) { if (rsvd_pkt->type == RSVD_BEACON) list_add(&rsvd_pkt->build_list, -@@ -1614,6 +1618,7 @@ +@@ -1614,6 +1686,7 @@ mutex_lock(&rtwdev->mutex); rtw_fw_download_rsvd_page(rtwdev); @@ -31,7 +278,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real mutex_unlock(&rtwdev->mutex); } -@@ -2155,11 +2160,19 @@ +@@ -2155,11 +2228,19 @@ } rtw_fw_set_scan_offload(rtwdev, &cs_option, rtwvif, &chan_list); out: @@ -52,7 +299,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD)) return; -@@ -2244,6 +2257,7 @@ +@@ -2244,6 +2325,7 @@ if (rtw_is_op_chan(rtwdev, chan)) { rtw_store_op_chan(rtwdev, false); ieee80211_wake_queues(rtwdev->hw); @@ -60,7 +307,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real } } else if (id == RTW_SCAN_NOTIFY_ID_PRESWITCH) { if (IS_CH_5G_BAND(chan)) { -@@ -2262,8 +2276,10 @@ +@@ -2262,8 +2344,10 @@ * if next channel is non-op channel. */ if (!rtw_is_op_chan(rtwdev, chan) && @@ -73,9 +320,43 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/real rtw_dbg(rtwdev, RTW_DBG_HW_SCAN, diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h ---- a/drivers/net/wireless/realtek/rtw88/fw.h 2023-06-09 04:48:26.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/fw.h 2023-06-11 07:25:27.486597214 -0400 -@@ -868,5 +868,5 @@ +--- a/drivers/net/wireless/realtek/rtw88/fw.h 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/fw.h 2023-06-22 13:52:09.000000000 -0400 +@@ -81,6 +81,17 @@ + u8 option; + } __packed; + ++struct rtw_h2c_register { ++ u32 w0; ++ u32 w1; ++} __packed; ++ ++#define RTW_H2C_W0_CMDID GENMASK(7, 0) ++ ++/* H2C_CMD_DEFAULT_PORT command */ ++#define RTW_H2C_DEFAULT_PORT_W0_PORTID GENMASK(15, 8) ++#define RTW_H2C_DEFAULT_PORT_W0_MACID GENMASK(23, 16) ++ + struct rtw_h2c_cmd { + __le32 msg; + __le32 msg_ext; +@@ -530,6 +541,7 @@ + #define H2C_CMD_MEDIA_STATUS_RPT 0x01 + #define H2C_CMD_SET_PWR_MODE 0x20 + #define H2C_CMD_LPS_PG_INFO 0x2b ++#define H2C_CMD_DEFAULT_PORT 0x2c + #define H2C_CMD_RA_INFO 0x40 + #define H2C_CMD_RSSI_MONITOR 0x42 + #define H2C_CMD_BCN_FILTER_OFFLOAD_P0 0x56 +@@ -801,6 +813,7 @@ + void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb); + void rtw_fw_send_general_info(struct rtw_dev *rtwdev); + void rtw_fw_send_phydm_info(struct rtw_dev *rtwdev); ++void rtw_fw_default_port(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif); + + void rtw_fw_do_iqk(struct rtw_dev *rtwdev, struct rtw_iqk_para *para); + void rtw_fw_inform_rfk_status(struct rtw_dev *rtwdev, bool start); +@@ -868,5 +881,5 @@ bool enable); void rtw_hw_scan_status_report(struct rtw_dev *rtwdev, struct sk_buff *skb); void rtw_hw_scan_chan_switch(struct rtw_dev *rtwdev, struct sk_buff *skb); @@ -83,8 +364,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/real +void rtw_hw_scan_abort(struct rtw_dev *rtwdev); #endif diff -Naur a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig ---- a/drivers/net/wireless/realtek/rtw88/Kconfig 2023-06-09 04:48:26.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/Kconfig 2023-06-11 07:28:33.845740907 -0400 +--- a/drivers/net/wireless/realtek/rtw88/Kconfig 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/Kconfig 2023-06-22 13:52:09.000000000 -0400 @@ -16,6 +16,9 @@ config RTW88_PCI tristate @@ -168,9 +449,22 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/r tristate "Realtek 8821CU USB wireless network adapter" depends on USB diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c ---- a/drivers/net/wireless/realtek/rtw88/mac80211.c 2023-06-14 05:17:06.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c 2023-06-14 08:27:14.326091479 -0400 -@@ -146,25 +146,30 @@ +--- a/drivers/net/wireless/realtek/rtw88/mac80211.c 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/mac80211.c 2023-06-22 13:52:09.000000000 -0400 +@@ -43,7 +43,11 @@ + list_add_tail(&rtwtxq->list, &rtwdev->txqs); + spin_unlock_bh(&rtwdev->txq_lock); + +- queue_work(rtwdev->tx_wq, &rtwdev->tx_work); ++ /* ensure to dequeue EAPOL (4/4) at the right time */ ++ if (txq->ac == IEEE80211_AC_VO) ++ __rtw_tx_work(rtwdev); ++ else ++ queue_work(rtwdev->tx_wq, &rtwdev->tx_work); + } + + static int rtw_ops_start(struct ieee80211_hw *hw) +@@ -146,25 +150,32 @@ struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; enum rtw_net_type net_type; u32 config = 0; @@ -195,8 +489,10 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles mutex_lock(&rtwdev->mutex); + port = find_first_zero_bit(rtwdev->hw_port, RTW_PORT_NUM); -+ if (port >= RTW_PORT_NUM) ++ if (port >= RTW_PORT_NUM) { ++ mutex_unlock(&rtwdev->mutex); + return -EINVAL; ++ } + set_bit(port, rtwdev->hw_port); + + rtwvif->port = port; @@ -204,7 +500,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles rtw_leave_lps_deep(rtwdev); switch (vif->type) { -@@ -186,6 +191,7 @@ +@@ -186,6 +197,7 @@ break; default: WARN_ON(1); @@ -212,7 +508,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles mutex_unlock(&rtwdev->mutex); return -EINVAL; } -@@ -197,6 +203,7 @@ +@@ -197,6 +209,7 @@ rtwvif->bcn_ctrl = bcn_ctrl; config |= PORT_SET_BCN_CTRL; rtw_vif_port_config(rtwdev, rtwvif, config); @@ -220,7 +516,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles rtw_recalc_lps(rtwdev, vif); mutex_unlock(&rtwdev->mutex); -@@ -228,6 +235,7 @@ +@@ -228,6 +241,7 @@ rtwvif->bcn_ctrl = 0; config |= PORT_SET_BCN_CTRL; rtw_vif_port_config(rtwdev, rtwvif, config); @@ -228,16 +524,25 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles rtw_recalc_lps(rtwdev, NULL); mutex_unlock(&rtwdev->mutex); -@@ -378,7 +386,7 @@ +@@ -368,6 +382,7 @@ + + rtw_fw_download_rsvd_page(rtwdev); + rtw_send_rsvd_page_h2c(rtwdev); ++ rtw_fw_default_port(rtwdev, rtwvif); + rtw_coex_media_status_notify(rtwdev, vif->cfg.assoc); + if (rtw_bf_support) + rtw_bf_assoc(rtwdev, vif, conf); +@@ -378,7 +393,8 @@ * when disconnected by peer */ if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) - rtw_hw_scan_abort(rtwdev, vif); + rtw_hw_scan_abort(rtwdev); ++ } config |= PORT_SET_NET_TYPE; -@@ -388,7 +396,7 @@ +@@ -388,7 +404,7 @@ if (changed & BSS_CHANGED_BSSID) { ether_addr_copy(rtwvif->bssid, conf->bssid); config |= PORT_SET_BSSID; @@ -246,7 +551,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles rtw_clear_op_chan(rtwdev); else rtw_store_op_chan(rtwdev, true); -@@ -402,6 +410,7 @@ +@@ -402,6 +418,7 @@ if (changed & BSS_CHANGED_BEACON) { rtw_set_dtim_period(rtwdev, conf->dtim_period); rtw_fw_download_rsvd_page(rtwdev); @@ -254,10 +559,11 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles } if (changed & BSS_CHANGED_BEACON_ENABLED) { -@@ -437,12 +446,27 @@ +@@ -437,12 +454,29 @@ const struct rtw_chip_info *chip = rtwdev->chip; mutex_lock(&rtwdev->mutex); ++ rtw_write32_set(rtwdev, REG_TCR, BIT_TCR_UPDATE_HGQMD); + rtwdev->ap_active = true; + rtw_store_op_chan(rtwdev, true); chip->ops->phy_calibration(rtwdev); @@ -273,6 +579,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles + struct rtw_dev *rtwdev = hw->priv; + + mutex_lock(&rtwdev->mutex); ++ rtw_write32_clr(rtwdev, REG_TCR, BIT_TCR_UPDATE_HGQMD); + rtwdev->ap_active = false; + if (!rtw_core_check_sta_active(rtwdev)) + rtw_clear_op_chan(rtwdev); @@ -282,7 +589,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles static int rtw_ops_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, unsigned int link_id, u16 ac, -@@ -845,7 +869,7 @@ +@@ -845,7 +879,7 @@ rtw_hw_scan_start(rtwdev, vif, req); ret = rtw_hw_scan_offload(rtwdev, vif, true); if (ret) { @@ -291,7 +598,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles rtw_err(rtwdev, "HW scan failed with status: %d\n", ret); } mutex_unlock(&rtwdev->mutex); -@@ -865,7 +889,7 @@ +@@ -865,7 +899,7 @@ return; mutex_lock(&rtwdev->mutex); @@ -300,7 +607,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles mutex_unlock(&rtwdev->mutex); } -@@ -904,6 +928,7 @@ +@@ -904,6 +938,7 @@ .configure_filter = rtw_ops_configure_filter, .bss_info_changed = rtw_ops_bss_info_changed, .start_ap = rtw_ops_start_ap, @@ -309,8 +616,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireles .sta_add = rtw_ops_sta_add, .sta_remove = rtw_ops_sta_remove, diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c ---- a/drivers/net/wireless/realtek/rtw88/mac.c 2023-06-09 04:48:26.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/mac.c 2023-06-11 07:25:27.487597199 -0400 +--- a/drivers/net/wireless/realtek/rtw88/mac.c 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/mac.c 2023-06-22 13:52:09.000000000 -0400 @@ -7,6 +7,7 @@ #include "reg.h" #include "fw.h" @@ -415,7 +722,20 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/rea /* Disable beacon related functions */ tmp = rtw_read8(rtwdev, REG_BCN_CTRL); bckp[bckp_idx].len = 1; -@@ -1042,6 +1080,9 @@ +@@ -756,8 +794,10 @@ + + wlan_cpu_enable(rtwdev, true); + +- if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) +- return -EBUSY; ++ if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) { ++ ret = -EBUSY; ++ goto dlfw_fail; ++ } + + ret = download_firmware_validate(rtwdev); + if (ret) +@@ -1042,6 +1082,9 @@ else return -EINVAL; break; @@ -425,7 +745,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/rea default: return -EINVAL; } -@@ -1060,8 +1101,12 @@ +@@ -1060,8 +1103,12 @@ if (rtw_chip_wcpu_11ac(rtwdev)) rtw_write32(rtwdev, REG_H2CQ_CSR, BIT_H2CQ_FULL); @@ -439,7 +759,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/rea return 0; } -@@ -1074,7 +1119,7 @@ +@@ -1074,7 +1121,7 @@ u8 csi_buf_pg_num = chip->csi_buf_pg_num; /* config rsvd page num */ @@ -448,7 +768,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/rea fifo->txff_pg_num = chip->txff_size >> 7; if (rtw_chip_wcpu_11n(rtwdev)) fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num; -@@ -1204,6 +1249,9 @@ +@@ -1204,6 +1251,9 @@ else return -EINVAL; break; @@ -459,8 +779,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/rea return -EINVAL; } diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.h b/drivers/net/wireless/realtek/rtw88/mac.h ---- a/drivers/net/wireless/realtek/rtw88/mac.h 2023-06-09 04:48:26.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/mac.h 2023-06-11 07:25:27.487597199 -0400 +--- a/drivers/net/wireless/realtek/rtw88/mac.h 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/mac.h 2023-06-22 13:52:09.000000000 -0400 @@ -7,7 +7,6 @@ #define RTW_HW_PORT_NUM 5 @@ -470,8 +790,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.h b/drivers/net/wireless/rea #define C2H_PKT_BUF 256 #define REPORT_BUF 128 diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c ---- a/drivers/net/wireless/realtek/rtw88/main.c 2023-06-14 05:17:06.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/main.c 2023-06-14 08:33:55.273201294 -0400 +--- a/drivers/net/wireless/realtek/rtw88/main.c 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/main.c 2023-06-22 13:52:09.000000000 -0400 @@ -18,6 +18,7 @@ #include "debug.h" #include "bf.h" @@ -516,7 +836,23 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re rtw_enter_lps(rtwdev, data.rtwvif->port); rtwdev->watch_dog_cnt++; -@@ -624,6 +645,7 @@ +@@ -313,12 +334,15 @@ + struct ieee80211_vif *vif) + { + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; ++ struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + int i; + + si->mac_id = rtw_acquire_macid(rtwdev); + if (si->mac_id >= RTW_MAX_MAC_ID_NUM) + return -ENOSPC; + ++ if (vif->type == NL80211_IFTYPE_STATION && vif->cfg.assoc == 0) ++ rtwvif->mac_id = si->mac_id; + si->rtwdev = rtwdev; + si->sta = sta; + si->vif = vif; +@@ -624,6 +648,7 @@ rcu_read_unlock(); rtw_iterate_stas_atomic(rtwdev, rtw_reset_sta_iter, rtwdev); rtw_iterate_vifs_atomic(rtwdev, rtw_reset_vif_iter, rtwdev); @@ -524,7 +860,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re rtw_enter_ips(rtwdev); } -@@ -843,6 +865,9 @@ +@@ -843,6 +868,9 @@ rtw_update_channel(rtwdev, center_chan, primary_chan, band, bandwidth); @@ -534,7 +870,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re chip->ops->set_channel(rtwdev, center_chan, bandwidth, hal->current_primary_channel_index); -@@ -1800,6 +1825,10 @@ +@@ -1800,6 +1828,10 @@ rtwdev->hci.rpwm_addr = 0x03d9; rtwdev->hci.cpwm_addr = 0x03da; break; @@ -545,7 +881,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re case RTW_HCI_TYPE_USB: rtwdev->hci.rpwm_addr = 0xfe58; rtwdev->hci.cpwm_addr = 0xfe57; -@@ -1994,7 +2023,7 @@ +@@ -1994,7 +2026,7 @@ if (!rfe_def) return -ENODEV; @@ -554,7 +890,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re rtw_phy_init_tx_power(rtwdev); if (rfe_def->agc_btg_tbl) -@@ -2173,9 +2202,11 @@ +@@ -2173,9 +2205,11 @@ int max_tx_headroom = 0; int ret; @@ -567,7 +903,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re hw->extra_tx_headroom = max_tx_headroom; hw->queues = IEEE80211_NUM_ACS; hw->txq_data_size = sizeof(struct rtw_txq); -@@ -2209,6 +2240,11 @@ +@@ -2209,6 +2243,11 @@ hw->wiphy->max_scan_ssids = RTW_SCAN_MAX_SSIDS; hw->wiphy->max_scan_ie_len = rtw_get_max_scan_ie_len(rtwdev); @@ -579,7 +915,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_SCAN_RANDOM_SN); wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL); -@@ -2258,6 +2294,121 @@ +@@ -2258,6 +2297,129 @@ } EXPORT_SYMBOL(rtw_unregister_hw); @@ -629,6 +965,9 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re + rtw_dbg(rtwdev, RTW_DBG_STATE, "AP port switch from %d -> %d\n", + rtwvif_ap->port, rtwvif_target->port); + ++ /* Leave LPS so the value swapped are not in PS mode */ ++ rtw_leave_lps(rtwdev); ++ + reg1 = &rtwvif_ap->conf->net_type; + reg2 = &rtwvif_target->conf->net_type; + rtw_swap_reg_mask(rtwdev, reg1, reg2); @@ -647,6 +986,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re + + swap(rtwvif_target->port, rtwvif_ap->port); + swap(rtwvif_target->conf, rtwvif_ap->conf); ++ ++ rtw_fw_default_port(rtwdev, rtwvif_target); +} + +void rtw_core_port_switch(struct rtw_dev *rtwdev, struct ieee80211_vif *vif) @@ -692,18 +1033,21 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/re + if (!rtwdev->ap_active) + return; + -+ if (enable) ++ if (enable) { + rtw_write32_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); -+ else ++ rtw_write32_clr(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); ++ } else { + rtw_write32_clr(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); ++ rtw_write32_set(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); ++ } +} + MODULE_AUTHOR("Realtek Corporation"); MODULE_DESCRIPTION("Realtek 802.11ac wireless core module"); MODULE_LICENSE("Dual BSD/GPL"); diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h ---- a/drivers/net/wireless/realtek/rtw88/main.h 2023-06-09 04:48:26.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/main.h 2023-06-11 07:25:27.490597153 -0400 +--- a/drivers/net/wireless/realtek/rtw88/main.h 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/main.h 2023-06-22 13:52:09.000000000 -0400 @@ -88,7 +88,7 @@ RTW_BAND_60G = BIT(NL80211_BAND_60GHZ), }; @@ -729,7 +1073,15 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re enum rtw_wow_flags { RTW_WOW_FLAG_EN_MAGIC_PKT, RTW_WOW_FLAG_EN_REKEY_PKT, -@@ -1171,6 +1180,7 @@ +@@ -794,6 +803,7 @@ + struct rtw_vif { + enum rtw_net_type net_type; + u16 aid; ++ u8 mac_id; /* for STA mode only */ + u8 mac_addr[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + u8 port; +@@ -1171,6 +1181,7 @@ u32 txff_size; u32 rxff_size; u32 fw_rxff_size; @@ -737,7 +1089,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re u8 band; u8 page_size; u8 csi_buf_pg_num; -@@ -1874,7 +1884,7 @@ +@@ -1874,7 +1885,7 @@ RTW_SAR_BAND_NR, }; @@ -746,7 +1098,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re * which might not re-use same format with array common. */ union rtw_sar_cfg { -@@ -1893,7 +1903,9 @@ +@@ -1893,7 +1904,9 @@ u8 cut_version; u8 mp_chip; u8 oem_id; @@ -756,7 +1108,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re u8 ps_mode; u8 current_channel; -@@ -2023,7 +2035,7 @@ +@@ -2023,7 +2036,7 @@ struct rtw_tx_report tx_report; struct { @@ -765,7 +1117,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re u8 last_box_num; u32 seq; } h2c; -@@ -2039,6 +2051,7 @@ +@@ -2039,6 +2052,7 @@ u8 sta_cnt; u32 rts_threshold; @@ -773,7 +1125,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re DECLARE_BITMAP(mac_id_map, RTW_MAX_MAC_ID_NUM); DECLARE_BITMAP(flags, NUM_OF_RTW_FLAGS); -@@ -2050,6 +2063,7 @@ +@@ -2050,6 +2064,7 @@ bool need_rfk; struct completion fw_scan_density; @@ -781,7 +1133,7 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re /* hci related data, must be last */ u8 priv[] __aligned(sizeof(void *)); -@@ -2191,4 +2205,7 @@ +@@ -2191,4 +2206,7 @@ void rtw_update_channel(struct rtw_dev *rtwdev, u8 center_channel, u8 primary_channel, enum rtw_supported_band band, enum rtw_bandwidth bandwidth); @@ -790,8 +1142,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/re +void rtw_core_enable_beacon(struct rtw_dev *rtwdev, bool enable); #endif diff -Naur a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile ---- a/drivers/net/wireless/realtek/rtw88/Makefile 2023-06-09 04:48:26.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/Makefile 2023-06-11 07:28:33.845740907 -0400 +--- a/drivers/net/wireless/realtek/rtw88/Makefile 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/Makefile 2023-06-22 13:52:09.000000000 -0400 @@ -26,6 +26,9 @@ obj-$(CONFIG_RTW88_8822BE) += rtw88_8822be.o rtw88_8822be-objs := rtw8822be.o @@ -841,8 +1193,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/ obj-$(CONFIG_RTW88_USB) += rtw88_usb.o rtw88_usb-objs := usb.o diff -Naur a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c ---- a/drivers/net/wireless/realtek/rtw88/pci.c 2023-06-09 04:48:26.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/pci.c 2023-06-11 07:25:27.490597153 -0400 +--- a/drivers/net/wireless/realtek/rtw88/pci.c 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/pci.c 2023-06-22 13:52:09.000000000 -0400 @@ -89,13 +89,6 @@ writel(val, rtwpci->mmap + addr); } @@ -857,7 +1209,19 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/rea static void rtw_pci_free_tx_ring_skbs(struct rtw_dev *rtwdev, struct rtw_pci_tx_ring *tx_ring) { -@@ -1552,7 +1545,6 @@ +@@ -745,8 +738,9 @@ + u8 q; + + for (q = 0; q < RTK_MAX_TX_QUEUE_NUM; q++) { +- /* It may be not necessary to flush BCN and H2C tx queues. */ +- if (q == RTW_TX_QUEUE_BCN || q == RTW_TX_QUEUE_H2C) ++ /* Unnecessary to flush BCN, H2C and HI tx queues. */ ++ if (q == RTW_TX_QUEUE_BCN || q == RTW_TX_QUEUE_H2C || ++ q == RTW_TX_QUEUE_HI0) + continue; + + if (pci_queues & BIT(q)) +@@ -1552,7 +1546,6 @@ static void rtw_pci_declaim(struct rtw_dev *rtwdev, struct pci_dev *pdev) { @@ -865,9 +1229,29 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/rea pci_disable_device(pdev); } +diff -Naur a/drivers/net/wireless/realtek/rtw88/ps.c b/drivers/net/wireless/realtek/rtw88/ps.c +--- a/drivers/net/wireless/realtek/rtw88/ps.c 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/ps.c 2023-06-22 13:52:09.000000000 -0400 +@@ -18,6 +18,7 @@ + if (ret) + rtw_err(rtwdev, "leave idle state failed\n"); + ++ rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); + rtw_set_channel(rtwdev); + + return ret; +@@ -63,8 +64,6 @@ + + rtw_iterate_vifs(rtwdev, rtw_restore_port_cfg_iter, rtwdev); + +- rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); +- + return 0; + } + diff -Naur a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h ---- a/drivers/net/wireless/realtek/rtw88/reg.h 2023-06-09 04:48:26.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/reg.h 2023-06-11 07:25:27.493597107 -0400 +--- a/drivers/net/wireless/realtek/rtw88/reg.h 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/reg.h 2023-06-22 13:52:09.000000000 -0400 @@ -87,6 +87,7 @@ #define BIT_LTE_MUX_CTRL_PATH BIT(26) #define REG_HCI_OPT_CTRL 0x0074 @@ -905,9 +1289,25 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/rea #define REG_RXPKTNUM 0x02B0 #define REG_INT_MIG 0x0304 +@@ -366,6 +378,7 @@ + #define BIT_SIFS_BK_EN BIT(12) + #define REG_TXPAUSE 0x0522 + #define BIT_AC_QUEUE GENMASK(7, 0) ++#define BIT_HIGH_QUEUE BIT(5) + #define REG_RD_CTRL 0x0524 + #define BIT_EDCCA_MSK_CNTDOWN_EN BIT(11) + #define BIT_DIS_TXOP_CFE BIT(10) +@@ -398,6 +411,7 @@ + #define REG_TCR 0x0604 + #define BIT_PWRMGT_HWDATA_EN BIT(7) + #define BIT_TCR_UPDATE_TIMIE BIT(5) ++#define BIT_TCR_UPDATE_HGQMD BIT(4) + #define REG_RCR 0x0608 + #define BIT_APP_FCS BIT(31) + #define BIT_APP_MIC BIT(30) diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c ---- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c 2023-06-09 04:48:26.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c 2023-06-11 07:28:33.845740907 -0400 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c 2023-06-22 13:52:09.000000000 -0400 @@ -216,6 +216,12 @@ ether_addr_copy(efuse->addr, map->u.mac_addr); } @@ -931,7 +1331,27 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireles default: /* unsupported now */ return -ENOTSUPP; -@@ -2743,6 +2752,7 @@ +@@ -1961,15 +1970,17 @@ + size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */ + __le16 chksum = 0; + __le16 *data = (__le16 *)(txdesc); ++ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc; + +- SET_TX_DESC_TXDESC_CHECKSUM(txdesc, 0x0000); ++ le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM); + + while (words--) + chksum ^= *data++; + + chksum = ~chksum; + +- SET_TX_DESC_TXDESC_CHECKSUM(txdesc, __le16_to_cpu(chksum)); ++ le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum), ++ RTW_TX_DESC_W7_TXDESC_CHECKSUM); + } + + static struct rtw_chip_ops rtw8723d_ops = { +@@ -2743,6 +2754,7 @@ .ptct_efuse_size = 96 + 1, .txff_size = 32768, .rxff_size = 16384, @@ -940,8 +1360,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireles .is_pwr_by_rate_dec = true, .max_power_index = 0x3f, diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8723d.h b/drivers/net/wireless/realtek/rtw88/rtw8723d.h ---- a/drivers/net/wireless/realtek/rtw88/rtw8723d.h 2023-06-09 04:48:26.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h 2023-06-11 07:28:33.845740907 -0400 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.h 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h 2023-06-22 13:52:09.000000000 -0400 @@ -49,6 +49,11 @@ u8 mac_addr[ETH_ALEN]; /* 0x107 */ }; @@ -963,8 +1383,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8723d.h b/drivers/net/wireles }; diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c ---- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c 2023-06-09 04:48:26.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c 2023-06-11 07:25:27.498597030 -0400 +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c 2023-06-22 13:52:09.000000000 -0400 @@ -32,6 +32,12 @@ ether_addr_copy(efuse->addr, map->u.mac_addr); } @@ -1048,8 +1468,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireles .is_pwr_by_rate_dec = true, .max_power_index = 0x3f, diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8821c.h b/drivers/net/wireless/realtek/rtw88/rtw8821c.h ---- a/drivers/net/wireless/realtek/rtw88/rtw8821c.h 2023-06-09 04:48:26.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.h 2023-06-11 07:25:27.498597030 -0400 +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.h 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.h 2023-06-22 13:52:09.000000000 -0400 @@ -65,6 +65,11 @@ u8 res7; }; @@ -1071,8 +1491,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8821c.h b/drivers/net/wireles }; diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c ---- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c 2023-06-09 04:48:26.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c 2023-06-11 07:25:27.503596953 -0400 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c 2023-06-22 13:52:09.000000000 -0400 @@ -32,6 +32,12 @@ ether_addr_copy(efuse->addr, map->u.mac_addr); } @@ -1105,8 +1525,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireles .is_pwr_by_rate_dec = true, .max_power_index = 0x3f, diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822b.h b/drivers/net/wireless/realtek/rtw88/rtw8822b.h ---- a/drivers/net/wireless/realtek/rtw88/rtw8822b.h 2023-06-09 04:48:26.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.h 2023-06-11 07:25:27.503596953 -0400 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.h 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.h 2023-06-22 13:52:09.000000000 -0400 @@ -65,6 +65,11 @@ u8 res7; }; @@ -1131,8 +1551,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822b.h b/drivers/net/wireles }; diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c ---- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c 2023-06-09 04:48:26.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c 2023-06-11 07:25:27.510596846 -0400 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c 2023-06-22 13:52:09.000000000 -0400 @@ -35,6 +35,12 @@ ether_addr_copy(efuse->addr, map->u.mac_addr); } @@ -1165,8 +1585,8 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireles .is_pwr_by_rate_dec = false, .max_power_index = 0x7f, diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822c.h b/drivers/net/wireless/realtek/rtw88/rtw8822c.h ---- a/drivers/net/wireless/realtek/rtw88/rtw8822c.h 2023-06-09 04:48:26.000000000 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.h 2023-06-11 07:25:27.510596846 -0400 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.h 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.h 2023-06-22 13:52:09.000000000 -0400 @@ -16,6 +16,11 @@ u8 res2[0x3d]; }; @@ -1190,6 +1610,343 @@ diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8822c.h b/drivers/net/wireles }; }; +diff -Naur a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c +--- a/drivers/net/wireless/realtek/rtw88/tx.c 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/tx.c 2023-06-22 13:52:09.000000000 -0400 +@@ -34,43 +34,57 @@ + + void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb) + { +- __le32 *txdesc = (__le32 *)skb->data; ++ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data; ++ bool more_data = false; ++ ++ if (pkt_info->qsel == TX_DESC_QSEL_HIGH) ++ more_data = true; ++ ++ tx_desc->w0 = le32_encode_bits(pkt_info->tx_pkt_size, RTW_TX_DESC_W0_TXPKTSIZE) | ++ le32_encode_bits(pkt_info->offset, RTW_TX_DESC_W0_OFFSET) | ++ le32_encode_bits(pkt_info->bmc, RTW_TX_DESC_W0_BMC) | ++ le32_encode_bits(pkt_info->ls, RTW_TX_DESC_W0_LS) | ++ le32_encode_bits(pkt_info->dis_qselseq, RTW_TX_DESC_W0_DISQSELSEQ); ++ ++ tx_desc->w1 = le32_encode_bits(pkt_info->qsel, RTW_TX_DESC_W1_QSEL) | ++ le32_encode_bits(pkt_info->rate_id, RTW_TX_DESC_W1_RATE_ID) | ++ le32_encode_bits(pkt_info->sec_type, RTW_TX_DESC_W1_SEC_TYPE) | ++ le32_encode_bits(pkt_info->pkt_offset, RTW_TX_DESC_W1_PKT_OFFSET) | ++ le32_encode_bits(more_data, RTW_TX_DESC_W1_MORE_DATA); ++ ++ tx_desc->w2 = le32_encode_bits(pkt_info->ampdu_en, RTW_TX_DESC_W2_AGG_EN) | ++ le32_encode_bits(pkt_info->report, RTW_TX_DESC_W2_SPE_RPT) | ++ le32_encode_bits(pkt_info->ampdu_density, RTW_TX_DESC_W2_AMPDU_DEN) | ++ le32_encode_bits(pkt_info->bt_null, RTW_TX_DESC_W2_BT_NULL); ++ ++ tx_desc->w3 = le32_encode_bits(pkt_info->hw_ssn_sel, RTW_TX_DESC_W3_HW_SSN_SEL) | ++ le32_encode_bits(pkt_info->use_rate, RTW_TX_DESC_W3_USE_RATE) | ++ le32_encode_bits(pkt_info->dis_rate_fallback, RTW_TX_DESC_W3_DISDATAFB) | ++ le32_encode_bits(pkt_info->rts, RTW_TX_DESC_W3_USE_RTS) | ++ le32_encode_bits(pkt_info->nav_use_hdr, RTW_TX_DESC_W3_NAVUSEHDR) | ++ le32_encode_bits(pkt_info->ampdu_factor, RTW_TX_DESC_W3_MAX_AGG_NUM); ++ ++ tx_desc->w4 = le32_encode_bits(pkt_info->rate, RTW_TX_DESC_W4_DATARATE); ++ ++ tx_desc->w5 = le32_encode_bits(pkt_info->short_gi, RTW_TX_DESC_W5_DATA_SHORT) | ++ le32_encode_bits(pkt_info->bw, RTW_TX_DESC_W5_DATA_BW) | ++ le32_encode_bits(pkt_info->ldpc, RTW_TX_DESC_W5_DATA_LDPC) | ++ le32_encode_bits(pkt_info->stbc, RTW_TX_DESC_W5_DATA_STBC); ++ ++ tx_desc->w6 = le32_encode_bits(pkt_info->sn, RTW_TX_DESC_W6_SW_DEFINE); ++ ++ tx_desc->w8 = le32_encode_bits(pkt_info->en_hwseq, RTW_TX_DESC_W8_EN_HWSEQ); ++ ++ tx_desc->w9 = le32_encode_bits(pkt_info->seq, RTW_TX_DESC_W9_SW_SEQ); + +- SET_TX_DESC_TXPKTSIZE(txdesc, pkt_info->tx_pkt_size); +- SET_TX_DESC_OFFSET(txdesc, pkt_info->offset); +- SET_TX_DESC_PKT_OFFSET(txdesc, pkt_info->pkt_offset); +- SET_TX_DESC_QSEL(txdesc, pkt_info->qsel); +- SET_TX_DESC_BMC(txdesc, pkt_info->bmc); +- SET_TX_DESC_RATE_ID(txdesc, pkt_info->rate_id); +- SET_TX_DESC_DATARATE(txdesc, pkt_info->rate); +- SET_TX_DESC_DISDATAFB(txdesc, pkt_info->dis_rate_fallback); +- SET_TX_DESC_USE_RATE(txdesc, pkt_info->use_rate); +- SET_TX_DESC_SEC_TYPE(txdesc, pkt_info->sec_type); +- SET_TX_DESC_DATA_BW(txdesc, pkt_info->bw); +- SET_TX_DESC_SW_SEQ(txdesc, pkt_info->seq); +- SET_TX_DESC_MAX_AGG_NUM(txdesc, pkt_info->ampdu_factor); +- SET_TX_DESC_AMPDU_DENSITY(txdesc, pkt_info->ampdu_density); +- SET_TX_DESC_DATA_STBC(txdesc, pkt_info->stbc); +- SET_TX_DESC_DATA_LDPC(txdesc, pkt_info->ldpc); +- SET_TX_DESC_AGG_EN(txdesc, pkt_info->ampdu_en); +- SET_TX_DESC_LS(txdesc, pkt_info->ls); +- SET_TX_DESC_DATA_SHORT(txdesc, pkt_info->short_gi); +- SET_TX_DESC_SPE_RPT(txdesc, pkt_info->report); +- SET_TX_DESC_SW_DEFINE(txdesc, pkt_info->sn); +- SET_TX_DESC_USE_RTS(txdesc, pkt_info->rts); + if (pkt_info->rts) { +- SET_TX_DESC_RTSRATE(txdesc, DESC_RATE24M); +- SET_TX_DESC_DATA_RTS_SHORT(txdesc, 1); +- } +- SET_TX_DESC_DISQSELSEQ(txdesc, pkt_info->dis_qselseq); +- SET_TX_DESC_EN_HWSEQ(txdesc, pkt_info->en_hwseq); +- SET_TX_DESC_HW_SSN_SEL(txdesc, pkt_info->hw_ssn_sel); +- SET_TX_DESC_NAVUSEHDR(txdesc, pkt_info->nav_use_hdr); +- SET_TX_DESC_BT_NULL(txdesc, pkt_info->bt_null); +- if (pkt_info->tim_offset) { +- SET_TX_DESC_TIM_EN(txdesc, 1); +- SET_TX_DESC_TIM_OFFSET(txdesc, pkt_info->tim_offset); ++ tx_desc->w4 |= le32_encode_bits(DESC_RATE24M, RTW_TX_DESC_W4_RTSRATE); ++ tx_desc->w5 |= le32_encode_bits(1, RTW_TX_DESC_W5_DATA_RTS_SHORT); + } ++ ++ if (pkt_info->tim_offset) ++ tx_desc->w9 |= le32_encode_bits(1, RTW_TX_DESC_W9_TIM_EN) | ++ le32_encode_bits(pkt_info->tim_offset, RTW_TX_DESC_W9_TIM_OFFSET); + } + EXPORT_SYMBOL(rtw_tx_fill_tx_desc); + +@@ -635,9 +649,8 @@ + rcu_read_unlock(); + } + +-void rtw_tx_work(struct work_struct *w) ++void __rtw_tx_work(struct rtw_dev *rtwdev) + { +- struct rtw_dev *rtwdev = container_of(w, struct rtw_dev, tx_work); + struct rtw_txq *rtwtxq, *tmp; + + spin_lock_bh(&rtwdev->txq_lock); +@@ -658,6 +671,13 @@ + spin_unlock_bh(&rtwdev->txq_lock); + } + ++void rtw_tx_work(struct work_struct *w) ++{ ++ struct rtw_dev *rtwdev = container_of(w, struct rtw_dev, tx_work); ++ ++ __rtw_tx_work(rtwdev); ++} ++ + void rtw_txq_init(struct rtw_dev *rtwdev, struct ieee80211_txq *txq) + { + struct rtw_txq *rtwtxq; +diff -Naur a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/realtek/rtw88/tx.h +--- a/drivers/net/wireless/realtek/rtw88/tx.h 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/tx.h 2023-06-22 13:52:09.000000000 -0400 +@@ -9,76 +9,53 @@ + + #define RTW_TX_PROBE_TIMEOUT msecs_to_jiffies(500) + +-#define SET_TX_DESC_TXPKTSIZE(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, GENMASK(15, 0)) +-#define SET_TX_DESC_OFFSET(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, GENMASK(23, 16)) +-#define SET_TX_DESC_PKT_OFFSET(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x01, value, GENMASK(28, 24)) +-#define SET_TX_DESC_QSEL(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x01, value, GENMASK(12, 8)) +-#define SET_TX_DESC_BMC(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, BIT(24)) +-#define SET_TX_DESC_RATE_ID(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x01, value, GENMASK(20, 16)) +-#define SET_TX_DESC_DATARATE(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x04, value, GENMASK(6, 0)) +-#define SET_TX_DESC_DISDATAFB(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(10)) +-#define SET_TX_DESC_USE_RATE(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(8)) +-#define SET_TX_DESC_SEC_TYPE(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x01, value, GENMASK(23, 22)) +-#define SET_TX_DESC_DATA_BW(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, GENMASK(6, 5)) +-#define SET_TX_DESC_SW_SEQ(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x09, value, GENMASK(23, 12)) +-#define SET_TX_DESC_TIM_EN(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x09, value, BIT(7)) +-#define SET_TX_DESC_TIM_OFFSET(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x09, value, GENMASK(6, 0)) +-#define SET_TX_DESC_MAX_AGG_NUM(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, GENMASK(21, 17)) +-#define SET_TX_DESC_USE_RTS(tx_desc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(12)) +-#define SET_TX_DESC_RTSRATE(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x04, value, GENMASK(28, 24)) +-#define SET_TX_DESC_DATA_RTS_SHORT(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, BIT(12)) +-#define SET_TX_DESC_AMPDU_DENSITY(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, GENMASK(22, 20)) +-#define SET_TX_DESC_DATA_STBC(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, GENMASK(9, 8)) +-#define SET_TX_DESC_DATA_LDPC(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, BIT(7)) +-#define SET_TX_DESC_AGG_EN(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(12)) +-#define SET_TX_DESC_LS(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, BIT(26)) +-#define SET_TX_DESC_DATA_SHORT(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, BIT(4)) +-#define SET_TX_DESC_SPE_RPT(tx_desc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(19)) +-#define SET_TX_DESC_SW_DEFINE(tx_desc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x06, value, GENMASK(11, 0)) +-#define SET_TX_DESC_DISQSELSEQ(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, BIT(31)) +-#define SET_TX_DESC_EN_HWSEQ(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x08, value, BIT(15)) +-#define SET_TX_DESC_HW_SSN_SEL(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, GENMASK(7, 6)) +-#define SET_TX_DESC_NAVUSEHDR(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(15)) +-#define SET_TX_DESC_BT_NULL(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(23)) +-#define SET_TX_DESC_TXDESC_CHECKSUM(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x07, value, GENMASK(15, 0)) +-#define SET_TX_DESC_DMA_TXAGG_NUM(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x07, value, GENMASK(31, 24)) +-#define GET_TX_DESC_PKT_OFFSET(txdesc) \ +- le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(28, 24)) +-#define GET_TX_DESC_QSEL(txdesc) \ +- le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(12, 8)) ++struct rtw_tx_desc { ++ __le32 w0; ++ __le32 w1; ++ __le32 w2; ++ __le32 w3; ++ __le32 w4; ++ __le32 w5; ++ __le32 w6; ++ __le32 w7; ++ __le32 w8; ++ __le32 w9; ++} __packed; ++ ++#define RTW_TX_DESC_W0_TXPKTSIZE GENMASK(15, 0) ++#define RTW_TX_DESC_W0_OFFSET GENMASK(23, 16) ++#define RTW_TX_DESC_W0_BMC BIT(24) ++#define RTW_TX_DESC_W0_LS BIT(26) ++#define RTW_TX_DESC_W0_DISQSELSEQ BIT(31) ++#define RTW_TX_DESC_W1_QSEL GENMASK(12, 8) ++#define RTW_TX_DESC_W1_RATE_ID GENMASK(20, 16) ++#define RTW_TX_DESC_W1_SEC_TYPE GENMASK(23, 22) ++#define RTW_TX_DESC_W1_PKT_OFFSET GENMASK(28, 24) ++#define RTW_TX_DESC_W1_MORE_DATA BIT(29) ++#define RTW_TX_DESC_W2_AGG_EN BIT(12) ++#define RTW_TX_DESC_W2_SPE_RPT BIT(19) ++#define RTW_TX_DESC_W2_AMPDU_DEN GENMASK(22, 20) ++#define RTW_TX_DESC_W2_BT_NULL BIT(23) ++#define RTW_TX_DESC_W3_HW_SSN_SEL GENMASK(7, 6) ++#define RTW_TX_DESC_W3_USE_RATE BIT(8) ++#define RTW_TX_DESC_W3_DISDATAFB BIT(10) ++#define RTW_TX_DESC_W3_USE_RTS BIT(12) ++#define RTW_TX_DESC_W3_NAVUSEHDR BIT(15) ++#define RTW_TX_DESC_W3_MAX_AGG_NUM GENMASK(21, 17) ++#define RTW_TX_DESC_W4_DATARATE GENMASK(6, 0) ++#define RTW_TX_DESC_W4_RTSRATE GENMASK(28, 24) ++#define RTW_TX_DESC_W5_DATA_SHORT BIT(4) ++#define RTW_TX_DESC_W5_DATA_BW GENMASK(6, 5) ++#define RTW_TX_DESC_W5_DATA_LDPC BIT(7) ++#define RTW_TX_DESC_W5_DATA_STBC GENMASK(9, 8) ++#define RTW_TX_DESC_W5_DATA_RTS_SHORT BIT(12) ++#define RTW_TX_DESC_W6_SW_DEFINE GENMASK(11, 0) ++#define RTW_TX_DESC_W7_TXDESC_CHECKSUM GENMASK(15, 0) ++#define RTW_TX_DESC_W7_DMA_TXAGG_NUM GENMASK(31, 24) ++#define RTW_TX_DESC_W8_EN_HWSEQ BIT(15) ++#define RTW_TX_DESC_W9_SW_SEQ GENMASK(23, 12) ++#define RTW_TX_DESC_W9_TIM_EN BIT(7) ++#define RTW_TX_DESC_W9_TIM_OFFSET GENMASK(6, 0) + + enum rtw_tx_desc_queue_select { + TX_DESC_QSEL_TID0 = 0, +@@ -111,6 +88,7 @@ + void rtw_txq_init(struct rtw_dev *rtwdev, struct ieee80211_txq *txq); + void rtw_txq_cleanup(struct rtw_dev *rtwdev, struct ieee80211_txq *txq); + void rtw_tx_work(struct work_struct *w); ++void __rtw_tx_work(struct rtw_dev *rtwdev); + void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct ieee80211_sta *sta, +@@ -139,13 +117,15 @@ + { + __le16 chksum = 0; + __le16 *data = (__le16 *)(txdesc); ++ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc; + +- SET_TX_DESC_TXDESC_CHECKSUM(txdesc, 0x0000); ++ le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM); + + while (words--) + chksum ^= *data++; + +- SET_TX_DESC_TXDESC_CHECKSUM(txdesc, __le16_to_cpu(chksum)); ++ le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum), ++ RTW_TX_DESC_W7_TXDESC_CHECKSUM); + } + + static inline void rtw_tx_fill_txdesc_checksum(struct rtw_dev *rtwdev, +diff -Naur a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c +--- a/drivers/net/wireless/realtek/rtw88/usb.c 2023-06-21 10:02:19.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/usb.c 2023-06-22 13:52:09.000000000 -0400 +@@ -24,11 +24,12 @@ + static void rtw_usb_fill_tx_checksum(struct rtw_usb *rtwusb, + struct sk_buff *skb, int agg_num) + { ++ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data; + struct rtw_dev *rtwdev = rtwusb->rtwdev; + struct rtw_tx_pkt_info pkt_info; + +- SET_TX_DESC_DMA_TXAGG_NUM(skb->data, agg_num); +- pkt_info.pkt_offset = GET_TX_DESC_PKT_OFFSET(skb->data); ++ le32p_replace_bits(&tx_desc->w7, agg_num, RTW_TX_DESC_W7_DMA_TXAGG_NUM); ++ pkt_info.pkt_offset = le32_get_bits(tx_desc->w1, RTW_TX_DESC_W1_PKT_OFFSET); + rtw_tx_fill_txdesc_checksum(rtwdev, &pkt_info, skb->data); + } + +@@ -306,11 +307,13 @@ + static bool rtw_usb_tx_agg_skb(struct rtw_usb *rtwusb, struct sk_buff_head *list) + { + struct rtw_dev *rtwdev = rtwusb->rtwdev; ++ struct rtw_tx_desc *tx_desc; + struct rtw_usb_txcb *txcb; + struct sk_buff *skb_head; + struct sk_buff *skb_iter; + int agg_num = 0; + unsigned int align_next = 0; ++ u8 qsel; + + if (skb_queue_empty(list)) + return false; +@@ -363,9 +366,10 @@ + + queue: + skb_queue_tail(&txcb->tx_ack_queue, skb_head); ++ tx_desc = (struct rtw_tx_desc *)skb_head->data; ++ qsel = le32_get_bits(tx_desc->w1, RTW_TX_DESC_W1_QSEL); + +- rtw_usb_write_port(rtwdev, GET_TX_DESC_QSEL(skb_head->data), skb_head, +- rtw_usb_write_port_tx_complete, txcb); ++ rtw_usb_write_port(rtwdev, qsel, skb_head, rtw_usb_write_port_tx_complete, txcb); + + return true; + } +@@ -465,6 +469,9 @@ + + if (unlikely(ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))) + qsel = TX_DESC_QSEL_MGMT; ++ else if (is_broadcast_ether_addr(hdr->addr1) || ++ is_multicast_ether_addr(hdr->addr1)) ++ qsel = TX_DESC_QSEL_HIGH; + else if (skb_get_queue_mapping(skb) <= IEEE80211_AC_BK) + qsel = skb->priority; + else +@@ -535,7 +542,7 @@ + } + + if (skb_queue_len(&rtwusb->rx_queue) >= RTW_USB_MAX_RXQ_LEN) { +- rtw_err(rtwdev, "failed to get rx_queue, overflow\n"); ++ dev_dbg_ratelimited(rtwdev->dev, "failed to get rx_queue, overflow\n"); + dev_kfree_skb_any(skb); + continue; + } diff -Naur a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h --- a/include/linux/mmc/sdio_ids.h 2023-06-09 04:48:26.000000000 -0400 +++ b/include/linux/mmc/sdio_ids.h 2023-06-11 07:28:33.845740907 -0400 diff --git a/patch/misc/rtw88/6.3/002-rtw88-linux-next.patch b/patch/misc/rtw88/6.3/002-rtw88-linux-next.patch index ed19aafa43..f29e5a96f2 100644 --- a/patch/misc/rtw88/6.3/002-rtw88-linux-next.patch +++ b/patch/misc/rtw88/6.3/002-rtw88-linux-next.patch @@ -1,5 +1,5 @@ ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723ds.c 2023-06-11 07:28:33.845740907 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723ds.c 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) Martin Blumenstingl @@ -42,8 +42,8 @@ +MODULE_AUTHOR("Martin Blumenstingl "); +MODULE_DESCRIPTION("Realtek 802.11n wireless 8723ds driver"); +MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821cs.c 2023-06-11 07:25:27.501596984 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821cs.c 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) Martin Blumenstingl @@ -81,8 +81,8 @@ +MODULE_AUTHOR("Martin Blumenstingl "); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821cs driver"); +MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822bs.c 2023-06-11 07:25:27.508596876 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822bs.c 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) Jernej Skrabec @@ -120,8 +120,8 @@ +MODULE_AUTHOR("Jernej Skrabec "); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822bs driver"); +MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822cs.c 2023-06-11 07:25:27.519596708 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822cs.c 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) Martin Blumenstingl @@ -159,8 +159,8 @@ +MODULE_AUTHOR("Martin Blumenstingl "); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822cs driver"); +MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/sdio.c 2023-06-11 07:28:33.844740922 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/sdio.c 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,1404 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright (C) 2021 Martin Blumenstingl @@ -1566,8 +1566,8 @@ +MODULE_AUTHOR("Jernej Skrabec"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless SDIO driver"); +MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null 2023-06-08 17:12:18.013167787 -0400 -+++ b/drivers/net/wireless/realtek/rtw88/sdio.h 2023-06-11 07:25:27.521596677 -0400 +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/sdio.h 2023-06-22 13:52:09.000000000 -0400 @@ -0,0 +1,178 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright (C) 2021 Martin Blumenstingl diff --git a/patch/misc/rtw88/6.3/003-rtw88-add-missing-unwind-goto-for_rtw_download_firmware.patch b/patch/misc/rtw88/6.3/003-rtw88-add-missing-unwind-goto-for_rtw_download_firmware.patch deleted file mode 100644 index e1d032bbf2..0000000000 --- a/patch/misc/rtw88/6.3/003-rtw88-add-missing-unwind-goto-for_rtw_download_firmware.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Ping-Ke Shih @ 2023-06-07 1:27 UTC (permalink / raw) - To: tony0620emma, kvalo; +Cc: s.hauer, dan.carpenter, lkp, linux-wireless - -This flaw is detected by smatch: - drivers/net/wireless/realtek/rtw88/mac.c:748 __rtw_download_firmware() - warn: missing unwind goto? - -Though most things of dlfw_fail have been done by -download_firmware_end_flow() and wlan_cpu_enable(), an exception is that -download_firmware_end_flow() clear BIT_MCUFWDL_EN bit conditionally. -So, make this change to clear the bit. - -diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c -index a168f36c38ece..298663b035808 100644 ---- a/drivers/net/wireless/realtek/rtw88/mac.c -+++ b/drivers/net/wireless/realtek/rtw88/mac.c -@@ -794,8 +794,10 @@ static int __rtw_download_firmware(struct rtw_dev *rtwdev, - - wlan_cpu_enable(rtwdev, true); - -- if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) -- return -EBUSY; -+ if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) { -+ ret = -EBUSY; -+ goto dlfw_fail; -+ } - - ret = download_firmware_validate(rtwdev); - if (ret) --- -2.25.1 diff --git a/patch/misc/rtw88/6.3/004-rtw88-fix-action-frame-transmission-fail-before-association.patch b/patch/misc/rtw88/6.3/004-rtw88-fix-action-frame-transmission-fail-before-association.patch deleted file mode 100644 index a41e6fb153..0000000000 --- a/patch/misc/rtw88/6.3/004-rtw88-fix-action-frame-transmission-fail-before-association.patch +++ /dev/null @@ -1,41 +0,0 @@ -From: Ping-Ke Shih @ 2023-06-15 11:43 UTC (permalink / raw) - To: tony0620emma, kvalo; +Cc: phhuang, linux-wireless - -From: Po-Hao Huang - -For combo chips, antennas were controlled by bluetooth only during -power on. If WiFi wish to do transmission, notification to the coexistence -module are required. Previously we only do this before authentication. -To allow transmission before auth, such as management TX, now we start -the initiation of coexistence earlier so antennas are shared between -WiFi and bluetooth after set_channel(), and frames could then be sent. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih ---- - drivers/net/wireless/realtek/rtw88/ps.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/drivers/net/wireless/realtek/rtw88/ps.c b/drivers/net/wireless/realtek/rtw88/ps.c -index 53933fb38a330..43e80a3a8136d 100644 ---- a/drivers/net/wireless/realtek/rtw88/ps.c -+++ b/drivers/net/wireless/realtek/rtw88/ps.c -@@ -18,6 +18,7 @@ static int rtw_ips_pwr_up(struct rtw_dev *rtwdev) - if (ret) - rtw_err(rtwdev, "leave idle state failed\n"); - -+ rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); - rtw_set_channel(rtwdev); - - return ret; -@@ -63,8 +64,6 @@ int rtw_leave_ips(struct rtw_dev *rtwdev) - - rtw_iterate_vifs(rtwdev, rtw_restore_port_cfg_iter, rtwdev); - -- rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); -- - return 0; - } - --- -2.25.1 diff --git a/patch/misc/rtw88/6.4/001-rtw88-add-support-for-the-RTL8723DS-SDIO-wifi-chip.patch b/patch/misc/rtw88/6.4/001-rtw88-add-support-for-the-RTL8723DS-SDIO-wifi-chip.patch deleted file mode 100644 index ff6277e1f3..0000000000 --- a/patch/misc/rtw88/6.4/001-rtw88-add-support-for-the-RTL8723DS-SDIO-wifi-chip.patch +++ /dev/null @@ -1,314 +0,0 @@ -From: Martin Blumenstingl @ 2023-05-22 20:24 UTC (permalink / raw) - To: linux-wireless - Cc: linux-mmc, linux-kernel, ulf.hansson, kvalo, tony0620emma, - Peter Robinson, Ping-Ke Shih, jernej.skrabec, Larry Finger, - Martin Blumenstingl - -rtw_sdio_rx_isr() is responsible for receiving data from the wifi chip -and is called from the SDIO interrupt handler when the interrupt status -register (HISR) has the RX_REQUEST bit set. After the first batch of -data has been processed by the driver the wifi chip may have more data -ready to be read, which is managed by a loop in rtw_sdio_rx_isr(). - -It turns out that there are cases where the RX buffer length (from the -REG_SDIO_RX0_REQ_LEN register) does not match the data we receive. The -following two cases were observed with a RTL8723DS card: -- RX length is smaller than the total packet length including overhead - and actual data bytes (whose length is part of the buffer we read from - the wifi chip and is stored in rtw_rx_pkt_stat.pkt_len). This can - result in errors like: - skbuff: skb_over_panic: text:ffff8000011924ac len:3341 put:3341 - (one case observed was: RX buffer length = 1536 bytes but - rtw_rx_pkt_stat.pkt_len = 1546 bytes, this is not valid as it means - we need to read beyond the end of the buffer) -- RX length looks valid but rtw_rx_pkt_stat.pkt_len is zero - -Check if the RX_REQUEST is set in the HISR register for each iteration -inside rtw_sdio_rx_isr(). This mimics what the RTL8723DS vendor driver -does and makes the driver only read more data if the RX_REQUEST bit is -set (which seems to be a way for the card's hardware or firmware to -tell the host that data is ready to be processed). - -For RTW_WCPU_11AC chips this check is not needed. The RTL8822BS vendor -driver for example states that this check is unnecessary (but still uses -it) and the RTL8822CS drops this check entirely. - -Reviewed-by: Ping-Ke Shih -Signed-off-by: Martin Blumenstingl ---- -Changes since v1: -- added Ping-Ke's Reviewed-by (thank you!) - - - drivers/net/wireless/realtek/rtw88/sdio.c | 24 ++++++++++++++++++++--- - 1 file changed, 21 insertions(+), 3 deletions(-) - -diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c -index 06fce7c3adda..2c1fb2dabd40 100644 ---- a/drivers/net/wireless/realtek/rtw88/sdio.c -+++ b/drivers/net/wireless/realtek/rtw88/sdio.c -@@ -998,9 +998,9 @@ static void rtw_sdio_rxfifo_recv(struct rtw_dev *rtwdev, u32 rx_len) - - static void rtw_sdio_rx_isr(struct rtw_dev *rtwdev) - { -- u32 rx_len, total_rx_bytes = 0; -+ u32 rx_len, hisr, total_rx_bytes = 0; - -- while (total_rx_bytes < SZ_64K) { -+ do { - if (rtw_chip_wcpu_11n(rtwdev)) - rx_len = rtw_read16(rtwdev, REG_SDIO_RX0_REQ_LEN); - else -@@ -1012,7 +1012,25 @@ static void rtw_sdio_rx_isr(struct rtw_dev *rtwdev) - rtw_sdio_rxfifo_recv(rtwdev, rx_len); - - total_rx_bytes += rx_len; -- } -+ -+ if (rtw_chip_wcpu_11n(rtwdev)) { -+ /* Stop if no more RX requests are pending, even if -+ * rx_len could be greater than zero in the next -+ * iteration. This is needed because the RX buffer may -+ * already contain data while either HW or FW are not -+ * done filling that buffer yet. Still reading the -+ * buffer can result in packets where -+ * rtw_rx_pkt_stat.pkt_len is zero or points beyond the -+ * end of the buffer. -+ */ -+ hisr = rtw_read32(rtwdev, REG_SDIO_HISR); -+ } else { -+ /* RTW_WCPU_11AC chips have improved hardware or -+ * firmware and can use rx_len unconditionally. -+ */ -+ hisr = REG_SDIO_HISR_RX_REQUEST; -+ } -+ } while (total_rx_bytes < SZ_64K && hisr & REG_SDIO_HISR_RX_REQUEST); - } - - static void rtw_sdio_handle_interrupt(struct sdio_func *sdio_func) --- -2.40.1 -From: Martin Blumenstingl @ 2023-05-22 20:24 UTC (permalink / raw) - To: linux-wireless - Cc: linux-mmc, linux-kernel, ulf.hansson, kvalo, tony0620emma, - Peter Robinson, Ping-Ke Shih, jernej.skrabec, Larry Finger, - Martin Blumenstingl - -The efuse of the SDIO RTL8723DS chip has only one known member: the mac -address is at offset 0x11a. Add a struct rtw8723ds_efuse describing this -and use it for copying the mac address when the SDIO bus is used. - -Reviewed-by: Ping-Ke Shih -Signed-off-by: Martin Blumenstingl ---- -Changes since v1: -- added Ping-Ke's Reviewed-by (thank you!) - - - drivers/net/wireless/realtek/rtw88/rtw8723d.c | 9 +++++++++ - drivers/net/wireless/realtek/rtw88/rtw8723d.h | 6 ++++++ - 2 files changed, 15 insertions(+) - -diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c -index 06e7454c9ca6..cadf66f4e854 100644 ---- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c -@@ -216,6 +216,12 @@ static void rtw8723du_efuse_parsing(struct rtw_efuse *efuse, - ether_addr_copy(efuse->addr, map->u.mac_addr); - } - -+static void rtw8723ds_efuse_parsing(struct rtw_efuse *efuse, -+ struct rtw8723d_efuse *map) -+{ -+ ether_addr_copy(efuse->addr, map->s.mac_addr); -+} -+ - static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) - { - struct rtw_efuse *efuse = &rtwdev->efuse; -@@ -248,6 +254,9 @@ static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) - case RTW_HCI_TYPE_USB: - rtw8723du_efuse_parsing(efuse, map); - break; -+ case RTW_HCI_TYPE_SDIO: -+ rtw8723ds_efuse_parsing(efuse, map); -+ break; - default: - /* unsupported now */ - return -ENOTSUPP; -diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.h b/drivers/net/wireless/realtek/rtw88/rtw8723d.h -index a356318a5c15..3642a2c7f80c 100644 ---- a/drivers/net/wireless/realtek/rtw88/rtw8723d.h -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h -@@ -49,6 +49,11 @@ struct rtw8723du_efuse { - u8 mac_addr[ETH_ALEN]; /* 0x107 */ - }; - -+struct rtw8723ds_efuse { -+ u8 res4[0x4a]; /* 0xd0 */ -+ u8 mac_addr[ETH_ALEN]; /* 0x11a */ -+}; -+ - struct rtw8723d_efuse { - __le16 rtl_id; - u8 rsvd[2]; -@@ -80,6 +85,7 @@ struct rtw8723d_efuse { - union { - struct rtw8723de_efuse e; - struct rtw8723du_efuse u; -+ struct rtw8723ds_efuse s; - }; - }; - --- -2.40.1 -From: Martin Blumenstingl @ 2023-05-22 20:24 UTC (permalink / raw) - To: linux-wireless - Cc: linux-mmc, linux-kernel, ulf.hansson, kvalo, tony0620emma, - Peter Robinson, Ping-Ke Shih, jernej.skrabec, Larry Finger, - Martin Blumenstingl - -RTL8723DS comes in two variant and each of them has their own SDIO ID: -- 0xd723 can connect two antennas. The WiFi part is still 1x1 so the - second antenna can be dedicated to Bluetooth -- 0xd724 can only connect one antenna so it's shared between WiFi and - Bluetooth - -Add a new entry for the single antenna RTL8723DS (0xd724) which can be -found on the MangoPi MQ-Quad. Also rename the existing RTL8723DS entry -(0xd723) so it's name reflects that it's the variant with support for -two antennas. - -Reviewed-by: Ping-Ke Shih -Signed-off-by: Martin Blumenstingl ---- -Changes since v1: -- added Ping-Ke's Reviewed-by (thank you!) - - - include/linux/mmc/sdio_ids.h | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h -index c653accdc7fd..7fada7a714fe 100644 ---- a/include/linux/mmc/sdio_ids.h -+++ b/include/linux/mmc/sdio_ids.h -@@ -121,7 +121,8 @@ - #define SDIO_DEVICE_ID_REALTEK_RTW8822BS 0xb822 - #define SDIO_DEVICE_ID_REALTEK_RTW8821CS 0xc821 - #define SDIO_DEVICE_ID_REALTEK_RTW8822CS 0xc822 --#define SDIO_DEVICE_ID_REALTEK_RTW8723DS 0xd723 -+#define SDIO_DEVICE_ID_REALTEK_RTW8723DS_2ANT 0xd723 -+#define SDIO_DEVICE_ID_REALTEK_RTW8723DS_1ANT 0xd724 - #define SDIO_DEVICE_ID_REALTEK_RTW8821DS 0xd821 - - #define SDIO_VENDOR_ID_SIANO 0x039a --- -2.40.1 -From: Martin Blumenstingl @ 2023-05-22 20:24 UTC (permalink / raw) - To: linux-wireless - Cc: linux-mmc, linux-kernel, ulf.hansson, kvalo, tony0620emma, - Peter Robinson, Ping-Ke Shih, jernej.skrabec, Larry Finger, - Martin Blumenstingl - -Wire up RTL8723DS chipset support using the rtw88 SDIO HCI code as well -as the existing RTL8723D chipset code. - -Reviewed-by: Ping-Ke Shih -Signed-off-by: Martin Blumenstingl ---- -Changes since v1: -- added Ping-Ke's Reviewed-by (thank you!) - - - drivers/net/wireless/realtek/rtw88/Kconfig | 11 +++++ - drivers/net/wireless/realtek/rtw88/Makefile | 3 ++ - .../net/wireless/realtek/rtw88/rtw8723ds.c | 41 +++++++++++++++++++ - 3 files changed, 55 insertions(+) - create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723ds.c - -diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig -index 29eb2f8e0eb7..cffad1c01249 100644 ---- a/drivers/net/wireless/realtek/rtw88/Kconfig -+++ b/drivers/net/wireless/realtek/rtw88/Kconfig -@@ -111,6 +111,17 @@ config RTW88_8723DE - - 802.11n PCIe wireless network adapter - -+config RTW88_8723DS -+ tristate "Realtek 8723DS SDIO wireless network adapter" -+ depends on MMC -+ select RTW88_CORE -+ select RTW88_SDIO -+ select RTW88_8723D -+ help -+ Select this option will enable support for 8723DS chipset -+ -+ 802.11n SDIO wireless network adapter -+ - config RTW88_8723DU - tristate "Realtek 8723DU USB wireless network adapter" - depends on USB -diff --git a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile -index 82979b30ae8d..fd212c09d88a 100644 ---- a/drivers/net/wireless/realtek/rtw88/Makefile -+++ b/drivers/net/wireless/realtek/rtw88/Makefile -@@ -50,6 +50,9 @@ rtw88_8723d-objs := rtw8723d.o rtw8723d_table.o - obj-$(CONFIG_RTW88_8723DE) += rtw88_8723de.o - rtw88_8723de-objs := rtw8723de.o - -+obj-$(CONFIG_RTW88_8723DS) += rtw88_8723ds.o -+rtw88_8723ds-objs := rtw8723ds.o -+ - obj-$(CONFIG_RTW88_8723DU) += rtw88_8723du.o - rtw88_8723du-objs := rtw8723du.o - -diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723ds.c b/drivers/net/wireless/realtek/rtw88/rtw8723ds.c -new file mode 100644 -index 000000000000..e5b6960ba0a0 ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723ds.c -@@ -0,0 +1,41 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright(c) Martin Blumenstingl -+ */ -+ -+#include -+#include -+#include -+#include "main.h" -+#include "rtw8723d.h" -+#include "sdio.h" -+ -+static const struct sdio_device_id rtw_8723ds_id_table[] = { -+ { -+ SDIO_DEVICE(SDIO_VENDOR_ID_REALTEK, -+ SDIO_DEVICE_ID_REALTEK_RTW8723DS_1ANT), -+ .driver_data = (kernel_ulong_t)&rtw8723d_hw_spec, -+ }, -+ { -+ SDIO_DEVICE(SDIO_VENDOR_ID_REALTEK, -+ SDIO_DEVICE_ID_REALTEK_RTW8723DS_2ANT), -+ .driver_data = (kernel_ulong_t)&rtw8723d_hw_spec, -+ }, -+ {} -+}; -+MODULE_DEVICE_TABLE(sdio, rtw_8723ds_id_table); -+ -+static struct sdio_driver rtw_8723ds_driver = { -+ .name = "rtw_8723ds", -+ .probe = rtw_sdio_probe, -+ .remove = rtw_sdio_remove, -+ .id_table = rtw_8723ds_id_table, -+ .drv = { -+ .pm = &rtw_sdio_pm_ops, -+ .shutdown = rtw_sdio_shutdown, -+ } -+}; -+module_sdio_driver(rtw_8723ds_driver); -+ -+MODULE_AUTHOR("Martin Blumenstingl "); -+MODULE_DESCRIPTION("Realtek 802.11n wireless 8723ds driver"); -+MODULE_LICENSE("Dual BSD/GPL"); --- -2.40.1 diff --git a/patch/misc/rtw88/6.4/001-rtw88-linux-next.patch b/patch/misc/rtw88/6.4/001-rtw88-linux-next.patch new file mode 100644 index 0000000000..77032103de --- /dev/null +++ b/patch/misc/rtw88/6.4/001-rtw88-linux-next.patch @@ -0,0 +1,969 @@ +diff -Naur a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c +--- a/drivers/net/wireless/realtek/rtw88/debug.c 2023-06-18 17:06:27.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/debug.c 2023-06-22 13:52:09.000000000 -0400 +@@ -183,8 +183,8 @@ + + tmp_len = (count > size - 1 ? size - 1 : count); + +- if (!buffer || copy_from_user(tmp, buffer, tmp_len)) +- return count; ++ if (copy_from_user(tmp, buffer, tmp_len)) ++ return -EFAULT; + + tmp[tmp_len] = '\0'; + +@@ -201,13 +201,16 @@ + char tmp[32 + 1]; + u32 addr, len; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); ++ if (ret) ++ return ret; + + num = sscanf(tmp, "%x %x", &addr, &len); + + if (num != 2) +- return count; ++ return -EINVAL; + + if (len != 1 && len != 2 && len != 4) { + rtw_warn(rtwdev, "read reg setting wrong len\n"); +@@ -288,8 +291,11 @@ + char tmp[32 + 1]; + u32 offset, page_num; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); ++ if (ret) ++ return ret; + + num = sscanf(tmp, "%d %d", &offset, &page_num); + +@@ -314,8 +320,11 @@ + char tmp[32 + 1]; + u32 input; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ if (ret) ++ return ret; + + num = kstrtoint(tmp, 0, &input); + +@@ -338,14 +347,17 @@ + char tmp[32 + 1]; + u32 addr, val, len; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ if (ret) ++ return ret; + + /* write BB/MAC register */ + num = sscanf(tmp, "%x %x %x", &addr, &val, &len); + + if (num != 3) +- return count; ++ return -EINVAL; + + switch (len) { + case 1: +@@ -381,8 +393,11 @@ + char tmp[32 + 1]; + u8 param[8]; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ if (ret) ++ return ret; + + num = sscanf(tmp, "%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx", + ¶m[0], ¶m[1], ¶m[2], ¶m[3], +@@ -408,14 +423,17 @@ + char tmp[32 + 1]; + u32 path, addr, mask, val; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 4); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 4); ++ if (ret) ++ return ret; + + num = sscanf(tmp, "%x %x %x %x", &path, &addr, &mask, &val); + + if (num != 4) { + rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); +- return count; ++ return -EINVAL; + } + + mutex_lock(&rtwdev->mutex); +@@ -438,14 +456,17 @@ + char tmp[32 + 1]; + u32 path, addr, mask; + int num; ++ int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); ++ if (ret) ++ return ret; + + num = sscanf(tmp, "%x %x %x", &path, &addr, &mask); + + if (num != 3) { + rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); +- return count; ++ return -EINVAL; + } + + debugfs_priv->rf_path = path; +@@ -467,7 +488,9 @@ + char tmp[32 + 1]; + int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ if (ret) ++ return ret; + + ret = kstrtou8(tmp, 0, &fix_rate); + if (ret) { +@@ -860,7 +883,9 @@ + bool enable; + int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ if (ret) ++ return ret; + + ret = kstrtobool(tmp, &enable); + if (ret) { +@@ -930,7 +955,9 @@ + bool input; + int ret; + +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); ++ if (ret) ++ return ret; + + ret = kstrtobool(tmp, &input); + if (ret) +diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c +--- a/drivers/net/wireless/realtek/rtw88/fw.c 2023-06-18 17:06:27.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/fw.c 2023-06-22 13:52:09.000000000 -0400 +@@ -308,6 +308,57 @@ + } + EXPORT_SYMBOL(rtw_fw_c2h_cmd_isr); + ++static void rtw_fw_send_h2c_command_register(struct rtw_dev *rtwdev, ++ struct rtw_h2c_register *h2c) ++{ ++ u32 box_reg, box_ex_reg; ++ u8 box_state, box; ++ int ret; ++ ++ rtw_dbg(rtwdev, RTW_DBG_FW, "send H2C content %08x %08x\n", h2c->w0, ++ h2c->w1); ++ ++ lockdep_assert_held(&rtwdev->mutex); ++ ++ box = rtwdev->h2c.last_box_num; ++ switch (box) { ++ case 0: ++ box_reg = REG_HMEBOX0; ++ box_ex_reg = REG_HMEBOX0_EX; ++ break; ++ case 1: ++ box_reg = REG_HMEBOX1; ++ box_ex_reg = REG_HMEBOX1_EX; ++ break; ++ case 2: ++ box_reg = REG_HMEBOX2; ++ box_ex_reg = REG_HMEBOX2_EX; ++ break; ++ case 3: ++ box_reg = REG_HMEBOX3; ++ box_ex_reg = REG_HMEBOX3_EX; ++ break; ++ default: ++ WARN(1, "invalid h2c mail box number\n"); ++ return; ++ } ++ ++ ret = read_poll_timeout_atomic(rtw_read8, box_state, ++ !((box_state >> box) & 0x1), 100, 3000, ++ false, rtwdev, REG_HMETFR); ++ ++ if (ret) { ++ rtw_err(rtwdev, "failed to send h2c command\n"); ++ return; ++ } ++ ++ rtw_write32(rtwdev, box_ex_reg, h2c->w1); ++ rtw_write32(rtwdev, box_reg, h2c->w0); ++ ++ if (++rtwdev->h2c.last_box_num >= 4) ++ rtwdev->h2c.last_box_num = 0; ++} ++ + static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev, + u8 *h2c) + { +@@ -468,6 +519,23 @@ + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); + } + ++void rtw_fw_default_port(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif) ++{ ++ struct rtw_h2c_register h2c = {}; ++ ++ if (rtwvif->net_type != RTW_NET_MGD_LINKED) ++ return; ++ ++ /* Leave LPS before default port H2C so FW timer is correct */ ++ rtw_leave_lps(rtwdev); ++ ++ h2c.w0 = u32_encode_bits(H2C_CMD_DEFAULT_PORT, RTW_H2C_W0_CMDID) | ++ u32_encode_bits(rtwvif->port, RTW_H2C_DEFAULT_PORT_W0_PORTID) | ++ u32_encode_bits(rtwvif->mac_id, RTW_H2C_DEFAULT_PORT_W0_MACID); ++ ++ rtw_fw_send_h2c_command_register(rtwdev, &h2c); ++} ++ + void rtw_fw_wl_ch_info(struct rtw_dev *rtwdev, u8 link, u8 ch, u8 bw) + { + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; +diff -Naur a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h +--- a/drivers/net/wireless/realtek/rtw88/fw.h 2023-06-18 17:06:27.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/fw.h 2023-06-22 13:52:09.000000000 -0400 +@@ -81,6 +81,17 @@ + u8 option; + } __packed; + ++struct rtw_h2c_register { ++ u32 w0; ++ u32 w1; ++} __packed; ++ ++#define RTW_H2C_W0_CMDID GENMASK(7, 0) ++ ++/* H2C_CMD_DEFAULT_PORT command */ ++#define RTW_H2C_DEFAULT_PORT_W0_PORTID GENMASK(15, 8) ++#define RTW_H2C_DEFAULT_PORT_W0_MACID GENMASK(23, 16) ++ + struct rtw_h2c_cmd { + __le32 msg; + __le32 msg_ext; +@@ -530,6 +541,7 @@ + #define H2C_CMD_MEDIA_STATUS_RPT 0x01 + #define H2C_CMD_SET_PWR_MODE 0x20 + #define H2C_CMD_LPS_PG_INFO 0x2b ++#define H2C_CMD_DEFAULT_PORT 0x2c + #define H2C_CMD_RA_INFO 0x40 + #define H2C_CMD_RSSI_MONITOR 0x42 + #define H2C_CMD_BCN_FILTER_OFFLOAD_P0 0x56 +@@ -801,6 +813,7 @@ + void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb); + void rtw_fw_send_general_info(struct rtw_dev *rtwdev); + void rtw_fw_send_phydm_info(struct rtw_dev *rtwdev); ++void rtw_fw_default_port(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif); + + void rtw_fw_do_iqk(struct rtw_dev *rtwdev, struct rtw_iqk_para *para); + void rtw_fw_inform_rfk_status(struct rtw_dev *rtwdev, bool start); +diff -Naur a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig +--- a/drivers/net/wireless/realtek/rtw88/Kconfig 2023-06-18 17:06:27.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/Kconfig 2023-06-22 13:52:09.000000000 -0400 +@@ -111,6 +111,17 @@ + + 802.11n PCIe wireless network adapter + ++config RTW88_8723DS ++ tristate "Realtek 8723DS SDIO wireless network adapter" ++ depends on MMC ++ select RTW88_CORE ++ select RTW88_SDIO ++ select RTW88_8723D ++ help ++ Select this option will enable support for 8723DS chipset ++ ++ 802.11n SDIO wireless network adapter ++ + config RTW88_8723DU + tristate "Realtek 8723DU USB wireless network adapter" + depends on USB +diff -Naur a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c +--- a/drivers/net/wireless/realtek/rtw88/mac80211.c 2023-06-18 17:06:27.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/mac80211.c 2023-06-22 13:52:09.000000000 -0400 +@@ -43,7 +43,11 @@ + list_add_tail(&rtwtxq->list, &rtwdev->txqs); + spin_unlock_bh(&rtwdev->txq_lock); + +- queue_work(rtwdev->tx_wq, &rtwdev->tx_work); ++ /* ensure to dequeue EAPOL (4/4) at the right time */ ++ if (txq->ac == IEEE80211_AC_VO) ++ __rtw_tx_work(rtwdev); ++ else ++ queue_work(rtwdev->tx_wq, &rtwdev->tx_work); + } + + static int rtw_ops_start(struct ieee80211_hw *hw) +@@ -164,8 +168,10 @@ + mutex_lock(&rtwdev->mutex); + + port = find_first_zero_bit(rtwdev->hw_port, RTW_PORT_NUM); +- if (port >= RTW_PORT_NUM) ++ if (port >= RTW_PORT_NUM) { ++ mutex_unlock(&rtwdev->mutex); + return -EINVAL; ++ } + set_bit(port, rtwdev->hw_port); + + rtwvif->port = port; +@@ -376,6 +382,7 @@ + + rtw_fw_download_rsvd_page(rtwdev); + rtw_send_rsvd_page_h2c(rtwdev); ++ rtw_fw_default_port(rtwdev, rtwvif); + rtw_coex_media_status_notify(rtwdev, vif->cfg.assoc); + if (rtw_bf_support) + rtw_bf_assoc(rtwdev, vif, conf); +@@ -447,6 +454,7 @@ + const struct rtw_chip_info *chip = rtwdev->chip; + + mutex_lock(&rtwdev->mutex); ++ rtw_write32_set(rtwdev, REG_TCR, BIT_TCR_UPDATE_HGQMD); + rtwdev->ap_active = true; + rtw_store_op_chan(rtwdev, true); + chip->ops->phy_calibration(rtwdev); +@@ -462,6 +470,7 @@ + struct rtw_dev *rtwdev = hw->priv; + + mutex_lock(&rtwdev->mutex); ++ rtw_write32_clr(rtwdev, REG_TCR, BIT_TCR_UPDATE_HGQMD); + rtwdev->ap_active = false; + if (!rtw_core_check_sta_active(rtwdev)) + rtw_clear_op_chan(rtwdev); +diff -Naur a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c +--- a/drivers/net/wireless/realtek/rtw88/mac.c 2023-06-18 17:06:27.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/mac.c 2023-06-22 13:52:09.000000000 -0400 +@@ -794,8 +794,10 @@ + + wlan_cpu_enable(rtwdev, true); + +- if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) +- return -EBUSY; ++ if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) { ++ ret = -EBUSY; ++ goto dlfw_fail; ++ } + + ret = download_firmware_validate(rtwdev); + if (ret) +diff -Naur a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c +--- a/drivers/net/wireless/realtek/rtw88/main.c 2023-06-18 17:06:27.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/main.c 2023-06-22 13:52:09.000000000 -0400 +@@ -334,12 +334,15 @@ + struct ieee80211_vif *vif) + { + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; ++ struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + int i; + + si->mac_id = rtw_acquire_macid(rtwdev); + if (si->mac_id >= RTW_MAX_MAC_ID_NUM) + return -ENOSPC; + ++ if (vif->type == NL80211_IFTYPE_STATION && vif->cfg.assoc == 0) ++ rtwvif->mac_id = si->mac_id; + si->rtwdev = rtwdev; + si->sta = sta; + si->vif = vif; +@@ -2340,6 +2343,9 @@ + rtw_dbg(rtwdev, RTW_DBG_STATE, "AP port switch from %d -> %d\n", + rtwvif_ap->port, rtwvif_target->port); + ++ /* Leave LPS so the value swapped are not in PS mode */ ++ rtw_leave_lps(rtwdev); ++ + reg1 = &rtwvif_ap->conf->net_type; + reg2 = &rtwvif_target->conf->net_type; + rtw_swap_reg_mask(rtwdev, reg1, reg2); +@@ -2358,6 +2364,8 @@ + + swap(rtwvif_target->port, rtwvif_ap->port); + swap(rtwvif_target->conf, rtwvif_ap->conf); ++ ++ rtw_fw_default_port(rtwdev, rtwvif_target); + } + + void rtw_core_port_switch(struct rtw_dev *rtwdev, struct ieee80211_vif *vif) +@@ -2403,10 +2411,13 @@ + if (!rtwdev->ap_active) + return; + +- if (enable) ++ if (enable) { + rtw_write32_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); +- else ++ rtw_write32_clr(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); ++ } else { + rtw_write32_clr(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); ++ rtw_write32_set(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); ++ } + } + + MODULE_AUTHOR("Realtek Corporation"); +diff -Naur a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h +--- a/drivers/net/wireless/realtek/rtw88/main.h 2023-06-18 17:06:27.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/main.h 2023-06-22 13:52:09.000000000 -0400 +@@ -803,6 +803,7 @@ + struct rtw_vif { + enum rtw_net_type net_type; + u16 aid; ++ u8 mac_id; /* for STA mode only */ + u8 mac_addr[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + u8 port; +diff -Naur a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile +--- a/drivers/net/wireless/realtek/rtw88/Makefile 2023-06-18 17:06:27.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/Makefile 2023-06-22 13:52:09.000000000 -0400 +@@ -50,6 +50,9 @@ + obj-$(CONFIG_RTW88_8723DE) += rtw88_8723de.o + rtw88_8723de-objs := rtw8723de.o + ++obj-$(CONFIG_RTW88_8723DS) += rtw88_8723ds.o ++rtw88_8723ds-objs := rtw8723ds.o ++ + obj-$(CONFIG_RTW88_8723DU) += rtw88_8723du.o + rtw88_8723du-objs := rtw8723du.o + +diff -Naur a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c +--- a/drivers/net/wireless/realtek/rtw88/pci.c 2023-06-18 17:06:27.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/pci.c 2023-06-22 13:52:09.000000000 -0400 +@@ -738,8 +738,9 @@ + u8 q; + + for (q = 0; q < RTK_MAX_TX_QUEUE_NUM; q++) { +- /* It may be not necessary to flush BCN and H2C tx queues. */ +- if (q == RTW_TX_QUEUE_BCN || q == RTW_TX_QUEUE_H2C) ++ /* Unnecessary to flush BCN, H2C and HI tx queues. */ ++ if (q == RTW_TX_QUEUE_BCN || q == RTW_TX_QUEUE_H2C || ++ q == RTW_TX_QUEUE_HI0) + continue; + + if (pci_queues & BIT(q)) +diff -Naur a/drivers/net/wireless/realtek/rtw88/ps.c b/drivers/net/wireless/realtek/rtw88/ps.c +--- a/drivers/net/wireless/realtek/rtw88/ps.c 2023-06-18 17:06:27.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/ps.c 2023-06-22 13:52:09.000000000 -0400 +@@ -18,6 +18,7 @@ + if (ret) + rtw_err(rtwdev, "leave idle state failed\n"); + ++ rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); + rtw_set_channel(rtwdev); + + return ret; +@@ -63,8 +64,6 @@ + + rtw_iterate_vifs(rtwdev, rtw_restore_port_cfg_iter, rtwdev); + +- rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); +- + return 0; + } + +diff -Naur a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h +--- a/drivers/net/wireless/realtek/rtw88/reg.h 2023-06-18 17:06:27.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/reg.h 2023-06-22 13:52:09.000000000 -0400 +@@ -378,6 +378,7 @@ + #define BIT_SIFS_BK_EN BIT(12) + #define REG_TXPAUSE 0x0522 + #define BIT_AC_QUEUE GENMASK(7, 0) ++#define BIT_HIGH_QUEUE BIT(5) + #define REG_RD_CTRL 0x0524 + #define BIT_EDCCA_MSK_CNTDOWN_EN BIT(11) + #define BIT_DIS_TXOP_CFE BIT(10) +@@ -410,6 +411,7 @@ + #define REG_TCR 0x0604 + #define BIT_PWRMGT_HWDATA_EN BIT(7) + #define BIT_TCR_UPDATE_TIMIE BIT(5) ++#define BIT_TCR_UPDATE_HGQMD BIT(4) + #define REG_RCR 0x0608 + #define BIT_APP_FCS BIT(31) + #define BIT_APP_MIC BIT(30) +diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c 2023-06-18 17:06:27.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c 2023-06-22 13:52:09.000000000 -0400 +@@ -216,6 +216,12 @@ + ether_addr_copy(efuse->addr, map->u.mac_addr); + } + ++static void rtw8723ds_efuse_parsing(struct rtw_efuse *efuse, ++ struct rtw8723d_efuse *map) ++{ ++ ether_addr_copy(efuse->addr, map->s.mac_addr); ++} ++ + static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) + { + struct rtw_efuse *efuse = &rtwdev->efuse; +@@ -248,6 +254,9 @@ + case RTW_HCI_TYPE_USB: + rtw8723du_efuse_parsing(efuse, map); + break; ++ case RTW_HCI_TYPE_SDIO: ++ rtw8723ds_efuse_parsing(efuse, map); ++ break; + default: + /* unsupported now */ + return -ENOTSUPP; +@@ -1961,15 +1970,17 @@ + size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */ + __le16 chksum = 0; + __le16 *data = (__le16 *)(txdesc); ++ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc; + +- SET_TX_DESC_TXDESC_CHECKSUM(txdesc, 0x0000); ++ le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM); + + while (words--) + chksum ^= *data++; + + chksum = ~chksum; + +- SET_TX_DESC_TXDESC_CHECKSUM(txdesc, __le16_to_cpu(chksum)); ++ le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum), ++ RTW_TX_DESC_W7_TXDESC_CHECKSUM); + } + + static struct rtw_chip_ops rtw8723d_ops = { +diff -Naur a/drivers/net/wireless/realtek/rtw88/rtw8723d.h b/drivers/net/wireless/realtek/rtw88/rtw8723d.h +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.h 2023-06-18 17:06:27.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h 2023-06-22 13:52:09.000000000 -0400 +@@ -49,6 +49,11 @@ + u8 mac_addr[ETH_ALEN]; /* 0x107 */ + }; + ++struct rtw8723ds_efuse { ++ u8 res4[0x4a]; /* 0xd0 */ ++ u8 mac_addr[ETH_ALEN]; /* 0x11a */ ++}; ++ + struct rtw8723d_efuse { + __le16 rtl_id; + u8 rsvd[2]; +@@ -80,6 +85,7 @@ + union { + struct rtw8723de_efuse e; + struct rtw8723du_efuse u; ++ struct rtw8723ds_efuse s; + }; + }; + +diff -Naur a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c +--- a/drivers/net/wireless/realtek/rtw88/sdio.c 2023-06-18 17:06:27.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/sdio.c 2023-06-22 13:52:09.000000000 -0400 +@@ -998,9 +998,9 @@ + + static void rtw_sdio_rx_isr(struct rtw_dev *rtwdev) + { +- u32 rx_len, total_rx_bytes = 0; ++ u32 rx_len, hisr, total_rx_bytes = 0; + +- while (total_rx_bytes < SZ_64K) { ++ do { + if (rtw_chip_wcpu_11n(rtwdev)) + rx_len = rtw_read16(rtwdev, REG_SDIO_RX0_REQ_LEN); + else +@@ -1012,7 +1012,25 @@ + rtw_sdio_rxfifo_recv(rtwdev, rx_len); + + total_rx_bytes += rx_len; +- } ++ ++ if (rtw_chip_wcpu_11n(rtwdev)) { ++ /* Stop if no more RX requests are pending, even if ++ * rx_len could be greater than zero in the next ++ * iteration. This is needed because the RX buffer may ++ * already contain data while either HW or FW are not ++ * done filling that buffer yet. Still reading the ++ * buffer can result in packets where ++ * rtw_rx_pkt_stat.pkt_len is zero or points beyond the ++ * end of the buffer. ++ */ ++ hisr = rtw_read32(rtwdev, REG_SDIO_HISR); ++ } else { ++ /* RTW_WCPU_11AC chips have improved hardware or ++ * firmware and can use rx_len unconditionally. ++ */ ++ hisr = REG_SDIO_HISR_RX_REQUEST; ++ } ++ } while (total_rx_bytes < SZ_64K && hisr & REG_SDIO_HISR_RX_REQUEST); + } + + static void rtw_sdio_handle_interrupt(struct sdio_func *sdio_func) +diff -Naur a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c +--- a/drivers/net/wireless/realtek/rtw88/tx.c 2023-06-18 17:06:27.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/tx.c 2023-06-22 13:52:09.000000000 -0400 +@@ -34,43 +34,57 @@ + + void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb) + { +- __le32 *txdesc = (__le32 *)skb->data; ++ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data; ++ bool more_data = false; ++ ++ if (pkt_info->qsel == TX_DESC_QSEL_HIGH) ++ more_data = true; ++ ++ tx_desc->w0 = le32_encode_bits(pkt_info->tx_pkt_size, RTW_TX_DESC_W0_TXPKTSIZE) | ++ le32_encode_bits(pkt_info->offset, RTW_TX_DESC_W0_OFFSET) | ++ le32_encode_bits(pkt_info->bmc, RTW_TX_DESC_W0_BMC) | ++ le32_encode_bits(pkt_info->ls, RTW_TX_DESC_W0_LS) | ++ le32_encode_bits(pkt_info->dis_qselseq, RTW_TX_DESC_W0_DISQSELSEQ); ++ ++ tx_desc->w1 = le32_encode_bits(pkt_info->qsel, RTW_TX_DESC_W1_QSEL) | ++ le32_encode_bits(pkt_info->rate_id, RTW_TX_DESC_W1_RATE_ID) | ++ le32_encode_bits(pkt_info->sec_type, RTW_TX_DESC_W1_SEC_TYPE) | ++ le32_encode_bits(pkt_info->pkt_offset, RTW_TX_DESC_W1_PKT_OFFSET) | ++ le32_encode_bits(more_data, RTW_TX_DESC_W1_MORE_DATA); ++ ++ tx_desc->w2 = le32_encode_bits(pkt_info->ampdu_en, RTW_TX_DESC_W2_AGG_EN) | ++ le32_encode_bits(pkt_info->report, RTW_TX_DESC_W2_SPE_RPT) | ++ le32_encode_bits(pkt_info->ampdu_density, RTW_TX_DESC_W2_AMPDU_DEN) | ++ le32_encode_bits(pkt_info->bt_null, RTW_TX_DESC_W2_BT_NULL); ++ ++ tx_desc->w3 = le32_encode_bits(pkt_info->hw_ssn_sel, RTW_TX_DESC_W3_HW_SSN_SEL) | ++ le32_encode_bits(pkt_info->use_rate, RTW_TX_DESC_W3_USE_RATE) | ++ le32_encode_bits(pkt_info->dis_rate_fallback, RTW_TX_DESC_W3_DISDATAFB) | ++ le32_encode_bits(pkt_info->rts, RTW_TX_DESC_W3_USE_RTS) | ++ le32_encode_bits(pkt_info->nav_use_hdr, RTW_TX_DESC_W3_NAVUSEHDR) | ++ le32_encode_bits(pkt_info->ampdu_factor, RTW_TX_DESC_W3_MAX_AGG_NUM); ++ ++ tx_desc->w4 = le32_encode_bits(pkt_info->rate, RTW_TX_DESC_W4_DATARATE); ++ ++ tx_desc->w5 = le32_encode_bits(pkt_info->short_gi, RTW_TX_DESC_W5_DATA_SHORT) | ++ le32_encode_bits(pkt_info->bw, RTW_TX_DESC_W5_DATA_BW) | ++ le32_encode_bits(pkt_info->ldpc, RTW_TX_DESC_W5_DATA_LDPC) | ++ le32_encode_bits(pkt_info->stbc, RTW_TX_DESC_W5_DATA_STBC); ++ ++ tx_desc->w6 = le32_encode_bits(pkt_info->sn, RTW_TX_DESC_W6_SW_DEFINE); ++ ++ tx_desc->w8 = le32_encode_bits(pkt_info->en_hwseq, RTW_TX_DESC_W8_EN_HWSEQ); ++ ++ tx_desc->w9 = le32_encode_bits(pkt_info->seq, RTW_TX_DESC_W9_SW_SEQ); + +- SET_TX_DESC_TXPKTSIZE(txdesc, pkt_info->tx_pkt_size); +- SET_TX_DESC_OFFSET(txdesc, pkt_info->offset); +- SET_TX_DESC_PKT_OFFSET(txdesc, pkt_info->pkt_offset); +- SET_TX_DESC_QSEL(txdesc, pkt_info->qsel); +- SET_TX_DESC_BMC(txdesc, pkt_info->bmc); +- SET_TX_DESC_RATE_ID(txdesc, pkt_info->rate_id); +- SET_TX_DESC_DATARATE(txdesc, pkt_info->rate); +- SET_TX_DESC_DISDATAFB(txdesc, pkt_info->dis_rate_fallback); +- SET_TX_DESC_USE_RATE(txdesc, pkt_info->use_rate); +- SET_TX_DESC_SEC_TYPE(txdesc, pkt_info->sec_type); +- SET_TX_DESC_DATA_BW(txdesc, pkt_info->bw); +- SET_TX_DESC_SW_SEQ(txdesc, pkt_info->seq); +- SET_TX_DESC_MAX_AGG_NUM(txdesc, pkt_info->ampdu_factor); +- SET_TX_DESC_AMPDU_DENSITY(txdesc, pkt_info->ampdu_density); +- SET_TX_DESC_DATA_STBC(txdesc, pkt_info->stbc); +- SET_TX_DESC_DATA_LDPC(txdesc, pkt_info->ldpc); +- SET_TX_DESC_AGG_EN(txdesc, pkt_info->ampdu_en); +- SET_TX_DESC_LS(txdesc, pkt_info->ls); +- SET_TX_DESC_DATA_SHORT(txdesc, pkt_info->short_gi); +- SET_TX_DESC_SPE_RPT(txdesc, pkt_info->report); +- SET_TX_DESC_SW_DEFINE(txdesc, pkt_info->sn); +- SET_TX_DESC_USE_RTS(txdesc, pkt_info->rts); + if (pkt_info->rts) { +- SET_TX_DESC_RTSRATE(txdesc, DESC_RATE24M); +- SET_TX_DESC_DATA_RTS_SHORT(txdesc, 1); +- } +- SET_TX_DESC_DISQSELSEQ(txdesc, pkt_info->dis_qselseq); +- SET_TX_DESC_EN_HWSEQ(txdesc, pkt_info->en_hwseq); +- SET_TX_DESC_HW_SSN_SEL(txdesc, pkt_info->hw_ssn_sel); +- SET_TX_DESC_NAVUSEHDR(txdesc, pkt_info->nav_use_hdr); +- SET_TX_DESC_BT_NULL(txdesc, pkt_info->bt_null); +- if (pkt_info->tim_offset) { +- SET_TX_DESC_TIM_EN(txdesc, 1); +- SET_TX_DESC_TIM_OFFSET(txdesc, pkt_info->tim_offset); ++ tx_desc->w4 |= le32_encode_bits(DESC_RATE24M, RTW_TX_DESC_W4_RTSRATE); ++ tx_desc->w5 |= le32_encode_bits(1, RTW_TX_DESC_W5_DATA_RTS_SHORT); + } ++ ++ if (pkt_info->tim_offset) ++ tx_desc->w9 |= le32_encode_bits(1, RTW_TX_DESC_W9_TIM_EN) | ++ le32_encode_bits(pkt_info->tim_offset, RTW_TX_DESC_W9_TIM_OFFSET); + } + EXPORT_SYMBOL(rtw_tx_fill_tx_desc); + +@@ -635,9 +649,8 @@ + rcu_read_unlock(); + } + +-void rtw_tx_work(struct work_struct *w) ++void __rtw_tx_work(struct rtw_dev *rtwdev) + { +- struct rtw_dev *rtwdev = container_of(w, struct rtw_dev, tx_work); + struct rtw_txq *rtwtxq, *tmp; + + spin_lock_bh(&rtwdev->txq_lock); +@@ -658,6 +671,13 @@ + spin_unlock_bh(&rtwdev->txq_lock); + } + ++void rtw_tx_work(struct work_struct *w) ++{ ++ struct rtw_dev *rtwdev = container_of(w, struct rtw_dev, tx_work); ++ ++ __rtw_tx_work(rtwdev); ++} ++ + void rtw_txq_init(struct rtw_dev *rtwdev, struct ieee80211_txq *txq) + { + struct rtw_txq *rtwtxq; +diff -Naur a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/realtek/rtw88/tx.h +--- a/drivers/net/wireless/realtek/rtw88/tx.h 2023-06-18 17:06:27.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/tx.h 2023-06-22 13:52:09.000000000 -0400 +@@ -9,76 +9,53 @@ + + #define RTW_TX_PROBE_TIMEOUT msecs_to_jiffies(500) + +-#define SET_TX_DESC_TXPKTSIZE(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, GENMASK(15, 0)) +-#define SET_TX_DESC_OFFSET(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, GENMASK(23, 16)) +-#define SET_TX_DESC_PKT_OFFSET(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x01, value, GENMASK(28, 24)) +-#define SET_TX_DESC_QSEL(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x01, value, GENMASK(12, 8)) +-#define SET_TX_DESC_BMC(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, BIT(24)) +-#define SET_TX_DESC_RATE_ID(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x01, value, GENMASK(20, 16)) +-#define SET_TX_DESC_DATARATE(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x04, value, GENMASK(6, 0)) +-#define SET_TX_DESC_DISDATAFB(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(10)) +-#define SET_TX_DESC_USE_RATE(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(8)) +-#define SET_TX_DESC_SEC_TYPE(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x01, value, GENMASK(23, 22)) +-#define SET_TX_DESC_DATA_BW(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, GENMASK(6, 5)) +-#define SET_TX_DESC_SW_SEQ(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x09, value, GENMASK(23, 12)) +-#define SET_TX_DESC_TIM_EN(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x09, value, BIT(7)) +-#define SET_TX_DESC_TIM_OFFSET(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x09, value, GENMASK(6, 0)) +-#define SET_TX_DESC_MAX_AGG_NUM(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, GENMASK(21, 17)) +-#define SET_TX_DESC_USE_RTS(tx_desc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(12)) +-#define SET_TX_DESC_RTSRATE(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x04, value, GENMASK(28, 24)) +-#define SET_TX_DESC_DATA_RTS_SHORT(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, BIT(12)) +-#define SET_TX_DESC_AMPDU_DENSITY(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, GENMASK(22, 20)) +-#define SET_TX_DESC_DATA_STBC(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, GENMASK(9, 8)) +-#define SET_TX_DESC_DATA_LDPC(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, BIT(7)) +-#define SET_TX_DESC_AGG_EN(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(12)) +-#define SET_TX_DESC_LS(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, BIT(26)) +-#define SET_TX_DESC_DATA_SHORT(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, BIT(4)) +-#define SET_TX_DESC_SPE_RPT(tx_desc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(19)) +-#define SET_TX_DESC_SW_DEFINE(tx_desc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x06, value, GENMASK(11, 0)) +-#define SET_TX_DESC_DISQSELSEQ(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, BIT(31)) +-#define SET_TX_DESC_EN_HWSEQ(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x08, value, BIT(15)) +-#define SET_TX_DESC_HW_SSN_SEL(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, GENMASK(7, 6)) +-#define SET_TX_DESC_NAVUSEHDR(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(15)) +-#define SET_TX_DESC_BT_NULL(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(23)) +-#define SET_TX_DESC_TXDESC_CHECKSUM(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x07, value, GENMASK(15, 0)) +-#define SET_TX_DESC_DMA_TXAGG_NUM(txdesc, value) \ +- le32p_replace_bits((__le32 *)(txdesc) + 0x07, value, GENMASK(31, 24)) +-#define GET_TX_DESC_PKT_OFFSET(txdesc) \ +- le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(28, 24)) +-#define GET_TX_DESC_QSEL(txdesc) \ +- le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(12, 8)) ++struct rtw_tx_desc { ++ __le32 w0; ++ __le32 w1; ++ __le32 w2; ++ __le32 w3; ++ __le32 w4; ++ __le32 w5; ++ __le32 w6; ++ __le32 w7; ++ __le32 w8; ++ __le32 w9; ++} __packed; ++ ++#define RTW_TX_DESC_W0_TXPKTSIZE GENMASK(15, 0) ++#define RTW_TX_DESC_W0_OFFSET GENMASK(23, 16) ++#define RTW_TX_DESC_W0_BMC BIT(24) ++#define RTW_TX_DESC_W0_LS BIT(26) ++#define RTW_TX_DESC_W0_DISQSELSEQ BIT(31) ++#define RTW_TX_DESC_W1_QSEL GENMASK(12, 8) ++#define RTW_TX_DESC_W1_RATE_ID GENMASK(20, 16) ++#define RTW_TX_DESC_W1_SEC_TYPE GENMASK(23, 22) ++#define RTW_TX_DESC_W1_PKT_OFFSET GENMASK(28, 24) ++#define RTW_TX_DESC_W1_MORE_DATA BIT(29) ++#define RTW_TX_DESC_W2_AGG_EN BIT(12) ++#define RTW_TX_DESC_W2_SPE_RPT BIT(19) ++#define RTW_TX_DESC_W2_AMPDU_DEN GENMASK(22, 20) ++#define RTW_TX_DESC_W2_BT_NULL BIT(23) ++#define RTW_TX_DESC_W3_HW_SSN_SEL GENMASK(7, 6) ++#define RTW_TX_DESC_W3_USE_RATE BIT(8) ++#define RTW_TX_DESC_W3_DISDATAFB BIT(10) ++#define RTW_TX_DESC_W3_USE_RTS BIT(12) ++#define RTW_TX_DESC_W3_NAVUSEHDR BIT(15) ++#define RTW_TX_DESC_W3_MAX_AGG_NUM GENMASK(21, 17) ++#define RTW_TX_DESC_W4_DATARATE GENMASK(6, 0) ++#define RTW_TX_DESC_W4_RTSRATE GENMASK(28, 24) ++#define RTW_TX_DESC_W5_DATA_SHORT BIT(4) ++#define RTW_TX_DESC_W5_DATA_BW GENMASK(6, 5) ++#define RTW_TX_DESC_W5_DATA_LDPC BIT(7) ++#define RTW_TX_DESC_W5_DATA_STBC GENMASK(9, 8) ++#define RTW_TX_DESC_W5_DATA_RTS_SHORT BIT(12) ++#define RTW_TX_DESC_W6_SW_DEFINE GENMASK(11, 0) ++#define RTW_TX_DESC_W7_TXDESC_CHECKSUM GENMASK(15, 0) ++#define RTW_TX_DESC_W7_DMA_TXAGG_NUM GENMASK(31, 24) ++#define RTW_TX_DESC_W8_EN_HWSEQ BIT(15) ++#define RTW_TX_DESC_W9_SW_SEQ GENMASK(23, 12) ++#define RTW_TX_DESC_W9_TIM_EN BIT(7) ++#define RTW_TX_DESC_W9_TIM_OFFSET GENMASK(6, 0) + + enum rtw_tx_desc_queue_select { + TX_DESC_QSEL_TID0 = 0, +@@ -111,6 +88,7 @@ + void rtw_txq_init(struct rtw_dev *rtwdev, struct ieee80211_txq *txq); + void rtw_txq_cleanup(struct rtw_dev *rtwdev, struct ieee80211_txq *txq); + void rtw_tx_work(struct work_struct *w); ++void __rtw_tx_work(struct rtw_dev *rtwdev); + void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct ieee80211_sta *sta, +@@ -139,13 +117,15 @@ + { + __le16 chksum = 0; + __le16 *data = (__le16 *)(txdesc); ++ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc; + +- SET_TX_DESC_TXDESC_CHECKSUM(txdesc, 0x0000); ++ le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM); + + while (words--) + chksum ^= *data++; + +- SET_TX_DESC_TXDESC_CHECKSUM(txdesc, __le16_to_cpu(chksum)); ++ le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum), ++ RTW_TX_DESC_W7_TXDESC_CHECKSUM); + } + + static inline void rtw_tx_fill_txdesc_checksum(struct rtw_dev *rtwdev, +diff -Naur a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c +--- a/drivers/net/wireless/realtek/rtw88/usb.c 2023-06-18 17:06:27.000000000 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/usb.c 2023-06-22 13:52:09.000000000 -0400 +@@ -24,11 +24,12 @@ + static void rtw_usb_fill_tx_checksum(struct rtw_usb *rtwusb, + struct sk_buff *skb, int agg_num) + { ++ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data; + struct rtw_dev *rtwdev = rtwusb->rtwdev; + struct rtw_tx_pkt_info pkt_info; + +- SET_TX_DESC_DMA_TXAGG_NUM(skb->data, agg_num); +- pkt_info.pkt_offset = GET_TX_DESC_PKT_OFFSET(skb->data); ++ le32p_replace_bits(&tx_desc->w7, agg_num, RTW_TX_DESC_W7_DMA_TXAGG_NUM); ++ pkt_info.pkt_offset = le32_get_bits(tx_desc->w1, RTW_TX_DESC_W1_PKT_OFFSET); + rtw_tx_fill_txdesc_checksum(rtwdev, &pkt_info, skb->data); + } + +@@ -306,11 +307,13 @@ + static bool rtw_usb_tx_agg_skb(struct rtw_usb *rtwusb, struct sk_buff_head *list) + { + struct rtw_dev *rtwdev = rtwusb->rtwdev; ++ struct rtw_tx_desc *tx_desc; + struct rtw_usb_txcb *txcb; + struct sk_buff *skb_head; + struct sk_buff *skb_iter; + int agg_num = 0; + unsigned int align_next = 0; ++ u8 qsel; + + if (skb_queue_empty(list)) + return false; +@@ -363,9 +366,10 @@ + + queue: + skb_queue_tail(&txcb->tx_ack_queue, skb_head); ++ tx_desc = (struct rtw_tx_desc *)skb_head->data; ++ qsel = le32_get_bits(tx_desc->w1, RTW_TX_DESC_W1_QSEL); + +- rtw_usb_write_port(rtwdev, GET_TX_DESC_QSEL(skb_head->data), skb_head, +- rtw_usb_write_port_tx_complete, txcb); ++ rtw_usb_write_port(rtwdev, qsel, skb_head, rtw_usb_write_port_tx_complete, txcb); + + return true; + } +@@ -465,6 +469,9 @@ + + if (unlikely(ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))) + qsel = TX_DESC_QSEL_MGMT; ++ else if (is_broadcast_ether_addr(hdr->addr1) || ++ is_multicast_ether_addr(hdr->addr1)) ++ qsel = TX_DESC_QSEL_HIGH; + else if (skb_get_queue_mapping(skb) <= IEEE80211_AC_BK) + qsel = skb->priority; + else +@@ -535,7 +542,7 @@ + } + + if (skb_queue_len(&rtwusb->rx_queue) >= RTW_USB_MAX_RXQ_LEN) { +- rtw_err(rtwdev, "failed to get rx_queue, overflow\n"); ++ dev_dbg_ratelimited(rtwdev->dev, "failed to get rx_queue, overflow\n"); + dev_kfree_skb_any(skb); + continue; + } +diff -Naur a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h +--- a/include/linux/mmc/sdio_ids.h 2023-06-18 17:06:27.000000000 -0400 ++++ b/include/linux/mmc/sdio_ids.h 2023-06-22 13:52:09.000000000 -0400 +@@ -121,7 +121,8 @@ + #define SDIO_DEVICE_ID_REALTEK_RTW8822BS 0xb822 + #define SDIO_DEVICE_ID_REALTEK_RTW8821CS 0xc821 + #define SDIO_DEVICE_ID_REALTEK_RTW8822CS 0xc822 +-#define SDIO_DEVICE_ID_REALTEK_RTW8723DS 0xd723 ++#define SDIO_DEVICE_ID_REALTEK_RTW8723DS_2ANT 0xd723 ++#define SDIO_DEVICE_ID_REALTEK_RTW8723DS_1ANT 0xd724 + #define SDIO_DEVICE_ID_REALTEK_RTW8821DS 0xd821 + + #define SDIO_VENDOR_ID_SIANO 0x039a diff --git a/patch/misc/rtw88/6.4/002-rtw88-add-missing-unwind-goto-for_rtw_download_firmware.patch b/patch/misc/rtw88/6.4/002-rtw88-add-missing-unwind-goto-for_rtw_download_firmware.patch deleted file mode 100644 index e1d032bbf2..0000000000 --- a/patch/misc/rtw88/6.4/002-rtw88-add-missing-unwind-goto-for_rtw_download_firmware.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Ping-Ke Shih @ 2023-06-07 1:27 UTC (permalink / raw) - To: tony0620emma, kvalo; +Cc: s.hauer, dan.carpenter, lkp, linux-wireless - -This flaw is detected by smatch: - drivers/net/wireless/realtek/rtw88/mac.c:748 __rtw_download_firmware() - warn: missing unwind goto? - -Though most things of dlfw_fail have been done by -download_firmware_end_flow() and wlan_cpu_enable(), an exception is that -download_firmware_end_flow() clear BIT_MCUFWDL_EN bit conditionally. -So, make this change to clear the bit. - -diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c -index a168f36c38ece..298663b035808 100644 ---- a/drivers/net/wireless/realtek/rtw88/mac.c -+++ b/drivers/net/wireless/realtek/rtw88/mac.c -@@ -794,8 +794,10 @@ static int __rtw_download_firmware(struct rtw_dev *rtwdev, - - wlan_cpu_enable(rtwdev, true); - -- if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) -- return -EBUSY; -+ if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) { -+ ret = -EBUSY; -+ goto dlfw_fail; -+ } - - ret = download_firmware_validate(rtwdev); - if (ret) --- -2.25.1 diff --git a/patch/misc/rtw88/6.4/002-rtw88-linux-next.patch b/patch/misc/rtw88/6.4/002-rtw88-linux-next.patch new file mode 100644 index 0000000000..08c149a061 --- /dev/null +++ b/patch/misc/rtw88/6.4/002-rtw88-linux-next.patch @@ -0,0 +1,44 @@ +--- /dev/null 2023-06-17 08:32:20.061755428 -0400 ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723ds.c 2023-06-22 13:52:09.000000000 -0400 +@@ -0,0 +1,41 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) Martin Blumenstingl ++ */ ++ ++#include ++#include ++#include ++#include "main.h" ++#include "rtw8723d.h" ++#include "sdio.h" ++ ++static const struct sdio_device_id rtw_8723ds_id_table[] = { ++ { ++ SDIO_DEVICE(SDIO_VENDOR_ID_REALTEK, ++ SDIO_DEVICE_ID_REALTEK_RTW8723DS_1ANT), ++ .driver_data = (kernel_ulong_t)&rtw8723d_hw_spec, ++ }, ++ { ++ SDIO_DEVICE(SDIO_VENDOR_ID_REALTEK, ++ SDIO_DEVICE_ID_REALTEK_RTW8723DS_2ANT), ++ .driver_data = (kernel_ulong_t)&rtw8723d_hw_spec, ++ }, ++ {} ++}; ++MODULE_DEVICE_TABLE(sdio, rtw_8723ds_id_table); ++ ++static struct sdio_driver rtw_8723ds_driver = { ++ .name = "rtw_8723ds", ++ .probe = rtw_sdio_probe, ++ .remove = rtw_sdio_remove, ++ .id_table = rtw_8723ds_id_table, ++ .drv = { ++ .pm = &rtw_sdio_pm_ops, ++ .shutdown = rtw_sdio_shutdown, ++ } ++}; ++module_sdio_driver(rtw_8723ds_driver); ++ ++MODULE_AUTHOR("Martin Blumenstingl "); ++MODULE_DESCRIPTION("Realtek 802.11n wireless 8723ds driver"); ++MODULE_LICENSE("Dual BSD/GPL"); diff --git a/patch/misc/rtw88/6.4/003-rtw88-fix-action-frame-transmission-fail-before-association.patch b/patch/misc/rtw88/6.4/003-rtw88-fix-action-frame-transmission-fail-before-association.patch deleted file mode 100644 index a41e6fb153..0000000000 --- a/patch/misc/rtw88/6.4/003-rtw88-fix-action-frame-transmission-fail-before-association.patch +++ /dev/null @@ -1,41 +0,0 @@ -From: Ping-Ke Shih @ 2023-06-15 11:43 UTC (permalink / raw) - To: tony0620emma, kvalo; +Cc: phhuang, linux-wireless - -From: Po-Hao Huang - -For combo chips, antennas were controlled by bluetooth only during -power on. If WiFi wish to do transmission, notification to the coexistence -module are required. Previously we only do this before authentication. -To allow transmission before auth, such as management TX, now we start -the initiation of coexistence earlier so antennas are shared between -WiFi and bluetooth after set_channel(), and frames could then be sent. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih ---- - drivers/net/wireless/realtek/rtw88/ps.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/drivers/net/wireless/realtek/rtw88/ps.c b/drivers/net/wireless/realtek/rtw88/ps.c -index 53933fb38a330..43e80a3a8136d 100644 ---- a/drivers/net/wireless/realtek/rtw88/ps.c -+++ b/drivers/net/wireless/realtek/rtw88/ps.c -@@ -18,6 +18,7 @@ static int rtw_ips_pwr_up(struct rtw_dev *rtwdev) - if (ret) - rtw_err(rtwdev, "leave idle state failed\n"); - -+ rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); - rtw_set_channel(rtwdev); - - return ret; -@@ -63,8 +64,6 @@ int rtw_leave_ips(struct rtw_dev *rtwdev) - - rtw_iterate_vifs(rtwdev, rtw_restore_port_cfg_iter, rtwdev); - -- rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); -- - return 0; - } - --- -2.25.1