mirror of
https://github.com/opnsense/src.git
synced 2026-02-04 03:00:53 -06:00
rtw88: merge Realtek's rtw88 driver based on Linux v6.14
This version is based on git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 38fec10eb60d687e30c8c6b5420d86e8149f7557 ( tag: v6.14 ). Sponsored by: The FreeBSD Foundation (cherry picked from commit a0ccc12f6882a886d89ae279c541b2c2b62c6aca)
This commit is contained in:
parent
664a23a948
commit
53e30a7797
@ -20,6 +20,8 @@ rtw88_core-y += main.o \
|
||||
|
||||
rtw88_core-$(CONFIG_PM) += wow.o
|
||||
|
||||
rtw88_core-$(CONFIG_RTW88_LEDS) += led.o
|
||||
|
||||
obj-$(CONFIG_RTW88_8822B) += rtw88_8822b.o
|
||||
rtw88_8822b-objs := rtw8822b.o rtw8822b_table.o
|
||||
|
||||
@ -77,6 +79,21 @@ rtw88_8821cs-objs := rtw8821cs.o
|
||||
obj-$(CONFIG_RTW88_8821CU) += rtw88_8821cu.o
|
||||
rtw88_8821cu-objs := rtw8821cu.o
|
||||
|
||||
obj-$(CONFIG_RTW88_88XXA) += rtw88_88xxa.o
|
||||
rtw88_88xxa-objs := rtw88xxa.o
|
||||
|
||||
obj-$(CONFIG_RTW88_8821A) += rtw88_8821a.o
|
||||
rtw88_8821a-objs := rtw8821a.o rtw8821a_table.o
|
||||
|
||||
obj-$(CONFIG_RTW88_8812A) += rtw88_8812a.o
|
||||
rtw88_8812a-objs := rtw8812a.o rtw8812a_table.o
|
||||
|
||||
obj-$(CONFIG_RTW88_8821AU) += rtw88_8821au.o
|
||||
rtw88_8821au-objs := rtw8821au.o
|
||||
|
||||
obj-$(CONFIG_RTW88_8812AU) += rtw88_8812au.o
|
||||
rtw88_8812au-objs := rtw8812au.o
|
||||
|
||||
obj-$(CONFIG_RTW88_PCI) += rtw88_pci.o
|
||||
rtw88_pci-objs := pci.o
|
||||
|
||||
|
||||
@ -446,7 +446,7 @@ static void rtw_coex_check_rfk(struct rtw_dev *rtwdev)
|
||||
}
|
||||
}
|
||||
|
||||
static void rtw_coex_query_bt_info(struct rtw_dev *rtwdev)
|
||||
void rtw_coex_query_bt_info(struct rtw_dev *rtwdev)
|
||||
{
|
||||
struct rtw_coex *coex = &rtwdev->coex;
|
||||
struct rtw_coex_stat *coex_stat = &coex->stat;
|
||||
@ -494,11 +494,29 @@ static void rtw_coex_monitor_bt_enable(struct rtw_dev *rtwdev)
|
||||
struct rtw_coex_stat *coex_stat = &coex->stat;
|
||||
struct rtw_coex_dm *coex_dm = &coex->dm;
|
||||
bool bt_disabled = false;
|
||||
bool bt_active = true;
|
||||
u16 score_board;
|
||||
|
||||
if (chip->scbd_support) {
|
||||
score_board = rtw_coex_read_scbd(rtwdev);
|
||||
bt_disabled = !(score_board & COEX_SCBD_ONOFF);
|
||||
} else {
|
||||
if (coex_stat->hi_pri_tx == 0 && coex_stat->hi_pri_rx == 0 &&
|
||||
coex_stat->lo_pri_tx == 0 && coex_stat->lo_pri_rx == 0)
|
||||
bt_active = false;
|
||||
|
||||
if (coex_stat->hi_pri_tx == 0xffff && coex_stat->hi_pri_rx == 0xffff &&
|
||||
coex_stat->lo_pri_tx == 0xffff && coex_stat->lo_pri_rx == 0xffff)
|
||||
bt_active = false;
|
||||
|
||||
if (bt_active) {
|
||||
coex_stat->bt_disable_cnt = 0;
|
||||
bt_disabled = false;
|
||||
} else {
|
||||
coex_stat->bt_disable_cnt++;
|
||||
if (coex_stat->bt_disable_cnt >= 10)
|
||||
bt_disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (coex_stat->bt_disabled != bt_disabled) {
|
||||
@ -950,12 +968,18 @@ static void rtw_coex_coex_ctrl_owner(struct rtw_dev *rtwdev, bool wifi_control)
|
||||
|
||||
static void rtw_coex_set_gnt_bt(struct rtw_dev *rtwdev, u8 state)
|
||||
{
|
||||
if (!rtwdev->chip->ltecoex_addr)
|
||||
return;
|
||||
|
||||
rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0xc000, state);
|
||||
rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x0c00, state);
|
||||
}
|
||||
|
||||
static void rtw_coex_set_gnt_wl(struct rtw_dev *rtwdev, u8 state)
|
||||
{
|
||||
if (!rtwdev->chip->ltecoex_addr)
|
||||
return;
|
||||
|
||||
rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x3000, state);
|
||||
rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x0300, state);
|
||||
}
|
||||
@ -2194,7 +2218,6 @@ static void rtw_coex_action_bt_a2dp_pan(struct rtw_dev *rtwdev)
|
||||
struct rtw_coex_stat *coex_stat = &coex->stat;
|
||||
struct rtw_efuse *efuse = &rtwdev->efuse;
|
||||
u8 table_case, tdma_case;
|
||||
bool wl_cpt_test = false, bt_cpt_test = false;
|
||||
|
||||
rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
|
||||
|
||||
@ -2202,29 +2225,16 @@ static void rtw_coex_action_bt_a2dp_pan(struct rtw_dev *rtwdev)
|
||||
rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
|
||||
if (efuse->share_ant) {
|
||||
/* Shared-Ant */
|
||||
if (wl_cpt_test) {
|
||||
if (coex_stat->wl_gl_busy) {
|
||||
table_case = 20;
|
||||
tdma_case = 17;
|
||||
} else {
|
||||
table_case = 10;
|
||||
tdma_case = 15;
|
||||
}
|
||||
} else if (bt_cpt_test) {
|
||||
table_case = 26;
|
||||
tdma_case = 26;
|
||||
} else {
|
||||
if (coex_stat->wl_gl_busy &&
|
||||
coex_stat->wl_noisy_level == 0)
|
||||
table_case = 14;
|
||||
else
|
||||
table_case = 10;
|
||||
if (coex_stat->wl_gl_busy &&
|
||||
coex_stat->wl_noisy_level == 0)
|
||||
table_case = 14;
|
||||
else
|
||||
table_case = 10;
|
||||
|
||||
if (coex_stat->wl_gl_busy)
|
||||
tdma_case = 15;
|
||||
else
|
||||
tdma_case = 20;
|
||||
}
|
||||
if (coex_stat->wl_gl_busy)
|
||||
tdma_case = 15;
|
||||
else
|
||||
tdma_case = 20;
|
||||
} else {
|
||||
/* Non-Shared-Ant */
|
||||
table_case = 112;
|
||||
@ -2235,11 +2245,7 @@ static void rtw_coex_action_bt_a2dp_pan(struct rtw_dev *rtwdev)
|
||||
tdma_case = 120;
|
||||
}
|
||||
|
||||
if (wl_cpt_test)
|
||||
rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[1]);
|
||||
else
|
||||
rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
|
||||
|
||||
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);
|
||||
}
|
||||
@ -2765,16 +2771,19 @@ void rtw_coex_power_on_setting(struct rtw_dev *rtwdev)
|
||||
rtw_write8(rtwdev, 0xff1a, 0x0);
|
||||
rtw_coex_set_gnt_debug(rtwdev);
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_coex_power_on_setting);
|
||||
|
||||
void rtw_coex_power_off_setting(struct rtw_dev *rtwdev)
|
||||
{
|
||||
rtw_write16(rtwdev, REG_WIFI_BT_INFO, BIT_BT_INT_EN);
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_coex_power_off_setting);
|
||||
|
||||
void rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only)
|
||||
{
|
||||
__rtw_coex_init_hw_config(rtwdev, wifi_only);
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_coex_init_hw_config);
|
||||
|
||||
void rtw_coex_ips_notify(struct rtw_dev *rtwdev, u8 type)
|
||||
{
|
||||
@ -3922,7 +3931,7 @@ void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m)
|
||||
u8 sys_lte;
|
||||
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 lte_coex = 0, bt_coex = 0;
|
||||
int i;
|
||||
|
||||
score_board_BW = rtw_coex_read_scbd(rtwdev);
|
||||
@ -3934,8 +3943,10 @@ void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m)
|
||||
wl_reg_778 = rtw_read8(rtwdev, REG_BT_STAT_CTRL);
|
||||
|
||||
sys_lte = rtw_read8(rtwdev, 0x73);
|
||||
lte_coex = rtw_coex_read_indirect_reg(rtwdev, 0x38);
|
||||
bt_coex = rtw_coex_read_indirect_reg(rtwdev, 0x54);
|
||||
if (rtwdev->chip->ltecoex_addr) {
|
||||
lte_coex = rtw_coex_read_indirect_reg(rtwdev, 0x38);
|
||||
bt_coex = rtw_coex_read_indirect_reg(rtwdev, 0x54);
|
||||
}
|
||||
|
||||
if (!coex_stat->wl_under_ips &&
|
||||
(!coex_stat->wl_under_lps || coex_stat->wl_force_lps_ctrl) &&
|
||||
|
||||
@ -384,6 +384,7 @@ u32 rtw_coex_read_indirect_reg(struct rtw_dev *rtwdev, u16 addr);
|
||||
void rtw_coex_write_indirect_reg(struct rtw_dev *rtwdev, u16 addr,
|
||||
u32 mask, u32 val);
|
||||
void rtw_coex_write_scbd(struct rtw_dev *rtwdev, u16 bitpos, bool set);
|
||||
void rtw_coex_query_bt_info(struct rtw_dev *rtwdev);
|
||||
|
||||
void rtw_coex_bt_relink_work(struct work_struct *work);
|
||||
void rtw_coex_bt_reenable_work(struct work_struct *work);
|
||||
@ -419,4 +420,14 @@ static inline bool rtw_coex_disabled(struct rtw_dev *rtwdev)
|
||||
return coex_stat->bt_disabled;
|
||||
}
|
||||
|
||||
static inline void rtw_coex_active_query_bt_info(struct rtw_dev *rtwdev)
|
||||
{
|
||||
/* The RTL8821AU firmware doesn't send C2H_BT_INFO by itself
|
||||
* when bluetooth headphones are disconnected, so we have to
|
||||
* ask for it regularly.
|
||||
*/
|
||||
if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A && rtwdev->efuse.btcoex)
|
||||
rtw_coex_query_bt_info(rtwdev);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -43,6 +43,62 @@ struct rtw_debugfs_priv {
|
||||
};
|
||||
};
|
||||
|
||||
struct rtw_debugfs {
|
||||
struct rtw_debugfs_priv mac_0;
|
||||
struct rtw_debugfs_priv mac_1;
|
||||
struct rtw_debugfs_priv mac_2;
|
||||
struct rtw_debugfs_priv mac_3;
|
||||
struct rtw_debugfs_priv mac_4;
|
||||
struct rtw_debugfs_priv mac_5;
|
||||
struct rtw_debugfs_priv mac_6;
|
||||
struct rtw_debugfs_priv mac_7;
|
||||
struct rtw_debugfs_priv mac_10;
|
||||
struct rtw_debugfs_priv mac_11;
|
||||
struct rtw_debugfs_priv mac_12;
|
||||
struct rtw_debugfs_priv mac_13;
|
||||
struct rtw_debugfs_priv mac_14;
|
||||
struct rtw_debugfs_priv mac_15;
|
||||
struct rtw_debugfs_priv mac_16;
|
||||
struct rtw_debugfs_priv mac_17;
|
||||
struct rtw_debugfs_priv bb_8;
|
||||
struct rtw_debugfs_priv bb_9;
|
||||
struct rtw_debugfs_priv bb_a;
|
||||
struct rtw_debugfs_priv bb_b;
|
||||
struct rtw_debugfs_priv bb_c;
|
||||
struct rtw_debugfs_priv bb_d;
|
||||
struct rtw_debugfs_priv bb_e;
|
||||
struct rtw_debugfs_priv bb_f;
|
||||
struct rtw_debugfs_priv bb_18;
|
||||
struct rtw_debugfs_priv bb_19;
|
||||
struct rtw_debugfs_priv bb_1a;
|
||||
struct rtw_debugfs_priv bb_1b;
|
||||
struct rtw_debugfs_priv bb_1c;
|
||||
struct rtw_debugfs_priv bb_1d;
|
||||
struct rtw_debugfs_priv bb_1e;
|
||||
struct rtw_debugfs_priv bb_1f;
|
||||
struct rtw_debugfs_priv bb_2c;
|
||||
struct rtw_debugfs_priv bb_2d;
|
||||
struct rtw_debugfs_priv bb_40;
|
||||
struct rtw_debugfs_priv bb_41;
|
||||
struct rtw_debugfs_priv rf_dump;
|
||||
struct rtw_debugfs_priv tx_pwr_tbl;
|
||||
struct rtw_debugfs_priv write_reg;
|
||||
struct rtw_debugfs_priv h2c;
|
||||
struct rtw_debugfs_priv rf_write;
|
||||
struct rtw_debugfs_priv rf_read;
|
||||
struct rtw_debugfs_priv read_reg;
|
||||
struct rtw_debugfs_priv fix_rate;
|
||||
struct rtw_debugfs_priv dump_cam;
|
||||
struct rtw_debugfs_priv rsvd_page;
|
||||
struct rtw_debugfs_priv phy_info;
|
||||
struct rtw_debugfs_priv coex_enable;
|
||||
struct rtw_debugfs_priv coex_info;
|
||||
struct rtw_debugfs_priv edcca_enable;
|
||||
struct rtw_debugfs_priv fw_crash;
|
||||
struct rtw_debugfs_priv force_lowest_basic_rate;
|
||||
struct rtw_debugfs_priv dm_cap;
|
||||
};
|
||||
|
||||
static const char * const rtw_dm_cap_strs[] = {
|
||||
[RTW_DM_CAP_NA] = "NA",
|
||||
[RTW_DM_CAP_TXGAPK] = "TXGAPK",
|
||||
@ -252,7 +308,7 @@ static int rtw_debugfs_get_rsvd_page(struct seq_file *m, void *v)
|
||||
{
|
||||
struct rtw_debugfs_priv *debugfs_priv = m->private;
|
||||
struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
|
||||
u8 page_size = rtwdev->chip->page_size;
|
||||
u16 page_size = rtwdev->chip->page_size;
|
||||
u32 buf_size = debugfs_priv->rsvd_page.page_num * page_size;
|
||||
u32 offset = debugfs_priv->rsvd_page.page_offset * page_size;
|
||||
u8 *buf;
|
||||
@ -524,7 +580,7 @@ static int rtw_debug_get_bb_page(struct seq_file *m, void *v)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw_debug_get_rf_dump(struct seq_file *m, void *v)
|
||||
static int rtw_debugfs_get_rf_dump(struct seq_file *m, void *v)
|
||||
{
|
||||
struct rtw_debugfs_priv *debugfs_priv = m->private;
|
||||
struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
|
||||
@ -1074,139 +1130,102 @@ static int rtw_debugfs_get_dm_cap(struct seq_file *m, void *v)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define rtw_debug_impl_mac(page, addr) \
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = { \
|
||||
#define rtw_debug_priv_mac(addr) \
|
||||
{ \
|
||||
.cb_read = rtw_debug_get_mac_page, \
|
||||
.cb_data = addr, \
|
||||
}
|
||||
|
||||
rtw_debug_impl_mac(0, 0x0000);
|
||||
rtw_debug_impl_mac(1, 0x0100);
|
||||
rtw_debug_impl_mac(2, 0x0200);
|
||||
rtw_debug_impl_mac(3, 0x0300);
|
||||
rtw_debug_impl_mac(4, 0x0400);
|
||||
rtw_debug_impl_mac(5, 0x0500);
|
||||
rtw_debug_impl_mac(6, 0x0600);
|
||||
rtw_debug_impl_mac(7, 0x0700);
|
||||
rtw_debug_impl_mac(10, 0x1000);
|
||||
rtw_debug_impl_mac(11, 0x1100);
|
||||
rtw_debug_impl_mac(12, 0x1200);
|
||||
rtw_debug_impl_mac(13, 0x1300);
|
||||
rtw_debug_impl_mac(14, 0x1400);
|
||||
rtw_debug_impl_mac(15, 0x1500);
|
||||
rtw_debug_impl_mac(16, 0x1600);
|
||||
rtw_debug_impl_mac(17, 0x1700);
|
||||
|
||||
#define rtw_debug_impl_bb(page, addr) \
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_bb_ ##page = { \
|
||||
#define rtw_debug_priv_bb(addr) \
|
||||
{ \
|
||||
.cb_read = rtw_debug_get_bb_page, \
|
||||
.cb_data = addr, \
|
||||
}
|
||||
|
||||
rtw_debug_impl_bb(8, 0x0800);
|
||||
rtw_debug_impl_bb(9, 0x0900);
|
||||
rtw_debug_impl_bb(a, 0x0a00);
|
||||
rtw_debug_impl_bb(b, 0x0b00);
|
||||
rtw_debug_impl_bb(c, 0x0c00);
|
||||
rtw_debug_impl_bb(d, 0x0d00);
|
||||
rtw_debug_impl_bb(e, 0x0e00);
|
||||
rtw_debug_impl_bb(f, 0x0f00);
|
||||
rtw_debug_impl_bb(18, 0x1800);
|
||||
rtw_debug_impl_bb(19, 0x1900);
|
||||
rtw_debug_impl_bb(1a, 0x1a00);
|
||||
rtw_debug_impl_bb(1b, 0x1b00);
|
||||
rtw_debug_impl_bb(1c, 0x1c00);
|
||||
rtw_debug_impl_bb(1d, 0x1d00);
|
||||
rtw_debug_impl_bb(1e, 0x1e00);
|
||||
rtw_debug_impl_bb(1f, 0x1f00);
|
||||
rtw_debug_impl_bb(2c, 0x2c00);
|
||||
rtw_debug_impl_bb(2d, 0x2d00);
|
||||
rtw_debug_impl_bb(40, 0x4000);
|
||||
rtw_debug_impl_bb(41, 0x4100);
|
||||
#define rtw_debug_priv_get(name) \
|
||||
{ \
|
||||
.cb_read = rtw_debugfs_get_ ##name, \
|
||||
}
|
||||
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_rf_dump = {
|
||||
.cb_read = rtw_debug_get_rf_dump,
|
||||
};
|
||||
#define rtw_debug_priv_set(name) \
|
||||
{ \
|
||||
.cb_write = rtw_debugfs_set_ ##name, \
|
||||
}
|
||||
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_tx_pwr_tbl = {
|
||||
.cb_read = rtw_debugfs_get_tx_pwr_tbl,
|
||||
};
|
||||
#define rtw_debug_priv_set_and_get(name) \
|
||||
{ \
|
||||
.cb_write = rtw_debugfs_set_ ##name, \
|
||||
.cb_read = rtw_debugfs_get_ ##name, \
|
||||
}
|
||||
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_write_reg = {
|
||||
.cb_write = rtw_debugfs_set_write_reg,
|
||||
};
|
||||
#define rtw_debug_priv_set_single_and_get(name) \
|
||||
{ \
|
||||
.cb_write = rtw_debugfs_set_single_input, \
|
||||
.cb_read = rtw_debugfs_get_ ##name, \
|
||||
}
|
||||
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_h2c = {
|
||||
.cb_write = rtw_debugfs_set_h2c,
|
||||
};
|
||||
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_rf_write = {
|
||||
.cb_write = rtw_debugfs_set_rf_write,
|
||||
};
|
||||
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_rf_read = {
|
||||
.cb_write = rtw_debugfs_set_rf_read,
|
||||
.cb_read = rtw_debugfs_get_rf_read,
|
||||
};
|
||||
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_read_reg = {
|
||||
.cb_write = rtw_debugfs_set_read_reg,
|
||||
.cb_read = rtw_debugfs_get_read_reg,
|
||||
};
|
||||
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_fix_rate = {
|
||||
.cb_write = rtw_debugfs_set_fix_rate,
|
||||
.cb_read = rtw_debugfs_get_fix_rate,
|
||||
};
|
||||
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_dump_cam = {
|
||||
.cb_write = rtw_debugfs_set_single_input,
|
||||
.cb_read = rtw_debugfs_get_dump_cam,
|
||||
};
|
||||
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_rsvd_page = {
|
||||
.cb_write = rtw_debugfs_set_rsvd_page,
|
||||
.cb_read = rtw_debugfs_get_rsvd_page,
|
||||
};
|
||||
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_phy_info = {
|
||||
.cb_read = rtw_debugfs_get_phy_info,
|
||||
};
|
||||
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_coex_enable = {
|
||||
.cb_write = rtw_debugfs_set_coex_enable,
|
||||
.cb_read = rtw_debugfs_get_coex_enable,
|
||||
};
|
||||
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_coex_info = {
|
||||
.cb_read = rtw_debugfs_get_coex_info,
|
||||
};
|
||||
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_edcca_enable = {
|
||||
.cb_write = rtw_debugfs_set_edcca_enable,
|
||||
.cb_read = rtw_debugfs_get_edcca_enable,
|
||||
};
|
||||
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_fw_crash = {
|
||||
.cb_write = rtw_debugfs_set_fw_crash,
|
||||
.cb_read = rtw_debugfs_get_fw_crash,
|
||||
};
|
||||
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_force_lowest_basic_rate = {
|
||||
.cb_write = rtw_debugfs_set_force_lowest_basic_rate,
|
||||
.cb_read = rtw_debugfs_get_force_lowest_basic_rate,
|
||||
};
|
||||
|
||||
static struct rtw_debugfs_priv rtw_debug_priv_dm_cap = {
|
||||
.cb_write = rtw_debugfs_set_dm_cap,
|
||||
.cb_read = rtw_debugfs_get_dm_cap,
|
||||
static const struct rtw_debugfs rtw_debugfs_templ = {
|
||||
.mac_0 = rtw_debug_priv_mac(0x0000),
|
||||
.mac_1 = rtw_debug_priv_mac(0x0100),
|
||||
.mac_2 = rtw_debug_priv_mac(0x0200),
|
||||
.mac_3 = rtw_debug_priv_mac(0x0300),
|
||||
.mac_4 = rtw_debug_priv_mac(0x0400),
|
||||
.mac_5 = rtw_debug_priv_mac(0x0500),
|
||||
.mac_6 = rtw_debug_priv_mac(0x0600),
|
||||
.mac_7 = rtw_debug_priv_mac(0x0700),
|
||||
.mac_10 = rtw_debug_priv_mac(0x1000),
|
||||
.mac_11 = rtw_debug_priv_mac(0x1100),
|
||||
.mac_12 = rtw_debug_priv_mac(0x1200),
|
||||
.mac_13 = rtw_debug_priv_mac(0x1300),
|
||||
.mac_14 = rtw_debug_priv_mac(0x1400),
|
||||
.mac_15 = rtw_debug_priv_mac(0x1500),
|
||||
.mac_16 = rtw_debug_priv_mac(0x1600),
|
||||
.mac_17 = rtw_debug_priv_mac(0x1700),
|
||||
.bb_8 = rtw_debug_priv_bb(0x0800),
|
||||
.bb_9 = rtw_debug_priv_bb(0x0900),
|
||||
.bb_a = rtw_debug_priv_bb(0x0a00),
|
||||
.bb_b = rtw_debug_priv_bb(0x0b00),
|
||||
.bb_c = rtw_debug_priv_bb(0x0c00),
|
||||
.bb_d = rtw_debug_priv_bb(0x0d00),
|
||||
.bb_e = rtw_debug_priv_bb(0x0e00),
|
||||
.bb_f = rtw_debug_priv_bb(0x0f00),
|
||||
.bb_18 = rtw_debug_priv_bb(0x1800),
|
||||
.bb_19 = rtw_debug_priv_bb(0x1900),
|
||||
.bb_1a = rtw_debug_priv_bb(0x1a00),
|
||||
.bb_1b = rtw_debug_priv_bb(0x1b00),
|
||||
.bb_1c = rtw_debug_priv_bb(0x1c00),
|
||||
.bb_1d = rtw_debug_priv_bb(0x1d00),
|
||||
.bb_1e = rtw_debug_priv_bb(0x1e00),
|
||||
.bb_1f = rtw_debug_priv_bb(0x1f00),
|
||||
.bb_2c = rtw_debug_priv_bb(0x2c00),
|
||||
.bb_2d = rtw_debug_priv_bb(0x2d00),
|
||||
.bb_40 = rtw_debug_priv_bb(0x4000),
|
||||
.bb_41 = rtw_debug_priv_bb(0x4100),
|
||||
.rf_dump = rtw_debug_priv_get(rf_dump),
|
||||
.tx_pwr_tbl = rtw_debug_priv_get(tx_pwr_tbl),
|
||||
.write_reg = rtw_debug_priv_set(write_reg),
|
||||
.h2c = rtw_debug_priv_set(h2c),
|
||||
.rf_write = rtw_debug_priv_set(rf_write),
|
||||
.rf_read = rtw_debug_priv_set_and_get(rf_read),
|
||||
.read_reg = rtw_debug_priv_set_and_get(read_reg),
|
||||
.fix_rate = rtw_debug_priv_set_and_get(fix_rate),
|
||||
.dump_cam = rtw_debug_priv_set_single_and_get(dump_cam),
|
||||
.rsvd_page = rtw_debug_priv_set_and_get(rsvd_page),
|
||||
.phy_info = rtw_debug_priv_get(phy_info),
|
||||
.coex_enable = rtw_debug_priv_set_and_get(coex_enable),
|
||||
.coex_info = rtw_debug_priv_get(coex_info),
|
||||
.edcca_enable = rtw_debug_priv_set_and_get(edcca_enable),
|
||||
.fw_crash = rtw_debug_priv_set_and_get(fw_crash),
|
||||
.force_lowest_basic_rate = rtw_debug_priv_set_and_get(force_lowest_basic_rate),
|
||||
.dm_cap = rtw_debug_priv_set_and_get(dm_cap),
|
||||
};
|
||||
|
||||
#define rtw_debugfs_add_core(name, mode, fopname, parent) \
|
||||
do { \
|
||||
rtw_debug_priv_ ##name.rtwdev = rtwdev; \
|
||||
struct rtw_debugfs_priv *priv = &rtwdev->debugfs->name; \
|
||||
priv->rtwdev = rtwdev; \
|
||||
if (IS_ERR(debugfs_create_file(#name, mode, \
|
||||
parent, &rtw_debug_priv_ ##name,\
|
||||
parent, priv, \
|
||||
&file_ops_ ##fopname))) \
|
||||
pr_debug("Unable to initialize debugfs:%s\n", \
|
||||
#name); \
|
||||
@ -1219,16 +1238,9 @@ static struct rtw_debugfs_priv rtw_debug_priv_dm_cap = {
|
||||
#define rtw_debugfs_add_r(name) \
|
||||
rtw_debugfs_add_core(name, S_IFREG | 0444, single_r, debugfs_topdir)
|
||||
|
||||
void rtw_debugfs_init(struct rtw_dev *rtwdev)
|
||||
static
|
||||
void rtw_debugfs_add_basic(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir)
|
||||
{
|
||||
struct dentry *debugfs_topdir;
|
||||
|
||||
#if defined(__linux__)
|
||||
debugfs_topdir = debugfs_create_dir("rtw88",
|
||||
#elif defined(__FreeBSD__)
|
||||
debugfs_topdir = debugfs_create_dir(dev_name(rtwdev->dev),
|
||||
#endif
|
||||
rtwdev->hw->wiphy->debugfsdir);
|
||||
rtw_debugfs_add_w(write_reg);
|
||||
rtw_debugfs_add_rw(read_reg);
|
||||
rtw_debugfs_add_w(rf_write);
|
||||
@ -1240,6 +1252,17 @@ void rtw_debugfs_init(struct rtw_dev *rtwdev)
|
||||
rtw_debugfs_add_r(coex_info);
|
||||
rtw_debugfs_add_rw(coex_enable);
|
||||
rtw_debugfs_add_w(h2c);
|
||||
rtw_debugfs_add_r(rf_dump);
|
||||
rtw_debugfs_add_r(tx_pwr_tbl);
|
||||
rtw_debugfs_add_rw(edcca_enable);
|
||||
rtw_debugfs_add_rw(fw_crash);
|
||||
rtw_debugfs_add_rw(force_lowest_basic_rate);
|
||||
rtw_debugfs_add_rw(dm_cap);
|
||||
}
|
||||
|
||||
static
|
||||
void rtw_debugfs_add_sec0(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir)
|
||||
{
|
||||
rtw_debugfs_add_r(mac_0);
|
||||
rtw_debugfs_add_r(mac_1);
|
||||
rtw_debugfs_add_r(mac_2);
|
||||
@ -1256,6 +1279,11 @@ void rtw_debugfs_init(struct rtw_dev *rtwdev)
|
||||
rtw_debugfs_add_r(bb_d);
|
||||
rtw_debugfs_add_r(bb_e);
|
||||
rtw_debugfs_add_r(bb_f);
|
||||
}
|
||||
|
||||
static
|
||||
void rtw_debugfs_add_sec1(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir)
|
||||
{
|
||||
rtw_debugfs_add_r(mac_10);
|
||||
rtw_debugfs_add_r(mac_11);
|
||||
rtw_debugfs_add_r(mac_12);
|
||||
@ -1278,14 +1306,33 @@ void rtw_debugfs_init(struct rtw_dev *rtwdev)
|
||||
rtw_debugfs_add_r(bb_40);
|
||||
rtw_debugfs_add_r(bb_41);
|
||||
}
|
||||
rtw_debugfs_add_r(rf_dump);
|
||||
rtw_debugfs_add_r(tx_pwr_tbl);
|
||||
rtw_debugfs_add_rw(edcca_enable);
|
||||
rtw_debugfs_add_rw(fw_crash);
|
||||
rtw_debugfs_add_rw(force_lowest_basic_rate);
|
||||
rtw_debugfs_add_rw(dm_cap);
|
||||
}
|
||||
|
||||
void rtw_debugfs_init(struct rtw_dev *rtwdev)
|
||||
{
|
||||
struct dentry *debugfs_topdir;
|
||||
|
||||
rtwdev->debugfs = kmemdup(&rtw_debugfs_templ, sizeof(rtw_debugfs_templ),
|
||||
GFP_KERNEL);
|
||||
if (!rtwdev->debugfs)
|
||||
return;
|
||||
|
||||
#if defined(__linux__)
|
||||
debugfs_topdir = debugfs_create_dir("rtw88",
|
||||
#elif defined(__FreeBSD__)
|
||||
debugfs_topdir = debugfs_create_dir(dev_name(rtwdev->dev),
|
||||
#endif
|
||||
rtwdev->hw->wiphy->debugfsdir);
|
||||
|
||||
rtw_debugfs_add_basic(rtwdev, debugfs_topdir);
|
||||
rtw_debugfs_add_sec0(rtwdev, debugfs_topdir);
|
||||
rtw_debugfs_add_sec1(rtwdev, debugfs_topdir);
|
||||
}
|
||||
|
||||
void rtw_debugfs_deinit(struct rtw_dev *rtwdev)
|
||||
{
|
||||
kfree(rtwdev->debugfs);
|
||||
}
|
||||
#endif /* CONFIG_RTW88_DEBUGFS */
|
||||
|
||||
#ifdef CONFIG_RTW88_DEBUG
|
||||
|
||||
@ -25,6 +25,7 @@ enum rtw_debug_mask {
|
||||
RTW_DBG_HW_SCAN = 0x00010000,
|
||||
RTW_DBG_STATE = 0x00020000,
|
||||
RTW_DBG_SDIO = 0x00040000,
|
||||
RTW_DBG_USB = 0x00080000,
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
RTW_DBG_IO_RW = 0x10000000,
|
||||
@ -36,11 +37,13 @@ enum rtw_debug_mask {
|
||||
#ifdef CONFIG_RTW88_DEBUGFS
|
||||
|
||||
void rtw_debugfs_init(struct rtw_dev *rtwdev);
|
||||
void rtw_debugfs_deinit(struct rtw_dev *rtwdev);
|
||||
void rtw_debugfs_get_simple_phy_info(struct seq_file *m);
|
||||
|
||||
#else
|
||||
|
||||
static inline void rtw_debugfs_init(struct rtw_dev *rtwdev) {}
|
||||
static inline void rtw_debugfs_deinit(struct rtw_dev *rtwdev) {}
|
||||
|
||||
#endif /* CONFIG_RTW88_DEBUGFS */
|
||||
|
||||
|
||||
@ -139,25 +139,30 @@ static u16 get_max_amsdu_len(u32 bit_rate)
|
||||
struct rtw_fw_iter_ra_data {
|
||||
struct rtw_dev *rtwdev;
|
||||
u8 *payload;
|
||||
u8 length;
|
||||
};
|
||||
|
||||
static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta)
|
||||
{
|
||||
struct rtw_fw_iter_ra_data *ra_data = data;
|
||||
struct rtw_c2h_ra_rpt *ra_rpt = (struct rtw_c2h_ra_rpt *)ra_data->payload;
|
||||
struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
|
||||
u8 mac_id, rate, sgi, bw;
|
||||
u8 mcs, nss;
|
||||
u32 bit_rate;
|
||||
|
||||
mac_id = GET_RA_REPORT_MACID(ra_data->payload);
|
||||
mac_id = ra_rpt->mac_id;
|
||||
if (si->mac_id != mac_id)
|
||||
return;
|
||||
|
||||
si->ra_report.txrate.flags = 0;
|
||||
|
||||
rate = GET_RA_REPORT_RATE(ra_data->payload);
|
||||
sgi = GET_RA_REPORT_SGI(ra_data->payload);
|
||||
bw = GET_RA_REPORT_BW(ra_data->payload);
|
||||
rate = u8_get_bits(ra_rpt->rate_sgi, RTW_C2H_RA_RPT_RATE);
|
||||
sgi = u8_get_bits(ra_rpt->rate_sgi, RTW_C2H_RA_RPT_SGI);
|
||||
if (ra_data->length >= offsetofend(typeof(*ra_rpt), bw))
|
||||
bw = ra_rpt->bw;
|
||||
else
|
||||
bw = si->bw_mode;
|
||||
|
||||
if (rate < DESC_RATEMCS0) {
|
||||
si->ra_report.txrate.legacy = rtw_desc_to_bitrate(rate);
|
||||
@ -197,14 +202,18 @@ legacy:
|
||||
static void rtw_fw_ra_report_handle(struct rtw_dev *rtwdev, u8 *payload,
|
||||
u8 length)
|
||||
{
|
||||
struct rtw_c2h_ra_rpt *ra_rpt = (struct rtw_c2h_ra_rpt *)payload;
|
||||
struct rtw_fw_iter_ra_data ra_data;
|
||||
|
||||
if (WARN(length < 7, "invalid ra report c2h length\n"))
|
||||
if (WARN(length < rtwdev->chip->c2h_ra_report_size,
|
||||
"invalid ra report c2h length %d\n", length))
|
||||
return;
|
||||
|
||||
rtwdev->dm_info.tx_rate = GET_RA_REPORT_RATE(payload);
|
||||
rtwdev->dm_info.tx_rate = u8_get_bits(ra_rpt->rate_sgi,
|
||||
RTW_C2H_RA_RPT_RATE);
|
||||
ra_data.rtwdev = rtwdev;
|
||||
ra_data.payload = payload;
|
||||
ra_data.length = length;
|
||||
rtw_iterate_stas_atomic(rtwdev, rtw_fw_ra_report_iter, &ra_data);
|
||||
}
|
||||
|
||||
@ -267,7 +276,7 @@ static void rtw_fw_scan_result(struct rtw_dev *rtwdev, u8 *payload,
|
||||
static void rtw_fw_adaptivity_result(struct rtw_dev *rtwdev, u8 *payload,
|
||||
u8 length)
|
||||
{
|
||||
struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
|
||||
const struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
|
||||
struct rtw_c2h_adaptivity *result = (struct rtw_c2h_adaptivity *)payload;
|
||||
|
||||
rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY,
|
||||
@ -323,6 +332,9 @@ void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)
|
||||
case C2H_RA_RPT:
|
||||
rtw_fw_ra_report_handle(rtwdev, c2h->payload, len);
|
||||
break;
|
||||
case C2H_ADAPTIVITY:
|
||||
rtw_fw_adaptivity_result(rtwdev, c2h->payload, len);
|
||||
break;
|
||||
default:
|
||||
rtw_dbg(rtwdev, RTW_DBG_FW, "C2H 0x%x isn't handled\n", c2h->id);
|
||||
break;
|
||||
@ -358,10 +370,6 @@ void rtw_fw_c2h_cmd_rx_irqsafe(struct rtw_dev *rtwdev, u32 pkt_offset,
|
||||
rtw_fw_scan_result(rtwdev, c2h->payload, len);
|
||||
dev_kfree_skb_any(skb);
|
||||
break;
|
||||
case C2H_ADAPTIVITY:
|
||||
rtw_fw_adaptivity_result(rtwdev, c2h->payload, len);
|
||||
dev_kfree_skb_any(skb);
|
||||
break;
|
||||
default:
|
||||
/* pass offset for further operation */
|
||||
*((u32 *)skb->cb) = pkt_offset;
|
||||
@ -1281,16 +1289,16 @@ static void rtw_fill_rsvd_page_desc(struct rtw_dev *rtwdev, struct sk_buff *skb,
|
||||
rtw_tx_rsvd_page_pkt_info_update(rtwdev, &pkt_info, skb, type);
|
||||
pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
|
||||
memset(pkt_desc, 0, chip->tx_pkt_desc_sz);
|
||||
rtw_tx_fill_tx_desc(&pkt_info, skb);
|
||||
rtw_tx_fill_tx_desc(rtwdev, &pkt_info, skb);
|
||||
}
|
||||
|
||||
static inline u8 rtw_len_to_page(unsigned int len, u8 page_size)
|
||||
static inline u8 rtw_len_to_page(unsigned int len, u16 page_size)
|
||||
{
|
||||
return DIV_ROUND_UP(len, page_size);
|
||||
}
|
||||
|
||||
static void rtw_rsvd_page_list_to_buf(struct rtw_dev *rtwdev, u8 page_size,
|
||||
u8 page_margin, u32 page, u8 *buf,
|
||||
static void rtw_rsvd_page_list_to_buf(struct rtw_dev *rtwdev, u16 page_size,
|
||||
u16 page_margin, u32 page, u8 *buf,
|
||||
struct rtw_rsvd_page *rsvd_pkt)
|
||||
{
|
||||
struct sk_buff *skb = rsvd_pkt->skb;
|
||||
@ -1468,10 +1476,12 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr,
|
||||
val |= BIT_ENSWBCN >> 8;
|
||||
rtw_write8(rtwdev, REG_CR + 1, val);
|
||||
|
||||
val = rtw_read8(rtwdev, REG_FWHW_TXQ_CTRL + 2);
|
||||
bckp[1] = val;
|
||||
val &= ~(BIT_EN_BCNQ_DL >> 16);
|
||||
rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 2, val);
|
||||
if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) {
|
||||
val = rtw_read8(rtwdev, REG_FWHW_TXQ_CTRL + 2);
|
||||
bckp[1] = val;
|
||||
val &= ~(BIT_EN_BCNQ_DL >> 16);
|
||||
rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 2, val);
|
||||
}
|
||||
|
||||
ret = rtw_hci_write_data_rsvd_page(rtwdev, buf, size);
|
||||
if (ret) {
|
||||
@ -1496,7 +1506,8 @@ restore:
|
||||
rsvd_pg_head = rtwdev->fifo.rsvd_boundary;
|
||||
rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2,
|
||||
rsvd_pg_head | BIT_BCN_VALID_V1);
|
||||
rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 2, bckp[1]);
|
||||
if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE)
|
||||
rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 2, bckp[1]);
|
||||
rtw_write8(rtwdev, REG_CR + 1, bckp[0]);
|
||||
|
||||
return ret;
|
||||
@ -1589,13 +1600,13 @@ static int __rtw_build_rsvd_page_from_vifs(struct rtw_dev *rtwdev)
|
||||
|
||||
static u8 *rtw_build_rsvd_page(struct rtw_dev *rtwdev, u32 *size)
|
||||
{
|
||||
struct ieee80211_hw *hw = rtwdev->hw;
|
||||
const struct rtw_chip_info *chip = rtwdev->chip;
|
||||
struct sk_buff *iter;
|
||||
struct ieee80211_hw *hw = rtwdev->hw;
|
||||
struct rtw_rsvd_page *rsvd_pkt;
|
||||
u32 page = 0;
|
||||
struct sk_buff *iter;
|
||||
u16 page_size, page_margin, tx_desc_sz;
|
||||
u8 total_page = 0;
|
||||
u8 page_size, page_margin, tx_desc_sz;
|
||||
u32 page = 0;
|
||||
u8 *buf;
|
||||
int ret;
|
||||
|
||||
@ -2001,12 +2012,13 @@ static int _rtw_hw_scan_update_probe_req(struct rtw_dev *rtwdev, u8 num_probes,
|
||||
{
|
||||
const struct rtw_chip_info *chip = rtwdev->chip;
|
||||
struct sk_buff *skb, *tmp;
|
||||
u8 page_offset = 1, *buf, page_size = chip->page_size;
|
||||
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;
|
||||
u8 page_cnt, pages;
|
||||
u16 page_size = chip->page_size;
|
||||
u8 page_offset = 1, *buf;
|
||||
u16 buf_offset = page_size * page_offset;
|
||||
unsigned int pkt_len;
|
||||
u8 page_cnt, pages;
|
||||
int ret;
|
||||
|
||||
if (rtw_fw_feature_ext_check(&rtwdev->fw, FW_FEATURE_EXT_OLD_PAGE_NUM))
|
||||
|
||||
@ -85,6 +85,19 @@ struct rtw_c2h_adaptivity {
|
||||
u8 option;
|
||||
} __packed;
|
||||
|
||||
struct rtw_c2h_ra_rpt {
|
||||
u8 rate_sgi;
|
||||
u8 mac_id;
|
||||
u8 byte2;
|
||||
u8 status;
|
||||
u8 byte4;
|
||||
u8 ra_ratio;
|
||||
u8 bw;
|
||||
} __packed;
|
||||
|
||||
#define RTW_C2H_RA_RPT_RATE GENMASK(6, 0)
|
||||
#define RTW_C2H_RA_RPT_SGI BIT(7)
|
||||
|
||||
struct rtw_h2c_register {
|
||||
u32 w0;
|
||||
u32 w1;
|
||||
@ -364,10 +377,6 @@ struct rtw_fw_hdr_legacy {
|
||||
#define GET_CHAN_SWITCH_CENTRAL_CH(c2h_payload) (c2h_payload[2])
|
||||
#define GET_CHAN_SWITCH_ID(c2h_payload) (c2h_payload[3])
|
||||
#define GET_CHAN_SWITCH_STATUS(c2h_payload) (c2h_payload[4])
|
||||
#define GET_RA_REPORT_RATE(c2h_payload) (c2h_payload[0] & 0x7f)
|
||||
#define GET_RA_REPORT_SGI(c2h_payload) ((c2h_payload[0] & 0x80) >> 7)
|
||||
#define GET_RA_REPORT_BW(c2h_payload) (c2h_payload[6])
|
||||
#define GET_RA_REPORT_MACID(c2h_payload) (c2h_payload[1])
|
||||
|
||||
#define GET_BCN_FILTER_NOTIFY_TYPE(c2h_payload) (c2h_payload[1] & 0xf)
|
||||
#define GET_BCN_FILTER_NOTIFY_EVENT(c2h_payload) (c2h_payload[1] & 0x10)
|
||||
|
||||
@ -18,6 +18,7 @@ struct rtw_hci_ops {
|
||||
void (*deep_ps)(struct rtw_dev *rtwdev, bool enter);
|
||||
void (*link_ps)(struct rtw_dev *rtwdev, bool enter);
|
||||
void (*interface_cfg)(struct rtw_dev *rtwdev);
|
||||
void (*dynamic_rx_agg)(struct rtw_dev *rtwdev, bool enable);
|
||||
|
||||
int (*write_data_rsvd_page)(struct rtw_dev *rtwdev, u8 *buf, u32 size);
|
||||
int (*write_data_h2c)(struct rtw_dev *rtwdev, u8 *buf, u32 size);
|
||||
@ -72,6 +73,12 @@ static inline void rtw_hci_interface_cfg(struct rtw_dev *rtwdev)
|
||||
rtwdev->hci.ops->interface_cfg(rtwdev);
|
||||
}
|
||||
|
||||
static inline void rtw_hci_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable)
|
||||
{
|
||||
if (rtwdev->hci.ops->dynamic_rx_agg)
|
||||
rtwdev->hci.ops->dynamic_rx_agg(rtwdev, enable);
|
||||
}
|
||||
|
||||
static inline int
|
||||
rtw_hci_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, u32 size)
|
||||
{
|
||||
|
||||
73
sys/contrib/dev/rtw88/led.c
Normal file
73
sys/contrib/dev/rtw88/led.c
Normal file
@ -0,0 +1,73 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/* Copyright(c) 2025 Realtek Corporation
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "debug.h"
|
||||
#include "led.h"
|
||||
|
||||
static int rtw_led_set_blocking(struct led_classdev *led,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev);
|
||||
|
||||
rtwdev->chip->ops->led_set(led, brightness);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtw_led_init(struct rtw_dev *rtwdev)
|
||||
{
|
||||
static const struct ieee80211_tpt_blink rtw_tpt_blink[] = {
|
||||
{ .throughput = 0 * 1024, .blink_time = 334 },
|
||||
{ .throughput = 1 * 1024, .blink_time = 260 },
|
||||
{ .throughput = 5 * 1024, .blink_time = 220 },
|
||||
{ .throughput = 10 * 1024, .blink_time = 190 },
|
||||
{ .throughput = 20 * 1024, .blink_time = 170 },
|
||||
{ .throughput = 50 * 1024, .blink_time = 150 },
|
||||
{ .throughput = 70 * 1024, .blink_time = 130 },
|
||||
{ .throughput = 100 * 1024, .blink_time = 110 },
|
||||
{ .throughput = 200 * 1024, .blink_time = 80 },
|
||||
{ .throughput = 300 * 1024, .blink_time = 50 },
|
||||
};
|
||||
struct led_classdev *led = &rtwdev->led_cdev;
|
||||
int err;
|
||||
|
||||
if (!rtwdev->chip->ops->led_set)
|
||||
return;
|
||||
|
||||
if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE)
|
||||
led->brightness_set = rtwdev->chip->ops->led_set;
|
||||
else
|
||||
led->brightness_set_blocking = rtw_led_set_blocking;
|
||||
|
||||
snprintf(rtwdev->led_name, sizeof(rtwdev->led_name),
|
||||
"rtw88-%s", dev_name(rtwdev->dev));
|
||||
|
||||
led->name = rtwdev->led_name;
|
||||
led->max_brightness = LED_ON;
|
||||
led->default_trigger =
|
||||
ieee80211_create_tpt_led_trigger(rtwdev->hw,
|
||||
IEEE80211_TPT_LEDTRIG_FL_RADIO,
|
||||
rtw_tpt_blink,
|
||||
ARRAY_SIZE(rtw_tpt_blink));
|
||||
|
||||
err = led_classdev_register(rtwdev->dev, led);
|
||||
if (err) {
|
||||
rtw_warn(rtwdev, "Failed to register the LED, error %d\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
rtwdev->led_registered = true;
|
||||
}
|
||||
|
||||
void rtw_led_deinit(struct rtw_dev *rtwdev)
|
||||
{
|
||||
struct led_classdev *led = &rtwdev->led_cdev;
|
||||
|
||||
if (!rtwdev->led_registered)
|
||||
return;
|
||||
|
||||
rtwdev->chip->ops->led_set(led, LED_OFF);
|
||||
led_classdev_unregister(led);
|
||||
}
|
||||
25
sys/contrib/dev/rtw88/led.h
Normal file
25
sys/contrib/dev/rtw88/led.h
Normal file
@ -0,0 +1,25 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2025 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW_LED_H
|
||||
#define __RTW_LED_H
|
||||
|
||||
#ifdef CONFIG_RTW88_LEDS
|
||||
|
||||
void rtw_led_init(struct rtw_dev *rtwdev);
|
||||
void rtw_led_deinit(struct rtw_dev *rtwdev);
|
||||
|
||||
#else
|
||||
|
||||
static inline void rtw_led_init(struct rtw_dev *rtwdev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void rtw_led_deinit(struct rtw_dev *rtwdev)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -227,8 +227,8 @@ static int rtw_sub_pwr_seq_parser(struct rtw_dev *rtwdev, u8 intf_mask,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
|
||||
const struct rtw_pwr_seq_cmd **cmd_seq)
|
||||
int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
|
||||
const struct rtw_pwr_seq_cmd * const *cmd_seq)
|
||||
{
|
||||
u8 cut_mask;
|
||||
u8 intf_mask;
|
||||
@ -267,11 +267,12 @@ static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_pwr_seq_parser);
|
||||
|
||||
static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)
|
||||
{
|
||||
const struct rtw_chip_info *chip = rtwdev->chip;
|
||||
const struct rtw_pwr_seq_cmd **pwr_seq;
|
||||
const struct rtw_pwr_seq_cmd * const *pwr_seq;
|
||||
u32 imr = 0;
|
||||
u8 rpwm;
|
||||
bool cur_pwr;
|
||||
@ -994,6 +995,7 @@ int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_download_firmware);
|
||||
|
||||
static u32 get_priority_queues(struct rtw_dev *rtwdev, u32 queues)
|
||||
{
|
||||
@ -1127,7 +1129,7 @@ static int txdma_queue_mapping(struct rtw_dev *rtwdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_trx_fifo_info(struct rtw_dev *rtwdev)
|
||||
int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev)
|
||||
{
|
||||
const struct rtw_chip_info *chip = rtwdev->chip;
|
||||
struct rtw_fifo_conf *fifo = &rtwdev->fifo;
|
||||
@ -1136,7 +1138,7 @@ static int set_trx_fifo_info(struct rtw_dev *rtwdev)
|
||||
|
||||
/* config rsvd page num */
|
||||
fifo->rsvd_drv_pg_num = chip->rsvd_drv_pg_num;
|
||||
fifo->txff_pg_num = chip->txff_size >> 7;
|
||||
fifo->txff_pg_num = chip->txff_size / chip->page_size;
|
||||
if (rtw_chip_wcpu_11n(rtwdev))
|
||||
fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num;
|
||||
else
|
||||
@ -1179,6 +1181,7 @@ static int set_trx_fifo_info(struct rtw_dev *rtwdev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_set_trx_fifo_info);
|
||||
|
||||
static int __priority_queue_cfg(struct rtw_dev *rtwdev,
|
||||
const struct rtw_page_table *pg_tbl,
|
||||
@ -1256,7 +1259,7 @@ static int priority_queue_cfg(struct rtw_dev *rtwdev)
|
||||
u16 pubq_num;
|
||||
int ret;
|
||||
|
||||
ret = set_trx_fifo_info(rtwdev);
|
||||
ret = rtw_set_trx_fifo_info(rtwdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
@ -30,11 +30,14 @@
|
||||
|
||||
void rtw_set_channel_mac(struct rtw_dev *rtwdev, u8 channel, u8 bw,
|
||||
u8 primary_ch_idx);
|
||||
int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
|
||||
const struct rtw_pwr_seq_cmd * const *cmd_seq);
|
||||
int rtw_mac_power_on(struct rtw_dev *rtwdev);
|
||||
void rtw_mac_power_off(struct rtw_dev *rtwdev);
|
||||
int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw);
|
||||
int rtw_mac_init(struct rtw_dev *rtwdev);
|
||||
void rtw_mac_flush_queues(struct rtw_dev *rtwdev, u32 queues, bool drop);
|
||||
int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev);
|
||||
int rtw_ddma_to_fw_fifo(struct rtw_dev *rtwdev, u32 ocp_src, u32 size);
|
||||
|
||||
static inline void rtw_mac_flush_all_queues(struct rtw_dev *rtwdev, bool drop)
|
||||
|
||||
@ -167,6 +167,12 @@ static int rtw_ops_add_interface(struct ieee80211_hw *hw,
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
|
||||
rtwvif->mac_id = rtw_acquire_macid(rtwdev);
|
||||
if (rtwvif->mac_id >= RTW_MAX_MAC_ID_NUM) {
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
port = find_first_zero_bit(rtwdev->hw_port, RTW_PORT_NUM);
|
||||
if (port >= RTW_PORT_NUM) {
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
@ -215,9 +221,11 @@ static int rtw_ops_add_interface(struct ieee80211_hw *hw,
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
|
||||
#if defined(__linux__)
|
||||
rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %pM on port %d\n", vif->addr, rtwvif->port);
|
||||
rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %pM mac_id %d on port %d\n",
|
||||
vif->addr, rtwvif->mac_id, rtwvif->port);
|
||||
#elif defined(__FreeBSD__)
|
||||
rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %6D on port %d\n", vif->addr, ":", rtwvif->port);
|
||||
rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %6D mac_id %d on port %d\n",
|
||||
vif->addr, ":", rtwvif->mac_id, rtwvif->port);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@ -230,9 +238,11 @@ static void rtw_ops_remove_interface(struct ieee80211_hw *hw,
|
||||
u32 config = 0;
|
||||
|
||||
#if defined(__linux__)
|
||||
rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %pM on port %d\n", vif->addr, rtwvif->port);
|
||||
rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %pM mac_id %d on port %d\n",
|
||||
vif->addr, rtwvif->mac_id, rtwvif->port);
|
||||
#elif defined(__FreeBSD__)
|
||||
rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %6D on port %d\n", vif->addr, ":", rtwvif->port);
|
||||
rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %6D mac_id %d on port %d\n",
|
||||
vif->addr, ":", rtwvif->mac_id, rtwvif->port);
|
||||
#endif
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
@ -250,6 +260,7 @@ static void rtw_ops_remove_interface(struct ieee80211_hw *hw,
|
||||
config |= PORT_SET_BCN_CTRL;
|
||||
rtw_vif_port_config(rtwdev, rtwvif, config);
|
||||
clear_bit(rtwvif->port, rtwdev->hw_port);
|
||||
rtw_release_macid(rtwdev, rtwvif->mac_id);
|
||||
rtw_recalc_lps(rtwdev, NULL);
|
||||
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
@ -932,8 +943,10 @@ static int rtw_ops_set_sar_specs(struct ieee80211_hw *hw,
|
||||
|
||||
static void rtw_ops_sta_rc_update(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, u32 changed)
|
||||
struct ieee80211_link_sta *link_sta,
|
||||
u32 changed)
|
||||
{
|
||||
struct ieee80211_sta *sta = link_sta->sta;
|
||||
struct rtw_dev *rtwdev = hw->priv;
|
||||
struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
|
||||
|
||||
@ -977,7 +990,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,
|
||||
.link_sta_rc_update = rtw_ops_sta_rc_update,
|
||||
.set_sar_specs = rtw_ops_set_sar_specs,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = rtw_ops_suspend,
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include "bf.h"
|
||||
#include "sar.h"
|
||||
#include "sdio.h"
|
||||
#include "led.h"
|
||||
|
||||
bool rtw_disable_lps_deep_mode;
|
||||
EXPORT_SYMBOL(rtw_disable_lps_deep_mode);
|
||||
@ -216,6 +217,21 @@ static void rtw_vif_watch_dog_iter(void *data, struct ieee80211_vif *vif)
|
||||
rtwvif->stats.rx_cnt = 0;
|
||||
}
|
||||
|
||||
static void rtw_sw_beacon_loss_check(struct rtw_dev *rtwdev,
|
||||
struct rtw_vif *rtwvif, int received_beacons)
|
||||
{
|
||||
int watchdog_delay = 2000000 / 1024; /* TU */
|
||||
int beacon_int, expected_beacons;
|
||||
|
||||
if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER) || !rtwvif)
|
||||
return;
|
||||
|
||||
beacon_int = rtwvif_to_vif(rtwvif)->bss_conf.beacon_int;
|
||||
expected_beacons = DIV_ROUND_UP(watchdog_delay, beacon_int);
|
||||
|
||||
rtwdev->beacon_loss = received_beacons < expected_beacons / 2;
|
||||
}
|
||||
|
||||
/* process TX/RX statistics periodically for hardware,
|
||||
* the information helps hardware to enhance performance
|
||||
*/
|
||||
@ -226,6 +242,8 @@ static void rtw_watch_dog_work(struct work_struct *work)
|
||||
struct rtw_traffic_stats *stats = &rtwdev->stats;
|
||||
struct rtw_watch_dog_iter_data data = {};
|
||||
bool busy_traffic = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags);
|
||||
int received_beacons = rtwdev->dm_info.cur_pkt_count.num_bcn_pkt;
|
||||
u32 tx_unicast_mbps, rx_unicast_mbps;
|
||||
bool ps_active;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
@ -250,10 +268,11 @@ static void rtw_watch_dog_work(struct work_struct *work)
|
||||
else
|
||||
ps_active = false;
|
||||
|
||||
ewma_tp_add(&stats->tx_ewma_tp,
|
||||
(u32)(stats->tx_unicast >> RTW_TP_SHIFT));
|
||||
ewma_tp_add(&stats->rx_ewma_tp,
|
||||
(u32)(stats->rx_unicast >> RTW_TP_SHIFT));
|
||||
tx_unicast_mbps = stats->tx_unicast >> RTW_TP_SHIFT;
|
||||
rx_unicast_mbps = stats->rx_unicast >> RTW_TP_SHIFT;
|
||||
|
||||
ewma_tp_add(&stats->tx_ewma_tp, tx_unicast_mbps);
|
||||
ewma_tp_add(&stats->rx_ewma_tp, rx_unicast_mbps);
|
||||
stats->tx_throughput = ewma_tp_read(&stats->tx_ewma_tp);
|
||||
stats->rx_throughput = ewma_tp_read(&stats->rx_ewma_tp);
|
||||
|
||||
@ -270,15 +289,21 @@ static void rtw_watch_dog_work(struct work_struct *work)
|
||||
rtw_leave_lps(rtwdev);
|
||||
rtw_coex_wl_status_check(rtwdev);
|
||||
rtw_coex_query_bt_hid_list(rtwdev);
|
||||
rtw_coex_active_query_bt_info(rtwdev);
|
||||
|
||||
rtw_phy_dynamic_mechanism(rtwdev);
|
||||
|
||||
rtw_hci_dynamic_rx_agg(rtwdev,
|
||||
tx_unicast_mbps >= 1 || rx_unicast_mbps >= 1);
|
||||
|
||||
data.rtwdev = rtwdev;
|
||||
/* rtw_iterate_vifs internally uses an atomic iterator which is needed
|
||||
* to avoid taking local->iflist_mtx mutex
|
||||
*/
|
||||
rtw_iterate_vifs(rtwdev, rtw_vif_watch_dog_iter, &data);
|
||||
|
||||
rtw_sw_beacon_loss_check(rtwdev, data.rtwvif, received_beacons);
|
||||
|
||||
/* fw supports only one station associated to enter lps, if there are
|
||||
* more than two stations associated to the AP, then we can not enter
|
||||
* lps, because fw does not handle the overlapped beacon interval
|
||||
@ -320,17 +345,6 @@ static void rtw_ips_work(struct work_struct *work)
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
}
|
||||
|
||||
static u8 rtw_acquire_macid(struct rtw_dev *rtwdev)
|
||||
{
|
||||
unsigned long mac_id;
|
||||
|
||||
mac_id = find_first_zero_bit(rtwdev->mac_id_map, RTW_MAX_MAC_ID_NUM);
|
||||
if (mac_id < RTW_MAX_MAC_ID_NUM)
|
||||
set_bit(mac_id, rtwdev->mac_id_map);
|
||||
|
||||
return mac_id;
|
||||
}
|
||||
|
||||
static void rtw_sta_rc_work(struct work_struct *work)
|
||||
{
|
||||
struct rtw_sta_info *si = container_of(work, struct rtw_sta_info,
|
||||
@ -349,12 +363,14 @@ int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
|
||||
struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
|
||||
int i;
|
||||
|
||||
si->mac_id = rtw_acquire_macid(rtwdev);
|
||||
if (si->mac_id >= RTW_MAX_MAC_ID_NUM)
|
||||
return -ENOSPC;
|
||||
if (vif->type == NL80211_IFTYPE_STATION) {
|
||||
si->mac_id = rtwvif->mac_id;
|
||||
} else {
|
||||
si->mac_id = rtw_acquire_macid(rtwdev);
|
||||
if (si->mac_id >= RTW_MAX_MAC_ID_NUM)
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION && vif->cfg.assoc == 0)
|
||||
rtwvif->mac_id = si->mac_id;
|
||||
si->rtwdev = rtwdev;
|
||||
si->sta = sta;
|
||||
si->vif = vif;
|
||||
@ -384,11 +400,13 @@ void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
|
||||
bool fw_exist)
|
||||
{
|
||||
struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
|
||||
struct ieee80211_vif *vif = si->vif;
|
||||
int i;
|
||||
|
||||
cancel_work_sync(&si->rc_work);
|
||||
|
||||
rtw_release_macid(rtwdev, si->mac_id);
|
||||
if (vif->type != NL80211_IFTYPE_STATION)
|
||||
rtw_release_macid(rtwdev, si->mac_id);
|
||||
if (fw_exist)
|
||||
rtw_fw_media_status_report(rtwdev, si->mac_id, false);
|
||||
|
||||
@ -633,6 +651,8 @@ static void rtw_reset_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
|
||||
rtw_bf_disassoc(rtwdev, vif, NULL);
|
||||
rtw_vif_assoc_changed(rtwvif, NULL);
|
||||
rtw_txq_cleanup(rtwdev, vif->txq);
|
||||
|
||||
rtw_release_macid(rtwdev, rtwvif->mac_id);
|
||||
}
|
||||
|
||||
void rtw_fw_recovery(struct rtw_dev *rtwdev)
|
||||
@ -1222,7 +1242,6 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
|
||||
u8 wireless_set;
|
||||
u8 bw_mode;
|
||||
u8 rate_id;
|
||||
u8 rf_type = RF_1T1R;
|
||||
u8 stbc_en = 0;
|
||||
u8 ldpc_en = 0;
|
||||
u8 tx_num = 1;
|
||||
@ -1311,13 +1330,10 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
|
||||
break;
|
||||
}
|
||||
|
||||
if (sta->deflink.vht_cap.vht_supported && ra_mask & 0xffc00000) {
|
||||
if (sta->deflink.vht_cap.vht_supported && ra_mask & 0xffc00000)
|
||||
tx_num = 2;
|
||||
rf_type = RF_2T2R;
|
||||
} else if (sta->deflink.ht_cap.ht_supported && ra_mask & 0xfff00000) {
|
||||
else if (sta->deflink.ht_cap.ht_supported && ra_mask & 0xfff00000)
|
||||
tx_num = 2;
|
||||
rf_type = RF_2T2R;
|
||||
}
|
||||
|
||||
rate_id = get_rate_id(wireless_set, bw_mode, tx_num);
|
||||
|
||||
@ -1328,7 +1344,6 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
|
||||
si->bw_mode = bw_mode;
|
||||
si->stbc_en = stbc_en;
|
||||
si->ldpc_en = ldpc_en;
|
||||
si->rf_type = rf_type;
|
||||
si->sgi_enable = is_support_sgi;
|
||||
si->vht_enable = is_vht_enable;
|
||||
si->ra_mask = ra_mask;
|
||||
@ -1337,25 +1352,27 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
|
||||
rtw_fw_send_ra_info(rtwdev, si, reset_ra_mask);
|
||||
}
|
||||
|
||||
static int rtw_wait_firmware_completion(struct rtw_dev *rtwdev)
|
||||
int rtw_wait_firmware_completion(struct rtw_dev *rtwdev)
|
||||
{
|
||||
const struct rtw_chip_info *chip = rtwdev->chip;
|
||||
struct rtw_fw_state *fw;
|
||||
int ret = 0;
|
||||
|
||||
fw = &rtwdev->fw;
|
||||
wait_for_completion(&fw->completion);
|
||||
if (!fw->firmware)
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
|
||||
if (chip->wow_fw_name) {
|
||||
fw = &rtwdev->wow_fw;
|
||||
wait_for_completion(&fw->completion);
|
||||
if (!fw->firmware)
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_wait_firmware_completion);
|
||||
|
||||
static enum rtw_lps_deep_mode rtw_update_lps_deep_mode(struct rtw_dev *rtwdev,
|
||||
struct rtw_fw_state *fw)
|
||||
@ -1377,7 +1394,7 @@ static enum rtw_lps_deep_mode rtw_update_lps_deep_mode(struct rtw_dev *rtwdev,
|
||||
return LPS_DEEP_MODE_NONE;
|
||||
}
|
||||
|
||||
static int rtw_power_on(struct rtw_dev *rtwdev)
|
||||
int rtw_power_on(struct rtw_dev *rtwdev)
|
||||
{
|
||||
const struct rtw_chip_info *chip = rtwdev->chip;
|
||||
struct rtw_fw_state *fw = &rtwdev->fw;
|
||||
@ -1440,6 +1457,7 @@ err_off:
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_power_on);
|
||||
|
||||
void rtw_core_fw_scan_notify(struct rtw_dev *rtwdev, bool start)
|
||||
{
|
||||
@ -1512,7 +1530,7 @@ int rtw_core_start(struct rtw_dev *rtwdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = rtw_power_on(rtwdev);
|
||||
ret = rtwdev->chip->ops->power_on(rtwdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -1532,12 +1550,13 @@ int rtw_core_start(struct rtw_dev *rtwdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rtw_power_off(struct rtw_dev *rtwdev)
|
||||
void rtw_power_off(struct rtw_dev *rtwdev)
|
||||
{
|
||||
rtw_hci_stop(rtwdev);
|
||||
rtw_coex_power_off_setting(rtwdev);
|
||||
rtw_mac_power_off(rtwdev);
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_power_off);
|
||||
|
||||
void rtw_core_stop(struct rtw_dev *rtwdev)
|
||||
{
|
||||
@ -1562,7 +1581,7 @@ void rtw_core_stop(struct rtw_dev *rtwdev)
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
|
||||
rtw_power_off(rtwdev);
|
||||
rtwdev->chip->ops->power_off(rtwdev);
|
||||
}
|
||||
|
||||
static void rtw_init_ht_cap(struct rtw_dev *rtwdev,
|
||||
@ -1960,6 +1979,9 @@ static int rtw_dump_hw_feature(struct rtw_dev *rtwdev)
|
||||
u8 bw;
|
||||
int i;
|
||||
|
||||
if (!rtwdev->chip->hw_feature_report)
|
||||
return 0;
|
||||
|
||||
id = rtw_read8(rtwdev, REG_C2HEVT);
|
||||
if (id != C2H_HW_FEATURE_REPORT) {
|
||||
rtw_err(rtwdev, "failed to read hw feature report\n");
|
||||
@ -2049,7 +2071,7 @@ static int rtw_chip_efuse_info_setup(struct rtw_dev *rtwdev)
|
||||
efuse->ext_pa_2g = efuse->pa_type_2g & BIT(4) ? 1 : 0;
|
||||
efuse->ext_lna_2g = efuse->lna_type_2g & BIT(3) ? 1 : 0;
|
||||
efuse->ext_pa_5g = efuse->pa_type_5g & BIT(0) ? 1 : 0;
|
||||
efuse->ext_lna_2g = efuse->lna_type_5g & BIT(3) ? 1 : 0;
|
||||
efuse->ext_lna_5g = efuse->lna_type_5g & BIT(3) ? 1 : 0;
|
||||
|
||||
if (!is_valid_ether_addr(efuse->addr)) {
|
||||
eth_random_addr(efuse->addr);
|
||||
@ -2177,7 +2199,6 @@ int rtw_core_init(struct rtw_dev *rtwdev)
|
||||
rtwdev->sec.total_cam_num = 32;
|
||||
rtwdev->hal.current_channel = 1;
|
||||
rtwdev->dm_info.fix_rate = U8_MAX;
|
||||
set_bit(RTW_BC_MC_MACID, rtwdev->mac_id_map);
|
||||
|
||||
rtw_stats_init(rtwdev);
|
||||
|
||||
@ -2320,16 +2341,18 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
|
||||
return ret;
|
||||
}
|
||||
|
||||
rtw_led_init(rtwdev);
|
||||
|
||||
ret = ieee80211_register_hw(hw);
|
||||
if (ret) {
|
||||
rtw_err(rtwdev, "failed to register hw\n");
|
||||
return ret;
|
||||
goto led_deinit;
|
||||
}
|
||||
|
||||
ret = rtw_regd_hint(rtwdev);
|
||||
if (ret) {
|
||||
rtw_err(rtwdev, "failed to hint regd\n");
|
||||
return ret;
|
||||
goto led_deinit;
|
||||
}
|
||||
|
||||
rtw_debugfs_init(rtwdev);
|
||||
@ -2338,6 +2361,10 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
|
||||
rtwdev->bf_info.bfer_su_cnt = 0;
|
||||
|
||||
return 0;
|
||||
|
||||
led_deinit:
|
||||
rtw_led_deinit(rtwdev);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_register_hw);
|
||||
|
||||
@ -2347,6 +2374,8 @@ void rtw_unregister_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
|
||||
|
||||
ieee80211_unregister_hw(hw);
|
||||
rtw_unset_supported_band(hw, chip);
|
||||
rtw_debugfs_deinit(rtwdev);
|
||||
rtw_led_deinit(rtwdev);
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_unregister_hw);
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/lockdep.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/leds.h>
|
||||
#endif
|
||||
|
||||
#include "util.h"
|
||||
@ -58,6 +59,7 @@ extern const struct ieee80211_ops rtw_ops;
|
||||
#define RTW_MAX_CHANNEL_NUM_5G 49
|
||||
|
||||
struct rtw_dev;
|
||||
struct rtw_debugfs;
|
||||
|
||||
enum rtw_hci_type {
|
||||
RTW_HCI_TYPE_PCIE,
|
||||
@ -196,6 +198,8 @@ enum rtw_chip_type {
|
||||
RTW_CHIP_TYPE_8723D,
|
||||
RTW_CHIP_TYPE_8821C,
|
||||
RTW_CHIP_TYPE_8703B,
|
||||
RTW_CHIP_TYPE_8821A,
|
||||
RTW_CHIP_TYPE_8812A,
|
||||
};
|
||||
|
||||
enum rtw_tx_queue_type {
|
||||
@ -515,12 +519,12 @@ struct rtw_5g_txpwr_idx {
|
||||
struct rtw_5g_vht_ns_pwr_idx_diff vht_2s_diff;
|
||||
struct rtw_5g_vht_ns_pwr_idx_diff vht_3s_diff;
|
||||
struct rtw_5g_vht_ns_pwr_idx_diff vht_4s_diff;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct rtw_txpwr_idx {
|
||||
struct rtw_2g_txpwr_idx pwr_idx_2g;
|
||||
struct rtw_5g_txpwr_idx pwr_idx_5g;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct rtw_channel_params {
|
||||
u8 center_chan;
|
||||
@ -630,6 +634,7 @@ struct rtw_rx_pkt_stat {
|
||||
bool crc_err;
|
||||
bool decrypted;
|
||||
bool is_c2h;
|
||||
bool channel_invalid;
|
||||
|
||||
s32 signal_power;
|
||||
u16 pkt_len;
|
||||
@ -748,7 +753,6 @@ struct rtw_txq {
|
||||
unsigned long flags;
|
||||
};
|
||||
|
||||
#define RTW_BC_MC_MACID 1
|
||||
DECLARE_EWMA(rssi, 10, 16);
|
||||
|
||||
struct rtw_sta_info {
|
||||
@ -762,7 +766,6 @@ struct rtw_sta_info {
|
||||
u8 mac_id;
|
||||
u8 rate_id;
|
||||
enum rtw_bandwidth bw_mode;
|
||||
enum rtw_rf_type rf_type;
|
||||
u8 stbc_en:2;
|
||||
u8 ldpc_en:2;
|
||||
bool sgi_enable;
|
||||
@ -811,7 +814,7 @@ struct rtw_bf_info {
|
||||
struct rtw_vif {
|
||||
enum rtw_net_type net_type;
|
||||
u16 aid;
|
||||
u8 mac_id; /* for STA mode only */
|
||||
u8 mac_id;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 port;
|
||||
@ -848,6 +851,8 @@ struct rtw_regd {
|
||||
};
|
||||
|
||||
struct rtw_chip_ops {
|
||||
int (*power_on)(struct rtw_dev *rtwdev);
|
||||
void (*power_off)(struct rtw_dev *rtwdev);
|
||||
int (*mac_init)(struct rtw_dev *rtwdev);
|
||||
int (*dump_fw_crash)(struct rtw_dev *rtwdev);
|
||||
void (*shutdown)(struct rtw_dev *rtwdev);
|
||||
@ -855,9 +860,8 @@ struct rtw_chip_ops {
|
||||
void (*phy_set_param)(struct rtw_dev *rtwdev);
|
||||
void (*set_channel)(struct rtw_dev *rtwdev, u8 channel,
|
||||
u8 bandwidth, u8 primary_chan_idx);
|
||||
void (*query_rx_desc)(struct rtw_dev *rtwdev, u8 *rx_desc,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_rx_status *rx_status);
|
||||
void (*query_phy_status)(struct rtw_dev *rtwdev, u8 *phy_status,
|
||||
struct rtw_rx_pkt_stat *pkt_stat);
|
||||
u32 (*read_rf)(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
|
||||
u32 addr, u32 mask);
|
||||
bool (*write_rf)(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
|
||||
@ -892,6 +896,7 @@ struct rtw_chip_ops {
|
||||
bool is_tx2_path);
|
||||
void (*config_txrx_mode)(struct rtw_dev *rtwdev, u8 tx_path,
|
||||
u8 rx_path, bool is_tx2_path);
|
||||
void (*led_set)(struct led_classdev *led, enum led_brightness brightness);
|
||||
/* for USB/SDIO only */
|
||||
void (*fill_txdesc_checksum)(struct rtw_dev *rtwdev,
|
||||
struct rtw_tx_pkt_info *pkt_info,
|
||||
@ -1103,17 +1108,20 @@ enum rtw_rfe_fem {
|
||||
struct rtw_rfe_def {
|
||||
const struct rtw_table *phy_pg_tbl;
|
||||
const struct rtw_table *txpwr_lmt_tbl;
|
||||
const struct rtw_pwr_track_tbl *pwr_track_tbl;
|
||||
const struct rtw_table *agc_btg_tbl;
|
||||
};
|
||||
|
||||
#define RTW_DEF_RFE(chip, bb_pg, pwrlmt) { \
|
||||
#define RTW_DEF_RFE(chip, bb_pg, pwrlmt, track) { \
|
||||
.phy_pg_tbl = &rtw ## chip ## _bb_pg_type ## bb_pg ## _tbl, \
|
||||
.txpwr_lmt_tbl = &rtw ## chip ## _txpwr_lmt_type ## pwrlmt ## _tbl, \
|
||||
.pwr_track_tbl = &rtw ## chip ## _pwr_track_type ## track ## _tbl, \
|
||||
}
|
||||
|
||||
#define RTW_DEF_RFE_EXT(chip, bb_pg, pwrlmt, btg) { \
|
||||
#define RTW_DEF_RFE_EXT(chip, bb_pg, pwrlmt, track, btg) { \
|
||||
.phy_pg_tbl = &rtw ## chip ## _bb_pg_type ## bb_pg ## _tbl, \
|
||||
.txpwr_lmt_tbl = &rtw ## chip ## _txpwr_lmt_type ## pwrlmt ## _tbl, \
|
||||
.pwr_track_tbl = &rtw ## chip ## _pwr_track_type ## track ## _tbl, \
|
||||
.agc_btg_tbl = &rtw ## chip ## _agc_btg_type ## btg ## _tbl, \
|
||||
}
|
||||
|
||||
@ -1174,7 +1182,7 @@ enum rtw_fwcd_item {
|
||||
|
||||
/* hardware configuration for each IC */
|
||||
struct rtw_chip_info {
|
||||
struct rtw_chip_ops *ops;
|
||||
const struct rtw_chip_ops *ops;
|
||||
u8 id;
|
||||
|
||||
const char *fw_name;
|
||||
@ -1191,7 +1199,7 @@ struct rtw_chip_info {
|
||||
u32 fw_rxff_size;
|
||||
u16 rsvd_drv_pg_num;
|
||||
u8 band;
|
||||
u8 page_size;
|
||||
u16 page_size;
|
||||
u8 csi_buf_pg_num;
|
||||
u8 dig_max;
|
||||
u8 dig_min;
|
||||
@ -1206,6 +1214,9 @@ struct rtw_chip_info {
|
||||
const struct rtw_fwcd_segs *fwcd_segs;
|
||||
|
||||
u8 usb_tx_agg_desc_num;
|
||||
bool hw_feature_report;
|
||||
u8 c2h_ra_report_size;
|
||||
bool old_datarate_fb_limit;
|
||||
|
||||
u8 default_1ss_tx_path;
|
||||
|
||||
@ -1216,8 +1227,8 @@ struct rtw_chip_info {
|
||||
|
||||
/* init values */
|
||||
u8 sys_func_en;
|
||||
const struct rtw_pwr_seq_cmd **pwr_on_seq;
|
||||
const struct rtw_pwr_seq_cmd **pwr_off_seq;
|
||||
const struct rtw_pwr_seq_cmd * const *pwr_on_seq;
|
||||
const struct rtw_pwr_seq_cmd * const *pwr_off_seq;
|
||||
const struct rtw_rqpn *rqpn_table;
|
||||
const struct rtw_prioq_addrs *prioq_addrs;
|
||||
const struct rtw_page_table *page_table;
|
||||
@ -1244,12 +1255,11 @@ struct rtw_chip_info {
|
||||
u16 dpd_ratemask;
|
||||
u8 iqk_threshold;
|
||||
u8 lck_threshold;
|
||||
const struct rtw_pwr_track_tbl *pwr_track_tbl;
|
||||
|
||||
u8 bfer_su_max_num;
|
||||
u8 bfer_mu_max_num;
|
||||
|
||||
struct rtw_hw_reg_offset *edcca_th;
|
||||
const struct rtw_hw_reg_offset *edcca_th;
|
||||
s8 l2h_th_ini_cs;
|
||||
s8 l2h_th_ini_ad;
|
||||
|
||||
@ -1493,6 +1503,7 @@ struct rtw_coex_stat {
|
||||
u8 bt_hid_slot;
|
||||
u8 bt_a2dp_bitpool;
|
||||
u8 bt_iqk_state;
|
||||
u8 bt_disable_cnt;
|
||||
|
||||
u16 wl_beacon_interval;
|
||||
u8 wl_noisy_level;
|
||||
@ -1716,7 +1727,7 @@ struct rtw_dm_info {
|
||||
bool pwr_trk_init_trigger;
|
||||
struct ewma_thermal avg_thermal[RTW_RF_PATH_MAX];
|
||||
s8 txagc_remnant_cck;
|
||||
s8 txagc_remnant_ofdm;
|
||||
s8 txagc_remnant_ofdm[RTW_RF_PATH_MAX];
|
||||
u8 rx_cck_agc_report_type;
|
||||
|
||||
/* backup dack results for each path and I/Q */
|
||||
@ -1793,6 +1804,8 @@ struct rtw_efuse {
|
||||
bool share_ant;
|
||||
u8 bt_setting;
|
||||
|
||||
u8 usb_mode_switch;
|
||||
|
||||
struct {
|
||||
u8 hci;
|
||||
u8 bw;
|
||||
@ -1837,6 +1850,20 @@ struct rtw_phy_cond {
|
||||
#define BRANCH_ENDIF 3
|
||||
};
|
||||
|
||||
struct rtw_phy_cond2 {
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
u8 type_glna;
|
||||
u8 type_gpa;
|
||||
u8 type_alna;
|
||||
u8 type_apa;
|
||||
#else
|
||||
u8 type_apa;
|
||||
u8 type_alna;
|
||||
u8 type_gpa;
|
||||
u8 type_glna;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct rtw_fifo_conf {
|
||||
/* tx fifo information */
|
||||
u16 rsvd_boundary;
|
||||
@ -1918,6 +1945,7 @@ struct rtw_hal {
|
||||
u8 oem_id;
|
||||
u8 pkg_type;
|
||||
struct rtw_phy_cond phy_cond;
|
||||
struct rtw_phy_cond2 phy_cond2;
|
||||
bool rfe_btg;
|
||||
|
||||
u8 ps_mode;
|
||||
@ -1940,6 +1968,7 @@ struct rtw_hal {
|
||||
u32 antenna_rx;
|
||||
u8 bfee_sts_cap;
|
||||
bool txrx_1ss;
|
||||
bool cck_high_power;
|
||||
|
||||
/* protect tx power section */
|
||||
struct mutex tx_power_mutex;
|
||||
@ -2059,7 +2088,7 @@ struct rtw_dev {
|
||||
bool beacon_loss;
|
||||
struct completion lps_leave_check;
|
||||
|
||||
struct dentry *debugfs;
|
||||
struct rtw_debugfs *debugfs;
|
||||
|
||||
u8 sta_cnt;
|
||||
u32 rts_threshold;
|
||||
@ -2078,6 +2107,10 @@ struct rtw_dev {
|
||||
struct completion fw_scan_density;
|
||||
bool ap_active;
|
||||
|
||||
bool led_registered;
|
||||
char led_name[32];
|
||||
struct led_classdev led_cdev;
|
||||
|
||||
/* hci related data, must be last */
|
||||
u8 priv[] __aligned(sizeof(void *));
|
||||
};
|
||||
@ -2135,6 +2168,17 @@ static inline bool rtw_chip_has_tx_stbc(struct rtw_dev *rtwdev)
|
||||
return rtwdev->chip->tx_stbc;
|
||||
}
|
||||
|
||||
static inline u8 rtw_acquire_macid(struct rtw_dev *rtwdev)
|
||||
{
|
||||
unsigned long mac_id;
|
||||
|
||||
mac_id = find_first_zero_bit(rtwdev->mac_id_map, RTW_MAX_MAC_ID_NUM);
|
||||
if (mac_id < RTW_MAX_MAC_ID_NUM)
|
||||
set_bit(mac_id, rtwdev->mac_id_map);
|
||||
|
||||
return mac_id;
|
||||
}
|
||||
|
||||
static inline void rtw_release_macid(struct rtw_dev *rtwdev, u8 mac_id)
|
||||
{
|
||||
clear_bit(mac_id, rtwdev->mac_id_map);
|
||||
@ -2184,6 +2228,7 @@ void rtw_core_scan_start(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif,
|
||||
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_power_off(struct rtw_dev *rtwdev);
|
||||
void rtw_core_stop(struct rtw_dev *rtwdev);
|
||||
int rtw_chip_info_setup(struct rtw_dev *rtwdev);
|
||||
int rtw_core_init(struct rtw_dev *rtwdev);
|
||||
@ -2198,6 +2243,8 @@ int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
|
||||
void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
|
||||
bool fw_exist);
|
||||
void rtw_fw_recovery(struct rtw_dev *rtwdev);
|
||||
int rtw_wait_firmware_completion(struct rtw_dev *rtwdev);
|
||||
int rtw_power_on(struct rtw_dev *rtwdev);
|
||||
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);
|
||||
|
||||
@ -875,7 +875,7 @@ static int rtw_pci_tx_write_data(struct rtw_dev *rtwdev,
|
||||
pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
|
||||
memset(pkt_desc, 0, tx_pkt_desc_sz);
|
||||
pkt_info->qsel = rtw_pci_get_tx_qsel(skb, queue);
|
||||
rtw_tx_fill_tx_desc(pkt_info, skb);
|
||||
rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
|
||||
dma = dma_map_single(&rtwpci->pdev->dev, skb->data, skb->len,
|
||||
DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(&rtwpci->pdev->dev, dma))
|
||||
@ -1122,7 +1122,7 @@ static u32 rtw_pci_rx_napi(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci,
|
||||
dma_sync_single_for_cpu(rtwdev->dev, dma, RTK_PCI_RX_BUF_SIZE,
|
||||
DMA_FROM_DEVICE);
|
||||
rx_desc = skb->data;
|
||||
chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status);
|
||||
rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status);
|
||||
|
||||
/* offset from rx_desc to payload */
|
||||
pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz +
|
||||
@ -1145,6 +1145,7 @@ static u32 rtw_pci_rx_napi(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci,
|
||||
/* remove rx_desc */
|
||||
skb_pull(new, pkt_offset);
|
||||
|
||||
rtw_update_rx_freq_for_invalid(rtwdev, new, &rx_status, &pkt_stat);
|
||||
rtw_rx_stats(rtwdev, pkt_stat.vif, new);
|
||||
memcpy(new->cb, &rx_status, sizeof(rx_status));
|
||||
ieee80211_rx_napi(rtwdev->hw, NULL, new, napi);
|
||||
@ -1679,6 +1680,7 @@ static struct rtw_hci_ops rtw_pci_ops = {
|
||||
.deep_ps = rtw_pci_deep_ps,
|
||||
.link_ps = rtw_pci_link_ps,
|
||||
.interface_cfg = rtw_pci_interface_cfg,
|
||||
.dynamic_rx_agg = NULL,
|
||||
|
||||
.read8 = rtw_pci_read8,
|
||||
.read16 = rtw_pci_read16,
|
||||
|
||||
@ -18,7 +18,10 @@ struct phy_cfg_pair {
|
||||
};
|
||||
|
||||
union phy_table_tile {
|
||||
struct rtw_phy_cond cond;
|
||||
struct {
|
||||
struct rtw_phy_cond cond;
|
||||
struct rtw_phy_cond2 cond2;
|
||||
} __packed;
|
||||
struct phy_cfg_pair cfg;
|
||||
};
|
||||
|
||||
@ -123,7 +126,7 @@ static void rtw_phy_cck_pd_init(struct rtw_dev *rtwdev)
|
||||
|
||||
void rtw_phy_set_edcca_th(struct rtw_dev *rtwdev, u8 l2h, u8 h2l)
|
||||
{
|
||||
struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
|
||||
const struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
|
||||
|
||||
rtw_write32_mask(rtwdev,
|
||||
edcca_th[EDCCA_TH_L2H_IDX].hw_reg.addr,
|
||||
@ -527,6 +530,13 @@ static void rtw_phy_dig(struct rtw_dev *rtwdev)
|
||||
*/
|
||||
rtw_phy_dig_recorder(dm_info, cur_igi, fa_cnt);
|
||||
|
||||
/* Mitigate beacon loss and connectivity issues, mainly (only?)
|
||||
* in the 5 GHz band
|
||||
*/
|
||||
if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A && rtwdev->beacon_loss &&
|
||||
linked && dm_info->total_fa_cnt < DIG_PERF_FA_TH_EXTRA_HIGH)
|
||||
cur_igi = DIG_CVRG_MIN;
|
||||
|
||||
if (cur_igi != pre_igi)
|
||||
rtw_phy_dig_write(rtwdev, cur_igi);
|
||||
}
|
||||
@ -1041,7 +1051,8 @@ void rtw_phy_setup_phy_cond(struct rtw_dev *rtwdev, u32 pkg)
|
||||
{
|
||||
struct rtw_hal *hal = &rtwdev->hal;
|
||||
struct rtw_efuse *efuse = &rtwdev->efuse;
|
||||
struct rtw_phy_cond cond = {0};
|
||||
struct rtw_phy_cond cond = {};
|
||||
struct rtw_phy_cond2 cond2 = {};
|
||||
|
||||
cond.cut = hal->cut_version ? hal->cut_version : 15;
|
||||
cond.pkg = pkg ? pkg : 15;
|
||||
@ -1061,15 +1072,34 @@ void rtw_phy_setup_phy_cond(struct rtw_dev *rtwdev, u32 pkg)
|
||||
break;
|
||||
}
|
||||
|
||||
hal->phy_cond = cond;
|
||||
if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A ||
|
||||
rtwdev->chip->id == RTW_CHIP_TYPE_8821A) {
|
||||
cond.rfe = 0;
|
||||
cond.rfe |= efuse->ext_lna_2g;
|
||||
cond.rfe |= efuse->ext_pa_2g << 1;
|
||||
cond.rfe |= efuse->ext_lna_5g << 2;
|
||||
cond.rfe |= efuse->ext_pa_5g << 3;
|
||||
cond.rfe |= efuse->btcoex << 4;
|
||||
|
||||
rtw_dbg(rtwdev, RTW_DBG_PHY, "phy cond=0x%08x\n", *((u32 *)&hal->phy_cond));
|
||||
cond2.type_alna = efuse->alna_type;
|
||||
cond2.type_glna = efuse->glna_type;
|
||||
cond2.type_apa = efuse->apa_type;
|
||||
cond2.type_gpa = efuse->gpa_type;
|
||||
}
|
||||
|
||||
hal->phy_cond = cond;
|
||||
hal->phy_cond2 = cond2;
|
||||
|
||||
rtw_dbg(rtwdev, RTW_DBG_PHY, "phy cond=0x%08x cond2=0x%08x\n",
|
||||
*((u32 *)&hal->phy_cond), *((u32 *)&hal->phy_cond2));
|
||||
}
|
||||
|
||||
static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond)
|
||||
static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond,
|
||||
struct rtw_phy_cond2 cond2)
|
||||
{
|
||||
struct rtw_hal *hal = &rtwdev->hal;
|
||||
struct rtw_phy_cond drv_cond = hal->phy_cond;
|
||||
struct rtw_phy_cond2 drv_cond2 = hal->phy_cond2;
|
||||
|
||||
if (cond.cut && cond.cut != drv_cond.cut)
|
||||
return false;
|
||||
@ -1080,8 +1110,29 @@ static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond)
|
||||
if (cond.intf && cond.intf != drv_cond.intf)
|
||||
return false;
|
||||
|
||||
if (cond.rfe != drv_cond.rfe)
|
||||
return false;
|
||||
if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A ||
|
||||
rtwdev->chip->id == RTW_CHIP_TYPE_8821A) {
|
||||
if (!(cond.rfe & 0x0f))
|
||||
return true;
|
||||
|
||||
if ((cond.rfe & drv_cond.rfe) != cond.rfe)
|
||||
return false;
|
||||
|
||||
if ((cond.rfe & BIT(0)) && cond2.type_glna != drv_cond2.type_glna)
|
||||
return false;
|
||||
|
||||
if ((cond.rfe & BIT(1)) && cond2.type_gpa != drv_cond2.type_gpa)
|
||||
return false;
|
||||
|
||||
if ((cond.rfe & BIT(2)) && cond2.type_alna != drv_cond2.type_alna)
|
||||
return false;
|
||||
|
||||
if ((cond.rfe & BIT(3)) && cond2.type_apa != drv_cond2.type_apa)
|
||||
return false;
|
||||
} else {
|
||||
if (cond.rfe != drv_cond.rfe)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1090,7 +1141,8 @@ void rtw_parse_tbl_phy_cond(struct rtw_dev *rtwdev, const struct rtw_table *tbl)
|
||||
{
|
||||
const union phy_table_tile *p = tbl->data;
|
||||
const union phy_table_tile *end = p + tbl->size / 2;
|
||||
struct rtw_phy_cond pos_cond = {0};
|
||||
struct rtw_phy_cond pos_cond = {};
|
||||
struct rtw_phy_cond2 pos_cond2 = {};
|
||||
bool is_matched = true, is_skipped = false;
|
||||
|
||||
BUILD_BUG_ON(sizeof(union phy_table_tile) != sizeof(struct phy_cfg_pair));
|
||||
@ -1109,11 +1161,12 @@ void rtw_parse_tbl_phy_cond(struct rtw_dev *rtwdev, const struct rtw_table *tbl)
|
||||
case BRANCH_ELIF:
|
||||
default:
|
||||
pos_cond = p->cond;
|
||||
pos_cond2 = p->cond2;
|
||||
break;
|
||||
}
|
||||
} else if (p->cond.neg) {
|
||||
if (!is_skipped) {
|
||||
if (check_positive(rtwdev, pos_cond)) {
|
||||
if (check_positive(rtwdev, pos_cond, pos_cond2)) {
|
||||
is_matched = true;
|
||||
is_skipped = true;
|
||||
} else {
|
||||
@ -1470,10 +1523,8 @@ static void rtw_phy_store_tx_power_by_rate(struct rtw_dev *rtwdev,
|
||||
rate = rates[i];
|
||||
if (band == PHY_BAND_2G)
|
||||
hal->tx_pwr_by_rate_offset_2g[rfpath][rate] = offset;
|
||||
else if (band == PHY_BAND_5G)
|
||||
hal->tx_pwr_by_rate_offset_5g[rfpath][rate] = offset;
|
||||
else
|
||||
continue;
|
||||
hal->tx_pwr_by_rate_offset_5g[rfpath][rate] = offset;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2125,8 +2176,8 @@ void rtw_get_tx_power_params(struct rtw_dev *rtwdev, u8 path, u8 rate, u8 bw,
|
||||
|
||||
*limit = rtw_phy_get_tx_power_limit(rtwdev, band, bw, path,
|
||||
rate, ch, regd);
|
||||
*remnant = (rate <= DESC_RATE11M ? dm_info->txagc_remnant_cck :
|
||||
dm_info->txagc_remnant_ofdm);
|
||||
*remnant = rate <= DESC_RATE11M ? dm_info->txagc_remnant_cck :
|
||||
dm_info->txagc_remnant_ofdm[path];
|
||||
*sar = rtw_phy_get_tx_power_sar(rtwdev, hal->sar_band, path, rate);
|
||||
}
|
||||
|
||||
@ -2340,7 +2391,8 @@ void rtw_phy_init_tx_power(struct rtw_dev *rtwdev)
|
||||
void rtw_phy_config_swing_table(struct rtw_dev *rtwdev,
|
||||
struct rtw_swing_table *swing_table)
|
||||
{
|
||||
const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl;
|
||||
const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev);
|
||||
const struct rtw_pwr_track_tbl *tbl = rfe_def->pwr_track_tbl;
|
||||
u8 channel = rtwdev->hal.current_channel;
|
||||
|
||||
if (IS_CH_2G_BAND(channel)) {
|
||||
|
||||
@ -9,12 +9,18 @@
|
||||
#define BIT_FEN_EN_25_1 BIT(13)
|
||||
#define BIT_FEN_ELDR BIT(12)
|
||||
#define BIT_FEN_CPUEN BIT(2)
|
||||
#define BIT_FEN_USBA BIT(2)
|
||||
#define BIT_FEN_BB_GLB_RST BIT(1)
|
||||
#define BIT_FEN_BB_RSTB BIT(0)
|
||||
#define BIT_R_DIS_PRST BIT(6)
|
||||
#define BIT_WLOCK_1C_B6 BIT(5)
|
||||
#define REG_SYS_PW_CTRL 0x0004
|
||||
#define BIT_PFM_WOWL BIT(3)
|
||||
#define BIT_APFM_OFFMAC BIT(9)
|
||||
#define REG_APS_FSMCO 0x0004
|
||||
#define APS_FSMCO_MAC_ENABLE BIT(8)
|
||||
#define APS_FSMCO_MAC_OFF BIT(9)
|
||||
#define APS_FSMCO_HW_POWERDOWN BIT(15)
|
||||
#define REG_SYS_CLK_CTRL 0x0008
|
||||
#define BIT_CPU_CLK_EN BIT(14)
|
||||
|
||||
@ -57,6 +63,8 @@
|
||||
#define BIT_SHIFT_LDO25_VOLTAGE 4
|
||||
#define BIT_LDO25_EN BIT(7)
|
||||
|
||||
#define REG_ACLK_MON 0x3e
|
||||
|
||||
#define REG_GPIO_MUXCFG 0x0040
|
||||
#define BIT_FSPI_EN BIT(19)
|
||||
#define BIT_EN_SIC BIT(12)
|
||||
@ -70,7 +78,19 @@
|
||||
#define BIT_PAPE_SEL_EN BIT(25)
|
||||
#define BIT_DPDT_WL_SEL BIT(24)
|
||||
#define BIT_DPDT_SEL_EN BIT(23)
|
||||
#define BIT_GPIO13_14_WL_CTRL_EN BIT(22)
|
||||
#define BIT_LED2_SV BIT(19)
|
||||
#define BIT_LED2_CM GENMASK(18, 16)
|
||||
#define BIT_LED1_SV BIT(11)
|
||||
#define BIT_LED1_CM GENMASK(10, 8)
|
||||
#define BIT_LED0_SV BIT(3)
|
||||
#define BIT_LED0_CM GENMASK(2, 0)
|
||||
#define BIT_LED_MODE_SW_CTRL 0
|
||||
#define BIT_LED_MODE_RX 6
|
||||
#define BIT_LED_MODE_TX 4
|
||||
#define BIT_LED_MODE_TRX 2
|
||||
#define REG_LEDCFG2 0x004E
|
||||
#define REG_GPIO_PIN_CTRL_2 0x0060
|
||||
#define REG_PAD_CTRL1 0x0064
|
||||
#define BIT_BT_BTG_SEL BIT(31)
|
||||
#define BIT_PAPE_WLBT_SEL BIT(29)
|
||||
@ -89,6 +109,8 @@
|
||||
#define BIT_USB_SUS_DIS BIT(8)
|
||||
#define BIT_SDIO_PAD_E5 BIT(18)
|
||||
|
||||
#define REG_RF_B_CTRL 0x76
|
||||
|
||||
#define REG_AFE_CTRL_4 0x0078
|
||||
#define BIT_CK320M_AFE_EN BIT(4)
|
||||
#define BIT_EN_SYN BIT(15)
|
||||
@ -133,6 +155,19 @@
|
||||
#define REG_PMC_DBG_CTRL1 0xa8
|
||||
#define BITS_PMC_BT_IQK_STS GENMASK(22, 21)
|
||||
|
||||
#define REG_HIMR0 0xb0
|
||||
#define REG_HISR0 0xb4
|
||||
#define REG_HIMR1 0xb8
|
||||
#define REG_HISR1 0xbc
|
||||
|
||||
#define REG_PAD_CTRL2 0x00C4
|
||||
#define BIT_RSM_EN_V1 BIT(16)
|
||||
#define BIT_NO_PDN_CHIPOFF_V1 BIT(17)
|
||||
#define BIT_MASK_USB23_SW_MODE_V1 GENMASK(19, 18)
|
||||
#define BIT_USB3_USB2_TRANSITION BIT(20)
|
||||
#define BIT_USB_MODE_U2 1
|
||||
#define BIT_USB_MODE_U3 2
|
||||
|
||||
#define REG_EFUSE_ACCESS 0x00CF
|
||||
#define EFUSE_ACCESS_ON 0x69
|
||||
#define EFUSE_ACCESS_OFF 0x00
|
||||
@ -176,6 +211,15 @@
|
||||
#define MAC_TRX_ENABLE (BIT_HCI_TXDMA_EN | BIT_HCI_RXDMA_EN | BIT_TXDMA_EN | \
|
||||
BIT_RXDMA_EN | BIT_PROTOCOL_EN | BIT_SCHEDULE_EN | \
|
||||
BIT_MACTXEN | BIT_MACRXEN)
|
||||
#define REG_PBP 0x104
|
||||
#define PBP_RX_MASK 0x0f
|
||||
#define PBP_TX_MASK 0xf0
|
||||
#define PBP_64 0x0
|
||||
#define PBP_128 0x1
|
||||
#define PBP_256 0x2
|
||||
#define PBP_512 0x3
|
||||
#define PBP_1024 0x4
|
||||
|
||||
#define BIT_SHIFT_TXDMA_VOQ_MAP 4
|
||||
#define BIT_MASK_TXDMA_VOQ_MAP 0x3
|
||||
#define BIT_TXDMA_VOQ_MAP(x) \
|
||||
@ -247,6 +291,8 @@
|
||||
#define REG_HMEBOX1 0x01D4
|
||||
#define REG_HMEBOX2 0x01D8
|
||||
#define REG_HMEBOX3 0x01DC
|
||||
#define REG_LLT_INIT 0x01E0
|
||||
#define BIT_LLT_WRITE_ACCESS BIT(30)
|
||||
#define REG_HMEBOX0_EX 0x01F0
|
||||
#define REG_HMEBOX1_EX 0x01F4
|
||||
#define REG_HMEBOX2_EX 0x01F8
|
||||
@ -289,6 +335,7 @@
|
||||
|
||||
#define REG_AUTO_LLT 0x0224
|
||||
#define BIT_AUTO_INIT_LLT BIT(16)
|
||||
#define REG_DWBCN1_CTRL 0x0228
|
||||
#define REG_RQPN_CTRL_1 0x0228
|
||||
#define REG_RQPN_CTRL_2 0x022C
|
||||
#define BIT_LD_RQPN BIT(31)
|
||||
@ -313,7 +360,14 @@
|
||||
#define REG_RXDMA_DPR 0x028C
|
||||
#define REG_RXDMA_MODE 0x0290
|
||||
#define BIT_DMA_MODE BIT(1)
|
||||
#define BIT_DMA_BURST_CNT GENMASK(3, 2)
|
||||
#define BIT_DMA_BURST_SIZE GENMASK(5, 4)
|
||||
#define BIT_DMA_BURST_SIZE_64 2
|
||||
#define BIT_DMA_BURST_SIZE_512 1
|
||||
#define BIT_DMA_BURST_SIZE_1024 0
|
||||
|
||||
#define REG_RXPKTNUM 0x02B0
|
||||
#define REG_EARLY_MODE_CONTROL 0x02BC
|
||||
|
||||
#define REG_INT_MIG 0x0304
|
||||
#define REG_HCI_MIX_CFG 0x03FC
|
||||
@ -321,6 +375,7 @@
|
||||
|
||||
#define REG_BCNQ_INFO 0x0418
|
||||
#define BIT_MGQ_CPU_EMPTY BIT(24)
|
||||
#define REG_TXPKT_EMPTY 0x041A
|
||||
#define REG_FWHW_TXQ_CTRL 0x0420
|
||||
#define BIT_EN_BCNQ_DL BIT(22)
|
||||
#define BIT_EN_WR_FREE_TAIL BIT(20)
|
||||
@ -347,10 +402,12 @@
|
||||
#define REG_AMPDU_MAX_TIME_V1 0x0455
|
||||
#define REG_BCNQ1_BDNY_V1 0x0456
|
||||
#define REG_AMPDU_MAX_TIME 0x0456
|
||||
#define REG_AMPDU_MAX_LENGTH 0x0458
|
||||
#define REG_WMAC_LBK_BF_HD 0x045D
|
||||
#define REG_TX_HANG_CTRL 0x045E
|
||||
#define BIT_EN_GNT_BT_AWAKE BIT(3)
|
||||
#define BIT_EN_EOF_V1 BIT(2)
|
||||
#define REG_FAST_EDCA_CTRL 0x0460
|
||||
#define REG_DATA_SC 0x0483
|
||||
#define REG_ARFR2_V1 0x048C
|
||||
#define REG_ARFRH2_V1 0x0490
|
||||
@ -375,6 +432,8 @@
|
||||
#define REG_PRECNT_CTRL 0x04E5
|
||||
#define BIT_BTCCA_CTRL (BIT(0) | BIT(1))
|
||||
#define BIT_EN_PRECNT BIT(11)
|
||||
#define REG_TX_RPT_CTRL 0x04EC
|
||||
#define REG_TX_RPT_TIME 0x04F0
|
||||
#define REG_DUMMY_PAGE4_V1 0x04FC
|
||||
|
||||
#define REG_EDCA_VO_PARAM 0x0500
|
||||
@ -385,6 +444,7 @@
|
||||
#define BIT_MASK_CWMAX GENMASK(15, 12)
|
||||
#define BIT_MASK_CWMIN GENMASK(11, 8)
|
||||
#define BIT_MASK_AIFS GENMASK(7, 0)
|
||||
#define REG_BCNTCFG 0x0510
|
||||
#define REG_PIFS 0x0512
|
||||
#define REG_SIFS 0x0514
|
||||
#define BIT_SHIFT_SIFS_OFDM_CTX 8
|
||||
@ -511,6 +571,8 @@
|
||||
#define REG_BT_COEX_V2 0x0762
|
||||
#define BIT_GNT_BT_POLARITY BIT(12)
|
||||
#define BIT_LTE_COEX_EN BIT(7)
|
||||
#define REG_GNT_BT 0x0765
|
||||
#define BIT_PTA_SW_CTL GENMASK(4, 3)
|
||||
#define REG_BT_COEX_ENH_INTR_CTRL 0x76E
|
||||
#define BIT_R_GRANTALL_WLMASK BIT(3)
|
||||
#define BIT_STATIS_BT_EN BIT(2)
|
||||
@ -528,14 +590,43 @@
|
||||
#define REG_FPGA0_RFMOD 0x0800
|
||||
#define BIT_CCKEN BIT(24)
|
||||
#define BIT_OFDMEN BIT(25)
|
||||
#define REG_CCK_RPT_FORMAT 0x0804
|
||||
#define BIT_CCK_RPT_FORMAT BIT(16)
|
||||
#define REG_RXPSEL 0x0808
|
||||
#define BIT_RX_PSEL_RST (BIT(28) | BIT(29))
|
||||
#define REG_TXPSEL 0x080C
|
||||
#define REG_RX_GAIN_EN 0x081c
|
||||
#define REG_CCASEL 0x082C
|
||||
#define REG_PDMFTH 0x0830
|
||||
#define REG_BWINDICATION 0x0834
|
||||
#define REG_CCA2ND 0x0838
|
||||
#define REG_L1PKTH 0x0848
|
||||
#define REG_CLKTRK 0x0860
|
||||
#define REG_ADCCLK 0x08AC
|
||||
#define REG_HSSI_READ 0x08B0
|
||||
#define REG_FPGA0_XCD_RF_PARA 0x08B4
|
||||
#define REG_RX_MCS_LIMIT 0x08BC
|
||||
#define REG_ADC160 0x08C4
|
||||
#define REG_ANTSEL_SW 0x0900
|
||||
#define REG_DAC_RSTB 0x090c
|
||||
#define REG_SINGLE_TONE_CONT_TX 0x0914
|
||||
|
||||
#define REG_RFE_CTRL_E 0x0974
|
||||
#define REG_2ND_CCA_CTRL 0x0976
|
||||
#define REG_IQK_COM00 0x0978
|
||||
#define REG_IQK_COM32 0x097c
|
||||
#define REG_IQK_COM64 0x0980
|
||||
#define REG_IQK_COM96 0x0984
|
||||
|
||||
#define REG_FAS 0x09a4
|
||||
#define REG_RXSB 0x0a00
|
||||
#define REG_CCK_RX 0x0a04
|
||||
#define REG_CCK_PD_TH 0x0a0a
|
||||
|
||||
#define REG_CCK0_FAREPORT 0xa2c
|
||||
#define BIT_CCK0_2RX BIT(18)
|
||||
#define BIT_CCK0_MRC BIT(22)
|
||||
#define REG_FA_CCK 0x0a5c
|
||||
|
||||
#define REG_DIS_DPD 0x0a70
|
||||
#define DIS_DPD_MASK GENMASK(9, 0)
|
||||
@ -551,13 +642,109 @@
|
||||
#define DIS_DPD_RATEVHT2SS_MCS1 BIT(9)
|
||||
#define DIS_DPD_RATEALL GENMASK(9, 0)
|
||||
|
||||
#define REG_CNTRST 0x0b58
|
||||
|
||||
#define REG_3WIRE_SWA 0x0c00
|
||||
#define REG_RX_IQC_AB_A 0x0c10
|
||||
#define REG_TXSCALE_A 0x0c1c
|
||||
#define BB_SWING_MASK GENMASK(31, 21)
|
||||
#define REG_TX_AGC_A_CCK_11_CCK_1 0xc20
|
||||
#define REG_TX_AGC_A_OFDM18_OFDM6 0xc24
|
||||
#define REG_TX_AGC_A_OFDM54_OFDM24 0xc28
|
||||
#define REG_TX_AGC_A_MCS3_MCS0 0xc2c
|
||||
#define REG_TX_AGC_A_MCS7_MCS4 0xc30
|
||||
#define REG_TX_AGC_A_MCS11_MCS8 0xc34
|
||||
#define REG_TX_AGC_A_MCS15_MCS12 0xc38
|
||||
#define REG_TX_AGC_A_NSS1_INDEX3_NSS1_INDEX0 0xc3c
|
||||
#define REG_TX_AGC_A_NSS1_INDEX7_NSS1_INDEX4 0xc40
|
||||
#define REG_TX_AGC_A_NSS2_INDEX1_NSS1_INDEX8 0xc44
|
||||
#define REG_TX_AGC_A_NSS2_INDEX5_NSS2_INDEX2 0xc48
|
||||
#define REG_TX_AGC_A_NSS2_INDEX9_NSS2_INDEX6 0xc4c
|
||||
#define REG_RXIGI_A 0x0c50
|
||||
#define REG_TX_PWR_TRAINING_A 0x0c54
|
||||
#define REG_CK_MONHA 0x0c5c
|
||||
#define REG_AFE_PWR1_A 0x0c60
|
||||
#define REG_AFE_PWR2_A 0x0c64
|
||||
#define REG_RX_WAIT_CCA_TX_CCK_RFON_A 0x0c68
|
||||
#define REG_OFDM0_XA_TX_IQ_IMBALANCE 0x0c80
|
||||
#define REG_OFDM0_A_TX_AFE 0x0c84
|
||||
#define REG_OFDM0_XB_TX_IQ_IMBALANCE 0x0c88
|
||||
#define REG_TSSI_TRK_SW 0x0c8c
|
||||
#define REG_LSSI_WRITE_A 0x0c90
|
||||
#define REG_PREDISTA 0x0c90
|
||||
#define REG_TXAGCIDX 0x0c94
|
||||
|
||||
#define REG_RFE_PINMUX_A 0x0cb0
|
||||
#define REG_RFE_INV_A 0x0cb4
|
||||
#define REG_RFE_CTRL8 0x0cb4
|
||||
#define BIT_MASK_RFE_SEL89 GENMASK(7, 0)
|
||||
#define PTA_CTRL_PIN 0x66
|
||||
#define DPDT_CTRL_PIN 0x77
|
||||
#define RFE_INV_MASK 0x3ff00000
|
||||
#define REG_RFECTL_A 0x0cb8
|
||||
#define REG_RFE_INV8 0x0cbd
|
||||
#define BIT_MASK_RFE_INV89 GENMASK(1, 0)
|
||||
#define REG_RFE_INV16 0x0cbe
|
||||
#define BIT_RFE_BUF_EN BIT(3)
|
||||
|
||||
#define REG_IQK_DPD_CFG 0x0cc4
|
||||
#define REG_CFG_PMPD 0x0cc8
|
||||
#define REG_IQC_Y 0x0ccc
|
||||
#define REG_IQC_X 0x0cd4
|
||||
#define REG_INTPO_SETA 0x0ce8
|
||||
|
||||
#define REG_IQKA_END 0x0d00
|
||||
#define REG_PI_READ_A 0x0d04
|
||||
#define REG_SI_READ_A 0x0d08
|
||||
#define REG_IQKB_END 0x0d40
|
||||
#define REG_PI_READ_B 0x0d44
|
||||
#define REG_SI_READ_B 0x0d48
|
||||
|
||||
#define REG_3WIRE_SWB 0x0e00
|
||||
#define REG_RX_IQC_AB_B 0x0e10
|
||||
#define REG_TXSCALE_B 0x0e1c
|
||||
#define REG_TX_AGC_B_CCK_11_CCK_1 0xe20
|
||||
#define REG_TX_AGC_B_OFDM18_OFDM6 0xe24
|
||||
#define REG_TX_AGC_B_OFDM54_OFDM24 0xe28
|
||||
#define REG_TX_AGC_B_MCS3_MCS0 0xe2c
|
||||
#define REG_TX_AGC_B_MCS7_MCS4 0xe30
|
||||
#define REG_TX_AGC_B_MCS11_MCS8 0xe34
|
||||
#define REG_TX_AGC_B_MCS15_MCS12 0xe38
|
||||
#define REG_TX_AGC_B_NSS1_INDEX3_NSS1_INDEX0 0xe3c
|
||||
#define REG_TX_AGC_B_NSS1_INDEX7_NSS1_INDEX4 0xe40
|
||||
#define REG_TX_AGC_B_NSS2_INDEX1_NSS1_INDEX8 0xe44
|
||||
#define REG_TX_AGC_B_NSS2_INDEX5_NSS2_INDEX2 0xe48
|
||||
#define REG_TX_AGC_B_NSS2_INDEX9_NSS2_INDEX6 0xe4c
|
||||
#define REG_RXIGI_B 0x0e50
|
||||
#define REG_TX_PWR_TRAINING_B 0x0e54
|
||||
#define REG_CK_MONHB 0x0e5c
|
||||
#define REG_AFE_PWR1_B 0x0e60
|
||||
#define REG_AFE_PWR2_B 0x0e64
|
||||
#define REG_RX_WAIT_CCA_TX_CCK_RFON_B 0x0e68
|
||||
#define REG_TXTONEB 0x0e80
|
||||
#define REG_RXTONEB 0x0e84
|
||||
#define REG_TXPITMB 0x0e88
|
||||
#define REG_RXPITMB 0x0e8c
|
||||
#define REG_LSSI_WRITE_B 0x0e90
|
||||
#define REG_PREDISTB 0x0e90
|
||||
#define REG_INIDLYB 0x0e94
|
||||
#define REG_RFE_PINMUX_B 0x0eb0
|
||||
#define REG_RFE_INV_B 0x0eb4
|
||||
#define REG_RFECTL_B 0x0eb8
|
||||
#define REG_BPBDB 0x0ec4
|
||||
#define REG_PHYTXONB 0x0ec8
|
||||
#define REG_IQKYB 0x0ecc
|
||||
#define REG_IQKXB 0x0ed4
|
||||
#define REG_INTPO_SETB 0x0ee8
|
||||
|
||||
#define REG_CRC_CCK 0x0f04
|
||||
#define REG_CCA_OFDM 0x0f08
|
||||
#define REG_CRC_VHT 0x0f0c
|
||||
#define REG_CRC_HT 0x0f10
|
||||
#define REG_CRC_OFDM 0x0f14
|
||||
#define REG_FA_OFDM 0x0f48
|
||||
#define REG_CCA_CCK 0x0fcc
|
||||
|
||||
#define REG_ANAPARSW_MAC_0 0x1010
|
||||
#define BIT_CF_L_V2 GENMASK(29, 28)
|
||||
|
||||
@ -568,6 +755,8 @@
|
||||
#define BIT_WL_SECURITY_CLK BIT(15)
|
||||
#define BIT_DDMA_EN BIT(8)
|
||||
|
||||
#define REG_SW_MDIO 0x10C0
|
||||
|
||||
#define REG_H2C_PKT_READADDR 0x10D0
|
||||
#define REG_H2C_PKT_WRITEADDR 0x10D4
|
||||
#define REG_FW_DBG6 0x10F8
|
||||
@ -692,6 +881,20 @@
|
||||
|
||||
#define REG_IGN_GNTBT4 0x4160
|
||||
|
||||
#define REG_USB_MOD 0xf008
|
||||
#define REG_USB3_RXITV 0xf050
|
||||
#define REG_USB2_PHY_ADR 0xfe40
|
||||
#define REG_USB2_PHY_DAT 0xfe41
|
||||
#define REG_USB2_PHY_CMD 0xfe42
|
||||
#define BIT_USB2_PHY_CMD_TRG 0x81
|
||||
#define REG_USB_HRPWM 0xfe58
|
||||
#define REG_USB3_PHY_ADR 0xff0c
|
||||
#define REG_USB3_PHY_DAT_L 0xff0d
|
||||
#define REG_USB3_PHY_DAT_H 0xff0e
|
||||
#define BIT_USB3_PHY_ADR_WR BIT(7)
|
||||
#define BIT_USB3_PHY_ADR_RD BIT(6)
|
||||
#define BIT_USB3_PHY_ADR_MASK GENMASK(5, 0)
|
||||
|
||||
#define RF_MODE 0x00
|
||||
#define RF_MODOPT 0x01
|
||||
#define RF_WLINT 0x01
|
||||
@ -699,7 +902,13 @@
|
||||
#define RF_DTXLOK 0x08
|
||||
#define RF_CFGCH 0x18
|
||||
#define BIT_BAND GENMASK(18, 16)
|
||||
#define RF18_BAND_MASK (BIT(16) | BIT(9) | BIT(8))
|
||||
#define RF18_CHANNEL_MASK (MASKBYTE0)
|
||||
#define RF18_RFSI_MASK (BIT(18) | BIT(17))
|
||||
#define RF_RCK 0x1d
|
||||
#define RF_MODE_TABLE_ADDR 0x30
|
||||
#define RF_MODE_TABLE_DATA0 0x31
|
||||
#define RF_MODE_TABLE_DATA1 0x32
|
||||
#define RF_LUTWA 0x33
|
||||
#define RF_LUTWD1 0x3e
|
||||
#define RF_LUTWD0 0x3f
|
||||
@ -708,10 +917,14 @@
|
||||
#define RF_T_METER 0x42
|
||||
#define RF_BSPAD 0x54
|
||||
#define RF_GAINTX 0x56
|
||||
#define RF_TXMOD 0x58
|
||||
#define RF_TXATANK 0x64
|
||||
#define RF_TXA_PREPAD 0x65
|
||||
#define RF_TRXIQ 0x66
|
||||
#define RF_RXIQGEN 0x8d
|
||||
#define RF_RXBB2 0x8f
|
||||
#define RF_SYN_PFD 0xb0
|
||||
#define RF_LCK 0xb4
|
||||
#define RF_XTALX2 0xb8
|
||||
#define RF_SYN_CTRL 0xbb
|
||||
#define RF_MALSEL 0xbe
|
||||
|
||||
@ -29,9 +29,6 @@
|
||||
#define TBTT_PROHIBIT_HOLD_TIME 0x80
|
||||
#define TBTT_PROHIBIT_HOLD_TIME_STOP_BCN 0x64
|
||||
|
||||
/* raw pkt_stat->drv_info_sz is in unit of 8-bytes */
|
||||
#define RX_DRV_INFO_SZ_UNIT_8703B 8
|
||||
|
||||
#define TRANS_SEQ_END \
|
||||
0xFFFF, \
|
||||
RTW_PWR_CUT_ALL_MSK, \
|
||||
@ -481,14 +478,14 @@ static const struct rtw_pwr_seq_cmd trans_act_to_lps_8703b[] = {
|
||||
{TRANS_SEQ_END},
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_seq_cmd *card_enable_flow_8703b[] = {
|
||||
static const struct rtw_pwr_seq_cmd * const card_enable_flow_8703b[] = {
|
||||
trans_pre_enable_8703b,
|
||||
trans_carddis_to_cardemu_8703b,
|
||||
trans_cardemu_to_act_8703b,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_seq_cmd *card_disable_flow_8703b[] = {
|
||||
static const struct rtw_pwr_seq_cmd * const card_disable_flow_8703b[] = {
|
||||
trans_act_to_lps_8703b,
|
||||
trans_act_to_reset_mcu_8703b,
|
||||
trans_act_to_cardemu_8703b,
|
||||
@ -496,11 +493,6 @@ static const struct rtw_pwr_seq_cmd *card_disable_flow_8703b[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct rtw_rfe_def rtw8703b_rfe_defs[] = {
|
||||
[0] = { .phy_pg_tbl = &rtw8703b_bb_pg_tbl,
|
||||
.txpwr_lmt_tbl = &rtw8703b_txpwr_lmt_tbl,},
|
||||
};
|
||||
|
||||
static const struct rtw_page_table page_table_8703b[] = {
|
||||
{12, 2, 2, 0, 1},
|
||||
{12, 2, 2, 0, 1},
|
||||
@ -642,7 +634,7 @@ static void rtw8703b_pwrtrack_init(struct rtw_dev *rtwdev)
|
||||
dm_info->pwr_trk_init_trigger = true;
|
||||
dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k;
|
||||
dm_info->txagc_remnant_cck = 0;
|
||||
dm_info->txagc_remnant_ofdm = 0;
|
||||
dm_info->txagc_remnant_ofdm[RF_PATH_A] = 0;
|
||||
}
|
||||
|
||||
static void rtw8703b_phy_set_param(struct rtw_dev *rtwdev)
|
||||
@ -913,7 +905,7 @@ static void rtw8703b_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw,
|
||||
rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x0);
|
||||
rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x0);
|
||||
rtw_write32_mask(rtwdev, REG_OFDM0_TX_PSD_NOISE,
|
||||
GENMASK(31, 20), 0x0);
|
||||
GENMASK(31, 30), 0x0);
|
||||
rtw_write32(rtwdev, REG_BBRX_DFIR, 0x4A880000);
|
||||
rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x19F60000);
|
||||
break;
|
||||
@ -1034,57 +1026,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
|
||||
query_phy_status_ofdm(rtwdev, phy_status, pkt_stat);
|
||||
}
|
||||
|
||||
static void rtw8703b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct ieee80211_hdr *hdr;
|
||||
u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
|
||||
u8 *phy_status = NULL;
|
||||
|
||||
memset(pkt_stat, 0, sizeof(*pkt_stat));
|
||||
|
||||
pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
|
||||
pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
|
||||
pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
|
||||
pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
|
||||
GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
|
||||
pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
|
||||
pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
|
||||
pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
|
||||
pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
|
||||
pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
|
||||
pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
|
||||
pkt_stat->ppdu_cnt = 0;
|
||||
pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
|
||||
|
||||
pkt_stat->drv_info_sz *= RX_DRV_INFO_SZ_UNIT_8703B;
|
||||
|
||||
if (pkt_stat->is_c2h)
|
||||
return;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
|
||||
pkt_stat->drv_info_sz);
|
||||
|
||||
pkt_stat->bw = GET_RX_DESC_BW(rx_desc);
|
||||
|
||||
if (pkt_stat->phy_status) {
|
||||
phy_status = rx_desc + desc_sz + pkt_stat->shift;
|
||||
query_phy_status(rtwdev, phy_status, pkt_stat);
|
||||
}
|
||||
|
||||
rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
|
||||
|
||||
/* Rtl8723cs driver checks for size < 14 or size > 8192 and
|
||||
* simply drops the packet. Maybe this should go into
|
||||
* rtw_rx_fill_rx_status()?
|
||||
*/
|
||||
if (pkt_stat->pkt_len == 0) {
|
||||
rx_status->flag |= RX_FLAG_NO_PSDU;
|
||||
rtw_dbg(rtwdev, RTW_DBG_RX, "zero length packet");
|
||||
}
|
||||
}
|
||||
|
||||
#define ADDA_ON_VAL_8703B 0x03c00014
|
||||
|
||||
static
|
||||
@ -1269,9 +1210,9 @@ static u8 rtw8703b_iqk_rx_path(struct rtw_dev *rtwdev,
|
||||
rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x38008c1c);
|
||||
rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c);
|
||||
rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c);
|
||||
rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x8216000f);
|
||||
rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x8214030f);
|
||||
rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28110000);
|
||||
rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x28110000);
|
||||
rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x82110000);
|
||||
rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000);
|
||||
|
||||
/* LOK setting */
|
||||
@ -1443,7 +1384,7 @@ void rtw8703b_iqk_fill_a_matrix(struct rtw_dev *rtwdev, const s32 result[])
|
||||
return;
|
||||
|
||||
tmp_rx_iqi |= FIELD_PREP(BIT_MASK_RXIQ_S1_X, result[IQK_S1_RX_X]);
|
||||
tmp_rx_iqi |= FIELD_PREP(BIT_MASK_RXIQ_S1_Y1, result[IQK_S1_RX_X]);
|
||||
tmp_rx_iqi |= FIELD_PREP(BIT_MASK_RXIQ_S1_Y1, result[IQK_S1_RX_Y]);
|
||||
rtw_write32(rtwdev, REG_A_RXIQI, tmp_rx_iqi);
|
||||
rtw_write32_mask(rtwdev, REG_RXIQK_MATRIX_LSB_11N, BIT_MASK_RXIQ_S1_Y2,
|
||||
BIT_SET_RXIQ_S1_Y2(result[IQK_S1_RX_Y]));
|
||||
@ -1655,7 +1596,7 @@ static void rtw8703b_pwrtrack_set_ofdm_pwr(struct rtw_dev *rtwdev, s8 swing_idx,
|
||||
{
|
||||
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
|
||||
|
||||
dm_info->txagc_remnant_ofdm = txagc_idx;
|
||||
dm_info->txagc_remnant_ofdm[RF_PATH_A] = txagc_idx;
|
||||
|
||||
/* Only path A is calibrated for rtl8703b */
|
||||
rtw8703b_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A);
|
||||
@ -1884,6 +1825,12 @@ static const struct rtw_pwr_track_tbl rtw8703b_rtw_pwr_track_tbl = {
|
||||
.pwrtrk_xtal_p = rtw8703b_pwrtrk_xtal_p,
|
||||
};
|
||||
|
||||
static const struct rtw_rfe_def rtw8703b_rfe_defs[] = {
|
||||
[0] = { .phy_pg_tbl = &rtw8703b_bb_pg_tbl,
|
||||
.txpwr_lmt_tbl = &rtw8703b_txpwr_lmt_tbl,
|
||||
.pwr_track_tbl = &rtw8703b_rtw_pwr_track_tbl, },
|
||||
};
|
||||
|
||||
/* Shared-Antenna Coex Table */
|
||||
static const struct coex_table_para table_sant_8703b[] = {
|
||||
{0xffffffff, 0xffffffff}, /* case-0 */
|
||||
@ -1953,14 +1900,16 @@ static const struct coex_tdma_para tdma_sant_8703b[] = {
|
||||
{ {0x61, 0x08, 0x03, 0x11, 0x11} },
|
||||
};
|
||||
|
||||
static struct rtw_chip_ops rtw8703b_ops = {
|
||||
static const struct rtw_chip_ops rtw8703b_ops = {
|
||||
.power_on = rtw_power_on,
|
||||
.power_off = rtw_power_off,
|
||||
.mac_init = rtw8723x_mac_init,
|
||||
.dump_fw_crash = NULL,
|
||||
.shutdown = NULL,
|
||||
.read_efuse = rtw8703b_read_efuse,
|
||||
.phy_set_param = rtw8703b_phy_set_param,
|
||||
.set_channel = rtw8703b_set_channel,
|
||||
.query_rx_desc = rtw8703b_query_rx_desc,
|
||||
.query_phy_status = query_phy_status,
|
||||
.read_rf = rtw_phy_read_rf_sipi,
|
||||
.write_rf = rtw_phy_write_rf_reg_sipi,
|
||||
.set_tx_power_index = rtw8723x_set_tx_power_index,
|
||||
@ -2026,6 +1975,9 @@ const struct rtw_chip_info rtw8703b_hw_spec = {
|
||||
.max_power_index = 0x3f,
|
||||
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
|
||||
.usb_tx_agg_desc_num = 1, /* Not sure if this chip has USB interface */
|
||||
.hw_feature_report = true,
|
||||
.c2h_ra_report_size = 7,
|
||||
.old_datarate_fb_limit = true,
|
||||
|
||||
.path_div_supported = false,
|
||||
.ht_supported = true,
|
||||
@ -2058,7 +2010,6 @@ const struct rtw_chip_info rtw8703b_hw_spec = {
|
||||
.rfe_defs_size = ARRAY_SIZE(rtw8703b_rfe_defs),
|
||||
|
||||
.iqk_threshold = 8,
|
||||
.pwr_track_tbl = &rtw8703b_rtw_pwr_track_tbl,
|
||||
|
||||
/* WOWLAN firmware exists, but not implemented yet */
|
||||
.wow_fw_name = "rtw88/rtw8703b_wow_fw.bin",
|
||||
|
||||
@ -79,7 +79,7 @@ static void rtw8723d_pwrtrack_init(struct rtw_dev *rtwdev)
|
||||
dm_info->pwr_trk_init_trigger = true;
|
||||
dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k;
|
||||
dm_info->txagc_remnant_cck = 0;
|
||||
dm_info->txagc_remnant_ofdm = 0;
|
||||
dm_info->txagc_remnant_ofdm[RF_PATH_A] = 0;
|
||||
}
|
||||
|
||||
static void rtw8723d_phy_set_param(struct rtw_dev *rtwdev)
|
||||
@ -227,47 +227,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
|
||||
}
|
||||
}
|
||||
|
||||
static void rtw8723d_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct ieee80211_hdr *hdr;
|
||||
u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
|
||||
u8 *phy_status = NULL;
|
||||
|
||||
memset(pkt_stat, 0, sizeof(*pkt_stat));
|
||||
|
||||
pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
|
||||
pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
|
||||
pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
|
||||
pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
|
||||
GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
|
||||
pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
|
||||
pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
|
||||
pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
|
||||
pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
|
||||
pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
|
||||
pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
|
||||
pkt_stat->ppdu_cnt = 0;
|
||||
pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
|
||||
|
||||
/* drv_info_sz is in unit of 8-bytes */
|
||||
pkt_stat->drv_info_sz *= 8;
|
||||
|
||||
/* c2h cmd pkt's rx/phy status is not interested */
|
||||
if (pkt_stat->is_c2h)
|
||||
return;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
|
||||
pkt_stat->drv_info_sz);
|
||||
if (pkt_stat->phy_status) {
|
||||
phy_status = rx_desc + desc_sz + pkt_stat->shift;
|
||||
query_phy_status(rtwdev, phy_status, pkt_stat);
|
||||
}
|
||||
|
||||
rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
|
||||
}
|
||||
|
||||
static bool rtw8723d_check_spur_ov_thres(struct rtw_dev *rtwdev,
|
||||
u8 channel, u32 thres)
|
||||
{
|
||||
@ -1306,7 +1265,7 @@ static void rtw8723d_pwrtrack_set_ofdm_pwr(struct rtw_dev *rtwdev, s8 swing_idx,
|
||||
{
|
||||
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
|
||||
|
||||
dm_info->txagc_remnant_ofdm = txagc_idx;
|
||||
dm_info->txagc_remnant_ofdm[RF_PATH_A] = txagc_idx;
|
||||
|
||||
rtw8723d_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A);
|
||||
rtw8723d_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_B);
|
||||
@ -1430,10 +1389,12 @@ static void rtw8723d_pwr_track(struct rtw_dev *rtwdev)
|
||||
dm_info->pwr_trk_triggered = false;
|
||||
}
|
||||
|
||||
static struct rtw_chip_ops rtw8723d_ops = {
|
||||
static const struct rtw_chip_ops rtw8723d_ops = {
|
||||
.power_on = rtw_power_on,
|
||||
.power_off = rtw_power_off,
|
||||
.phy_set_param = rtw8723d_phy_set_param,
|
||||
.read_efuse = rtw8723x_read_efuse,
|
||||
.query_rx_desc = rtw8723d_query_rx_desc,
|
||||
.query_phy_status = query_phy_status,
|
||||
.set_channel = rtw8723d_set_channel,
|
||||
.mac_init = rtw8723x_mac_init,
|
||||
.shutdown = rtw8723d_shutdown,
|
||||
@ -1788,7 +1749,7 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8723d[] = {
|
||||
RTW_PWR_CMD_END, 0, 0},
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_seq_cmd *card_enable_flow_8723d[] = {
|
||||
static const struct rtw_pwr_seq_cmd * const card_enable_flow_8723d[] = {
|
||||
trans_carddis_to_cardemu_8723d,
|
||||
trans_cardemu_to_act_8723d,
|
||||
NULL
|
||||
@ -2004,7 +1965,7 @@ static const struct rtw_pwr_seq_cmd trans_act_to_post_carddis_8723d[] = {
|
||||
RTW_PWR_CMD_END, 0, 0},
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_seq_cmd *card_disable_flow_8723d[] = {
|
||||
static const struct rtw_pwr_seq_cmd * const card_disable_flow_8723d[] = {
|
||||
trans_act_to_lps_8723d,
|
||||
trans_act_to_pre_carddis_8723d,
|
||||
trans_act_to_cardemu_8723d,
|
||||
@ -2059,11 +2020,6 @@ static const struct rtw_intf_phy_para_table phy_para_table_8723d = {
|
||||
.n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8723d),
|
||||
};
|
||||
|
||||
static const struct rtw_rfe_def rtw8723d_rfe_defs[] = {
|
||||
[0] = { .phy_pg_tbl = &rtw8723d_bb_pg_tbl,
|
||||
.txpwr_lmt_tbl = &rtw8723d_txpwr_lmt_tbl,},
|
||||
};
|
||||
|
||||
static const u8 rtw8723d_pwrtrk_2gb_n[] = {
|
||||
0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5,
|
||||
6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10
|
||||
@ -2127,6 +2083,12 @@ static const struct rtw_pwr_track_tbl rtw8723d_rtw_pwr_track_tbl = {
|
||||
.pwrtrk_xtal_n = rtw8723d_pwrtrk_xtal_n,
|
||||
};
|
||||
|
||||
static const struct rtw_rfe_def rtw8723d_rfe_defs[] = {
|
||||
[0] = { .phy_pg_tbl = &rtw8723d_bb_pg_tbl,
|
||||
.txpwr_lmt_tbl = &rtw8723d_txpwr_lmt_tbl,
|
||||
.pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl, },
|
||||
};
|
||||
|
||||
static const struct rtw_reg_domain coex_info_hw_regs_8723d[] = {
|
||||
{0x948, MASKDWORD, RTW_REG_DOMAIN_MAC32},
|
||||
{0x67, BIT(7), RTW_REG_DOMAIN_MAC8},
|
||||
@ -2172,6 +2134,9 @@ const struct rtw_chip_info rtw8723d_hw_spec = {
|
||||
.page_size = TX_PAGE_SIZE,
|
||||
.dig_min = 0x20,
|
||||
.usb_tx_agg_desc_num = 1,
|
||||
.hw_feature_report = true,
|
||||
.c2h_ra_report_size = 7,
|
||||
.old_datarate_fb_limit = true,
|
||||
.ht_supported = true,
|
||||
.vht_supported = false,
|
||||
.lps_deep_mode_supported = 0,
|
||||
@ -2195,7 +2160,6 @@ const struct rtw_chip_info rtw8723d_hw_spec = {
|
||||
.rfe_defs = rtw8723d_rfe_defs,
|
||||
.rfe_defs_size = ARRAY_SIZE(rtw8723d_rfe_defs),
|
||||
.rx_ldpc = false,
|
||||
.pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl,
|
||||
.iqk_threshold = 8,
|
||||
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
|
||||
.max_scan_ie_len = IEEE80211_MAX_DATA_LEN,
|
||||
|
||||
@ -598,7 +598,8 @@ void __rtw8723x_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path,
|
||||
u8 delta)
|
||||
{
|
||||
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
|
||||
const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl;
|
||||
const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev);
|
||||
const struct rtw_pwr_track_tbl *tbl = rfe_def->pwr_track_tbl;
|
||||
const s8 *pwrtrk_xtal;
|
||||
s8 xtal_cap;
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@ struct rtw8723xe_efuse {
|
||||
u8 device_id[2];
|
||||
u8 sub_vendor_id[2];
|
||||
u8 sub_device_id[2];
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct rtw8723xu_efuse {
|
||||
u8 res4[48]; /* 0xd0 */
|
||||
@ -56,12 +56,12 @@ struct rtw8723xu_efuse {
|
||||
u8 usb_option; /* 0x104 */
|
||||
u8 res5[2]; /* 0x105 */
|
||||
u8 mac_addr[ETH_ALEN]; /* 0x107 */
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct rtw8723xs_efuse {
|
||||
u8 res4[0x4a]; /* 0xd0 */
|
||||
u8 mac_addr[ETH_ALEN]; /* 0x11a */
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct rtw8723x_efuse {
|
||||
__le16 rtl_id;
|
||||
@ -96,7 +96,7 @@ struct rtw8723x_efuse {
|
||||
struct rtw8723xu_efuse u;
|
||||
struct rtw8723xs_efuse s;
|
||||
};
|
||||
};
|
||||
} __packed;
|
||||
|
||||
#define RTW8723X_IQK_ADDA_REG_NUM 16
|
||||
#define RTW8723X_IQK_MAC8_REG_NUM 3
|
||||
|
||||
1122
sys/contrib/dev/rtw88/rtw8812a.c
Normal file
1122
sys/contrib/dev/rtw88/rtw8812a.c
Normal file
File diff suppressed because it is too large
Load Diff
10
sys/contrib/dev/rtw88/rtw8812a.h
Normal file
10
sys/contrib/dev/rtw88/rtw8812a.h
Normal file
@ -0,0 +1,10 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2024 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW8812A_H__
|
||||
#define __RTW8812A_H__
|
||||
|
||||
extern const struct rtw_chip_info rtw8812a_hw_spec;
|
||||
|
||||
#endif
|
||||
2812
sys/contrib/dev/rtw88/rtw8812a_table.c
Normal file
2812
sys/contrib/dev/rtw88/rtw8812a_table.c
Normal file
File diff suppressed because it is too large
Load Diff
26
sys/contrib/dev/rtw88/rtw8812a_table.h
Normal file
26
sys/contrib/dev/rtw88/rtw8812a_table.h
Normal file
@ -0,0 +1,26 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2024 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW8812A_TABLE_H__
|
||||
#define __RTW8812A_TABLE_H__
|
||||
|
||||
extern const struct rtw_table rtw8812a_mac_tbl;
|
||||
extern const struct rtw_table rtw8812a_agc_tbl;
|
||||
extern const struct rtw_table rtw8812a_agc_diff_lb_tbl;
|
||||
extern const struct rtw_table rtw8812a_agc_diff_hb_tbl;
|
||||
extern const struct rtw_table rtw8812a_bb_tbl;
|
||||
extern const struct rtw_table rtw8812a_bb_pg_tbl;
|
||||
extern const struct rtw_table rtw8812a_bb_pg_rfe3_tbl;
|
||||
extern const struct rtw_table rtw8812a_rf_a_tbl;
|
||||
extern const struct rtw_table rtw8812a_rf_b_tbl;
|
||||
extern const struct rtw_table rtw8812a_txpwr_lmt_tbl;
|
||||
|
||||
extern const struct rtw_pwr_seq_cmd * const card_enable_flow_8812a[];
|
||||
extern const struct rtw_pwr_seq_cmd * const enter_lps_flow_8812a[];
|
||||
extern const struct rtw_pwr_seq_cmd * const card_disable_flow_8812a[];
|
||||
|
||||
extern const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_tbl;
|
||||
extern const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_rfe3_tbl;
|
||||
|
||||
#endif
|
||||
94
sys/contrib/dev/rtw88/rtw8812au.c
Normal file
94
sys/contrib/dev/rtw88/rtw8812au.c
Normal file
@ -0,0 +1,94 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/* Copyright(c) 2024 Realtek Corporation
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/usb.h>
|
||||
#include "main.h"
|
||||
#include "rtw8812a.h"
|
||||
#include "usb.h"
|
||||
|
||||
static const struct usb_device_id rtw_8812au_id_table[] = {
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x8812, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x881a, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x881b, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x881c, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0409, 0x0408, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* NEC */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x025d, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Buffalo */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x04bb, 0x0952, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* I-O DATA */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x1106, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Belkin */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x1109, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Belkin */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0586, 0x3426, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* ZyXEL */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0789, 0x016e, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Logitec */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x07b8, 0x8812, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Abocom */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9051, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Netgear */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x17d2, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* ASUS */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0074, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Sitecom */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0022, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Hawking */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x1058, 0x0632, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* WD */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x003f, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Linksys */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x148f, 0x9097, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Amped Wireless */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x1740, 0x0100, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* EnGenius */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x330e, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* D-Link */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3313, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* D-Link */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3315, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* D-Link */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3316, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* D-Link */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab30, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Planex */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x805b, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TRENDnet */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0101, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0103, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x010d, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x010e, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x010f, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0122, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2604, 0x0012, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Tenda */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa822, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Edimax */
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, rtw_8812au_id_table);
|
||||
|
||||
static struct usb_driver rtw_8812au_driver = {
|
||||
.name = "rtw_8812au",
|
||||
.id_table = rtw_8812au_id_table,
|
||||
.probe = rtw_usb_probe,
|
||||
.disconnect = rtw_usb_disconnect,
|
||||
};
|
||||
module_usb_driver(rtw_8812au_driver);
|
||||
|
||||
MODULE_AUTHOR("Bitterblue Smith <rtl8821cerfe2@gmail.com>");
|
||||
MODULE_DESCRIPTION("Realtek 802.11ac wireless 8812au driver");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
1223
sys/contrib/dev/rtw88/rtw8821a.c
Normal file
1223
sys/contrib/dev/rtw88/rtw8821a.c
Normal file
File diff suppressed because it is too large
Load Diff
10
sys/contrib/dev/rtw88/rtw8821a.h
Normal file
10
sys/contrib/dev/rtw88/rtw8821a.h
Normal file
@ -0,0 +1,10 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2024 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW8821A_H__
|
||||
#define __RTW8821A_H__
|
||||
|
||||
extern const struct rtw_chip_info rtw8821a_hw_spec;
|
||||
|
||||
#endif
|
||||
2350
sys/contrib/dev/rtw88/rtw8821a_table.c
Normal file
2350
sys/contrib/dev/rtw88/rtw8821a_table.c
Normal file
File diff suppressed because it is too large
Load Diff
21
sys/contrib/dev/rtw88/rtw8821a_table.h
Normal file
21
sys/contrib/dev/rtw88/rtw8821a_table.h
Normal file
@ -0,0 +1,21 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2024 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW8821A_TABLE_H__
|
||||
#define __RTW8821A_TABLE_H__
|
||||
|
||||
extern const struct rtw_table rtw8821a_mac_tbl;
|
||||
extern const struct rtw_table rtw8821a_agc_tbl;
|
||||
extern const struct rtw_table rtw8821a_bb_tbl;
|
||||
extern const struct rtw_table rtw8821a_bb_pg_tbl;
|
||||
extern const struct rtw_table rtw8821a_rf_a_tbl;
|
||||
extern const struct rtw_table rtw8821a_txpwr_lmt_tbl;
|
||||
|
||||
extern const struct rtw_pwr_seq_cmd * const card_enable_flow_8821a[];
|
||||
extern const struct rtw_pwr_seq_cmd * const enter_lps_flow_8821a[];
|
||||
extern const struct rtw_pwr_seq_cmd * const card_disable_flow_8821a[];
|
||||
|
||||
extern const struct rtw_pwr_track_tbl rtw8821a_rtw_pwr_track_tbl;
|
||||
|
||||
#endif
|
||||
78
sys/contrib/dev/rtw88/rtw8821au.c
Normal file
78
sys/contrib/dev/rtw88/rtw8821au.c
Normal file
@ -0,0 +1,78 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/* Copyright(c) 2024 Realtek Corporation
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/usb.h>
|
||||
#include "main.h"
|
||||
#include "rtw8821a.h"
|
||||
#include "usb.h"
|
||||
|
||||
static const struct usb_device_id rtw_8821au_id_table[] = {
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x0811, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x0820, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x0821, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x8822, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x0823, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xa811, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x0242, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Buffalo */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x029b, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Buffalo */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x04bb, 0x0953, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* I-O DATA */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4007, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* ELECOM */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x400e, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* ELECOM */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x400f, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* ELECOM */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9052, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Netgear */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0023, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* HAWKING */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3314, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* D-Link */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3318, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* D-Link */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab32, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Planex */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x804b, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* TRENDnet */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x011e, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* TP Link */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x011f, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* TP Link */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0120, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* TP Link */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3823, 0x6249, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Obihai */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa811, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Edimax */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa812, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Edimax */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa813, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Edimax */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xb611, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Edimax */
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, rtw_8821au_id_table);
|
||||
|
||||
static struct usb_driver rtw_8821au_driver = {
|
||||
.name = "rtw_8821au",
|
||||
.id_table = rtw_8821au_id_table,
|
||||
.probe = rtw_usb_probe,
|
||||
.disconnect = rtw_usb_disconnect,
|
||||
};
|
||||
module_usb_driver(rtw_8821au_driver);
|
||||
|
||||
MODULE_AUTHOR("Bitterblue Smith <rtl8821cerfe2@gmail.com>");
|
||||
MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821au/8811au driver");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
@ -679,47 +679,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
|
||||
}
|
||||
}
|
||||
|
||||
static void rtw8821c_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct ieee80211_hdr *hdr;
|
||||
u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
|
||||
u8 *phy_status = NULL;
|
||||
|
||||
memset(pkt_stat, 0, sizeof(*pkt_stat));
|
||||
|
||||
pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
|
||||
pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
|
||||
pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
|
||||
pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
|
||||
GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
|
||||
pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
|
||||
pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
|
||||
pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
|
||||
pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
|
||||
pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
|
||||
pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
|
||||
pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc);
|
||||
pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
|
||||
|
||||
/* drv_info_sz is in unit of 8-bytes */
|
||||
pkt_stat->drv_info_sz *= 8;
|
||||
|
||||
/* c2h cmd pkt's rx/phy status is not interested */
|
||||
if (pkt_stat->is_c2h)
|
||||
return;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
|
||||
pkt_stat->drv_info_sz);
|
||||
if (pkt_stat->phy_status) {
|
||||
phy_status = rx_desc + desc_sz + pkt_stat->shift;
|
||||
query_phy_status(rtwdev, phy_status, pkt_stat);
|
||||
}
|
||||
|
||||
rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
|
||||
}
|
||||
|
||||
static void
|
||||
rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
|
||||
{
|
||||
@ -1247,6 +1206,24 @@ static void rtw8821c_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl)
|
||||
dm_info->cck_pd_default + new_lvl * 2);
|
||||
}
|
||||
|
||||
static void rtw8821c_led_set(struct led_classdev *led,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev);
|
||||
u32 ledcfg;
|
||||
|
||||
ledcfg = rtw_read32(rtwdev, REG_LED_CFG);
|
||||
u32p_replace_bits(&ledcfg, BIT_LED_MODE_SW_CTRL, BIT_LED2_CM);
|
||||
ledcfg &= ~BIT_GPIO13_14_WL_CTRL_EN;
|
||||
|
||||
if (brightness == LED_OFF)
|
||||
ledcfg |= BIT_LED2_SV;
|
||||
else
|
||||
ledcfg &= ~BIT_LED2_SV;
|
||||
|
||||
rtw_write32(rtwdev, REG_LED_CFG, ledcfg);
|
||||
}
|
||||
|
||||
static void rtw8821c_fill_txdesc_checksum(struct rtw_dev *rtwdev,
|
||||
struct rtw_tx_pkt_info *pkt_info,
|
||||
u8 *txdesc)
|
||||
@ -1254,7 +1231,7 @@ static void rtw8821c_fill_txdesc_checksum(struct rtw_dev *rtwdev,
|
||||
fill_txdesc_checksum_common(txdesc, 16);
|
||||
}
|
||||
|
||||
static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = {
|
||||
static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = {
|
||||
{0x0086,
|
||||
RTW_PWR_CUT_ALL_MSK,
|
||||
RTW_PWR_INTF_SDIO_MSK,
|
||||
@ -1292,7 +1269,7 @@ static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = {
|
||||
RTW_PWR_CMD_END, 0, 0},
|
||||
};
|
||||
|
||||
static struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = {
|
||||
static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = {
|
||||
{0x0020,
|
||||
RTW_PWR_CUT_ALL_MSK,
|
||||
RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
|
||||
@ -1396,7 +1373,7 @@ static struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = {
|
||||
RTW_PWR_CMD_END, 0, 0},
|
||||
};
|
||||
|
||||
static struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = {
|
||||
static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = {
|
||||
{0x0093,
|
||||
RTW_PWR_CUT_ALL_MSK,
|
||||
RTW_PWR_INTF_ALL_MSK,
|
||||
@ -1454,7 +1431,7 @@ static struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = {
|
||||
RTW_PWR_CMD_END, 0, 0},
|
||||
};
|
||||
|
||||
static struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = {
|
||||
static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = {
|
||||
{0x0007,
|
||||
RTW_PWR_CUT_ALL_MSK,
|
||||
RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
|
||||
@ -1567,13 +1544,13 @@ static struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = {
|
||||
RTW_PWR_CMD_END, 0, 0},
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_seq_cmd *card_enable_flow_8821c[] = {
|
||||
static const struct rtw_pwr_seq_cmd * const card_enable_flow_8821c[] = {
|
||||
trans_carddis_to_cardemu_8821c,
|
||||
trans_cardemu_to_act_8821c,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_seq_cmd *card_disable_flow_8821c[] = {
|
||||
static const struct rtw_pwr_seq_cmd * const card_disable_flow_8821c[] = {
|
||||
trans_act_to_cardemu_8821c,
|
||||
trans_cardemu_to_carddis_8821c,
|
||||
NULL
|
||||
@ -1622,14 +1599,7 @@ static const struct rtw_intf_phy_para_table phy_para_table_8821c = {
|
||||
.n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8821c),
|
||||
};
|
||||
|
||||
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[] = {
|
||||
static const struct rtw_hw_reg rtw8821c_dig[] = {
|
||||
[0] = { .addr = 0xc50, .mask = 0x7f },
|
||||
};
|
||||
|
||||
@ -1639,7 +1609,7 @@ static const struct rtw_ltecoex_addr rtw8821c_ltecoex_addr = {
|
||||
.rdata = LTECOEX_READ_DATA,
|
||||
};
|
||||
|
||||
static struct rtw_page_table page_table_8821c[] = {
|
||||
static const struct rtw_page_table page_table_8821c[] = {
|
||||
/* not sure what [0] stands for */
|
||||
{16, 16, 16, 14, 1},
|
||||
{16, 16, 16, 14, 1},
|
||||
@ -1648,7 +1618,7 @@ static struct rtw_page_table page_table_8821c[] = {
|
||||
{16, 16, 16, 14, 1},
|
||||
};
|
||||
|
||||
static struct rtw_rqpn rqpn_table_8821c[] = {
|
||||
static const struct rtw_rqpn rqpn_table_8821c[] = {
|
||||
/* not sure what [0] stands for */
|
||||
{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
|
||||
RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
|
||||
@ -1667,7 +1637,7 @@ static struct rtw_rqpn rqpn_table_8821c[] = {
|
||||
RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
|
||||
};
|
||||
|
||||
static struct rtw_prioq_addrs prioq_addrs_8821c = {
|
||||
static const struct rtw_prioq_addrs prioq_addrs_8821c = {
|
||||
.prio[RTW_DMA_MAPPING_EXTRA] = {
|
||||
.rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2,
|
||||
},
|
||||
@ -1683,10 +1653,12 @@ static struct rtw_prioq_addrs prioq_addrs_8821c = {
|
||||
.wsize = true,
|
||||
};
|
||||
|
||||
static struct rtw_chip_ops rtw8821c_ops = {
|
||||
static const struct rtw_chip_ops rtw8821c_ops = {
|
||||
.power_on = rtw_power_on,
|
||||
.power_off = rtw_power_off,
|
||||
.phy_set_param = rtw8821c_phy_set_param,
|
||||
.read_efuse = rtw8821c_read_efuse,
|
||||
.query_rx_desc = rtw8821c_query_rx_desc,
|
||||
.query_phy_status = query_phy_status,
|
||||
.set_channel = rtw8821c_set_channel,
|
||||
.mac_init = rtw8821c_mac_init,
|
||||
.read_rf = rtw_phy_read_rf,
|
||||
@ -1701,6 +1673,7 @@ static struct rtw_chip_ops rtw8821c_ops = {
|
||||
.config_bfee = rtw8821c_bf_config_bfee,
|
||||
.set_gid_table = rtw_bf_set_gid_table,
|
||||
.cfg_csi_rate = rtw_bf_cfg_csi_rate,
|
||||
.led_set = rtw8821c_led_set,
|
||||
.fill_txdesc_checksum = rtw8821c_fill_txdesc_checksum,
|
||||
|
||||
.coex_set_init = rtw8821c_coex_cfg_init,
|
||||
@ -1942,7 +1915,7 @@ static const u8 rtw8821c_pwrtrk_2g_cck_a_p[] = {
|
||||
5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_track_tbl rtw8821c_rtw_pwr_track_tbl = {
|
||||
static const struct rtw_pwr_track_tbl rtw8821c_pwr_track_type0_tbl = {
|
||||
.pwrtrk_5gb_n[0] = rtw8821c_pwrtrk_5gb_n[0],
|
||||
.pwrtrk_5gb_n[1] = rtw8821c_pwrtrk_5gb_n[1],
|
||||
.pwrtrk_5gb_n[2] = rtw8821c_pwrtrk_5gb_n[2],
|
||||
@ -1965,6 +1938,13 @@ static const struct rtw_pwr_track_tbl rtw8821c_rtw_pwr_track_tbl = {
|
||||
.pwrtrk_2g_ccka_p = rtw8821c_pwrtrk_2g_cck_a_p,
|
||||
};
|
||||
|
||||
static const struct rtw_rfe_def rtw8821c_rfe_defs[] = {
|
||||
[0] = RTW_DEF_RFE(8821c, 0, 0, 0),
|
||||
[2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 0, 2),
|
||||
[4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 0, 2),
|
||||
[6] = RTW_DEF_RFE(8821c, 0, 0, 0),
|
||||
};
|
||||
|
||||
static const struct rtw_reg_domain coex_info_hw_regs_8821c[] = {
|
||||
{0xCB0, MASKDWORD, RTW_REG_DOMAIN_MAC32},
|
||||
{0xCB4, MASKDWORD, RTW_REG_DOMAIN_MAC32},
|
||||
@ -2013,6 +1993,9 @@ const struct rtw_chip_info rtw8821c_hw_spec = {
|
||||
.page_size = TX_PAGE_SIZE,
|
||||
.dig_min = 0x1c,
|
||||
.usb_tx_agg_desc_num = 3,
|
||||
.hw_feature_report = true,
|
||||
.c2h_ra_report_size = 7,
|
||||
.old_datarate_fb_limit = false,
|
||||
.ht_supported = true,
|
||||
.vht_supported = true,
|
||||
.lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
|
||||
@ -2034,7 +2017,6 @@ const struct rtw_chip_info rtw8821c_hw_spec = {
|
||||
.rfe_defs = rtw8821c_rfe_defs,
|
||||
.rfe_defs_size = ARRAY_SIZE(rtw8821c_rfe_defs),
|
||||
.rx_ldpc = false,
|
||||
.pwr_track_tbl = &rtw8821c_rtw_pwr_track_tbl,
|
||||
.iqk_threshold = 8,
|
||||
.bfer_su_max_num = 2,
|
||||
.bfer_mu_max_num = 1,
|
||||
|
||||
@ -27,7 +27,7 @@ struct rtw8821cu_efuse {
|
||||
u8 res11[0xcf];
|
||||
u8 package_type; /* 0x1fb */
|
||||
u8 res12[0x4];
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct rtw8821ce_efuse {
|
||||
u8 mac_addr[ETH_ALEN]; /* 0xd0 */
|
||||
@ -47,7 +47,8 @@ struct rtw8821ce_efuse {
|
||||
u8 ltr_en:1;
|
||||
u8 res1:2;
|
||||
u8 obff:2;
|
||||
u8 res2:3;
|
||||
u8 res2_1:1;
|
||||
u8 res2_2:2;
|
||||
u8 obff_cap:2;
|
||||
u8 res3:4;
|
||||
u8 res4[3];
|
||||
@ -63,7 +64,7 @@ struct rtw8821ce_efuse {
|
||||
u8 res6:1;
|
||||
u8 port_t_power_on_value:5;
|
||||
u8 res7;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct rtw8821cs_efuse {
|
||||
u8 res4[0x4a]; /* 0xd0 */
|
||||
@ -101,7 +102,7 @@ struct rtw8821c_efuse {
|
||||
struct rtw8821cu_efuse u;
|
||||
struct rtw8821cs_efuse s;
|
||||
};
|
||||
};
|
||||
} __packed;
|
||||
|
||||
static inline void
|
||||
_rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
|
||||
@ -214,19 +215,10 @@ extern const struct rtw_chip_info rtw8821c_hw_spec;
|
||||
#define BIT_FEN_EN BIT(26)
|
||||
#define REG_INIRTS_RATE_SEL 0x0480
|
||||
#define REG_HTSTFWT 0x800
|
||||
#define REG_RXPSEL 0x808
|
||||
#define BIT_RX_PSEL_RST (BIT(28) | BIT(29))
|
||||
#define REG_TXPSEL 0x80c
|
||||
#define REG_RXCCAMSK 0x814
|
||||
#define REG_CCASEL 0x82c
|
||||
#define REG_PDMFTH 0x830
|
||||
#define REG_CCA2ND 0x838
|
||||
#define REG_L1WT 0x83c
|
||||
#define REG_L1PKWT 0x840
|
||||
#define REG_MRC 0x850
|
||||
#define REG_CLKTRK 0x860
|
||||
#define REG_ADCCLK 0x8ac
|
||||
#define REG_ADC160 0x8c4
|
||||
#define REG_ADC40 0x8c8
|
||||
#define REG_CHFIR 0x8f0
|
||||
#define REG_CDDTXP 0x93c
|
||||
@ -234,14 +226,11 @@ extern const struct rtw_chip_info rtw8821c_hw_spec;
|
||||
#define REG_ACBB0 0x948
|
||||
#define REG_ACBBRXFIR 0x94c
|
||||
#define REG_ACGG2TBL 0x958
|
||||
#define REG_FAS 0x9a4
|
||||
#define REG_RXSB 0xa00
|
||||
#define REG_ADCINI 0xa04
|
||||
#define REG_PWRTH 0xa08
|
||||
#define REG_CCA_FLTR 0xa20
|
||||
#define REG_TXSF2 0xa24
|
||||
#define REG_TXSF6 0xa28
|
||||
#define REG_FA_CCK 0xa5c
|
||||
#define REG_RXDESC 0xa2c
|
||||
#define REG_ENTXCCK 0xa80
|
||||
#define BTG_LNA 0xfc84
|
||||
@ -252,12 +241,8 @@ extern const struct rtw_chip_info rtw8821c_hw_spec;
|
||||
#define REG_PWRTH2 0xaa8
|
||||
#define REG_CSRATIO 0xaaa
|
||||
#define REG_TXFILTER 0xaac
|
||||
#define REG_CNTRST 0xb58
|
||||
#define REG_AGCTR_A 0xc08
|
||||
#define REG_TXSCALE_A 0xc1c
|
||||
#define REG_TXDFIR 0xc20
|
||||
#define REG_RXIGI_A 0xc50
|
||||
#define REG_TXAGCIDX 0xc94
|
||||
#define REG_TRSW 0xca0
|
||||
#define REG_RFESEL0 0xcb0
|
||||
#define REG_RFESEL8 0xcb4
|
||||
@ -269,14 +254,6 @@ extern const struct rtw_chip_info rtw8821c_hw_spec;
|
||||
#define B_WLA_SWITCH BIT(23)
|
||||
#define REG_RFEINV 0xcbc
|
||||
#define REG_AGCTR_B 0xe08
|
||||
#define REG_RXIGI_B 0xe50
|
||||
#define REG_CRC_CCK 0xf04
|
||||
#define REG_CRC_OFDM 0xf14
|
||||
#define REG_CRC_HT 0xf10
|
||||
#define REG_CRC_VHT 0xf0c
|
||||
#define REG_CCA_OFDM 0xf08
|
||||
#define REG_FA_OFDM 0xf48
|
||||
#define REG_CCA_CCK 0xfcc
|
||||
#define REG_DMEM_CTRL 0x1080
|
||||
#define BIT_WL_RST BIT(16)
|
||||
#define REG_ANTWT 0x1904
|
||||
|
||||
@ -31,8 +31,6 @@ static const struct usb_device_id rtw_8821cu_id_table[] = {
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82b, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82c, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331d, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* D-Link */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xc811, 0xff, 0xff, 0xff),
|
||||
|
||||
@ -46,6 +46,7 @@ static int rtw8822b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
|
||||
|
||||
map = (struct rtw8822b_efuse *)log_map;
|
||||
|
||||
efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(7));
|
||||
efuse->rfe_option = map->rfe_option;
|
||||
efuse->rf_board_option = map->rf_board_option;
|
||||
efuse->crystal_cap = map->xtal_k;
|
||||
@ -933,47 +934,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
|
||||
}
|
||||
}
|
||||
|
||||
static void rtw8822b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct ieee80211_hdr *hdr;
|
||||
u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
|
||||
u8 *phy_status = NULL;
|
||||
|
||||
memset(pkt_stat, 0, sizeof(*pkt_stat));
|
||||
|
||||
pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
|
||||
pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
|
||||
pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
|
||||
pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
|
||||
GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
|
||||
pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
|
||||
pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
|
||||
pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
|
||||
pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
|
||||
pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
|
||||
pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
|
||||
pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc);
|
||||
pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
|
||||
|
||||
/* drv_info_sz is in unit of 8-bytes */
|
||||
pkt_stat->drv_info_sz *= 8;
|
||||
|
||||
/* c2h cmd pkt's rx/phy status is not interested */
|
||||
if (pkt_stat->is_c2h)
|
||||
return;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
|
||||
pkt_stat->drv_info_sz);
|
||||
if (pkt_stat->phy_status) {
|
||||
phy_status = rx_desc + desc_sz + pkt_stat->shift;
|
||||
query_phy_status(rtwdev, phy_status, pkt_stat);
|
||||
}
|
||||
|
||||
rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
|
||||
}
|
||||
|
||||
static void
|
||||
rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
|
||||
{
|
||||
@ -1606,6 +1566,24 @@ static void rtw8822b_adaptivity(struct rtw_dev *rtwdev)
|
||||
rtw_phy_set_edcca_th(rtwdev, l2h, h2l);
|
||||
}
|
||||
|
||||
static void rtw8822b_led_set(struct led_classdev *led,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev);
|
||||
u32 ledcfg;
|
||||
|
||||
ledcfg = rtw_read32(rtwdev, REG_LED_CFG);
|
||||
u32p_replace_bits(&ledcfg, BIT_LED_MODE_SW_CTRL, BIT_LED2_CM);
|
||||
ledcfg &= ~BIT_GPIO13_14_WL_CTRL_EN;
|
||||
|
||||
if (brightness == LED_OFF)
|
||||
ledcfg |= BIT_LED2_SV;
|
||||
else
|
||||
ledcfg &= ~BIT_LED2_SV;
|
||||
|
||||
rtw_write32(rtwdev, REG_LED_CFG, ledcfg);
|
||||
}
|
||||
|
||||
static void rtw8822b_fill_txdesc_checksum(struct rtw_dev *rtwdev,
|
||||
struct rtw_tx_pkt_info *pkt_info,
|
||||
u8 *txdesc)
|
||||
@ -1977,13 +1955,13 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8822b[] = {
|
||||
RTW_PWR_CMD_END, 0, 0},
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_seq_cmd *card_enable_flow_8822b[] = {
|
||||
static const struct rtw_pwr_seq_cmd * const card_enable_flow_8822b[] = {
|
||||
trans_carddis_to_cardemu_8822b,
|
||||
trans_cardemu_to_act_8822b,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_seq_cmd *card_disable_flow_8822b[] = {
|
||||
static const struct rtw_pwr_seq_cmd * const card_disable_flow_8822b[] = {
|
||||
trans_act_to_cardemu_8822b,
|
||||
trans_cardemu_to_carddis_8822b,
|
||||
NULL
|
||||
@ -2112,12 +2090,6 @@ static const struct rtw_intf_phy_para_table phy_para_table_8822b = {
|
||||
.n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8822b),
|
||||
};
|
||||
|
||||
static const struct rtw_rfe_def rtw8822b_rfe_defs[] = {
|
||||
[2] = RTW_DEF_RFE(8822b, 2, 2),
|
||||
[3] = RTW_DEF_RFE(8822b, 3, 0),
|
||||
[5] = RTW_DEF_RFE(8822b, 5, 5),
|
||||
};
|
||||
|
||||
static const struct rtw_hw_reg rtw8822b_dig[] = {
|
||||
[0] = { .addr = 0xc50, .mask = 0x7f },
|
||||
[1] = { .addr = 0xe50, .mask = 0x7f },
|
||||
@ -2155,7 +2127,7 @@ static const struct rtw_rqpn rqpn_table_8822b[] = {
|
||||
RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
|
||||
};
|
||||
|
||||
static struct rtw_prioq_addrs prioq_addrs_8822b = {
|
||||
static const struct rtw_prioq_addrs prioq_addrs_8822b = {
|
||||
.prio[RTW_DMA_MAPPING_EXTRA] = {
|
||||
.rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2,
|
||||
},
|
||||
@ -2171,10 +2143,12 @@ static struct rtw_prioq_addrs prioq_addrs_8822b = {
|
||||
.wsize = true,
|
||||
};
|
||||
|
||||
static struct rtw_chip_ops rtw8822b_ops = {
|
||||
static const struct rtw_chip_ops rtw8822b_ops = {
|
||||
.power_on = rtw_power_on,
|
||||
.power_off = rtw_power_off,
|
||||
.phy_set_param = rtw8822b_phy_set_param,
|
||||
.read_efuse = rtw8822b_read_efuse,
|
||||
.query_rx_desc = rtw8822b_query_rx_desc,
|
||||
.query_phy_status = query_phy_status,
|
||||
.set_channel = rtw8822b_set_channel,
|
||||
.mac_init = rtw8822b_mac_init,
|
||||
.read_rf = rtw_phy_read_rf,
|
||||
@ -2190,6 +2164,7 @@ static struct rtw_chip_ops rtw8822b_ops = {
|
||||
.cfg_csi_rate = rtw_bf_cfg_csi_rate,
|
||||
.adaptivity_init = rtw8822b_adaptivity_init,
|
||||
.adaptivity = rtw8822b_adaptivity,
|
||||
.led_set = rtw8822b_led_set,
|
||||
.fill_txdesc_checksum = rtw8822b_fill_txdesc_checksum,
|
||||
|
||||
.coex_set_init = rtw8822b_coex_cfg_init,
|
||||
@ -2474,7 +2449,7 @@ static const u8 rtw8822b_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = {
|
||||
10, 11, 11, 12, 12, 13, 13, 14, 14, 15
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_track_tbl rtw8822b_rtw_pwr_track_tbl = {
|
||||
static const struct rtw_pwr_track_tbl rtw8822b_pwr_track_type0_tbl = {
|
||||
.pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1],
|
||||
.pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2],
|
||||
.pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3],
|
||||
@ -2497,6 +2472,12 @@ static const struct rtw_pwr_track_tbl rtw8822b_rtw_pwr_track_tbl = {
|
||||
.pwrtrk_2g_ccka_p = rtw8822b_pwrtrk_2g_cck_a_p,
|
||||
};
|
||||
|
||||
static const struct rtw_rfe_def rtw8822b_rfe_defs[] = {
|
||||
[2] = RTW_DEF_RFE(8822b, 2, 2, 0),
|
||||
[3] = RTW_DEF_RFE(8822b, 3, 0, 0),
|
||||
[5] = RTW_DEF_RFE(8822b, 5, 5, 0),
|
||||
};
|
||||
|
||||
static const struct rtw_reg_domain coex_info_hw_regs_8822b[] = {
|
||||
{0xcb0, MASKDWORD, RTW_REG_DOMAIN_MAC32},
|
||||
{0xcb4, MASKDWORD, RTW_REG_DOMAIN_MAC32},
|
||||
@ -2524,7 +2505,7 @@ static const struct rtw_reg_domain coex_info_hw_regs_8822b[] = {
|
||||
{0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
|
||||
};
|
||||
|
||||
static struct rtw_hw_reg_offset rtw8822b_edcca_th[] = {
|
||||
static const struct rtw_hw_reg_offset rtw8822b_edcca_th[] = {
|
||||
[EDCCA_TH_L2H_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE0}, .offset = 0},
|
||||
[EDCCA_TH_H2L_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE1}, .offset = 0},
|
||||
};
|
||||
@ -2553,6 +2534,9 @@ const struct rtw_chip_info rtw8822b_hw_spec = {
|
||||
.page_size = TX_PAGE_SIZE,
|
||||
.dig_min = 0x1c,
|
||||
.usb_tx_agg_desc_num = 3,
|
||||
.hw_feature_report = true,
|
||||
.c2h_ra_report_size = 7,
|
||||
.old_datarate_fb_limit = false,
|
||||
.ht_supported = true,
|
||||
.vht_supported = true,
|
||||
.lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
|
||||
@ -2574,7 +2558,6 @@ const struct rtw_chip_info rtw8822b_hw_spec = {
|
||||
.rf_tbl = {&rtw8822b_rf_a_tbl, &rtw8822b_rf_b_tbl},
|
||||
.rfe_defs = rtw8822b_rfe_defs,
|
||||
.rfe_defs_size = ARRAY_SIZE(rtw8822b_rfe_defs),
|
||||
.pwr_track_tbl = &rtw8822b_rtw_pwr_track_tbl,
|
||||
.iqk_threshold = 8,
|
||||
.bfer_su_max_num = 2,
|
||||
.bfer_mu_max_num = 1,
|
||||
|
||||
@ -27,7 +27,7 @@ struct rtw8822bu_efuse {
|
||||
u8 res11[0xcf];
|
||||
u8 package_type; /* 0x1fb */
|
||||
u8 res12[0x4];
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct rtw8822be_efuse {
|
||||
u8 mac_addr[ETH_ALEN]; /* 0xd0 */
|
||||
@ -47,7 +47,8 @@ struct rtw8822be_efuse {
|
||||
u8 ltr_en:1;
|
||||
u8 res1:2;
|
||||
u8 obff:2;
|
||||
u8 res2:3;
|
||||
u8 res2_1:1;
|
||||
u8 res2_2:2;
|
||||
u8 obff_cap:2;
|
||||
u8 res3:4;
|
||||
u8 res4[3];
|
||||
@ -63,7 +64,7 @@ struct rtw8822be_efuse {
|
||||
u8 res6:1;
|
||||
u8 port_t_power_on_value:5;
|
||||
u8 res7;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct rtw8822bs_efuse {
|
||||
u8 res4[0x4a]; /* 0xd0 */
|
||||
@ -72,7 +73,9 @@ struct rtw8822bs_efuse {
|
||||
|
||||
struct rtw8822b_efuse {
|
||||
__le16 rtl_id;
|
||||
u8 res0[0x0e];
|
||||
u8 res0[4];
|
||||
u8 usb_mode;
|
||||
u8 res1[0x09];
|
||||
|
||||
/* power index for four RF paths */
|
||||
struct rtw_txpwr_idx txpwr_idx_table[4];
|
||||
@ -101,7 +104,7 @@ struct rtw8822b_efuse {
|
||||
struct rtw8822bu_efuse u;
|
||||
struct rtw8822bs_efuse s;
|
||||
};
|
||||
};
|
||||
} __packed;
|
||||
|
||||
static inline void
|
||||
_rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
|
||||
@ -149,21 +152,12 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
|
||||
#define RTW8822B_EDCCA_MAX 0x7f
|
||||
#define RTW8822B_EDCCA_SRC_DEF 1
|
||||
#define REG_HTSTFWT 0x800
|
||||
#define REG_RXPSEL 0x808
|
||||
#define BIT_RX_PSEL_RST (BIT(28) | BIT(29))
|
||||
#define REG_TXPSEL 0x80c
|
||||
#define REG_RXCCAMSK 0x814
|
||||
#define REG_CCASEL 0x82c
|
||||
#define REG_PDMFTH 0x830
|
||||
#define REG_CCA2ND 0x838
|
||||
#define REG_L1WT 0x83c
|
||||
#define REG_L1PKWT 0x840
|
||||
#define REG_MRC 0x850
|
||||
#define REG_CLKTRK 0x860
|
||||
#define REG_EDCCA_POW_MA 0x8a0
|
||||
#define BIT_MA_LEVEL GENMASK(1, 0)
|
||||
#define REG_ADCCLK 0x8ac
|
||||
#define REG_ADC160 0x8c4
|
||||
#define REG_ADC40 0x8c8
|
||||
#define REG_EDCCA_DECISION 0x8dc
|
||||
#define BIT_EDCCA_OPTION BIT(5)
|
||||
@ -174,7 +168,6 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
|
||||
#define REG_ACBB0 0x948
|
||||
#define REG_ACBBRXFIR 0x94c
|
||||
#define REG_ACGG2TBL 0x958
|
||||
#define REG_RXSB 0xa00
|
||||
#define REG_ADCINI 0xa04
|
||||
#define REG_TXSF2 0xa24
|
||||
#define REG_TXSF6 0xa28
|
||||
@ -182,14 +175,12 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
|
||||
#define REG_ENTXCCK 0xa80
|
||||
#define REG_AGCTR_A 0xc08
|
||||
#define REG_TXDFIR 0xc20
|
||||
#define REG_RXIGI_A 0xc50
|
||||
#define REG_TRSW 0xca0
|
||||
#define REG_RFESEL0 0xcb0
|
||||
#define REG_RFESEL8 0xcb4
|
||||
#define REG_RFECTL 0xcb8
|
||||
#define REG_RFEINV 0xcbc
|
||||
#define REG_AGCTR_B 0xe08
|
||||
#define REG_RXIGI_B 0xe50
|
||||
#define REG_ANTWT 0x1904
|
||||
#define REG_IQKFAILMSK 0x1bf0
|
||||
|
||||
|
||||
@ -67,6 +67,12 @@ static const struct usb_device_id rtw_8822bu_id_table[] = {
|
||||
.driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* LiteOn */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x808a, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TRENDnet TEW-808UBM */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x805a, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TRENDnet TEW-805UBH */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4011, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ELECOM WDB-867DU3S */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x0107, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Mercusys MA30H */
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, rtw_8822bu_id_table);
|
||||
|
||||
@ -49,6 +49,7 @@ static int rtw8822c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
|
||||
|
||||
map = (struct rtw8822c_efuse *)log_map;
|
||||
|
||||
efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(7));
|
||||
efuse->rfe_option = map->rfe_option;
|
||||
efuse->rf_board_option = map->rf_board_option;
|
||||
efuse->crystal_cap = map->xtal_k & XCAP_MASK;
|
||||
@ -2579,9 +2580,10 @@ static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status,
|
||||
rx_power[RF_PATH_B] -= 110;
|
||||
|
||||
channel = GET_PHY_STAT_P0_CHANNEL(phy_status);
|
||||
if (channel == 0)
|
||||
channel = rtwdev->hal.current_channel;
|
||||
rtw_set_rx_freq_band(pkt_stat, channel);
|
||||
if (channel != 0)
|
||||
rtw_set_rx_freq_band(pkt_stat, channel);
|
||||
else
|
||||
pkt_stat->channel_invalid = true;
|
||||
|
||||
pkt_stat->rx_power[RF_PATH_A] = rx_power[RF_PATH_A];
|
||||
pkt_stat->rx_power[RF_PATH_B] = rx_power[RF_PATH_B];
|
||||
@ -2615,12 +2617,14 @@ static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status,
|
||||
else
|
||||
rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status);
|
||||
|
||||
if (rxsc >= 9 && rxsc <= 12)
|
||||
bw = RTW_CHANNEL_WIDTH_40;
|
||||
else if (rxsc >= 13)
|
||||
bw = RTW_CHANNEL_WIDTH_80;
|
||||
else
|
||||
if (rxsc == 0)
|
||||
bw = rtwdev->hal.current_band_width;
|
||||
else if (rxsc >= 1 && rxsc <= 8)
|
||||
bw = RTW_CHANNEL_WIDTH_20;
|
||||
else if (rxsc >= 9 && rxsc <= 12)
|
||||
bw = RTW_CHANNEL_WIDTH_40;
|
||||
else
|
||||
bw = RTW_CHANNEL_WIDTH_80;
|
||||
|
||||
channel = GET_PHY_STAT_P1_CHANNEL(phy_status);
|
||||
rtw_set_rx_freq_band(pkt_stat, channel);
|
||||
@ -2690,48 +2694,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
|
||||
}
|
||||
}
|
||||
|
||||
static void rtw8822c_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct ieee80211_hdr *hdr;
|
||||
u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
|
||||
u8 *phy_status = NULL;
|
||||
|
||||
memset(pkt_stat, 0, sizeof(*pkt_stat));
|
||||
|
||||
pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
|
||||
pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
|
||||
pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
|
||||
pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
|
||||
GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
|
||||
pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
|
||||
pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
|
||||
pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
|
||||
pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
|
||||
pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
|
||||
pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
|
||||
pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc);
|
||||
pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
|
||||
|
||||
/* drv_info_sz is in unit of 8-bytes */
|
||||
pkt_stat->drv_info_sz *= 8;
|
||||
|
||||
/* c2h cmd pkt's rx/phy status is not interested */
|
||||
if (pkt_stat->is_c2h)
|
||||
return;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
|
||||
pkt_stat->drv_info_sz);
|
||||
pkt_stat->hdr = hdr;
|
||||
if (pkt_stat->phy_status) {
|
||||
phy_status = rx_desc + desc_sz + pkt_stat->shift;
|
||||
query_phy_status(rtwdev, phy_status, pkt_stat);
|
||||
}
|
||||
|
||||
rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
|
||||
}
|
||||
|
||||
static void
|
||||
rtw8822c_set_write_tx_power_ref(struct rtw_dev *rtwdev, u8 *tx_pwr_ref_cck,
|
||||
u8 *tx_pwr_ref_ofdm)
|
||||
@ -4587,6 +4549,24 @@ static void rtw8822c_adaptivity(struct rtw_dev *rtwdev)
|
||||
rtw_phy_set_edcca_th(rtwdev, l2h, h2l);
|
||||
}
|
||||
|
||||
static void rtw8822c_led_set(struct led_classdev *led,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev);
|
||||
u32 ledcfg;
|
||||
|
||||
ledcfg = rtw_read32(rtwdev, REG_LED_CFG);
|
||||
u32p_replace_bits(&ledcfg, BIT_LED_MODE_SW_CTRL, BIT_LED2_CM);
|
||||
ledcfg &= ~BIT_GPIO13_14_WL_CTRL_EN;
|
||||
|
||||
if (brightness == LED_OFF)
|
||||
ledcfg |= BIT_LED2_SV;
|
||||
else
|
||||
ledcfg &= ~BIT_LED2_SV;
|
||||
|
||||
rtw_write32(rtwdev, REG_LED_CFG, ledcfg);
|
||||
}
|
||||
|
||||
static void rtw8822c_fill_txdesc_checksum(struct rtw_dev *rtwdev,
|
||||
struct rtw_tx_pkt_info *pkt_info,
|
||||
u8 *txdesc)
|
||||
@ -4882,13 +4862,13 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8822c[] = {
|
||||
RTW_PWR_CMD_END, 0, 0},
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_seq_cmd *card_enable_flow_8822c[] = {
|
||||
static const struct rtw_pwr_seq_cmd * const card_enable_flow_8822c[] = {
|
||||
trans_carddis_to_cardemu_8822c,
|
||||
trans_cardemu_to_act_8822c,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_seq_cmd *card_disable_flow_8822c[] = {
|
||||
static const struct rtw_pwr_seq_cmd * const card_disable_flow_8822c[] = {
|
||||
trans_act_to_cardemu_8822c,
|
||||
trans_cardemu_to_carddis_8822c,
|
||||
NULL
|
||||
@ -4933,16 +4913,6 @@ static const struct rtw_intf_phy_para_table phy_para_table_8822c = {
|
||||
.n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8822c),
|
||||
};
|
||||
|
||||
static const struct rtw_rfe_def rtw8822c_rfe_defs[] = {
|
||||
[0] = RTW_DEF_RFE(8822c, 0, 0),
|
||||
[1] = RTW_DEF_RFE(8822c, 0, 0),
|
||||
[2] = RTW_DEF_RFE(8822c, 0, 0),
|
||||
[3] = RTW_DEF_RFE(8822c, 0, 0),
|
||||
[4] = RTW_DEF_RFE(8822c, 0, 0),
|
||||
[5] = RTW_DEF_RFE(8822c, 0, 5),
|
||||
[6] = RTW_DEF_RFE(8822c, 0, 0),
|
||||
};
|
||||
|
||||
static const struct rtw_hw_reg rtw8822c_dig[] = {
|
||||
[0] = { .addr = 0x1d70, .mask = 0x7f },
|
||||
[1] = { .addr = 0x1d70, .mask = 0x7f00 },
|
||||
@ -4980,7 +4950,7 @@ static const struct rtw_rqpn rqpn_table_8822c[] = {
|
||||
RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
|
||||
};
|
||||
|
||||
static struct rtw_prioq_addrs prioq_addrs_8822c = {
|
||||
static const struct rtw_prioq_addrs prioq_addrs_8822c = {
|
||||
.prio[RTW_DMA_MAPPING_EXTRA] = {
|
||||
.rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2,
|
||||
},
|
||||
@ -4996,10 +4966,12 @@ static struct rtw_prioq_addrs prioq_addrs_8822c = {
|
||||
.wsize = true,
|
||||
};
|
||||
|
||||
static struct rtw_chip_ops rtw8822c_ops = {
|
||||
static const struct rtw_chip_ops rtw8822c_ops = {
|
||||
.power_on = rtw_power_on,
|
||||
.power_off = rtw_power_off,
|
||||
.phy_set_param = rtw8822c_phy_set_param,
|
||||
.read_efuse = rtw8822c_read_efuse,
|
||||
.query_rx_desc = rtw8822c_query_rx_desc,
|
||||
.query_phy_status = query_phy_status,
|
||||
.set_channel = rtw8822c_set_channel,
|
||||
.mac_init = rtw8822c_mac_init,
|
||||
.dump_fw_crash = rtw8822c_dump_fw_crash,
|
||||
@ -5022,6 +4994,7 @@ static struct rtw_chip_ops rtw8822c_ops = {
|
||||
.cfo_track = rtw8822c_cfo_track,
|
||||
.config_tx_path = rtw8822c_config_tx_path,
|
||||
.config_txrx_mode = rtw8822c_config_trx_mode,
|
||||
.led_set = rtw8822c_led_set,
|
||||
.fill_txdesc_checksum = rtw8822c_fill_txdesc_checksum,
|
||||
|
||||
.coex_set_init = rtw8822c_coex_cfg_init,
|
||||
@ -5290,7 +5263,7 @@ static const u8 rtw8822c_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = {
|
||||
18, 18, 19, 20, 21, 22, 23, 24, 24, 25
|
||||
};
|
||||
|
||||
static const struct rtw_pwr_track_tbl rtw8822c_rtw_pwr_track_tbl = {
|
||||
static const struct rtw_pwr_track_tbl rtw8822c_pwr_track_type0_tbl = {
|
||||
.pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1],
|
||||
.pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2],
|
||||
.pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3],
|
||||
@ -5313,7 +5286,17 @@ static const struct rtw_pwr_track_tbl rtw8822c_rtw_pwr_track_tbl = {
|
||||
.pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p,
|
||||
};
|
||||
|
||||
static struct rtw_hw_reg_offset rtw8822c_edcca_th[] = {
|
||||
static const struct rtw_rfe_def rtw8822c_rfe_defs[] = {
|
||||
[0] = RTW_DEF_RFE(8822c, 0, 0, 0),
|
||||
[1] = RTW_DEF_RFE(8822c, 0, 0, 0),
|
||||
[2] = RTW_DEF_RFE(8822c, 0, 0, 0),
|
||||
[3] = RTW_DEF_RFE(8822c, 0, 0, 0),
|
||||
[4] = RTW_DEF_RFE(8822c, 0, 0, 0),
|
||||
[5] = RTW_DEF_RFE(8822c, 0, 5, 0),
|
||||
[6] = RTW_DEF_RFE(8822c, 0, 0, 0),
|
||||
};
|
||||
|
||||
static const struct rtw_hw_reg_offset rtw8822c_edcca_th[] = {
|
||||
[EDCCA_TH_L2H_IDX] = {
|
||||
{.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80
|
||||
},
|
||||
@ -5383,6 +5366,9 @@ const struct rtw_chip_info rtw8822c_hw_spec = {
|
||||
.page_size = TX_PAGE_SIZE,
|
||||
.dig_min = 0x20,
|
||||
.usb_tx_agg_desc_num = 3,
|
||||
.hw_feature_report = true,
|
||||
.c2h_ra_report_size = 7,
|
||||
.old_datarate_fb_limit = false,
|
||||
.default_1ss_tx_path = BB_PATH_A,
|
||||
.path_div_supported = true,
|
||||
.ht_supported = true,
|
||||
@ -5409,7 +5395,6 @@ const struct rtw_chip_info rtw8822c_hw_spec = {
|
||||
.rfe_defs_size = ARRAY_SIZE(rtw8822c_rfe_defs),
|
||||
.en_dis_dpd = true,
|
||||
.dpd_ratemask = DIS_DPD_RATEALL,
|
||||
.pwr_track_tbl = &rtw8822c_rtw_pwr_track_tbl,
|
||||
.iqk_threshold = 8,
|
||||
.lck_threshold = 8,
|
||||
.bfer_su_max_num = 2,
|
||||
|
||||
@ -14,7 +14,7 @@ struct rtw8822cu_efuse {
|
||||
u8 res1[3];
|
||||
u8 mac_addr[ETH_ALEN]; /* 0x157 */
|
||||
u8 res2[0x3d];
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct rtw8822cs_efuse {
|
||||
u8 res0[0x4a]; /* 0x120 */
|
||||
@ -39,7 +39,8 @@ struct rtw8822ce_efuse {
|
||||
u8 ltr_en:1;
|
||||
u8 res1:2;
|
||||
u8 obff:2;
|
||||
u8 res2:3;
|
||||
u8 res2_1:1;
|
||||
u8 res2_2:2;
|
||||
u8 obff_cap:2;
|
||||
u8 res3:4;
|
||||
u8 class_code[3];
|
||||
@ -55,20 +56,22 @@ struct rtw8822ce_efuse {
|
||||
u8 res6:1;
|
||||
u8 port_t_power_on_value:5;
|
||||
u8 res7;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct rtw8822c_efuse {
|
||||
__le16 rtl_id;
|
||||
u8 res0[0x0e];
|
||||
u8 res0[4];
|
||||
u8 usb_mode;
|
||||
u8 res1[0x09];
|
||||
|
||||
/* power index for four RF paths */
|
||||
struct rtw_txpwr_idx txpwr_idx_table[4];
|
||||
|
||||
u8 channel_plan; /* 0xb8 */
|
||||
u8 xtal_k;
|
||||
u8 res1;
|
||||
u8 res2;
|
||||
u8 iqk_lck;
|
||||
u8 res2[5]; /* 0xbc */
|
||||
u8 res3[5]; /* 0xbc */
|
||||
u8 rf_board_option;
|
||||
u8 rf_feature_option;
|
||||
u8 rf_bt_setting;
|
||||
@ -80,27 +83,27 @@ struct rtw8822c_efuse {
|
||||
u8 rf_antenna_option; /* 0xc9 */
|
||||
u8 rfe_option;
|
||||
u8 country_code[2];
|
||||
u8 res3[3];
|
||||
u8 res4[3];
|
||||
u8 path_a_thermal; /* 0xd0 */
|
||||
u8 path_b_thermal;
|
||||
u8 res4[2];
|
||||
u8 res5[2];
|
||||
u8 rx_gain_gap_2g_ofdm;
|
||||
u8 res5;
|
||||
u8 rx_gain_gap_2g_cck;
|
||||
u8 res6;
|
||||
u8 rx_gain_gap_5gl;
|
||||
u8 rx_gain_gap_2g_cck;
|
||||
u8 res7;
|
||||
u8 rx_gain_gap_5gm;
|
||||
u8 rx_gain_gap_5gl;
|
||||
u8 res8;
|
||||
u8 rx_gain_gap_5gh;
|
||||
u8 rx_gain_gap_5gm;
|
||||
u8 res9;
|
||||
u8 res10[0x42];
|
||||
u8 rx_gain_gap_5gh;
|
||||
u8 res10;
|
||||
u8 res11[0x42];
|
||||
union {
|
||||
struct rtw8822ce_efuse e;
|
||||
struct rtw8822cu_efuse u;
|
||||
struct rtw8822cs_efuse s;
|
||||
};
|
||||
};
|
||||
} __packed;
|
||||
|
||||
enum rtw8822c_dpk_agc_phase {
|
||||
RTW_DPK_GAIN_CHECK,
|
||||
|
||||
1989
sys/contrib/dev/rtw88/rtw88xxa.c
Normal file
1989
sys/contrib/dev/rtw88/rtw88xxa.c
Normal file
File diff suppressed because it is too large
Load Diff
175
sys/contrib/dev/rtw88/rtw88xxa.h
Normal file
175
sys/contrib/dev/rtw88/rtw88xxa.h
Normal file
@ -0,0 +1,175 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2024 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW88XXA_H__
|
||||
#define __RTW88XXA_H__
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
#include "reg.h"
|
||||
|
||||
struct rtw8821au_efuse {
|
||||
u8 res4[48]; /* 0xd0 */
|
||||
u8 vid[2]; /* 0x100 */
|
||||
u8 pid[2];
|
||||
u8 res8[3];
|
||||
u8 mac_addr[ETH_ALEN]; /* 0x107 */
|
||||
u8 res9[243];
|
||||
} __packed;
|
||||
|
||||
struct rtw8812au_efuse {
|
||||
u8 vid[2]; /* 0xd0 */
|
||||
u8 pid[2]; /* 0xd2 */
|
||||
u8 res0[3];
|
||||
u8 mac_addr[ETH_ALEN]; /* 0xd7 */
|
||||
u8 res1[291];
|
||||
} __packed;
|
||||
|
||||
struct rtw88xxa_efuse {
|
||||
__le16 rtl_id;
|
||||
u8 res0[6]; /* 0x02 */
|
||||
u8 usb_mode; /* 0x08 */
|
||||
u8 res1[7]; /* 0x09 */
|
||||
|
||||
/* power index for four RF paths */
|
||||
struct rtw_txpwr_idx txpwr_idx_table[4];
|
||||
|
||||
u8 channel_plan; /* 0xb8 */
|
||||
u8 xtal_k;
|
||||
u8 thermal_meter;
|
||||
u8 iqk_lck;
|
||||
u8 pa_type; /* 0xbc */
|
||||
u8 lna_type_2g; /* 0xbd */
|
||||
u8 res2;
|
||||
u8 lna_type_5g; /* 0xbf */
|
||||
u8 res3;
|
||||
u8 rf_board_option; /* 0xc1 */
|
||||
u8 rf_feature_option;
|
||||
u8 rf_bt_setting;
|
||||
u8 eeprom_version;
|
||||
u8 eeprom_customer_id; /* 0xc5 */
|
||||
u8 tx_bb_swing_setting_2g;
|
||||
u8 tx_bb_swing_setting_5g;
|
||||
u8 tx_pwr_calibrate_rate;
|
||||
u8 rf_antenna_option; /* 0xc9 */
|
||||
u8 rfe_option;
|
||||
u8 country_code[2];
|
||||
u8 res4[3];
|
||||
union {
|
||||
struct rtw8821au_efuse rtw8821au;
|
||||
struct rtw8812au_efuse rtw8812au;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
static_assert(sizeof(struct rtw88xxa_efuse) == 512);
|
||||
|
||||
#define WLAN_BCN_DMA_TIME 0x02
|
||||
#define WLAN_TBTT_PROHIBIT 0x04
|
||||
#define WLAN_TBTT_HOLD_TIME 0x064
|
||||
#define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\
|
||||
(WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP))
|
||||
|
||||
struct rtw_jaguar_phy_status_rpt {
|
||||
__le32 w0;
|
||||
__le32 w1;
|
||||
__le32 w2;
|
||||
__le32 w3;
|
||||
__le32 w4;
|
||||
__le32 w5;
|
||||
__le32 w6;
|
||||
} __packed;
|
||||
|
||||
#define RTW_JGRPHY_W0_GAIN_A GENMASK(6, 0)
|
||||
#define RTW_JGRPHY_W0_TRSW_A BIT(7)
|
||||
#define RTW_JGRPHY_W0_GAIN_B GENMASK(14, 8)
|
||||
#define RTW_JGRPHY_W0_TRSW_B BIT(15)
|
||||
#define RTW_JGRPHY_W0_CHL_NUM GENMASK(25, 16)
|
||||
#define RTW_JGRPHY_W0_SUB_CHNL GENMASK(29, 26)
|
||||
#define RTW_JGRPHY_W0_R_RFMOD GENMASK(31, 30)
|
||||
|
||||
/* CCK: */
|
||||
#define RTW_JGRPHY_W1_SIG_QUAL GENMASK(7, 0)
|
||||
#define RTW_JGRPHY_W1_AGC_RPT_VGA_IDX GENMASK(12, 8)
|
||||
#define RTW_JGRPHY_W1_AGC_RPT_LNA_IDX GENMASK(15, 13)
|
||||
#define RTW_JGRPHY_W1_BB_POWER GENMASK(23, 16)
|
||||
/* OFDM: */
|
||||
#define RTW_JGRPHY_W1_PWDB_ALL GENMASK(7, 0)
|
||||
#define RTW_JGRPHY_W1_CFO_SHORT_A GENMASK(15, 8) /* s8 */
|
||||
#define RTW_JGRPHY_W1_CFO_SHORT_B GENMASK(23, 16) /* s8 */
|
||||
#define RTW_JGRPHY_W1_BT_RF_CH_MSB GENMASK(31, 30)
|
||||
|
||||
#define RTW_JGRPHY_W2_ANT_DIV_SW_A BIT(0)
|
||||
#define RTW_JGRPHY_W2_ANT_DIV_SW_B BIT(1)
|
||||
#define RTW_JGRPHY_W2_BT_RF_CH_LSB GENMASK(7, 2)
|
||||
#define RTW_JGRPHY_W2_CFO_TAIL_A GENMASK(15, 8) /* s8 */
|
||||
#define RTW_JGRPHY_W2_CFO_TAIL_B GENMASK(23, 16) /* s8 */
|
||||
#define RTW_JGRPHY_W2_PCTS_MSK_RPT_0 GENMASK(31, 24)
|
||||
|
||||
#define RTW_JGRPHY_W3_PCTS_MSK_RPT_1 GENMASK(7, 0)
|
||||
/* Stream 1 and 2 RX EVM: */
|
||||
#define RTW_JGRPHY_W3_RXEVM_1 GENMASK(15, 8) /* s8 */
|
||||
#define RTW_JGRPHY_W3_RXEVM_2 GENMASK(23, 16) /* s8 */
|
||||
#define RTW_JGRPHY_W3_RXSNR_A GENMASK(31, 24) /* s8 */
|
||||
|
||||
#define RTW_JGRPHY_W4_RXSNR_B GENMASK(7, 0) /* s8 */
|
||||
#define RTW_JGRPHY_W4_PCTS_MSK_RPT_2 GENMASK(21, 8)
|
||||
#define RTW_JGRPHY_W4_PCTS_RPT_VALID BIT(22)
|
||||
#define RTW_JGRPHY_W4_RXEVM_3 GENMASK(31, 24) /* s8 */
|
||||
|
||||
#define RTW_JGRPHY_W5_RXEVM_4 GENMASK(7, 0) /* s8 */
|
||||
/* 8812a, stream 1 and 2 CSI: */
|
||||
#define RTW_JGRPHY_W5_CSI_CURRENT_1 GENMASK(15, 8)
|
||||
#define RTW_JGRPHY_W5_CSI_CURRENT_2 GENMASK(23, 16)
|
||||
/* 8814a: */
|
||||
#define RTW_JGRPHY_W5_RXSNR_C GENMASK(15, 8) /* s8 */
|
||||
#define RTW_JGRPHY_W5_RXSNR_D GENMASK(23, 16) /* s8 */
|
||||
#define RTW_JGRPHY_W5_GAIN_C GENMASK(30, 24)
|
||||
#define RTW_JGRPHY_W5_TRSW_C BIT(31)
|
||||
|
||||
#define RTW_JGRPHY_W6_GAIN_D GENMASK(6, 0)
|
||||
#define RTW_JGRPHY_W6_TRSW_D BIT(7)
|
||||
#define RTW_JGRPHY_W6_SIGEVM GENMASK(15, 8) /* s8 */
|
||||
#define RTW_JGRPHY_W6_ANTIDX_ANTC GENMASK(18, 16)
|
||||
#define RTW_JGRPHY_W6_ANTIDX_ANTD GENMASK(21, 19)
|
||||
#define RTW_JGRPHY_W6_DPDT_CTRL_KEEP BIT(22)
|
||||
#define RTW_JGRPHY_W6_GNT_BT_KEEP BIT(23)
|
||||
#define RTW_JGRPHY_W6_ANTIDX_ANTA GENMASK(26, 24)
|
||||
#define RTW_JGRPHY_W6_ANTIDX_ANTB GENMASK(29, 27)
|
||||
#define RTW_JGRPHY_W6_HW_ANTSW_OCCUR GENMASK(31, 30)
|
||||
|
||||
#define RF18_BW_MASK (BIT(11) | BIT(10))
|
||||
|
||||
void rtw88xxa_efuse_grant(struct rtw_dev *rtwdev, bool on);
|
||||
int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map);
|
||||
void rtw88xxa_power_off(struct rtw_dev *rtwdev,
|
||||
const struct rtw_pwr_seq_cmd *const *enter_lps_flow);
|
||||
int rtw88xxa_power_on(struct rtw_dev *rtwdev);
|
||||
u32 rtw88xxa_phy_read_rf(struct rtw_dev *rtwdev,
|
||||
enum rtw_rf_path rf_path, u32 addr, u32 mask);
|
||||
void rtw88xxa_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw,
|
||||
u8 primary_chan_idx);
|
||||
void rtw88xxa_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
s8 (*cck_rx_pwr)(u8 lna_idx, u8 vga_idx));
|
||||
void rtw88xxa_set_tx_power_index(struct rtw_dev *rtwdev);
|
||||
void rtw88xxa_false_alarm_statistics(struct rtw_dev *rtwdev);
|
||||
void rtw88xxa_iqk_backup_mac_bb(struct rtw_dev *rtwdev,
|
||||
u32 *macbb_backup,
|
||||
const u32 *backup_macbb_reg,
|
||||
u32 macbb_num);
|
||||
void rtw88xxa_iqk_backup_afe(struct rtw_dev *rtwdev, u32 *afe_backup,
|
||||
const u32 *backup_afe_reg, u32 afe_num);
|
||||
void rtw88xxa_iqk_restore_mac_bb(struct rtw_dev *rtwdev,
|
||||
u32 *macbb_backup,
|
||||
const u32 *backup_macbb_reg,
|
||||
u32 macbb_num);
|
||||
void rtw88xxa_iqk_configure_mac(struct rtw_dev *rtwdev);
|
||||
bool rtw88xxa_iqk_finish(int average, int threshold,
|
||||
int *x_temp, int *y_temp, int *x, int *y,
|
||||
bool break_inner, bool break_outer);
|
||||
void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev,
|
||||
void (*do_lck)(struct rtw_dev *rtwdev),
|
||||
void (*do_iqk)(struct rtw_dev *rtwdev));
|
||||
void rtw88xxa_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl);
|
||||
|
||||
#endif
|
||||
@ -146,11 +146,51 @@ static void rtw_set_rx_freq_by_pktstat(struct rtw_rx_pkt_stat *pkt_stat,
|
||||
rx_status->band = pkt_stat->band;
|
||||
}
|
||||
|
||||
void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_hdr *hdr,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
u8 *phy_status)
|
||||
void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
struct rtw_rx_pkt_stat *pkt_stat)
|
||||
{
|
||||
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
||||
int channel = rtwdev->hal.current_channel;
|
||||
size_t hdr_len, ielen;
|
||||
int channel_number;
|
||||
u8 *variable;
|
||||
|
||||
if (!test_bit(RTW_FLAG_SCANNING, rtwdev->flags))
|
||||
goto fill_rx_status;
|
||||
|
||||
if (ieee80211_is_beacon(mgmt->frame_control)) {
|
||||
variable = mgmt->u.beacon.variable;
|
||||
hdr_len = offsetof(struct ieee80211_mgmt,
|
||||
u.beacon.variable);
|
||||
} else if (ieee80211_is_probe_resp(mgmt->frame_control)) {
|
||||
variable = mgmt->u.probe_resp.variable;
|
||||
hdr_len = offsetof(struct ieee80211_mgmt,
|
||||
u.probe_resp.variable);
|
||||
} else {
|
||||
goto fill_rx_status;
|
||||
}
|
||||
|
||||
if (skb->len > hdr_len)
|
||||
ielen = skb->len - hdr_len;
|
||||
else
|
||||
goto fill_rx_status;
|
||||
|
||||
channel_number = cfg80211_get_ies_channel_number(variable, ielen,
|
||||
NL80211_BAND_2GHZ);
|
||||
if (channel_number != -1)
|
||||
channel = channel_number;
|
||||
|
||||
fill_rx_status:
|
||||
rtw_set_rx_freq_band(pkt_stat, channel);
|
||||
rtw_set_rx_freq_by_pktstat(pkt_stat, rx_status);
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_update_rx_freq_from_ie);
|
||||
|
||||
static void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_hdr *hdr,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct ieee80211_hw *hw = rtwdev->hw;
|
||||
u8 path;
|
||||
@ -194,12 +234,84 @@ void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
|
||||
else
|
||||
rx_status->bw = RATE_INFO_BW_20;
|
||||
|
||||
rx_status->signal = pkt_stat->signal_power;
|
||||
for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
|
||||
rx_status->chains |= BIT(path);
|
||||
rx_status->chain_signal[path] = pkt_stat->rx_power[path];
|
||||
if (pkt_stat->phy_status) {
|
||||
rx_status->signal = pkt_stat->signal_power;
|
||||
for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
|
||||
rx_status->chains |= BIT(path);
|
||||
rx_status->chain_signal[path] = pkt_stat->rx_power[path];
|
||||
}
|
||||
} else {
|
||||
rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
|
||||
}
|
||||
|
||||
rtw_rx_addr_match(rtwdev, pkt_stat, hdr);
|
||||
|
||||
/* Rtl8723cs driver checks for size < 14 or size > 8192 and
|
||||
* simply drops the packet.
|
||||
*/
|
||||
if (rtwdev->chip->id == RTW_CHIP_TYPE_8703B && pkt_stat->pkt_len == 0) {
|
||||
rx_status->flag |= RX_FLAG_NO_PSDU;
|
||||
rtw_dbg(rtwdev, RTW_DBG_RX, "zero length packet");
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_rx_fill_rx_status);
|
||||
|
||||
void rtw_rx_query_rx_desc(struct rtw_dev *rtwdev, void *rx_desc8,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
|
||||
struct rtw_rx_desc *rx_desc = rx_desc8;
|
||||
struct ieee80211_hdr *hdr;
|
||||
u32 enc_type, swdec;
|
||||
#if defined(__linux__)
|
||||
void *phy_status;
|
||||
#elif defined(__FreeBSD__)
|
||||
u8 *phy_status;
|
||||
#endif
|
||||
|
||||
memset(pkt_stat, 0, sizeof(*pkt_stat));
|
||||
|
||||
pkt_stat->pkt_len = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_PKT_LEN);
|
||||
pkt_stat->crc_err = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_CRC32);
|
||||
pkt_stat->icv_err = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_ICV_ERR);
|
||||
pkt_stat->drv_info_sz = le32_get_bits(rx_desc->w0,
|
||||
RTW_RX_DESC_W0_DRV_INFO_SIZE);
|
||||
enc_type = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_ENC_TYPE);
|
||||
pkt_stat->shift = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_SHIFT);
|
||||
pkt_stat->phy_status = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_PHYST);
|
||||
swdec = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_SWDEC);
|
||||
pkt_stat->decrypted = !swdec && enc_type != RX_DESC_ENC_NONE;
|
||||
|
||||
pkt_stat->cam_id = le32_get_bits(rx_desc->w1, RTW_RX_DESC_W1_MACID);
|
||||
|
||||
pkt_stat->is_c2h = le32_get_bits(rx_desc->w2, RTW_RX_DESC_W2_C2H);
|
||||
pkt_stat->ppdu_cnt = le32_get_bits(rx_desc->w2, RTW_RX_DESC_W2_PPDU_CNT);
|
||||
|
||||
pkt_stat->rate = le32_get_bits(rx_desc->w3, RTW_RX_DESC_W3_RX_RATE);
|
||||
|
||||
pkt_stat->bw = le32_get_bits(rx_desc->w4, RTW_RX_DESC_W4_BW);
|
||||
|
||||
pkt_stat->tsf_low = le32_get_bits(rx_desc->w5, RTW_RX_DESC_W5_TSFL);
|
||||
|
||||
/* drv_info_sz is in unit of 8-bytes */
|
||||
pkt_stat->drv_info_sz *= 8;
|
||||
|
||||
/* c2h cmd pkt's rx/phy status is not interested */
|
||||
if (pkt_stat->is_c2h)
|
||||
return;
|
||||
|
||||
#if defined(__linux__)
|
||||
phy_status = rx_desc8 + desc_sz + pkt_stat->shift;
|
||||
hdr = phy_status + pkt_stat->drv_info_sz;
|
||||
#elif defined(__FreeBSD__)
|
||||
phy_status = (u8 *)rx_desc8 + desc_sz + pkt_stat->shift;
|
||||
hdr = (void *)(phy_status + pkt_stat->drv_info_sz);
|
||||
#endif
|
||||
pkt_stat->hdr = hdr;
|
||||
|
||||
if (pkt_stat->phy_status)
|
||||
rtwdev->chip->ops->query_phy_status(rtwdev, phy_status, pkt_stat);
|
||||
|
||||
rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status);
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_rx_query_rx_desc);
|
||||
|
||||
@ -14,41 +14,52 @@ enum rtw_rx_desc_enc {
|
||||
RX_DESC_ENC_WEP104 = 5,
|
||||
};
|
||||
|
||||
#define GET_RX_DESC_PHYST(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(26))
|
||||
#define GET_RX_DESC_ICV_ERR(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(15))
|
||||
#define GET_RX_DESC_CRC32(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(14))
|
||||
#define GET_RX_DESC_SWDEC(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(27))
|
||||
#define GET_RX_DESC_C2H(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x02), BIT(28))
|
||||
#define GET_RX_DESC_PKT_LEN(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(13, 0))
|
||||
#define GET_RX_DESC_DRV_INFO_SIZE(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(19, 16))
|
||||
#define GET_RX_DESC_SHIFT(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(25, 24))
|
||||
#define GET_RX_DESC_ENC_TYPE(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(22, 20))
|
||||
#define GET_RX_DESC_RX_RATE(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x03), GENMASK(6, 0))
|
||||
#define GET_RX_DESC_MACID(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x01), GENMASK(6, 0))
|
||||
#define GET_RX_DESC_PPDU_CNT(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x02), GENMASK(30, 29))
|
||||
#define GET_RX_DESC_TSFL(rxdesc) \
|
||||
le32_get_bits(*((__le32 *)(rxdesc) + 0x05), GENMASK(31, 0))
|
||||
#define GET_RX_DESC_BW(rxdesc) \
|
||||
(le32_get_bits(*((__le32 *)(rxdesc) + 0x04), GENMASK(31, 24)))
|
||||
struct rtw_rx_desc {
|
||||
__le32 w0;
|
||||
__le32 w1;
|
||||
__le32 w2;
|
||||
__le32 w3;
|
||||
__le32 w4;
|
||||
__le32 w5;
|
||||
} __packed;
|
||||
|
||||
#define RTW_RX_DESC_W0_PKT_LEN GENMASK(13, 0)
|
||||
#define RTW_RX_DESC_W0_CRC32 BIT(14)
|
||||
#define RTW_RX_DESC_W0_ICV_ERR BIT(15)
|
||||
#define RTW_RX_DESC_W0_DRV_INFO_SIZE GENMASK(19, 16)
|
||||
#define RTW_RX_DESC_W0_ENC_TYPE GENMASK(22, 20)
|
||||
#define RTW_RX_DESC_W0_SHIFT GENMASK(25, 24)
|
||||
#define RTW_RX_DESC_W0_PHYST BIT(26)
|
||||
#define RTW_RX_DESC_W0_SWDEC BIT(27)
|
||||
|
||||
#define RTW_RX_DESC_W1_MACID GENMASK(6, 0)
|
||||
|
||||
#define RTW_RX_DESC_W2_C2H BIT(28)
|
||||
#define RTW_RX_DESC_W2_PPDU_CNT GENMASK(30, 29)
|
||||
|
||||
#define RTW_RX_DESC_W3_RX_RATE GENMASK(6, 0)
|
||||
|
||||
#define RTW_RX_DESC_W4_BW GENMASK(5, 4)
|
||||
|
||||
#define RTW_RX_DESC_W5_TSFL GENMASK(31, 0)
|
||||
|
||||
void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
|
||||
struct sk_buff *skb);
|
||||
void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_hdr *hdr,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
u8 *phy_status);
|
||||
void rtw_rx_query_rx_desc(struct rtw_dev *rtwdev, void *rx_desc8,
|
||||
struct rtw_rx_pkt_stat *pkt_stat,
|
||||
struct ieee80211_rx_status *rx_status);
|
||||
void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
struct rtw_rx_pkt_stat *pkt_stat);
|
||||
|
||||
static inline
|
||||
void rtw_update_rx_freq_for_invalid(struct rtw_dev *rtwdev, struct sk_buff *skb,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
struct rtw_rx_pkt_stat *pkt_stat)
|
||||
{
|
||||
if (pkt_stat->channel_invalid)
|
||||
rtw_update_rx_freq_from_ie(rtwdev, skb, rx_status, pkt_stat);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@ -864,7 +864,7 @@ static void rtw_sdio_tx_skb_prepare(struct rtw_dev *rtwdev,
|
||||
|
||||
pkt_info->qsel = rtw_sdio_get_tx_qsel(rtwdev, skb, queue);
|
||||
|
||||
rtw_tx_fill_tx_desc(pkt_info, skb);
|
||||
rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
|
||||
rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, pkt_desc);
|
||||
}
|
||||
|
||||
@ -948,6 +948,7 @@ static void rtw_sdio_rx_skb(struct rtw_dev *rtwdev, struct sk_buff *skb,
|
||||
skb_put(skb, pkt_stat->pkt_len);
|
||||
skb_reserve(skb, pkt_offset);
|
||||
|
||||
rtw_update_rx_freq_for_invalid(rtwdev, skb, rx_status, pkt_stat);
|
||||
rtw_rx_stats(rtwdev, pkt_stat->vif, skb);
|
||||
|
||||
ieee80211_rx_irqsafe(rtwdev->hw, skb);
|
||||
@ -980,8 +981,7 @@ static void rtw_sdio_rxfifo_recv(struct rtw_dev *rtwdev, u32 rx_len)
|
||||
|
||||
while (true) {
|
||||
rx_desc = skb->data;
|
||||
chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat,
|
||||
&rx_status);
|
||||
rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status);
|
||||
pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz +
|
||||
pkt_stat.shift;
|
||||
|
||||
@ -1156,6 +1156,7 @@ static struct rtw_hci_ops rtw_sdio_ops = {
|
||||
.deep_ps = rtw_sdio_deep_ps,
|
||||
.link_ps = rtw_sdio_link_ps,
|
||||
.interface_cfg = rtw_sdio_interface_cfg,
|
||||
.dynamic_rx_agg = NULL,
|
||||
|
||||
.read8 = rtw_sdio_read8,
|
||||
.read16 = rtw_sdio_read16,
|
||||
@ -1191,6 +1192,8 @@ static void rtw_sdio_indicate_tx_status(struct rtw_dev *rtwdev,
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_hw *hw = rtwdev->hw;
|
||||
|
||||
skb_pull(skb, rtwdev->chip->tx_pkt_desc_sz);
|
||||
|
||||
/* enqueue to wait for tx report */
|
||||
if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) {
|
||||
rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn);
|
||||
@ -1295,12 +1298,12 @@ static void rtw_sdio_deinit_tx(struct rtw_dev *rtwdev)
|
||||
struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++)
|
||||
skb_queue_purge(&rtwsdio->tx_queue[i]);
|
||||
|
||||
flush_workqueue(rtwsdio->txwq);
|
||||
destroy_workqueue(rtwsdio->txwq);
|
||||
kfree(rtwsdio->tx_handler_data);
|
||||
|
||||
for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++)
|
||||
ieee80211_purge_tx_queue(rtwdev->hw, &rtwsdio->tx_queue[i]);
|
||||
}
|
||||
|
||||
int rtw_sdio_probe(struct sdio_func *sdio_func,
|
||||
|
||||
@ -32,7 +32,8 @@ void rtw_tx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
|
||||
}
|
||||
}
|
||||
|
||||
void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
|
||||
void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev,
|
||||
struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
|
||||
{
|
||||
struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data;
|
||||
bool more_data = false;
|
||||
@ -46,7 +47,8 @@ void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
|
||||
le32_encode_bits(pkt_info->ls, RTW_TX_DESC_W0_LS) |
|
||||
le32_encode_bits(pkt_info->dis_qselseq, RTW_TX_DESC_W0_DISQSELSEQ);
|
||||
|
||||
tx_desc->w1 = le32_encode_bits(pkt_info->qsel, RTW_TX_DESC_W1_QSEL) |
|
||||
tx_desc->w1 = le32_encode_bits(pkt_info->mac_id, RTW_TX_DESC_W1_MACID) |
|
||||
le32_encode_bits(pkt_info->qsel, RTW_TX_DESC_W1_QSEL) |
|
||||
le32_encode_bits(pkt_info->rate_id, RTW_TX_DESC_W1_RATE_ID) |
|
||||
le32_encode_bits(pkt_info->sec_type, RTW_TX_DESC_W1_SEC_TYPE) |
|
||||
le32_encode_bits(pkt_info->pkt_offset, RTW_TX_DESC_W1_PKT_OFFSET) |
|
||||
@ -66,6 +68,9 @@ void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
|
||||
|
||||
tx_desc->w4 = le32_encode_bits(pkt_info->rate, RTW_TX_DESC_W4_DATARATE);
|
||||
|
||||
if (rtwdev->chip->old_datarate_fb_limit)
|
||||
tx_desc->w4 |= le32_encode_bits(0x1f, RTW_TX_DESC_W4_DATARATE_FB_LIMIT);
|
||||
|
||||
tx_desc->w5 = le32_encode_bits(pkt_info->short_gi, RTW_TX_DESC_W5_DATA_SHORT) |
|
||||
le32_encode_bits(pkt_info->bw, RTW_TX_DESC_W5_DATA_BW) |
|
||||
le32_encode_bits(pkt_info->ldpc, RTW_TX_DESC_W5_DATA_LDPC) |
|
||||
@ -421,14 +426,18 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev,
|
||||
const struct rtw_chip_info *chip = rtwdev->chip;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
struct ieee80211_vif *vif = info->control.vif;
|
||||
struct rtw_sta_info *si;
|
||||
struct ieee80211_vif *vif = NULL;
|
||||
struct rtw_vif *rtwvif;
|
||||
__le16 fc = hdr->frame_control;
|
||||
bool bmc;
|
||||
|
||||
if (sta) {
|
||||
si = (struct rtw_sta_info *)sta->drv_priv;
|
||||
vif = si->vif;
|
||||
pkt_info->mac_id = si->mac_id;
|
||||
} else if (vif) {
|
||||
rtwvif = (struct rtw_vif *)vif->drv_priv;
|
||||
pkt_info->mac_id = rtwvif->mac_id;
|
||||
}
|
||||
|
||||
if (ieee80211_is_mgmt(fc) || ieee80211_is_nullfunc(fc))
|
||||
|
||||
@ -27,6 +27,7 @@ struct rtw_tx_desc {
|
||||
#define RTW_TX_DESC_W0_BMC BIT(24)
|
||||
#define RTW_TX_DESC_W0_LS BIT(26)
|
||||
#define RTW_TX_DESC_W0_DISQSELSEQ BIT(31)
|
||||
#define RTW_TX_DESC_W1_MACID GENMASK(7, 0)
|
||||
#define RTW_TX_DESC_W1_QSEL GENMASK(12, 8)
|
||||
#define RTW_TX_DESC_W1_RATE_ID GENMASK(20, 16)
|
||||
#define RTW_TX_DESC_W1_SEC_TYPE GENMASK(23, 22)
|
||||
@ -43,6 +44,7 @@ struct rtw_tx_desc {
|
||||
#define RTW_TX_DESC_W3_NAVUSEHDR BIT(15)
|
||||
#define RTW_TX_DESC_W3_MAX_AGG_NUM GENMASK(21, 17)
|
||||
#define RTW_TX_DESC_W4_DATARATE GENMASK(6, 0)
|
||||
#define RTW_TX_DESC_W4_DATARATE_FB_LIMIT GENMASK(12, 8)
|
||||
#define RTW_TX_DESC_W4_RTSRATE GENMASK(28, 24)
|
||||
#define RTW_TX_DESC_W5_DATA_SHORT BIT(4)
|
||||
#define RTW_TX_DESC_W5_DATA_BW GENMASK(6, 5)
|
||||
@ -93,7 +95,8 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev,
|
||||
struct rtw_tx_pkt_info *pkt_info,
|
||||
struct ieee80211_sta *sta,
|
||||
struct sk_buff *skb);
|
||||
void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb);
|
||||
void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev,
|
||||
struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb);
|
||||
void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn);
|
||||
void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src);
|
||||
void rtw_tx_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev,
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include <linux/mutex.h>
|
||||
#include "main.h"
|
||||
#include "debug.h"
|
||||
#include "mac.h"
|
||||
#include "reg.h"
|
||||
#include "tx.h"
|
||||
#include "rx.h"
|
||||
@ -14,6 +15,11 @@
|
||||
#include "ps.h"
|
||||
#include "usb.h"
|
||||
|
||||
static bool rtw_switch_usb_mode = true;
|
||||
module_param_named(switch_usb_mode, rtw_switch_usb_mode, bool, 0644);
|
||||
MODULE_PARM_DESC(switch_usb_mode,
|
||||
"Set to N to disable switching to USB 3 mode to avoid potential interference in the 2.4 GHz band (default: Y)");
|
||||
|
||||
#define RTW_USB_MAX_RXQ_LEN 512
|
||||
|
||||
struct rtw_usb_txcb {
|
||||
@ -418,10 +424,11 @@ static void rtw_usb_tx_handler(struct work_struct *work)
|
||||
|
||||
static void rtw_usb_tx_queue_purge(struct rtw_usb *rtwusb)
|
||||
{
|
||||
struct rtw_dev *rtwdev = rtwusb->rtwdev;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rtwusb->tx_queue); i++)
|
||||
skb_queue_purge(&rtwusb->tx_queue[i]);
|
||||
ieee80211_purge_tx_queue(rtwdev->hw, &rtwusb->tx_queue[i]);
|
||||
}
|
||||
|
||||
static void rtw_usb_write_port_complete(struct urb *urb)
|
||||
@ -452,7 +459,7 @@ static int rtw_usb_write_data(struct rtw_dev *rtwdev,
|
||||
skb_put_data(skb, buf, size);
|
||||
skb_push(skb, chip->tx_pkt_desc_sz);
|
||||
memset(skb->data, 0, chip->tx_pkt_desc_sz);
|
||||
rtw_tx_fill_tx_desc(pkt_info, skb);
|
||||
rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
|
||||
rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data);
|
||||
|
||||
ret = rtw_usb_write_port(rtwdev, qsel, skb,
|
||||
@ -472,6 +479,7 @@ static int rtw_usb_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf,
|
||||
pkt_info.tx_pkt_size = size;
|
||||
pkt_info.qsel = TX_DESC_QSEL_BEACON;
|
||||
pkt_info.offset = chip->tx_pkt_desc_sz;
|
||||
pkt_info.ls = true;
|
||||
|
||||
return rtw_usb_write_data(rtwdev, &pkt_info, buf);
|
||||
}
|
||||
@ -519,7 +527,7 @@ static int rtw_usb_tx_write(struct rtw_dev *rtwdev,
|
||||
pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
|
||||
memset(pkt_desc, 0, chip->tx_pkt_desc_sz);
|
||||
ep = qsel_to_ep(rtwusb, pkt_info->qsel);
|
||||
rtw_tx_fill_tx_desc(pkt_info, skb);
|
||||
rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
|
||||
rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data);
|
||||
tx_data = rtw_usb_get_tx_data(skb);
|
||||
tx_data->sn = pkt_info->sn;
|
||||
@ -540,67 +548,135 @@ static void rtw_usb_rx_handler(struct work_struct *work)
|
||||
{
|
||||
struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, rx_work);
|
||||
struct rtw_dev *rtwdev = rtwusb->rtwdev;
|
||||
const struct rtw_chip_info *chip = rtwdev->chip;
|
||||
struct rtw_rx_pkt_stat pkt_stat;
|
||||
struct ieee80211_rx_status rx_status;
|
||||
struct rtw_rx_pkt_stat pkt_stat;
|
||||
struct sk_buff *rx_skb;
|
||||
struct sk_buff *skb;
|
||||
u32 pkt_desc_sz = chip->rx_pkt_desc_sz;
|
||||
u32 pkt_offset;
|
||||
u32 pkt_desc_sz = rtwdev->chip->rx_pkt_desc_sz;
|
||||
u32 max_skb_len = pkt_desc_sz + PHY_STATUS_SIZE * 8 +
|
||||
IEEE80211_MAX_MPDU_LEN_VHT_11454;
|
||||
u32 pkt_offset, next_pkt, skb_len;
|
||||
u8 *rx_desc;
|
||||
int limit;
|
||||
|
||||
for (limit = 0; limit < 200; limit++) {
|
||||
skb = skb_dequeue(&rtwusb->rx_queue);
|
||||
if (!skb)
|
||||
rx_skb = skb_dequeue(&rtwusb->rx_queue);
|
||||
if (!rx_skb)
|
||||
break;
|
||||
|
||||
rx_desc = skb->data;
|
||||
chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat,
|
||||
&rx_status);
|
||||
pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz +
|
||||
pkt_stat.shift;
|
||||
|
||||
if (pkt_stat.is_c2h) {
|
||||
skb_put(skb, pkt_stat.pkt_len + pkt_offset);
|
||||
rtw_fw_c2h_cmd_rx_irqsafe(rtwdev, pkt_offset, skb);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (skb_queue_len(&rtwusb->rx_queue) >= RTW_USB_MAX_RXQ_LEN) {
|
||||
dev_dbg_ratelimited(rtwdev->dev, "failed to get rx_queue, overflow\n");
|
||||
dev_kfree_skb_any(skb);
|
||||
dev_kfree_skb_any(rx_skb);
|
||||
continue;
|
||||
}
|
||||
|
||||
skb_put(skb, pkt_stat.pkt_len);
|
||||
skb_reserve(skb, pkt_offset);
|
||||
memcpy(skb->cb, &rx_status, sizeof(rx_status));
|
||||
ieee80211_rx_irqsafe(rtwdev->hw, skb);
|
||||
rx_desc = rx_skb->data;
|
||||
|
||||
do {
|
||||
rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat,
|
||||
&rx_status);
|
||||
pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz +
|
||||
pkt_stat.shift;
|
||||
|
||||
skb_len = pkt_stat.pkt_len + pkt_offset;
|
||||
if (skb_len > max_skb_len) {
|
||||
rtw_dbg(rtwdev, RTW_DBG_USB,
|
||||
"skipping too big packet: %u\n",
|
||||
skb_len);
|
||||
goto skip_packet;
|
||||
}
|
||||
|
||||
skb = alloc_skb(skb_len, GFP_ATOMIC);
|
||||
if (!skb) {
|
||||
rtw_dbg(rtwdev, RTW_DBG_USB,
|
||||
"failed to allocate RX skb of size %u\n",
|
||||
skb_len);
|
||||
goto skip_packet;
|
||||
}
|
||||
|
||||
skb_put_data(skb, rx_desc, skb_len);
|
||||
|
||||
if (pkt_stat.is_c2h) {
|
||||
rtw_fw_c2h_cmd_rx_irqsafe(rtwdev, pkt_offset, skb);
|
||||
} else {
|
||||
skb_pull(skb, pkt_offset);
|
||||
rtw_update_rx_freq_for_invalid(rtwdev, skb,
|
||||
&rx_status,
|
||||
&pkt_stat);
|
||||
rtw_rx_stats(rtwdev, pkt_stat.vif, skb);
|
||||
memcpy(skb->cb, &rx_status, sizeof(rx_status));
|
||||
ieee80211_rx_irqsafe(rtwdev->hw, skb);
|
||||
}
|
||||
|
||||
skip_packet:
|
||||
next_pkt = round_up(skb_len, 8);
|
||||
rx_desc += next_pkt;
|
||||
} while (rx_desc + pkt_desc_sz < rx_skb->data + rx_skb->len);
|
||||
|
||||
if (skb_queue_len(&rtwusb->rx_free_queue) >= RTW_USB_RX_SKB_NUM)
|
||||
dev_kfree_skb_any(rx_skb);
|
||||
else
|
||||
skb_queue_tail(&rtwusb->rx_free_queue, rx_skb);
|
||||
}
|
||||
}
|
||||
|
||||
static void rtw_usb_read_port_complete(struct urb *urb);
|
||||
|
||||
static void rtw_usb_rx_resubmit(struct rtw_usb *rtwusb, struct rx_usb_ctrl_block *rxcb)
|
||||
static void rtw_usb_rx_resubmit(struct rtw_usb *rtwusb,
|
||||
struct rx_usb_ctrl_block *rxcb,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct rtw_dev *rtwdev = rtwusb->rtwdev;
|
||||
struct sk_buff *rx_skb;
|
||||
int error;
|
||||
|
||||
rxcb->rx_skb = alloc_skb(RTW_USB_MAX_RECVBUF_SZ, GFP_ATOMIC);
|
||||
if (!rxcb->rx_skb)
|
||||
return;
|
||||
rx_skb = skb_dequeue(&rtwusb->rx_free_queue);
|
||||
if (!rx_skb)
|
||||
rx_skb = alloc_skb(RTW_USB_MAX_RECVBUF_SZ, gfp);
|
||||
|
||||
if (!rx_skb)
|
||||
goto try_later;
|
||||
|
||||
skb_reset_tail_pointer(rx_skb);
|
||||
rx_skb->len = 0;
|
||||
|
||||
rxcb->rx_skb = rx_skb;
|
||||
|
||||
usb_fill_bulk_urb(rxcb->rx_urb, rtwusb->udev,
|
||||
usb_rcvbulkpipe(rtwusb->udev, rtwusb->pipe_in),
|
||||
rxcb->rx_skb->data, RTW_USB_MAX_RECVBUF_SZ,
|
||||
rtw_usb_read_port_complete, rxcb);
|
||||
|
||||
error = usb_submit_urb(rxcb->rx_urb, GFP_ATOMIC);
|
||||
error = usb_submit_urb(rxcb->rx_urb, gfp);
|
||||
if (error) {
|
||||
kfree_skb(rxcb->rx_skb);
|
||||
skb_queue_tail(&rtwusb->rx_free_queue, rxcb->rx_skb);
|
||||
|
||||
if (error != -ENODEV)
|
||||
rtw_err(rtwdev, "Err sending rx data urb %d\n",
|
||||
error);
|
||||
|
||||
if (error == -ENOMEM)
|
||||
goto try_later;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
try_later:
|
||||
rxcb->rx_skb = NULL;
|
||||
queue_work(rtwusb->rxwq, &rtwusb->rx_urb_work);
|
||||
}
|
||||
|
||||
static void rtw_usb_rx_resubmit_work(struct work_struct *work)
|
||||
{
|
||||
struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, rx_urb_work);
|
||||
struct rx_usb_ctrl_block *rxcb;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < RTW_USB_RXCB_NUM; i++) {
|
||||
rxcb = &rtwusb->rx_cb[i];
|
||||
|
||||
if (!rxcb->rx_skb)
|
||||
rtw_usb_rx_resubmit(rtwusb, rxcb, GFP_ATOMIC);
|
||||
}
|
||||
}
|
||||
|
||||
@ -616,14 +692,16 @@ static void rtw_usb_read_port_complete(struct urb *urb)
|
||||
urb->actual_length < 24) {
|
||||
rtw_err(rtwdev, "failed to get urb length:%d\n",
|
||||
urb->actual_length);
|
||||
if (skb)
|
||||
dev_kfree_skb_any(skb);
|
||||
skb_queue_tail(&rtwusb->rx_free_queue, skb);
|
||||
} else {
|
||||
skb_put(skb, urb->actual_length);
|
||||
skb_queue_tail(&rtwusb->rx_queue, skb);
|
||||
queue_work(rtwusb->rxwq, &rtwusb->rx_work);
|
||||
}
|
||||
rtw_usb_rx_resubmit(rtwusb, rxcb);
|
||||
rtw_usb_rx_resubmit(rtwusb, rxcb, GFP_ATOMIC);
|
||||
} else {
|
||||
skb_queue_tail(&rtwusb->rx_free_queue, skb);
|
||||
|
||||
switch (urb->status) {
|
||||
case -EINVAL:
|
||||
case -EPIPE:
|
||||
@ -641,8 +719,6 @@ static void rtw_usb_read_port_complete(struct urb *urb)
|
||||
rtw_err(rtwdev, "status %d\n", urb->status);
|
||||
break;
|
||||
}
|
||||
if (skb)
|
||||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
}
|
||||
|
||||
@ -713,9 +789,96 @@ static void rtw_usb_link_ps(struct rtw_dev *rtwdev, bool enter)
|
||||
/* empty function for rtw_hci_ops */
|
||||
}
|
||||
|
||||
static void rtw_usb_init_burst_pkt_len(struct rtw_dev *rtwdev)
|
||||
{
|
||||
struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
|
||||
enum usb_device_speed speed = rtwusb->udev->speed;
|
||||
u8 rxdma, burst_size;
|
||||
|
||||
rxdma = BIT_DMA_BURST_CNT | BIT_DMA_MODE;
|
||||
|
||||
if (speed == USB_SPEED_SUPER)
|
||||
burst_size = BIT_DMA_BURST_SIZE_1024;
|
||||
else if (speed == USB_SPEED_HIGH)
|
||||
burst_size = BIT_DMA_BURST_SIZE_512;
|
||||
else
|
||||
burst_size = BIT_DMA_BURST_SIZE_64;
|
||||
|
||||
u8p_replace_bits(&rxdma, burst_size, BIT_DMA_BURST_SIZE);
|
||||
|
||||
rtw_write8(rtwdev, REG_RXDMA_MODE, rxdma);
|
||||
rtw_write16_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN);
|
||||
}
|
||||
|
||||
static void rtw_usb_interface_cfg(struct rtw_dev *rtwdev)
|
||||
{
|
||||
/* empty function for rtw_hci_ops */
|
||||
rtw_usb_init_burst_pkt_len(rtwdev);
|
||||
}
|
||||
|
||||
static void rtw_usb_dynamic_rx_agg_v1(struct rtw_dev *rtwdev, bool enable)
|
||||
{
|
||||
u8 size, timeout;
|
||||
u16 val16;
|
||||
|
||||
rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN);
|
||||
rtw_write8_clr(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7));
|
||||
|
||||
if (enable) {
|
||||
size = 0x5;
|
||||
timeout = 0x20;
|
||||
} else {
|
||||
size = 0x0;
|
||||
timeout = 0x1;
|
||||
}
|
||||
val16 = u16_encode_bits(size, BIT_RXDMA_AGG_PG_TH) |
|
||||
u16_encode_bits(timeout, BIT_DMA_AGG_TO_V1);
|
||||
|
||||
rtw_write16(rtwdev, REG_RXDMA_AGG_PG_TH, val16);
|
||||
}
|
||||
|
||||
static void rtw_usb_dynamic_rx_agg_v2(struct rtw_dev *rtwdev, bool enable)
|
||||
{
|
||||
struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
|
||||
u8 size, timeout;
|
||||
u16 val16;
|
||||
|
||||
if (!enable) {
|
||||
size = 0x0;
|
||||
timeout = 0x1;
|
||||
} else if (rtwusb->udev->speed == USB_SPEED_SUPER) {
|
||||
size = 0x6;
|
||||
timeout = 0x1a;
|
||||
} else {
|
||||
size = 0x5;
|
||||
timeout = 0x20;
|
||||
}
|
||||
|
||||
val16 = u16_encode_bits(size, BIT_RXDMA_AGG_PG_TH) |
|
||||
u16_encode_bits(timeout, BIT_DMA_AGG_TO_V1);
|
||||
|
||||
rtw_write16(rtwdev, REG_RXDMA_AGG_PG_TH, val16);
|
||||
rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN);
|
||||
}
|
||||
|
||||
static void rtw_usb_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable)
|
||||
{
|
||||
switch (rtwdev->chip->id) {
|
||||
case RTW_CHIP_TYPE_8822C:
|
||||
case RTW_CHIP_TYPE_8822B:
|
||||
case RTW_CHIP_TYPE_8821C:
|
||||
rtw_usb_dynamic_rx_agg_v1(rtwdev, enable);
|
||||
break;
|
||||
case RTW_CHIP_TYPE_8821A:
|
||||
case RTW_CHIP_TYPE_8812A:
|
||||
rtw_usb_dynamic_rx_agg_v2(rtwdev, enable);
|
||||
break;
|
||||
case RTW_CHIP_TYPE_8723D:
|
||||
/* Doesn't like aggregation. */
|
||||
break;
|
||||
case RTW_CHIP_TYPE_8703B:
|
||||
/* Likely not found in USB devices. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct rtw_hci_ops rtw_usb_ops = {
|
||||
@ -727,6 +890,7 @@ static struct rtw_hci_ops rtw_usb_ops = {
|
||||
.deep_ps = rtw_usb_deep_ps,
|
||||
.link_ps = rtw_usb_link_ps,
|
||||
.interface_cfg = rtw_usb_interface_cfg,
|
||||
.dynamic_rx_agg = rtw_usb_dynamic_rx_agg,
|
||||
|
||||
.write8 = rtw_usb_write8,
|
||||
.write16 = rtw_usb_write16,
|
||||
@ -742,16 +906,26 @@ static struct rtw_hci_ops rtw_usb_ops = {
|
||||
static int rtw_usb_init_rx(struct rtw_dev *rtwdev)
|
||||
{
|
||||
struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
|
||||
struct sk_buff *rx_skb;
|
||||
int i;
|
||||
|
||||
rtwusb->rxwq = create_singlethread_workqueue("rtw88_usb: rx wq");
|
||||
rtwusb->rxwq = alloc_workqueue("rtw88_usb: rx wq", WQ_BH, 0);
|
||||
if (!rtwusb->rxwq) {
|
||||
rtw_err(rtwdev, "failed to create RX work queue\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
skb_queue_head_init(&rtwusb->rx_queue);
|
||||
skb_queue_head_init(&rtwusb->rx_free_queue);
|
||||
|
||||
INIT_WORK(&rtwusb->rx_work, rtw_usb_rx_handler);
|
||||
INIT_WORK(&rtwusb->rx_urb_work, rtw_usb_rx_resubmit_work);
|
||||
|
||||
for (i = 0; i < RTW_USB_RX_SKB_NUM; i++) {
|
||||
rx_skb = alloc_skb(RTW_USB_MAX_RECVBUF_SZ, GFP_KERNEL);
|
||||
if (rx_skb)
|
||||
skb_queue_tail(&rtwusb->rx_free_queue, rx_skb);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -764,7 +938,7 @@ static void rtw_usb_setup_rx(struct rtw_dev *rtwdev)
|
||||
for (i = 0; i < RTW_USB_RXCB_NUM; i++) {
|
||||
struct rx_usb_ctrl_block *rxcb = &rtwusb->rx_cb[i];
|
||||
|
||||
rtw_usb_rx_resubmit(rtwusb, rxcb);
|
||||
rtw_usb_rx_resubmit(rtwusb, rxcb, GFP_KERNEL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -776,6 +950,8 @@ static void rtw_usb_deinit_rx(struct rtw_dev *rtwdev)
|
||||
|
||||
flush_workqueue(rtwusb->rxwq);
|
||||
destroy_workqueue(rtwusb->rxwq);
|
||||
|
||||
skb_queue_purge(&rtwusb->rx_free_queue);
|
||||
}
|
||||
|
||||
static int rtw_usb_init_tx(struct rtw_dev *rtwdev)
|
||||
@ -801,9 +977,9 @@ static void rtw_usb_deinit_tx(struct rtw_dev *rtwdev)
|
||||
{
|
||||
struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
|
||||
|
||||
rtw_usb_tx_queue_purge(rtwusb);
|
||||
flush_workqueue(rtwusb->txwq);
|
||||
destroy_workqueue(rtwusb->txwq);
|
||||
rtw_usb_tx_queue_purge(rtwusb);
|
||||
}
|
||||
|
||||
static int rtw_usb_intf_init(struct rtw_dev *rtwdev,
|
||||
@ -841,6 +1017,182 @@ static void rtw_usb_intf_deinit(struct rtw_dev *rtwdev,
|
||||
usb_set_intfdata(intf, NULL);
|
||||
}
|
||||
|
||||
static int rtw_usb_switch_mode_old(struct rtw_dev *rtwdev)
|
||||
{
|
||||
struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
|
||||
enum usb_device_speed cur_speed = rtwusb->udev->speed;
|
||||
u8 hci_opt;
|
||||
|
||||
if (cur_speed == USB_SPEED_HIGH) {
|
||||
hci_opt = rtw_read8(rtwdev, REG_HCI_OPT_CTRL);
|
||||
|
||||
if ((hci_opt & (BIT(2) | BIT(3))) != BIT(3)) {
|
||||
rtw_write8(rtwdev, REG_HCI_OPT_CTRL, 0x8);
|
||||
rtw_write8(rtwdev, REG_SYS_SDIO_CTRL, 0x2);
|
||||
rtw_write8(rtwdev, REG_ACLK_MON, 0x1);
|
||||
rtw_write8(rtwdev, 0x3d, 0x3);
|
||||
/* usb disconnect */
|
||||
rtw_write8(rtwdev, REG_SYS_PW_CTRL + 1, 0x80);
|
||||
return 1;
|
||||
}
|
||||
} else if (cur_speed == USB_SPEED_SUPER) {
|
||||
rtw_write8_clr(rtwdev, REG_SYS_SDIO_CTRL, BIT(1));
|
||||
rtw_write8_clr(rtwdev, REG_ACLK_MON, BIT(0));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw_usb_switch_mode_new(struct rtw_dev *rtwdev)
|
||||
{
|
||||
enum usb_device_speed cur_speed;
|
||||
u8 id = rtwdev->chip->id;
|
||||
bool can_switch;
|
||||
u32 pad_ctrl2;
|
||||
|
||||
if (rtw_read8(rtwdev, REG_SYS_CFG2 + 3) == 0x20)
|
||||
cur_speed = USB_SPEED_SUPER;
|
||||
else
|
||||
cur_speed = USB_SPEED_HIGH;
|
||||
|
||||
if (cur_speed == USB_SPEED_SUPER)
|
||||
return 0;
|
||||
|
||||
pad_ctrl2 = rtw_read32(rtwdev, REG_PAD_CTRL2);
|
||||
|
||||
can_switch = !!(pad_ctrl2 & (BIT_MASK_USB23_SW_MODE_V1 |
|
||||
BIT_USB3_USB2_TRANSITION));
|
||||
|
||||
if (!can_switch) {
|
||||
rtw_dbg(rtwdev, RTW_DBG_USB,
|
||||
"Switching to USB 3 mode unsupported by the chip\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* At this point cur_speed is USB_SPEED_HIGH. If we already tried
|
||||
* to switch don't try again - it's a USB 2 port.
|
||||
*/
|
||||
if (u32_get_bits(pad_ctrl2, BIT_MASK_USB23_SW_MODE_V1) == BIT_USB_MODE_U3)
|
||||
return 0;
|
||||
|
||||
/* Enable IO wrapper timeout */
|
||||
if (id == RTW_CHIP_TYPE_8822B || id == RTW_CHIP_TYPE_8821C)
|
||||
rtw_write8_clr(rtwdev, REG_SW_MDIO + 3, BIT(0));
|
||||
|
||||
u32p_replace_bits(&pad_ctrl2, BIT_USB_MODE_U3, BIT_MASK_USB23_SW_MODE_V1);
|
||||
pad_ctrl2 |= BIT_RSM_EN_V1;
|
||||
|
||||
rtw_write32(rtwdev, REG_PAD_CTRL2, pad_ctrl2);
|
||||
rtw_write8(rtwdev, REG_PAD_CTRL2 + 1, 4);
|
||||
|
||||
rtw_write16_set(rtwdev, REG_SYS_PW_CTRL, BIT_APFM_OFFMAC);
|
||||
usleep_range(1000, 1001);
|
||||
rtw_write32_set(rtwdev, REG_PAD_CTRL2, BIT_NO_PDN_CHIPOFF_V1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool rtw_usb3_chip_old(u8 chip_id)
|
||||
{
|
||||
return chip_id == RTW_CHIP_TYPE_8812A;
|
||||
}
|
||||
|
||||
static bool rtw_usb3_chip_new(u8 chip_id)
|
||||
{
|
||||
return chip_id == RTW_CHIP_TYPE_8822C ||
|
||||
chip_id == RTW_CHIP_TYPE_8822B;
|
||||
}
|
||||
|
||||
static int rtw_usb_switch_mode(struct rtw_dev *rtwdev)
|
||||
{
|
||||
u8 id = rtwdev->chip->id;
|
||||
|
||||
if (!rtw_usb3_chip_new(id) && !rtw_usb3_chip_old(id))
|
||||
return 0;
|
||||
|
||||
if (!rtwdev->efuse.usb_mode_switch) {
|
||||
rtw_dbg(rtwdev, RTW_DBG_USB,
|
||||
"Switching to USB 3 mode disabled by chip's efuse\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!rtw_switch_usb_mode) {
|
||||
rtw_dbg(rtwdev, RTW_DBG_USB,
|
||||
"Switching to USB 3 mode disabled by module parameter\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rtw_usb3_chip_old(id))
|
||||
return rtw_usb_switch_mode_old(rtwdev);
|
||||
else
|
||||
return rtw_usb_switch_mode_new(rtwdev);
|
||||
}
|
||||
|
||||
#define USB_REG_PAGE 0xf4
|
||||
#define USB_PHY_PAGE0 0x9b
|
||||
#define USB_PHY_PAGE1 0xbb
|
||||
|
||||
static void rtw_usb_phy_write(struct rtw_dev *rtwdev, u8 addr, u16 data,
|
||||
enum usb_device_speed speed)
|
||||
{
|
||||
if (speed == USB_SPEED_SUPER) {
|
||||
rtw_write8(rtwdev, REG_USB3_PHY_DAT_L, data & 0xff);
|
||||
rtw_write8(rtwdev, REG_USB3_PHY_DAT_H, data >> 8);
|
||||
rtw_write8(rtwdev, REG_USB3_PHY_ADR, addr | BIT_USB3_PHY_ADR_WR);
|
||||
} else if (speed == USB_SPEED_HIGH) {
|
||||
rtw_write8(rtwdev, REG_USB2_PHY_DAT, data);
|
||||
rtw_write8(rtwdev, REG_USB2_PHY_ADR, addr);
|
||||
rtw_write8(rtwdev, REG_USB2_PHY_CMD, BIT_USB2_PHY_CMD_TRG);
|
||||
}
|
||||
}
|
||||
|
||||
static void rtw_usb_page_switch(struct rtw_dev *rtwdev,
|
||||
enum usb_device_speed speed, u8 page)
|
||||
{
|
||||
if (speed == USB_SPEED_SUPER)
|
||||
return;
|
||||
|
||||
rtw_usb_phy_write(rtwdev, USB_REG_PAGE, page, speed);
|
||||
}
|
||||
|
||||
static void rtw_usb_phy_cfg(struct rtw_dev *rtwdev,
|
||||
enum usb_device_speed speed)
|
||||
{
|
||||
const struct rtw_intf_phy_para *para = NULL;
|
||||
u16 offset;
|
||||
|
||||
if (!rtwdev->chip->intf_table)
|
||||
return;
|
||||
|
||||
if (speed == USB_SPEED_SUPER)
|
||||
para = rtwdev->chip->intf_table->usb3_para;
|
||||
else if (speed == USB_SPEED_HIGH)
|
||||
para = rtwdev->chip->intf_table->usb2_para;
|
||||
|
||||
if (!para)
|
||||
return;
|
||||
|
||||
for ( ; para->offset != 0xffff; para++) {
|
||||
if (!(para->cut_mask & BIT(rtwdev->hal.cut_version)))
|
||||
continue;
|
||||
|
||||
offset = para->offset;
|
||||
|
||||
if (para->ip_sel == RTW_IP_SEL_MAC) {
|
||||
rtw_write8(rtwdev, offset, para->value);
|
||||
} else {
|
||||
if (offset > 0x100)
|
||||
rtw_usb_page_switch(rtwdev, speed, USB_PHY_PAGE1);
|
||||
else
|
||||
rtw_usb_page_switch(rtwdev, speed, USB_PHY_PAGE0);
|
||||
|
||||
offset &= 0xff;
|
||||
|
||||
rtw_usb_phy_write(rtwdev, offset, para->value, speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
{
|
||||
struct rtw_dev *rtwdev;
|
||||
@ -896,6 +1248,17 @@ int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
goto err_destroy_rxwq;
|
||||
}
|
||||
|
||||
rtw_usb_phy_cfg(rtwdev, USB_SPEED_HIGH);
|
||||
rtw_usb_phy_cfg(rtwdev, USB_SPEED_SUPER);
|
||||
|
||||
ret = rtw_usb_switch_mode(rtwdev);
|
||||
if (ret) {
|
||||
/* Not a fail, but we do need to skip rtw_register_hw. */
|
||||
rtw_dbg(rtwdev, RTW_DBG_USB, "switching to USB 3 mode\n");
|
||||
ret = 0;
|
||||
goto err_destroy_rxwq;
|
||||
}
|
||||
|
||||
ret = rtw_register_hw(rtwdev, rtwdev->hw);
|
||||
if (ret) {
|
||||
rtw_err(rtwdev, "failed to register hw\n");
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
#define RTW_USB_RXAGG_TIMEOUT 10
|
||||
|
||||
#define RTW_USB_RXCB_NUM 4
|
||||
#define RTW_USB_RX_SKB_NUM 8
|
||||
|
||||
#define RTW_USB_EP_MAX 4
|
||||
|
||||
@ -81,7 +82,9 @@ struct rtw_usb {
|
||||
|
||||
struct rx_usb_ctrl_block rx_cb[RTW_USB_RXCB_NUM];
|
||||
struct sk_buff_head rx_queue;
|
||||
struct sk_buff_head rx_free_queue;
|
||||
struct work_struct rx_work;
|
||||
struct work_struct rx_urb_work;
|
||||
};
|
||||
|
||||
static inline struct rtw_usb_tx_data *rtw_usb_get_tx_data(struct sk_buff *skb)
|
||||
|
||||
@ -5,6 +5,7 @@ DEVRTW88DIR= ${SRCTOP}/sys/contrib/dev/rtw88
|
||||
|
||||
WITH_CONFIG_PM= 0
|
||||
WITH_DEBUGFS= 1
|
||||
WITH_LEDS= 0
|
||||
|
||||
KMOD= if_rtw88
|
||||
|
||||
@ -28,15 +29,21 @@ SRCS+= rtw8821c.c rtw8821c_table.c rtw8821ce.c # 11ac
|
||||
SRCS+= rtw8822b.c rtw8822b_table.c rtw8822be.c # 11ac
|
||||
SRCS+= rtw8822c.c rtw8822c_table.c rtw8822ce.c # 11ac
|
||||
|
||||
# USB parts
|
||||
#SRCS+= rtw88xxa.c # 88xxa common
|
||||
#SRCS+= rtw8812a.c rtw8812a_table.c rtw8812au.c
|
||||
#SRCS+= rtw8821a.c rtw8821a_table.c rtw8821au.c
|
||||
|
||||
.if defined(WITH_LEDS) && ${WITH_LEDS} > 0
|
||||
CFLAGS+= -DCONFIG_RTW88_LEDS
|
||||
SRCS+= led.c
|
||||
.endif
|
||||
|
||||
# Other
|
||||
SRCS+= ${LINUXKPI_GENSRCS}
|
||||
SRCS+= opt_wlan.h opt_inet6.h opt_inet.h
|
||||
|
||||
# Helpful after fresh imports.
|
||||
#CFLAGS+= -ferror-limit=0
|
||||
|
||||
CFLAGS+= -DKBUILD_MODNAME='"rtw88"'
|
||||
CFLAGS+= -DLINUXKPI_VERSION=60800
|
||||
|
||||
CFLAGS+= -I${DEVRTW88DIR}
|
||||
CFLAGS+= ${LINUXKPI_INCLUDES}
|
||||
@ -45,4 +52,7 @@ CFLAGS+= -DCONFIG_RTW88_DEBUG
|
||||
CFLAGS+= -DCONFIG_RTW88_DEBUGFS
|
||||
.endif
|
||||
|
||||
# Helpful after fresh imports.
|
||||
#CFLAGS+= -ferror-limit=0
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user