rtw88: update Realtek's rtw88 driver

Update rtw88 based on wireless-testing at
4e051428044d5c47cd2c81c3b154788efe07ee11 (tag: wt-2022-06-10).

This is in preparation to apply USB changes to work on these and
LinuxKPI for them over the next weeks, as well to debug a
reported issue, and possibly extract and upstream some local fixes.

MFC after:	3 days
This commit is contained in:
Bjoern A. Zeeb 2022-06-13 13:57:42 +00:00
parent 5dd1f6f144
commit 9c951734c2
34 changed files with 741 additions and 188 deletions

View File

@ -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;
}
} 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);

View File

@ -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)

View File

@ -269,11 +269,7 @@ static int rtw_debugfs_get_rsvd_page(struct seq_file *m, void *v)
for (i = 0 ; i < buf_size ; i += 8) {
if (i % page_size == 0)
seq_printf(m, "PAGE %d\n", (i + offset) / page_size);
seq_printf(m, "%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
*(buf + i), *(buf + i + 1),
*(buf + i + 2), *(buf + i + 3),
*(buf + i + 4), *(buf + i + 5),
*(buf + i + 6), *(buf + i + 7));
seq_printf(m, "%8ph\n", buf + i);
}
vfree(buf);
@ -390,7 +386,7 @@ static ssize_t rtw_debugfs_set_h2c(struct file *filp,
&param[0], &param[1], &param[2], &param[3],
&param[4], &param[5], &param[6], &param[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 +711,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] = ");

View File

@ -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,
#if defined(__FreeBSD__)
RTW_DBG_IO_RW = 0x80000000,

View File

@ -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};
@ -570,10 +585,10 @@ void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
}
void rtw_fw_send_ra_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,
bool reset_ra_mask)
{
u8 h2c_pkt[H2C_PKT_SIZE] = {0};
bool no_update = si->updated;
bool disable_pt = true;
SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RA_INFO);
@ -584,7 +599,7 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
SET_RA_INFO_SGI_EN(h2c_pkt, si->sgi_enable);
SET_RA_INFO_BW_MODE(h2c_pkt, si->bw_mode);
SET_RA_INFO_LDPC(h2c_pkt, !!si->ldpc_en);
SET_RA_INFO_NO_UPDATE(h2c_pkt, no_update);
SET_RA_INFO_NO_UPDATE(h2c_pkt, !reset_ra_mask);
SET_RA_INFO_VHT_EN(h2c_pkt, si->vht_enable);
SET_RA_INFO_DIS_PT(h2c_pkt, disable_pt);
SET_RA_INFO_RA_MASK0(h2c_pkt, (si->ra_mask & 0xff));
@ -593,7 +608,6 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
SET_RA_INFO_RA_MASK3(h2c_pkt, (si->ra_mask & 0xff000000) >> 24);
si->init_ra_lv = 0;
si->updated = true;
rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
}
@ -635,7 +649,7 @@ void rtw_fw_beacon_filter_config(struct rtw_dev *rtwdev, bool connect,
s32 threshold = bss_conf->cqm_rssi_thold + rssi_offset;
u8 h2c_pkt[H2C_PKT_SIZE] = {0};
if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER) || !si)
if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER))
return;
if (!connect) {
@ -645,6 +659,10 @@ void rtw_fw_beacon_filter_config(struct rtw_dev *rtwdev, bool connect,
return;
}
if (!si)
return;
SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_BCN_FILTER_OFFLOAD_P0);
ether_addr_copy(&h2c_pkt[1], bss_conf->bssid);
rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
@ -1033,6 +1051,7 @@ static struct sk_buff *rtw_get_rsvd_page_skb(struct ieee80211_hw *hw,
struct rtw_vif *rtwvif;
struct sk_buff *skb_new;
struct cfg80211_ssid *ssid;
u16 tim_offset = 0;
if (rsvd_pkt->type == RSVD_DUMMY) {
skb_new = alloc_skb(1, GFP_KERNEL);
@ -1051,7 +1070,8 @@ static struct sk_buff *rtw_get_rsvd_page_skb(struct ieee80211_hw *hw,
switch (rsvd_pkt->type) {
case RSVD_BEACON:
skb_new = ieee80211_beacon_get(hw, vif);
skb_new = ieee80211_beacon_get_tim(hw, vif, &tim_offset, NULL);
rsvd_pkt->tim_offset = tim_offset;
break;
case RSVD_PS_POLL:
skb_new = ieee80211_pspoll_get(hw, vif);
@ -1582,6 +1602,16 @@ int rtw_fw_download_rsvd_page(struct rtw_dev *rtwdev)
return ret;
}
void rtw_fw_update_beacon_work(struct work_struct *work)
{
struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
update_beacon_work);
mutex_lock(&rtwdev->mutex);
rtw_fw_download_rsvd_page(rtwdev);
mutex_unlock(&rtwdev->mutex);
}
static void rtw_fw_read_fifo_page(struct rtw_dev *rtwdev, u32 offset, u32 size,
u32 *buf, u32 residue, u16 start_pg)
{
@ -1766,7 +1796,7 @@ void rtw_fw_adaptivity(struct rtw_dev *rtwdev)
SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_ADAPTIVITY);
SET_ADAPTIVITY_MODE(h2c_pkt, dm_info->edcca_mode);
SET_ADAPTIVITY_OPTION(h2c_pkt, 2);
SET_ADAPTIVITY_OPTION(h2c_pkt, 1);
SET_ADAPTIVITY_IGI(h2c_pkt, dm_info->igi_history[0]);
SET_ADAPTIVITY_L2H(h2c_pkt, dm_info->l2h_th_ini);
SET_ADAPTIVITY_DENSITY(h2c_pkt, dm_info->scan_density);
@ -1784,8 +1814,8 @@ void rtw_fw_scan_notify(struct rtw_dev *rtwdev, bool start)
rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
}
static void rtw_append_probe_req_ie(struct rtw_dev *rtwdev, struct sk_buff *skb,
struct sk_buff_head *list,
static int rtw_append_probe_req_ie(struct rtw_dev *rtwdev, struct sk_buff *skb,
struct sk_buff_head *list, u8 *bands,
struct rtw_vif *rtwvif)
{
struct ieee80211_scan_ies *ies = rtwvif->scan_ies;
@ -1797,19 +1827,24 @@ static void rtw_append_probe_req_ie(struct rtw_dev *rtwdev, struct sk_buff *skb,
if (!(BIT(idx) & chip->band))
continue;
new = skb_copy(skb, GFP_KERNEL);
if (!new)
return -ENOMEM;
skb_put_data(new, ies->ies[idx], ies->len[idx]);
skb_put_data(new, ies->common_ies, ies->common_ie_len);
skb_queue_tail(list, new);
}
(*bands)++;
}
static int _rtw_hw_scan_update_probe_req(struct rtw_dev *rtwdev, u8 num_ssids,
return 0;
}
static int _rtw_hw_scan_update_probe_req(struct rtw_dev *rtwdev, u8 num_probes,
struct sk_buff_head *probe_req_list)
{
struct rtw_chip_info *chip = rtwdev->chip;
struct sk_buff *skb, *tmp;
u8 page_offset = 1, *buf, page_size = chip->page_size;
u8 pages = page_offset + num_ssids * RTW_PROBE_PG_CNT;
u8 pages = page_offset + num_probes * RTW_PROBE_PG_CNT;
u16 pg_addr = rtwdev->fifo.rsvd_h2c_info_addr, loc;
u16 buf_offset = page_size * page_offset;
u8 tx_desc_sz = chip->tx_pkt_desc_sz;
@ -1851,6 +1886,8 @@ static int _rtw_hw_scan_update_probe_req(struct rtw_dev *rtwdev, u8 num_ssids,
rtwdev->scan_info.probe_pg_size = page_offset;
out:
kfree(buf);
skb_queue_walk_safe(probe_req_list, skb, tmp)
kfree_skb(skb);
return ret;
}
@ -1860,8 +1897,9 @@ static int rtw_hw_scan_update_probe_req(struct rtw_dev *rtwdev,
{
struct cfg80211_scan_request *req = rtwvif->scan_req;
struct sk_buff_head list;
struct sk_buff *skb;
u8 num = req->n_ssids, i;
struct sk_buff *skb, *tmp;
u8 num = req->n_ssids, i, bands = 0;
int ret;
skb_queue_head_init(&list);
for (i = 0; i < num; i++) {
@ -1869,11 +1907,25 @@ static int rtw_hw_scan_update_probe_req(struct rtw_dev *rtwdev,
req->ssids[i].ssid,
req->ssids[i].ssid_len,
req->ie_len);
rtw_append_probe_req_ie(rtwdev, skb, &list, rtwvif);
if (!skb) {
ret = -ENOMEM;
goto out;
}
ret = rtw_append_probe_req_ie(rtwdev, skb, &list, &bands,
rtwvif);
if (ret)
goto out;
kfree_skb(skb);
}
return _rtw_hw_scan_update_probe_req(rtwdev, num, &list);
return _rtw_hw_scan_update_probe_req(rtwdev, num * bands, &list);
out:
skb_queue_walk_safe(&list, skb, tmp)
kfree_skb(skb);
return ret;
}
static int rtw_add_chan_info(struct rtw_dev *rtwdev, struct rtw_chan_info *info,
@ -2017,7 +2069,10 @@ void rtw_hw_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
struct cfg80211_scan_info info = {
.aborted = aborted,
};
struct rtw_hw_scan_info *scan_info = &rtwdev->scan_info;
struct rtw_hal *hal = &rtwdev->hal;
struct rtw_vif *rtwvif;
u8 chan = scan_info->op_chan;
if (!vif)
return;
@ -2025,12 +2080,16 @@ void rtw_hw_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
rtwdev->hal.rcr |= BIT_CBSSID_BCN;
rtw_write32(rtwdev, REG_RCR, rtwdev->hal.rcr);
rtw_core_scan_complete(rtwdev, vif);
rtw_core_scan_complete(rtwdev, vif, true);
rtwvif = (struct rtw_vif *)vif->drv_priv;
if (rtwvif->net_type == RTW_NET_MGD_LINKED) {
hal->current_channel = chan;
hal->current_band_type = chan > 14 ? RTW_BAND_5G : RTW_BAND_2G;
}
ieee80211_wake_queues(rtwdev->hw);
ieee80211_scan_completed(rtwdev->hw, &info);
rtwvif = (struct rtw_vif *)vif->drv_priv;
rtwvif->scan_req = NULL;
rtwvif->scan_ies = NULL;
rtwdev->scan_info.scanning_vif = NULL;
@ -2112,7 +2171,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)
@ -2139,6 +2198,9 @@ void rtw_hw_scan_chan_switch(struct rtw_dev *rtwdev, struct sk_buff *skb)
enum rtw_scan_notify_id id;
u8 chan, status;
if (!test_bit(RTW_FLAG_SCANNING, rtwdev->flags))
return;
c2h = get_c2h_from_skb(skb);
chan = GET_CHAN_SWITCH_CENTRAL_CH(c2h->payload);
id = GET_CHAN_SWITCH_ID(c2h->payload);

View File

@ -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,
@ -171,6 +172,7 @@ struct rtw_rsvd_page {
struct sk_buff *skb;
enum rtw_rsvd_packet_type type;
u8 page;
u16 tim_offset;
bool add_txdesc;
struct cfg80211_ssid *ssid;
u16 probe_req_size;
@ -529,6 +531,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 +684,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,9 +788,12 @@ 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);
void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
bool reset_ra_mask);
void rtw_fw_media_status_report(struct rtw_dev *rtwdev, u8 mac_id, bool conn);
void rtw_fw_update_wl_phy_info(struct rtw_dev *rtwdev);
void rtw_fw_beacon_filter_config(struct rtw_dev *rtwdev, bool connect,
@ -798,6 +809,7 @@ void rtw_add_rsvd_page_pno(struct rtw_dev *rtwdev,
void rtw_add_rsvd_page_sta(struct rtw_dev *rtwdev,
struct rtw_vif *rtwvif);
int rtw_fw_download_rsvd_page(struct rtw_dev *rtwdev);
void rtw_fw_update_beacon_work(struct work_struct *work);
void rtw_send_rsvd_page_h2c(struct rtw_dev *rtwdev);
int rtw_dump_drv_rsvd_page(struct rtw_dev *rtwdev,
u32 offset, u32 size, u32 *buf);

View File

@ -75,7 +75,7 @@ static int rtw_mac_pre_system_cfg(struct rtw_dev *rtwdev)
switch (rtw_hci_type(rtwdev)) {
case RTW_HCI_TYPE_PCIE:
rtw_write32_set(rtwdev, REG_HCI_OPT_CTRL, BIT_BT_DIG_CLK_EN);
rtw_write32_set(rtwdev, REG_HCI_OPT_CTRL, BIT_USB_SUS_DIS);
break;
case RTW_HCI_TYPE_USB:
break;

View File

@ -72,6 +72,9 @@ static int rtw_ops_config(struct ieee80211_hw *hw, u32 changed)
struct rtw_dev *rtwdev = hw->priv;
int ret = 0;
/* let previous ips work finish to ensure we don't leave ips twice */
cancel_work_sync(&rtwdev->ips_work);
mutex_lock(&rtwdev->mutex);
rtw_leave_lps_deep(rtwdev);
@ -206,9 +209,9 @@ static int rtw_ops_add_interface(struct ieee80211_hw *hw,
mutex_unlock(&rtwdev->mutex);
#if defined(__linux__)
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);
#elif defined(__FreeBSD__)
rtw_info(rtwdev, "start vif %6D on port %d\n", vif->addr, ":", rtwvif->port);
rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %6D on port %d\n", vif->addr, ":", rtwvif->port);
#endif
return 0;
}
@ -221,9 +224,9 @@ static void rtw_ops_remove_interface(struct ieee80211_hw *hw,
u32 config = 0;
#if defined(__linux__)
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);
#elif defined(__FreeBSD__)
rtw_info(rtwdev, "stop vif %6D on port %d\n", vif->addr, ":", rtwvif->port);
rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %6D on port %d\n", vif->addr, ":", rtwvif->port);
#endif
mutex_lock(&rtwdev->mutex);
@ -251,10 +254,10 @@ static int rtw_ops_change_interface(struct ieee80211_hw *hw,
struct rtw_dev *rtwdev = hw->priv;
#if defined(__linux__)
rtw_info(rtwdev, "change vif %pM (%d)->(%d), p2p (%d)->(%d)\n",
rtw_dbg(rtwdev, RTW_DBG_STATE, "change vif %pM (%d)->(%d), p2p (%d)->(%d)\n",
vif->addr, vif->type, type, vif->p2p, p2p);
#elif defined(__FreeBSD__)
rtw_info(rtwdev, "change vif %6D (%d)->(%d), p2p (%d)->(%d)\n",
rtw_dbg(rtwdev, RTW_DBG_STATE, "change vif %6D (%d)->(%d), p2p (%d)->(%d)\n",
vif->addr, ":", vif->type, type, vif->p2p, p2p);
#endif
@ -412,8 +415,10 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
coex_stat->wl_beacon_interval = conf->beacon_int;
}
if (changed & BSS_CHANGED_BEACON)
if (changed & BSS_CHANGED_BEACON) {
rtw_set_dtim_period(rtwdev, conf->dtim_period);
rtw_fw_download_rsvd_page(rtwdev);
}
if (changed & BSS_CHANGED_BEACON_ENABLED) {
if (conf->enable_beacon)
@ -437,6 +442,18 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
mutex_unlock(&rtwdev->mutex);
}
static int rtw_ops_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
struct rtw_dev *rtwdev = hw->priv;
struct rtw_chip_info *chip = rtwdev->chip;
mutex_lock(&rtwdev->mutex);
chip->ops->phy_calibration(rtwdev);
mutex_unlock(&rtwdev->mutex);
return 0;
}
static int rtw_ops_conf_tx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, u16 ac,
const struct ieee80211_tx_queue_params *params)
@ -484,6 +501,16 @@ static int rtw_ops_sta_remove(struct ieee80211_hw *hw,
return 0;
}
static int rtw_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
bool set)
{
struct rtw_dev *rtwdev = hw->priv;
ieee80211_queue_work(hw, &rtwdev->update_beacon_work);
return 0;
}
static int rtw_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
struct ieee80211_vif *vif, struct ieee80211_sta *sta,
struct ieee80211_key_conf *key)
@ -627,7 +654,7 @@ static void rtw_ops_sw_scan_complete(struct ieee80211_hw *hw,
struct rtw_dev *rtwdev = hw->priv;
mutex_lock(&rtwdev->mutex);
rtw_core_scan_complete(rtwdev, vif);
rtw_core_scan_complete(rtwdev, vif, false);
mutex_unlock(&rtwdev->mutex);
}
@ -704,7 +731,7 @@ static void rtw_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta)
}
si->use_cfg_mask = true;
rtw_update_sta_info(br_data->rtwdev, si);
rtw_update_sta_info(br_data->rtwdev, si, true);
}
static void rtw_ra_mask_info_update(struct rtw_dev *rtwdev,
@ -860,6 +887,17 @@ static int rtw_ops_set_sar_specs(struct ieee80211_hw *hw,
return 0;
}
static void rtw_ops_sta_rc_update(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u32 changed)
{
struct rtw_dev *rtwdev = hw->priv;
struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
if (changed & IEEE80211_RC_BW_CHANGED)
rtw_update_sta_info(rtwdev, si, true);
}
const struct ieee80211_ops rtw_ops = {
.tx = rtw_ops_tx,
.wake_tx_queue = rtw_ops_wake_tx_queue,
@ -871,9 +909,11 @@ const struct ieee80211_ops rtw_ops = {
.change_interface = rtw_ops_change_interface,
.configure_filter = rtw_ops_configure_filter,
.bss_info_changed = rtw_ops_bss_info_changed,
.start_ap = rtw_ops_start_ap,
.conf_tx = rtw_ops_conf_tx,
.sta_add = rtw_ops_sta_add,
.sta_remove = rtw_ops_sta_remove,
.set_tim = rtw_ops_set_tim,
.set_key = rtw_ops_set_key,
.ampdu_action = rtw_ops_ampdu_action,
.can_aggregate_in_amsdu = rtw_ops_can_aggregate_in_amsdu,
@ -889,6 +929,7 @@ const struct ieee80211_ops rtw_ops = {
.reconfig_complete = rtw_reconfig_complete,
.hw_scan = rtw_ops_hw_scan,
.cancel_hw_scan = rtw_ops_cancel_hw_scan,
.sta_rc_update = rtw_ops_sta_rc_update,
.set_sar_specs = rtw_ops_set_sar_specs,
#ifdef CONFIG_PM
.suspend = rtw_ops_suspend,

View File

@ -211,6 +211,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);
@ -276,6 +279,16 @@ static void rtw_c2h_work(struct work_struct *work)
}
}
static void rtw_ips_work(struct work_struct *work)
{
struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, ips_work);
mutex_lock(&rtwdev->mutex);
if (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE)
rtw_enter_ips(rtwdev);
mutex_unlock(&rtwdev->mutex);
}
static u8 rtw_acquire_macid(struct rtw_dev *rtwdev)
{
unsigned long mac_id;
@ -304,16 +317,16 @@ int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
rtw_txq_init(rtwdev, sta->txq[i]);
rtw_update_sta_info(rtwdev, si);
rtw_update_sta_info(rtwdev, si, true);
rtw_fw_media_status_report(rtwdev, si->mac_id, true);
rtwdev->sta_cnt++;
rtwdev->beacon_loss = false;
#if defined(__linux__)
rtw_info(rtwdev, "sta %pM joined with macid %d\n",
rtw_dbg(rtwdev, RTW_DBG_STATE, "sta %pM joined with macid %d\n",
sta->addr, si->mac_id);
#elif defined(__FreeBSD__)
rtw_info(rtwdev, "sta %6D joined with macid %d\n",
rtw_dbg(rtwdev, RTW_DBG_STATE, "sta %6D joined with macid %d\n",
sta->addr, ":", si->mac_id);
#endif
@ -337,10 +350,10 @@ void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
rtwdev->sta_cnt--;
#if defined(__linux__)
rtw_info(rtwdev, "sta %pM with macid %d left\n",
rtw_dbg(rtwdev, RTW_DBG_STATE, "sta %pM with macid %d left\n",
sta->addr, si->mac_id);
#elif defined(__FreeBSD__)
rtw_info(rtwdev, "sta %6D with macid %d left\n",
rtw_dbg(rtwdev, RTW_DBG_STATE, "sta %6D with macid %d left\n",
sta->addr, ":", si->mac_id);
#endif
}
@ -665,6 +678,12 @@ void rtw_set_rx_freq_band(struct rtw_rx_pkt_stat *pkt_stat, u8 channel)
}
EXPORT_SYMBOL(rtw_set_rx_freq_band);
void rtw_set_dtim_period(struct rtw_dev *rtwdev, int dtim_period)
{
rtw_write32_set(rtwdev, REG_TCR, BIT_TCR_UPDATE_TIMIE);
rtw_write8(rtwdev, REG_DTIM_COUNTER_ROOT, dtim_period - 1);
}
void rtw_get_channel_params(struct cfg80211_chan_def *chandef,
struct rtw_channel_params *chan_params)
{
@ -1025,37 +1044,52 @@ static u8 get_rate_id(u8 wireless_set, enum rtw_bandwidth bw_mode, u8 tx_num)
#define RA_MASK_VHT_RATES (RA_MASK_VHT_RATES_1SS | \
RA_MASK_VHT_RATES_2SS | \
RA_MASK_VHT_RATES_3SS)
#define RA_MASK_CCK_IN_BG 0x00005
#define RA_MASK_CCK_IN_HT 0x00005
#define RA_MASK_CCK_IN_VHT 0x00005
#define RA_MASK_OFDM_IN_VHT 0x00010
#define RA_MASK_OFDM_IN_HT_2G 0x00010
#define RA_MASK_OFDM_IN_HT_5G 0x00030
static u64 rtw_update_rate_mask(struct rtw_dev *rtwdev,
struct rtw_sta_info *si,
u64 ra_mask, bool is_vht_enable,
u8 wireless_set)
static u64 rtw_rate_mask_rssi(struct rtw_sta_info *si, u8 wireless_set)
{
u8 rssi_level = si->rssi_level;
if (wireless_set == WIRELESS_CCK)
return 0xffffffffffffffffULL;
if (rssi_level == 0)
return 0xffffffffffffffffULL;
else if (rssi_level == 1)
return 0xfffffffffffffff0ULL;
else if (rssi_level == 2)
return 0xffffffffffffefe0ULL;
else if (rssi_level == 3)
return 0xffffffffffffcfc0ULL;
else if (rssi_level == 4)
return 0xffffffffffff8f80ULL;
else
return 0xffffffffffff0f00ULL;
}
static u64 rtw_rate_mask_recover(u64 ra_mask, u64 ra_mask_bak)
{
if ((ra_mask & ~(RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES)) == 0)
ra_mask |= (ra_mask_bak & ~(RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES));
if (ra_mask == 0)
ra_mask |= (ra_mask_bak & (RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES));
return ra_mask;
}
static u64 rtw_rate_mask_cfg(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
u64 ra_mask, bool is_vht_enable)
{
struct rtw_hal *hal = &rtwdev->hal;
const struct cfg80211_bitrate_mask *mask = si->mask;
u64 cfg_mask = GENMASK_ULL(63, 0);
u8 rssi_level, band;
if (wireless_set != WIRELESS_CCK) {
rssi_level = si->rssi_level;
if (rssi_level == 0)
ra_mask &= 0xffffffffffffffffULL;
else if (rssi_level == 1)
ra_mask &= 0xfffffffffffffff0ULL;
else if (rssi_level == 2)
ra_mask &= 0xffffffffffffefe0ULL;
else if (rssi_level == 3)
ra_mask &= 0xffffffffffffcfc0ULL;
else if (rssi_level == 4)
ra_mask &= 0xffffffffffff8f80ULL;
else if (rssi_level >= 5)
ra_mask &= 0xffffffffffff0f00ULL;
}
u8 band;
if (!si->use_cfg_mask)
return ra_mask;
@ -1091,7 +1125,8 @@ static u64 rtw_update_rate_mask(struct rtw_dev *rtwdev,
return ra_mask;
}
void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
bool reset_ra_mask)
{
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
struct ieee80211_sta *sta = si->sta;
@ -1105,6 +1140,7 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
u8 ldpc_en = 0;
u8 tx_num = 1;
u64 ra_mask = 0;
u64 ra_mask_bak = 0;
bool is_vht_enable = false;
bool is_support_sgi = false;
@ -1124,11 +1160,12 @@ 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) {
ra_mask |= (u64)sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 4;
ra_mask_bak = ra_mask;
if (sta->deflink.vht_cap.vht_supported) {
ra_mask &= RA_MASK_VHT_RATES | RA_MASK_OFDM_IN_VHT;
wireless_set = WIRELESS_OFDM | WIRELESS_VHT;
@ -1141,6 +1178,7 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
dm_info->rrsr_val_init = RRSR_INIT_5G;
} else if (hal->current_band_type == RTW_BAND_2G) {
ra_mask |= sta->deflink.supp_rates[NL80211_BAND_2GHZ];
ra_mask_bak = ra_mask;
if (sta->deflink.vht_cap.vht_supported) {
ra_mask &= RA_MASK_VHT_RATES | RA_MASK_CCK_IN_VHT |
RA_MASK_OFDM_IN_VHT;
@ -1154,11 +1192,13 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
} else if (sta->deflink.supp_rates[0] <= 0xf) {
wireless_set = WIRELESS_CCK;
} else {
ra_mask &= RA_MASK_OFDM_RATES | RA_MASK_CCK_IN_BG;
wireless_set = WIRELESS_CCK | WIRELESS_OFDM;
}
dm_info->rrsr_val_init = RRSR_INIT_2G;
} else {
rtw_err(rtwdev, "Unknown band type\n");
ra_mask_bak = ra_mask;
wireless_set = 0;
}
@ -1190,8 +1230,9 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
rate_id = get_rate_id(wireless_set, bw_mode, tx_num);
ra_mask = rtw_update_rate_mask(rtwdev, si, ra_mask, is_vht_enable,
wireless_set);
ra_mask &= rtw_rate_mask_rssi(si, wireless_set);
ra_mask = rtw_rate_mask_recover(ra_mask, ra_mask_bak);
ra_mask = rtw_rate_mask_cfg(rtwdev, si, ra_mask, is_vht_enable);
si->bw_mode = bw_mode;
si->stbc_en = stbc_en;
@ -1203,7 +1244,7 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
si->ra_mask = ra_mask;
si->rate_id = rate_id;
rtw_fw_send_ra_info(rtwdev, si);
rtw_fw_send_ra_info(rtwdev, si, reset_ra_mask);
}
static int rtw_wait_firmware_completion(struct rtw_dev *rtwdev)
@ -1334,7 +1375,7 @@ void rtw_core_scan_start(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif,
rtw_leave_lps(rtwdev);
if (hw_scan && rtwvif->net_type == RTW_NET_NO_LINK) {
if (hw_scan && (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE)) {
ret = rtw_leave_ips(rtwdev);
if (ret) {
rtw_err(rtwdev, "failed to leave idle state\n");
@ -1353,11 +1394,15 @@ void rtw_core_scan_start(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif,
set_bit(RTW_FLAG_SCANNING, rtwdev->flags);
}
void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif)
void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
bool hw_scan)
{
struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
struct rtw_vif *rtwvif = vif ? (struct rtw_vif *)vif->drv_priv : NULL;
u32 config = 0;
if (!rtwvif)
return;
clear_bit(RTW_FLAG_SCANNING, rtwdev->flags);
clear_bit(RTW_FLAG_DIG_DISABLE, rtwdev->flags);
@ -1368,6 +1413,9 @@ void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif)
rtw_vif_port_config(rtwdev, rtwvif, config);
rtw_coex_scan_notify(rtwdev, COEX_SCAN_FINISH);
if (hw_scan && (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE))
ieee80211_queue_work(rtwdev->hw, &rtwdev->ips_work);
}
int rtw_core_start(struct rtw_dev *rtwdev)
@ -1411,6 +1459,7 @@ void rtw_core_stop(struct rtw_dev *rtwdev)
mutex_unlock(&rtwdev->mutex);
cancel_work_sync(&rtwdev->c2h_work);
cancel_work_sync(&rtwdev->update_beacon_work);
cancel_delayed_work_sync(&rtwdev->watch_dog_work);
cancel_delayed_work_sync(&coex->bt_relink_work);
cancel_delayed_work_sync(&coex->bt_reenable_work);
@ -1430,6 +1479,7 @@ static void rtw_init_ht_cap(struct rtw_dev *rtwdev,
struct ieee80211_sta_ht_cap *ht_cap)
{
struct rtw_efuse *efuse = &rtwdev->efuse;
struct rtw_chip_info *chip = rtwdev->chip;
ht_cap->ht_supported = true;
ht_cap->cap = 0;
@ -1447,7 +1497,7 @@ static void rtw_init_ht_cap(struct rtw_dev *rtwdev,
IEEE80211_HT_CAP_DSSSCCK40 |
IEEE80211_HT_CAP_SGI_40;
ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
ht_cap->ampdu_density = chip->ampdu_density;
ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
if (efuse->hw_cap.nss > 1) {
ht_cap->mcs.rx_mask[0] = 0xFF;
@ -1550,6 +1600,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)
{
@ -1937,7 +2018,9 @@ int rtw_core_init(struct rtw_dev *rtwdev)
INIT_DELAYED_WORK(&coex->wl_ccklock_work, rtw_coex_wl_ccklock_work);
INIT_WORK(&rtwdev->tx_work, rtw_tx_work);
INIT_WORK(&rtwdev->c2h_work, rtw_c2h_work);
INIT_WORK(&rtwdev->ips_work, rtw_ips_work);
INIT_WORK(&rtwdev->fw_recovery_work, rtw_fw_recovery_work);
INIT_WORK(&rtwdev->update_beacon_work, rtw_fw_update_beacon_work);
INIT_WORK(&rtwdev->ba_work, rtw_txq_ba_work);
skb_queue_head_init(&rtwdev->c2h_queue);
skb_queue_head_init(&rtwdev->coex.queue);

View File

@ -25,7 +25,6 @@
#include "util.h"
#define RTW_NAPI_WEIGHT_NUM 64
#define RTW_MAX_MAC_ID_NUM 32
#define RTW_MAX_SEC_CAM_NUM 32
#define MAX_PG_CAM_BACKUP_NUM 8
@ -588,6 +587,7 @@ struct rtw_tx_pkt_info {
u32 tx_pkt_size;
u8 offset;
u8 pkt_offset;
u8 tim_offset;
u8 mac_id;
u8 rate_id;
u8 rate;
@ -761,7 +761,6 @@ struct rtw_sta_info {
u8 ldpc_en:2;
bool sgi_enable;
bool vht_enable;
bool updated;
u8 init_ra_lv;
u64 ra_mask;
@ -882,6 +881,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);
@ -1185,6 +1186,7 @@ struct rtw_chip_info {
bool rx_ldpc;
bool tx_stbc;
u8 max_power_index;
u8 ampdu_density;
u16 fw_fifo_addr[RTW_FW_FIFO_MAX];
const struct rtw_fwcd_segs *fwcd_segs;
@ -1239,15 +1241,13 @@ struct rtw_chip_info {
const struct wiphy_wowlan_support *wowlan_stub;
const u8 max_sched_scan_ssids;
/* for 8821c set channel */
u32 ch_param[3];
/* coex paras */
u32 coex_para_ver;
u8 bt_desired_ver;
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;
@ -1360,6 +1360,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;
@ -1390,6 +1426,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;
@ -1410,6 +1448,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;
@ -1467,6 +1506,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 {
@ -1875,6 +1917,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;
@ -1899,6 +1942,9 @@ struct rtw_hal {
enum rtw_sar_bands sar_band;
struct rtw_sar sar;
/* for 8821c set channel */
u32 ch_param[3];
};
struct rtw_path_div {
@ -1968,7 +2014,9 @@ struct rtw_dev {
/* c2h cmd queue & handler work */
struct sk_buff_head c2h_queue;
struct work_struct c2h_work;
struct work_struct ips_work;
struct work_struct fw_recovery_work;
struct work_struct update_beacon_work;
/* used to protect txqs list */
spinlock_t txq_lock;
@ -2093,6 +2141,7 @@ static inline int rtw_chip_dump_fw_crash(struct rtw_dev *rtwdev)
}
void rtw_set_rx_freq_band(struct rtw_rx_pkt_stat *pkt_stat, u8 channel);
void rtw_set_dtim_period(struct rtw_dev *rtwdev, int dtim_period);
void rtw_get_channel_params(struct cfg80211_chan_def *chandef,
struct rtw_channel_params *ch_param);
bool check_hw_ready(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 target);
@ -2106,10 +2155,12 @@ void rtw_chip_prepare_tx(struct rtw_dev *rtwdev);
void rtw_vif_port_config(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif,
u32 config);
void rtw_tx_report_purge_timer(struct timer_list *t);
void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si);
void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
bool reset_ra_mask);
void rtw_core_scan_start(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif,
const u8 *mac_addr, bool hw_scan);
void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif);
void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
bool hw_scan);
int rtw_core_start(struct rtw_dev *rtwdev);
void rtw_core_stop(struct rtw_dev *rtwdev);
int rtw_chip_info_setup(struct rtw_dev *rtwdev);
@ -2129,7 +2180,7 @@ 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);
#if defined(__linux__)
#define rtw88_static_assert(_x) static_assert(_x)
#elif defined(__FreeBSD__)

View File

@ -745,6 +745,9 @@ static u8 rtw_hw_queue_mapping(struct sk_buff *skb)
queue = RTW_TX_QUEUE_BCN;
else if (unlikely(ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)))
queue = RTW_TX_QUEUE_MGMT;
else if (is_broadcast_ether_addr(hdr->addr1) ||
is_multicast_ether_addr(hdr->addr1))
queue = RTW_TX_QUEUE_HI0;
else if (WARN_ON_ONCE(q_mapping >= ARRAY_SIZE(ac_to_hwq)))
queue = ac_to_hwq[IEEE80211_AC_BE];
else
@ -1563,12 +1566,15 @@ static void rtw_pci_interface_cfg(struct rtw_dev *rtwdev)
static void rtw_pci_phy_cfg(struct rtw_dev *rtwdev)
{
struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv;
struct rtw_chip_info *chip = rtwdev->chip;
struct pci_dev *pdev = rtwpci->pdev;
const struct rtw_intf_phy_para *para;
u16 cut;
u16 value;
u16 offset;
int i;
int ret;
cut = BIT(0) << rtwdev->hal.cut_version;
@ -1601,6 +1607,15 @@ static void rtw_pci_phy_cfg(struct rtw_dev *rtwdev)
}
rtw_pci_link_cfg(rtwdev);
/* Disable 8821ce completion timeout by default */
if (chip->id == RTW_CHIP_TYPE_8821C) {
ret = pcie_capability_set_word(pdev, PCI_EXP_DEVCTL2,
PCI_EXP_DEVCTL2_COMP_TMOUT_DIS);
if (ret)
rtw_err(rtwdev, "failed to set PCI cap, ret = %d\n",
ret);
}
}
static int __maybe_unused rtw_pci_suspend(struct device *dev)
@ -1787,7 +1802,7 @@ static void rtw_pci_napi_init(struct rtw_dev *rtwdev)
init_dummy_netdev(&rtwpci->netdev);
netif_napi_add(&rtwpci->netdev, &rtwpci->napi, rtw_pci_napi_poll,
RTW_NAPI_WEIGHT_NUM);
NAPI_POLL_WEIGHT);
}
static void rtw_pci_napi_deinit(struct rtw_dev *rtwdev)
@ -1854,7 +1869,7 @@ int rtw_pci_probe(struct pci_dev *pdev,
}
/* Disable PCIe ASPM L1 while doing NAPI poll for 8821CE */
if (pdev->device == 0xc821 && bridge->vendor == PCI_VENDOR_ID_INTEL)
if (rtwdev->chip->id == RTW_CHIP_TYPE_8821C && bridge->vendor == PCI_VENDOR_ID_INTEL)
rtwpci->rx_no_aspm = true;
rtw_pci_phy_cfg(rtwdev);

View File

@ -536,7 +536,7 @@ static void rtw_phy_ra_info_update_iter(void *data, struct ieee80211_sta *sta)
struct rtw_dev *rtwdev = data;
struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
rtw_update_sta_info(rtwdev, si);
rtw_update_sta_info(rtwdev, si, false);
}
static void rtw_phy_ra_info_update(struct rtw_dev *rtwdev)

View File

@ -389,12 +389,14 @@
#define BIT_EN_FREE_CNT BIT(3)
#define BIT_DIS_SECOND_CCA (BIT(0) | BIT(1))
#define REG_HIQ_NO_LMT_EN 0x5A7
#define REG_DTIM_COUNTER_ROOT 0x5A8
#define BIT_HIQ_NO_LMT_EN_ROOT BIT(0)
#define REG_TIMER0_SRC_SEL 0x05B4
#define BIT_TSFT_SEL_TIMER0 (BIT(4) | BIT(5) | BIT(6))
#define REG_TCR 0x0604
#define BIT_PWRMGT_HWDATA_EN BIT(7)
#define BIT_TCR_UPDATE_TIMIE BIT(5)
#define REG_RCR 0x0608
#define BIT_APP_FCS BIT(31)
#define BIT_APP_MIC BIT(30)

View File

@ -2701,7 +2701,7 @@ static const struct rtw_reg_domain coex_info_hw_regs_8723d[] = {
{0x953, BIT(1), RTW_REG_DOMAIN_MAC8},
};
struct rtw_chip_info rtw8723d_hw_spec = {
const struct rtw_chip_info rtw8723d_hw_spec = {
.ops = &rtw8723d_ops,
.id = RTW_CHIP_TYPE_8723D,
.fw_name = "rtw88/rtw8723d_fw.bin",
@ -2747,12 +2747,14 @@ struct rtw_chip_info rtw8723d_hw_spec = {
.rx_ldpc = false,
.pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl,
.iqk_threshold = 8,
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
.coex_para_ver = 0x2007022f,
.bt_desired_ver = 0x2f,
.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,

View File

@ -72,6 +72,8 @@ struct rtw8723d_efuse {
struct rtw8723de_efuse e;
};
extern const struct rtw_chip_info rtw8723d_hw_spec;
/* phy status page0 */
#define GET_PHY_STAT_P0_PWDB(phy_stat) \
le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(15, 8))

View File

@ -5,7 +5,7 @@
#include <linux/module.h>
#include <linux/pci.h>
#include "pci.h"
#include "rtw8723de.h"
#include "rtw8723d.h"
static const struct pci_device_id rtw_8723de_id_table[] = {
{

View File

@ -1,10 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2018-2019 Realtek Corporation
*/
#ifndef __RTW_8723DE_H_
#define __RTW_8723DE_H_
extern struct rtw_chip_info rtw8723d_hw_spec;
#endif

View File

@ -125,6 +125,7 @@ static void rtw8821c_phy_bf_init(struct rtw_dev *rtwdev)
static void rtw8821c_phy_set_param(struct rtw_dev *rtwdev)
{
struct rtw_hal *hal = &rtwdev->hal;
u8 crystal_cap, val;
/* power on BB/RF domain */
@ -159,9 +160,9 @@ static void rtw8821c_phy_set_param(struct rtw_dev *rtwdev)
/* post init after header files config */
rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST);
rtwdev->chip->ch_param[0] = rtw_read32_mask(rtwdev, REG_TXSF2, MASKDWORD);
rtwdev->chip->ch_param[1] = rtw_read32_mask(rtwdev, REG_TXSF6, MASKDWORD);
rtwdev->chip->ch_param[2] = rtw_read32_mask(rtwdev, REG_TXFILTER, MASKDWORD);
hal->ch_param[0] = rtw_read32_mask(rtwdev, REG_TXSF2, MASKDWORD);
hal->ch_param[1] = rtw_read32_mask(rtwdev, REG_TXSF6, MASKDWORD);
hal->ch_param[2] = rtw_read32_mask(rtwdev, REG_TXFILTER, MASKDWORD);
rtw_phy_init(rtwdev);
rtwdev->dm_info.cck_pd_default = rtw_read8(rtwdev, REG_CSRATIO) & 0x1f;
@ -351,6 +352,7 @@ static void rtw8821c_set_channel_rxdfir(struct rtw_dev *rtwdev, u8 bw)
static void rtw8821c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw,
u8 primary_ch_idx)
{
struct rtw_hal *hal = &rtwdev->hal;
u32 val32;
if (channel <= 14) {
@ -367,11 +369,11 @@ static void rtw8821c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw,
rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD, 0x00003667);
} else {
rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD,
rtwdev->chip->ch_param[0]);
hal->ch_param[0]);
rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD,
rtwdev->chip->ch_param[1] & MASKLWORD);
hal->ch_param[1] & MASKLWORD);
rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD,
rtwdev->chip->ch_param[2]);
hal->ch_param[2]);
}
} else if (channel > 35) {
rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x1);
@ -499,7 +501,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;
}
@ -512,6 +514,7 @@ static s8 get_cck_rx_pwr(struct rtw_dev *rtwdev, u8 lna_idx, u8 vga_idx)
static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status,
struct rtw_rx_pkt_stat *pkt_stat)
{
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
s8 rx_power;
u8 lna_idx = 0;
u8 vga_idx = 0;
@ -523,6 +526,7 @@ static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status,
pkt_stat->rx_power[RF_PATH_A] = rx_power;
pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
dm_info->rssi[RF_PATH_A] = pkt_stat->rssi;
pkt_stat->bw = RTW_CHANNEL_WIDTH_20;
pkt_stat->signal_power = rx_power;
}
@ -530,6 +534,7 @@ static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status,
static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status,
struct rtw_rx_pkt_stat *pkt_stat)
{
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
u8 rxsc, bw;
s8 min_rx_power = -120;
@ -549,6 +554,7 @@ static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status,
pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110;
pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
dm_info->rssi[RF_PATH_A] = pkt_stat->rssi;
pkt_stat->bw = bw;
pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A],
min_rx_power);
@ -1514,6 +1520,7 @@ static const struct rtw_rfe_def rtw8821c_rfe_defs[] = {
[0] = RTW_DEF_RFE(8821c, 0, 0),
[2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2),
[4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2),
[6] = RTW_DEF_RFE(8821c, 0, 0),
};
static struct rtw_hw_reg rtw8821c_dig[] = {
@ -1876,7 +1883,7 @@ static const struct rtw_reg_domain coex_info_hw_regs_8821c[] = {
{0x60A, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
};
struct rtw_chip_info rtw8821c_hw_spec = {
const struct rtw_chip_info rtw8821c_hw_spec = {
.ops = &rtw8821c_ops,
.id = RTW_CHIP_TYPE_8821C,
.fw_name = "rtw88/rtw8821c_fw.bin",
@ -1922,12 +1929,14 @@ struct rtw_chip_info rtw8821c_hw_spec = {
.iqk_threshold = 8,
.bfer_su_max_num = 2,
.bfer_mu_max_num = 1,
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_2,
.coex_para_ver = 0x19092746,
.bt_desired_ver = 0x46,
.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,

View File

@ -84,6 +84,8 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
rtw_write32_mask(rtwdev, addr + 0x200, mask, data);
}
extern const struct rtw_chip_info rtw8821c_hw_spec;
#define rtw_write32s_mask(rtwdev, addr, mask, data) \
do { \
BUILD_BUG_ON((addr) < 0xC00 || (addr) >= 0xD00); \

View File

@ -13,7 +13,7 @@ static const u32 rtw8821c_mac[] = {
0x04F, 0x00000001,
0x029, 0x000000F9,
0x420, 0x00000080,
0x421, 0x0000000F,
0x421, 0x0000001F,
0x428, 0x0000000A,
0x429, 0x00000010,
0x430, 0x00000000,

View File

@ -5,9 +5,13 @@
#include <linux/module.h>
#include <linux/pci.h>
#include "pci.h"
#include "rtw8821ce.h"
#include "rtw8821c.h"
static const struct pci_device_id rtw_8821ce_id_table[] = {
{
PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xB821),
.driver_data = (kernel_ulong_t)&rtw8821c_hw_spec
},
{
PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xC821),
.driver_data = (kernel_ulong_t)&rtw8821c_hw_spec

View File

@ -1,10 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2018-2019 Realtek Corporation
*/
#ifndef __RTW_8821CE_H_
#define __RTW_8821CE_H_
extern struct rtw_chip_info rtw8821c_hw_spec;
#endif

View File

@ -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;
}
@ -2501,7 +2501,7 @@ static struct rtw_hw_reg_offset rtw8822b_edcca_th[] = {
[EDCCA_TH_H2L_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE1}, .offset = 0},
};
struct rtw_chip_info rtw8822b_hw_spec = {
const struct rtw_chip_info rtw8822b_hw_spec = {
.ops = &rtw8822b_ops,
.id = RTW_CHIP_TYPE_8822B,
.fw_name = "rtw88/rtw8822b_fw.bin",
@ -2552,12 +2552,14 @@ struct rtw_chip_info rtw8822b_hw_spec = {
.edcca_th = rtw8822b_edcca_th,
.l2h_th_ini_cs = 10 + EDCCA_IGI_BASE,
.l2h_th_ini_ad = -14 + EDCCA_IGI_BASE,
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_2,
.coex_para_ver = 0x20070206,
.bt_desired_ver = 0x6,
.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,

View File

@ -187,4 +187,6 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
#define REG_ANTWT 0x1904
#define REG_IQKFAILMSK 0x1bf0
extern const struct rtw_chip_info rtw8822b_hw_spec;
#endif

View File

@ -5,7 +5,7 @@
#include <linux/module.h>
#include <linux/pci.h>
#include "pci.h"
#include "rtw8822be.h"
#include "rtw8822b.h"
static const struct pci_device_id rtw_8822be_id_table[] = {
{

View File

@ -1,10 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2018-2019 Realtek Corporation
*/
#ifndef __RTW_8822BE_H_
#define __RTW_8822BE_H_
extern struct rtw_chip_info rtw8822b_hw_spec;
#endif

View File

@ -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 */
};
#if defined(__linux__)
@ -5294,7 +5314,7 @@ static const struct rtw_reg_domain coex_info_hw_regs_8822c[] = {
{0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
};
struct rtw_chip_info rtw8822c_hw_spec = {
const struct rtw_chip_info rtw8822c_hw_spec = {
.ops = &rtw8822c_ops,
.id = RTW_CHIP_TYPE_8822C,
.fw_name = "rtw88/rtw8822c_fw.bin",
@ -5352,17 +5372,19 @@ struct rtw_chip_info rtw8822c_hw_spec = {
.edcca_th = rtw8822c_edcca_th,
.l2h_th_ini_cs = 60,
.l2h_th_ini_ad = 45,
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_2,
#ifdef CONFIG_PM
.wow_fw_name = "rtw88/rtw8822c_wow_fw.bin",
.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,

View File

@ -118,6 +118,8 @@ enum rtw8822c_dpk_one_shot_action {
void rtw8822c_parse_tbl_dpk(struct rtw_dev *rtwdev,
const struct rtw_table *tbl);
extern const struct rtw_chip_info rtw8822c_hw_spec;
#define RTW_DECL_TABLE_DPK(name) \
const struct rtw_table name ## _tbl = { \
.data = name, \

View File

@ -5,7 +5,7 @@
#include <linux/module.h>
#include <linux/pci.h>
#include "pci.h"
#include "rtw8822ce.h"
#include "rtw8822c.h"
static const struct pci_device_id rtw_8822ce_id_table[] = {
{

View File

@ -1,10 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2018-2019 Realtek Corporation
*/
#ifndef __RTW_8822CE_H_
#define __RTW_8822CE_H_
extern struct rtw_chip_info rtw8822c_hw_spec;
#endif

View File

@ -158,7 +158,8 @@ void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
memset(rx_status, 0, sizeof(*rx_status));
rx_status->freq = hw->conf.chandef.chan->center_freq;
rx_status->band = hw->conf.chandef.chan->band;
if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD))
if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD) &&
test_bit(RTW_FLAG_SCANNING, rtwdev->flags))
rtw_set_rx_freq_by_pktstat(pkt_stat, rx_status);
if (pkt_stat->crc_err)
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;

View File

@ -91,7 +91,7 @@ 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_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));

View File

@ -67,6 +67,10 @@ void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
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);
}
}
EXPORT_SYMBOL(rtw_tx_fill_tx_desc);
@ -373,7 +377,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:
@ -468,6 +472,19 @@ void rtw_tx_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev,
if (type == RSVD_QOS_NULL)
pkt_info->bt_null = true;
if (type == RSVD_BEACON) {
struct rtw_rsvd_page *rsvd_pkt;
int hdr_len;
rsvd_pkt = list_first_entry_or_null(&rtwdev->rsvd_page_list,
struct rtw_rsvd_page,
build_list);
if (rsvd_pkt && rsvd_pkt->tim_offset != 0) {
hdr_len = sizeof(struct ieee80211_hdr_3addr);
pkt_info->tim_offset = rsvd_pkt->tim_offset - hdr_len;
}
}
rtw_tx_pkt_info_update_sec(rtwdev, pkt_info, skb);
/* TODO: need to change hw port and hw ssn sel for multiple vifs */

View File

@ -33,6 +33,10 @@
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) \