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:
parent
5dd1f6f144
commit
9c951734c2
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
¶m[0], ¶m[1], ¶m[2], ¶m[3],
|
||||
¶m[4], ¶m[5], ¶m[6], ¶m[7]);
|
||||
if (num != 8) {
|
||||
rtw_info(rtwdev, "invalid H2C command format for debug\n");
|
||||
rtw_warn(rtwdev, "invalid H2C command format for debug\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -715,8 +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] = ");
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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__)
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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))
|
||||
|
@ -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[] = {
|
||||
{
|
||||
|
@ -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
|
@ -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,
|
||||
|
@ -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); \
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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[] = {
|
||||
{
|
||||
|
@ -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
|
@ -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,
|
||||
|
@ -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, \
|
||||
|
@ -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[] = {
|
||||
{
|
||||
|
@ -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
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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 */
|
||||
|
@ -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) \
|
||||
|
Loading…
Reference in New Issue
Block a user