diff options
Diffstat (limited to 'drivers/net/wireless/realtek/rtw88')
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/coex.c | 298 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/coex.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/debug.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/debug.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/fw.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/fw.h | 9 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/mac80211.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/main.c | 44 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/main.h | 48 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/rtw8821c.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/rtw8822b.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/rtw8822c.c | 47 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/sar.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/tx.c | 2 |
15 files changed, 446 insertions, 56 deletions
diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c index 2551e228b581..cac053f485c3 100644 --- a/drivers/net/wireless/realtek/rtw88/coex.c +++ b/drivers/net/wireless/realtek/rtw88/coex.c @@ -211,6 +211,10 @@ static void rtw_coex_wl_ccklock_detect(struct rtw_dev *rtwdev) bool is_cck_lock_rate = false; + if (coex_stat->wl_coex_mode != COEX_WLINK_2G1PORT && + coex_stat->wl_coex_mode != COEX_WLINK_2GFREE) + return; + if (coex_dm->bt_status == COEX_BTSTATUS_INQ_PAGE || coex_stat->bt_setup_link) { coex_stat->wl_cck_lock = false; @@ -460,6 +464,29 @@ static void rtw_coex_gnt_workaround(struct rtw_dev *rtwdev, bool force, u8 mode) rtw_coex_set_gnt_fix(rtwdev); } +static void rtw_coex_monitor_bt_ctr(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + u32 tmp; + + tmp = rtw_read32(rtwdev, REG_BT_ACT_STATISTICS); + coex_stat->hi_pri_tx = FIELD_GET(MASKLWORD, tmp); + coex_stat->hi_pri_rx = FIELD_GET(MASKHWORD, tmp); + + tmp = rtw_read32(rtwdev, REG_BT_ACT_STATISTICS_1); + coex_stat->lo_pri_tx = FIELD_GET(MASKLWORD, tmp); + coex_stat->lo_pri_rx = FIELD_GET(MASKHWORD, tmp); + + rtw_write8(rtwdev, REG_BT_COEX_ENH_INTR_CTRL, + BIT_R_GRANTALL_WLMASK | BIT_STATIS_BT_EN); + + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], Hi-Pri Rx/Tx: %d/%d, Lo-Pri Rx/Tx: %d/%d\n", + coex_stat->hi_pri_rx, coex_stat->hi_pri_tx, + coex_stat->lo_pri_rx, coex_stat->lo_pri_tx); +} + static void rtw_coex_monitor_bt_enable(struct rtw_dev *rtwdev) { struct rtw_chip_info *chip = rtwdev->chip; @@ -780,7 +807,9 @@ static void rtw_coex_update_bt_link_info(struct rtw_dev *rtwdev) static void rtw_coex_update_wl_ch_info(struct rtw_dev *rtwdev, u8 type) { struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; struct rtw_coex_dm *coex_dm = &rtwdev->coex.dm; + struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; u8 link = 0; u8 center_chan = 0; u8 bw; @@ -791,7 +820,9 @@ static void rtw_coex_update_wl_ch_info(struct rtw_dev *rtwdev, u8 type) if (type != COEX_MEDIA_DISCONNECT) center_chan = rtwdev->hal.current_channel; - if (center_chan == 0) { + if (center_chan == 0 || + (efuse->share_ant && center_chan <= 14 && + coex_stat->wl_coex_mode != COEX_WLINK_2GFREE)) { link = 0; center_chan = 0; bw = 0; @@ -930,6 +961,23 @@ static void rtw_coex_set_gnt_wl(struct rtw_dev *rtwdev, u8 state) rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x0300, state); } +static void rtw_coex_mimo_ps(struct rtw_dev *rtwdev, bool force, bool state) +{ + struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + + if (!force && state == coex_stat->wl_mimo_ps) + return; + + coex_stat->wl_mimo_ps = state; + + rtw_set_txrx_1ss(rtwdev, state); + + rtw_coex_update_wl_ch_info(rtwdev, (u8)coex_stat->wl_connected); + + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], %s(): state = %d\n", __func__, state); +} + static void rtw_btc_wltoggle_table_a(struct rtw_dev *rtwdev, bool force, u8 table_case) { @@ -1106,7 +1154,8 @@ static void rtw_coex_set_tdma(struct rtw_dev *rtwdev, u8 byte1, u8 byte2, ps_type = COEX_PS_WIFI_NATIVE; rtw_coex_power_save_state(rtwdev, ps_type, 0x0, 0x0); - } else if (byte1 & BIT(4) && !(byte1 & BIT(5))) { + } else if ((byte1 & BIT(4) && !(byte1 & BIT(5))) || + coex_stat->wl_coex_mode == COEX_WLINK_2GFREE) { rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s(): Force LPS (byte1 = 0x%x)\n", __func__, byte1); @@ -1802,6 +1851,54 @@ static void rtw_coex_action_bt_inquiry(struct rtw_dev *rtwdev) rtw_coex_tdma(rtwdev, false, tdma_case | slot_type); } +static void rtw_coex_action_bt_game_hid(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_coex_dm *coex_dm = &coex->dm; + struct rtw_chip_info *chip = rtwdev->chip; + u8 table_case, tdma_case; + + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); + rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); + + if (efuse->share_ant) { + coex_stat->wl_coex_mode = COEX_WLINK_2GFREE; + if (coex_stat->bt_whck_test) + table_case = 2; + else if (coex_stat->wl_linkscan_proc || coex_stat->bt_hid_exist) + table_case = 33; + else if (coex_stat->bt_setup_link || coex_stat->bt_inq_page) + table_case = 0; + else if (coex_stat->bt_a2dp_exist) + table_case = 34; + else + table_case = 33; + + tdma_case = 0; + } else { + if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[1])) + tdma_case = 112; + else + tdma_case = 113; + + table_case = 121; + } + + if (coex_stat->wl_coex_mode == COEX_WLINK_2GFREE) { + if (coex_stat->wl_tput_dir == COEX_WL_TPUT_TX) + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_tx[6]); + else + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[5]); + } else { + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + } + + rtw_coex_table(rtwdev, false, table_case); + rtw_coex_tdma(rtwdev, false, tdma_case); +} + static void rtw_coex_action_bt_hfp(struct rtw_dev *rtwdev) { struct rtw_coex *coex = &rtwdev->coex; @@ -1816,13 +1913,8 @@ static void rtw_coex_action_bt_hfp(struct rtw_dev *rtwdev) if (efuse->share_ant) { /* Shared-Ant */ - if (coex_stat->bt_multi_link) { - table_case = 10; - tdma_case = 17; - } else { - table_case = 10; - tdma_case = 5; - } + table_case = 10; + tdma_case = 5; } else { /* Non-Shared-Ant */ if (coex_stat->bt_multi_link) { @@ -2224,8 +2316,10 @@ static void rtw_coex_action_bt_a2dp_pan_hid(struct rtw_dev *rtwdev) static void rtw_coex_action_wl_under5g(struct rtw_dev *rtwdev) { + struct rtw_coex *coex = &rtwdev->coex; struct rtw_efuse *efuse = &rtwdev->efuse; struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex_stat *coex_stat = &coex->stat; u8 table_case, tdma_case; rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); @@ -2235,6 +2329,9 @@ static void rtw_coex_action_wl_under5g(struct rtw_dev *rtwdev) rtw_coex_write_scbd(rtwdev, COEX_SCBD_FIX2M, false); + if (coex_stat->bt_game_hid_exist && coex_stat->wl_linkscan_proc) + coex_stat->wl_coex_mode = COEX_WLINK_2GFREE; + if (efuse->share_ant) { /* Shared-Ant */ table_case = 0; @@ -2278,6 +2375,7 @@ static void rtw_coex_action_wl_native_lps(struct rtw_dev *rtwdev) struct rtw_coex *coex = &rtwdev->coex; struct rtw_efuse *efuse = &rtwdev->efuse; struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex_stat *coex_stat = &coex->stat; u8 table_case, tdma_case; if (coex->under_5g) @@ -2286,7 +2384,6 @@ static void rtw_coex_action_wl_native_lps(struct rtw_dev *rtwdev) rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); - rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); if (efuse->share_ant) { /* Shared-Ant */ @@ -2298,6 +2395,16 @@ static void rtw_coex_action_wl_native_lps(struct rtw_dev *rtwdev) tdma_case = 100; } + if (coex_stat->bt_game_hid_exist) { + coex_stat->wl_coex_mode = COEX_WLINK_2GFREE; + if (coex_stat->wl_tput_dir == COEX_WL_TPUT_TX) + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_tx[6]); + else + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[5]); + } else { + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); + } + rtw_coex_table(rtwdev, false, table_case); rtw_coex_tdma(rtwdev, false, tdma_case); } @@ -2422,6 +2529,7 @@ static void rtw_coex_action_wl_connected(struct rtw_dev *rtwdev) static void rtw_coex_run_coex(struct rtw_dev *rtwdev, u8 reason) { struct rtw_coex *coex = &rtwdev->coex; + struct rtw_chip_info *chip = rtwdev->chip; struct rtw_coex_dm *coex_dm = &coex->dm; struct rtw_coex_stat *coex_stat = &coex->stat; bool rf4ce_en = false; @@ -2494,6 +2602,11 @@ static void rtw_coex_run_coex(struct rtw_dev *rtwdev, u8 reason) goto exit; } + if (coex_stat->bt_game_hid_exist && coex_stat->wl_connected) { + rtw_coex_action_bt_game_hid(rtwdev); + goto exit; + } + if (coex_stat->bt_whck_test) { rtw_coex_action_bt_whql_test(rtwdev); goto exit; @@ -2530,6 +2643,18 @@ static void rtw_coex_run_coex(struct rtw_dev *rtwdev, u8 reason) } exit: + + if (chip->wl_mimo_ps_support) { + if (coex_stat->wl_coex_mode == COEX_WLINK_2GFREE) { + if (coex_dm->reason == COEX_RSN_2GMEDIA) + rtw_coex_mimo_ps(rtwdev, true, true); + else + rtw_coex_mimo_ps(rtwdev, false, true); + } else { + rtw_coex_mimo_ps(rtwdev, false, false); + } + } + rtw_coex_gnt_workaround(rtwdev, false, coex_stat->wl_coex_mode); rtw_coex_limited_wl(rtwdev); } @@ -3139,6 +3264,135 @@ void rtw_coex_bt_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length) rtw_coex_run_coex(rtwdev, COEX_RSN_BTINFO); } +#define COEX_BT_HIDINFO_MTK 0x46 +static const u8 coex_bt_hidinfo_ps[] = {0x57, 0x69, 0x72}; +static const u8 coex_bt_hidinfo_xb[] = {0x58, 0x62, 0x6f}; + +void rtw_coex_bt_hid_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_hid *hidinfo; + struct rtw_coex_hid_info_a *hida; + struct rtw_coex_hid_handle_list *hl, *bhl; + u8 sub_id = buf[2], gamehid_cnt = 0, handle, i; + bool cur_game_hid_exist, complete; + + if (!chip->wl_mimo_ps_support && + (sub_id == COEX_BT_HIDINFO_LIST || sub_id == COEX_BT_HIDINFO_A)) + return; + + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], HID info notify, sub_id = 0x%x\n", sub_id); + + switch (sub_id) { + case COEX_BT_HIDINFO_LIST: + hl = &coex_stat->hid_handle_list; + bhl = (struct rtw_coex_hid_handle_list *)buf; + if (!memcmp(hl, bhl, sizeof(*hl))) + return; + coex_stat->hid_handle_list = *bhl; + memset(&coex_stat->hid_info, 0, sizeof(coex_stat->hid_info)); + for (i = 0; i < COEX_BT_HIDINFO_HANDLE_NUM; i++) { + hidinfo = &coex_stat->hid_info[i]; + if (hl->handle[i] != COEX_BT_HIDINFO_NOTCON && + hl->handle[i] != 0) + hidinfo->hid_handle = hl->handle[i]; + } + break; + case COEX_BT_HIDINFO_A: + hida = (struct rtw_coex_hid_info_a *)buf; + handle = hida->handle; + for (i = 0; i < COEX_BT_HIDINFO_HANDLE_NUM; i++) { + hidinfo = &coex_stat->hid_info[i]; + if (hidinfo->hid_handle == handle) { + hidinfo->hid_vendor = hida->vendor; + memcpy(hidinfo->hid_name, hida->name, + sizeof(hidinfo->hid_name)); + hidinfo->hid_info_completed = true; + break; + } + } + break; + } + for (i = 0; i < COEX_BT_HIDINFO_HANDLE_NUM; i++) { + hidinfo = &coex_stat->hid_info[i]; + complete = hidinfo->hid_info_completed; + handle = hidinfo->hid_handle; + if (!complete || handle == COEX_BT_HIDINFO_NOTCON || + handle == 0 || handle >= COEX_BT_BLE_HANDLE_THRS) { + hidinfo->is_game_hid = false; + continue; + } + + if (hidinfo->hid_vendor == COEX_BT_HIDINFO_MTK) { + if ((memcmp(hidinfo->hid_name, + coex_bt_hidinfo_ps, + COEX_BT_HIDINFO_NAME)) == 0) + hidinfo->is_game_hid = true; + else if ((memcmp(hidinfo->hid_name, + coex_bt_hidinfo_xb, + COEX_BT_HIDINFO_NAME)) == 0) + hidinfo->is_game_hid = true; + else + hidinfo->is_game_hid = false; + } else { + hidinfo->is_game_hid = false; + } + if (hidinfo->is_game_hid) + gamehid_cnt++; + } + + if (gamehid_cnt > 0) + cur_game_hid_exist = true; + else + cur_game_hid_exist = false; + + if (cur_game_hid_exist != coex_stat->bt_game_hid_exist) { + coex_stat->bt_game_hid_exist = cur_game_hid_exist; + rtw_dbg(rtwdev, RTW_DBG_COEX, + "[BTCoex], HID info changed!bt_game_hid_exist = %d!\n", + coex_stat->bt_game_hid_exist); + rtw_coex_run_coex(rtwdev, COEX_RSN_BTSTATUS); + } +} + +void rtw_coex_query_bt_hid_list(struct rtw_dev *rtwdev) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_hid *hidinfo; + u8 i, handle; + bool complete; + + if (!chip->wl_mimo_ps_support || coex_stat->wl_under_ips || + (coex_stat->wl_under_lps && !coex_stat->wl_force_lps_ctrl)) + return; + + if (!coex_stat->bt_hid_exist && + !((coex_stat->bt_info_lb2 & COEX_INFO_CONNECTION) && + (coex_stat->hi_pri_tx + coex_stat->hi_pri_rx > + COEX_BT_GAMEHID_CNT))) + return; + + rtw_fw_coex_query_hid_info(rtwdev, COEX_BT_HIDINFO_LIST, 0); + + for (i = 0; i < COEX_BT_HIDINFO_HANDLE_NUM; i++) { + hidinfo = &coex_stat->hid_info[i]; + complete = hidinfo->hid_info_completed; + handle = hidinfo->hid_handle; + if (handle == 0 || handle == COEX_BT_HIDINFO_NOTCON || + handle >= COEX_BT_BLE_HANDLE_THRS || complete) + continue; + + rtw_fw_coex_query_hid_info(rtwdev, + COEX_BT_HIDINFO_A, + handle); + } +} + void rtw_coex_wl_fwdbginfo_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length) { struct rtw_coex *coex = &rtwdev->coex; @@ -3175,6 +3429,17 @@ void rtw_coex_wl_status_change_notify(struct rtw_dev *rtwdev, u32 type) rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS); } +void rtw_coex_wl_status_check(struct rtw_dev *rtwdev) +{ + struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + + if ((coex_stat->wl_under_lps && !coex_stat->wl_force_lps_ctrl) || + coex_stat->wl_under_ips) + return; + + rtw_coex_monitor_bt_ctr(rtwdev); +} + void rtw_coex_bt_relink_work(struct work_struct *work) { struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, @@ -3637,6 +3902,7 @@ static const char *rtw_coex_get_wl_coex_mode(u8 coex_wl_link_mode) switch (coex_wl_link_mode) { case_WLINK(2G1PORT); case_WLINK(5G); + case_WLINK(2GFREE); default: return "Unknown"; } @@ -3658,7 +3924,6 @@ void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m) u16 score_board_WB, score_board_BW; u32 wl_reg_6c0, wl_reg_6c4, wl_reg_6c8, wl_reg_778, wl_reg_6cc; u32 lte_coex, bt_coex; - u32 bt_hi_pri, bt_lo_pri; int i; score_board_BW = rtw_coex_read_scbd(rtwdev); @@ -3669,17 +3934,6 @@ void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m) wl_reg_6cc = rtw_read32(rtwdev, REG_BT_COEX_TABLE_H); wl_reg_778 = rtw_read8(rtwdev, REG_BT_STAT_CTRL); - bt_hi_pri = rtw_read32(rtwdev, REG_BT_ACT_STATISTICS); - bt_lo_pri = rtw_read32(rtwdev, REG_BT_ACT_STATISTICS_1); - rtw_write8(rtwdev, REG_BT_COEX_ENH_INTR_CTRL, - BIT_R_GRANTALL_WLMASK | BIT_STATIS_BT_EN); - - coex_stat->hi_pri_tx = FIELD_GET(MASKLWORD, bt_hi_pri); - coex_stat->hi_pri_rx = FIELD_GET(MASKHWORD, bt_hi_pri); - - coex_stat->lo_pri_tx = FIELD_GET(MASKLWORD, bt_lo_pri); - coex_stat->lo_pri_rx = FIELD_GET(MASKHWORD, bt_lo_pri); - sys_lte = rtw_read8(rtwdev, 0x73); lte_coex = rtw_coex_read_indirect_reg(rtwdev, 0x38); bt_coex = rtw_coex_read_indirect_reg(rtwdev, 0x54); diff --git a/drivers/net/wireless/realtek/rtw88/coex.h b/drivers/net/wireless/realtek/rtw88/coex.h index fc61a0cab3e4..07fa7aa34d4b 100644 --- a/drivers/net/wireless/realtek/rtw88/coex.h +++ b/drivers/net/wireless/realtek/rtw88/coex.h @@ -11,6 +11,7 @@ #define COEX_MIN_DELAY 10 /* delay unit in ms */ #define COEX_RFK_TIMEOUT 600 /* RFK timeout in ms */ +#define COEX_BT_GAMEHID_CNT 800 #define COEX_RF_OFF 0x0 #define COEX_RF_ON 0x1 @@ -172,6 +173,7 @@ enum coex_bt_profile { enum coex_wl_link_mode { COEX_WLINK_2G1PORT = 0x0, COEX_WLINK_5G = 0x3, + COEX_WLINK_2GFREE = 0x7, COEX_WLINK_MAX }; @@ -401,9 +403,12 @@ void rtw_coex_scan_notify(struct rtw_dev *rtwdev, u8 type); void rtw_coex_connect_notify(struct rtw_dev *rtwdev, u8 type); void rtw_coex_media_status_notify(struct rtw_dev *rtwdev, u8 type); void rtw_coex_bt_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length); +void rtw_coex_bt_hid_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length); void rtw_coex_wl_fwdbginfo_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length); void rtw_coex_switchband_notify(struct rtw_dev *rtwdev, u8 type); void rtw_coex_wl_status_change_notify(struct rtw_dev *rtwdev, u32 type); +void rtw_coex_wl_status_check(struct rtw_dev *rtwdev); +void rtw_coex_query_bt_hid_list(struct rtw_dev *rtwdev); void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m); static inline bool rtw_coex_disabled(struct rtw_dev *rtwdev) diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c index e429428232c1..1a52ff585fbc 100644 --- a/drivers/net/wireless/realtek/rtw88/debug.c +++ b/drivers/net/wireless/realtek/rtw88/debug.c @@ -390,7 +390,7 @@ static ssize_t rtw_debugfs_set_h2c(struct file *filp, ¶m[0], ¶m[1], ¶m[2], ¶m[3], ¶m[4], ¶m[5], ¶m[6], ¶m[7]); if (num != 8) { - rtw_info(rtwdev, "invalid H2C command format for debug\n"); + rtw_warn(rtwdev, "invalid H2C command format for debug\n"); return -EINVAL; } @@ -715,8 +715,10 @@ static int rtw_debugfs_get_phy_info(struct seq_file *m, void *v) seq_printf(m, "Current CH(fc) = %u\n", rtwdev->hal.current_channel); seq_printf(m, "Current BW = %u\n", rtwdev->hal.current_band_width); seq_printf(m, "Current IGI = 0x%x\n", dm_info->igi_history[0]); - seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n\n", + seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n", stats->tx_throughput, stats->rx_throughput); + seq_printf(m, "1SS for TX and RX = %c\n\n", rtwdev->hal.txrx_1ss ? + 'Y' : 'N'); seq_puts(m, "==========[Tx Phy Info]========\n"); seq_puts(m, "[Tx Rate] = "); diff --git a/drivers/net/wireless/realtek/rtw88/debug.h b/drivers/net/wireless/realtek/rtw88/debug.h index 61f8369fe2d6..066792dd96af 100644 --- a/drivers/net/wireless/realtek/rtw88/debug.h +++ b/drivers/net/wireless/realtek/rtw88/debug.h @@ -23,6 +23,7 @@ enum rtw_debug_mask { RTW_DBG_PATH_DIV = 0x00004000, RTW_DBG_ADAPTIVITY = 0x00008000, RTW_DBG_HW_SCAN = 0x00010000, + RTW_DBG_STATE = 0x00020000, RTW_DBG_ALL = 0xffffffff }; diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c index 4c8e5ea5d069..aa2aeb5fb2cc 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.c +++ b/drivers/net/wireless/realtek/rtw88/fw.c @@ -233,6 +233,9 @@ void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb) case C2H_BT_INFO: rtw_coex_bt_info_notify(rtwdev, c2h->payload, len); break; + case C2H_BT_HID_INFO: + rtw_coex_bt_hid_info_notify(rtwdev, c2h->payload, len); + break; case C2H_WLAN_INFO: rtw_coex_wl_fwdbginfo_notify(rtwdev, c2h->payload, len); break; @@ -538,6 +541,18 @@ void rtw_fw_coex_tdma_type(struct rtw_dev *rtwdev, rtw_fw_send_h2c_command(rtwdev, h2c_pkt); } +void rtw_fw_coex_query_hid_info(struct rtw_dev *rtwdev, u8 sub_id, u8 data) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_QUERY_BT_HID_INFO); + + SET_COEX_QUERY_HID_INFO_SUBID(h2c_pkt, sub_id); + SET_COEX_QUERY_HID_INFO_DATA1(h2c_pkt, data); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + void rtw_fw_bt_wifi_control(struct rtw_dev *rtwdev, u8 op_code, u8 *data) { u8 h2c_pkt[H2C_PKT_SIZE] = {0}; @@ -2131,7 +2146,7 @@ void rtw_hw_scan_status_report(struct rtw_dev *rtwdev, struct sk_buff *skb) rtw_hw_scan_complete(rtwdev, vif, aborted); if (aborted) - rtw_info(rtwdev, "HW scan aborted with code: %d\n", rc); + rtw_dbg(rtwdev, RTW_DBG_HW_SCAN, "HW scan aborted with code: %d\n", rc); } void rtw_store_op_chan(struct rtw_dev *rtwdev) diff --git a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h index 654c3c2e5721..b59d2cbad5d7 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.h +++ b/drivers/net/wireless/realtek/rtw88/fw.h @@ -47,6 +47,7 @@ enum rtw_c2h_cmd_id { C2H_CCX_TX_RPT = 0x03, C2H_BT_INFO = 0x09, C2H_BT_MP_INFO = 0x0b, + C2H_BT_HID_INFO = 0x45, C2H_RA_RPT = 0x0c, C2H_HW_FEATURE_REPORT = 0x19, C2H_WLAN_INFO = 0x27, @@ -529,6 +530,7 @@ static inline void rtw_h2c_pkt_set_header(u8 *h2c_pkt, u8 sub_id) #define H2C_CMD_QUERY_BT_MP_INFO 0x67 #define H2C_CMD_BT_WIFI_CONTROL 0x69 #define H2C_CMD_WIFI_CALIBRATION 0x6d +#define H2C_CMD_QUERY_BT_HID_INFO 0x73 #define H2C_CMD_KEEP_ALIVE 0x03 #define H2C_CMD_DISCONNECT_DECISION 0x04 @@ -681,6 +683,11 @@ static inline void rtw_h2c_pkt_set_header(u8 *h2c_pkt, u8 sub_id) #define SET_BT_WIFI_CONTROL_DATA5(h2c_pkt, value) \ le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(23, 16)) +#define SET_COEX_QUERY_HID_INFO_SUBID(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8)) +#define SET_COEX_QUERY_HID_INFO_DATA1(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16)) + #define SET_KEEP_ALIVE_ENABLE(h2c_pkt, value) \ le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8)) #define SET_KEEP_ALIVE_ADOPT(h2c_pkt, value) \ @@ -780,6 +787,8 @@ void rtw_fw_force_bt_tx_power(struct rtw_dev *rtwdev, u8 bt_pwr_dec_lvl); void rtw_fw_bt_ignore_wlan_action(struct rtw_dev *rtwdev, bool enable); void rtw_fw_coex_tdma_type(struct rtw_dev *rtwdev, u8 para1, u8 para2, u8 para3, u8 para4, u8 para5); +void rtw_fw_coex_query_hid_info(struct rtw_dev *rtwdev, u8 sub_id, u8 data); + void rtw_fw_bt_wifi_control(struct rtw_dev *rtwdev, u8 op_code, u8 *data); void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si); void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si); diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c index 647d2662955b..5cdc54c9a9aa 100644 --- a/drivers/net/wireless/realtek/rtw88/mac80211.c +++ b/drivers/net/wireless/realtek/rtw88/mac80211.c @@ -208,7 +208,7 @@ static int rtw_ops_add_interface(struct ieee80211_hw *hw, mutex_unlock(&rtwdev->mutex); - rtw_info(rtwdev, "start vif %pM on port %d\n", vif->addr, rtwvif->port); + rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %pM on port %d\n", vif->addr, rtwvif->port); return 0; } @@ -219,7 +219,7 @@ static void rtw_ops_remove_interface(struct ieee80211_hw *hw, struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; u32 config = 0; - rtw_info(rtwdev, "stop vif %pM on port %d\n", vif->addr, rtwvif->port); + rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %pM on port %d\n", vif->addr, rtwvif->port); mutex_lock(&rtwdev->mutex); @@ -245,8 +245,8 @@ static int rtw_ops_change_interface(struct ieee80211_hw *hw, { struct rtw_dev *rtwdev = hw->priv; - rtw_info(rtwdev, "change vif %pM (%d)->(%d), p2p (%d)->(%d)\n", - vif->addr, vif->type, type, vif->p2p, p2p); + rtw_dbg(rtwdev, RTW_DBG_STATE, "change vif %pM (%d)->(%d), p2p (%d)->(%d)\n", + vif->addr, vif->type, type, vif->p2p, p2p); rtw_ops_remove_interface(hw, vif); diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index 2757aa0dc586..8b9899e41b0b 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -207,6 +207,9 @@ static void rtw_watch_dog_work(struct work_struct *work) else clear_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); + rtw_coex_wl_status_check(rtwdev); + rtw_coex_query_bt_hid_list(rtwdev); + if (busy_traffic != test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags)) rtw_coex_wl_status_change_notify(rtwdev, 0); @@ -314,8 +317,8 @@ int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta, rtwdev->sta_cnt++; rtwdev->beacon_loss = false; - rtw_info(rtwdev, "sta %pM joined with macid %d\n", - sta->addr, si->mac_id); + rtw_dbg(rtwdev, RTW_DBG_STATE, "sta %pM joined with macid %d\n", + sta->addr, si->mac_id); return 0; } @@ -336,8 +339,8 @@ void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta, kfree(si->mask); rtwdev->sta_cnt--; - rtw_info(rtwdev, "sta %pM with macid %d left\n", - sta->addr, si->mac_id); + rtw_dbg(rtwdev, RTW_DBG_STATE, "sta %pM with macid %d left\n", + sta->addr, si->mac_id); } struct rtw_fwcd_hdr { @@ -1135,7 +1138,7 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) ldpc_en = HT_LDPC_EN; } - if (efuse->hw_cap.nss == 1) + if (efuse->hw_cap.nss == 1 || rtwdev->hal.txrx_1ss) ra_mask &= RA_MASK_VHT_RATES_1SS | RA_MASK_HT_RATES_1SS; if (hal->current_band_type == RTW_BAND_5G) { @@ -1570,6 +1573,37 @@ static void rtw_unset_supported_band(struct ieee80211_hw *hw, kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]); } +static void rtw_vif_smps_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct rtw_dev *rtwdev = (struct rtw_dev *)data; + + if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc) + return; + + if (rtwdev->hal.txrx_1ss) + ieee80211_request_smps(vif, IEEE80211_SMPS_STATIC); + else + ieee80211_request_smps(vif, IEEE80211_SMPS_OFF); +} + +void rtw_set_txrx_1ss(struct rtw_dev *rtwdev, bool txrx_1ss) +{ + struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_hal *hal = &rtwdev->hal; + + if (!chip->ops->config_txrx_mode || rtwdev->hal.txrx_1ss == txrx_1ss) + return; + + rtwdev->hal.txrx_1ss = txrx_1ss; + if (txrx_1ss) + chip->ops->config_txrx_mode(rtwdev, BB_PATH_A, BB_PATH_A, false); + else + chip->ops->config_txrx_mode(rtwdev, hal->antenna_tx, + hal->antenna_rx, false); + rtw_iterate_vifs_atomic(rtwdev, rtw_vif_smps_iter, rtwdev); +} + static void __update_firmware_feature(struct rtw_dev *rtwdev, struct rtw_fw_state *fw) { diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index 36e1e408933d..17815af9dd4e 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -874,6 +874,8 @@ struct rtw_chip_ops { enum rtw_bb_path tx_path_1ss, enum rtw_bb_path tx_path_cck, bool is_tx2_path); + void (*config_txrx_mode)(struct rtw_dev *rtwdev, u8 tx_path, + u8 rx_path, bool is_tx2_path); /* for coex */ void (*coex_set_init)(struct rtw_dev *rtwdev); @@ -1240,6 +1242,7 @@ struct rtw_chip_info { bool scbd_support; bool new_scbd10_def; /* true: fix 2M(8822c) */ bool ble_hid_profile_support; + bool wl_mimo_ps_support; u8 pstdma_type; /* 0: LPSoff, 1:LPSon */ u8 bt_rssi_type; u8 ant_isolation; @@ -1352,6 +1355,42 @@ struct rtw_coex_dm { #define COEX_BTINFO_LENGTH_MAX 10 #define COEX_BTINFO_LENGTH 7 +#define COEX_BT_HIDINFO_LIST 0x0 +#define COEX_BT_HIDINFO_A 0x1 +#define COEX_BT_HIDINFO_NAME 3 + +#define COEX_BT_HIDINFO_LENGTH 6 +#define COEX_BT_HIDINFO_HANDLE_NUM 4 +#define COEX_BT_HIDINFO_C2H_HANDLE 0 +#define COEX_BT_HIDINFO_C2H_VENDOR 1 +#define COEX_BT_BLE_HANDLE_THRS 0x10 +#define COEX_BT_HIDINFO_NOTCON 0xff + +struct rtw_coex_hid { + u8 hid_handle; + u8 hid_vendor; + u8 hid_name[COEX_BT_HIDINFO_NAME]; + bool hid_info_completed; + bool is_game_hid; +}; + +struct rtw_coex_hid_handle_list { + u8 cmd_id; + u8 len; + u8 subid; + u8 handle_cnt; + u8 handle[COEX_BT_HIDINFO_HANDLE_NUM]; +} __packed; + +struct rtw_coex_hid_info_a { + u8 cmd_id; + u8 len; + u8 subid; + u8 handle; + u8 vendor; + u8 name[COEX_BT_HIDINFO_NAME]; +} __packed; + struct rtw_coex_stat { bool bt_disabled; bool bt_disabled_pre; @@ -1382,6 +1421,8 @@ struct rtw_coex_stat { bool bt_slave; bool bt_418_hid_exist; bool bt_ble_hid_exist; + bool bt_game_hid_exist; + bool bt_hid_handle_cnt; bool bt_mailbox_reply; bool wl_under_lps; @@ -1402,6 +1443,7 @@ struct rtw_coex_stat { bool wl_connecting; bool wl_slot_toggle; bool wl_slot_toggle_change; /* if toggle to no-toggle */ + bool wl_mimo_ps; u32 bt_supported_version; u32 bt_supported_feature; @@ -1459,6 +1501,9 @@ struct rtw_coex_stat { u32 darfrc; u32 darfrch; + + struct rtw_coex_hid hid_info[COEX_BT_HIDINFO_HANDLE_NUM]; + struct rtw_coex_hid_handle_list hid_handle_list; }; struct rtw_coex { @@ -1867,6 +1912,7 @@ struct rtw_hal { u32 antenna_tx; u32 antenna_rx; u8 bfee_sts_cap; + bool txrx_1ss; /* protect tx power section */ struct mutex tx_power_mutex; @@ -2123,5 +2169,5 @@ void rtw_core_fw_scan_notify(struct rtw_dev *rtwdev, bool start); int rtw_dump_fw(struct rtw_dev *rtwdev, const u32 ocp_src, u32 size, u32 fwcd_item); int rtw_dump_reg(struct rtw_dev *rtwdev, const u32 addr, const u32 size); - +void rtw_set_txrx_1ss(struct rtw_dev *rtwdev, bool config_1ss); #endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c index 3fdbaf7302c5..ad2b323a0423 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c @@ -2753,6 +2753,7 @@ struct rtw_chip_info rtw8723d_hw_spec = { .scbd_support = true, .new_scbd10_def = true, .ble_hid_profile_support = false, + .wl_mimo_ps_support = false, .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, .bt_rssi_type = COEX_BTRSSI_RATIO, .ant_isolation = 15, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c index b1f4afb50830..99eee128ae94 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c @@ -499,7 +499,7 @@ static s8 get_cck_rx_pwr(struct rtw_dev *rtwdev, u8 lna_idx, u8 vga_idx) } if (lna_idx >= lna_gain_table_size) { - rtw_info(rtwdev, "incorrect lna index (%d)\n", lna_idx); + rtw_warn(rtwdev, "incorrect lna index (%d)\n", lna_idx); return -120; } @@ -1925,6 +1925,7 @@ struct rtw_chip_info rtw8821c_hw_spec = { .scbd_support = true, .new_scbd10_def = false, .ble_hid_profile_support = false, + .wl_mimo_ps_support = false, .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, .bt_rssi_type = COEX_BTRSSI_RATIO, .ant_isolation = 15, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c index dd4fbb82750d..eee7bf035403 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c @@ -1012,12 +1012,12 @@ static int rtw8822b_set_antenna(struct rtw_dev *rtwdev, antenna_tx, antenna_rx); if (!rtw8822b_check_rf_path(antenna_tx)) { - rtw_info(rtwdev, "unsupported tx path 0x%x\n", antenna_tx); + rtw_warn(rtwdev, "unsupported tx path 0x%x\n", antenna_tx); return -EINVAL; } if (!rtw8822b_check_rf_path(antenna_rx)) { - rtw_info(rtwdev, "unsupported rx path 0x%x\n", antenna_rx); + rtw_warn(rtwdev, "unsupported rx path 0x%x\n", antenna_rx); return -EINVAL; } @@ -2554,6 +2554,7 @@ struct rtw_chip_info rtw8822b_hw_spec = { .scbd_support = true, .new_scbd10_def = false, .ble_hid_profile_support = false, + .wl_mimo_ps_support = false, .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, .bt_rssi_type = COEX_BTRSSI_RATIO, .ant_isolation = 15, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c index 35c46e5209de..cd74607a61a2 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c @@ -2798,7 +2798,7 @@ static int rtw8822c_set_antenna(struct rtw_dev *rtwdev, case BB_PATH_AB: break; default: - rtw_info(rtwdev, "unsupported tx path 0x%x\n", antenna_tx); + rtw_warn(rtwdev, "unsupported tx path 0x%x\n", antenna_tx); return -EINVAL; } @@ -2808,7 +2808,7 @@ static int rtw8822c_set_antenna(struct rtw_dev *rtwdev, case BB_PATH_AB: break; default: - rtw_info(rtwdev, "unsupported rx path 0x%x\n", antenna_rx); + rtw_warn(rtwdev, "unsupported rx path 0x%x\n", antenna_rx); return -EINVAL; } @@ -2996,19 +2996,34 @@ static void rtw8822c_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) * enable "DAC off if GNT_WL = 0" for non-shared-antenna * disable 0x1c30[22] = 0, * enable: 0x1c30[22] = 1, 0x1c38[12] = 0, 0x1c38[28] = 1 - * - * disable WL-S1 BB chage RF mode if GNT_BT + */ + if (coex_stat->wl_coex_mode == COEX_WLINK_2GFREE) { + rtw_write8_mask(rtwdev, REG_ANAPAR + 2, + BIT_ANAPAR_BTPS >> 16, 0); + } else { + rtw_write8_mask(rtwdev, REG_ANAPAR + 2, + BIT_ANAPAR_BTPS >> 16, 1); + rtw_write8_mask(rtwdev, REG_RSTB_SEL + 1, + BIT_DAC_OFF_ENABLE, 0); + rtw_write8_mask(rtwdev, REG_RSTB_SEL + 3, + BIT_DAC_OFF_ENABLE, 1); + } + + /* disable WL-S1 BB chage RF mode if GNT_BT * since RF TRx mask can do it */ - rtw_write8_mask(rtwdev, REG_ANAPAR + 2, BIT_ANAPAR_BTPS >> 16, 1); - rtw_write8_mask(rtwdev, REG_RSTB_SEL + 1, BIT_DAC_OFF_ENABLE, 0); - rtw_write8_mask(rtwdev, REG_RSTB_SEL + 3, BIT_DAC_OFF_ENABLE, 1); - rtw_write8_mask(rtwdev, REG_IGN_GNTBT4, BIT_PI_IGNORE_GNT_BT, 1); + rtw_write8_mask(rtwdev, REG_IGN_GNTBT4, + BIT_PI_IGNORE_GNT_BT, 1); /* disable WL-S0 BB chage RF mode if wifi is at 5G, * or antenna path is separated */ - if (coex_stat->wl_coex_mode == COEX_WLINK_5G || + if (coex_stat->wl_coex_mode == COEX_WLINK_2GFREE) { + rtw_write8_mask(rtwdev, REG_IGN_GNT_BT1, + BIT_PI_IGNORE_GNT_BT, 1); + rtw_write8_mask(rtwdev, REG_NOMASK_TXBT, + BIT_NOMASK_TXBT_ENABLE, 1); + } else if (coex_stat->wl_coex_mode == COEX_WLINK_5G || coex->under_5g || !efuse->share_ant) { if (coex_stat->kt_ver >= 3) { rtw_write8_mask(rtwdev, REG_IGN_GNT_BT1, @@ -4962,6 +4977,7 @@ static struct rtw_chip_ops rtw8822c_ops = { .cfo_init = rtw8822c_cfo_init, .cfo_track = rtw8822c_cfo_track, .config_tx_path = rtw8822c_config_tx_path, + .config_txrx_mode = rtw8822c_config_trx_mode, .coex_set_init = rtw8822c_coex_cfg_init, .coex_set_ant_switch = NULL, @@ -5007,6 +5023,8 @@ static const struct coex_table_para table_sant_8822c[] = { {0x66556aaa, 0x6a5a6aaa}, /*case-30*/ {0xffffffff, 0x5aaa5aaa}, {0x56555555, 0x5a5a5aaa}, + {0xdaffdaff, 0xdaffdaff}, + {0xddffddff, 0xddffddff}, }; /* Non-Shared-Antenna Coex Table */ @@ -5107,7 +5125,8 @@ static const struct coex_rf_para rf_para_tx_8822c[] = { {8, 17, true, 4}, {7, 18, true, 4}, {6, 19, true, 4}, - {5, 20, true, 4} + {5, 20, true, 4}, + {0, 21, true, 4} /* for gamg hid */ }; static const struct coex_rf_para rf_para_rx_8822c[] = { @@ -5116,7 +5135,8 @@ static const struct coex_rf_para rf_para_rx_8822c[] = { {3, 24, true, 5}, {2, 26, true, 5}, {1, 27, true, 5}, - {0, 28, true, 5} + {0, 28, true, 5}, + {0, 28, true, 5} /* for gamg hid */ }; static_assert(ARRAY_SIZE(rf_para_tx_8822c) == ARRAY_SIZE(rf_para_rx_8822c)); @@ -5354,11 +5374,12 @@ struct rtw_chip_info rtw8822c_hw_spec = { .wowlan_stub = &rtw_wowlan_stub_8822c, .max_sched_scan_ssids = 4, #endif - .coex_para_ver = 0x2103181c, - .bt_desired_ver = 0x1c, + .coex_para_ver = 0x22020720, + .bt_desired_ver = 0x20, .scbd_support = true, .new_scbd10_def = true, .ble_hid_profile_support = true, + .wl_mimo_ps_support = true, .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, .bt_rssi_type = COEX_BTRSSI_DBM, .ant_isolation = 15, diff --git a/drivers/net/wireless/realtek/rtw88/sar.c b/drivers/net/wireless/realtek/rtw88/sar.c index 3383726c4d90..c472f1502b82 100644 --- a/drivers/net/wireless/realtek/rtw88/sar.c +++ b/drivers/net/wireless/realtek/rtw88/sar.c @@ -91,10 +91,10 @@ int rtw_set_sar_specs(struct rtw_dev *rtwdev, return -EINVAL; power = sar->sub_specs[i].power; - rtw_info(rtwdev, "On freq %u to %u, set SAR %d in 1/%lu dBm\n", - rtw_common_sar_freq_ranges[idx].start_freq, - rtw_common_sar_freq_ranges[idx].end_freq, - power, BIT(RTW_COMMON_SAR_FCT)); + rtw_dbg(rtwdev, RTW_DBG_REGD, "On freq %u to %u, set SAR %d in 1/%lu dBm\n", + rtw_common_sar_freq_ranges[idx].start_freq, + rtw_common_sar_freq_ranges[idx].end_freq, + power, BIT(RTW_COMMON_SAR_FCT)); for (j = 0; j < RTW_RF_PATH_MAX; j++) { for (k = 0; k < RTW_RATE_SECTION_MAX; k++) { diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c index efcc1b0371a8..94d1089f4022 100644 --- a/drivers/net/wireless/realtek/rtw88/tx.c +++ b/drivers/net/wireless/realtek/rtw88/tx.c @@ -353,7 +353,7 @@ static void rtw_tx_data_pkt_info_update(struct rtw_dev *rtwdev, bw = si->bw_mode; rate_id = si->rate_id; - stbc = si->stbc_en; + stbc = rtwdev->hal.txrx_1ss ? false : si->stbc_en; ldpc = si->ldpc_en; out: |