rtw89: update driver from upstream

This is a set of updates of the rtw89 driver based on wireless-testing
(wt-2023-05-11) 711dca0ca3d77414f8f346e564e9c8640147f40d (after v6.4-rc1).
(wt-2023-06-09) 7bd20e011626ccc3ad53e57873452b1716fcfaaa (after v6.4-rc5).
(wt-2023-07-24) 62e409149b62a285e89018e49b2e115757fb9022 (after v6.5-rc3).
(wt-2023-08-06) 2a220a15be657a24868368892e3e2caba2115283 (after v6.5-rc4).
(wt-2023-08-13) 81e147b1317ee7cde8b624ee8c0501b470d7e91c (after v6.5-rc5).

MFC after:      20 days
This commit is contained in:
Bjoern A. Zeeb 2023-05-16 23:44:56 +00:00
parent cbb3ec2523
commit e2340276fc
64 changed files with 92943 additions and 8062 deletions

View file

@ -16,12 +16,29 @@ config RTW89_CORE
config RTW89_PCI
tristate
config RTW89_8851B
tristate
config RTW89_8852A
tristate
config RTW89_8852B
tristate
config RTW89_8852C
tristate
config RTW89_8851BE
tristate "Realtek 8851BE PCI wireless network (Wi-Fi 6) adapter"
depends on PCI
select RTW89_CORE
select RTW89_PCI
select RTW89_8851B
help
Select this option will enable support for 8851BE chipset
802.11ax PCIe wireless network (Wi-Fi 6) adapter
config RTW89_8852AE
tristate "Realtek 8852AE PCI wireless network (Wi-Fi 6) adapter"
depends on PCI
@ -33,6 +50,17 @@ config RTW89_8852AE
802.11ax PCIe wireless network (Wi-Fi 6) adapter
config RTW89_8852BE
tristate "Realtek 8852BE PCI wireless network (Wi-Fi 6) adapter"
depends on PCI
select RTW89_CORE
select RTW89_PCI
select RTW89_8852B
help
Select this option will enable support for 8852BE chipset
802.11ax PCIe wireless network (Wi-Fi 6) adapter
config RTW89_8852CE
tristate "Realtek 8852CE PCI wireless network (Wi-Fi 6E) adapter"
depends on PCI

View file

@ -13,7 +13,19 @@ rtw89_core-y += core.o \
coex.o \
ps.o \
chan.o \
ser.o
ser.o \
acpi.o
rtw89_core-$(CONFIG_PM) += wow.o
obj-$(CONFIG_RTW89_8851B) += rtw89_8851b.o
rtw89_8851b-objs := rtw8851b.o \
rtw8851b_table.o \
rtw8851b_rfk.o \
rtw8851b_rfk_table.o
obj-$(CONFIG_RTW89_8851BE) += rtw89_8851be.o
rtw89_8851be-objs := rtw8851be.o
obj-$(CONFIG_RTW89_8852A) += rtw89_8852a.o
rtw89_8852a-objs := rtw8852a.o \
@ -24,6 +36,15 @@ rtw89_8852a-objs := rtw8852a.o \
obj-$(CONFIG_RTW89_8852AE) += rtw89_8852ae.o
rtw89_8852ae-objs := rtw8852ae.o
obj-$(CONFIG_RTW89_8852B) += rtw89_8852b.o
rtw89_8852b-objs := rtw8852b.o \
rtw8852b_table.o \
rtw8852b_rfk.o \
rtw8852b_rfk_table.o
obj-$(CONFIG_RTW89_8852BE) += rtw89_8852be.o
rtw89_8852be-objs := rtw8852be.o
obj-$(CONFIG_RTW89_8852C) += rtw89_8852c.o
rtw89_8852c-objs := rtw8852c.o \
rtw8852c_table.o \

View file

@ -0,0 +1,60 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2021-2023 Realtek Corporation
*/
#include <linux/acpi.h>
#include <linux/uuid.h>
#include "acpi.h"
#include "debug.h"
#if defined(__linux__)
static const guid_t rtw89_guid = GUID_INIT(0xD2A8C3E8, 0x4B69, 0x4F00,
0x82, 0xBD, 0xFE, 0x86,
0x07, 0x80, 0x3A, 0xA7);
static int rtw89_acpi_dsm_get(struct rtw89_dev *rtwdev, union acpi_object *obj,
u8 *value)
{
switch (obj->type) {
case ACPI_TYPE_INTEGER:
*value = (u8)obj->integer.value;
break;
case ACPI_TYPE_BUFFER:
*value = obj->buffer.pointer[0];
break;
default:
rtw89_debug(rtwdev, RTW89_DBG_UNEXP,
"acpi dsm return unhandled type: %d\n", obj->type);
return -EINVAL;
}
return 0;
}
int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev,
enum rtw89_acpi_dsm_func func, u8 *value)
{
union acpi_object *obj;
int ret;
obj = acpi_evaluate_dsm(ACPI_HANDLE(rtwdev->dev), &rtw89_guid,
0, func, NULL);
if (!obj) {
rtw89_debug(rtwdev, RTW89_DBG_UNEXP,
"acpi dsm fail to evaluate func: %d\n", func);
return -ENOENT;
}
ret = rtw89_acpi_dsm_get(rtwdev, obj, value);
ACPI_FREE(obj);
return ret;
}
#elif defined(__FreeBSD__)
int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev,
enum rtw89_acpi_dsm_func func, u8 *value)
{
return -ENOENT;
}
#endif

View file

@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2021-2023 Realtek Corporation
*/
#ifndef __RTW89_ACPI_H__
#define __RTW89_ACPI_H__
#include "core.h"
enum rtw89_acpi_dsm_func {
RTW89_ACPI_DSM_FUNC_IDN_BAND_SUP = 2,
RTW89_ACPI_DSM_FUNC_6G_DIS = 3,
RTW89_ACPI_DSM_FUNC_6G_BP = 4,
RTW89_ACPI_DSM_FUNC_TAS_EN = 5,
RTW89_ACPI_DSM_FUNC_59G_EN = 6,
};
int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev,
enum rtw89_acpi_dsm_func func, u8 *value);
#endif

View file

@ -4,6 +4,7 @@
#include "chan.h"
#include "debug.h"
#include "util.h"
static enum rtw89_subband rtw89_get_subband_type(enum rtw89_band band,
u8 center_chan)
@ -108,8 +109,8 @@ bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
const struct rtw89_chan *new)
{
struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_chan *chan = &hal->chan[idx];
struct rtw89_chan_rcd *rcd = &hal->chan_rcd[idx];
struct rtw89_chan *chan = &hal->sub[idx].chan;
struct rtw89_chan_rcd *rcd = &hal->sub[idx].rcd;
bool band_changed;
rcd->prev_primary_channel = chan->primary_channel;
@ -127,7 +128,7 @@ static void __rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
{
struct rtw89_hal *hal = &rtwdev->hal;
hal->chandef[idx] = *chandef;
hal->sub[idx].chandef = *chandef;
if (from_stack)
set_bit(idx, hal->entity_map);
@ -140,6 +141,38 @@ void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
__rtw89_config_entity_chandef(rtwdev, idx, chandef, true);
}
void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev,
enum rtw89_sub_entity_idx idx,
const struct cfg80211_chan_def *chandef)
{
struct rtw89_hal *hal = &rtwdev->hal;
enum rtw89_sub_entity_idx cur;
if (chandef) {
cur = atomic_cmpxchg(&hal->roc_entity_idx,
RTW89_SUB_ENTITY_IDLE, idx);
if (cur != RTW89_SUB_ENTITY_IDLE) {
rtw89_debug(rtwdev, RTW89_DBG_TXRX,
"ROC still processing on entity %d\n", idx);
return;
}
hal->roc_chandef = *chandef;
} else {
cur = atomic_cmpxchg(&hal->roc_entity_idx, idx,
RTW89_SUB_ENTITY_IDLE);
if (cur == idx)
return;
if (cur == RTW89_SUB_ENTITY_IDLE)
rtw89_debug(rtwdev, RTW89_DBG_TXRX,
"ROC already finished on entity %d\n", idx);
else
rtw89_debug(rtwdev, RTW89_DBG_TXRX,
"ROC is processing on entity %d\n", cur);
}
}
static void rtw89_config_default_chandef(struct rtw89_dev *rtwdev)
{
struct cfg80211_chan_def chandef = {0};
@ -153,6 +186,7 @@ void rtw89_entity_init(struct rtw89_dev *rtwdev)
struct rtw89_hal *hal = &rtwdev->hal;
bitmap_zero(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
atomic_set(&hal->roc_entity_idx, RTW89_SUB_ENTITY_IDLE);
rtw89_config_default_chandef(rtwdev);
}
@ -195,6 +229,7 @@ int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
rtw89_config_entity_chandef(rtwdev, idx, &ctx->def);
rtw89_set_channel(rtwdev);
cfg->idx = idx;
hal->sub[idx].cfg = cfg;
return 0;
}
@ -203,8 +238,36 @@ void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
{
struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
struct rtw89_vif *rtwvif;
u8 drop, roll;
clear_bit(cfg->idx, hal->entity_map);
drop = cfg->idx;
if (drop != RTW89_SUB_ENTITY_0)
goto out;
roll = find_next_bit(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY, drop + 1);
/* Follow rtw89_config_default_chandef() when rtw89_entity_recalc(). */
if (roll == NUM_OF_RTW89_SUB_ENTITY)
goto out;
/* RTW89_SUB_ENTITY_0 is going to release, and another exists.
* Make another roll down to RTW89_SUB_ENTITY_0 to replace.
*/
hal->sub[roll].cfg->idx = RTW89_SUB_ENTITY_0;
hal->sub[RTW89_SUB_ENTITY_0] = hal->sub[roll];
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
if (rtwvif->sub_entity_idx == roll)
rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0;
}
atomic_cmpxchg(&hal->roc_entity_idx, roll, RTW89_SUB_ENTITY_0);
drop = roll;
out:
clear_bit(drop, hal->entity_map);
rtw89_set_channel(rtwdev);
}
@ -225,6 +288,9 @@ int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct ieee80211_chanctx_conf *ctx)
{
struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
rtwvif->sub_entity_idx = cfg->idx;
return 0;
}
@ -232,4 +298,5 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct ieee80211_chanctx_conf *ctx)
{
rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0;
}

View file

@ -45,6 +45,9 @@ bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
enum rtw89_sub_entity_idx idx,
const struct cfg80211_chan_def *chandef);
void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev,
enum rtw89_sub_entity_idx idx,
const struct cfg80211_chan_def *chandef);
void rtw89_entity_init(struct rtw89_dev *rtwdev);
enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev);
int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,

File diff suppressed because it is too large Load diff

View file

@ -66,6 +66,11 @@ enum btc_rssi_st {
BTC_RSSI_ST_MAX
};
enum btc_fddt_en {
BTC_FDDT_DISABLE,
BTC_FDDT_ENABLE,
};
#define BTC_RSSI_HIGH(_rssi_) \
({typeof(_rssi_) __rssi = (_rssi_); \
((__rssi == BTC_RSSI_ST_HIGH || \
@ -126,6 +131,7 @@ enum btc_role_state {
enum btc_rfctrl {
BTC_RFCTRL_WL_OFF,
BTC_RFCTRL_WL_ON,
BTC_RFCTRL_LPS_WL_ON,
BTC_RFCTRL_FW_CTRL,
BTC_RFCTRL_MAX
};
@ -164,6 +170,7 @@ void rtw89_coex_rfk_chk_work(struct work_struct *work);
void rtw89_coex_power_on(struct rtw89_dev *rtwdev);
void rtw89_btc_set_policy(struct rtw89_dev *rtwdev, u16 policy_type);
void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type);
void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev);
static inline u8 rtw89_btc_phymap(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -32,6 +32,10 @@ enum rtw89_debug_mask {
RTW89_DBG_BF = BIT(14),
RTW89_DBG_HW_SCAN = BIT(15),
RTW89_DBG_SAR = BIT(16),
RTW89_DBG_STATE = BIT(17),
RTW89_DBG_WOW = BIT(18),
RTW89_DBG_UL_TB = BIT(19),
RTW89_DBG_CHAN = BIT(20),
#if defined(__FreeBSD__)
RTW89_DBG_IO_RW = BIT(30),

View file

@ -7,6 +7,10 @@
#include "mac.h"
#include "reg.h"
#define EF_FV_OFSET 0x5ea
#define EF_CV_MASK GENMASK(7, 4)
#define EF_CV_INV 15
enum rtw89_efuse_bank {
RTW89_EFUSE_BANK_WIFI,
RTW89_EFUSE_BANK_BT,
@ -328,3 +332,20 @@ int rtw89_parse_phycap_map(struct rtw89_dev *rtwdev)
return ret;
}
int rtw89_read_efuse_ver(struct rtw89_dev *rtwdev, u8 *ecv)
{
int ret;
u8 val;
ret = rtw89_dump_physical_efuse_map(rtwdev, &val, EF_FV_OFSET, 1, false);
if (ret)
return ret;
*ecv = u8_get_bits(val, EF_CV_MASK);
if (*ecv == EF_CV_INV)
return -ENOENT;
return 0;
}
EXPORT_SYMBOL(rtw89_read_efuse_ver);

View file

@ -9,5 +9,6 @@
int rtw89_parse_efuse_map(struct rtw89_dev *rtwdev);
int rtw89_parse_phycap_map(struct rtw89_dev *rtwdev);
int rtw89_read_efuse_ver(struct rtw89_dev *rtwdev, u8 *efv);
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -6,6 +6,7 @@
#define __RTW89_MAC_H__
#include "core.h"
#include "reg.h"
#define MAC_MEM_DUMP_PAGE_SIZE 0x40000
#define ADDR_CAM_ENT_SIZE 0x40
@ -167,6 +168,8 @@ enum rtw89_mac_ax_l0_to_l1_event {
MAC_AX_L0_TO_L1_EVENT_MAX = 15,
};
#define RTW89_PORT_OFFSET_TU_TO_32US(shift_tu) ((shift_tu) * 1024 / 32)
enum rtw89_mac_dbg_port_sel {
/* CMAC 0 related */
RTW89_DBG_PORT_SEL_PTCL_C0 = 0,
@ -210,6 +213,51 @@ enum rtw89_mac_dbg_port_sel {
RTW89_DBG_PORT_SEL_PLE_QUEMGN_QLNKTBL,
RTW89_DBG_PORT_SEL_PLE_QUEMGN_QEMPTY,
RTW89_DBG_PORT_SEL_PKTINFO,
/* DISPATCHER related */
RTW89_DBG_PORT_SEL_DSPT_HDT_TX0,
RTW89_DBG_PORT_SEL_DSPT_HDT_TX1,
RTW89_DBG_PORT_SEL_DSPT_HDT_TX2,
RTW89_DBG_PORT_SEL_DSPT_HDT_TX3,
RTW89_DBG_PORT_SEL_DSPT_HDT_TX4,
RTW89_DBG_PORT_SEL_DSPT_HDT_TX5,
RTW89_DBG_PORT_SEL_DSPT_HDT_TX6,
RTW89_DBG_PORT_SEL_DSPT_HDT_TX7,
RTW89_DBG_PORT_SEL_DSPT_HDT_TX8,
RTW89_DBG_PORT_SEL_DSPT_HDT_TX9,
RTW89_DBG_PORT_SEL_DSPT_HDT_TXA,
RTW89_DBG_PORT_SEL_DSPT_HDT_TXB,
RTW89_DBG_PORT_SEL_DSPT_HDT_TXC,
RTW89_DBG_PORT_SEL_DSPT_HDT_TXD,
RTW89_DBG_PORT_SEL_DSPT_HDT_TXE,
RTW89_DBG_PORT_SEL_DSPT_HDT_TXF,
RTW89_DBG_PORT_SEL_DSPT_CDT_TX0,
RTW89_DBG_PORT_SEL_DSPT_CDT_TX1,
RTW89_DBG_PORT_SEL_DSPT_CDT_TX3,
RTW89_DBG_PORT_SEL_DSPT_CDT_TX4,
RTW89_DBG_PORT_SEL_DSPT_CDT_TX5,
RTW89_DBG_PORT_SEL_DSPT_CDT_TX6,
RTW89_DBG_PORT_SEL_DSPT_CDT_TX7,
RTW89_DBG_PORT_SEL_DSPT_CDT_TX8,
RTW89_DBG_PORT_SEL_DSPT_CDT_TX9,
RTW89_DBG_PORT_SEL_DSPT_CDT_TXA,
RTW89_DBG_PORT_SEL_DSPT_CDT_TXB,
RTW89_DBG_PORT_SEL_DSPT_CDT_TXC,
RTW89_DBG_PORT_SEL_DSPT_HDT_RX0,
RTW89_DBG_PORT_SEL_DSPT_HDT_RX1,
RTW89_DBG_PORT_SEL_DSPT_HDT_RX2,
RTW89_DBG_PORT_SEL_DSPT_HDT_RX3,
RTW89_DBG_PORT_SEL_DSPT_HDT_RX4,
RTW89_DBG_PORT_SEL_DSPT_HDT_RX5,
RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0,
RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_0,
RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_1,
RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_2,
RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P1,
RTW89_DBG_PORT_SEL_DSPT_STF_CTRL,
RTW89_DBG_PORT_SEL_DSPT_ADDR_CTRL,
RTW89_DBG_PORT_SEL_DSPT_WDE_INTF,
RTW89_DBG_PORT_SEL_DSPT_PLE_INTF,
RTW89_DBG_PORT_SEL_DSPT_FLOW_CTRL,
/* PCIE related */
RTW89_DBG_PORT_SEL_PCIE_TXDMA,
RTW89_DBG_PORT_SEL_PCIE_RXDMA,
@ -244,6 +292,8 @@ enum rtw89_mac_dbg_port_sel {
#define BCN_IE_CAM1_BASE_ADDR 0x188A0000
#define TXD_FIFO_0_BASE_ADDR 0x18856200
#define TXD_FIFO_1_BASE_ADDR 0x188A1080
#define TXD_FIFO_0_BASE_ADDR_V1 0x18856400 /* for 8852C */
#define TXD_FIFO_1_BASE_ADDR_V1 0x188A1080 /* for 8852C */
#define TXDATA_FIFO_0_BASE_ADDR 0x18856000
#define TXDATA_FIFO_1_BASE_ADDR 0x188A1000
#define CPU_LOCAL_BASE_ADDR 0x18003000
@ -270,6 +320,8 @@ enum rtw89_mac_mem_sel {
RTW89_MAC_MEM_TXDATA_FIFO_1,
RTW89_MAC_MEM_CPU_LOCAL,
RTW89_MAC_MEM_BSSID_CAM,
RTW89_MAC_MEM_TXD_FIFO_0_V1,
RTW89_MAC_MEM_TXD_FIFO_1_V1,
/* keep last */
RTW89_MAC_MEM_NUM,
@ -305,7 +357,9 @@ enum rtw89_mac_c2h_ofld_func {
RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP,
RTW89_MAC_C2H_FUNC_BCN_RESEND,
RTW89_MAC_C2H_FUNC_MACID_PAUSE,
RTW89_MAC_C2H_FUNC_TSF32_TOGL_RPT = 0x6,
RTW89_MAC_C2H_FUNC_SCANOFLD_RSP = 0x9,
RTW89_MAC_C2H_FUNC_BCNFLTR_RPT = 0xd,
RTW89_MAC_C2H_FUNC_OFLD_MAX,
};
@ -317,6 +371,15 @@ enum rtw89_mac_c2h_info_func {
RTW89_MAC_C2H_FUNC_INFO_MAX,
};
enum rtw89_mac_c2h_mcc_func {
RTW89_MAC_C2H_FUNC_MCC_RCV_ACK = 0,
RTW89_MAC_C2H_FUNC_MCC_REQ_ACK = 1,
RTW89_MAC_C2H_FUNC_MCC_TSF_RPT = 2,
RTW89_MAC_C2H_FUNC_MCC_STATUS_RPT = 3,
NUM_OF_RTW89_MAC_C2H_FUNC_MCC,
};
enum rtw89_mac_c2h_class {
RTW89_MAC_C2H_CLASS_INFO,
RTW89_MAC_C2H_CLASS_OFLD,
@ -327,6 +390,31 @@ enum rtw89_mac_c2h_class {
RTW89_MAC_C2H_CLASS_MAX,
};
enum rtw89_mac_mcc_status {
RTW89_MAC_MCC_ADD_ROLE_OK = 0,
RTW89_MAC_MCC_START_GROUP_OK = 1,
RTW89_MAC_MCC_STOP_GROUP_OK = 2,
RTW89_MAC_MCC_DEL_GROUP_OK = 3,
RTW89_MAC_MCC_RESET_GROUP_OK = 4,
RTW89_MAC_MCC_SWITCH_CH_OK = 5,
RTW89_MAC_MCC_TXNULL0_OK = 6,
RTW89_MAC_MCC_TXNULL1_OK = 7,
RTW89_MAC_MCC_SWITCH_EARLY = 10,
RTW89_MAC_MCC_TBTT = 11,
RTW89_MAC_MCC_DURATION_START = 12,
RTW89_MAC_MCC_DURATION_END = 13,
RTW89_MAC_MCC_ADD_ROLE_FAIL = 20,
RTW89_MAC_MCC_START_GROUP_FAIL = 21,
RTW89_MAC_MCC_STOP_GROUP_FAIL = 22,
RTW89_MAC_MCC_DEL_GROUP_FAIL = 23,
RTW89_MAC_MCC_RESET_GROUP_FAIL = 24,
RTW89_MAC_MCC_SWITCH_CH_FAIL = 25,
RTW89_MAC_MCC_TXNULL0_FAIL = 26,
RTW89_MAC_MCC_TXNULL1_FAIL = 27,
};
struct rtw89_mac_ax_coex {
#define RTW89_MAC_AX_COEX_RTK_MODE 0
#define RTW89_MAC_AX_COEX_CSR_MODE 1
@ -389,6 +477,7 @@ enum rtw89_mac_bf_rrsc_rate {
#define ACCESS_CMAC(_addr) \
({typeof(_addr) __addr = (_addr); \
__addr >= R_AX_CMAC_REG_START && __addr <= R_AX_CMAC_REG_END; })
#define RTW89_MAC_AX_BAND_REG_OFFSET 0x2000
#define PTCL_IDLE_POLL_CNT 10000
#define SW_CVR_DUR_US 8
@ -414,6 +503,17 @@ enum rtw89_mac_bf_rrsc_rate {
#define S_AX_PLE_PAGE_SEL_128 1
#define S_AX_PLE_PAGE_SEL_256 2
#define B_CMAC0_MGQ_NORMAL BIT(2)
#define B_CMAC0_MGQ_NO_PWRSAV BIT(3)
#define B_CMAC0_CPUMGQ BIT(4)
#define B_CMAC1_MGQ_NORMAL BIT(10)
#define B_CMAC1_MGQ_NO_PWRSAV BIT(11)
#define B_CMAC1_CPUMGQ BIT(12)
#define QEMP_ACQ_GRP_MACID_NUM 8
#define QEMP_ACQ_GRP_QSEL_SH 4
#define QEMP_ACQ_GRP_QSEL_MASK 0xF
#define SDIO_LOCAL_BASE_ADDR 0x80000000
#define PWR_CMD_WRITE 0
@ -524,6 +624,7 @@ struct rtw89_mac_dle_dfi_qempty {
};
enum rtw89_mac_error_scenario {
RTW89_RXI300_ERROR = 1,
RTW89_WCPU_CPU_EXCEPTION = 2,
RTW89_WCPU_ASSERTION = 3,
};
@ -541,6 +642,7 @@ enum mac_ax_err_info {
MAC_AX_ERR_L0_PROMOTE_TO_L1 = 0x0010,
/* L1 */
MAC_AX_ERR_L1_PREERR_DMAC = 0x999,
MAC_AX_ERR_L1_ERR_DMAC = 0x1000,
MAC_AX_ERR_L1_RESET_DISABLE_DMAC_DONE = 0x1001,
MAC_AX_ERR_L1_RESET_RECOVERY_DONE = 0x1002,
@ -670,6 +772,7 @@ enum mac_ax_err_info {
MAC_AX_ERR_L2_ERR_WDT_TIMEOUT_INT = 0x2599,
MAC_AX_ERR_CPU_EXCEPTION = 0x3000,
MAC_AX_ERR_ASSERTION = 0x4000,
MAC_AX_ERR_RXI300 = 0x5000,
MAC_AX_GET_ERR_MAX,
MAC_AX_DUMP_SHAREBUFF_INDICATOR = 0x80000000,
@ -678,6 +781,7 @@ enum mac_ax_err_info {
MAC_AX_ERR_L1_RCVY_EN = 0x0002,
MAC_AX_ERR_L1_RCVY_STOP_REQ = 0x0003,
MAC_AX_ERR_L1_RCVY_START_REQ = 0x0004,
MAC_AX_ERR_L1_RESET_START_DMAC = 0x000A,
MAC_AX_ERR_L0_CFG_NOTIFY = 0x0010,
MAC_AX_ERR_L0_CFG_DIS_NOTIFY = 0x0011,
MAC_AX_ERR_L0_CFG_HANDSHAKE = 0x0012,
@ -689,23 +793,35 @@ struct rtw89_mac_size_set {
const struct rtw89_hfc_prec_cfg hfc_preccfg_pcie;
const struct rtw89_dle_size wde_size0;
const struct rtw89_dle_size wde_size4;
const struct rtw89_dle_size wde_size6;
const struct rtw89_dle_size wde_size7;
const struct rtw89_dle_size wde_size9;
const struct rtw89_dle_size wde_size18;
const struct rtw89_dle_size wde_size19;
const struct rtw89_dle_size ple_size0;
const struct rtw89_dle_size ple_size4;
const struct rtw89_dle_size ple_size6;
const struct rtw89_dle_size ple_size8;
const struct rtw89_dle_size ple_size18;
const struct rtw89_dle_size ple_size19;
const struct rtw89_wde_quota wde_qt0;
const struct rtw89_wde_quota wde_qt4;
const struct rtw89_wde_quota wde_qt6;
const struct rtw89_wde_quota wde_qt7;
const struct rtw89_wde_quota wde_qt17;
const struct rtw89_wde_quota wde_qt18;
const struct rtw89_ple_quota ple_qt4;
const struct rtw89_ple_quota ple_qt5;
const struct rtw89_ple_quota ple_qt13;
const struct rtw89_ple_quota ple_qt18;
const struct rtw89_ple_quota ple_qt44;
const struct rtw89_ple_quota ple_qt45;
const struct rtw89_ple_quota ple_qt46;
const struct rtw89_ple_quota ple_qt47;
const struct rtw89_ple_quota ple_qt58;
const struct rtw89_ple_quota ple_qt_52a_wow;
const struct rtw89_ple_quota ple_qt_52b_wow;
const struct rtw89_ple_quota ple_qt_51b_wow;
};
extern const struct rtw89_mac_size_set rtw89_mac_size;
@ -720,6 +836,15 @@ static inline u32 rtw89_mac_reg_by_port(u32 base, u8 port, u8 mac_idx)
return rtw89_mac_reg_by_idx(base + port * 0x40, mac_idx);
}
static inline u32
rtw89_read32_port(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, u32 base)
{
u32 reg;
reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx);
return rtw89_read32(rtwdev, reg);
}
static inline u32
rtw89_read32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
u32 base, u32 mask)
@ -799,9 +924,20 @@ int rtw89_mac_write_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 val);
int rtw89_mac_read_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 *val);
int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_vif *rtwvif_src,
u16 offset_tu);
int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
u64 *tsf);
void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif);
void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
void rtw89_mac_disable_cpu(struct rtw89_dev *rtwdev);
int rtw89_mac_enable_cpu(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw);
int rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev);
void rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev);
int rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev);
static inline int rtw89_chip_enable_bb_rf(struct rtw89_dev *rtwdev)
{
@ -810,15 +946,16 @@ static inline int rtw89_chip_enable_bb_rf(struct rtw89_dev *rtwdev)
return chip->ops->enable_bb_rf(rtwdev);
}
static inline void rtw89_chip_disable_bb_rf(struct rtw89_dev *rtwdev)
static inline int rtw89_chip_disable_bb_rf(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
chip->ops->disable_bb_rf(rtwdev);
return chip->ops->disable_bb_rf(rtwdev);
}
u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev);
int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err);
bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func);
void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
u32 len, u8 class, u8 func);
int rtw89_mac_setup_phycap(struct rtw89_dev *rtwdev);
@ -912,6 +1049,55 @@ static inline int rtw89_mac_txpwr_write32_mask(struct rtw89_dev *rtwdev,
return 0;
}
static inline void rtw89_mac_ctrl_hci_dma_tx(struct rtw89_dev *rtwdev,
bool enable)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (enable)
rtw89_write32_set(rtwdev, chip->hci_func_en_addr,
B_AX_HCI_TXDMA_EN);
else
rtw89_write32_clr(rtwdev, chip->hci_func_en_addr,
B_AX_HCI_TXDMA_EN);
}
static inline void rtw89_mac_ctrl_hci_dma_rx(struct rtw89_dev *rtwdev,
bool enable)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (enable)
rtw89_write32_set(rtwdev, chip->hci_func_en_addr,
B_AX_HCI_RXDMA_EN);
else
rtw89_write32_clr(rtwdev, chip->hci_func_en_addr,
B_AX_HCI_RXDMA_EN);
}
static inline void rtw89_mac_ctrl_hci_dma_trx(struct rtw89_dev *rtwdev,
bool enable)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (enable)
rtw89_write32_set(rtwdev, chip->hci_func_en_addr,
B_AX_HCI_TXDMA_EN | B_AX_HCI_RXDMA_EN);
else
rtw89_write32_clr(rtwdev, chip->hci_func_en_addr,
B_AX_HCI_TXDMA_EN | B_AX_HCI_RXDMA_EN);
}
static inline bool rtw89_mac_get_power_state(struct rtw89_dev *rtwdev)
{
u32 val;
val = rtw89_read32_mask(rtwdev, R_AX_IC_PWR_STATE,
B_AX_WLMAC_PWR_STE_MASK);
return !!val;
}
int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
bool resume, u32 tx_time);
int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
@ -932,11 +1118,14 @@ enum rtw89_mac_xtal_si_offset {
XTAL_SI_PWR_CUT = 0x10,
#define XTAL_SI_SMALL_PWR_CUT BIT(0)
#define XTAL_SI_BIG_PWR_CUT BIT(1)
XTAL_SI_XTAL_DRV = 0x15,
#define XTAL_SI_DRV_LATCH BIT(4)
XTAL_SI_XTAL_XMD_2 = 0x24,
#define XTAL_SI_LDO_LPS GENMASK(6, 4)
XTAL_SI_XTAL_XMD_4 = 0x26,
#define XTAL_SI_LPS_CAP GENMASK(3, 0)
XTAL_SI_CV = 0x41,
#define XTAL_SI_ACV_MASK GENMASK(3, 0)
XTAL_SI_LOW_ADDR = 0x62,
#define XTAL_SI_LOW_ADDR_MASK GENMASK(7, 0)
XTAL_SI_CTRL = 0x63,
@ -945,8 +1134,10 @@ enum rtw89_mac_xtal_si_offset {
#define XTAL_SI_HIGH_ADDR_MASK GENMASK(2, 0)
XTAL_SI_READ_VAL = 0x7A,
XTAL_SI_WL_RFC_S0 = 0x80,
#define XTAL_SI_RF00S_EN GENMASK(2, 0)
#define XTAL_SI_RF00 BIT(0)
XTAL_SI_WL_RFC_S1 = 0x81,
#define XTAL_SI_RF10S_EN GENMASK(2, 0)
#define XTAL_SI_RF10 BIT(0)
XTAL_SI_ANAPAR_WL = 0x90,
#define XTAL_SI_SRAM2RFC BIT(7)
@ -958,10 +1149,22 @@ enum rtw89_mac_xtal_si_offset {
#define XTAL_SI_PON_EI BIT(1)
#define XTAL_SI_PON_WEI BIT(0)
XTAL_SI_SRAM_CTRL = 0xA1,
#define XTAL_SI_SRAM_DIS BIT(1)
#define FULL_BIT_MASK GENMASK(7, 0)
};
int rtw89_mac_write_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 mask);
int rtw89_mac_read_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 *val);
void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
int rtw89_mac_dle_buf_req(struct rtw89_dev *rtwdev, u16 buf_len, bool wd, u16 *pkt_id);
int rtw89_mac_set_cpuio(struct rtw89_dev *rtwdev,
struct rtw89_cpuio_ctrl *ctrl_para, bool wd);
int rtw89_mac_typ_fltr_opt(struct rtw89_dev *rtwdev,
enum rtw89_machdr_frame_type type,
enum rtw89_mac_fwd_target fwd_target, u8 mac_idx);
int rtw89_mac_resize_ple_rx_quota(struct rtw89_dev *rtwdev, bool wow);
int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev,
enum rtw89_mac_idx band);
void rtw89_mac_hw_mgnt_sec(struct rtw89_dev *rtwdev, bool wow);
#endif

View file

@ -13,6 +13,8 @@
#include "reg.h"
#include "sar.h"
#include "ser.h"
#include "util.h"
#include "wow.h"
static void rtw89_ops_tx(struct ieee80211_hw *hw,
struct ieee80211_tx_control *control,
@ -21,9 +23,19 @@ static void rtw89_ops_tx(struct ieee80211_hw *hw,
struct rtw89_dev *rtwdev = hw->priv;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_vif *vif = info->control.vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct ieee80211_sta *sta = control->sta;
u32 flags = IEEE80211_SKB_CB(skb)->flags;
int ret, qsel;
if (rtwvif->offchan && !(flags & IEEE80211_TX_CTL_TX_OFFCHAN) && sta) {
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
rtw89_debug(rtwdev, RTW89_DBG_TXRX, "ops_tx during offchan\n");
skb_queue_tail(&rtwsta->roc_queue, skb);
return;
}
ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, &qsel);
if (ret) {
rtw89_err(rtwdev, "failed to transmit skb: %d\n", ret);
@ -77,15 +89,6 @@ static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed)
!(hw->conf.flags & IEEE80211_CONF_IDLE))
rtw89_leave_ips(rtwdev);
if (changed & IEEE80211_CONF_CHANGE_PS) {
if (hw->conf.flags & IEEE80211_CONF_PS) {
rtwdev->lps_enabled = true;
} else {
rtw89_leave_lps(rtwdev);
rtwdev->lps_enabled = false;
}
}
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
rtw89_config_entity_chandef(rtwdev, RTW89_SUB_ENTITY_0,
&hw->conf.chandef);
@ -93,7 +96,8 @@ static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed)
}
if ((changed & IEEE80211_CONF_CHANGE_IDLE) &&
(hw->conf.flags & IEEE80211_CONF_IDLE))
(hw->conf.flags & IEEE80211_CONF_IDLE) &&
!rtwdev->scanning)
rtw89_enter_ips(rtwdev);
mutex_unlock(&rtwdev->mutex);
@ -108,10 +112,23 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
int ret = 0;
rtw89_debug(rtwdev, RTW89_DBG_STATE, "add vif %pM type %d, p2p %d\n",
vif->addr, vif->type, vif->p2p);
mutex_lock(&rtwdev->mutex);
rtw89_leave_ips_by_hwflags(rtwdev);
if (RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw))
vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
IEEE80211_VIF_SUPPORTS_CQM_RSSI;
rtwvif->rtwdev = rtwdev;
rtwvif->roc.state = RTW89_ROC_IDLE;
rtwvif->offchan = false;
list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list);
INIT_WORK(&rtwvif->update_beacon_work, rtw89_core_update_beacon_work);
INIT_DELAYED_WORK(&rtwvif->roc.roc_work, rtw89_roc_work);
rtw89_leave_ps_mode(rtwdev);
rtw89_traffic_stats_init(rtwdev, &rtwvif->stats);
@ -120,24 +137,31 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
RTW89_PORT_NUM);
if (rtwvif->port == RTW89_PORT_NUM) {
ret = -ENOSPC;
list_del_init(&rtwvif->list);
goto out;
}
rtwvif->bcn_hit_cond = 0;
rtwvif->mac_idx = RTW89_MAC_0;
rtwvif->phy_idx = RTW89_PHY_0;
rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0;
rtwvif->hit_rule = 0;
rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
ether_addr_copy(rtwvif->mac_addr, vif->addr);
INIT_LIST_HEAD(&rtwvif->general_pkt_list);
ret = rtw89_mac_add_vif(rtwdev, rtwvif);
if (ret) {
rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
list_del_init(&rtwvif->list);
goto out;
}
rtw89_core_txq_init(rtwdev, vif->txq);
rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_START);
rtw89_recalc_lps(rtwdev);
out:
mutex_unlock(&rtwdev->mutex);
@ -150,7 +174,11 @@ static void rtw89_ops_remove_interface(struct ieee80211_hw *hw,
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
rtw89_debug(rtwdev, RTW89_DBG_STATE, "remove vif %pM type %d p2p %d\n",
vif->addr, vif->type, vif->p2p);
cancel_work_sync(&rtwvif->update_beacon_work);
cancel_delayed_work_sync(&rtwvif->roc.roc_work);
mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
@ -158,9 +186,38 @@ static void rtw89_ops_remove_interface(struct ieee80211_hw *hw,
rtw89_mac_remove_vif(rtwdev, rtwvif);
rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
list_del_init(&rtwvif->list);
rtw89_recalc_lps(rtwdev);
rtw89_enter_ips_by_hwflags(rtwdev);
mutex_unlock(&rtwdev->mutex);
}
static int rtw89_ops_change_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
enum nl80211_iftype type, bool p2p)
{
struct rtw89_dev *rtwdev = hw->priv;
int ret;
set_bit(RTW89_FLAG_CHANGING_INTERFACE, rtwdev->flags);
rtw89_debug(rtwdev, RTW89_DBG_STATE, "change vif %pM (%d)->(%d), p2p (%d)->(%d)\n",
vif->addr, vif->type, type, vif->p2p, p2p);
rtw89_ops_remove_interface(hw, vif);
vif->type = type;
vif->p2p = p2p;
ret = rtw89_ops_add_interface(hw, vif);
if (ret)
rtw89_warn(rtwdev, "failed to change interface %d\n", ret);
clear_bit(RTW89_FLAG_CHANGING_INTERFACE, rtwdev->flags);
return ret;
}
static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
unsigned int *new_flags,
@ -355,7 +412,7 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
rtw89_phy_set_bss_color(rtwdev, vif);
rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, vif);
rtw89_mac_port_update(rtwdev, rtwvif);
rtw89_store_op_chan(rtwdev, true);
rtw89_mac_set_he_obss_narrow_bw_ru(rtwdev, vif);
} else {
/* Abort ongoing scan if cancel_scan isn't issued
* when disconnected by peer
@ -383,6 +440,15 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_MU_GROUPS)
rtw89_mac_bf_set_gid_table(rtwdev, vif, conf);
if (changed & BSS_CHANGED_P2P_PS)
rtw89_process_p2p_ps(rtwdev, vif);
if (changed & BSS_CHANGED_CQM)
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true);
if (changed & BSS_CHANGED_PS)
rtw89_recalc_lps(rtwdev);
mutex_unlock(&rtwdev->mutex);
}
@ -392,8 +458,16 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw,
{
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
const struct rtw89_chan *chan;
mutex_lock(&rtwdev->mutex);
chan = rtw89_chan_get(rtwdev, rtwvif->sub_entity_idx);
if (chan->band_type == RTW89_BAND_6G) {
mutex_unlock(&rtwdev->mutex);
return -EOPNOTSUPP;
}
ether_addr_copy(rtwvif->bssid, vif->bss_conf.bssid);
rtw89_cam_bssid_changed(rtwdev, rtwvif);
rtw89_mac_port_update(rtwdev, rtwvif);
@ -415,6 +489,7 @@ void rtw89_ops_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
mutex_lock(&rtwdev->mutex);
rtw89_mac_stop_ap(rtwdev, rtwvif);
rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, NULL);
rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true);
mutex_unlock(&rtwdev->mutex);
@ -610,6 +685,20 @@ static void rtw89_ops_sta_statistics(struct ieee80211_hw *hw,
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
}
static
void __rtw89_drop_packets(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
{
struct rtw89_vif *rtwvif;
if (vif) {
rtwvif = (struct rtw89_vif *)vif->drv_priv;
rtw89_mac_pkt_drop_vif(rtwdev, rtwvif);
} else {
rtw89_for_each_rtwvif(rtwdev, rtwvif)
rtw89_mac_pkt_drop_vif(rtwdev, rtwvif);
}
}
static void rtw89_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u32 queues, bool drop)
{
@ -618,7 +707,12 @@ static void rtw89_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
mutex_lock(&rtwdev->mutex);
rtw89_leave_lps(rtwdev);
rtw89_hci_flush_queues(rtwdev, queues, drop);
rtw89_mac_flush_txq(rtwdev, queues, drop);
if (drop && !RTW89_CHK_FW_FEATURE(NO_PACKET_DROP, &rtwdev->fw))
__rtw89_drop_packets(rtwdev, vif);
else
rtw89_mac_flush_txq(rtwdev, queues, drop);
mutex_unlock(&rtwdev->mutex);
}
@ -634,7 +728,7 @@ static void rtw89_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta->rtwvif);
if (vif != br_data->vif)
if (vif != br_data->vif || vif->p2p)
return;
rtwsta->use_cfg_mask = true;
@ -674,12 +768,18 @@ int rtw89_ops_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_hal *hal = &rtwdev->hal;
if (rx_ant != hw->wiphy->available_antennas_rx)
if (hal->ant_diversity) {
if (tx_ant != rx_ant || hweight32(tx_ant) != 1)
return -EINVAL;
} else if (rx_ant != hw->wiphy->available_antennas_rx && rx_ant != hal->antenna_rx) {
return -EINVAL;
}
mutex_lock(&rtwdev->mutex);
hal->antenna_tx = tx_ant;
hal->antenna_rx = rx_ant;
hal->tx_path_diversity = false;
hal->ant_diversity_fixed = true;
mutex_unlock(&rtwdev->mutex);
return 0;
@ -732,12 +832,13 @@ static int rtw89_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_scan_request *req)
{
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
int ret = 0;
if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw))
return 1;
if (rtwdev->scanning)
if (rtwdev->scanning || rtwvif->offchan)
return -EBUSY;
mutex_lock(&rtwdev->mutex);
@ -840,6 +941,140 @@ static void rtw89_ops_unassign_vif_chanctx(struct ieee80211_hw *hw,
mutex_unlock(&rtwdev->mutex);
}
static int rtw89_ops_remain_on_channel(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_channel *chan,
int duration,
enum ieee80211_roc_type type)
{
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
struct rtw89_roc *roc = &rtwvif->roc;
if (!vif)
return -EINVAL;
mutex_lock(&rtwdev->mutex);
if (roc->state != RTW89_ROC_IDLE) {
mutex_unlock(&rtwdev->mutex);
return -EBUSY;
}
if (rtwdev->scanning)
rtw89_hw_scan_abort(rtwdev, vif);
if (type == IEEE80211_ROC_TYPE_MGMT_TX)
roc->state = RTW89_ROC_MGMT;
else
roc->state = RTW89_ROC_NORMAL;
roc->duration = duration;
roc->chan = *chan;
roc->type = type;
rtw89_roc_start(rtwdev, rtwvif);
mutex_unlock(&rtwdev->mutex);
return 0;
}
static int rtw89_ops_cancel_remain_on_channel(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
if (!rtwvif)
return -EINVAL;
cancel_delayed_work_sync(&rtwvif->roc.roc_work);
mutex_lock(&rtwdev->mutex);
rtw89_roc_end(rtwdev, rtwvif);
mutex_unlock(&rtwdev->mutex);
return 0;
}
static void rtw89_set_tid_config_iter(void *data, struct ieee80211_sta *sta)
{
struct cfg80211_tid_config *tid_config = data;
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct rtw89_dev *rtwdev = rtwsta->rtwvif->rtwdev;
rtw89_core_set_tid_config(rtwdev, sta, tid_config);
}
static int rtw89_ops_set_tid_config(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct cfg80211_tid_config *tid_config)
{
struct rtw89_dev *rtwdev = hw->priv;
mutex_lock(&rtwdev->mutex);
if (sta)
rtw89_core_set_tid_config(rtwdev, sta, tid_config);
else
ieee80211_iterate_stations_atomic(rtwdev->hw,
rtw89_set_tid_config_iter,
tid_config);
mutex_unlock(&rtwdev->mutex);
return 0;
}
#ifdef CONFIG_PM
static int rtw89_ops_suspend(struct ieee80211_hw *hw,
struct cfg80211_wowlan *wowlan)
{
struct rtw89_dev *rtwdev = hw->priv;
int ret;
set_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags);
cancel_delayed_work_sync(&rtwdev->track_work);
mutex_lock(&rtwdev->mutex);
ret = rtw89_wow_suspend(rtwdev, wowlan);
mutex_unlock(&rtwdev->mutex);
if (ret) {
rtw89_warn(rtwdev, "failed to suspend for wow %d\n", ret);
clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags);
return 1;
}
return 0;
}
static int rtw89_ops_resume(struct ieee80211_hw *hw)
{
struct rtw89_dev *rtwdev = hw->priv;
int ret;
mutex_lock(&rtwdev->mutex);
ret = rtw89_wow_resume(rtwdev);
if (ret)
rtw89_warn(rtwdev, "failed to resume for wow %d\n", ret);
mutex_unlock(&rtwdev->mutex);
clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags);
ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work,
RTW89_TRACK_WORK_PERIOD);
return ret ? 1 : 0;
}
static void rtw89_ops_set_wakeup(struct ieee80211_hw *hw, bool enabled)
{
struct rtw89_dev *rtwdev = hw->priv;
device_set_wakeup_enable(rtwdev->dev, enabled);
}
#endif
const struct ieee80211_ops rtw89_ops = {
.tx = rtw89_ops_tx,
.wake_tx_queue = rtw89_ops_wake_tx_queue,
@ -847,6 +1082,7 @@ const struct ieee80211_ops rtw89_ops = {
.stop = rtw89_ops_stop,
.config = rtw89_ops_config,
.add_interface = rtw89_ops_add_interface,
.change_interface = rtw89_ops_change_interface,
.remove_interface = rtw89_ops_remove_interface,
.configure_filter = rtw89_ops_configure_filter,
.bss_info_changed = rtw89_ops_bss_info_changed,
@ -873,7 +1109,15 @@ const struct ieee80211_ops rtw89_ops = {
.change_chanctx = rtw89_ops_change_chanctx,
.assign_vif_chanctx = rtw89_ops_assign_vif_chanctx,
.unassign_vif_chanctx = rtw89_ops_unassign_vif_chanctx,
.remain_on_channel = rtw89_ops_remain_on_channel,
.cancel_remain_on_channel = rtw89_ops_cancel_remain_on_channel,
.set_sar_specs = rtw89_ops_set_sar_specs,
.sta_rc_update = rtw89_ops_sta_rc_update,
.set_tid_config = rtw89_ops_set_tid_config,
#ifdef CONFIG_PM
.suspend = rtw89_ops_suspend,
.resume = rtw89_ops_resume,
.set_wakeup = rtw89_ops_set_wakeup,
#endif
};
EXPORT_SYMBOL(rtw89_ops);

View file

@ -173,6 +173,34 @@ static int rtw89_pci_rxbd_info_update(struct rtw89_dev *rtwdev,
return 0;
}
static void rtw89_pci_ctrl_txdma_ch_pcie(struct rtw89_dev *rtwdev, bool enable)
{
const struct rtw89_pci_info *info = rtwdev->pci_info;
const struct rtw89_reg_def *dma_stop1 = &info->dma_stop1;
const struct rtw89_reg_def *dma_stop2 = &info->dma_stop2;
if (enable) {
rtw89_write32_clr(rtwdev, dma_stop1->addr, dma_stop1->mask);
if (dma_stop2->addr)
rtw89_write32_clr(rtwdev, dma_stop2->addr, dma_stop2->mask);
} else {
rtw89_write32_set(rtwdev, dma_stop1->addr, dma_stop1->mask);
if (dma_stop2->addr)
rtw89_write32_set(rtwdev, dma_stop2->addr, dma_stop2->mask);
}
}
static void rtw89_pci_ctrl_txdma_fw_ch_pcie(struct rtw89_dev *rtwdev, bool enable)
{
const struct rtw89_pci_info *info = rtwdev->pci_info;
const struct rtw89_reg_def *dma_stop1 = &info->dma_stop1;
if (enable)
rtw89_write32_clr(rtwdev, dma_stop1->addr, B_AX_STOP_CH12);
else
rtw89_write32_set(rtwdev, dma_stop1->addr, B_AX_STOP_CH12);
}
static bool
rtw89_skb_put_rx_data(struct rtw89_dev *rtwdev, bool fs, bool ls,
struct sk_buff *new,
@ -241,18 +269,16 @@ static u32 rtw89_pci_rxbd_deliver_skbs(struct rtw89_dev *rtwdev,
goto err_sync_device;
}
rtw89_core_query_rxdesc(rtwdev, desc_info, skb->data, rxinfo_size);
rtw89_chip_query_rxdesc(rtwdev, desc_info, skb->data, rxinfo_size);
new = dev_alloc_skb(desc_info->pkt_size);
new = rtw89_alloc_skb_for_rx(rtwdev, desc_info->pkt_size);
if (!new)
goto err_sync_device;
rx_ring->diliver_skb = new;
/* first segment has RX desc */
offset = desc_info->offset;
offset += desc_info->long_rxdesc ? sizeof(struct rtw89_rxdesc_long) :
sizeof(struct rtw89_rxdesc_short);
offset = desc_info->offset + desc_info->rxd_len;
} else {
offset = sizeof(struct rtw89_pci_rxbd_info);
if (!new) {
@ -340,8 +366,11 @@ static void rtw89_pci_tx_status(struct rtw89_dev *rtwdev,
struct rtw89_pci_tx_ring *tx_ring,
struct sk_buff *skb, u8 tx_status)
{
struct rtw89_tx_skb_data *skb_data = RTW89_TX_SKB_CB(skb);
struct ieee80211_tx_info *info;
rtw89_core_tx_wait_complete(rtwdev, skb_data, tx_status == RTW89_TX_DONE);
info = IEEE80211_SKB_CB(skb);
ieee80211_tx_info_clear_status(info);
@ -519,12 +548,10 @@ static u32 rtw89_pci_release_tx_skbs(struct rtw89_dev *rtwdev,
return cnt;
}
rtw89_core_query_rxdesc(rtwdev, &desc_info, skb->data, rxinfo_size);
rtw89_chip_query_rxdesc(rtwdev, &desc_info, skb->data, rxinfo_size);
/* first segment has RX desc */
offset = desc_info.offset;
offset += desc_info.long_rxdesc ? sizeof(struct rtw89_rxdesc_long) :
sizeof(struct rtw89_rxdesc_short);
offset = desc_info.offset + desc_info.rxd_len;
for (; offset + rpp_size <= rx_info->len; offset += rpp_size) {
rpp = (struct rtw89_pci_rpp_fmt *)(skb->data + offset);
rtw89_pci_release_rpp(rtwdev, rpp);
@ -947,8 +974,10 @@ static u32 __rtw89_pci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev,
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx_rings[txch];
struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring;
const struct rtw89_chip_info *chip = rtwdev->chip;
u32 bd_cnt, wd_cnt, min_cnt = 0;
struct rtw89_pci_rx_ring *rx_ring;
enum rtw89_debug_mask debug_mask;
u32 cnt;
rx_ring = &rtwpci->rx_rings[RTW89_RXCH_RPQ];
@ -972,10 +1001,20 @@ static u32 __rtw89_pci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev,
bd_cnt = rtw89_pci_get_avail_txbd_num(tx_ring);
wd_cnt = wd_ring->curr_num;
min_cnt = min(bd_cnt, wd_cnt);
if (min_cnt == 0)
rtw89_debug(rtwdev, rtwpci->low_power ? RTW89_DBG_TXRX : RTW89_DBG_UNEXP,
if (min_cnt == 0) {
/* This message can be frequently shown in low power mode or
* high traffic with small FIFO chips, and we have recognized it as normal
* behavior, so print with mask RTW89_DBG_TXRX in these situations.
*/
if (rtwpci->low_power || chip->small_fifo_size)
debug_mask = RTW89_DBG_TXRX;
else
debug_mask = RTW89_DBG_UNEXP;
rtw89_debug(rtwdev, debug_mask,
"still no tx resource after reclaim: wd_cnt=%d bd_cnt=%d\n",
wd_cnt, bd_cnt);
}
out_unlock:
spin_unlock_bh(&rtwpci->trx_lock);
@ -1080,12 +1119,15 @@ static void __pci_flush_txch(struct rtw89_dev *rtwdev, u8 txch, bool drop)
static void __rtw89_pci_ops_flush_txchs(struct rtw89_dev *rtwdev, u32 txchs,
bool drop)
{
const struct rtw89_pci_info *info = rtwdev->pci_info;
u8 i;
for (i = 0; i < RTW89_TXCH_NUM; i++) {
/* It may be unnecessary to flush FWCMD queue. */
if (i == RTW89_TXCH_CH12)
continue;
if (info->tx_dma_ch_mask & BIT(i))
continue;
if (txchs & BIT(i))
__pci_flush_txch(rtwdev, i, drop);
@ -1164,6 +1206,7 @@ static int rtw89_pci_txwd_submit(struct rtw89_dev *rtwdev,
struct pci_dev *pdev = rtwpci->pdev;
struct sk_buff *skb = tx_req->skb;
struct rtw89_pci_tx_data *tx_data = RTW89_PCI_TX_SKB_CB(skb);
struct rtw89_tx_skb_data *skb_data = RTW89_TX_SKB_CB(skb);
bool en_wd_info = desc_info->en_wd_info;
u32 txwd_len;
u32 txwp_len;
@ -1179,6 +1222,7 @@ static int rtw89_pci_txwd_submit(struct rtw89_dev *rtwdev,
}
tx_data->dma = dma;
rcu_assign_pointer(skb_data->wait, NULL);
txwp_len = sizeof(*txwp_info);
txwd_len = chip->txwd_body_size;
@ -1353,7 +1397,7 @@ static int rtw89_pci_ops_tx_write(struct rtw89_dev *rtwdev, struct rtw89_core_tx
return 0;
}
static const struct rtw89_pci_bd_ram bd_ram_table[RTW89_TXCH_NUM] = {
const struct rtw89_pci_bd_ram rtw89_bd_ram_table_dual[RTW89_TXCH_NUM] = {
[RTW89_TXCH_ACH0] = {.start_idx = 0, .max_num = 5, .min_num = 2},
[RTW89_TXCH_ACH1] = {.start_idx = 5, .max_num = 5, .min_num = 2},
[RTW89_TXCH_ACH2] = {.start_idx = 10, .max_num = 5, .min_num = 2},
@ -1368,10 +1412,24 @@ static const struct rtw89_pci_bd_ram bd_ram_table[RTW89_TXCH_NUM] = {
[RTW89_TXCH_CH11] = {.start_idx = 55, .max_num = 5, .min_num = 1},
[RTW89_TXCH_CH12] = {.start_idx = 60, .max_num = 4, .min_num = 1},
};
EXPORT_SYMBOL(rtw89_bd_ram_table_dual);
const struct rtw89_pci_bd_ram rtw89_bd_ram_table_single[RTW89_TXCH_NUM] = {
[RTW89_TXCH_ACH0] = {.start_idx = 0, .max_num = 5, .min_num = 2},
[RTW89_TXCH_ACH1] = {.start_idx = 5, .max_num = 5, .min_num = 2},
[RTW89_TXCH_ACH2] = {.start_idx = 10, .max_num = 5, .min_num = 2},
[RTW89_TXCH_ACH3] = {.start_idx = 15, .max_num = 5, .min_num = 2},
[RTW89_TXCH_CH8] = {.start_idx = 20, .max_num = 4, .min_num = 1},
[RTW89_TXCH_CH9] = {.start_idx = 24, .max_num = 4, .min_num = 1},
[RTW89_TXCH_CH12] = {.start_idx = 28, .max_num = 4, .min_num = 1},
};
EXPORT_SYMBOL(rtw89_bd_ram_table_single);
static void rtw89_pci_reset_trx_rings(struct rtw89_dev *rtwdev)
{
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
const struct rtw89_pci_info *info = rtwdev->pci_info;
const struct rtw89_pci_bd_ram *bd_ram_table = *info->bd_ram_table;
struct rtw89_pci_tx_ring *tx_ring;
struct rtw89_pci_rx_ring *rx_ring;
struct rtw89_pci_dma_ring *bd_ring;
@ -1383,6 +1441,9 @@ static void rtw89_pci_reset_trx_rings(struct rtw89_dev *rtwdev)
int i;
for (i = 0; i < RTW89_TXCH_NUM; i++) {
if (info->tx_dma_ch_mask & BIT(i))
continue;
tx_ring = &rtwpci->tx_rings[i];
bd_ring = &tx_ring->bd_ring;
bd_ram = &bd_ram_table[i];
@ -1426,12 +1487,15 @@ static void rtw89_pci_release_tx_ring(struct rtw89_dev *rtwdev,
static void rtw89_pci_ops_reset(struct rtw89_dev *rtwdev)
{
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
const struct rtw89_pci_info *info = rtwdev->pci_info;
int txch;
rtw89_pci_reset_trx_rings(rtwdev);
spin_lock_bh(&rtwpci->trx_lock);
for (txch = 0; txch < RTW89_TXCH_NUM; txch++) {
if (info->tx_dma_ch_mask & BIT(txch))
continue;
if (txch == RTW89_TXCH_CH12) {
rtw89_pci_release_fwcmd(rtwdev, rtwpci,
skb_queue_len(&rtwpci->h2c_queue), true);
@ -1676,35 +1740,41 @@ static void rtw89_pci_ops_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data)
#endif
}
static void rtw89_pci_ctrl_dma_all(struct rtw89_dev *rtwdev, bool enable)
static void rtw89_pci_ctrl_dma_trx(struct rtw89_dev *rtwdev, bool enable)
{
const struct rtw89_pci_info *info = rtwdev->pci_info;
if (enable)
rtw89_write32_set(rtwdev, info->init_cfg_reg,
info->rxhci_en_bit | info->txhci_en_bit);
else
rtw89_write32_clr(rtwdev, info->init_cfg_reg,
info->rxhci_en_bit | info->txhci_en_bit);
}
static void rtw89_pci_ctrl_dma_io(struct rtw89_dev *rtwdev, bool enable)
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
const struct rtw89_pci_info *info = rtwdev->pci_info;
u32 txhci_en = info->txhci_en_bit;
u32 rxhci_en = info->rxhci_en_bit;
u32 reg, mask;
if (enable) {
if (chip_id != RTL8852C)
rtw89_write32_clr(rtwdev, info->dma_stop1_reg,
B_AX_STOP_PCIEIO);
rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1,
txhci_en | rxhci_en);
if (chip_id == RTL8852C)
rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1,
B_AX_STOP_AXI_MST);
if (chip_id == RTL8852C) {
reg = R_AX_HAXI_INIT_CFG1;
mask = B_AX_STOP_AXI_MST;
} else {
if (chip_id != RTL8852C)
rtw89_write32_set(rtwdev, info->dma_stop1_reg,
B_AX_STOP_PCIEIO);
else
rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1,
B_AX_STOP_AXI_MST);
rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1,
txhci_en | rxhci_en);
if (chip_id == RTL8852C)
rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1,
B_AX_STOP_AXI_MST);
reg = R_AX_PCIE_DMA_STOP1;
mask = B_AX_STOP_PCIEIO;
}
if (enable)
rtw89_write32_clr(rtwdev, reg, mask);
else
rtw89_write32_set(rtwdev, reg, mask);
}
static void rtw89_pci_ctrl_dma_all(struct rtw89_dev *rtwdev, bool enable)
{
rtw89_pci_ctrl_dma_io(rtwdev, enable);
rtw89_pci_ctrl_dma_trx(rtwdev, enable);
}
static int rtw89_pci_check_mdio(struct rtw89_dev *rtwdev, u8 addr, u8 speed, u16 rw_bit)
@ -1910,15 +1980,29 @@ __get_target(struct rtw89_dev *rtwdev, u16 *target, enum rtw89_pcie_phy phy_rate
return 0;
}
static int rtw89_pci_autok_x(struct rtw89_dev *rtwdev)
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
int ret;
if (chip_id != RTL8852B && chip_id != RTL8851B)
return 0;
ret = rtw89_write16_mdio_mask(rtwdev, RAC_REG_FLD_0, BAC_AUTOK_N_MASK,
PCIE_AUTOK_4, PCIE_PHY_GEN1);
return ret;
}
static int rtw89_pci_auto_refclk_cal(struct rtw89_dev *rtwdev, bool autook_en)
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
enum rtw89_pcie_phy phy_rate;
u16 val16, mgn_set, div_set, tar;
u8 val8, bdr_ori;
bool l1_flag = false;
int ret = 0;
if (rtwdev->chip->chip_id != RTL8852B)
if (chip_id != RTL8852B && chip_id != RTL8851B)
return 0;
ret = rtw89_pci_read_config_byte(rtwdev, RTW89_PCIE_PHY_RATE, &val8);
@ -2095,7 +2179,9 @@ static void rtw89_pci_rxdma_prefth(struct rtw89_dev *rtwdev)
static void rtw89_pci_l1off_pwroff(struct rtw89_dev *rtwdev)
{
if (rtwdev->chip->chip_id != RTL8852A && rtwdev->chip->chip_id != RTL8852B)
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
if (chip_id != RTL8852A && chip_id != RTL8852B && chip_id != RTL8851B)
return;
rtw89_write32_clr(rtwdev, R_AX_PCIE_PS_CTRL, B_AX_L1OFF_PWR_OFF_EN);
@ -2123,7 +2209,9 @@ static u32 rtw89_pci_l2_rxen_lat(struct rtw89_dev *rtwdev)
static void rtw89_pci_aphy_pwrcut(struct rtw89_dev *rtwdev)
{
if (rtwdev->chip->chip_id != RTL8852A)
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
if (chip_id != RTL8852A && chip_id != RTL8852B && chip_id != RTL8851B)
return;
rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_PSUS_OFF_CAPC_EN);
@ -2131,8 +2219,9 @@ static void rtw89_pci_aphy_pwrcut(struct rtw89_dev *rtwdev)
static void rtw89_pci_hci_ldo(struct rtw89_dev *rtwdev)
{
if (rtwdev->chip->chip_id == RTL8852A ||
rtwdev->chip->chip_id == RTL8852B) {
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) {
rtw89_write32_set(rtwdev, R_AX_SYS_SDIO_CTRL,
B_AX_PCIE_DIS_L2_CTRL_LDO_HCI);
rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL,
@ -2145,7 +2234,9 @@ static void rtw89_pci_hci_ldo(struct rtw89_dev *rtwdev)
static int rtw89_pci_dphy_delay(struct rtw89_dev *rtwdev)
{
if (rtwdev->chip->chip_id != RTL8852B)
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
if (chip_id != RTL8852B && chip_id != RTL8851B)
return 0;
return rtw89_write16_mdio_mask(rtwdev, RAC_REG_REV2, BAC_CMU_EN_DLY_MASK,
@ -2308,19 +2399,19 @@ static int rtw89_poll_txdma_ch_idle_pcie(struct rtw89_dev *rtwdev)
{
const struct rtw89_pci_info *info = rtwdev->pci_info;
u32 ret, check, dma_busy;
u32 dma_busy1 = info->dma_busy1_reg;
u32 dma_busy1 = info->dma_busy1.addr;
u32 dma_busy2 = info->dma_busy2_reg;
check = B_AX_ACH0_BUSY | B_AX_ACH1_BUSY | B_AX_ACH2_BUSY |
B_AX_ACH3_BUSY | B_AX_ACH4_BUSY | B_AX_ACH5_BUSY |
B_AX_ACH6_BUSY | B_AX_ACH7_BUSY | B_AX_CH8_BUSY |
B_AX_CH9_BUSY | B_AX_CH12_BUSY;
check = info->dma_busy1.mask;
ret = read_poll_timeout(rtw89_read32, dma_busy, (dma_busy & check) == 0,
10, 100, false, rtwdev, dma_busy1);
if (ret)
return ret;
if (!dma_busy2)
return 0;
check = B_AX_CH10_BUSY | B_AX_CH11_BUSY;
ret = read_poll_timeout(rtw89_read32, dma_busy, (dma_busy & check) == 0,
@ -2488,6 +2579,12 @@ static int rtw89_pci_ops_mac_pre_init(struct rtw89_dev *rtwdev)
rtw89_pci_hci_ldo(rtwdev);
rtw89_pci_dphy_delay(rtwdev);
ret = rtw89_pci_autok_x(rtwdev);
if (ret) {
rtw89_err(rtwdev, "[ERR] pcie autok_x fail %d\n", ret);
return ret;
}
ret = rtw89_pci_auto_refclk_cal(rtwdev, false);
if (ret) {
rtw89_err(rtwdev, "[ERR] pcie autok fail %d\n", ret);
@ -2506,7 +2603,7 @@ static int rtw89_pci_ops_mac_pre_init(struct rtw89_dev *rtwdev)
rtw89_pci_set_dbg(rtwdev);
rtw89_pci_set_keep_reg(rtwdev);
rtw89_write32_set(rtwdev, info->dma_stop1_reg, B_AX_STOP_WPDMA);
rtw89_write32_set(rtwdev, info->dma_stop1.addr, B_AX_STOP_WPDMA);
/* stop DMA activities */
rtw89_pci_ctrl_dma_all(rtwdev, false);
@ -2529,10 +2626,9 @@ static int rtw89_pci_ops_mac_pre_init(struct rtw89_dev *rtwdev)
return ret;
}
/* enable FW CMD queue to download firmware */
rtw89_write32_set(rtwdev, info->dma_stop1_reg, B_AX_TX_STOP1_ALL);
rtw89_write32_clr(rtwdev, info->dma_stop1_reg, B_AX_STOP_CH12);
rtw89_write32_set(rtwdev, info->dma_stop2_reg, B_AX_TX_STOP2_ALL);
/* disable all channels except to FW CMD channel to download firmware */
rtw89_pci_ctrl_txdma_ch_pcie(rtwdev, false);
rtw89_pci_ctrl_txdma_fw_ch_pcie(rtwdev, true);
/* start DMA activities */
rtw89_pci_ctrl_dma_all(rtwdev, true);
@ -2560,15 +2656,15 @@ int rtw89_pci_ltr_set(struct rtw89_dev *rtwdev, bool en)
if (rtw89_pci_ltr_is_err_reg_val(val))
return -EINVAL;
rtw89_write32_clr(rtwdev, R_AX_LTR_CTRL_0, B_AX_LTR_HW_EN);
rtw89_write32_set(rtwdev, R_AX_LTR_CTRL_0, B_AX_LTR_EN);
rtw89_write32_set(rtwdev, R_AX_LTR_CTRL_0, B_AX_LTR_HW_EN | B_AX_LTR_EN |
B_AX_LTR_WD_NOEMP_CHK);
rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_0, B_AX_LTR_SPACE_IDX_MASK,
PCI_LTR_SPC_500US);
rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_0, B_AX_LTR_IDLE_TIMER_IDX_MASK,
PCI_LTR_IDLE_TIMER_800US);
PCI_LTR_IDLE_TIMER_3_2MS);
rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_1, B_AX_LTR_RX0_TH_MASK, 0x28);
rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_1, B_AX_LTR_RX1_TH_MASK, 0x28);
rtw89_write32(rtwdev, R_AX_LTR_IDLE_LATENCY, 0x88e088e0);
rtw89_write32(rtwdev, R_AX_LTR_IDLE_LATENCY, 0x90039003);
rtw89_write32(rtwdev, R_AX_LTR_ACTIVE_LATENCY, 0x880b880b);
return 0;
@ -2645,11 +2741,10 @@ static int rtw89_pci_ops_mac_post_init(struct rtw89_dev *rtwdev)
}
/* enable DMA for all queues */
rtw89_write32_clr(rtwdev, info->dma_stop1_reg, B_AX_TX_STOP1_ALL);
rtw89_write32_clr(rtwdev, info->dma_stop2_reg, B_AX_TX_STOP2_ALL);
rtw89_pci_ctrl_txdma_ch_pcie(rtwdev, true);
/* Release PCI IO */
rtw89_write32_clr(rtwdev, info->dma_stop1_reg,
rtw89_write32_clr(rtwdev, info->dma_stop1.addr,
B_AX_STOP_WPDMA | B_AX_STOP_PCIEIO);
return 0;
@ -2678,7 +2773,6 @@ static int rtw89_pci_claim_device(struct rtw89_dev *rtwdev,
static void rtw89_pci_declaim_device(struct rtw89_dev *rtwdev,
struct pci_dev *pdev)
{
pci_clear_master(pdev);
pci_disable_device(pdev);
}
@ -2773,10 +2867,13 @@ static void rtw89_pci_free_tx_rings(struct rtw89_dev *rtwdev,
struct pci_dev *pdev)
{
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
const struct rtw89_pci_info *info = rtwdev->pci_info;
struct rtw89_pci_tx_ring *tx_ring;
int i;
for (i = 0; i < RTW89_TXCH_NUM; i++) {
if (info->tx_dma_ch_mask & BIT(i))
continue;
tx_ring = &rtwpci->tx_rings[i];
rtw89_pci_free_tx_wd_ring(rtwdev, pdev, tx_ring);
rtw89_pci_free_tx_ring(rtwdev, pdev, tx_ring);
@ -2964,6 +3061,7 @@ static int rtw89_pci_alloc_tx_rings(struct rtw89_dev *rtwdev,
struct pci_dev *pdev)
{
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
const struct rtw89_pci_info *info = rtwdev->pci_info;
struct rtw89_pci_tx_ring *tx_ring;
u32 desc_size;
u32 len;
@ -2971,6 +3069,8 @@ static int rtw89_pci_alloc_tx_rings(struct rtw89_dev *rtwdev,
int ret;
for (i = 0; i < RTW89_TXCH_NUM; i++) {
if (info->tx_dma_ch_mask & BIT(i))
continue;
tx_ring = &rtwpci->tx_rings[i];
desc_size = sizeof(struct rtw89_pci_tx_bd_32);
len = RTW89_PCI_TXBD_NUM_MAX;
@ -3192,11 +3292,16 @@ static void rtw89_pci_clear_resource(struct rtw89_dev *rtwdev,
void rtw89_pci_config_intr_mask(struct rtw89_dev *rtwdev)
{
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
const struct rtw89_chip_info *chip = rtwdev->chip;
u32 hs0isr_ind_int_en = B_AX_HS0ISR_IND_INT_EN;
if (chip->chip_id == RTL8851B)
hs0isr_ind_int_en = B_AX_HS0ISR_IND_INT_EN_WKARND;
rtwpci->halt_c2h_intrs = B_AX_HALT_C2H_INT_EN | 0;
if (rtwpci->under_recovery) {
rtwpci->intrs[0] = B_AX_HS0ISR_IND_INT_EN;
rtwpci->intrs[0] = hs0isr_ind_int_en;
rtwpci->intrs[1] = 0;
} else {
rtwpci->intrs[0] = B_AX_TXDMA_STUCK_INT_EN |
@ -3206,7 +3311,7 @@ void rtw89_pci_config_intr_mask(struct rtw89_dev *rtwdev)
B_AX_RXDMA_STUCK_INT_EN |
B_AX_RDU_INT_EN |
B_AX_RPQBD_FULL_INT_EN |
B_AX_HS0ISR_IND_INT_EN;
hs0isr_ind_int_en;
rtwpci->intrs[1] = B_AX_HC10ISR_IND_INT_EN;
}
@ -3387,7 +3492,7 @@ static void rtw89_pci_clkreq_set(struct rtw89_dev *rtwdev, bool enable)
if (ret)
rtw89_err(rtwdev, "failed to set CLKREQ Delay\n");
if (chip_id == RTL8852A) {
if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) {
if (enable)
ret = rtw89_pci_config_byte_set(rtwdev,
RTW89_PCIE_L1_CTRL,
@ -3432,7 +3537,7 @@ static void rtw89_pci_aspm_set(struct rtw89_dev *rtwdev, bool enable)
if (ret)
rtw89_err(rtwdev, "failed to read ASPM Delay\n");
if (chip_id == RTL8852A || chip_id == RTL8852B) {
if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) {
if (enable)
ret = rtw89_pci_config_byte_set(rtwdev,
RTW89_PCIE_L1_CTRL,
@ -3512,7 +3617,7 @@ static void rtw89_pci_l1ss_set(struct rtw89_dev *rtwdev, bool enable)
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
int ret;
if (chip_id == RTL8852A || chip_id == RTL8852B) {
if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) {
if (enable)
ret = rtw89_pci_config_byte_set(rtwdev,
RTW89_PCIE_TIMER_CTRL,
@ -3558,26 +3663,6 @@ static void rtw89_pci_l1ss_cfg(struct rtw89_dev *rtwdev)
rtw89_pci_l1ss_set(rtwdev, true);
}
static void rtw89_pci_ctrl_dma_all_pcie(struct rtw89_dev *rtwdev, u8 en)
{
const struct rtw89_pci_info *info = rtwdev->pci_info;
u32 val32;
if (en == MAC_AX_FUNC_EN) {
val32 = B_AX_STOP_PCIEIO;
rtw89_write32_clr(rtwdev, info->dma_stop1_reg, val32);
val32 = B_AX_TXHCI_EN | B_AX_RXHCI_EN;
rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, val32);
} else {
val32 = B_AX_STOP_PCIEIO;
rtw89_write32_set(rtwdev, info->dma_stop1_reg, val32);
val32 = B_AX_TXHCI_EN | B_AX_RXHCI_EN;
rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, val32);
}
}
static int rtw89_pci_poll_io_idle(struct rtw89_dev *rtwdev)
{
int ret = 0;
@ -3597,10 +3682,13 @@ static int rtw89_pci_poll_io_idle(struct rtw89_dev *rtwdev)
static int rtw89_pci_lv1rst_stop_dma(struct rtw89_dev *rtwdev)
{
u32 val, dma_rst = 0;
u32 val;
int ret;
rtw89_pci_ctrl_dma_all_pcie(rtwdev, MAC_AX_FUNC_DIS);
if (rtwdev->chip->chip_id == RTL8852C)
return 0;
rtw89_pci_ctrl_dma_all(rtwdev, false);
ret = rtw89_pci_poll_io_idle(rtwdev);
if (ret) {
val = rtw89_read32(rtwdev, R_AX_DBG_ERR_FLAG);
@ -3608,12 +3696,10 @@ static int rtw89_pci_lv1rst_stop_dma(struct rtw89_dev *rtwdev)
"[PCIe] poll_io_idle fail, before 0x%08x: 0x%08x\n",
R_AX_DBG_ERR_FLAG, val);
if (val & B_AX_TX_STUCK || val & B_AX_PCIE_TXBD_LEN0)
dma_rst |= B_AX_HCI_TXDMA_EN;
rtw89_mac_ctrl_hci_dma_tx(rtwdev, false);
if (val & B_AX_RX_STUCK)
dma_rst |= B_AX_HCI_RXDMA_EN;
val = rtw89_read32(rtwdev, R_AX_HCI_FUNC_EN);
rtw89_write32(rtwdev, R_AX_HCI_FUNC_EN, val & ~dma_rst);
rtw89_write32(rtwdev, R_AX_HCI_FUNC_EN, val | dma_rst);
rtw89_mac_ctrl_hci_dma_rx(rtwdev, false);
rtw89_mac_ctrl_hci_dma_trx(rtwdev, true);
ret = rtw89_pci_poll_io_idle(rtwdev);
val = rtw89_read32(rtwdev, R_AX_DBG_ERR_FLAG);
rtw89_debug(rtwdev, RTW89_DBG_HCI,
@ -3624,18 +3710,7 @@ static int rtw89_pci_lv1rst_stop_dma(struct rtw89_dev *rtwdev)
return ret;
}
static void rtw89_pci_ctrl_hci_dma_en(struct rtw89_dev *rtwdev, u8 en)
{
u32 val32;
if (en == MAC_AX_FUNC_EN) {
val32 = B_AX_HCI_TXDMA_EN | B_AX_HCI_RXDMA_EN;
rtw89_write32_set(rtwdev, R_AX_HCI_FUNC_EN, val32);
} else {
val32 = B_AX_HCI_TXDMA_EN | B_AX_HCI_RXDMA_EN;
rtw89_write32_clr(rtwdev, R_AX_HCI_FUNC_EN, val32);
}
}
static int rtw89_pci_rst_bdram(struct rtw89_dev *rtwdev)
{
@ -3655,15 +3730,18 @@ static int rtw89_pci_lv1rst_start_dma(struct rtw89_dev *rtwdev)
{
u32 ret;
rtw89_pci_ctrl_hci_dma_en(rtwdev, MAC_AX_FUNC_DIS);
rtw89_pci_ctrl_hci_dma_en(rtwdev, MAC_AX_FUNC_EN);
if (rtwdev->chip->chip_id == RTL8852C)
return 0;
rtw89_mac_ctrl_hci_dma_trx(rtwdev, false);
rtw89_mac_ctrl_hci_dma_trx(rtwdev, true);
rtw89_pci_clr_idx_all(rtwdev);
ret = rtw89_pci_rst_bdram(rtwdev);
if (ret)
return ret;
rtw89_pci_ctrl_dma_all_pcie(rtwdev, MAC_AX_FUNC_EN);
rtw89_pci_ctrl_dma_all(rtwdev, true);
return ret;
}
@ -3738,7 +3816,7 @@ static int __maybe_unused rtw89_pci_suspend(struct device *dev)
rtw89_write32_set(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6);
rtw89_write32_set(rtwdev, R_AX_RSV_CTRL, B_AX_R_DIS_PRST);
rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6);
if (chip_id == RTL8852A || chip_id == RTL8852B) {
if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) {
rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL,
B_AX_PCIE_DIS_L2_CTRL_LDO_HCI);
rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1,
@ -3772,7 +3850,7 @@ static int __maybe_unused rtw89_pci_resume(struct device *dev)
rtw89_write32_set(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6);
rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_R_DIS_PRST);
rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6);
if (chip_id == RTL8852A || chip_id == RTL8852B) {
if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) {
rtw89_write32_set(rtwdev, R_AX_SYS_SDIO_CTRL,
B_AX_PCIE_DIS_L2_CTRL_LDO_HCI);
rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1,
@ -3823,6 +3901,16 @@ static const struct rtw89_hci_ops rtw89_pci_ops = {
.recovery_start = rtw89_pci_ops_recovery_start,
.recovery_complete = rtw89_pci_ops_recovery_complete,
.ctrl_txdma_ch = rtw89_pci_ctrl_txdma_ch_pcie,
.ctrl_txdma_fw_ch = rtw89_pci_ctrl_txdma_fw_ch_pcie,
.ctrl_trxhci = rtw89_pci_ctrl_dma_trx,
.poll_txdma_ch = rtw89_poll_txdma_ch_idle_pcie,
.clr_idx_all = rtw89_pci_clr_idx_all,
.clear = rtw89_pci_clear_resource,
.disable_intr = rtw89_pci_disable_intr_lock,
.enable_intr = rtw89_pci_enable_intr_lock,
.rst_bdram = rtw89_pci_rst_bdram_pcie,
};
int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@ -3880,25 +3968,26 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
rtw89_pci_link_cfg(rtwdev);
rtw89_pci_l1ss_cfg(rtwdev);
ret = rtw89_core_register(rtwdev);
if (ret) {
rtw89_err(rtwdev, "failed to register core\n");
goto err_clear_resource;
}
rtw89_core_napi_init(rtwdev);
ret = rtw89_pci_request_irq(rtwdev, pdev);
if (ret) {
rtw89_err(rtwdev, "failed to request pci irq\n");
goto err_unregister;
goto err_deinit_napi;
}
ret = rtw89_core_register(rtwdev);
if (ret) {
rtw89_err(rtwdev, "failed to register core\n");
goto err_free_irq;
}
return 0;
err_unregister:
err_free_irq:
rtw89_pci_free_irq(rtwdev, pdev);
err_deinit_napi:
rtw89_core_napi_deinit(rtwdev);
rtw89_core_unregister(rtwdev);
err_clear_resource:
rtw89_pci_clear_resource(rtwdev, pdev);
err_declaim_pci:

View file

@ -23,6 +23,9 @@
#define PCIE_DPHY_DLY_25US 0x1
#define RAC_ANA19 0x19
#define B_PCIE_BIT_RD_SEL BIT(2)
#define RAC_REG_FLD_0 0x1D
#define BAC_AUTOK_N_MASK GENMASK(3, 2)
#define PCIE_AUTOK_4 0x3
#define RAC_ANA1F 0x1F
#define RAC_ANA24 0x24
#define B_AX_DEGLITCH GENMASK(11, 8)
@ -147,6 +150,7 @@
#define B_AX_HD1ISR_IND_INT_EN BIT(26)
#define B_AX_HD0ISR_IND_INT_EN BIT(25)
#define B_AX_HS0ISR_IND_INT_EN BIT(24)
#define B_AX_HS0ISR_IND_INT_EN_WKARND BIT(23)
#define B_AX_RETRAIN_INT_EN BIT(21)
#define B_AX_RPQBD_FULL_INT_EN BIT(20)
#define B_AX_RDU_INT_EN BIT(19)
@ -199,6 +203,18 @@
#define B_AX_RXP1DMA_INT BIT(1)
#define B_AX_RXDMA_INT BIT(0)
#define R_AX_HAXI_IDCT_MSK 0x10B8
#define B_AX_TXBD_LEN0_ERR_IDCT_MSK BIT(3)
#define B_AX_TXBD_4KBOUND_ERR_IDCT_MSK BIT(2)
#define B_AX_RXMDA_STUCK_IDCT_MSK BIT(1)
#define B_AX_TXMDA_STUCK_IDCT_MSK BIT(0)
#define R_AX_HAXI_IDCT 0x10BC
#define B_AX_TXBD_LEN0_ERR_IDCT BIT(3)
#define B_AX_TXBD_4KBOUND_ERR_IDCT BIT(2)
#define B_AX_RXMDA_STUCK_IDCT BIT(1)
#define B_AX_TXMDA_STUCK_IDCT BIT(0)
#define R_AX_HAXI_HIMR10 0x11E0
#define B_AX_TXDMA_CH11_INT_EN_V1 BIT(1)
#define B_AX_TXDMA_CH10_INT_EN_V1 BIT(0)
@ -410,6 +426,16 @@
#define B_AX_STOP_RPQ BIT(1)
#define B_AX_STOP_RXQ BIT(0)
#define B_AX_TX_STOP1_ALL GENMASK(18, 8)
#define B_AX_TX_STOP1_MASK (B_AX_STOP_ACH0 | B_AX_STOP_ACH1 | \
B_AX_STOP_ACH2 | B_AX_STOP_ACH3 | \
B_AX_STOP_ACH4 | B_AX_STOP_ACH5 | \
B_AX_STOP_ACH6 | B_AX_STOP_ACH7 | \
B_AX_STOP_CH8 | B_AX_STOP_CH9 | \
B_AX_STOP_CH12)
#define B_AX_TX_STOP1_MASK_V1 (B_AX_STOP_ACH0 | B_AX_STOP_ACH1 | \
B_AX_STOP_ACH2 | B_AX_STOP_ACH3 | \
B_AX_STOP_CH8 | B_AX_STOP_CH9 | \
B_AX_STOP_CH12)
#define R_AX_PCIE_DMA_STOP2 0x1310
#define B_AX_STOP_CH11 BIT(1)
@ -458,6 +484,13 @@
#define B_AX_ACH0_BUSY BIT(8)
#define B_AX_RPQ_BUSY BIT(1)
#define B_AX_RXQ_BUSY BIT(0)
#define DMA_BUSY1_CHECK (B_AX_ACH0_BUSY | B_AX_ACH1_BUSY | B_AX_ACH2_BUSY | \
B_AX_ACH3_BUSY | B_AX_ACH4_BUSY | B_AX_ACH5_BUSY | \
B_AX_ACH6_BUSY | B_AX_ACH7_BUSY | B_AX_CH8_BUSY | \
B_AX_CH9_BUSY | B_AX_CH12_BUSY)
#define DMA_BUSY1_CHECK_V1 (B_AX_ACH0_BUSY | B_AX_ACH1_BUSY | B_AX_ACH2_BUSY | \
B_AX_ACH3_BUSY | B_AX_CH8_BUSY | B_AX_CH9_BUSY | \
B_AX_CH12_BUSY)
#define R_AX_PCIE_DMA_BUSY2 0x131C
#define B_AX_CH11_BUSY BIT(1)
@ -564,11 +597,6 @@ enum rtw89_pcie_phy {
PCIE_PHY_GEN1_UNDEFINE = 0x7F,
};
enum mac_ax_func_sw {
MAC_AX_FUNC_DIS,
MAC_AX_FUNC_EN,
};
enum rtw89_pcie_l0sdly {
PCIE_L0SDLY_1US = 0,
PCIE_L0SDLY_2US = 1,
@ -723,6 +751,12 @@ struct rtw89_pci_ch_dma_addr_set {
struct rtw89_pci_ch_dma_addr rx[RTW89_RXCH_NUM];
};
struct rtw89_pci_bd_ram {
u8 start_idx;
u8 max_num;
u8 min_num;
};
struct rtw89_pci_info {
enum mac_ax_bd_trunc_mode txbd_trunc_mode;
enum mac_ax_bd_trunc_mode rxbd_trunc_mode;
@ -747,16 +781,18 @@ struct rtw89_pci_info {
u32 max_tag_num_mask;
u32 rxbd_rwptr_clr_reg;
u32 txbd_rwptr_clr2_reg;
u32 dma_stop1_reg;
u32 dma_stop2_reg;
u32 dma_busy1_reg;
struct rtw89_reg_def dma_stop1;
struct rtw89_reg_def dma_stop2;
struct rtw89_reg_def dma_busy1;
u32 dma_busy2_reg;
u32 dma_busy3_reg;
u32 rpwm_addr;
u32 cpwm_addr;
u32 tx_dma_ch_mask;
const struct rtw89_pci_bd_idx_addr *bd_idx_addr_low_power;
const struct rtw89_pci_ch_dma_addr_set *dma_addr_set;
const struct rtw89_pci_bd_ram (*bd_ram_table)[RTW89_TXCH_NUM];
int (*ltr_set)(struct rtw89_dev *rtwdev, bool en);
u32 (*fill_txaddr_info)(struct rtw89_dev *rtwdev,
@ -770,12 +806,6 @@ struct rtw89_pci_info {
struct rtw89_pci_isrs *isrs);
};
struct rtw89_pci_bd_ram {
u8 start_idx;
u8 max_num;
u8 min_num;
};
struct rtw89_pci_tx_data {
dma_addr_t dma;
};
@ -975,9 +1005,9 @@ rtw89_pci_rxbd_increase(struct rtw89_pci_rx_ring *rx_ring, u32 cnt)
static inline struct rtw89_pci_tx_data *RTW89_PCI_TX_SKB_CB(struct sk_buff *skb)
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct rtw89_tx_skb_data *data = RTW89_TX_SKB_CB(skb);
return (struct rtw89_pci_tx_data *)info->status.status_driver_data;
return (struct rtw89_pci_tx_data *)data->hci_priv;
}
static inline struct rtw89_pci_tx_bd_32 *
@ -1029,6 +1059,8 @@ static inline bool rtw89_pci_ltr_is_err_reg_val(u32 val)
extern const struct dev_pm_ops rtw89_pm_ops;
extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set;
extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_v1;
extern const struct rtw89_pci_bd_ram rtw89_bd_ram_table_dual[RTW89_TXCH_NUM];
extern const struct rtw89_pci_bd_ram rtw89_bd_ram_table_single[RTW89_TXCH_NUM];
struct pci_device_id;

File diff suppressed because it is too large Load diff

View file

@ -64,6 +64,17 @@
#define MAX_CFO_TOLERANCE 30
#define CFO_TF_CNT_TH 300
#define UL_TB_TF_CNT_L2H_TH 100
#define UL_TB_TF_CNT_H2L_TH 70
#define ANTDIV_TRAINNING_CNT 2
#define ANTDIV_TRAINNING_INTVL 30
#define ANTDIV_DELAY 110
#define ANTDIV_TP_DIFF_TH_HIGH 100
#define ANTDIV_TP_DIFF_TH_LOW 5
#define ANTDIV_EVM_DIFF_TH 8
#define ANTDIV_RSSI_DIFF_TH 3
#define CCX_MAX_PERIOD 2097
#define CCX_MAX_PERIOD_UNIT 32
#define MS_TO_4US_RATIO 250
@ -114,6 +125,15 @@ enum rtw89_phy_c2h_ra_func {
RTW89_PHY_C2H_FUNC_RA_MAX,
};
enum rtw89_phy_c2h_dm_func {
RTW89_PHY_C2H_DM_FUNC_FW_TEST,
RTW89_PHY_C2H_DM_FUNC_FW_TRIG_TX_RPT,
RTW89_PHY_C2H_DM_FUNC_SIGB,
RTW89_PHY_C2H_DM_FUNC_LOWRT_RTY,
RTW89_PHY_C2H_DM_FUNC_MCC_DIG,
RTW89_PHY_C2H_DM_FUNC_NUM,
};
enum rtw89_phy_c2h_class {
RTW89_PHY_C2H_CLASS_RUA,
RTW89_PHY_C2H_CLASS_RA,
@ -317,9 +337,6 @@ struct rtw89_nbi_reg_def {
struct rtw89_reg_def notch2_en;
};
extern const u8 rtw89_rs_idx_max[RTW89_RS_MAX];
extern const u8 rtw89_rs_nss_max[RTW89_RS_MAX];
static inline void rtw89_phy_write8(struct rtw89_dev *rtwdev,
u32 addr, u8 data)
{
@ -377,6 +394,50 @@ static inline u32 rtw89_phy_read32_mask(struct rtw89_dev *rtwdev,
return rtw89_read32_mask(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, mask);
}
static inline
enum rtw89_gain_offset rtw89_subband_to_gain_offset_band_of_ofdm(enum rtw89_subband subband)
{
switch (subband) {
default:
case RTW89_CH_2G:
return RTW89_GAIN_OFFSET_2G_OFDM;
case RTW89_CH_5G_BAND_1:
return RTW89_GAIN_OFFSET_5G_LOW;
case RTW89_CH_5G_BAND_3:
return RTW89_GAIN_OFFSET_5G_MID;
case RTW89_CH_5G_BAND_4:
return RTW89_GAIN_OFFSET_5G_HIGH;
}
}
static inline
enum rtw89_phy_bb_gain_band rtw89_subband_to_bb_gain_band(enum rtw89_subband subband)
{
switch (subband) {
default:
case RTW89_CH_2G:
return RTW89_BB_GAIN_BAND_2G;
case RTW89_CH_5G_BAND_1:
return RTW89_BB_GAIN_BAND_5G_L;
case RTW89_CH_5G_BAND_3:
return RTW89_BB_GAIN_BAND_5G_M;
case RTW89_CH_5G_BAND_4:
return RTW89_BB_GAIN_BAND_5G_H;
case RTW89_CH_6G_BAND_IDX0:
case RTW89_CH_6G_BAND_IDX1:
return RTW89_BB_GAIN_BAND_6G_L;
case RTW89_CH_6G_BAND_IDX2:
case RTW89_CH_6G_BAND_IDX3:
return RTW89_BB_GAIN_BAND_6G_M;
case RTW89_CH_6G_BAND_IDX4:
case RTW89_CH_6G_BAND_IDX5:
return RTW89_BB_GAIN_BAND_6G_H;
case RTW89_CH_6G_BAND_IDX6:
case RTW89_CH_6G_BAND_IDX7:
return RTW89_BB_GAIN_BAND_6G_UH;
}
}
enum rtw89_rfk_flag {
RTW89_RFK_F_WRF = 0,
RTW89_RFK_F_WM = 1,
@ -450,7 +511,7 @@ bool rtw89_phy_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
bool rtw89_phy_write_rf_v1(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
u32 addr, u32 mask, u32 data);
void rtw89_phy_init_bb_reg(struct rtw89_dev *rtwdev);
void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev);
void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev, bool noio);
void rtw89_phy_config_rf_reg_v1(struct rtw89_dev *rtwdev,
const struct rtw89_reg2_def *reg,
enum rtw89_rf_path rf_path,
@ -458,20 +519,24 @@ void rtw89_phy_config_rf_reg_v1(struct rtw89_dev *rtwdev,
void rtw89_phy_dm_init(struct rtw89_dev *rtwdev);
void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
u32 data, enum rtw89_phy_idx phy_idx);
u32 rtw89_phy_read32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
enum rtw89_phy_idx phy_idx);
void rtw89_phy_load_txpwr_byrate(struct rtw89_dev *rtwdev,
const struct rtw89_txpwr_table *tbl);
s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, u8 band,
const struct rtw89_rate_desc *rate_desc);
void rtw89_phy_fill_txpwr_limit(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
struct rtw89_txpwr_limit *lmt,
u8 ntx);
void rtw89_phy_fill_txpwr_limit_ru(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
struct rtw89_txpwr_limit_ru *lmt_ru,
u8 ntx);
s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band,
u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch);
void rtw89_phy_set_txpwr_byrate(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx);
void rtw89_phy_set_txpwr_offset(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx);
void rtw89_phy_set_txpwr_limit(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx);
void rtw89_phy_set_txpwr_limit_ru(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx);
void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta);
void rtw89_phy_ra_update(struct rtw89_dev *rtwdev);
void rtw89_phy_ra_updata_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta,
@ -491,9 +556,20 @@ void rtw89_phy_set_phy_regs(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
u32 val);
void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev);
void rtw89_phy_dig(struct rtw89_dev *rtwdev);
void rtw89_phy_tx_path_div_track(struct rtw89_dev *rtwdev);
void rtw89_phy_antdiv_parse(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu);
void rtw89_phy_antdiv_track(struct rtw89_dev *rtwdev);
void rtw89_phy_antdiv_work(struct work_struct *work);
void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
void rtw89_phy_tssi_ctrl_set_bandedge_cfg(struct rtw89_dev *rtwdev,
enum rtw89_mac_idx mac_idx,
enum rtw89_tssi_bandedge_cfg bandedge_cfg);
void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev);
u8 rtw89_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band);
void rtw89_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx,
u8 *ch, enum nl80211_band *band);
void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev, bool scan);
#endif

View file

@ -59,8 +59,11 @@ static void rtw89_ps_power_mode_change(struct rtw89_dev *rtwdev, bool enter)
rtw89_mac_power_mode_change(rtwdev, enter);
}
static void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev)
void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
if (rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT)
return;
if (!rtwdev->ps_mode)
return;
@ -111,20 +114,23 @@ void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev)
__rtw89_leave_ps_mode(rtwdev);
}
void rtw89_enter_lps(struct rtw89_dev *rtwdev, u8 mac_id)
void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
bool ps_mode)
{
lockdep_assert_held(&rtwdev->mutex);
if (test_and_set_bit(RTW89_FLAG_LEISURE_PS, rtwdev->flags))
return;
__rtw89_enter_lps(rtwdev, mac_id);
__rtw89_enter_ps_mode(rtwdev);
__rtw89_enter_lps(rtwdev, rtwvif->mac_id);
if (ps_mode)
__rtw89_enter_ps_mode(rtwdev, rtwvif);
}
static void rtw89_leave_lps_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION)
if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION &&
rtwvif->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT)
return;
__rtw89_leave_lps(rtwdev, rtwvif->mac_id);
@ -151,6 +157,9 @@ void rtw89_enter_ips(struct rtw89_dev *rtwdev)
set_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags);
if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags))
return;
rtw89_for_each_rtwvif(rtwdev, rtwvif)
rtw89_mac_vif_deinit(rtwdev, rtwvif);
@ -162,6 +171,9 @@ void rtw89_leave_ips(struct rtw89_dev *rtwdev)
struct rtw89_vif *rtwvif;
int ret;
if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags))
return;
ret = rtw89_core_start(rtwdev);
if (ret)
rtw89_err(rtwdev, "failed to leave idle state\n");
@ -179,3 +191,90 @@ void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl)
if (btc_ctrl)
rtw89_leave_lps(rtwdev);
}
static void rtw89_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
enum rtw89_p2pps_action act)
{
if (act == RTW89_P2P_ACT_UPDATE || act == RTW89_P2P_ACT_REMOVE)
return;
if (act == RTW89_P2P_ACT_INIT)
rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif, true);
else if (act == RTW89_P2P_ACT_TERMINATE)
rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif, false);
}
static void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif)
{
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
enum rtw89_p2pps_action act;
u8 noa_id;
if (rtwvif->last_noa_nr == 0)
return;
for (noa_id = 0; noa_id < rtwvif->last_noa_nr; noa_id++) {
if (noa_id == rtwvif->last_noa_nr - 1)
act = RTW89_P2P_ACT_TERMINATE;
else
act = RTW89_P2P_ACT_REMOVE;
rtw89_tsf32_toggle(rtwdev, rtwvif, act);
rtw89_fw_h2c_p2p_act(rtwdev, vif, NULL, act, noa_id);
}
}
static void rtw89_p2p_update_noa(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif)
{
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct ieee80211_p2p_noa_desc *desc;
enum rtw89_p2pps_action act;
u8 noa_id;
for (noa_id = 0; noa_id < RTW89_P2P_MAX_NOA_NUM; noa_id++) {
desc = &vif->bss_conf.p2p_noa_attr.desc[noa_id];
if (!desc->count || !desc->duration)
break;
if (noa_id == 0)
act = RTW89_P2P_ACT_INIT;
else
act = RTW89_P2P_ACT_UPDATE;
rtw89_tsf32_toggle(rtwdev, rtwvif, act);
rtw89_fw_h2c_p2p_act(rtwdev, vif, desc, act, noa_id);
}
rtwvif->last_noa_nr = noa_id;
}
void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
{
rtw89_p2p_disable_all_noa(rtwdev, vif);
rtw89_p2p_update_noa(rtwdev, vif);
}
void rtw89_recalc_lps(struct rtw89_dev *rtwdev)
{
struct ieee80211_vif *vif, *found_vif = NULL;
struct rtw89_vif *rtwvif;
int count = 0;
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
vif = rtwvif_to_vif(rtwvif);
if (vif->type != NL80211_IFTYPE_STATION) {
count = 0;
break;
}
count++;
found_vif = vif;
}
if (count == 1 && found_vif->cfg.ps) {
rtwdev->lps_enabled = true;
} else {
rtw89_leave_lps(rtwdev);
rtwdev->lps_enabled = false;
}
}

View file

@ -5,12 +5,32 @@
#ifndef __RTW89_PS_H_
#define __RTW89_PS_H_
void rtw89_enter_lps(struct rtw89_dev *rtwdev, u8 mac_id);
void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
bool ps_mode);
void rtw89_leave_lps(struct rtw89_dev *rtwdev);
void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev);
void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev);
void rtw89_enter_ips(struct rtw89_dev *rtwdev);
void rtw89_leave_ips(struct rtw89_dev *rtwdev);
void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl);
void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
void rtw89_recalc_lps(struct rtw89_dev *rtwdev);
static inline void rtw89_leave_ips_by_hwflags(struct rtw89_dev *rtwdev)
{
struct ieee80211_hw *hw = rtwdev->hw;
if (hw->conf.flags & IEEE80211_CONF_IDLE)
rtw89_leave_ips(rtwdev);
}
static inline void rtw89_enter_ips_by_hwflags(struct rtw89_dev *rtwdev)
{
struct ieee80211_hw *hw = rtwdev->hw;
if (hw->conf.flags & IEEE80211_CONF_IDLE)
rtw89_enter_ips(rtwdev);
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -2,33 +2,35 @@
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#include "acpi.h"
#include "debug.h"
#include "ps.h"
#include "util.h"
#define COUNTRY_REGD(_alpha2, _txpwr_regd...) \
{.alpha2 = (_alpha2), \
.txpwr_regd = {_txpwr_regd}, \
}
static const struct rtw89_regulatory rtw89_ww_regd =
static const struct rtw89_regd rtw89_ww_regd =
COUNTRY_REGD("00", RTW89_WW, RTW89_WW);
static const struct rtw89_regulatory rtw89_regd_map[] = {
static const struct rtw89_regd rtw89_regd_map[] = {
COUNTRY_REGD("AR", RTW89_MEXICO, RTW89_MEXICO, RTW89_NA),
COUNTRY_REGD("BO", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("BO", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("BR", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("CL", RTW89_CHILE, RTW89_CHILE, RTW89_CHILE),
COUNTRY_REGD("CO", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("CO", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("CR", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("EC", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("SV", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("GT", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("SV", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("GT", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("HN", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("MX", RTW89_MEXICO, RTW89_MEXICO, RTW89_NA),
COUNTRY_REGD("NI", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("PA", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("PY", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("PE", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("PE", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("US", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("UY", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("VE", RTW89_FCC, RTW89_FCC, RTW89_NA),
@ -65,37 +67,37 @@ static const struct rtw89_regulatory rtw89_regd_map[] = {
COUNTRY_REGD("CH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("GB", RTW89_UK, RTW89_UK, RTW89_UK),
COUNTRY_REGD("AL", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("AZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("BH", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("AZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("BH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("BA", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("BG", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("HR", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("BG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("HR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("EG", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GH", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("IQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("IL", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("JO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("IL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("JO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("KZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("KE", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("KW", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("KG", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("KE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("KW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("KG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("LB", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("LS", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MK", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MA", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("MZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("NA", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("NG", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("OM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("QA", RTW89_QATAR, RTW89_QATAR, RTW89_QATAR),
COUNTRY_REGD("RO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("RO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("RU", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("SA", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("SA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("SN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("RS", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("RS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("ME", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("ZA", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("TR", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("TR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("UA", RTW89_UKRAINE, RTW89_UKRAINE, RTW89_UKRAINE),
COUNTRY_REGD("AE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("YE", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
@ -103,11 +105,11 @@ static const struct rtw89_regulatory rtw89_regd_map[] = {
COUNTRY_REGD("BD", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("KH", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("CN", RTW89_CN, RTW89_CN, RTW89_CN),
COUNTRY_REGD("HK", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("HK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("IN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("ID", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("KR", RTW89_KCC, RTW89_KCC, RTW89_KCC),
COUNTRY_REGD("MY", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MY", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("PK", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("PH", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("SG", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
@ -115,55 +117,55 @@ static const struct rtw89_regulatory rtw89_regd_map[] = {
COUNTRY_REGD("TW", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("TH", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("VN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("AU", RTW89_ACMA, RTW89_ACMA, RTW89_NA),
COUNTRY_REGD("NZ", RTW89_ACMA, RTW89_ACMA, RTW89_NA),
COUNTRY_REGD("PG", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("AU", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA),
COUNTRY_REGD("NZ", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA),
COUNTRY_REGD("PG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("CA", RTW89_IC, RTW89_IC, RTW89_IC),
COUNTRY_REGD("JP", RTW89_MKK, RTW89_MKK, RTW89_NA),
COUNTRY_REGD("JM", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("AN", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("JP", RTW89_MKK, RTW89_MKK, RTW89_MKK),
COUNTRY_REGD("JM", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("AN", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("TT", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("TN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("AF", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("DZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("DZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("AS", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("AD", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("AO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("AI", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("AI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("AQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("AG", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("AM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("AW", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("BS", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("BB", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("AG", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("AM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("AW", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("BS", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("BB", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("BY", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("BZ", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("BJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("BM", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("BM", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("BT", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("BW", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("BW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("BV", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("IO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("VG", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("VG", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("BN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("BF", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("BI", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("BI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("CM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("CV", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("KY", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("KY", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("CF", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("TD", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("TD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("CX", RTW89_ACMA, RTW89_ACMA, RTW89_NA),
COUNTRY_REGD("CC", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("KM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("CC", RTW89_ACMA, RTW89_ACMA, RTW89_NA),
COUNTRY_REGD("KM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("CG", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("CD", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("CK", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("CI", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("DJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("DM", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("GQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("DJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("DM", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("GQ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("ER", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("ET", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("FK", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
@ -173,17 +175,17 @@ static const struct rtw89_regulatory rtw89_regd_map[] = {
COUNTRY_REGD("PF", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("TF", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GA", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("GE", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GI", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GL", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GD", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("GD", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("GP", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GU", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("GG", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("GW", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GY", RTW89_NCC, RTW89_NCC, RTW89_NA),
COUNTRY_REGD("GY", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("HT", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("HM", RTW89_ACMA, RTW89_ACMA, RTW89_NA),
COUNTRY_REGD("VA", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
@ -194,17 +196,17 @@ static const struct rtw89_regulatory rtw89_regd_map[] = {
COUNTRY_REGD("LR", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("LY", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MG", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("MW", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MV", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("ML", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MH", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("MQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MR", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MU", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("YT", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("FM", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("MD", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("MN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MS", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("NR", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
@ -218,26 +220,26 @@ static const struct rtw89_regulatory rtw89_regd_map[] = {
COUNTRY_REGD("RE", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("RW", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("SH", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("KN", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("LC", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("KN", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("LC", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("MF", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("SX", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("PM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("VC", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("WS", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("SM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("ST", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("ST", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("SC", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("SL", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("SL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("SB", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("SO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GS", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("SR", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("SR", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("SJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("SZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("TJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("TJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("TZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("TG", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("TG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("TK", RTW89_ACMA, RTW89_ACMA, RTW89_NA),
COUNTRY_REGD("TO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("TM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
@ -245,7 +247,7 @@ static const struct rtw89_regulatory rtw89_regd_map[] = {
COUNTRY_REGD("TV", RTW89_ETSI, RTW89_NA, RTW89_NA),
COUNTRY_REGD("UG", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("VI", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("UZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("UZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("VU", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("WF", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("EH", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
@ -254,7 +256,7 @@ static const struct rtw89_regulatory rtw89_regd_map[] = {
COUNTRY_REGD("PS", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
};
static const struct rtw89_regulatory *rtw89_regd_find_reg_by_name(char *alpha2)
static const struct rtw89_regd *rtw89_regd_find_reg_by_name(char *alpha2)
{
u32 i;
@ -266,7 +268,7 @@ static const struct rtw89_regulatory *rtw89_regd_find_reg_by_name(char *alpha2)
return &rtw89_ww_regd;
}
static bool rtw89_regd_is_ww(const struct rtw89_regulatory *regd)
static bool rtw89_regd_is_ww(const struct rtw89_regd *regd)
{
return regd == &rtw89_ww_regd;
}
@ -282,30 +284,144 @@ do { \
__r->txpwr_regd[RTW89_BAND_6G]); \
} while (0)
static void rtw89_regd_setup_unii4(struct rtw89_dev *rtwdev,
struct wiphy *wiphy)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
bool regd_allow_unii_4 = chip->support_unii4;
struct ieee80211_supported_band *sband;
int ret;
u8 val;
if (!chip->support_unii4)
goto bottom;
ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_59G_EN, &val);
if (ret) {
rtw89_debug(rtwdev, RTW89_DBG_REGD,
"acpi: cannot eval unii 4: %d\n", ret);
goto bottom;
}
rtw89_debug(rtwdev, RTW89_DBG_REGD,
"acpi: eval if allow unii 4: %d\n", val);
switch (val) {
case 0:
regd_allow_unii_4 = false;
break;
case 1:
regd_allow_unii_4 = true;
break;
default:
break;
}
bottom:
rtw89_debug(rtwdev, RTW89_DBG_REGD, "regd: allow unii 4: %d\n",
regd_allow_unii_4);
if (regd_allow_unii_4)
return;
sband = wiphy->bands[NL80211_BAND_5GHZ];
if (!sband)
return;
sband->n_channels -= 3;
}
static void rtw89_regd_setup_6ghz(struct rtw89_dev *rtwdev, struct wiphy *wiphy)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
bool chip_support_6ghz = chip->support_bands & BIT(NL80211_BAND_6GHZ);
bool regd_allow_6ghz = chip_support_6ghz;
struct ieee80211_supported_band *sband;
int ret;
u8 val;
if (!chip_support_6ghz)
goto bottom;
ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_6G_DIS, &val);
if (ret) {
rtw89_debug(rtwdev, RTW89_DBG_REGD,
"acpi: cannot eval 6ghz: %d\n", ret);
goto bottom;
}
rtw89_debug(rtwdev, RTW89_DBG_REGD,
"acpi: eval if disallow 6ghz: %d\n", val);
switch (val) {
case 0:
regd_allow_6ghz = true;
break;
case 1:
regd_allow_6ghz = false;
break;
default:
break;
}
bottom:
rtw89_debug(rtwdev, RTW89_DBG_REGD, "regd: allow 6ghz: %d\n",
regd_allow_6ghz);
if (regd_allow_6ghz)
return;
sband = wiphy->bands[NL80211_BAND_6GHZ];
if (!sband)
return;
wiphy->bands[NL80211_BAND_6GHZ] = NULL;
kfree(sband->iftype_data);
kfree(sband);
}
int rtw89_regd_setup(struct rtw89_dev *rtwdev)
{
struct wiphy *wiphy = rtwdev->hw->wiphy;
if (!wiphy)
return -EINVAL;
rtw89_regd_setup_unii4(rtwdev, wiphy);
rtw89_regd_setup_6ghz(rtwdev, wiphy);
wiphy->reg_notifier = rtw89_regd_notifier;
return 0;
}
int rtw89_regd_init(struct rtw89_dev *rtwdev,
void (*reg_notifier)(struct wiphy *wiphy,
struct regulatory_request *request))
{
const struct rtw89_regulatory *chip_regd;
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
const struct rtw89_regd *chip_regd;
struct wiphy *wiphy = rtwdev->hw->wiphy;
int ret;
regulatory->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
if (!wiphy)
return -EINVAL;
chip_regd = rtw89_regd_find_reg_by_name(rtwdev->efuse.country_code);
#if defined(__FreeBSD__)
rtwdev->regd = chip_regd;
rtwdev->regulatory.regd = chip_regd;
#endif
if (!rtw89_regd_is_ww(chip_regd)) {
#if defined(__linux__)
rtwdev->regd = chip_regd;
rtwdev->regulatory.regd = chip_regd;
#endif
/* Ignore country ie if there is a country domain programmed in chip */
wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
ret = regulatory_hint(rtwdev->hw->wiphy, rtwdev->regd->alpha2);
ret = regulatory_hint(rtwdev->hw->wiphy,
rtwdev->regulatory.regd->alpha2);
if (ret)
rtw89_warn(rtwdev, "failed to hint regulatory:%d\n", ret);
@ -313,7 +429,7 @@ int rtw89_regd_init(struct rtw89_dev *rtwdev,
return 0;
}
rtw89_debug_regd(rtwdev, rtwdev->regd,
rtw89_debug_regd(rtwdev, rtwdev->regulatory.regd,
"worldwide roaming chip, follow the setting of stack");
return 0;
}
@ -322,13 +438,13 @@ static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev,
struct wiphy *wiphy,
struct regulatory_request *request)
{
rtwdev->regd = rtw89_regd_find_reg_by_name(request->alpha2);
rtwdev->regulatory.regd = rtw89_regd_find_reg_by_name(request->alpha2);
/* This notification might be set from the system of distros,
* and it does not expect the regulatory will be modified by
* connecting to an AP (i.e. country ie).
*/
if (request->initiator == NL80211_REGDOM_SET_BY_USER &&
!rtw89_regd_is_ww(rtwdev->regd))
!rtw89_regd_is_ww(rtwdev->regulatory.regd))
wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
else
wiphy->regulatory_flags &= ~REGULATORY_COUNTRY_IE_IGNORE;
@ -348,7 +464,8 @@ void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request
goto exit;
}
rtw89_regd_notifier_apply(rtwdev, wiphy, request);
rtw89_debug_regd(rtwdev, rtwdev->regd, "get from initiator %d, alpha2",
rtw89_debug_regd(rtwdev, rtwdev->regulatory.regd,
"get from initiator %d, alpha2",
request->initiator);
rtw89_core_set_chip_txpwr(rtwdev);
@ -356,3 +473,66 @@ void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request
exit:
mutex_unlock(&rtwdev->mutex);
}
static void __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
enum rtw89_reg_6ghz_power sel;
const struct rtw89_chan *chan;
struct rtw89_vif *rtwvif;
int count = 0;
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
chan = rtw89_chan_get(rtwdev, rtwvif->sub_entity_idx);
if (chan->band_type != RTW89_BAND_6G)
continue;
if (count != 0 && rtwvif->reg_6ghz_power == sel)
continue;
sel = rtwvif->reg_6ghz_power;
count++;
}
if (count != 1)
sel = RTW89_REG_6GHZ_POWER_DFLT;
if (regulatory->reg_6ghz_power == sel)
return;
rtw89_debug(rtwdev, RTW89_DBG_REGD,
"recalc 6 GHz reg power type to %d\n", sel);
regulatory->reg_6ghz_power = sel;
rtw89_core_set_chip_txpwr(rtwdev);
}
void rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, bool active)
{
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
lockdep_assert_held(&rtwdev->mutex);
if (active) {
switch (vif->bss_conf.power_type) {
case IEEE80211_REG_VLP_AP:
rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_VLP;
break;
case IEEE80211_REG_LPI_AP:
rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_LPI;
break;
case IEEE80211_REG_SP_AP:
rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_STD;
break;
default:
rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
break;
}
} else {
rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
}
__rtw89_reg_6ghz_power_recalc(rtwdev);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,76 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2022-2023 Realtek Corporation
*/
#ifndef __RTW89_8851B_H__
#define __RTW89_8851B_H__
#include "core.h"
#define RF_PATH_NUM_8851B 1
#define BB_PATH_NUM_8851B 1
struct rtw8851bu_efuse {
u8 rsvd[0x88];
u8 mac_addr[ETH_ALEN];
};
struct rtw8851be_efuse {
u8 mac_addr[ETH_ALEN];
};
struct rtw8851b_tssi_offset {
u8 cck_tssi[TSSI_CCK_CH_GROUP_NUM];
u8 bw40_tssi[TSSI_MCS_2G_CH_GROUP_NUM];
u8 rsvd[7];
u8 bw40_1s_tssi_5g[TSSI_MCS_5G_CH_GROUP_NUM];
} __packed;
struct rtw8851b_efuse {
u8 rsvd[0x210];
struct rtw8851b_tssi_offset path_a_tssi;
u8 rsvd1[136];
u8 channel_plan;
u8 xtal_k;
u8 rsvd2;
u8 iqk_lck;
u8 rsvd3[8];
u8 eeprom_version;
u8 customer_id;
u8 tx_bb_swing_2g;
u8 tx_bb_swing_5g;
u8 tx_cali_pwr_trk_mode;
u8 trx_path_selection;
u8 rfe_type;
u8 country_code[2];
u8 rsvd4[3];
u8 path_a_therm;
u8 rsvd5[3];
u8 rx_gain_2g_ofdm;
u8 rsvd6;
u8 rx_gain_2g_cck;
u8 rsvd7;
u8 rx_gain_5g_low;
u8 rsvd8;
u8 rx_gain_5g_mid;
u8 rsvd9;
u8 rx_gain_5g_high;
u8 rsvd10[35];
u8 path_a_cck_pwr_idx[6];
u8 path_a_bw40_1tx_pwr_idx[5];
u8 path_a_ofdm_1tx_pwr_idx_diff:4;
u8 path_a_bw20_1tx_pwr_idx_diff:4;
u8 path_a_bw20_2tx_pwr_idx_diff:4;
u8 path_a_bw40_2tx_pwr_idx_diff:4;
u8 path_a_cck_2tx_pwr_idx_diff:4;
u8 path_a_ofdm_2tx_pwr_idx_diff:4;
u8 rsvd11[0xf2];
union {
struct rtw8851bu_efuse u;
struct rtw8851be_efuse e;
};
} __packed;
extern const struct rtw89_chip_info rtw8851b_chip_info;
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,28 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2022-2023 Realtek Corporation
*/
#ifndef __RTW89_8851B_RFK_H__
#define __RTW89_8851B_RFK_H__
#include "core.h"
void rtw8851b_aack(struct rtw89_dev *rtwdev);
void rtw8851b_lck_init(struct rtw89_dev *rtwdev);
void rtw8851b_lck_track(struct rtw89_dev *rtwdev);
void rtw8851b_rck(struct rtw89_dev *rtwdev);
void rtw8851b_dack(struct rtw89_dev *rtwdev);
void rtw8851b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
void rtw8851b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
void rtw8851b_dpk_init(struct rtw89_dev *rtwdev);
void rtw8851b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy);
void rtw8851b_dpk_track(struct rtw89_dev *rtwdev);
void rtw8851b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool hwtx_en);
void rtw8851b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy);
void rtw8851b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start,
enum rtw89_phy_idx phy_idx);
void rtw8851b_set_channel_rf(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx);
#endif

View file

@ -0,0 +1,534 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2022-2023 Realtek Corporation
*/
#include "rtw8851b_rfk_table.h"
static const struct rtw89_reg5_def rtw8851b_dadck_setup_defs[] = {
RTW89_DECL_RFK_WM(0xc210, 0x003fc000, 0x80),
RTW89_DECL_RFK_WM(0xc224, 0x003fc000, 0x80),
RTW89_DECL_RFK_WM(0xc0f8, 0x30000000, 0x3),
RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x1),
RTW89_DECL_RFK_WM(0x030c, 0x1f000000, 0x1f),
RTW89_DECL_RFK_WM(0x032c, 0xc0000000, 0x0),
RTW89_DECL_RFK_WM(0x032c, BIT(22), 0x0),
RTW89_DECL_RFK_WM(0x032c, BIT(22), 0x1),
RTW89_DECL_RFK_WM(0x032c, BIT(16), 0x0),
RTW89_DECL_RFK_WM(0x032c, BIT(20), 0x1),
RTW89_DECL_RFK_WM(0x030c, 0x0f000000, 0x3),
RTW89_DECL_RFK_WM(0xc0f4, BIT(2), 0x0),
RTW89_DECL_RFK_WM(0xc0f4, BIT(4), 0x0),
RTW89_DECL_RFK_WM(0xc0f4, BIT(11), 0x1),
RTW89_DECL_RFK_WM(0xc0f4, BIT(11), 0x0),
RTW89_DECL_RFK_DELAY(1),
RTW89_DECL_RFK_WM(0xc0f4, 0x300, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_dadck_setup_defs);
static const struct rtw89_reg5_def rtw8851b_dadck_post_defs[] = {
RTW89_DECL_RFK_WM(0x032c, BIT(16), 0x1),
RTW89_DECL_RFK_WM(0x032c, BIT(20), 0x0),
RTW89_DECL_RFK_WM(0x030c, 0x1f000000, 0xc),
RTW89_DECL_RFK_WM(0x032c, 0xc0000000, 0x1),
RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_dadck_post_defs);
static const struct rtw89_reg5_def rtw8851b_dack_s0_1_defs[] = {
RTW89_DECL_RFK_WM(0x12a0, BIT(15), 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x7000, 0x3),
RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x1),
RTW89_DECL_RFK_WM(0x030c, BIT(28), 0x1),
RTW89_DECL_RFK_WM(0x032c, 0x80000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_dack_s0_1_defs);
static const struct rtw89_reg5_def rtw8851b_dack_s0_2_defs[] = {
RTW89_DECL_RFK_WM(0xc004, BIT(0), 0x0),
RTW89_DECL_RFK_WM(0x12a0, BIT(15), 0x0),
RTW89_DECL_RFK_WM(0x12a0, 0x7000, 0x7),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_dack_s0_2_defs);
static const struct rtw89_reg5_def rtw8851b_dack_manual_off_defs[] = {
RTW89_DECL_RFK_WM(0xc0f8, 0x30000000, 0x0),
RTW89_DECL_RFK_WM(0xc210, BIT(0), 0x0),
RTW89_DECL_RFK_WM(0xc224, BIT(0), 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_dack_manual_off_defs);
static const struct rtw89_reg5_def rtw8851b_iqk_rxclk_80_defs[] = {
RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x0101),
RTW89_DECL_RFK_WM(0x5670, 0x00002000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00080000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00070000, 0x2),
RTW89_DECL_RFK_WM(0x5670, 0x60000000, 0x1),
RTW89_DECL_RFK_WM(0xc0d4, 0x00000780, 0x8),
RTW89_DECL_RFK_WM(0xc0d4, 0x00007800, 0x2),
RTW89_DECL_RFK_WM(0xc0d4, 0x0c000000, 0x2),
RTW89_DECL_RFK_WM(0xc0d8, 0x000001e0, 0x5),
RTW89_DECL_RFK_WM(0xc0c4, 0x003e0000, 0xf),
RTW89_DECL_RFK_WM(0xc0ec, 0x00006000, 0x0),
RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x1),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x0f),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x03),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0001),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041),
RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x1101),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_rxclk_80_defs);
static const struct rtw89_reg5_def rtw8851b_iqk_rxclk_others_defs[] = {
RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x0101),
RTW89_DECL_RFK_WM(0x5670, 0x00002000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00080000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00070000, 0x2),
RTW89_DECL_RFK_WM(0x5670, 0x60000000, 0x0),
RTW89_DECL_RFK_WM(0xc0d4, 0x00000780, 0x8),
RTW89_DECL_RFK_WM(0xc0d4, 0x00007800, 0x2),
RTW89_DECL_RFK_WM(0xc0d4, 0x0c000000, 0x2),
RTW89_DECL_RFK_WM(0xc0d8, 0x000001e0, 0x5),
RTW89_DECL_RFK_WM(0xc0c4, 0x003e0000, 0xf),
RTW89_DECL_RFK_WM(0xc0ec, 0x00006000, 0x2),
RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x1),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x0f),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x03),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0001),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041),
RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x1101),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_rxclk_others_defs);
static const struct rtw89_reg5_def rtw8851b_iqk_txk_2ghz_defs[] = {
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x51, 0x80000, 0x0),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x51, 0x00800, 0x0),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x52, 0x00800, 0x0),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x55, 0x0001f, 0x4),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0xef, 0x00004, 0x1),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x00, 0xffff0, 0x403e),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x00003, 0x0),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x00070, 0x6),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x1f000, 0x10),
RTW89_DECL_RFK_DELAY(1),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_txk_2ghz_defs);
static const struct rtw89_reg5_def rtw8851b_iqk_txk_5ghz_defs[] = {
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x60, 0x00007, 0x0),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x55, 0x0001f, 0x4),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0xef, 0x00004, 0x1),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x00, 0xffff0, 0x403e),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x00003, 0x0),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x00070, 0x7),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x1f000, 0x7),
RTW89_DECL_RFK_DELAY(1),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_txk_5ghz_defs);
static const struct rtw89_reg5_def rtw8851b_iqk_afebb_restore_defs[] = {
RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x0),
RTW89_DECL_RFK_WM(0x20fc, 0x00010000, 0x1),
RTW89_DECL_RFK_WM(0x20fc, 0x00100000, 0x0),
RTW89_DECL_RFK_WM(0x20fc, 0x01000000, 0x1),
RTW89_DECL_RFK_WM(0x20fc, 0x10000000, 0x0),
RTW89_DECL_RFK_WM(0x5670, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x12a0, 0x000ff000, 0x00),
RTW89_DECL_RFK_WM(0x20fc, 0x00010000, 0x0),
RTW89_DECL_RFK_WM(0x20fc, 0x01000000, 0x0),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x10005, 0x00001, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_afebb_restore_defs);
static const struct rtw89_reg5_def rtw8851b_iqk_macbb_defs[] = {
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x10005, 0x00001, 0x0),
RTW89_DECL_RFK_WM(0x20fc, 0x00010000, 0x1),
RTW89_DECL_RFK_WM(0x20fc, 0x00100000, 0x0),
RTW89_DECL_RFK_WM(0x20fc, 0x01000000, 0x1),
RTW89_DECL_RFK_WM(0x20fc, 0x10000000, 0x0),
RTW89_DECL_RFK_WM(0x5670, MASKDWORD, 0xf801fffd),
RTW89_DECL_RFK_WM(0x5670, 0x00004000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00008000, 0x1),
RTW89_DECL_RFK_WM(0x5670, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00007000, 0x7),
RTW89_DECL_RFK_WM(0x5670, 0x00002000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00080000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00070000, 0x3),
RTW89_DECL_RFK_WM(0x5670, 0x60000000, 0x2),
RTW89_DECL_RFK_WM(0xc0d4, 0x00000780, 0x9),
RTW89_DECL_RFK_WM(0xc0d4, 0x00007800, 0x1),
RTW89_DECL_RFK_WM(0xc0d4, 0x0c000000, 0x0),
RTW89_DECL_RFK_WM(0xc0d8, 0x000001e0, 0x3),
RTW89_DECL_RFK_WM(0xc0c4, 0x003e0000, 0xa),
RTW89_DECL_RFK_WM(0xc0ec, 0x00006000, 0x0),
RTW89_DECL_RFK_WM(0xc0e8, 0x00000040, 0x1),
RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x1),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x1f),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x13),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0001),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041),
RTW89_DECL_RFK_WM(0x20fc, 0x00100000, 0x1),
RTW89_DECL_RFK_WM(0x20fc, 0x10000000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_macbb_defs);
static const struct rtw89_reg5_def rtw8851b_iqk_bb_afe_defs[] = {
RTW89_DECL_RFK_WM(0x5670, 0x00004000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00008000, 0x1),
RTW89_DECL_RFK_WM(0x5670, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00007000, 0x7),
RTW89_DECL_RFK_WM(0x5670, 0x00002000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00080000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00070000, 0x3),
RTW89_DECL_RFK_WM(0x5670, 0x60000000, 0x2),
RTW89_DECL_RFK_WM(0xc0d4, 0x00000780, 0x9),
RTW89_DECL_RFK_WM(0xc0d4, 0x00007800, 0x1),
RTW89_DECL_RFK_WM(0xc0d4, 0x0c000000, 0x0),
RTW89_DECL_RFK_WM(0xc0d8, 0x000001e0, 0x3),
RTW89_DECL_RFK_WM(0xc0c4, 0x003e0000, 0xa),
RTW89_DECL_RFK_WM(0xc0ec, 0x00006000, 0x0),
RTW89_DECL_RFK_WM(0xc0e8, 0x00000040, 0x1),
RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x1),
RTW89_DECL_RFK_WM(0x030c, MASKBYTE3, 0x1f),
RTW89_DECL_RFK_WM(0x030c, MASKBYTE3, 0x13),
RTW89_DECL_RFK_WM(0x032c, MASKHWORD, 0x0001),
RTW89_DECL_RFK_WM(0x032c, MASKHWORD, 0x0041),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_bb_afe_defs);
static const struct rtw89_reg5_def rtw8851b_tssi_sys_defs[] = {
RTW89_DECL_RFK_WM(0x12bc, 0x000ffff0, 0xb5b5),
RTW89_DECL_RFK_WM(0x32bc, 0x000ffff0, 0xb5b5),
RTW89_DECL_RFK_WM(0x0300, 0xff000000, 0x16),
RTW89_DECL_RFK_WM(0x0304, 0x0000ffff, 0x1f19),
RTW89_DECL_RFK_WM(0x0308, 0xff000000, 0x1c),
RTW89_DECL_RFK_WM(0x0314, 0xffff0000, 0x2041),
RTW89_DECL_RFK_WM(0x0318, 0xffffffff, 0x20012041),
RTW89_DECL_RFK_WM(0x0324, 0xffff0000, 0x2001),
RTW89_DECL_RFK_WM(0x0020, 0x00006000, 0x3),
RTW89_DECL_RFK_WM(0x0024, 0x00006000, 0x3),
RTW89_DECL_RFK_WM(0x0704, 0xffff0000, 0x601e),
RTW89_DECL_RFK_WM(0x2704, 0xffff0000, 0x601e),
RTW89_DECL_RFK_WM(0x0700, 0xf0000000, 0x4),
RTW89_DECL_RFK_WM(0x2700, 0xf0000000, 0x4),
RTW89_DECL_RFK_WM(0x0650, 0x3c000000, 0x0),
RTW89_DECL_RFK_WM(0x2650, 0x3c000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_sys_defs);
static const struct rtw89_reg5_def rtw8851b_tssi_sys_a_defs_2g[] = {
RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x33),
RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x33),
RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x1),
RTW89_DECL_RFK_WM(0x5814, 0x20000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_sys_a_defs_2g);
static const struct rtw89_reg5_def rtw8851b_tssi_sys_a_defs_5g[] = {
RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x44),
RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x44),
RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x0),
RTW89_DECL_RFK_WM(0x5814, 0x20000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_sys_a_defs_5g);
static const struct rtw89_reg5_def rtw8851b_tssi_init_txpwr_defs_a[] = {
RTW89_DECL_RFK_WM(0x566c, 0x00001000, 0x0),
RTW89_DECL_RFK_WM(0x5800, 0xffffffff, 0x003f807f),
RTW89_DECL_RFK_WM(0x580c, 0x0000007f, 0x40),
RTW89_DECL_RFK_WM(0x580c, 0x0fffff00, 0x00040),
RTW89_DECL_RFK_WM(0x5810, 0xffffffff, 0x59010000),
RTW89_DECL_RFK_WM(0x5814, 0x01ffffff, 0x026d000),
RTW89_DECL_RFK_WM(0x5814, 0xf8000000, 0x00),
RTW89_DECL_RFK_WM(0x5818, 0x00ffffff, 0x2c18e8),
RTW89_DECL_RFK_WM(0x5818, 0x07000000, 0x0),
RTW89_DECL_RFK_WM(0x5818, 0xf0000000, 0x0),
RTW89_DECL_RFK_WM(0x581c, 0x3fffffff, 0x3dc80280),
RTW89_DECL_RFK_WM(0x5820, 0xffffffff, 0x00000080),
RTW89_DECL_RFK_WM(0x58e8, 0x0000003f, 0x04),
RTW89_DECL_RFK_WM(0x580c, 0x10000000, 0x1),
RTW89_DECL_RFK_WM(0x580c, 0x40000000, 0x1),
RTW89_DECL_RFK_WM(0x5834, 0x3fffffff, 0x000115f2),
RTW89_DECL_RFK_WM(0x5838, 0x7fffffff, 0x0000121),
RTW89_DECL_RFK_WM(0x5854, 0x3fffffff, 0x000115f2),
RTW89_DECL_RFK_WM(0x5858, 0x7fffffff, 0x0000121),
RTW89_DECL_RFK_WM(0x5860, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0x5864, 0x07ffffff, 0x00801ff),
RTW89_DECL_RFK_WM(0x5898, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x589c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x58a4, 0x000000ff, 0x16),
RTW89_DECL_RFK_WM(0x58b0, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x58b4, 0x7fffffff, 0x0a002000),
RTW89_DECL_RFK_WM(0x58b8, 0x7fffffff, 0x00007628),
RTW89_DECL_RFK_WM(0x58bc, 0x07ffffff, 0x7a7807f),
RTW89_DECL_RFK_WM(0x58c0, 0xfffe0000, 0x003f),
RTW89_DECL_RFK_WM(0x58c4, 0xffffffff, 0x0003ffff),
RTW89_DECL_RFK_WM(0x58c8, 0x00ffffff, 0x000000),
RTW89_DECL_RFK_WM(0x58c8, 0xf0000000, 0x0),
RTW89_DECL_RFK_WM(0x58cc, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x58d0, 0x07ffffff, 0x2008101),
RTW89_DECL_RFK_WM(0x58d4, 0x000000ff, 0x00),
RTW89_DECL_RFK_WM(0x58d4, 0x0003fe00, 0x0ff),
RTW89_DECL_RFK_WM(0x58d4, 0x07fc0000, 0x100),
RTW89_DECL_RFK_WM(0x58d8, 0xffffffff, 0x8008016c),
RTW89_DECL_RFK_WM(0x58dc, 0x0001ffff, 0x0807f),
RTW89_DECL_RFK_WM(0x58dc, 0xfff00000, 0x800),
RTW89_DECL_RFK_WM(0x58f0, 0x0003ffff, 0x001ff),
RTW89_DECL_RFK_WM(0x58f4, 0x000fffff, 0x00000),
RTW89_DECL_RFK_WM(0x58f8, 0x000fffff, 0x00000),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_init_txpwr_defs_a);
static const struct rtw89_reg5_def rtw8851b_tssi_init_txpwr_he_tb_defs_a[] = {
RTW89_DECL_RFK_WM(0x58a0, MASKDWORD, 0x000000fe),
RTW89_DECL_RFK_WM(0x58e4, 0x0000007f, 0x1f),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_init_txpwr_he_tb_defs_a);
static const struct rtw89_reg5_def rtw8851b_tssi_dck_defs_a[] = {
RTW89_DECL_RFK_WM(0x580c, 0x0fff0000, 0x000),
RTW89_DECL_RFK_WM(0x5814, 0x00001000, 0x1),
RTW89_DECL_RFK_WM(0x5814, 0x00002000, 0x1),
RTW89_DECL_RFK_WM(0x5814, 0x00004000, 0x1),
RTW89_DECL_RFK_WM(0x5814, 0x00038000, 0x3),
RTW89_DECL_RFK_WM(0x5814, 0x003c0000, 0x5),
RTW89_DECL_RFK_WM(0x5814, 0x18000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_dck_defs_a);
static const struct rtw89_reg5_def rtw8851b_tssi_dac_gain_defs_a[] = {
RTW89_DECL_RFK_WM(0x58b0, 0x00000fff, 0x000),
RTW89_DECL_RFK_WM(0x5a00, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a04, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a08, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a0c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a10, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a14, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a18, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a1c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a20, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a24, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a28, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a2c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a30, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a34, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a38, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a3c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a40, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a44, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a48, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a4c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a50, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a54, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a58, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a5c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a60, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a64, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a68, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a6c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a70, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a74, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a78, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a7c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a80, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a84, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a88, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a8c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a90, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a94, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a98, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a9c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5aa0, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5aa4, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5aa8, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5aac, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5ab0, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5ab4, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5ab8, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5abc, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5ac0, MASKDWORD, 0x00000000),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_dac_gain_defs_a);
static const struct rtw89_reg5_def rtw8851b_tssi_slope_a_defs_2g[] = {
RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0200e08),
RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x007),
RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808),
RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x08080808),
RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x08080808),
RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08080808),
RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x0808),
RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_slope_a_defs_2g);
static const struct rtw89_reg5_def rtw8851b_tssi_slope_a_defs_5g[] = {
RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0341a08),
RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0201417),
RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x008),
RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808),
RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x0e0e0808),
RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x08080d18),
RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08080808),
RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x0808),
RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_slope_a_defs_5g);
static const struct rtw89_reg5_def rtw8851b_tssi_align_a_2g_defs[] = {
RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x000000),
RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x2d2400),
RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5634, 0x000003ff, 0x000),
RTW89_DECL_RFK_WM(0x5634, 0x000ffc00, 0x000),
RTW89_DECL_RFK_WM(0x5634, 0x3ff00000, 0x3fa),
RTW89_DECL_RFK_WM(0x5638, 0x000003ff, 0x02e),
RTW89_DECL_RFK_WM(0x5638, 0x000ffc00, 0x09c),
RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x3fb00000),
RTW89_DECL_RFK_WM(0x5644, 0x000003ff, 0x02f),
RTW89_DECL_RFK_WM(0x5644, 0x000ffc00, 0x09c),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_align_a_2g_defs);
static const struct rtw89_reg5_def rtw8851b_tssi_align_a_5g_defs[] = {
RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x000000),
RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x3b2d24),
RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5634, 0x000003ff, 0x000),
RTW89_DECL_RFK_WM(0x5634, 0x000ffc00, 0x3cb),
RTW89_DECL_RFK_WM(0x5634, 0x3ff00000, 0x030),
RTW89_DECL_RFK_WM(0x5638, 0x000003ff, 0x73),
RTW89_DECL_RFK_WM(0x5638, 0x000ffc00, 0xd4),
RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_align_a_5g_defs);
static const struct rtw89_reg5_def rtw8851b_tssi_slope_defs_a[] = {
RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x0),
RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x1),
RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x1),
RTW89_DECL_RFK_WM(0x5820, 0x0000f000, 0xf),
RTW89_DECL_RFK_WM(0x581c, 0x000003ff, 0x280),
RTW89_DECL_RFK_WM(0x581c, 0x000ffc00, 0x200),
RTW89_DECL_RFK_WM(0x58b8, 0x007f0000, 0x00),
RTW89_DECL_RFK_WM(0x58b8, 0x7f000000, 0x00),
RTW89_DECL_RFK_WM(0x58b4, 0x7f000000, 0x0a),
RTW89_DECL_RFK_WM(0x58b8, 0x0000007f, 0x28),
RTW89_DECL_RFK_WM(0x58b8, 0x00007f00, 0x76),
RTW89_DECL_RFK_WM(0x5810, 0x20000000, 0x0),
RTW89_DECL_RFK_WM(0x580c, 0x10000000, 0x1),
RTW89_DECL_RFK_WM(0x580c, 0x40000000, 0x1),
RTW89_DECL_RFK_WM(0x5834, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x5834, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5838, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5838, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x5854, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x5854, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5858, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5858, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x5824, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x5824, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5828, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5828, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x582c, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x582c, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5830, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5830, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x583c, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x583c, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5840, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5840, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x5844, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x5844, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5848, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5848, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x584c, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x584c, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5850, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5850, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x585c, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x585c, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5860, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5860, 0x003ff000, 0x000),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_slope_defs_a);
static const struct rtw89_reg5_def rtw8851b_tssi_track_defs_a[] = {
RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x0),
RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x0),
RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x1),
RTW89_DECL_RFK_WM(0x5864, 0x000003ff, 0x1ff),
RTW89_DECL_RFK_WM(0x5864, 0x000ffc00, 0x200),
RTW89_DECL_RFK_WM(0x5820, 0x00000fff, 0x080),
RTW89_DECL_RFK_WM(0x5814, 0x01000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_track_defs_a);
static const struct rtw89_reg5_def rtw8851b_tssi_mv_avg_defs_a[] = {
RTW89_DECL_RFK_WM(0x58e4, 0x00003800, 0x1),
RTW89_DECL_RFK_WM(0x58e4, 0x00004000, 0x0),
RTW89_DECL_RFK_WM(0x58e4, 0x00008000, 0x1),
RTW89_DECL_RFK_WM(0x58e4, 0x000f0000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_mv_avg_defs_a);
static const struct rtw89_reg5_def rtw8851b_nctl_post_defs[] = {
RTW89_DECL_RFK_WM(0x5864, 0x18000000, 0x3),
RTW89_DECL_RFK_WM(0x7864, 0x18000000, 0x3),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x13),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041),
RTW89_DECL_RFK_WM(0x12b8, 0x10000000, 0x1),
RTW89_DECL_RFK_WM(0x2008, 0x01ffffff, 0x00fffff),
RTW89_DECL_RFK_WM(0x0c60, 0x00000003, 0x3),
RTW89_DECL_RFK_WM(0x0c6c, 0x00000001, 0x1),
RTW89_DECL_RFK_WM(0x58ac, 0x08000000, 0x1),
RTW89_DECL_RFK_WM(0x78ac, 0x08000000, 0x1),
RTW89_DECL_RFK_WM(0x0730, 0x00003800, 0x7),
RTW89_DECL_RFK_WM(0x2730, 0x00003800, 0x7),
RTW89_DECL_RFK_WM(0x0c7c, 0x00e00000, 0x1),
RTW89_DECL_RFK_WM(0x58c0, 0x0001ffff, 0x00000),
RTW89_DECL_RFK_WM(0x78c0, 0x0001ffff, 0x00000),
RTW89_DECL_RFK_WM(0x58fc, 0x3f000000, 0x00),
RTW89_DECL_RFK_WM(0x78fc, 0x3f000000, 0x00),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_nctl_post_defs);

View file

@ -0,0 +1,38 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2022-2023 Realtek Corporation
*/
#ifndef __RTW89_8851B_RFK_TABLE_H__
#define __RTW89_8851B_RFK_TABLE_H__
#include "phy.h"
extern const struct rtw89_rfk_tbl rtw8851b_dadck_setup_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_dadck_post_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_dack_s0_1_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_dack_s0_2_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_dack_manual_off_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_iqk_rxclk_80_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_iqk_rxclk_others_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_iqk_txk_2ghz_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_iqk_txk_5ghz_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_iqk_afebb_restore_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_iqk_bb_afe_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_iqk_macbb_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_sys_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_sys_a_defs_2g_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_sys_a_defs_5g_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_init_txpwr_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_init_txpwr_he_tb_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_dck_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_dac_gain_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_slope_a_defs_2g_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_slope_a_defs_5g_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_align_a_2g_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_align_a_5g_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_slope_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_track_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_mv_avg_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_nctl_post_defs_tbl;
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2022-2023 Realtek Corporation
*/
#ifndef __RTW89_8851B_TABLE_H__
#define __RTW89_8851B_TABLE_H__
#include "core.h"
extern const struct rtw89_phy_table rtw89_8851b_phy_bb_table;
extern const struct rtw89_phy_table rtw89_8851b_phy_bb_gain_table;
extern const struct rtw89_phy_table rtw89_8851b_phy_radioa_table;
extern const struct rtw89_phy_table rtw89_8851b_phy_nctl_table;
extern const struct rtw89_txpwr_table rtw89_8851b_byr_table;
extern const struct rtw89_txpwr_track_cfg rtw89_8851b_trk_cfg;
extern const u8 rtw89_8851b_tx_shape[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM]
[RTW89_REGD_NUM];
extern const struct rtw89_rfe_parms rtw89_8851b_dflt_parms;
extern const struct rtw89_rfe_parms_conf rtw89_8851b_rfe_parms_conf[];
#endif

View file

@ -0,0 +1,86 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2022-2023 Realtek Corporation
*/
#include <linux/module.h>
#include <linux/pci.h>
#include "pci.h"
#include "reg.h"
#include "rtw8851b.h"
static const struct rtw89_pci_info rtw8851b_pci_info = {
.txbd_trunc_mode = MAC_AX_BD_TRUNC,
.rxbd_trunc_mode = MAC_AX_BD_TRUNC,
.rxbd_mode = MAC_AX_RXBD_PKT,
.tag_mode = MAC_AX_TAG_MULTI,
.tx_burst = MAC_AX_TX_BURST_2048B,
.rx_burst = MAC_AX_RX_BURST_128B,
.wd_dma_idle_intvl = MAC_AX_WD_DMA_INTVL_256NS,
.wd_dma_act_intvl = MAC_AX_WD_DMA_INTVL_256NS,
.multi_tag_num = MAC_AX_TAG_NUM_8,
.lbc_en = MAC_AX_PCIE_ENABLE,
.lbc_tmr = MAC_AX_LBC_TMR_2MS,
.autok_en = MAC_AX_PCIE_DISABLE,
.io_rcy_en = MAC_AX_PCIE_DISABLE,
.io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_6MS,
.init_cfg_reg = R_AX_PCIE_INIT_CFG1,
.txhci_en_bit = B_AX_TXHCI_EN,
.rxhci_en_bit = B_AX_RXHCI_EN,
.rxbd_mode_bit = B_AX_RXBD_MODE,
.exp_ctrl_reg = R_AX_PCIE_EXP_CTRL,
.max_tag_num_mask = B_AX_MAX_TAG_NUM,
.rxbd_rwptr_clr_reg = R_AX_RXBD_RWPTR_CLR,
.txbd_rwptr_clr2_reg = 0,
.dma_stop1 = {R_AX_PCIE_DMA_STOP1, B_AX_TX_STOP1_MASK_V1},
.dma_stop2 = {0},
.dma_busy1 = {R_AX_PCIE_DMA_BUSY1, DMA_BUSY1_CHECK_V1},
.dma_busy2_reg = 0,
.dma_busy3_reg = R_AX_PCIE_DMA_BUSY1,
.rpwm_addr = R_AX_PCIE_HRPWM,
.cpwm_addr = R_AX_CPWM,
.tx_dma_ch_mask = BIT(RTW89_TXCH_ACH4) | BIT(RTW89_TXCH_ACH5) |
BIT(RTW89_TXCH_ACH6) | BIT(RTW89_TXCH_ACH7) |
BIT(RTW89_TXCH_CH10) | BIT(RTW89_TXCH_CH11),
.bd_idx_addr_low_power = NULL,
.dma_addr_set = &rtw89_pci_ch_dma_addr_set,
.bd_ram_table = &rtw89_bd_ram_table_single,
.ltr_set = rtw89_pci_ltr_set,
.fill_txaddr_info = rtw89_pci_fill_txaddr_info,
.config_intr_mask = rtw89_pci_config_intr_mask,
.enable_intr = rtw89_pci_enable_intr,
.disable_intr = rtw89_pci_disable_intr,
.recognize_intrs = rtw89_pci_recognize_intrs,
};
static const struct rtw89_driver_info rtw89_8851be_info = {
.chip = &rtw8851b_chip_info,
.bus = {
.pci = &rtw8851b_pci_info,
},
};
static const struct pci_device_id rtw89_8851be_id_table[] = {
{
PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xb851),
.driver_data = (kernel_ulong_t)&rtw89_8851be_info,
},
{},
};
MODULE_DEVICE_TABLE(pci, rtw89_8851be_id_table);
static struct pci_driver rtw89_8851be_driver = {
.name = "rtw89_8851be",
.id_table = rtw89_8851be_id_table,
.probe = rtw89_pci_probe,
.remove = rtw89_pci_remove,
.driver.pm = &rtw89_pm_ops,
};
module_pci_driver(rtw89_8851be_driver);
MODULE_AUTHOR("Realtek Corporation");
MODULE_DESCRIPTION("Realtek 802.11ax wireless 8851BE driver");
MODULE_LICENSE("Dual BSD/GPL");

View file

@ -12,6 +12,11 @@
#include "rtw8852a_table.h"
#include "txrx.h"
#define RTW8852A_FW_FORMAT_MAX 0
#define RTW8852A_FW_BASENAME "rtw89/rtw8852a_fw"
#define RTW8852A_MODULE_FIRMWARE \
RTW8852A_FW_BASENAME ".bin"
static const struct rtw89_hfc_ch_cfg rtw8852a_hfc_chcfg_pcie[] = {
{128, 1896, grp_0}, /* ACH 0 */
{128, 1896, grp_0}, /* ACH 1 */
@ -48,6 +53,10 @@ static const struct rtw89_dle_mem rtw8852a_dle_mem_pcie[] = {
&rtw89_mac_size.ple_size0, &rtw89_mac_size.wde_qt0,
&rtw89_mac_size.wde_qt0, &rtw89_mac_size.ple_qt4,
&rtw89_mac_size.ple_qt5},
[RTW89_QTA_WOW] = {RTW89_QTA_WOW, &rtw89_mac_size.wde_size0,
&rtw89_mac_size.ple_size0, &rtw89_mac_size.wde_qt0,
&rtw89_mac_size.wde_qt0, &rtw89_mac_size.ple_qt4,
&rtw89_mac_size.ple_qt_52a_wow},
[RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size4,
&rtw89_mac_size.ple_size4, &rtw89_mac_size.wde_qt4,
&rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt13,
@ -431,6 +440,7 @@ static const struct rtw89_imr_info rtw8852a_imr_info = {
.cpu_disp_imr_set = B_AX_CPU_DISP_IMR_SET,
.other_disp_imr_clr = B_AX_OTHER_DISP_IMR_CLR,
.other_disp_imr_set = 0,
.bbrpt_com_err_imr_reg = R_AX_BBRPT_COM_ERR_IMR_ISR,
.bbrpt_chinfo_err_imr_reg = R_AX_BBRPT_CHINFO_ERR_IMR_ISR,
.bbrpt_err_imr_set = 0,
.bbrpt_dfs_err_imr_reg = R_AX_BBRPT_DFS_ERR_IMR_ISR,
@ -453,6 +463,37 @@ static const struct rtw89_imr_info rtw8852a_imr_info = {
.tmac_imr_set = B_AX_TMAC_IMR_SET,
};
static const struct rtw89_xtal_info rtw8852a_xtal_info = {
.xcap_reg = R_AX_XTAL_ON_CTRL0,
.sc_xo_mask = B_AX_XTAL_SC_XO_MASK,
.sc_xi_mask = B_AX_XTAL_SC_XI_MASK,
};
static const struct rtw89_rrsr_cfgs rtw8852a_rrsr_cfgs = {
.ref_rate = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_REF_RATE_SEL, 0},
.rsc = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_RSC_MASK, 2},
};
static const struct rtw89_dig_regs rtw8852a_dig_regs = {
.seg0_pd_reg = R_SEG0R_PD,
.pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
.pd_spatial_reuse_en = B_SEG0R_PD_SPATIAL_REUSE_EN_MSK,
.p0_lna_init = {R_PATH0_LNA_INIT, B_PATH0_LNA_INIT_IDX_MSK},
.p1_lna_init = {R_PATH1_LNA_INIT, B_PATH1_LNA_INIT_IDX_MSK},
.p0_tia_init = {R_PATH0_TIA_INIT, B_PATH0_TIA_INIT_IDX_MSK},
.p1_tia_init = {R_PATH1_TIA_INIT, B_PATH1_TIA_INIT_IDX_MSK},
.p0_rxb_init = {R_PATH0_RXB_INIT, B_PATH0_RXB_INIT_IDX_MSK},
.p1_rxb_init = {R_PATH1_RXB_INIT, B_PATH1_RXB_INIT_IDX_MSK},
.p0_p20_pagcugc_en = {R_PATH0_P20_FOLLOW_BY_PAGCUGC,
B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK},
.p0_s20_pagcugc_en = {R_PATH0_S20_FOLLOW_BY_PAGCUGC,
B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK},
.p1_p20_pagcugc_en = {R_PATH1_P20_FOLLOW_BY_PAGCUGC,
B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK},
.p1_s20_pagcugc_en = {R_PATH1_S20_FOLLOW_BY_PAGCUGC,
B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK},
};
static void rtw8852ae_efuse_parsing(struct rtw89_efuse *efuse,
struct rtw8852a_efuse *map)
{
@ -1005,7 +1046,7 @@ static void rtw8852a_spur_elimination(struct rtw89_dev *rtwdev, u8 central_ch)
0x210);
rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL,
0x210);
rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, 0xfff, 0x7c0);
rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, B_SEG0CSI_IDX, 0x7c0);
rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX,
B_P0_NBIIDX_NOTCH_EN, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX,
@ -1017,7 +1058,7 @@ static void rtw8852a_spur_elimination(struct rtw89_dev *rtwdev, u8 central_ch)
0x210);
rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL,
0x210);
rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, 0xfff, 0x40);
rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, B_SEG0CSI_IDX, 0x40);
rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX,
B_P0_NBIIDX_NOTCH_EN, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX,
@ -1029,7 +1070,7 @@ static void rtw8852a_spur_elimination(struct rtw89_dev *rtwdev, u8 central_ch)
0x2d0);
rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL,
0x2d0);
rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, 0xfff, 0x740);
rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, B_SEG0CSI_IDX, 0x740);
rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX,
B_P0_NBIIDX_NOTCH_EN, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX,
@ -1297,7 +1338,6 @@ static void rtw8852a_rfk_scan(struct rtw89_dev *rtwdev, bool start)
static void rtw8852a_rfk_track(struct rtw89_dev *rtwdev)
{
rtw8852a_dpk_track(rtwdev);
rtw8852a_iqk_track(rtwdev);
rtw8852a_tssi_track(rtwdev);
}
@ -1384,151 +1424,14 @@ static void rtw8852a_set_txpwr_ref(struct rtw89_dev *rtwdev,
phy_idx);
}
static void rtw8852a_set_txpwr_byrate(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
u8 band = chan->band_type;
u8 ch = chan->channel;
static const u8 rs[] = {
RTW89_RS_CCK,
RTW89_RS_OFDM,
RTW89_RS_MCS,
RTW89_RS_HEDCM,
};
s8 tmp;
u8 i, j;
u32 val, shf, addr = R_AX_PWR_BY_RATE;
struct rtw89_rate_desc cur;
rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
"[TXPWR] set txpwr byrate with ch=%d\n", ch);
for (cur.nss = 0; cur.nss <= RTW89_NSS_2; cur.nss++) {
for (i = 0; i < ARRAY_SIZE(rs); i++) {
if (cur.nss >= rtw89_rs_nss_max[rs[i]])
continue;
val = 0;
cur.rs = rs[i];
for (j = 0; j < rtw89_rs_idx_max[rs[i]]; j++) {
cur.idx = j;
shf = (j % 4) * 8;
tmp = rtw89_phy_read_txpwr_byrate(rtwdev, band,
&cur);
val |= (tmp << shf);
if ((j + 1) % 4)
continue;
rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val);
val = 0;
addr += 4;
}
}
}
}
static void rtw8852a_set_txpwr_offset(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
u8 band = chan->band_type;
struct rtw89_rate_desc desc = {
.nss = RTW89_NSS_1,
.rs = RTW89_RS_OFFSET,
};
u32 val = 0;
s8 v;
rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr offset\n");
for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_MAX; desc.idx++) {
v = rtw89_phy_read_txpwr_byrate(rtwdev, band, &desc);
val |= ((v & 0xf) << (4 * desc.idx));
}
rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_OFST_CTRL,
GENMASK(19, 0), val);
}
static void rtw8852a_set_txpwr_limit(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
#define __MAC_TXPWR_LMT_PAGE_SIZE 40
u8 ch = chan->channel;
u8 bw = chan->band_width;
struct rtw89_txpwr_limit lmt[NTX_NUM_8852A];
u32 addr, val;
const s8 *ptr;
u8 i, j;
rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
"[TXPWR] set txpwr limit with ch=%d bw=%d\n", ch, bw);
for (i = 0; i < NTX_NUM_8852A; i++) {
rtw89_phy_fill_txpwr_limit(rtwdev, chan, &lmt[i], i);
for (j = 0; j < __MAC_TXPWR_LMT_PAGE_SIZE; j += 4) {
addr = R_AX_PWR_LMT + j + __MAC_TXPWR_LMT_PAGE_SIZE * i;
ptr = (s8 *)&lmt[i] + j;
val = FIELD_PREP(GENMASK(7, 0), ptr[0]) |
FIELD_PREP(GENMASK(15, 8), ptr[1]) |
FIELD_PREP(GENMASK(23, 16), ptr[2]) |
FIELD_PREP(GENMASK(31, 24), ptr[3]);
rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val);
}
}
#undef __MAC_TXPWR_LMT_PAGE_SIZE
}
static void rtw8852a_set_txpwr_limit_ru(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
#define __MAC_TXPWR_LMT_RU_PAGE_SIZE 24
u8 ch = chan->channel;
u8 bw = chan->band_width;
struct rtw89_txpwr_limit_ru lmt_ru[NTX_NUM_8852A];
u32 addr, val;
const s8 *ptr;
u8 i, j;
rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
"[TXPWR] set txpwr limit ru with ch=%d bw=%d\n", ch, bw);
for (i = 0; i < NTX_NUM_8852A; i++) {
rtw89_phy_fill_txpwr_limit_ru(rtwdev, chan, &lmt_ru[i], i);
for (j = 0; j < __MAC_TXPWR_LMT_RU_PAGE_SIZE; j += 4) {
addr = R_AX_PWR_RU_LMT + j +
__MAC_TXPWR_LMT_RU_PAGE_SIZE * i;
ptr = (s8 *)&lmt_ru[i] + j;
val = FIELD_PREP(GENMASK(7, 0), ptr[0]) |
FIELD_PREP(GENMASK(15, 8), ptr[1]) |
FIELD_PREP(GENMASK(23, 16), ptr[2]) |
FIELD_PREP(GENMASK(31, 24), ptr[3]);
rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val);
}
}
#undef __MAC_TXPWR_LMT_RU_PAGE_SIZE
}
static void rtw8852a_set_txpwr(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
rtw8852a_set_txpwr_byrate(rtwdev, chan, phy_idx);
rtw8852a_set_txpwr_offset(rtwdev, chan, phy_idx);
rtw8852a_set_txpwr_limit(rtwdev, chan, phy_idx);
rtw8852a_set_txpwr_limit_ru(rtwdev, chan, phy_idx);
rtw89_phy_set_txpwr_byrate(rtwdev, chan, phy_idx);
rtw89_phy_set_txpwr_offset(rtwdev, chan, phy_idx);
rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx);
rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx);
}
static void rtw8852a_set_txpwr_ctrl(struct rtw89_dev *rtwdev,
@ -1818,6 +1721,9 @@ static void rtw8852a_btc_init_cfg(struct rtw89_dev *rtwdev)
RF_PATH_A, BTC_BT_SS_GROUP, 0x5ff);
rtw8852a_set_trx_mask(rtwdev,
RF_PATH_B, BTC_BT_SS_GROUP, 0x5ff);
/* set path-A(S0) Tx/Rx no-mask if GNT_WL=0 && BT_S1=tx group */
rtw8852a_set_trx_mask(rtwdev,
RF_PATH_A, BTC_BT_TX_GROUP, 0x5ff);
} else { /* set WL Tx stb if GNT_WL = 0 && BT_S1 = ss group for 3-ant */
rtw8852a_set_trx_mask(rtwdev,
RF_PATH_A, BTC_BT_SS_GROUP, 0x5df);
@ -1931,7 +1837,8 @@ rtw8852a_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val)
static
s8 rtw8852a_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val)
{
return clamp_t(s8, val, -100, 0) + 100;
/* +6 for compensate offset */
return clamp_t(s8, val + 6, -100, 0) + 100;
}
static struct rtw89_btc_rf_trx_para rtw89_btc_8852a_rf_ul[] = {
@ -1978,26 +1885,17 @@ static struct rtw89_btc_fbtc_mreg rtw89_btc_8852a_mon_reg[] = {
RTW89_DEF_FBTC_MREG(REG_BT_MODEM, 4, 0x178),
};
static
void rtw8852a_btc_bt_aci_imp(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_bt_info *bt = &btc->cx.bt;
struct rtw89_btc_bt_link_info *b = &bt->link_info;
/* fix LNA2 = level-5 for BT ACI issue at BTG */
if (btc->dm.wl_btg_rx && b->profile_cnt.now != 0)
dm->trx_para_level = 1;
}
static
void rtw8852a_btc_update_bt_cnt(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_cx *cx = &btc->cx;
u32 val;
if (ver->fcxbtcrpt != 1)
return;
val = rtw89_read32(rtwdev, R_AX_BT_STAST_HIGH);
cx->cnt_bt[BTC_BCNT_HIPRI_TX] = FIELD_GET(B_AX_STATIS_BT_HI_TX_MASK, val);
cx->cnt_bt[BTC_BCNT_HIPRI_RX] = FIELD_GET(B_AX_STATIS_BT_HI_RX_MASK, val);
@ -2031,6 +1929,56 @@ void rtw8852a_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state)
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0);
}
static void rtw8852a_set_wl_lna2(struct rtw89_dev *rtwdev, u8 level)
{
/* level=0 Default: TIA 1/0= (LNA2,TIAN6) = (7,1)/(5,1) = 21dB/12dB
* level=1 Fix LNA2=5: TIA 1/0= (LNA2,TIAN6) = (5,0)/(5,1) = 18dB/12dB
* To improve BT ACI in co-rx
*/
switch (level) {
case 0: /* default */
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x1000);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x3);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x17);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x2);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0);
break;
case 1: /* Fix LNA2=5 */
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x1000);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x3);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x5);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x2);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0);
break;
}
}
static void rtw8852a_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level)
{
struct rtw89_btc *btc = &rtwdev->btc;
switch (level) {
case 0: /* original */
default:
rtw8852a_bb_ctrl_btc_preagc(rtwdev, false);
btc->dm.wl_lna2 = 0;
break;
case 1: /* for FDD free-run */
rtw8852a_bb_ctrl_btc_preagc(rtwdev, true);
btc->dm.wl_lna2 = 0;
break;
case 2: /* for BTG Co-Rx*/
rtw8852a_bb_ctrl_btc_preagc(rtwdev, false);
btc->dm.wl_lna2 = 1;
break;
}
rtw8852a_set_wl_lna2(rtwdev, btc->dm.wl_lna2);
}
static void rtw8852a_fill_freq_with_ppdu(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu,
struct ieee80211_rx_status *status)
@ -2051,17 +1999,26 @@ static void rtw8852a_query_ppdu(struct rtw89_dev *rtwdev,
struct ieee80211_rx_status *status)
{
u8 path;
s8 *rx_power = phy_ppdu->rssi;
u8 *rx_power = phy_ppdu->rssi;
status->signal = max_t(s8, rx_power[RF_PATH_A], rx_power[RF_PATH_B]);
status->signal = RTW89_RSSI_RAW_TO_DBM(max(rx_power[RF_PATH_A], rx_power[RF_PATH_B]));
for (path = 0; path < rtwdev->chip->rf_path_num; path++) {
status->chains |= BIT(path);
status->chain_signal[path] = rx_power[path];
status->chain_signal[path] = RTW89_RSSI_RAW_TO_DBM(rx_power[path]);
}
if (phy_ppdu->valid)
rtw8852a_fill_freq_with_ppdu(rtwdev, phy_ppdu, status);
}
#ifdef CONFIG_PM
static const struct wiphy_wowlan_support rtw_wowlan_stub_8852a = {
.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
.n_patterns = RTW89_MAX_PATTERN_NUM,
.pattern_max_len = RTW89_MAX_PATTERN_SIZE,
.pattern_min_len = 1,
};
#endif
static const struct rtw89_chip_ops rtw8852a_chip_ops = {
.enable_bb_rf = rtw89_mac_enable_bb_rf,
.disable_bb_rf = rtw89_mac_disable_bb_rf,
@ -2074,6 +2031,7 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = {
.read_efuse = rtw8852a_read_efuse,
.read_phycap = rtw8852a_read_phycap,
.fem_setup = rtw8852a_fem_setup,
.rfe_gpio = NULL,
.rfk_init = rtw8852a_rfk_init,
.rfk_channel = rtw8852a_rfk_channel,
.rfk_band_changed = rtw8852a_rfk_band_changed,
@ -2091,6 +2049,7 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = {
.set_txpwr_ul_tb_offset = rtw8852a_set_txpwr_ul_tb_offset,
.pwr_on_func = NULL,
.pwr_off_func = NULL,
.query_rxdesc = rtw89_core_query_rxdesc,
.fill_txdesc = rtw89_core_fill_txdesc,
.fill_txdesc_fwcmd = rtw89_core_fill_txdesc,
.cfg_ctrl_path = rtw89_mac_cfg_ctrl_path,
@ -2104,22 +2063,30 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = {
.btc_set_wl_pri = rtw8852a_btc_set_wl_pri,
.btc_set_wl_txpwr_ctrl = rtw8852a_btc_set_wl_txpwr_ctrl,
.btc_get_bt_rssi = rtw8852a_btc_get_bt_rssi,
.btc_bt_aci_imp = rtw8852a_btc_bt_aci_imp,
.btc_update_bt_cnt = rtw8852a_btc_update_bt_cnt,
.btc_wl_s1_standby = rtw8852a_btc_wl_s1_standby,
.btc_set_wl_rx_gain = rtw8852a_btc_set_wl_rx_gain,
.btc_set_policy = rtw89_btc_set_policy,
};
const struct rtw89_chip_info rtw8852a_chip_info = {
.chip_id = RTL8852A,
.chip_gen = RTW89_CHIP_AX,
.ops = &rtw8852a_chip_ops,
.fw_name = "rtw89/rtw8852a_fw.bin",
.fw_basename = RTW8852A_FW_BASENAME,
.fw_format_max = RTW8852A_FW_FORMAT_MAX,
.try_ce_fw = false,
.needed_fw_elms = 0,
.fifo_size = 458752,
.small_fifo_size = false,
.dle_scc_rsvd_size = 0,
.max_amsdu_limit = 3500,
.dis_2g_40m_ul_ofdma = true,
.rsvd_ple_ofst = 0x6f800,
.hfc_param_ini = rtw8852a_hfc_param_ini_pcie,
.dle_mem = rtw8852a_dle_mem_pcie,
.wde_qempty_acq_num = 16,
.wde_qempty_mgq_sel = 16,
.rf_base_addr = {0xc000, 0xd000},
.pwr_on_seq = pwr_on_seq_8852a,
.pwr_off_seq = pwr_off_seq_8852a,
@ -2128,19 +2095,21 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.rf_table = {&rtw89_8852a_phy_radioa_table,
&rtw89_8852a_phy_radiob_table,},
.nctl_table = &rtw89_8852a_phy_nctl_table,
.nctl_post_table = NULL,
.byr_table = &rtw89_8852a_byr_table,
.txpwr_lmt_2g = &rtw89_8852a_txpwr_lmt_2g,
.txpwr_lmt_5g = &rtw89_8852a_txpwr_lmt_5g,
.txpwr_lmt_ru_2g = &rtw89_8852a_txpwr_lmt_ru_2g,
.txpwr_lmt_ru_5g = &rtw89_8852a_txpwr_lmt_ru_5g,
.dflt_parms = &rtw89_8852a_dflt_parms,
.rfe_parms_conf = NULL,
.txpwr_factor_rf = 2,
.txpwr_factor_mac = 1,
.dig_table = &rtw89_8852a_phy_dig_table,
.dig_regs = &rtw8852a_dig_regs,
.tssi_dbw_table = NULL,
.support_chanctx_num = 1,
.support_bands = BIT(NL80211_BAND_2GHZ) |
BIT(NL80211_BAND_5GHZ),
.support_bw160 = false,
.support_unii4 = false,
.support_ul_tb_ctrl = false,
.hw_sec_hdr = false,
.rf_path_num = 2,
.tx_nss = 2,
@ -2150,7 +2119,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.scam_num = 128,
.bacam_num = 2,
.bacam_dynamic_num = 4,
.bacam_v1 = false,
.bacam_ver = RTW89_BACAM_V0,
.sec_ctrl_efuse_size = 4,
.physical_efuse_size = 1216,
.logical_efuse_size = 1536,
@ -2159,25 +2128,12 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.dav_log_efuse_size = 0,
.phycap_addr = 0x580,
.phycap_size = 128,
.para_ver = 0x05050864,
.wlcx_desired = 0x05050000,
.btcx_desired = 0x5,
.para_ver = 0x0,
.wlcx_desired = 0x06000000,
.btcx_desired = 0x7,
.scbd = 0x1,
.mailbox = 0x1,
.fcxbtcrpt_ver = 1,
.fcxtdma_ver = 1,
.fcxslots_ver = 1,
.fcxcysta_ver = 2,
.fcxstep_ver = 2,
.fcxnullsta_ver = 1,
.fcxmreg_ver = 1,
.fcxgpiodbg_ver = 1,
.fcxbtver_ver = 1,
.fcxbtscan_ver = 1,
.fcxbtafh_ver = 1,
.fcxbtdevinfo_ver = 1,
.afh_guard_ch = 6,
.wl_rssi_thres = rtw89_btc_8852a_wl_rssi_thres,
.bt_rssi_thres = rtw89_btc_8852a_bt_rssi_thres,
@ -2197,17 +2153,29 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.h2c_desc_size = sizeof(struct rtw89_txwd_body),
.txwd_body_size = sizeof(struct rtw89_txwd_body),
.h2c_ctrl_reg = R_AX_H2CREG_CTRL,
.h2c_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8},
.h2c_regs = rtw8852a_h2c_regs,
.c2h_ctrl_reg = R_AX_C2HREG_CTRL,
.c2h_regs = rtw8852a_c2h_regs,
.c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8},
.page_regs = &rtw8852a_page_regs,
.cfo_src_fd = false,
.cfo_hw_comp = false,
.dcfo_comp = &rtw8852a_dcfo_comp,
.dcfo_comp_sft = 3,
.imr_info = &rtw8852a_imr_info
.dcfo_comp_sft = 10,
.imr_info = &rtw8852a_imr_info,
.rrsr_cfgs = &rtw8852a_rrsr_cfgs,
.bss_clr_map_reg = R_BSS_CLR_MAP,
.dma_ch_mask = 0,
.edcca_lvl_reg = R_SEG0R_EDCCA_LVL,
#ifdef CONFIG_PM
.wowlan_stub = &rtw_wowlan_stub_8852a,
#endif
.xtal_info = &rtw8852a_xtal_info,
};
EXPORT_SYMBOL(rtw8852a_chip_info);
MODULE_FIRMWARE("rtw89/rtw8852a_fw.bin");
MODULE_FIRMWARE(RTW8852A_MODULE_FIRMWARE);
MODULE_AUTHOR("Realtek Corporation");
MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852A driver");
MODULE_LICENSE("Dual BSD/GPL");

View file

@ -8,7 +8,6 @@
#include "core.h"
#define RF_PATH_NUM_8852A 2
#define NTX_NUM_8852A 2
enum rtw8852a_pmac_mode {
NONE_TEST,

View file

@ -1284,11 +1284,8 @@ static void _iqk_info_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
u32 tmp = 0x0;
bool flag = 0x0;
iqk_info->thermal[path] =
ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]);
iqk_info->thermal_rek_en = false;
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_thermal = %d\n", path,
iqk_info->thermal[path]);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_thermal = %lu\n", path,
ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]));
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_LOK_COR_fail= %d\n", path,
iqk_info->lok_cor_fail[0][path]);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_LOK_FIN_fail= %d\n", path,
@ -1536,28 +1533,6 @@ static void _iqk_dbcc(struct rtw89_dev *rtwdev, u8 path)
_iqk_afebb_restore(rtwdev, phy_idx, path);
}
static void _iqk_track(struct rtw89_dev *rtwdev)
{
struct rtw89_iqk_info *iqk = &rtwdev->iqk;
u8 path = 0x0;
u8 cur_ther;
if (iqk->iqk_band[0] == RTW89_BAND_2G)
return;
if (iqk->iqk_bw[0] < RTW89_CHANNEL_WIDTH_80)
return;
/* only check path 0 */
for (path = 0; path < 1; path++) {
cur_ther = ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]);
if (abs(cur_ther - iqk->thermal[path]) > RTW8852A_IQK_THR_REK)
iqk->thermal_rek_en = true;
else
iqk->thermal_rek_en = false;
}
}
static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
{
u32 rf_reg5, rck_val = 0;
@ -1616,7 +1591,6 @@ static void _iqk_init(struct rtw89_dev *rtwdev)
iqk_info->iqk_sram_en = false;
iqk_info->iqk_cfir_en = false;
iqk_info->iqk_xym_en = false;
iqk_info->thermal_rek_en = false;
iqk_info->iqk_times = 0x0;
for (ch = 0; ch < RTW89_IQK_CHS_NR; ch++) {
@ -1643,9 +1617,8 @@ static void _doiqk(struct rtw89_dev *rtwdev, bool force,
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[IQK]==========IQK strat!!!!!==========\n");
"[IQK]==========IQK start!!!!!==========\n");
iqk_info->iqk_times++;
iqk_info->kcount = 0;
iqk_info->version = RTW8852A_IQK_VER;
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version);
@ -3655,11 +3628,6 @@ void rtw8852a_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP);
}
void rtw8852a_iqk_track(struct rtw89_dev *rtwdev)
{
_iqk_track(rtwdev);
}
void rtw8852a_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
bool is_afe)
{

View file

@ -10,7 +10,6 @@
void rtw8852a_rck(struct rtw89_dev *rtwdev);
void rtw8852a_dack(struct rtw89_dev *rtwdev);
void rtw8852a_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
void rtw8852a_iqk_track(struct rtw89_dev *rtwdev);
void rtw8852a_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
bool is_afe);
void rtw8852a_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy);

View file

@ -43377,6 +43377,7 @@ static const s8 _txpwr_track_delta_swingidx_2g_cck_a_p[] = {
0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5,
6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10};
static
const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM]
[RTW89_RS_LMT_NUM][RTW89_BF_NUM]
[RTW89_REGD_NUM][RTW89_2G_CH_NUM] = {
@ -45566,6 +45567,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_UK][13] = 127,
};
static
const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[RTW89_RS_LMT_NUM][RTW89_BF_NUM]
[RTW89_REGD_NUM][RTW89_5G_CH_NUM] = {
@ -47898,6 +47900,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][1][RTW89_UK][41] = 40,
};
static
const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM]
[RTW89_REGD_NUM][RTW89_2G_CH_NUM] = {
[0][0][RTW89_WW][0] = 32,
@ -48994,6 +48997,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_UK][13] = 127,
};
static
const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[RTW89_REGD_NUM][RTW89_5G_CH_NUM] = {
[0][0][RTW89_WW][0] = 22,
@ -51043,3 +51047,14 @@ const struct rtw89_phy_dig_gain_table rtw89_8852a_phy_dig_table = {
.cfg_lna_a = &rtw89_8852a_lna_gain_a_table,
.cfg_tia_a = &rtw89_8852a_tia_gain_a_table
};
const struct rtw89_rfe_parms rtw89_8852a_dflt_parms = {
.rule_2ghz = {
.lmt = &rtw89_8852a_txpwr_lmt_2g,
.lmt_ru = &rtw89_8852a_txpwr_lmt_ru_2g,
},
.rule_5ghz = {
.lmt = &rtw89_8852a_txpwr_lmt_5g,
.lmt_ru = &rtw89_8852a_txpwr_lmt_ru_5g,
},
};

View file

@ -14,15 +14,6 @@ extern const struct rtw89_phy_table rtw89_8852a_phy_nctl_table;
extern const struct rtw89_txpwr_table rtw89_8852a_byr_table;
extern const struct rtw89_phy_dig_gain_table rtw89_8852a_phy_dig_table;
extern const struct rtw89_txpwr_track_cfg rtw89_8852a_trk_cfg;
extern const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM]
[RTW89_RS_LMT_NUM][RTW89_BF_NUM]
[RTW89_REGD_NUM][RTW89_2G_CH_NUM];
extern const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[RTW89_RS_LMT_NUM][RTW89_BF_NUM]
[RTW89_REGD_NUM][RTW89_5G_CH_NUM];
extern const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM]
[RTW89_REGD_NUM][RTW89_2G_CH_NUM];
extern const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[RTW89_REGD_NUM][RTW89_5G_CH_NUM];
extern const struct rtw89_rfe_parms rtw89_8852a_dflt_parms;
#endif

View file

@ -33,16 +33,18 @@ static const struct rtw89_pci_info rtw8852a_pci_info = {
.max_tag_num_mask = B_AX_MAX_TAG_NUM,
.rxbd_rwptr_clr_reg = R_AX_RXBD_RWPTR_CLR,
.txbd_rwptr_clr2_reg = R_AX_TXBD_RWPTR_CLR2,
.dma_stop1_reg = R_AX_PCIE_DMA_STOP1,
.dma_stop2_reg = R_AX_PCIE_DMA_STOP2,
.dma_busy1_reg = R_AX_PCIE_DMA_BUSY1,
.dma_stop1 = {R_AX_PCIE_DMA_STOP1, B_AX_TX_STOP1_MASK},
.dma_stop2 = {R_AX_PCIE_DMA_STOP2, B_AX_TX_STOP2_ALL},
.dma_busy1 = {R_AX_PCIE_DMA_BUSY1, DMA_BUSY1_CHECK},
.dma_busy2_reg = R_AX_PCIE_DMA_BUSY2,
.dma_busy3_reg = R_AX_PCIE_DMA_BUSY1,
.rpwm_addr = R_AX_PCIE_HRPWM,
.cpwm_addr = R_AX_CPWM,
.tx_dma_ch_mask = 0,
.bd_idx_addr_low_power = NULL,
.dma_addr_set = &rtw89_pci_ch_dma_addr_set,
.bd_ram_table = &rtw89_bd_ram_table_dual,
.ltr_set = rtw89_pci_ltr_set,
.fill_txaddr_info = rtw89_pci_fill_txaddr_info,

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,137 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2022 Realtek Corporation
*/
#ifndef __RTW89_8852B_H__
#define __RTW89_8852B_H__
#include "core.h"
#define RF_PATH_NUM_8852B 2
#define BB_PATH_NUM_8852B 2
enum rtw8852b_pmac_mode {
NONE_TEST,
PKTS_TX,
PKTS_RX,
CONT_TX
};
struct rtw8852b_u_efuse {
u8 rsvd[0x88];
u8 mac_addr[ETH_ALEN];
};
struct rtw8852b_e_efuse {
u8 mac_addr[ETH_ALEN];
};
struct rtw8852b_tssi_offset {
u8 cck_tssi[TSSI_CCK_CH_GROUP_NUM];
u8 bw40_tssi[TSSI_MCS_2G_CH_GROUP_NUM];
u8 rsvd[7];
u8 bw40_1s_tssi_5g[TSSI_MCS_5G_CH_GROUP_NUM];
} __packed;
struct rtw8852b_efuse {
u8 rsvd[0x210];
struct rtw8852b_tssi_offset path_a_tssi;
u8 rsvd1[10];
struct rtw8852b_tssi_offset path_b_tssi;
u8 rsvd2[94];
u8 channel_plan;
u8 xtal_k;
u8 rsvd3;
u8 iqk_lck;
u8 rsvd4[5];
u8 reg_setting:2;
u8 tx_diversity:1;
u8 rx_diversity:2;
u8 ac_mode:1;
u8 module_type:2;
u8 rsvd5;
u8 shared_ant:1;
u8 coex_type:3;
u8 ant_iso:1;
u8 radio_on_off:1;
u8 rsvd6:2;
u8 eeprom_version;
u8 customer_id;
u8 tx_bb_swing_2g;
u8 tx_bb_swing_5g;
u8 tx_cali_pwr_trk_mode;
u8 trx_path_selection;
u8 rfe_type;
u8 country_code[2];
u8 rsvd7[3];
u8 path_a_therm;
u8 path_b_therm;
u8 rsvd8[2];
u8 rx_gain_2g_ofdm;
u8 rsvd9;
u8 rx_gain_2g_cck;
u8 rsvd10;
u8 rx_gain_5g_low;
u8 rsvd11;
u8 rx_gain_5g_mid;
u8 rsvd12;
u8 rx_gain_5g_high;
u8 rsvd13[35];
u8 path_a_cck_pwr_idx[6];
u8 path_a_bw40_1tx_pwr_idx[5];
u8 path_a_ofdm_1tx_pwr_idx_diff:4;
u8 path_a_bw20_1tx_pwr_idx_diff:4;
u8 path_a_bw20_2tx_pwr_idx_diff:4;
u8 path_a_bw40_2tx_pwr_idx_diff:4;
u8 path_a_cck_2tx_pwr_idx_diff:4;
u8 path_a_ofdm_2tx_pwr_idx_diff:4;
u8 rsvd14[0xf2];
union {
struct rtw8852b_u_efuse u;
struct rtw8852b_e_efuse e;
};
} __packed;
struct rtw8852b_bb_pmac_info {
u8 en_pmac_tx:1;
u8 is_cck:1;
u8 mode:3;
u8 rsvd:3;
u16 tx_cnt;
u16 period;
u16 tx_time;
u8 duty_cycle;
};
struct rtw8852b_bb_tssi_bak {
u8 tx_path;
u8 rx_path;
u32 p0_rfmode;
u32 p0_rfmode_ftm;
u32 p1_rfmode;
u32 p1_rfmode_ftm;
s16 tx_pwr; /* S9 */
};
extern const struct rtw89_chip_info rtw8852b_chip_info;
void rtw8852b_bb_set_plcp_tx(struct rtw89_dev *rtwdev);
void rtw8852b_bb_set_pmac_tx(struct rtw89_dev *rtwdev,
struct rtw8852b_bb_pmac_info *tx_info,
enum rtw89_phy_idx idx);
void rtw8852b_bb_set_pmac_pkt_tx(struct rtw89_dev *rtwdev, u8 enable,
u16 tx_cnt, u16 period, u16 tx_time,
enum rtw89_phy_idx idx);
void rtw8852b_bb_set_power(struct rtw89_dev *rtwdev, s16 pwr_dbm,
enum rtw89_phy_idx idx);
void rtw8852b_bb_cfg_tx_path(struct rtw89_dev *rtwdev, u8 tx_path);
void rtw8852b_bb_ctrl_rx_path(struct rtw89_dev *rtwdev,
enum rtw89_rf_path_bit rx_path);
void rtw8852b_bb_tx_mode_switch(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx idx, u8 mode);
void rtw8852b_bb_backup_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx,
struct rtw8852b_bb_tssi_bak *bak);
void rtw8852b_bb_restore_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx,
const struct rtw8852b_bb_tssi_bak *bak);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2022 Realtek Corporation
*/
#ifndef __RTW89_8852B_RFK_H__
#define __RTW89_8852B_RFK_H__
#include "core.h"
void rtw8852b_rck(struct rtw89_dev *rtwdev);
void rtw8852b_dack(struct rtw89_dev *rtwdev);
void rtw8852b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
void rtw8852b_dpk_init(struct rtw89_dev *rtwdev);
void rtw8852b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy);
void rtw8852b_dpk_track(struct rtw89_dev *rtwdev);
void rtw8852b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool hwtx_en);
void rtw8852b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy);
void rtw8852b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start,
enum rtw89_phy_idx phy_idx);
void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx);
#endif

View file

@ -0,0 +1,794 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#include "rtw8852b_rfk_table.h"
static const struct rtw89_reg5_def rtw8852b_afe_init_defs[] = {
RTW89_DECL_RFK_WM(0xC0D4, 0xffffffff, 0x4486888c),
RTW89_DECL_RFK_WM(0xC0D8, 0xffffffff, 0xc6ba10e0),
RTW89_DECL_RFK_WM(0xc0dc, 0xffffffff, 0x30c52868),
RTW89_DECL_RFK_WM(0xc0e0, 0xffffffff, 0x05008128),
RTW89_DECL_RFK_WM(0xc0e4, 0xffffffff, 0x0000272b),
RTW89_DECL_RFK_WM(0xC1D4, 0xffffffff, 0x4486888c),
RTW89_DECL_RFK_WM(0xC1D8, 0xffffffff, 0xc6ba10e0),
RTW89_DECL_RFK_WM(0xc1dc, 0xffffffff, 0x30c52868),
RTW89_DECL_RFK_WM(0xc1e0, 0xffffffff, 0x05008128),
RTW89_DECL_RFK_WM(0xc1e4, 0xffffffff, 0x0000272b),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_afe_init_defs);
static const struct rtw89_reg5_def rtw8852b_check_addc_defs_a[] = {
RTW89_DECL_RFK_WM(0x20f4, BIT(24), 0x0),
RTW89_DECL_RFK_WM(0x20f8, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x20f0, 0xff0000, 0x1),
RTW89_DECL_RFK_WM(0x20f0, 0xf00, 0x2),
RTW89_DECL_RFK_WM(0x20f0, 0xf, 0x0),
RTW89_DECL_RFK_WM(0x20f0, 0xc0, 0x2),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_check_addc_defs_a);
static const struct rtw89_reg5_def rtw8852b_check_addc_defs_b[] = {
RTW89_DECL_RFK_WM(0x20f4, BIT(24), 0x0),
RTW89_DECL_RFK_WM(0x20f8, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x20f0, 0xff0000, 0x1),
RTW89_DECL_RFK_WM(0x20f0, 0xf00, 0x2),
RTW89_DECL_RFK_WM(0x20f0, 0xf, 0x0),
RTW89_DECL_RFK_WM(0x20f0, 0xc0, 0x3),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_check_addc_defs_b);
static const struct rtw89_reg5_def rtw8852b_check_dadc_en_defs_a[] = {
RTW89_DECL_RFK_WM(0x032C, BIT(30), 0x0),
RTW89_DECL_RFK_WM(0x030C, 0x0f000000, 0xf),
RTW89_DECL_RFK_WM(0x030C, 0x0f000000, 0x3),
RTW89_DECL_RFK_WM(0x032C, BIT(16), 0x0),
RTW89_DECL_RFK_WM(0x12dc, BIT(0), 0x1),
RTW89_DECL_RFK_WM(0x12e8, BIT(2), 0x1),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x8f, BIT(13), 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_check_dadc_en_defs_a);
static const struct rtw89_reg5_def rtw8852b_check_dadc_en_defs_b[] = {
RTW89_DECL_RFK_WM(0x032C, BIT(30), 0x0),
RTW89_DECL_RFK_WM(0x030C, 0x0f000000, 0xf),
RTW89_DECL_RFK_WM(0x030C, 0x0f000000, 0x3),
RTW89_DECL_RFK_WM(0x032C, BIT(16), 0x0),
RTW89_DECL_RFK_WM(0x32dc, BIT(0), 0x1),
RTW89_DECL_RFK_WM(0x32e8, BIT(2), 0x1),
RTW89_DECL_RFK_WRF(RF_PATH_B, 0x8f, BIT(13), 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_check_dadc_en_defs_b);
static const struct rtw89_reg5_def rtw8852b_check_dadc_dis_defs_a[] = {
RTW89_DECL_RFK_WM(0x12dc, BIT(0), 0x0),
RTW89_DECL_RFK_WM(0x12e8, BIT(2), 0x0),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x8f, BIT(13), 0x0),
RTW89_DECL_RFK_WM(0x032C, BIT(16), 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_check_dadc_dis_defs_a);
static const struct rtw89_reg5_def rtw8852b_check_dadc_dis_defs_b[] = {
RTW89_DECL_RFK_WM(0x32dc, BIT(0), 0x0),
RTW89_DECL_RFK_WM(0x32e8, BIT(2), 0x0),
RTW89_DECL_RFK_WRF(RF_PATH_B, 0x8f, BIT(13), 0x0),
RTW89_DECL_RFK_WM(0x032C, BIT(16), 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_check_dadc_dis_defs_b);
static const struct rtw89_reg5_def rtw8852b_dack_s0_1_defs[] = {
RTW89_DECL_RFK_WM(0x12A0, BIT(15), 0x1),
RTW89_DECL_RFK_WM(0x12A0, 0x00007000, 0x3),
RTW89_DECL_RFK_WM(0x12B8, BIT(30), 0x1),
RTW89_DECL_RFK_WM(0x030C, BIT(28), 0x1),
RTW89_DECL_RFK_WM(0x032C, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0xC0D8, BIT(16), 0x1),
RTW89_DECL_RFK_WM(0xc0dc, 0x0c000000, 0x3),
RTW89_DECL_RFK_WM(0xC004, BIT(30), 0x0),
RTW89_DECL_RFK_WM(0xc024, BIT(30), 0x0),
RTW89_DECL_RFK_WM(0xC004, 0x3ff00000, 0x30),
RTW89_DECL_RFK_WM(0xC004, 0xc0000000, 0x0),
RTW89_DECL_RFK_WM(0xC004, BIT(17), 0x1),
RTW89_DECL_RFK_WM(0xc024, BIT(17), 0x1),
RTW89_DECL_RFK_WM(0xc00c, BIT(2), 0x0),
RTW89_DECL_RFK_WM(0xc02c, BIT(2), 0x0),
RTW89_DECL_RFK_WM(0xC004, BIT(0), 0x1),
RTW89_DECL_RFK_WM(0xc024, BIT(0), 0x1),
RTW89_DECL_RFK_DELAY(1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s0_1_defs);
static const struct rtw89_reg5_def rtw8852b_dack_s0_2_defs[] = {
RTW89_DECL_RFK_WM(0xc0dc, 0x0c000000, 0x0),
RTW89_DECL_RFK_WM(0xc00c, BIT(2), 0x1),
RTW89_DECL_RFK_WM(0xc02c, BIT(2), 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s0_2_defs);
static const struct rtw89_reg5_def rtw8852b_dack_s0_3_defs[] = {
RTW89_DECL_RFK_WM(0xC004, BIT(0), 0x0),
RTW89_DECL_RFK_WM(0xc024, BIT(0), 0x0),
RTW89_DECL_RFK_WM(0xC0D8, BIT(16), 0x0),
RTW89_DECL_RFK_WM(0x12A0, BIT(15), 0x0),
RTW89_DECL_RFK_WM(0x12A0, 0x00007000, 0x7),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s0_3_defs);
static const struct rtw89_reg5_def rtw8852b_dack_s1_1_defs[] = {
RTW89_DECL_RFK_WM(0x32a0, BIT(15), 0x1),
RTW89_DECL_RFK_WM(0x32a0, 0x7000, 0x3),
RTW89_DECL_RFK_WM(0x32B8, BIT(30), 0x1),
RTW89_DECL_RFK_WM(0x030C, BIT(28), 0x1),
RTW89_DECL_RFK_WM(0x032C, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0xC1D8, BIT(16), 0x1),
RTW89_DECL_RFK_WM(0xc1dc, 0x0c000000, 0x3),
RTW89_DECL_RFK_WM(0xc104, BIT(30), 0x0),
RTW89_DECL_RFK_WM(0xc124, BIT(30), 0x0),
RTW89_DECL_RFK_WM(0xc104, 0x3ff00000, 0x30),
RTW89_DECL_RFK_WM(0xc104, 0xc0000000, 0x0),
RTW89_DECL_RFK_WM(0xc104, BIT(17), 0x1),
RTW89_DECL_RFK_WM(0xc124, BIT(17), 0x1),
RTW89_DECL_RFK_WM(0xc10c, BIT(2), 0x0),
RTW89_DECL_RFK_WM(0xc12c, BIT(2), 0x0),
RTW89_DECL_RFK_WM(0xc104, BIT(0), 0x1),
RTW89_DECL_RFK_WM(0xc124, BIT(0), 0x1),
RTW89_DECL_RFK_DELAY(1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s1_1_defs);
static const struct rtw89_reg5_def rtw8852b_dack_s1_2_defs[] = {
RTW89_DECL_RFK_WM(0xc1dc, 0x0c000000, 0x0),
RTW89_DECL_RFK_WM(0xc10c, BIT(2), 0x1),
RTW89_DECL_RFK_WM(0xc12c, BIT(2), 0x1),
RTW89_DECL_RFK_DELAY(1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s1_2_defs);
static const struct rtw89_reg5_def rtw8852b_dack_s1_3_defs[] = {
RTW89_DECL_RFK_WM(0xc104, BIT(0), 0x0),
RTW89_DECL_RFK_WM(0xc124, BIT(0), 0x0),
RTW89_DECL_RFK_WM(0xC1D8, BIT(16), 0x0),
RTW89_DECL_RFK_WM(0x32a0, BIT(15), 0x0),
RTW89_DECL_RFK_WM(0x32a0, 0x7000, 0x7),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s1_3_defs);
static const struct rtw89_reg5_def rtw8852b_dpk_afe_defs[] = {
RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x0303),
RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x1),
RTW89_DECL_RFK_WM(0x32b8, BIT(30), 0x1),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x13),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041),
RTW89_DECL_RFK_WM(0x12b8, BIT(28), 0x1),
RTW89_DECL_RFK_WM(0x58c8, BIT(24), 0x1),
RTW89_DECL_RFK_WM(0x78c8, BIT(24), 0x1),
RTW89_DECL_RFK_WM(0x5864, 0xc0000000, 0x3),
RTW89_DECL_RFK_WM(0x7864, 0xc0000000, 0x3),
RTW89_DECL_RFK_WM(0x2008, 0x01FFFFFF, 0x1ffffff),
RTW89_DECL_RFK_WM(0x0c1c, BIT(2), 0x1),
RTW89_DECL_RFK_WM(0x0700, BIT(27), 0x1),
RTW89_DECL_RFK_WM(0x0c70, 0x000003FF, 0x3ff),
RTW89_DECL_RFK_WM(0x0c60, 0x00000003, 0x3),
RTW89_DECL_RFK_WM(0x0c6c, BIT(0), 0x1),
RTW89_DECL_RFK_WM(0x58ac, BIT(27), 0x1),
RTW89_DECL_RFK_WM(0x78ac, BIT(27), 0x1),
RTW89_DECL_RFK_WM(0x0c3c, BIT(9), 0x1),
RTW89_DECL_RFK_WM(0x2344, BIT(31), 0x1),
RTW89_DECL_RFK_WM(0x4490, BIT(31), 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x000ff000, 0xbf),
RTW89_DECL_RFK_WM(0x32a0, 0x000f0000, 0xb),
RTW89_DECL_RFK_WM(0x0700, 0x07000000, 0x5),
RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x3333),
RTW89_DECL_RFK_WM(0x580c, BIT(15), 0x1),
RTW89_DECL_RFK_WM(0x5800, 0x0000ffff, 0x0000),
RTW89_DECL_RFK_WM(0x780c, BIT(15), 0x1),
RTW89_DECL_RFK_WM(0x7800, 0x0000ffff, 0x0000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_dpk_afe_defs);
static const struct rtw89_reg5_def rtw8852b_dpk_afe_restore_defs[] = {
RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x0303),
RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x0),
RTW89_DECL_RFK_WM(0x32b8, BIT(30), 0x0),
RTW89_DECL_RFK_WM(0x5864, 0xc0000000, 0x0),
RTW89_DECL_RFK_WM(0x7864, 0xc0000000, 0x0),
RTW89_DECL_RFK_WM(0x2008, 0x01FFFFFF, 0x0),
RTW89_DECL_RFK_WM(0x0c1c, BIT(2), 0x0),
RTW89_DECL_RFK_WM(0x0700, BIT(27), 0x0),
RTW89_DECL_RFK_WM(0x0c70, 0x000003FF, 0x63),
RTW89_DECL_RFK_WM(0x12a0, 0x000FF000, 0x00),
RTW89_DECL_RFK_WM(0x32a0, 0x000FF000, 0x00),
RTW89_DECL_RFK_WM(0x0700, 0x07000000, 0x0),
RTW89_DECL_RFK_WM(0x5864, BIT(29), 0x0),
RTW89_DECL_RFK_WM(0x7864, BIT(29), 0x0),
RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x0000),
RTW89_DECL_RFK_WM(0x58c8, BIT(24), 0x0),
RTW89_DECL_RFK_WM(0x78c8, BIT(24), 0x0),
RTW89_DECL_RFK_WM(0x0c3c, BIT(9), 0x0),
RTW89_DECL_RFK_WM(0x580c, BIT(15), 0x0),
RTW89_DECL_RFK_WM(0x58e4, 0x18000000, 0x1),
RTW89_DECL_RFK_WM(0x58e4, 0x18000000, 0x2),
RTW89_DECL_RFK_WM(0x780c, BIT(15), 0x0),
RTW89_DECL_RFK_WM(0x78e4, 0x18000000, 0x1),
RTW89_DECL_RFK_WM(0x78e4, 0x18000000, 0x2),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_dpk_afe_restore_defs);
static const struct rtw89_reg5_def rtw8852b_dpk_kip_defs[] = {
RTW89_DECL_RFK_WM(0x8008, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x8088, 0xffffffff, 0x80000000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_dpk_kip_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_sys_defs[] = {
RTW89_DECL_RFK_WM(0x12a8, 0x0000000f, 0x5),
RTW89_DECL_RFK_WM(0x32a8, 0x0000000f, 0x5),
RTW89_DECL_RFK_WM(0x12bc, 0x000ffff0, 0x5555),
RTW89_DECL_RFK_WM(0x32bc, 0x000ffff0, 0x5555),
RTW89_DECL_RFK_WM(0x0300, 0xff000000, 0x16),
RTW89_DECL_RFK_WM(0x0304, 0x000000ff, 0x19),
RTW89_DECL_RFK_WM(0x0314, 0xffff0000, 0x2041),
RTW89_DECL_RFK_WM(0x0318, 0xffffffff, 0x2041),
RTW89_DECL_RFK_WM(0x0318, 0xffffffff, 0x20012041),
RTW89_DECL_RFK_WM(0x0020, 0x00006000, 0x3),
RTW89_DECL_RFK_WM(0x0024, 0x00006000, 0x3),
RTW89_DECL_RFK_WM(0x0704, 0xffff0000, 0x601e),
RTW89_DECL_RFK_WM(0x2704, 0xffff0000, 0x601e),
RTW89_DECL_RFK_WM(0x0700, 0xf0000000, 0x4),
RTW89_DECL_RFK_WM(0x2700, 0xf0000000, 0x4),
RTW89_DECL_RFK_WM(0x0650, 0x3c000000, 0x0),
RTW89_DECL_RFK_WM(0x2650, 0x3c000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_sys_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_sys_a_defs_2g[] = {
RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x33),
RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x33),
RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x1),
RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x1e),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_sys_a_defs_2g);
static const struct rtw89_reg5_def rtw8852b_tssi_sys_a_defs_5g[] = {
RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x44),
RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x44),
RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x0),
RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x1d),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_sys_a_defs_5g);
static const struct rtw89_reg5_def rtw8852b_tssi_sys_b_defs_2g[] = {
RTW89_DECL_RFK_WM(0x32c0, 0x0ff00000, 0x33),
RTW89_DECL_RFK_WM(0x320c, 0x000000ff, 0x33),
RTW89_DECL_RFK_WM(0x78f8, 0x40000000, 0x1),
RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x1e),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_sys_b_defs_2g);
static const struct rtw89_reg5_def rtw8852b_tssi_sys_b_defs_5g[] = {
RTW89_DECL_RFK_WM(0x32c0, 0x0ff00000, 0x44),
RTW89_DECL_RFK_WM(0x320c, 0x000000ff, 0x44),
RTW89_DECL_RFK_WM(0x78f8, 0x40000000, 0x0),
RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x1d),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_sys_b_defs_5g);
static const struct rtw89_reg5_def rtw8852b_tssi_init_txpwr_defs_a[] = {
RTW89_DECL_RFK_WM(0x566c, 0x00001000, 0x0),
RTW89_DECL_RFK_WM(0x5800, 0xffffffff, 0x003f807f),
RTW89_DECL_RFK_WM(0x580c, 0x0000007f, 0x40),
RTW89_DECL_RFK_WM(0x580c, 0x0fffff00, 0x00040),
RTW89_DECL_RFK_WM(0x5810, 0xffffffff, 0x59010000),
RTW89_DECL_RFK_WM(0x5814, 0x01ffffff, 0x002d000),
RTW89_DECL_RFK_WM(0x5814, 0xf8000000, 0x00),
RTW89_DECL_RFK_WM(0x5818, 0xffffffff, 0x002c1800),
RTW89_DECL_RFK_WM(0x581c, 0x3fffffff, 0x1dc80280),
RTW89_DECL_RFK_WM(0x5820, 0xffffffff, 0x00002080),
RTW89_DECL_RFK_WM(0x580c, 0x10000000, 0x1),
RTW89_DECL_RFK_WM(0x580c, 0x40000000, 0x1),
RTW89_DECL_RFK_WM(0x5834, 0x3fffffff, 0x000115f2),
RTW89_DECL_RFK_WM(0x5838, 0x7fffffff, 0x0000121),
RTW89_DECL_RFK_WM(0x5854, 0x3fffffff, 0x000115f2),
RTW89_DECL_RFK_WM(0x5858, 0x7fffffff, 0x0000121),
RTW89_DECL_RFK_WM(0x5860, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0x5864, 0x07ffffff, 0x00801ff),
RTW89_DECL_RFK_WM(0x5898, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x589c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x58a4, 0x000000ff, 0x16),
RTW89_DECL_RFK_WM(0x58b0, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x58b4, 0x7fffffff, 0x0a002000),
RTW89_DECL_RFK_WM(0x58b8, 0x7fffffff, 0x00007628),
RTW89_DECL_RFK_WM(0x58bc, 0x07ffffff, 0x7a7807f),
RTW89_DECL_RFK_WM(0x58c0, 0xfffe0000, 0x003f),
RTW89_DECL_RFK_WM(0x58c4, 0xffffffff, 0x0003ffff),
RTW89_DECL_RFK_WM(0x58c8, 0x00ffffff, 0x000000),
RTW89_DECL_RFK_WM(0x58c8, 0xf0000000, 0x0),
RTW89_DECL_RFK_WM(0x58cc, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x58d0, 0x07ffffff, 0x2008101),
RTW89_DECL_RFK_WM(0x58d4, 0x000000ff, 0x00),
RTW89_DECL_RFK_WM(0x58d4, 0x0003fe00, 0x0ff),
RTW89_DECL_RFK_WM(0x58d4, 0x07fc0000, 0x100),
RTW89_DECL_RFK_WM(0x58d8, 0xffffffff, 0x8008016c),
RTW89_DECL_RFK_WM(0x58dc, 0x0001ffff, 0x0807f),
RTW89_DECL_RFK_WM(0x58dc, 0xfff00000, 0x800),
RTW89_DECL_RFK_WM(0x58f0, 0x0003ffff, 0x001ff),
RTW89_DECL_RFK_WM(0x58f4, 0x000fffff, 0x000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_init_txpwr_defs_a);
static const struct rtw89_reg5_def rtw8852b_tssi_init_txpwr_defs_b[] = {
RTW89_DECL_RFK_WM(0x566c, 0x00001000, 0x0),
RTW89_DECL_RFK_WM(0x7800, 0xffffffff, 0x003f807f),
RTW89_DECL_RFK_WM(0x780c, 0x0000007f, 0x40),
RTW89_DECL_RFK_WM(0x780c, 0x0fffff00, 0x00040),
RTW89_DECL_RFK_WM(0x7810, 0xffffffff, 0x59010000),
RTW89_DECL_RFK_WM(0x7814, 0x01ffffff, 0x002d000),
RTW89_DECL_RFK_WM(0x7814, 0xf8000000, 0x00),
RTW89_DECL_RFK_WM(0x7818, 0xffffffff, 0x002c1800),
RTW89_DECL_RFK_WM(0x781c, 0x3fffffff, 0x1dc80280),
RTW89_DECL_RFK_WM(0x7820, 0xffffffff, 0x00002080),
RTW89_DECL_RFK_WM(0x780c, 0x10000000, 0x1),
RTW89_DECL_RFK_WM(0x780c, 0x40000000, 0x1),
RTW89_DECL_RFK_WM(0x7834, 0x3fffffff, 0x000115f2),
RTW89_DECL_RFK_WM(0x7838, 0x7fffffff, 0x0000121),
RTW89_DECL_RFK_WM(0x7854, 0x3fffffff, 0x000115f2),
RTW89_DECL_RFK_WM(0x7858, 0x7fffffff, 0x0000121),
RTW89_DECL_RFK_WM(0x7860, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0x7864, 0x07ffffff, 0x00801ff),
RTW89_DECL_RFK_WM(0x7898, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x789c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x78a4, 0x000000ff, 0x16),
RTW89_DECL_RFK_WM(0x78b0, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x78b4, 0x7fffffff, 0x0a002000),
RTW89_DECL_RFK_WM(0x78b8, 0x7fffffff, 0x00007628),
RTW89_DECL_RFK_WM(0x78bc, 0x07ffffff, 0x7a7807f),
RTW89_DECL_RFK_WM(0x78c0, 0xfffe0000, 0x003f),
RTW89_DECL_RFK_WM(0x78c4, 0xffffffff, 0x0003ffff),
RTW89_DECL_RFK_WM(0x78c8, 0x00ffffff, 0x000000),
RTW89_DECL_RFK_WM(0x78c8, 0xf0000000, 0x0),
RTW89_DECL_RFK_WM(0x78cc, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x78d0, 0x07ffffff, 0x2008101),
RTW89_DECL_RFK_WM(0x78d4, 0x000000ff, 0x00),
RTW89_DECL_RFK_WM(0x78d4, 0x0003fe00, 0x0ff),
RTW89_DECL_RFK_WM(0x78d4, 0x07fc0000, 0x100),
RTW89_DECL_RFK_WM(0x78d8, 0xffffffff, 0x8008016c),
RTW89_DECL_RFK_WM(0x78dc, 0x0001ffff, 0x0807f),
RTW89_DECL_RFK_WM(0x78dc, 0xfff00000, 0x800),
RTW89_DECL_RFK_WM(0x78f0, 0x0003ffff, 0x001ff),
RTW89_DECL_RFK_WM(0x78f4, 0x000fffff, 0x000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_init_txpwr_defs_b);
static const struct rtw89_reg5_def rtw8852b_tssi_init_txpwr_he_tb_defs_a[] = {
RTW89_DECL_RFK_WM(0x58a0, 0xffffffff, 0x000000fe),
RTW89_DECL_RFK_WM(0x58e4, 0x0000007f, 0x1f),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_init_txpwr_he_tb_defs_a);
static const struct rtw89_reg5_def rtw8852b_tssi_init_txpwr_he_tb_defs_b[] = {
RTW89_DECL_RFK_WM(0x78a0, 0xffffffff, 0x000000fe),
RTW89_DECL_RFK_WM(0x78e4, 0x0000007f, 0x1f),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_init_txpwr_he_tb_defs_b);
static const struct rtw89_reg5_def rtw8852b_tssi_dck_defs_a[] = {
RTW89_DECL_RFK_WM(0x580c, 0x0fff0000, 0x000),
RTW89_DECL_RFK_WM(0x5814, 0x003ff000, 0x0ef),
RTW89_DECL_RFK_WM(0x5814, 0x18000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_dck_defs_a);
static const struct rtw89_reg5_def rtw8852b_tssi_dck_defs_b[] = {
RTW89_DECL_RFK_WM(0x780c, 0x0fff0000, 0x000),
RTW89_DECL_RFK_WM(0x7814, 0x003ff000, 0x0ef),
RTW89_DECL_RFK_WM(0x7814, 0x18000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_dck_defs_b);
static const struct rtw89_reg5_def rtw8852b_tssi_dac_gain_defs_a[] = {
RTW89_DECL_RFK_WM(0x58b0, 0x00000400, 0x1),
RTW89_DECL_RFK_WM(0x58b0, 0x00000fff, 0x000),
RTW89_DECL_RFK_WM(0x58b0, 0x00000800, 0x1),
RTW89_DECL_RFK_WM(0x5a00, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a04, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a08, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a0c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a10, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a14, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a18, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a1c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a20, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a24, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a28, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a2c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a30, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a34, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a38, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a3c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a40, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a44, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a48, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a4c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a50, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a54, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a58, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a5c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a60, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a64, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a68, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a6c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a70, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a74, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a78, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a7c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a80, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a84, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a88, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a8c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a90, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a94, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a98, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5a9c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5aa0, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5aa4, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5aa8, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5aac, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5ab0, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5ab4, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5ab8, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5abc, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5ac0, 0xffffffff, 0x00000000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_dac_gain_defs_a);
static const struct rtw89_reg5_def rtw8852b_tssi_dac_gain_defs_b[] = {
RTW89_DECL_RFK_WM(0x78b0, 0x00000fff, 0x000),
RTW89_DECL_RFK_WM(0x78b0, 0x00000800, 0x1),
RTW89_DECL_RFK_WM(0x7a00, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a04, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a08, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a0c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a10, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a14, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a18, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a1c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a20, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a24, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a28, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a2c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a30, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a34, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a38, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a3c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a40, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a44, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a48, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a4c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a50, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a54, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a58, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a5c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a60, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a64, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a68, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a6c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a70, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a74, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a78, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a7c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a80, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a84, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a88, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a8c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a90, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a94, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a98, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7a9c, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7aa0, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7aa4, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7aa8, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7aac, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7ab0, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7ab4, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7ab8, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7abc, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7ac0, 0xffffffff, 0x00000000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_dac_gain_defs_b);
static const struct rtw89_reg5_def rtw8852b_tssi_slope_a_defs_2g[] = {
RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0801008),
RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201020),
RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0804008),
RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x008),
RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808),
RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x08081e28),
RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x08080808),
RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08081e28),
RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x0808),
RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_slope_a_defs_2g);
static const struct rtw89_reg5_def rtw8852b_tssi_slope_a_defs_5g[] = {
RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201020),
RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x008),
RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808),
RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x08081e08),
RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x08080808),
RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08080808),
RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x0808),
RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_slope_a_defs_5g);
static const struct rtw89_reg5_def rtw8852b_tssi_slope_b_defs_2g[] = {
RTW89_DECL_RFK_WM(0x7608, 0x07ffffff, 0x0801008),
RTW89_DECL_RFK_WM(0x760c, 0x07ffffff, 0x0201020),
RTW89_DECL_RFK_WM(0x7610, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x7614, 0x07ffffff, 0x0804008),
RTW89_DECL_RFK_WM(0x7618, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x761c, 0x000001ff, 0x008),
RTW89_DECL_RFK_WM(0x761c, 0xffff0000, 0x0808),
RTW89_DECL_RFK_WM(0x7620, 0xffffffff, 0x08081e28),
RTW89_DECL_RFK_WM(0x7624, 0xffffffff, 0x08080808),
RTW89_DECL_RFK_WM(0x7628, 0xffffffff, 0x08081e28),
RTW89_DECL_RFK_WM(0x762c, 0x0000ffff, 0x0808),
RTW89_DECL_RFK_WM(0x781c, 0x00100000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_slope_b_defs_2g);
static const struct rtw89_reg5_def rtw8852b_tssi_slope_b_defs_5g[] = {
RTW89_DECL_RFK_WM(0x7608, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x760c, 0x07ffffff, 0x0201020),
RTW89_DECL_RFK_WM(0x7610, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x7614, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x7618, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x761c, 0x000001ff, 0x008),
RTW89_DECL_RFK_WM(0x761c, 0xffff0000, 0x0808),
RTW89_DECL_RFK_WM(0x7620, 0xffffffff, 0x08081e08),
RTW89_DECL_RFK_WM(0x7624, 0xffffffff, 0x08080808),
RTW89_DECL_RFK_WM(0x7628, 0xffffffff, 0x08080808),
RTW89_DECL_RFK_WM(0x762c, 0x0000ffff, 0x0808),
RTW89_DECL_RFK_WM(0x781c, 0x00100000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_slope_b_defs_5g);
static const struct rtw89_reg5_def rtw8852b_tssi_align_a_2g_all_defs[] = {
RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x3f2d2721),
RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x010101),
RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01ef27af),
RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000075),
RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000),
RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x017f13ae),
RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x0000006e),
RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_2g_all_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_a_2g_part_defs[] = {
RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01ef27af),
RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000075),
RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x017f13ae),
RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x0000006e),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_2g_part_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g1_all_defs[] = {
RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x3f2d2721),
RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x010101),
RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x016037e7),
RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x0000006f),
RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000),
RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g1_all_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g1_part_defs[] = {
RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x016037e7),
RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x0000006f),
RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g1_part_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g2_all_defs[] = {
RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x3f2d2721),
RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x010101),
RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01f053f1),
RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000070),
RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000),
RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g2_all_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g2_part_defs[] = {
RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01f053f1),
RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000070),
RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g2_part_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g3_all_defs[] = {
RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x3f2d2721),
RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x010101),
RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01c047ee),
RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000070),
RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000),
RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g3_all_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g3_part_defs[] = {
RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01c047ee),
RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000070),
RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g3_part_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_b_2g_all_defs[] = {
RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x3f2d2721),
RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x010101),
RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x01ff2bb5),
RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000078),
RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000),
RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x018f2bb0),
RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000072),
RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_2g_all_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_b_2g_part_defs[] = {
RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x01ff2bb5),
RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000078),
RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x018f2bb0),
RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000072),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_2g_part_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g1_all_defs[] = {
RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x3f2d2721),
RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x010101),
RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x009003da),
RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069),
RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000),
RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g1_all_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g1_part_defs[] = {
RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x009003da),
RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069),
RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g1_part_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g2_all_defs[] = {
RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x3f2d2721),
RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x010101),
RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x013027e6),
RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069),
RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000),
RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g2_all_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g2_part_defs[] = {
RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x013027e6),
RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069),
RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g2_part_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g3_all_defs[] = {
RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x3f2d2721),
RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x010101),
RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x009003da),
RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069),
RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000),
RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g3_all_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g3_part_defs[] = {
RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x009003da),
RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069),
RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g3_part_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_slope_defs_a[] = {
RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x1),
RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x1),
RTW89_DECL_RFK_WM(0x5814, 0x20000000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_slope_defs_a);
static const struct rtw89_reg5_def rtw8852b_tssi_slope_defs_b[] = {
RTW89_DECL_RFK_WM(0x7814, 0x00000800, 0x1),
RTW89_DECL_RFK_WM(0x781c, 0x20000000, 0x1),
RTW89_DECL_RFK_WM(0x7814, 0x20000000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_slope_defs_b);

View file

@ -0,0 +1,62 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#ifndef __RTW89_8852B_RFK_TABLE_H__
#define __RTW89_8852B_RFK_TABLE_H__
#include "phy.h"
extern const struct rtw89_rfk_tbl rtw8852b_afe_init_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_check_addc_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_check_addc_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_check_dadc_en_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_check_dadc_en_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_check_dadc_dis_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_check_dadc_dis_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_dack_s0_1_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_dack_s0_2_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_dack_s0_3_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_dack_s1_1_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_dack_s1_2_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_dack_s1_3_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_dpk_afe_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_dpk_afe_restore_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_dpk_kip_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_sys_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_sys_a_defs_2g_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_sys_a_defs_5g_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_sys_b_defs_2g_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_sys_b_defs_5g_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_init_txpwr_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_init_txpwr_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_init_txpwr_he_tb_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_init_txpwr_he_tb_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_dck_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_dck_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_dac_gain_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_dac_gain_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_a_defs_2g_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_a_defs_5g_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_b_defs_2g_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_b_defs_5g_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_2g_all_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_2g_part_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g1_all_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g1_part_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g2_all_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g2_part_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g3_all_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g3_part_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_2g_all_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_2g_part_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g1_all_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g1_part_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g2_all_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g2_part_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g3_all_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g3_part_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_defs_b_tbl;
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#ifndef __RTW89_8852B_TABLE_H__
#define __RTW89_8852B_TABLE_H__
#include "core.h"
extern const struct rtw89_phy_table rtw89_8852b_phy_bb_table;
extern const struct rtw89_phy_table rtw89_8852b_phy_bb_gain_table;
extern const struct rtw89_phy_table rtw89_8852b_phy_radioa_table;
extern const struct rtw89_phy_table rtw89_8852b_phy_radiob_table;
extern const struct rtw89_phy_table rtw89_8852b_phy_nctl_table;
extern const struct rtw89_txpwr_table rtw89_8852b_byr_table;
extern const struct rtw89_txpwr_track_cfg rtw89_8852b_trk_cfg;
extern const u8 rtw89_8852b_tx_shape[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM]
[RTW89_REGD_NUM];
extern const struct rtw89_rfe_parms rtw89_8852b_dflt_parms;
#endif

View file

@ -0,0 +1,90 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2020-2022 Realtek Corporation
*/
#include <linux/module.h>
#include <linux/pci.h>
#include "pci.h"
#include "reg.h"
#include "rtw8852b.h"
static const struct rtw89_pci_info rtw8852b_pci_info = {
.txbd_trunc_mode = MAC_AX_BD_TRUNC,
.rxbd_trunc_mode = MAC_AX_BD_TRUNC,
.rxbd_mode = MAC_AX_RXBD_PKT,
.tag_mode = MAC_AX_TAG_MULTI,
.tx_burst = MAC_AX_TX_BURST_2048B,
.rx_burst = MAC_AX_RX_BURST_128B,
.wd_dma_idle_intvl = MAC_AX_WD_DMA_INTVL_256NS,
.wd_dma_act_intvl = MAC_AX_WD_DMA_INTVL_256NS,
.multi_tag_num = MAC_AX_TAG_NUM_8,
.lbc_en = MAC_AX_PCIE_ENABLE,
.lbc_tmr = MAC_AX_LBC_TMR_2MS,
.autok_en = MAC_AX_PCIE_DISABLE,
.io_rcy_en = MAC_AX_PCIE_DISABLE,
.io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_6MS,
.init_cfg_reg = R_AX_PCIE_INIT_CFG1,
.txhci_en_bit = B_AX_TXHCI_EN,
.rxhci_en_bit = B_AX_RXHCI_EN,
.rxbd_mode_bit = B_AX_RXBD_MODE,
.exp_ctrl_reg = R_AX_PCIE_EXP_CTRL,
.max_tag_num_mask = B_AX_MAX_TAG_NUM,
.rxbd_rwptr_clr_reg = R_AX_RXBD_RWPTR_CLR,
.txbd_rwptr_clr2_reg = 0,
.dma_stop1 = {R_AX_PCIE_DMA_STOP1, B_AX_TX_STOP1_MASK_V1},
.dma_stop2 = {0},
.dma_busy1 = {R_AX_PCIE_DMA_BUSY1, DMA_BUSY1_CHECK_V1},
.dma_busy2_reg = 0,
.dma_busy3_reg = R_AX_PCIE_DMA_BUSY1,
.rpwm_addr = R_AX_PCIE_HRPWM,
.cpwm_addr = R_AX_CPWM,
.tx_dma_ch_mask = BIT(RTW89_TXCH_ACH4) | BIT(RTW89_TXCH_ACH5) |
BIT(RTW89_TXCH_ACH6) | BIT(RTW89_TXCH_ACH7) |
BIT(RTW89_TXCH_CH10) | BIT(RTW89_TXCH_CH11),
.bd_idx_addr_low_power = NULL,
.dma_addr_set = &rtw89_pci_ch_dma_addr_set,
.bd_ram_table = &rtw89_bd_ram_table_single,
.ltr_set = rtw89_pci_ltr_set,
.fill_txaddr_info = rtw89_pci_fill_txaddr_info,
.config_intr_mask = rtw89_pci_config_intr_mask,
.enable_intr = rtw89_pci_enable_intr,
.disable_intr = rtw89_pci_disable_intr,
.recognize_intrs = rtw89_pci_recognize_intrs,
};
static const struct rtw89_driver_info rtw89_8852be_info = {
.chip = &rtw8852b_chip_info,
.bus = {
.pci = &rtw8852b_pci_info,
},
};
static const struct pci_device_id rtw89_8852be_id_table[] = {
{
PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xb852),
.driver_data = (kernel_ulong_t)&rtw89_8852be_info,
},
{
PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xb85b),
.driver_data = (kernel_ulong_t)&rtw89_8852be_info,
},
{},
};
MODULE_DEVICE_TABLE(pci, rtw89_8852be_id_table);
static struct pci_driver rtw89_8852be_driver = {
.name = "rtw89_8852be",
.id_table = rtw89_8852be_id_table,
.probe = rtw89_pci_probe,
.remove = rtw89_pci_remove,
.driver.pm = &rtw89_pm_ops,
};
module_pci_driver(rtw89_8852be_driver);
MODULE_AUTHOR("Realtek Corporation");
MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852BE driver");
MODULE_LICENSE("Dual BSD/GPL");

View file

@ -13,6 +13,11 @@
#include "rtw8852c_table.h"
#include "util.h"
#define RTW8852C_FW_FORMAT_MAX 0
#define RTW8852C_FW_BASENAME "rtw89/rtw8852c_fw"
#define RTW8852C_MODULE_FIRMWARE \
RTW8852C_FW_BASENAME ".bin"
static const struct rtw89_hfc_ch_cfg rtw8852c_hfc_chcfg_pcie[] = {
{13, 1614, grp_0}, /* ACH 0 */
{13, 1614, grp_0}, /* ACH 1 */
@ -109,6 +114,7 @@ static const struct rtw89_imr_info rtw8852c_imr_info = {
.cpu_disp_imr_set = B_AX_CPU_DISP_IMR_SET_V1,
.other_disp_imr_clr = B_AX_OTHER_DISP_IMR_CLR_V1,
.other_disp_imr_set = B_AX_OTHER_DISP_IMR_SET_V1,
.bbrpt_com_err_imr_reg = R_AX_BBRPT_COM_ERR_IMR,
.bbrpt_chinfo_err_imr_reg = R_AX_BBRPT_CHINFO_ERR_IMR,
.bbrpt_err_imr_set = R_AX_BBRPT_CHINFO_IMR_SET_V1,
.bbrpt_dfs_err_imr_reg = R_AX_BBRPT_DFS_ERR_IMR,
@ -131,7 +137,34 @@ static const struct rtw89_imr_info rtw8852c_imr_info = {
.tmac_imr_set = B_AX_TMAC_IMR_SET_V1,
};
static const struct rtw89_rrsr_cfgs rtw8852c_rrsr_cfgs = {
.ref_rate = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_REF_RATE_SEL, 0},
.rsc = {R_AX_PTCL_RRSR1, B_AX_RSC_MASK, 2},
};
static const struct rtw89_dig_regs rtw8852c_dig_regs = {
.seg0_pd_reg = R_SEG0R_PD,
.pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
.pd_spatial_reuse_en = B_SEG0R_PD_SPATIAL_REUSE_EN_MSK,
.p0_lna_init = {R_PATH0_LNA_INIT_V1, B_PATH0_LNA_INIT_IDX_MSK},
.p1_lna_init = {R_PATH1_LNA_INIT_V1, B_PATH1_LNA_INIT_IDX_MSK},
.p0_tia_init = {R_PATH0_TIA_INIT_V1, B_PATH0_TIA_INIT_IDX_MSK_V1},
.p1_tia_init = {R_PATH1_TIA_INIT_V1, B_PATH1_TIA_INIT_IDX_MSK_V1},
.p0_rxb_init = {R_PATH0_RXB_INIT_V1, B_PATH0_RXB_INIT_IDX_MSK_V1},
.p1_rxb_init = {R_PATH1_RXB_INIT_V1, B_PATH1_RXB_INIT_IDX_MSK_V1},
.p0_p20_pagcugc_en = {R_PATH0_P20_FOLLOW_BY_PAGCUGC_V1,
B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK},
.p0_s20_pagcugc_en = {R_PATH0_S20_FOLLOW_BY_PAGCUGC_V1,
B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK},
.p1_p20_pagcugc_en = {R_PATH1_P20_FOLLOW_BY_PAGCUGC_V1,
B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK},
.p1_s20_pagcugc_en = {R_PATH1_S20_FOLLOW_BY_PAGCUGC_V1,
B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK},
};
static void rtw8852c_ctrl_btg(struct rtw89_dev *rtwdev, bool btg);
static void rtw8852c_ctrl_tx_path_tmac(struct rtw89_dev *rtwdev, u8 tx_path,
enum rtw89_mac_idx mac_idx);
static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
{
@ -245,6 +278,9 @@ static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
B_AX_CMAC_DMA_EN | B_AX_PTCLTOP_EN | B_AX_SCHEDULER_EN |
B_AX_TMAC_EN | B_AX_RMAC_EN);
rtw89_write32_mask(rtwdev, R_AX_LED1_FUNC_SEL, B_AX_PINMUX_EESK_FUNC_SEL_V1_MASK,
PINMUX_EESK_FUNC_SEL_BT_LOG);
return 0;
}
@ -757,40 +793,12 @@ static const struct rtw8852c_bb_gain_op1db bb_gain_op1db_a = {
.mask_tia0_lna6 = 0xff000000,
};
static enum rtw89_phy_bb_gain_band
rtw8852c_mapping_gain_band(enum rtw89_subband subband)
{
switch (subband) {
default:
case RTW89_CH_2G:
return RTW89_BB_GAIN_BAND_2G;
case RTW89_CH_5G_BAND_1:
return RTW89_BB_GAIN_BAND_5G_L;
case RTW89_CH_5G_BAND_3:
return RTW89_BB_GAIN_BAND_5G_M;
case RTW89_CH_5G_BAND_4:
return RTW89_BB_GAIN_BAND_5G_H;
case RTW89_CH_6G_BAND_IDX0:
case RTW89_CH_6G_BAND_IDX1:
return RTW89_BB_GAIN_BAND_6G_L;
case RTW89_CH_6G_BAND_IDX2:
case RTW89_CH_6G_BAND_IDX3:
return RTW89_BB_GAIN_BAND_6G_M;
case RTW89_CH_6G_BAND_IDX4:
case RTW89_CH_6G_BAND_IDX5:
return RTW89_BB_GAIN_BAND_6G_H;
case RTW89_CH_6G_BAND_IDX6:
case RTW89_CH_6G_BAND_IDX7:
return RTW89_BB_GAIN_BAND_6G_UH;
}
}
static void rtw8852c_set_gain_error(struct rtw89_dev *rtwdev,
enum rtw89_subband subband,
enum rtw89_rf_path path)
{
const struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain;
u8 gain_band = rtw8852c_mapping_gain_band(subband);
u8 gain_band = rtw89_subband_to_bb_gain_band(subband);
s32 val;
u32 reg;
u32 mask;
@ -849,76 +857,6 @@ static void rtw8852c_set_gain_error(struct rtw89_dev *rtwdev,
}
}
static
const u8 rtw8852c_ch_base_table[16] = {1, 0xff,
36, 100, 132, 149, 0xff,
1, 33, 65, 97, 129, 161, 193, 225, 0xff};
#define RTW8852C_CH_BASE_IDX_2G 0
#define RTW8852C_CH_BASE_IDX_5G_FIRST 2
#define RTW8852C_CH_BASE_IDX_5G_LAST 5
#define RTW8852C_CH_BASE_IDX_6G_FIRST 7
#define RTW8852C_CH_BASE_IDX_6G_LAST 14
#define RTW8852C_CH_BASE_IDX_MASK GENMASK(7, 4)
#define RTW8852C_CH_OFFSET_MASK GENMASK(3, 0)
static u8 rtw8852c_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band)
{
u8 chan_idx;
u8 last, first;
u8 idx;
switch (band) {
case RTW89_BAND_2G:
chan_idx = FIELD_PREP(RTW8852C_CH_BASE_IDX_MASK, RTW8852C_CH_BASE_IDX_2G) |
FIELD_PREP(RTW8852C_CH_OFFSET_MASK, central_ch);
return chan_idx;
case RTW89_BAND_5G:
first = RTW8852C_CH_BASE_IDX_5G_FIRST;
last = RTW8852C_CH_BASE_IDX_5G_LAST;
break;
case RTW89_BAND_6G:
first = RTW8852C_CH_BASE_IDX_6G_FIRST;
last = RTW8852C_CH_BASE_IDX_6G_LAST;
break;
default:
rtw89_warn(rtwdev, "Unsupported band %d\n", band);
return 0;
}
for (idx = last; idx >= first; idx--)
if (central_ch >= rtw8852c_ch_base_table[idx])
break;
if (idx < first) {
rtw89_warn(rtwdev, "Unknown band %d channel %d\n", band, central_ch);
return 0;
}
chan_idx = FIELD_PREP(RTW8852C_CH_BASE_IDX_MASK, idx) |
FIELD_PREP(RTW8852C_CH_OFFSET_MASK,
(central_ch - rtw8852c_ch_base_table[idx]) >> 1);
return chan_idx;
}
static void rtw8852c_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx,
u8 *ch, enum nl80211_band *band)
{
u8 idx, offset;
idx = FIELD_GET(RTW8852C_CH_BASE_IDX_MASK, chan_idx);
offset = FIELD_GET(RTW8852C_CH_OFFSET_MASK, chan_idx);
if (idx == RTW8852C_CH_BASE_IDX_2G) {
*band = NL80211_BAND_2GHZ;
*ch = offset;
return;
}
*band = idx <= RTW8852C_CH_BASE_IDX_5G_LAST ? NL80211_BAND_5GHZ : NL80211_BAND_6GHZ;
*ch = rtw8852c_ch_base_table[idx] + (offset << 1);
}
static void rtw8852c_set_gain_offset(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx,
@ -948,21 +886,7 @@ static void rtw8852c_set_gain_offset(struct rtw89_dev *rtwdev,
rtw89_phy_write32_mask(rtwdev, R_RPL_OFST, B_RPL_OFST_MASK, tmp & 0x7f);
}
switch (chan->subband_type) {
default:
case RTW89_CH_2G:
gain_band = RTW89_GAIN_OFFSET_2G_OFDM;
break;
case RTW89_CH_5G_BAND_1:
gain_band = RTW89_GAIN_OFFSET_5G_LOW;
break;
case RTW89_CH_5G_BAND_3:
gain_band = RTW89_GAIN_OFFSET_5G_MID;
break;
case RTW89_CH_5G_BAND_4:
gain_band = RTW89_GAIN_OFFSET_5G_HIGH;
break;
}
gain_band = rtw89_subband_to_gain_offset_band_of_ofdm(chan->subband_type);
offset_q0 = -efuse_gain->offset[path][gain_band];
offset_base_q4 = efuse_gain->offset_base[phy_idx];
@ -1095,7 +1019,7 @@ static void rtw8852c_ctrl_ch(struct rtw89_dev *rtwdev,
}
}
chan_idx = rtw8852c_encode_chan_idx(rtwdev, chan->primary_channel, band);
chan_idx = rtw89_encode_chan_idx(rtwdev, chan->primary_channel, band);
rtw89_phy_write32_idx(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, chan_idx, phy_idx);
}
@ -1456,18 +1380,19 @@ static void rtw8852c_5m_mask(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
u8 pri_ch = chan->primary_channel;
u8 pri_ch = chan->pri_ch_idx;
bool mask_5m_low;
bool mask_5m_en;
switch (chan->band_width) {
case RTW89_CHANNEL_WIDTH_40:
mask_5m_en = true;
mask_5m_low = pri_ch == 2;
mask_5m_low = pri_ch == RTW89_SC_20_LOWER;
break;
case RTW89_CHANNEL_WIDTH_80:
mask_5m_en = ((pri_ch == 3) || (pri_ch == 4));
mask_5m_low = pri_ch == 4;
mask_5m_en = pri_ch == RTW89_SC_20_UPMOST ||
pri_ch == RTW89_SC_20_LOWEST;
mask_5m_low = pri_ch == RTW89_SC_20_LOWEST;
break;
default:
mask_5m_en = false;
@ -1694,11 +1619,13 @@ static void rtw8852c_set_channel_bb(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
static const u32 ru_alloc_msk[2] = {B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY0,
B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY1};
struct rtw89_hal *hal = &rtwdev->hal;
bool cck_en = chan->band_type == RTW89_BAND_2G;
u8 pri_ch_idx = chan->pri_ch_idx;
u32 mask, reg;
u32 ru_alloc_msk[2] = {B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY0,
B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY1};
u8 ntx_path;
if (chan->band_type == RTW89_BAND_2G)
rtw8852c_ctrl_sco_cck(rtwdev, chan->channel,
@ -1771,6 +1698,18 @@ static void rtw8852c_set_channel_bb(struct rtw89_dev *rtwdev,
}
}
if (chan->band_type == RTW89_BAND_6G)
rtw89_phy_write32_set(rtwdev, R_MUIC, B_MUIC_EN);
else
rtw89_phy_write32_clr(rtwdev, R_MUIC, B_MUIC_EN);
if (hal->antenna_tx)
ntx_path = hal->antenna_tx;
else
ntx_path = chan->band_type == RTW89_BAND_6G ? RF_B : RF_AB;
rtw8852c_ctrl_tx_path_tmac(rtwdev, ntx_path, (enum rtw89_mac_idx)phy_idx);
rtw8852c_bb_reset_all(rtwdev, phy_idx);
}
@ -1829,11 +1768,11 @@ static void rtw8852c_set_channel_help(struct rtw89_dev *rtwdev, bool enter,
static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev)
{
struct rtw89_mcc_info *mcc_info = &rtwdev->mcc;
struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
rtwdev->is_tssi_mode[RF_PATH_A] = false;
rtwdev->is_tssi_mode[RF_PATH_B] = false;
memset(mcc_info, 0, sizeof(*mcc_info));
memset(rfk_mcc, 0, sizeof(*rfk_mcc));
rtw8852c_lck_init(rtwdev);
rtw8852c_rck(rtwdev);
@ -1964,76 +1903,8 @@ static void rtw8852c_set_txpwr_ref(struct rtw89_dev *rtwdev,
phy_idx);
}
static void rtw8852c_set_txpwr_byrate(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
u8 band = chan->band_type;
u8 ch = chan->channel;
static const u8 rs[] = {
RTW89_RS_CCK,
RTW89_RS_OFDM,
RTW89_RS_MCS,
RTW89_RS_HEDCM,
};
s8 tmp;
u8 i, j;
u32 val, shf, addr = R_AX_PWR_BY_RATE;
struct rtw89_rate_desc cur;
rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
"[TXPWR] set txpwr byrate with ch=%d\n", ch);
for (cur.nss = 0; cur.nss <= RTW89_NSS_2; cur.nss++) {
for (i = 0; i < ARRAY_SIZE(rs); i++) {
if (cur.nss >= rtw89_rs_nss_max[rs[i]])
continue;
val = 0;
cur.rs = rs[i];
for (j = 0; j < rtw89_rs_idx_max[rs[i]]; j++) {
cur.idx = j;
shf = (j % 4) * 8;
tmp = rtw89_phy_read_txpwr_byrate(rtwdev, band,
&cur);
val |= (tmp << shf);
if ((j + 1) % 4)
continue;
rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val);
val = 0;
addr += 4;
}
}
}
}
static void rtw8852c_set_txpwr_offset(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
u8 band = chan->band_type;
struct rtw89_rate_desc desc = {
.nss = RTW89_NSS_1,
.rs = RTW89_RS_OFFSET,
};
u32 val = 0;
s8 v;
rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr offset\n");
for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_MAX; desc.idx++) {
v = rtw89_phy_read_txpwr_byrate(rtwdev, band, &desc);
val |= ((v & 0xf) << (4 * desc.idx));
}
rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_OFST_CTRL,
GENMASK(19, 0), val);
}
static void rtw8852c_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
u8 tx_shape_idx,
enum rtw89_phy_idx phy_idx)
{
@ -2063,7 +1934,6 @@ static void rtw8852c_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev,
__DECL_DFIR_ADDR(filter,
0x45BC, 0x45CC, 0x45D0, 0x45D4, 0x45D8, 0x45C0,
0x45C4, 0x45C8);
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 ch = chan->channel;
const u32 *param;
int i;
@ -2104,90 +1974,22 @@ static void rtw8852c_set_tx_shape(struct rtw89_dev *rtwdev,
u8 tx_shape_ofdm = rtw89_8852c_tx_shape[band][RTW89_RS_OFDM][regd];
if (band == RTW89_BAND_2G)
rtw8852c_bb_set_tx_shape_dfir(rtwdev, tx_shape_cck, phy_idx);
rtw8852c_bb_set_tx_shape_dfir(rtwdev, chan, tx_shape_cck, phy_idx);
rtw89_phy_tssi_ctrl_set_bandedge_cfg(rtwdev,
(enum rtw89_mac_idx)phy_idx,
tx_shape_ofdm);
}
static void rtw8852c_set_txpwr_limit(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
#define __MAC_TXPWR_LMT_PAGE_SIZE 40
u8 ch = chan->channel;
u8 bw = chan->band_width;
struct rtw89_txpwr_limit lmt[NTX_NUM_8852C];
u32 addr, val;
const s8 *ptr;
u8 i, j;
rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
"[TXPWR] set txpwr limit with ch=%d bw=%d\n", ch, bw);
for (i = 0; i < NTX_NUM_8852C; i++) {
rtw89_phy_fill_txpwr_limit(rtwdev, chan, &lmt[i], i);
for (j = 0; j < __MAC_TXPWR_LMT_PAGE_SIZE; j += 4) {
addr = R_AX_PWR_LMT + j + __MAC_TXPWR_LMT_PAGE_SIZE * i;
ptr = (s8 *)&lmt[i] + j;
val = FIELD_PREP(GENMASK(7, 0), ptr[0]) |
FIELD_PREP(GENMASK(15, 8), ptr[1]) |
FIELD_PREP(GENMASK(23, 16), ptr[2]) |
FIELD_PREP(GENMASK(31, 24), ptr[3]);
rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val);
}
}
#undef __MAC_TXPWR_LMT_PAGE_SIZE
}
static void rtw8852c_set_txpwr_limit_ru(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
#define __MAC_TXPWR_LMT_RU_PAGE_SIZE 24
u8 ch = chan->channel;
u8 bw = chan->band_width;
struct rtw89_txpwr_limit_ru lmt_ru[NTX_NUM_8852C];
u32 addr, val;
const s8 *ptr;
u8 i, j;
rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
"[TXPWR] set txpwr limit ru with ch=%d bw=%d\n", ch, bw);
for (i = 0; i < NTX_NUM_8852C; i++) {
rtw89_phy_fill_txpwr_limit_ru(rtwdev, chan, &lmt_ru[i], i);
for (j = 0; j < __MAC_TXPWR_LMT_RU_PAGE_SIZE; j += 4) {
addr = R_AX_PWR_RU_LMT + j +
__MAC_TXPWR_LMT_RU_PAGE_SIZE * i;
ptr = (s8 *)&lmt_ru[i] + j;
val = FIELD_PREP(GENMASK(7, 0), ptr[0]) |
FIELD_PREP(GENMASK(15, 8), ptr[1]) |
FIELD_PREP(GENMASK(23, 16), ptr[2]) |
FIELD_PREP(GENMASK(31, 24), ptr[3]);
rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val);
}
}
#undef __MAC_TXPWR_LMT_RU_PAGE_SIZE
}
static void rtw8852c_set_txpwr(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
rtw8852c_set_txpwr_byrate(rtwdev, chan, phy_idx);
rtw8852c_set_txpwr_offset(rtwdev, chan, phy_idx);
rtw89_phy_set_txpwr_byrate(rtwdev, chan, phy_idx);
rtw89_phy_set_txpwr_offset(rtwdev, chan, phy_idx);
rtw8852c_set_tx_shape(rtwdev, chan, phy_idx);
rtw8852c_set_txpwr_limit(rtwdev, chan, phy_idx);
rtw8852c_set_txpwr_limit_ru(rtwdev, chan, phy_idx);
rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx);
rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx);
}
static void rtw8852c_set_txpwr_ctrl(struct rtw89_dev *rtwdev,
@ -2486,7 +2288,6 @@ static void rtw8852c_bb_ctrl_btc_preagc(struct rtw89_dev *rtwdev, bool bt_en)
static void rtw8852c_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
{
struct rtw89_hal *hal = &rtwdev->hal;
u8 ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_AB;
rtw8852c_bb_cfg_rx_path(rtwdev, RF_PATH_AB);
@ -2501,8 +2302,6 @@ static void rtw8852c_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 1);
rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 1);
}
rtw8852c_ctrl_tx_path_tmac(rtwdev, ntx_path, RTW89_MAC_0);
}
static u8 rtw8852c_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path)
@ -2740,7 +2539,8 @@ do { \
static
s8 rtw8852c_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val)
{
return clamp_t(s8, val, -100, 0) + 100;
/* +6 for compensate offset */
return clamp_t(s8, val + 6, -100, 0) + 100;
}
static const struct rtw89_btc_rf_trx_para rtw89_btc_8852c_rf_ul[] = {
@ -2749,7 +2549,7 @@ static const struct rtw89_btc_rf_trx_para rtw89_btc_8852c_rf_ul[] = {
{255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
{255, 0, 0, 7}, /* 3- >reserved for shared-antenna */
{255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */
{255, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */
{255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */
{6, 1, 0, 7},
{13, 1, 0, 7},
{13, 1, 0, 7}
@ -2761,7 +2561,7 @@ static const struct rtw89_btc_rf_trx_para rtw89_btc_8852c_rf_dl[] = {
{255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
{255, 0, 0, 7}, /* 3- >reserved for shared-antenna */
{255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */
{255, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */
{255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */
{255, 1, 0, 7},
{255, 1, 0, 7},
{255, 1, 0, 7}
@ -2783,21 +2583,11 @@ static const struct rtw89_btc_fbtc_mreg rtw89_btc_8852c_mon_reg[] = {
RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd200),
RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd220),
RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980),
RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4aa4),
RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4778),
RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x476c),
};
static
void rtw8852c_btc_bt_aci_imp(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_bt_info *bt = &btc->cx.bt;
struct rtw89_btc_bt_link_info *b = &bt->link_info;
/* fix LNA2 = level-5 for BT ACI issue at BTG */
if (btc->dm.wl_btg_rx && b->profile_cnt.now != 0)
dm->trx_para_level = 1;
}
static
void rtw8852c_btc_update_bt_cnt(struct rtw89_dev *rtwdev)
{
@ -2822,6 +2612,64 @@ void rtw8852c_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state)
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0);
}
static void rtw8852c_set_wl_lna2(struct rtw89_dev *rtwdev, u8 level)
{
/* level=0 Default: TIA 1/0= (LNA2,TIAN6) = (7,1)/(5,1) = 21dB/12dB
* level=1 Fix LNA2=5: TIA 1/0= (LNA2,TIAN6) = (5,0)/(5,1) = 18dB/12dB
* To improve BT ACI in co-rx
*/
switch (level) {
case 0: /* default */
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x1000);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x0);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x17);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x2);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x3);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x17);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0);
break;
case 1: /* Fix LNA2=5 */
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x1000);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x0);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x5);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x2);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x3);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x5);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0);
break;
}
}
static void rtw8852c_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level)
{
struct rtw89_btc *btc = &rtwdev->btc;
switch (level) {
case 0: /* original */
default:
rtw8852c_bb_ctrl_btc_preagc(rtwdev, false);
btc->dm.wl_lna2 = 0;
break;
case 1: /* for FDD free-run */
rtw8852c_bb_ctrl_btc_preagc(rtwdev, true);
btc->dm.wl_lna2 = 0;
break;
case 2: /* for BTG Co-Rx*/
rtw8852c_bb_ctrl_btc_preagc(rtwdev, false);
btc->dm.wl_lna2 = 1;
break;
}
rtw8852c_set_wl_lna2(rtwdev, btc->dm.wl_lna2);
}
static void rtw8852c_fill_freq_with_ppdu(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu,
struct ieee80211_rx_status *status)
@ -2833,7 +2681,7 @@ static void rtw8852c_fill_freq_with_ppdu(struct rtw89_dev *rtwdev,
if (chan_idx == 0)
return;
rtw8852c_decode_chan_idx(rtwdev, chan_idx, &ch, &band);
rtw89_decode_chan_idx(rtwdev, chan_idx, &ch, &band);
status->freq = ieee80211_channel_to_frequency(ch, band);
status->band = band;
}
@ -2843,12 +2691,12 @@ static void rtw8852c_query_ppdu(struct rtw89_dev *rtwdev,
struct ieee80211_rx_status *status)
{
u8 path;
s8 *rx_power = phy_ppdu->rssi;
u8 *rx_power = phy_ppdu->rssi;
status->signal = max_t(s8, rx_power[RF_PATH_A], rx_power[RF_PATH_B]);
status->signal = RTW89_RSSI_RAW_TO_DBM(max(rx_power[RF_PATH_A], rx_power[RF_PATH_B]));
for (path = 0; path < rtwdev->chip->rf_path_num; path++) {
status->chains |= BIT(path);
status->chain_signal[path] = rx_power[path];
status->chain_signal[path] = RTW89_RSSI_RAW_TO_DBM(rx_power[path]);
}
if (phy_ppdu->valid)
rtw8852c_fill_freq_with_ppdu(rtwdev, phy_ppdu, status);
@ -2891,12 +2739,23 @@ static int rtw8852c_mac_enable_bb_rf(struct rtw89_dev *rtwdev)
return 0;
}
static void rtw8852c_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
static int rtw8852c_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
{
rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN,
B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
return 0;
}
#ifdef CONFIG_PM
static const struct wiphy_wowlan_support rtw_wowlan_stub_8852c = {
.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
.n_patterns = RTW89_MAX_PATTERN_NUM,
.pattern_max_len = RTW89_MAX_PATTERN_SIZE,
.pattern_min_len = 1,
};
#endif
static const struct rtw89_chip_ops rtw8852c_chip_ops = {
.enable_bb_rf = rtw8852c_mac_enable_bb_rf,
.disable_bb_rf = rtw8852c_mac_disable_bb_rf,
@ -2909,6 +2768,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = {
.read_efuse = rtw8852c_read_efuse,
.read_phycap = rtw8852c_read_phycap,
.fem_setup = NULL,
.rfe_gpio = NULL,
.rfk_init = rtw8852c_rfk_init,
.rfk_channel = rtw8852c_rfk_channel,
.rfk_band_changed = rtw8852c_rfk_band_changed,
@ -2926,6 +2786,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = {
.set_txpwr_ul_tb_offset = rtw8852c_set_txpwr_ul_tb_offset,
.pwr_on_func = rtw8852c_pwr_on_func,
.pwr_off_func = rtw8852c_pwr_off_func,
.query_rxdesc = rtw89_core_query_rxdesc,
.fill_txdesc = rtw89_core_fill_txdesc_v1,
.fill_txdesc_fwcmd = rtw89_core_fill_txdesc_fwcmd_v1,
.cfg_ctrl_path = rtw89_mac_cfg_ctrl_path_v1,
@ -2939,22 +2800,30 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = {
.btc_set_wl_pri = rtw8852c_btc_set_wl_pri,
.btc_set_wl_txpwr_ctrl = rtw8852c_btc_set_wl_txpwr_ctrl,
.btc_get_bt_rssi = rtw8852c_btc_get_bt_rssi,
.btc_bt_aci_imp = rtw8852c_btc_bt_aci_imp,
.btc_update_bt_cnt = rtw8852c_btc_update_bt_cnt,
.btc_wl_s1_standby = rtw8852c_btc_wl_s1_standby,
.btc_set_wl_rx_gain = rtw8852c_btc_set_wl_rx_gain,
.btc_set_policy = rtw89_btc_set_policy_v1,
};
const struct rtw89_chip_info rtw8852c_chip_info = {
.chip_id = RTL8852C,
.chip_gen = RTW89_CHIP_AX,
.ops = &rtw8852c_chip_ops,
.fw_name = "rtw89/rtw8852c_fw.bin",
.fw_basename = RTW8852C_FW_BASENAME,
.fw_format_max = RTW8852C_FW_FORMAT_MAX,
.try_ce_fw = false,
.needed_fw_elms = 0,
.fifo_size = 458752,
.small_fifo_size = false,
.dle_scc_rsvd_size = 0,
.max_amsdu_limit = 8000,
.dis_2g_40m_ul_ofdma = false,
.rsvd_ple_ofst = 0x6f800,
.hfc_param_ini = rtw8852c_hfc_param_ini_pcie,
.dle_mem = rtw8852c_dle_mem_pcie,
.wde_qempty_acq_num = 16,
.wde_qempty_mgq_sel = 16,
.rf_base_addr = {0xe000, 0xf000},
.pwr_on_seq = NULL,
.pwr_off_seq = NULL,
@ -2963,22 +2832,22 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.rf_table = {&rtw89_8852c_phy_radiob_table,
&rtw89_8852c_phy_radioa_table,},
.nctl_table = &rtw89_8852c_phy_nctl_table,
.nctl_post_table = NULL,
.byr_table = &rtw89_8852c_byr_table,
.txpwr_lmt_2g = &rtw89_8852c_txpwr_lmt_2g,
.txpwr_lmt_5g = &rtw89_8852c_txpwr_lmt_5g,
.txpwr_lmt_6g = &rtw89_8852c_txpwr_lmt_6g,
.txpwr_lmt_ru_2g = &rtw89_8852c_txpwr_lmt_ru_2g,
.txpwr_lmt_ru_5g = &rtw89_8852c_txpwr_lmt_ru_5g,
.txpwr_lmt_ru_6g = &rtw89_8852c_txpwr_lmt_ru_6g,
.dflt_parms = &rtw89_8852c_dflt_parms,
.rfe_parms_conf = NULL,
.txpwr_factor_rf = 2,
.txpwr_factor_mac = 1,
.dig_table = NULL,
.dig_regs = &rtw8852c_dig_regs,
.tssi_dbw_table = &rtw89_8852c_tssi_dbw_table,
.support_chanctx_num = 1,
.support_bands = BIT(NL80211_BAND_2GHZ) |
BIT(NL80211_BAND_5GHZ) |
BIT(NL80211_BAND_6GHZ),
.support_bw160 = true,
.support_unii4 = true,
.support_ul_tb_ctrl = false,
.hw_sec_hdr = true,
.rf_path_num = 2,
.tx_nss = 2,
@ -2988,7 +2857,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.scam_num = 128,
.bacam_num = 8,
.bacam_dynamic_num = 8,
.bacam_v1 = true,
.bacam_ver = RTW89_BACAM_V0_EXT,
.sec_ctrl_efuse_size = 4,
.physical_efuse_size = 1216,
.logical_efuse_size = 2048,
@ -2997,25 +2866,12 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.dav_log_efuse_size = 16,
.phycap_addr = 0x590,
.phycap_size = 0x60,
.para_ver = 0x05050764,
.wlcx_desired = 0x05050000,
.btcx_desired = 0x5,
.para_ver = 0x1,
.wlcx_desired = 0x06000000,
.btcx_desired = 0x7,
.scbd = 0x1,
.mailbox = 0x1,
.fcxbtcrpt_ver = 4,
.fcxtdma_ver = 3,
.fcxslots_ver = 1,
.fcxcysta_ver = 3,
.fcxstep_ver = 3,
.fcxnullsta_ver = 2,
.fcxmreg_ver = 1,
.fcxgpiodbg_ver = 1,
.fcxbtver_ver = 1,
.fcxbtscan_ver = 1,
.fcxbtafh_ver = 1,
.fcxbtdevinfo_ver = 1,
.afh_guard_ch = 6,
.wl_rssi_thres = rtw89_btc_8852c_wl_rssi_thres,
.bt_rssi_thres = rtw89_btc_8852c_bt_rssi_thres,
@ -3026,7 +2882,9 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.rf_para_ulink = rtw89_btc_8852c_rf_ul,
.rf_para_dlink_num = ARRAY_SIZE(rtw89_btc_8852c_rf_dl),
.rf_para_dlink = rtw89_btc_8852c_rf_dl,
.ps_mode_supported = 0,
.ps_mode_supported = BIT(RTW89_PS_MODE_RFOFF) |
BIT(RTW89_PS_MODE_CLK_GATED) |
BIT(RTW89_PS_MODE_PWR_GATED),
.low_power_hci_modes = BIT(RTW89_PS_MODE_CLK_GATED) |
BIT(RTW89_PS_MODE_PWR_GATED),
.h2c_cctl_func_id = H2C_FUNC_MAC_CCTLINFO_UD_V1,
@ -3034,17 +2892,29 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.h2c_desc_size = sizeof(struct rtw89_rxdesc_short),
.txwd_body_size = sizeof(struct rtw89_txwd_body_v1),
.h2c_ctrl_reg = R_AX_H2CREG_CTRL_V1,
.h2c_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8},
.h2c_regs = rtw8852c_h2c_regs,
.c2h_ctrl_reg = R_AX_C2HREG_CTRL_V1,
.c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8},
.c2h_regs = rtw8852c_c2h_regs,
.page_regs = &rtw8852c_page_regs,
.cfo_src_fd = false,
.cfo_hw_comp = false,
.dcfo_comp = &rtw8852c_dcfo_comp,
.dcfo_comp_sft = 5,
.imr_info = &rtw8852c_imr_info
.dcfo_comp_sft = 12,
.imr_info = &rtw8852c_imr_info,
.rrsr_cfgs = &rtw8852c_rrsr_cfgs,
.bss_clr_map_reg = R_BSS_CLR_MAP,
.dma_ch_mask = 0,
.edcca_lvl_reg = R_SEG0R_EDCCA_LVL,
#ifdef CONFIG_PM
.wowlan_stub = &rtw_wowlan_stub_8852c,
#endif
.xtal_info = NULL,
};
EXPORT_SYMBOL(rtw8852c_chip_info);
MODULE_FIRMWARE("rtw89/rtw8852c_fw.bin");
MODULE_FIRMWARE(RTW8852C_MODULE_FIRMWARE);
MODULE_AUTHOR("Realtek Corporation");
MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852C driver");
MODULE_LICENSE("Dual BSD/GPL");

View file

@ -9,7 +9,6 @@
#define RF_PATH_NUM_8852C 2
#define BB_PATH_NUM_8852C 2
#define NTX_NUM_8852C 2
struct rtw8852c_u_efuse {
u8 rsvd[0x38];

View file

@ -11,6 +11,15 @@
#include "rtw8852c_rfk_table.h"
#include "rtw8852c_table.h"
struct rxck_def {
u32 ctl;
u32 en;
u32 bw0;
u32 bw1;
u32 mul;
u32 lp;
};
#define _TSSI_DE_MASK GENMASK(21, 12)
static const u32 _tssi_de_cck_long[RF_PATH_NUM_8852C] = {0x5858, 0x7858};
static const u32 _tssi_de_cck_short[RF_PATH_NUM_8852C] = {0x5860, 0x7860};
@ -22,12 +31,11 @@ static const u32 _tssi_de_mcs_5m[RF_PATH_NUM_8852C] = {0x5828, 0x7828};
static const u32 _tssi_de_mcs_10m[RF_PATH_NUM_8852C] = {0x5830, 0x7830};
static const u32 rtw8852c_backup_bb_regs[] = {
0x813c, 0x8124, 0x8120, 0xc0d4, 0xc0d8, 0xc0e8, 0x823c, 0x8224, 0x8220,
0xc1d4, 0xc1d8, 0xc1e8
0x8120, 0xc0d4, 0xc0d8, 0xc0e8, 0x8220, 0xc1d4, 0xc1d8, 0xc1e8
};
static const u32 rtw8852c_backup_rf_regs[] = {
0xdf, 0x8f, 0x97, 0xa3, 0x5, 0x10005
0xdf, 0x5f, 0x8f, 0x97, 0xa3, 0x5, 0x10005
};
#define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8852c_backup_bb_regs)
@ -60,6 +68,13 @@ static const u32 dpk_par_regs[RTW89_DPK_RF_PATH][4] = {
{0x81a8, 0x81c4, 0x81c8, 0x81e8},
};
static const u8 _dck_addr_bs[RF_PATH_NUM_8852C] = {0x0, 0x10};
static const u8 _dck_addr[RF_PATH_NUM_8852C] = {0xc, 0x1c};
static const struct rxck_def _ck480M = {0x8, 0x2, 0x3, 0xf, 0x0, 0x9};
static const struct rxck_def _ck960M = {0x8, 0x2, 0x2, 0x8, 0x0, 0x9};
static const struct rxck_def _ck1920M = {0x8, 0x0, 0x2, 0x4, 0x6, 0x9};
static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
{
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]dbcc_en: %x, PHY%d\n",
@ -338,7 +353,7 @@ static void _dack_reload_by_path(struct rtw89_dev *rtwdev,
(dack->dadck_d[path][index] << 14);
addr = 0xc210 + offset;
rtw89_phy_write32(rtwdev, addr, val32);
rtw89_phy_write32_set(rtwdev, addr, BIT(1));
rtw89_phy_write32_set(rtwdev, addr, BIT(0));
}
static void _dack_reload(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
@ -438,6 +453,8 @@ static void rtw8852c_txck_force(struct rtw89_dev *rtwdev, u8 path, bool force,
static void rtw8852c_rxck_force(struct rtw89_dev *rtwdev, u8 path, bool force,
enum adc_ck ck)
{
const struct rxck_def *def;
rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, 0x0);
if (!force)
@ -445,6 +462,26 @@ static void rtw8852c_rxck_force(struct rtw89_dev *rtwdev, u8 path, bool force,
rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_VAL, ck);
rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, 0x1);
switch (ck) {
case ADC_480M:
def = &_ck480M;
break;
case ADC_960M:
def = &_ck960M;
break;
case ADC_1920M:
default:
def = &_ck1920M;
break;
}
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_CTL, def->ctl);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_EN, def->en);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, def->bw0);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, def->bw1);
rtw89_phy_write32_mask(rtwdev, R_DRCK | (path << 8), B_DRCK_MUL, def->mul);
rtw89_phy_write32_mask(rtwdev, R_ADCMOD | (path << 8), B_ADCMOD_LP, def->lp);
}
static bool _check_dack_done(struct rtw89_dev *rtwdev, bool s0)
@ -628,8 +665,6 @@ static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path)
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_DPD_GDIS, 0x1);
rtw8852c_rxck_force(rtwdev, path, true, ADC_480M);
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_ACK_VAL, 0x0);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 + (path << 8), B_P0_CFCH_BW0, 0x3);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 + (path << 8), B_P0_CFCH_BW1, 0xf);
rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_CKT, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, 0x1);
break;
@ -637,8 +672,6 @@ static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path)
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_DPD_GDIS, 0x1);
rtw8852c_rxck_force(rtwdev, path, true, ADC_960M);
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_ACK_VAL, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 + (path << 8), B_P0_CFCH_BW0, 0x2);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 + (path << 8), B_P0_CFCH_BW1, 0xd);
rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_CKT, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, 0x1);
break;
@ -646,8 +679,6 @@ static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path)
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_DPD_GDIS, 0x1);
rtw8852c_rxck_force(rtwdev, path, true, ADC_1920M);
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_ACK_VAL, 0x2);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 + (path << 8), B_P0_CFCH_BW0, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 + (path << 8), B_P0_CFCH_BW1, 0xb);
rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_CKT, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, 0x1);
break;
@ -1031,9 +1062,9 @@ static bool _iqk_nbtxk(struct rtw89_dev *rtwdev,
static bool _lok_finetune_check(struct rtw89_dev *rtwdev, u8 path)
{
struct rtw89_mcc_info *mcc_info = &rtwdev->mcc;
struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
u8 idx = mcc_info->table_idx;
u8 idx = rfk_mcc->table_idx;
bool is_fail1, is_fail2;
u32 val;
u32 core_i;
@ -1230,11 +1261,8 @@ static void _iqk_info_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
u32 tmp;
bool flag;
iqk_info->thermal[path] =
ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]);
iqk_info->thermal_rek_en = false;
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_thermal = %d\n", path,
iqk_info->thermal[path]);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_thermal = %lu\n", path,
ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]));
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_LOK_COR_fail= %d\n", path,
iqk_info->lok_cor_fail[0][path]);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_LOK_FIN_fail= %d\n", path,
@ -1376,10 +1404,10 @@ static void _iqk_afebb_restore(struct rtw89_dev *rtwdev,
static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path)
{
struct rtw89_mcc_info *mcc_info = &rtwdev->mcc;
struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
u8 idx = 0;
idx = mcc_info->table_idx;
idx = rfk_mcc->table_idx;
rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), B_COEF_SEL_IQC, idx);
rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3, idx);
rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0);
@ -1411,8 +1439,6 @@ static void _iqk_macbb_setting(struct rtw89_dev *rtwdev,
rtw8852c_rxck_force(rtwdev, path, true, ADC_1920M);
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK | (path << 13), B_ACK_VAL, 0x2);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, 0xb);
rtw89_phy_write32_mask(rtwdev, R_P0_NRBW | (path << 13), B_P0_NRBW_DBG, 0x1);
rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x1f);
rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x13);
@ -1473,7 +1499,6 @@ static void _iqk_init(struct rtw89_dev *rtwdev)
iqk_info->iqk_sram_en = false;
iqk_info->iqk_cfir_en = false;
iqk_info->iqk_xym_en = false;
iqk_info->thermal_rek_en = false;
iqk_info->iqk_times = 0x0;
for (ch = 0; ch < RTW89_IQK_CHS_NR; ch++) {
@ -1500,9 +1525,8 @@ static void _doiqk(struct rtw89_dev *rtwdev, bool force,
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[IQK]==========IQK strat!!!!!==========\n");
"[IQK]==========IQK start!!!!!==========\n");
iqk_info->iqk_times++;
iqk_info->kcount = 0;
iqk_info->version = RTW8852C_IQK_VER;
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version);
@ -1537,6 +1561,155 @@ static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool forc
}
}
static void _rx_dck_value_rewrite(struct rtw89_dev *rtwdev, u8 path, u8 addr,
u8 val_i, u8 val_q)
{
u32 ofst_val;
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] rewrite val_i = 0x%x, val_q = 0x%x\n", val_i, val_q);
/* val_i and val_q are 7 bits, and target is 6 bits. */
ofst_val = u32_encode_bits(val_q >> 1, RR_LUTWD0_MB) |
u32_encode_bits(val_i >> 1, RR_LUTWD0_LB);
rtw89_write_rf(rtwdev, path, RR_LUTPLL, RR_CAL_RW, 0x1);
rtw89_write_rf(rtwdev, path, RR_RFC, RR_WCAL, 0x1);
rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, 0x1);
rtw89_write_rf(rtwdev, path, RR_LUTWA, MASKBYTE0, addr);
rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, ofst_val);
rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, ofst_val);
rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, 0x0);
rtw89_write_rf(rtwdev, path, RR_RFC, RR_WCAL, 0x0);
rtw89_write_rf(rtwdev, path, RR_LUTPLL, RR_CAL_RW, 0x0);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] Final val_i = 0x%x, val_q = 0x%x\n",
u32_get_bits(ofst_val, RR_LUTWD0_LB) << 1,
u32_get_bits(ofst_val, RR_LUTWD0_MB) << 1);
}
static bool _rx_dck_rek_check(struct rtw89_dev *rtwdev, u8 path)
{
u8 i_even_bs, q_even_bs;
u8 i_odd_bs, q_odd_bs;
u8 i_even, q_even;
u8 i_odd, q_odd;
const u8 th = 10;
u8 i;
for (i = 0; i < RF_PATH_NUM_8852C; i++) {
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr_bs[i]);
i_even_bs = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA);
q_even_bs = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] Gain[0x%x] i_even_bs/ q_even_bs = 0x%x/ 0x%x\n",
_dck_addr_bs[i], i_even_bs, q_even_bs);
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr[i]);
i_even = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA);
q_even = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] Gain[0x%x] i_even/ q_even = 0x%x/ 0x%x\n",
_dck_addr[i], i_even, q_even);
if (abs(i_even_bs - i_even) > th || abs(q_even_bs - q_even) > th)
return true;
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr_bs[i] + 1);
i_odd_bs = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA);
q_odd_bs = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] Gain[0x%x] i_odd_bs/ q_odd_bs = 0x%x/ 0x%x\n",
_dck_addr_bs[i] + 1, i_odd_bs, q_odd_bs);
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr[i] + 1);
i_odd = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA);
q_odd = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] Gain[0x%x] i_odd/ q_odd = 0x%x/ 0x%x\n",
_dck_addr[i] + 1, i_odd, q_odd);
if (abs(i_odd_bs - i_odd) > th || abs(q_odd_bs - q_odd) > th)
return true;
}
return false;
}
static void _rx_dck_fix_if_need(struct rtw89_dev *rtwdev, u8 path, u8 addr,
u8 val_i_bs, u8 val_q_bs, u8 val_i, u8 val_q)
{
const u8 th = 10;
if ((abs(val_i_bs - val_i) < th) && (abs(val_q_bs - val_q) <= th)) {
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] offset check PASS!!\n");
return;
}
if (abs(val_i_bs - val_i) > th) {
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] val_i over TH (0x%x / 0x%x)\n", val_i_bs, val_i);
val_i = val_i_bs;
}
if (abs(val_q_bs - val_q) > th) {
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] val_q over TH (0x%x / 0x%x)\n", val_q_bs, val_q);
val_q = val_q_bs;
}
_rx_dck_value_rewrite(rtwdev, path, addr, val_i, val_q);
}
static void _rx_dck_recover(struct rtw89_dev *rtwdev, u8 path)
{
u8 i_even_bs, q_even_bs;
u8 i_odd_bs, q_odd_bs;
u8 i_even, q_even;
u8 i_odd, q_odd;
u8 i;
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] ===> recovery\n");
for (i = 0; i < RF_PATH_NUM_8852C; i++) {
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr_bs[i]);
i_even_bs = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA);
q_even_bs = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA);
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr_bs[i] + 1);
i_odd_bs = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA);
q_odd_bs = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] Gain[0x%x] i_even_bs/ q_even_bs = 0x%x/ 0x%x\n",
_dck_addr_bs[i], i_even_bs, q_even_bs);
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr[i]);
i_even = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA);
q_even = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] Gain[0x%x] i_even/ q_even = 0x%x/ 0x%x\n",
_dck_addr[i], i_even, q_even);
_rx_dck_fix_if_need(rtwdev, path, _dck_addr[i],
i_even_bs, q_even_bs, i_even, q_even);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] Gain[0x%x] i_odd_bs/ q_odd_bs = 0x%x/ 0x%x\n",
_dck_addr_bs[i] + 1, i_odd_bs, q_odd_bs);
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr[i] + 1);
i_odd = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA);
q_odd = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] Gain[0x%x] i_odd/ q_odd = 0x%x/ 0x%x\n",
_dck_addr[i] + 1, i_odd, q_odd);
_rx_dck_fix_if_need(rtwdev, path, _dck_addr[i] + 1,
i_odd_bs, q_odd_bs, i_odd, q_odd);
}
}
static void _rx_dck_toggle(struct rtw89_dev *rtwdev, u8 path)
{
int ret;
@ -1546,7 +1719,8 @@ static void _rx_dck_toggle(struct rtw89_dev *rtwdev, u8 path)
rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x1);
ret = read_poll_timeout_atomic(rtw89_read_rf, val, val,
2, 1000, false, rtwdev, path, 0x93, BIT(5));
2, 2000, false, rtwdev, path,
RR_DCK1, RR_DCK1_DONE);
if (ret)
rtw89_warn(rtwdev, "[RX_DCK] S%d RXDCK timeout\n", path);
else
@ -1573,11 +1747,42 @@ static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, u8 pat
}
}
static
u8 _rx_dck_channel_calc(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan)
{
u8 target_ch = 0;
if (chan->band_type == RTW89_BAND_5G) {
if (chan->channel >= 36 && chan->channel <= 64) {
target_ch = 100;
} else if (chan->channel >= 100 && chan->channel <= 144) {
target_ch = chan->channel + 32;
if (target_ch > 144)
target_ch = chan->channel + 33;
} else if (chan->channel >= 149 && chan->channel <= 177) {
target_ch = chan->channel - 33;
}
} else if (chan->band_type == RTW89_BAND_6G) {
if (chan->channel >= 1 && chan->channel <= 125)
target_ch = chan->channel + 32;
else
target_ch = chan->channel - 32;
} else {
target_ch = chan->channel;
}
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] cur_ch / target_ch = %d / %d\n",
chan->channel, target_ch);
return target_ch;
}
#define RTW8852C_RF_REL_VERSION 34
#define RTW8852C_DPK_VER 0x10
#define RTW8852C_DPK_VER 0xf
#define RTW8852C_DPK_TH_AVG_NUM 4
#define RTW8852C_DPK_RF_PATH 2
#define RTW8852C_DPK_KIP_REG_NUM 5
#define RTW8852C_DPK_KIP_REG_NUM 7
#define RTW8852C_DPK_RXSRAM_DBG 0
enum rtw8852c_dpk_id {
@ -1614,6 +1819,12 @@ enum dpk_agc_step {
DPK_AGC_STEP_SET_TX_GAIN,
};
enum dpk_pas_result {
DPK_PAS_NOR,
DPK_PAS_GT,
DPK_PAS_LT,
};
static void _rf_direct_cntrl(struct rtw89_dev *rtwdev,
enum rtw89_rf_path path, bool is_bybb)
{
@ -1666,7 +1877,7 @@ static u8 _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55,
10, 20000, false, rtwdev, 0xbff8, MASKBYTE0);
mdelay(10);
udelay(10);
rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, MASKBYTE0);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
@ -1730,8 +1941,6 @@ static void _dpk_bb_afe_setting(struct rtw89_dev *rtwdev,
/*4. Set ADC clk*/
rtw8852c_rxck_force(rtwdev, path, true, ADC_1920M);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 + (path << 8), B_P0_CFCH_BW0, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 + (path << 8), B_P0_CFCH_BW1, 0xb);
rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13),
B_P0_NRBW_DBG, 0x1);
rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, MASKBYTE3, 0x1f);
@ -1872,12 +2081,11 @@ static void _dpk_rf_setting(struct rtw89_dev *rtwdev, u8 gain,
0x50101 | BIT(rtwdev->dbcc_en));
rtw89_write_rf(rtwdev, path, RR_MOD_V1, RR_MOD_MASK, RF_DPK);
if (dpk->bp[path][kidx].band == RTW89_BAND_6G && dpk->bp[path][kidx].ch >= 161) {
if (dpk->bp[path][kidx].band == RTW89_BAND_6G && dpk->bp[path][kidx].ch >= 161)
rtw89_write_rf(rtwdev, path, RR_IQGEN, RR_IQGEN_BIAS, 0x8);
rtw89_write_rf(rtwdev, path, RR_LOGEN, RR_LOGEN_RPT, 0xd);
} else {
rtw89_write_rf(rtwdev, path, RR_LOGEN, RR_LOGEN_RPT, 0xd);
}
rtw89_write_rf(rtwdev, path, RR_LOGEN, RR_LOGEN_RPT, 0xd);
rtw89_write_rf(rtwdev, path, RR_TXAC, RR_TXAC_IQG, 0x8);
rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_ATT, 0x0);
rtw89_write_rf(rtwdev, path, RR_TXIQK, RR_TXIQK_ATT2, 0x3);
@ -2024,9 +2232,10 @@ static u8 _dpk_gainloss(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
return _dpk_gainloss_read(rtwdev);
}
static bool _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check)
static enum dpk_pas_result _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check)
{
u32 val1_i = 0, val1_q = 0, val2_i = 0, val2_q = 0;
u32 val1_sqrt_sum, val2_sqrt_sum;
u8 i;
rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKBYTE2, 0x06);
@ -2057,15 +2266,25 @@ static bool _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check)
}
}
if (val1_i * val1_i + val1_q * val1_q >= (val2_i * val2_i + val2_q * val2_q) * 8 / 5)
return true;
val1_sqrt_sum = val1_i * val1_i + val1_q * val1_q;
val2_sqrt_sum = val2_i * val2_i + val2_q * val2_q;
if (val1_sqrt_sum < val2_sqrt_sum)
return DPK_PAS_LT;
else if (val1_sqrt_sum >= val2_sqrt_sum * 8 / 5)
return DPK_PAS_GT;
else
return false;
return DPK_PAS_NOR;
}
static bool _dpk_kip_set_rxagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_rf_path path, u8 kidx)
{
_dpk_kip_control_rfc(rtwdev, path, false);
rtw89_phy_write32_mask(rtwdev, R_KIP_MOD, B_KIP_MOD,
rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK));
_dpk_kip_control_rfc(rtwdev, path, true);
_dpk_one_shot(rtwdev, phy, path, D_RXAGC);
return _dpk_sync_check(rtwdev, path, kidx);
@ -2103,6 +2322,7 @@ static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
u8 tmp_dbm = init_xdbm, tmp_gl_idx = 0;
u8 tmp_rxbb;
u8 goout = 0, agc_cnt = 0;
enum dpk_pas_result pas;
u16 dgain = 0;
bool is_fail = false;
int limit = 200;
@ -2138,9 +2358,13 @@ static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
case DPK_AGC_STEP_GAIN_LOSS_IDX:
tmp_gl_idx = _dpk_gainloss(rtwdev, phy, path, kidx);
pas = _dpk_pas_read(rtwdev, true);
if ((tmp_gl_idx == 0 && _dpk_pas_read(rtwdev, true)) ||
tmp_gl_idx >= 7)
if (pas == DPK_PAS_LT && tmp_gl_idx > 0)
step = DPK_AGC_STEP_GL_LT_CRITERION;
else if (pas == DPK_PAS_GT && tmp_gl_idx == 0)
step = DPK_AGC_STEP_GL_GT_CRITERION;
else if (tmp_gl_idx >= 7)
step = DPK_AGC_STEP_GL_GT_CRITERION;
else if (tmp_gl_idx == 0)
step = DPK_AGC_STEP_GL_LT_CRITERION;
@ -2467,12 +2691,18 @@ static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
enum rtw89_phy_idx phy, u8 kpath)
{
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
static const u32 kip_reg[] = {0x813c, 0x8124, 0x8120, 0xc0d4, 0xc0d8};
static const u32 kip_reg[] = {0x813c, 0x8124, 0x8120, 0xc0c4, 0xc0e8, 0xc0d4, 0xc0d8};
u32 backup_rf_val[RTW8852C_DPK_RF_PATH][BACKUP_RF_REGS_NR];
u32 kip_bkup[RTW8852C_DPK_RF_PATH][RTW8852C_DPK_KIP_REG_NUM] = {};
u8 path;
bool is_fail = true, reloaded[RTW8852C_DPK_RF_PATH] = {false};
#if defined(__linux__)
static_assert(ARRAY_SIZE(kip_reg) == RTW8852C_DPK_KIP_REG_NUM);
#elif defined(__FreeBSD__)
rtw89_static_assert(ARRAY_SIZE(kip_reg) == RTW8852C_DPK_KIP_REG_NUM);
#endif
if (dpk->is_dpk_reload_en) {
for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) {
if (!(kpath & BIT(path)))
@ -3824,20 +4054,20 @@ void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev,
void rtw8852c_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
{
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
struct rtw89_mcc_info *mcc_info = &rtwdev->mcc;
u8 idx = mcc_info->table_idx;
struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
u8 idx = rfk_mcc->table_idx;
int i;
for (i = 0; i < RTW89_IQK_CHS_NR; i++) {
if (mcc_info->ch[idx] == 0)
if (rfk_mcc->ch[idx] == 0)
break;
if (++idx >= RTW89_IQK_CHS_NR)
idx = 0;
}
mcc_info->table_idx = idx;
mcc_info->ch[idx] = chan->channel;
mcc_info->band[idx] = chan->band_type;
rfk_mcc->table_idx = idx;
rfk_mcc->ch[idx] = chan->channel;
rfk_mcc->band[idx] = chan->band_type;
}
void rtw8852c_rck(struct rtw89_dev *rtwdev)
@ -3875,11 +4105,14 @@ void rtw8852c_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
#define RXDCK_VER_8852C 0xe
void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_afe)
static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
bool is_afe, u8 retry_limit)
{
struct rtw89_rx_dck_info *rx_dck = &rtwdev->rx_dck;
u8 path, kpath;
u32 rf_reg5;
bool is_fail;
u8 rek_cnt;
kpath = _kpath(rtwdev, phy);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
@ -3896,7 +4129,27 @@ void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_a
B_P0_TSSI_TRK_EN, 0x1);
rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0);
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX);
_set_rx_dck(rtwdev, phy, path, is_afe);
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_LO_SEL, rtwdev->dbcc_en);
for (rek_cnt = 0; rek_cnt < retry_limit; rek_cnt++) {
_set_rx_dck(rtwdev, phy, path, is_afe);
/* To reduce IO of dck_rek_check(), the last try is seen
* as failure always, and then do recovery procedure.
*/
if (rek_cnt == retry_limit - 1) {
_rx_dck_recover(rtwdev, path);
break;
}
is_fail = _rx_dck_rek_check(rtwdev, path);
if (!is_fail)
break;
}
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] rek_cnt[%d]=%d",
path, rek_cnt);
rx_dck->thermal[path] = ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]);
rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5);
@ -3906,15 +4159,31 @@ void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_a
}
}
#define RTW8852C_RX_DCK_TH 8
void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_afe)
{
_rx_dck(rtwdev, phy, is_afe, 1);
}
#define RTW8852C_RX_DCK_TH 12
void rtw8852c_rx_dck_track(struct rtw89_dev *rtwdev)
{
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
struct rtw89_rx_dck_info *rx_dck = &rtwdev->rx_dck;
enum rtw89_phy_idx phy_idx = RTW89_PHY_0;
u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0);
u8 dck_channel;
u8 cur_thermal;
u32 tx_en;
int delta;
int path;
if (chan->band_type == RTW89_BAND_2G)
return;
if (rtwdev->scanning)
return;
for (path = 0; path < RF_PATH_NUM_8852C; path++) {
cur_thermal =
ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]);
@ -3924,11 +4193,28 @@ void rtw8852c_rx_dck_track(struct rtw89_dev *rtwdev)
"[RX_DCK] path=%d current thermal=0x%x delta=0x%x\n",
path, cur_thermal, delta);
if (delta >= RTW8852C_RX_DCK_TH) {
rtw8852c_rx_dck(rtwdev, RTW89_PHY_0, false);
return;
}
if (delta >= RTW8852C_RX_DCK_TH)
goto trigger_rx_dck;
}
return;
trigger_rx_dck:
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_START);
rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL);
for (path = 0; path < RF_PATH_NUM_8852C; path++) {
dck_channel = _rx_dck_channel_calc(rtwdev, chan);
_ctrl_ch(rtwdev, RTW89_PHY_0, dck_channel, chan->band_type);
}
_rx_dck(rtwdev, RTW89_PHY_0, false, 20);
for (path = 0; path < RF_PATH_NUM_8852C; path++)
_ctrl_ch(rtwdev, RTW89_PHY_0, chan->channel, chan->band_type);
rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP);
}
void rtw8852c_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)

File diff suppressed because it is too large Load diff

View file

@ -15,22 +15,8 @@ extern const struct rtw89_phy_table rtw89_8852c_phy_nctl_table;
extern const struct rtw89_txpwr_table rtw89_8852c_byr_table;
extern const struct rtw89_phy_tssi_dbw_table rtw89_8852c_tssi_dbw_table;
extern const struct rtw89_txpwr_track_cfg rtw89_8852c_trk_cfg;
extern const u8 rtw89_8852c_tx_shape[RTW89_BAND_MAX][RTW89_RS_TX_SHAPE_NUM]
extern const u8 rtw89_8852c_tx_shape[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM]
[RTW89_REGD_NUM];
extern const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM]
[RTW89_RS_LMT_NUM][RTW89_BF_NUM]
[RTW89_REGD_NUM][RTW89_2G_CH_NUM];
extern const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[RTW89_RS_LMT_NUM][RTW89_BF_NUM]
[RTW89_REGD_NUM][RTW89_5G_CH_NUM];
extern const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[RTW89_RS_LMT_NUM][RTW89_BF_NUM]
[RTW89_REGD_NUM][RTW89_6G_CH_NUM];
extern const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM]
[RTW89_REGD_NUM][RTW89_2G_CH_NUM];
extern const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[RTW89_REGD_NUM][RTW89_5G_CH_NUM];
extern const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[RTW89_REGD_NUM][RTW89_6G_CH_NUM];
extern const struct rtw89_rfe_parms rtw89_8852c_dflt_parms;
#endif

View file

@ -42,16 +42,18 @@ static const struct rtw89_pci_info rtw8852c_pci_info = {
.max_tag_num_mask = B_AX_MAX_TAG_NUM_V1_MASK,
.rxbd_rwptr_clr_reg = R_AX_RXBD_RWPTR_CLR_V1,
.txbd_rwptr_clr2_reg = R_AX_TXBD_RWPTR_CLR2_V1,
.dma_stop1_reg = R_AX_HAXI_DMA_STOP1,
.dma_stop2_reg = R_AX_HAXI_DMA_STOP2,
.dma_busy1_reg = R_AX_HAXI_DMA_BUSY1,
.dma_stop1 = {R_AX_HAXI_DMA_STOP1, B_AX_TX_STOP1_MASK},
.dma_stop2 = {R_AX_HAXI_DMA_STOP2, B_AX_TX_STOP2_ALL},
.dma_busy1 = {R_AX_HAXI_DMA_BUSY1, DMA_BUSY1_CHECK},
.dma_busy2_reg = R_AX_HAXI_DMA_BUSY2,
.dma_busy3_reg = R_AX_HAXI_DMA_BUSY3,
.rpwm_addr = R_AX_PCIE_HRPWM_V1,
.cpwm_addr = R_AX_PCIE_CRPWM,
.tx_dma_ch_mask = 0,
.bd_idx_addr_low_power = &rtw8852c_bd_idx_addr_low_power,
.dma_addr_set = &rtw89_pci_ch_dma_addr_set_v1,
.bd_ram_table = &rtw89_bd_ram_table_dual,
.ltr_set = rtw89_pci_ltr_set_v1,
.fill_txaddr_info = rtw89_pci_fill_txaddr_info_v1,

View file

@ -20,12 +20,14 @@ enum ser_evt {
SER_EV_NONE,
SER_EV_STATE_IN,
SER_EV_STATE_OUT,
SER_EV_L1_RESET_PREPARE, /* pre-M0 */
SER_EV_L1_RESET, /* M1 */
SER_EV_DO_RECOVERY, /* M3 */
SER_EV_MAC_RESET_DONE, /* M5 */
SER_EV_L2_RESET,
SER_EV_L2_RECFG_DONE,
SER_EV_L2_RECFG_TIMEOUT,
SER_EV_M1_TIMEOUT,
SER_EV_M3_TIMEOUT,
SER_EV_FW_M5_TIMEOUT,
SER_EV_L0_RESET,
@ -34,6 +36,7 @@ enum ser_evt {
enum ser_state {
SER_IDLE_ST,
SER_L1_RESET_PRE_ST,
SER_RESET_TRX_ST,
SER_DO_HCI_ST,
SER_L2_RESET_ST,
@ -300,6 +303,7 @@ static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
rtwvif->net_type = RTW89_NET_TYPE_NO_LINK;
rtwvif->trigger = false;
rtwvif->tdls_peer = 0;
}
static void ser_sta_deinit_cam_iter(void *data, struct ieee80211_sta *sta)
@ -338,6 +342,8 @@ static void ser_reset_mac_binding(struct rtw89_dev *rtwdev)
rtw89_core_release_all_bits_map(rtwdev->mac_id_map, RTW89_MAX_MAC_ID_NUM);
rtw89_for_each_rtwvif(rtwdev, rtwvif)
ser_reset_vif(rtwdev, rtwvif);
rtwdev->total_sta_assoc = 0;
}
/* hal function */
@ -374,6 +380,13 @@ static int hal_stop_dma(struct rtw89_ser *ser)
return ret;
}
static void hal_send_post_m0_event(struct rtw89_ser *ser)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L1_RESET_START_DMAC);
}
static void hal_send_m2_event(struct rtw89_ser *ser)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
@ -396,6 +409,11 @@ static void ser_idle_st_hdl(struct rtw89_ser *ser, u8 evt)
switch (evt) {
case SER_EV_STATE_IN:
rtw89_hci_recovery_complete(rtwdev);
clear_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags);
clear_bit(RTW89_FLAG_CRASH_SIMULATING, rtwdev->flags);
break;
case SER_EV_L1_RESET_PREPARE:
ser_state_goto(ser, SER_L1_RESET_PRE_ST);
break;
case SER_EV_L1_RESET:
ser_state_goto(ser, SER_RESET_TRX_ST);
@ -404,6 +422,7 @@ static void ser_idle_st_hdl(struct rtw89_ser *ser, u8 evt)
ser_state_goto(ser, SER_L2_RESET_ST);
break;
case SER_EV_STATE_OUT:
set_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags);
rtw89_hci_recovery_start(rtwdev);
break;
default:
@ -411,10 +430,35 @@ static void ser_idle_st_hdl(struct rtw89_ser *ser, u8 evt)
}
}
static void ser_l1_reset_pre_st_hdl(struct rtw89_ser *ser, u8 evt)
{
switch (evt) {
case SER_EV_STATE_IN:
ser->prehandle_l1 = true;
hal_send_post_m0_event(ser);
ser_set_alarm(ser, 1000, SER_EV_M1_TIMEOUT);
break;
case SER_EV_L1_RESET:
ser_state_goto(ser, SER_RESET_TRX_ST);
break;
case SER_EV_M1_TIMEOUT:
ser_state_goto(ser, SER_L2_RESET_ST);
break;
case SER_EV_STATE_OUT:
ser_del_alarm(ser);
break;
default:
break;
}
}
static void ser_reset_trx_st_hdl(struct rtw89_ser *ser, u8 evt)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
switch (evt) {
case SER_EV_STATE_IN:
cancel_delayed_work_sync(&rtwdev->track_work);
drv_stop_tx(ser);
if (hal_stop_dma(ser)) {
@ -445,6 +489,8 @@ static void ser_reset_trx_st_hdl(struct rtw89_ser *ser, u8 evt)
hal_enable_dma(ser);
drv_resume_rx(ser);
drv_resume_tx(ser);
ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work,
RTW89_TRACK_WORK_PERIOD);
break;
default:
@ -543,7 +589,7 @@ static int rtw89_ser_fw_backtrace_dump(struct rtw89_dev *rtwdev, u8 *buf,
const struct __fw_backtrace_entry *ent)
{
struct __fw_backtrace_info *ptr = (struct __fw_backtrace_info *)buf;
u32 fwbt_addr = ent->wcpu_addr - RTW89_WCPU_BASE_ADDR;
u32 fwbt_addr = ent->wcpu_addr & RTW89_WCPU_BASE_MASK;
u32 fwbt_size = ent->size;
u32 fwbt_key = ent->key;
u32 i;
@ -614,6 +660,7 @@ static void ser_l2_reset_st_pre_hdl(struct rtw89_ser *ser)
ser_reset_mac_binding(rtwdev);
rtw89_core_stop(rtwdev);
rtw89_entity_init(rtwdev);
rtw89_fw_release_general_pkt_list(rtwdev, false);
INIT_LIST_HEAD(&rtwdev->rtwvifs_list);
}
@ -636,7 +683,6 @@ static void ser_l2_reset_st_hdl(struct rtw89_ser *ser, u8 evt)
fallthrough;
case SER_EV_L2_RECFG_DONE:
ser_state_goto(ser, SER_IDLE_ST);
clear_bit(RTW89_FLAG_RESTART_TRIGGER, rtwdev->flags);
break;
case SER_EV_STATE_OUT:
@ -652,12 +698,14 @@ static const struct event_ent ser_ev_tbl[] = {
{SER_EV_NONE, "SER_EV_NONE"},
{SER_EV_STATE_IN, "SER_EV_STATE_IN"},
{SER_EV_STATE_OUT, "SER_EV_STATE_OUT"},
{SER_EV_L1_RESET, "SER_EV_L1_RESET"},
{SER_EV_L1_RESET_PREPARE, "SER_EV_L1_RESET_PREPARE pre-m0"},
{SER_EV_L1_RESET, "SER_EV_L1_RESET m1"},
{SER_EV_DO_RECOVERY, "SER_EV_DO_RECOVERY m3"},
{SER_EV_MAC_RESET_DONE, "SER_EV_MAC_RESET_DONE m5"},
{SER_EV_L2_RESET, "SER_EV_L2_RESET"},
{SER_EV_L2_RECFG_DONE, "SER_EV_L2_RECFG_DONE"},
{SER_EV_L2_RECFG_TIMEOUT, "SER_EV_L2_RECFG_TIMEOUT"},
{SER_EV_M1_TIMEOUT, "SER_EV_M1_TIMEOUT"},
{SER_EV_M3_TIMEOUT, "SER_EV_M3_TIMEOUT"},
{SER_EV_FW_M5_TIMEOUT, "SER_EV_FW_M5_TIMEOUT"},
{SER_EV_L0_RESET, "SER_EV_L0_RESET"},
@ -666,6 +714,7 @@ static const struct event_ent ser_ev_tbl[] = {
static const struct state_ent ser_st_tbl[] = {
{SER_IDLE_ST, "SER_IDLE_ST", ser_idle_st_hdl},
{SER_L1_RESET_PRE_ST, "SER_L1_RESET_PRE_ST", ser_l1_reset_pre_st_hdl},
{SER_RESET_TRX_ST, "SER_RESET_TRX_ST", ser_reset_trx_st_hdl},
{SER_DO_HCI_ST, "SER_DO_HCI_ST", ser_do_hci_st_hdl},
{SER_L2_RESET_ST, "SER_L2_RESET_ST", ser_l2_reset_st_hdl}
@ -711,6 +760,9 @@ int rtw89_ser_notify(struct rtw89_dev *rtwdev, u32 err)
rtw89_info(rtwdev, "SER catches error: 0x%x\n", err);
switch (err) {
case MAC_AX_ERR_L1_PREERR_DMAC: /* pre-M0 */
event = SER_EV_L1_RESET_PREPARE;
break;
case MAC_AX_ERR_L1_ERR_DMAC:
case MAC_AX_ERR_L0_PROMOTE_TO_L1:
event = SER_EV_L1_RESET; /* M1 */

View file

@ -8,19 +8,56 @@
#include "debug.h"
#define DATA_RATE_MODE_CTRL_MASK GENMASK(8, 7)
#define DATA_RATE_MODE_CTRL_MASK_V1 GENMASK(10, 8)
#define DATA_RATE_NOT_HT_IDX_MASK GENMASK(3, 0)
#define DATA_RATE_MODE_NON_HT 0x0
#define DATA_RATE_HT_IDX_MASK GENMASK(4, 0)
#define DATA_RATE_HT_IDX_MASK_V1 GENMASK(4, 0)
#define DATA_RATE_MODE_HT 0x1
#define DATA_RATE_VHT_HE_NSS_MASK GENMASK(6, 4)
#define DATA_RATE_VHT_HE_IDX_MASK GENMASK(3, 0)
#define DATA_RATE_NSS_MASK_V1 GENMASK(7, 5)
#define DATA_RATE_MCS_MASK_V1 GENMASK(4, 0)
#define DATA_RATE_MODE_VHT 0x2
#define DATA_RATE_MODE_HE 0x3
#define GET_DATA_RATE_MODE(r) FIELD_GET(DATA_RATE_MODE_CTRL_MASK, r)
#define GET_DATA_RATE_NOT_HT_IDX(r) FIELD_GET(DATA_RATE_NOT_HT_IDX_MASK, r)
#define GET_DATA_RATE_HT_IDX(r) FIELD_GET(DATA_RATE_HT_IDX_MASK, r)
#define GET_DATA_RATE_VHT_HE_IDX(r) FIELD_GET(DATA_RATE_VHT_HE_IDX_MASK, r)
#define GET_DATA_RATE_NSS(r) FIELD_GET(DATA_RATE_VHT_HE_NSS_MASK, r)
#define DATA_RATE_MODE_EHT 0x4
static inline u8 rtw89_get_data_rate_mode(struct rtw89_dev *rtwdev, u16 hw_rate)
{
if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
return u16_get_bits(hw_rate, DATA_RATE_MODE_CTRL_MASK_V1);
return u16_get_bits(hw_rate, DATA_RATE_MODE_CTRL_MASK);
}
static inline u8 rtw89_get_data_not_ht_idx(struct rtw89_dev *rtwdev, u16 hw_rate)
{
return u16_get_bits(hw_rate, DATA_RATE_NOT_HT_IDX_MASK);
}
static inline u8 rtw89_get_data_ht_mcs(struct rtw89_dev *rtwdev, u16 hw_rate)
{
if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
return u16_get_bits(hw_rate, DATA_RATE_HT_IDX_MASK_V1);
return u16_get_bits(hw_rate, DATA_RATE_HT_IDX_MASK);
}
static inline u8 rtw89_get_data_mcs(struct rtw89_dev *rtwdev, u16 hw_rate)
{
if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
return u16_get_bits(hw_rate, DATA_RATE_MCS_MASK_V1);
return u16_get_bits(hw_rate, DATA_RATE_VHT_HE_IDX_MASK);
}
static inline u8 rtw89_get_data_nss(struct rtw89_dev *rtwdev, u16 hw_rate)
{
if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
return u16_get_bits(hw_rate, DATA_RATE_NSS_MASK_V1);
return u16_get_bits(hw_rate, DATA_RATE_VHT_HE_NSS_MASK);
}
/* TX WD BODY DWORD 0 */
#define RTW89_TXWD_BODY0_WP_OFFSET GENMASK(31, 24)
@ -75,7 +112,9 @@
#define RTW89_TXWD_INFO0_DATA_BW GENMASK(29, 28)
#define RTW89_TXWD_INFO0_GI_LTF GENMASK(27, 25)
#define RTW89_TXWD_INFO0_DATA_RATE GENMASK(24, 16)
#define RTW89_TXWD_INFO0_DATA_ER BIT(15)
#define RTW89_TXWD_INFO0_DISDATAFB BIT(10)
#define RTW89_TXWD_INFO0_DATA_BW_ER BIT(8)
#define RTW89_TXWD_INFO0_MULTIPORT_ID GENMASK(6, 4)
/* TX WD INFO DWORD 1 */
@ -184,122 +223,64 @@
#define AX_RXD_BIP_KEYID BIT(27)
#define AX_RXD_BIP_ENC BIT(28)
/* RX DESC helpers */
/* Short Descriptor */
#define RTW89_GET_RXWD_LONG_RXD(rxdesc) \
le32_get_bits((rxdesc)->dword0, BIT(31))
#define RTW89_GET_RXWD_DRV_INFO_SIZE(rxdesc) \
le32_get_bits((rxdesc)->dword0, GENMASK(30, 28))
#define RTW89_GET_RXWD_RPKT_TYPE(rxdesc) \
le32_get_bits((rxdesc)->dword0, GENMASK(27, 24))
#define RTW89_GET_RXWD_MAC_INFO_VALID(rxdesc) \
le32_get_bits((rxdesc)->dword0, BIT(23))
#define RTW89_GET_RXWD_BB_SEL(rxdesc) \
le32_get_bits((rxdesc)->dword0, BIT(22))
#define RTW89_GET_RXWD_HD_IV_LEN(rxdesc) \
le32_get_bits((rxdesc)->dword0, GENMASK(21, 16))
#define RTW89_GET_RXWD_SHIFT(rxdesc) \
le32_get_bits((rxdesc)->dword0, GENMASK(15, 14))
#define RTW89_GET_RXWD_PKT_SIZE(rxdesc) \
le32_get_bits((rxdesc)->dword0, GENMASK(13, 0))
#define RTW89_GET_RXWD_BW(rxdesc) \
le32_get_bits((rxdesc)->dword1, GENMASK(31, 30))
#define RTW89_GET_RXWD_BW_V1(rxdesc) \
le32_get_bits((rxdesc)->dword1, GENMASK(31, 29))
#define RTW89_GET_RXWD_GI_LTF(rxdesc) \
le32_get_bits((rxdesc)->dword1, GENMASK(27, 25))
#define RTW89_GET_RXWD_DATA_RATE(rxdesc) \
le32_get_bits((rxdesc)->dword1, GENMASK(24, 16))
#define RTW89_GET_RXWD_USER_ID(rxdesc) \
le32_get_bits((rxdesc)->dword1, GENMASK(15, 8))
#define RTW89_GET_RXWD_SR_EN(rxdesc) \
le32_get_bits((rxdesc)->dword1, BIT(7))
#define RTW89_GET_RXWD_PPDU_CNT(rxdesc) \
le32_get_bits((rxdesc)->dword1, GENMASK(6, 4))
#define RTW89_GET_RXWD_PPDU_TYPE(rxdesc) \
le32_get_bits((rxdesc)->dword1, GENMASK(3, 0))
#define RTW89_GET_RXWD_FREE_RUN_CNT(rxdesc) \
le32_get_bits((rxdesc)->dword2, GENMASK(31, 0))
#define RTW89_GET_RXWD_ICV_ERR(rxdesc) \
le32_get_bits((rxdesc)->dword3, BIT(10))
#define RTW89_GET_RXWD_CRC32_ERR(rxdesc) \
le32_get_bits((rxdesc)->dword3, BIT(9))
#define RTW89_GET_RXWD_HW_DEC(rxdesc) \
le32_get_bits((rxdesc)->dword3, BIT(2))
#define RTW89_GET_RXWD_SW_DEC(rxdesc) \
le32_get_bits((rxdesc)->dword3, BIT(1))
#define RTW89_GET_RXWD_A1_MATCH(rxdesc) \
le32_get_bits((rxdesc)->dword3, BIT(0))
struct rtw89_rxinfo_user {
__le32 w0;
};
/* Long Descriptor */
#define RTW89_GET_RXWD_FRAG(rxdesc) \
le32_get_bits((rxdesc)->dword4, GENMASK(31, 28))
#define RTW89_GET_RXWD_SEQ(rxdesc) \
le32_get_bits((rxdesc)->dword4, GENMASK(27, 16))
#define RTW89_GET_RXWD_TYPE(rxdesc) \
le32_get_bits((rxdesc)->dword4, GENMASK(1, 0))
#define RTW89_GET_RXWD_ADDR_CAM_VLD(rxdesc) \
le32_get_bits((rxdesc)->dword5, BIT(28))
#define RTW89_GET_RXWD_RX_PL_ID(rxdesc) \
le32_get_bits((rxdesc)->dword5, GENMASK(27, 24))
#define RTW89_GET_RXWD_MAC_ID(rxdesc) \
le32_get_bits((rxdesc)->dword5, GENMASK(23, 16))
#define RTW89_GET_RXWD_ADDR_CAM_ID(rxdesc) \
le32_get_bits((rxdesc)->dword5, GENMASK(15, 8))
#define RTW89_GET_RXWD_SEC_CAM_ID(rxdesc) \
le32_get_bits((rxdesc)->dword5, GENMASK(7, 0))
#define RTW89_RXINFO_USER_MAC_ID_VALID BIT(0)
#define RTW89_RXINFO_USER_DATA BIT(1)
#define RTW89_RXINFO_USER_CTRL BIT(2)
#define RTW89_RXINFO_USER_MGMT BIT(3)
#define RTW89_RXINFO_USER_BCM BIT(4)
#define RTW89_RXINFO_USER_MACID GENMASK(15, 8)
#define RTW89_GET_RXINFO_USR_NUM(rpt) \
le32_get_bits(*((const __le32 *)rpt), GENMASK(3, 0))
#define RTW89_GET_RXINFO_FW_DEFINE(rpt) \
le32_get_bits(*((const __le32 *)rpt), GENMASK(15, 8))
#define RTW89_GET_RXINFO_LSIG_LEN(rpt) \
le32_get_bits(*((const __le32 *)rpt), GENMASK(27, 16))
#define RTW89_GET_RXINFO_IS_TO_SELF(rpt) \
le32_get_bits(*((const __le32 *)rpt), BIT(28))
#define RTW89_GET_RXINFO_RX_CNT_VLD(rpt) \
le32_get_bits(*((const __le32 *)rpt), BIT(29))
#define RTW89_GET_RXINFO_LONG_RXD(rpt) \
le32_get_bits(*((const __le32 *)rpt), GENMASK(31, 30))
#define RTW89_GET_RXINFO_SERVICE(rpt) \
le32_get_bits(*((const __le32 *)(rpt) + 1), GENMASK(15, 0))
#define RTW89_GET_RXINFO_PLCP_LEN(rpt) \
le32_get_bits(*((const __le32 *)(rpt) + 1), GENMASK(23, 16))
#define RTW89_GET_RXINFO_MAC_ID_VALID(rpt, usr) \
le32_get_bits(*((const __le32 *)(rpt) + (usr) + 2), BIT(0))
#define RTW89_GET_RXINFO_DATA(rpt, usr) \
le32_get_bits(*((const __le32 *)(rpt) + (usr) + 2), BIT(1))
#define RTW89_GET_RXINFO_CTRL(rpt, usr) \
le32_get_bits(*((const __le32 *)(rpt) + (usr) + 2), BIT(2))
#define RTW89_GET_RXINFO_MGMT(rpt, usr) \
le32_get_bits(*((const __le32 *)(rpt) + (usr) + 2), BIT(3))
#define RTW89_GET_RXINFO_BCM(rpt, usr) \
le32_get_bits(*((const __le32 *)(rpt) + (usr) + 2), BIT(4))
#define RTW89_GET_RXINFO_MACID(rpt, usr) \
le32_get_bits(*((const __le32 *)(rpt) + (usr) + 2), GENMASK(15, 8))
struct rtw89_rxinfo {
__le32 w0;
__le32 w1;
struct rtw89_rxinfo_user user[];
} __packed;
#define RTW89_GET_PHY_STS_IE_MAP(sts) \
le32_get_bits(*((const __le32 *)(sts)), GENMASK(4, 0))
#define RTW89_GET_PHY_STS_RSSI_A(sts) \
le32_get_bits(*((const __le32 *)(sts) + 1), GENMASK(7, 0))
#define RTW89_GET_PHY_STS_RSSI_B(sts) \
le32_get_bits(*((const __le32 *)(sts) + 1), GENMASK(15, 8))
#define RTW89_GET_PHY_STS_RSSI_C(sts) \
le32_get_bits(*((const __le32 *)(sts) + 1), GENMASK(23, 16))
#define RTW89_GET_PHY_STS_RSSI_D(sts) \
le32_get_bits(*((const __le32 *)(sts) + 1), GENMASK(31, 24))
#define RTW89_GET_PHY_STS_LEN(sts) \
le32_get_bits(*((const __le32 *)sts), GENMASK(15, 8))
#define RTW89_GET_PHY_STS_RSSI_AVG(sts) \
le32_get_bits(*((const __le32 *)sts), GENMASK(31, 24))
#define RTW89_GET_PHY_STS_IE_TYPE(ie) \
le32_get_bits(*((const __le32 *)ie), GENMASK(4, 0))
#define RTW89_GET_PHY_STS_IE_LEN(ie) \
le32_get_bits(*((const __le32 *)ie), GENMASK(11, 5))
#define RTW89_GET_PHY_STS_IE01_CH_IDX(ie) \
le32_get_bits(*((const __le32 *)ie), GENMASK(23, 16))
#define RTW89_GET_PHY_STS_IE01_CFO(ie) \
le32_get_bits(*((const __le32 *)(ie) + 1), GENMASK(31, 20))
#define RTW89_RXINFO_W0_USR_NUM GENMASK(3, 0)
#define RTW89_RXINFO_W0_FW_DEFINE GENMASK(15, 8)
#define RTW89_RXINFO_W0_LSIG_LEN GENMASK(27, 16)
#define RTW89_RXINFO_W0_IS_TO_SELF BIT(28)
#define RTW89_RXINFO_W0_RX_CNT_VLD BIT(29)
#define RTW89_RXINFO_W0_LONG_RXD GENMASK(31, 30)
#define RTW89_RXINFO_W1_SERVICE GENMASK(15, 0)
#define RTW89_RXINFO_W1_PLCP_LEN GENMASK(23, 16)
struct rtw89_phy_sts_hdr {
__le32 w0;
__le32 w1;
} __packed;
#define RTW89_PHY_STS_HDR_W0_IE_MAP GENMASK(4, 0)
#define RTW89_PHY_STS_HDR_W0_LEN GENMASK(15, 8)
#define RTW89_PHY_STS_HDR_W0_RSSI_AVG GENMASK(31, 24)
#define RTW89_PHY_STS_HDR_W1_RSSI_A GENMASK(7, 0)
#define RTW89_PHY_STS_HDR_W1_RSSI_B GENMASK(15, 8)
#define RTW89_PHY_STS_HDR_W1_RSSI_C GENMASK(23, 16)
#define RTW89_PHY_STS_HDR_W1_RSSI_D GENMASK(31, 24)
struct rtw89_phy_sts_iehdr {
__le32 w0;
};
#define RTW89_PHY_STS_IEHDR_TYPE GENMASK(4, 0)
#define RTW89_PHY_STS_IEHDR_LEN GENMASK(11, 5)
struct rtw89_phy_sts_ie0 {
__le32 w0;
__le32 w1;
__le32 w2;
} __packed;
#define RTW89_PHY_STS_IE01_W0_CH_IDX GENMASK(23, 16)
#define RTW89_PHY_STS_IE01_W1_FD_CFO GENMASK(19, 8)
#define RTW89_PHY_STS_IE01_W1_PREMB_CFO GENMASK(31, 20)
#define RTW89_PHY_STS_IE01_W2_AVG_SNR GENMASK(5, 0)
#define RTW89_PHY_STS_IE01_W2_EVM_MAX GENMASK(15, 8)
#define RTW89_PHY_STS_IE01_W2_EVM_MIN GENMASK(23, 16)
enum rtw89_tx_channel {
RTW89_TXCH_ACH0 = 0,

View file

@ -44,4 +44,15 @@ static inline s32 s32_div_u32_round_closest(s32 dividend, u32 divisor)
return s32_div_u32_round_down(dividend + divisor / 2, divisor, NULL);
}
static inline void ether_addr_copy_mask(u8 *dst, const u8 *src, u8 mask)
{
int i;
eth_zero_addr(dst);
for (i = 0; i < ETH_ALEN; i++) {
if (mask & BIT(i))
dst[i] = src[i];
}
}
#endif

842
sys/contrib/dev/rtw89/wow.c Normal file
View file

@ -0,0 +1,842 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2019-2022 Realtek Corporation
*/
#include "cam.h"
#include "core.h"
#include "debug.h"
#include "fw.h"
#include "mac.h"
#include "phy.h"
#include "ps.h"
#include "reg.h"
#include "util.h"
#include "wow.h"
static void rtw89_wow_leave_deep_ps(struct rtw89_dev *rtwdev)
{
__rtw89_leave_ps_mode(rtwdev);
}
static void rtw89_wow_enter_deep_ps(struct rtw89_dev *rtwdev)
{
struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
__rtw89_enter_ps_mode(rtwdev, rtwvif);
}
static void rtw89_wow_enter_lps(struct rtw89_dev *rtwdev)
{
struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
rtw89_enter_lps(rtwdev, rtwvif, false);
}
static void rtw89_wow_leave_lps(struct rtw89_dev *rtwdev)
{
rtw89_leave_lps(rtwdev);
}
static int rtw89_wow_config_mac(struct rtw89_dev *rtwdev, bool enable_wow)
{
int ret;
if (enable_wow) {
ret = rtw89_mac_resize_ple_rx_quota(rtwdev, true);
if (ret) {
rtw89_err(rtwdev, "[ERR]patch rx qta %d\n", ret);
return ret;
}
rtw89_write32_set(rtwdev, R_AX_RX_FUNCTION_STOP, B_AX_HDR_RX_STOP);
rtw89_write32_clr(rtwdev, R_AX_RX_FLTR_OPT, B_AX_SNIFFER_MODE);
rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false);
rtw89_write32(rtwdev, R_AX_ACTION_FWD0, 0);
rtw89_write32(rtwdev, R_AX_ACTION_FWD1, 0);
rtw89_write32(rtwdev, R_AX_TF_FWD, 0);
rtw89_write32(rtwdev, R_AX_HW_RPT_FWD, 0);
} else {
ret = rtw89_mac_resize_ple_rx_quota(rtwdev, false);
if (ret) {
rtw89_err(rtwdev, "[ERR]patch rx qta %d\n", ret);
return ret;
}
rtw89_write32_clr(rtwdev, R_AX_RX_FUNCTION_STOP, B_AX_HDR_RX_STOP);
rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true);
rtw89_write32(rtwdev, R_AX_ACTION_FWD0, TRXCFG_MPDU_PROC_ACT_FRWD);
rtw89_write32(rtwdev, R_AX_TF_FWD, TRXCFG_MPDU_PROC_TF_FRWD);
}
return 0;
}
static void rtw89_wow_set_rx_filter(struct rtw89_dev *rtwdev, bool enable)
{
enum rtw89_mac_fwd_target fwd_target = enable ?
RTW89_FWD_DONT_CARE :
RTW89_FWD_TO_HOST;
rtw89_mac_typ_fltr_opt(rtwdev, RTW89_MGNT, fwd_target, RTW89_MAC_0);
rtw89_mac_typ_fltr_opt(rtwdev, RTW89_CTRL, fwd_target, RTW89_MAC_0);
rtw89_mac_typ_fltr_opt(rtwdev, RTW89_DATA, fwd_target, RTW89_MAC_0);
}
static void rtw89_wow_show_wakeup_reason(struct rtw89_dev *rtwdev)
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
struct cfg80211_wowlan_nd_info nd_info;
struct cfg80211_wowlan_wakeup wakeup = {
.pattern_idx = -1,
};
u32 wow_reason_reg;
u8 reason;
if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B)
wow_reason_reg = R_AX_C2HREG_DATA3 + 3;
else
wow_reason_reg = R_AX_C2HREG_DATA3_V1 + 3;
reason = rtw89_read8(rtwdev, wow_reason_reg);
switch (reason) {
case RTW89_WOW_RSN_RX_DEAUTH:
wakeup.disconnect = true;
rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx deauth\n");
break;
case RTW89_WOW_RSN_DISCONNECT:
wakeup.disconnect = true;
rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: AP is off\n");
break;
case RTW89_WOW_RSN_RX_MAGIC_PKT:
wakeup.magic_pkt = true;
rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx magic packet\n");
break;
case RTW89_WOW_RSN_RX_GTK_REKEY:
wakeup.gtk_rekey_failure = true;
rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx gtk rekey\n");
break;
case RTW89_WOW_RSN_RX_PATTERN_MATCH:
/* Current firmware and driver don't report pattern index
* Use pattern_idx to 0 defaultly.
*/
wakeup.pattern_idx = 0;
rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx pattern match packet\n");
break;
case RTW89_WOW_RSN_RX_NLO:
/* Current firmware and driver don't report ssid index.
* Use 0 for n_matches based on its comment.
*/
nd_info.n_matches = 0;
wakeup.net_detect = &nd_info;
rtw89_debug(rtwdev, RTW89_DBG_WOW, "Rx NLO\n");
break;
default:
rtw89_warn(rtwdev, "Unknown wakeup reason %x\n", reason);
ieee80211_report_wowlan_wakeup(rtwdev->wow.wow_vif, NULL,
GFP_KERNEL);
return;
}
ieee80211_report_wowlan_wakeup(rtwdev->wow.wow_vif, &wakeup,
GFP_KERNEL);
}
static void rtw89_wow_vif_iter(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
/* Current wowlan function support setting of only one STATION vif.
* So when one suitable vif is found, stop the iteration.
*/
if (rtw_wow->wow_vif || vif->type != NL80211_IFTYPE_STATION)
return;
switch (rtwvif->net_type) {
case RTW89_NET_TYPE_INFRA:
rtw_wow->wow_vif = vif;
break;
case RTW89_NET_TYPE_NO_LINK:
default:
break;
}
}
static u16 __rtw89_cal_crc16(u8 data, u16 crc)
{
u8 shift_in, data_bit;
u8 crc_bit4, crc_bit11, crc_bit15;
u16 crc_result;
int index;
for (index = 0; index < 8; index++) {
crc_bit15 = crc & BIT(15) ? 1 : 0;
data_bit = data & BIT(index) ? 1 : 0;
shift_in = crc_bit15 ^ data_bit;
crc_result = crc << 1;
if (shift_in == 0)
crc_result &= ~BIT(0);
else
crc_result |= BIT(0);
crc_bit11 = (crc & BIT(11) ? 1 : 0) ^ shift_in;
if (crc_bit11 == 0)
crc_result &= ~BIT(12);
else
crc_result |= BIT(12);
crc_bit4 = (crc & BIT(4) ? 1 : 0) ^ shift_in;
if (crc_bit4 == 0)
crc_result &= ~BIT(5);
else
crc_result |= BIT(5);
crc = crc_result;
}
return crc;
}
static u16 rtw89_calc_crc(u8 *pdata, int length)
{
u16 crc = 0xffff;
int i;
for (i = 0; i < length; i++)
crc = __rtw89_cal_crc16(pdata[i], crc);
/* get 1' complement */
return ~crc;
}
static int rtw89_wow_pattern_get_type(struct rtw89_vif *rtwvif,
struct rtw89_wow_cam_info *rtw_pattern,
const u8 *pattern, u8 da_mask)
{
u8 da[ETH_ALEN];
ether_addr_copy_mask(da, pattern, da_mask);
/* Each pattern is divided into different kinds by DA address
* a. DA is broadcast address: set bc = 0;
* b. DA is multicast address: set mc = 0
* c. DA is unicast address same as dev's mac address: set uc = 0
* d. DA is unmasked. Also called wildcard type: set uc = bc = mc = 0
* e. Others is invalid type.
*/
if (is_broadcast_ether_addr(da))
rtw_pattern->bc = true;
else if (is_multicast_ether_addr(da))
rtw_pattern->mc = true;
else if (ether_addr_equal(da, rtwvif->mac_addr) &&
da_mask == GENMASK(5, 0))
rtw_pattern->uc = true;
else if (!da_mask) /*da_mask == 0 mean wildcard*/
return 0;
else
return -EPERM;
return 0;
}
static int rtw89_wow_pattern_generate(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
const struct cfg80211_pkt_pattern *pkt_pattern,
struct rtw89_wow_cam_info *rtw_pattern)
{
u8 mask_hw[RTW89_MAX_PATTERN_MASK_SIZE * 4] = {0};
u8 content[RTW89_MAX_PATTERN_SIZE] = {0};
const u8 *mask;
const u8 *pattern;
u8 mask_len;
u16 count;
u32 len;
int i, ret;
pattern = pkt_pattern->pattern;
len = pkt_pattern->pattern_len;
mask = pkt_pattern->mask;
mask_len = DIV_ROUND_UP(len, 8);
memset(rtw_pattern, 0, sizeof(*rtw_pattern));
ret = rtw89_wow_pattern_get_type(rtwvif, rtw_pattern, pattern,
mask[0] & GENMASK(5, 0));
if (ret)
return ret;
/* translate mask from os to mask for hw
* pattern from OS uses 'ethenet frame', like this:
* | 6 | 6 | 2 | 20 | Variable | 4 |
* |--------+--------+------+-----------+------------+-----|
* | 802.3 Mac Header | IP Header | TCP Packet | FCS |
* | DA | SA | Type |
*
* BUT, packet catched by our HW is in '802.11 frame', begin from LLC
* | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
* |-------------------+--------+------+-----------+------------+-----|
* | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
* | Others | Tpye |
*
* Therefore, we need translate mask_from_OS to mask_to_hw.
* We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
* because new mask[0~5] means 'SA', but our HW packet begins from LLC,
* bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
*/
/* Shift 6 bits */
for (i = 0; i < mask_len - 1; i++) {
mask_hw[i] = u8_get_bits(mask[i], GENMASK(7, 6)) |
u8_get_bits(mask[i + 1], GENMASK(5, 0)) << 2;
}
mask_hw[i] = u8_get_bits(mask[i], GENMASK(7, 6));
/* Set bit 0-5 to zero */
mask_hw[0] &= ~GENMASK(5, 0);
memcpy(rtw_pattern->mask, mask_hw, sizeof(rtw_pattern->mask));
/* To get the wake up pattern from the mask.
* We do not count first 12 bits which means
* DA[6] and SA[6] in the pattern to match HW design.
*/
count = 0;
for (i = 12; i < len; i++) {
if ((mask[i / 8] >> (i % 8)) & 0x01) {
content[count] = pattern[i];
count++;
}
}
rtw_pattern->crc = rtw89_calc_crc(content, count);
return 0;
}
static int rtw89_wow_parse_patterns(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct cfg80211_wowlan *wowlan)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns;
int i;
int ret;
if (!wowlan->n_patterns || !wowlan->patterns)
return 0;
for (i = 0; i < wowlan->n_patterns; i++) {
rtw_pattern = &rtw_wow->patterns[i];
ret = rtw89_wow_pattern_generate(rtwdev, rtwvif,
&wowlan->patterns[i],
rtw_pattern);
if (ret) {
rtw89_err(rtwdev, "failed to generate pattern(%d)\n", i);
rtw_wow->pattern_cnt = 0;
return ret;
}
rtw_pattern->r_w = true;
rtw_pattern->idx = i;
rtw_pattern->negative_pattern_match = false;
rtw_pattern->skip_mac_hdr = true;
rtw_pattern->valid = true;
}
rtw_wow->pattern_cnt = wowlan->n_patterns;
return 0;
}
static void rtw89_wow_pattern_clear_cam(struct rtw89_dev *rtwdev)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns;
int i = 0;
for (i = 0; i < rtw_wow->pattern_cnt; i++) {
rtw_pattern = &rtw_wow->patterns[i];
rtw_pattern->valid = false;
rtw89_fw_wow_cam_update(rtwdev, rtw_pattern);
}
}
static void rtw89_wow_pattern_write(struct rtw89_dev *rtwdev)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns;
int i;
for (i = 0; i < rtw_wow->pattern_cnt; i++)
rtw89_fw_wow_cam_update(rtwdev, rtw_pattern + i);
}
static void rtw89_wow_pattern_clear(struct rtw89_dev *rtwdev)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
rtw89_wow_pattern_clear_cam(rtwdev);
rtw_wow->pattern_cnt = 0;
memset(rtw_wow->patterns, 0, sizeof(rtw_wow->patterns));
}
static void rtw89_wow_clear_wakeups(struct rtw89_dev *rtwdev)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
rtw_wow->wow_vif = NULL;
rtw89_core_release_all_bits_map(rtw_wow->flags, RTW89_WOW_FLAG_NUM);
rtw_wow->pattern_cnt = 0;
}
static int rtw89_wow_set_wakeups(struct rtw89_dev *rtwdev,
struct cfg80211_wowlan *wowlan)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct rtw89_vif *rtwvif;
if (wowlan->disconnect)
set_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags);
if (wowlan->magic_pkt)
set_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags);
rtw89_for_each_rtwvif(rtwdev, rtwvif)
rtw89_wow_vif_iter(rtwdev, rtwvif);
if (!rtw_wow->wow_vif)
return -EPERM;
rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv;
return rtw89_wow_parse_patterns(rtwdev, rtwvif, wowlan);
}
static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
struct ieee80211_sta *wow_sta;
struct rtw89_sta *rtwsta = NULL;
int ret;
wow_sta = ieee80211_find_sta(wow_vif, rtwvif->bssid);
if (wow_sta)
rtwsta = (struct rtw89_sta *)wow_sta->drv_priv;
if (wow) {
if (rtw_wow->pattern_cnt)
rtwvif->wowlan_pattern = true;
if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags))
rtwvif->wowlan_magic = true;
} else {
rtwvif->wowlan_pattern = false;
rtwvif->wowlan_magic = false;
}
ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif, wow);
if (ret) {
rtw89_err(rtwdev, "failed to fw wow wakeup ctrl\n");
return ret;
}
if (wow) {
ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
if (ret) {
rtw89_err(rtwdev, "failed to update dctl cam sec entry: %d\n",
ret);
return ret;
}
}
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c cam\n");
return ret;
}
ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif, wow);
if (ret) {
rtw89_err(rtwdev, "failed to fw wow global\n");
return ret;
}
return 0;
}
static int rtw89_wow_check_fw_status(struct rtw89_dev *rtwdev, bool wow_enable)
{
u8 polling;
int ret;
ret = read_poll_timeout_atomic(rtw89_read8_mask, polling,
wow_enable == !!polling,
50, 50000, false, rtwdev,
R_AX_WOW_CTRL, B_AX_WOW_WOWEN);
if (ret)
rtw89_err(rtwdev, "failed to check wow status %s\n",
wow_enable ? "enabled" : "disabled");
return ret;
}
static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
{
enum rtw89_fw_type fw_type = wow ? RTW89_FW_WOWLAN : RTW89_FW_NORMAL;
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
struct ieee80211_sta *wow_sta;
struct rtw89_sta *rtwsta = NULL;
bool is_conn = true;
int ret;
rtw89_hci_disable_intr(rtwdev);
wow_sta = ieee80211_find_sta(wow_vif, rtwvif->bssid);
if (wow_sta)
rtwsta = (struct rtw89_sta *)wow_sta->drv_priv;
else
is_conn = false;
ret = rtw89_fw_download(rtwdev, fw_type);
if (ret) {
rtw89_warn(rtwdev, "download fw failed\n");
return ret;
}
rtw89_phy_init_rf_reg(rtwdev, true);
ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta,
RTW89_ROLE_FW_RESTORE);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c role maintain\n");
return ret;
}
ret = rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, wow_vif, wow_sta);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c assoc cmac tbl\n");
return ret;
}
if (!is_conn)
rtw89_cam_reset_keys(rtwdev);
ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, rtwsta, !is_conn);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c join info\n");
return ret;
}
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c cam\n");
return ret;
}
if (is_conn) {
ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif, rtwsta->mac_id);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c general packet\n");
return ret;
}
rtw89_phy_ra_assoc(rtwdev, wow_sta);
rtw89_phy_set_bss_color(rtwdev, wow_vif);
rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, wow_vif);
}
rtw89_mac_hw_mgnt_sec(rtwdev, wow);
rtw89_hci_enable_intr(rtwdev);
return 0;
}
static int rtw89_wow_enable_trx_pre(struct rtw89_dev *rtwdev)
{
int ret;
rtw89_hci_ctrl_txdma_ch(rtwdev, false);
rtw89_hci_ctrl_txdma_fw_ch(rtwdev, true);
rtw89_mac_ptk_drop_by_band_and_wait(rtwdev, RTW89_MAC_0);
ret = rtw89_hci_poll_txdma_ch(rtwdev);
if (ret) {
rtw89_err(rtwdev, "txdma ch busy\n");
return ret;
}
rtw89_wow_set_rx_filter(rtwdev, true);
ret = rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false);
if (ret) {
rtw89_err(rtwdev, "cfg ppdu status\n");
return ret;
}
return 0;
}
static int rtw89_wow_enable_trx_post(struct rtw89_dev *rtwdev)
{
int ret;
rtw89_hci_disable_intr(rtwdev);
rtw89_hci_ctrl_trxhci(rtwdev, false);
ret = rtw89_hci_poll_txdma_ch(rtwdev);
if (ret) {
rtw89_err(rtwdev, "failed to poll txdma ch idle pcie\n");
return ret;
}
ret = rtw89_wow_config_mac(rtwdev, true);
if (ret) {
rtw89_err(rtwdev, "failed to config mac\n");
return ret;
}
rtw89_wow_set_rx_filter(rtwdev, false);
rtw89_hci_reset(rtwdev);
return 0;
}
static int rtw89_wow_disable_trx_pre(struct rtw89_dev *rtwdev)
{
int ret;
rtw89_hci_clr_idx_all(rtwdev);
ret = rtw89_hci_rst_bdram(rtwdev);
if (ret) {
rtw89_warn(rtwdev, "reset bdram busy\n");
return ret;
}
rtw89_hci_ctrl_trxhci(rtwdev, true);
rtw89_hci_ctrl_txdma_ch(rtwdev, true);
ret = rtw89_wow_config_mac(rtwdev, false);
if (ret) {
rtw89_err(rtwdev, "failed to config mac\n");
return ret;
}
rtw89_hci_enable_intr(rtwdev);
return 0;
}
static int rtw89_wow_disable_trx_post(struct rtw89_dev *rtwdev)
{
int ret;
ret = rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true);
if (ret)
rtw89_err(rtwdev, "cfg ppdu status\n");
return ret;
}
static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv;
int ret;
rtw89_wow_pattern_write(rtwdev);
ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif, true);
if (ret) {
rtw89_err(rtwdev, "wow: failed to enable keep alive\n");
return ret;
}
ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif, true);
if (ret) {
rtw89_err(rtwdev, "wow: failed to enable disconnect detect\n");
goto out;
}
ret = rtw89_wow_cfg_wake(rtwdev, true);
if (ret) {
rtw89_err(rtwdev, "wow: failed to config wake\n");
goto out;
}
ret = rtw89_wow_check_fw_status(rtwdev, true);
if (ret) {
rtw89_err(rtwdev, "wow: failed to check enable fw ready\n");
goto out;
}
out:
return ret;
}
static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv;
int ret;
rtw89_wow_pattern_clear(rtwdev);
ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif, false);
if (ret) {
rtw89_err(rtwdev, "wow: failed to disable keep alive\n");
goto out;
}
ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif, false);
if (ret) {
rtw89_err(rtwdev, "wow: failed to disable disconnect detect\n");
goto out;
}
ret = rtw89_wow_cfg_wake(rtwdev, false);
if (ret) {
rtw89_err(rtwdev, "wow: failed to disable config wake\n");
goto out;
}
rtw89_fw_release_general_pkt_list(rtwdev, true);
ret = rtw89_wow_check_fw_status(rtwdev, false);
if (ret) {
rtw89_err(rtwdev, "wow: failed to check disable fw ready\n");
goto out;
}
out:
return ret;
}
static int rtw89_wow_enable(struct rtw89_dev *rtwdev)
{
int ret;
set_bit(RTW89_FLAG_WOWLAN, rtwdev->flags);
ret = rtw89_wow_enable_trx_pre(rtwdev);
if (ret) {
rtw89_err(rtwdev, "wow: failed to enable trx_pre\n");
goto out;
}
rtw89_fw_release_general_pkt_list(rtwdev, true);
ret = rtw89_wow_swap_fw(rtwdev, true);
if (ret) {
rtw89_err(rtwdev, "wow: failed to swap to wow fw\n");
goto out;
}
ret = rtw89_wow_fw_start(rtwdev);
if (ret) {
rtw89_err(rtwdev, "wow: failed to let wow fw start\n");
goto out;
}
rtw89_wow_enter_lps(rtwdev);
ret = rtw89_wow_enable_trx_post(rtwdev);
if (ret) {
rtw89_err(rtwdev, "wow: failed to enable trx_post\n");
goto out;
}
return 0;
out:
clear_bit(RTW89_FLAG_WOWLAN, rtwdev->flags);
return ret;
}
static int rtw89_wow_disable(struct rtw89_dev *rtwdev)
{
int ret;
ret = rtw89_wow_disable_trx_pre(rtwdev);
if (ret) {
rtw89_err(rtwdev, "wow: failed to disable trx_pre\n");
goto out;
}
rtw89_wow_leave_lps(rtwdev);
ret = rtw89_wow_fw_stop(rtwdev);
if (ret) {
rtw89_err(rtwdev, "wow: failed to swap to normal fw\n");
goto out;
}
ret = rtw89_wow_swap_fw(rtwdev, false);
if (ret) {
rtw89_err(rtwdev, "wow: failed to disable trx_post\n");
goto out;
}
ret = rtw89_wow_disable_trx_post(rtwdev);
if (ret) {
rtw89_err(rtwdev, "wow: failed to disable trx_pre\n");
goto out;
}
out:
clear_bit(RTW89_FLAG_WOWLAN, rtwdev->flags);
return ret;
}
int rtw89_wow_resume(struct rtw89_dev *rtwdev)
{
int ret;
if (!test_bit(RTW89_FLAG_WOWLAN, rtwdev->flags)) {
rtw89_err(rtwdev, "wow is not enabled\n");
ret = -EPERM;
goto out;
}
if (!rtw89_mac_get_power_state(rtwdev)) {
rtw89_err(rtwdev, "chip is no power when resume\n");
ret = -EPERM;
goto out;
}
rtw89_wow_leave_deep_ps(rtwdev);
rtw89_wow_show_wakeup_reason(rtwdev);
ret = rtw89_wow_disable(rtwdev);
if (ret)
rtw89_err(rtwdev, "failed to disable wow\n");
out:
rtw89_wow_clear_wakeups(rtwdev);
return ret;
}
int rtw89_wow_suspend(struct rtw89_dev *rtwdev, struct cfg80211_wowlan *wowlan)
{
int ret;
ret = rtw89_wow_set_wakeups(rtwdev, wowlan);
if (ret) {
rtw89_err(rtwdev, "failed to set wakeup event\n");
return ret;
}
rtw89_wow_leave_lps(rtwdev);
ret = rtw89_wow_enable(rtwdev);
if (ret) {
rtw89_err(rtwdev, "failed to enable wow\n");
return ret;
}
rtw89_wow_enter_deep_ps(rtwdev);
return 0;
}

View file

@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2022 Realtek Corporation
*/
#ifndef __RTW89_WOW_H__
#define __RTW89_WOW_H__
enum rtw89_wake_reason {
RTW89_WOW_RSN_RX_PTK_REKEY = 0x1,
RTW89_WOW_RSN_RX_GTK_REKEY = 0x2,
RTW89_WOW_RSN_RX_DEAUTH = 0x8,
RTW89_WOW_RSN_DISCONNECT = 0x10,
RTW89_WOW_RSN_RX_MAGIC_PKT = 0x21,
RTW89_WOW_RSN_RX_PATTERN_MATCH = 0x23,
RTW89_WOW_RSN_RX_NLO = 0x55,
};
int rtw89_wow_suspend(struct rtw89_dev *rtwdev, struct cfg80211_wowlan *wowlan);
int rtw89_wow_resume(struct rtw89_dev *rtwdev);
#endif

View file

@ -10,22 +10,27 @@ KMOD= if_rtw89
SRCS= core.c
SRCS+= pci.c
SRCS+= chan.c mac80211.c mac.c phy.c fw.c
SRCS+= rtw8852a.c rtw8852a_table.c
SRCS+= rtw8852a_rfk.c rtw8852a_rfk_table.c
SRCS+= rtw8852a.c rtw8852a_rfk.c rtw8852a_rfk_table.c rtw8852a_table.c
SRCS+= rtw8852ae.c
SRCS+= rtw8852c.c rtw8852c_table.c
SRCS+= rtw8852c_rfk.c rtw8852c_rfk_table.c
SRCS+= rtw8852c.c rtw8852c_rfk.c rtw8852c_rfk_table.c rtw8852c_table.c
SRCS+= rtw8852ce.c
SRCS+= cam.c efuse.c regd.c sar.c coex.c ps.c ser.c
SRCS+= rtw8851b.c rtw8851b_rfk.c rtw8851b_rfk_table.c rtw8851b_table.c
SRCS+= rtw8851be.c
SRCS+= rtw8852b.c rtw8852b_rfk.c rtw8852b_rfk_table.c rtw8852b_table.c
SRCS+= rtw8852be.c
SRCS+= acpi.c cam.c efuse.c regd.c sar.c coex.c ps.c ser.c
# CONFIG_RTW89_DEBUG (always on for now)
SRCS+= debug.c
.if defined(WITH_CONFIG_PM) && ${WITH_CONFIG_PM} > 0
CFLAGS+= -DCONFIG_PM=${WITH_CONFIG_PM}
SRCS+= wow.c
.endif
# Other
SRCS+= ${LINUXKPI_GENSRCS}
SRCS+= opt_wlan.h opt_inet6.h opt_inet.h
SRCS+= opt_wlan.h opt_inet6.h opt_inet.h opt_acpi.h
CFLAGS+= -DKBUILD_MODNAME='"rtw89"'