diff options
Diffstat (limited to 'drivers/net/wireless/realtek/rtw89')
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/coex.c | 212 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/core.c | 33 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/core.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/debug.c | 43 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/debug.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/fw.c | 84 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/fw.h | 40 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/mac.c | 88 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/mac.h | 19 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/mac80211.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/pci.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/phy.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/reg.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/rtw8852b.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/rtw8852c.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/ser.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/wow.c | 26 |
18 files changed, 384 insertions, 197 deletions
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index d48ae25823ff..bcf483cafd20 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -9,7 +9,7 @@ #include "ps.h" #include "reg.h" -#define RTW89_COEX_VERSION 0x06030013 +#define RTW89_COEX_VERSION 0x07000013 #define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/ enum btc_fbtc_tdma_template { @@ -63,7 +63,7 @@ struct btc_fbtc_1slot { static const struct rtw89_btc_fbtc_tdma t_def[] = { [CXTD_OFF] = { CXTDMA_OFF, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0}, [CXTD_OFF_B2] = { CXTDMA_OFF, CXFLC_OFF, CXTPS_OFF, 0, 0, 1, 0, 0}, - [CXTD_OFF_EXT] = { CXTDMA_OFF, CXFLC_OFF, CXTPS_OFF, 0, 0, 3, 0, 0}, + [CXTD_OFF_EXT] = { CXTDMA_OFF, CXFLC_OFF, CXTPS_OFF, 0, 0, 2, 0, 0}, [CXTD_FIX] = { CXTDMA_FIX, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0}, [CXTD_PFIX] = { CXTDMA_FIX, CXFLC_NULLP, CXTPS_ON, 0, 5, 0, 0, 0}, [CXTD_AUTO] = { CXTDMA_AUTO, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0}, @@ -80,21 +80,21 @@ static const struct rtw89_btc_fbtc_slot s_def[] = { [CXST_OFF] = __DEF_FBTC_SLOT(100, 0x55555555, SLOT_MIX), [CXST_B2W] = __DEF_FBTC_SLOT(5, 0xea5a5a5a, SLOT_ISO), [CXST_W1] = __DEF_FBTC_SLOT(70, 0xea5a5a5a, SLOT_ISO), - [CXST_W2] = __DEF_FBTC_SLOT(70, 0xea5a5aaa, SLOT_ISO), + [CXST_W2] = __DEF_FBTC_SLOT(15, 0xea5a5a5a, SLOT_ISO), [CXST_W2B] = __DEF_FBTC_SLOT(15, 0xea5a5a5a, SLOT_ISO), - [CXST_B1] = __DEF_FBTC_SLOT(100, 0xe5555555, SLOT_MIX), + [CXST_B1] = __DEF_FBTC_SLOT(250, 0xe5555555, SLOT_MIX), [CXST_B2] = __DEF_FBTC_SLOT(7, 0xea5a5a5a, SLOT_MIX), [CXST_B3] = __DEF_FBTC_SLOT(5, 0xe5555555, SLOT_MIX), [CXST_B4] = __DEF_FBTC_SLOT(50, 0xe5555555, SLOT_MIX), [CXST_LK] = __DEF_FBTC_SLOT(20, 0xea5a5a5a, SLOT_ISO), - [CXST_BLK] = __DEF_FBTC_SLOT(250, 0x55555555, SLOT_MIX), - [CXST_E2G] = __DEF_FBTC_SLOT(20, 0xea5a5a5a, SLOT_MIX), - [CXST_E5G] = __DEF_FBTC_SLOT(20, 0xffffffff, SLOT_MIX), - [CXST_EBT] = __DEF_FBTC_SLOT(20, 0xe5555555, SLOT_MIX), - [CXST_ENULL] = __DEF_FBTC_SLOT(7, 0xaaaaaaaa, SLOT_ISO), + [CXST_BLK] = __DEF_FBTC_SLOT(500, 0x55555555, SLOT_MIX), + [CXST_E2G] = __DEF_FBTC_SLOT(0, 0xea5a5a5a, SLOT_MIX), + [CXST_E5G] = __DEF_FBTC_SLOT(0, 0xffffffff, SLOT_ISO), + [CXST_EBT] = __DEF_FBTC_SLOT(0, 0xe5555555, SLOT_MIX), + [CXST_ENULL] = __DEF_FBTC_SLOT(0, 0xaaaaaaaa, SLOT_ISO), [CXST_WLK] = __DEF_FBTC_SLOT(250, 0xea5a5a5a, SLOT_MIX), - [CXST_W1FDD] = __DEF_FBTC_SLOT(35, 0xfafafafa, SLOT_ISO), - [CXST_B1FDD] = __DEF_FBTC_SLOT(100, 0xffffffff, SLOT_MIX), + [CXST_W1FDD] = __DEF_FBTC_SLOT(50, 0xffffffff, SLOT_ISO), + [CXST_B1FDD] = __DEF_FBTC_SLOT(50, 0xffffdfff, SLOT_ISO), }; static const u32 cxtbl[] = { @@ -117,7 +117,12 @@ static const u32 cxtbl[] = { 0xfafafafa, /* 16 */ 0xffffddff, /* 17 */ 0xdaffdaff, /* 18 */ - 0xfafadafa /* 19 */ + 0xfafadafa, /* 19 */ + 0xea6a6a6a, /* 20 */ + 0xea55556a, /* 21 */ + 0xaafafafa, /* 22 */ + 0xfafaaafa, /* 23 */ + 0xfafffaff /* 24 */ }; static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = { @@ -2701,15 +2706,16 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type) break; case BTC_CXP_OFF_EQ0: _slot_set_tbl(btc, CXST_OFF, cxtbl[0]); + _slot_set_type(btc, CXST_OFF, SLOT_ISO); break; case BTC_CXP_OFF_EQ1: _slot_set_tbl(btc, CXST_OFF, cxtbl[16]); break; case BTC_CXP_OFF_EQ2: - _slot_set_tbl(btc, CXST_OFF, cxtbl[17]); + _slot_set_tbl(btc, CXST_OFF, cxtbl[0]); break; case BTC_CXP_OFF_EQ3: - _slot_set_tbl(btc, CXST_OFF, cxtbl[18]); + _slot_set_tbl(btc, CXST_OFF, cxtbl[24]); break; case BTC_CXP_OFF_BWB0: _slot_set_tbl(btc, CXST_OFF, cxtbl[5]); @@ -2765,6 +2771,7 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type) default: break; } + s[CXST_OFF] = s_def[CXST_OFF]; break; case BTC_CXP_FIX: /* TDMA Fix-Slot */ _write_scbd(rtwdev, BTC_WSCB_TDMA, true); @@ -2791,6 +2798,10 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type) _slot_set(btc, CXST_W1, 40, cxtbl[1], SLOT_ISO); _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); break; + case BTC_CXP_FIX_TD4020: + _slot_set(btc, CXST_W1, 40, cxtbl[1], SLOT_MIX); + _slot_set(btc, CXST_B1, 20, tbl_b1, SLOT_MIX); + break; case BTC_CXP_FIX_TD7010: _slot_set(btc, CXST_W1, 70, tbl_w1, SLOT_ISO); _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); @@ -3807,6 +3818,7 @@ static void _action_common(struct rtw89_dev *rtwdev) wl->scbd_change = false; btc->cx.cnt_wl[BTC_WCNT_SCBDUPDATE]++; } + btc->dm.tdma_instant_excute = 0; } static void _action_by_bt(struct rtw89_dev *rtwdev) @@ -3835,7 +3847,7 @@ static void _action_by_bt(struct rtw89_dev *rtwdev) case BTC_BT_NOPROFILE: if (_check_freerun(rtwdev)) _action_freerun(rtwdev); - else if (a2dp.active || pan.active) + else if (pan.active) _action_bt_pan(rtwdev); else _action_bt_idle(rtwdev); @@ -4590,7 +4602,7 @@ static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update) bt->whql_test = !!(val & BTC_BSCB_WHQL); bt->btg_type = val & BTC_BSCB_BT_S1 ? BTC_BT_BTG : BTC_BT_ALONE; - bt->link_info.a2dp_desc.active = !!(val & BTC_BSCB_A2DP_ACT); + bt->link_info.a2dp_desc.exist = !!(val & BTC_BSCB_A2DP_ACT); /* if rfk run 1->0 */ if (bt->rfk_info.map.run && !(val & BTC_BSCB_RFK_RUN)) @@ -4751,6 +4763,8 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason) _action_wl_nc(rtwdev); break; case BTC_WLINK_2G_STA: + if (wl->status.map.traffic_dir & BIT(RTW89_TFC_DL)) + bt->scan_rx_low_pri = true; _action_wl_2g_sta(rtwdev); break; case BTC_WLINK_2G_AP: @@ -5324,7 +5338,6 @@ void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_sta } if (rf_state == BTC_RFCTRL_WL_ON) { - btc->dm.cnt_dm[BTC_DCNT_BTCNT_FREEZE] = 0; rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_MREG, true); val = BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG; _write_scbd(rtwdev, val, true); @@ -5336,6 +5349,13 @@ void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_sta _write_scbd(rtwdev, BTC_WSCB_ALL, false); } + btc->dm.cnt_dm[BTC_DCNT_BTCNT_FREEZE] = 0; + if (wl->status.map.lps_pre == BTC_LPS_OFF && + wl->status.map.lps_pre != wl->status.map.lps) + btc->dm.tdma_instant_excute = 1; + else + btc->dm.tdma_instant_excute = 0; + _run_coex(rtwdev, BTC_RSN_NTFY_RADIO_STATE); wl->status.map.rf_off_pre = wl->status.map.rf_off; @@ -6383,20 +6403,21 @@ static void _show_fbtc_slots(struct rtw89_dev *rtwdev, struct seq_file *m) for (i = 0; i < CXST_MAX; i++) { s = &dm->slot_now[i]; - if (i % 6 == 0) + if (i % 5 == 0) seq_printf(m, - " %-15s : %02d[%03d/0x%x/%d]", + " %-15s : %5s[%03d/0x%x/%d]", "[slot_list]", - (u32)i, + id_to_slot((u32)i), s->dur, s->cxtbl, s->cxtype); else seq_printf(m, - ", %02d[%03d/0x%x/%d]", - (u32)i, + ", %5s[%03d/0x%x/%d]", + id_to_slot((u32)i), s->dur, s->cxtbl, s->cxtype); - if (i % 6 == 5) + if (i % 5 == 4) seq_puts(m, "\n"); } + seq_puts(m, "\n"); } static void _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, struct seq_file *m) @@ -6428,7 +6449,7 @@ static void _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, struct seq_file *m) for (i = 0; i < CXST_MAX; i++) { if (!le32_to_cpu(pcysta_le32->slot_cnt[i])) continue; - seq_printf(m, ", %d:%d", (u32)i, + seq_printf(m, ", %s:%d", id_to_slot((u32)i), le32_to_cpu(pcysta_le32->slot_cnt[i])); } @@ -6463,7 +6484,7 @@ static void _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, struct seq_file *m) le16_to_cpu(pcysta_le32->tmaxdiff_cycle[CXT_WL]), le16_to_cpu(pcysta_le32->tmaxdiff_cycle[CXT_BT])); - if (le16_to_cpu(pcysta_le32->cycles) == 0) + if (le16_to_cpu(pcysta_le32->cycles) <= 1) return; /* 1 cycle record 1 wl-slot and 1 bt-slot */ @@ -6590,7 +6611,7 @@ static void _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, struct seq_file *m) le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT])); cycle = le16_to_cpu(pcysta->cycles); - if (cycle == 0) + if (cycle <= 1) return; /* 1 cycle record 1 wl-slot and 1 bt-slot */ @@ -6612,40 +6633,39 @@ static void _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, struct seq_file *m) cnt++; store_index = ((cycle - 1) % slot_pair) * 2; - if (cnt % divide_cnt == 1) { - seq_printf(m, "\n\r %-15s : ", "[cycle_step]"); - } else { - seq_printf(m, "->b%02d", - le16_to_cpu(pcysta->slot_step_time[store_index])); - if (a2dp->exist) { - a2dp_trx = &pcysta->a2dp_trx[store_index]; - seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", - a2dp_trx->empty_cnt, - a2dp_trx->retry_cnt, - a2dp_trx->tx_rate ? 3 : 2, - a2dp_trx->tx_cnt, - a2dp_trx->ack_cnt, - a2dp_trx->nack_cnt); - } - seq_printf(m, "->w%02d", - le16_to_cpu(pcysta->slot_step_time[store_index + 1])); - if (a2dp->exist) { - a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; - seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", - a2dp_trx->empty_cnt, - a2dp_trx->retry_cnt, - a2dp_trx->tx_rate ? 3 : 2, - a2dp_trx->tx_cnt, - a2dp_trx->ack_cnt, - a2dp_trx->nack_cnt); - } + if (cnt % divide_cnt == 1) + seq_printf(m, " %-15s : ", "[cycle_step]"); + + seq_printf(m, "->b%02d", + le16_to_cpu(pcysta->slot_step_time[store_index])); + if (a2dp->exist) { + a2dp_trx = &pcysta->a2dp_trx[store_index]; + seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", + a2dp_trx->empty_cnt, + a2dp_trx->retry_cnt, + a2dp_trx->tx_rate ? 3 : 2, + a2dp_trx->tx_cnt, + a2dp_trx->ack_cnt, + a2dp_trx->nack_cnt); } - if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 0 || cnt == c_end) + seq_printf(m, "->w%02d", + le16_to_cpu(pcysta->slot_step_time[store_index + 1])); + if (a2dp->exist) { + a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; + seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", + a2dp_trx->empty_cnt, + a2dp_trx->retry_cnt, + a2dp_trx->tx_rate ? 3 : 2, + a2dp_trx->tx_cnt, + a2dp_trx->ack_cnt, + a2dp_trx->nack_cnt); + } + if (cnt % divide_cnt == 0 || cnt == c_end) seq_puts(m, "\n"); } if (a2dp->exist) { - seq_printf(m, "%-15s : a2dp_ept:%d, a2dp_late:%d", + seq_printf(m, " %-15s : a2dp_ept:%d, a2dp_late:%d", "[a2dp_t_sta]", le16_to_cpu(pcysta->a2dp_ept.cnt), le16_to_cpu(pcysta->a2dp_ept.cnt_timeout)); @@ -6723,7 +6743,7 @@ static void _show_fbtc_cysta_v4(struct rtw89_dev *rtwdev, struct seq_file *m) le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT])); cycle = le16_to_cpu(pcysta->cycles); - if (cycle == 0) + if (cycle <= 1) return; /* 1 cycle record 1 wl-slot and 1 bt-slot */ @@ -6745,40 +6765,39 @@ static void _show_fbtc_cysta_v4(struct rtw89_dev *rtwdev, struct seq_file *m) cnt++; store_index = ((cycle - 1) % slot_pair) * 2; - if (cnt % divide_cnt == 1) { - seq_printf(m, "\n\r %-15s : ", "[cycle_step]"); - } else { - seq_printf(m, "->b%02d", - le16_to_cpu(pcysta->slot_step_time[store_index])); - if (a2dp->exist) { - a2dp_trx = &pcysta->a2dp_trx[store_index]; - seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", - a2dp_trx->empty_cnt, - a2dp_trx->retry_cnt, - a2dp_trx->tx_rate ? 3 : 2, - a2dp_trx->tx_cnt, - a2dp_trx->ack_cnt, - a2dp_trx->nack_cnt); - } - seq_printf(m, "->w%02d", - le16_to_cpu(pcysta->slot_step_time[store_index + 1])); - if (a2dp->exist) { - a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; - seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", - a2dp_trx->empty_cnt, - a2dp_trx->retry_cnt, - a2dp_trx->tx_rate ? 3 : 2, - a2dp_trx->tx_cnt, - a2dp_trx->ack_cnt, - a2dp_trx->nack_cnt); - } + if (cnt % divide_cnt == 1) + seq_printf(m, " %-15s : ", "[cycle_step]"); + + seq_printf(m, "->b%02d", + le16_to_cpu(pcysta->slot_step_time[store_index])); + if (a2dp->exist) { + a2dp_trx = &pcysta->a2dp_trx[store_index]; + seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", + a2dp_trx->empty_cnt, + a2dp_trx->retry_cnt, + a2dp_trx->tx_rate ? 3 : 2, + a2dp_trx->tx_cnt, + a2dp_trx->ack_cnt, + a2dp_trx->nack_cnt); } - if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 0 || cnt == c_end) + seq_printf(m, "->w%02d", + le16_to_cpu(pcysta->slot_step_time[store_index + 1])); + if (a2dp->exist) { + a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; + seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", + a2dp_trx->empty_cnt, + a2dp_trx->retry_cnt, + a2dp_trx->tx_rate ? 3 : 2, + a2dp_trx->tx_cnt, + a2dp_trx->ack_cnt, + a2dp_trx->nack_cnt); + } + if (cnt % divide_cnt == 0 || cnt == c_end) seq_puts(m, "\n"); } if (a2dp->exist) { - seq_printf(m, "%-15s : a2dp_ept:%d, a2dp_late:%d", + seq_printf(m, " %-15s : a2dp_ept:%d, a2dp_late:%d", "[a2dp_t_sta]", le16_to_cpu(pcysta->a2dp_ept.cnt), le16_to_cpu(pcysta->a2dp_ept.cnt_timeout)); @@ -6809,13 +6828,9 @@ static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m) ns = &pfwinfo->rpt_fbtc_nullsta.finfo; if (ver->fcxnullsta == 1) { - seq_printf(m, " %-15s : ", "[null_sta]"); - for (i = 0; i < 2; i++) { - if (i != 0) - seq_printf(m, ", null-%d", i); - else - seq_printf(m, "null-%d", i); + seq_printf(m, " %-15s : ", "[NULL-STA]"); + seq_printf(m, "null-%d", i); seq_printf(m, "[ok:%d/", le32_to_cpu(ns->v1.result[i][1])); seq_printf(m, "fail:%d/", @@ -6827,17 +6842,14 @@ static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m) seq_printf(m, "avg_t:%d.%03d/", le32_to_cpu(ns->v1.avg_t[i]) / 1000, le32_to_cpu(ns->v1.avg_t[i]) % 1000); - seq_printf(m, "max_t:%d.%03d]", + seq_printf(m, "max_t:%d.%03d]\n", le32_to_cpu(ns->v1.max_t[i]) / 1000, le32_to_cpu(ns->v1.max_t[i]) % 1000); } } else { - seq_printf(m, " %-15s : ", "[null_sta]"); for (i = 0; i < 2; i++) { - if (i != 0) - seq_printf(m, ", null-%d", i); - else - seq_printf(m, "null-%d", i); + seq_printf(m, " %-15s : ", "[NULL-STA]"); + seq_printf(m, "null-%d", i); seq_printf(m, "[Tx:%d/", le32_to_cpu(ns->v2.result[i][4])); seq_printf(m, "[ok:%d/", @@ -6851,12 +6863,11 @@ static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m) seq_printf(m, "avg_t:%d.%03d/", le32_to_cpu(ns->v2.avg_t[i]) / 1000, le32_to_cpu(ns->v2.avg_t[i]) % 1000); - seq_printf(m, "max_t:%d.%03d]", + seq_printf(m, "max_t:%d.%03d]\n", le32_to_cpu(ns->v2.max_t[i]) / 1000, le32_to_cpu(ns->v2.max_t[i]) % 1000); } } - seq_puts(m, "\n"); } static void _show_fbtc_step_v2(struct rtw89_dev *rtwdev, struct seq_file *m) @@ -7129,6 +7140,9 @@ static void _show_mreg(struct rtw89_dev *rtwdev, struct seq_file *m) if (cnt % 6 == 5) seq_puts(m, "\n"); cnt++; + + if (i >= pmreg->reg_num) + seq_puts(m, "\n"); } pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo; diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 4cf4a81ed4f7..3ed2f3a96635 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -1764,7 +1764,8 @@ static enum rtw89_ps_mode rtw89_update_ps_mode(struct rtw89_dev *rtwdev) RTW89_CHK_FW_FEATURE(NO_DEEP_PS, &rtwdev->fw)) return RTW89_PS_MODE_NONE; - if (chip->ps_mode_supported & BIT(RTW89_PS_MODE_PWR_GATED)) + if ((chip->ps_mode_supported & BIT(RTW89_PS_MODE_PWR_GATED)) && + !RTW89_CHK_FW_FEATURE(NO_LPS_PG, &rtwdev->fw)) return RTW89_PS_MODE_PWR_GATED; if (chip->ps_mode_supported & BIT(RTW89_PS_MODE_CLK_GATED)) @@ -2206,8 +2207,9 @@ static bool rtw89_traffic_stats_track(struct rtw89_dev *rtwdev) static void rtw89_vif_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) { - if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION && - rtwvif->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT) + if ((rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION && + rtwvif->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT) || + rtwvif->tdls_peer) return; if (rtwvif->stats.tx_tfc_lv == RTW89_TFC_IDLE && @@ -2466,9 +2468,12 @@ int rtw89_core_sta_disassoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { + struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; rtwdev->total_sta_assoc--; + if (sta->tdls) + rtwvif->tdls_peer--; rtwsta->disassoc = true; return 0; @@ -2491,8 +2496,10 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev, if (sta->tdls) rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta->bssid_cam); - if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) + if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { rtw89_vif_type_mapping(vif, false); + rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif, true); + } ret = rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, sta); if (ret) { @@ -2580,13 +2587,9 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, return ret; } - ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwsta->mac_id); - if (ret) { - rtw89_warn(rtwdev, "failed to send h2c general packet\n"); - return ret; - } - rtwdev->total_sta_assoc++; + if (sta->tdls) + rtwvif->tdls_peer++; rtw89_phy_ra_assoc(rtwdev, sta); rtw89_mac_bf_assoc(rtwdev, vif, sta); rtw89_mac_bf_monitor_calc(rtwdev, sta, false); @@ -2602,6 +2605,12 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, BTC_ROLE_MSTS_STA_CONN_END); rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta->htc_template); rtw89_phy_ul_tb_assoc(rtwdev, rtwvif); + + ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif, rtwsta->mac_id); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c general packet\n"); + return ret; + } } return ret; @@ -3126,7 +3135,6 @@ int rtw89_core_init(struct rtw89_dev *rtwdev) continue; INIT_LIST_HEAD(&rtwdev->scan_info.pkt_list[band]); } - INIT_LIST_HEAD(&rtwdev->wow.pkt_list); INIT_WORK(&rtwdev->ba_work, rtw89_core_ba_work); INIT_WORK(&rtwdev->txq_work, rtw89_core_txq_work); INIT_DELAYED_WORK(&rtwdev->txq_reinvoke_work, rtw89_core_txq_reinvoke_work); @@ -3153,7 +3161,6 @@ int rtw89_core_init(struct rtw89_dev *rtwdev) rtw89_core_ppdu_sts_init(rtwdev); rtw89_traffic_stats_init(rtwdev, &rtwdev->stats); - rtwdev->ps_mode = rtw89_update_ps_mode(rtwdev); rtwdev->hal.rx_fltr = DEFAULT_AX_RX_FLTR; INIT_WORK(&btc->eapol_notify_work, rtw89_btc_ntfy_eapol_packet_work); @@ -3309,6 +3316,8 @@ int rtw89_chip_info_setup(struct rtw89_dev *rtwdev) if (ret) return ret; + rtwdev->ps_mode = rtw89_update_ps_mode(rtwdev); + return 0; } EXPORT_SYMBOL(rtw89_chip_info_setup); diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 39c5a003e36c..41365ffb7e5e 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2452,6 +2452,7 @@ struct rtw89_vif { bool last_a_ctrl; bool dyn_tb_bedge_en; u8 def_tri_idx; + u32 tdls_peer; struct work_struct update_beacon_work; struct rtw89_addr_cam_entry addr_cam; struct rtw89_bssid_cam_entry bssid_cam; @@ -2460,6 +2461,7 @@ struct rtw89_vif { struct rtw89_phy_rate_pattern rate_pattern; struct cfg80211_scan_request *scan_req; struct ieee80211_scan_ies *scan_ies; + struct list_head general_pkt_list; }; enum rtw89_lv1_rcvy_step { @@ -2846,6 +2848,7 @@ struct rtw89_chip_info { enum rtw89_core_chip_id chip_id; const struct rtw89_chip_ops *ops; const char *fw_name; + bool try_ce_fw; u32 fifo_size; u32 dle_scc_rsvd_size; u16 max_amsdu_limit; @@ -3012,6 +3015,7 @@ static inline void rtw89_init_wait(struct rtw89_wait_info *wait) enum rtw89_fw_type { RTW89_FW_NORMAL = 1, RTW89_FW_WOWLAN = 3, + RTW89_FW_NORMAL_CE = 5, }; enum rtw89_fw_feature { @@ -3021,6 +3025,7 @@ enum rtw89_fw_feature { RTW89_FW_FEATURE_CRASH_TRIGGER, RTW89_FW_FEATURE_PACKET_DROP, RTW89_FW_FEATURE_NO_DEEP_PS, + RTW89_FW_FEATURE_NO_LPS_PG, }; struct rtw89_fw_suit { @@ -3723,7 +3728,6 @@ struct rtw89_wow_param { DECLARE_BITMAP(flags, RTW89_WOW_FLAG_NUM); struct rtw89_wow_cam_info patterns[RTW89_MAX_PATTERN_NUM]; u8 pattern_cnt; - struct list_head pkt_list; }; struct rtw89_mcc_info { diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c index 8297e35bfa52..0e0e1483c099 100644 --- a/drivers/net/wireless/realtek/rtw89/debug.c +++ b/drivers/net/wireless/realtek/rtw89/debug.c @@ -615,6 +615,7 @@ rtw89_debug_priv_mac_reg_dump_select(struct file *filp, struct seq_file *m = (struct seq_file *)filp->private_data; struct rtw89_debugfs_priv *debugfs_priv = m->private; struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; + const struct rtw89_chip_info *chip = rtwdev->chip; char buf[32]; size_t buf_size; int sel; @@ -634,6 +635,12 @@ rtw89_debug_priv_mac_reg_dump_select(struct file *filp, return -EINVAL; } + if (sel == RTW89_DBG_SEL_MAC_30 && chip->chip_id != RTL8852C) { + rtw89_info(rtwdev, "sel %d is address hole on chip %d\n", sel, + chip->chip_id); + return -EINVAL; + } + debugfs_priv->cb_data = sel; rtw89_info(rtwdev, "select mac page dump %d\n", debugfs_priv->cb_data); @@ -3347,6 +3354,31 @@ static void rtw89_dump_addr_cam(struct seq_file *m, } } +__printf(3, 4) +static void rtw89_dump_pkt_offload(struct seq_file *m, struct list_head *pkt_list, + const char *fmt, ...) +{ + struct rtw89_pktofld_info *info; + struct va_format vaf; + va_list args; + + if (list_empty(pkt_list)) + return; + + va_start(args, fmt); + vaf.va = &args; + vaf.fmt = fmt; + + seq_printf(m, "%pV", &vaf); + + va_end(args); + + list_for_each_entry(info, pkt_list, list) + seq_printf(m, "%d ", info->id); + + seq_puts(m, "\n"); +} + static void rtw89_vif_ids_get_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { @@ -3357,6 +3389,7 @@ void rtw89_vif_ids_get_iter(void *data, u8 *mac, struct ieee80211_vif *vif) seq_printf(m, "VIF [%d] %pM\n", rtwvif->mac_id, rtwvif->mac_addr); seq_printf(m, "\tbssid_cam_idx=%u\n", bssid_cam->bssid_cam_idx); rtw89_dump_addr_cam(m, &rtwvif->addr_cam); + rtw89_dump_pkt_offload(m, &rtwvif->general_pkt_list, "\tpkt_ofld[GENERAL]: "); } static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_sta *rtwsta) @@ -3395,6 +3428,7 @@ static int rtw89_debug_priv_stations_get(struct seq_file *m, void *v) struct rtw89_debugfs_priv *debugfs_priv = m->private; struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; struct rtw89_cam_info *cam_info = &rtwdev->cam_info; + u8 idx; mutex_lock(&rtwdev->mutex); @@ -3409,6 +3443,15 @@ static int rtw89_debug_priv_stations_get(struct seq_file *m, void *v) cam_info->sec_cam_map); seq_printf(m, "\tba_cam: %*ph\n", (int)sizeof(cam_info->ba_cam_map), cam_info->ba_cam_map); + seq_printf(m, "\tpkt_ofld: %*ph\n", (int)sizeof(rtwdev->pkt_offload), + rtwdev->pkt_offload); + + for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) { + if (!(rtwdev->chip->support_bands & BIT(idx))) + continue; + rtw89_dump_pkt_offload(m, &rtwdev->scan_info.pkt_list[idx], + "\t\t[SCAN %u]: ", idx); + } ieee80211_iterate_active_interfaces_atomic(rtwdev->hw, IEEE80211_IFACE_ITER_NORMAL, rtw89_vif_ids_get_iter, m); diff --git a/drivers/net/wireless/realtek/rtw89/debug.h b/drivers/net/wireless/realtek/rtw89/debug.h index d1de5e600836..079269bb5251 100644 --- a/drivers/net/wireless/realtek/rtw89/debug.h +++ b/drivers/net/wireless/realtek/rtw89/debug.h @@ -28,6 +28,7 @@ enum rtw89_debug_mask { RTW89_DBG_STATE = BIT(17), RTW89_DBG_WOW = BIT(18), RTW89_DBG_UL_TB = BIT(19), + RTW89_DBG_CHAN = BIT(20), RTW89_DBG_UNEXP = BIT(31), }; diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 85c7172e931b..0b73dc2e9ad7 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -10,6 +10,7 @@ #include "mac.h" #include "phy.h" #include "reg.h" +#include "util.h" static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb); @@ -151,7 +152,7 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, static int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, - struct rtw89_fw_suit *fw_suit) + struct rtw89_fw_suit *fw_suit, bool nowarn) { struct rtw89_fw_info *fw_info = &rtwdev->fw; const u8 *mfw = fw_info->firmware->data; @@ -182,7 +183,8 @@ int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, return 0; } - rtw89_err(rtwdev, "no suitable firmware found\n"); + if (!nowarn) + rtw89_err(rtwdev, "no suitable firmware found\n"); return -ENOENT; } @@ -210,12 +212,13 @@ static void rtw89_fw_update_ver(struct rtw89_dev *rtwdev, } static -int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type) +int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, + bool nowarn) { struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type); int ret; - ret = rtw89_mfw_recognize(rtwdev, type, fw_suit); + ret = rtw89_mfw_recognize(rtwdev, type, fw_suit, nowarn); if (ret) return ret; @@ -254,6 +257,7 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = { __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE), __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER), __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 38, 0, PACKET_DROP), + __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, NO_LPS_PG), __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 20, 0, PACKET_DROP), __CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS), __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE), @@ -341,14 +345,22 @@ out: int rtw89_fw_recognize(struct rtw89_dev *rtwdev) { + const struct rtw89_chip_info *chip = rtwdev->chip; int ret; - ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL); + if (chip->try_ce_fw) { + ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL_CE, true); + if (!ret) + goto normal_done; + } + + ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL, false); if (ret) return ret; +normal_done: /* It still works if wowlan firmware isn't existing. */ - __rtw89_fw_recognize(rtwdev, RTW89_FW_WOWLAN); + __rtw89_fw_recognize(rtwdev, RTW89_FW_WOWLAN, false); rtw89_fw_recognize_features(rtwdev); @@ -913,13 +925,12 @@ fail: return ret; } -static int rtw89_fw_h2c_add_wow_fw_ofld(struct rtw89_dev *rtwdev, +static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, enum rtw89_fw_pkt_ofld_type type, u8 *id) { struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); - struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct rtw89_pktofld_info *info; struct sk_buff *skb; int ret; @@ -948,13 +959,13 @@ static int rtw89_fw_h2c_add_wow_fw_ofld(struct rtw89_dev *rtwdev, if (!skb) goto err; - list_add_tail(&info->list, &rtw_wow->pkt_list); ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); kfree_skb(skb); if (ret) - return ret; + goto err; + list_add_tail(&info->list, &rtwvif->general_pkt_list); *id = info->id; return 0; @@ -963,13 +974,48 @@ err: return -ENOMEM; } +void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, bool notify_fw) +{ + struct list_head *pkt_list = &rtwvif->general_pkt_list; + struct rtw89_pktofld_info *info, *tmp; + + list_for_each_entry_safe(info, tmp, pkt_list, list) { + if (notify_fw) + rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); + rtw89_core_release_bit_map(rtwdev->pkt_offload, + info->id); + list_del(&info->list); + kfree(info); + } +} + +void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw) +{ + struct rtw89_vif *rtwvif; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) + rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif, notify_fw); +} + #define H2C_GENERAL_PKT_LEN 6 #define H2C_GENERAL_PKT_ID_UND 0xff -int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid) +int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, u8 macid) { + u8 pkt_id_ps_poll = H2C_GENERAL_PKT_ID_UND; + u8 pkt_id_null = H2C_GENERAL_PKT_ID_UND; + u8 pkt_id_qos_null = H2C_GENERAL_PKT_ID_UND; struct sk_buff *skb; int ret; + rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, + RTW89_PKT_OFLD_TYPE_PS_POLL, &pkt_id_ps_poll); + rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, + RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id_null); + rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, + RTW89_PKT_OFLD_TYPE_QOS_NULL, &pkt_id_qos_null); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_GENERAL_PKT_LEN); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); @@ -978,9 +1024,9 @@ int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid) skb_put(skb, H2C_GENERAL_PKT_LEN); SET_GENERAL_PKT_MACID(skb->data, macid); SET_GENERAL_PKT_PROBRSP_ID(skb->data, H2C_GENERAL_PKT_ID_UND); - SET_GENERAL_PKT_PSPOLL_ID(skb->data, H2C_GENERAL_PKT_ID_UND); - SET_GENERAL_PKT_NULL_ID(skb->data, H2C_GENERAL_PKT_ID_UND); - SET_GENERAL_PKT_QOS_NULL_ID(skb->data, H2C_GENERAL_PKT_ID_UND); + SET_GENERAL_PKT_PSPOLL_ID(skb->data, pkt_id_ps_poll); + SET_GENERAL_PKT_NULL_ID(skb->data, pkt_id_null); + SET_GENERAL_PKT_QOS_NULL_ID(skb->data, pkt_id_qos_null); SET_GENERAL_PKT_CTS2SELF_ID(skb->data, H2C_GENERAL_PKT_ID_UND); rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, @@ -2133,6 +2179,7 @@ int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id, skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD + skb_ofld->len); if (!skb) { rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n"); + rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id); return -ENOMEM; } skb_put(skb, H2C_LEN_PKT_OFLD); @@ -2151,6 +2198,7 @@ int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id, ret = rtw89_h2c_tx(rtwdev, skb, false); if (ret) { rtw89_err(rtwdev, "failed to send h2c\n"); + rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id); goto fail; } @@ -2684,13 +2732,14 @@ static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev, goto out; } - list_add_tail(&info->list, &scan_info->pkt_list[band]); ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, new); if (ret) { kfree_skb(new); + kfree(info); goto out; } + list_add_tail(&info->list, &scan_info->pkt_list[band]); kfree_skb(new); } out: @@ -3096,8 +3145,9 @@ int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, int ret; if (enable) { - ret = rtw89_fw_h2c_add_wow_fw_ofld(rtwdev, rtwvif, - RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id); + ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, + RTW89_PKT_OFLD_TYPE_NULL_DATA, + &pkt_id); if (ret) return -EPERM; } diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index 3ce59ac48f43..cae07e325326 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -3219,16 +3219,16 @@ static inline struct rtw89_fw_c2h_attr *RTW89_SKB_C2H_CB(struct sk_buff *skb) le32_get_bits(*((const __le32 *)(c2h) + 5), GENMASK(25, 24)) #define RTW89_GET_MAC_C2H_MCC_RCV_ACK_GROUP(c2h) \ - le32_get_bits(*((const __le32 *)(c2h)), GENMASK(1, 0)) + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(1, 0)) #define RTW89_GET_MAC_C2H_MCC_RCV_ACK_H2C_FUNC(c2h) \ - le32_get_bits(*((const __le32 *)(c2h)), GENMASK(15, 8)) + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(15, 8)) #define RTW89_GET_MAC_C2H_MCC_REQ_ACK_GROUP(c2h) \ - le32_get_bits(*((const __le32 *)(c2h)), GENMASK(1, 0)) + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(1, 0)) #define RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_RETURN(c2h) \ - le32_get_bits(*((const __le32 *)(c2h)), GENMASK(7, 2)) + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(7, 2)) #define RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_FUNC(c2h) \ - le32_get_bits(*((const __le32 *)(c2h)), GENMASK(15, 8)) + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(15, 8)) struct rtw89_mac_mcc_tsf_rpt { u32 macid_x; @@ -3242,30 +3242,30 @@ struct rtw89_mac_mcc_tsf_rpt { static_assert(sizeof(struct rtw89_mac_mcc_tsf_rpt) <= RTW89_COMPLETION_BUF_SIZE); #define RTW89_GET_MAC_C2H_MCC_TSF_RPT_MACID_X(c2h) \ - le32_get_bits(*((const __le32 *)(c2h)), GENMASK(7, 0)) + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(7, 0)) #define RTW89_GET_MAC_C2H_MCC_TSF_RPT_MACID_Y(c2h) \ - le32_get_bits(*((const __le32 *)(c2h)), GENMASK(15, 8)) + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(15, 8)) #define RTW89_GET_MAC_C2H_MCC_TSF_RPT_GROUP(c2h) \ - le32_get_bits(*((const __le32 *)(c2h)), GENMASK(17, 16)) + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(17, 16)) #define RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_LOW_X(c2h) \ - le32_get_bits(*((const __le32 *)(c2h) + 1), GENMASK(31, 0)) + le32_get_bits(*((const __le32 *)(c2h) + 3), GENMASK(31, 0)) #define RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_HIGH_X(c2h) \ - le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(31, 0)) + le32_get_bits(*((const __le32 *)(c2h) + 4), GENMASK(31, 0)) #define RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_LOW_Y(c2h) \ - le32_get_bits(*((const __le32 *)(c2h) + 3), GENMASK(31, 0)) + le32_get_bits(*((const __le32 *)(c2h) + 5), GENMASK(31, 0)) #define RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_HIGH_Y(c2h) \ - le32_get_bits(*((const __le32 *)(c2h) + 4), GENMASK(31, 0)) + le32_get_bits(*((const __le32 *)(c2h) + 6), GENMASK(31, 0)) #define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_STATUS(c2h) \ - le32_get_bits(*((const __le32 *)(c2h)), GENMASK(5, 0)) + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(5, 0)) #define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_GROUP(c2h) \ - le32_get_bits(*((const __le32 *)(c2h)), GENMASK(7, 6)) + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(7, 6)) #define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_MACID(c2h) \ - le32_get_bits(*((const __le32 *)(c2h)), GENMASK(15, 8)) + le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(15, 8)) #define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_LOW(c2h) \ - le32_get_bits(*((const __le32 *)(c2h) + 1), GENMASK(31, 0)) + le32_get_bits(*((const __le32 *)(c2h) + 3), GENMASK(31, 0)) #define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_HIGH(c2h) \ - le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(31, 0)) + le32_get_bits(*((const __le32 *)(c2h) + 4), GENMASK(31, 0)) #define RTW89_FW_HDR_SIZE 32 #define RTW89_FW_SECTION_HDR_SIZE 16 @@ -3518,7 +3518,11 @@ int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev, int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len); void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev); void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev); -int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid); +int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + u8 macid); +void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, bool notify_fw); +void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw); int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, bool valid, struct ieee80211_ampdu_params *params); void rtw89_fw_h2c_init_ba_cam_v1(struct rtw89_dev *rtwdev); diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 5ab0590485e0..2e2a2b6eab09 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -623,7 +623,8 @@ static void rtw89_mac_dump_err_status(struct rtw89_dev *rtwdev, if (err != MAC_AX_ERR_L1_ERR_DMAC && err != MAC_AX_ERR_L0_PROMOTE_TO_L1 && err != MAC_AX_ERR_L0_ERR_CMAC0 && - err != MAC_AX_ERR_L0_ERR_CMAC1) + err != MAC_AX_ERR_L0_ERR_CMAC1 && + err != MAC_AX_ERR_RXI300) return; rtw89_info(rtwdev, "--->\nerr=0x%x\n", err); @@ -663,6 +664,8 @@ u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev) err = MAC_AX_ERR_CPU_EXCEPTION; else if (err_scnr == RTW89_WCPU_ASSERTION) err = MAC_AX_ERR_ASSERTION; + else if (err_scnr == RTW89_RXI300_ERROR) + err = MAC_AX_ERR_RXI300; rtw89_fw_st_dbg_dump(rtwdev); rtw89_mac_dump_err_status(rtwdev, err); @@ -3411,6 +3414,11 @@ int rtw89_mac_enable_cpu(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw) val |= B_AX_WCPU_FWDL_EN; rtw89_write32(rtwdev, R_AX_WCPU_FW_CTRL, val); + + if (rtwdev->chip->chip_id == RTL8852B) + rtw89_write32_mask(rtwdev, R_AX_SEC_CTRL, + B_AX_SEC_IDMEM_SIZE_CONFIG_MASK, 0x2); + rtw89_write16_mask(rtwdev, R_AX_BOOT_REASON, B_AX_BOOT_REASON_MASK, boot_reason); rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_WCPU_EN); @@ -3918,19 +3926,14 @@ static void rtw89_mac_port_cfg_tbtt_shift(struct rtw89_dev *rtwdev, B_AX_TBTT_SHIFT_OFST_MASK, val); } -static void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, - struct rtw89_vif *rtwvif_src, u8 offset, - int *n_offset) +void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + struct rtw89_vif *rtwvif_src, + u16 offset_tu) { u32 val, reg; - if (rtwvif->net_type != RTW89_NET_TYPE_AP_MODE || rtwvif == rtwvif_src) - return; - - /* adjust offset randomly to avoid beacon conflict */ - offset = offset - offset / 4 + get_random_u32() % (offset / 2); - val = RTW89_PORT_OFFSET_MS_TO_32US((*n_offset)++, offset); + val = RTW89_PORT_OFFSET_TU_TO_32US(offset_tu); reg = rtw89_mac_reg_by_idx(R_AX_PORT0_TSF_SYNC + rtwvif->port * 4, rtwvif->mac_idx); @@ -3939,6 +3942,22 @@ static void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev, rtw89_write32_set(rtwdev, reg, B_AX_SYNC_NOW); } +static void rtw89_mac_port_tsf_sync_rand(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + struct rtw89_vif *rtwvif_src, + u8 offset, int *n_offset) +{ + if (rtwvif->net_type != RTW89_NET_TYPE_AP_MODE || rtwvif == rtwvif_src) + return; + + /* adjust offset randomly to avoid beacon conflict */ + offset = offset - offset / 4 + get_random_u32() % (offset / 2); + rtw89_mac_port_tsf_sync(rtwdev, rtwvif, rtwvif_src, + (*n_offset) * offset); + + (*n_offset)++; +} + static void rtw89_mac_port_tsf_resync_all(struct rtw89_dev *rtwdev) { struct rtw89_vif *src = NULL, *tmp; @@ -3958,7 +3977,7 @@ static void rtw89_mac_port_tsf_resync_all(struct rtw89_dev *rtwdev) offset /= (vif_aps + 1); rtw89_for_each_rtwvif(rtwdev, tmp) - rtw89_mac_port_tsf_sync(rtwdev, tmp, src, offset, &n_offset); + rtw89_mac_port_tsf_sync_rand(rtwdev, tmp, src, offset, &n_offset); } int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) @@ -4050,6 +4069,24 @@ int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) return 0; } +int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + u64 *tsf) +{ + const struct rtw89_port_reg *p = &rtw_port_base; + u32 tsf_low, tsf_high; + int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, rtwvif->mac_idx, RTW89_CMAC_SEL); + if (ret) + return ret; + + tsf_low = rtw89_read32_port(rtwdev, rtwvif, p->tsftr_l); + tsf_high = rtw89_read32_port(rtwdev, rtwvif, p->tsftr_h); + *tsf = (u64)tsf_high << 32 | tsf_low; + + return 0; +} + static void rtw89_mac_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy, struct cfg80211_bss *bss, void *data) @@ -4263,12 +4300,12 @@ rtw89_mac_c2h_mcc_rcv_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len case H2C_FUNC_MCC_SET_DURATION: break; default: - rtw89_debug(rtwdev, RTW89_DBG_FW, + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "invalid MCC C2H RCV ACK: func %d\n", func); return; } - rtw89_debug(rtwdev, RTW89_DBG_FW, + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC C2H RCV ACK: group %d, func %d\n", group, func); } @@ -4296,12 +4333,12 @@ rtw89_mac_c2h_mcc_req_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len case H2C_FUNC_DEL_MCC_GROUP: case H2C_FUNC_RESET_MCC_GROUP: default: - rtw89_debug(rtwdev, RTW89_DBG_FW, + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "invalid MCC C2H REQ ACK: func %d\n", func); return; } - rtw89_debug(rtwdev, RTW89_DBG_FW, + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC C2H REQ ACK: group %d, func %d, return code %d\n", group, func, retcode); @@ -4329,6 +4366,11 @@ rtw89_mac_c2h_mcc_tsf_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len rpt->tsf_y_low = RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_LOW_Y(c2h->data); rpt->tsf_y_high = RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_HIGH_Y(c2h->data); + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC C2H TSF RPT: macid %d> %llu, macid %d> %llu\n", + rpt->macid_x, (u64)rpt->tsf_x_high << 32 | rpt->tsf_x_low, + rpt->macid_y, (u64)rpt->tsf_y_high << 32 | rpt->tsf_y_low); + cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_REQ_TSF); rtw89_complete_cond(&rtwdev->mcc.wait, cond, &data); } @@ -4386,14 +4428,14 @@ rtw89_mac_c2h_mcc_status_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 rsp = false; break; default: - rtw89_debug(rtwdev, RTW89_DBG_FW, + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "invalid MCC C2H STS RPT: status %d\n", status); return; } - rtw89_debug(rtwdev, RTW89_DBG_FW, - "MCC C2H STS RPT: group %d, macid %d, status %d, tsf {%d, %d}\n", - group, macid, status, tsf_low, tsf_high); + rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC C2H STS RPT: group %d, macid %d, status %d, tsf %llu\n", + group, macid, status, (u64)tsf_high << 32 | tsf_low); if (!rsp) return; @@ -4512,7 +4554,7 @@ EXPORT_SYMBOL(rtw89_mac_get_txpwr_cr); int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable) { u32 reg = rtw89_mac_reg_by_idx(R_AX_PPDU_STAT, mac_idx); - int ret = 0; + int ret; ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); if (ret) @@ -4520,7 +4562,7 @@ int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable) if (!enable) { rtw89_write32_clr(rtwdev, reg, B_AX_PPDU_STAT_RPT_EN); - return ret; + return 0; } rtw89_write32(rtwdev, reg, B_AX_PPDU_STAT_RPT_EN | @@ -4530,7 +4572,7 @@ int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable) rtw89_write32_mask(rtwdev, R_AX_HW_RPT_FWD, B_AX_FWD_PPDU_STAT_MASK, RTW89_PRPT_DEST_HOST); - return ret; + return 0; } EXPORT_SYMBOL(rtw89_mac_cfg_ppdu_status); diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h index f0b684b205f1..8064d3953d7f 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -168,7 +168,7 @@ enum rtw89_mac_ax_l0_to_l1_event { MAC_AX_L0_TO_L1_EVENT_MAX = 15, }; -#define RTW89_PORT_OFFSET_MS_TO_32US(n, shift_ms) ((n) * (shift_ms) * 1000 / 32) +#define RTW89_PORT_OFFSET_TU_TO_32US(shift_tu) ((shift_tu) * 1024 / 32) enum rtw89_mac_dbg_port_sel { /* CMAC 0 related */ @@ -623,6 +623,7 @@ struct rtw89_mac_dle_dfi_qempty { }; enum rtw89_mac_error_scenario { + RTW89_RXI300_ERROR = 1, RTW89_WCPU_CPU_EXCEPTION = 2, RTW89_WCPU_ASSERTION = 3, }; @@ -769,6 +770,7 @@ enum mac_ax_err_info { MAC_AX_ERR_L2_ERR_WDT_TIMEOUT_INT = 0x2599, MAC_AX_ERR_CPU_EXCEPTION = 0x3000, MAC_AX_ERR_ASSERTION = 0x4000, + MAC_AX_ERR_RXI300 = 0x5000, MAC_AX_GET_ERR_MAX, MAC_AX_DUMP_SHAREBUFF_INDICATOR = 0x80000000, @@ -828,6 +830,15 @@ static inline u32 rtw89_mac_reg_by_port(u32 base, u8 port, u8 mac_idx) } static inline u32 +rtw89_read32_port(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, u32 base) +{ + u32 reg; + + reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx); + return rtw89_read32(rtwdev, reg); +} + +static inline u32 rtw89_read32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, u32 base, u32 mask) { @@ -906,6 +917,12 @@ int rtw89_mac_write_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 val); int rtw89_mac_read_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 *val); int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); +void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + struct rtw89_vif *rtwvif_src, + u16 offset_tu); +int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + u64 *tsf); void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif); void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c index f9b95c52916b..d43281f7335b 100644 --- a/drivers/net/wireless/realtek/rtw89/mac80211.c +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -135,6 +135,7 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw, rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0; rtwvif->hit_rule = 0; ether_addr_copy(rtwvif->mac_addr, vif->addr); + INIT_LIST_HEAD(&rtwvif->general_pkt_list); ret = rtw89_mac_add_vif(rtwdev, rtwvif); if (ret) { diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 0ea734c81b4f..ec8bb5f10482 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -3398,7 +3398,7 @@ static void rtw89_pci_clkreq_set(struct rtw89_dev *rtwdev, bool enable) if (ret) rtw89_err(rtwdev, "failed to set CLKREQ Delay\n"); - if (chip_id == RTL8852A) { + if (chip_id == RTL8852A || chip_id == RTL8852B) { if (enable) ret = rtw89_pci_config_byte_set(rtwdev, RTW89_PCIE_L1_CTRL, diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index ca2b5c17d6da..d9f61ba3d176 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -2042,6 +2042,7 @@ void rtw89_phy_set_txpwr_byrate(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, enum rtw89_phy_idx phy_idx) { + u8 max_nss_num = rtwdev->chip->rf_path_num; static const u8 rs[] = { RTW89_RS_CCK, RTW89_RS_OFDM, @@ -2064,7 +2065,7 @@ void rtw89_phy_set_txpwr_byrate(struct rtw89_dev *rtwdev, BUILD_BUG_ON(rtw89_rs_idx_max[RTW89_RS_HEDCM] % 4); addr = R_AX_PWR_BY_RATE; - for (cur.nss = 0; cur.nss <= RTW89_NSS_2; cur.nss++) { + for (cur.nss = 0; cur.nss < max_nss_num; cur.nss++) { for (i = 0; i < ARRAY_SIZE(rs); i++) { if (cur.nss >= rtw89_rs_nss_max[rs[i]]) continue; @@ -2127,6 +2128,7 @@ void rtw89_phy_set_txpwr_limit(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, enum rtw89_phy_idx phy_idx) { + u8 max_ntx_num = rtwdev->chip->rf_path_num; struct rtw89_txpwr_limit lmt; u8 ch = chan->channel; u8 bw = chan->band_width; @@ -2141,7 +2143,7 @@ void rtw89_phy_set_txpwr_limit(struct rtw89_dev *rtwdev, RTW89_TXPWR_LMT_PAGE_SIZE); addr = R_AX_PWR_LMT; - for (i = 0; i < RTW89_NTX_NUM; i++) { + for (i = 0; i < max_ntx_num; i++) { rtw89_phy_fill_txpwr_limit(rtwdev, chan, &lmt, i); ptr = (s8 *)&lmt; @@ -2162,6 +2164,7 @@ void rtw89_phy_set_txpwr_limit_ru(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, enum rtw89_phy_idx phy_idx) { + u8 max_ntx_num = rtwdev->chip->rf_path_num; struct rtw89_txpwr_limit_ru lmt_ru; u8 ch = chan->channel; u8 bw = chan->band_width; @@ -2176,7 +2179,7 @@ void rtw89_phy_set_txpwr_limit_ru(struct rtw89_dev *rtwdev, RTW89_TXPWR_LMT_RU_PAGE_SIZE); addr = R_AX_PWR_RU_LMT; - for (i = 0; i < RTW89_NTX_NUM; i++) { + for (i = 0; i < max_ntx_num; i++) { rtw89_phy_fill_txpwr_limit_ru(rtwdev, chan, &lmt_ru, i); ptr = (s8 *)&lmt_ru; diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 036953f0ec46..600257909df2 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -275,6 +275,9 @@ #define B_AX_S1_LDO2PWRCUT_F BIT(23) #define B_AX_S0_LDO_VSEL_F_MASK GENMASK(22, 21) +#define R_AX_SEC_CTRL 0x0C00 +#define B_AX_SEC_IDMEM_SIZE_CONFIG_MASK GENMASK(17, 16) + #define R_AX_FILTER_MODEL_ADDR 0x0C04 #define R_AX_HAXI_INIT_CFG1 0x1000 diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 45119c512a05..9c42b6abd223 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -2055,6 +2055,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { .chip_id = RTL8852A, .ops = &rtw8852a_chip_ops, .fw_name = "rtw89/rtw8852a_fw.bin", + .try_ce_fw = false, .fifo_size = 458752, .dle_scc_rsvd_size = 0, .max_amsdu_limit = 3500, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c index c6345228d049..ee8dba7e0074 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c @@ -1618,6 +1618,7 @@ static void rtw8852b_set_txpwr_ref(struct rtw89_dev *rtwdev, } static void rtw8852b_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, u8 tx_shape_idx, enum rtw89_phy_idx phy_idx) { @@ -1637,7 +1638,6 @@ static void rtw8852b_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev, __DECL_DFIR_PARAM(sharp_14, 0x023B13FF, 0x001C42DE, 0x00FDB0AD, 0x00F60F6E, 0x00FD8F92, 0x0602D011, 0x0001C02C, 0x00FFF00A); - const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); u8 ch = chan->channel; const u32 *param; u32 addr; @@ -1678,7 +1678,7 @@ static void rtw8852b_set_tx_shape(struct rtw89_dev *rtwdev, u8 tx_shape_ofdm = rtw89_8852b_tx_shape[band][RTW89_RS_OFDM][regd]; if (band == RTW89_BAND_2G) - rtw8852b_bb_set_tx_shape_dfir(rtwdev, tx_shape_cck, phy_idx); + rtw8852b_bb_set_tx_shape_dfir(rtwdev, chan, tx_shape_cck, phy_idx); rtw89_phy_write32_mask(rtwdev, R_DCFO_OPT, B_TXSHAPE_TRIANGULAR_CFG, tx_shape_ofdm); @@ -1720,7 +1720,7 @@ void rtw8852b_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, pw_ofst = max_t(s8, pw_ofst - 3, -16); reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_2T, mac_idx); - rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_MASK, pw_ofst); + rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_2T_MASK, pw_ofst); } static int @@ -2430,6 +2430,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = { .chip_id = RTL8852B, .ops = &rtw8852b_chip_ops, .fw_name = "rtw89/rtw8852b_fw.bin", + .try_ce_fw = true, .fifo_size = 196608, .dle_scc_rsvd_size = 98304, .max_amsdu_limit = 3500, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 00fbb6535506..d2dde21d3daf 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -1968,6 +1968,7 @@ static void rtw8852c_set_txpwr_ref(struct rtw89_dev *rtwdev, } static void rtw8852c_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, u8 tx_shape_idx, enum rtw89_phy_idx phy_idx) { @@ -1991,7 +1992,6 @@ static void rtw8852c_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev, __DECL_DFIR_ADDR(filter, 0x45BC, 0x45CC, 0x45D0, 0x45D4, 0x45D8, 0x45C0, 0x45C4, 0x45C8); - const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); u8 ch = chan->channel; const u32 *param; int i; @@ -2032,7 +2032,7 @@ static void rtw8852c_set_tx_shape(struct rtw89_dev *rtwdev, u8 tx_shape_ofdm = rtw89_8852c_tx_shape[band][RTW89_RS_OFDM][regd]; if (band == RTW89_BAND_2G) - rtw8852c_bb_set_tx_shape_dfir(rtwdev, tx_shape_cck, phy_idx); + rtw8852c_bb_set_tx_shape_dfir(rtwdev, chan, tx_shape_cck, phy_idx); rtw89_phy_tssi_ctrl_set_bandedge_cfg(rtwdev, (enum rtw89_mac_idx)phy_idx, @@ -2857,6 +2857,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .chip_id = RTL8852C, .ops = &rtw8852c_chip_ops, .fw_name = "rtw89/rtw8852c_fw.bin", + .try_ce_fw = false, .fifo_size = 458752, .dle_scc_rsvd_size = 0, .max_amsdu_limit = 8000, diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c index c1a4bc1c64d1..61db7189fdab 100644 --- a/drivers/net/wireless/realtek/rtw89/ser.c +++ b/drivers/net/wireless/realtek/rtw89/ser.c @@ -611,6 +611,7 @@ bottom: ser_reset_mac_binding(rtwdev); rtw89_core_stop(rtwdev); rtw89_entity_init(rtwdev); + rtw89_fw_release_general_pkt_list(rtwdev, false); INIT_LIST_HEAD(&rtwdev->rtwvifs_list); } diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c index b2b826b2e09a..c78ee2ab732c 100644 --- a/drivers/net/wireless/realtek/rtw89/wow.c +++ b/drivers/net/wireless/realtek/rtw89/wow.c @@ -490,21 +490,6 @@ static int rtw89_wow_check_fw_status(struct rtw89_dev *rtwdev, bool wow_enable) return ret; } -static void rtw89_wow_release_pkt_list(struct rtw89_dev *rtwdev) -{ - struct rtw89_wow_param *rtw_wow = &rtwdev->wow; - struct list_head *pkt_list = &rtw_wow->pkt_list; - struct rtw89_pktofld_info *info, *tmp; - - list_for_each_entry_safe(info, tmp, pkt_list, list) { - rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); - rtw89_core_release_bit_map(rtwdev->pkt_offload, - info->id); - list_del(&info->list); - kfree(info); - } -} - static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow) { enum rtw89_fw_type fw_type = wow ? RTW89_FW_WOWLAN : RTW89_FW_NORMAL; @@ -561,6 +546,11 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow) } if (is_conn) { + ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif, rtwsta->mac_id); + if (ret) { + rtw89_warn(rtwdev, "failed to send h2c general packet\n"); + return ret; + } rtw89_phy_ra_assoc(rtwdev, wow_sta); rtw89_phy_set_bss_color(rtwdev, wow_vif); rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, wow_vif); @@ -708,8 +698,6 @@ static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev) goto out; } - rtw89_wow_release_pkt_list(rtwdev); - ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif, false); if (ret) { rtw89_err(rtwdev, "wow: failed to disable disconnect detect\n"); @@ -722,6 +710,8 @@ static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev) goto out; } + rtw89_fw_release_general_pkt_list(rtwdev, true); + ret = rtw89_wow_check_fw_status(rtwdev, false); if (ret) { rtw89_err(rtwdev, "wow: failed to check disable fw ready\n"); @@ -744,6 +734,8 @@ static int rtw89_wow_enable(struct rtw89_dev *rtwdev) goto out; } + rtw89_fw_release_general_pkt_list(rtwdev, true); + ret = rtw89_wow_swap_fw(rtwdev, true); if (ret) { rtw89_err(rtwdev, "wow: failed to swap to wow fw\n"); |