rtw89: add Realtek 802.11ax driver
This driver named rtw89, which is the next generation of rtw88, supports Realtek 8852AE 802.11ax 2x2 chip whose new features are OFDMA, DBCC, Spatial reuse, TWT and BSS coloring; now some of them aren't implemented though. The chip architecture is entirely different from the chips supported by rtw88 like RTL8822CE 802.11ac chip. First of all, register address ranges are totally redefined, so it's impossible to reuse register definition. To communicate with firmware, new H2C/C2H format is proposed. In order to have better utilization, TX DMA flow is changed to two stages DMA. To provide rich RX status information, additional RX PPDU packets are added. Since there are so many differences mentioned above, we decide to propose a new driver. It has many authors, they are listed in alphabetic order: Chin-Yen Lee <timlee@realtek.com> Ping-Ke Shih <pkshih@realtek.com> Po Hao Huang <phhuang@realtek.com> Tzu-En Huang <tehuang@realtek.com> Vincent Fann <vincent_fann@realtek.com> Yan-Hsuan Chuang <tony0620emma@gmail.com> Zong-Zhe Yang <kevin_yang@realtek.com> Tested-by: Aaron Ma <aaron.ma@canonical.com> Tested-by: Brian Norris <briannorris@chromium.org> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Link: https://lore.kernel.org/r/20211008035627.19463-1-pkshih@realtek.com
This commit is contained in:
parent
9b793db5fc
commit
e3ec7017f6
@ -16,5 +16,6 @@ source "drivers/net/wireless/realtek/rtl818x/Kconfig"
|
||||
source "drivers/net/wireless/realtek/rtlwifi/Kconfig"
|
||||
source "drivers/net/wireless/realtek/rtl8xxxu/Kconfig"
|
||||
source "drivers/net/wireless/realtek/rtw88/Kconfig"
|
||||
source "drivers/net/wireless/realtek/rtw89/Kconfig"
|
||||
|
||||
endif # WLAN_VENDOR_REALTEK
|
||||
|
@ -8,4 +8,5 @@ obj-$(CONFIG_RTL8187) += rtl818x/
|
||||
obj-$(CONFIG_RTLWIFI) += rtlwifi/
|
||||
obj-$(CONFIG_RTL8XXXU) += rtl8xxxu/
|
||||
obj-$(CONFIG_RTW88) += rtw88/
|
||||
obj-$(CONFIG_RTW89) += rtw89/
|
||||
|
||||
|
50
drivers/net/wireless/realtek/rtw89/Kconfig
Normal file
50
drivers/net/wireless/realtek/rtw89/Kconfig
Normal file
@ -0,0 +1,50 @@
|
||||
# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
menuconfig RTW89
|
||||
tristate "Realtek 802.11ax wireless chips support"
|
||||
depends on MAC80211
|
||||
help
|
||||
This module adds support for mac80211-based wireless drivers that
|
||||
enables Realtek IEEE 802.11ax wireless chipsets.
|
||||
|
||||
If you choose to build a module, it'll be called rtw89.
|
||||
|
||||
if RTW89
|
||||
|
||||
config RTW89_CORE
|
||||
tristate
|
||||
|
||||
config RTW89_PCI
|
||||
tristate
|
||||
|
||||
config RTW89_8852AE
|
||||
tristate "Realtek 8852AE PCI wireless network adapter"
|
||||
depends on PCI
|
||||
select RTW89_CORE
|
||||
select RTW89_PCI
|
||||
help
|
||||
Select this option will enable support for 8852AE chipset
|
||||
|
||||
802.11ax PCIe wireless network adapter
|
||||
|
||||
config RTW89_DEBUG
|
||||
bool
|
||||
|
||||
config RTW89_DEBUGMSG
|
||||
bool "Realtek rtw89 debug message support"
|
||||
depends on RTW89_CORE
|
||||
select RTW89_DEBUG
|
||||
help
|
||||
Enable debug message support
|
||||
|
||||
If unsure, say Y to simplify debug problems
|
||||
|
||||
config RTW89_DEBUGFS
|
||||
bool "Realtek rtw89 debugfs support"
|
||||
depends on RTW89_CORE
|
||||
select RTW89_DEBUG
|
||||
help
|
||||
Enable debugfs support
|
||||
|
||||
If unsure, say Y to simplify debug problems
|
||||
|
||||
endif
|
25
drivers/net/wireless/realtek/rtw89/Makefile
Normal file
25
drivers/net/wireless/realtek/rtw89/Makefile
Normal file
@ -0,0 +1,25 @@
|
||||
# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
|
||||
obj-$(CONFIG_RTW89_CORE) += rtw89_core.o
|
||||
rtw89_core-y += core.o \
|
||||
mac80211.o \
|
||||
mac.o \
|
||||
phy.o \
|
||||
fw.o \
|
||||
rtw8852a.o \
|
||||
rtw8852a_table.o \
|
||||
rtw8852a_rfk.o \
|
||||
rtw8852a_rfk_table.o \
|
||||
cam.o \
|
||||
efuse.o \
|
||||
regd.o \
|
||||
sar.o \
|
||||
coex.o \
|
||||
ps.o \
|
||||
ser.o
|
||||
|
||||
rtw89_core-$(CONFIG_RTW89_DEBUG) += debug.o
|
||||
|
||||
obj-$(CONFIG_RTW89_PCI) += rtw89_pci.o
|
||||
rtw89_pci-y := pci.o
|
||||
|
695
drivers/net/wireless/realtek/rtw89/cam.c
Normal file
695
drivers/net/wireless/realtek/rtw89/cam.c
Normal file
@ -0,0 +1,695 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#include "cam.h"
|
||||
#include "debug.h"
|
||||
#include "fw.h"
|
||||
#include "mac.h"
|
||||
|
||||
static struct sk_buff *
|
||||
rtw89_cam_get_sec_key_cmd(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_sec_cam_entry *sec_cam,
|
||||
bool ext_key)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
u32 cmd_len = H2C_SEC_CAM_LEN;
|
||||
u32 key32[4];
|
||||
u8 *cmd;
|
||||
int i, j;
|
||||
|
||||
skb = rtw89_fw_h2c_alloc_skb_with_hdr(cmd_len);
|
||||
if (!skb)
|
||||
return NULL;
|
||||
|
||||
skb_put_zero(skb, cmd_len);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
j = i * 4;
|
||||
j += ext_key ? 16 : 0;
|
||||
key32[i] = FIELD_PREP(GENMASK(7, 0), sec_cam->key[j + 0]) |
|
||||
FIELD_PREP(GENMASK(15, 8), sec_cam->key[j + 1]) |
|
||||
FIELD_PREP(GENMASK(23, 16), sec_cam->key[j + 2]) |
|
||||
FIELD_PREP(GENMASK(31, 24), sec_cam->key[j + 3]);
|
||||
}
|
||||
|
||||
cmd = skb->data;
|
||||
RTW89_SET_FWCMD_SEC_IDX(cmd, sec_cam->sec_cam_idx + (ext_key ? 1 : 0));
|
||||
RTW89_SET_FWCMD_SEC_OFFSET(cmd, sec_cam->offset);
|
||||
RTW89_SET_FWCMD_SEC_LEN(cmd, sec_cam->len);
|
||||
RTW89_SET_FWCMD_SEC_TYPE(cmd, sec_cam->type);
|
||||
RTW89_SET_FWCMD_SEC_EXT_KEY(cmd, ext_key);
|
||||
RTW89_SET_FWCMD_SEC_SPP_MODE(cmd, sec_cam->spp_mode);
|
||||
RTW89_SET_FWCMD_SEC_KEY0(cmd, key32[0]);
|
||||
RTW89_SET_FWCMD_SEC_KEY1(cmd, key32[1]);
|
||||
RTW89_SET_FWCMD_SEC_KEY2(cmd, key32[2]);
|
||||
RTW89_SET_FWCMD_SEC_KEY3(cmd, key32[3]);
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static int rtw89_cam_send_sec_key_cmd(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_sec_cam_entry *sec_cam)
|
||||
{
|
||||
struct sk_buff *skb, *ext_skb;
|
||||
int ret;
|
||||
|
||||
skb = rtw89_cam_get_sec_key_cmd(rtwdev, sec_cam, false);
|
||||
if (!skb) {
|
||||
rtw89_err(rtwdev, "failed to get sec key command\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rtw89_h2c_pkt_set_hdr(rtwdev, skb,
|
||||
FWCMD_TYPE_H2C,
|
||||
H2C_CAT_MAC,
|
||||
H2C_CL_MAC_SEC_CAM,
|
||||
H2C_FUNC_MAC_SEC_UPD, 1, 0,
|
||||
H2C_SEC_CAM_LEN);
|
||||
ret = rtw89_h2c_tx(rtwdev, skb, false);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to send sec key h2c: %d\n", ret);
|
||||
dev_kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!sec_cam->ext_key)
|
||||
return 0;
|
||||
|
||||
ext_skb = rtw89_cam_get_sec_key_cmd(rtwdev, sec_cam, true);
|
||||
if (!skb) {
|
||||
rtw89_err(rtwdev, "failed to get ext sec key command\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rtw89_h2c_pkt_set_hdr(rtwdev, ext_skb,
|
||||
FWCMD_TYPE_H2C,
|
||||
H2C_CAT_MAC,
|
||||
H2C_CL_MAC_SEC_CAM,
|
||||
H2C_FUNC_MAC_SEC_UPD,
|
||||
1, 0, H2C_SEC_CAM_LEN);
|
||||
ret = rtw89_h2c_tx(rtwdev, ext_skb, false);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to send ext sec key h2c: %d\n", ret);
|
||||
dev_kfree_skb(ext_skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_cam_get_avail_sec_cam(struct rtw89_dev *rtwdev,
|
||||
u8 *sec_cam_idx, bool ext_key)
|
||||
{
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
|
||||
u8 sec_cam_num = chip->scam_num;
|
||||
u8 idx = 0;
|
||||
|
||||
if (!ext_key) {
|
||||
idx = find_first_zero_bit(cam_info->sec_cam_map, sec_cam_num);
|
||||
if (idx >= sec_cam_num)
|
||||
return -EBUSY;
|
||||
|
||||
set_bit(idx, cam_info->sec_cam_map);
|
||||
*sec_cam_idx = idx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
again:
|
||||
idx = find_next_zero_bit(cam_info->sec_cam_map, sec_cam_num, idx);
|
||||
if (idx >= sec_cam_num - 1)
|
||||
return -EBUSY;
|
||||
/* ext keys need two cam entries for 256-bit key */
|
||||
if (test_bit(idx + 1, cam_info->sec_cam_map)) {
|
||||
idx++;
|
||||
goto again;
|
||||
}
|
||||
|
||||
set_bit(idx, cam_info->sec_cam_map);
|
||||
set_bit(idx + 1, cam_info->sec_cam_map);
|
||||
*sec_cam_idx = idx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_cam_get_addr_cam_key_idx(struct rtw89_addr_cam_entry *addr_cam,
|
||||
struct rtw89_sec_cam_entry *sec_cam,
|
||||
struct ieee80211_key_conf *key,
|
||||
u8 *key_idx)
|
||||
{
|
||||
u8 idx;
|
||||
|
||||
/* RTW89_ADDR_CAM_SEC_NONE : not enabled
|
||||
* RTW89_ADDR_CAM_SEC_ALL_UNI : 0 - 6 unicast
|
||||
* RTW89_ADDR_CAM_SEC_NORMAL : 0 - 1 unicast, 2 - 4 group, 5 - 6 BIP
|
||||
* RTW89_ADDR_CAM_SEC_4GROUP : 0 - 1 unicast, 2 - 5 group, 6 BIP
|
||||
*/
|
||||
switch (addr_cam->sec_ent_mode) {
|
||||
case RTW89_ADDR_CAM_SEC_NONE:
|
||||
return -EINVAL;
|
||||
case RTW89_ADDR_CAM_SEC_ALL_UNI:
|
||||
if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
|
||||
return -EINVAL;
|
||||
idx = find_first_zero_bit(addr_cam->sec_cam_map,
|
||||
RTW89_SEC_CAM_IN_ADDR_CAM);
|
||||
if (idx >= RTW89_SEC_CAM_IN_ADDR_CAM)
|
||||
return -EBUSY;
|
||||
*key_idx = idx;
|
||||
break;
|
||||
case RTW89_ADDR_CAM_SEC_NORMAL:
|
||||
if (sec_cam->type == RTW89_SEC_KEY_TYPE_BIP_CCMP128) {
|
||||
idx = find_next_zero_bit(addr_cam->sec_cam_map,
|
||||
RTW89_SEC_CAM_IN_ADDR_CAM, 5);
|
||||
if (idx > 6)
|
||||
return -EBUSY;
|
||||
*key_idx = idx;
|
||||
break;
|
||||
}
|
||||
|
||||
if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
|
||||
idx = find_next_zero_bit(addr_cam->sec_cam_map,
|
||||
RTW89_SEC_CAM_IN_ADDR_CAM, 0);
|
||||
if (idx > 1)
|
||||
return -EBUSY;
|
||||
*key_idx = idx;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Group keys */
|
||||
idx = find_next_zero_bit(addr_cam->sec_cam_map,
|
||||
RTW89_SEC_CAM_IN_ADDR_CAM, 2);
|
||||
if (idx > 4)
|
||||
return -EBUSY;
|
||||
*key_idx = idx;
|
||||
break;
|
||||
case RTW89_ADDR_CAM_SEC_4GROUP:
|
||||
if (sec_cam->type == RTW89_SEC_KEY_TYPE_BIP_CCMP128) {
|
||||
if (test_bit(6, addr_cam->sec_cam_map))
|
||||
return -EINVAL;
|
||||
*key_idx = 6;
|
||||
break;
|
||||
}
|
||||
|
||||
if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
|
||||
idx = find_next_zero_bit(addr_cam->sec_cam_map,
|
||||
RTW89_SEC_CAM_IN_ADDR_CAM, 0);
|
||||
if (idx > 1)
|
||||
return -EBUSY;
|
||||
*key_idx = idx;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Group keys */
|
||||
idx = find_next_zero_bit(addr_cam->sec_cam_map,
|
||||
RTW89_SEC_CAM_IN_ADDR_CAM, 2);
|
||||
if (idx > 5)
|
||||
return -EBUSY;
|
||||
*key_idx = idx;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key,
|
||||
struct rtw89_sec_cam_entry *sec_cam)
|
||||
{
|
||||
struct rtw89_vif *rtwvif;
|
||||
struct rtw89_addr_cam_entry *addr_cam;
|
||||
u8 key_idx = 0;
|
||||
int ret;
|
||||
|
||||
if (!vif) {
|
||||
rtw89_err(rtwdev, "No iface for adding sec cam\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rtwvif = (struct rtw89_vif *)vif->drv_priv;
|
||||
addr_cam = &rtwvif->addr_cam;
|
||||
ret = rtw89_cam_get_addr_cam_key_idx(addr_cam, sec_cam, key, &key_idx);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to get addr cam key idx %d, %d\n",
|
||||
addr_cam->sec_ent_mode, sec_cam->type);
|
||||
return ret;
|
||||
}
|
||||
|
||||
key->hw_key_idx = key_idx;
|
||||
addr_cam->sec_ent_keyid[key_idx] = key->keyidx;
|
||||
addr_cam->sec_ent[key_idx] = sec_cam->sec_cam_idx;
|
||||
addr_cam->sec_entries[key_idx] = sec_cam;
|
||||
set_bit(key_idx, addr_cam->sec_cam_map);
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to update addr cam sec entry: %d\n",
|
||||
ret);
|
||||
clear_bit(key_idx, addr_cam->sec_cam_map);
|
||||
addr_cam->sec_entries[key_idx] = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_cam_sec_key_install(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key,
|
||||
u8 hw_key_type, bool ext_key)
|
||||
{
|
||||
struct rtw89_sec_cam_entry *sec_cam = NULL;
|
||||
struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
|
||||
u8 sec_cam_idx;
|
||||
int ret;
|
||||
|
||||
/* maximum key length 256-bit */
|
||||
if (key->keylen > 32) {
|
||||
rtw89_err(rtwdev, "invalid sec key length %d\n", key->keylen);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = rtw89_cam_get_avail_sec_cam(rtwdev, &sec_cam_idx, ext_key);
|
||||
if (ret) {
|
||||
rtw89_warn(rtwdev, "no available sec cam: %d ext: %d\n",
|
||||
ret, ext_key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sec_cam = kzalloc(sizeof(*sec_cam), GFP_KERNEL);
|
||||
if (!sec_cam) {
|
||||
ret = -ENOMEM;
|
||||
goto err_release_cam;
|
||||
}
|
||||
|
||||
sec_cam->sec_cam_idx = sec_cam_idx;
|
||||
sec_cam->type = hw_key_type;
|
||||
sec_cam->len = RTW89_SEC_CAM_LEN;
|
||||
sec_cam->ext_key = ext_key;
|
||||
memcpy(sec_cam->key, key->key, key->keylen);
|
||||
ret = rtw89_cam_send_sec_key_cmd(rtwdev, sec_cam);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to send sec key cmd: %d\n", ret);
|
||||
goto err_release_cam;
|
||||
}
|
||||
|
||||
/* associate with addr cam */
|
||||
ret = rtw89_cam_attach_sec_cam(rtwdev, vif, sta, key, sec_cam);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to attach sec cam: %d\n", ret);
|
||||
goto err_release_cam;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_release_cam:
|
||||
kfree(sec_cam);
|
||||
clear_bit(sec_cam_idx, cam_info->sec_cam_map);
|
||||
if (ext_key)
|
||||
clear_bit(sec_cam_idx + 1, cam_info->sec_cam_map);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key)
|
||||
{
|
||||
u8 hw_key_type;
|
||||
bool ext_key = false;
|
||||
int ret;
|
||||
|
||||
switch (key->cipher) {
|
||||
case WLAN_CIPHER_SUITE_WEP40:
|
||||
hw_key_type = RTW89_SEC_KEY_TYPE_WEP40;
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_WEP104:
|
||||
hw_key_type = RTW89_SEC_KEY_TYPE_WEP104;
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_CCMP:
|
||||
hw_key_type = RTW89_SEC_KEY_TYPE_CCMP128;
|
||||
key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_CCMP_256:
|
||||
hw_key_type = RTW89_SEC_KEY_TYPE_CCMP256;
|
||||
key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
|
||||
ext_key = true;
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_GCMP:
|
||||
hw_key_type = RTW89_SEC_KEY_TYPE_GCMP128;
|
||||
key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_GCMP_256:
|
||||
hw_key_type = RTW89_SEC_KEY_TYPE_GCMP256;
|
||||
key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
|
||||
ext_key = true;
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
|
||||
|
||||
ret = rtw89_cam_sec_key_install(rtwdev, vif, sta, key, hw_key_type,
|
||||
ext_key);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to install key type %d ext %d: %d\n",
|
||||
hw_key_type, ext_key, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtw89_cam_sec_key_del(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key,
|
||||
bool inform_fw)
|
||||
{
|
||||
struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
|
||||
struct rtw89_vif *rtwvif;
|
||||
struct rtw89_addr_cam_entry *addr_cam;
|
||||
struct rtw89_sec_cam_entry *sec_cam;
|
||||
u8 key_idx = key->hw_key_idx;
|
||||
u8 sec_cam_idx;
|
||||
int ret = 0;
|
||||
|
||||
if (!vif) {
|
||||
rtw89_err(rtwdev, "No iface for deleting sec cam\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rtwvif = (struct rtw89_vif *)vif->drv_priv;
|
||||
addr_cam = &rtwvif->addr_cam;
|
||||
sec_cam = addr_cam->sec_entries[key_idx];
|
||||
if (!sec_cam)
|
||||
return -EINVAL;
|
||||
|
||||
/* detach sec cam from addr cam */
|
||||
clear_bit(key_idx, addr_cam->sec_cam_map);
|
||||
addr_cam->sec_entries[key_idx] = NULL;
|
||||
if (inform_fw) {
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif);
|
||||
if (ret)
|
||||
rtw89_err(rtwdev, "failed to update cam del key: %d\n", ret);
|
||||
}
|
||||
|
||||
/* clear valid bit in addr cam will disable sec cam,
|
||||
* so we don't need to send H2C command again
|
||||
*/
|
||||
sec_cam_idx = sec_cam->sec_cam_idx;
|
||||
clear_bit(sec_cam_idx, cam_info->sec_cam_map);
|
||||
if (sec_cam->ext_key)
|
||||
clear_bit(sec_cam_idx + 1, cam_info->sec_cam_map);
|
||||
|
||||
kfree(sec_cam);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rtw89_cam_reset_key_iter(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key,
|
||||
void *data)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = (struct rtw89_dev *)data;
|
||||
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
|
||||
|
||||
rtw89_cam_sec_key_del(rtwdev, vif, sta, key, false);
|
||||
rtw89_cam_deinit(rtwdev, rtwvif);
|
||||
}
|
||||
|
||||
void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
|
||||
{
|
||||
struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
|
||||
struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
|
||||
struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
|
||||
|
||||
addr_cam->valid = false;
|
||||
bssid_cam->valid = false;
|
||||
clear_bit(addr_cam->addr_cam_idx, cam_info->addr_cam_map);
|
||||
clear_bit(bssid_cam->bssid_cam_idx, cam_info->bssid_cam_map);
|
||||
}
|
||||
|
||||
void rtw89_cam_reset_keys(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
rcu_read_lock();
|
||||
ieee80211_iter_keys_rcu(rtwdev->hw, NULL, rtw89_cam_reset_key_iter, rtwdev);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static int rtw89_cam_get_avail_addr_cam(struct rtw89_dev *rtwdev,
|
||||
u8 *addr_cam_idx)
|
||||
{
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
|
||||
u8 addr_cam_num = chip->acam_num;
|
||||
u8 idx;
|
||||
|
||||
idx = find_first_zero_bit(cam_info->addr_cam_map, addr_cam_num);
|
||||
if (idx >= addr_cam_num)
|
||||
return -EBUSY;
|
||||
|
||||
set_bit(idx, cam_info->addr_cam_map);
|
||||
*addr_cam_idx = idx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_cam_init_addr_cam(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif)
|
||||
{
|
||||
struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
|
||||
u8 addr_cam_idx;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
ret = rtw89_cam_get_avail_addr_cam(rtwdev, &addr_cam_idx);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to get available addr cam\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
addr_cam->addr_cam_idx = addr_cam_idx;
|
||||
addr_cam->len = ADDR_CAM_ENT_SIZE;
|
||||
addr_cam->offset = 0;
|
||||
addr_cam->valid = true;
|
||||
addr_cam->addr_mask = 0;
|
||||
addr_cam->mask_sel = RTW89_NO_MSK;
|
||||
bitmap_zero(addr_cam->sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM);
|
||||
ether_addr_copy(addr_cam->sma, rtwvif->mac_addr);
|
||||
|
||||
for (i = 0; i < RTW89_SEC_CAM_IN_ADDR_CAM; i++) {
|
||||
addr_cam->sec_ent_keyid[i] = 0;
|
||||
addr_cam->sec_ent[i] = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_cam_get_avail_bssid_cam(struct rtw89_dev *rtwdev,
|
||||
u8 *bssid_cam_idx)
|
||||
{
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
|
||||
u8 bssid_cam_num = chip->bcam_num;
|
||||
u8 idx;
|
||||
|
||||
idx = find_first_zero_bit(cam_info->bssid_cam_map, bssid_cam_num);
|
||||
if (idx >= bssid_cam_num)
|
||||
return -EBUSY;
|
||||
|
||||
set_bit(idx, cam_info->bssid_cam_map);
|
||||
*bssid_cam_idx = idx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif)
|
||||
{
|
||||
struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
|
||||
u8 bssid_cam_idx;
|
||||
int ret;
|
||||
|
||||
ret = rtw89_cam_get_avail_bssid_cam(rtwdev, &bssid_cam_idx);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to get available bssid cam\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
bssid_cam->bssid_cam_idx = bssid_cam_idx;
|
||||
bssid_cam->phy_idx = rtwvif->phy_idx;
|
||||
bssid_cam->len = BSSID_CAM_ENT_SIZE;
|
||||
bssid_cam->offset = 0;
|
||||
bssid_cam->valid = true;
|
||||
ether_addr_copy(bssid_cam->bssid, rtwvif->bssid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
|
||||
{
|
||||
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
|
||||
struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
|
||||
struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION)
|
||||
ether_addr_copy(addr_cam->tma, rtwvif->bssid);
|
||||
ether_addr_copy(bssid_cam->bssid, rtwvif->bssid);
|
||||
}
|
||||
|
||||
int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
|
||||
{
|
||||
struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
|
||||
struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
|
||||
int ret;
|
||||
|
||||
ret = rtw89_cam_init_addr_cam(rtwdev, rtwvif);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to init addr cam\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to init bssid cam\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* associate addr cam with bssid cam */
|
||||
addr_cam->bssid_cam_idx = bssid_cam->bssid_cam_idx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif, u8 *cmd)
|
||||
{
|
||||
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
|
||||
struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
|
||||
u8 bss_color = vif->bss_conf.he_bss_color.color;
|
||||
|
||||
FWCMD_SET_ADDR_BSSID_IDX(cmd, bssid_cam->bssid_cam_idx);
|
||||
FWCMD_SET_ADDR_BSSID_OFFSET(cmd, bssid_cam->offset);
|
||||
FWCMD_SET_ADDR_BSSID_LEN(cmd, bssid_cam->len);
|
||||
FWCMD_SET_ADDR_BSSID_VALID(cmd, bssid_cam->valid);
|
||||
FWCMD_SET_ADDR_BSSID_BB_SEL(cmd, bssid_cam->phy_idx);
|
||||
FWCMD_SET_ADDR_BSSID_BSS_COLOR(cmd, bss_color);
|
||||
|
||||
FWCMD_SET_ADDR_BSSID_BSSID0(cmd, bssid_cam->bssid[0]);
|
||||
FWCMD_SET_ADDR_BSSID_BSSID1(cmd, bssid_cam->bssid[1]);
|
||||
FWCMD_SET_ADDR_BSSID_BSSID2(cmd, bssid_cam->bssid[2]);
|
||||
FWCMD_SET_ADDR_BSSID_BSSID3(cmd, bssid_cam->bssid[3]);
|
||||
FWCMD_SET_ADDR_BSSID_BSSID4(cmd, bssid_cam->bssid[4]);
|
||||
FWCMD_SET_ADDR_BSSID_BSSID5(cmd, bssid_cam->bssid[5]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 rtw89_cam_addr_hash(u8 start, u8 *addr)
|
||||
{
|
||||
u8 hash = 0;
|
||||
u8 i;
|
||||
|
||||
for (i = start; i < ETH_ALEN; i++)
|
||||
hash ^= addr[i];
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif,
|
||||
u8 *cmd)
|
||||
{
|
||||
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
|
||||
struct ieee80211_sta *sta;
|
||||
struct rtw89_sta *rtwsta;
|
||||
struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
|
||||
u8 sma_hash, tma_hash, addr_msk_start;
|
||||
u8 sma_start = 0;
|
||||
u8 tma_start = 0;
|
||||
|
||||
if (addr_cam->addr_mask != 0) {
|
||||
addr_msk_start = __ffs(addr_cam->addr_mask);
|
||||
if (addr_cam->mask_sel == RTW89_SMA)
|
||||
sma_start = addr_msk_start;
|
||||
else if (addr_cam->mask_sel == RTW89_TMA)
|
||||
tma_start = addr_msk_start;
|
||||
}
|
||||
sma_hash = rtw89_cam_addr_hash(sma_start, rtwvif->mac_addr);
|
||||
tma_hash = rtw89_cam_addr_hash(tma_start, addr_cam->tma);
|
||||
|
||||
FWCMD_SET_ADDR_IDX(cmd, addr_cam->addr_cam_idx);
|
||||
FWCMD_SET_ADDR_OFFSET(cmd, addr_cam->offset);
|
||||
FWCMD_SET_ADDR_LEN(cmd, addr_cam->len);
|
||||
|
||||
FWCMD_SET_ADDR_VALID(cmd, addr_cam->valid);
|
||||
FWCMD_SET_ADDR_NET_TYPE(cmd, rtwvif->net_type);
|
||||
FWCMD_SET_ADDR_BCN_HIT_COND(cmd, rtwvif->bcn_hit_cond);
|
||||
FWCMD_SET_ADDR_HIT_RULE(cmd, rtwvif->hit_rule);
|
||||
FWCMD_SET_ADDR_BB_SEL(cmd, rtwvif->phy_idx);
|
||||
FWCMD_SET_ADDR_ADDR_MASK(cmd, addr_cam->addr_mask);
|
||||
FWCMD_SET_ADDR_MASK_SEL(cmd, addr_cam->mask_sel);
|
||||
FWCMD_SET_ADDR_SMA_HASH(cmd, sma_hash);
|
||||
FWCMD_SET_ADDR_TMA_HASH(cmd, tma_hash);
|
||||
|
||||
FWCMD_SET_ADDR_BSSID_CAM_IDX(cmd, addr_cam->bssid_cam_idx);
|
||||
|
||||
FWCMD_SET_ADDR_SMA0(cmd, rtwvif->mac_addr[0]);
|
||||
FWCMD_SET_ADDR_SMA1(cmd, rtwvif->mac_addr[1]);
|
||||
FWCMD_SET_ADDR_SMA2(cmd, rtwvif->mac_addr[2]);
|
||||
FWCMD_SET_ADDR_SMA3(cmd, rtwvif->mac_addr[3]);
|
||||
FWCMD_SET_ADDR_SMA4(cmd, rtwvif->mac_addr[4]);
|
||||
FWCMD_SET_ADDR_SMA5(cmd, rtwvif->mac_addr[5]);
|
||||
|
||||
FWCMD_SET_ADDR_TMA0(cmd, addr_cam->tma[0]);
|
||||
FWCMD_SET_ADDR_TMA1(cmd, addr_cam->tma[1]);
|
||||
FWCMD_SET_ADDR_TMA2(cmd, addr_cam->tma[2]);
|
||||
FWCMD_SET_ADDR_TMA3(cmd, addr_cam->tma[3]);
|
||||
FWCMD_SET_ADDR_TMA4(cmd, addr_cam->tma[4]);
|
||||
FWCMD_SET_ADDR_TMA5(cmd, addr_cam->tma[5]);
|
||||
|
||||
FWCMD_SET_ADDR_PORT_INT(cmd, rtwvif->port);
|
||||
FWCMD_SET_ADDR_TSF_SYNC(cmd, rtwvif->port);
|
||||
FWCMD_SET_ADDR_TF_TRS(cmd, rtwvif->trigger);
|
||||
FWCMD_SET_ADDR_LSIG_TXOP(cmd, rtwvif->lsig_txop);
|
||||
FWCMD_SET_ADDR_TGT_IND(cmd, rtwvif->tgt_ind);
|
||||
FWCMD_SET_ADDR_FRM_TGT_IND(cmd, rtwvif->frm_tgt_ind);
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION) {
|
||||
sta = rtwvif->mgd.ap;
|
||||
if (sta) {
|
||||
rtwsta = (struct rtw89_sta *)sta->drv_priv;
|
||||
FWCMD_SET_ADDR_MACID(cmd, rtwsta->mac_id);
|
||||
FWCMD_SET_ADDR_AID12(cmd, vif->bss_conf.aid & 0xfff);
|
||||
}
|
||||
}
|
||||
FWCMD_SET_ADDR_WOL_PATTERN(cmd, rtwvif->wowlan_pattern);
|
||||
FWCMD_SET_ADDR_WOL_UC(cmd, rtwvif->wowlan_uc);
|
||||
FWCMD_SET_ADDR_WOL_MAGIC(cmd, rtwvif->wowlan_magic);
|
||||
FWCMD_SET_ADDR_WAPI(cmd, addr_cam->wapi);
|
||||
FWCMD_SET_ADDR_SEC_ENT_MODE(cmd, addr_cam->sec_ent_mode);
|
||||
FWCMD_SET_ADDR_SEC_ENT0_KEYID(cmd, addr_cam->sec_ent_keyid[0]);
|
||||
FWCMD_SET_ADDR_SEC_ENT1_KEYID(cmd, addr_cam->sec_ent_keyid[1]);
|
||||
FWCMD_SET_ADDR_SEC_ENT2_KEYID(cmd, addr_cam->sec_ent_keyid[2]);
|
||||
FWCMD_SET_ADDR_SEC_ENT3_KEYID(cmd, addr_cam->sec_ent_keyid[3]);
|
||||
FWCMD_SET_ADDR_SEC_ENT4_KEYID(cmd, addr_cam->sec_ent_keyid[4]);
|
||||
FWCMD_SET_ADDR_SEC_ENT5_KEYID(cmd, addr_cam->sec_ent_keyid[5]);
|
||||
FWCMD_SET_ADDR_SEC_ENT6_KEYID(cmd, addr_cam->sec_ent_keyid[6]);
|
||||
|
||||
FWCMD_SET_ADDR_SEC_ENT_VALID(cmd, addr_cam->sec_cam_map[0] & 0xff);
|
||||
FWCMD_SET_ADDR_SEC_ENT0(cmd, addr_cam->sec_ent[0]);
|
||||
FWCMD_SET_ADDR_SEC_ENT1(cmd, addr_cam->sec_ent[1]);
|
||||
FWCMD_SET_ADDR_SEC_ENT2(cmd, addr_cam->sec_ent[2]);
|
||||
FWCMD_SET_ADDR_SEC_ENT3(cmd, addr_cam->sec_ent[3]);
|
||||
FWCMD_SET_ADDR_SEC_ENT4(cmd, addr_cam->sec_ent[4]);
|
||||
FWCMD_SET_ADDR_SEC_ENT5(cmd, addr_cam->sec_ent[5]);
|
||||
FWCMD_SET_ADDR_SEC_ENT6(cmd, addr_cam->sec_ent[6]);
|
||||
}
|
165
drivers/net/wireless/realtek/rtw89/cam.h
Normal file
165
drivers/net/wireless/realtek/rtw89/cam.h
Normal file
@ -0,0 +1,165 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW89_CAM_H__
|
||||
#define __RTW89_CAM_H__
|
||||
|
||||
#include "core.h"
|
||||
|
||||
#define RTW89_SEC_CAM_LEN 20
|
||||
|
||||
#define FWCMD_SET_ADDR_IDX(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 1, value, GENMASK(7, 0))
|
||||
#define FWCMD_SET_ADDR_OFFSET(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 1, value, GENMASK(15, 8))
|
||||
#define FWCMD_SET_ADDR_LEN(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 1, value, GENMASK(23, 16))
|
||||
#define FWCMD_SET_ADDR_VALID(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 2, value, BIT(0))
|
||||
#define FWCMD_SET_ADDR_NET_TYPE(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(2, 1))
|
||||
#define FWCMD_SET_ADDR_BCN_HIT_COND(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(4, 3))
|
||||
#define FWCMD_SET_ADDR_HIT_RULE(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(6, 5))
|
||||
#define FWCMD_SET_ADDR_BB_SEL(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 2, value, BIT(7))
|
||||
#define FWCMD_SET_ADDR_ADDR_MASK(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(13, 8))
|
||||
#define FWCMD_SET_ADDR_MASK_SEL(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(15, 14))
|
||||
#define FWCMD_SET_ADDR_SMA_HASH(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(23, 16))
|
||||
#define FWCMD_SET_ADDR_TMA_HASH(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(31, 24))
|
||||
#define FWCMD_SET_ADDR_BSSID_CAM_IDX(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 3, value, GENMASK(5, 0))
|
||||
#define FWCMD_SET_ADDR_SMA0(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 4, value, GENMASK(7, 0))
|
||||
#define FWCMD_SET_ADDR_SMA1(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 4, value, GENMASK(15, 8))
|
||||
#define FWCMD_SET_ADDR_SMA2(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 4, value, GENMASK(23, 16))
|
||||
#define FWCMD_SET_ADDR_SMA3(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 4, value, GENMASK(31, 24))
|
||||
#define FWCMD_SET_ADDR_SMA4(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 5, value, GENMASK(7, 0))
|
||||
#define FWCMD_SET_ADDR_SMA5(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 5, value, GENMASK(15, 8))
|
||||
#define FWCMD_SET_ADDR_TMA0(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 5, value, GENMASK(23, 16))
|
||||
#define FWCMD_SET_ADDR_TMA1(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 5, value, GENMASK(31, 24))
|
||||
#define FWCMD_SET_ADDR_TMA2(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 6, value, GENMASK(7, 0))
|
||||
#define FWCMD_SET_ADDR_TMA3(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 6, value, GENMASK(15, 8))
|
||||
#define FWCMD_SET_ADDR_TMA4(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 6, value, GENMASK(23, 16))
|
||||
#define FWCMD_SET_ADDR_TMA5(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 6, value, GENMASK(31, 24))
|
||||
#define FWCMD_SET_ADDR_MACID(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 8, value, GENMASK(7, 0))
|
||||
#define FWCMD_SET_ADDR_PORT_INT(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 8, value, GENMASK(10, 8))
|
||||
#define FWCMD_SET_ADDR_TSF_SYNC(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 8, value, GENMASK(13, 11))
|
||||
#define FWCMD_SET_ADDR_TF_TRS(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 8, value, BIT(14))
|
||||
#define FWCMD_SET_ADDR_LSIG_TXOP(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 8, value, BIT(15))
|
||||
#define FWCMD_SET_ADDR_TGT_IND(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 8, value, GENMASK(26, 24))
|
||||
#define FWCMD_SET_ADDR_FRM_TGT_IND(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 8, value, GENMASK(29, 27))
|
||||
#define FWCMD_SET_ADDR_AID12(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(11, 0))
|
||||
#define FWCMD_SET_ADDR_AID12_0(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(7, 0))
|
||||
#define FWCMD_SET_ADDR_AID12_1(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(11, 8))
|
||||
#define FWCMD_SET_ADDR_WOL_PATTERN(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, BIT(12))
|
||||
#define FWCMD_SET_ADDR_WOL_UC(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, BIT(13))
|
||||
#define FWCMD_SET_ADDR_WOL_MAGIC(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, BIT(14))
|
||||
#define FWCMD_SET_ADDR_WAPI(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, BIT(15))
|
||||
#define FWCMD_SET_ADDR_SEC_ENT_MODE(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(17, 16))
|
||||
#define FWCMD_SET_ADDR_SEC_ENT0_KEYID(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(19, 18))
|
||||
#define FWCMD_SET_ADDR_SEC_ENT1_KEYID(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(21, 20))
|
||||
#define FWCMD_SET_ADDR_SEC_ENT2_KEYID(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(23, 22))
|
||||
#define FWCMD_SET_ADDR_SEC_ENT3_KEYID(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(25, 24))
|
||||
#define FWCMD_SET_ADDR_SEC_ENT4_KEYID(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(27, 26))
|
||||
#define FWCMD_SET_ADDR_SEC_ENT5_KEYID(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(29, 28))
|
||||
#define FWCMD_SET_ADDR_SEC_ENT6_KEYID(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(31, 30))
|
||||
#define FWCMD_SET_ADDR_SEC_ENT_VALID(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 10, value, GENMASK(7, 0))
|
||||
#define FWCMD_SET_ADDR_SEC_ENT0(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 10, value, GENMASK(15, 8))
|
||||
#define FWCMD_SET_ADDR_SEC_ENT1(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 10, value, GENMASK(23, 16))
|
||||
#define FWCMD_SET_ADDR_SEC_ENT2(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 10, value, GENMASK(31, 24))
|
||||
#define FWCMD_SET_ADDR_SEC_ENT3(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 11, value, GENMASK(7, 0))
|
||||
#define FWCMD_SET_ADDR_SEC_ENT4(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 11, value, GENMASK(15, 8))
|
||||
#define FWCMD_SET_ADDR_SEC_ENT5(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 11, value, GENMASK(23, 16))
|
||||
#define FWCMD_SET_ADDR_SEC_ENT6(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 11, value, GENMASK(31, 24))
|
||||
#define FWCMD_SET_ADDR_BSSID_IDX(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 12, value, GENMASK(7, 0))
|
||||
#define FWCMD_SET_ADDR_BSSID_OFFSET(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 12, value, GENMASK(15, 8))
|
||||
#define FWCMD_SET_ADDR_BSSID_LEN(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 12, value, GENMASK(23, 16))
|
||||
#define FWCMD_SET_ADDR_BSSID_VALID(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 13, value, BIT(0))
|
||||
#define FWCMD_SET_ADDR_BSSID_BB_SEL(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 13, value, BIT(1))
|
||||
#define FWCMD_SET_ADDR_BSSID_BSS_COLOR(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 13, value, GENMASK(13, 8))
|
||||
#define FWCMD_SET_ADDR_BSSID_BSSID0(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 13, value, GENMASK(23, 16))
|
||||
#define FWCMD_SET_ADDR_BSSID_BSSID1(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 13, value, GENMASK(31, 24))
|
||||
#define FWCMD_SET_ADDR_BSSID_BSSID2(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 14, value, GENMASK(7, 0))
|
||||
#define FWCMD_SET_ADDR_BSSID_BSSID3(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 14, value, GENMASK(15, 8))
|
||||
#define FWCMD_SET_ADDR_BSSID_BSSID4(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 14, value, GENMASK(23, 16))
|
||||
#define FWCMD_SET_ADDR_BSSID_BSSID5(cmd, value) \
|
||||
le32p_replace_bits((__le32 *)(cmd) + 14, value, GENMASK(31, 24))
|
||||
|
||||
int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
|
||||
void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
|
||||
void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *vif, u8 *cmd);
|
||||
int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *vif, u8 *cmd);
|
||||
int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key);
|
||||
int rtw89_cam_sec_key_del(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key,
|
||||
bool inform_fw);
|
||||
void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif);
|
||||
void rtw89_cam_reset_keys(struct rtw89_dev *rtwdev);
|
||||
#endif
|
5716
drivers/net/wireless/realtek/rtw89/coex.c
Normal file
5716
drivers/net/wireless/realtek/rtw89/coex.c
Normal file
File diff suppressed because it is too large
Load Diff
181
drivers/net/wireless/realtek/rtw89/coex.h
Normal file
181
drivers/net/wireless/realtek/rtw89/coex.h
Normal file
@ -0,0 +1,181 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW89_COEX_H__
|
||||
#define __RTW89_COEX_H__
|
||||
|
||||
#include "core.h"
|
||||
|
||||
enum btc_mode {
|
||||
BTC_MODE_NORMAL,
|
||||
BTC_MODE_WL,
|
||||
BTC_MODE_BT,
|
||||
BTC_MODE_WLOFF,
|
||||
BTC_MODE_MAX
|
||||
};
|
||||
|
||||
enum btc_wl_rfk_type {
|
||||
BTC_WRFKT_IQK = 0,
|
||||
BTC_WRFKT_LCK = 1,
|
||||
BTC_WRFKT_DPK = 2,
|
||||
BTC_WRFKT_TXGAPK = 3,
|
||||
BTC_WRFKT_DACK = 4,
|
||||
BTC_WRFKT_RXDCK = 5,
|
||||
BTC_WRFKT_TSSI = 6,
|
||||
};
|
||||
|
||||
#define NM_EXEC false
|
||||
#define FC_EXEC true
|
||||
|
||||
#define RTW89_COEX_ACT1_WORK_PERIOD round_jiffies_relative(HZ * 4)
|
||||
#define RTW89_COEX_BT_DEVINFO_WORK_PERIOD round_jiffies_relative(HZ * 16)
|
||||
#define RTW89_COEX_RFK_CHK_WORK_PERIOD msecs_to_jiffies(300)
|
||||
#define BTC_RFK_PATH_MAP GENMASK(3, 0)
|
||||
#define BTC_RFK_PHY_MAP GENMASK(5, 4)
|
||||
#define BTC_RFK_BAND_MAP GENMASK(7, 6)
|
||||
|
||||
enum btc_wl_rfk_state {
|
||||
BTC_WRFK_STOP = 0,
|
||||
BTC_WRFK_START = 1,
|
||||
BTC_WRFK_ONESHOT_START = 2,
|
||||
BTC_WRFK_ONESHOT_STOP = 3,
|
||||
};
|
||||
|
||||
enum btc_pri {
|
||||
BTC_PRI_MASK_RX_RESP = 0,
|
||||
BTC_PRI_MASK_TX_RESP,
|
||||
BTC_PRI_MASK_BEACON,
|
||||
BTC_PRI_MASK_RX_CCK,
|
||||
BTC_PRI_MASK_TX_MNGQ,
|
||||
BTC_PRI_MASK_MAX,
|
||||
};
|
||||
|
||||
enum btc_bt_trs {
|
||||
BTC_BT_SS_GROUP = 0x0,
|
||||
BTC_BT_TX_GROUP = 0x2,
|
||||
BTC_BT_RX_GROUP = 0x3,
|
||||
BTC_BT_MAX_GROUP,
|
||||
};
|
||||
|
||||
enum btc_rssi_st {
|
||||
BTC_RSSI_ST_LOW = 0x0,
|
||||
BTC_RSSI_ST_HIGH,
|
||||
BTC_RSSI_ST_STAY_LOW,
|
||||
BTC_RSSI_ST_STAY_HIGH,
|
||||
BTC_RSSI_ST_MAX
|
||||
};
|
||||
|
||||
#define BTC_RSSI_HIGH(_rssi_) \
|
||||
({typeof(_rssi_) __rssi = (_rssi_); \
|
||||
((__rssi == BTC_RSSI_ST_HIGH || \
|
||||
__rssi == BTC_RSSI_ST_STAY_HIGH) ? 1 : 0); })
|
||||
|
||||
#define BTC_RSSI_LOW(_rssi_) \
|
||||
({typeof(_rssi_) __rssi = (_rssi_); \
|
||||
((__rssi == BTC_RSSI_ST_LOW || \
|
||||
__rssi == BTC_RSSI_ST_STAY_LOW) ? 1 : 0); })
|
||||
|
||||
#define BTC_RSSI_CHANGE(_rssi_) \
|
||||
({typeof(_rssi_) __rssi = (_rssi_); \
|
||||
((__rssi == BTC_RSSI_ST_LOW || \
|
||||
__rssi == BTC_RSSI_ST_HIGH) ? 1 : 0); })
|
||||
|
||||
enum btc_ant {
|
||||
BTC_ANT_SHARED = 0,
|
||||
BTC_ANT_DEDICATED,
|
||||
BTC_ANTTYPE_MAX
|
||||
};
|
||||
|
||||
enum btc_bt_btg {
|
||||
BTC_BT_ALONE = 0,
|
||||
BTC_BT_BTG
|
||||
};
|
||||
|
||||
enum btc_switch {
|
||||
BTC_SWITCH_INTERNAL = 0,
|
||||
BTC_SWITCH_EXTERNAL
|
||||
};
|
||||
|
||||
enum btc_pkt_type {
|
||||
PACKET_DHCP,
|
||||
PACKET_ARP,
|
||||
PACKET_EAPOL,
|
||||
PACKET_EAPOL_END,
|
||||
PACKET_ICMP,
|
||||
PACKET_MAX
|
||||
};
|
||||
|
||||
enum btc_bt_mailbox_id {
|
||||
BTC_BTINFO_REPLY = 0x23,
|
||||
BTC_BTINFO_AUTO = 0x27
|
||||
};
|
||||
|
||||
enum btc_role_state {
|
||||
BTC_ROLE_START,
|
||||
BTC_ROLE_STOP,
|
||||
BTC_ROLE_CHG_TYPE,
|
||||
BTC_ROLE_MSTS_STA_CONN_START,
|
||||
BTC_ROLE_MSTS_STA_CONN_END,
|
||||
BTC_ROLE_MSTS_STA_DIS_CONN,
|
||||
BTC_ROLE_MSTS_AP_START,
|
||||
BTC_ROLE_MSTS_AP_STOP,
|
||||
BTC_ROLE_STATE_UNKNOWN
|
||||
};
|
||||
|
||||
enum btc_rfctrl {
|
||||
BTC_RFCTRL_WL_OFF,
|
||||
BTC_RFCTRL_WL_ON,
|
||||
BTC_RFCTRL_FW_CTRL,
|
||||
BTC_RFCTRL_MAX
|
||||
};
|
||||
|
||||
void rtw89_btc_ntfy_poweron(struct rtw89_dev *rtwdev);
|
||||
void rtw89_btc_ntfy_poweroff(struct rtw89_dev *rtwdev);
|
||||
void rtw89_btc_ntfy_init(struct rtw89_dev *rtwdev, u8 mode);
|
||||
void rtw89_btc_ntfy_scan_start(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band);
|
||||
void rtw89_btc_ntfy_scan_finish(struct rtw89_dev *rtwdev, u8 phy_idx);
|
||||
void rtw89_btc_ntfy_switch_band(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band);
|
||||
void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev,
|
||||
enum btc_pkt_type pkt_type);
|
||||
void rtw89_btc_ntfy_eapol_packet_work(struct work_struct *work);
|
||||
void rtw89_btc_ntfy_arp_packet_work(struct work_struct *work);
|
||||
void rtw89_btc_ntfy_dhcp_packet_work(struct work_struct *work);
|
||||
void rtw89_btc_ntfy_icmp_packet_work(struct work_struct *work);
|
||||
void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
|
||||
struct rtw89_sta *rtwsta, enum btc_role_state state);
|
||||
void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_state);
|
||||
void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map,
|
||||
enum btc_wl_rfk_type type,
|
||||
enum btc_wl_rfk_state state);
|
||||
void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev);
|
||||
void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
|
||||
u32 len, u8 class, u8 func);
|
||||
void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m);
|
||||
void rtw89_coex_act1_work(struct work_struct *work);
|
||||
void rtw89_coex_bt_devinfo_work(struct work_struct *work);
|
||||
void rtw89_coex_rfk_chk_work(struct work_struct *work);
|
||||
void rtw89_coex_power_on(struct rtw89_dev *rtwdev);
|
||||
|
||||
static inline u8 rtw89_btc_phymap(struct rtw89_dev *rtwdev,
|
||||
enum rtw89_phy_idx phy_idx,
|
||||
enum rtw89_rf_path_bit paths)
|
||||
{
|
||||
struct rtw89_hal *hal = &rtwdev->hal;
|
||||
u8 phy_map;
|
||||
|
||||
phy_map = FIELD_PREP(BTC_RFK_PATH_MAP, paths) |
|
||||
FIELD_PREP(BTC_RFK_PHY_MAP, BIT(phy_idx)) |
|
||||
FIELD_PREP(BTC_RFK_BAND_MAP, hal->current_band_type);
|
||||
|
||||
return phy_map;
|
||||
}
|
||||
|
||||
static inline u8 rtw89_btc_path_phymap(struct rtw89_dev *rtwdev,
|
||||
enum rtw89_phy_idx phy_idx,
|
||||
enum rtw89_rf_path path)
|
||||
{
|
||||
return rtw89_btc_phymap(rtwdev, phy_idx, BIT(path));
|
||||
}
|
||||
|
||||
#endif
|
2502
drivers/net/wireless/realtek/rtw89/core.c
Normal file
2502
drivers/net/wireless/realtek/rtw89/core.c
Normal file
File diff suppressed because it is too large
Load Diff
3384
drivers/net/wireless/realtek/rtw89/core.h
Normal file
3384
drivers/net/wireless/realtek/rtw89/core.h
Normal file
File diff suppressed because it is too large
Load Diff
2489
drivers/net/wireless/realtek/rtw89/debug.c
Normal file
2489
drivers/net/wireless/realtek/rtw89/debug.c
Normal file
File diff suppressed because it is too large
Load Diff
77
drivers/net/wireless/realtek/rtw89/debug.h
Normal file
77
drivers/net/wireless/realtek/rtw89/debug.h
Normal file
@ -0,0 +1,77 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW89_DEBUG_H__
|
||||
#define __RTW89_DEBUG_H__
|
||||
|
||||
#include "core.h"
|
||||
|
||||
enum rtw89_debug_mask {
|
||||
RTW89_DBG_TXRX = BIT(0),
|
||||
RTW89_DBG_RFK = BIT(1),
|
||||
RTW89_DBG_RFK_TRACK = BIT(2),
|
||||
RTW89_DBG_CFO = BIT(3),
|
||||
RTW89_DBG_TSSI = BIT(4),
|
||||
RTW89_DBG_TXPWR = BIT(5),
|
||||
RTW89_DBG_HCI = BIT(6),
|
||||
RTW89_DBG_RA = BIT(7),
|
||||
RTW89_DBG_REGD = BIT(8),
|
||||
RTW89_DBG_PHY_TRACK = BIT(9),
|
||||
RTW89_DBG_DIG = BIT(10),
|
||||
RTW89_DBG_SER = BIT(11),
|
||||
RTW89_DBG_FW = BIT(12),
|
||||
RTW89_DBG_BTC = BIT(13),
|
||||
RTW89_DBG_BF = BIT(14),
|
||||
};
|
||||
|
||||
enum rtw89_debug_mac_reg_sel {
|
||||
RTW89_DBG_SEL_MAC_00,
|
||||
RTW89_DBG_SEL_MAC_40,
|
||||
RTW89_DBG_SEL_MAC_80,
|
||||
RTW89_DBG_SEL_MAC_C0,
|
||||
RTW89_DBG_SEL_MAC_E0,
|
||||
RTW89_DBG_SEL_BB,
|
||||
RTW89_DBG_SEL_IQK,
|
||||
RTW89_DBG_SEL_RFC,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_RTW89_DEBUGFS
|
||||
void rtw89_debugfs_init(struct rtw89_dev *rtwdev);
|
||||
#else
|
||||
static inline void rtw89_debugfs_init(struct rtw89_dev *rtwdev) {}
|
||||
#endif
|
||||
|
||||
#define rtw89_info(rtwdev, a...) dev_info((rtwdev)->dev, ##a)
|
||||
#define rtw89_warn(rtwdev, a...) dev_warn((rtwdev)->dev, ##a)
|
||||
#define rtw89_err(rtwdev, a...) dev_err((rtwdev)->dev, ##a)
|
||||
|
||||
#ifdef CONFIG_RTW89_DEBUGMSG
|
||||
extern unsigned int rtw89_debug_mask;
|
||||
#define rtw89_debug(rtwdev, a...) __rtw89_debug(rtwdev, ##a)
|
||||
|
||||
__printf(3, 4)
|
||||
void __rtw89_debug(struct rtw89_dev *rtwdev,
|
||||
enum rtw89_debug_mask mask,
|
||||
const char *fmt, ...);
|
||||
static inline void rtw89_hex_dump(struct rtw89_dev *rtwdev,
|
||||
enum rtw89_debug_mask mask,
|
||||
const char *prefix_str,
|
||||
const void *buf, size_t len)
|
||||
{
|
||||
if (!(rtw89_debug_mask & mask))
|
||||
return;
|
||||
|
||||
print_hex_dump_bytes(prefix_str, DUMP_PREFIX_OFFSET, buf, len);
|
||||
}
|
||||
#else
|
||||
static inline void rtw89_debug(struct rtw89_dev *rtwdev,
|
||||
enum rtw89_debug_mask mask,
|
||||
const char *fmt, ...) {}
|
||||
static inline void rtw89_hex_dump(struct rtw89_dev *rtwdev,
|
||||
enum rtw89_debug_mask mask,
|
||||
const char *prefix_str,
|
||||
const void *buf, size_t len) {}
|
||||
#endif
|
||||
|
||||
#endif
|
188
drivers/net/wireless/realtek/rtw89/efuse.c
Normal file
188
drivers/net/wireless/realtek/rtw89/efuse.c
Normal file
@ -0,0 +1,188 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
#include "efuse.h"
|
||||
#include "reg.h"
|
||||
|
||||
enum rtw89_efuse_bank {
|
||||
RTW89_EFUSE_BANK_WIFI,
|
||||
RTW89_EFUSE_BANK_BT,
|
||||
};
|
||||
|
||||
static int rtw89_switch_efuse_bank(struct rtw89_dev *rtwdev,
|
||||
enum rtw89_efuse_bank bank)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
val = rtw89_read32_mask(rtwdev, R_AX_EFUSE_CTRL_1,
|
||||
B_AX_EF_CELL_SEL_MASK);
|
||||
if (bank == val)
|
||||
return 0;
|
||||
|
||||
rtw89_write32_mask(rtwdev, R_AX_EFUSE_CTRL_1, B_AX_EF_CELL_SEL_MASK,
|
||||
bank);
|
||||
|
||||
val = rtw89_read32_mask(rtwdev, R_AX_EFUSE_CTRL_1,
|
||||
B_AX_EF_CELL_SEL_MASK);
|
||||
if (bank == val)
|
||||
return 0;
|
||||
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
static int rtw89_dump_physical_efuse_map(struct rtw89_dev *rtwdev, u8 *map,
|
||||
u32 dump_addr, u32 dump_size)
|
||||
{
|
||||
u32 efuse_ctl;
|
||||
u32 addr;
|
||||
int ret;
|
||||
|
||||
rtw89_switch_efuse_bank(rtwdev, RTW89_EFUSE_BANK_WIFI);
|
||||
|
||||
for (addr = dump_addr; addr < dump_addr + dump_size; addr++) {
|
||||
efuse_ctl = u32_encode_bits(addr, B_AX_EF_ADDR_MASK);
|
||||
rtw89_write32(rtwdev, R_AX_EFUSE_CTRL, efuse_ctl & ~B_AX_EF_RDY);
|
||||
|
||||
ret = read_poll_timeout_atomic(rtw89_read32, efuse_ctl,
|
||||
efuse_ctl & B_AX_EF_RDY, 1, 1000000,
|
||||
true, rtwdev, R_AX_EFUSE_CTRL);
|
||||
if (ret)
|
||||
return -EBUSY;
|
||||
|
||||
*map++ = (u8)(efuse_ctl & 0xff);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define invalid_efuse_header(hdr1, hdr2) \
|
||||
((hdr1) == 0xff || (hdr2) == 0xff)
|
||||
#define invalid_efuse_content(word_en, i) \
|
||||
(((word_en) & BIT(i)) != 0x0)
|
||||
#define get_efuse_blk_idx(hdr1, hdr2) \
|
||||
((((hdr2) & 0xf0) >> 4) | (((hdr1) & 0x0f) << 4))
|
||||
#define block_idx_to_logical_idx(blk_idx, i) \
|
||||
(((blk_idx) << 3) + ((i) << 1))
|
||||
static int rtw89_dump_logical_efuse_map(struct rtw89_dev *rtwdev, u8 *phy_map,
|
||||
u8 *log_map)
|
||||
{
|
||||
u32 physical_size = rtwdev->chip->physical_efuse_size;
|
||||
u32 logical_size = rtwdev->chip->logical_efuse_size;
|
||||
u8 sec_ctrl_size = rtwdev->chip->sec_ctrl_efuse_size;
|
||||
u32 phy_idx = sec_ctrl_size;
|
||||
u32 log_idx;
|
||||
u8 hdr1, hdr2;
|
||||
u8 blk_idx;
|
||||
u8 word_en;
|
||||
int i;
|
||||
|
||||
while (phy_idx < physical_size - sec_ctrl_size) {
|
||||
hdr1 = phy_map[phy_idx];
|
||||
hdr2 = phy_map[phy_idx + 1];
|
||||
if (invalid_efuse_header(hdr1, hdr2))
|
||||
break;
|
||||
|
||||
blk_idx = get_efuse_blk_idx(hdr1, hdr2);
|
||||
word_en = hdr2 & 0xf;
|
||||
phy_idx += 2;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (invalid_efuse_content(word_en, i))
|
||||
continue;
|
||||
|
||||
log_idx = block_idx_to_logical_idx(blk_idx, i);
|
||||
if (phy_idx + 1 > physical_size - sec_ctrl_size - 1 ||
|
||||
log_idx + 1 > logical_size)
|
||||
return -EINVAL;
|
||||
|
||||
log_map[log_idx] = phy_map[phy_idx];
|
||||
log_map[log_idx + 1] = phy_map[phy_idx + 1];
|
||||
phy_idx += 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtw89_parse_efuse_map(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
u32 phy_size = rtwdev->chip->physical_efuse_size;
|
||||
u32 log_size = rtwdev->chip->logical_efuse_size;
|
||||
u8 *phy_map = NULL;
|
||||
u8 *log_map = NULL;
|
||||
int ret;
|
||||
|
||||
if (rtw89_read16(rtwdev, R_AX_SYS_WL_EFUSE_CTRL) & B_AX_AUTOLOAD_SUS)
|
||||
rtwdev->efuse.valid = true;
|
||||
else
|
||||
rtw89_warn(rtwdev, "failed to check efuse autoload\n");
|
||||
|
||||
phy_map = kmalloc(phy_size, GFP_KERNEL);
|
||||
log_map = kmalloc(log_size, GFP_KERNEL);
|
||||
|
||||
if (!phy_map || !log_map) {
|
||||
ret = -ENOMEM;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
ret = rtw89_dump_physical_efuse_map(rtwdev, phy_map, 0, phy_size);
|
||||
if (ret) {
|
||||
rtw89_warn(rtwdev, "failed to dump efuse physical map\n");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
memset(log_map, 0xff, log_size);
|
||||
ret = rtw89_dump_logical_efuse_map(rtwdev, phy_map, log_map);
|
||||
if (ret) {
|
||||
rtw89_warn(rtwdev, "failed to dump efuse logical map\n");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "log_map: ", log_map, log_size);
|
||||
|
||||
ret = rtwdev->chip->ops->read_efuse(rtwdev, log_map);
|
||||
if (ret) {
|
||||
rtw89_warn(rtwdev, "failed to read efuse map\n");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
out_free:
|
||||
kfree(log_map);
|
||||
kfree(phy_map);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rtw89_parse_phycap_map(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
u32 phycap_addr = rtwdev->chip->phycap_addr;
|
||||
u32 phycap_size = rtwdev->chip->phycap_size;
|
||||
u8 *phycap_map = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (!phycap_size)
|
||||
return 0;
|
||||
|
||||
phycap_map = kmalloc(phycap_size, GFP_KERNEL);
|
||||
if (!phycap_map)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = rtw89_dump_physical_efuse_map(rtwdev, phycap_map,
|
||||
phycap_addr, phycap_size);
|
||||
if (ret) {
|
||||
rtw89_warn(rtwdev, "failed to dump phycap map\n");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
ret = rtwdev->chip->ops->read_phycap(rtwdev, phycap_map);
|
||||
if (ret) {
|
||||
rtw89_warn(rtwdev, "failed to read phycap map\n");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
out_free:
|
||||
kfree(phycap_map);
|
||||
|
||||
return ret;
|
||||
}
|
13
drivers/net/wireless/realtek/rtw89/efuse.h
Normal file
13
drivers/net/wireless/realtek/rtw89/efuse.h
Normal file
@ -0,0 +1,13 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW89_EFUSE_H__
|
||||
#define __RTW89_EFUSE_H__
|
||||
|
||||
#include "core.h"
|
||||
|
||||
int rtw89_parse_efuse_map(struct rtw89_dev *rtwdev);
|
||||
int rtw89_parse_phycap_map(struct rtw89_dev *rtwdev);
|
||||
|
||||
#endif
|
1641
drivers/net/wireless/realtek/rtw89/fw.c
Normal file
1641
drivers/net/wireless/realtek/rtw89/fw.c
Normal file
File diff suppressed because it is too large
Load Diff
1378
drivers/net/wireless/realtek/rtw89/fw.h
Normal file
1378
drivers/net/wireless/realtek/rtw89/fw.h
Normal file
File diff suppressed because it is too large
Load Diff
3838
drivers/net/wireless/realtek/rtw89/mac.c
Normal file
3838
drivers/net/wireless/realtek/rtw89/mac.c
Normal file
File diff suppressed because it is too large
Load Diff
860
drivers/net/wireless/realtek/rtw89/mac.h
Normal file
860
drivers/net/wireless/realtek/rtw89/mac.h
Normal file
@ -0,0 +1,860 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW89_MAC_H__
|
||||
#define __RTW89_MAC_H__
|
||||
|
||||
#include "core.h"
|
||||
|
||||
#define MAC_MEM_DUMP_PAGE_SIZE 0x40000
|
||||
#define ADDR_CAM_ENT_SIZE 0x40
|
||||
#define BSSID_CAM_ENT_SIZE 0x08
|
||||
#define HFC_PAGE_UNIT 64
|
||||
|
||||
enum rtw89_mac_hwmod_sel {
|
||||
RTW89_DMAC_SEL = 0,
|
||||
RTW89_CMAC_SEL = 1,
|
||||
|
||||
RTW89_MAC_INVALID,
|
||||
};
|
||||
|
||||
enum rtw89_mac_fwd_target {
|
||||
RTW89_FWD_DONT_CARE = 0,
|
||||
RTW89_FWD_TO_HOST = 1,
|
||||
RTW89_FWD_TO_WLAN_CPU = 2
|
||||
};
|
||||
|
||||
enum rtw89_mac_wd_dma_intvl {
|
||||
RTW89_MAC_WD_DMA_INTVL_0S,
|
||||
RTW89_MAC_WD_DMA_INTVL_256NS,
|
||||
RTW89_MAC_WD_DMA_INTVL_512NS,
|
||||
RTW89_MAC_WD_DMA_INTVL_768NS,
|
||||
RTW89_MAC_WD_DMA_INTVL_1US,
|
||||
RTW89_MAC_WD_DMA_INTVL_1_5US,
|
||||
RTW89_MAC_WD_DMA_INTVL_2US,
|
||||
RTW89_MAC_WD_DMA_INTVL_4US,
|
||||
RTW89_MAC_WD_DMA_INTVL_8US,
|
||||
RTW89_MAC_WD_DMA_INTVL_16US,
|
||||
RTW89_MAC_WD_DMA_INTVL_DEF = 0xFE
|
||||
};
|
||||
|
||||
enum rtw89_mac_multi_tag_num {
|
||||
RTW89_MAC_TAG_NUM_1,
|
||||
RTW89_MAC_TAG_NUM_2,
|
||||
RTW89_MAC_TAG_NUM_3,
|
||||
RTW89_MAC_TAG_NUM_4,
|
||||
RTW89_MAC_TAG_NUM_5,
|
||||
RTW89_MAC_TAG_NUM_6,
|
||||
RTW89_MAC_TAG_NUM_7,
|
||||
RTW89_MAC_TAG_NUM_8,
|
||||
RTW89_MAC_TAG_NUM_DEF = 0xFE
|
||||
};
|
||||
|
||||
enum rtw89_mac_lbc_tmr {
|
||||
RTW89_MAC_LBC_TMR_8US = 0,
|
||||
RTW89_MAC_LBC_TMR_16US,
|
||||
RTW89_MAC_LBC_TMR_32US,
|
||||
RTW89_MAC_LBC_TMR_64US,
|
||||
RTW89_MAC_LBC_TMR_128US,
|
||||
RTW89_MAC_LBC_TMR_256US,
|
||||
RTW89_MAC_LBC_TMR_512US,
|
||||
RTW89_MAC_LBC_TMR_1MS,
|
||||
RTW89_MAC_LBC_TMR_2MS,
|
||||
RTW89_MAC_LBC_TMR_4MS,
|
||||
RTW89_MAC_LBC_TMR_8MS,
|
||||
RTW89_MAC_LBC_TMR_DEF = 0xFE
|
||||
};
|
||||
|
||||
enum rtw89_mac_cpuio_op_cmd_type {
|
||||
CPUIO_OP_CMD_GET_1ST_PID = 0,
|
||||
CPUIO_OP_CMD_GET_NEXT_PID = 1,
|
||||
CPUIO_OP_CMD_ENQ_TO_TAIL = 4,
|
||||
CPUIO_OP_CMD_ENQ_TO_HEAD = 5,
|
||||
CPUIO_OP_CMD_DEQ = 8,
|
||||
CPUIO_OP_CMD_DEQ_ENQ_ALL = 9,
|
||||
CPUIO_OP_CMD_DEQ_ENQ_TO_TAIL = 12
|
||||
};
|
||||
|
||||
enum rtw89_mac_wde_dle_port_id {
|
||||
WDE_DLE_PORT_ID_DISPATCH = 0,
|
||||
WDE_DLE_PORT_ID_PKTIN = 1,
|
||||
WDE_DLE_PORT_ID_CMAC0 = 3,
|
||||
WDE_DLE_PORT_ID_CMAC1 = 4,
|
||||
WDE_DLE_PORT_ID_CPU_IO = 6,
|
||||
WDE_DLE_PORT_ID_WDRLS = 7,
|
||||
WDE_DLE_PORT_ID_END = 8
|
||||
};
|
||||
|
||||
enum rtw89_mac_wde_dle_queid_wdrls {
|
||||
WDE_DLE_QUEID_TXOK = 0,
|
||||
WDE_DLE_QUEID_DROP_RETRY_LIMIT = 1,
|
||||
WDE_DLE_QUEID_DROP_LIFETIME_TO = 2,
|
||||
WDE_DLE_QUEID_DROP_MACID_DROP = 3,
|
||||
WDE_DLE_QUEID_NO_REPORT = 4
|
||||
};
|
||||
|
||||
enum rtw89_mac_ple_dle_port_id {
|
||||
PLE_DLE_PORT_ID_DISPATCH = 0,
|
||||
PLE_DLE_PORT_ID_MPDU = 1,
|
||||
PLE_DLE_PORT_ID_SEC = 2,
|
||||
PLE_DLE_PORT_ID_CMAC0 = 3,
|
||||
PLE_DLE_PORT_ID_CMAC1 = 4,
|
||||
PLE_DLE_PORT_ID_WDRLS = 5,
|
||||
PLE_DLE_PORT_ID_CPU_IO = 6,
|
||||
PLE_DLE_PORT_ID_PLRLS = 7,
|
||||
PLE_DLE_PORT_ID_END = 8
|
||||
};
|
||||
|
||||
enum rtw89_mac_ple_dle_queid_plrls {
|
||||
PLE_DLE_QUEID_NO_REPORT = 0x0
|
||||
};
|
||||
|
||||
enum rtw89_machdr_frame_type {
|
||||
RTW89_MGNT = 0,
|
||||
RTW89_CTRL = 1,
|
||||
RTW89_DATA = 2,
|
||||
};
|
||||
|
||||
enum rtw89_mac_dle_dfi_type {
|
||||
DLE_DFI_TYPE_FREEPG = 0,
|
||||
DLE_DFI_TYPE_QUOTA = 1,
|
||||
DLE_DFI_TYPE_PAGELLT = 2,
|
||||
DLE_DFI_TYPE_PKTINFO = 3,
|
||||
DLE_DFI_TYPE_PREPKTLLT = 4,
|
||||
DLE_DFI_TYPE_NXTPKTLLT = 5,
|
||||
DLE_DFI_TYPE_QLNKTBL = 6,
|
||||
DLE_DFI_TYPE_QEMPTY = 7,
|
||||
};
|
||||
|
||||
enum rtw89_mac_dle_wde_quota_id {
|
||||
WDE_QTAID_HOST_IF = 0,
|
||||
WDE_QTAID_WLAN_CPU = 1,
|
||||
WDE_QTAID_DATA_CPU = 2,
|
||||
WDE_QTAID_PKTIN = 3,
|
||||
WDE_QTAID_CPUIO = 4,
|
||||
};
|
||||
|
||||
enum rtw89_mac_dle_ple_quota_id {
|
||||
PLE_QTAID_B0_TXPL = 0,
|
||||
PLE_QTAID_B1_TXPL = 1,
|
||||
PLE_QTAID_C2H = 2,
|
||||
PLE_QTAID_H2C = 3,
|
||||
PLE_QTAID_WLAN_CPU = 4,
|
||||
PLE_QTAID_MPDU = 5,
|
||||
PLE_QTAID_CMAC0_RX = 6,
|
||||
PLE_QTAID_CMAC1_RX = 7,
|
||||
PLE_QTAID_CMAC1_BBRPT = 8,
|
||||
PLE_QTAID_WDRLS = 9,
|
||||
PLE_QTAID_CPUIO = 10,
|
||||
};
|
||||
|
||||
enum rtw89_mac_dle_ctrl_type {
|
||||
DLE_CTRL_TYPE_WDE = 0,
|
||||
DLE_CTRL_TYPE_PLE = 1,
|
||||
DLE_CTRL_TYPE_NUM = 2,
|
||||
};
|
||||
|
||||
enum rtw89_mac_ax_l0_to_l1_event {
|
||||
MAC_AX_L0_TO_L1_CHIF_IDLE = 0,
|
||||
MAC_AX_L0_TO_L1_CMAC_DMA_IDLE = 1,
|
||||
MAC_AX_L0_TO_L1_RLS_PKID = 2,
|
||||
MAC_AX_L0_TO_L1_PTCL_IDLE = 3,
|
||||
MAC_AX_L0_TO_L1_RX_QTA_LOST = 4,
|
||||
MAC_AX_L0_TO_L1_DLE_STAT_HANG = 5,
|
||||
MAC_AX_L0_TO_L1_PCIE_STUCK = 6,
|
||||
MAC_AX_L0_TO_L1_EVENT_MAX = 15,
|
||||
};
|
||||
|
||||
enum rtw89_mac_dbg_port_sel {
|
||||
/* CMAC 0 related */
|
||||
RTW89_DBG_PORT_SEL_PTCL_C0 = 0,
|
||||
RTW89_DBG_PORT_SEL_SCH_C0,
|
||||
RTW89_DBG_PORT_SEL_TMAC_C0,
|
||||
RTW89_DBG_PORT_SEL_RMAC_C0,
|
||||
RTW89_DBG_PORT_SEL_RMACST_C0,
|
||||
RTW89_DBG_PORT_SEL_RMAC_PLCP_C0,
|
||||
RTW89_DBG_PORT_SEL_TRXPTCL_C0,
|
||||
RTW89_DBG_PORT_SEL_TX_INFOL_C0,
|
||||
RTW89_DBG_PORT_SEL_TX_INFOH_C0,
|
||||
RTW89_DBG_PORT_SEL_TXTF_INFOL_C0,
|
||||
RTW89_DBG_PORT_SEL_TXTF_INFOH_C0,
|
||||
/* CMAC 1 related */
|
||||
RTW89_DBG_PORT_SEL_PTCL_C1,
|
||||
RTW89_DBG_PORT_SEL_SCH_C1,
|
||||
RTW89_DBG_PORT_SEL_TMAC_C1,
|
||||
RTW89_DBG_PORT_SEL_RMAC_C1,
|
||||
RTW89_DBG_PORT_SEL_RMACST_C1,
|
||||
RTW89_DBG_PORT_SEL_RMAC_PLCP_C1,
|
||||
RTW89_DBG_PORT_SEL_TRXPTCL_C1,
|
||||
RTW89_DBG_PORT_SEL_TX_INFOL_C1,
|
||||
RTW89_DBG_PORT_SEL_TX_INFOH_C1,
|
||||
RTW89_DBG_PORT_SEL_TXTF_INFOL_C1,
|
||||
RTW89_DBG_PORT_SEL_TXTF_INFOH_C1,
|
||||
/* DLE related */
|
||||
RTW89_DBG_PORT_SEL_WDE_BUFMGN_FREEPG,
|
||||
RTW89_DBG_PORT_SEL_WDE_BUFMGN_QUOTA,
|
||||
RTW89_DBG_PORT_SEL_WDE_BUFMGN_PAGELLT,
|
||||
RTW89_DBG_PORT_SEL_WDE_BUFMGN_PKTINFO,
|
||||
RTW89_DBG_PORT_SEL_WDE_QUEMGN_PREPKT,
|
||||
RTW89_DBG_PORT_SEL_WDE_QUEMGN_NXTPKT,
|
||||
RTW89_DBG_PORT_SEL_WDE_QUEMGN_QLNKTBL,
|
||||
RTW89_DBG_PORT_SEL_WDE_QUEMGN_QEMPTY,
|
||||
RTW89_DBG_PORT_SEL_PLE_BUFMGN_FREEPG,
|
||||
RTW89_DBG_PORT_SEL_PLE_BUFMGN_QUOTA,
|
||||
RTW89_DBG_PORT_SEL_PLE_BUFMGN_PAGELLT,
|
||||
RTW89_DBG_PORT_SEL_PLE_BUFMGN_PKTINFO,
|
||||
RTW89_DBG_PORT_SEL_PLE_QUEMGN_PREPKT,
|
||||
RTW89_DBG_PORT_SEL_PLE_QUEMGN_NXTPKT,
|
||||
RTW89_DBG_PORT_SEL_PLE_QUEMGN_QLNKTBL,
|
||||
RTW89_DBG_PORT_SEL_PLE_QUEMGN_QEMPTY,
|
||||
RTW89_DBG_PORT_SEL_PKTINFO,
|
||||
/* PCIE related */
|
||||
RTW89_DBG_PORT_SEL_PCIE_TXDMA,
|
||||
RTW89_DBG_PORT_SEL_PCIE_RXDMA,
|
||||
RTW89_DBG_PORT_SEL_PCIE_CVT,
|
||||
RTW89_DBG_PORT_SEL_PCIE_CXPL,
|
||||
RTW89_DBG_PORT_SEL_PCIE_IO,
|
||||
RTW89_DBG_PORT_SEL_PCIE_MISC,
|
||||
RTW89_DBG_PORT_SEL_PCIE_MISC2,
|
||||
|
||||
/* keep last */
|
||||
RTW89_DBG_PORT_SEL_LAST,
|
||||
RTW89_DBG_PORT_SEL_MAX = RTW89_DBG_PORT_SEL_LAST,
|
||||
RTW89_DBG_PORT_SEL_INVALID = RTW89_DBG_PORT_SEL_LAST,
|
||||
};
|
||||
|
||||
/* SRAM mem dump */
|
||||
#define R_AX_INDIR_ACCESS_ENTRY 0x40000
|
||||
|
||||
#define STA_SCHED_BASE_ADDR 0x18808000
|
||||
#define RXPLD_FLTR_CAM_BASE_ADDR 0x18813000
|
||||
#define SECURITY_CAM_BASE_ADDR 0x18814000
|
||||
#define WOW_CAM_BASE_ADDR 0x18815000
|
||||
#define CMAC_TBL_BASE_ADDR 0x18840000
|
||||
#define ADDR_CAM_BASE_ADDR 0x18850000
|
||||
#define BSSID_CAM_BASE_ADDR 0x18853000
|
||||
#define BA_CAM_BASE_ADDR 0x18854000
|
||||
#define BCN_IE_CAM0_BASE_ADDR 0x18855000
|
||||
#define SHARED_BUF_BASE_ADDR 0x18700000
|
||||
#define DMAC_TBL_BASE_ADDR 0x18800000
|
||||
#define SHCUT_MACHDR_BASE_ADDR 0x18800800
|
||||
#define BCN_IE_CAM1_BASE_ADDR 0x188A0000
|
||||
|
||||
#define CCTL_INFO_SIZE 32
|
||||
|
||||
enum rtw89_mac_mem_sel {
|
||||
RTW89_MAC_MEM_SHARED_BUF,
|
||||
RTW89_MAC_MEM_DMAC_TBL,
|
||||
RTW89_MAC_MEM_SHCUT_MACHDR,
|
||||
RTW89_MAC_MEM_STA_SCHED,
|
||||
RTW89_MAC_MEM_RXPLD_FLTR_CAM,
|
||||
RTW89_MAC_MEM_SECURITY_CAM,
|
||||
RTW89_MAC_MEM_WOW_CAM,
|
||||
RTW89_MAC_MEM_CMAC_TBL,
|
||||
RTW89_MAC_MEM_ADDR_CAM,
|
||||
RTW89_MAC_MEM_BA_CAM,
|
||||
RTW89_MAC_MEM_BCN_IE_CAM0,
|
||||
RTW89_MAC_MEM_BCN_IE_CAM1,
|
||||
|
||||
/* keep last */
|
||||
RTW89_MAC_MEM_LAST,
|
||||
RTW89_MAC_MEM_MAX = RTW89_MAC_MEM_LAST,
|
||||
RTW89_MAC_MEM_INVALID = RTW89_MAC_MEM_LAST,
|
||||
};
|
||||
|
||||
enum rtw89_rpwm_req_pwr_state {
|
||||
RTW89_MAC_RPWM_REQ_PWR_STATE_ACTIVE = 0,
|
||||
RTW89_MAC_RPWM_REQ_PWR_STATE_BAND0_RFON = 1,
|
||||
RTW89_MAC_RPWM_REQ_PWR_STATE_BAND1_RFON = 2,
|
||||
RTW89_MAC_RPWM_REQ_PWR_STATE_BAND0_RFOFF = 3,
|
||||
RTW89_MAC_RPWM_REQ_PWR_STATE_BAND1_RFOFF = 4,
|
||||
RTW89_MAC_RPWM_REQ_PWR_STATE_CLK_GATED = 5,
|
||||
RTW89_MAC_RPWM_REQ_PWR_STATE_PWR_GATED = 6,
|
||||
RTW89_MAC_RPWM_REQ_PWR_STATE_HIOE_PWR_GATED = 7,
|
||||
RTW89_MAC_RPWM_REQ_PWR_STATE_MAX,
|
||||
};
|
||||
|
||||
struct rtw89_pwr_cfg {
|
||||
u16 addr;
|
||||
u8 cv_msk;
|
||||
u8 intf_msk;
|
||||
u8 base:4;
|
||||
u8 cmd:4;
|
||||
u8 msk;
|
||||
u8 val;
|
||||
};
|
||||
|
||||
enum rtw89_mac_c2h_ofld_func {
|
||||
RTW89_MAC_C2H_FUNC_EFUSE_DUMP,
|
||||
RTW89_MAC_C2H_FUNC_READ_RSP,
|
||||
RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP,
|
||||
RTW89_MAC_C2H_FUNC_BCN_RESEND,
|
||||
RTW89_MAC_C2H_FUNC_MACID_PAUSE,
|
||||
RTW89_MAC_C2H_FUNC_OFLD_MAX,
|
||||
};
|
||||
|
||||
enum rtw89_mac_c2h_info_func {
|
||||
RTW89_MAC_C2H_FUNC_REC_ACK,
|
||||
RTW89_MAC_C2H_FUNC_DONE_ACK,
|
||||
RTW89_MAC_C2H_FUNC_C2H_LOG,
|
||||
RTW89_MAC_C2H_FUNC_INFO_MAX,
|
||||
};
|
||||
|
||||
enum rtw89_mac_c2h_class {
|
||||
RTW89_MAC_C2H_CLASS_INFO,
|
||||
RTW89_MAC_C2H_CLASS_OFLD,
|
||||
RTW89_MAC_C2H_CLASS_TWT,
|
||||
RTW89_MAC_C2H_CLASS_WOW,
|
||||
RTW89_MAC_C2H_CLASS_MCC,
|
||||
RTW89_MAC_C2H_CLASS_FWDBG,
|
||||
RTW89_MAC_C2H_CLASS_MAX,
|
||||
};
|
||||
|
||||
struct rtw89_mac_ax_coex {
|
||||
#define RTW89_MAC_AX_COEX_RTK_MODE 0
|
||||
#define RTW89_MAC_AX_COEX_CSR_MODE 1
|
||||
u8 pta_mode;
|
||||
#define RTW89_MAC_AX_COEX_INNER 0
|
||||
#define RTW89_MAC_AX_COEX_OUTPUT 1
|
||||
#define RTW89_MAC_AX_COEX_INPUT 2
|
||||
u8 direction;
|
||||
};
|
||||
|
||||
struct rtw89_mac_ax_plt {
|
||||
#define RTW89_MAC_AX_PLT_LTE_RX BIT(0)
|
||||
#define RTW89_MAC_AX_PLT_GNT_BT_TX BIT(1)
|
||||
#define RTW89_MAC_AX_PLT_GNT_BT_RX BIT(2)
|
||||
#define RTW89_MAC_AX_PLT_GNT_WL BIT(3)
|
||||
u8 band;
|
||||
u8 tx;
|
||||
u8 rx;
|
||||
};
|
||||
|
||||
enum rtw89_mac_bf_rrsc_rate {
|
||||
RTW89_MAC_BF_RRSC_6M = 0,
|
||||
RTW89_MAC_BF_RRSC_9M = 1,
|
||||
RTW89_MAC_BF_RRSC_12M,
|
||||
RTW89_MAC_BF_RRSC_18M,
|
||||
RTW89_MAC_BF_RRSC_24M,
|
||||
RTW89_MAC_BF_RRSC_36M,
|
||||
RTW89_MAC_BF_RRSC_48M,
|
||||
RTW89_MAC_BF_RRSC_54M,
|
||||
RTW89_MAC_BF_RRSC_HT_MSC0,
|
||||
RTW89_MAC_BF_RRSC_HT_MSC1,
|
||||
RTW89_MAC_BF_RRSC_HT_MSC2,
|
||||
RTW89_MAC_BF_RRSC_HT_MSC3,
|
||||
RTW89_MAC_BF_RRSC_HT_MSC4,
|
||||
RTW89_MAC_BF_RRSC_HT_MSC5,
|
||||
RTW89_MAC_BF_RRSC_HT_MSC6,
|
||||
RTW89_MAC_BF_RRSC_HT_MSC7,
|
||||
RTW89_MAC_BF_RRSC_VHT_MSC0,
|
||||
RTW89_MAC_BF_RRSC_VHT_MSC1,
|
||||
RTW89_MAC_BF_RRSC_VHT_MSC2,
|
||||
RTW89_MAC_BF_RRSC_VHT_MSC3,
|
||||
RTW89_MAC_BF_RRSC_VHT_MSC4,
|
||||
RTW89_MAC_BF_RRSC_VHT_MSC5,
|
||||
RTW89_MAC_BF_RRSC_VHT_MSC6,
|
||||
RTW89_MAC_BF_RRSC_VHT_MSC7,
|
||||
RTW89_MAC_BF_RRSC_HE_MSC0,
|
||||
RTW89_MAC_BF_RRSC_HE_MSC1,
|
||||
RTW89_MAC_BF_RRSC_HE_MSC2,
|
||||
RTW89_MAC_BF_RRSC_HE_MSC3,
|
||||
RTW89_MAC_BF_RRSC_HE_MSC4,
|
||||
RTW89_MAC_BF_RRSC_HE_MSC5,
|
||||
RTW89_MAC_BF_RRSC_HE_MSC6,
|
||||
RTW89_MAC_BF_RRSC_HE_MSC7 = 31,
|
||||
RTW89_MAC_BF_RRSC_MAX = 32
|
||||
};
|
||||
|
||||
#define RTW89_R32_EA 0xEAEAEAEA
|
||||
#define RTW89_R32_DEAD 0xDEADBEEF
|
||||
#define MAC_REG_POOL_COUNT 10
|
||||
#define ACCESS_CMAC(_addr) \
|
||||
({typeof(_addr) __addr = (_addr); \
|
||||
__addr >= R_AX_CMAC_REG_START && __addr <= R_AX_CMAC_REG_END; })
|
||||
|
||||
#define PTCL_IDLE_POLL_CNT 10000
|
||||
#define SW_CVR_DUR_US 8
|
||||
#define SW_CVR_CNT 8
|
||||
|
||||
#define DLE_BOUND_UNIT (8 * 1024)
|
||||
#define DLE_WAIT_CNT 2000
|
||||
#define TRXCFG_WAIT_CNT 2000
|
||||
|
||||
#define RTW89_WDE_PG_64 64
|
||||
#define RTW89_WDE_PG_128 128
|
||||
#define RTW89_WDE_PG_256 256
|
||||
|
||||
#define S_AX_WDE_PAGE_SEL_64 0
|
||||
#define S_AX_WDE_PAGE_SEL_128 1
|
||||
#define S_AX_WDE_PAGE_SEL_256 2
|
||||
|
||||
#define RTW89_PLE_PG_64 64
|
||||
#define RTW89_PLE_PG_128 128
|
||||
#define RTW89_PLE_PG_256 256
|
||||
|
||||
#define S_AX_PLE_PAGE_SEL_64 0
|
||||
#define S_AX_PLE_PAGE_SEL_128 1
|
||||
#define S_AX_PLE_PAGE_SEL_256 2
|
||||
|
||||
#define SDIO_LOCAL_BASE_ADDR 0x80000000
|
||||
|
||||
#define PWR_CMD_WRITE 0
|
||||
#define PWR_CMD_POLL 1
|
||||
#define PWR_CMD_DELAY 2
|
||||
#define PWR_CMD_END 3
|
||||
|
||||
#define PWR_INTF_MSK_SDIO BIT(0)
|
||||
#define PWR_INTF_MSK_USB BIT(1)
|
||||
#define PWR_INTF_MSK_PCIE BIT(2)
|
||||
#define PWR_INTF_MSK_ALL 0x7
|
||||
|
||||
#define PWR_BASE_MAC 0
|
||||
#define PWR_BASE_USB 1
|
||||
#define PWR_BASE_PCIE 2
|
||||
#define PWR_BASE_SDIO 3
|
||||
|
||||
#define PWR_CV_MSK_A BIT(0)
|
||||
#define PWR_CV_MSK_B BIT(1)
|
||||
#define PWR_CV_MSK_C BIT(2)
|
||||
#define PWR_CV_MSK_D BIT(3)
|
||||
#define PWR_CV_MSK_E BIT(4)
|
||||
#define PWR_CV_MSK_F BIT(5)
|
||||
#define PWR_CV_MSK_G BIT(6)
|
||||
#define PWR_CV_MSK_TEST BIT(7)
|
||||
#define PWR_CV_MSK_ALL 0xFF
|
||||
|
||||
#define PWR_DELAY_US 0
|
||||
#define PWR_DELAY_MS 1
|
||||
|
||||
/* STA scheduler */
|
||||
#define SS_MACID_SH 8
|
||||
#define SS_TX_LEN_MSK 0x1FFFFF
|
||||
#define SS_CTRL1_R_TX_LEN 5
|
||||
#define SS_CTRL1_R_NEXT_LINK 20
|
||||
#define SS_LINK_SIZE 256
|
||||
|
||||
/* MAC debug port */
|
||||
#define TMAC_DBG_SEL_C0 0xA5
|
||||
#define RMAC_DBG_SEL_C0 0xA6
|
||||
#define TRXPTCL_DBG_SEL_C0 0xA7
|
||||
#define TMAC_DBG_SEL_C1 0xB5
|
||||
#define RMAC_DBG_SEL_C1 0xB6
|
||||
#define TRXPTCL_DBG_SEL_C1 0xB7
|
||||
#define FW_PROG_CNTR_DBG_SEL 0xF2
|
||||
#define PCIE_TXDMA_DBG_SEL 0x30
|
||||
#define PCIE_RXDMA_DBG_SEL 0x31
|
||||
#define PCIE_CVT_DBG_SEL 0x32
|
||||
#define PCIE_CXPL_DBG_SEL 0x33
|
||||
#define PCIE_IO_DBG_SEL 0x37
|
||||
#define PCIE_MISC_DBG_SEL 0x38
|
||||
#define PCIE_MISC2_DBG_SEL 0x00
|
||||
#define MAC_DBG_SEL 1
|
||||
#define RMAC_CMAC_DBG_SEL 1
|
||||
|
||||
/* TRXPTCL dbg port sel */
|
||||
#define TRXPTRL_DBG_SEL_TMAC 0
|
||||
#define TRXPTRL_DBG_SEL_RMAC 1
|
||||
|
||||
struct rtw89_cpuio_ctrl {
|
||||
u16 pkt_num;
|
||||
u16 start_pktid;
|
||||
u16 end_pktid;
|
||||
u8 cmd_type;
|
||||
u8 macid;
|
||||
u8 src_pid;
|
||||
u8 src_qid;
|
||||
u8 dst_pid;
|
||||
u8 dst_qid;
|
||||
u16 pktid;
|
||||
};
|
||||
|
||||
struct rtw89_mac_dbg_port_info {
|
||||
u32 sel_addr;
|
||||
u8 sel_byte;
|
||||
u32 sel_msk;
|
||||
u32 srt;
|
||||
u32 end;
|
||||
u32 rd_addr;
|
||||
u8 rd_byte;
|
||||
u32 rd_msk;
|
||||
};
|
||||
|
||||
#define QLNKTBL_ADDR_INFO_SEL BIT(0)
|
||||
#define QLNKTBL_ADDR_INFO_SEL_0 0
|
||||
#define QLNKTBL_ADDR_INFO_SEL_1 1
|
||||
#define QLNKTBL_ADDR_TBL_IDX_MASK GENMASK(10, 1)
|
||||
#define QLNKTBL_DATA_SEL1_PKT_CNT_MASK GENMASK(11, 0)
|
||||
|
||||
struct rtw89_mac_dle_dfi_ctrl {
|
||||
enum rtw89_mac_dle_ctrl_type type;
|
||||
u32 target;
|
||||
u32 addr;
|
||||
u32 out_data;
|
||||
};
|
||||
|
||||
struct rtw89_mac_dle_dfi_quota {
|
||||
enum rtw89_mac_dle_ctrl_type dle_type;
|
||||
u32 qtaid;
|
||||
u16 rsv_pgnum;
|
||||
u16 use_pgnum;
|
||||
};
|
||||
|
||||
struct rtw89_mac_dle_dfi_qempty {
|
||||
enum rtw89_mac_dle_ctrl_type dle_type;
|
||||
u32 grpsel;
|
||||
u32 qempty;
|
||||
};
|
||||
|
||||
/* Define DBG and recovery enum */
|
||||
enum mac_ax_err_info {
|
||||
/* Get error info */
|
||||
|
||||
/* L0 */
|
||||
MAC_AX_ERR_L0_ERR_CMAC0 = 0x0001,
|
||||
MAC_AX_ERR_L0_ERR_CMAC1 = 0x0002,
|
||||
MAC_AX_ERR_L0_RESET_DONE = 0x0003,
|
||||
MAC_AX_ERR_L0_PROMOTE_TO_L1 = 0x0010,
|
||||
|
||||
/* L1 */
|
||||
MAC_AX_ERR_L1_ERR_DMAC = 0x1000,
|
||||
MAC_AX_ERR_L1_RESET_DISABLE_DMAC_DONE = 0x1001,
|
||||
MAC_AX_ERR_L1_RESET_RECOVERY_DONE = 0x1002,
|
||||
MAC_AX_ERR_L1_PROMOTE_TO_L2 = 0x1010,
|
||||
MAC_AX_ERR_L1_RCVY_STOP_DONE = 0x1011,
|
||||
|
||||
/* L2 */
|
||||
/* address hole (master) */
|
||||
MAC_AX_ERR_L2_ERR_AH_DMA = 0x2000,
|
||||
MAC_AX_ERR_L2_ERR_AH_HCI = 0x2010,
|
||||
MAC_AX_ERR_L2_ERR_AH_RLX4081 = 0x2020,
|
||||
MAC_AX_ERR_L2_ERR_AH_IDDMA = 0x2030,
|
||||
MAC_AX_ERR_L2_ERR_AH_HIOE = 0x2040,
|
||||
MAC_AX_ERR_L2_ERR_AH_IPSEC = 0x2050,
|
||||
MAC_AX_ERR_L2_ERR_AH_RX4281 = 0x2060,
|
||||
MAC_AX_ERR_L2_ERR_AH_OTHERS = 0x2070,
|
||||
|
||||
/* AHB bridge timeout (master) */
|
||||
MAC_AX_ERR_L2_ERR_AHB_TO_DMA = 0x2100,
|
||||
MAC_AX_ERR_L2_ERR_AHB_TO_HCI = 0x2110,
|
||||
MAC_AX_ERR_L2_ERR_AHB_TO_RLX4081 = 0x2120,
|
||||
MAC_AX_ERR_L2_ERR_AHB_TO_IDDMA = 0x2130,
|
||||
MAC_AX_ERR_L2_ERR_AHB_TO_HIOE = 0x2140,
|
||||
MAC_AX_ERR_L2_ERR_AHB_TO_IPSEC = 0x2150,
|
||||
MAC_AX_ERR_L2_ERR_AHB_TO_RX4281 = 0x2160,
|
||||
MAC_AX_ERR_L2_ERR_AHB_TO_OTHERS = 0x2170,
|
||||
|
||||
/* APB_SA bridge timeout (master + slave) */
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_WVA = 0x2200,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_UART = 0x2201,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_CPULOCAL = 0x2202,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_AXIDMA = 0x2203,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_HIOE = 0x2204,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_IDDMA = 0x2205,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_IPSEC = 0x2206,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_WON = 0x2207,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_WDMAC = 0x2208,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_WCMAC = 0x2209,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_OTHERS = 0x220A,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_WVA = 0x2210,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_UART = 0x2211,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_CPULOCAL = 0x2212,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_AXIDMA = 0x2213,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_HIOE = 0x2214,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_IDDMA = 0x2215,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_IPSEC = 0x2216,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_WDMAC = 0x2218,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_WCMAC = 0x2219,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_OTHERS = 0x221A,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_WVA = 0x2220,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_UART = 0x2221,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_CPULOCAL = 0x2222,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_AXIDMA = 0x2223,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_HIOE = 0x2224,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_IDDMA = 0x2225,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_IPSEC = 0x2226,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_WON = 0x2227,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_WDMAC = 0x2228,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_WCMAC = 0x2229,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_OTHERS = 0x222A,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_WVA = 0x2230,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_UART = 0x2231,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_CPULOCAL = 0x2232,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_AXIDMA = 0x2233,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_HIOE = 0x2234,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_IDDMA = 0x2235,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_IPSEC = 0x2236,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_WON = 0x2237,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_WDMAC = 0x2238,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_WCMAC = 0x2239,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_OTHERS = 0x223A,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_WVA = 0x2240,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_UART = 0x2241,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_CPULOCAL = 0x2242,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_AXIDMA = 0x2243,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_HIOE = 0x2244,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_IDDMA = 0x2245,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_IPSEC = 0x2246,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_WON = 0x2247,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_WDMAC = 0x2248,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_WCMAC = 0x2249,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_OTHERS = 0x224A,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_WVA = 0x2250,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_UART = 0x2251,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_CPULOCAL = 0x2252,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_AXIDMA = 0x2253,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_HIOE = 0x2254,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_IDDMA = 0x2255,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_IPSEC = 0x2256,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_WON = 0x2257,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_WDMAC = 0x2258,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_WCMAC = 0x2259,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_OTHERS = 0x225A,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_WVA = 0x2260,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_UART = 0x2261,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_CPULOCAL = 0x2262,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_AXIDMA = 0x2263,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_HIOE = 0x2264,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_IDDMA = 0x2265,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_IPSEC = 0x2266,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_WON = 0x2267,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_WDMAC = 0x2268,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_WCMAC = 0x2269,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_OTHERS = 0x226A,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_WVA = 0x2270,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_UART = 0x2271,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_CPULOCAL = 0x2272,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_AXIDMA = 0x2273,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_HIOE = 0x2274,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_IDDMA = 0x2275,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_IPSEC = 0x2276,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_WON = 0x2277,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_WDMAC = 0x2278,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_WCMAC = 0x2279,
|
||||
MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_OTHERS = 0x227A,
|
||||
|
||||
/* APB_BBRF bridge timeout (master) */
|
||||
MAC_AX_ERR_L2_ERR_APB_BBRF_TO_DMA = 0x2300,
|
||||
MAC_AX_ERR_L2_ERR_APB_BBRF_TO_HCI = 0x2310,
|
||||
MAC_AX_ERR_L2_ERR_APB_BBRF_TO_RLX4081 = 0x2320,
|
||||
MAC_AX_ERR_L2_ERR_APB_BBRF_TO_IDDMA = 0x2330,
|
||||
MAC_AX_ERR_L2_ERR_APB_BBRF_TO_HIOE = 0x2340,
|
||||
MAC_AX_ERR_L2_ERR_APB_BBRF_TO_IPSEC = 0x2350,
|
||||
MAC_AX_ERR_L2_ERR_APB_BBRF_TO_RX4281 = 0x2360,
|
||||
MAC_AX_ERR_L2_ERR_APB_BBRF_TO_OTHERS = 0x2370,
|
||||
MAC_AX_ERR_L2_RESET_DONE = 0x2400,
|
||||
MAC_AX_ERR_CPU_EXCEPTION = 0x3000,
|
||||
MAC_AX_GET_ERR_MAX,
|
||||
MAC_AX_DUMP_SHAREBUFF_INDICATOR = 0x80000000,
|
||||
|
||||
/* set error info */
|
||||
MAC_AX_ERR_L1_DISABLE_EN = 0x0001,
|
||||
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_L0_CFG_NOTIFY = 0x0010,
|
||||
MAC_AX_ERR_L0_CFG_DIS_NOTIFY = 0x0011,
|
||||
MAC_AX_ERR_L0_CFG_HANDSHAKE = 0x0012,
|
||||
MAC_AX_ERR_L0_RCVY_EN = 0x0013,
|
||||
MAC_AX_SET_ERR_MAX,
|
||||
};
|
||||
|
||||
extern const struct rtw89_hfc_prec_cfg rtw_hfc_preccfg_pcie;
|
||||
extern const struct rtw89_dle_size wde_size0;
|
||||
extern const struct rtw89_dle_size wde_size4;
|
||||
extern const struct rtw89_dle_size ple_size0;
|
||||
extern const struct rtw89_dle_size ple_size4;
|
||||
extern const struct rtw89_wde_quota wde_qt0;
|
||||
extern const struct rtw89_wde_quota wde_qt4;
|
||||
extern const struct rtw89_ple_quota ple_qt4;
|
||||
extern const struct rtw89_ple_quota ple_qt5;
|
||||
extern const struct rtw89_ple_quota ple_qt13;
|
||||
|
||||
static inline u32 rtw89_mac_reg_by_idx(u32 reg_base, u8 band)
|
||||
{
|
||||
return band == 0 ? reg_base : (reg_base + 0x2000);
|
||||
}
|
||||
|
||||
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_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
|
||||
u32 base, u32 mask)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx);
|
||||
return rtw89_read32_mask(rtwdev, reg, mask);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rtw89_write32_port(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, u32 base,
|
||||
u32 data)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx);
|
||||
rtw89_write32(rtwdev, reg, data);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rtw89_write32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
|
||||
u32 base, u32 mask, u32 data)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx);
|
||||
rtw89_write32_mask(rtwdev, reg, mask, data);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rtw89_write16_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
|
||||
u32 base, u32 mask, u16 data)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx);
|
||||
rtw89_write16_mask(rtwdev, reg, mask, data);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rtw89_write32_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
|
||||
u32 base, u32 bit)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx);
|
||||
rtw89_write32_clr(rtwdev, reg, bit);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rtw89_write16_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
|
||||
u32 base, u16 bit)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx);
|
||||
rtw89_write16_clr(rtwdev, reg, bit);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rtw89_write32_port_set(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
|
||||
u32 base, u32 bit)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx);
|
||||
rtw89_write32_set(rtwdev, reg, bit);
|
||||
}
|
||||
|
||||
void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev);
|
||||
int rtw89_mac_partial_init(struct rtw89_dev *rtwdev);
|
||||
int rtw89_mac_init(struct rtw89_dev *rtwdev);
|
||||
int rtw89_mac_check_mac_en(struct rtw89_dev *rtwdev, u8 band,
|
||||
enum rtw89_mac_hwmod_sel sel);
|
||||
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);
|
||||
int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
|
||||
void rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev);
|
||||
void rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev);
|
||||
u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev);
|
||||
int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err);
|
||||
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);
|
||||
int rtw89_mac_stop_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx,
|
||||
u16 *tx_en, enum rtw89_sch_tx_sel sel);
|
||||
int rtw89_mac_resume_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, u16 tx_en);
|
||||
int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_ids, bool enable);
|
||||
void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx);
|
||||
void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop);
|
||||
int rtw89_mac_coex_init(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex *coex);
|
||||
int rtw89_mac_cfg_gnt(struct rtw89_dev *rtwdev,
|
||||
const struct rtw89_mac_ax_coex_gnt *gnt_cfg);
|
||||
int rtw89_mac_cfg_plt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_plt *plt);
|
||||
void rtw89_mac_cfg_sb(struct rtw89_dev *rtwdev, u32 val);
|
||||
u32 rtw89_mac_get_sb(struct rtw89_dev *rtwdev);
|
||||
bool rtw89_mac_get_ctrl_path(struct rtw89_dev *rtwdev);
|
||||
int rtw89_mac_cfg_ctrl_path(struct rtw89_dev *rtwdev, bool wl);
|
||||
bool rtw89_mac_get_txpwr_cr(struct rtw89_dev *rtwdev,
|
||||
enum rtw89_phy_idx phy_idx,
|
||||
u32 reg_base, u32 *cr);
|
||||
void rtw89_mac_power_mode_change(struct rtw89_dev *rtwdev, bool enter);
|
||||
void rtw89_mac_bf_assoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta);
|
||||
void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta);
|
||||
void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *conf);
|
||||
void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_sta *sta, bool disconnect);
|
||||
void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev);
|
||||
int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
|
||||
int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
|
||||
int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif, bool en);
|
||||
|
||||
static inline void rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
if (!test_bit(RTW89_FLAG_BFEE_MON, rtwdev->flags))
|
||||
return;
|
||||
|
||||
_rtw89_mac_bf_monitor_track(rtwdev);
|
||||
}
|
||||
|
||||
static inline int rtw89_mac_txpwr_read32(struct rtw89_dev *rtwdev,
|
||||
enum rtw89_phy_idx phy_idx,
|
||||
u32 reg_base, u32 *val)
|
||||
{
|
||||
u32 cr;
|
||||
|
||||
if (!rtw89_mac_get_txpwr_cr(rtwdev, phy_idx, reg_base, &cr))
|
||||
return -EINVAL;
|
||||
|
||||
*val = rtw89_read32(rtwdev, cr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int rtw89_mac_txpwr_write32(struct rtw89_dev *rtwdev,
|
||||
enum rtw89_phy_idx phy_idx,
|
||||
u32 reg_base, u32 val)
|
||||
{
|
||||
u32 cr;
|
||||
|
||||
if (!rtw89_mac_get_txpwr_cr(rtwdev, phy_idx, reg_base, &cr))
|
||||
return -EINVAL;
|
||||
|
||||
rtw89_write32(rtwdev, cr, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int rtw89_mac_txpwr_write32_mask(struct rtw89_dev *rtwdev,
|
||||
enum rtw89_phy_idx phy_idx,
|
||||
u32 reg_base, u32 mask, u32 val)
|
||||
{
|
||||
u32 cr;
|
||||
|
||||
if (!rtw89_mac_get_txpwr_cr(rtwdev, phy_idx, reg_base, &cr))
|
||||
return -EINVAL;
|
||||
|
||||
rtw89_write32_mask(rtwdev, cr, mask, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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,
|
||||
u32 *tx_time);
|
||||
int rtw89_mac_set_tx_retry_limit(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_sta *rtwsta,
|
||||
bool resume, u8 tx_retry);
|
||||
int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_sta *rtwsta, u8 *tx_retry);
|
||||
|
||||
#endif
|
676
drivers/net/wireless/realtek/rtw89/mac80211.c
Normal file
676
drivers/net/wireless/realtek/rtw89/mac80211.c
Normal file
@ -0,0 +1,676 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#include "cam.h"
|
||||
#include "coex.h"
|
||||
#include "debug.h"
|
||||
#include "fw.h"
|
||||
#include "mac.h"
|
||||
#include "phy.h"
|
||||
#include "ps.h"
|
||||
#include "reg.h"
|
||||
#include "sar.h"
|
||||
#include "ser.h"
|
||||
|
||||
static void rtw89_ops_tx(struct ieee80211_hw *hw,
|
||||
struct ieee80211_tx_control *control,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_vif *vif = info->control.vif;
|
||||
struct ieee80211_sta *sta = control->sta;
|
||||
int ret, qsel;
|
||||
|
||||
ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, &qsel);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to transmit skb: %d\n", ret);
|
||||
ieee80211_free_txskb(hw, skb);
|
||||
}
|
||||
rtw89_core_tx_kick_off(rtwdev, qsel);
|
||||
}
|
||||
|
||||
static void rtw89_ops_wake_tx_queue(struct ieee80211_hw *hw,
|
||||
struct ieee80211_txq *txq)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
|
||||
ieee80211_schedule_txq(hw, txq);
|
||||
queue_work(rtwdev->txq_wq, &rtwdev->txq_work);
|
||||
}
|
||||
|
||||
static int rtw89_ops_start(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
ret = rtw89_core_start(rtwdev);
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rtw89_ops_stop(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
rtw89_core_stop(rtwdev);
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
}
|
||||
|
||||
static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
rtw89_leave_ps_mode(rtwdev);
|
||||
|
||||
if ((changed & IEEE80211_CONF_CHANGE_IDLE) &&
|
||||
!(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_set_channel(rtwdev);
|
||||
|
||||
if ((changed & IEEE80211_CONF_CHANGE_IDLE) &&
|
||||
(hw->conf.flags & IEEE80211_CONF_IDLE))
|
||||
rtw89_enter_ips(rtwdev);
|
||||
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list);
|
||||
rtw89_leave_ps_mode(rtwdev);
|
||||
|
||||
rtw89_traffic_stats_init(rtwdev, &rtwvif->stats);
|
||||
rtw89_vif_type_mapping(vif, false);
|
||||
rtwvif->port = rtw89_core_acquire_bit_map(rtwdev->hw_port,
|
||||
RTW89_MAX_HW_PORT_NUM);
|
||||
if (rtwvif->port == RTW89_MAX_HW_PORT_NUM) {
|
||||
ret = -ENOSPC;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rtwvif->bcn_hit_cond = 0;
|
||||
rtwvif->mac_idx = RTW89_MAC_0;
|
||||
rtwvif->phy_idx = RTW89_PHY_0;
|
||||
rtwvif->hit_rule = 0;
|
||||
ether_addr_copy(rtwvif->mac_addr, vif->addr);
|
||||
|
||||
ret = rtw89_mac_add_vif(rtwdev, rtwvif);
|
||||
if (ret) {
|
||||
rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
|
||||
goto out;
|
||||
}
|
||||
|
||||
rtw89_core_txq_init(rtwdev, vif->txq);
|
||||
|
||||
rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_START);
|
||||
out:
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rtw89_ops_remove_interface(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
rtw89_leave_ps_mode(rtwdev);
|
||||
rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_STOP);
|
||||
rtw89_mac_remove_vif(rtwdev, rtwvif);
|
||||
rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
|
||||
list_del_init(&rtwvif->list);
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
}
|
||||
|
||||
static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,
|
||||
unsigned int changed_flags,
|
||||
unsigned int *new_flags,
|
||||
u64 multicast)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
rtw89_leave_ps_mode(rtwdev);
|
||||
|
||||
*new_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_FCSFAIL |
|
||||
FIF_BCN_PRBRESP_PROMISC;
|
||||
|
||||
if (changed_flags & FIF_ALLMULTI) {
|
||||
if (*new_flags & FIF_ALLMULTI)
|
||||
rtwdev->hal.rx_fltr &= ~B_AX_A_MC;
|
||||
else
|
||||
rtwdev->hal.rx_fltr |= B_AX_A_MC;
|
||||
}
|
||||
if (changed_flags & FIF_FCSFAIL) {
|
||||
if (*new_flags & FIF_FCSFAIL)
|
||||
rtwdev->hal.rx_fltr |= B_AX_A_CRC32_ERR;
|
||||
else
|
||||
rtwdev->hal.rx_fltr &= ~B_AX_A_CRC32_ERR;
|
||||
}
|
||||
if (changed_flags & FIF_OTHER_BSS) {
|
||||
if (*new_flags & FIF_OTHER_BSS)
|
||||
rtwdev->hal.rx_fltr &= ~B_AX_A_A1_MATCH;
|
||||
else
|
||||
rtwdev->hal.rx_fltr |= B_AX_A_A1_MATCH;
|
||||
}
|
||||
if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
|
||||
if (*new_flags & FIF_BCN_PRBRESP_PROMISC) {
|
||||
rtwdev->hal.rx_fltr &= ~B_AX_A_BCN_CHK_EN;
|
||||
rtwdev->hal.rx_fltr &= ~B_AX_A_BC;
|
||||
rtwdev->hal.rx_fltr &= ~B_AX_A_A1_MATCH;
|
||||
} else {
|
||||
rtwdev->hal.rx_fltr |= B_AX_A_BCN_CHK_EN;
|
||||
rtwdev->hal.rx_fltr |= B_AX_A_BC;
|
||||
rtwdev->hal.rx_fltr |= B_AX_A_A1_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
rtw89_write32_mask(rtwdev,
|
||||
rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
|
||||
B_AX_RX_FLTR_CFG_MASK,
|
||||
rtwdev->hal.rx_fltr);
|
||||
if (!rtwdev->dbcc_en)
|
||||
goto out;
|
||||
rtw89_write32_mask(rtwdev,
|
||||
rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_1),
|
||||
B_AX_RX_FLTR_CFG_MASK,
|
||||
rtwdev->hal.rx_fltr);
|
||||
|
||||
out:
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
}
|
||||
|
||||
static const u8 ac_to_fw_idx[IEEE80211_NUM_ACS] = {
|
||||
[IEEE80211_AC_VO] = 3,
|
||||
[IEEE80211_AC_VI] = 2,
|
||||
[IEEE80211_AC_BE] = 0,
|
||||
[IEEE80211_AC_BK] = 1,
|
||||
};
|
||||
|
||||
static u8 rtw89_aifsn_to_aifs(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif, u8 aifsn)
|
||||
{
|
||||
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
|
||||
u8 slot_time;
|
||||
u8 sifs;
|
||||
|
||||
slot_time = vif->bss_conf.use_short_slot ? 9 : 20;
|
||||
sifs = rtwdev->hal.current_band_type == RTW89_BAND_5G ? 16 : 10;
|
||||
|
||||
return aifsn * slot_time + sifs;
|
||||
}
|
||||
|
||||
static void ____rtw89_conf_tx_edca(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif, u16 ac)
|
||||
{
|
||||
struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac];
|
||||
u32 val;
|
||||
u8 ecw_max, ecw_min;
|
||||
u8 aifs;
|
||||
|
||||
/* 2^ecw - 1 = cw; ecw = log2(cw + 1) */
|
||||
ecw_max = ilog2(params->cw_max + 1);
|
||||
ecw_min = ilog2(params->cw_min + 1);
|
||||
aifs = rtw89_aifsn_to_aifs(rtwdev, rtwvif, params->aifs);
|
||||
val = FIELD_PREP(FW_EDCA_PARAM_TXOPLMT_MSK, params->txop) |
|
||||
FIELD_PREP(FW_EDCA_PARAM_CWMAX_MSK, ecw_max) |
|
||||
FIELD_PREP(FW_EDCA_PARAM_CWMIN_MSK, ecw_min) |
|
||||
FIELD_PREP(FW_EDCA_PARAM_AIFS_MSK, aifs);
|
||||
rtw89_fw_h2c_set_edca(rtwdev, rtwvif, ac_to_fw_idx[ac], val);
|
||||
}
|
||||
|
||||
static const u32 ac_to_mu_edca_param[IEEE80211_NUM_ACS] = {
|
||||
[IEEE80211_AC_VO] = R_AX_MUEDCA_VO_PARAM_0,
|
||||
[IEEE80211_AC_VI] = R_AX_MUEDCA_VI_PARAM_0,
|
||||
[IEEE80211_AC_BE] = R_AX_MUEDCA_BE_PARAM_0,
|
||||
[IEEE80211_AC_BK] = R_AX_MUEDCA_BK_PARAM_0,
|
||||
};
|
||||
|
||||
static void ____rtw89_conf_tx_mu_edca(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif, u16 ac)
|
||||
{
|
||||
struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac];
|
||||
struct ieee80211_he_mu_edca_param_ac_rec *mu_edca;
|
||||
u8 aifs, aifsn;
|
||||
u16 timer_32us;
|
||||
u32 reg;
|
||||
u32 val;
|
||||
|
||||
if (!params->mu_edca)
|
||||
return;
|
||||
|
||||
mu_edca = ¶ms->mu_edca_param_rec;
|
||||
aifsn = FIELD_GET(GENMASK(3, 0), mu_edca->aifsn);
|
||||
aifs = aifsn ? rtw89_aifsn_to_aifs(rtwdev, rtwvif, aifsn) : 0;
|
||||
timer_32us = mu_edca->mu_edca_timer << 8;
|
||||
|
||||
val = FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_TIMER_MASK, timer_32us) |
|
||||
FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_CW_MASK, mu_edca->ecw_min_max) |
|
||||
FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_AIFS_MASK, aifs);
|
||||
reg = rtw89_mac_reg_by_idx(ac_to_mu_edca_param[ac], rtwvif->mac_idx);
|
||||
rtw89_write32(rtwdev, reg, val);
|
||||
|
||||
rtw89_mac_set_hw_muedca_ctrl(rtwdev, rtwvif, true);
|
||||
}
|
||||
|
||||
static void __rtw89_conf_tx(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif, u16 ac)
|
||||
{
|
||||
____rtw89_conf_tx_edca(rtwdev, rtwvif, ac);
|
||||
____rtw89_conf_tx_mu_edca(rtwdev, rtwvif, ac);
|
||||
}
|
||||
|
||||
static void rtw89_conf_tx(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif)
|
||||
{
|
||||
u16 ac;
|
||||
|
||||
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
|
||||
__rtw89_conf_tx(rtwdev, rtwvif, ac);
|
||||
}
|
||||
|
||||
static void rtw89_station_mode_sta_assoc(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *conf)
|
||||
{
|
||||
struct ieee80211_sta *sta;
|
||||
|
||||
if (vif->type != NL80211_IFTYPE_STATION)
|
||||
return;
|
||||
|
||||
sta = ieee80211_find_sta(vif, conf->bssid);
|
||||
if (!sta) {
|
||||
rtw89_err(rtwdev, "can't find sta to set sta_assoc state\n");
|
||||
return;
|
||||
}
|
||||
rtw89_core_sta_assoc(rtwdev, vif, sta);
|
||||
}
|
||||
|
||||
static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *conf,
|
||||
u32 changed)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
rtw89_leave_ps_mode(rtwdev);
|
||||
|
||||
if (changed & BSS_CHANGED_ASSOC) {
|
||||
if (conf->assoc) {
|
||||
rtw89_station_mode_sta_assoc(rtwdev, vif, conf);
|
||||
rtw89_phy_set_bss_color(rtwdev, vif);
|
||||
rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, vif);
|
||||
rtw89_mac_port_update(rtwdev, rtwvif);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_BSSID) {
|
||||
ether_addr_copy(rtwvif->bssid, conf->bssid);
|
||||
rtw89_cam_bssid_changed(rtwdev, rtwvif);
|
||||
rtw89_fw_h2c_cam(rtwdev, rtwvif);
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_ERP_SLOT)
|
||||
rtw89_conf_tx(rtwdev, rtwvif);
|
||||
|
||||
if (changed & BSS_CHANGED_HE_BSS_COLOR)
|
||||
rtw89_phy_set_bss_color(rtwdev, vif);
|
||||
|
||||
if (changed & BSS_CHANGED_MU_GROUPS)
|
||||
rtw89_mac_bf_set_gid_table(rtwdev, vif, conf);
|
||||
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
}
|
||||
|
||||
static int rtw89_ops_conf_tx(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif, u16 ac,
|
||||
const struct ieee80211_tx_queue_params *params)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
rtw89_leave_ps_mode(rtwdev);
|
||||
rtwvif->tx_params[ac] = *params;
|
||||
__rtw89_conf_tx(rtwdev, rtwvif, ac);
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __rtw89_ops_sta_state(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
enum ieee80211_sta_state old_state,
|
||||
enum ieee80211_sta_state new_state)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
|
||||
if (old_state == IEEE80211_STA_NOTEXIST &&
|
||||
new_state == IEEE80211_STA_NONE)
|
||||
return rtw89_core_sta_add(rtwdev, vif, sta);
|
||||
|
||||
if (old_state == IEEE80211_STA_AUTH &&
|
||||
new_state == IEEE80211_STA_ASSOC) {
|
||||
if (vif->type == NL80211_IFTYPE_STATION)
|
||||
return 0; /* defer to bss_info_changed to have vif info */
|
||||
return rtw89_core_sta_assoc(rtwdev, vif, sta);
|
||||
}
|
||||
|
||||
if (old_state == IEEE80211_STA_ASSOC &&
|
||||
new_state == IEEE80211_STA_AUTH)
|
||||
return rtw89_core_sta_disassoc(rtwdev, vif, sta);
|
||||
|
||||
if (old_state == IEEE80211_STA_AUTH &&
|
||||
new_state == IEEE80211_STA_NONE)
|
||||
return rtw89_core_sta_disconnect(rtwdev, vif, sta);
|
||||
|
||||
if (old_state == IEEE80211_STA_NONE &&
|
||||
new_state == IEEE80211_STA_NOTEXIST)
|
||||
return rtw89_core_sta_remove(rtwdev, vif, sta);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_ops_sta_state(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
enum ieee80211_sta_state old_state,
|
||||
enum ieee80211_sta_state new_state)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
rtw89_leave_ps_mode(rtwdev);
|
||||
ret = __rtw89_ops_sta_state(hw, vif, sta, old_state, new_state);
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
rtw89_leave_ps_mode(rtwdev);
|
||||
|
||||
switch (cmd) {
|
||||
case SET_KEY:
|
||||
rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_EAPOL_END);
|
||||
ret = rtw89_cam_sec_key_add(rtwdev, vif, sta, key);
|
||||
if (ret && ret != -EOPNOTSUPP) {
|
||||
rtw89_err(rtwdev, "failed to add key to sec cam\n");
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
case DISABLE_KEY:
|
||||
rtw89_hci_flush_queues(rtwdev, BIT(rtwdev->hw->queues) - 1,
|
||||
false);
|
||||
rtw89_mac_flush_txq(rtwdev, BIT(rtwdev->hw->queues) - 1, false);
|
||||
ret = rtw89_cam_sec_key_del(rtwdev, vif, sta, key, true);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to remove key from sec cam\n");
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_ampdu_params *params)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
struct ieee80211_sta *sta = params->sta;
|
||||
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
|
||||
u16 tid = params->tid;
|
||||
struct ieee80211_txq *txq = sta->txq[tid];
|
||||
struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv;
|
||||
|
||||
switch (params->action) {
|
||||
case IEEE80211_AMPDU_TX_START:
|
||||
return IEEE80211_AMPDU_TX_START_IMMEDIATE;
|
||||
case IEEE80211_AMPDU_TX_STOP_CONT:
|
||||
case IEEE80211_AMPDU_TX_STOP_FLUSH:
|
||||
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
clear_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags);
|
||||
rtw89_fw_h2c_ba_cam(rtwdev, false, rtwsta->mac_id, params);
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
|
||||
break;
|
||||
case IEEE80211_AMPDU_TX_OPERATIONAL:
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
set_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags);
|
||||
rtwsta->ampdu_params[tid].agg_num = params->buf_size;
|
||||
rtwsta->ampdu_params[tid].amsdu = params->amsdu;
|
||||
rtw89_leave_ps_mode(rtwdev);
|
||||
rtw89_fw_h2c_ba_cam(rtwdev, true, rtwsta->mac_id, params);
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
break;
|
||||
case IEEE80211_AMPDU_RX_START:
|
||||
case IEEE80211_AMPDU_RX_STOP:
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
rtw89_leave_ps_mode(rtwdev);
|
||||
if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags))
|
||||
rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0);
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rtw89_ops_sta_statistics(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct station_info *sinfo)
|
||||
{
|
||||
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
|
||||
|
||||
sinfo->txrate = rtwsta->ra_report.txrate;
|
||||
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
|
||||
}
|
||||
|
||||
static void rtw89_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
u32 queues, bool drop)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
rtw89_leave_lps(rtwdev);
|
||||
rtw89_hci_flush_queues(rtwdev, queues, drop);
|
||||
rtw89_mac_flush_txq(rtwdev, queues, drop);
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
}
|
||||
|
||||
struct rtw89_iter_bitrate_mask_data {
|
||||
struct rtw89_dev *rtwdev;
|
||||
struct ieee80211_vif *vif;
|
||||
const struct cfg80211_bitrate_mask *mask;
|
||||
};
|
||||
|
||||
static void rtw89_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta)
|
||||
{
|
||||
struct rtw89_iter_bitrate_mask_data *br_data = data;
|
||||
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
|
||||
struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta->rtwvif);
|
||||
|
||||
if (vif != br_data->vif)
|
||||
return;
|
||||
|
||||
rtwsta->use_cfg_mask = true;
|
||||
rtwsta->mask = *br_data->mask;
|
||||
rtw89_phy_ra_updata_sta(br_data->rtwdev, sta);
|
||||
}
|
||||
|
||||
static void rtw89_ra_mask_info_update(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_vif *vif,
|
||||
const struct cfg80211_bitrate_mask *mask)
|
||||
{
|
||||
struct rtw89_iter_bitrate_mask_data br_data = { .rtwdev = rtwdev,
|
||||
.vif = vif,
|
||||
.mask = mask};
|
||||
|
||||
ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_ra_mask_info_update_iter,
|
||||
&br_data);
|
||||
}
|
||||
|
||||
static int rtw89_ops_set_bitrate_mask(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
const struct cfg80211_bitrate_mask *mask)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
rtw89_phy_rate_pattern_vif(rtwdev, vif, mask);
|
||||
rtw89_ra_mask_info_update(rtwdev, vif, mask);
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
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)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
hal->antenna_tx = tx_ant;
|
||||
hal->antenna_rx = rx_ant;
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int rtw89_ops_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
struct rtw89_hal *hal = &rtwdev->hal;
|
||||
|
||||
*tx_ant = hal->antenna_tx;
|
||||
*rx_ant = hal->antenna_rx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rtw89_ops_sw_scan_start(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
const u8 *mac_addr)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
struct rtw89_hal *hal = &rtwdev->hal;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
rtwdev->scanning = true;
|
||||
rtw89_leave_lps(rtwdev);
|
||||
rtw89_btc_ntfy_scan_start(rtwdev, RTW89_PHY_0, hal->current_band_type);
|
||||
rtw89_chip_rfk_scan(rtwdev, true);
|
||||
rtw89_hci_recalc_int_mit(rtwdev);
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
}
|
||||
|
||||
static void rtw89_ops_sw_scan_complete(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
rtw89_chip_rfk_scan(rtwdev, false);
|
||||
rtw89_btc_ntfy_scan_finish(rtwdev, RTW89_PHY_0);
|
||||
rtwdev->scanning = false;
|
||||
rtwdev->dig.bypass_dig = true;
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
}
|
||||
|
||||
static void rtw89_ops_reconfig_complete(struct ieee80211_hw *hw,
|
||||
enum ieee80211_reconfig_type reconfig_type)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
|
||||
if (reconfig_type == IEEE80211_RECONFIG_TYPE_RESTART)
|
||||
rtw89_ser_recfg_done(rtwdev);
|
||||
}
|
||||
|
||||
const struct ieee80211_ops rtw89_ops = {
|
||||
.tx = rtw89_ops_tx,
|
||||
.wake_tx_queue = rtw89_ops_wake_tx_queue,
|
||||
.start = rtw89_ops_start,
|
||||
.stop = rtw89_ops_stop,
|
||||
.config = rtw89_ops_config,
|
||||
.add_interface = rtw89_ops_add_interface,
|
||||
.remove_interface = rtw89_ops_remove_interface,
|
||||
.configure_filter = rtw89_ops_configure_filter,
|
||||
.bss_info_changed = rtw89_ops_bss_info_changed,
|
||||
.conf_tx = rtw89_ops_conf_tx,
|
||||
.sta_state = rtw89_ops_sta_state,
|
||||
.set_key = rtw89_ops_set_key,
|
||||
.ampdu_action = rtw89_ops_ampdu_action,
|
||||
.set_rts_threshold = rtw89_ops_set_rts_threshold,
|
||||
.sta_statistics = rtw89_ops_sta_statistics,
|
||||
.flush = rtw89_ops_flush,
|
||||
.set_bitrate_mask = rtw89_ops_set_bitrate_mask,
|
||||
.set_antenna = rtw89_ops_set_antenna,
|
||||
.get_antenna = rtw89_ops_get_antenna,
|
||||
.sw_scan_start = rtw89_ops_sw_scan_start,
|
||||
.sw_scan_complete = rtw89_ops_sw_scan_complete,
|
||||
.reconfig_complete = rtw89_ops_reconfig_complete,
|
||||
.set_sar_specs = rtw89_ops_set_sar_specs,
|
||||
};
|
||||
EXPORT_SYMBOL(rtw89_ops);
|
3060
drivers/net/wireless/realtek/rtw89/pci.c
Normal file
3060
drivers/net/wireless/realtek/rtw89/pci.c
Normal file
File diff suppressed because it is too large
Load Diff
635
drivers/net/wireless/realtek/rtw89/pci.h
Normal file
635
drivers/net/wireless/realtek/rtw89/pci.h
Normal file
@ -0,0 +1,635 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW89_PCI_H__
|
||||
#define __RTW89_PCI_H__
|
||||
|
||||
#include "txrx.h"
|
||||
|
||||
#define MDIO_PG0_G1 0
|
||||
#define MDIO_PG1_G1 1
|
||||
#define MDIO_PG0_G2 2
|
||||
#define MDIO_PG1_G2 3
|
||||
#define RAC_ANA10 0x10
|
||||
#define RAC_ANA19 0x19
|
||||
#define RAC_ANA1F 0x1F
|
||||
#define RAC_ANA24 0x24
|
||||
#define B_AX_DEGLITCH GENMASK(11, 8)
|
||||
#define RAC_ANA26 0x26
|
||||
#define B_AX_RXEN GENMASK(15, 14)
|
||||
#define RAC_CTRL_PPR_V1 0x30
|
||||
#define B_AX_CLK_CALIB_EN BIT(12)
|
||||
#define B_AX_CALIB_EN BIT(13)
|
||||
#define B_AX_DIV GENMASK(15, 14)
|
||||
#define RAC_SET_PPR_V1 0x31
|
||||
|
||||
#define R_AX_DBI_FLAG 0x1090
|
||||
#define B_AX_DBI_RFLAG BIT(17)
|
||||
#define B_AX_DBI_WFLAG BIT(16)
|
||||
#define B_AX_DBI_WREN_MSK GENMASK(15, 12)
|
||||
#define B_AX_DBI_ADDR_MSK GENMASK(11, 2)
|
||||
#define R_AX_DBI_WDATA 0x1094
|
||||
#define R_AX_DBI_RDATA 0x1098
|
||||
|
||||
#define R_AX_MDIO_WDATA 0x10A4
|
||||
#define R_AX_MDIO_RDATA 0x10A6
|
||||
|
||||
#define RTW89_PCI_WR_RETRY_CNT 20
|
||||
|
||||
/* Interrupts */
|
||||
#define R_AX_HIMR0 0x01A0
|
||||
#define B_AX_HALT_C2H_INT_EN BIT(21)
|
||||
#define R_AX_HISR0 0x01A4
|
||||
|
||||
#define R_AX_MDIO_CFG 0x10A0
|
||||
#define B_AX_MDIO_PHY_ADDR_MASK GENMASK(13, 12)
|
||||
#define B_AX_MDIO_RFLAG BIT(9)
|
||||
#define B_AX_MDIO_WFLAG BIT(8)
|
||||
#define B_AX_MDIO_ADDR_MASK GENMASK(4, 0)
|
||||
|
||||
#define R_AX_PCIE_HIMR00 0x10B0
|
||||
#define B_AX_HC00ISR_IND_INT_EN BIT(27)
|
||||
#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_RETRAIN_INT_EN BIT(21)
|
||||
#define B_AX_RPQBD_FULL_INT_EN BIT(20)
|
||||
#define B_AX_RDU_INT_EN BIT(19)
|
||||
#define B_AX_RXDMA_STUCK_INT_EN BIT(18)
|
||||
#define B_AX_TXDMA_STUCK_INT_EN BIT(17)
|
||||
#define B_AX_PCIE_HOTRST_INT_EN BIT(16)
|
||||
#define B_AX_PCIE_FLR_INT_EN BIT(15)
|
||||
#define B_AX_PCIE_PERST_INT_EN BIT(14)
|
||||
#define B_AX_TXDMA_CH12_INT_EN BIT(13)
|
||||
#define B_AX_TXDMA_CH9_INT_EN BIT(12)
|
||||
#define B_AX_TXDMA_CH8_INT_EN BIT(11)
|
||||
#define B_AX_TXDMA_ACH7_INT_EN BIT(10)
|
||||
#define B_AX_TXDMA_ACH6_INT_EN BIT(9)
|
||||
#define B_AX_TXDMA_ACH5_INT_EN BIT(8)
|
||||
#define B_AX_TXDMA_ACH4_INT_EN BIT(7)
|
||||
#define B_AX_TXDMA_ACH3_INT_EN BIT(6)
|
||||
#define B_AX_TXDMA_ACH2_INT_EN BIT(5)
|
||||
#define B_AX_TXDMA_ACH1_INT_EN BIT(4)
|
||||
#define B_AX_TXDMA_ACH0_INT_EN BIT(3)
|
||||
#define B_AX_RPQDMA_INT_EN BIT(2)
|
||||
#define B_AX_RXP1DMA_INT_EN BIT(1)
|
||||
#define B_AX_RXDMA_INT_EN BIT(0)
|
||||
|
||||
#define R_AX_PCIE_HISR00 0x10B4
|
||||
#define B_AX_HC00ISR_IND_INT BIT(27)
|
||||
#define B_AX_HD1ISR_IND_INT BIT(26)
|
||||
#define B_AX_HD0ISR_IND_INT BIT(25)
|
||||
#define B_AX_HS0ISR_IND_INT BIT(24)
|
||||
#define B_AX_RETRAIN_INT BIT(21)
|
||||
#define B_AX_RPQBD_FULL_INT BIT(20)
|
||||
#define B_AX_RDU_INT BIT(19)
|
||||
#define B_AX_RXDMA_STUCK_INT BIT(18)
|
||||
#define B_AX_TXDMA_STUCK_INT BIT(17)
|
||||
#define B_AX_PCIE_HOTRST_INT BIT(16)
|
||||
#define B_AX_PCIE_FLR_INT BIT(15)
|
||||
#define B_AX_PCIE_PERST_INT BIT(14)
|
||||
#define B_AX_TXDMA_CH12_INT BIT(13)
|
||||
#define B_AX_TXDMA_CH9_INT BIT(12)
|
||||
#define B_AX_TXDMA_CH8_INT BIT(11)
|
||||
#define B_AX_TXDMA_ACH7_INT BIT(10)
|
||||
#define B_AX_TXDMA_ACH6_INT BIT(9)
|
||||
#define B_AX_TXDMA_ACH5_INT BIT(8)
|
||||
#define B_AX_TXDMA_ACH4_INT BIT(7)
|
||||
#define B_AX_TXDMA_ACH3_INT BIT(6)
|
||||
#define B_AX_TXDMA_ACH2_INT BIT(5)
|
||||
#define B_AX_TXDMA_ACH1_INT BIT(4)
|
||||
#define B_AX_TXDMA_ACH0_INT BIT(3)
|
||||
#define B_AX_RPQDMA_INT BIT(2)
|
||||
#define B_AX_RXP1DMA_INT BIT(1)
|
||||
#define B_AX_RXDMA_INT BIT(0)
|
||||
|
||||
#define R_AX_PCIE_HIMR10 0x13B0
|
||||
#define B_AX_HC10ISR_IND_INT_EN BIT(28)
|
||||
#define B_AX_TXDMA_CH11_INT_EN BIT(12)
|
||||
#define B_AX_TXDMA_CH10_INT_EN BIT(11)
|
||||
|
||||
#define R_AX_PCIE_HISR10 0x13B4
|
||||
#define B_AX_HC10ISR_IND_INT BIT(28)
|
||||
#define B_AX_TXDMA_CH11_INT BIT(12)
|
||||
#define B_AX_TXDMA_CH10_INT BIT(11)
|
||||
|
||||
/* TX/RX */
|
||||
#define R_AX_RXQ_RXBD_IDX 0x1050
|
||||
#define R_AX_RPQ_RXBD_IDX 0x1054
|
||||
#define R_AX_ACH0_TXBD_IDX 0x1058
|
||||
#define R_AX_ACH1_TXBD_IDX 0x105C
|
||||
#define R_AX_ACH2_TXBD_IDX 0x1060
|
||||
#define R_AX_ACH3_TXBD_IDX 0x1064
|
||||
#define R_AX_ACH4_TXBD_IDX 0x1068
|
||||
#define R_AX_ACH5_TXBD_IDX 0x106C
|
||||
#define R_AX_ACH6_TXBD_IDX 0x1070
|
||||
#define R_AX_ACH7_TXBD_IDX 0x1074
|
||||
#define R_AX_CH8_TXBD_IDX 0x1078 /* Management Queue band 0 */
|
||||
#define R_AX_CH9_TXBD_IDX 0x107C /* HI Queue band 0 */
|
||||
#define R_AX_CH10_TXBD_IDX 0x137C /* Management Queue band 1 */
|
||||
#define R_AX_CH11_TXBD_IDX 0x1380 /* HI Queue band 1 */
|
||||
#define R_AX_CH12_TXBD_IDX 0x1080 /* FWCMD Queue */
|
||||
#define TXBD_HW_IDX_MASK GENMASK(27, 16)
|
||||
#define TXBD_HOST_IDX_MASK GENMASK(11, 0)
|
||||
|
||||
#define R_AX_ACH0_TXBD_DESA_L 0x1110
|
||||
#define R_AX_ACH0_TXBD_DESA_H 0x1114
|
||||
#define R_AX_ACH1_TXBD_DESA_L 0x1118
|
||||
#define R_AX_ACH1_TXBD_DESA_H 0x111C
|
||||
#define R_AX_ACH2_TXBD_DESA_L 0x1120
|
||||
#define R_AX_ACH2_TXBD_DESA_H 0x1124
|
||||
#define R_AX_ACH3_TXBD_DESA_L 0x1128
|
||||
#define R_AX_ACH3_TXBD_DESA_H 0x112C
|
||||
#define R_AX_ACH4_TXBD_DESA_L 0x1130
|
||||
#define R_AX_ACH4_TXBD_DESA_H 0x1134
|
||||
#define R_AX_ACH5_TXBD_DESA_L 0x1138
|
||||
#define R_AX_ACH5_TXBD_DESA_H 0x113C
|
||||
#define R_AX_ACH6_TXBD_DESA_L 0x1140
|
||||
#define R_AX_ACH6_TXBD_DESA_H 0x1144
|
||||
#define R_AX_ACH7_TXBD_DESA_L 0x1148
|
||||
#define R_AX_ACH7_TXBD_DESA_H 0x114C
|
||||
#define R_AX_CH8_TXBD_DESA_L 0x1150
|
||||
#define R_AX_CH8_TXBD_DESA_H 0x1154
|
||||
#define R_AX_CH9_TXBD_DESA_L 0x1158
|
||||
#define R_AX_CH9_TXBD_DESA_H 0x115C
|
||||
#define R_AX_CH10_TXBD_DESA_L 0x1358
|
||||
#define R_AX_CH10_TXBD_DESA_H 0x135C
|
||||
#define R_AX_CH11_TXBD_DESA_L 0x1360
|
||||
#define R_AX_CH11_TXBD_DESA_H 0x1364
|
||||
#define R_AX_CH12_TXBD_DESA_L 0x1160
|
||||
#define R_AX_CH12_TXBD_DESA_H 0x1164
|
||||
#define R_AX_RXQ_RXBD_DESA_L 0x1100
|
||||
#define R_AX_RXQ_RXBD_DESA_H 0x1104
|
||||
#define R_AX_RPQ_RXBD_DESA_L 0x1108
|
||||
#define R_AX_RPQ_RXBD_DESA_H 0x110C
|
||||
#define B_AX_DESC_NUM_MSK GENMASK(11, 0)
|
||||
|
||||
#define R_AX_RXQ_RXBD_NUM 0x1020
|
||||
#define R_AX_RPQ_RXBD_NUM 0x1022
|
||||
#define R_AX_ACH0_TXBD_NUM 0x1024
|
||||
#define R_AX_ACH1_TXBD_NUM 0x1026
|
||||
#define R_AX_ACH2_TXBD_NUM 0x1028
|
||||
#define R_AX_ACH3_TXBD_NUM 0x102A
|
||||
#define R_AX_ACH4_TXBD_NUM 0x102C
|
||||
#define R_AX_ACH5_TXBD_NUM 0x102E
|
||||
#define R_AX_ACH6_TXBD_NUM 0x1030
|
||||
#define R_AX_ACH7_TXBD_NUM 0x1032
|
||||
#define R_AX_CH8_TXBD_NUM 0x1034
|
||||
#define R_AX_CH9_TXBD_NUM 0x1036
|
||||
#define R_AX_CH10_TXBD_NUM 0x1338
|
||||
#define R_AX_CH11_TXBD_NUM 0x133A
|
||||
#define R_AX_CH12_TXBD_NUM 0x1038
|
||||
|
||||
#define R_AX_ACH0_BDRAM_CTRL 0x1200
|
||||
#define R_AX_ACH1_BDRAM_CTRL 0x1204
|
||||
#define R_AX_ACH2_BDRAM_CTRL 0x1208
|
||||
#define R_AX_ACH3_BDRAM_CTRL 0x120C
|
||||
#define R_AX_ACH4_BDRAM_CTRL 0x1210
|
||||
#define R_AX_ACH5_BDRAM_CTRL 0x1214
|
||||
#define R_AX_ACH6_BDRAM_CTRL 0x1218
|
||||
#define R_AX_ACH7_BDRAM_CTRL 0x121C
|
||||
#define R_AX_CH8_BDRAM_CTRL 0x1220
|
||||
#define R_AX_CH9_BDRAM_CTRL 0x1224
|
||||
#define R_AX_CH10_BDRAM_CTRL 0x1320
|
||||
#define R_AX_CH11_BDRAM_CTRL 0x1324
|
||||
#define R_AX_CH12_BDRAM_CTRL 0x1228
|
||||
#define BDRAM_SIDX_MASK GENMASK(7, 0)
|
||||
#define BDRAM_MAX_MASK GENMASK(15, 8)
|
||||
#define BDRAM_MIN_MASK GENMASK(23, 16)
|
||||
|
||||
#define R_AX_PCIE_INIT_CFG1 0x1000
|
||||
#define B_AX_PCIE_RXRST_KEEP_REG BIT(23)
|
||||
#define B_AX_PCIE_TXRST_KEEP_REG BIT(22)
|
||||
#define B_AX_PCIE_PERST_KEEP_REG BIT(21)
|
||||
#define B_AX_PCIE_FLR_KEEP_REG BIT(20)
|
||||
#define B_AX_PCIE_TRAIN_KEEP_REG BIT(19)
|
||||
#define B_AX_RXBD_MODE BIT(18)
|
||||
#define B_AX_PCIE_MAX_RXDMA_MASK GENMASK(16, 14)
|
||||
#define B_AX_RXHCI_EN BIT(13)
|
||||
#define B_AX_LATENCY_CONTROL BIT(12)
|
||||
#define B_AX_TXHCI_EN BIT(11)
|
||||
#define B_AX_PCIE_MAX_TXDMA_MASK GENMASK(10, 8)
|
||||
#define B_AX_TX_TRUNC_MODE BIT(5)
|
||||
#define B_AX_RX_TRUNC_MODE BIT(4)
|
||||
#define B_AX_RST_BDRAM BIT(3)
|
||||
#define B_AX_DIS_RXDMA_PRE BIT(2)
|
||||
|
||||
#define R_AX_TXDMA_ADDR_H 0x10F0
|
||||
#define R_AX_RXDMA_ADDR_H 0x10F4
|
||||
|
||||
#define R_AX_PCIE_DMA_STOP1 0x1010
|
||||
#define B_AX_STOP_PCIEIO BIT(20)
|
||||
#define B_AX_STOP_WPDMA BIT(19)
|
||||
#define B_AX_STOP_CH12 BIT(18)
|
||||
#define B_AX_STOP_CH9 BIT(17)
|
||||
#define B_AX_STOP_CH8 BIT(16)
|
||||
#define B_AX_STOP_ACH7 BIT(15)
|
||||
#define B_AX_STOP_ACH6 BIT(14)
|
||||
#define B_AX_STOP_ACH5 BIT(13)
|
||||
#define B_AX_STOP_ACH4 BIT(12)
|
||||
#define B_AX_STOP_ACH3 BIT(11)
|
||||
#define B_AX_STOP_ACH2 BIT(10)
|
||||
#define B_AX_STOP_ACH1 BIT(9)
|
||||
#define B_AX_STOP_ACH0 BIT(8)
|
||||
#define B_AX_STOP_RPQ BIT(1)
|
||||
#define B_AX_STOP_RXQ BIT(0)
|
||||
#define B_AX_TX_STOP1_ALL GENMASK(18, 8)
|
||||
|
||||
#define R_AX_PCIE_DMA_STOP2 0x1310
|
||||
#define B_AX_STOP_CH11 BIT(1)
|
||||
#define B_AX_STOP_CH10 BIT(0)
|
||||
#define B_AX_TX_STOP2_ALL GENMASK(1, 0)
|
||||
|
||||
#define R_AX_TXBD_RWPTR_CLR1 0x1014
|
||||
#define B_AX_CLR_CH12_IDX BIT(10)
|
||||
#define B_AX_CLR_CH9_IDX BIT(9)
|
||||
#define B_AX_CLR_CH8_IDX BIT(8)
|
||||
#define B_AX_CLR_ACH7_IDX BIT(7)
|
||||
#define B_AX_CLR_ACH6_IDX BIT(6)
|
||||
#define B_AX_CLR_ACH5_IDX BIT(5)
|
||||
#define B_AX_CLR_ACH4_IDX BIT(4)
|
||||
#define B_AX_CLR_ACH3_IDX BIT(3)
|
||||
#define B_AX_CLR_ACH2_IDX BIT(2)
|
||||
#define B_AX_CLR_ACH1_IDX BIT(1)
|
||||
#define B_AX_CLR_ACH0_IDX BIT(0)
|
||||
#define B_AX_TXBD_CLR1_ALL GENMASK(10, 0)
|
||||
|
||||
#define R_AX_RXBD_RWPTR_CLR 0x1018
|
||||
#define B_AX_CLR_RPQ_IDX BIT(1)
|
||||
#define B_AX_CLR_RXQ_IDX BIT(0)
|
||||
#define B_AX_RXBD_CLR_ALL GENMASK(1, 0)
|
||||
|
||||
#define R_AX_TXBD_RWPTR_CLR2 0x1314
|
||||
#define B_AX_CLR_CH11_IDX BIT(1)
|
||||
#define B_AX_CLR_CH10_IDX BIT(0)
|
||||
#define B_AX_TXBD_CLR2_ALL GENMASK(1, 0)
|
||||
|
||||
#define R_AX_PCIE_DMA_BUSY1 0x101C
|
||||
#define B_AX_PCIEIO_RX_BUSY BIT(22)
|
||||
#define B_AX_PCIEIO_TX_BUSY BIT(21)
|
||||
#define B_AX_PCIEIO_BUSY BIT(20)
|
||||
#define B_AX_WPDMA_BUSY BIT(19)
|
||||
|
||||
#define R_AX_PCIE_DMA_BUSY2 0x131C
|
||||
#define B_AX_CH11_BUSY BIT(1)
|
||||
#define B_AX_CH10_BUSY BIT(0)
|
||||
|
||||
/* Configure */
|
||||
#define R_AX_PCIE_INIT_CFG1 0x1000
|
||||
#define B_AX_PCIE_RXRST_KEEP_REG BIT(23)
|
||||
#define B_AX_PCIE_TXRST_KEEP_REG BIT(22)
|
||||
#define B_AX_DIS_RXDMA_PRE BIT(2)
|
||||
|
||||
#define R_AX_PCIE_INIT_CFG2 0x1004
|
||||
#define B_AX_WD_ITVL_IDLE GENMASK(27, 24)
|
||||
#define B_AX_WD_ITVL_ACT GENMASK(19, 16)
|
||||
|
||||
#define R_AX_PCIE_PS_CTRL 0x1008
|
||||
#define B_AX_L1OFF_PWR_OFF_EN BIT(5)
|
||||
|
||||
#define R_AX_INT_MIT_RX 0x10D4
|
||||
#define B_AX_RXMIT_RXP2_SEL BIT(19)
|
||||
#define B_AX_RXMIT_RXP1_SEL BIT(18)
|
||||
#define B_AX_RXTIMER_UNIT_MASK GENMASK(17, 16)
|
||||
#define AX_RXTIMER_UNIT_64US 0
|
||||
#define AX_RXTIMER_UNIT_128US 1
|
||||
#define AX_RXTIMER_UNIT_256US 2
|
||||
#define AX_RXTIMER_UNIT_512US 3
|
||||
#define B_AX_RXCOUNTER_MATCH_MASK GENMASK(15, 8)
|
||||
#define B_AX_RXTIMER_MATCH_MASK GENMASK(7, 0)
|
||||
|
||||
#define R_AX_DBG_ERR_FLAG 0x11C4
|
||||
#define B_AX_PCIE_RPQ_FULL BIT(29)
|
||||
#define B_AX_PCIE_RXQ_FULL BIT(28)
|
||||
#define B_AX_CPL_STATUS_MASK GENMASK(27, 25)
|
||||
#define B_AX_RX_STUCK BIT(22)
|
||||
#define B_AX_TX_STUCK BIT(21)
|
||||
#define B_AX_PCIEDBG_TXERR0 BIT(16)
|
||||
#define B_AX_PCIE_RXP1_ERR0 BIT(4)
|
||||
#define B_AX_PCIE_TXBD_LEN0 BIT(1)
|
||||
#define B_AX_PCIE_TXBD_4KBOUD_LENERR BIT(0)
|
||||
|
||||
#define R_AX_LBC_WATCHDOG 0x11D8
|
||||
#define B_AX_LBC_TIMER GENMASK(7, 4)
|
||||
#define B_AX_LBC_FLAG BIT(1)
|
||||
#define B_AX_LBC_EN BIT(0)
|
||||
|
||||
#define R_AX_PCIE_EXP_CTRL 0x13F0
|
||||
#define B_AX_EN_CHKDSC_NO_RX_STUCK BIT(20)
|
||||
#define B_AX_MAX_TAG_NUM GENMASK(18, 16)
|
||||
#define B_AX_SIC_EN_FORCE_CLKREQ BIT(4)
|
||||
|
||||
#define R_AX_PCIE_RX_PREF_ADV 0x13F4
|
||||
#define B_AX_RXDMA_PREF_ADV_EN BIT(0)
|
||||
|
||||
#define RTW89_PCI_TXBD_NUM_MAX 256
|
||||
#define RTW89_PCI_RXBD_NUM_MAX 256
|
||||
#define RTW89_PCI_TXWD_NUM_MAX 512
|
||||
#define RTW89_PCI_TXWD_PAGE_SIZE 128
|
||||
#define RTW89_PCI_ADDRINFO_MAX 4
|
||||
#define RTW89_PCI_RX_BUF_SIZE 11460
|
||||
|
||||
#define RTW89_PCI_POLL_BDRAM_RST_CNT 100
|
||||
#define RTW89_PCI_MULTITAG 8
|
||||
|
||||
/* PCIE CFG register */
|
||||
#define RTW89_PCIE_ASPM_CTRL 0x070F
|
||||
#define RTW89_L1DLY_MASK GENMASK(5, 3)
|
||||
#define RTW89_L0DLY_MASK GENMASK(2, 0)
|
||||
#define RTW89_PCIE_TIMER_CTRL 0x0718
|
||||
#define RTW89_PCIE_BIT_L1SUB BIT(5)
|
||||
#define RTW89_PCIE_L1_CTRL 0x0719
|
||||
#define RTW89_PCIE_BIT_CLK BIT(4)
|
||||
#define RTW89_PCIE_BIT_L1 BIT(3)
|
||||
#define RTW89_PCIE_CLK_CTRL 0x0725
|
||||
#define RTW89_PCIE_RST_MSTATE 0x0B48
|
||||
#define RTW89_PCIE_BIT_CFG_RST_MSTATE BIT(0)
|
||||
#define RTW89_PCIE_PHY_RATE 0x82
|
||||
#define RTW89_PCIE_PHY_RATE_MASK GENMASK(1, 0)
|
||||
#define INTF_INTGRA_MINREF_V1 90
|
||||
#define INTF_INTGRA_HOSTREF_V1 100
|
||||
|
||||
enum rtw89_pcie_phy {
|
||||
PCIE_PHY_GEN1,
|
||||
PCIE_PHY_GEN2,
|
||||
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,
|
||||
PCIE_L0SDLY_3US = 2,
|
||||
PCIE_L0SDLY_4US = 3,
|
||||
PCIE_L0SDLY_5US = 4,
|
||||
PCIE_L0SDLY_6US = 5,
|
||||
PCIE_L0SDLY_7US = 6,
|
||||
};
|
||||
|
||||
enum rtw89_pcie_l1dly {
|
||||
PCIE_L1DLY_16US = 4,
|
||||
PCIE_L1DLY_32US = 5,
|
||||
PCIE_L1DLY_64US = 6,
|
||||
PCIE_L1DLY_HW_INFI = 7,
|
||||
};
|
||||
|
||||
enum rtw89_pcie_clkdly_hw {
|
||||
PCIE_CLKDLY_HW_0 = 0,
|
||||
PCIE_CLKDLY_HW_30US = 0x1,
|
||||
PCIE_CLKDLY_HW_50US = 0x2,
|
||||
PCIE_CLKDLY_HW_100US = 0x3,
|
||||
PCIE_CLKDLY_HW_150US = 0x4,
|
||||
PCIE_CLKDLY_HW_200US = 0x5,
|
||||
};
|
||||
|
||||
struct rtw89_pci_bd_ram {
|
||||
u8 start_idx;
|
||||
u8 max_num;
|
||||
u8 min_num;
|
||||
};
|
||||
|
||||
struct rtw89_pci_tx_data {
|
||||
dma_addr_t dma;
|
||||
};
|
||||
|
||||
struct rtw89_pci_rx_info {
|
||||
dma_addr_t dma;
|
||||
u32 fs:1, ls:1, tag:11, len:14;
|
||||
};
|
||||
|
||||
#define RTW89_PCI_TXBD_OPTION_LS BIT(14)
|
||||
|
||||
struct rtw89_pci_tx_bd_32 {
|
||||
__le16 length;
|
||||
__le16 option;
|
||||
__le32 dma;
|
||||
} __packed;
|
||||
|
||||
#define RTW89_PCI_TXWP_VALID BIT(15)
|
||||
|
||||
struct rtw89_pci_tx_wp_info {
|
||||
__le16 seq0;
|
||||
__le16 seq1;
|
||||
__le16 seq2;
|
||||
__le16 seq3;
|
||||
} __packed;
|
||||
|
||||
#define RTW89_PCI_ADDR_MSDU_LS BIT(15)
|
||||
#define RTW89_PCI_ADDR_LS BIT(14)
|
||||
#define RTW89_PCI_ADDR_HIGH(a) (((a) << 6) & GENMASK(13, 6))
|
||||
#define RTW89_PCI_ADDR_NUM(x) ((x) & GENMASK(5, 0))
|
||||
|
||||
struct rtw89_pci_tx_addr_info_32 {
|
||||
__le16 length;
|
||||
__le16 option;
|
||||
__le32 dma;
|
||||
} __packed;
|
||||
|
||||
#define RTW89_PCI_RPP_POLLUTED BIT(31)
|
||||
#define RTW89_PCI_RPP_SEQ GENMASK(30, 16)
|
||||
#define RTW89_PCI_RPP_TX_STATUS GENMASK(15, 13)
|
||||
#define RTW89_TX_DONE 0x0
|
||||
#define RTW89_TX_RETRY_LIMIT 0x1
|
||||
#define RTW89_TX_LIFE_TIME 0x2
|
||||
#define RTW89_TX_MACID_DROP 0x3
|
||||
#define RTW89_PCI_RPP_QSEL GENMASK(12, 8)
|
||||
#define RTW89_PCI_RPP_MACID GENMASK(7, 0)
|
||||
|
||||
struct rtw89_pci_rpp_fmt {
|
||||
__le32 dword;
|
||||
} __packed;
|
||||
|
||||
struct rtw89_pci_rx_bd_32 {
|
||||
__le16 buf_size;
|
||||
__le16 rsvd;
|
||||
__le32 dma;
|
||||
} __packed;
|
||||
|
||||
#define RTW89_PCI_RXBD_FS BIT(15)
|
||||
#define RTW89_PCI_RXBD_LS BIT(14)
|
||||
#define RTW89_PCI_RXBD_WRITE_SIZE GENMASK(13, 0)
|
||||
#define RTW89_PCI_RXBD_TAG GENMASK(28, 16)
|
||||
|
||||
struct rtw89_pci_rxbd_info {
|
||||
__le32 dword;
|
||||
};
|
||||
|
||||
struct rtw89_pci_tx_wd {
|
||||
struct list_head list;
|
||||
struct sk_buff_head queue;
|
||||
|
||||
void *vaddr;
|
||||
dma_addr_t paddr;
|
||||
u32 len;
|
||||
u32 seq;
|
||||
};
|
||||
|
||||
struct rtw89_pci_dma_ring {
|
||||
void *head;
|
||||
u8 desc_size;
|
||||
dma_addr_t dma;
|
||||
|
||||
u32 addr_num;
|
||||
u32 addr_idx;
|
||||
u32 addr_bdram;
|
||||
u32 addr_desa_l;
|
||||
u32 addr_desa_h;
|
||||
|
||||
u32 len;
|
||||
u32 wp; /* host idx */
|
||||
u32 rp; /* hw idx */
|
||||
};
|
||||
|
||||
struct rtw89_pci_tx_wd_ring {
|
||||
void *head;
|
||||
dma_addr_t dma;
|
||||
|
||||
struct rtw89_pci_tx_wd pages[RTW89_PCI_TXWD_NUM_MAX];
|
||||
struct list_head free_pages;
|
||||
|
||||
u32 page_size;
|
||||
u32 page_num;
|
||||
u32 curr_num;
|
||||
};
|
||||
|
||||
#define RTW89_RX_TAG_MAX 0x1fff
|
||||
|
||||
struct rtw89_pci_tx_ring {
|
||||
struct rtw89_pci_tx_wd_ring wd_ring;
|
||||
struct rtw89_pci_dma_ring bd_ring;
|
||||
struct list_head busy_pages;
|
||||
u8 txch;
|
||||
bool dma_enabled;
|
||||
u16 tag; /* range from 0x0001 ~ 0x1fff */
|
||||
|
||||
u64 tx_cnt;
|
||||
u64 tx_acked;
|
||||
u64 tx_retry_lmt;
|
||||
u64 tx_life_time;
|
||||
u64 tx_mac_id_drop;
|
||||
};
|
||||
|
||||
struct rtw89_pci_rx_ring {
|
||||
struct rtw89_pci_dma_ring bd_ring;
|
||||
struct sk_buff *buf[RTW89_PCI_RXBD_NUM_MAX];
|
||||
u32 buf_sz;
|
||||
struct sk_buff *diliver_skb;
|
||||
struct rtw89_rx_desc_info diliver_desc;
|
||||
};
|
||||
|
||||
struct rtw89_pci_isrs {
|
||||
u32 halt_c2h_isrs;
|
||||
u32 isrs[2];
|
||||
};
|
||||
|
||||
struct rtw89_pci {
|
||||
struct pci_dev *pdev;
|
||||
|
||||
/* protect HW irq related registers */
|
||||
spinlock_t irq_lock;
|
||||
/* protect TRX resources (exclude RXQ) */
|
||||
spinlock_t trx_lock;
|
||||
bool running;
|
||||
struct rtw89_pci_tx_ring tx_rings[RTW89_TXCH_NUM];
|
||||
struct rtw89_pci_rx_ring rx_rings[RTW89_RXCH_NUM];
|
||||
struct sk_buff_head h2c_queue;
|
||||
struct sk_buff_head h2c_release_queue;
|
||||
|
||||
u32 halt_c2h_intrs;
|
||||
u32 intrs[2];
|
||||
void __iomem *mmap;
|
||||
};
|
||||
|
||||
static inline struct rtw89_pci_rx_info *RTW89_PCI_RX_SKB_CB(struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
|
||||
BUILD_BUG_ON(sizeof(struct rtw89_pci_tx_data) >
|
||||
sizeof(info->status.status_driver_data));
|
||||
|
||||
return (struct rtw89_pci_rx_info *)skb->cb;
|
||||
}
|
||||
|
||||
static inline struct rtw89_pci_rx_bd_32 *
|
||||
RTW89_PCI_RX_BD(struct rtw89_pci_rx_ring *rx_ring, u32 idx)
|
||||
{
|
||||
struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring;
|
||||
u8 *head = bd_ring->head;
|
||||
u32 desc_size = bd_ring->desc_size;
|
||||
u32 offset = idx * desc_size;
|
||||
|
||||
return (struct rtw89_pci_rx_bd_32 *)(head + offset);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rtw89_pci_rxbd_increase(struct rtw89_pci_rx_ring *rx_ring, u32 cnt)
|
||||
{
|
||||
struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring;
|
||||
|
||||
bd_ring->wp += cnt;
|
||||
|
||||
if (bd_ring->wp >= bd_ring->len)
|
||||
bd_ring->wp -= bd_ring->len;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return (struct rtw89_pci_tx_data *)info->status.status_driver_data;
|
||||
}
|
||||
|
||||
static inline struct rtw89_pci_tx_bd_32 *
|
||||
rtw89_pci_get_next_txbd(struct rtw89_pci_tx_ring *tx_ring)
|
||||
{
|
||||
struct rtw89_pci_dma_ring *bd_ring = &tx_ring->bd_ring;
|
||||
struct rtw89_pci_tx_bd_32 *tx_bd, *head;
|
||||
|
||||
head = bd_ring->head;
|
||||
tx_bd = head + bd_ring->wp;
|
||||
|
||||
return tx_bd;
|
||||
}
|
||||
|
||||
static inline struct rtw89_pci_tx_wd *
|
||||
rtw89_pci_dequeue_txwd(struct rtw89_pci_tx_ring *tx_ring)
|
||||
{
|
||||
struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring;
|
||||
struct rtw89_pci_tx_wd *txwd;
|
||||
|
||||
txwd = list_first_entry_or_null(&wd_ring->free_pages,
|
||||
struct rtw89_pci_tx_wd, list);
|
||||
if (!txwd)
|
||||
return NULL;
|
||||
|
||||
list_del_init(&txwd->list);
|
||||
txwd->len = 0;
|
||||
wd_ring->curr_num--;
|
||||
|
||||
return txwd;
|
||||
}
|
||||
|
||||
static inline void
|
||||
rtw89_pci_enqueue_txwd(struct rtw89_pci_tx_ring *tx_ring,
|
||||
struct rtw89_pci_tx_wd *txwd)
|
||||
{
|
||||
struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring;
|
||||
|
||||
memset(txwd->vaddr, 0, wd_ring->page_size);
|
||||
list_add_tail(&txwd->list, &wd_ring->free_pages);
|
||||
wd_ring->curr_num++;
|
||||
}
|
||||
|
||||
static inline bool rtw89_pci_ltr_is_err_reg_val(u32 val)
|
||||
{
|
||||
return val == 0xffffffff || val == 0xeaeaeaea;
|
||||
}
|
||||
|
||||
extern const struct dev_pm_ops rtw89_pm_ops;
|
||||
|
||||
#endif
|
2868
drivers/net/wireless/realtek/rtw89/phy.c
Normal file
2868
drivers/net/wireless/realtek/rtw89/phy.c
Normal file
File diff suppressed because it is too large
Load Diff
311
drivers/net/wireless/realtek/rtw89/phy.h
Normal file
311
drivers/net/wireless/realtek/rtw89/phy.h
Normal file
@ -0,0 +1,311 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW89_PHY_H__
|
||||
#define __RTW89_PHY_H__
|
||||
|
||||
#include "core.h"
|
||||
|
||||
#define RTW89_PHY_ADDR_OFFSET 0x10000
|
||||
|
||||
#define get_phy_headline(addr) FIELD_GET(GENMASK(31, 28), addr)
|
||||
#define PHY_HEADLINE_VALID 0xf
|
||||
#define get_phy_target(addr) FIELD_GET(GENMASK(27, 0), addr)
|
||||
#define get_phy_compare(rfe, cv) (FIELD_PREP(GENMASK(23, 16), rfe) | \
|
||||
FIELD_PREP(GENMASK(7, 0), cv))
|
||||
|
||||
#define get_phy_cond(addr) FIELD_GET(GENMASK(31, 28), addr)
|
||||
#define get_phy_cond_rfe(addr) FIELD_GET(GENMASK(23, 16), addr)
|
||||
#define get_phy_cond_pkg(addr) FIELD_GET(GENMASK(15, 8), addr)
|
||||
#define get_phy_cond_cv(addr) FIELD_GET(GENMASK(7, 0), addr)
|
||||
#define phy_div(a, b) ({typeof(b) _b = (b); (_b) ? ((a) / (_b)) : 0; })
|
||||
#define PHY_COND_BRANCH_IF 0x8
|
||||
#define PHY_COND_BRANCH_ELIF 0x9
|
||||
#define PHY_COND_BRANCH_ELSE 0xa
|
||||
#define PHY_COND_BRANCH_END 0xb
|
||||
#define PHY_COND_CHECK 0x4
|
||||
#define PHY_COND_DONT_CARE 0xff
|
||||
|
||||
#define RA_MASK_CCK_RATES GENMASK_ULL(3, 0)
|
||||
#define RA_MASK_OFDM_RATES GENMASK_ULL(11, 4)
|
||||
#define RA_MASK_SUBCCK_RATES 0x5ULL
|
||||
#define RA_MASK_SUBOFDM_RATES 0x10ULL
|
||||
#define RA_MASK_HT_1SS_RATES GENMASK_ULL(19, 12)
|
||||
#define RA_MASK_HT_2SS_RATES GENMASK_ULL(31, 24)
|
||||
#define RA_MASK_HT_3SS_RATES GENMASK_ULL(43, 36)
|
||||
#define RA_MASK_HT_4SS_RATES GENMASK_ULL(55, 48)
|
||||
#define RA_MASK_HT_RATES GENMASK_ULL(55, 12)
|
||||
#define RA_MASK_VHT_1SS_RATES GENMASK_ULL(21, 12)
|
||||
#define RA_MASK_VHT_2SS_RATES GENMASK_ULL(33, 24)
|
||||
#define RA_MASK_VHT_3SS_RATES GENMASK_ULL(45, 36)
|
||||
#define RA_MASK_VHT_4SS_RATES GENMASK_ULL(57, 48)
|
||||
#define RA_MASK_VHT_RATES GENMASK_ULL(57, 12)
|
||||
#define RA_MASK_HE_1SS_RATES GENMASK_ULL(23, 12)
|
||||
#define RA_MASK_HE_2SS_RATES GENMASK_ULL(35, 24)
|
||||
#define RA_MASK_HE_3SS_RATES GENMASK_ULL(47, 36)
|
||||
#define RA_MASK_HE_4SS_RATES GENMASK_ULL(59, 48)
|
||||
#define RA_MASK_HE_RATES GENMASK_ULL(59, 12)
|
||||
|
||||
#define CFO_TRK_ENABLE_TH (2 << 2)
|
||||
#define CFO_TRK_STOP_TH_4 (30 << 2)
|
||||
#define CFO_TRK_STOP_TH_3 (20 << 2)
|
||||
#define CFO_TRK_STOP_TH_2 (10 << 2)
|
||||
#define CFO_TRK_STOP_TH_1 (00 << 2)
|
||||
#define CFO_TRK_STOP_TH (2 << 2)
|
||||
#define CFO_SW_COMP_FINE_TUNE (2 << 2)
|
||||
#define CFO_PERIOD_CNT 15
|
||||
#define CFO_TP_UPPER 100
|
||||
#define CFO_TP_LOWER 50
|
||||
#define CFO_COMP_PERIOD 250
|
||||
#define CFO_COMP_WEIGHT 8
|
||||
#define MAX_CFO_TOLERANCE 30
|
||||
|
||||
#define CCX_MAX_PERIOD 2097
|
||||
#define CCX_MAX_PERIOD_UNIT 32
|
||||
#define MS_TO_4US_RATIO 250
|
||||
#define ENV_MNTR_FAIL_DWORD 0xffffffff
|
||||
#define ENV_MNTR_IFSCLM_HIS_MAX 127
|
||||
#define PERMIL 1000
|
||||
#define PERCENT 100
|
||||
#define IFS_CLM_TH0_UPPER 64
|
||||
#define IFS_CLM_TH_MUL 4
|
||||
#define IFS_CLM_TH_START_IDX 0
|
||||
|
||||
#define TIA0_GAIN_A 12
|
||||
#define TIA0_GAIN_G 16
|
||||
#define LNA0_GAIN (-24)
|
||||
#define U4_MAX_BIT 3
|
||||
#define U8_MAX_BIT 7
|
||||
#define DIG_GAIN_SHIFT 2
|
||||
#define DIG_GAIN 8
|
||||
|
||||
#define LNA_IDX_MAX 6
|
||||
#define LNA_IDX_MIN 0
|
||||
#define TIA_IDX_MAX 1
|
||||
#define TIA_IDX_MIN 0
|
||||
#define RXB_IDX_MAX 31
|
||||
#define RXB_IDX_MIN 0
|
||||
|
||||
#define PD_TH_MAX_RSSI 70
|
||||
#define PD_TH_MIN_RSSI 8
|
||||
#define PD_TH_BW80_CMP_VAL 6
|
||||
#define PD_TH_BW40_CMP_VAL 3
|
||||
#define PD_TH_BW20_CMP_VAL 0
|
||||
#define PD_TH_CMP_VAL 3
|
||||
#define PD_TH_SB_FLTR_CMP_VAL 7
|
||||
|
||||
#define PHYSTS_MGNT BIT(RTW89_RX_TYPE_MGNT)
|
||||
#define PHYSTS_CTRL BIT(RTW89_RX_TYPE_CTRL)
|
||||
#define PHYSTS_DATA BIT(RTW89_RX_TYPE_DATA)
|
||||
#define PHYSTS_RSVD BIT(RTW89_RX_TYPE_RSVD)
|
||||
#define PPDU_FILTER_BITMAP (PHYSTS_MGNT | PHYSTS_DATA)
|
||||
|
||||
enum rtw89_phy_c2h_ra_func {
|
||||
RTW89_PHY_C2H_FUNC_STS_RPT,
|
||||
RTW89_PHY_C2H_FUNC_MU_GPTBL_RPT,
|
||||
RTW89_PHY_C2H_FUNC_TXSTS,
|
||||
RTW89_PHY_C2H_FUNC_RA_MAX,
|
||||
};
|
||||
|
||||
enum rtw89_phy_c2h_class {
|
||||
RTW89_PHY_C2H_CLASS_RUA,
|
||||
RTW89_PHY_C2H_CLASS_RA,
|
||||
RTW89_PHY_C2H_CLASS_DM,
|
||||
RTW89_PHY_C2H_CLASS_BTC_MIN = 0x10,
|
||||
RTW89_PHY_C2H_CLASS_BTC_MAX = 0x17,
|
||||
RTW89_PHY_C2H_CLASS_MAX,
|
||||
};
|
||||
|
||||
enum rtw89_env_monitor_result_level {
|
||||
RTW89_PHY_ENV_MON_CCX_FAIL = 0,
|
||||
RTW89_PHY_ENV_MON_NHM = BIT(0),
|
||||
RTW89_PHY_ENV_MON_CLM = BIT(1),
|
||||
RTW89_PHY_ENV_MON_FAHM = BIT(2),
|
||||
RTW89_PHY_ENV_MON_IFS_CLM = BIT(3),
|
||||
RTW89_PHY_ENV_MON_EDCCA_CLM = BIT(4),
|
||||
};
|
||||
|
||||
#define CCX_US_BASE_RATIO 4
|
||||
enum rtw89_ccx_unit {
|
||||
RTW89_CCX_4_US = 0,
|
||||
RTW89_CCX_8_US = 1,
|
||||
RTW89_CCX_16_US = 2,
|
||||
RTW89_CCX_32_US = 3
|
||||
};
|
||||
|
||||
enum rtw89_dig_gain_type {
|
||||
RTW89_DIG_GAIN_LNA_G = 0,
|
||||
RTW89_DIG_GAIN_TIA_G = 1,
|
||||
RTW89_DIG_GAIN_LNA_A = 2,
|
||||
RTW89_DIG_GAIN_TIA_A = 3,
|
||||
RTW89_DIG_GAIN_MAX = 4
|
||||
};
|
||||
|
||||
enum rtw89_dig_gain_lna_idx {
|
||||
RTW89_DIG_GAIN_LNA_IDX1 = 1,
|
||||
RTW89_DIG_GAIN_LNA_IDX2 = 2,
|
||||
RTW89_DIG_GAIN_LNA_IDX3 = 3,
|
||||
RTW89_DIG_GAIN_LNA_IDX4 = 4,
|
||||
RTW89_DIG_GAIN_LNA_IDX5 = 5,
|
||||
RTW89_DIG_GAIN_LNA_IDX6 = 6
|
||||
};
|
||||
|
||||
enum rtw89_dig_gain_tia_idx {
|
||||
RTW89_DIG_GAIN_TIA_IDX0 = 0,
|
||||
RTW89_DIG_GAIN_TIA_IDX1 = 1
|
||||
};
|
||||
|
||||
struct rtw89_txpwr_byrate_cfg {
|
||||
enum rtw89_band band;
|
||||
enum rtw89_nss nss;
|
||||
enum rtw89_rate_section rs;
|
||||
u8 shf;
|
||||
u8 len;
|
||||
u32 data;
|
||||
};
|
||||
|
||||
#define DELTA_SWINGIDX_SIZE 30
|
||||
|
||||
struct rtw89_txpwr_track_cfg {
|
||||
const u8 (*delta_swingidx_5gb_n)[DELTA_SWINGIDX_SIZE];
|
||||
const u8 (*delta_swingidx_5gb_p)[DELTA_SWINGIDX_SIZE];
|
||||
const u8 (*delta_swingidx_5ga_n)[DELTA_SWINGIDX_SIZE];
|
||||
const u8 (*delta_swingidx_5ga_p)[DELTA_SWINGIDX_SIZE];
|
||||
const u8 *delta_swingidx_2gb_n;
|
||||
const u8 *delta_swingidx_2gb_p;
|
||||
const u8 *delta_swingidx_2ga_n;
|
||||
const u8 *delta_swingidx_2ga_p;
|
||||
const u8 *delta_swingidx_2g_cck_b_n;
|
||||
const u8 *delta_swingidx_2g_cck_b_p;
|
||||
const u8 *delta_swingidx_2g_cck_a_n;
|
||||
const u8 *delta_swingidx_2g_cck_a_p;
|
||||
};
|
||||
|
||||
struct rtw89_phy_dig_gain_cfg {
|
||||
const struct rtw89_reg_def *table;
|
||||
u8 size;
|
||||
};
|
||||
|
||||
struct rtw89_phy_dig_gain_table {
|
||||
const struct rtw89_phy_dig_gain_cfg *cfg_lna_g;
|
||||
const struct rtw89_phy_dig_gain_cfg *cfg_tia_g;
|
||||
const struct rtw89_phy_dig_gain_cfg *cfg_lna_a;
|
||||
const struct rtw89_phy_dig_gain_cfg *cfg_tia_a;
|
||||
};
|
||||
|
||||
struct rtw89_phy_reg3_tbl {
|
||||
const struct rtw89_reg3_def *reg3;
|
||||
int size;
|
||||
};
|
||||
|
||||
#define DECLARE_PHY_REG3_TBL(_name) \
|
||||
const struct rtw89_phy_reg3_tbl _name ## _tbl = { \
|
||||
.reg3 = _name, \
|
||||
.size = ARRAY_SIZE(_name), \
|
||||
}
|
||||
|
||||
static inline void rtw89_phy_write8(struct rtw89_dev *rtwdev,
|
||||
u32 addr, u8 data)
|
||||
{
|
||||
rtw89_write8(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, data);
|
||||
}
|
||||
|
||||
static inline void rtw89_phy_write16(struct rtw89_dev *rtwdev,
|
||||
u32 addr, u16 data)
|
||||
{
|
||||
rtw89_write16(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, data);
|
||||
}
|
||||
|
||||
static inline void rtw89_phy_write32(struct rtw89_dev *rtwdev,
|
||||
u32 addr, u32 data)
|
||||
{
|
||||
rtw89_write32(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, data);
|
||||
}
|
||||
|
||||
static inline void rtw89_phy_write32_set(struct rtw89_dev *rtwdev,
|
||||
u32 addr, u32 bits)
|
||||
{
|
||||
rtw89_write32_set(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, bits);
|
||||
}
|
||||
|
||||
static inline void rtw89_phy_write32_clr(struct rtw89_dev *rtwdev,
|
||||
u32 addr, u32 bits)
|
||||
{
|
||||
rtw89_write32_clr(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, bits);
|
||||
}
|
||||
|
||||
static inline void rtw89_phy_write32_mask(struct rtw89_dev *rtwdev,
|
||||
u32 addr, u32 mask, u32 data)
|
||||
{
|
||||
rtw89_write32_mask(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, mask, data);
|
||||
}
|
||||
|
||||
static inline u8 rtw89_phy_read8(struct rtw89_dev *rtwdev, u32 addr)
|
||||
{
|
||||
return rtw89_read8(rtwdev, addr | RTW89_PHY_ADDR_OFFSET);
|
||||
}
|
||||
|
||||
static inline u16 rtw89_phy_read16(struct rtw89_dev *rtwdev, u32 addr)
|
||||
{
|
||||
return rtw89_read16(rtwdev, addr | RTW89_PHY_ADDR_OFFSET);
|
||||
}
|
||||
|
||||
static inline u32 rtw89_phy_read32(struct rtw89_dev *rtwdev, u32 addr)
|
||||
{
|
||||
return rtw89_read32(rtwdev, addr | RTW89_PHY_ADDR_OFFSET);
|
||||
}
|
||||
|
||||
static inline u32 rtw89_phy_read32_mask(struct rtw89_dev *rtwdev,
|
||||
u32 addr, u32 mask)
|
||||
{
|
||||
return rtw89_read32_mask(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, mask);
|
||||
}
|
||||
|
||||
void rtw89_phy_write_reg3_tbl(struct rtw89_dev *rtwdev,
|
||||
const struct rtw89_phy_reg3_tbl *tbl);
|
||||
u8 rtw89_phy_get_txsc(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_channel_params *param,
|
||||
enum rtw89_bandwidth dbw);
|
||||
u32 rtw89_phy_read_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
|
||||
u32 addr, u32 mask);
|
||||
bool rtw89_phy_write_rf(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_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);
|
||||
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,
|
||||
const struct rtw89_rate_desc *rate_desc);
|
||||
void rtw89_phy_fill_txpwr_limit(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_txpwr_limit *lmt,
|
||||
u8 ntx);
|
||||
void rtw89_phy_fill_txpwr_limit_ru(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_txpwr_limit_ru *lmt_ru,
|
||||
u8 ntx);
|
||||
s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev,
|
||||
u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch);
|
||||
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);
|
||||
void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_vif *vif,
|
||||
const struct cfg80211_bitrate_mask *mask);
|
||||
void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
|
||||
u32 len, u8 class, u8 func);
|
||||
void rtw89_phy_cfo_track(struct rtw89_dev *rtwdev);
|
||||
void rtw89_phy_cfo_track_work(struct work_struct *work);
|
||||
void rtw89_phy_cfo_parse(struct rtw89_dev *rtwdev, s16 cfo_val,
|
||||
struct rtw89_rx_phy_ppdu *phy_ppdu);
|
||||
void rtw89_phy_stat_track(struct rtw89_dev *rtwdev);
|
||||
void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev);
|
||||
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_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
|
||||
|
||||
#endif
|
150
drivers/net/wireless/realtek/rtw89/ps.c
Normal file
150
drivers/net/wireless/realtek/rtw89/ps.c
Normal file
@ -0,0 +1,150 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#include "coex.h"
|
||||
#include "core.h"
|
||||
#include "debug.h"
|
||||
#include "fw.h"
|
||||
#include "mac.h"
|
||||
#include "ps.h"
|
||||
#include "reg.h"
|
||||
#include "util.h"
|
||||
|
||||
static int rtw89_fw_leave_lps_check(struct rtw89_dev *rtwdev, u8 macid)
|
||||
{
|
||||
u32 pwr_en_bit = 0xE;
|
||||
u32 chk_msk = pwr_en_bit << (4 * macid);
|
||||
u32 polling;
|
||||
int ret;
|
||||
|
||||
ret = read_poll_timeout_atomic(rtw89_read32_mask, polling, !polling,
|
||||
1000, 50000, false, rtwdev,
|
||||
R_AX_PPWRBIT_SETTING, chk_msk);
|
||||
if (ret) {
|
||||
rtw89_info(rtwdev, "rtw89: failed to leave lps state\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
if (!rtwdev->ps_mode)
|
||||
return;
|
||||
|
||||
if (test_and_set_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags))
|
||||
return;
|
||||
|
||||
rtw89_mac_power_mode_change(rtwdev, true);
|
||||
}
|
||||
|
||||
void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
if (!rtwdev->ps_mode)
|
||||
return;
|
||||
|
||||
if (test_and_clear_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags))
|
||||
rtw89_mac_power_mode_change(rtwdev, false);
|
||||
}
|
||||
|
||||
static void __rtw89_enter_lps(struct rtw89_dev *rtwdev, u8 mac_id)
|
||||
{
|
||||
struct rtw89_lps_parm lps_param = {
|
||||
.macid = mac_id,
|
||||
.psmode = RTW89_MAC_AX_PS_MODE_LEGACY,
|
||||
.lastrpwm = RTW89_LAST_RPWM_PS,
|
||||
};
|
||||
|
||||
rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_FW_CTRL);
|
||||
rtw89_fw_h2c_lps_parm(rtwdev, &lps_param);
|
||||
}
|
||||
|
||||
static void __rtw89_leave_lps(struct rtw89_dev *rtwdev, u8 mac_id)
|
||||
{
|
||||
struct rtw89_lps_parm lps_param = {
|
||||
.macid = mac_id,
|
||||
.psmode = RTW89_MAC_AX_PS_MODE_ACTIVE,
|
||||
.lastrpwm = RTW89_LAST_RPWM_ACTIVE,
|
||||
};
|
||||
|
||||
rtw89_fw_h2c_lps_parm(rtwdev, &lps_param);
|
||||
rtw89_fw_leave_lps_check(rtwdev, 0);
|
||||
rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_WL_ON);
|
||||
}
|
||||
|
||||
void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
lockdep_assert_held(&rtwdev->mutex);
|
||||
|
||||
__rtw89_leave_ps_mode(rtwdev);
|
||||
}
|
||||
|
||||
void rtw89_enter_lps(struct rtw89_dev *rtwdev, u8 mac_id)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
static void rtw89_leave_lps_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
|
||||
{
|
||||
if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION)
|
||||
return;
|
||||
|
||||
__rtw89_leave_ps_mode(rtwdev);
|
||||
__rtw89_leave_lps(rtwdev, rtwvif->mac_id);
|
||||
}
|
||||
|
||||
void rtw89_leave_lps(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_vif *rtwvif;
|
||||
|
||||
lockdep_assert_held(&rtwdev->mutex);
|
||||
|
||||
if (!test_and_clear_bit(RTW89_FLAG_LEISURE_PS, rtwdev->flags))
|
||||
return;
|
||||
|
||||
rtw89_for_each_rtwvif(rtwdev, rtwvif)
|
||||
rtw89_leave_lps_vif(rtwdev, rtwvif);
|
||||
}
|
||||
|
||||
void rtw89_enter_ips(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_vif *rtwvif;
|
||||
|
||||
set_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags);
|
||||
|
||||
rtw89_for_each_rtwvif(rtwdev, rtwvif)
|
||||
rtw89_mac_vif_deinit(rtwdev, rtwvif);
|
||||
|
||||
rtw89_core_stop(rtwdev);
|
||||
}
|
||||
|
||||
void rtw89_leave_ips(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_vif *rtwvif;
|
||||
int ret;
|
||||
|
||||
ret = rtw89_core_start(rtwdev);
|
||||
if (ret)
|
||||
rtw89_err(rtwdev, "failed to leave idle state\n");
|
||||
|
||||
rtw89_set_channel(rtwdev);
|
||||
|
||||
rtw89_for_each_rtwvif(rtwdev, rtwvif)
|
||||
rtw89_mac_vif_init(rtwdev, rtwvif);
|
||||
|
||||
clear_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags);
|
||||
}
|
||||
|
||||
void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl)
|
||||
{
|
||||
if (btc_ctrl)
|
||||
rtw89_leave_lps(rtwdev);
|
||||
}
|
16
drivers/net/wireless/realtek/rtw89/ps.h
Normal file
16
drivers/net/wireless/realtek/rtw89/ps.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW89_PS_H_
|
||||
#define __RTW89_PS_H_
|
||||
|
||||
void rtw89_enter_lps(struct rtw89_dev *rtwdev, u8 mac_id);
|
||||
void rtw89_leave_lps(struct rtw89_dev *rtwdev);
|
||||
void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev);
|
||||
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);
|
||||
|
||||
#endif
|
2159
drivers/net/wireless/realtek/rtw89/reg.h
Normal file
2159
drivers/net/wireless/realtek/rtw89/reg.h
Normal file
File diff suppressed because it is too large
Load Diff
353
drivers/net/wireless/realtek/rtw89/regd.c
Normal file
353
drivers/net/wireless/realtek/rtw89/regd.c
Normal file
@ -0,0 +1,353 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
#include "ps.h"
|
||||
|
||||
#define COUNTRY_REGD(_alpha2, _txpwr_regd_2g, _txpwr_regd_5g) \
|
||||
{.alpha2 = (_alpha2), \
|
||||
.txpwr_regd[RTW89_BAND_2G] = (_txpwr_regd_2g), \
|
||||
.txpwr_regd[RTW89_BAND_5G] = (_txpwr_regd_5g) \
|
||||
}
|
||||
|
||||
static const struct rtw89_regulatory rtw89_ww_regd =
|
||||
COUNTRY_REGD("00", RTW89_WW, RTW89_WW);
|
||||
|
||||
static const struct rtw89_regulatory rtw89_regd_map[] = {
|
||||
COUNTRY_REGD("AR", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("BO", RTW89_WW, RTW89_FCC),
|
||||
COUNTRY_REGD("BR", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("CL", RTW89_WW, RTW89_CHILE),
|
||||
COUNTRY_REGD("CO", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("CR", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("EC", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("SV", RTW89_WW, RTW89_FCC),
|
||||
COUNTRY_REGD("GT", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("HN", RTW89_WW, RTW89_FCC),
|
||||
COUNTRY_REGD("MX", RTW89_FCC, RTW89_MEXICO),
|
||||
COUNTRY_REGD("NI", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("PA", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("PY", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("PE", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("US", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("UY", RTW89_WW, RTW89_FCC),
|
||||
COUNTRY_REGD("VE", RTW89_WW, RTW89_FCC),
|
||||
COUNTRY_REGD("PR", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("DO", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("AT", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("BE", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("CY", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("CZ", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("DK", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("EE", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("FI", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("FR", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("DE", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("GR", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("HU", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("IS", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("IE", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("IT", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("LV", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("LI", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("LT", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("LU", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("MT", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("MC", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("NL", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("NO", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("PL", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("PT", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("SK", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("SI", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("ES", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("SE", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("CH", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("GB", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("AL", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("AZ", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("BH", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("BA", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("BG", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("HR", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("EG", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("GH", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("IQ", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("IL", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("JO", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("KZ", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("KE", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("KW", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("KG", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("LB", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("LS", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("MK", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("MA", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("MZ", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("NA", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("NG", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("OM", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("QA", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("RO", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("RU", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("SA", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("SN", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("RS", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("ME", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("ZA", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("TR", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("UA", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("AE", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("YE", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("ZW", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("BD", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("KH", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("CN", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("HK", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("IN", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("ID", RTW89_ETSI, RTW89_ETSI),
|
||||
COUNTRY_REGD("KR", RTW89_KCC, RTW89_KCC),
|
||||
COUNTRY_REGD("MY", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("PK", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("PH", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("SG", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("LK", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("TW", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("TH", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("VN", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("AU", RTW89_WW, RTW89_ACMA),
|
||||
COUNTRY_REGD("NZ", RTW89_WW, RTW89_ACMA),
|
||||
COUNTRY_REGD("PG", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("CA", RTW89_IC, RTW89_IC),
|
||||
COUNTRY_REGD("JP", RTW89_MKK, RTW89_MKK),
|
||||
COUNTRY_REGD("JM", RTW89_WW, RTW89_FCC),
|
||||
COUNTRY_REGD("AN", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("TT", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("TN", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("AF", RTW89_ETSI, RTW89_ETSI),
|
||||
COUNTRY_REGD("DZ", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("AS", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("AD", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("AO", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("AI", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("AQ", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("AG", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("AM", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("AW", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("BS", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("BB", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("BY", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("BZ", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("BJ", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("BM", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("BT", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("BW", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("BV", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("IO", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("VG", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("BN", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("BF", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("MM", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("BI", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("CM", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("CV", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("KY", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("CF", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("TD", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("CX", RTW89_WW, RTW89_ACMA),
|
||||
COUNTRY_REGD("CC", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("KM", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("CG", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("CD", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("CK", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("CI", RTW89_ETSI, RTW89_ETSI),
|
||||
COUNTRY_REGD("DJ", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("DM", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("GQ", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("ER", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("ET", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("FK", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("FO", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("FJ", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("GF", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("PF", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("TF", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("GA", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("GM", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("GE", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("GI", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("GL", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("GD", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("GP", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("GU", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("GG", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("GN", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("GW", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("GY", RTW89_FCC, RTW89_NCC),
|
||||
COUNTRY_REGD("HT", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("HM", RTW89_WW, RTW89_ACMA),
|
||||
COUNTRY_REGD("VA", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("IM", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("JE", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("KI", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("LA", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("LR", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("LY", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("MO", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("MG", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("MW", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("MV", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("ML", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("MH", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("MQ", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("MR", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("MU", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("YT", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("FM", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("MD", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("MN", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("MS", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("NR", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("NP", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("NC", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("NE", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("NU", RTW89_WW, RTW89_ACMA),
|
||||
COUNTRY_REGD("NF", RTW89_WW, RTW89_ACMA),
|
||||
COUNTRY_REGD("MP", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("PW", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("RE", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("RW", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("SH", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("KN", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("LC", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("MF", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("SX", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("PM", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("VC", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("WS", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("SM", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("ST", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("SC", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("SL", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("SB", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("SO", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("GS", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("SR", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("SJ", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("SZ", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("TJ", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("TZ", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("TG", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("TK", RTW89_WW, RTW89_ACMA),
|
||||
COUNTRY_REGD("TO", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("TM", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("TC", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("TV", RTW89_ETSI, RTW89_NA),
|
||||
COUNTRY_REGD("UG", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("VI", RTW89_FCC, RTW89_FCC),
|
||||
COUNTRY_REGD("UZ", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("VU", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("WF", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("EH", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("ZM", RTW89_WW, RTW89_ETSI),
|
||||
COUNTRY_REGD("IR", RTW89_WW, RTW89_ETSI),
|
||||
};
|
||||
|
||||
static const struct rtw89_regulatory *rtw89_regd_find_reg_by_name(char *alpha2)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rtw89_regd_map); i++) {
|
||||
if (!memcmp(rtw89_regd_map[i].alpha2, alpha2, 2))
|
||||
return &rtw89_regd_map[i];
|
||||
}
|
||||
|
||||
return &rtw89_ww_regd;
|
||||
}
|
||||
|
||||
static bool rtw89_regd_is_ww(const struct rtw89_regulatory *regd)
|
||||
{
|
||||
return regd == &rtw89_ww_regd;
|
||||
}
|
||||
|
||||
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 wiphy *wiphy = rtwdev->hw->wiphy;
|
||||
int ret;
|
||||
|
||||
if (!wiphy)
|
||||
return -EINVAL;
|
||||
|
||||
chip_regd = rtw89_regd_find_reg_by_name(rtwdev->efuse.country_code);
|
||||
if (!rtw89_regd_is_ww(chip_regd)) {
|
||||
rtwdev->regd = chip_regd;
|
||||
/* 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);
|
||||
if (ret)
|
||||
rtw89_warn(rtwdev, "failed to hint regulatory:%d\n", ret);
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_REGD,
|
||||
"efuse country code %c%c, mapping to 2g txregd %d, 5g txregd %d\n",
|
||||
rtwdev->efuse.country_code[0], rtwdev->efuse.country_code[1],
|
||||
rtwdev->regd->txpwr_regd[RTW89_BAND_2G],
|
||||
rtwdev->regd->txpwr_regd[RTW89_BAND_5G]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
rtw89_debug(rtwdev, RTW89_DBG_REGD,
|
||||
"worldwide roaming chip, follow the setting of stack(%c%c), mapping to 2g txregd %d, 5g txregd %d\n",
|
||||
rtwdev->regd->alpha2[0], rtwdev->regd->alpha2[1],
|
||||
rtwdev->regd->txpwr_regd[RTW89_BAND_2G],
|
||||
rtwdev->regd->txpwr_regd[RTW89_BAND_5G]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
/* 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))
|
||||
wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
|
||||
else
|
||||
wiphy->regulatory_flags &= ~REGULATORY_COUNTRY_IE_IGNORE;
|
||||
}
|
||||
|
||||
void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request)
|
||||
{
|
||||
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
rtw89_leave_ps_mode(rtwdev);
|
||||
|
||||
if (wiphy->regd) {
|
||||
rtw89_debug(rtwdev, RTW89_DBG_REGD,
|
||||
"There is a country domain programmed in chip, ignore notifications\n");
|
||||
goto exit;
|
||||
}
|
||||
rtw89_regd_notifier_apply(rtwdev, wiphy, request);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_REGD,
|
||||
"get alpha2 %c%c from initiator %d, mapping to 2g txregd %d, 5g txregd %d\n",
|
||||
request->alpha2[0], request->alpha2[1], request->initiator,
|
||||
rtwdev->regd->txpwr_regd[RTW89_BAND_2G],
|
||||
rtwdev->regd->txpwr_regd[RTW89_BAND_5G]);
|
||||
|
||||
rtw89_chip_set_txpwr(rtwdev);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
}
|
2036
drivers/net/wireless/realtek/rtw89/rtw8852a.c
Normal file
2036
drivers/net/wireless/realtek/rtw89/rtw8852a.c
Normal file
File diff suppressed because it is too large
Load Diff
109
drivers/net/wireless/realtek/rtw89/rtw8852a.h
Normal file
109
drivers/net/wireless/realtek/rtw89/rtw8852a.h
Normal file
@ -0,0 +1,109 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW89_8852A_H__
|
||||
#define __RTW89_8852A_H__
|
||||
|
||||
#include "core.h"
|
||||
|
||||
#define RF_PATH_NUM_8852A 2
|
||||
#define NTX_NUM_8852A 2
|
||||
|
||||
enum rtw8852a_pmac_mode {
|
||||
NONE_TEST,
|
||||
PKTS_TX,
|
||||
PKTS_RX,
|
||||
CONT_TX
|
||||
};
|
||||
|
||||
struct rtw8852au_efuse {
|
||||
u8 rsvd[0x38];
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
};
|
||||
|
||||
struct rtw8852ae_efuse {
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
};
|
||||
|
||||
struct rtw8852a_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 rtw8852a_efuse {
|
||||
u8 rsvd[0x210];
|
||||
struct rtw8852a_tssi_offset path_a_tssi;
|
||||
u8 rsvd1[10];
|
||||
struct rtw8852a_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[46];
|
||||
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 rsvd9[0xf2];
|
||||
union {
|
||||
struct rtw8852au_efuse u;
|
||||
struct rtw8852ae_efuse e;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct rtw8852a_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;
|
||||
};
|
||||
|
||||
void rtw8852a_bb_set_plcp_tx(struct rtw89_dev *rtwdev);
|
||||
void rtw8852a_bb_set_pmac_tx(struct rtw89_dev *rtwdev,
|
||||
struct rtw8852a_bb_pmac_info *tx_info,
|
||||
enum rtw89_phy_idx idx);
|
||||
void rtw8852a_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 rtw8852a_bb_set_power(struct rtw89_dev *rtwdev, s16 pwr_dbm,
|
||||
enum rtw89_phy_idx idx);
|
||||
void rtw8852a_bb_cfg_tx_path(struct rtw89_dev *rtwdev, u8 tx_path);
|
||||
void rtw8852a_bb_tx_mode_switch(struct rtw89_dev *rtwdev,
|
||||
enum rtw89_phy_idx idx, u8 mode);
|
||||
|
||||
#endif
|
3911
drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c
Normal file
3911
drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c
Normal file
File diff suppressed because it is too large
Load Diff
24
drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h
Normal file
24
drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW89_8852A_RFK_H__
|
||||
#define __RTW89_8852A_RFK_H__
|
||||
|
||||
#include "core.h"
|
||||
|
||||
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);
|
||||
void rtw8852a_dpk_track(struct rtw89_dev *rtwdev);
|
||||
void rtw8852a_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy);
|
||||
void rtw8852a_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy);
|
||||
void rtw8852a_tssi_track(struct rtw89_dev *rtwdev);
|
||||
void rtw8852a_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start,
|
||||
enum rtw89_phy_idx phy_idx);
|
||||
|
||||
#endif
|
1607
drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.c
Normal file
1607
drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.c
Normal file
File diff suppressed because it is too large
Load Diff
133
drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.h
Normal file
133
drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.h
Normal file
@ -0,0 +1,133 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW89_8852A_RFK_TABLE_H__
|
||||
#define __RTW89_8852A_RFK_TABLE_H__
|
||||
|
||||
#include "core.h"
|
||||
|
||||
enum rtw89_rfk_flag {
|
||||
RTW89_RFK_F_WRF = 0,
|
||||
RTW89_RFK_F_WM = 1,
|
||||
RTW89_RFK_F_WS = 2,
|
||||
RTW89_RFK_F_WC = 3,
|
||||
RTW89_RFK_F_DELAY = 4,
|
||||
RTW89_RFK_F_NUM,
|
||||
};
|
||||
|
||||
struct rtw89_rfk_tbl {
|
||||
const struct rtw89_reg5_def *defs;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
#define DECLARE_RFK_TBL(_name) \
|
||||
const struct rtw89_rfk_tbl _name ## _tbl = { \
|
||||
.defs = _name, \
|
||||
.size = ARRAY_SIZE(_name), \
|
||||
}
|
||||
|
||||
#define DECL_RFK_WRF(_path, _addr, _mask, _data) \
|
||||
{.flag = RTW89_RFK_F_WRF, \
|
||||
.path = _path, \
|
||||
.addr = _addr, \
|
||||
.mask = _mask, \
|
||||
.data = _data,}
|
||||
|
||||
#define DECL_RFK_WM(_addr, _mask, _data) \
|
||||
{.flag = RTW89_RFK_F_WM, \
|
||||
.addr = _addr, \
|
||||
.mask = _mask, \
|
||||
.data = _data,}
|
||||
|
||||
#define DECL_RFK_WS(_addr, _mask) \
|
||||
{.flag = RTW89_RFK_F_WS, \
|
||||
.addr = _addr, \
|
||||
.mask = _mask,}
|
||||
|
||||
#define DECL_RFK_WC(_addr, _mask) \
|
||||
{.flag = RTW89_RFK_F_WC, \
|
||||
.addr = _addr, \
|
||||
.mask = _mask,}
|
||||
|
||||
#define DECL_RFK_DELAY(_data) \
|
||||
{.flag = RTW89_RFK_F_DELAY, \
|
||||
.data = _data,}
|
||||
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_sys_defs_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_sys_defs_2g_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_sys_defs_5g_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_defs_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_defs_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_defs_2g_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_defs_5g_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_dck_defs_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_dck_defs_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_dac_gain_tbl_defs_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_dac_gain_tbl_defs_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_slope_cal_org_defs_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_slope_cal_org_defs_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_rf_gap_tbl_defs_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_rf_gap_tbl_defs_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_slope_defs_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_slope_defs_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_track_defs_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_track_defs_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_txagc_ofst_mv_avg_defs_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_txagc_ofst_mv_avg_defs_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_a_2g_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_a_5g_1_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_a_5g_3_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_a_5g_4_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_b_2g_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_b_5g_1_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_b_5g_3_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_b_5g_4_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_enable_defs_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_enable_defs_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_enable_defs_ab_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_disable_defs_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_tssi_tracking_defs_tbl;
|
||||
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_afe_init_defs_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_reload_defs_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_reload_defs_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_addc_defs_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_addc_defs_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_reset_defs_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_trigger_defs_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_restore_defs_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_reset_defs_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_trigger_defs_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_restore_defs_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_dadc_defs_f_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_dadc_defs_f_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_dadc_defs_r_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_dadc_defs_r_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_f_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_m_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_r_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_f_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_m_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_r_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_sf_defs_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_sr_defs_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_sf_defs_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_sr_defs_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_s_defs_ab_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_r_defs_a_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_r_defs_b_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_r_defs_ab_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_lbk_rxiqk_defs_f_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_lbk_rxiqk_defs_r_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_pas_read_defs_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_set_defs_nondbcc_path01_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_set_defs_dbcc_path0_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_set_defs_dbcc_path1_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_restore_defs_nondbcc_path01_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_restore_defs_dbcc_path0_tbl;
|
||||
extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_restore_defs_dbcc_path1_tbl;
|
||||
|
||||
#endif
|
48725
drivers/net/wireless/realtek/rtw89/rtw8852a_table.c
Normal file
48725
drivers/net/wireless/realtek/rtw89/rtw8852a_table.c
Normal file
File diff suppressed because it is too large
Load Diff
28
drivers/net/wireless/realtek/rtw89/rtw8852a_table.h
Normal file
28
drivers/net/wireless/realtek/rtw89/rtw8852a_table.h
Normal file
@ -0,0 +1,28 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW89_8852A_TABLE_H__
|
||||
#define __RTW89_8852A_TABLE_H__
|
||||
|
||||
#include "core.h"
|
||||
|
||||
extern const struct rtw89_phy_table rtw89_8852a_phy_bb_table;
|
||||
extern const struct rtw89_phy_table rtw89_8852a_phy_radioa_table;
|
||||
extern const struct rtw89_phy_table rtw89_8852a_phy_radiob_table;
|
||||
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];
|
||||
|
||||
#endif
|
190
drivers/net/wireless/realtek/rtw89/sar.c
Normal file
190
drivers/net/wireless/realtek/rtw89/sar.c
Normal file
@ -0,0 +1,190 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
#include "sar.h"
|
||||
|
||||
static int rtw89_query_sar_config_common(struct rtw89_dev *rtwdev, s32 *cfg)
|
||||
{
|
||||
struct rtw89_sar_cfg_common *rtwsar = &rtwdev->sar.cfg_common;
|
||||
enum rtw89_subband subband = rtwdev->hal.current_subband;
|
||||
|
||||
if (!rtwsar->set[subband])
|
||||
return -ENODATA;
|
||||
|
||||
*cfg = rtwsar->cfg[subband];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const
|
||||
struct rtw89_sar_handler rtw89_sar_handlers[RTW89_SAR_SOURCE_NR] = {
|
||||
[RTW89_SAR_SOURCE_COMMON] = {
|
||||
.descr_sar_source = "RTW89_SAR_SOURCE_COMMON",
|
||||
.txpwr_factor_sar = 2,
|
||||
.query_sar_config = rtw89_query_sar_config_common,
|
||||
},
|
||||
};
|
||||
|
||||
#define rtw89_sar_set_src(_dev, _src, _cfg_name, _cfg_data) \
|
||||
do { \
|
||||
typeof(_src) _s = (_src); \
|
||||
typeof(_dev) _d = (_dev); \
|
||||
BUILD_BUG_ON(!rtw89_sar_handlers[_s].descr_sar_source); \
|
||||
BUILD_BUG_ON(!rtw89_sar_handlers[_s].query_sar_config); \
|
||||
lockdep_assert_held(&_d->mutex); \
|
||||
_d->sar._cfg_name = *(_cfg_data); \
|
||||
_d->sar.src = _s; \
|
||||
} while (0)
|
||||
|
||||
static s8 rtw89_txpwr_sar_to_mac(struct rtw89_dev *rtwdev, u8 fct, s32 cfg)
|
||||
{
|
||||
const u8 fct_mac = rtwdev->chip->txpwr_factor_mac;
|
||||
s32 cfg_mac;
|
||||
|
||||
cfg_mac = fct > fct_mac ?
|
||||
cfg >> (fct - fct_mac) : cfg << (fct_mac - fct);
|
||||
|
||||
return (s8)clamp_t(s32, cfg_mac,
|
||||
RTW89_SAR_TXPWR_MAC_MIN,
|
||||
RTW89_SAR_TXPWR_MAC_MAX);
|
||||
}
|
||||
|
||||
s8 rtw89_query_sar(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
const enum rtw89_sar_sources src = rtwdev->sar.src;
|
||||
/* its members are protected by rtw89_sar_set_src() */
|
||||
const struct rtw89_sar_handler *sar_hdl = &rtw89_sar_handlers[src];
|
||||
int ret;
|
||||
s32 cfg;
|
||||
u8 fct;
|
||||
|
||||
lockdep_assert_held(&rtwdev->mutex);
|
||||
|
||||
if (src == RTW89_SAR_SOURCE_NONE)
|
||||
return RTW89_SAR_TXPWR_MAC_MAX;
|
||||
|
||||
ret = sar_hdl->query_sar_config(rtwdev, &cfg);
|
||||
if (ret)
|
||||
return RTW89_SAR_TXPWR_MAC_MAX;
|
||||
|
||||
fct = sar_hdl->txpwr_factor_sar;
|
||||
|
||||
return rtw89_txpwr_sar_to_mac(rtwdev, fct, cfg);
|
||||
}
|
||||
|
||||
void rtw89_print_sar(struct seq_file *m, struct rtw89_dev *rtwdev)
|
||||
{
|
||||
const enum rtw89_sar_sources src = rtwdev->sar.src;
|
||||
/* its members are protected by rtw89_sar_set_src() */
|
||||
const struct rtw89_sar_handler *sar_hdl = &rtw89_sar_handlers[src];
|
||||
const u8 fct_mac = rtwdev->chip->txpwr_factor_mac;
|
||||
int ret;
|
||||
s32 cfg;
|
||||
u8 fct;
|
||||
|
||||
lockdep_assert_held(&rtwdev->mutex);
|
||||
|
||||
if (src == RTW89_SAR_SOURCE_NONE) {
|
||||
seq_puts(m, "no SAR is applied\n");
|
||||
return;
|
||||
}
|
||||
|
||||
seq_printf(m, "source: %d (%s)\n", src, sar_hdl->descr_sar_source);
|
||||
|
||||
ret = sar_hdl->query_sar_config(rtwdev, &cfg);
|
||||
if (ret) {
|
||||
seq_printf(m, "config: return code: %d\n", ret);
|
||||
seq_printf(m, "assign: max setting: %d (unit: 1/%lu dBm)\n",
|
||||
RTW89_SAR_TXPWR_MAC_MAX, BIT(fct_mac));
|
||||
return;
|
||||
}
|
||||
|
||||
fct = sar_hdl->txpwr_factor_sar;
|
||||
|
||||
seq_printf(m, "config: %d (unit: 1/%lu dBm)\n", cfg, BIT(fct));
|
||||
}
|
||||
|
||||
static int rtw89_apply_sar_common(struct rtw89_dev *rtwdev,
|
||||
const struct rtw89_sar_cfg_common *sar)
|
||||
{
|
||||
enum rtw89_sar_sources src;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
|
||||
src = rtwdev->sar.src;
|
||||
if (src != RTW89_SAR_SOURCE_NONE && src != RTW89_SAR_SOURCE_COMMON) {
|
||||
rtw89_warn(rtwdev, "SAR source: %d is in use", src);
|
||||
ret = -EBUSY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rtw89_sar_set_src(rtwdev, RTW89_SAR_SOURCE_COMMON, cfg_common, sar);
|
||||
rtw89_chip_set_txpwr(rtwdev);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const u8 rtw89_common_sar_subband_map[] = {
|
||||
RTW89_CH_2G,
|
||||
RTW89_CH_5G_BAND_1,
|
||||
RTW89_CH_5G_BAND_3,
|
||||
RTW89_CH_5G_BAND_4,
|
||||
};
|
||||
|
||||
static const struct cfg80211_sar_freq_ranges rtw89_common_sar_freq_ranges[] = {
|
||||
{ .start_freq = 2412, .end_freq = 2484, },
|
||||
{ .start_freq = 5180, .end_freq = 5320, },
|
||||
{ .start_freq = 5500, .end_freq = 5720, },
|
||||
{ .start_freq = 5745, .end_freq = 5825, },
|
||||
};
|
||||
|
||||
static_assert(ARRAY_SIZE(rtw89_common_sar_subband_map) ==
|
||||
ARRAY_SIZE(rtw89_common_sar_freq_ranges));
|
||||
|
||||
const struct cfg80211_sar_capa rtw89_sar_capa = {
|
||||
.type = NL80211_SAR_TYPE_POWER,
|
||||
.num_freq_ranges = ARRAY_SIZE(rtw89_common_sar_freq_ranges),
|
||||
.freq_ranges = rtw89_common_sar_freq_ranges,
|
||||
};
|
||||
|
||||
int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw,
|
||||
const struct cfg80211_sar_specs *sar)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
struct rtw89_sar_cfg_common sar_common = {0};
|
||||
u8 fct;
|
||||
u32 freq_start;
|
||||
u32 freq_end;
|
||||
u32 band;
|
||||
s32 power;
|
||||
u32 i, idx;
|
||||
|
||||
if (sar->type != NL80211_SAR_TYPE_POWER)
|
||||
return -EINVAL;
|
||||
|
||||
fct = rtw89_sar_handlers[RTW89_SAR_SOURCE_COMMON].txpwr_factor_sar;
|
||||
|
||||
for (i = 0; i < sar->num_sub_specs; i++) {
|
||||
idx = sar->sub_specs[i].freq_range_index;
|
||||
if (idx >= ARRAY_SIZE(rtw89_common_sar_freq_ranges))
|
||||
return -EINVAL;
|
||||
|
||||
freq_start = rtw89_common_sar_freq_ranges[idx].start_freq;
|
||||
freq_end = rtw89_common_sar_freq_ranges[idx].end_freq;
|
||||
band = rtw89_common_sar_subband_map[idx];
|
||||
power = sar->sub_specs[i].power;
|
||||
|
||||
rtw89_info(rtwdev, "On freq %u to %u, ", freq_start, freq_end);
|
||||
rtw89_info(rtwdev, "set SAR power limit %d (unit: 1/%lu dBm)\n",
|
||||
power, BIT(fct));
|
||||
|
||||
sar_common.set[band] = true;
|
||||
sar_common.cfg[band] = power;
|
||||
}
|
||||
|
||||
return rtw89_apply_sar_common(rtwdev, &sar_common);
|
||||
}
|
26
drivers/net/wireless/realtek/rtw89/sar.h
Normal file
26
drivers/net/wireless/realtek/rtw89/sar.h
Normal file
@ -0,0 +1,26 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW89_SAR_H__
|
||||
#define __RTW89_SAR_H__
|
||||
|
||||
#include "core.h"
|
||||
|
||||
#define RTW89_SAR_TXPWR_MAC_MAX S8_MAX
|
||||
#define RTW89_SAR_TXPWR_MAC_MIN S8_MIN
|
||||
|
||||
struct rtw89_sar_handler {
|
||||
const char *descr_sar_source;
|
||||
u8 txpwr_factor_sar;
|
||||
int (*query_sar_config)(struct rtw89_dev *rtwdev, s32 *cfg);
|
||||
};
|
||||
|
||||
extern const struct cfg80211_sar_capa rtw89_sar_capa;
|
||||
|
||||
s8 rtw89_query_sar(struct rtw89_dev *rtwdev);
|
||||
void rtw89_print_sar(struct seq_file *m, struct rtw89_dev *rtwdev);
|
||||
int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw,
|
||||
const struct cfg80211_sar_specs *sar);
|
||||
|
||||
#endif
|
491
drivers/net/wireless/realtek/rtw89/ser.c
Normal file
491
drivers/net/wireless/realtek/rtw89/ser.c
Normal file
@ -0,0 +1,491 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#include "cam.h"
|
||||
#include "debug.h"
|
||||
#include "mac.h"
|
||||
#include "ps.h"
|
||||
#include "ser.h"
|
||||
#include "util.h"
|
||||
|
||||
#define SER_RECFG_TIMEOUT 1000
|
||||
|
||||
enum ser_evt {
|
||||
SER_EV_NONE,
|
||||
SER_EV_STATE_IN,
|
||||
SER_EV_STATE_OUT,
|
||||
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_M3_TIMEOUT,
|
||||
SER_EV_FW_M5_TIMEOUT,
|
||||
SER_EV_L0_RESET,
|
||||
SER_EV_MAXX
|
||||
};
|
||||
|
||||
enum ser_state {
|
||||
SER_IDLE_ST,
|
||||
SER_RESET_TRX_ST,
|
||||
SER_DO_HCI_ST,
|
||||
SER_L2_RESET_ST,
|
||||
SER_ST_MAX_ST
|
||||
};
|
||||
|
||||
struct ser_msg {
|
||||
struct list_head list;
|
||||
u8 event;
|
||||
};
|
||||
|
||||
struct state_ent {
|
||||
u8 state;
|
||||
char *name;
|
||||
void (*st_func)(struct rtw89_ser *ser, u8 event);
|
||||
};
|
||||
|
||||
struct event_ent {
|
||||
u8 event;
|
||||
char *name;
|
||||
};
|
||||
|
||||
static char *ser_ev_name(struct rtw89_ser *ser, u8 event)
|
||||
{
|
||||
if (event < SER_EV_MAXX)
|
||||
return ser->ev_tbl[event].name;
|
||||
|
||||
return "err_ev_name";
|
||||
}
|
||||
|
||||
static char *ser_st_name(struct rtw89_ser *ser)
|
||||
{
|
||||
if (ser->state < SER_ST_MAX_ST)
|
||||
return ser->st_tbl[ser->state].name;
|
||||
|
||||
return "err_st_name";
|
||||
}
|
||||
|
||||
static void ser_state_run(struct rtw89_ser *ser, u8 evt)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_SER, "ser: %s receive %s\n",
|
||||
ser_st_name(ser), ser_ev_name(ser, evt));
|
||||
|
||||
rtw89_leave_lps(rtwdev);
|
||||
ser->st_tbl[ser->state].st_func(ser, evt);
|
||||
}
|
||||
|
||||
static void ser_state_goto(struct rtw89_ser *ser, u8 new_state)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
|
||||
|
||||
if (ser->state == new_state || new_state >= SER_ST_MAX_ST)
|
||||
return;
|
||||
ser_state_run(ser, SER_EV_STATE_OUT);
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_SER, "ser: %s goto -> %s\n",
|
||||
ser_st_name(ser), ser->st_tbl[new_state].name);
|
||||
|
||||
ser->state = new_state;
|
||||
ser_state_run(ser, SER_EV_STATE_IN);
|
||||
}
|
||||
|
||||
static struct ser_msg *__rtw89_ser_dequeue_msg(struct rtw89_ser *ser)
|
||||
{
|
||||
struct ser_msg *msg;
|
||||
|
||||
spin_lock_irq(&ser->msg_q_lock);
|
||||
msg = list_first_entry_or_null(&ser->msg_q, struct ser_msg, list);
|
||||
if (msg)
|
||||
list_del(&msg->list);
|
||||
spin_unlock_irq(&ser->msg_q_lock);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
static void rtw89_ser_hdl_work(struct work_struct *work)
|
||||
{
|
||||
struct ser_msg *msg;
|
||||
struct rtw89_ser *ser = container_of(work, struct rtw89_ser,
|
||||
ser_hdl_work);
|
||||
|
||||
while ((msg = __rtw89_ser_dequeue_msg(ser))) {
|
||||
ser_state_run(ser, msg->event);
|
||||
kfree(msg);
|
||||
}
|
||||
}
|
||||
|
||||
static int ser_send_msg(struct rtw89_ser *ser, u8 event)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
|
||||
struct ser_msg *msg = NULL;
|
||||
|
||||
if (test_bit(RTW89_SER_DRV_STOP_RUN, ser->flags))
|
||||
return -EIO;
|
||||
|
||||
msg = kmalloc(sizeof(*msg), GFP_ATOMIC);
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
|
||||
msg->event = event;
|
||||
|
||||
spin_lock_irq(&ser->msg_q_lock);
|
||||
list_add(&msg->list, &ser->msg_q);
|
||||
spin_unlock_irq(&ser->msg_q_lock);
|
||||
|
||||
ieee80211_queue_work(rtwdev->hw, &ser->ser_hdl_work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rtw89_ser_alarm_work(struct work_struct *work)
|
||||
{
|
||||
struct rtw89_ser *ser = container_of(work, struct rtw89_ser,
|
||||
ser_alarm_work.work);
|
||||
|
||||
ser_send_msg(ser, ser->alarm_event);
|
||||
ser->alarm_event = SER_EV_NONE;
|
||||
}
|
||||
|
||||
static void ser_set_alarm(struct rtw89_ser *ser, u32 ms, u8 event)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
|
||||
|
||||
if (test_bit(RTW89_SER_DRV_STOP_RUN, ser->flags))
|
||||
return;
|
||||
|
||||
ser->alarm_event = event;
|
||||
ieee80211_queue_delayed_work(rtwdev->hw, &ser->ser_alarm_work,
|
||||
msecs_to_jiffies(ms));
|
||||
}
|
||||
|
||||
static void ser_del_alarm(struct rtw89_ser *ser)
|
||||
{
|
||||
cancel_delayed_work(&ser->ser_alarm_work);
|
||||
ser->alarm_event = SER_EV_NONE;
|
||||
}
|
||||
|
||||
/* driver function */
|
||||
static void drv_stop_tx(struct rtw89_ser *ser)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
|
||||
|
||||
ieee80211_stop_queues(rtwdev->hw);
|
||||
set_bit(RTW89_SER_DRV_STOP_TX, ser->flags);
|
||||
}
|
||||
|
||||
static void drv_stop_rx(struct rtw89_ser *ser)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
|
||||
|
||||
clear_bit(RTW89_FLAG_RUNNING, rtwdev->flags);
|
||||
set_bit(RTW89_SER_DRV_STOP_RX, ser->flags);
|
||||
}
|
||||
|
||||
static void drv_trx_reset(struct rtw89_ser *ser)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
|
||||
|
||||
rtw89_hci_reset(rtwdev);
|
||||
}
|
||||
|
||||
static void drv_resume_tx(struct rtw89_ser *ser)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
|
||||
|
||||
if (!test_bit(RTW89_SER_DRV_STOP_TX, ser->flags))
|
||||
return;
|
||||
|
||||
ieee80211_wake_queues(rtwdev->hw);
|
||||
clear_bit(RTW89_SER_DRV_STOP_TX, ser->flags);
|
||||
}
|
||||
|
||||
static void drv_resume_rx(struct rtw89_ser *ser)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
|
||||
|
||||
if (!test_bit(RTW89_SER_DRV_STOP_RX, ser->flags))
|
||||
return;
|
||||
|
||||
set_bit(RTW89_FLAG_RUNNING, rtwdev->flags);
|
||||
clear_bit(RTW89_SER_DRV_STOP_RX, ser->flags);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static void ser_reset_mac_binding(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_vif *rtwvif;
|
||||
|
||||
rtw89_cam_reset_keys(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);
|
||||
}
|
||||
|
||||
/* hal function */
|
||||
static int hal_enable_dma(struct rtw89_ser *ser)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
|
||||
int ret;
|
||||
|
||||
if (!test_bit(RTW89_SER_HAL_STOP_DMA, ser->flags))
|
||||
return 0;
|
||||
|
||||
if (!rtwdev->hci.ops->mac_lv1_rcvy)
|
||||
return -EIO;
|
||||
|
||||
ret = rtwdev->hci.ops->mac_lv1_rcvy(rtwdev, RTW89_LV1_RCVY_STEP_2);
|
||||
if (!ret)
|
||||
clear_bit(RTW89_SER_HAL_STOP_DMA, ser->flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hal_stop_dma(struct rtw89_ser *ser)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
|
||||
int ret;
|
||||
|
||||
if (!rtwdev->hci.ops->mac_lv1_rcvy)
|
||||
return -EIO;
|
||||
|
||||
ret = rtwdev->hci.ops->mac_lv1_rcvy(rtwdev, RTW89_LV1_RCVY_STEP_1);
|
||||
if (!ret)
|
||||
set_bit(RTW89_SER_HAL_STOP_DMA, ser->flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hal_send_m2_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_DISABLE_EN);
|
||||
}
|
||||
|
||||
static void hal_send_m4_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_RCVY_EN);
|
||||
}
|
||||
|
||||
/* state handler */
|
||||
static void ser_idle_st_hdl(struct rtw89_ser *ser, u8 evt)
|
||||
{
|
||||
switch (evt) {
|
||||
case SER_EV_STATE_IN:
|
||||
break;
|
||||
case SER_EV_L1_RESET:
|
||||
ser_state_goto(ser, SER_RESET_TRX_ST);
|
||||
break;
|
||||
case SER_EV_L2_RESET:
|
||||
ser_state_goto(ser, SER_L2_RESET_ST);
|
||||
break;
|
||||
case SER_EV_STATE_OUT:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ser_reset_trx_st_hdl(struct rtw89_ser *ser, u8 evt)
|
||||
{
|
||||
switch (evt) {
|
||||
case SER_EV_STATE_IN:
|
||||
drv_stop_tx(ser);
|
||||
|
||||
if (hal_stop_dma(ser)) {
|
||||
ser_state_goto(ser, SER_L2_RESET_ST);
|
||||
break;
|
||||
}
|
||||
|
||||
drv_stop_rx(ser);
|
||||
drv_trx_reset(ser);
|
||||
|
||||
/* wait m3 */
|
||||
hal_send_m2_event(ser);
|
||||
|
||||
/* set alarm to prevent FW response timeout */
|
||||
ser_set_alarm(ser, 1000, SER_EV_M3_TIMEOUT);
|
||||
break;
|
||||
|
||||
case SER_EV_DO_RECOVERY:
|
||||
ser_state_goto(ser, SER_DO_HCI_ST);
|
||||
break;
|
||||
|
||||
case SER_EV_M3_TIMEOUT:
|
||||
ser_state_goto(ser, SER_L2_RESET_ST);
|
||||
break;
|
||||
|
||||
case SER_EV_STATE_OUT:
|
||||
ser_del_alarm(ser);
|
||||
hal_enable_dma(ser);
|
||||
drv_resume_rx(ser);
|
||||
drv_resume_tx(ser);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ser_do_hci_st_hdl(struct rtw89_ser *ser, u8 evt)
|
||||
{
|
||||
switch (evt) {
|
||||
case SER_EV_STATE_IN:
|
||||
/* wait m5 */
|
||||
hal_send_m4_event(ser);
|
||||
|
||||
/* prevent FW response timeout */
|
||||
ser_set_alarm(ser, 1000, SER_EV_FW_M5_TIMEOUT);
|
||||
break;
|
||||
|
||||
case SER_EV_FW_M5_TIMEOUT:
|
||||
ser_state_goto(ser, SER_L2_RESET_ST);
|
||||
break;
|
||||
|
||||
case SER_EV_MAC_RESET_DONE:
|
||||
ser_state_goto(ser, SER_IDLE_ST);
|
||||
break;
|
||||
|
||||
case SER_EV_STATE_OUT:
|
||||
ser_del_alarm(ser);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ser_l2_reset_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:
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
ser_reset_mac_binding(rtwdev);
|
||||
rtw89_core_stop(rtwdev);
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
|
||||
ieee80211_restart_hw(rtwdev->hw);
|
||||
ser_set_alarm(ser, SER_RECFG_TIMEOUT, SER_EV_L2_RECFG_TIMEOUT);
|
||||
break;
|
||||
|
||||
case SER_EV_L2_RECFG_TIMEOUT:
|
||||
rtw89_info(rtwdev, "Err: ser L2 re-config timeout\n");
|
||||
fallthrough;
|
||||
case SER_EV_L2_RECFG_DONE:
|
||||
ser_state_goto(ser, SER_IDLE_ST);
|
||||
break;
|
||||
|
||||
case SER_EV_STATE_OUT:
|
||||
ser_del_alarm(ser);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static 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_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_M3_TIMEOUT, "SER_EV_M3_TIMEOUT"},
|
||||
{SER_EV_FW_M5_TIMEOUT, "SER_EV_FW_M5_TIMEOUT"},
|
||||
{SER_EV_L0_RESET, "SER_EV_L0_RESET"},
|
||||
{SER_EV_MAXX, "SER_EV_MAX"}
|
||||
};
|
||||
|
||||
static struct state_ent ser_st_tbl[] = {
|
||||
{SER_IDLE_ST, "SER_IDLE_ST", ser_idle_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}
|
||||
};
|
||||
|
||||
int rtw89_ser_init(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_ser *ser = &rtwdev->ser;
|
||||
|
||||
memset(ser, 0, sizeof(*ser));
|
||||
INIT_LIST_HEAD(&ser->msg_q);
|
||||
ser->state = SER_IDLE_ST;
|
||||
ser->st_tbl = ser_st_tbl;
|
||||
ser->ev_tbl = ser_ev_tbl;
|
||||
|
||||
bitmap_zero(ser->flags, RTW89_NUM_OF_SER_FLAGS);
|
||||
spin_lock_init(&ser->msg_q_lock);
|
||||
INIT_WORK(&ser->ser_hdl_work, rtw89_ser_hdl_work);
|
||||
INIT_DELAYED_WORK(&ser->ser_alarm_work, rtw89_ser_alarm_work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtw89_ser_deinit(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_ser *ser = (struct rtw89_ser *)&rtwdev->ser;
|
||||
|
||||
set_bit(RTW89_SER_DRV_STOP_RUN, ser->flags);
|
||||
cancel_delayed_work_sync(&ser->ser_alarm_work);
|
||||
cancel_work_sync(&ser->ser_hdl_work);
|
||||
clear_bit(RTW89_SER_DRV_STOP_RUN, ser->flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtw89_ser_recfg_done(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
ser_send_msg(&rtwdev->ser, SER_EV_L2_RECFG_DONE);
|
||||
}
|
||||
|
||||
int rtw89_ser_notify(struct rtw89_dev *rtwdev, u32 err)
|
||||
{
|
||||
u8 event = SER_EV_NONE;
|
||||
|
||||
rtw89_info(rtwdev, "ser event = 0x%04x\n", err);
|
||||
|
||||
switch (err) {
|
||||
case MAC_AX_ERR_L1_ERR_DMAC:
|
||||
case MAC_AX_ERR_L0_PROMOTE_TO_L1:
|
||||
event = SER_EV_L1_RESET; /* M1 */
|
||||
break;
|
||||
case MAC_AX_ERR_L1_RESET_DISABLE_DMAC_DONE:
|
||||
event = SER_EV_DO_RECOVERY; /* M3 */
|
||||
break;
|
||||
case MAC_AX_ERR_L1_RESET_RECOVERY_DONE:
|
||||
event = SER_EV_MAC_RESET_DONE; /* M5 */
|
||||
break;
|
||||
case MAC_AX_ERR_L0_ERR_CMAC0:
|
||||
case MAC_AX_ERR_L0_ERR_CMAC1:
|
||||
case MAC_AX_ERR_L0_RESET_DONE:
|
||||
event = SER_EV_L0_RESET;
|
||||
break;
|
||||
default:
|
||||
if (err == MAC_AX_ERR_L1_PROMOTE_TO_L2 ||
|
||||
(err >= MAC_AX_ERR_L2_ERR_AH_DMA &&
|
||||
err <= MAC_AX_GET_ERR_MAX))
|
||||
event = SER_EV_L2_RESET;
|
||||
break;
|
||||
}
|
||||
|
||||
if (event == SER_EV_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
ser_send_msg(&rtwdev->ser, event);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(rtw89_ser_notify);
|
15
drivers/net/wireless/realtek/rtw89/ser.h
Normal file
15
drivers/net/wireless/realtek/rtw89/ser.h
Normal file
@ -0,0 +1,15 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
#ifndef __SER_H__
|
||||
#define __SER_H__
|
||||
|
||||
#include "core.h"
|
||||
|
||||
int rtw89_ser_init(struct rtw89_dev *rtwdev);
|
||||
int rtw89_ser_deinit(struct rtw89_dev *rtwdev);
|
||||
int rtw89_ser_notify(struct rtw89_dev *rtwdev, u32 err);
|
||||
void rtw89_ser_recfg_done(struct rtw89_dev *rtwdev);
|
||||
|
||||
#endif /* __SER_H__*/
|
||||
|
358
drivers/net/wireless/realtek/rtw89/txrx.h
Normal file
358
drivers/net/wireless/realtek/rtw89/txrx.h
Normal file
@ -0,0 +1,358 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW89_TXRX_H__
|
||||
#define __RTW89_TXRX_H__
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#define DATA_RATE_MODE_CTRL_MASK GENMASK(8, 7)
|
||||
#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_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_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)
|
||||
|
||||
/* TX WD BODY DWORD 0 */
|
||||
#define RTW89_TXWD_BODY0_WP_OFFSET GENMASK(31, 24)
|
||||
#define RTW89_TXWD_BODY0_MORE_DATA BIT(23)
|
||||
#define RTW89_TXWD_BODY0_WD_INFO_EN BIT(22)
|
||||
#define RTW89_TXWD_BODY0_FW_DL BIT(20)
|
||||
#define RTW89_TXWD_BODY0_CHANNEL_DMA GENMASK(19, 16)
|
||||
#define RTW89_TXWD_BODY0_HDR_LLC_LEN GENMASK(15, 11)
|
||||
#define RTW89_TXWD_BODY0_WD_PAGE BIT(7)
|
||||
#define RTW89_TXWD_BODY0_HW_AMSDU BIT(5)
|
||||
|
||||
/* TX WD BODY DWORD 1 */
|
||||
#define RTW89_TXWD_BODY1_PAYLOAD_ID GENMASK(31, 16)
|
||||
|
||||
/* TX WD BODY DWORD 2 */
|
||||
#define RTW89_TXWD_BODY2_MACID GENMASK(30, 24)
|
||||
#define RTW89_TXWD_BODY2_TID_INDICATE BIT(23)
|
||||
#define RTW89_TXWD_BODY2_QSEL GENMASK(22, 17)
|
||||
#define RTW89_TXWD_BODY2_TXPKT_SIZE GENMASK(13, 0)
|
||||
|
||||
/* TX WD BODY DWORD 3 */
|
||||
#define RTW89_TXWD_BODY3_BK BIT(13)
|
||||
#define RTW89_TXWD_BODY3_AGG_EN BIT(12)
|
||||
#define RTW89_TXWD_BODY3_SW_SEQ GENMASK(11, 0)
|
||||
|
||||
/* TX WD BODY DWORD 4 */
|
||||
|
||||
/* TX WD BODY DWORD 5 */
|
||||
|
||||
/* TX WD INFO DWORD 0 */
|
||||
#define RTW89_TXWD_INFO0_USE_RATE BIT(30)
|
||||
#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_DISDATAFB BIT(10)
|
||||
|
||||
/* TX WD INFO DWORD 1 */
|
||||
#define RTW89_TXWD_INFO1_DATA_RTY_LOWEST_RATE GENMASK(24, 16)
|
||||
#define RTW89_TXWD_INFO1_A_CTRL_BSR BIT(14)
|
||||
#define RTW89_TXWD_INFO1_MAX_AGGNUM GENMASK(7, 0)
|
||||
|
||||
/* TX WD INFO DWORD 2 */
|
||||
#define RTW89_TXWD_INFO2_AMPDU_DENSITY GENMASK(20, 18)
|
||||
#define RTW89_TXWD_INFO2_SEC_TYPE GENMASK(12, 9)
|
||||
#define RTW89_TXWD_INFO2_SEC_HW_ENC BIT(8)
|
||||
#define RTW89_TXWD_INFO2_SEC_CAM_IDX GENMASK(7, 0)
|
||||
|
||||
/* TX WD INFO DWORD 3 */
|
||||
|
||||
/* TX WD INFO DWORD 4 */
|
||||
#define RTW89_TXWD_INFO4_RTS_EN BIT(27)
|
||||
#define RTW89_TXWD_INFO4_HW_RTS_EN BIT(31)
|
||||
|
||||
/* TX WD INFO DWORD 5 */
|
||||
|
||||
/* 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_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))
|
||||
|
||||
/* 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_GET_RXINFO_USR_NUM(rpt) \
|
||||
le32_get_bits(*((__le32 *)rpt), GENMASK(3, 0))
|
||||
#define RTW89_GET_RXINFO_FW_DEFINE(rpt) \
|
||||
le32_get_bits(*((__le32 *)rpt), GENMASK(15, 8))
|
||||
#define RTW89_GET_RXINFO_LSIG_LEN(rpt) \
|
||||
le32_get_bits(*((__le32 *)rpt), GENMASK(27, 16))
|
||||
#define RTW89_GET_RXINFO_IS_TO_SELF(rpt) \
|
||||
le32_get_bits(*((__le32 *)rpt), BIT(28))
|
||||
#define RTW89_GET_RXINFO_RX_CNT_VLD(rpt) \
|
||||
le32_get_bits(*((__le32 *)rpt), BIT(29))
|
||||
#define RTW89_GET_RXINFO_LONG_RXD(rpt) \
|
||||
le32_get_bits(*((__le32 *)rpt), GENMASK(31, 30))
|
||||
#define RTW89_GET_RXINFO_SERVICE(rpt) \
|
||||
le32_get_bits(*((__le32 *)(rpt) + 1), GENMASK(15, 0))
|
||||
#define RTW89_GET_RXINFO_PLCP_LEN(rpt) \
|
||||
le32_get_bits(*((__le32 *)(rpt) + 1), GENMASK(23, 16))
|
||||
#define RTW89_GET_RXINFO_MAC_ID_VALID(rpt, usr) \
|
||||
le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), BIT(0))
|
||||
#define RTW89_GET_RXINFO_DATA(rpt, usr) \
|
||||
le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), BIT(1))
|
||||
#define RTW89_GET_RXINFO_CTRL(rpt, usr) \
|
||||
le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), BIT(2))
|
||||
#define RTW89_GET_RXINFO_MGMT(rpt, usr) \
|
||||
le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), BIT(3))
|
||||
#define RTW89_GET_RXINFO_BCM(rpt, usr) \
|
||||
le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), BIT(4))
|
||||
#define RTW89_GET_RXINFO_MACID(rpt, usr) \
|
||||
le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), GENMASK(15, 8))
|
||||
|
||||
#define RTW89_GET_PHY_STS_RSSI_A(sts) \
|
||||
le32_get_bits(*((__le32 *)(sts) + 1), GENMASK(7, 0))
|
||||
#define RTW89_GET_PHY_STS_RSSI_B(sts) \
|
||||
le32_get_bits(*((__le32 *)(sts) + 1), GENMASK(15, 8))
|
||||
#define RTW89_GET_PHY_STS_RSSI_C(sts) \
|
||||
le32_get_bits(*((__le32 *)(sts) + 1), GENMASK(23, 16))
|
||||
#define RTW89_GET_PHY_STS_RSSI_D(sts) \
|
||||
le32_get_bits(*((__le32 *)(sts) + 1), GENMASK(31, 24))
|
||||
#define RTW89_GET_PHY_STS_LEN(sts) \
|
||||
le32_get_bits(*((__le32 *)sts), GENMASK(15, 8))
|
||||
#define RTW89_GET_PHY_STS_RSSI_AVG(sts) \
|
||||
le32_get_bits(*((__le32 *)sts), GENMASK(31, 24))
|
||||
#define RTW89_GET_PHY_STS_IE_TYPE(ie) \
|
||||
le32_get_bits(*((__le32 *)ie), GENMASK(4, 0))
|
||||
#define RTW89_GET_PHY_STS_IE_LEN(ie) \
|
||||
le32_get_bits(*((__le32 *)ie), GENMASK(11, 5))
|
||||
#define RTW89_GET_PHY_STS_IE0_CFO(ie) \
|
||||
le32_get_bits(*((__le32 *)(ie) + 1), GENMASK(31, 20))
|
||||
|
||||
enum rtw89_tx_channel {
|
||||
RTW89_TXCH_ACH0 = 0,
|
||||
RTW89_TXCH_ACH1 = 1,
|
||||
RTW89_TXCH_ACH2 = 2,
|
||||
RTW89_TXCH_ACH3 = 3,
|
||||
RTW89_TXCH_ACH4 = 4,
|
||||
RTW89_TXCH_ACH5 = 5,
|
||||
RTW89_TXCH_ACH6 = 6,
|
||||
RTW89_TXCH_ACH7 = 7,
|
||||
RTW89_TXCH_CH8 = 8, /* MGMT Band 0 */
|
||||
RTW89_TXCH_CH9 = 9, /* HI Band 0 */
|
||||
RTW89_TXCH_CH10 = 10, /* MGMT Band 1 */
|
||||
RTW89_TXCH_CH11 = 11, /* HI Band 1 */
|
||||
RTW89_TXCH_CH12 = 12, /* FW CMD */
|
||||
|
||||
/* keep last */
|
||||
RTW89_TXCH_NUM,
|
||||
RTW89_TXCH_MAX = RTW89_TXCH_NUM - 1
|
||||
};
|
||||
|
||||
enum rtw89_rx_channel {
|
||||
RTW89_RXCH_RXQ = 0,
|
||||
RTW89_RXCH_RPQ = 1,
|
||||
|
||||
/* keep last */
|
||||
RTW89_RXCH_NUM,
|
||||
RTW89_RXCH_MAX = RTW89_RXCH_NUM - 1
|
||||
};
|
||||
|
||||
enum rtw89_tx_qsel {
|
||||
RTW89_TX_QSEL_BE_0 = 0x00,
|
||||
RTW89_TX_QSEL_BK_0 = 0x01,
|
||||
RTW89_TX_QSEL_VI_0 = 0x02,
|
||||
RTW89_TX_QSEL_VO_0 = 0x03,
|
||||
RTW89_TX_QSEL_BE_1 = 0x04,
|
||||
RTW89_TX_QSEL_BK_1 = 0x05,
|
||||
RTW89_TX_QSEL_VI_1 = 0x06,
|
||||
RTW89_TX_QSEL_VO_1 = 0x07,
|
||||
RTW89_TX_QSEL_BE_2 = 0x08,
|
||||
RTW89_TX_QSEL_BK_2 = 0x09,
|
||||
RTW89_TX_QSEL_VI_2 = 0x0a,
|
||||
RTW89_TX_QSEL_VO_2 = 0x0b,
|
||||
RTW89_TX_QSEL_BE_3 = 0x0c,
|
||||
RTW89_TX_QSEL_BK_3 = 0x0d,
|
||||
RTW89_TX_QSEL_VI_3 = 0x0e,
|
||||
RTW89_TX_QSEL_VO_3 = 0x0f,
|
||||
RTW89_TX_QSEL_B0_BCN = 0x10,
|
||||
RTW89_TX_QSEL_B0_HI = 0x11,
|
||||
RTW89_TX_QSEL_B0_MGMT = 0x12,
|
||||
RTW89_TX_QSEL_B0_NOPS = 0x13,
|
||||
RTW89_TX_QSEL_B0_MGMT_FAST = 0x14,
|
||||
/* reserved */
|
||||
/* reserved */
|
||||
/* reserved */
|
||||
RTW89_TX_QSEL_B1_BCN = 0x18,
|
||||
RTW89_TX_QSEL_B1_HI = 0x19,
|
||||
RTW89_TX_QSEL_B1_MGMT = 0x1a,
|
||||
RTW89_TX_QSEL_B1_NOPS = 0x1b,
|
||||
RTW89_TX_QSEL_B1_MGMT_FAST = 0x1c,
|
||||
/* reserved */
|
||||
/* reserved */
|
||||
/* reserved */
|
||||
};
|
||||
|
||||
enum rtw89_phy_status_ie_type {
|
||||
RTW89_PHYSTS_IE00_CMN_CCK = 0,
|
||||
RTW89_PHYSTS_IE01_CMN_OFDM = 1,
|
||||
RTW89_PHYSTS_IE02_CMN_EXT_AX = 2,
|
||||
RTW89_PHYSTS_IE03_CMN_EXT_SEG_1 = 3,
|
||||
RTW89_PHYSTS_IE04_CMN_EXT_PATH_A = 4,
|
||||
RTW89_PHYSTS_IE05_CMN_EXT_PATH_B = 5,
|
||||
RTW89_PHYSTS_IE06_CMN_EXT_PATH_C = 6,
|
||||
RTW89_PHYSTS_IE07_CMN_EXT_PATH_D = 7,
|
||||
RTW89_PHYSTS_IE08_FTR_CH = 8,
|
||||
RTW89_PHYSTS_IE09_FTR_PLCP_0 = 9,
|
||||
RTW89_PHYSTS_IE10_FTR_PLCP_EXT = 10,
|
||||
RTW89_PHYSTS_IE11_FTR_PLCP_HISTOGRAM = 11,
|
||||
RTW89_PHYSTS_IE12_MU_EIGEN_INFO = 12,
|
||||
RTW89_PHYSTS_IE13_DL_MU_DEF = 13,
|
||||
RTW89_PHYSTS_IE14_TB_UL_CQI = 14,
|
||||
RTW89_PHYSTS_IE15_TB_UL_DEF = 15,
|
||||
RTW89_PHYSTS_IE16_RSVD16 = 16,
|
||||
RTW89_PHYSTS_IE17_TB_UL_CTRL = 17,
|
||||
RTW89_PHYSTS_IE18_DBG_OFDM_FD_CMN = 18,
|
||||
RTW89_PHYSTS_IE19_DBG_OFDM_TD_CMN = 19,
|
||||
RTW89_PHYSTS_IE20_DBG_OFDM_FD_USER_SEG_0 = 20,
|
||||
RTW89_PHYSTS_IE21_DBG_OFDM_FD_USER_SEG_1 = 21,
|
||||
RTW89_PHYSTS_IE22_DBG_OFDM_FD_USER_AGC = 22,
|
||||
RTW89_PHYSTS_IE23_RSVD23 = 23,
|
||||
RTW89_PHYSTS_IE24_DBG_OFDM_TD_PATH_A = 24,
|
||||
RTW89_PHYSTS_IE25_DBG_OFDM_TD_PATH_B = 25,
|
||||
RTW89_PHYSTS_IE26_DBG_OFDM_TD_PATH_C = 26,
|
||||
RTW89_PHYSTS_IE27_DBG_OFDM_TD_PATH_D = 27,
|
||||
RTW89_PHYSTS_IE28_DBG_CCK_PATH_A = 28,
|
||||
RTW89_PHYSTS_IE29_DBG_CCK_PATH_B = 29,
|
||||
RTW89_PHYSTS_IE30_DBG_CCK_PATH_C = 30,
|
||||
RTW89_PHYSTS_IE31_DBG_CCK_PATH_D = 31,
|
||||
|
||||
/* keep last */
|
||||
RTW89_PHYSTS_IE_NUM,
|
||||
RTW89_PHYSTS_IE_MAX = RTW89_PHYSTS_IE_NUM - 1
|
||||
};
|
||||
|
||||
static inline u8 rtw89_core_get_qsel(struct rtw89_dev *rtwdev, u8 tid)
|
||||
{
|
||||
switch (tid) {
|
||||
default:
|
||||
rtw89_warn(rtwdev, "Should use tag 1d: %d\n", tid);
|
||||
fallthrough;
|
||||
case 0:
|
||||
case 3:
|
||||
return RTW89_TX_QSEL_BE_0;
|
||||
case 1:
|
||||
case 2:
|
||||
return RTW89_TX_QSEL_BK_0;
|
||||
case 4:
|
||||
case 5:
|
||||
return RTW89_TX_QSEL_VI_0;
|
||||
case 6:
|
||||
case 7:
|
||||
return RTW89_TX_QSEL_VO_0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline u8 rtw89_core_get_ch_dma(struct rtw89_dev *rtwdev, u8 qsel)
|
||||
{
|
||||
switch (qsel) {
|
||||
default:
|
||||
rtw89_warn(rtwdev, "Cannot map qsel to dma: %d\n", qsel);
|
||||
fallthrough;
|
||||
case RTW89_TX_QSEL_BE_0:
|
||||
return RTW89_TXCH_ACH0;
|
||||
case RTW89_TX_QSEL_BK_0:
|
||||
return RTW89_TXCH_ACH1;
|
||||
case RTW89_TX_QSEL_VI_0:
|
||||
return RTW89_TXCH_ACH2;
|
||||
case RTW89_TX_QSEL_VO_0:
|
||||
return RTW89_TXCH_ACH3;
|
||||
case RTW89_TX_QSEL_B0_MGMT:
|
||||
return RTW89_TXCH_CH8;
|
||||
case RTW89_TX_QSEL_B0_HI:
|
||||
return RTW89_TXCH_CH9;
|
||||
case RTW89_TX_QSEL_B1_MGMT:
|
||||
return RTW89_TXCH_CH10;
|
||||
case RTW89_TX_QSEL_B1_HI:
|
||||
return RTW89_TXCH_CH11;
|
||||
}
|
||||
}
|
||||
|
||||
static inline u8 rtw89_core_get_tid_indicate(struct rtw89_dev *rtwdev, u8 tid)
|
||||
{
|
||||
switch (tid) {
|
||||
case 3:
|
||||
case 2:
|
||||
case 5:
|
||||
case 7:
|
||||
return 1;
|
||||
default:
|
||||
rtw89_warn(rtwdev, "Should use tag 1d: %d\n", tid);
|
||||
fallthrough;
|
||||
case 0:
|
||||
case 1:
|
||||
case 4:
|
||||
case 6:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
17
drivers/net/wireless/realtek/rtw89/util.h
Normal file
17
drivers/net/wireless/realtek/rtw89/util.h
Normal file
@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
#ifndef __RTW89_UTIL_H__
|
||||
#define __RTW89_UTIL_H__
|
||||
|
||||
#include "core.h"
|
||||
|
||||
#define rtw89_iterate_vifs_bh(rtwdev, iterator, data) \
|
||||
ieee80211_iterate_active_interfaces_atomic((rtwdev)->hw, \
|
||||
IEEE80211_IFACE_ITER_NORMAL, iterator, data)
|
||||
|
||||
/* call this function with rtwdev->mutex is held */
|
||||
#define rtw89_for_each_rtwvif(rtwdev, rtwvif) \
|
||||
list_for_each_entry(rtwvif, &(rtwdev)->rtwvifs_list, list)
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user