mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-09-21 20:22:13 +08:00
rtw-next patches for v6.10
Major changes are listed as below rtl8xxxu: - remove rtl8xxxu_ prefix from filename - cleanup includes of header files rtlwifi: - adjust code to share with coming support of rtl8192du rtw89: - complete features of new WiFi 7 chip 8922AE including BT-coexistence and WoWLAN - use BIOS ACPI settings to set TX power and channels -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEuyEnvMdOsBl1WjpdjlvZYmhshd8FAmY2Jk8ACgkQjlvZYmhs hd/I9Q//aatzdSDkVtVC9YUFLAb+UYXc0s8t7Kq4eYEu/ZgFRgWHcB1Ka8OBE/9p mkCiLPBujzqI5nLq+9HoJ0ptzI9F93QnPrsLr670NpY5Nt7IRO5ph90/HN/e2VPm +FlF+EZ5UuHolw+KaA3Kym3a6Ui7vnmIZympRkk9vKrq4GAXmcVI4zVNAFgRfHo1 tWBdGONlMJGjjIQ2UJ8CiTRMkM7Ph3VgK/aCJyHwtAJvVxSJFN9b1cDzW64DES5V cPQgVtRg3o/l05KJ+xrggXQWSkiYrtbBMX6URTkOaX6cfVDd6D8qsLLB/CabXGjo 12LqxAxMQuQ44kxXyFSln5SgNwMA0X301Qbzms5KCfKDd9SMZ0MKmOrAlEI35Og5 T03DUg2btD6VSFZJcnNCmBZtSdlm7fhRlxmJTo/N++6lS8CmA0NettkwcOPpfi1l KdaU735KUG3lgelW9gj4RWUI06cVZ2y4UPAh3fvMq7FuwGDyJvFftrgwn/bN2jPH 9Zmivq1Q2/7xwZ/hhzAwLNUAUv6191XZXAwMxBGT/qpNNrgwMiLnVEjMa1/pgixH Z5cMlg5c14wpaepB70PCvy2CImOBcGAs8kfvX8cER5L29+lmg5vpdz+DGTCKK8t3 2tdMTA9xtDc+J1EIqgydSXvMfDwdyX9wBr+3sqOVdzfFqeSEx9I= =z69x -----END PGP SIGNATURE----- Merge tag 'rtw-next-2024-05-04-v2' of https://github.com/pkshih/rtw rtw-next patches for v6.10 Major changes are listed as below rtl8xxxu: - remove rtl8xxxu_ prefix from filename - cleanup includes of header files rtlwifi: - adjust code to share with coming support of rtl8192du rtw89: - complete features of new WiFi 7 chip 8922AE including BT-coexistence and WoWLAN - use BIOS ACPI settings to set TX power and channels
This commit is contained in:
commit
2d6c717760
@ -13,24 +13,8 @@
|
||||
* additional 8xxx chips like the 8192cu, 8188cus, etc.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <net/mac80211.h>
|
||||
#include "regs.h"
|
||||
#include "rtl8xxxu.h"
|
||||
#include "rtl8xxxu_regs.h"
|
||||
|
||||
static const struct rtl8xxxu_reg8val rtl8188e_mac_init_table[] = {
|
||||
{0x026, 0x41}, {0x027, 0x35}, {0x040, 0x00}, {0x421, 0x0f},
|
@ -11,24 +11,8 @@
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <net/mac80211.h>
|
||||
#include "regs.h"
|
||||
#include "rtl8xxxu.h"
|
||||
#include "rtl8xxxu_regs.h"
|
||||
|
||||
static const struct rtl8xxxu_reg8val rtl8188f_mac_init_table[] = {
|
||||
{0x024, 0xDF}, {0x025, 0x07}, {0x02B, 0x1C}, {0x283, 0x20},
|
@ -13,24 +13,8 @@
|
||||
* additional 8xxx chips like the 8192cu, 8188cus, etc.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <net/mac80211.h>
|
||||
#include "regs.h"
|
||||
#include "rtl8xxxu.h"
|
||||
#include "rtl8xxxu_regs.h"
|
||||
|
||||
#ifdef CONFIG_RTL8XXXU_UNTESTED
|
||||
static struct rtl8xxxu_power_base rtl8192c_power_base = {
|
||||
@ -77,6 +61,32 @@ static struct rtl8xxxu_power_base rtl8188r_power_base = {
|
||||
.reg_0868 = 0x00020204,
|
||||
};
|
||||
|
||||
static const struct rtl8xxxu_reg8val rtl8192cu_mac_init_table[] = {
|
||||
{0x420, 0x80}, {0x423, 0x00}, {0x430, 0x00}, {0x431, 0x00},
|
||||
{0x432, 0x00}, {0x433, 0x01}, {0x434, 0x04}, {0x435, 0x05},
|
||||
{0x436, 0x06}, {0x437, 0x07}, {0x438, 0x00}, {0x439, 0x00},
|
||||
{0x43a, 0x00}, {0x43b, 0x01}, {0x43c, 0x04}, {0x43d, 0x05},
|
||||
{0x43e, 0x06}, {0x43f, 0x07}, {0x440, 0x5d}, {0x441, 0x01},
|
||||
{0x442, 0x00}, {0x444, 0x15}, {0x445, 0xf0}, {0x446, 0x0f},
|
||||
{0x447, 0x00}, {0x458, 0x41}, {0x459, 0xa8}, {0x45a, 0x72},
|
||||
{0x45b, 0xb9}, {0x460, 0x66}, {0x461, 0x66}, {0x462, 0x08},
|
||||
{0x463, 0x03}, {0x4c8, 0xff}, {0x4c9, 0x08}, {0x4cc, 0xff},
|
||||
{0x4cd, 0xff}, {0x4ce, 0x01}, {0x500, 0x26}, {0x501, 0xa2},
|
||||
{0x502, 0x2f}, {0x503, 0x00}, {0x504, 0x28}, {0x505, 0xa3},
|
||||
{0x506, 0x5e}, {0x507, 0x00}, {0x508, 0x2b}, {0x509, 0xa4},
|
||||
{0x50a, 0x5e}, {0x50b, 0x00}, {0x50c, 0x4f}, {0x50d, 0xa4},
|
||||
{0x50e, 0x00}, {0x50f, 0x00}, {0x512, 0x1c}, {0x514, 0x0a},
|
||||
{0x515, 0x10}, {0x516, 0x0a}, {0x517, 0x10}, {0x51a, 0x16},
|
||||
{0x524, 0x0f}, {0x525, 0x4f}, {0x546, 0x40}, {0x547, 0x00},
|
||||
{0x550, 0x10}, {0x551, 0x10}, {0x559, 0x02}, {0x55a, 0x02},
|
||||
{0x55d, 0xff}, {0x605, 0x30}, {0x608, 0x0e}, {0x609, 0x2a},
|
||||
{0x652, 0x20}, {0x652, 0x20}, {0x63c, 0x08}, {0x63d, 0x08},
|
||||
{0x63e, 0x0c}, {0x63f, 0x0c}, {0x66e, 0x05}, {0x700, 0x21},
|
||||
{0x701, 0x43}, {0x702, 0x65}, {0x703, 0x87}, {0x708, 0x21},
|
||||
{0x709, 0x43}, {0x70a, 0x65}, {0x70b, 0x87},
|
||||
{0xffff, 0xff},
|
||||
};
|
||||
|
||||
static const struct rtl8xxxu_rfregval rtl8192cu_radioa_2t_init_table[] = {
|
||||
{0x00, 0x00030159}, {0x01, 0x00031284},
|
||||
{0x02, 0x00098000}, {0x03, 0x00018c63},
|
||||
@ -583,6 +593,26 @@ static int rtl8192cu_power_on(struct rtl8xxxu_priv *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtl8192cu_led_brightness_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
struct rtl8xxxu_priv *priv = container_of(led_cdev,
|
||||
struct rtl8xxxu_priv,
|
||||
led_cdev);
|
||||
u8 ledcfg = rtl8xxxu_read8(priv, REG_LEDCFG0);
|
||||
|
||||
if (brightness == LED_OFF)
|
||||
ledcfg = LEDCFG2_SW_LED_CONTROL | LEDCFG2_SW_LED_DISABLE;
|
||||
else if (brightness == LED_ON)
|
||||
ledcfg = LEDCFG2_SW_LED_CONTROL;
|
||||
else if (brightness == RTL8XXXU_HW_LED_CONTROL)
|
||||
ledcfg = LEDCFG2_HW_LED_CONTROL | LEDCFG2_HW_LED_ENABLE;
|
||||
|
||||
rtl8xxxu_write8(priv, REG_LEDCFG0, ledcfg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct rtl8xxxu_fileops rtl8192cu_fops = {
|
||||
.identify_chip = rtl8192cu_identify_chip,
|
||||
.parse_efuse = rtl8192cu_parse_efuse,
|
||||
@ -609,6 +639,7 @@ struct rtl8xxxu_fileops rtl8192cu_fops = {
|
||||
.report_rssi = rtl8xxxu_gen1_report_rssi,
|
||||
.fill_txdesc = rtl8xxxu_fill_txdesc_v1,
|
||||
.cck_rssi = rtl8723a_cck_rssi,
|
||||
.led_classdev_brightness_set = rtl8192cu_led_brightness_set,
|
||||
.writeN_block_size = 128,
|
||||
.rx_agg_buf_size = 16000,
|
||||
.tx_desc_size = sizeof(struct rtl8xxxu_txdesc32),
|
||||
@ -621,7 +652,7 @@ struct rtl8xxxu_fileops rtl8192cu_fops = {
|
||||
.trxff_boundary = 0x27ff,
|
||||
.pbp_rx = PBP_PAGE_SIZE_128,
|
||||
.pbp_tx = PBP_PAGE_SIZE_128,
|
||||
.mactable = rtl8xxxu_gen1_mac_init_table,
|
||||
.mactable = rtl8192cu_mac_init_table,
|
||||
.total_page_num = TX_TOTAL_PAGE_NUM,
|
||||
.page_num_hi = TX_PAGE_NUM_HI_PQ,
|
||||
.page_num_lo = TX_PAGE_NUM_LO_PQ,
|
@ -13,24 +13,8 @@
|
||||
* additional 8xxx chips like the 8192cu, 8188cus, etc.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <net/mac80211.h>
|
||||
#include "regs.h"
|
||||
#include "rtl8xxxu.h"
|
||||
#include "rtl8xxxu_regs.h"
|
||||
|
||||
static const struct rtl8xxxu_reg8val rtl8192e_mac_init_table[] = {
|
||||
{0x011, 0xeb}, {0x012, 0x07}, {0x014, 0x75}, {0x303, 0xa7},
|
@ -11,24 +11,8 @@
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <net/mac80211.h>
|
||||
#include "regs.h"
|
||||
#include "rtl8xxxu.h"
|
||||
#include "rtl8xxxu_regs.h"
|
||||
|
||||
static const struct rtl8xxxu_reg8val rtl8192f_mac_init_table[] = {
|
||||
{0x420, 0x00}, {0x422, 0x78}, {0x428, 0x0a}, {0x429, 0x10},
|
@ -11,24 +11,8 @@
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <net/mac80211.h>
|
||||
#include "regs.h"
|
||||
#include "rtl8xxxu.h"
|
||||
#include "rtl8xxxu_regs.h"
|
||||
|
||||
static const struct rtl8xxxu_reg8val rtl8710b_mac_init_table[] = {
|
||||
{0x421, 0x0F}, {0x428, 0x0A}, {0x429, 0x10}, {0x430, 0x00},
|
@ -13,24 +13,8 @@
|
||||
* additional 8xxx chips like the 8192cu, 8188cus, etc.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <net/mac80211.h>
|
||||
#include "regs.h"
|
||||
#include "rtl8xxxu.h"
|
||||
#include "rtl8xxxu_regs.h"
|
||||
|
||||
static struct rtl8xxxu_power_base rtl8723a_power_base = {
|
||||
.reg_0e00 = 0x0a0c0c0c,
|
||||
@ -54,6 +38,31 @@ static struct rtl8xxxu_power_base rtl8723a_power_base = {
|
||||
.reg_0868 = 0x02040608,
|
||||
};
|
||||
|
||||
static const struct rtl8xxxu_reg8val rtl8723au_mac_init_table[] = {
|
||||
{0x420, 0x80}, {0x423, 0x00}, {0x430, 0x00}, {0x431, 0x00},
|
||||
{0x432, 0x00}, {0x433, 0x01}, {0x434, 0x04}, {0x435, 0x05},
|
||||
{0x436, 0x06}, {0x437, 0x07}, {0x438, 0x00}, {0x439, 0x00},
|
||||
{0x43a, 0x00}, {0x43b, 0x01}, {0x43c, 0x04}, {0x43d, 0x05},
|
||||
{0x43e, 0x06}, {0x43f, 0x07}, {0x440, 0x5d}, {0x441, 0x01},
|
||||
{0x442, 0x00}, {0x444, 0x15}, {0x445, 0xf0}, {0x446, 0x0f},
|
||||
{0x447, 0x00}, {0x458, 0x41}, {0x459, 0xa8}, {0x45a, 0x72},
|
||||
{0x45b, 0xb9}, {0x460, 0x66}, {0x461, 0x66}, {0x462, 0x08},
|
||||
{0x463, 0x03}, {0x4c8, 0xff}, {0x4c9, 0x08}, {0x4cc, 0xff},
|
||||
{0x4cd, 0xff}, {0x4ce, 0x01}, {0x500, 0x26}, {0x501, 0xa2},
|
||||
{0x502, 0x2f}, {0x503, 0x00}, {0x504, 0x28}, {0x505, 0xa3},
|
||||
{0x506, 0x5e}, {0x507, 0x00}, {0x508, 0x2b}, {0x509, 0xa4},
|
||||
{0x50a, 0x5e}, {0x50b, 0x00}, {0x50c, 0x4f}, {0x50d, 0xa4},
|
||||
{0x50e, 0x00}, {0x50f, 0x00}, {0x512, 0x1c}, {0x514, 0x0a},
|
||||
{0x515, 0x10}, {0x516, 0x0a}, {0x517, 0x10}, {0x51a, 0x16},
|
||||
{0x524, 0x0f}, {0x525, 0x4f}, {0x546, 0x40}, {0x547, 0x00},
|
||||
{0x550, 0x10}, {0x551, 0x10}, {0x559, 0x02}, {0x55a, 0x02},
|
||||
{0x55d, 0xff}, {0x605, 0x30}, {0x608, 0x0e}, {0x609, 0x2a},
|
||||
{0x652, 0x20}, {0x63c, 0x0a}, {0x63d, 0x0a}, {0x63e, 0x0e},
|
||||
{0x63f, 0x0e}, {0x66e, 0x05}, {0x700, 0x21}, {0x701, 0x43},
|
||||
{0x702, 0x65}, {0x703, 0x87}, {0x708, 0x21}, {0x709, 0x43},
|
||||
{0x70a, 0x65}, {0x70b, 0x87}, {0xffff, 0xff},
|
||||
};
|
||||
|
||||
static const struct rtl8xxxu_rfregval rtl8723au_radioa_1t_init_table[] = {
|
||||
{0x00, 0x00030159}, {0x01, 0x00031284},
|
||||
{0x02, 0x00098000}, {0x03, 0x00039c63},
|
||||
@ -518,7 +527,7 @@ struct rtl8xxxu_fileops rtl8723au_fops = {
|
||||
.trxff_boundary = 0x27ff,
|
||||
.pbp_rx = PBP_PAGE_SIZE_128,
|
||||
.pbp_tx = PBP_PAGE_SIZE_128,
|
||||
.mactable = rtl8xxxu_gen1_mac_init_table,
|
||||
.mactable = rtl8723au_mac_init_table,
|
||||
.total_page_num = TX_TOTAL_PAGE_NUM,
|
||||
.page_num_hi = TX_PAGE_NUM_HI_PQ,
|
||||
.page_num_lo = TX_PAGE_NUM_LO_PQ,
|
@ -13,24 +13,8 @@
|
||||
* additional 8xxx chips like the 8192cu, 8188cus, etc.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <net/mac80211.h>
|
||||
#include "regs.h"
|
||||
#include "rtl8xxxu.h"
|
||||
#include "rtl8xxxu_regs.h"
|
||||
|
||||
static const struct rtl8xxxu_reg8val rtl8723b_mac_init_table[] = {
|
||||
{0x02f, 0x30}, {0x035, 0x00}, {0x039, 0x08}, {0x04e, 0xe0},
|
||||
@ -1701,6 +1685,28 @@ static s8 rtl8723b_cck_rssi(struct rtl8xxxu_priv *priv, struct rtl8723au_phy_sta
|
||||
return rx_pwr_all;
|
||||
}
|
||||
|
||||
static int rtl8723bu_led_brightness_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
struct rtl8xxxu_priv *priv = container_of(led_cdev,
|
||||
struct rtl8xxxu_priv,
|
||||
led_cdev);
|
||||
u8 ledcfg = rtl8xxxu_read8(priv, REG_LEDCFG2);
|
||||
|
||||
ledcfg &= LEDCFG2_DPDT_SELECT;
|
||||
|
||||
if (brightness == LED_OFF)
|
||||
ledcfg |= LEDCFG2_SW_LED_CONTROL | LEDCFG2_SW_LED_DISABLE;
|
||||
else if (brightness == LED_ON)
|
||||
ledcfg |= LEDCFG2_SW_LED_CONTROL;
|
||||
else if (brightness == RTL8XXXU_HW_LED_CONTROL)
|
||||
ledcfg |= LEDCFG2_HW_LED_CONTROL | LEDCFG2_HW_LED_ENABLE;
|
||||
|
||||
rtl8xxxu_write8(priv, REG_LEDCFG2, ledcfg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct rtl8xxxu_fileops rtl8723bu_fops = {
|
||||
.identify_chip = rtl8723bu_identify_chip,
|
||||
.parse_efuse = rtl8723bu_parse_efuse,
|
||||
@ -1731,6 +1737,7 @@ struct rtl8xxxu_fileops rtl8723bu_fops = {
|
||||
.fill_txdesc = rtl8xxxu_fill_txdesc_v2,
|
||||
.set_crystal_cap = rtl8723a_set_crystal_cap,
|
||||
.cck_rssi = rtl8723b_cck_rssi,
|
||||
.led_classdev_brightness_set = rtl8723bu_led_brightness_set,
|
||||
.writeN_block_size = 1024,
|
||||
.tx_desc_size = sizeof(struct rtl8xxxu_txdesc40),
|
||||
.rx_desc_size = sizeof(struct rtl8xxxu_rxdesc24),
|
@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_RTL8XXXU) += rtl8xxxu.o
|
||||
|
||||
rtl8xxxu-y := rtl8xxxu_core.o rtl8xxxu_8192e.o rtl8xxxu_8723b.o \
|
||||
rtl8xxxu_8723a.o rtl8xxxu_8192c.o rtl8xxxu_8188f.o \
|
||||
rtl8xxxu_8188e.o rtl8xxxu_8710b.o rtl8xxxu_8192f.o
|
||||
rtl8xxxu-y := core.o 8192e.o 8723b.o \
|
||||
8723a.o 8192c.o 8188f.o \
|
||||
8188e.o 8710b.o 8192f.o
|
||||
|
@ -13,24 +13,9 @@
|
||||
* additional 8xxx chips like the 8192cu, 8188cus, etc.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <net/mac80211.h>
|
||||
#include "regs.h"
|
||||
#include "rtl8xxxu.h"
|
||||
#include "rtl8xxxu_regs.h"
|
||||
|
||||
#define DRIVER_NAME "rtl8xxxu"
|
||||
|
||||
@ -132,31 +117,6 @@ static struct ieee80211_supported_band rtl8xxxu_supported_band = {
|
||||
.n_bitrates = ARRAY_SIZE(rtl8xxxu_rates),
|
||||
};
|
||||
|
||||
const struct rtl8xxxu_reg8val rtl8xxxu_gen1_mac_init_table[] = {
|
||||
{0x420, 0x80}, {0x423, 0x00}, {0x430, 0x00}, {0x431, 0x00},
|
||||
{0x432, 0x00}, {0x433, 0x01}, {0x434, 0x04}, {0x435, 0x05},
|
||||
{0x436, 0x06}, {0x437, 0x07}, {0x438, 0x00}, {0x439, 0x00},
|
||||
{0x43a, 0x00}, {0x43b, 0x01}, {0x43c, 0x04}, {0x43d, 0x05},
|
||||
{0x43e, 0x06}, {0x43f, 0x07}, {0x440, 0x5d}, {0x441, 0x01},
|
||||
{0x442, 0x00}, {0x444, 0x15}, {0x445, 0xf0}, {0x446, 0x0f},
|
||||
{0x447, 0x00}, {0x458, 0x41}, {0x459, 0xa8}, {0x45a, 0x72},
|
||||
{0x45b, 0xb9}, {0x460, 0x66}, {0x461, 0x66}, {0x462, 0x08},
|
||||
{0x463, 0x03}, {0x4c8, 0xff}, {0x4c9, 0x08}, {0x4cc, 0xff},
|
||||
{0x4cd, 0xff}, {0x4ce, 0x01}, {0x500, 0x26}, {0x501, 0xa2},
|
||||
{0x502, 0x2f}, {0x503, 0x00}, {0x504, 0x28}, {0x505, 0xa3},
|
||||
{0x506, 0x5e}, {0x507, 0x00}, {0x508, 0x2b}, {0x509, 0xa4},
|
||||
{0x50a, 0x5e}, {0x50b, 0x00}, {0x50c, 0x4f}, {0x50d, 0xa4},
|
||||
{0x50e, 0x00}, {0x50f, 0x00}, {0x512, 0x1c}, {0x514, 0x0a},
|
||||
{0x515, 0x10}, {0x516, 0x0a}, {0x517, 0x10}, {0x51a, 0x16},
|
||||
{0x524, 0x0f}, {0x525, 0x4f}, {0x546, 0x40}, {0x547, 0x00},
|
||||
{0x550, 0x10}, {0x551, 0x10}, {0x559, 0x02}, {0x55a, 0x02},
|
||||
{0x55d, 0xff}, {0x605, 0x30}, {0x608, 0x0e}, {0x609, 0x2a},
|
||||
{0x652, 0x20}, {0x63c, 0x0a}, {0x63d, 0x0a}, {0x63e, 0x0e},
|
||||
{0x63f, 0x0e}, {0x66e, 0x05}, {0x700, 0x21}, {0x701, 0x43},
|
||||
{0x702, 0x65}, {0x703, 0x87}, {0x708, 0x21}, {0x709, 0x43},
|
||||
{0x70a, 0x65}, {0x70b, 0x87}, {0xffff, 0xff},
|
||||
};
|
||||
|
||||
static const struct rtl8xxxu_reg32val rtl8723a_phy_1t_init_table[] = {
|
||||
{0x800, 0x80040000}, {0x804, 0x00000003},
|
||||
{0x808, 0x0000fc00}, {0x80c, 0x0000000a},
|
||||
@ -1505,13 +1465,13 @@ rtl8xxxu_gen1_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40)
|
||||
u8 cck[RTL8723A_MAX_RF_PATHS], ofdm[RTL8723A_MAX_RF_PATHS];
|
||||
u8 ofdmbase[RTL8723A_MAX_RF_PATHS], mcsbase[RTL8723A_MAX_RF_PATHS];
|
||||
u32 val32, ofdm_a, ofdm_b, mcs_a, mcs_b;
|
||||
u8 val8;
|
||||
u8 val8, base;
|
||||
int group, i;
|
||||
|
||||
group = rtl8xxxu_gen1_channel_to_group(channel);
|
||||
|
||||
cck[0] = priv->cck_tx_power_index_A[group] - 1;
|
||||
cck[1] = priv->cck_tx_power_index_B[group] - 1;
|
||||
cck[0] = priv->cck_tx_power_index_A[group];
|
||||
cck[1] = priv->cck_tx_power_index_B[group];
|
||||
|
||||
if (priv->hi_pa) {
|
||||
if (cck[0] > 0x20)
|
||||
@ -1522,10 +1482,6 @@ rtl8xxxu_gen1_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40)
|
||||
|
||||
ofdm[0] = priv->ht40_1s_tx_power_index_A[group];
|
||||
ofdm[1] = priv->ht40_1s_tx_power_index_B[group];
|
||||
if (ofdm[0])
|
||||
ofdm[0] -= 1;
|
||||
if (ofdm[1])
|
||||
ofdm[1] -= 1;
|
||||
|
||||
ofdmbase[0] = ofdm[0] + priv->ofdm_tx_power_index_diff[group].a;
|
||||
ofdmbase[1] = ofdm[1] + priv->ofdm_tx_power_index_diff[group].b;
|
||||
@ -1614,20 +1570,19 @@ rtl8xxxu_gen1_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40)
|
||||
|
||||
rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS15_MCS12,
|
||||
mcs_a + power_base->reg_0e1c);
|
||||
val8 = u32_get_bits(mcs_a + power_base->reg_0e1c, 0xff000000);
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (i != 2)
|
||||
val8 = (mcsbase[0] > 8) ? (mcsbase[0] - 8) : 0;
|
||||
else
|
||||
val8 = (mcsbase[0] > 6) ? (mcsbase[0] - 6) : 0;
|
||||
base = i != 2 ? 8 : 6;
|
||||
val8 = max_t(int, val8 - base, 0);
|
||||
rtl8xxxu_write8(priv, REG_OFDM0_XC_TX_IQ_IMBALANCE + i, val8);
|
||||
}
|
||||
|
||||
rtl8xxxu_write32(priv, REG_TX_AGC_B_MCS15_MCS12,
|
||||
mcs_b + power_base->reg_0868);
|
||||
val8 = u32_get_bits(mcs_b + power_base->reg_0868, 0xff000000);
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (i != 2)
|
||||
val8 = (mcsbase[1] > 8) ? (mcsbase[1] - 8) : 0;
|
||||
else
|
||||
val8 = (mcsbase[1] > 6) ? (mcsbase[1] - 6) : 0;
|
||||
base = i != 2 ? 8 : 6;
|
||||
val8 = max_t(int, val8 - base, 0);
|
||||
rtl8xxxu_write8(priv, REG_OFDM0_XD_TX_IQ_IMBALANCE + i, val8);
|
||||
}
|
||||
}
|
||||
@ -4385,7 +4340,7 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
|
||||
|
||||
/* Let the 8051 take control of antenna setting */
|
||||
if (priv->rtl_chip != RTL8192E && priv->rtl_chip != RTL8188F &&
|
||||
priv->rtl_chip != RTL8710B) {
|
||||
priv->rtl_chip != RTL8710B && priv->rtl_chip != RTL8192C) {
|
||||
val8 = rtl8xxxu_read8(priv, REG_LEDCFG2);
|
||||
val8 |= LEDCFG2_DPDT_SELECT;
|
||||
rtl8xxxu_write8(priv, REG_LEDCFG2, val8);
|
||||
@ -6474,8 +6429,7 @@ int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb)
|
||||
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||
|
||||
if (!rx_desc->swdec &&
|
||||
!(_ieee80211_is_robust_mgmt_frame(hdr) &&
|
||||
ieee80211_has_protected(hdr->frame_control)))
|
||||
rx_desc->security != RX_DESC_ENC_NONE)
|
||||
rx_status->flag |= RX_FLAG_DECRYPTED;
|
||||
if (rx_desc->crc32)
|
||||
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||
@ -6581,8 +6535,7 @@ int rtl8xxxu_parse_rxdesc24(struct rtl8xxxu_priv *priv, struct sk_buff *skb)
|
||||
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||
|
||||
if (!rx_desc->swdec &&
|
||||
!(_ieee80211_is_robust_mgmt_frame(hdr) &&
|
||||
ieee80211_has_protected(hdr->frame_control)))
|
||||
rx_desc->security != RX_DESC_ENC_NONE)
|
||||
rx_status->flag |= RX_FLAG_DECRYPTED;
|
||||
if (rx_desc->crc32)
|
||||
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
|
@ -5,8 +5,9 @@
|
||||
* Register definitions taken from original Realtek rtl8723au driver
|
||||
*/
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
#include <linux/average.h>
|
||||
#include <linux/usb.h>
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#define RTL8XXXU_DEBUG_REG_WRITE 0x01
|
||||
#define RTL8XXXU_DEBUG_REG_READ 0x02
|
||||
@ -122,6 +123,15 @@ enum rtl8xxxu_rx_type {
|
||||
RX_TYPE_ERROR = -1
|
||||
};
|
||||
|
||||
enum rtl8xxxu_rx_desc_enc {
|
||||
RX_DESC_ENC_NONE = 0,
|
||||
RX_DESC_ENC_WEP40 = 1,
|
||||
RX_DESC_ENC_TKIP_WO_MIC = 2,
|
||||
RX_DESC_ENC_TKIP_MIC = 3,
|
||||
RX_DESC_ENC_AES = 4,
|
||||
RX_DESC_ENC_WEP104 = 5,
|
||||
};
|
||||
|
||||
struct rtl8xxxu_rxdesc16 {
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
u32 pktlen:14;
|
||||
@ -2022,7 +2032,6 @@ struct rtl8xxxu_fileops {
|
||||
|
||||
extern int rtl8xxxu_debug;
|
||||
|
||||
extern const struct rtl8xxxu_reg8val rtl8xxxu_gen1_mac_init_table[];
|
||||
extern const u32 rtl8xxxu_iqk_phy_iq_bb_reg[];
|
||||
u8 rtl8xxxu_read8(struct rtl8xxxu_priv *priv, u16 addr);
|
||||
u16 rtl8xxxu_read16(struct rtl8xxxu_priv *priv, u16 addr);
|
||||
|
@ -37,6 +37,7 @@ config RTL8192SE
|
||||
config RTL8192DE
|
||||
tristate "Realtek RTL8192DE/RTL8188DE PCIe Wireless Network Adapter"
|
||||
depends on PCI
|
||||
select RTL8192D_COMMON
|
||||
select RTLWIFI
|
||||
select RTLWIFI_PCI
|
||||
help
|
||||
@ -142,6 +143,9 @@ config RTL8192C_COMMON
|
||||
depends on RTL8192CE || RTL8192CU
|
||||
default y
|
||||
|
||||
config RTL8192D_COMMON
|
||||
tristate
|
||||
|
||||
config RTL8723_COMMON
|
||||
tristate
|
||||
depends on RTL8723AE || RTL8723BE
|
||||
|
@ -23,6 +23,7 @@ obj-$(CONFIG_RTL8192C_COMMON) += rtl8192c/
|
||||
obj-$(CONFIG_RTL8192CE) += rtl8192ce/
|
||||
obj-$(CONFIG_RTL8192CU) += rtl8192cu/
|
||||
obj-$(CONFIG_RTL8192SE) += rtl8192se/
|
||||
obj-$(CONFIG_RTL8192D_COMMON) += rtl8192d/
|
||||
obj-$(CONFIG_RTL8192DE) += rtl8192de/
|
||||
obj-$(CONFIG_RTL8723AE) += rtl8723ae/
|
||||
obj-$(CONFIG_RTL8723BE) += rtl8723be/
|
||||
|
@ -18,7 +18,8 @@ void rtl_cam_reset_sec_info(struct ieee80211_hw *hw)
|
||||
}
|
||||
|
||||
static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
|
||||
u8 *mac_addr, u8 *key_cont_128, u16 us_config)
|
||||
const u8 *mac_addr, u8 *key_cont_128,
|
||||
u16 us_config)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
@ -94,7 +95,7 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
|
||||
"after set key, usconfig:%x\n", us_config);
|
||||
}
|
||||
|
||||
u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
|
||||
u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, const u8 *mac_addr,
|
||||
u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg,
|
||||
u32 ul_default_key, u8 *key_content)
|
||||
{
|
||||
|
@ -14,9 +14,9 @@
|
||||
#define CAM_CONFIG_NO_USEDK 0
|
||||
|
||||
void rtl_cam_reset_all_entry(struct ieee80211_hw *hw);
|
||||
u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
|
||||
u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg,
|
||||
u32 ul_default_key, u8 *key_content);
|
||||
u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, const u8 *mac_addr,
|
||||
u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg,
|
||||
u32 ul_default_key, u8 *key_content);
|
||||
int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
|
||||
u32 ul_key_id);
|
||||
void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index);
|
||||
|
@ -1211,7 +1211,7 @@ static u8 efuse_calculate_word_cnts(u8 word_en)
|
||||
}
|
||||
|
||||
int rtl_get_hwinfo(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv,
|
||||
int max_size, u8 *hwinfo, int *params)
|
||||
int max_size, u8 *hwinfo, const int *params)
|
||||
{
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
|
||||
|
@ -89,7 +89,7 @@ void efuse_force_write_vendor_id(struct ieee80211_hw *hw);
|
||||
void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx);
|
||||
void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate);
|
||||
int rtl_get_hwinfo(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv,
|
||||
int max_size, u8 *hwinfo, int *params);
|
||||
int max_size, u8 *hwinfo, const int *params);
|
||||
void rtl_fill_dummy(u8 *pfwbuf, u32 *pfwlen);
|
||||
void rtl_fw_page_write(struct ieee80211_hw *hw, u32 page, u8 *buffer,
|
||||
u32 size);
|
||||
|
11
drivers/net/wireless/realtek/rtlwifi/rtl8192d/Makefile
Normal file
11
drivers/net/wireless/realtek/rtlwifi/rtl8192d/Makefile
Normal file
@ -0,0 +1,11 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
rtl8192d-common-objs := \
|
||||
dm_common.o \
|
||||
fw_common.o \
|
||||
hw_common.o \
|
||||
main.o \
|
||||
phy_common.o \
|
||||
rf_common.o \
|
||||
trx_common.o
|
||||
|
||||
obj-$(CONFIG_RTL8192D_COMMON) += rtl8192d-common.o
|
1061
drivers/net/wireless/realtek/rtlwifi/rtl8192d/dm_common.c
Normal file
1061
drivers/net/wireless/realtek/rtlwifi/rtl8192d/dm_common.c
Normal file
File diff suppressed because it is too large
Load Diff
79
drivers/net/wireless/realtek/rtlwifi/rtl8192d/dm_common.h
Normal file
79
drivers/net/wireless/realtek/rtlwifi/rtl8192d/dm_common.h
Normal file
@ -0,0 +1,79 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright(c) 2009-2012 Realtek Corporation.*/
|
||||
|
||||
#ifndef __RTL92D_DM_COMMON_H__
|
||||
#define __RTL92D_DM_COMMON_H__
|
||||
|
||||
#define HAL_DM_DIG_DISABLE BIT(0)
|
||||
#define HAL_DM_HIPWR_DISABLE BIT(1)
|
||||
|
||||
#define OFDM_TABLE_LENGTH 37
|
||||
#define OFDM_TABLE_SIZE_92D 43
|
||||
#define CCK_TABLE_LENGTH 33
|
||||
|
||||
#define CCK_TABLE_SIZE 33
|
||||
|
||||
#define BW_AUTO_SWITCH_HIGH_LOW 25
|
||||
#define BW_AUTO_SWITCH_LOW_HIGH 30
|
||||
|
||||
#define DM_DIG_FA_UPPER 0x32
|
||||
#define DM_DIG_FA_LOWER 0x20
|
||||
#define DM_DIG_FA_TH0 0x100
|
||||
#define DM_DIG_FA_TH1 0x400
|
||||
#define DM_DIG_FA_TH2 0x600
|
||||
|
||||
#define RXPATHSELECTION_SS_TH_LOW 30
|
||||
#define RXPATHSELECTION_DIFF_TH 18
|
||||
|
||||
#define DM_RATR_STA_INIT 0
|
||||
#define DM_RATR_STA_HIGH 1
|
||||
#define DM_RATR_STA_MIDDLE 2
|
||||
#define DM_RATR_STA_LOW 3
|
||||
|
||||
#define CTS2SELF_THVAL 30
|
||||
#define REGC38_TH 20
|
||||
|
||||
#define WAIOTTHVAL 25
|
||||
|
||||
#define TXHIGHPWRLEVEL_NORMAL 0
|
||||
#define TXHIGHPWRLEVEL_LEVEL1 1
|
||||
#define TXHIGHPWRLEVEL_LEVEL2 2
|
||||
#define TXHIGHPWRLEVEL_BT1 3
|
||||
#define TXHIGHPWRLEVEL_BT2 4
|
||||
|
||||
#define DM_TYPE_BYFW 0
|
||||
#define DM_TYPE_BYDRIVER 1
|
||||
|
||||
#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
|
||||
#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
|
||||
#define INDEX_MAPPING_NUM 13
|
||||
|
||||
enum dm_1r_cca {
|
||||
CCA_1R = 0,
|
||||
CCA_2R = 1,
|
||||
CCA_MAX = 2,
|
||||
};
|
||||
|
||||
enum dm_rf {
|
||||
RF_SAVE = 0,
|
||||
RF_NORMAL = 1,
|
||||
RF_MAX = 2,
|
||||
};
|
||||
|
||||
enum dm_sw_ant_switch {
|
||||
ANS_ANTENNA_B = 1,
|
||||
ANS_ANTENNA_A = 2,
|
||||
ANS_ANTENNA_MAX = 3,
|
||||
};
|
||||
|
||||
void rtl92d_dm_initialize_txpower_tracking(struct ieee80211_hw *hw);
|
||||
void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw);
|
||||
void rtl92d_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw);
|
||||
void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw);
|
||||
void rtl92d_dm_write_dig(struct ieee80211_hw *hw);
|
||||
void rtl92d_dm_dig(struct ieee80211_hw *hw);
|
||||
void rtl92d_dm_init_edca_turbo(struct ieee80211_hw *hw);
|
||||
void rtl92d_dm_check_edca_turbo(struct ieee80211_hw *hw);
|
||||
void rtl92d_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);
|
||||
|
||||
#endif
|
370
drivers/net/wireless/realtek/rtlwifi/rtl8192d/fw_common.c
Normal file
370
drivers/net/wireless/realtek/rtlwifi/rtl8192d/fw_common.c
Normal file
@ -0,0 +1,370 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright(c) 2009-2012 Realtek Corporation.*/
|
||||
|
||||
#include "../wifi.h"
|
||||
#include "../pci.h"
|
||||
#include "../base.h"
|
||||
#include "../efuse.h"
|
||||
#include "def.h"
|
||||
#include "reg.h"
|
||||
#include "fw_common.h"
|
||||
|
||||
bool rtl92d_is_fw_downloaded(struct rtl_priv *rtlpriv)
|
||||
{
|
||||
return !!(rtl_read_dword(rtlpriv, REG_MCUFWDL) & MCUFWDL_RDY);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_is_fw_downloaded);
|
||||
|
||||
void rtl92d_enable_fw_download(struct ieee80211_hw *hw, bool enable)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 tmp;
|
||||
|
||||
if (enable) {
|
||||
tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
|
||||
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04);
|
||||
tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
|
||||
rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
|
||||
tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
|
||||
rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
|
||||
} else {
|
||||
tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
|
||||
rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
|
||||
/* Reserved for fw extension.
|
||||
* 0x81[7] is used for mac0 status ,
|
||||
* so don't write this reg here
|
||||
* rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);
|
||||
*/
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_enable_fw_download);
|
||||
|
||||
void rtl92d_write_fw(struct ieee80211_hw *hw,
|
||||
enum version_8192d version, u8 *buffer, u32 size)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
u8 *bufferptr = buffer;
|
||||
u32 pagenums, remainsize;
|
||||
u32 page, offset;
|
||||
|
||||
rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size);
|
||||
|
||||
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE)
|
||||
rtl_fill_dummy(bufferptr, &size);
|
||||
|
||||
pagenums = size / FW_8192D_PAGE_SIZE;
|
||||
remainsize = size % FW_8192D_PAGE_SIZE;
|
||||
|
||||
if (pagenums > 8)
|
||||
pr_err("Page numbers should not greater then 8\n");
|
||||
|
||||
for (page = 0; page < pagenums; page++) {
|
||||
offset = page * FW_8192D_PAGE_SIZE;
|
||||
rtl_fw_page_write(hw, page, (bufferptr + offset),
|
||||
FW_8192D_PAGE_SIZE);
|
||||
}
|
||||
|
||||
if (remainsize) {
|
||||
offset = pagenums * FW_8192D_PAGE_SIZE;
|
||||
page = pagenums;
|
||||
rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_write_fw);
|
||||
|
||||
int rtl92d_fw_free_to_go(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u32 counter = 0;
|
||||
u32 value32;
|
||||
|
||||
do {
|
||||
value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
|
||||
} while ((counter++ < FW_8192D_POLLING_TIMEOUT_COUNT) &&
|
||||
(!(value32 & FWDL_CHKSUM_RPT)));
|
||||
|
||||
if (counter >= FW_8192D_POLLING_TIMEOUT_COUNT) {
|
||||
pr_err("chksum report fail! REG_MCUFWDL:0x%08x\n",
|
||||
value32);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
|
||||
value32 |= MCUFWDL_RDY;
|
||||
rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_fw_free_to_go);
|
||||
|
||||
#define RTL_USB_DELAY_FACTOR 60
|
||||
|
||||
void rtl92d_firmware_selfreset(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
|
||||
u8 u1b_tmp;
|
||||
u8 delay = 100;
|
||||
|
||||
if (rtlhal->interface == INTF_USB) {
|
||||
delay *= RTL_USB_DELAY_FACTOR;
|
||||
|
||||
rtl_write_byte(rtlpriv, REG_FSIMR, 0);
|
||||
|
||||
/* We need to disable other HRCV INT to influence 8051 reset. */
|
||||
rtl_write_byte(rtlpriv, REG_FWIMR, 0x20);
|
||||
|
||||
/* Close mask to prevent incorrect FW write operation. */
|
||||
rtl_write_byte(rtlpriv, REG_FTIMR, 0);
|
||||
}
|
||||
|
||||
/* Set (REG_HMETFR + 3) to 0x20 is reset 8051 */
|
||||
rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
|
||||
|
||||
u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
|
||||
|
||||
while (u1b_tmp & (FEN_CPUEN >> 8)) {
|
||||
delay--;
|
||||
if (delay == 0)
|
||||
break;
|
||||
udelay(50);
|
||||
u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
|
||||
}
|
||||
|
||||
if (rtlhal->interface == INTF_USB) {
|
||||
if ((u1b_tmp & (FEN_CPUEN >> 8)) && delay == 0)
|
||||
rtl_write_byte(rtlpriv, REG_FWIMR, 0);
|
||||
}
|
||||
|
||||
WARN_ONCE((delay <= 0), "rtl8192de: 8051 reset failed!\n");
|
||||
rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
|
||||
"=====> 8051 reset success (%d)\n", delay);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_firmware_selfreset);
|
||||
|
||||
int rtl92d_fw_init(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
u32 counter;
|
||||
|
||||
rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, "FW already have download\n");
|
||||
/* polling for FW ready */
|
||||
counter = 0;
|
||||
do {
|
||||
if (rtlhal->interfaceindex == 0) {
|
||||
if (rtl_read_byte(rtlpriv, FW_MAC0_READY) &
|
||||
MAC0_READY) {
|
||||
rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
|
||||
"Polling FW ready success!! REG_MCUFWDL: 0x%x\n",
|
||||
rtl_read_byte(rtlpriv,
|
||||
FW_MAC0_READY));
|
||||
return 0;
|
||||
}
|
||||
udelay(5);
|
||||
} else {
|
||||
if (rtl_read_byte(rtlpriv, FW_MAC1_READY) &
|
||||
MAC1_READY) {
|
||||
rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
|
||||
"Polling FW ready success!! REG_MCUFWDL: 0x%x\n",
|
||||
rtl_read_byte(rtlpriv,
|
||||
FW_MAC1_READY));
|
||||
return 0;
|
||||
}
|
||||
udelay(5);
|
||||
}
|
||||
} while (counter++ < POLLING_READY_TIMEOUT_COUNT);
|
||||
|
||||
if (rtlhal->interfaceindex == 0) {
|
||||
rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
|
||||
"Polling FW ready fail!! MAC0 FW init not ready: 0x%x\n",
|
||||
rtl_read_byte(rtlpriv, FW_MAC0_READY));
|
||||
} else {
|
||||
rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
|
||||
"Polling FW ready fail!! MAC1 FW init not ready: 0x%x\n",
|
||||
rtl_read_byte(rtlpriv, FW_MAC1_READY));
|
||||
}
|
||||
rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
|
||||
"Polling FW ready fail!! REG_MCUFWDL:0x%08x\n",
|
||||
rtl_read_dword(rtlpriv, REG_MCUFWDL));
|
||||
return -1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_fw_init);
|
||||
|
||||
static bool _rtl92d_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 val_hmetfr;
|
||||
bool result = false;
|
||||
|
||||
val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
|
||||
if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
|
||||
result = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw,
|
||||
u8 element_id, u32 cmd_len, u8 *cmdbuffer)
|
||||
{
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 boxcontent[4], boxextcontent[2];
|
||||
u16 box_reg = 0, box_extreg = 0;
|
||||
u8 wait_writeh2c_limmit = 100;
|
||||
bool bwrite_success = false;
|
||||
u8 wait_h2c_limmit = 100;
|
||||
u32 h2c_waitcounter = 0;
|
||||
bool isfw_read = false;
|
||||
unsigned long flag;
|
||||
u8 u1b_tmp;
|
||||
u8 boxnum;
|
||||
u8 idx;
|
||||
|
||||
if (ppsc->rfpwr_state == ERFOFF || ppsc->inactive_pwrstate == ERFOFF) {
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
"Return as RF is off!!!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
|
||||
|
||||
while (true) {
|
||||
spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
|
||||
if (rtlhal->h2c_setinprogress) {
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
"H2C set in progress! Wait to set..element_id(%d)\n",
|
||||
element_id);
|
||||
|
||||
while (rtlhal->h2c_setinprogress) {
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
|
||||
flag);
|
||||
h2c_waitcounter++;
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
"Wait 100 us (%d times)...\n",
|
||||
h2c_waitcounter);
|
||||
udelay(100);
|
||||
|
||||
if (h2c_waitcounter > 1000)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
|
||||
flag);
|
||||
}
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
|
||||
} else {
|
||||
rtlhal->h2c_setinprogress = true;
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (!bwrite_success) {
|
||||
wait_writeh2c_limmit--;
|
||||
if (wait_writeh2c_limmit == 0) {
|
||||
pr_err("Write H2C fail because no trigger for FW INT!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
boxnum = rtlhal->last_hmeboxnum;
|
||||
if (boxnum > 3) {
|
||||
pr_err("boxnum %#x too big\n", boxnum);
|
||||
break;
|
||||
}
|
||||
|
||||
box_reg = REG_HMEBOX_0 + boxnum * SIZE_OF_REG_HMEBOX;
|
||||
box_extreg = REG_HMEBOX_EXT_0 + boxnum * SIZE_OF_REG_HMEBOX_EXT;
|
||||
|
||||
isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
|
||||
while (!isfw_read) {
|
||||
wait_h2c_limmit--;
|
||||
if (wait_h2c_limmit == 0) {
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
"Waiting too long for FW read clear HMEBox(%d)!\n",
|
||||
boxnum);
|
||||
break;
|
||||
}
|
||||
|
||||
udelay(10);
|
||||
|
||||
isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
|
||||
u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
"Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n",
|
||||
boxnum, u1b_tmp);
|
||||
}
|
||||
|
||||
if (!isfw_read) {
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
"Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
|
||||
boxnum);
|
||||
break;
|
||||
}
|
||||
|
||||
memset(boxcontent, 0, sizeof(boxcontent));
|
||||
memset(boxextcontent, 0, sizeof(boxextcontent));
|
||||
boxcontent[0] = element_id;
|
||||
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
"Write element_id box_reg(%4x) = %2x\n",
|
||||
box_reg, element_id);
|
||||
|
||||
switch (cmd_len) {
|
||||
case 1 ... 3:
|
||||
/* BOX: | ID | A0 | A1 | A2 |
|
||||
* BOX_EXT: --- N/A ------
|
||||
*/
|
||||
boxcontent[0] &= ~BIT(7);
|
||||
memcpy(boxcontent + 1, cmdbuffer, cmd_len);
|
||||
|
||||
for (idx = 0; idx < 4; idx++)
|
||||
rtl_write_byte(rtlpriv, box_reg + idx,
|
||||
boxcontent[idx]);
|
||||
break;
|
||||
case 4 ... 5:
|
||||
/* * ID ext = ID | BIT(7)
|
||||
* BOX: | ID ext | A2 | A3 | A4 |
|
||||
* BOX_EXT: | A0 | A1 |
|
||||
*/
|
||||
boxcontent[0] |= BIT(7);
|
||||
memcpy(boxextcontent, cmdbuffer, 2);
|
||||
memcpy(boxcontent + 1, cmdbuffer + 2, cmd_len - 2);
|
||||
|
||||
for (idx = 0; idx < 2; idx++)
|
||||
rtl_write_byte(rtlpriv, box_extreg + idx,
|
||||
boxextcontent[idx]);
|
||||
|
||||
for (idx = 0; idx < 4; idx++)
|
||||
rtl_write_byte(rtlpriv, box_reg + idx,
|
||||
boxcontent[idx]);
|
||||
break;
|
||||
default:
|
||||
pr_err("switch case %#x not processed\n", cmd_len);
|
||||
break;
|
||||
}
|
||||
|
||||
bwrite_success = true;
|
||||
rtlhal->last_hmeboxnum = boxnum + 1;
|
||||
if (rtlhal->last_hmeboxnum == 4)
|
||||
rtlhal->last_hmeboxnum = 0;
|
||||
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
"pHalData->last_hmeboxnum = %d\n",
|
||||
rtlhal->last_hmeboxnum);
|
||||
}
|
||||
spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
|
||||
rtlhal->h2c_setinprogress = false;
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_fill_h2c_cmd);
|
||||
|
||||
void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
|
||||
{
|
||||
u8 u1_joinbssrpt_parm[1] = {0};
|
||||
|
||||
u1_joinbssrpt_parm[0] = mstatus;
|
||||
rtl92d_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_set_fw_joinbss_report_cmd);
|
49
drivers/net/wireless/realtek/rtlwifi/rtl8192d/fw_common.h
Normal file
49
drivers/net/wireless/realtek/rtlwifi/rtl8192d/fw_common.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright(c) 2009-2012 Realtek Corporation.*/
|
||||
|
||||
#ifndef __RTL92D_FW_COMMON_H__
|
||||
#define __RTL92D_FW_COMMON_H__
|
||||
|
||||
#define FW_8192D_START_ADDRESS 0x1000
|
||||
#define FW_8192D_PAGE_SIZE 4096
|
||||
#define FW_8192D_POLLING_TIMEOUT_COUNT 1000
|
||||
|
||||
#define IS_FW_HEADER_EXIST(_pfwhdr) \
|
||||
((GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFF0) == 0x92C0 || \
|
||||
(GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFF0) == 0x88C0 || \
|
||||
(GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D0 || \
|
||||
(GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D1 || \
|
||||
(GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D2 || \
|
||||
(GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D3)
|
||||
|
||||
/* Firmware Header(8-byte alinment required) */
|
||||
/* --- LONG WORD 0 ---- */
|
||||
#define GET_FIRMWARE_HDR_SIGNATURE(__fwhdr) \
|
||||
le32_get_bits(*(__le32 *)__fwhdr, GENMASK(15, 0))
|
||||
#define GET_FIRMWARE_HDR_VERSION(__fwhdr) \
|
||||
le32_get_bits(*(__le32 *)((__fwhdr) + 4), GENMASK(15, 0))
|
||||
#define GET_FIRMWARE_HDR_SUB_VER(__fwhdr) \
|
||||
le32_get_bits(*(__le32 *)((__fwhdr) + 4), GENMASK(23, 16))
|
||||
|
||||
#define RAID_MASK GENMASK(31, 28)
|
||||
#define RATE_MASK_MASK GENMASK(27, 0)
|
||||
#define SHORT_GI_MASK BIT(5)
|
||||
#define MACID_MASK GENMASK(4, 0)
|
||||
|
||||
struct rtl92d_rate_mask_h2c {
|
||||
__le32 rate_mask_and_raid;
|
||||
u8 macid_and_short_gi;
|
||||
} __packed;
|
||||
|
||||
bool rtl92d_is_fw_downloaded(struct rtl_priv *rtlpriv);
|
||||
void rtl92d_enable_fw_download(struct ieee80211_hw *hw, bool enable);
|
||||
void rtl92d_write_fw(struct ieee80211_hw *hw,
|
||||
enum version_8192d version, u8 *buffer, u32 size);
|
||||
int rtl92d_fw_free_to_go(struct ieee80211_hw *hw);
|
||||
void rtl92d_firmware_selfreset(struct ieee80211_hw *hw);
|
||||
int rtl92d_fw_init(struct ieee80211_hw *hw);
|
||||
void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
|
||||
u32 cmd_len, u8 *p_cmdbuffer);
|
||||
void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
|
||||
|
||||
#endif
|
1225
drivers/net/wireless/realtek/rtlwifi/rtl8192d/hw_common.c
Normal file
1225
drivers/net/wireless/realtek/rtlwifi/rtl8192d/hw_common.c
Normal file
File diff suppressed because it is too large
Load Diff
24
drivers/net/wireless/realtek/rtlwifi/rtl8192d/hw_common.h
Normal file
24
drivers/net/wireless/realtek/rtlwifi/rtl8192d/hw_common.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright(c) 2009-2012 Realtek Corporation.*/
|
||||
|
||||
#ifndef __RTL92D_HW_COMMON_H__
|
||||
#define __RTL92D_HW_COMMON_H__
|
||||
|
||||
void rtl92de_stop_tx_beacon(struct ieee80211_hw *hw);
|
||||
void rtl92de_resume_tx_beacon(struct ieee80211_hw *hw);
|
||||
void rtl92d_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
|
||||
void rtl92d_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
|
||||
bool rtl92de_llt_write(struct ieee80211_hw *hw, u32 address, u32 data);
|
||||
void rtl92de_enable_hw_security_config(struct ieee80211_hw *hw);
|
||||
void rtl92de_set_qos(struct ieee80211_hw *hw, int aci);
|
||||
void rtl92de_read_eeprom_info(struct ieee80211_hw *hw);
|
||||
void rtl92de_update_hal_rate_tbl(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta,
|
||||
u8 rssi_level, bool update_bw);
|
||||
void rtl92de_update_channel_access_setting(struct ieee80211_hw *hw);
|
||||
bool rtl92de_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
|
||||
void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index,
|
||||
u8 *p_macaddr, bool is_group, u8 enc_algo,
|
||||
bool is_wepkey, bool clear_all);
|
||||
|
||||
#endif
|
9
drivers/net/wireless/realtek/rtlwifi/rtl8192d/main.c
Normal file
9
drivers/net/wireless/realtek/rtlwifi/rtl8192d/main.c
Normal file
@ -0,0 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright(c) 2009-2012 Realtek Corporation.*/
|
||||
|
||||
#include "../wifi.h"
|
||||
#include <linux/module.h>
|
||||
|
||||
MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Realtek 8192D 802.11n common routines");
|
856
drivers/net/wireless/realtek/rtlwifi/rtl8192d/phy_common.c
Normal file
856
drivers/net/wireless/realtek/rtlwifi/rtl8192d/phy_common.c
Normal file
@ -0,0 +1,856 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright(c) 2009-2012 Realtek Corporation.*/
|
||||
|
||||
#include "../wifi.h"
|
||||
#include "../core.h"
|
||||
#include "def.h"
|
||||
#include "reg.h"
|
||||
#include "dm_common.h"
|
||||
#include "phy_common.h"
|
||||
#include "rf_common.h"
|
||||
|
||||
static const u8 channel_all[59] = {
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
|
||||
60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
|
||||
114, 116, 118, 120, 122, 124, 126, 128, 130,
|
||||
132, 134, 136, 138, 140, 149, 151, 153, 155,
|
||||
157, 159, 161, 163, 165
|
||||
};
|
||||
|
||||
static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw,
|
||||
enum radio_path rfpath, u32 offset)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
|
||||
u32 newoffset;
|
||||
u32 tmplong, tmplong2;
|
||||
u8 rfpi_enable = 0;
|
||||
u32 retvalue;
|
||||
|
||||
newoffset = offset;
|
||||
tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
|
||||
if (rfpath == RF90_PATH_A)
|
||||
tmplong2 = tmplong;
|
||||
else
|
||||
tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
|
||||
tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
|
||||
(newoffset << 23) | BLSSIREADEDGE;
|
||||
rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
|
||||
tmplong & (~BLSSIREADEDGE));
|
||||
udelay(10);
|
||||
rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
|
||||
udelay(100);
|
||||
rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
|
||||
tmplong | BLSSIREADEDGE);
|
||||
udelay(10);
|
||||
if (rfpath == RF90_PATH_A)
|
||||
rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
|
||||
BIT(8));
|
||||
else if (rfpath == RF90_PATH_B)
|
||||
rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
|
||||
BIT(8));
|
||||
if (rfpi_enable)
|
||||
retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi,
|
||||
BLSSIREADBACKDATA);
|
||||
else
|
||||
retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb,
|
||||
BLSSIREADBACKDATA);
|
||||
rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x] = 0x%x\n",
|
||||
rfpath, pphyreg->rf_rb, retvalue);
|
||||
return retvalue;
|
||||
}
|
||||
|
||||
static void _rtl92d_phy_rf_serial_write(struct ieee80211_hw *hw,
|
||||
enum radio_path rfpath,
|
||||
u32 offset, u32 data)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
|
||||
u32 data_and_addr;
|
||||
u32 newoffset;
|
||||
|
||||
newoffset = offset;
|
||||
/* T65 RF */
|
||||
data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
|
||||
rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
|
||||
rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n",
|
||||
rfpath, pphyreg->rf3wire_offset, data_and_addr);
|
||||
}
|
||||
|
||||
u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
|
||||
u32 regaddr, u32 bitmask)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u32 original_value, readback_value, bitshift;
|
||||
|
||||
rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
|
||||
"regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
|
||||
regaddr, rfpath, bitmask);
|
||||
rtl92d_pci_lock(rtlpriv);
|
||||
original_value = _rtl92d_phy_rf_serial_read(hw, rfpath, regaddr);
|
||||
bitshift = calculate_bit_shift(bitmask);
|
||||
readback_value = (original_value & bitmask) >> bitshift;
|
||||
rtl92d_pci_unlock(rtlpriv);
|
||||
rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
|
||||
"regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
|
||||
regaddr, rfpath, bitmask, original_value);
|
||||
return readback_value;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_phy_query_rf_reg);
|
||||
|
||||
void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
|
||||
u32 regaddr, u32 bitmask, u32 data)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
u32 original_value, bitshift;
|
||||
|
||||
rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
|
||||
"regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
|
||||
regaddr, bitmask, data, rfpath);
|
||||
if (bitmask == 0)
|
||||
return;
|
||||
rtl92d_pci_lock(rtlpriv);
|
||||
if (rtlphy->rf_mode != RF_OP_BY_FW) {
|
||||
if (bitmask != RFREG_OFFSET_MASK) {
|
||||
original_value = _rtl92d_phy_rf_serial_read(hw,
|
||||
rfpath,
|
||||
regaddr);
|
||||
bitshift = calculate_bit_shift(bitmask);
|
||||
data = ((original_value & (~bitmask)) |
|
||||
(data << bitshift));
|
||||
}
|
||||
_rtl92d_phy_rf_serial_write(hw, rfpath, regaddr, data);
|
||||
}
|
||||
rtl92d_pci_unlock(rtlpriv);
|
||||
rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
|
||||
"regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
|
||||
regaddr, bitmask, data, rfpath);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_phy_set_rf_reg);
|
||||
|
||||
void rtl92d_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
|
||||
/* RF Interface Sowrtware Control */
|
||||
/* 16 LSBs if read 32-bit from 0x870 */
|
||||
rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
|
||||
/* 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */
|
||||
rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
|
||||
/* 16 LSBs if read 32-bit from 0x874 */
|
||||
rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
|
||||
/* 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876) */
|
||||
|
||||
rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
|
||||
/* RF Interface Readback Value */
|
||||
/* 16 LSBs if read 32-bit from 0x8E0 */
|
||||
rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
|
||||
/* 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2) */
|
||||
rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
|
||||
/* 16 LSBs if read 32-bit from 0x8E4 */
|
||||
rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
|
||||
/* 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6) */
|
||||
rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
|
||||
|
||||
/* RF Interface Output (and Enable) */
|
||||
/* 16 LSBs if read 32-bit from 0x860 */
|
||||
rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
|
||||
/* 16 LSBs if read 32-bit from 0x864 */
|
||||
rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
|
||||
|
||||
/* RF Interface (Output and) Enable */
|
||||
/* 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */
|
||||
rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
|
||||
/* 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */
|
||||
rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
|
||||
|
||||
/* Addr of LSSI. Write RF register by driver */
|
||||
/* LSSI Parameter */
|
||||
rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
|
||||
RFPGA0_XA_LSSIPARAMETER;
|
||||
rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
|
||||
RFPGA0_XB_LSSIPARAMETER;
|
||||
|
||||
/* RF parameter */
|
||||
/* BB Band Select */
|
||||
rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER;
|
||||
rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER;
|
||||
rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER;
|
||||
rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER;
|
||||
|
||||
/* Tx AGC Gain Stage (same for all path. Should we remove this?) */
|
||||
/* Tx gain stage */
|
||||
rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
|
||||
/* Tx gain stage */
|
||||
rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
|
||||
/* Tx gain stage */
|
||||
rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
|
||||
/* Tx gain stage */
|
||||
rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
|
||||
|
||||
/* Transceiver A~D HSSI Parameter-1 */
|
||||
/* wire control parameter1 */
|
||||
rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
|
||||
/* wire control parameter1 */
|
||||
rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
|
||||
|
||||
/* Transceiver A~D HSSI Parameter-2 */
|
||||
/* wire control parameter2 */
|
||||
rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
|
||||
/* wire control parameter2 */
|
||||
rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
|
||||
|
||||
/* RF switch Control */
|
||||
/* TR/Ant switch control */
|
||||
rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
|
||||
rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
|
||||
rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
|
||||
rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
|
||||
|
||||
/* AGC control 1 */
|
||||
rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
|
||||
rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
|
||||
rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
|
||||
rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
|
||||
|
||||
/* AGC control 2 */
|
||||
rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
|
||||
rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
|
||||
rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
|
||||
rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
|
||||
|
||||
/* RX AFE control 1 */
|
||||
rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE;
|
||||
rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE;
|
||||
rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBALANCE;
|
||||
rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE;
|
||||
|
||||
/*RX AFE control 1 */
|
||||
rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
|
||||
rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
|
||||
rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
|
||||
rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
|
||||
|
||||
/* Tx AFE control 1 */
|
||||
rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE;
|
||||
rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE;
|
||||
rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE;
|
||||
rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE;
|
||||
|
||||
/* Tx AFE control 2 */
|
||||
rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
|
||||
rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
|
||||
rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
|
||||
rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
|
||||
|
||||
/* Transceiver LSSI Readback SI mode */
|
||||
rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK;
|
||||
rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK;
|
||||
rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK;
|
||||
rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK;
|
||||
|
||||
/* Transceiver LSSI Readback PI mode */
|
||||
rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVERA_HSPI_READBACK;
|
||||
rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVERB_HSPI_READBACK;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_phy_init_bb_rf_register_definition);
|
||||
|
||||
void rtl92d_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw,
|
||||
u32 regaddr, u32 bitmask, u32 data)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
int index;
|
||||
|
||||
if (regaddr == RTXAGC_A_RATE18_06)
|
||||
index = 0;
|
||||
else if (regaddr == RTXAGC_A_RATE54_24)
|
||||
index = 1;
|
||||
else if (regaddr == RTXAGC_A_CCK1_MCS32)
|
||||
index = 6;
|
||||
else if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00)
|
||||
index = 7;
|
||||
else if (regaddr == RTXAGC_A_MCS03_MCS00)
|
||||
index = 2;
|
||||
else if (regaddr == RTXAGC_A_MCS07_MCS04)
|
||||
index = 3;
|
||||
else if (regaddr == RTXAGC_A_MCS11_MCS08)
|
||||
index = 4;
|
||||
else if (regaddr == RTXAGC_A_MCS15_MCS12)
|
||||
index = 5;
|
||||
else if (regaddr == RTXAGC_B_RATE18_06)
|
||||
index = 8;
|
||||
else if (regaddr == RTXAGC_B_RATE54_24)
|
||||
index = 9;
|
||||
else if (regaddr == RTXAGC_B_CCK1_55_MCS32)
|
||||
index = 14;
|
||||
else if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff)
|
||||
index = 15;
|
||||
else if (regaddr == RTXAGC_B_MCS03_MCS00)
|
||||
index = 10;
|
||||
else if (regaddr == RTXAGC_B_MCS07_MCS04)
|
||||
index = 11;
|
||||
else if (regaddr == RTXAGC_B_MCS11_MCS08)
|
||||
index = 12;
|
||||
else if (regaddr == RTXAGC_B_MCS15_MCS12)
|
||||
index = 13;
|
||||
else
|
||||
return;
|
||||
|
||||
rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data;
|
||||
rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
|
||||
"MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%x\n",
|
||||
rtlphy->pwrgroup_cnt, index,
|
||||
rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index]);
|
||||
if (index == 13)
|
||||
rtlphy->pwrgroup_cnt++;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_store_pwrindex_diffrate_offset);
|
||||
|
||||
void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
|
||||
rtlphy->default_initialgain[0] =
|
||||
rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
|
||||
rtlphy->default_initialgain[1] =
|
||||
rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
|
||||
rtlphy->default_initialgain[2] =
|
||||
rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
|
||||
rtlphy->default_initialgain[3] =
|
||||
rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
|
||||
rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
|
||||
"Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
|
||||
rtlphy->default_initialgain[0],
|
||||
rtlphy->default_initialgain[1],
|
||||
rtlphy->default_initialgain[2],
|
||||
rtlphy->default_initialgain[3]);
|
||||
rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0);
|
||||
rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, MASKDWORD);
|
||||
rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
|
||||
"Default framesync (0x%x) = 0x%x\n",
|
||||
ROFDM0_RXDETECTOR3, rtlphy->framesync);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_phy_get_hw_reg_originalvalue);
|
||||
|
||||
static void _rtl92d_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
|
||||
u8 *cckpowerlevel, u8 *ofdmpowerlevel)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
u8 index = channel - 1;
|
||||
|
||||
/* 1. CCK */
|
||||
if (rtlhal->current_bandtype == BAND_ON_2_4G) {
|
||||
/* RF-A */
|
||||
cckpowerlevel[RF90_PATH_A] =
|
||||
rtlefuse->txpwrlevel_cck[RF90_PATH_A][index];
|
||||
/* RF-B */
|
||||
cckpowerlevel[RF90_PATH_B] =
|
||||
rtlefuse->txpwrlevel_cck[RF90_PATH_B][index];
|
||||
} else {
|
||||
cckpowerlevel[RF90_PATH_A] = 0;
|
||||
cckpowerlevel[RF90_PATH_B] = 0;
|
||||
}
|
||||
/* 2. OFDM for 1S or 2S */
|
||||
if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_1T1R) {
|
||||
/* Read HT 40 OFDM TX power */
|
||||
ofdmpowerlevel[RF90_PATH_A] =
|
||||
rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index];
|
||||
ofdmpowerlevel[RF90_PATH_B] =
|
||||
rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index];
|
||||
} else if (rtlphy->rf_type == RF_2T2R) {
|
||||
/* Read HT 40 OFDM TX power */
|
||||
ofdmpowerlevel[RF90_PATH_A] =
|
||||
rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index];
|
||||
ofdmpowerlevel[RF90_PATH_B] =
|
||||
rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index];
|
||||
}
|
||||
}
|
||||
|
||||
static void _rtl92d_ccxpower_index_check(struct ieee80211_hw *hw,
|
||||
u8 channel, u8 *cckpowerlevel,
|
||||
u8 *ofdmpowerlevel)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
|
||||
rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
|
||||
rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
|
||||
}
|
||||
|
||||
static u8 _rtl92c_phy_get_rightchnlplace(u8 chnl)
|
||||
{
|
||||
u8 place = chnl;
|
||||
|
||||
if (chnl > 14) {
|
||||
for (place = 14; place < ARRAY_SIZE(channel_all); place++) {
|
||||
if (channel_all[place] == chnl) {
|
||||
place++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return place;
|
||||
}
|
||||
|
||||
void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
|
||||
{
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 cckpowerlevel[2], ofdmpowerlevel[2];
|
||||
|
||||
if (!rtlefuse->txpwr_fromeprom)
|
||||
return;
|
||||
channel = _rtl92c_phy_get_rightchnlplace(channel);
|
||||
_rtl92d_get_txpower_index(hw, channel, &cckpowerlevel[0],
|
||||
&ofdmpowerlevel[0]);
|
||||
if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
|
||||
_rtl92d_ccxpower_index_check(hw, channel, &cckpowerlevel[0],
|
||||
&ofdmpowerlevel[0]);
|
||||
if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
|
||||
rtl92d_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]);
|
||||
rtl92d_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_phy_set_txpower_level);
|
||||
|
||||
void rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw, u8 rfpath,
|
||||
u32 *pu4_regval)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
|
||||
|
||||
rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "====>\n");
|
||||
/*----Store original RFENV control type----*/
|
||||
switch (rfpath) {
|
||||
case RF90_PATH_A:
|
||||
case RF90_PATH_C:
|
||||
*pu4_regval = rtl_get_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV);
|
||||
break;
|
||||
case RF90_PATH_B:
|
||||
case RF90_PATH_D:
|
||||
*pu4_regval =
|
||||
rtl_get_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16);
|
||||
break;
|
||||
}
|
||||
/*----Set RF_ENV enable----*/
|
||||
rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
|
||||
udelay(1);
|
||||
/*----Set RF_ENV output high----*/
|
||||
rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
|
||||
udelay(1);
|
||||
/* Set bit number of Address and Data for RF register */
|
||||
/* Set 1 to 4 bits for 8255 */
|
||||
rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREADDRESSLENGTH, 0x0);
|
||||
udelay(1);
|
||||
/*Set 0 to 12 bits for 8255 */
|
||||
rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
|
||||
udelay(1);
|
||||
rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "<====\n");
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_phy_enable_rf_env);
|
||||
|
||||
void rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath,
|
||||
u32 *pu4_regval)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
|
||||
|
||||
rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "=====>\n");
|
||||
/*----Restore RFENV control type----*/
|
||||
switch (rfpath) {
|
||||
case RF90_PATH_A:
|
||||
case RF90_PATH_C:
|
||||
rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV, *pu4_regval);
|
||||
break;
|
||||
case RF90_PATH_B:
|
||||
case RF90_PATH_D:
|
||||
rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16,
|
||||
*pu4_regval);
|
||||
break;
|
||||
}
|
||||
rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "<=====\n");
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_phy_restore_rf_env);
|
||||
|
||||
u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl)
|
||||
{
|
||||
u8 place;
|
||||
|
||||
if (chnl > 14) {
|
||||
for (place = 14; place < ARRAY_SIZE(channel_all); place++) {
|
||||
if (channel_all[place] == chnl)
|
||||
return place - 13;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_get_rightchnlplace_for_iqk);
|
||||
|
||||
void rtl92d_phy_save_adda_registers(struct ieee80211_hw *hw, const u32 *adda_reg,
|
||||
u32 *adda_backup, u32 regnum)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u32 i;
|
||||
|
||||
RTPRINT(rtlpriv, FINIT, INIT_IQK, "Save ADDA parameters.\n");
|
||||
for (i = 0; i < regnum; i++)
|
||||
adda_backup[i] = rtl_get_bbreg(hw, adda_reg[i], MASKDWORD);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_phy_save_adda_registers);
|
||||
|
||||
void rtl92d_phy_save_mac_registers(struct ieee80211_hw *hw,
|
||||
const u32 *macreg, u32 *macbackup)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u32 i;
|
||||
|
||||
RTPRINT(rtlpriv, FINIT, INIT_IQK, "Save MAC parameters.\n");
|
||||
for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
|
||||
macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
|
||||
macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_phy_save_mac_registers);
|
||||
|
||||
void rtl92d_phy_path_adda_on(struct ieee80211_hw *hw,
|
||||
const u32 *adda_reg, bool patha_on, bool is2t)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u32 pathon;
|
||||
u32 i;
|
||||
|
||||
RTPRINT(rtlpriv, FINIT, INIT_IQK, "ADDA ON.\n");
|
||||
pathon = patha_on ? 0x04db25a4 : 0x0b1b25a4;
|
||||
if (patha_on)
|
||||
pathon = rtlpriv->rtlhal.interfaceindex == 0 ?
|
||||
0x04db25a4 : 0x0b1b25a4;
|
||||
for (i = 0; i < IQK_ADDA_REG_NUM; i++)
|
||||
rtl_set_bbreg(hw, adda_reg[i], MASKDWORD, pathon);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_phy_path_adda_on);
|
||||
|
||||
void rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw,
|
||||
const u32 *macreg, u32 *macbackup)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u32 i;
|
||||
|
||||
RTPRINT(rtlpriv, FINIT, INIT_IQK, "MAC settings for Calibration.\n");
|
||||
rtl_write_byte(rtlpriv, macreg[0], 0x3F);
|
||||
|
||||
for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
|
||||
rtl_write_byte(rtlpriv, macreg[i], (u8)(macbackup[i] &
|
||||
(~BIT(3))));
|
||||
rtl_write_byte(rtlpriv, macreg[i], (u8)(macbackup[i] & (~BIT(5))));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_phy_mac_setting_calibration);
|
||||
|
||||
static u32 _rtl92d_phy_get_abs(u32 val1, u32 val2)
|
||||
{
|
||||
u32 ret;
|
||||
|
||||
if (val1 >= val2)
|
||||
ret = val1 - val2;
|
||||
else
|
||||
ret = val2 - val1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool _rtl92d_is_legal_5g_channel(struct ieee80211_hw *hw, u8 channel)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(channel5g); i++)
|
||||
if (channel == channel5g[i])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void rtl92d_phy_calc_curvindex(struct ieee80211_hw *hw,
|
||||
const u32 *targetchnl, u32 *curvecount_val,
|
||||
bool is5g, u32 *curveindex)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u32 smallest_abs_val = 0xffffffff, u4tmp;
|
||||
u8 i, j;
|
||||
u8 chnl_num = is5g ? TARGET_CHNL_NUM_5G : TARGET_CHNL_NUM_2G;
|
||||
|
||||
for (i = 0; i < chnl_num; i++) {
|
||||
if (is5g && !_rtl92d_is_legal_5g_channel(hw, i + 1))
|
||||
continue;
|
||||
curveindex[i] = 0;
|
||||
for (j = 0; j < (CV_CURVE_CNT * 2); j++) {
|
||||
u4tmp = _rtl92d_phy_get_abs(targetchnl[i],
|
||||
curvecount_val[j]);
|
||||
|
||||
if (u4tmp < smallest_abs_val) {
|
||||
curveindex[i] = j;
|
||||
smallest_abs_val = u4tmp;
|
||||
}
|
||||
}
|
||||
smallest_abs_val = 0xffffffff;
|
||||
RTPRINT(rtlpriv, FINIT, INIT_IQK, "curveindex[%d] = %x\n",
|
||||
i, curveindex[i]);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_phy_calc_curvindex);
|
||||
|
||||
void rtl92d_phy_reset_iqk_result(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
u8 i;
|
||||
|
||||
rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
|
||||
"settings regs %zu default regs %d\n",
|
||||
ARRAY_SIZE(rtlphy->iqk_matrix),
|
||||
IQK_MATRIX_REG_NUM);
|
||||
/* 0xe94, 0xe9c, 0xea4, 0xeac, 0xeb4, 0xebc, 0xec4, 0xecc */
|
||||
for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
|
||||
rtlphy->iqk_matrix[i].value[0][0] = 0x100;
|
||||
rtlphy->iqk_matrix[i].value[0][2] = 0x100;
|
||||
rtlphy->iqk_matrix[i].value[0][4] = 0x100;
|
||||
rtlphy->iqk_matrix[i].value[0][6] = 0x100;
|
||||
rtlphy->iqk_matrix[i].value[0][1] = 0x0;
|
||||
rtlphy->iqk_matrix[i].value[0][3] = 0x0;
|
||||
rtlphy->iqk_matrix[i].value[0][5] = 0x0;
|
||||
rtlphy->iqk_matrix[i].value[0][7] = 0x0;
|
||||
rtlphy->iqk_matrix[i].iqk_done = false;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_phy_reset_iqk_result);
|
||||
|
||||
static void rtl92d_phy_set_io(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct dig_t *de_digtable = &rtlpriv->dm_digtable;
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
|
||||
"--->Cmd(%#x), set_io_inprogress(%d)\n",
|
||||
rtlphy->current_io_type, rtlphy->set_io_inprogress);
|
||||
|
||||
switch (rtlphy->current_io_type) {
|
||||
case IO_CMD_RESUME_DM_BY_SCAN:
|
||||
de_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
|
||||
rtl92d_dm_write_dig(hw);
|
||||
rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel);
|
||||
break;
|
||||
case IO_CMD_PAUSE_DM_BY_SCAN:
|
||||
rtlphy->initgain_backup.xaagccore1 = de_digtable->cur_igvalue;
|
||||
de_digtable->cur_igvalue = 0x37;
|
||||
if (rtlpriv->rtlhal.interface == INTF_USB)
|
||||
de_digtable->cur_igvalue = 0x17;
|
||||
rtl92d_dm_write_dig(hw);
|
||||
break;
|
||||
default:
|
||||
pr_err("switch case %#x not processed\n",
|
||||
rtlphy->current_io_type);
|
||||
break;
|
||||
}
|
||||
|
||||
rtlphy->set_io_inprogress = false;
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "<---(%#x)\n",
|
||||
rtlphy->current_io_type);
|
||||
}
|
||||
|
||||
bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
bool postprocessing = false;
|
||||
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
|
||||
"-->IO Cmd(%#x), set_io_inprogress(%d)\n",
|
||||
iotype, rtlphy->set_io_inprogress);
|
||||
|
||||
do {
|
||||
switch (iotype) {
|
||||
case IO_CMD_RESUME_DM_BY_SCAN:
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
|
||||
"[IO CMD] Resume DM after scan\n");
|
||||
postprocessing = true;
|
||||
break;
|
||||
case IO_CMD_PAUSE_DM_BY_SCAN:
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
|
||||
"[IO CMD] Pause DM before scan\n");
|
||||
postprocessing = true;
|
||||
break;
|
||||
default:
|
||||
pr_err("switch case %#x not processed\n",
|
||||
iotype);
|
||||
break;
|
||||
}
|
||||
} while (false);
|
||||
|
||||
if (postprocessing && !rtlphy->set_io_inprogress) {
|
||||
rtlphy->set_io_inprogress = true;
|
||||
rtlphy->current_io_type = iotype;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
rtl92d_phy_set_io(hw);
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype);
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_phy_set_io_cmd);
|
||||
|
||||
void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
u8 offset = REG_MAC_PHY_CTRL_NORMAL;
|
||||
u8 phy_ctrl = 0xf0;
|
||||
|
||||
if (rtlhal->interface == INTF_USB) {
|
||||
phy_ctrl = rtl_read_byte(rtlpriv, offset);
|
||||
phy_ctrl &= ~(BIT(0) | BIT(1) | BIT(2));
|
||||
}
|
||||
|
||||
switch (rtlhal->macphymode) {
|
||||
case DUALMAC_DUALPHY:
|
||||
rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
|
||||
"MacPhyMode: DUALMAC_DUALPHY\n");
|
||||
rtl_write_byte(rtlpriv, offset, phy_ctrl | BIT(0) | BIT(1));
|
||||
break;
|
||||
case SINGLEMAC_SINGLEPHY:
|
||||
rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
|
||||
"MacPhyMode: SINGLEMAC_SINGLEPHY\n");
|
||||
rtl_write_byte(rtlpriv, offset, phy_ctrl | BIT(2));
|
||||
break;
|
||||
case DUALMAC_SINGLEPHY:
|
||||
rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
|
||||
"MacPhyMode: DUALMAC_SINGLEPHY\n");
|
||||
rtl_write_byte(rtlpriv, offset, phy_ctrl | BIT(0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_phy_config_macphymode);
|
||||
|
||||
void rtl92d_phy_config_macphymode_info(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
|
||||
switch (rtlhal->macphymode) {
|
||||
case DUALMAC_SINGLEPHY:
|
||||
rtlphy->rf_type = RF_2T2R;
|
||||
rtlhal->version |= RF_TYPE_2T2R;
|
||||
rtlhal->bandset = BAND_ON_BOTH;
|
||||
rtlhal->current_bandtype = BAND_ON_2_4G;
|
||||
break;
|
||||
|
||||
case SINGLEMAC_SINGLEPHY:
|
||||
rtlphy->rf_type = RF_2T2R;
|
||||
rtlhal->version |= RF_TYPE_2T2R;
|
||||
rtlhal->bandset = BAND_ON_BOTH;
|
||||
rtlhal->current_bandtype = BAND_ON_2_4G;
|
||||
break;
|
||||
|
||||
case DUALMAC_DUALPHY:
|
||||
rtlphy->rf_type = RF_1T1R;
|
||||
rtlhal->version &= RF_TYPE_1T1R;
|
||||
/* Now we let MAC0 run on 5G band. */
|
||||
if (rtlhal->interfaceindex == 0) {
|
||||
rtlhal->bandset = BAND_ON_5G;
|
||||
rtlhal->current_bandtype = BAND_ON_5G;
|
||||
} else {
|
||||
rtlhal->bandset = BAND_ON_2_4G;
|
||||
rtlhal->current_bandtype = BAND_ON_2_4G;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_phy_config_macphymode_info);
|
||||
|
||||
u8 rtl92d_get_chnlgroup_fromarray(u8 chnl)
|
||||
{
|
||||
u8 group;
|
||||
|
||||
if (channel_all[chnl] <= 3)
|
||||
group = 0;
|
||||
else if (channel_all[chnl] <= 9)
|
||||
group = 1;
|
||||
else if (channel_all[chnl] <= 14)
|
||||
group = 2;
|
||||
else if (channel_all[chnl] <= 44)
|
||||
group = 3;
|
||||
else if (channel_all[chnl] <= 54)
|
||||
group = 4;
|
||||
else if (channel_all[chnl] <= 64)
|
||||
group = 5;
|
||||
else if (channel_all[chnl] <= 112)
|
||||
group = 6;
|
||||
else if (channel_all[chnl] <= 126)
|
||||
group = 7;
|
||||
else if (channel_all[chnl] <= 140)
|
||||
group = 8;
|
||||
else if (channel_all[chnl] <= 153)
|
||||
group = 9;
|
||||
else if (channel_all[chnl] <= 159)
|
||||
group = 10;
|
||||
else
|
||||
group = 11;
|
||||
return group;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_get_chnlgroup_fromarray);
|
||||
|
||||
u8 rtl92d_phy_get_chnlgroup_bypg(u8 chnlindex)
|
||||
{
|
||||
u8 group;
|
||||
|
||||
if (channel_all[chnlindex] <= 3) /* Chanel 1-3 */
|
||||
group = 0;
|
||||
else if (channel_all[chnlindex] <= 9) /* Channel 4-9 */
|
||||
group = 1;
|
||||
else if (channel_all[chnlindex] <= 14) /* Channel 10-14 */
|
||||
group = 2;
|
||||
else if (channel_all[chnlindex] <= 64)
|
||||
group = 6;
|
||||
else if (channel_all[chnlindex] <= 140)
|
||||
group = 7;
|
||||
else
|
||||
group = 8;
|
||||
return group;
|
||||
}
|
||||
|
||||
void rtl92d_phy_config_maccoexist_rfpage(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
switch (rtlpriv->rtlhal.macphymode) {
|
||||
case DUALMAC_DUALPHY:
|
||||
rtl_write_byte(rtlpriv, REG_DMC, 0x0);
|
||||
rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x08);
|
||||
rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x13ff);
|
||||
break;
|
||||
case DUALMAC_SINGLEPHY:
|
||||
rtl_write_byte(rtlpriv, REG_DMC, 0xf8);
|
||||
rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x08);
|
||||
rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x13ff);
|
||||
break;
|
||||
case SINGLEMAC_SINGLEPHY:
|
||||
rtl_write_byte(rtlpriv, REG_DMC, 0x0);
|
||||
rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x10);
|
||||
rtl_write_word(rtlpriv, (REG_TRXFF_BNDY + 2), 0x27FF);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_phy_config_maccoexist_rfpage);
|
111
drivers/net/wireless/realtek/rtlwifi/rtl8192d/phy_common.h
Normal file
111
drivers/net/wireless/realtek/rtlwifi/rtl8192d/phy_common.h
Normal file
@ -0,0 +1,111 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright(c) 2009-2012 Realtek Corporation.*/
|
||||
|
||||
#ifndef __RTL92D_PHY_COMMON_H__
|
||||
#define __RTL92D_PHY_COMMON_H__
|
||||
|
||||
#define TARGET_CHNL_NUM_5G 221
|
||||
#define TARGET_CHNL_NUM_2G 14
|
||||
#define CV_CURVE_CNT 64
|
||||
#define RT_CANNOT_IO(hw) false
|
||||
#define RX_INDEX_MAPPING_NUM 15
|
||||
#define IQK_BB_REG_NUM 10
|
||||
|
||||
#define IQK_DELAY_TIME 1
|
||||
#define MAX_TOLERANCE 5
|
||||
#define MAX_TOLERANCE_92D 3
|
||||
|
||||
enum baseband_config_type {
|
||||
BASEBAND_CONFIG_PHY_REG = 0,
|
||||
BASEBAND_CONFIG_AGC_TAB = 1,
|
||||
};
|
||||
|
||||
enum rf_content {
|
||||
radioa_txt = 0,
|
||||
radiob_txt = 1,
|
||||
radioc_txt = 2,
|
||||
radiod_txt = 3
|
||||
};
|
||||
|
||||
static inline void rtl92d_acquire_cckandrw_pagea_ctl(struct ieee80211_hw *hw,
|
||||
unsigned long *flag)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
if (rtlpriv->rtlhal.interface == INTF_USB)
|
||||
return;
|
||||
|
||||
if (rtlpriv->rtlhal.interfaceindex == 1)
|
||||
spin_lock_irqsave(&rtlpriv->locks.cck_and_rw_pagea_lock, *flag);
|
||||
}
|
||||
|
||||
static inline void rtl92d_release_cckandrw_pagea_ctl(struct ieee80211_hw *hw,
|
||||
unsigned long *flag)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
if (rtlpriv->rtlhal.interface == INTF_USB)
|
||||
return;
|
||||
|
||||
if (rtlpriv->rtlhal.interfaceindex == 1)
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.cck_and_rw_pagea_lock,
|
||||
*flag);
|
||||
}
|
||||
|
||||
u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
|
||||
u32 regaddr, u32 bitmask);
|
||||
void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
|
||||
u32 regaddr, u32 bitmask, u32 data);
|
||||
void rtl92d_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
|
||||
void rtl92d_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw,
|
||||
u32 regaddr, u32 bitmask, u32 data);
|
||||
void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
|
||||
void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
|
||||
void rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw, u8 rfpath,
|
||||
u32 *pu4_regval);
|
||||
void rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath,
|
||||
u32 *pu4_regval);
|
||||
u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl);
|
||||
void rtl92d_phy_save_adda_registers(struct ieee80211_hw *hw, const u32 *adda_reg,
|
||||
u32 *adda_backup, u32 regnum);
|
||||
void rtl92d_phy_save_mac_registers(struct ieee80211_hw *hw,
|
||||
const u32 *macreg, u32 *macbackup);
|
||||
void rtl92d_phy_path_adda_on(struct ieee80211_hw *hw,
|
||||
const u32 *adda_reg, bool patha_on, bool is2t);
|
||||
void rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw,
|
||||
const u32 *macreg, u32 *macbackup);
|
||||
void rtl92d_phy_calc_curvindex(struct ieee80211_hw *hw,
|
||||
const u32 *targetchnl, u32 *curvecount_val,
|
||||
bool is5g, u32 *curveindex);
|
||||
void rtl92d_phy_reset_iqk_result(struct ieee80211_hw *hw);
|
||||
bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
|
||||
void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw);
|
||||
void rtl92d_phy_config_macphymode_info(struct ieee80211_hw *hw);
|
||||
u8 rtl92d_get_chnlgroup_fromarray(u8 chnl);
|
||||
u8 rtl92d_phy_get_chnlgroup_bypg(u8 chnlindex);
|
||||
void rtl92d_phy_config_maccoexist_rfpage(struct ieee80211_hw *hw);
|
||||
/* Without these declarations sparse warns about context imbalance. */
|
||||
void rtl92d_acquire_cckandrw_pagea_ctl(struct ieee80211_hw *hw,
|
||||
unsigned long *flag);
|
||||
void rtl92d_release_cckandrw_pagea_ctl(struct ieee80211_hw *hw,
|
||||
unsigned long *flag);
|
||||
|
||||
/* Without these helpers and the declarations sparse warns about
|
||||
* context imbalance.
|
||||
*/
|
||||
static inline void rtl92d_pci_lock(struct rtl_priv *rtlpriv)
|
||||
{
|
||||
if (rtlpriv->rtlhal.interface == INTF_PCI)
|
||||
spin_lock(&rtlpriv->locks.rf_lock);
|
||||
}
|
||||
|
||||
static inline void rtl92d_pci_unlock(struct rtl_priv *rtlpriv)
|
||||
{
|
||||
if (rtlpriv->rtlhal.interface == INTF_PCI)
|
||||
spin_unlock(&rtlpriv->locks.rf_lock);
|
||||
}
|
||||
|
||||
void rtl92d_pci_lock(struct rtl_priv *rtlpriv);
|
||||
void rtl92d_pci_unlock(struct rtl_priv *rtlpriv);
|
||||
|
||||
#endif
|
@ -50,6 +50,9 @@
|
||||
#define REG_HMEBOX_EXT_1 0x008A
|
||||
#define REG_HMEBOX_EXT_2 0x008C
|
||||
#define REG_HMEBOX_EXT_3 0x008E
|
||||
#define SIZE_OF_REG_HMEBOX_EXT 2
|
||||
|
||||
#define REG_EFUSE_ACCESS 0x00CF
|
||||
|
||||
#define REG_BIST_SCAN 0x00D0
|
||||
#define REG_BIST_RPT 0x00D4
|
||||
@ -86,6 +89,7 @@
|
||||
#define REG_CPWM 0x012F
|
||||
#define REG_FWIMR 0x0130
|
||||
#define REG_FWISR 0x0134
|
||||
#define REG_FTIMR 0x0138
|
||||
#define REG_PKTBUF_DBG_CTRL 0x0140
|
||||
#define REG_PKTBUF_DBG_DATA_L 0x0144
|
||||
#define REG_PKTBUF_DBG_DATA_H 0x0148
|
||||
@ -109,6 +113,7 @@
|
||||
#define REG_HMEBOX_1 0x01D4
|
||||
#define REG_HMEBOX_2 0x01D8
|
||||
#define REG_HMEBOX_3 0x01DC
|
||||
#define SIZE_OF_REG_HMEBOX 4
|
||||
|
||||
#define REG_LLT_INIT 0x01E0
|
||||
#define REG_BB_ACCEESS_CTRL 0x01E8
|
||||
@ -197,6 +202,8 @@
|
||||
#define REG_POWER_STAGE1 0x04B4
|
||||
#define REG_POWER_STAGE2 0x04B8
|
||||
#define REG_PKT_LIFE_TIME 0x04C0
|
||||
#define REG_PKT_VO_VI_LIFE_TIME 0x04C0
|
||||
#define REG_PKT_BE_BK_LIFE_TIME 0x04C2
|
||||
#define REG_STBC_SETTING 0x04C4
|
||||
#define REG_PROT_MODE_CTRL 0x04C8
|
||||
#define REG_MAX_AGGR_NUM 0x04CA
|
||||
@ -233,6 +240,7 @@
|
||||
#define REG_RD_NAV_NXT 0x0544
|
||||
#define REG_NAV_PROT_LEN 0x0546
|
||||
#define REG_BCN_CTRL 0x0550
|
||||
#define REG_BCN_CTRL_1 0x0551
|
||||
#define REG_MBID_NUM 0x0552
|
||||
#define REG_DUAL_TSF_RST 0x0553
|
||||
#define REG_BCN_INTERVAL 0x0554
|
||||
@ -319,6 +327,8 @@
|
||||
#define REG_BT_COEX_TABLE 0x06C0
|
||||
#define REG_WMAC_RESP_TXINFO 0x06D8
|
||||
|
||||
#define REG_USB_Queue_Select_MAC0 0xFE44
|
||||
#define REG_USB_Queue_Select_MAC1 0xFE47
|
||||
|
||||
/* ----------------------------------------------------- */
|
||||
/* Redifine 8192C register definition for compatibility */
|
||||
@ -355,27 +365,27 @@
|
||||
#define RRSR_RSC_UPSUBCHNL 0x400000
|
||||
#define RRSR_RSC_LOWSUBCHNL 0x200000
|
||||
#define RRSR_SHORT 0x800000
|
||||
#define RRSR_1M BIT0
|
||||
#define RRSR_2M BIT1
|
||||
#define RRSR_5_5M BIT2
|
||||
#define RRSR_11M BIT3
|
||||
#define RRSR_6M BIT4
|
||||
#define RRSR_9M BIT5
|
||||
#define RRSR_12M BIT6
|
||||
#define RRSR_18M BIT7
|
||||
#define RRSR_24M BIT8
|
||||
#define RRSR_36M BIT9
|
||||
#define RRSR_48M BIT10
|
||||
#define RRSR_54M BIT11
|
||||
#define RRSR_MCS0 BIT12
|
||||
#define RRSR_MCS1 BIT13
|
||||
#define RRSR_MCS2 BIT14
|
||||
#define RRSR_MCS3 BIT15
|
||||
#define RRSR_MCS4 BIT16
|
||||
#define RRSR_MCS5 BIT17
|
||||
#define RRSR_MCS6 BIT18
|
||||
#define RRSR_MCS7 BIT19
|
||||
#define BRSR_ACKSHORTPMB BIT23
|
||||
#define RRSR_1M BIT(0)
|
||||
#define RRSR_2M BIT(1)
|
||||
#define RRSR_5_5M BIT(2)
|
||||
#define RRSR_11M BIT(3)
|
||||
#define RRSR_6M BIT(4)
|
||||
#define RRSR_9M BIT(5)
|
||||
#define RRSR_12M BIT(6)
|
||||
#define RRSR_18M BIT(7)
|
||||
#define RRSR_24M BIT(8)
|
||||
#define RRSR_36M BIT(9)
|
||||
#define RRSR_48M BIT(10)
|
||||
#define RRSR_54M BIT(11)
|
||||
#define RRSR_MCS0 BIT(12)
|
||||
#define RRSR_MCS1 BIT(13)
|
||||
#define RRSR_MCS2 BIT(14)
|
||||
#define RRSR_MCS3 BIT(15)
|
||||
#define RRSR_MCS4 BIT(16)
|
||||
#define RRSR_MCS5 BIT(17)
|
||||
#define RRSR_MCS6 BIT(18)
|
||||
#define RRSR_MCS7 BIT(19)
|
||||
#define BRSR_ACKSHORTPMB BIT(23)
|
||||
|
||||
/* ----------------------------------------------------- */
|
||||
/* 8192C Rate Definition */
|
||||
@ -600,7 +610,11 @@
|
||||
#define EEPROM_SVID 0x2C /* SE Vendor ID.E-F */
|
||||
#define EEPROM_SMID 0x2E /* SE PCI Subsystem ID. 10-11 */
|
||||
|
||||
#define EEPROM_VID_USB 0xC
|
||||
#define EEPROM_PID_USB 0xE
|
||||
#define EEPROM_ENDPOINT_SETTING 0x10
|
||||
#define EEPROM_MAC_ADDR 0x16 /* SEMAC Address. 12-17 */
|
||||
#define EEPROM_MAC_ADDR_MAC0_92DU 0x19
|
||||
#define EEPROM_MAC_ADDR_MAC0_92D 0x55
|
||||
#define EEPROM_MAC_ADDR_MAC1_92D 0x5B
|
||||
|
||||
@ -915,6 +929,42 @@
|
||||
#define BD_HCI_SEL BIT(26)
|
||||
#define TYPE_ID BIT(27)
|
||||
|
||||
#define HCI_TXDMA_EN BIT(0)
|
||||
#define HCI_RXDMA_EN BIT(1)
|
||||
#define TXDMA_EN BIT(2)
|
||||
#define RXDMA_EN BIT(3)
|
||||
#define PROTOCOL_EN BIT(4)
|
||||
#define SCHEDULE_EN BIT(5)
|
||||
#define MACTXEN BIT(6)
|
||||
#define MACRXEN BIT(7)
|
||||
#define ENSWBCN BIT(8)
|
||||
#define ENSEC BIT(9)
|
||||
|
||||
#define HQSEL_VOQ BIT(0)
|
||||
#define HQSEL_VIQ BIT(1)
|
||||
#define HQSEL_BEQ BIT(2)
|
||||
#define HQSEL_BKQ BIT(3)
|
||||
#define HQSEL_MGTQ BIT(4)
|
||||
#define HQSEL_HIQ BIT(5)
|
||||
|
||||
#define TXDMA_HIQ_MAP GENMASK(15, 14)
|
||||
#define TXDMA_MGQ_MAP GENMASK(13, 12)
|
||||
#define TXDMA_BKQ_MAP GENMASK(11, 10)
|
||||
#define TXDMA_BEQ_MAP GENMASK(9, 8)
|
||||
#define TXDMA_VIQ_MAP GENMASK(7, 6)
|
||||
#define TXDMA_VOQ_MAP GENMASK(5, 4)
|
||||
|
||||
#define QUEUE_LOW 1
|
||||
#define QUEUE_NORMAL 2
|
||||
#define QUEUE_HIGH 3
|
||||
|
||||
#define HPQ_MASK GENMASK(7, 0)
|
||||
#define LPQ_MASK GENMASK(15, 8)
|
||||
#define PUBQ_MASK GENMASK(23, 16)
|
||||
#define LD_RQPN BIT(31)
|
||||
|
||||
#define DROP_DATA_EN BIT(9)
|
||||
|
||||
/* LLT_INIT */
|
||||
#define _LLT_NO_ACTIVE 0x0
|
||||
#define _LLT_WRITE_ACCESS 0x1
|
||||
@ -929,6 +979,10 @@
|
||||
/* ----------------------------------------------------- */
|
||||
/* 0x0400h ~ 0x047Fh Protocol Configuration */
|
||||
/* ----------------------------------------------------- */
|
||||
/* FWHW_TXQ_CTRL */
|
||||
#define EN_AMPDU_RTY_NEW BIT(7)
|
||||
#define EN_BCNQ_DL BIT(22)
|
||||
|
||||
#define RETRY_LIMIT_SHORT_SHIFT 8
|
||||
#define RETRY_LIMIT_LONG_SHIFT 0
|
||||
|
||||
@ -942,6 +996,13 @@
|
||||
#define AC_PARAM_ECW_MIN_OFFSET 8
|
||||
#define AC_PARAM_AIFS_OFFSET 0
|
||||
|
||||
/* REG_RD_CTRL */
|
||||
#define DIS_EDCA_CNT_DWN BIT(11)
|
||||
|
||||
/* REG_BCN_CTRL */
|
||||
#define EN_BCN_FUNCTION BIT(3)
|
||||
#define DIS_TSF_UDT BIT(4)
|
||||
|
||||
/* ACMHWCTRL */
|
||||
#define ACMHW_HWEN BIT(0)
|
||||
#define ACMHW_BEQEN BIT(1)
|
||||
@ -1073,6 +1134,11 @@
|
||||
#define RCCK0_FACOUNTERLOWER 0xa5c
|
||||
#define RCCK0_FACOUNTERUPPER 0xa58
|
||||
|
||||
#define RPDP_ANTA 0xb00
|
||||
#define RCONFIG_ANTA 0xb68
|
||||
#define RCONFIG_ANTB 0xb6c
|
||||
#define RPDP_ANTB 0xb70
|
||||
|
||||
/* 6. PageC(0xC00) */
|
||||
#define ROFDM0_LSTF 0xc00
|
||||
|
||||
@ -1126,6 +1192,7 @@
|
||||
#define ROFDM0_TXPSEUDONOISEWGT 0xce4
|
||||
#define ROFDM0_FRAMESYNC 0xcf0
|
||||
#define ROFDM0_DFSREPORT 0xcf4
|
||||
#define ROFDM0_RXIQEXTANTA 0xca0
|
||||
#define ROFDM0_TXCOEFF1 0xca4
|
||||
#define ROFDM0_TXCOEFF2 0xca8
|
||||
#define ROFDM0_TXCOEFF3 0xcac
|
||||
@ -1184,17 +1251,70 @@
|
||||
#define RTXAGC_B_MCS15_MCS12 0x868
|
||||
#define RTXAGC_B_CCK11_A_CCK2_11 0x86c
|
||||
|
||||
#define RFPGA0_IQK 0xe28
|
||||
#define RTX_IQK_TONE_A 0xe30
|
||||
#define RRX_IQK_TONE_A 0xe34
|
||||
#define RTX_IQK_PI_A 0xe38
|
||||
#define RRX_IQK_PI_A 0xe3c
|
||||
|
||||
#define RTX_IQK 0xe40
|
||||
#define RRX_IQK 0xe44
|
||||
#define RIQK_AGC_PTS 0xe48
|
||||
#define RIQK_AGC_RSP 0xe4c
|
||||
#define RTX_IQK_TONE_B 0xe50
|
||||
#define RRX_IQK_TONE_B 0xe54
|
||||
#define RTX_IQK_PI_B 0xe58
|
||||
#define RRX_IQK_PI_B 0xe5c
|
||||
#define RIQK_AGC_CONT 0xe60
|
||||
|
||||
#define RBLUE_TOOTH 0xe6c
|
||||
#define RRX_WAIT_CCA 0xe70
|
||||
#define RTX_CCK_RFON 0xe74
|
||||
#define RTX_CCK_BBON 0xe78
|
||||
#define RTX_OFDM_RFON 0xe7c
|
||||
#define RTX_OFDM_BBON 0xe80
|
||||
#define RTX_TO_RX 0xe84
|
||||
#define RTX_TO_TX 0xe88
|
||||
#define RRX_CCK 0xe8c
|
||||
|
||||
#define RTX_POWER_BEFORE_IQK_A 0xe94
|
||||
#define RTX_POWER_AFTER_IQK_A 0xe9c
|
||||
|
||||
#define RRX_POWER_BEFORE_IQK_A 0xea0
|
||||
#define RRX_POWER_BEFORE_IQK_A_2 0xea4
|
||||
#define RRX_POWER_AFTER_IQK_A 0xea8
|
||||
#define RRX_POWER_AFTER_IQK_A_2 0xeac
|
||||
|
||||
#define RTX_POWER_BEFORE_IQK_B 0xeb4
|
||||
#define RTX_POWER_AFTER_IQK_B 0xebc
|
||||
|
||||
#define RRX_POWER_BEFORE_IQK_B 0xec0
|
||||
#define RRX_POWER_BEFORE_IQK_B_2 0xec4
|
||||
#define RRX_POWER_AFTER_IQK_B 0xec8
|
||||
#define RRX_POWER_AFTER_IQK_B_2 0xecc
|
||||
|
||||
#define MASK_IQK_RESULT 0x03ff0000
|
||||
|
||||
#define RRX_OFDM 0xed0
|
||||
#define RRX_WAIT_RIFS 0xed4
|
||||
#define RRX_TO_RX 0xed8
|
||||
#define RSTANDBY 0xedc
|
||||
#define RSLEEP 0xee0
|
||||
#define RPMPD_ANAEN 0xeec
|
||||
|
||||
/* RL6052 Register definition */
|
||||
#define RF_AC 0x00
|
||||
|
||||
#define RF_IQADJ_G1 0x01
|
||||
#define RF_IQADJ_G2 0x02
|
||||
#define RF_BS_PA_APSET_G1_G4 0x03
|
||||
#define RF_POW_TRSW 0x05
|
||||
|
||||
#define RF_GAIN_RX 0x06
|
||||
#define RF_GAIN_TX 0x07
|
||||
|
||||
#define RF_TXM_IDAC 0x08
|
||||
#define RF_TXPA_AG 0x0B
|
||||
#define RF_BS_IQGEN 0x0F
|
||||
|
||||
#define RF_MODE1 0x10
|
359
drivers/net/wireless/realtek/rtlwifi/rtl8192d/rf_common.c
Normal file
359
drivers/net/wireless/realtek/rtlwifi/rtl8192d/rf_common.c
Normal file
@ -0,0 +1,359 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright(c) 2009-2012 Realtek Corporation.*/
|
||||
|
||||
#include "../wifi.h"
|
||||
#include "def.h"
|
||||
#include "reg.h"
|
||||
#include "phy_common.h"
|
||||
#include "rf_common.h"
|
||||
|
||||
void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
u8 rfpath;
|
||||
|
||||
switch (bandwidth) {
|
||||
case HT_CHANNEL_WIDTH_20:
|
||||
for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
|
||||
rtlphy->rfreg_chnlval[rfpath] &= 0xfffff3ff;
|
||||
rtlphy->rfreg_chnlval[rfpath] |= 0x0400;
|
||||
|
||||
rtl_set_rfreg(hw, rfpath, RF_CHNLBW,
|
||||
BIT(10) | BIT(11), 0x01);
|
||||
|
||||
rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD,
|
||||
"20M RF 0x18 = 0x%x\n",
|
||||
rtlphy->rfreg_chnlval[rfpath]);
|
||||
}
|
||||
|
||||
break;
|
||||
case HT_CHANNEL_WIDTH_20_40:
|
||||
for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
|
||||
rtlphy->rfreg_chnlval[rfpath] &= 0xfffff3ff;
|
||||
|
||||
rtl_set_rfreg(hw, rfpath, RF_CHNLBW,
|
||||
BIT(10) | BIT(11), 0x00);
|
||||
|
||||
rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD,
|
||||
"40M RF 0x18 = 0x%x\n",
|
||||
rtlphy->rfreg_chnlval[rfpath]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_err("unknown bandwidth: %#X\n", bandwidth);
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_phy_rf6052_set_bandwidth);
|
||||
|
||||
void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
|
||||
u8 *ppowerlevel)
|
||||
{
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
u32 tx_agc[2] = {0, 0}, tmpval;
|
||||
bool turbo_scanoff = false;
|
||||
u8 idx1, idx2;
|
||||
u8 *ptr;
|
||||
|
||||
if (rtlefuse->eeprom_regulatory != 0)
|
||||
turbo_scanoff = true;
|
||||
if (mac->act_scanning) {
|
||||
tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
|
||||
tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
|
||||
if (turbo_scanoff) {
|
||||
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
|
||||
tx_agc[idx1] = ppowerlevel[idx1] |
|
||||
(ppowerlevel[idx1] << 8) |
|
||||
(ppowerlevel[idx1] << 16) |
|
||||
(ppowerlevel[idx1] << 24);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
|
||||
tx_agc[idx1] = ppowerlevel[idx1] |
|
||||
(ppowerlevel[idx1] << 8) |
|
||||
(ppowerlevel[idx1] << 16) |
|
||||
(ppowerlevel[idx1] << 24);
|
||||
}
|
||||
if (rtlefuse->eeprom_regulatory == 0) {
|
||||
tmpval = (rtlphy->mcs_offset[0][6]) +
|
||||
(rtlphy->mcs_offset[0][7] << 8);
|
||||
tx_agc[RF90_PATH_A] += tmpval;
|
||||
tmpval = (rtlphy->mcs_offset[0][14]) +
|
||||
(rtlphy->mcs_offset[0][15] << 24);
|
||||
tx_agc[RF90_PATH_B] += tmpval;
|
||||
}
|
||||
}
|
||||
|
||||
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
|
||||
ptr = (u8 *)(&tx_agc[idx1]);
|
||||
for (idx2 = 0; idx2 < 4; idx2++) {
|
||||
if (*ptr > RF6052_MAX_TX_PWR)
|
||||
*ptr = RF6052_MAX_TX_PWR;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
tmpval = tx_agc[RF90_PATH_A] & 0xff;
|
||||
rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n",
|
||||
tmpval, RTXAGC_A_CCK1_MCS32);
|
||||
tmpval = tx_agc[RF90_PATH_A] >> 8;
|
||||
rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n",
|
||||
tmpval, RTXAGC_B_CCK11_A_CCK2_11);
|
||||
tmpval = tx_agc[RF90_PATH_B] >> 24;
|
||||
rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n",
|
||||
tmpval, RTXAGC_B_CCK11_A_CCK2_11);
|
||||
tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
|
||||
rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n",
|
||||
tmpval, RTXAGC_B_CCK1_55_MCS32);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_phy_rf6052_set_cck_txpower);
|
||||
|
||||
static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw,
|
||||
u8 *ppowerlevel, u8 channel,
|
||||
u32 *ofdmbase, u32 *mcsbase)
|
||||
{
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
u32 powerbase0, powerbase1;
|
||||
u8 legacy_pwrdiff, ht20_pwrdiff;
|
||||
u8 i, powerlevel[2];
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
powerlevel[i] = ppowerlevel[i];
|
||||
legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1];
|
||||
powerbase0 = powerlevel[i] + legacy_pwrdiff;
|
||||
powerbase0 = (powerbase0 << 24) | (powerbase0 << 16) |
|
||||
(powerbase0 << 8) | powerbase0;
|
||||
*(ofdmbase + i) = powerbase0;
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
" [OFDM power base index rf(%c) = 0x%x]\n",
|
||||
i == 0 ? 'A' : 'B', *(ofdmbase + i));
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
|
||||
ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1];
|
||||
powerlevel[i] += ht20_pwrdiff;
|
||||
}
|
||||
powerbase1 = powerlevel[i];
|
||||
powerbase1 = (powerbase1 << 24) | (powerbase1 << 16) |
|
||||
(powerbase1 << 8) | powerbase1;
|
||||
*(mcsbase + i) = powerbase1;
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
" [MCS power base index rf(%c) = 0x%x]\n",
|
||||
i == 0 ? 'A' : 'B', *(mcsbase + i));
|
||||
}
|
||||
}
|
||||
|
||||
static void _rtl92d_get_pwr_diff_limit(struct ieee80211_hw *hw, u8 channel,
|
||||
u8 index, u8 rf, u8 pwr_diff_limit[4])
|
||||
{
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
u32 mcs_offset;
|
||||
u8 limit;
|
||||
int i;
|
||||
|
||||
mcs_offset = rtlphy->mcs_offset[0][index + (rf ? 8 : 0)];
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
pwr_diff_limit[i] = (mcs_offset >> (i * 8)) & 0x7f;
|
||||
|
||||
if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40)
|
||||
limit = rtlefuse->pwrgroup_ht40[rf][channel - 1];
|
||||
else
|
||||
limit = rtlefuse->pwrgroup_ht20[rf][channel - 1];
|
||||
|
||||
if (pwr_diff_limit[i] > limit)
|
||||
pwr_diff_limit[i] = limit;
|
||||
}
|
||||
}
|
||||
|
||||
static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
|
||||
u8 channel, u8 index,
|
||||
u32 *powerbase0,
|
||||
u32 *powerbase1,
|
||||
u32 *p_outwriteval)
|
||||
{
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
u32 writeval = 0, customer_limit, rf;
|
||||
u8 chnlgroup = 0, pwr_diff_limit[4];
|
||||
|
||||
for (rf = 0; rf < 2; rf++) {
|
||||
switch (rtlefuse->eeprom_regulatory) {
|
||||
case 0:
|
||||
writeval = rtlphy->mcs_offset[0][index + (rf ? 8 : 0)];
|
||||
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"RTK better performance\n");
|
||||
break;
|
||||
case 1:
|
||||
if (rtlphy->pwrgroup_cnt == 1)
|
||||
chnlgroup = 0;
|
||||
|
||||
if (rtlphy->pwrgroup_cnt < MAX_PG_GROUP)
|
||||
break;
|
||||
|
||||
chnlgroup = rtl92d_phy_get_chnlgroup_bypg(channel - 1);
|
||||
if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20)
|
||||
chnlgroup++;
|
||||
else
|
||||
chnlgroup += 4;
|
||||
|
||||
writeval = rtlphy->mcs_offset
|
||||
[chnlgroup][index + (rf ? 8 : 0)];
|
||||
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"Realtek regulatory, 20MHz\n");
|
||||
break;
|
||||
case 2:
|
||||
writeval = 0;
|
||||
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR, "Better regulatory\n");
|
||||
break;
|
||||
case 3:
|
||||
if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"customer's limit, 40MHz rf(%c) = 0x%x\n",
|
||||
rf == 0 ? 'A' : 'B',
|
||||
rtlefuse->pwrgroup_ht40[rf][channel - 1]);
|
||||
} else {
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"customer's limit, 20MHz rf(%c) = 0x%x\n",
|
||||
rf == 0 ? 'A' : 'B',
|
||||
rtlefuse->pwrgroup_ht20[rf][channel - 1]);
|
||||
}
|
||||
|
||||
_rtl92d_get_pwr_diff_limit(hw, channel, index, rf,
|
||||
pwr_diff_limit);
|
||||
|
||||
customer_limit = (pwr_diff_limit[3] << 24) |
|
||||
(pwr_diff_limit[2] << 16) |
|
||||
(pwr_diff_limit[1] << 8) |
|
||||
(pwr_diff_limit[0]);
|
||||
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"Customer's limit rf(%c) = 0x%x\n",
|
||||
rf == 0 ? 'A' : 'B', customer_limit);
|
||||
|
||||
writeval = customer_limit;
|
||||
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR, "Customer\n");
|
||||
break;
|
||||
default:
|
||||
writeval = rtlphy->mcs_offset[0][index + (rf ? 8 : 0)];
|
||||
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"RTK better performance\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (index < 2)
|
||||
writeval += powerbase0[rf];
|
||||
else
|
||||
writeval += powerbase1[rf];
|
||||
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR, "writeval rf(%c)= 0x%x\n",
|
||||
rf == 0 ? 'A' : 'B', writeval);
|
||||
|
||||
*(p_outwriteval + rf) = writeval;
|
||||
}
|
||||
}
|
||||
|
||||
static void _rtl92d_write_ofdm_power_reg(struct ieee80211_hw *hw,
|
||||
u8 index, u32 *pvalue)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
static const u16 regoffset_a[6] = {
|
||||
RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24,
|
||||
RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
|
||||
RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
|
||||
};
|
||||
static const u16 regoffset_b[6] = {
|
||||
RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24,
|
||||
RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
|
||||
RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
|
||||
};
|
||||
u8 i, rf, pwr_val[4];
|
||||
u32 writeval;
|
||||
u16 regoffset;
|
||||
|
||||
for (rf = 0; rf < 2; rf++) {
|
||||
writeval = pvalue[rf];
|
||||
for (i = 0; i < 4; i++) {
|
||||
pwr_val[i] = (u8)((writeval & (0x7f <<
|
||||
(i * 8))) >> (i * 8));
|
||||
if (pwr_val[i] > RF6052_MAX_TX_PWR)
|
||||
pwr_val[i] = RF6052_MAX_TX_PWR;
|
||||
}
|
||||
writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) |
|
||||
(pwr_val[1] << 8) | pwr_val[0];
|
||||
if (rf == 0)
|
||||
regoffset = regoffset_a[index];
|
||||
else
|
||||
regoffset = regoffset_b[index];
|
||||
rtl_set_bbreg(hw, regoffset, MASKDWORD, writeval);
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"Set 0x%x = %08x\n", regoffset, writeval);
|
||||
if (((get_rf_type(rtlphy) == RF_2T2R) &&
|
||||
(regoffset == RTXAGC_A_MCS15_MCS12 ||
|
||||
regoffset == RTXAGC_B_MCS15_MCS12)) ||
|
||||
((get_rf_type(rtlphy) != RF_2T2R) &&
|
||||
(regoffset == RTXAGC_A_MCS07_MCS04 ||
|
||||
regoffset == RTXAGC_B_MCS07_MCS04))) {
|
||||
writeval = pwr_val[3];
|
||||
if (regoffset == RTXAGC_A_MCS15_MCS12 ||
|
||||
regoffset == RTXAGC_A_MCS07_MCS04)
|
||||
regoffset = 0xc90;
|
||||
if (regoffset == RTXAGC_B_MCS15_MCS12 ||
|
||||
regoffset == RTXAGC_B_MCS07_MCS04)
|
||||
regoffset = 0xc98;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (i != 2)
|
||||
writeval = (writeval > 8) ?
|
||||
(writeval - 8) : 0;
|
||||
else
|
||||
writeval = (writeval > 6) ?
|
||||
(writeval - 6) : 0;
|
||||
rtl_write_byte(rtlpriv, (u32)(regoffset + i),
|
||||
(u8)writeval);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
|
||||
u8 *ppowerlevel, u8 channel)
|
||||
{
|
||||
u32 writeval[2], powerbase0[2], powerbase1[2];
|
||||
u8 index;
|
||||
|
||||
_rtl92d_phy_get_power_base(hw, ppowerlevel, channel,
|
||||
&powerbase0[0], &powerbase1[0]);
|
||||
for (index = 0; index < 6; index++) {
|
||||
_rtl92d_get_txpower_writeval_by_regulatory(hw, channel, index,
|
||||
&powerbase0[0],
|
||||
&powerbase1[0],
|
||||
&writeval[0]);
|
||||
_rtl92d_write_ofdm_power_reg(hw, index, &writeval[0]);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92d_phy_rf6052_set_ofdm_txpower);
|
13
drivers/net/wireless/realtek/rtlwifi/rtl8192d/rf_common.h
Normal file
13
drivers/net/wireless/realtek/rtlwifi/rtl8192d/rf_common.h
Normal file
@ -0,0 +1,13 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright(c) 2009-2012 Realtek Corporation.*/
|
||||
|
||||
#ifndef __RTL92D_RF_COMMON_H__
|
||||
#define __RTL92D_RF_COMMON_H__
|
||||
|
||||
void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth);
|
||||
void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
|
||||
u8 *ppowerlevel);
|
||||
void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
|
||||
u8 *ppowerlevel, u8 channel);
|
||||
|
||||
#endif
|
516
drivers/net/wireless/realtek/rtlwifi/rtl8192d/trx_common.c
Normal file
516
drivers/net/wireless/realtek/rtlwifi/rtl8192d/trx_common.c
Normal file
@ -0,0 +1,516 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright(c) 2009-2012 Realtek Corporation.*/
|
||||
|
||||
#include "../wifi.h"
|
||||
#include "../base.h"
|
||||
#include "../stats.h"
|
||||
#include "def.h"
|
||||
#include "trx_common.h"
|
||||
|
||||
static long _rtl92de_translate_todbm(struct ieee80211_hw *hw,
|
||||
u8 signal_strength_index)
|
||||
{
|
||||
long signal_power;
|
||||
|
||||
signal_power = (long)((signal_strength_index + 1) >> 1);
|
||||
signal_power -= 95;
|
||||
return signal_power;
|
||||
}
|
||||
|
||||
static void _rtl92de_query_rxphystatus(struct ieee80211_hw *hw,
|
||||
struct rtl_stats *pstats,
|
||||
__le32 *pdesc,
|
||||
struct rx_fwinfo_92d *p_drvinfo,
|
||||
bool packet_match_bssid,
|
||||
bool packet_toself,
|
||||
bool packet_beacon)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
|
||||
struct phy_sts_cck_8192d *cck_buf;
|
||||
s8 rx_pwr_all, rx_pwr[4];
|
||||
u8 rf_rx_num = 0, evm, pwdb_all;
|
||||
u8 i, max_spatial_stream;
|
||||
u32 rssi, total_rssi = 0;
|
||||
bool is_cck_rate;
|
||||
u8 rxmcs;
|
||||
|
||||
rxmcs = get_rx_desc_rxmcs(pdesc);
|
||||
is_cck_rate = rxmcs <= DESC_RATE11M;
|
||||
pstats->packet_matchbssid = packet_match_bssid;
|
||||
pstats->packet_toself = packet_toself;
|
||||
pstats->packet_beacon = packet_beacon;
|
||||
pstats->is_cck = is_cck_rate;
|
||||
pstats->rx_mimo_sig_qual[0] = -1;
|
||||
pstats->rx_mimo_sig_qual[1] = -1;
|
||||
|
||||
if (is_cck_rate) {
|
||||
u8 report, cck_highpwr;
|
||||
|
||||
cck_buf = (struct phy_sts_cck_8192d *)p_drvinfo;
|
||||
if (ppsc->rfpwr_state == ERFON)
|
||||
cck_highpwr = rtlphy->cck_high_power;
|
||||
else
|
||||
cck_highpwr = false;
|
||||
if (!cck_highpwr) {
|
||||
u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
|
||||
|
||||
report = cck_buf->cck_agc_rpt & 0xc0;
|
||||
report = report >> 6;
|
||||
switch (report) {
|
||||
case 0x3:
|
||||
rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
|
||||
break;
|
||||
case 0x2:
|
||||
rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
|
||||
break;
|
||||
case 0x1:
|
||||
rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
|
||||
break;
|
||||
case 0x0:
|
||||
rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
|
||||
|
||||
report = p_drvinfo->cfosho[0] & 0x60;
|
||||
report = report >> 5;
|
||||
switch (report) {
|
||||
case 0x3:
|
||||
rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1);
|
||||
break;
|
||||
case 0x2:
|
||||
rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1);
|
||||
break;
|
||||
case 0x1:
|
||||
rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1);
|
||||
break;
|
||||
case 0x0:
|
||||
rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
|
||||
/* CCK gain is smaller than OFDM/MCS gain, */
|
||||
/* so we add gain diff by experiences, the val is 6 */
|
||||
pwdb_all += 6;
|
||||
if (pwdb_all > 100)
|
||||
pwdb_all = 100;
|
||||
/* modify the offset to make the same gain index with OFDM. */
|
||||
if (pwdb_all > 34 && pwdb_all <= 42)
|
||||
pwdb_all -= 2;
|
||||
else if (pwdb_all > 26 && pwdb_all <= 34)
|
||||
pwdb_all -= 6;
|
||||
else if (pwdb_all > 14 && pwdb_all <= 26)
|
||||
pwdb_all -= 8;
|
||||
else if (pwdb_all > 4 && pwdb_all <= 14)
|
||||
pwdb_all -= 4;
|
||||
pstats->rx_pwdb_all = pwdb_all;
|
||||
pstats->recvsignalpower = rx_pwr_all;
|
||||
if (packet_match_bssid) {
|
||||
u8 sq;
|
||||
|
||||
if (pstats->rx_pwdb_all > 40) {
|
||||
sq = 100;
|
||||
} else {
|
||||
sq = cck_buf->sq_rpt;
|
||||
if (sq > 64)
|
||||
sq = 0;
|
||||
else if (sq < 20)
|
||||
sq = 100;
|
||||
else
|
||||
sq = ((64 - sq) * 100) / 44;
|
||||
}
|
||||
pstats->signalquality = sq;
|
||||
pstats->rx_mimo_sig_qual[0] = sq;
|
||||
pstats->rx_mimo_sig_qual[1] = -1;
|
||||
}
|
||||
} else {
|
||||
rtlpriv->dm.rfpath_rxenable[0] = true;
|
||||
rtlpriv->dm.rfpath_rxenable[1] = true;
|
||||
for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) {
|
||||
if (rtlpriv->dm.rfpath_rxenable[i])
|
||||
rf_rx_num++;
|
||||
rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & 0x3f) * 2)
|
||||
- 110;
|
||||
rssi = rtl_query_rxpwrpercentage(rx_pwr[i]);
|
||||
total_rssi += rssi;
|
||||
rtlpriv->stats.rx_snr_db[i] =
|
||||
(long)(p_drvinfo->rxsnr[i] / 2);
|
||||
if (packet_match_bssid)
|
||||
pstats->rx_mimo_signalstrength[i] = (u8)rssi;
|
||||
}
|
||||
rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 106;
|
||||
pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
|
||||
pstats->rx_pwdb_all = pwdb_all;
|
||||
pstats->rxpower = rx_pwr_all;
|
||||
pstats->recvsignalpower = rx_pwr_all;
|
||||
if (get_rx_desc_rxht(pdesc) && rxmcs >= DESC_RATEMCS8 &&
|
||||
rxmcs <= DESC_RATEMCS15)
|
||||
max_spatial_stream = 2;
|
||||
else
|
||||
max_spatial_stream = 1;
|
||||
for (i = 0; i < max_spatial_stream; i++) {
|
||||
evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]);
|
||||
if (packet_match_bssid) {
|
||||
if (i == 0)
|
||||
pstats->signalquality =
|
||||
(u8)(evm & 0xff);
|
||||
pstats->rx_mimo_sig_qual[i] =
|
||||
(u8)(evm & 0xff);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_cck_rate)
|
||||
pstats->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
|
||||
pwdb_all));
|
||||
else if (rf_rx_num != 0)
|
||||
pstats->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
|
||||
total_rssi /= rf_rx_num));
|
||||
}
|
||||
|
||||
static void rtl92d_loop_over_paths(struct ieee80211_hw *hw,
|
||||
struct rtl_stats *pstats)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &rtlpriv->phy;
|
||||
u8 rfpath;
|
||||
|
||||
for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
|
||||
rfpath++) {
|
||||
if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
|
||||
rtlpriv->stats.rx_rssi_percentage[rfpath] =
|
||||
pstats->rx_mimo_signalstrength[rfpath];
|
||||
}
|
||||
if (pstats->rx_mimo_signalstrength[rfpath] >
|
||||
rtlpriv->stats.rx_rssi_percentage[rfpath]) {
|
||||
rtlpriv->stats.rx_rssi_percentage[rfpath] =
|
||||
((rtlpriv->stats.rx_rssi_percentage[rfpath] *
|
||||
(RX_SMOOTH_FACTOR - 1)) +
|
||||
(pstats->rx_mimo_signalstrength[rfpath])) /
|
||||
(RX_SMOOTH_FACTOR);
|
||||
rtlpriv->stats.rx_rssi_percentage[rfpath] =
|
||||
rtlpriv->stats.rx_rssi_percentage[rfpath] + 1;
|
||||
} else {
|
||||
rtlpriv->stats.rx_rssi_percentage[rfpath] =
|
||||
((rtlpriv->stats.rx_rssi_percentage[rfpath] *
|
||||
(RX_SMOOTH_FACTOR - 1)) +
|
||||
(pstats->rx_mimo_signalstrength[rfpath])) /
|
||||
(RX_SMOOTH_FACTOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void _rtl92de_process_ui_rssi(struct ieee80211_hw *hw,
|
||||
struct rtl_stats *pstats)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rt_smooth_data *ui_rssi;
|
||||
u32 last_rssi, tmpval;
|
||||
|
||||
if (!pstats->packet_toself && !pstats->packet_beacon)
|
||||
return;
|
||||
|
||||
ui_rssi = &rtlpriv->stats.ui_rssi;
|
||||
|
||||
rtlpriv->stats.rssi_calculate_cnt++;
|
||||
if (ui_rssi->total_num++ >= PHY_RSSI_SLID_WIN_MAX) {
|
||||
ui_rssi->total_num = PHY_RSSI_SLID_WIN_MAX;
|
||||
last_rssi = ui_rssi->elements[ui_rssi->index];
|
||||
ui_rssi->total_val -= last_rssi;
|
||||
}
|
||||
ui_rssi->total_val += pstats->signalstrength;
|
||||
ui_rssi->elements[ui_rssi->index++] = pstats->signalstrength;
|
||||
if (ui_rssi->index >= PHY_RSSI_SLID_WIN_MAX)
|
||||
ui_rssi->index = 0;
|
||||
tmpval = ui_rssi->total_val / ui_rssi->total_num;
|
||||
rtlpriv->stats.signal_strength = _rtl92de_translate_todbm(hw, (u8)tmpval);
|
||||
pstats->rssi = rtlpriv->stats.signal_strength;
|
||||
|
||||
if (!pstats->is_cck && pstats->packet_toself)
|
||||
rtl92d_loop_over_paths(hw, pstats);
|
||||
}
|
||||
|
||||
static void _rtl92de_update_rxsignalstatistics(struct ieee80211_hw *hw,
|
||||
struct rtl_stats *pstats)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
int weighting = 0;
|
||||
|
||||
if (rtlpriv->stats.recv_signal_power == 0)
|
||||
rtlpriv->stats.recv_signal_power = pstats->recvsignalpower;
|
||||
if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power)
|
||||
weighting = 5;
|
||||
else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power)
|
||||
weighting = (-5);
|
||||
rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power *
|
||||
5 + pstats->recvsignalpower + weighting) / 6;
|
||||
}
|
||||
|
||||
static void _rtl92de_process_pwdb(struct ieee80211_hw *hw,
|
||||
struct rtl_stats *pstats)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
long undec_sm_pwdb;
|
||||
|
||||
if (mac->opmode == NL80211_IFTYPE_ADHOC ||
|
||||
mac->opmode == NL80211_IFTYPE_AP)
|
||||
return;
|
||||
|
||||
undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
|
||||
|
||||
if (pstats->packet_toself || pstats->packet_beacon) {
|
||||
if (undec_sm_pwdb < 0)
|
||||
undec_sm_pwdb = pstats->rx_pwdb_all;
|
||||
if (pstats->rx_pwdb_all > (u32)undec_sm_pwdb) {
|
||||
undec_sm_pwdb = (((undec_sm_pwdb) *
|
||||
(RX_SMOOTH_FACTOR - 1)) +
|
||||
(pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
|
||||
undec_sm_pwdb = undec_sm_pwdb + 1;
|
||||
} else {
|
||||
undec_sm_pwdb = (((undec_sm_pwdb) *
|
||||
(RX_SMOOTH_FACTOR - 1)) +
|
||||
(pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
|
||||
}
|
||||
rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb;
|
||||
_rtl92de_update_rxsignalstatistics(hw, pstats);
|
||||
}
|
||||
}
|
||||
|
||||
static void rtl92d_loop_over_streams(struct ieee80211_hw *hw,
|
||||
struct rtl_stats *pstats)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
int stream;
|
||||
|
||||
for (stream = 0; stream < 2; stream++) {
|
||||
if (pstats->rx_mimo_sig_qual[stream] != -1) {
|
||||
if (rtlpriv->stats.rx_evm_percentage[stream] == 0) {
|
||||
rtlpriv->stats.rx_evm_percentage[stream] =
|
||||
pstats->rx_mimo_sig_qual[stream];
|
||||
}
|
||||
rtlpriv->stats.rx_evm_percentage[stream] =
|
||||
((rtlpriv->stats.rx_evm_percentage[stream]
|
||||
* (RX_SMOOTH_FACTOR - 1)) +
|
||||
(pstats->rx_mimo_sig_qual[stream] * 1)) /
|
||||
(RX_SMOOTH_FACTOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void _rtl92de_process_ui_link_quality(struct ieee80211_hw *hw,
|
||||
struct rtl_stats *pstats)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rt_smooth_data *ui_link_quality;
|
||||
u32 last_evm, tmpval;
|
||||
|
||||
if (pstats->signalquality == 0)
|
||||
return;
|
||||
if (!pstats->packet_toself && !pstats->packet_beacon)
|
||||
return;
|
||||
|
||||
ui_link_quality = &rtlpriv->stats.ui_link_quality;
|
||||
|
||||
if (ui_link_quality->total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX) {
|
||||
ui_link_quality->total_num = PHY_LINKQUALITY_SLID_WIN_MAX;
|
||||
last_evm = ui_link_quality->elements[ui_link_quality->index];
|
||||
ui_link_quality->total_val -= last_evm;
|
||||
}
|
||||
ui_link_quality->total_val += pstats->signalquality;
|
||||
ui_link_quality->elements[ui_link_quality->index++] = pstats->signalquality;
|
||||
if (ui_link_quality->index >= PHY_LINKQUALITY_SLID_WIN_MAX)
|
||||
ui_link_quality->index = 0;
|
||||
tmpval = ui_link_quality->total_val / ui_link_quality->total_num;
|
||||
rtlpriv->stats.signal_quality = tmpval;
|
||||
rtlpriv->stats.last_sigstrength_inpercent = tmpval;
|
||||
rtl92d_loop_over_streams(hw, pstats);
|
||||
}
|
||||
|
||||
static void _rtl92de_process_phyinfo(struct ieee80211_hw *hw,
|
||||
u8 *buffer,
|
||||
struct rtl_stats *pcurrent_stats)
|
||||
{
|
||||
if (!pcurrent_stats->packet_matchbssid &&
|
||||
!pcurrent_stats->packet_beacon)
|
||||
return;
|
||||
|
||||
_rtl92de_process_ui_rssi(hw, pcurrent_stats);
|
||||
_rtl92de_process_pwdb(hw, pcurrent_stats);
|
||||
_rtl92de_process_ui_link_quality(hw, pcurrent_stats);
|
||||
}
|
||||
|
||||
static void _rtl92de_translate_rx_signal_stuff(struct ieee80211_hw *hw,
|
||||
struct sk_buff *skb,
|
||||
struct rtl_stats *pstats,
|
||||
__le32 *pdesc,
|
||||
struct rx_fwinfo_92d *p_drvinfo)
|
||||
{
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct ieee80211_hdr *hdr;
|
||||
bool packet_matchbssid;
|
||||
bool packet_beacon;
|
||||
bool packet_toself;
|
||||
u16 type, cfc;
|
||||
u8 *tmp_buf;
|
||||
u8 *praddr;
|
||||
__le16 fc;
|
||||
|
||||
tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
|
||||
hdr = (struct ieee80211_hdr *)tmp_buf;
|
||||
fc = hdr->frame_control;
|
||||
cfc = le16_to_cpu(fc);
|
||||
type = WLAN_FC_GET_TYPE(fc);
|
||||
praddr = hdr->addr1;
|
||||
packet_matchbssid = ((type != IEEE80211_FTYPE_CTL) &&
|
||||
ether_addr_equal(mac->bssid,
|
||||
(cfc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
|
||||
(cfc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
|
||||
hdr->addr3) &&
|
||||
(!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
|
||||
packet_toself = packet_matchbssid &&
|
||||
ether_addr_equal(praddr, rtlefuse->dev_addr);
|
||||
packet_beacon = ieee80211_is_beacon(fc);
|
||||
_rtl92de_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
|
||||
packet_matchbssid, packet_toself,
|
||||
packet_beacon);
|
||||
_rtl92de_process_phyinfo(hw, tmp_buf, pstats);
|
||||
}
|
||||
|
||||
bool rtl92de_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
u8 *pdesc8, struct sk_buff *skb)
|
||||
{
|
||||
__le32 *pdesc = (__le32 *)pdesc8;
|
||||
struct rx_fwinfo_92d *p_drvinfo;
|
||||
u32 phystatus = get_rx_desc_physt(pdesc);
|
||||
|
||||
stats->length = (u16)get_rx_desc_pkt_len(pdesc);
|
||||
stats->rx_drvinfo_size = (u8)get_rx_desc_drv_info_size(pdesc) *
|
||||
RX_DRV_INFO_SIZE_UNIT;
|
||||
stats->rx_bufshift = (u8)(get_rx_desc_shift(pdesc) & 0x03);
|
||||
stats->icv = (u16)get_rx_desc_icv(pdesc);
|
||||
stats->crc = (u16)get_rx_desc_crc32(pdesc);
|
||||
stats->hwerror = (stats->crc | stats->icv);
|
||||
stats->decrypted = !get_rx_desc_swdec(pdesc) &&
|
||||
get_rx_desc_enc_type(pdesc) != RX_DESC_ENC_NONE;
|
||||
stats->rate = (u8)get_rx_desc_rxmcs(pdesc);
|
||||
stats->shortpreamble = (u16)get_rx_desc_splcp(pdesc);
|
||||
stats->isampdu = (bool)(get_rx_desc_paggr(pdesc) == 1);
|
||||
stats->isfirst_ampdu = (bool)((get_rx_desc_paggr(pdesc) == 1) &&
|
||||
(get_rx_desc_faggr(pdesc) == 1));
|
||||
stats->timestamp_low = get_rx_desc_tsfl(pdesc);
|
||||
stats->rx_is40mhzpacket = (bool)get_rx_desc_bw(pdesc);
|
||||
stats->is_ht = (bool)get_rx_desc_rxht(pdesc);
|
||||
rx_status->freq = hw->conf.chandef.chan->center_freq;
|
||||
rx_status->band = hw->conf.chandef.chan->band;
|
||||
if (get_rx_desc_crc32(pdesc))
|
||||
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||
if (get_rx_desc_bw(pdesc))
|
||||
rx_status->bw = RATE_INFO_BW_40;
|
||||
if (get_rx_desc_rxht(pdesc))
|
||||
rx_status->encoding = RX_ENC_HT;
|
||||
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||
if (stats->decrypted)
|
||||
rx_status->flag |= RX_FLAG_DECRYPTED;
|
||||
rx_status->rate_idx = rtlwifi_rate_mapping(hw, stats->is_ht,
|
||||
false, stats->rate);
|
||||
rx_status->mactime = get_rx_desc_tsfl(pdesc);
|
||||
if (phystatus) {
|
||||
p_drvinfo = (struct rx_fwinfo_92d *)(skb->data +
|
||||
stats->rx_bufshift);
|
||||
_rtl92de_translate_rx_signal_stuff(hw, skb, stats, pdesc,
|
||||
p_drvinfo);
|
||||
}
|
||||
/*rx_status->qual = stats->signal; */
|
||||
rx_status->signal = stats->recvsignalpower + 10;
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92de_rx_query_desc);
|
||||
|
||||
void rtl92de_set_desc(struct ieee80211_hw *hw, u8 *pdesc8, bool istx,
|
||||
u8 desc_name, u8 *val)
|
||||
{
|
||||
__le32 *pdesc = (__le32 *)pdesc8;
|
||||
|
||||
if (istx) {
|
||||
switch (desc_name) {
|
||||
case HW_DESC_OWN:
|
||||
wmb();
|
||||
set_tx_desc_own(pdesc, 1);
|
||||
break;
|
||||
case HW_DESC_TX_NEXTDESC_ADDR:
|
||||
set_tx_desc_next_desc_address(pdesc, *(u32 *)val);
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(true, "rtl8192de: ERR txdesc :%d not processed\n",
|
||||
desc_name);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (desc_name) {
|
||||
case HW_DESC_RXOWN:
|
||||
wmb();
|
||||
set_rx_desc_own(pdesc, 1);
|
||||
break;
|
||||
case HW_DESC_RXBUFF_ADDR:
|
||||
set_rx_desc_buff_addr(pdesc, *(u32 *)val);
|
||||
break;
|
||||
case HW_DESC_RXPKT_LEN:
|
||||
set_rx_desc_pkt_len(pdesc, *(u32 *)val);
|
||||
break;
|
||||
case HW_DESC_RXERO:
|
||||
set_rx_desc_eor(pdesc, 1);
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(true, "rtl8192de: ERR rxdesc :%d not processed\n",
|
||||
desc_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92de_set_desc);
|
||||
|
||||
u64 rtl92de_get_desc(struct ieee80211_hw *hw,
|
||||
u8 *p_desc8, bool istx, u8 desc_name)
|
||||
{
|
||||
__le32 *p_desc = (__le32 *)p_desc8;
|
||||
u32 ret = 0;
|
||||
|
||||
if (istx) {
|
||||
switch (desc_name) {
|
||||
case HW_DESC_OWN:
|
||||
ret = get_tx_desc_own(p_desc);
|
||||
break;
|
||||
case HW_DESC_TXBUFF_ADDR:
|
||||
ret = get_tx_desc_tx_buffer_address(p_desc);
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(true, "rtl8192de: ERR txdesc :%d not processed\n",
|
||||
desc_name);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (desc_name) {
|
||||
case HW_DESC_OWN:
|
||||
ret = get_rx_desc_own(p_desc);
|
||||
break;
|
||||
case HW_DESC_RXPKT_LEN:
|
||||
ret = get_rx_desc_pkt_len(p_desc);
|
||||
break;
|
||||
case HW_DESC_RXBUFF_ADDR:
|
||||
ret = get_rx_desc_buff_addr(p_desc);
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(true, "rtl8192de: ERR rxdesc :%d not processed\n",
|
||||
desc_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl92de_get_desc);
|
405
drivers/net/wireless/realtek/rtlwifi/rtl8192d/trx_common.h
Normal file
405
drivers/net/wireless/realtek/rtlwifi/rtl8192d/trx_common.h
Normal file
@ -0,0 +1,405 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright(c) 2009-2012 Realtek Corporation.*/
|
||||
|
||||
#ifndef __RTL92D_TRX_COMMON_H__
|
||||
#define __RTL92D_TRX_COMMON_H__
|
||||
|
||||
#define RX_DRV_INFO_SIZE_UNIT 8
|
||||
|
||||
enum rtl92d_rx_desc_enc {
|
||||
RX_DESC_ENC_NONE = 0,
|
||||
RX_DESC_ENC_WEP40 = 1,
|
||||
RX_DESC_ENC_TKIP_WO_MIC = 2,
|
||||
RX_DESC_ENC_TKIP_MIC = 3,
|
||||
RX_DESC_ENC_AES = 4,
|
||||
RX_DESC_ENC_WEP104 = 5,
|
||||
};
|
||||
|
||||
/* macros to read/write various fields in RX or TX descriptors */
|
||||
|
||||
static inline void set_tx_desc_pkt_size(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits(__pdesc, __val, GENMASK(15, 0));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_offset(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits(__pdesc, __val, GENMASK(23, 16));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_htc(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits(__pdesc, __val, BIT(25));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_last_seg(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits(__pdesc, __val, BIT(26));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_first_seg(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits(__pdesc, __val, BIT(27));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_linip(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits(__pdesc, __val, BIT(28));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_own(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits(__pdesc, __val, BIT(31));
|
||||
}
|
||||
|
||||
static inline u32 get_tx_desc_own(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*__pdesc, BIT(31));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_macid(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 1), __val, GENMASK(4, 0));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_agg_enable(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 1), __val, BIT(5));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_rdg_enable(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 1), __val, BIT(7));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_queue_sel(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 1), __val, GENMASK(12, 8));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_rate_id(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 1), __val, GENMASK(19, 16));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_sec_type(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 1), __val, GENMASK(23, 22));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_pkt_offset(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 1), __val, GENMASK(30, 26));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_more_frag(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 2), __val, BIT(17));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_ampdu_density(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 2), __val, GENMASK(22, 20));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_seq(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 3), __val, GENMASK(27, 16));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_pkt_id(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 3), __val, GENMASK(31, 28));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_rts_rate(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, GENMASK(4, 0));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_qos(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, BIT(6));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_hwseq_en(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, BIT(7));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_use_rate(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, BIT(8));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_disable_fb(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, BIT(10));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_cts2self(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, BIT(11));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_rts_enable(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, BIT(12));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_hw_rts_enable(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, BIT(13));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_tx_sub_carrier(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, GENMASK(21, 20));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_data_bw(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, BIT(25));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_rts_short(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, BIT(26));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_rts_bw(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, BIT(27));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_rts_sc(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, GENMASK(29, 28));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_rts_stbc(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, GENMASK(31, 30));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_tx_rate(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 5), __val, GENMASK(5, 0));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_data_shortgi(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 5), __val, BIT(6));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_data_rate_fb_limit(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 5), __val, GENMASK(12, 8));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_rts_rate_fb_limit(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 5), __val, GENMASK(16, 13));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_max_agg_num(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 6), __val, GENMASK(15, 11));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_tx_buffer_size(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 7), __val, GENMASK(15, 0));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_tx_buffer_address(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
*(__pdesc + 8) = cpu_to_le32(__val);
|
||||
}
|
||||
|
||||
static inline u32 get_tx_desc_tx_buffer_address(__le32 *__pdesc)
|
||||
{
|
||||
return le32_to_cpu(*(__pdesc + 8));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_next_desc_address(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
*(__pdesc + 10) = cpu_to_le32(__val);
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_pkt_len(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*__pdesc, GENMASK(13, 0));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_crc32(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*__pdesc, BIT(14));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_icv(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*__pdesc, BIT(15));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_drv_info_size(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*__pdesc, GENMASK(19, 16));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_enc_type(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*__pdesc, GENMASK(22, 20));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_shift(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*__pdesc, GENMASK(25, 24));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_physt(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*__pdesc, BIT(26));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_swdec(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*__pdesc, BIT(27));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_own(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*__pdesc, BIT(31));
|
||||
}
|
||||
|
||||
static inline void set_rx_desc_pkt_len(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits(__pdesc, __val, GENMASK(13, 0));
|
||||
}
|
||||
|
||||
static inline void set_rx_desc_eor(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits(__pdesc, __val, BIT(30));
|
||||
}
|
||||
|
||||
static inline void set_rx_desc_own(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits(__pdesc, __val, BIT(31));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_paggr(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*(__pdesc + 1), BIT(14));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_faggr(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*(__pdesc + 1), BIT(15));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_rxmcs(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*(__pdesc + 3), GENMASK(5, 0));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_rxht(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*(__pdesc + 3), BIT(6));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_splcp(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*(__pdesc + 3), BIT(8));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_bw(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*(__pdesc + 3), BIT(9));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_tsfl(__le32 *__pdesc)
|
||||
{
|
||||
return le32_to_cpu(*(__pdesc + 5));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_buff_addr(__le32 *__pdesc)
|
||||
{
|
||||
return le32_to_cpu(*(__pdesc + 6));
|
||||
}
|
||||
|
||||
static inline void set_rx_desc_buff_addr(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
*(__pdesc + 6) = cpu_to_le32(__val);
|
||||
}
|
||||
|
||||
/* For 92D early mode */
|
||||
static inline void set_earlymode_pktnum(__le32 *__paddr, u32 __value)
|
||||
{
|
||||
le32p_replace_bits(__paddr, __value, GENMASK(2, 0));
|
||||
}
|
||||
|
||||
static inline void set_earlymode_len0(__le32 *__paddr, u32 __value)
|
||||
{
|
||||
le32p_replace_bits(__paddr, __value, GENMASK(15, 4));
|
||||
}
|
||||
|
||||
static inline void set_earlymode_len1(__le32 *__paddr, u32 __value)
|
||||
{
|
||||
le32p_replace_bits(__paddr, __value, GENMASK(27, 16));
|
||||
}
|
||||
|
||||
static inline void set_earlymode_len2_1(__le32 *__paddr, u32 __value)
|
||||
{
|
||||
le32p_replace_bits(__paddr, __value, GENMASK(31, 28));
|
||||
}
|
||||
|
||||
static inline void set_earlymode_len2_2(__le32 *__paddr, u32 __value)
|
||||
{
|
||||
le32p_replace_bits((__paddr + 1), __value, GENMASK(7, 0));
|
||||
}
|
||||
|
||||
static inline void set_earlymode_len3(__le32 *__paddr, u32 __value)
|
||||
{
|
||||
le32p_replace_bits((__paddr + 1), __value, GENMASK(19, 8));
|
||||
}
|
||||
|
||||
static inline void set_earlymode_len4(__le32 *__paddr, u32 __value)
|
||||
{
|
||||
le32p_replace_bits((__paddr + 1), __value, GENMASK(31, 20));
|
||||
}
|
||||
|
||||
struct rx_fwinfo_92d {
|
||||
u8 gain_trsw[4];
|
||||
u8 pwdb_all;
|
||||
u8 cfosho[4];
|
||||
u8 cfotail[4];
|
||||
s8 rxevm[2];
|
||||
s8 rxsnr[4];
|
||||
u8 pdsnr[2];
|
||||
u8 csi_current[2];
|
||||
u8 csi_target[2];
|
||||
u8 sigevm;
|
||||
u8 max_ex_pwr;
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
u8 ex_intf_flag:1;
|
||||
u8 sgi_en:1;
|
||||
u8 rxsc:2;
|
||||
u8 reserve:4;
|
||||
#else
|
||||
u8 reserve:4;
|
||||
u8 rxsc:2;
|
||||
u8 sgi_en:1;
|
||||
u8 ex_intf_flag:1;
|
||||
#endif
|
||||
} __packed;
|
||||
|
||||
bool rtl92de_rx_query_desc(struct ieee80211_hw *hw,
|
||||
struct rtl_stats *stats,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
u8 *pdesc, struct sk_buff *skb);
|
||||
void rtl92de_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
|
||||
u8 desc_name, u8 *val);
|
||||
u64 rtl92de_get_desc(struct ieee80211_hw *hw,
|
||||
u8 *p_desc, bool istx, u8 desc_name);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -4,94 +4,7 @@
|
||||
#ifndef __RTL92C_DM_H__
|
||||
#define __RTL92C_DM_H__
|
||||
|
||||
#define HAL_DM_DIG_DISABLE BIT(0)
|
||||
#define HAL_DM_HIPWR_DISABLE BIT(1)
|
||||
|
||||
#define OFDM_TABLE_LENGTH 37
|
||||
#define OFDM_TABLE_SIZE_92D 43
|
||||
#define CCK_TABLE_LENGTH 33
|
||||
|
||||
#define CCK_TABLE_SIZE 33
|
||||
|
||||
#define BW_AUTO_SWITCH_HIGH_LOW 25
|
||||
#define BW_AUTO_SWITCH_LOW_HIGH 30
|
||||
|
||||
#define DM_DIG_FA_UPPER 0x32
|
||||
#define DM_DIG_FA_LOWER 0x20
|
||||
#define DM_DIG_FA_TH0 0x100
|
||||
#define DM_DIG_FA_TH1 0x400
|
||||
#define DM_DIG_FA_TH2 0x600
|
||||
|
||||
#define RXPATHSELECTION_SS_TH_LOW 30
|
||||
#define RXPATHSELECTION_DIFF_TH 18
|
||||
|
||||
#define DM_RATR_STA_INIT 0
|
||||
#define DM_RATR_STA_HIGH 1
|
||||
#define DM_RATR_STA_MIDDLE 2
|
||||
#define DM_RATR_STA_LOW 3
|
||||
|
||||
#define CTS2SELF_THVAL 30
|
||||
#define REGC38_TH 20
|
||||
|
||||
#define WAIOTTHVAL 25
|
||||
|
||||
#define TXHIGHPWRLEVEL_NORMAL 0
|
||||
#define TXHIGHPWRLEVEL_LEVEL1 1
|
||||
#define TXHIGHPWRLEVEL_LEVEL2 2
|
||||
#define TXHIGHPWRLEVEL_BT1 3
|
||||
#define TXHIGHPWRLEVEL_BT2 4
|
||||
|
||||
#define DM_TYPE_BYFW 0
|
||||
#define DM_TYPE_BYDRIVER 1
|
||||
|
||||
#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
|
||||
#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
|
||||
#define INDEX_MAPPING_NUM 13
|
||||
|
||||
struct swat {
|
||||
u8 failure_cnt;
|
||||
u8 try_flag;
|
||||
u8 stop_trying;
|
||||
long pre_rssi;
|
||||
long trying_threshold;
|
||||
u8 cur_antenna;
|
||||
u8 pre_antenna;
|
||||
};
|
||||
|
||||
enum tag_dynamic_init_gain_operation_type_definition {
|
||||
DIG_TYPE_THRESH_HIGH = 0,
|
||||
DIG_TYPE_THRESH_LOW = 1,
|
||||
DIG_TYPE_BACKOFF = 2,
|
||||
DIG_TYPE_RX_GAIN_MIN = 3,
|
||||
DIG_TYPE_RX_GAIN_MAX = 4,
|
||||
DIG_TYPE_ENABLE = 5,
|
||||
DIG_TYPE_DISABLE = 6,
|
||||
DIG_OP_TYPE_MAX
|
||||
};
|
||||
|
||||
enum dm_1r_cca {
|
||||
CCA_1R = 0,
|
||||
CCA_2R = 1,
|
||||
CCA_MAX = 2,
|
||||
};
|
||||
|
||||
enum dm_rf {
|
||||
RF_SAVE = 0,
|
||||
RF_NORMAL = 1,
|
||||
RF_MAX = 2,
|
||||
};
|
||||
|
||||
enum dm_sw_ant_switch {
|
||||
ANS_ANTENNA_B = 1,
|
||||
ANS_ANTENNA_A = 2,
|
||||
ANS_ANTENNA_MAX = 3,
|
||||
};
|
||||
|
||||
void rtl92d_dm_init(struct ieee80211_hw *hw);
|
||||
void rtl92d_dm_watchdog(struct ieee80211_hw *hw);
|
||||
void rtl92d_dm_init_edca_turbo(struct ieee80211_hw *hw);
|
||||
void rtl92d_dm_write_dig(struct ieee80211_hw *hw);
|
||||
void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw);
|
||||
void rtl92d_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);
|
||||
void rtl92de_dm_init(struct ieee80211_hw *hw);
|
||||
void rtl92de_dm_watchdog(struct ieee80211_hw *hw);
|
||||
|
||||
#endif
|
||||
|
@ -5,157 +5,12 @@
|
||||
#include "../pci.h"
|
||||
#include "../base.h"
|
||||
#include "../efuse.h"
|
||||
#include "reg.h"
|
||||
#include "def.h"
|
||||
#include "../rtl8192d/reg.h"
|
||||
#include "../rtl8192d/def.h"
|
||||
#include "../rtl8192d/fw_common.h"
|
||||
#include "fw.h"
|
||||
#include "sw.h"
|
||||
|
||||
static bool _rtl92d_is_fw_downloaded(struct rtl_priv *rtlpriv)
|
||||
{
|
||||
return (rtl_read_dword(rtlpriv, REG_MCUFWDL) & MCUFWDL_RDY) ?
|
||||
true : false;
|
||||
}
|
||||
|
||||
static void _rtl92d_enable_fw_download(struct ieee80211_hw *hw, bool enable)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 tmp;
|
||||
|
||||
if (enable) {
|
||||
tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
|
||||
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04);
|
||||
tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
|
||||
rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
|
||||
tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
|
||||
rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
|
||||
} else {
|
||||
tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
|
||||
rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
|
||||
/* Reserved for fw extension.
|
||||
* 0x81[7] is used for mac0 status ,
|
||||
* so don't write this reg here
|
||||
* rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);*/
|
||||
}
|
||||
}
|
||||
|
||||
static void _rtl92d_write_fw(struct ieee80211_hw *hw,
|
||||
enum version_8192d version, u8 *buffer, u32 size)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
u8 *bufferptr = buffer;
|
||||
u32 pagenums, remainsize;
|
||||
u32 page, offset;
|
||||
|
||||
rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size);
|
||||
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE)
|
||||
rtl_fill_dummy(bufferptr, &size);
|
||||
pagenums = size / FW_8192D_PAGE_SIZE;
|
||||
remainsize = size % FW_8192D_PAGE_SIZE;
|
||||
if (pagenums > 8)
|
||||
pr_err("Page numbers should not greater then 8\n");
|
||||
for (page = 0; page < pagenums; page++) {
|
||||
offset = page * FW_8192D_PAGE_SIZE;
|
||||
rtl_fw_page_write(hw, page, (bufferptr + offset),
|
||||
FW_8192D_PAGE_SIZE);
|
||||
}
|
||||
if (remainsize) {
|
||||
offset = pagenums * FW_8192D_PAGE_SIZE;
|
||||
page = pagenums;
|
||||
rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize);
|
||||
}
|
||||
}
|
||||
|
||||
static int _rtl92d_fw_free_to_go(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u32 counter = 0;
|
||||
u32 value32;
|
||||
|
||||
do {
|
||||
value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
|
||||
} while ((counter++ < FW_8192D_POLLING_TIMEOUT_COUNT) &&
|
||||
(!(value32 & FWDL_CHKSUM_RPT)));
|
||||
if (counter >= FW_8192D_POLLING_TIMEOUT_COUNT) {
|
||||
pr_err("chksum report fail! REG_MCUFWDL:0x%08x\n",
|
||||
value32);
|
||||
return -EIO;
|
||||
}
|
||||
value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
|
||||
value32 |= MCUFWDL_RDY;
|
||||
rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtl92d_firmware_selfreset(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 u1b_tmp;
|
||||
u8 delay = 100;
|
||||
|
||||
/* Set (REG_HMETFR + 3) to 0x20 is reset 8051 */
|
||||
rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
|
||||
u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
|
||||
while (u1b_tmp & BIT(2)) {
|
||||
delay--;
|
||||
if (delay == 0)
|
||||
break;
|
||||
udelay(50);
|
||||
u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
|
||||
}
|
||||
WARN_ONCE((delay <= 0), "rtl8192de: 8051 reset failed!\n");
|
||||
rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
|
||||
"=====> 8051 reset success (%d)\n", delay);
|
||||
}
|
||||
|
||||
static int _rtl92d_fw_init(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
u32 counter;
|
||||
|
||||
rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, "FW already have download\n");
|
||||
/* polling for FW ready */
|
||||
counter = 0;
|
||||
do {
|
||||
if (rtlhal->interfaceindex == 0) {
|
||||
if (rtl_read_byte(rtlpriv, FW_MAC0_READY) &
|
||||
MAC0_READY) {
|
||||
rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
|
||||
"Polling FW ready success!! REG_MCUFWDL: 0x%x\n",
|
||||
rtl_read_byte(rtlpriv,
|
||||
FW_MAC0_READY));
|
||||
return 0;
|
||||
}
|
||||
udelay(5);
|
||||
} else {
|
||||
if (rtl_read_byte(rtlpriv, FW_MAC1_READY) &
|
||||
MAC1_READY) {
|
||||
rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
|
||||
"Polling FW ready success!! REG_MCUFWDL: 0x%x\n",
|
||||
rtl_read_byte(rtlpriv,
|
||||
FW_MAC1_READY));
|
||||
return 0;
|
||||
}
|
||||
udelay(5);
|
||||
}
|
||||
} while (counter++ < POLLING_READY_TIMEOUT_COUNT);
|
||||
|
||||
if (rtlhal->interfaceindex == 0) {
|
||||
rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
|
||||
"Polling FW ready fail!! MAC0 FW init not ready: 0x%x\n",
|
||||
rtl_read_byte(rtlpriv, FW_MAC0_READY));
|
||||
} else {
|
||||
rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
|
||||
"Polling FW ready fail!! MAC1 FW init not ready: 0x%x\n",
|
||||
rtl_read_byte(rtlpriv, FW_MAC1_READY));
|
||||
}
|
||||
rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
|
||||
"Polling FW ready fail!! REG_MCUFWDL:0x%08x\n",
|
||||
rtl_read_dword(rtlpriv, REG_MCUFWDL));
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rtl92d_download_fw(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
@ -189,7 +44,7 @@ int rtl92d_download_fw(struct ieee80211_hw *hw)
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
|
||||
fw_downloaded = _rtl92d_is_fw_downloaded(rtlpriv);
|
||||
fw_downloaded = rtl92d_is_fw_downloaded(rtlpriv);
|
||||
if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))
|
||||
fwdl_in_process = true;
|
||||
else
|
||||
@ -202,7 +57,7 @@ int rtl92d_download_fw(struct ieee80211_hw *hw)
|
||||
for (count = 0; count < 5000; count++) {
|
||||
udelay(500);
|
||||
spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
|
||||
fw_downloaded = _rtl92d_is_fw_downloaded(rtlpriv);
|
||||
fw_downloaded = rtl92d_is_fw_downloaded(rtlpriv);
|
||||
if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))
|
||||
fwdl_in_process = true;
|
||||
else
|
||||
@ -237,11 +92,11 @@ int rtl92d_download_fw(struct ieee80211_hw *hw)
|
||||
rtl92d_firmware_selfreset(hw);
|
||||
rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
|
||||
}
|
||||
_rtl92d_enable_fw_download(hw, true);
|
||||
_rtl92d_write_fw(hw, version, pfwdata, fwsize);
|
||||
_rtl92d_enable_fw_download(hw, false);
|
||||
rtl92d_enable_fw_download(hw, true);
|
||||
rtl92d_write_fw(hw, version, pfwdata, fwsize);
|
||||
rtl92d_enable_fw_download(hw, false);
|
||||
spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
|
||||
err = _rtl92d_fw_free_to_go(hw);
|
||||
err = rtl92d_fw_free_to_go(hw);
|
||||
/* download fw over,clear 0x1f[5] */
|
||||
value = rtl_read_byte(rtlpriv, 0x1f);
|
||||
value &= (~BIT(5));
|
||||
@ -250,207 +105,10 @@ int rtl92d_download_fw(struct ieee80211_hw *hw)
|
||||
if (err)
|
||||
pr_err("fw is not ready to run!\n");
|
||||
exit:
|
||||
err = _rtl92d_fw_init(hw);
|
||||
err = rtl92d_fw_init(hw);
|
||||
return err;
|
||||
}
|
||||
|
||||
static bool _rtl92d_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 val_hmetfr;
|
||||
bool result = false;
|
||||
|
||||
val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
|
||||
if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
|
||||
result = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
|
||||
u8 element_id, u32 cmd_len, u8 *cmdbuffer)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
u8 boxnum;
|
||||
u16 box_reg = 0, box_extreg = 0;
|
||||
u8 u1b_tmp;
|
||||
bool isfw_read = false;
|
||||
u8 buf_index = 0;
|
||||
bool bwrite_success = false;
|
||||
u8 wait_h2c_limmit = 100;
|
||||
u8 wait_writeh2c_limmit = 100;
|
||||
u8 boxcontent[4], boxextcontent[2];
|
||||
u32 h2c_waitcounter = 0;
|
||||
unsigned long flag;
|
||||
u8 idx;
|
||||
|
||||
if (ppsc->rfpwr_state == ERFOFF || ppsc->inactive_pwrstate == ERFOFF) {
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
"Return as RF is off!!!\n");
|
||||
return;
|
||||
}
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
|
||||
while (true) {
|
||||
spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
|
||||
if (rtlhal->h2c_setinprogress) {
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
"H2C set in progress! Wait to set..element_id(%d)\n",
|
||||
element_id);
|
||||
|
||||
while (rtlhal->h2c_setinprogress) {
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
|
||||
flag);
|
||||
h2c_waitcounter++;
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
"Wait 100 us (%d times)...\n",
|
||||
h2c_waitcounter);
|
||||
udelay(100);
|
||||
|
||||
if (h2c_waitcounter > 1000)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
|
||||
flag);
|
||||
}
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
|
||||
} else {
|
||||
rtlhal->h2c_setinprogress = true;
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (!bwrite_success) {
|
||||
wait_writeh2c_limmit--;
|
||||
if (wait_writeh2c_limmit == 0) {
|
||||
pr_err("Write H2C fail because no trigger for FW INT!\n");
|
||||
break;
|
||||
}
|
||||
boxnum = rtlhal->last_hmeboxnum;
|
||||
switch (boxnum) {
|
||||
case 0:
|
||||
box_reg = REG_HMEBOX_0;
|
||||
box_extreg = REG_HMEBOX_EXT_0;
|
||||
break;
|
||||
case 1:
|
||||
box_reg = REG_HMEBOX_1;
|
||||
box_extreg = REG_HMEBOX_EXT_1;
|
||||
break;
|
||||
case 2:
|
||||
box_reg = REG_HMEBOX_2;
|
||||
box_extreg = REG_HMEBOX_EXT_2;
|
||||
break;
|
||||
case 3:
|
||||
box_reg = REG_HMEBOX_3;
|
||||
box_extreg = REG_HMEBOX_EXT_3;
|
||||
break;
|
||||
default:
|
||||
pr_err("switch case %#x not processed\n",
|
||||
boxnum);
|
||||
break;
|
||||
}
|
||||
isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
|
||||
while (!isfw_read) {
|
||||
wait_h2c_limmit--;
|
||||
if (wait_h2c_limmit == 0) {
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
"Waiting too long for FW read clear HMEBox(%d)!\n",
|
||||
boxnum);
|
||||
break;
|
||||
}
|
||||
udelay(10);
|
||||
isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
|
||||
u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
"Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n",
|
||||
boxnum, u1b_tmp);
|
||||
}
|
||||
if (!isfw_read) {
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
"Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
|
||||
boxnum);
|
||||
break;
|
||||
}
|
||||
memset(boxcontent, 0, sizeof(boxcontent));
|
||||
memset(boxextcontent, 0, sizeof(boxextcontent));
|
||||
boxcontent[0] = element_id;
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
"Write element_id box_reg(%4x) = %2x\n",
|
||||
box_reg, element_id);
|
||||
switch (cmd_len) {
|
||||
case 1:
|
||||
boxcontent[0] &= ~(BIT(7));
|
||||
memcpy(boxcontent + 1, cmdbuffer + buf_index, 1);
|
||||
for (idx = 0; idx < 4; idx++)
|
||||
rtl_write_byte(rtlpriv, box_reg + idx,
|
||||
boxcontent[idx]);
|
||||
break;
|
||||
case 2:
|
||||
boxcontent[0] &= ~(BIT(7));
|
||||
memcpy(boxcontent + 1, cmdbuffer + buf_index, 2);
|
||||
for (idx = 0; idx < 4; idx++)
|
||||
rtl_write_byte(rtlpriv, box_reg + idx,
|
||||
boxcontent[idx]);
|
||||
break;
|
||||
case 3:
|
||||
boxcontent[0] &= ~(BIT(7));
|
||||
memcpy(boxcontent + 1, cmdbuffer + buf_index, 3);
|
||||
for (idx = 0; idx < 4; idx++)
|
||||
rtl_write_byte(rtlpriv, box_reg + idx,
|
||||
boxcontent[idx]);
|
||||
break;
|
||||
case 4:
|
||||
boxcontent[0] |= (BIT(7));
|
||||
memcpy(boxextcontent, cmdbuffer + buf_index, 2);
|
||||
memcpy(boxcontent + 1, cmdbuffer + buf_index + 2, 2);
|
||||
for (idx = 0; idx < 2; idx++)
|
||||
rtl_write_byte(rtlpriv, box_extreg + idx,
|
||||
boxextcontent[idx]);
|
||||
for (idx = 0; idx < 4; idx++)
|
||||
rtl_write_byte(rtlpriv, box_reg + idx,
|
||||
boxcontent[idx]);
|
||||
break;
|
||||
case 5:
|
||||
boxcontent[0] |= (BIT(7));
|
||||
memcpy(boxextcontent, cmdbuffer + buf_index, 2);
|
||||
memcpy(boxcontent + 1, cmdbuffer + buf_index + 2, 3);
|
||||
for (idx = 0; idx < 2; idx++)
|
||||
rtl_write_byte(rtlpriv, box_extreg + idx,
|
||||
boxextcontent[idx]);
|
||||
for (idx = 0; idx < 4; idx++)
|
||||
rtl_write_byte(rtlpriv, box_reg + idx,
|
||||
boxcontent[idx]);
|
||||
break;
|
||||
default:
|
||||
pr_err("switch case %#x not processed\n",
|
||||
cmd_len);
|
||||
break;
|
||||
}
|
||||
bwrite_success = true;
|
||||
rtlhal->last_hmeboxnum = boxnum + 1;
|
||||
if (rtlhal->last_hmeboxnum == 4)
|
||||
rtlhal->last_hmeboxnum = 0;
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
"pHalData->last_hmeboxnum = %d\n",
|
||||
rtlhal->last_hmeboxnum);
|
||||
}
|
||||
spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
|
||||
rtlhal->h2c_setinprogress = false;
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
|
||||
rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
|
||||
}
|
||||
|
||||
void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw,
|
||||
u8 element_id, u32 cmd_len, u8 *cmdbuffer)
|
||||
{
|
||||
u32 tmp_cmdbuf[2];
|
||||
|
||||
memset(tmp_cmdbuf, 0, 8);
|
||||
memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
|
||||
_rtl92d_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
static bool _rtl92d_cmd_send_packet(struct ieee80211_hw *hw,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
@ -599,7 +257,7 @@ void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
|
||||
struct sk_buff *skb = NULL;
|
||||
u32 totalpacketlen;
|
||||
bool rtstatus;
|
||||
u8 u1rsvdpageloc[3] = { 0 };
|
||||
u8 u1rsvdpageloc[3] = { PROBERSP_PG, PSPOLL_PG, NULL_PG };
|
||||
bool dlok = false;
|
||||
u8 *beacon;
|
||||
u8 *p_pspoll;
|
||||
@ -618,7 +276,6 @@ void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
|
||||
SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
|
||||
SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
|
||||
SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
|
||||
SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
|
||||
/*--------------------------------------------------------
|
||||
(3) null data
|
||||
---------------------------------------------------------*/
|
||||
@ -626,7 +283,6 @@ void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
|
||||
SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
|
||||
SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
|
||||
SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
|
||||
SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
|
||||
/*---------------------------------------------------------
|
||||
(4) probe response
|
||||
----------------------------------------------------------*/
|
||||
@ -634,7 +290,6 @@ void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
|
||||
SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
|
||||
SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
|
||||
SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
|
||||
SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
|
||||
totalpacketlen = TOTAL_RESERVED_PKT_LEN;
|
||||
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
"rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
|
||||
@ -663,11 +318,3 @@ void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
|
||||
rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
|
||||
"Set RSVD page location to Fw FAIL!!!!!!\n");
|
||||
}
|
||||
|
||||
void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
|
||||
{
|
||||
u8 u1_joinbssrpt_parm[1] = {0};
|
||||
|
||||
SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
|
||||
rtl92d_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
|
||||
}
|
||||
|
@ -4,44 +4,7 @@
|
||||
#ifndef __RTL92D__FW__H__
|
||||
#define __RTL92D__FW__H__
|
||||
|
||||
#define FW_8192D_START_ADDRESS 0x1000
|
||||
#define FW_8192D_PAGE_SIZE 4096
|
||||
#define FW_8192D_POLLING_TIMEOUT_COUNT 1000
|
||||
|
||||
#define IS_FW_HEADER_EXIST(_pfwhdr) \
|
||||
((GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFF0) == 0x92C0 || \
|
||||
(GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFF0) == 0x88C0 || \
|
||||
(GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D0 || \
|
||||
(GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D1 || \
|
||||
(GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D2 || \
|
||||
(GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D3)
|
||||
|
||||
/* Firmware Header(8-byte alinment required) */
|
||||
/* --- LONG WORD 0 ---- */
|
||||
#define GET_FIRMWARE_HDR_SIGNATURE(__fwhdr) \
|
||||
le32_get_bits(*(__le32 *)__fwhdr, GENMASK(15, 0))
|
||||
#define GET_FIRMWARE_HDR_VERSION(__fwhdr) \
|
||||
le32_get_bits(*(__le32 *)(__fwhdr + 4), GENMASK(15, 0))
|
||||
#define GET_FIRMWARE_HDR_SUB_VER(__fwhdr) \
|
||||
le32_get_bits(*(__le32 *)(__fwhdr + 4), GENMASK(23, 16))
|
||||
|
||||
#define pagenum_128(_len) \
|
||||
(u32)(((_len) >> 7) + ((_len) & 0x7F ? 1 : 0))
|
||||
|
||||
#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \
|
||||
*(u8 *)__ph2ccmd = __val;
|
||||
#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \
|
||||
*(u8 *)__ph2ccmd = __val;
|
||||
#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \
|
||||
*(u8 *)(__ph2ccmd + 1) = __val;
|
||||
#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \
|
||||
*(u8 *)(__ph2ccmd + 2) = __val;
|
||||
|
||||
int rtl92d_download_fw(struct ieee80211_hw *hw);
|
||||
void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
|
||||
u32 cmd_len, u8 *p_cmdbuffer);
|
||||
void rtl92d_firmware_selfreset(struct ieee80211_hw *hw);
|
||||
void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
|
||||
void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -5,7 +5,6 @@
|
||||
#define __RTL92DE_HW_H__
|
||||
|
||||
void rtl92de_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
|
||||
void rtl92de_read_eeprom_info(struct ieee80211_hw *hw);
|
||||
void rtl92de_interrupt_recognized(struct ieee80211_hw *hw,
|
||||
struct rtl_int *int_vec);
|
||||
int rtl92de_hw_init(struct ieee80211_hw *hw);
|
||||
@ -14,21 +13,11 @@ void rtl92de_enable_interrupt(struct ieee80211_hw *hw);
|
||||
void rtl92de_disable_interrupt(struct ieee80211_hw *hw);
|
||||
int rtl92de_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type);
|
||||
void rtl92de_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
|
||||
void rtl92de_set_qos(struct ieee80211_hw *hw, int aci);
|
||||
void rtl92de_set_beacon_related_registers(struct ieee80211_hw *hw);
|
||||
void rtl92de_set_beacon_interval(struct ieee80211_hw *hw);
|
||||
void rtl92de_update_interrupt_mask(struct ieee80211_hw *hw,
|
||||
u32 add_msr, u32 rm_msr);
|
||||
void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
|
||||
void rtl92de_update_hal_rate_tbl(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta, u8 rssi_level,
|
||||
bool update_bw);
|
||||
void rtl92de_update_channel_access_setting(struct ieee80211_hw *hw);
|
||||
bool rtl92de_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
|
||||
void rtl92de_enable_hw_security_config(struct ieee80211_hw *hw);
|
||||
void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index,
|
||||
u8 *p_macaddr, bool is_group, u8 enc_algo,
|
||||
bool is_wepkey, bool clear_all);
|
||||
|
||||
void rtl92de_write_dword_dbi(struct ieee80211_hw *hw, u16 offset, u32 value,
|
||||
u8 direct);
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include "../wifi.h"
|
||||
#include "../pci.h"
|
||||
#include "reg.h"
|
||||
#include "../rtl8192d/reg.h"
|
||||
#include "led.h"
|
||||
|
||||
void rtl92de_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -10,11 +10,8 @@
|
||||
|
||||
#define MAX_DOZE_WAITING_TIMES_9x 64
|
||||
|
||||
#define RT_CANNOT_IO(hw) false
|
||||
#define HIGHPOWER_RADIOA_ARRAYLEN 22
|
||||
|
||||
#define MAX_TOLERANCE 5
|
||||
|
||||
#define APK_BB_REG_NUM 5
|
||||
#define APK_AFE_REG_NUM 16
|
||||
#define APK_CURVE_REG_NUM 4
|
||||
@ -27,12 +24,8 @@
|
||||
#define RESET_CNT_LIMIT 3
|
||||
|
||||
#define IQK_ADDA_REG_NUM 16
|
||||
#define IQK_BB_REG_NUM 10
|
||||
#define IQK_BB_REG_NUM_test 6
|
||||
#define IQK_MAC_REG_NUM 4
|
||||
#define RX_INDEX_MAPPING_NUM 15
|
||||
|
||||
#define IQK_DELAY_TIME 1
|
||||
|
||||
#define CT_OFFSET_MAC_ADDR 0X16
|
||||
|
||||
@ -68,80 +61,30 @@ struct swchnlcmd {
|
||||
u32 msdelay;
|
||||
};
|
||||
|
||||
enum baseband_config_type {
|
||||
BASEBAND_CONFIG_PHY_REG = 0,
|
||||
BASEBAND_CONFIG_AGC_TAB = 1,
|
||||
};
|
||||
|
||||
enum rf_content {
|
||||
radioa_txt = 0,
|
||||
radiob_txt = 1,
|
||||
radioc_txt = 2,
|
||||
radiod_txt = 3
|
||||
};
|
||||
|
||||
static inline void rtl92d_acquire_cckandrw_pagea_ctl(struct ieee80211_hw *hw,
|
||||
unsigned long *flag)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
if (rtlpriv->rtlhal.interfaceindex == 1)
|
||||
spin_lock_irqsave(&rtlpriv->locks.cck_and_rw_pagea_lock, *flag);
|
||||
}
|
||||
|
||||
static inline void rtl92d_release_cckandrw_pagea_ctl(struct ieee80211_hw *hw,
|
||||
unsigned long *flag)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
if (rtlpriv->rtlhal.interfaceindex == 1)
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.cck_and_rw_pagea_lock,
|
||||
*flag);
|
||||
}
|
||||
|
||||
u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw,
|
||||
u32 regaddr, u32 bitmask);
|
||||
void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw,
|
||||
u32 regaddr, u32 bitmask, u32 data);
|
||||
u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw,
|
||||
enum radio_path rfpath, u32 regaddr,
|
||||
u32 bitmask);
|
||||
void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw,
|
||||
enum radio_path rfpath, u32 regaddr,
|
||||
u32 bitmask, u32 data);
|
||||
bool rtl92d_phy_mac_config(struct ieee80211_hw *hw);
|
||||
bool rtl92d_phy_bb_config(struct ieee80211_hw *hw);
|
||||
bool rtl92d_phy_rf_config(struct ieee80211_hw *hw);
|
||||
bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
|
||||
enum radio_path rfpath);
|
||||
void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
|
||||
void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
|
||||
void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw,
|
||||
enum nl80211_channel_type ch_type);
|
||||
u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw);
|
||||
bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
|
||||
enum rf_content content,
|
||||
enum radio_path rfpath);
|
||||
bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
|
||||
bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw,
|
||||
enum rf_pwrstate rfpwr_state);
|
||||
|
||||
void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw);
|
||||
void rtl92d_phy_config_macphymode_info(struct ieee80211_hw *hw);
|
||||
u8 rtl92d_get_chnlgroup_fromarray(u8 chnl);
|
||||
void rtl92d_phy_set_poweron(struct ieee80211_hw *hw);
|
||||
void rtl92d_phy_config_maccoexist_rfpage(struct ieee80211_hw *hw);
|
||||
bool rtl92d_phy_check_poweroff(struct ieee80211_hw *hw);
|
||||
void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw);
|
||||
void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t);
|
||||
void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw);
|
||||
void rtl92d_phy_ap_calibrate(struct ieee80211_hw *hw, s8 delta);
|
||||
void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw);
|
||||
void rtl92d_phy_reset_iqk_result(struct ieee80211_hw *hw);
|
||||
void rtl92d_release_cckandrw_pagea_ctl(struct ieee80211_hw *hw,
|
||||
unsigned long *flag);
|
||||
void rtl92d_acquire_cckandrw_pagea_ctl(struct ieee80211_hw *hw,
|
||||
unsigned long *flag);
|
||||
u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl);
|
||||
void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel);
|
||||
|
||||
#endif
|
||||
|
@ -2,383 +2,14 @@
|
||||
/* Copyright(c) 2009-2012 Realtek Corporation.*/
|
||||
|
||||
#include "../wifi.h"
|
||||
#include "reg.h"
|
||||
#include "def.h"
|
||||
#include "../rtl8192d/reg.h"
|
||||
#include "../rtl8192d/def.h"
|
||||
#include "../rtl8192d/phy_common.h"
|
||||
#include "phy.h"
|
||||
#include "rf.h"
|
||||
#include "dm.h"
|
||||
#include "hw.h"
|
||||
|
||||
void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
u8 rfpath;
|
||||
|
||||
switch (bandwidth) {
|
||||
case HT_CHANNEL_WIDTH_20:
|
||||
for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
|
||||
rtlphy->rfreg_chnlval[rfpath] = ((rtlphy->rfreg_chnlval
|
||||
[rfpath] & 0xfffff3ff) | 0x0400);
|
||||
rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(10) |
|
||||
BIT(11), 0x01);
|
||||
|
||||
rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD,
|
||||
"20M RF 0x18 = 0x%x\n",
|
||||
rtlphy->rfreg_chnlval[rfpath]);
|
||||
}
|
||||
|
||||
break;
|
||||
case HT_CHANNEL_WIDTH_20_40:
|
||||
for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
|
||||
rtlphy->rfreg_chnlval[rfpath] =
|
||||
((rtlphy->rfreg_chnlval[rfpath] & 0xfffff3ff));
|
||||
rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(10) | BIT(11),
|
||||
0x00);
|
||||
rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD,
|
||||
"40M RF 0x18 = 0x%x\n",
|
||||
rtlphy->rfreg_chnlval[rfpath]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_err("unknown bandwidth: %#X\n", bandwidth);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
|
||||
u8 *ppowerlevel)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
u32 tx_agc[2] = {0, 0}, tmpval;
|
||||
bool turbo_scanoff = false;
|
||||
u8 idx1, idx2;
|
||||
u8 *ptr;
|
||||
|
||||
if (rtlefuse->eeprom_regulatory != 0)
|
||||
turbo_scanoff = true;
|
||||
if (mac->act_scanning) {
|
||||
tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
|
||||
tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
|
||||
if (turbo_scanoff) {
|
||||
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
|
||||
tx_agc[idx1] = ppowerlevel[idx1] |
|
||||
(ppowerlevel[idx1] << 8) |
|
||||
(ppowerlevel[idx1] << 16) |
|
||||
(ppowerlevel[idx1] << 24);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
|
||||
tx_agc[idx1] = ppowerlevel[idx1] |
|
||||
(ppowerlevel[idx1] << 8) |
|
||||
(ppowerlevel[idx1] << 16) |
|
||||
(ppowerlevel[idx1] << 24);
|
||||
}
|
||||
if (rtlefuse->eeprom_regulatory == 0) {
|
||||
tmpval = (rtlphy->mcs_offset[0][6]) +
|
||||
(rtlphy->mcs_offset[0][7] << 8);
|
||||
tx_agc[RF90_PATH_A] += tmpval;
|
||||
tmpval = (rtlphy->mcs_offset[0][14]) +
|
||||
(rtlphy->mcs_offset[0][15] << 24);
|
||||
tx_agc[RF90_PATH_B] += tmpval;
|
||||
}
|
||||
}
|
||||
|
||||
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
|
||||
ptr = (u8 *) (&(tx_agc[idx1]));
|
||||
for (idx2 = 0; idx2 < 4; idx2++) {
|
||||
if (*ptr > RF6052_MAX_TX_PWR)
|
||||
*ptr = RF6052_MAX_TX_PWR;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
tmpval = tx_agc[RF90_PATH_A] & 0xff;
|
||||
rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n",
|
||||
tmpval, RTXAGC_A_CCK1_MCS32);
|
||||
tmpval = tx_agc[RF90_PATH_A] >> 8;
|
||||
rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n",
|
||||
tmpval, RTXAGC_B_CCK11_A_CCK2_11);
|
||||
tmpval = tx_agc[RF90_PATH_B] >> 24;
|
||||
rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n",
|
||||
tmpval, RTXAGC_B_CCK11_A_CCK2_11);
|
||||
tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
|
||||
rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n",
|
||||
tmpval, RTXAGC_B_CCK1_55_MCS32);
|
||||
}
|
||||
|
||||
static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw,
|
||||
u8 *ppowerlevel, u8 channel,
|
||||
u32 *ofdmbase, u32 *mcsbase)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
u32 powerbase0, powerbase1;
|
||||
u8 legacy_pwrdiff, ht20_pwrdiff;
|
||||
u8 i, powerlevel[2];
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
powerlevel[i] = ppowerlevel[i];
|
||||
legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1];
|
||||
powerbase0 = powerlevel[i] + legacy_pwrdiff;
|
||||
powerbase0 = (powerbase0 << 24) | (powerbase0 << 16) |
|
||||
(powerbase0 << 8) | powerbase0;
|
||||
*(ofdmbase + i) = powerbase0;
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
" [OFDM power base index rf(%c) = 0x%x]\n",
|
||||
i == 0 ? 'A' : 'B', *(ofdmbase + i));
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
|
||||
ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1];
|
||||
powerlevel[i] += ht20_pwrdiff;
|
||||
}
|
||||
powerbase1 = powerlevel[i];
|
||||
powerbase1 = (powerbase1 << 24) | (powerbase1 << 16) |
|
||||
(powerbase1 << 8) | powerbase1;
|
||||
*(mcsbase + i) = powerbase1;
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
" [MCS power base index rf(%c) = 0x%x]\n",
|
||||
i == 0 ? 'A' : 'B', *(mcsbase + i));
|
||||
}
|
||||
}
|
||||
|
||||
static u8 _rtl92d_phy_get_chnlgroup_bypg(u8 chnlindex)
|
||||
{
|
||||
u8 group;
|
||||
u8 channel_info[59] = {
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
|
||||
60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
|
||||
114, 116, 118, 120, 122, 124, 126, 128, 130, 132,
|
||||
134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
|
||||
161, 163, 165
|
||||
};
|
||||
|
||||
if (channel_info[chnlindex] <= 3) /* Chanel 1-3 */
|
||||
group = 0;
|
||||
else if (channel_info[chnlindex] <= 9) /* Channel 4-9 */
|
||||
group = 1;
|
||||
else if (channel_info[chnlindex] <= 14) /* Channel 10-14 */
|
||||
group = 2;
|
||||
else if (channel_info[chnlindex] <= 64)
|
||||
group = 6;
|
||||
else if (channel_info[chnlindex] <= 140)
|
||||
group = 7;
|
||||
else
|
||||
group = 8;
|
||||
return group;
|
||||
}
|
||||
|
||||
static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
|
||||
u8 channel, u8 index,
|
||||
u32 *powerbase0,
|
||||
u32 *powerbase1,
|
||||
u32 *p_outwriteval)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
u8 i, chnlgroup = 0, pwr_diff_limit[4];
|
||||
u32 writeval = 0, customer_limit, rf;
|
||||
|
||||
for (rf = 0; rf < 2; rf++) {
|
||||
switch (rtlefuse->eeprom_regulatory) {
|
||||
case 0:
|
||||
chnlgroup = 0;
|
||||
writeval = rtlphy->mcs_offset
|
||||
[chnlgroup][index +
|
||||
(rf ? 8 : 0)] + ((index < 2) ?
|
||||
powerbase0[rf] :
|
||||
powerbase1[rf]);
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"RTK better performance, writeval(%c) = 0x%x\n",
|
||||
rf == 0 ? 'A' : 'B', writeval);
|
||||
break;
|
||||
case 1:
|
||||
if (rtlphy->pwrgroup_cnt == 1)
|
||||
chnlgroup = 0;
|
||||
if (rtlphy->pwrgroup_cnt >= MAX_PG_GROUP) {
|
||||
chnlgroup = _rtl92d_phy_get_chnlgroup_bypg(
|
||||
channel - 1);
|
||||
if (rtlphy->current_chan_bw ==
|
||||
HT_CHANNEL_WIDTH_20)
|
||||
chnlgroup++;
|
||||
else
|
||||
chnlgroup += 4;
|
||||
writeval = rtlphy->mcs_offset
|
||||
[chnlgroup][index +
|
||||
(rf ? 8 : 0)] + ((index < 2) ?
|
||||
powerbase0[rf] :
|
||||
powerbase1[rf]);
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"Realtek regulatory, 20MHz, writeval(%c) = 0x%x\n",
|
||||
rf == 0 ? 'A' : 'B', writeval);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
writeval = ((index < 2) ? powerbase0[rf] :
|
||||
powerbase1[rf]);
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"Better regulatory, writeval(%c) = 0x%x\n",
|
||||
rf == 0 ? 'A' : 'B', writeval);
|
||||
break;
|
||||
case 3:
|
||||
chnlgroup = 0;
|
||||
if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"customer's limit, 40MHz rf(%c) = 0x%x\n",
|
||||
rf == 0 ? 'A' : 'B',
|
||||
rtlefuse->pwrgroup_ht40[rf]
|
||||
[channel - 1]);
|
||||
} else {
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"customer's limit, 20MHz rf(%c) = 0x%x\n",
|
||||
rf == 0 ? 'A' : 'B',
|
||||
rtlefuse->pwrgroup_ht20[rf]
|
||||
[channel - 1]);
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
pwr_diff_limit[i] = (u8)((rtlphy->mcs_offset
|
||||
[chnlgroup][index + (rf ? 8 : 0)] &
|
||||
(0x7f << (i * 8))) >> (i * 8));
|
||||
if (rtlphy->current_chan_bw ==
|
||||
HT_CHANNEL_WIDTH_20_40) {
|
||||
if (pwr_diff_limit[i] >
|
||||
rtlefuse->pwrgroup_ht40[rf]
|
||||
[channel - 1])
|
||||
pwr_diff_limit[i] =
|
||||
rtlefuse->pwrgroup_ht40
|
||||
[rf][channel - 1];
|
||||
} else {
|
||||
if (pwr_diff_limit[i] >
|
||||
rtlefuse->pwrgroup_ht20[rf][
|
||||
channel - 1])
|
||||
pwr_diff_limit[i] =
|
||||
rtlefuse->pwrgroup_ht20[rf]
|
||||
[channel - 1];
|
||||
}
|
||||
}
|
||||
customer_limit = (pwr_diff_limit[3] << 24) |
|
||||
(pwr_diff_limit[2] << 16) |
|
||||
(pwr_diff_limit[1] << 8) |
|
||||
(pwr_diff_limit[0]);
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"Customer's limit rf(%c) = 0x%x\n",
|
||||
rf == 0 ? 'A' : 'B', customer_limit);
|
||||
writeval = customer_limit + ((index < 2) ?
|
||||
powerbase0[rf] : powerbase1[rf]);
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"Customer, writeval rf(%c)= 0x%x\n",
|
||||
rf == 0 ? 'A' : 'B', writeval);
|
||||
break;
|
||||
default:
|
||||
chnlgroup = 0;
|
||||
writeval = rtlphy->mcs_offset[chnlgroup][index +
|
||||
(rf ? 8 : 0)] + ((index < 2) ?
|
||||
powerbase0[rf] : powerbase1[rf]);
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"RTK better performance, writeval rf(%c) = 0x%x\n",
|
||||
rf == 0 ? 'A' : 'B', writeval);
|
||||
break;
|
||||
}
|
||||
*(p_outwriteval + rf) = writeval;
|
||||
}
|
||||
}
|
||||
|
||||
static void _rtl92d_write_ofdm_power_reg(struct ieee80211_hw *hw,
|
||||
u8 index, u32 *pvalue)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
static u16 regoffset_a[6] = {
|
||||
RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24,
|
||||
RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
|
||||
RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
|
||||
};
|
||||
static u16 regoffset_b[6] = {
|
||||
RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24,
|
||||
RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
|
||||
RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
|
||||
};
|
||||
u8 i, rf, pwr_val[4];
|
||||
u32 writeval;
|
||||
u16 regoffset;
|
||||
|
||||
for (rf = 0; rf < 2; rf++) {
|
||||
writeval = pvalue[rf];
|
||||
for (i = 0; i < 4; i++) {
|
||||
pwr_val[i] = (u8) ((writeval & (0x7f <<
|
||||
(i * 8))) >> (i * 8));
|
||||
if (pwr_val[i] > RF6052_MAX_TX_PWR)
|
||||
pwr_val[i] = RF6052_MAX_TX_PWR;
|
||||
}
|
||||
writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) |
|
||||
(pwr_val[1] << 8) | pwr_val[0];
|
||||
if (rf == 0)
|
||||
regoffset = regoffset_a[index];
|
||||
else
|
||||
regoffset = regoffset_b[index];
|
||||
rtl_set_bbreg(hw, regoffset, MASKDWORD, writeval);
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
"Set 0x%x = %08x\n", regoffset, writeval);
|
||||
if (((get_rf_type(rtlphy) == RF_2T2R) &&
|
||||
(regoffset == RTXAGC_A_MCS15_MCS12 ||
|
||||
regoffset == RTXAGC_B_MCS15_MCS12)) ||
|
||||
((get_rf_type(rtlphy) != RF_2T2R) &&
|
||||
(regoffset == RTXAGC_A_MCS07_MCS04 ||
|
||||
regoffset == RTXAGC_B_MCS07_MCS04))) {
|
||||
writeval = pwr_val[3];
|
||||
if (regoffset == RTXAGC_A_MCS15_MCS12 ||
|
||||
regoffset == RTXAGC_A_MCS07_MCS04)
|
||||
regoffset = 0xc90;
|
||||
if (regoffset == RTXAGC_B_MCS15_MCS12 ||
|
||||
regoffset == RTXAGC_B_MCS07_MCS04)
|
||||
regoffset = 0xc98;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (i != 2)
|
||||
writeval = (writeval > 8) ?
|
||||
(writeval - 8) : 0;
|
||||
else
|
||||
writeval = (writeval > 6) ?
|
||||
(writeval - 6) : 0;
|
||||
rtl_write_byte(rtlpriv, (u32) (regoffset + i),
|
||||
(u8) writeval);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
|
||||
u8 *ppowerlevel, u8 channel)
|
||||
{
|
||||
u32 writeval[2], powerbase0[2], powerbase1[2];
|
||||
u8 index;
|
||||
|
||||
_rtl92d_phy_get_power_base(hw, ppowerlevel, channel,
|
||||
&powerbase0[0], &powerbase1[0]);
|
||||
for (index = 0; index < 6; index++) {
|
||||
_rtl92d_get_txpower_writeval_by_regulatory(hw,
|
||||
channel, index, &powerbase0[0],
|
||||
&powerbase1[0], &writeval[0]);
|
||||
_rtl92d_write_ofdm_power_reg(hw, index, &writeval[0]);
|
||||
}
|
||||
}
|
||||
|
||||
bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
@ -4,11 +4,6 @@
|
||||
#ifndef __RTL92D_RF_H__
|
||||
#define __RTL92D_RF_H__
|
||||
|
||||
void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth);
|
||||
void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
|
||||
u8 *ppowerlevel);
|
||||
void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
|
||||
u8 *ppowerlevel, u8 channel);
|
||||
bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw);
|
||||
bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0);
|
||||
void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0);
|
||||
|
@ -5,8 +5,12 @@
|
||||
#include "../core.h"
|
||||
#include "../pci.h"
|
||||
#include "../base.h"
|
||||
#include "reg.h"
|
||||
#include "def.h"
|
||||
#include "../rtl8192d/reg.h"
|
||||
#include "../rtl8192d/def.h"
|
||||
#include "../rtl8192d/dm_common.h"
|
||||
#include "../rtl8192d/hw_common.h"
|
||||
#include "../rtl8192d/phy_common.h"
|
||||
#include "../rtl8192d/trx_common.h"
|
||||
#include "phy.h"
|
||||
#include "dm.h"
|
||||
#include "hw.h"
|
||||
@ -207,7 +211,7 @@ static struct rtl_hal_ops rtl8192de_hal_ops = {
|
||||
.radio_onoff_checking = rtl92de_gpio_radio_on_off_checking,
|
||||
.set_bw_mode = rtl92d_phy_set_bw_mode,
|
||||
.switch_channel = rtl92d_phy_sw_chnl,
|
||||
.dm_watchdog = rtl92d_dm_watchdog,
|
||||
.dm_watchdog = rtl92de_dm_watchdog,
|
||||
.scan_operation_backup = rtl_phy_scan_operation_backup,
|
||||
.set_rf_power_state = rtl92d_phy_set_rf_power_state,
|
||||
.led_control = rtl92de_led_control,
|
||||
@ -223,6 +227,8 @@ static struct rtl_hal_ops rtl8192de_hal_ops = {
|
||||
.set_rfreg = rtl92d_phy_set_rf_reg,
|
||||
.linked_set_reg = rtl92d_linked_set_reg,
|
||||
.get_btc_status = rtl_btc_status_false,
|
||||
.phy_iq_calibrate = rtl92d_phy_iq_calibrate,
|
||||
.phy_lc_calibrate = rtl92d_phy_lc_calibrate,
|
||||
};
|
||||
|
||||
static struct rtl_mod_params rtl92de_mod_params = {
|
||||
|
@ -5,8 +5,10 @@
|
||||
#include "../pci.h"
|
||||
#include "../base.h"
|
||||
#include "../stats.h"
|
||||
#include "reg.h"
|
||||
#include "def.h"
|
||||
#include "../rtl8192d/reg.h"
|
||||
#include "../rtl8192d/def.h"
|
||||
#include "../rtl8192d/phy_common.h"
|
||||
#include "../rtl8192d/trx_common.h"
|
||||
#include "phy.h"
|
||||
#include "trx.h"
|
||||
#include "led.h"
|
||||
@ -23,434 +25,6 @@ static u8 _rtl92de_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
|
||||
return skb->priority;
|
||||
}
|
||||
|
||||
static long _rtl92de_translate_todbm(struct ieee80211_hw *hw,
|
||||
u8 signal_strength_index)
|
||||
{
|
||||
long signal_power;
|
||||
|
||||
signal_power = (long)((signal_strength_index + 1) >> 1);
|
||||
signal_power -= 95;
|
||||
return signal_power;
|
||||
}
|
||||
|
||||
static void _rtl92de_query_rxphystatus(struct ieee80211_hw *hw,
|
||||
struct rtl_stats *pstats,
|
||||
struct rx_desc_92d *pdesc,
|
||||
struct rx_fwinfo_92d *p_drvinfo,
|
||||
bool packet_match_bssid,
|
||||
bool packet_toself,
|
||||
bool packet_beacon)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
|
||||
struct phy_sts_cck_8192d *cck_buf;
|
||||
s8 rx_pwr_all, rx_pwr[4];
|
||||
u8 rf_rx_num = 0, evm, pwdb_all;
|
||||
u8 i, max_spatial_stream;
|
||||
u32 rssi, total_rssi = 0;
|
||||
bool is_cck_rate;
|
||||
|
||||
is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc->rxmcs);
|
||||
pstats->packet_matchbssid = packet_match_bssid;
|
||||
pstats->packet_toself = packet_toself;
|
||||
pstats->packet_beacon = packet_beacon;
|
||||
pstats->is_cck = is_cck_rate;
|
||||
pstats->rx_mimo_sig_qual[0] = -1;
|
||||
pstats->rx_mimo_sig_qual[1] = -1;
|
||||
|
||||
if (is_cck_rate) {
|
||||
u8 report, cck_highpwr;
|
||||
cck_buf = (struct phy_sts_cck_8192d *)p_drvinfo;
|
||||
if (ppsc->rfpwr_state == ERFON)
|
||||
cck_highpwr = rtlphy->cck_high_power;
|
||||
else
|
||||
cck_highpwr = false;
|
||||
if (!cck_highpwr) {
|
||||
u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
|
||||
report = cck_buf->cck_agc_rpt & 0xc0;
|
||||
report = report >> 6;
|
||||
switch (report) {
|
||||
case 0x3:
|
||||
rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
|
||||
break;
|
||||
case 0x2:
|
||||
rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
|
||||
break;
|
||||
case 0x1:
|
||||
rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
|
||||
break;
|
||||
case 0x0:
|
||||
rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
|
||||
report = p_drvinfo->cfosho[0] & 0x60;
|
||||
report = report >> 5;
|
||||
switch (report) {
|
||||
case 0x3:
|
||||
rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1);
|
||||
break;
|
||||
case 0x2:
|
||||
rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1);
|
||||
break;
|
||||
case 0x1:
|
||||
rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1);
|
||||
break;
|
||||
case 0x0:
|
||||
rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
|
||||
/* CCK gain is smaller than OFDM/MCS gain, */
|
||||
/* so we add gain diff by experiences, the val is 6 */
|
||||
pwdb_all += 6;
|
||||
if (pwdb_all > 100)
|
||||
pwdb_all = 100;
|
||||
/* modify the offset to make the same gain index with OFDM. */
|
||||
if (pwdb_all > 34 && pwdb_all <= 42)
|
||||
pwdb_all -= 2;
|
||||
else if (pwdb_all > 26 && pwdb_all <= 34)
|
||||
pwdb_all -= 6;
|
||||
else if (pwdb_all > 14 && pwdb_all <= 26)
|
||||
pwdb_all -= 8;
|
||||
else if (pwdb_all > 4 && pwdb_all <= 14)
|
||||
pwdb_all -= 4;
|
||||
pstats->rx_pwdb_all = pwdb_all;
|
||||
pstats->recvsignalpower = rx_pwr_all;
|
||||
if (packet_match_bssid) {
|
||||
u8 sq;
|
||||
if (pstats->rx_pwdb_all > 40) {
|
||||
sq = 100;
|
||||
} else {
|
||||
sq = cck_buf->sq_rpt;
|
||||
if (sq > 64)
|
||||
sq = 0;
|
||||
else if (sq < 20)
|
||||
sq = 100;
|
||||
else
|
||||
sq = ((64 - sq) * 100) / 44;
|
||||
}
|
||||
pstats->signalquality = sq;
|
||||
pstats->rx_mimo_sig_qual[0] = sq;
|
||||
pstats->rx_mimo_sig_qual[1] = -1;
|
||||
}
|
||||
} else {
|
||||
rtlpriv->dm.rfpath_rxenable[0] = true;
|
||||
rtlpriv->dm.rfpath_rxenable[1] = true;
|
||||
for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) {
|
||||
if (rtlpriv->dm.rfpath_rxenable[i])
|
||||
rf_rx_num++;
|
||||
rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & 0x3f) * 2)
|
||||
- 110;
|
||||
rssi = rtl_query_rxpwrpercentage(rx_pwr[i]);
|
||||
total_rssi += rssi;
|
||||
rtlpriv->stats.rx_snr_db[i] =
|
||||
(long)(p_drvinfo->rxsnr[i] / 2);
|
||||
if (packet_match_bssid)
|
||||
pstats->rx_mimo_signalstrength[i] = (u8) rssi;
|
||||
}
|
||||
rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 106;
|
||||
pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
|
||||
pstats->rx_pwdb_all = pwdb_all;
|
||||
pstats->rxpower = rx_pwr_all;
|
||||
pstats->recvsignalpower = rx_pwr_all;
|
||||
if (pdesc->rxht && pdesc->rxmcs >= DESC_RATEMCS8 &&
|
||||
pdesc->rxmcs <= DESC_RATEMCS15)
|
||||
max_spatial_stream = 2;
|
||||
else
|
||||
max_spatial_stream = 1;
|
||||
for (i = 0; i < max_spatial_stream; i++) {
|
||||
evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]);
|
||||
if (packet_match_bssid) {
|
||||
if (i == 0)
|
||||
pstats->signalquality =
|
||||
(u8)(evm & 0xff);
|
||||
pstats->rx_mimo_sig_qual[i] =
|
||||
(u8)(evm & 0xff);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_cck_rate)
|
||||
pstats->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
|
||||
pwdb_all));
|
||||
else if (rf_rx_num != 0)
|
||||
pstats->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
|
||||
total_rssi /= rf_rx_num));
|
||||
}
|
||||
|
||||
static void rtl92d_loop_over_paths(struct ieee80211_hw *hw,
|
||||
struct rtl_stats *pstats)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
u8 rfpath;
|
||||
|
||||
for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
|
||||
rfpath++) {
|
||||
if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
|
||||
rtlpriv->stats.rx_rssi_percentage[rfpath] =
|
||||
pstats->rx_mimo_signalstrength[rfpath];
|
||||
|
||||
}
|
||||
if (pstats->rx_mimo_signalstrength[rfpath] >
|
||||
rtlpriv->stats.rx_rssi_percentage[rfpath]) {
|
||||
rtlpriv->stats.rx_rssi_percentage[rfpath] =
|
||||
((rtlpriv->stats.rx_rssi_percentage[rfpath] *
|
||||
(RX_SMOOTH_FACTOR - 1)) +
|
||||
(pstats->rx_mimo_signalstrength[rfpath])) /
|
||||
(RX_SMOOTH_FACTOR);
|
||||
rtlpriv->stats.rx_rssi_percentage[rfpath] =
|
||||
rtlpriv->stats.rx_rssi_percentage[rfpath] + 1;
|
||||
} else {
|
||||
rtlpriv->stats.rx_rssi_percentage[rfpath] =
|
||||
((rtlpriv->stats.rx_rssi_percentage[rfpath] *
|
||||
(RX_SMOOTH_FACTOR - 1)) +
|
||||
(pstats->rx_mimo_signalstrength[rfpath])) /
|
||||
(RX_SMOOTH_FACTOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void _rtl92de_process_ui_rssi(struct ieee80211_hw *hw,
|
||||
struct rtl_stats *pstats)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u32 last_rssi, tmpval;
|
||||
|
||||
if (pstats->packet_toself || pstats->packet_beacon) {
|
||||
rtlpriv->stats.rssi_calculate_cnt++;
|
||||
if (rtlpriv->stats.ui_rssi.total_num++ >=
|
||||
PHY_RSSI_SLID_WIN_MAX) {
|
||||
rtlpriv->stats.ui_rssi.total_num =
|
||||
PHY_RSSI_SLID_WIN_MAX;
|
||||
last_rssi = rtlpriv->stats.ui_rssi.elements[
|
||||
rtlpriv->stats.ui_rssi.index];
|
||||
rtlpriv->stats.ui_rssi.total_val -= last_rssi;
|
||||
}
|
||||
rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength;
|
||||
rtlpriv->stats.ui_rssi.elements
|
||||
[rtlpriv->stats.ui_rssi.index++] =
|
||||
pstats->signalstrength;
|
||||
if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
|
||||
rtlpriv->stats.ui_rssi.index = 0;
|
||||
tmpval = rtlpriv->stats.ui_rssi.total_val /
|
||||
rtlpriv->stats.ui_rssi.total_num;
|
||||
rtlpriv->stats.signal_strength = _rtl92de_translate_todbm(hw,
|
||||
(u8) tmpval);
|
||||
pstats->rssi = rtlpriv->stats.signal_strength;
|
||||
}
|
||||
if (!pstats->is_cck && pstats->packet_toself)
|
||||
rtl92d_loop_over_paths(hw, pstats);
|
||||
}
|
||||
|
||||
static void _rtl92de_update_rxsignalstatistics(struct ieee80211_hw *hw,
|
||||
struct rtl_stats *pstats)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
int weighting = 0;
|
||||
|
||||
if (rtlpriv->stats.recv_signal_power == 0)
|
||||
rtlpriv->stats.recv_signal_power = pstats->recvsignalpower;
|
||||
if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power)
|
||||
weighting = 5;
|
||||
else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power)
|
||||
weighting = (-5);
|
||||
rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power *
|
||||
5 + pstats->recvsignalpower + weighting) / 6;
|
||||
}
|
||||
|
||||
static void _rtl92de_process_pwdb(struct ieee80211_hw *hw,
|
||||
struct rtl_stats *pstats)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
long undec_sm_pwdb;
|
||||
|
||||
if (mac->opmode == NL80211_IFTYPE_ADHOC ||
|
||||
mac->opmode == NL80211_IFTYPE_AP)
|
||||
return;
|
||||
else
|
||||
undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
|
||||
|
||||
if (pstats->packet_toself || pstats->packet_beacon) {
|
||||
if (undec_sm_pwdb < 0)
|
||||
undec_sm_pwdb = pstats->rx_pwdb_all;
|
||||
if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) {
|
||||
undec_sm_pwdb = (((undec_sm_pwdb) *
|
||||
(RX_SMOOTH_FACTOR - 1)) +
|
||||
(pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
|
||||
undec_sm_pwdb = undec_sm_pwdb + 1;
|
||||
} else {
|
||||
undec_sm_pwdb = (((undec_sm_pwdb) *
|
||||
(RX_SMOOTH_FACTOR - 1)) +
|
||||
(pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
|
||||
}
|
||||
rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb;
|
||||
_rtl92de_update_rxsignalstatistics(hw, pstats);
|
||||
}
|
||||
}
|
||||
|
||||
static void rtl92d_loop_over_streams(struct ieee80211_hw *hw,
|
||||
struct rtl_stats *pstats)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
int stream;
|
||||
|
||||
for (stream = 0; stream < 2; stream++) {
|
||||
if (pstats->rx_mimo_sig_qual[stream] != -1) {
|
||||
if (rtlpriv->stats.rx_evm_percentage[stream] == 0) {
|
||||
rtlpriv->stats.rx_evm_percentage[stream] =
|
||||
pstats->rx_mimo_sig_qual[stream];
|
||||
}
|
||||
rtlpriv->stats.rx_evm_percentage[stream] =
|
||||
((rtlpriv->stats.rx_evm_percentage[stream]
|
||||
* (RX_SMOOTH_FACTOR - 1)) +
|
||||
(pstats->rx_mimo_sig_qual[stream] * 1)) /
|
||||
(RX_SMOOTH_FACTOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void _rtl92de_process_ui_link_quality(struct ieee80211_hw *hw,
|
||||
struct rtl_stats *pstats)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u32 last_evm, tmpval;
|
||||
|
||||
if (pstats->signalquality == 0)
|
||||
return;
|
||||
if (pstats->packet_toself || pstats->packet_beacon) {
|
||||
if (rtlpriv->stats.ui_link_quality.total_num++ >=
|
||||
PHY_LINKQUALITY_SLID_WIN_MAX) {
|
||||
rtlpriv->stats.ui_link_quality.total_num =
|
||||
PHY_LINKQUALITY_SLID_WIN_MAX;
|
||||
last_evm = rtlpriv->stats.ui_link_quality.elements[
|
||||
rtlpriv->stats.ui_link_quality.index];
|
||||
rtlpriv->stats.ui_link_quality.total_val -= last_evm;
|
||||
}
|
||||
rtlpriv->stats.ui_link_quality.total_val +=
|
||||
pstats->signalquality;
|
||||
rtlpriv->stats.ui_link_quality.elements[
|
||||
rtlpriv->stats.ui_link_quality.index++] =
|
||||
pstats->signalquality;
|
||||
if (rtlpriv->stats.ui_link_quality.index >=
|
||||
PHY_LINKQUALITY_SLID_WIN_MAX)
|
||||
rtlpriv->stats.ui_link_quality.index = 0;
|
||||
tmpval = rtlpriv->stats.ui_link_quality.total_val /
|
||||
rtlpriv->stats.ui_link_quality.total_num;
|
||||
rtlpriv->stats.signal_quality = tmpval;
|
||||
rtlpriv->stats.last_sigstrength_inpercent = tmpval;
|
||||
rtl92d_loop_over_streams(hw, pstats);
|
||||
}
|
||||
}
|
||||
|
||||
static void _rtl92de_process_phyinfo(struct ieee80211_hw *hw,
|
||||
u8 *buffer,
|
||||
struct rtl_stats *pcurrent_stats)
|
||||
{
|
||||
|
||||
if (!pcurrent_stats->packet_matchbssid &&
|
||||
!pcurrent_stats->packet_beacon)
|
||||
return;
|
||||
|
||||
_rtl92de_process_ui_rssi(hw, pcurrent_stats);
|
||||
_rtl92de_process_pwdb(hw, pcurrent_stats);
|
||||
_rtl92de_process_ui_link_quality(hw, pcurrent_stats);
|
||||
}
|
||||
|
||||
static void _rtl92de_translate_rx_signal_stuff(struct ieee80211_hw *hw,
|
||||
struct sk_buff *skb,
|
||||
struct rtl_stats *pstats,
|
||||
struct rx_desc_92d *pdesc,
|
||||
struct rx_fwinfo_92d *p_drvinfo)
|
||||
{
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
struct ieee80211_hdr *hdr;
|
||||
u8 *tmp_buf;
|
||||
u8 *praddr;
|
||||
u16 type, cfc;
|
||||
__le16 fc;
|
||||
bool packet_matchbssid, packet_toself, packet_beacon = false;
|
||||
|
||||
tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
|
||||
hdr = (struct ieee80211_hdr *)tmp_buf;
|
||||
fc = hdr->frame_control;
|
||||
cfc = le16_to_cpu(fc);
|
||||
type = WLAN_FC_GET_TYPE(fc);
|
||||
praddr = hdr->addr1;
|
||||
packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
|
||||
ether_addr_equal(mac->bssid,
|
||||
(cfc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
|
||||
(cfc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
|
||||
hdr->addr3) &&
|
||||
(!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
|
||||
packet_toself = packet_matchbssid &&
|
||||
ether_addr_equal(praddr, rtlefuse->dev_addr);
|
||||
if (ieee80211_is_beacon(fc))
|
||||
packet_beacon = true;
|
||||
_rtl92de_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
|
||||
packet_matchbssid, packet_toself,
|
||||
packet_beacon);
|
||||
_rtl92de_process_phyinfo(hw, tmp_buf, pstats);
|
||||
}
|
||||
|
||||
bool rtl92de_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
u8 *pdesc8, struct sk_buff *skb)
|
||||
{
|
||||
__le32 *pdesc = (__le32 *)pdesc8;
|
||||
struct rx_fwinfo_92d *p_drvinfo;
|
||||
u32 phystatus = get_rx_desc_physt(pdesc);
|
||||
|
||||
stats->length = (u16)get_rx_desc_pkt_len(pdesc);
|
||||
stats->rx_drvinfo_size = (u8)get_rx_desc_drv_info_size(pdesc) *
|
||||
RX_DRV_INFO_SIZE_UNIT;
|
||||
stats->rx_bufshift = (u8)(get_rx_desc_shift(pdesc) & 0x03);
|
||||
stats->icv = (u16)get_rx_desc_icv(pdesc);
|
||||
stats->crc = (u16)get_rx_desc_crc32(pdesc);
|
||||
stats->hwerror = (stats->crc | stats->icv);
|
||||
stats->decrypted = !get_rx_desc_swdec(pdesc);
|
||||
stats->rate = (u8)get_rx_desc_rxmcs(pdesc);
|
||||
stats->shortpreamble = (u16)get_rx_desc_splcp(pdesc);
|
||||
stats->isampdu = (bool)(get_rx_desc_paggr(pdesc) == 1);
|
||||
stats->isfirst_ampdu = (bool)((get_rx_desc_paggr(pdesc) == 1) &&
|
||||
(get_rx_desc_faggr(pdesc) == 1));
|
||||
stats->timestamp_low = get_rx_desc_tsfl(pdesc);
|
||||
stats->rx_is40mhzpacket = (bool)get_rx_desc_bw(pdesc);
|
||||
stats->is_ht = (bool)get_rx_desc_rxht(pdesc);
|
||||
rx_status->freq = hw->conf.chandef.chan->center_freq;
|
||||
rx_status->band = hw->conf.chandef.chan->band;
|
||||
if (get_rx_desc_crc32(pdesc))
|
||||
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||
if (!get_rx_desc_swdec(pdesc))
|
||||
rx_status->flag |= RX_FLAG_DECRYPTED;
|
||||
if (get_rx_desc_bw(pdesc))
|
||||
rx_status->bw = RATE_INFO_BW_40;
|
||||
if (get_rx_desc_rxht(pdesc))
|
||||
rx_status->encoding = RX_ENC_HT;
|
||||
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||
if (stats->decrypted)
|
||||
rx_status->flag |= RX_FLAG_DECRYPTED;
|
||||
rx_status->rate_idx = rtlwifi_rate_mapping(hw, stats->is_ht,
|
||||
false, stats->rate);
|
||||
rx_status->mactime = get_rx_desc_tsfl(pdesc);
|
||||
if (phystatus) {
|
||||
p_drvinfo = (struct rx_fwinfo_92d *)(skb->data +
|
||||
stats->rx_bufshift);
|
||||
_rtl92de_translate_rx_signal_stuff(hw,
|
||||
skb, stats,
|
||||
(struct rx_desc_92d *)pdesc,
|
||||
p_drvinfo);
|
||||
}
|
||||
/*rx_status->qual = stats->signal; */
|
||||
rx_status->signal = stats->recvsignalpower + 10;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void _rtl92de_insert_emcontent(struct rtl_tcb_desc *ptcb_desc,
|
||||
u8 *virtualaddress8)
|
||||
{
|
||||
@ -712,87 +286,6 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc8,
|
||||
set_tx_desc_own(pdesc, 1);
|
||||
}
|
||||
|
||||
void rtl92de_set_desc(struct ieee80211_hw *hw, u8 *pdesc8, bool istx,
|
||||
u8 desc_name, u8 *val)
|
||||
{
|
||||
__le32 *pdesc = (__le32 *)pdesc8;
|
||||
|
||||
if (istx) {
|
||||
switch (desc_name) {
|
||||
case HW_DESC_OWN:
|
||||
wmb();
|
||||
set_tx_desc_own(pdesc, 1);
|
||||
break;
|
||||
case HW_DESC_TX_NEXTDESC_ADDR:
|
||||
set_tx_desc_next_desc_address(pdesc, *(u32 *)val);
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(true, "rtl8192de: ERR txdesc :%d not processed\n",
|
||||
desc_name);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (desc_name) {
|
||||
case HW_DESC_RXOWN:
|
||||
wmb();
|
||||
set_rx_desc_own(pdesc, 1);
|
||||
break;
|
||||
case HW_DESC_RXBUFF_ADDR:
|
||||
set_rx_desc_buff_addr(pdesc, *(u32 *)val);
|
||||
break;
|
||||
case HW_DESC_RXPKT_LEN:
|
||||
set_rx_desc_pkt_len(pdesc, *(u32 *)val);
|
||||
break;
|
||||
case HW_DESC_RXERO:
|
||||
set_rx_desc_eor(pdesc, 1);
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(true, "rtl8192de: ERR rxdesc :%d not processed\n",
|
||||
desc_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u64 rtl92de_get_desc(struct ieee80211_hw *hw,
|
||||
u8 *p_desc8, bool istx, u8 desc_name)
|
||||
{
|
||||
__le32 *p_desc = (__le32 *)p_desc8;
|
||||
u32 ret = 0;
|
||||
|
||||
if (istx) {
|
||||
switch (desc_name) {
|
||||
case HW_DESC_OWN:
|
||||
ret = get_tx_desc_own(p_desc);
|
||||
break;
|
||||
case HW_DESC_TXBUFF_ADDR:
|
||||
ret = get_tx_desc_tx_buffer_address(p_desc);
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(true, "rtl8192de: ERR txdesc :%d not processed\n",
|
||||
desc_name);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (desc_name) {
|
||||
case HW_DESC_OWN:
|
||||
ret = get_rx_desc_own(p_desc);
|
||||
break;
|
||||
case HW_DESC_RXPKT_LEN:
|
||||
ret = get_rx_desc_pkt_len(p_desc);
|
||||
break;
|
||||
case HW_DESC_RXBUFF_ADDR:
|
||||
ret = get_rx_desc_buff_addr(p_desc);
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(true, "rtl8192de: ERR rxdesc :%d not processed\n",
|
||||
desc_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool rtl92de_is_tx_desc_closed(struct ieee80211_hw *hw,
|
||||
u8 hw_queue, u16 index)
|
||||
{
|
||||
|
@ -8,384 +8,17 @@
|
||||
#define TX_DESC_AGGR_SUBFRAME_SIZE 32
|
||||
|
||||
#define RX_DESC_SIZE 32
|
||||
#define RX_DRV_INFO_SIZE_UNIT 8
|
||||
|
||||
#define TX_DESC_NEXT_DESC_OFFSET 40
|
||||
#define USB_HWDESC_HEADER_LEN 32
|
||||
#define CRCLENGTH 4
|
||||
|
||||
/* macros to read/write various fields in RX or TX descriptors */
|
||||
|
||||
static inline void set_tx_desc_pkt_size(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits(__pdesc, __val, GENMASK(15, 0));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_offset(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits(__pdesc, __val, GENMASK(23, 16));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_htc(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits(__pdesc, __val, BIT(25));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_last_seg(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits(__pdesc, __val, BIT(26));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_first_seg(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits(__pdesc, __val, BIT(27));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_linip(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits(__pdesc, __val, BIT(28));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_own(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits(__pdesc, __val, BIT(31));
|
||||
}
|
||||
|
||||
static inline u32 get_tx_desc_own(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*__pdesc, BIT(31));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_macid(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 1), __val, GENMASK(4, 0));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_agg_enable(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 1), __val, BIT(5));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_rdg_enable(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 1), __val, BIT(7));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_queue_sel(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 1), __val, GENMASK(12, 8));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_rate_id(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 1), __val, GENMASK(19, 16));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_sec_type(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 1), __val, GENMASK(23, 22));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_pkt_offset(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 1), __val, GENMASK(30, 26));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_more_frag(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 2), __val, BIT(17));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_ampdu_density(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 2), __val, GENMASK(22, 20));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_seq(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 3), __val, GENMASK(27, 16));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_pkt_id(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 3), __val, GENMASK(31, 28));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_rts_rate(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, GENMASK(4, 0));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_qos(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, BIT(6));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_hwseq_en(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, BIT(7));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_use_rate(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, BIT(8));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_disable_fb(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, BIT(10));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_cts2self(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, BIT(11));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_rts_enable(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, BIT(12));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_hw_rts_enable(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, BIT(13));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_tx_sub_carrier(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, GENMASK(21, 20));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_data_bw(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, BIT(25));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_rts_short(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, BIT(26));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_rts_bw(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, BIT(27));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_rts_sc(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, GENMASK(29, 28));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_rts_stbc(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 4), __val, GENMASK(31, 30));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_tx_rate(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 5), __val, GENMASK(5, 0));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_data_shortgi(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 5), __val, BIT(6));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_data_rate_fb_limit(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 5), __val, GENMASK(12, 8));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_rts_rate_fb_limit(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 5), __val, GENMASK(16, 13));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_max_agg_num(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 6), __val, GENMASK(15, 11));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_tx_buffer_size(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits((__pdesc + 7), __val, GENMASK(15, 0));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_tx_buffer_address(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
*(__pdesc + 8) = cpu_to_le32(__val);
|
||||
}
|
||||
|
||||
static inline u32 get_tx_desc_tx_buffer_address(__le32 *__pdesc)
|
||||
{
|
||||
return le32_to_cpu(*(__pdesc + 8));
|
||||
}
|
||||
|
||||
static inline void set_tx_desc_next_desc_address(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
*(__pdesc + 10) = cpu_to_le32(__val);
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_pkt_len(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*__pdesc, GENMASK(13, 0));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_crc32(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*__pdesc, BIT(14));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_icv(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*__pdesc, BIT(15));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_drv_info_size(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*__pdesc, GENMASK(19, 16));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_shift(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*__pdesc, GENMASK(25, 24));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_physt(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*__pdesc, BIT(26));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_swdec(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*__pdesc, BIT(27));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_own(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*__pdesc, BIT(31));
|
||||
}
|
||||
|
||||
static inline void set_rx_desc_pkt_len(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits(__pdesc, __val, GENMASK(13, 0));
|
||||
}
|
||||
|
||||
static inline void set_rx_desc_eor(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits(__pdesc, __val, BIT(30));
|
||||
}
|
||||
|
||||
static inline void set_rx_desc_own(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
le32p_replace_bits(__pdesc, __val, BIT(31));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_paggr(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*(__pdesc + 1), BIT(14));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_faggr(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*(__pdesc + 1), BIT(15));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_rxmcs(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*(__pdesc + 3), GENMASK(5, 0));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_rxht(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*(__pdesc + 3), BIT(6));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_splcp(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*(__pdesc + 3), BIT(8));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_bw(__le32 *__pdesc)
|
||||
{
|
||||
return le32_get_bits(*(__pdesc + 3), BIT(9));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_tsfl(__le32 *__pdesc)
|
||||
{
|
||||
return le32_to_cpu(*(__pdesc + 5));
|
||||
}
|
||||
|
||||
static inline u32 get_rx_desc_buff_addr(__le32 *__pdesc)
|
||||
{
|
||||
return le32_to_cpu(*(__pdesc + 6));
|
||||
}
|
||||
|
||||
static inline void set_rx_desc_buff_addr(__le32 *__pdesc, u32 __val)
|
||||
{
|
||||
*(__pdesc + 6) = cpu_to_le32(__val);
|
||||
}
|
||||
|
||||
static inline void clear_pci_tx_desc_content(__le32 *__pdesc, u32 _size)
|
||||
{
|
||||
memset((void *)__pdesc, 0,
|
||||
min_t(size_t, _size, TX_DESC_NEXT_DESC_OFFSET));
|
||||
}
|
||||
|
||||
/* For 92D early mode */
|
||||
static inline void set_earlymode_pktnum(__le32 *__paddr, u32 __value)
|
||||
{
|
||||
le32p_replace_bits(__paddr, __value, GENMASK(2, 0));
|
||||
}
|
||||
|
||||
static inline void set_earlymode_len0(__le32 *__paddr, u32 __value)
|
||||
{
|
||||
le32p_replace_bits(__paddr, __value, GENMASK(15, 4));
|
||||
}
|
||||
|
||||
static inline void set_earlymode_len1(__le32 *__paddr, u32 __value)
|
||||
{
|
||||
le32p_replace_bits(__paddr, __value, GENMASK(27, 16));
|
||||
}
|
||||
|
||||
static inline void set_earlymode_len2_1(__le32 *__paddr, u32 __value)
|
||||
{
|
||||
le32p_replace_bits(__paddr, __value, GENMASK(31, 28));
|
||||
}
|
||||
|
||||
static inline void set_earlymode_len2_2(__le32 *__paddr, u32 __value)
|
||||
{
|
||||
le32p_replace_bits((__paddr + 1), __value, GENMASK(7, 0));
|
||||
}
|
||||
|
||||
static inline void set_earlymode_len3(__le32 *__paddr, u32 __value)
|
||||
{
|
||||
le32p_replace_bits((__paddr + 1), __value, GENMASK(19, 8));
|
||||
}
|
||||
|
||||
static inline void set_earlymode_len4(__le32 *__paddr, u32 __value)
|
||||
{
|
||||
le32p_replace_bits((__paddr + 1), __value, GENMASK(31, 20));
|
||||
}
|
||||
|
||||
struct rx_fwinfo_92d {
|
||||
u8 gain_trsw[4];
|
||||
u8 pwdb_all;
|
||||
u8 cfosho[4];
|
||||
u8 cfotail[4];
|
||||
s8 rxevm[2];
|
||||
s8 rxsnr[4];
|
||||
u8 pdsnr[2];
|
||||
u8 csi_current[2];
|
||||
u8 csi_target[2];
|
||||
u8 sigevm;
|
||||
u8 max_ex_pwr;
|
||||
u8 ex_intf_flag:1;
|
||||
u8 sgi_en:1;
|
||||
u8 rxsc:2;
|
||||
u8 reserve:4;
|
||||
} __packed;
|
||||
|
||||
struct tx_desc_92d {
|
||||
u32 pktsize:16;
|
||||
u32 offset:8;
|
||||
@ -488,78 +121,12 @@ struct tx_desc_92d {
|
||||
u32 reserve_pass_pcie_mm_limit[4];
|
||||
} __packed;
|
||||
|
||||
struct rx_desc_92d {
|
||||
u32 length:14;
|
||||
u32 crc32:1;
|
||||
u32 icverror:1;
|
||||
u32 drv_infosize:4;
|
||||
u32 security:3;
|
||||
u32 qos:1;
|
||||
u32 shift:2;
|
||||
u32 phystatus:1;
|
||||
u32 swdec:1;
|
||||
u32 lastseg:1;
|
||||
u32 firstseg:1;
|
||||
u32 eor:1;
|
||||
u32 own:1;
|
||||
|
||||
u32 macid:5;
|
||||
u32 tid:4;
|
||||
u32 hwrsvd:5;
|
||||
u32 paggr:1;
|
||||
u32 faggr:1;
|
||||
u32 a1_fit:4;
|
||||
u32 a2_fit:4;
|
||||
u32 pam:1;
|
||||
u32 pwr:1;
|
||||
u32 moredata:1;
|
||||
u32 morefrag:1;
|
||||
u32 type:2;
|
||||
u32 mc:1;
|
||||
u32 bc:1;
|
||||
|
||||
u32 seq:12;
|
||||
u32 frag:4;
|
||||
u32 nextpktlen:14;
|
||||
u32 nextind:1;
|
||||
u32 rsvd:1;
|
||||
|
||||
u32 rxmcs:6;
|
||||
u32 rxht:1;
|
||||
u32 amsdu:1;
|
||||
u32 splcp:1;
|
||||
u32 bandwidth:1;
|
||||
u32 htc:1;
|
||||
u32 tcpchk_rpt:1;
|
||||
u32 ipcchk_rpt:1;
|
||||
u32 tcpchk_valid:1;
|
||||
u32 hwpcerr:1;
|
||||
u32 hwpcind:1;
|
||||
u32 iv0:16;
|
||||
|
||||
u32 iv1;
|
||||
|
||||
u32 tsfl;
|
||||
|
||||
u32 bufferaddress;
|
||||
u32 bufferaddress64;
|
||||
|
||||
} __packed;
|
||||
|
||||
void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
|
||||
struct ieee80211_hdr *hdr, u8 *pdesc,
|
||||
u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
|
||||
struct ieee80211_sta *sta,
|
||||
struct sk_buff *skb, u8 hw_queue,
|
||||
struct rtl_tcb_desc *ptcb_desc);
|
||||
bool rtl92de_rx_query_desc(struct ieee80211_hw *hw,
|
||||
struct rtl_stats *stats,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
u8 *pdesc, struct sk_buff *skb);
|
||||
void rtl92de_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
|
||||
u8 desc_name, u8 *val);
|
||||
u64 rtl92de_get_desc(struct ieee80211_hw *hw,
|
||||
u8 *p_desc, bool istx, u8 desc_name);
|
||||
bool rtl92de_is_tx_desc_closed(struct ieee80211_hw *hw,
|
||||
u8 hw_queue, u16 index);
|
||||
void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
|
||||
|
@ -1110,16 +1110,22 @@ static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw,
|
||||
void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
|
||||
{
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
u8 cck_rates[] = {DESC92C_RATE1M, DESC92C_RATE2M,
|
||||
DESC92C_RATE5_5M, DESC92C_RATE11M};
|
||||
u8 ofdm_rates[] = {DESC92C_RATE6M, DESC92C_RATE9M,
|
||||
DESC92C_RATE12M, DESC92C_RATE18M,
|
||||
DESC92C_RATE24M, DESC92C_RATE36M,
|
||||
DESC92C_RATE48M, DESC92C_RATE54M};
|
||||
u8 ht_rates_1t[] = {DESC92C_RATEMCS0, DESC92C_RATEMCS1,
|
||||
DESC92C_RATEMCS2, DESC92C_RATEMCS3,
|
||||
DESC92C_RATEMCS4, DESC92C_RATEMCS5,
|
||||
DESC92C_RATEMCS6, DESC92C_RATEMCS7};
|
||||
static const u8 cck_rates[] = {
|
||||
DESC92C_RATE1M, DESC92C_RATE2M,
|
||||
DESC92C_RATE5_5M, DESC92C_RATE11M
|
||||
};
|
||||
static const u8 ofdm_rates[] = {
|
||||
DESC92C_RATE6M, DESC92C_RATE9M,
|
||||
DESC92C_RATE12M, DESC92C_RATE18M,
|
||||
DESC92C_RATE24M, DESC92C_RATE36M,
|
||||
DESC92C_RATE48M, DESC92C_RATE54M
|
||||
};
|
||||
static const u8 ht_rates_1t[] = {
|
||||
DESC92C_RATEMCS0, DESC92C_RATEMCS1,
|
||||
DESC92C_RATEMCS2, DESC92C_RATEMCS3,
|
||||
DESC92C_RATEMCS4, DESC92C_RATEMCS5,
|
||||
DESC92C_RATEMCS6, DESC92C_RATEMCS7
|
||||
};
|
||||
u8 i;
|
||||
u8 power_index;
|
||||
|
||||
@ -2155,15 +2161,16 @@ static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw,
|
||||
|
||||
static u8 _get_right_chnl_place_for_iqk(u8 chnl)
|
||||
{
|
||||
u8 channel_all[TARGET_CHNL_NUM_2G_5G] = {
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
|
||||
13, 14, 36, 38, 40, 42, 44, 46,
|
||||
48, 50, 52, 54, 56, 58, 60, 62, 64,
|
||||
100, 102, 104, 106, 108, 110,
|
||||
112, 114, 116, 118, 120, 122,
|
||||
124, 126, 128, 130, 132, 134, 136,
|
||||
138, 140, 149, 151, 153, 155, 157,
|
||||
159, 161, 163, 165};
|
||||
static const u8 channel_all[TARGET_CHNL_NUM_2G_5G] = {
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
|
||||
13, 14, 36, 38, 40, 42, 44, 46,
|
||||
48, 50, 52, 54, 56, 58, 60, 62, 64,
|
||||
100, 102, 104, 106, 108, 110,
|
||||
112, 114, 116, 118, 120, 122,
|
||||
124, 126, 128, 130, 132, 134, 136,
|
||||
138, 140, 149, 151, 153, 155, 157,
|
||||
159, 161, 163, 165
|
||||
};
|
||||
u8 place = chnl;
|
||||
|
||||
if (chnl > 14) {
|
||||
|
@ -979,6 +979,9 @@ int rtl_usb_probe(struct usb_interface *intf,
|
||||
usb_priv->dev.intf = intf;
|
||||
usb_priv->dev.udev = udev;
|
||||
usb_set_intfdata(intf, hw);
|
||||
/* For dual MAC RTL8192DU, which has two interfaces. */
|
||||
rtlpriv->rtlhal.interfaceindex =
|
||||
intf->altsetting[0].desc.bInterfaceNumber;
|
||||
/* init cfg & intf_ops */
|
||||
rtlpriv->rtlhal.interface = INTF_USB;
|
||||
rtlpriv->cfg = rtl_hal_cfg;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#define MASKBYTE1 0xff00
|
||||
#define MASKBYTE2 0xff0000
|
||||
#define MASKBYTE3 0xff000000
|
||||
#define MASKH3BYTES 0xffffff00
|
||||
#define MASKHWORD 0xffff0000
|
||||
#define MASKLWORD 0x0000ffff
|
||||
#define MASKDWORD 0xffffffff
|
||||
@ -48,6 +49,10 @@
|
||||
#define MASK20BITS 0xfffff
|
||||
#define RFREG_OFFSET_MASK 0xfffff
|
||||
|
||||
/* For dual MAC RTL8192DU */
|
||||
#define MAC0_ACCESS_PHY1 0x4000
|
||||
#define MAC1_ACCESS_PHY0 0x2000
|
||||
|
||||
#define RF_CHANGE_BY_INIT 0
|
||||
#define RF_CHANGE_BY_IPS BIT(28)
|
||||
#define RF_CHANGE_BY_PS BIT(29)
|
||||
@ -1043,33 +1048,6 @@ struct octet_string {
|
||||
u16 length;
|
||||
};
|
||||
|
||||
struct rtl_hdr_3addr {
|
||||
__le16 frame_ctl;
|
||||
__le16 duration_id;
|
||||
u8 addr1[ETH_ALEN];
|
||||
u8 addr2[ETH_ALEN];
|
||||
u8 addr3[ETH_ALEN];
|
||||
__le16 seq_ctl;
|
||||
u8 payload[];
|
||||
} __packed;
|
||||
|
||||
struct rtl_info_element {
|
||||
u8 id;
|
||||
u8 len;
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
struct rtl_probe_rsp {
|
||||
struct rtl_hdr_3addr header;
|
||||
u32 time_stamp[2];
|
||||
__le16 beacon_interval;
|
||||
__le16 capability;
|
||||
/*SSID, supported rates, FH params, DS params,
|
||||
* CF params, IBSS params, TIM (if beacon), RSN
|
||||
*/
|
||||
struct rtl_info_element info_element[];
|
||||
} __packed;
|
||||
|
||||
struct rtl_led_ctl {
|
||||
bool led_opendrain;
|
||||
enum rtl_led_pin sw_led0;
|
||||
@ -2268,6 +2246,7 @@ struct rtl_hal_ops {
|
||||
bool (*config_bb_with_pgheaderfile)(struct ieee80211_hw *hw,
|
||||
u8 configtype);
|
||||
void (*phy_lc_calibrate)(struct ieee80211_hw *hw, bool is2t);
|
||||
void (*phy_iq_calibrate)(struct ieee80211_hw *hw);
|
||||
void (*phy_set_bw_mode_callback)(struct ieee80211_hw *hw);
|
||||
void (*dm_dynamic_txpower)(struct ieee80211_hw *hw);
|
||||
void (*c2h_command_handle)(struct ieee80211_hw *hw);
|
||||
|
@ -26,6 +26,7 @@ enum rtw_debug_mask {
|
||||
RTW_DBG_STATE = 0x00020000,
|
||||
RTW_DBG_SDIO = 0x00040000,
|
||||
|
||||
RTW_DBG_UNEXP = 0x80000000,
|
||||
RTW_DBG_ALL = 0xffffffff
|
||||
};
|
||||
|
||||
|
@ -1039,14 +1039,15 @@ static void __rtw_mac_flush_prio_queue(struct rtw_dev *rtwdev,
|
||||
msleep(20);
|
||||
}
|
||||
|
||||
/* priority queue is still not empty, throw a warning,
|
||||
/* priority queue is still not empty, throw a debug message
|
||||
*
|
||||
* Note that if we want to flush the tx queue when having a lot of
|
||||
* traffic (ex, 100Mbps up), some of the packets could be dropped.
|
||||
* And it requires like ~2secs to flush the full priority queue.
|
||||
*/
|
||||
if (!drop)
|
||||
rtw_warn(rtwdev, "timed out to flush queue %d\n", prio_queue);
|
||||
rtw_dbg(rtwdev, RTW_DBG_UNEXP,
|
||||
"timed out to flush queue %d\n", prio_queue);
|
||||
}
|
||||
|
||||
static void rtw_mac_flush_prio_queues(struct rtw_dev *rtwdev,
|
||||
|
@ -729,7 +729,8 @@ static void __pci_flush_queue(struct rtw_dev *rtwdev, u8 pci_q, bool drop)
|
||||
}
|
||||
|
||||
if (!drop)
|
||||
rtw_warn(rtwdev, "timed out to flush pci tx ring[%d]\n", pci_q);
|
||||
rtw_dbg(rtwdev, RTW_DBG_UNEXP,
|
||||
"timed out to flush pci tx ring[%d]\n", pci_q);
|
||||
}
|
||||
|
||||
static void __rtw_pci_flush_queues(struct rtw_dev *rtwdev, u32 pci_queues,
|
||||
|
@ -77,6 +77,50 @@ int rtw89_acpi_dsm_get_policy_6ghz(struct rtw89_dev *rtwdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool chk_acpi_policy_6ghz_sp_sig(const struct rtw89_acpi_policy_6ghz_sp *p)
|
||||
{
|
||||
return p->signature[0] == 0x52 &&
|
||||
p->signature[1] == 0x54 &&
|
||||
p->signature[2] == 0x4B &&
|
||||
p->signature[3] == 0x07;
|
||||
}
|
||||
|
||||
static
|
||||
int rtw89_acpi_dsm_get_policy_6ghz_sp(struct rtw89_dev *rtwdev,
|
||||
union acpi_object *obj,
|
||||
struct rtw89_acpi_policy_6ghz_sp **policy)
|
||||
{
|
||||
const struct rtw89_acpi_policy_6ghz_sp *ptr;
|
||||
u32 buf_len;
|
||||
|
||||
if (obj->type != ACPI_TYPE_BUFFER) {
|
||||
rtw89_debug(rtwdev, RTW89_DBG_ACPI,
|
||||
"acpi: expect buffer but type: %d\n", obj->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buf_len = obj->buffer.length;
|
||||
if (buf_len < sizeof(*ptr)) {
|
||||
rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: invalid buffer length: %u\n",
|
||||
__func__, buf_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ptr = (typeof(ptr))obj->buffer.pointer;
|
||||
if (!chk_acpi_policy_6ghz_sp_sig(ptr)) {
|
||||
rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: bad signature\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*policy = kmemdup(ptr, sizeof(*ptr), GFP_KERNEL);
|
||||
if (!*policy)
|
||||
return -ENOMEM;
|
||||
|
||||
rtw89_hex_dump(rtwdev, RTW89_DBG_ACPI, "policy_6ghz_sp: ", *policy,
|
||||
sizeof(*ptr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev,
|
||||
enum rtw89_acpi_dsm_func func,
|
||||
struct rtw89_acpi_dsm_result *res)
|
||||
@ -95,6 +139,9 @@ int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev,
|
||||
if (func == RTW89_ACPI_DSM_FUNC_6G_BP)
|
||||
ret = rtw89_acpi_dsm_get_policy_6ghz(rtwdev, obj,
|
||||
&res->u.policy_6ghz);
|
||||
else if (func == RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP)
|
||||
ret = rtw89_acpi_dsm_get_policy_6ghz_sp(rtwdev, obj,
|
||||
&res->u.policy_6ghz_sp);
|
||||
else
|
||||
ret = rtw89_acpi_dsm_get_value(rtwdev, obj, &res->u.value);
|
||||
|
||||
|
@ -12,7 +12,13 @@ enum rtw89_acpi_dsm_func {
|
||||
RTW89_ACPI_DSM_FUNC_6G_DIS = 3,
|
||||
RTW89_ACPI_DSM_FUNC_6G_BP = 4,
|
||||
RTW89_ACPI_DSM_FUNC_TAS_EN = 5,
|
||||
RTW89_ACPI_DSM_FUNC_59G_EN = 6,
|
||||
RTW89_ACPI_DSM_FUNC_UNII4_SUP = 6,
|
||||
RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP = 7,
|
||||
};
|
||||
|
||||
enum rtw89_acpi_conf_unii4 {
|
||||
RTW89_ACPI_CONF_UNII4_FCC = BIT(0),
|
||||
RTW89_ACPI_CONF_UNII4_IC = BIT(1),
|
||||
};
|
||||
|
||||
enum rtw89_acpi_policy_mode {
|
||||
@ -36,11 +42,24 @@ struct rtw89_acpi_policy_6ghz {
|
||||
struct rtw89_acpi_country_code country_list[] __counted_by(country_count);
|
||||
} __packed;
|
||||
|
||||
enum rtw89_acpi_conf_6ghz_sp {
|
||||
RTW89_ACPI_CONF_6GHZ_SP_US = BIT(0),
|
||||
};
|
||||
|
||||
struct rtw89_acpi_policy_6ghz_sp {
|
||||
u8 signature[4];
|
||||
u8 revision;
|
||||
u8 override;
|
||||
u8 conf;
|
||||
u8 rsvd;
|
||||
} __packed;
|
||||
|
||||
struct rtw89_acpi_dsm_result {
|
||||
union {
|
||||
u8 value;
|
||||
/* caller needs to free it after using */
|
||||
struct rtw89_acpi_policy_6ghz *policy_6ghz;
|
||||
struct rtw89_acpi_policy_6ghz_sp *policy_6ghz_sp;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
@ -150,8 +150,6 @@ static int rtw89_cam_get_addr_cam_key_idx(struct rtw89_addr_cam_entry *addr_cam,
|
||||
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)
|
||||
@ -232,6 +230,11 @@ static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
|
||||
|
||||
rtwvif = (struct rtw89_vif *)vif->drv_priv;
|
||||
addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
|
||||
|
||||
if (key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
|
||||
key->cipher == WLAN_CIPHER_SUITE_WEP104)
|
||||
addr_cam->sec_ent_mode = RTW89_ADDR_CAM_SEC_ALL_UNI;
|
||||
|
||||
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",
|
||||
@ -356,6 +359,9 @@ int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev,
|
||||
key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
|
||||
ext_key = true;
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_AES_CMAC:
|
||||
hw_key_type = RTW89_SEC_KEY_TYPE_BIP_CCMP128;
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@ -753,29 +759,80 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
|
||||
void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif,
|
||||
struct rtw89_sta *rtwsta,
|
||||
u8 *cmd)
|
||||
struct rtw89_h2c_dctlinfo_ud_v1 *h2c)
|
||||
{
|
||||
struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
u8 *ptk_tx_iv = rtw_wow->key_info.ptk_tx_iv;
|
||||
|
||||
SET_DCTL_MACID_V1(cmd, rtwsta ? rtwsta->mac_id : rtwvif->mac_id);
|
||||
SET_DCTL_OPERATION_V1(cmd, 1);
|
||||
h2c->c0 = le32_encode_bits(rtwsta ? rtwsta->mac_id : rtwvif->mac_id,
|
||||
DCTLINFO_V1_C0_MACID) |
|
||||
le32_encode_bits(1, DCTLINFO_V1_C0_OP);
|
||||
|
||||
SET_DCTL_SEC_ENT0_KEYID_V1(cmd, addr_cam->sec_ent_keyid[0]);
|
||||
SET_DCTL_SEC_ENT1_KEYID_V1(cmd, addr_cam->sec_ent_keyid[1]);
|
||||
SET_DCTL_SEC_ENT2_KEYID_V1(cmd, addr_cam->sec_ent_keyid[2]);
|
||||
SET_DCTL_SEC_ENT3_KEYID_V1(cmd, addr_cam->sec_ent_keyid[3]);
|
||||
SET_DCTL_SEC_ENT4_KEYID_V1(cmd, addr_cam->sec_ent_keyid[4]);
|
||||
SET_DCTL_SEC_ENT5_KEYID_V1(cmd, addr_cam->sec_ent_keyid[5]);
|
||||
SET_DCTL_SEC_ENT6_KEYID_V1(cmd, addr_cam->sec_ent_keyid[6]);
|
||||
h2c->w4 = le32_encode_bits(addr_cam->sec_ent_keyid[0],
|
||||
DCTLINFO_V1_W4_SEC_ENT0_KEYID) |
|
||||
le32_encode_bits(addr_cam->sec_ent_keyid[1],
|
||||
DCTLINFO_V1_W4_SEC_ENT1_KEYID) |
|
||||
le32_encode_bits(addr_cam->sec_ent_keyid[2],
|
||||
DCTLINFO_V1_W4_SEC_ENT2_KEYID) |
|
||||
le32_encode_bits(addr_cam->sec_ent_keyid[3],
|
||||
DCTLINFO_V1_W4_SEC_ENT3_KEYID) |
|
||||
le32_encode_bits(addr_cam->sec_ent_keyid[4],
|
||||
DCTLINFO_V1_W4_SEC_ENT4_KEYID) |
|
||||
le32_encode_bits(addr_cam->sec_ent_keyid[5],
|
||||
DCTLINFO_V1_W4_SEC_ENT5_KEYID) |
|
||||
le32_encode_bits(addr_cam->sec_ent_keyid[6],
|
||||
DCTLINFO_V1_W4_SEC_ENT6_KEYID);
|
||||
h2c->m4 = cpu_to_le32(DCTLINFO_V1_W4_SEC_ENT0_KEYID |
|
||||
DCTLINFO_V1_W4_SEC_ENT1_KEYID |
|
||||
DCTLINFO_V1_W4_SEC_ENT2_KEYID |
|
||||
DCTLINFO_V1_W4_SEC_ENT3_KEYID |
|
||||
DCTLINFO_V1_W4_SEC_ENT4_KEYID |
|
||||
DCTLINFO_V1_W4_SEC_ENT5_KEYID |
|
||||
DCTLINFO_V1_W4_SEC_ENT6_KEYID);
|
||||
|
||||
SET_DCTL_SEC_ENT_VALID_V1(cmd, addr_cam->sec_cam_map[0] & 0xff);
|
||||
SET_DCTL_SEC_ENT0_V1(cmd, addr_cam->sec_ent[0]);
|
||||
SET_DCTL_SEC_ENT1_V1(cmd, addr_cam->sec_ent[1]);
|
||||
SET_DCTL_SEC_ENT2_V1(cmd, addr_cam->sec_ent[2]);
|
||||
SET_DCTL_SEC_ENT3_V1(cmd, addr_cam->sec_ent[3]);
|
||||
SET_DCTL_SEC_ENT4_V1(cmd, addr_cam->sec_ent[4]);
|
||||
SET_DCTL_SEC_ENT5_V1(cmd, addr_cam->sec_ent[5]);
|
||||
SET_DCTL_SEC_ENT6_V1(cmd, addr_cam->sec_ent[6]);
|
||||
h2c->w5 = le32_encode_bits(addr_cam->sec_cam_map[0] & 0xff,
|
||||
DCTLINFO_V1_W5_SEC_ENT_VALID) |
|
||||
le32_encode_bits(addr_cam->sec_ent[0],
|
||||
DCTLINFO_V1_W5_SEC_ENT0) |
|
||||
le32_encode_bits(addr_cam->sec_ent[1],
|
||||
DCTLINFO_V1_W5_SEC_ENT1) |
|
||||
le32_encode_bits(addr_cam->sec_ent[2],
|
||||
DCTLINFO_V1_W5_SEC_ENT2);
|
||||
h2c->m5 = cpu_to_le32(DCTLINFO_V1_W5_SEC_ENT_VALID |
|
||||
DCTLINFO_V1_W5_SEC_ENT0 |
|
||||
DCTLINFO_V1_W5_SEC_ENT1 |
|
||||
DCTLINFO_V1_W5_SEC_ENT2);
|
||||
|
||||
h2c->w6 = le32_encode_bits(addr_cam->sec_ent[3],
|
||||
DCTLINFO_V1_W6_SEC_ENT3) |
|
||||
le32_encode_bits(addr_cam->sec_ent[4],
|
||||
DCTLINFO_V1_W6_SEC_ENT4) |
|
||||
le32_encode_bits(addr_cam->sec_ent[5],
|
||||
DCTLINFO_V1_W6_SEC_ENT5) |
|
||||
le32_encode_bits(addr_cam->sec_ent[6],
|
||||
DCTLINFO_V1_W6_SEC_ENT6);
|
||||
h2c->m6 = cpu_to_le32(DCTLINFO_V1_W6_SEC_ENT3 |
|
||||
DCTLINFO_V1_W6_SEC_ENT4 |
|
||||
DCTLINFO_V1_W6_SEC_ENT5 |
|
||||
DCTLINFO_V1_W6_SEC_ENT6);
|
||||
|
||||
if (rtw_wow->ptk_alg) {
|
||||
h2c->w0 = le32_encode_bits(ptk_tx_iv[0] | ptk_tx_iv[1] << 8,
|
||||
DCTLINFO_V1_W0_AES_IV_L);
|
||||
h2c->m0 = cpu_to_le32(DCTLINFO_V1_W0_AES_IV_L);
|
||||
|
||||
h2c->w1 = le32_encode_bits(ptk_tx_iv[4] |
|
||||
ptk_tx_iv[5] << 8 |
|
||||
ptk_tx_iv[6] << 16 |
|
||||
ptk_tx_iv[7] << 24,
|
||||
DCTLINFO_V1_W1_AES_IV_H);
|
||||
h2c->m1 = cpu_to_le32(DCTLINFO_V1_W1_AES_IV_H);
|
||||
|
||||
h2c->w4 |= le32_encode_bits(rtw_wow->ptk_keyidx,
|
||||
DCTLINFO_V1_W4_SEC_KEY_ID);
|
||||
h2c->m4 |= cpu_to_le32(DCTLINFO_V1_W4_SEC_KEY_ID);
|
||||
}
|
||||
}
|
||||
|
||||
void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
|
||||
@ -784,6 +841,8 @@ void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_h2c_dctlinfo_ud_v2 *h2c)
|
||||
{
|
||||
struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
u8 *ptk_tx_iv = rtw_wow->key_info.ptk_tx_iv;
|
||||
|
||||
h2c->c0 = le32_encode_bits(rtwsta ? rtwsta->mac_id : rtwvif->mac_id,
|
||||
DCTLINFO_V2_C0_MACID) |
|
||||
@ -837,4 +896,21 @@ void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
|
||||
DCTLINFO_V2_W7_SEC_ENT6_V1);
|
||||
h2c->m7 = cpu_to_le32(DCTLINFO_V2_W7_SEC_ENT5_V1 |
|
||||
DCTLINFO_V2_W7_SEC_ENT6_V1);
|
||||
|
||||
if (rtw_wow->ptk_alg) {
|
||||
h2c->w0 = le32_encode_bits(ptk_tx_iv[0] | ptk_tx_iv[1] << 8,
|
||||
DCTLINFO_V2_W0_AES_IV_L);
|
||||
h2c->m0 = cpu_to_le32(DCTLINFO_V2_W0_AES_IV_L);
|
||||
|
||||
h2c->w1 = le32_encode_bits(ptk_tx_iv[4] |
|
||||
ptk_tx_iv[5] << 8 |
|
||||
ptk_tx_iv[6] << 16 |
|
||||
ptk_tx_iv[7] << 24,
|
||||
DCTLINFO_V2_W1_AES_IV_H);
|
||||
h2c->m1 = cpu_to_le32(DCTLINFO_V2_W1_AES_IV_H);
|
||||
|
||||
h2c->w4 |= le32_encode_bits(rtw_wow->ptk_keyidx,
|
||||
DCTLINFO_V2_W4_SEC_KEY_ID);
|
||||
h2c->m4 |= cpu_to_le32(DCTLINFO_V2_W4_SEC_KEY_ID);
|
||||
}
|
||||
}
|
||||
|
@ -352,6 +352,75 @@ static inline void FWCMD_SET_ADDR_BSSID_BSSID5(void *cmd, u32 value)
|
||||
le32p_replace_bits((__le32 *)(cmd) + 14, value, GENMASK(31, 24));
|
||||
}
|
||||
|
||||
struct rtw89_h2c_dctlinfo_ud_v1 {
|
||||
__le32 c0;
|
||||
__le32 w0;
|
||||
__le32 w1;
|
||||
__le32 w2;
|
||||
__le32 w3;
|
||||
__le32 w4;
|
||||
__le32 w5;
|
||||
__le32 w6;
|
||||
__le32 w7;
|
||||
__le32 m0;
|
||||
__le32 m1;
|
||||
__le32 m2;
|
||||
__le32 m3;
|
||||
__le32 m4;
|
||||
__le32 m5;
|
||||
__le32 m6;
|
||||
__le32 m7;
|
||||
} __packed;
|
||||
|
||||
#define DCTLINFO_V1_C0_MACID GENMASK(6, 0)
|
||||
#define DCTLINFO_V1_C0_OP BIT(7)
|
||||
|
||||
#define DCTLINFO_V1_W0_QOS_FIELD_H GENMASK(7, 0)
|
||||
#define DCTLINFO_V1_W0_HW_EXSEQ_MACID GENMASK(14, 8)
|
||||
#define DCTLINFO_V1_W0_QOS_DATA BIT(15)
|
||||
#define DCTLINFO_V1_W0_AES_IV_L GENMASK(31, 16)
|
||||
#define DCTLINFO_V1_W0_ALL GENMASK(31, 0)
|
||||
#define DCTLINFO_V1_W1_AES_IV_H GENMASK(31, 0)
|
||||
#define DCTLINFO_V1_W1_ALL GENMASK(31, 0)
|
||||
#define DCTLINFO_V1_W2_SEQ0 GENMASK(11, 0)
|
||||
#define DCTLINFO_V1_W2_SEQ1 GENMASK(23, 12)
|
||||
#define DCTLINFO_V1_W2_AMSDU_MAX_LEN GENMASK(26, 24)
|
||||
#define DCTLINFO_V1_W2_STA_AMSDU_EN BIT(27)
|
||||
#define DCTLINFO_V1_W2_CHKSUM_OFLD_EN BIT(28)
|
||||
#define DCTLINFO_V1_W2_WITH_LLC BIT(29)
|
||||
#define DCTLINFO_V1_W2_ALL GENMASK(29, 0)
|
||||
#define DCTLINFO_V1_W3_SEQ2 GENMASK(11, 0)
|
||||
#define DCTLINFO_V1_W3_SEQ3 GENMASK(23, 12)
|
||||
#define DCTLINFO_V1_W3_TGT_IND GENMASK(27, 24)
|
||||
#define DCTLINFO_V1_W3_TGT_IND_EN BIT(28)
|
||||
#define DCTLINFO_V1_W3_HTC_LB GENMASK(31, 29)
|
||||
#define DCTLINFO_V1_W3_ALL GENMASK(31, 0)
|
||||
#define DCTLINFO_V1_W4_MHDR_LEN GENMASK(4, 0)
|
||||
#define DCTLINFO_V1_W4_VLAN_TAG_VALID BIT(5)
|
||||
#define DCTLINFO_V1_W4_VLAN_TAG_SEL GENMASK(7, 6)
|
||||
#define DCTLINFO_V1_W4_HTC_ORDER BIT(8)
|
||||
#define DCTLINFO_V1_W4_SEC_KEY_ID GENMASK(10, 9)
|
||||
#define DCTLINFO_V1_W4_WAPI BIT(15)
|
||||
#define DCTLINFO_V1_W4_SEC_ENT_MODE GENMASK(17, 16)
|
||||
#define DCTLINFO_V1_W4_SEC_ENT0_KEYID GENMASK(19, 18)
|
||||
#define DCTLINFO_V1_W4_SEC_ENT1_KEYID GENMASK(21, 20)
|
||||
#define DCTLINFO_V1_W4_SEC_ENT2_KEYID GENMASK(23, 22)
|
||||
#define DCTLINFO_V1_W4_SEC_ENT3_KEYID GENMASK(25, 24)
|
||||
#define DCTLINFO_V1_W4_SEC_ENT4_KEYID GENMASK(27, 26)
|
||||
#define DCTLINFO_V1_W4_SEC_ENT5_KEYID GENMASK(29, 28)
|
||||
#define DCTLINFO_V1_W4_SEC_ENT6_KEYID GENMASK(31, 30)
|
||||
#define DCTLINFO_V1_W4_ALL (GENMASK(31, 15) | GENMASK(10, 0))
|
||||
#define DCTLINFO_V1_W5_SEC_ENT_VALID GENMASK(7, 0)
|
||||
#define DCTLINFO_V1_W5_SEC_ENT0 GENMASK(15, 8)
|
||||
#define DCTLINFO_V1_W5_SEC_ENT1 GENMASK(23, 16)
|
||||
#define DCTLINFO_V1_W5_SEC_ENT2 GENMASK(31, 24)
|
||||
#define DCTLINFO_V1_W5_ALL GENMASK(31, 0)
|
||||
#define DCTLINFO_V1_W6_SEC_ENT3 GENMASK(7, 0)
|
||||
#define DCTLINFO_V1_W6_SEC_ENT4 GENMASK(15, 8)
|
||||
#define DCTLINFO_V1_W6_SEC_ENT5 GENMASK(23, 16)
|
||||
#define DCTLINFO_V1_W6_SEC_ENT6 GENMASK(31, 24)
|
||||
#define DCTLINFO_V1_W6_ALL GENMASK(31, 0)
|
||||
|
||||
struct rtw89_h2c_dctlinfo_ud_v2 {
|
||||
__le32 c0;
|
||||
__le32 w0;
|
||||
@ -477,7 +546,7 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
|
||||
void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif,
|
||||
struct rtw89_sta *rtwsta,
|
||||
u8 *cmd);
|
||||
struct rtw89_h2c_dctlinfo_ud_v1 *h2c);
|
||||
void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif,
|
||||
struct rtw89_sta *rtwsta,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -9,6 +9,7 @@
|
||||
|
||||
#define BTC_H2C_MAXLEN 2020
|
||||
#define BTC_TLV_SLOT_ID_LEN_V7 1
|
||||
#define BTC_SLOT_REQ_TH 2
|
||||
|
||||
enum btc_mode {
|
||||
BTC_MODE_NORMAL,
|
||||
@ -221,6 +222,41 @@ enum btc_wl_mode {
|
||||
BTC_WL_MODE_NUM,
|
||||
};
|
||||
|
||||
enum btc_wl_gpio_debug {
|
||||
BTC_DBG_GNT_BT = 0,
|
||||
BTC_DBG_GNT_WL = 1,
|
||||
BTC_DBG_BCN_EARLY = 2,
|
||||
BTC_DBG_WL_NULL0 = 3,
|
||||
BTC_DBG_WL_NULL1 = 4,
|
||||
BTC_DBG_WL_RXISR = 5,
|
||||
BTC_DBG_TDMA_ENTRY = 6,
|
||||
BTC_DBG_A2DP_EMPTY = 7,
|
||||
BTC_DBG_BT_RETRY = 8,
|
||||
BTC_DBG_BT_RELINK = 9,
|
||||
BTC_DBG_SLOT_WL = 10,
|
||||
BTC_DBG_SLOT_BT = 11,
|
||||
BTC_DBG_WL_ERR = 12,
|
||||
BTC_DBG_WL_OK = 13,
|
||||
BTC_DBG_SLOT_B2W = 14,
|
||||
BTC_DBG_SLOT_W1 = 15,
|
||||
BTC_DBG_SLOT_W2 = 16,
|
||||
BTC_DBG_SLOT_W2B = 17,
|
||||
BTC_DBG_SLOT_B1 = 18,
|
||||
BTC_DBG_SLOT_B2 = 19,
|
||||
BTC_DBG_SLOT_B3 = 20,
|
||||
BTC_DBG_SLOT_B4 = 21,
|
||||
BTC_DBG_SLOT_LK = 22,
|
||||
BTC_DBG_SLOT_E2G = 23,
|
||||
BTC_DBG_SLOT_E5G = 24,
|
||||
BTC_DBG_SLOT_EBT = 25,
|
||||
BTC_DBG_SLOT_WLK = 26,
|
||||
BTC_DBG_SLOT_B1FDD = 27,
|
||||
BTC_DBG_BT_CHANGE = 28,
|
||||
BTC_DBG_WL_CCA = 29,
|
||||
BTC_DBG_BT_LEAUDIO = 30,
|
||||
BTC_DBG_USER_DEF = 31,
|
||||
};
|
||||
|
||||
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);
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "ser.h"
|
||||
#include "txrx.h"
|
||||
#include "util.h"
|
||||
#include "wow.h"
|
||||
|
||||
static bool rtw89_disable_ps_mode;
|
||||
module_param_named(disable_ps_mode, rtw89_disable_ps_mode, bool, 0644);
|
||||
@ -82,6 +83,9 @@ static struct ieee80211_channel rtw89_channels_5ghz[] = {
|
||||
RTW89_DEF_CHAN_5G(5885, 177),
|
||||
};
|
||||
|
||||
static_assert(RTW89_5GHZ_UNII4_START_INDEX + RTW89_5GHZ_UNII4_CHANNEL_NUM ==
|
||||
ARRAY_SIZE(rtw89_channels_5ghz));
|
||||
|
||||
static struct ieee80211_channel rtw89_channels_6ghz[] = {
|
||||
RTW89_DEF_CHAN_6G(5955, 1),
|
||||
RTW89_DEF_CHAN_6G(5975, 5),
|
||||
@ -252,6 +256,9 @@ static void rtw89_traffic_stats_accu(struct rtw89_dev *rtwdev,
|
||||
{
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
|
||||
if (tx && ieee80211_is_assoc_req(hdr->frame_control))
|
||||
rtw89_wow_parse_akm(rtwdev, skb);
|
||||
|
||||
if (!ieee80211_is_data(hdr->frame_control))
|
||||
return;
|
||||
|
||||
@ -4504,11 +4511,15 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
|
||||
|
||||
hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
|
||||
WIPHY_FLAG_TDLS_EXTERNAL_SETUP |
|
||||
WIPHY_FLAG_AP_UAPSD;
|
||||
WIPHY_FLAG_AP_UAPSD |
|
||||
WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK;
|
||||
|
||||
if (!chip->support_rnr)
|
||||
hw->wiphy->flags |= WIPHY_FLAG_SPLIT_SCAN_6GHZ;
|
||||
|
||||
if (chip->chip_gen == RTW89_CHIP_BE)
|
||||
hw->wiphy->flags |= WIPHY_FLAG_DISABLE_WEXT;
|
||||
|
||||
hw->wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
|
||||
|
||||
hw->wiphy->max_scan_ssids = RTW89_SCANOFLD_MAX_SSID;
|
||||
|
@ -1180,9 +1180,13 @@ enum rtw89_btc_ncnt {
|
||||
BTC_NCNT_CUSTOMERIZE,
|
||||
BTC_NCNT_WL_RFK,
|
||||
BTC_NCNT_WL_STA,
|
||||
BTC_NCNT_WL_STA_LAST,
|
||||
BTC_NCNT_FWINFO,
|
||||
BTC_NCNT_TIMER,
|
||||
BTC_NCNT_NUM
|
||||
BTC_NCNT_SWITCH_CHBW,
|
||||
BTC_NCNT_RESUME_DL_FW,
|
||||
BTC_NCNT_COUNTRYCODE,
|
||||
BTC_NCNT_NUM,
|
||||
};
|
||||
|
||||
enum rtw89_btc_btinfo {
|
||||
@ -1211,6 +1215,7 @@ enum rtw89_btc_dcnt {
|
||||
BTC_DCNT_TDMA_NONSYNC,
|
||||
BTC_DCNT_SLOT_NONSYNC,
|
||||
BTC_DCNT_BTCNT_HANG,
|
||||
BTC_DCNT_BTTX_HANG,
|
||||
BTC_DCNT_WL_SLOT_DRIFT,
|
||||
BTC_DCNT_WL_STA_LAST,
|
||||
BTC_DCNT_BT_SLOT_DRIFT,
|
||||
@ -1218,7 +1223,10 @@ enum rtw89_btc_dcnt {
|
||||
BTC_DCNT_FDDT_TRIG,
|
||||
BTC_DCNT_E2G,
|
||||
BTC_DCNT_E2G_HANG,
|
||||
BTC_DCNT_NUM
|
||||
BTC_DCNT_WL_FW_VER_MATCH,
|
||||
BTC_DCNT_NULL_TX_FAIL,
|
||||
BTC_DCNT_WL_STA_NTFY,
|
||||
BTC_DCNT_NUM,
|
||||
};
|
||||
|
||||
enum rtw89_btc_wl_state_cnt {
|
||||
@ -1262,8 +1270,10 @@ enum rtw89_btc_bt_state_cnt {
|
||||
BTC_BCNT_LOPRI_TX,
|
||||
BTC_BCNT_LOPRI_RX,
|
||||
BTC_BCNT_POLUT,
|
||||
BTC_BCNT_POLUT_NOW,
|
||||
BTC_BCNT_POLUT_DIFF,
|
||||
BTC_BCNT_RATECHG,
|
||||
BTC_BCNT_NUM
|
||||
BTC_BCNT_NUM,
|
||||
};
|
||||
|
||||
enum rtw89_btc_bt_profile {
|
||||
@ -1308,6 +1318,7 @@ struct rtw89_btc_wl_smap {
|
||||
u32 scan: 1;
|
||||
u32 connecting: 1;
|
||||
u32 roaming: 1;
|
||||
u32 transacting: 1;
|
||||
u32 _4way: 1;
|
||||
u32 rf_off: 1;
|
||||
u32 lps: 2;
|
||||
@ -1316,6 +1327,8 @@ struct rtw89_btc_wl_smap {
|
||||
u32 traffic_dir : 2;
|
||||
u32 rf_off_pre: 1;
|
||||
u32 lps_pre: 2;
|
||||
u32 lps_exiting: 1;
|
||||
u32 emlsr: 1;
|
||||
};
|
||||
|
||||
enum rtw89_tfc_lv {
|
||||
@ -1432,6 +1445,11 @@ struct rtw89_btc_bt_a2dp_desc {
|
||||
u8 type: 3;
|
||||
u8 active: 1;
|
||||
u8 sink: 1;
|
||||
u32 handle_update: 1;
|
||||
u32 devinfo_query: 1;
|
||||
u32 no_empty_streak_2s: 8;
|
||||
u32 no_empty_streak_max: 8;
|
||||
u32 rsvd: 6;
|
||||
|
||||
u8 bitpool;
|
||||
u16 vendor_id;
|
||||
@ -1667,6 +1685,9 @@ struct rtw89_btc_wl_rfk_info {
|
||||
u32 band: 2;
|
||||
u32 type: 8;
|
||||
u32 rsvd: 14;
|
||||
|
||||
u32 start_time;
|
||||
u32 proc_time;
|
||||
};
|
||||
|
||||
struct rtw89_btc_bt_smap {
|
||||
@ -1799,11 +1820,13 @@ struct rtw89_btc_wl_info {
|
||||
u8 cn_report;
|
||||
u8 coex_mode;
|
||||
u8 pta_req_mac;
|
||||
u8 bt_polut_type[RTW89_PHY_MAX]; /* BT polluted WL-Tx type for phy0/1 */
|
||||
|
||||
bool is_5g_hi_channel;
|
||||
bool pta_reg_mac_chg;
|
||||
bool bg_mode;
|
||||
bool scbd_change;
|
||||
bool fw_ver_mismatch;
|
||||
u32 scbd;
|
||||
};
|
||||
|
||||
@ -1931,9 +1954,18 @@ struct rtw89_btc_fbtc_btscan_v2 {
|
||||
struct rtw89_btc_bt_scan_info_v2 para[CXSCAN_MAX];
|
||||
} __packed;
|
||||
|
||||
struct rtw89_btc_fbtc_btscan_v7 {
|
||||
u8 fver; /* btc_ver::fcxbtscan */
|
||||
u8 type;
|
||||
u8 rsvd0;
|
||||
u8 rsvd1;
|
||||
struct rtw89_btc_bt_scan_info_v2 para[CXSCAN_MAX];
|
||||
} __packed;
|
||||
|
||||
union rtw89_btc_fbtc_btscan {
|
||||
struct rtw89_btc_fbtc_btscan_v1 v1;
|
||||
struct rtw89_btc_fbtc_btscan_v2 v2;
|
||||
struct rtw89_btc_fbtc_btscan_v7 v7;
|
||||
};
|
||||
|
||||
struct rtw89_btc_bt_info {
|
||||
@ -2075,6 +2107,20 @@ struct rtw89_btc_fbtc_rpt_ctrl_info_v5 {
|
||||
__le16 cnt_aoac_rf_off; /* rf-off counter for aoac switch notify */
|
||||
} __packed;
|
||||
|
||||
struct rtw89_btc_fbtc_rpt_ctrl_info_v8 {
|
||||
__le16 cnt; /* fw report counter */
|
||||
__le16 cnt_c2h; /* fw send c2h counter */
|
||||
__le16 cnt_h2c; /* fw recv h2c counter */
|
||||
__le16 len_c2h; /* The total length of the last C2H */
|
||||
|
||||
__le16 cnt_aoac_rf_on; /* rf-on counter for aoac switch notify */
|
||||
__le16 cnt_aoac_rf_off; /* rf-off counter for aoac switch notify */
|
||||
|
||||
__le32 cx_ver; /* match which driver's coex version */
|
||||
__le32 fw_ver;
|
||||
__le32 en; /* report map */
|
||||
} __packed;
|
||||
|
||||
struct rtw89_btc_fbtc_rpt_ctrl_wl_fw_info {
|
||||
__le32 cx_ver; /* match which driver's coex version */
|
||||
__le32 cx_offload;
|
||||
@ -2131,11 +2177,25 @@ struct rtw89_btc_fbtc_rpt_ctrl_v105 {
|
||||
struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info;
|
||||
} __packed;
|
||||
|
||||
struct rtw89_btc_fbtc_rpt_ctrl_v8 {
|
||||
u8 fver;
|
||||
u8 rsvd0;
|
||||
u8 rpt_len_max_l; /* BTC_RPT_MAX bit0~7 */
|
||||
u8 rpt_len_max_h; /* BTC_RPT_MAX bit8~15 */
|
||||
|
||||
u8 gnt_val[RTW89_PHY_MAX][4];
|
||||
__le16 bt_cnt[BTC_BCNT_STA_MAX_V105];
|
||||
|
||||
struct rtw89_btc_fbtc_rpt_ctrl_info_v8 rpt_info;
|
||||
struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info;
|
||||
} __packed;
|
||||
|
||||
union rtw89_btc_fbtc_rpt_ctrl_ver_info {
|
||||
struct rtw89_btc_fbtc_rpt_ctrl_v1 v1;
|
||||
struct rtw89_btc_fbtc_rpt_ctrl_v4 v4;
|
||||
struct rtw89_btc_fbtc_rpt_ctrl_v5 v5;
|
||||
struct rtw89_btc_fbtc_rpt_ctrl_v105 v105;
|
||||
struct rtw89_btc_fbtc_rpt_ctrl_v8 v8;
|
||||
};
|
||||
|
||||
enum rtw89_fbtc_ext_ctrl_type {
|
||||
@ -2242,15 +2302,32 @@ enum rtw89_btc_afh_map_type { /*AFH MAP TYPE */
|
||||
};
|
||||
|
||||
#define BTC_DBG_MAX1 32
|
||||
struct rtw89_btc_fbtc_gpio_dbg {
|
||||
struct rtw89_btc_fbtc_gpio_dbg_v1 {
|
||||
u8 fver; /* btc_ver::fcxgpiodbg */
|
||||
u8 rsvd;
|
||||
u16 rsvd2;
|
||||
u32 en_map; /* which debug signal (see btc_wl_gpio_debug) is enable */
|
||||
u32 pre_state; /* the debug signal is 1 or 0 */
|
||||
__le16 rsvd2;
|
||||
__le32 en_map; /* which debug signal (see btc_wl_gpio_debug) is enable */
|
||||
__le32 pre_state; /* the debug signal is 1 or 0 */
|
||||
u8 gpio_map[BTC_DBG_MAX1]; /*the debug signals to GPIO-Position */
|
||||
} __packed;
|
||||
|
||||
struct rtw89_btc_fbtc_gpio_dbg_v7 {
|
||||
u8 fver;
|
||||
u8 rsvd0;
|
||||
u8 rsvd1;
|
||||
u8 rsvd2;
|
||||
|
||||
u8 gpio_map[BTC_DBG_MAX1];
|
||||
|
||||
__le32 en_map;
|
||||
__le32 pre_state;
|
||||
} __packed;
|
||||
|
||||
union rtw89_btc_fbtc_gpio_dbg {
|
||||
struct rtw89_btc_fbtc_gpio_dbg_v1 v1;
|
||||
struct rtw89_btc_fbtc_gpio_dbg_v7 v7;
|
||||
};
|
||||
|
||||
struct rtw89_btc_fbtc_mreg_val_v1 {
|
||||
u8 fver; /* btc_ver::fcxmreg */
|
||||
u8 reg_num;
|
||||
@ -2265,9 +2342,18 @@ struct rtw89_btc_fbtc_mreg_val_v2 {
|
||||
__le32 mreg_val[CXMREG_MAX_V2];
|
||||
} __packed;
|
||||
|
||||
struct rtw89_btc_fbtc_mreg_val_v7 {
|
||||
u8 fver;
|
||||
u8 reg_num;
|
||||
u8 rsvd0;
|
||||
u8 rsvd1;
|
||||
__le32 mreg_val[CXMREG_MAX_V2];
|
||||
} __packed;
|
||||
|
||||
union rtw89_btc_fbtc_mreg_val {
|
||||
struct rtw89_btc_fbtc_mreg_val_v1 v1;
|
||||
struct rtw89_btc_fbtc_mreg_val_v2 v2;
|
||||
struct rtw89_btc_fbtc_mreg_val_v7 v7;
|
||||
};
|
||||
|
||||
#define RTW89_DEF_FBTC_MREG(__type, __bytes, __offset) \
|
||||
@ -2434,6 +2520,12 @@ struct rtw89_btc_fbtc_cycle_leak_info {
|
||||
__le16 tmax; /* max leak-slot time */
|
||||
} __packed;
|
||||
|
||||
struct rtw89_btc_fbtc_cycle_leak_info_v7 {
|
||||
__le16 tavg;
|
||||
__le16 tamx;
|
||||
__le32 cnt_rximr;
|
||||
} __packed;
|
||||
|
||||
#define RTW89_BTC_FDDT_PHASE_CYCLE GENMASK(9, 0)
|
||||
#define RTW89_BTC_FDDT_TRAIN_STEP GENMASK(15, 10)
|
||||
|
||||
@ -2546,11 +2638,36 @@ struct rtw89_btc_fbtc_cysta_v5 { /* statistics for cycles */
|
||||
__le32 except_map;
|
||||
} __packed;
|
||||
|
||||
struct rtw89_btc_fbtc_cysta_v7 { /* statistics for cycles */
|
||||
u8 fver;
|
||||
u8 rsvd;
|
||||
u8 collision_cnt; /* counter for event/timer occur at the same time */
|
||||
u8 except_cnt;
|
||||
|
||||
u8 wl_rx_err_ratio[BTC_CYCLE_SLOT_MAX];
|
||||
|
||||
struct rtw89_btc_fbtc_a2dp_trx_stat_v4 a2dp_trx[BTC_CYCLE_SLOT_MAX];
|
||||
|
||||
__le16 skip_cnt;
|
||||
__le16 cycles; /* total cycle number */
|
||||
|
||||
__le16 slot_step_time[BTC_CYCLE_SLOT_MAX]; /* record the wl/bt slot time */
|
||||
__le16 slot_cnt[CXST_MAX]; /* slot count */
|
||||
__le16 bcn_cnt[CXBCN_MAX];
|
||||
|
||||
struct rtw89_btc_fbtc_cycle_time_info_v5 cycle_time;
|
||||
struct rtw89_btc_fbtc_cycle_a2dp_empty_info a2dp_ept;
|
||||
struct rtw89_btc_fbtc_cycle_leak_info_v7 leak_slot;
|
||||
|
||||
__le32 except_map;
|
||||
} __packed;
|
||||
|
||||
union rtw89_btc_fbtc_cysta_info {
|
||||
struct rtw89_btc_fbtc_cysta_v2 v2;
|
||||
struct rtw89_btc_fbtc_cysta_v3 v3;
|
||||
struct rtw89_btc_fbtc_cysta_v4 v4;
|
||||
struct rtw89_btc_fbtc_cysta_v5 v5;
|
||||
struct rtw89_btc_fbtc_cysta_v7 v7;
|
||||
};
|
||||
|
||||
struct rtw89_btc_fbtc_cynullsta_v1 { /* cycle null statistics */
|
||||
@ -2571,12 +2688,24 @@ struct rtw89_btc_fbtc_cynullsta_v2 { /* cycle null statistics */
|
||||
__le32 result[2][5]; /* 0:fail, 1:ok, 2:on_time, 3:retry, 4:tx */
|
||||
} __packed;
|
||||
|
||||
struct rtw89_btc_fbtc_cynullsta_v7 { /* cycle null statistics */
|
||||
u8 fver;
|
||||
u8 rsvd0;
|
||||
u8 rsvd1;
|
||||
u8 rsvd2;
|
||||
|
||||
__le32 tmax[2];
|
||||
__le32 tavg[2];
|
||||
__le32 result[2][5];
|
||||
} __packed;
|
||||
|
||||
union rtw89_btc_fbtc_cynullsta_info {
|
||||
struct rtw89_btc_fbtc_cynullsta_v1 v1; /* info from fw */
|
||||
struct rtw89_btc_fbtc_cynullsta_v2 v2;
|
||||
struct rtw89_btc_fbtc_cynullsta_v7 v7;
|
||||
};
|
||||
|
||||
struct rtw89_btc_fbtc_btver {
|
||||
struct rtw89_btc_fbtc_btver_v1 {
|
||||
u8 fver; /* btc_ver::fcxbtver */
|
||||
u8 rsvd;
|
||||
__le16 rsvd2;
|
||||
@ -2585,6 +2714,22 @@ struct rtw89_btc_fbtc_btver {
|
||||
__le32 feature;
|
||||
} __packed;
|
||||
|
||||
struct rtw89_btc_fbtc_btver_v7 {
|
||||
u8 fver;
|
||||
u8 rsvd0;
|
||||
u8 rsvd1;
|
||||
u8 rsvd2;
|
||||
|
||||
__le32 coex_ver; /*bit[15:8]->shared, bit[7:0]->non-shared */
|
||||
__le32 fw_ver;
|
||||
__le32 feature;
|
||||
} __packed;
|
||||
|
||||
union rtw89_btc_fbtc_btver {
|
||||
struct rtw89_btc_fbtc_btver_v1 v1;
|
||||
struct rtw89_btc_fbtc_btver_v7 v7;
|
||||
} __packed;
|
||||
|
||||
struct rtw89_btc_fbtc_btafh {
|
||||
u8 fver; /* btc_ver::fcxbtafh */
|
||||
u8 rsvd;
|
||||
@ -2606,6 +2751,18 @@ struct rtw89_btc_fbtc_btafh_v2 {
|
||||
u8 afh_le_b[4];
|
||||
} __packed;
|
||||
|
||||
struct rtw89_btc_fbtc_btafh_v7 {
|
||||
u8 fver;
|
||||
u8 map_type;
|
||||
u8 rsvd0;
|
||||
u8 rsvd1;
|
||||
u8 afh_l[4]; /*bit0:2402, bit1:2403.... bit31:2433 */
|
||||
u8 afh_m[4]; /*bit0:2434, bit1:2435.... bit31:2465 */
|
||||
u8 afh_h[4]; /*bit0:2466, bit1:2467.....bit14:2480 */
|
||||
u8 afh_le_a[4];
|
||||
u8 afh_le_b[4];
|
||||
} __packed;
|
||||
|
||||
struct rtw89_btc_fbtc_btdevinfo {
|
||||
u8 fver; /* btc_ver::fcxbtdevinfo */
|
||||
u8 rsvd;
|
||||
@ -2691,6 +2848,7 @@ struct rtw89_btc_dm {
|
||||
u32 wl_btg_rx_rb: 2;
|
||||
|
||||
u16 slot_dur[CXST_MAX];
|
||||
u16 bt_slot_flood;
|
||||
|
||||
u8 run_reason;
|
||||
u8 run_action;
|
||||
@ -2699,6 +2857,7 @@ struct rtw89_btc_dm {
|
||||
u8 wl_lna2: 1;
|
||||
u8 wl_pre_agc_rb: 2;
|
||||
u8 bt_select: 2; /* 0:s0, 1:s1, 2:s0 & s1, refer to enum btc_bt_index */
|
||||
u8 slot_req_more: 1;
|
||||
};
|
||||
|
||||
struct rtw89_btc_ctrl {
|
||||
@ -2746,6 +2905,7 @@ enum btf_fw_event_report {
|
||||
BTC_RPT_TYPE_CYSTA,
|
||||
BTC_RPT_TYPE_STEP,
|
||||
BTC_RPT_TYPE_NULLSTA,
|
||||
BTC_RPT_TYPE_FDDT, /* added by ver->fwevntrptl == 1 */
|
||||
BTC_RPT_TYPE_MREG,
|
||||
BTC_RPT_TYPE_GPIO_DBG,
|
||||
BTC_RPT_TYPE_BT_VER,
|
||||
@ -2753,7 +2913,10 @@ enum btf_fw_event_report {
|
||||
BTC_RPT_TYPE_BT_AFH,
|
||||
BTC_RPT_TYPE_BT_DEVICE,
|
||||
BTC_RPT_TYPE_TEST,
|
||||
BTC_RPT_TYPE_MAX = 31
|
||||
BTC_RPT_TYPE_MAX = 31,
|
||||
|
||||
__BTC_RPT_TYPE_V0_SAME = BTC_RPT_TYPE_NULLSTA,
|
||||
__BTC_RPT_TYPE_V0_MAX = 12,
|
||||
};
|
||||
|
||||
enum rtw_btc_btf_reg_type {
|
||||
@ -2819,12 +2982,12 @@ struct rtw89_btc_rpt_fbtc_mreg {
|
||||
|
||||
struct rtw89_btc_rpt_fbtc_gpio_dbg {
|
||||
struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */
|
||||
struct rtw89_btc_fbtc_gpio_dbg finfo; /* info from fw */
|
||||
union rtw89_btc_fbtc_gpio_dbg finfo; /* info from fw */
|
||||
};
|
||||
|
||||
struct rtw89_btc_rpt_fbtc_btver {
|
||||
struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */
|
||||
struct rtw89_btc_fbtc_btver finfo; /* info from fw */
|
||||
union rtw89_btc_fbtc_btver finfo; /* info from fw */
|
||||
};
|
||||
|
||||
struct rtw89_btc_rpt_fbtc_btscan {
|
||||
@ -2895,6 +3058,7 @@ struct rtw89_btc_ver {
|
||||
u8 fcxctrl;
|
||||
u8 fcxinit;
|
||||
|
||||
u8 fwevntrptl;
|
||||
u8 drvinfo_type;
|
||||
u16 info_buf;
|
||||
u8 max_role_num;
|
||||
@ -2924,6 +3088,7 @@ struct rtw89_btc {
|
||||
u8 btg_pos;
|
||||
u16 policy_len;
|
||||
u16 policy_type;
|
||||
u32 hubmsg_cnt;
|
||||
bool bt_req_en;
|
||||
bool update_policy_force;
|
||||
bool lps;
|
||||
@ -3225,6 +3390,7 @@ struct rtw89_vif {
|
||||
u8 port;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 bssid[ETH_ALEN];
|
||||
__be32 ip_addr;
|
||||
u8 phy_idx;
|
||||
u8 mac_idx;
|
||||
u8 net_type;
|
||||
@ -4752,11 +4918,15 @@ struct rtw89_regd {
|
||||
};
|
||||
|
||||
#define RTW89_REGD_MAX_COUNTRY_NUM U8_MAX
|
||||
#define RTW89_5GHZ_UNII4_CHANNEL_NUM 3
|
||||
#define RTW89_5GHZ_UNII4_START_INDEX 25
|
||||
|
||||
struct rtw89_regulatory_info {
|
||||
const struct rtw89_regd *regd;
|
||||
enum rtw89_reg_6ghz_power reg_6ghz_power;
|
||||
DECLARE_BITMAP(block_unii4, RTW89_REGD_MAX_COUNTRY_NUM);
|
||||
DECLARE_BITMAP(block_6ghz, RTW89_REGD_MAX_COUNTRY_NUM);
|
||||
DECLARE_BITMAP(block_6ghz_sp, RTW89_REGD_MAX_COUNTRY_NUM);
|
||||
};
|
||||
|
||||
enum rtw89_ifs_clm_application {
|
||||
@ -5036,11 +5206,61 @@ struct rtw89_wow_cam_info {
|
||||
bool valid;
|
||||
};
|
||||
|
||||
struct rtw89_wow_key_info {
|
||||
u8 ptk_tx_iv[8];
|
||||
u8 valid_check;
|
||||
u8 symbol_check_en;
|
||||
u8 gtk_keyidx;
|
||||
u8 rsvd[5];
|
||||
u8 ptk_rx_iv[8];
|
||||
u8 gtk_rx_iv[4][8];
|
||||
} __packed;
|
||||
|
||||
struct rtw89_wow_gtk_info {
|
||||
u8 kck[32];
|
||||
u8 kek[32];
|
||||
u8 tk1[16];
|
||||
u8 txmickey[8];
|
||||
u8 rxmickey[8];
|
||||
__le32 igtk_keyid;
|
||||
__le64 ipn;
|
||||
u8 igtk[2][32];
|
||||
u8 psk[32];
|
||||
} __packed;
|
||||
|
||||
struct rtw89_wow_aoac_report {
|
||||
u8 rpt_ver;
|
||||
u8 sec_type;
|
||||
u8 key_idx;
|
||||
u8 pattern_idx;
|
||||
u8 rekey_ok;
|
||||
u8 ptk_tx_iv[8];
|
||||
u8 eapol_key_replay_count[8];
|
||||
u8 gtk[32];
|
||||
u8 ptk_rx_iv[8];
|
||||
u8 gtk_rx_iv[4][8];
|
||||
u64 igtk_key_id;
|
||||
u64 igtk_ipn;
|
||||
u8 igtk[32];
|
||||
u8 csa_pri_ch;
|
||||
u8 csa_bw;
|
||||
u8 csa_ch_offset;
|
||||
u8 csa_chsw_failed;
|
||||
u8 csa_ch_band;
|
||||
};
|
||||
|
||||
struct rtw89_wow_param {
|
||||
struct ieee80211_vif *wow_vif;
|
||||
DECLARE_BITMAP(flags, RTW89_WOW_FLAG_NUM);
|
||||
struct rtw89_wow_cam_info patterns[RTW89_MAX_PATTERN_NUM];
|
||||
struct rtw89_wow_key_info key_info;
|
||||
struct rtw89_wow_gtk_info gtk_info;
|
||||
struct rtw89_wow_aoac_report aoac_rpt;
|
||||
u8 pattern_cnt;
|
||||
u8 ptk_alg;
|
||||
u8 gtk_alg;
|
||||
u8 ptk_keyidx;
|
||||
u8 akm;
|
||||
};
|
||||
|
||||
struct rtw89_mcc_limit {
|
||||
|
@ -2,6 +2,7 @@
|
||||
/* Copyright(c) 2019-2020 Realtek Corporation
|
||||
*/
|
||||
|
||||
#include <linux/if_arp.h>
|
||||
#include "cam.h"
|
||||
#include "chan.h"
|
||||
#include "coex.h"
|
||||
@ -13,6 +14,30 @@
|
||||
#include "reg.h"
|
||||
#include "util.h"
|
||||
|
||||
struct rtw89_eapol_2_of_2 {
|
||||
struct ieee80211_hdr_3addr hdr;
|
||||
u8 gtkbody[14];
|
||||
u8 key_des_ver;
|
||||
u8 rsvd[92];
|
||||
} __packed __aligned(2);
|
||||
|
||||
struct rtw89_sa_query {
|
||||
struct ieee80211_hdr_3addr hdr;
|
||||
u8 category;
|
||||
u8 action;
|
||||
} __packed __aligned(2);
|
||||
|
||||
struct rtw89_arp_rsp {
|
||||
struct ieee80211_hdr_3addr addr;
|
||||
u8 llc_hdr[sizeof(rfc1042_header)];
|
||||
__be16 llc_type;
|
||||
struct arphdr arp_hdr;
|
||||
u8 sender_hw[ETH_ALEN];
|
||||
__be32 sender_ip;
|
||||
u8 target_hw[ETH_ALEN];
|
||||
__be32 target_ip;
|
||||
} __packed __aligned(2);
|
||||
|
||||
static const u8 mss_signature[] = {0x4D, 0x53, 0x53, 0x4B, 0x50, 0x4F, 0x4F, 0x4C};
|
||||
|
||||
union rtw89_fw_element_arg {
|
||||
@ -1726,28 +1751,30 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define H2C_DCTL_SEC_CAM_LEN 68
|
||||
int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif,
|
||||
struct rtw89_sta *rtwsta)
|
||||
{
|
||||
struct rtw89_h2c_dctlinfo_ud_v1 *h2c;
|
||||
u32 len = sizeof(*h2c);
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DCTL_SEC_CAM_LEN);
|
||||
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
|
||||
if (!skb) {
|
||||
rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
skb_put(skb, H2C_DCTL_SEC_CAM_LEN);
|
||||
skb_put(skb, len);
|
||||
h2c = (struct rtw89_h2c_dctlinfo_ud_v1 *)skb->data;
|
||||
|
||||
rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif, rtwsta, skb->data);
|
||||
rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif, rtwsta, h2c);
|
||||
|
||||
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
|
||||
H2C_CAT_MAC,
|
||||
H2C_CL_MAC_FR_EXCHG,
|
||||
H2C_FUNC_MAC_DCTLINFO_UD_V1, 0, 0,
|
||||
H2C_DCTL_SEC_CAM_LEN);
|
||||
len);
|
||||
|
||||
ret = rtw89_h2c_tx(rtwdev, skb, false);
|
||||
if (ret) {
|
||||
@ -2145,6 +2172,111 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct sk_buff *rtw89_eapol_get(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif)
|
||||
{
|
||||
static const u8 gtkbody[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88,
|
||||
0x8E, 0x01, 0x03, 0x00, 0x5F, 0x02, 0x03};
|
||||
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
|
||||
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
struct rtw89_eapol_2_of_2 *eapol_pkt;
|
||||
struct sk_buff *skb;
|
||||
u8 key_des_ver;
|
||||
|
||||
if (rtw_wow->ptk_alg == 3)
|
||||
key_des_ver = 1;
|
||||
else if (rtw_wow->akm == 1 || rtw_wow->akm == 2)
|
||||
key_des_ver = 2;
|
||||
else if (rtw_wow->akm > 2 && rtw_wow->akm < 7)
|
||||
key_des_ver = 3;
|
||||
else
|
||||
key_des_ver = 0;
|
||||
|
||||
skb = dev_alloc_skb(sizeof(*eapol_pkt));
|
||||
if (!skb)
|
||||
return NULL;
|
||||
|
||||
eapol_pkt = skb_put_zero(skb, sizeof(*eapol_pkt));
|
||||
eapol_pkt->hdr.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
|
||||
IEEE80211_FCTL_TODS |
|
||||
IEEE80211_FCTL_PROTECTED);
|
||||
ether_addr_copy(eapol_pkt->hdr.addr1, bss_conf->bssid);
|
||||
ether_addr_copy(eapol_pkt->hdr.addr2, vif->addr);
|
||||
ether_addr_copy(eapol_pkt->hdr.addr3, bss_conf->bssid);
|
||||
memcpy(eapol_pkt->gtkbody, gtkbody, sizeof(gtkbody));
|
||||
eapol_pkt->key_des_ver = key_des_ver;
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *rtw89_sa_query_get(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif)
|
||||
{
|
||||
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
|
||||
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
|
||||
struct rtw89_sa_query *sa_query;
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = dev_alloc_skb(sizeof(*sa_query));
|
||||
if (!skb)
|
||||
return NULL;
|
||||
|
||||
sa_query = skb_put_zero(skb, sizeof(*sa_query));
|
||||
sa_query->hdr.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
|
||||
IEEE80211_STYPE_ACTION |
|
||||
IEEE80211_FCTL_PROTECTED);
|
||||
ether_addr_copy(sa_query->hdr.addr1, bss_conf->bssid);
|
||||
ether_addr_copy(sa_query->hdr.addr2, vif->addr);
|
||||
ether_addr_copy(sa_query->hdr.addr3, bss_conf->bssid);
|
||||
sa_query->category = WLAN_CATEGORY_SA_QUERY;
|
||||
sa_query->action = WLAN_ACTION_SA_QUERY_RESPONSE;
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *rtw89_arp_response_get(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif)
|
||||
{
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
struct rtw89_arp_rsp *arp_skb;
|
||||
struct arphdr *arp_hdr;
|
||||
struct sk_buff *skb;
|
||||
__le16 fc;
|
||||
|
||||
skb = dev_alloc_skb(sizeof(struct rtw89_arp_rsp));
|
||||
if (!skb)
|
||||
return NULL;
|
||||
|
||||
arp_skb = skb_put_zero(skb, sizeof(*arp_skb));
|
||||
|
||||
if (rtw_wow->ptk_alg)
|
||||
fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS |
|
||||
IEEE80211_FCTL_PROTECTED);
|
||||
else
|
||||
fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS);
|
||||
|
||||
arp_skb->addr.frame_control = fc;
|
||||
ether_addr_copy(arp_skb->addr.addr1, rtwvif->bssid);
|
||||
ether_addr_copy(arp_skb->addr.addr2, rtwvif->mac_addr);
|
||||
ether_addr_copy(arp_skb->addr.addr3, rtwvif->bssid);
|
||||
|
||||
memcpy(arp_skb->llc_hdr, rfc1042_header, sizeof(rfc1042_header));
|
||||
arp_skb->llc_type = htons(ETH_P_ARP);
|
||||
|
||||
arp_hdr = &arp_skb->arp_hdr;
|
||||
arp_hdr->ar_hrd = htons(ARPHRD_ETHER);
|
||||
arp_hdr->ar_pro = htons(ETH_P_IP);
|
||||
arp_hdr->ar_hln = ETH_ALEN;
|
||||
arp_hdr->ar_pln = 4;
|
||||
arp_hdr->ar_op = htons(ARPOP_REPLY);
|
||||
|
||||
ether_addr_copy(arp_skb->sender_hw, rtwvif->mac_addr);
|
||||
arp_skb->sender_ip = rtwvif->ip_addr;
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif,
|
||||
enum rtw89_fw_pkt_ofld_type type,
|
||||
@ -2172,6 +2304,15 @@ static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev,
|
||||
case RTW89_PKT_OFLD_TYPE_QOS_NULL:
|
||||
skb = ieee80211_nullfunc_get(rtwdev->hw, vif, -1, true);
|
||||
break;
|
||||
case RTW89_PKT_OFLD_TYPE_EAPOL_KEY:
|
||||
skb = rtw89_eapol_get(rtwdev, rtwvif);
|
||||
break;
|
||||
case RTW89_PKT_OFLD_TYPE_SA_QUERY:
|
||||
skb = rtw89_sa_query_get(rtwdev, rtwvif);
|
||||
break;
|
||||
case RTW89_PKT_OFLD_TYPE_ARP_RSP:
|
||||
skb = rtw89_arp_response_get(rtwdev, rtwvif);
|
||||
break;
|
||||
default:
|
||||
goto err;
|
||||
}
|
||||
@ -4689,6 +4830,10 @@ static void rtw89_scan_get_6g_disabled_chan(struct rtw89_dev *rtwdev,
|
||||
u8 i, idx;
|
||||
|
||||
sband = rtwdev->hw->wiphy->bands[NL80211_BAND_6GHZ];
|
||||
if (!sband) {
|
||||
option->prohib_chan = U64_MAX;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
chan = &sband->channels[i];
|
||||
@ -6302,6 +6447,57 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
|
||||
bool enable)
|
||||
{
|
||||
struct rtw89_h2c_arp_offload *h2c;
|
||||
u32 len = sizeof(*h2c);
|
||||
struct sk_buff *skb;
|
||||
u8 pkt_id = 0;
|
||||
int ret;
|
||||
|
||||
if (enable) {
|
||||
ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
|
||||
RTW89_PKT_OFLD_TYPE_ARP_RSP,
|
||||
&pkt_id);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
|
||||
if (!skb) {
|
||||
rtw89_err(rtwdev, "failed to alloc skb for arp offload\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
skb_put(skb, len);
|
||||
h2c = (struct rtw89_h2c_arp_offload *)skb->data;
|
||||
|
||||
h2c->w0 = le32_encode_bits(enable, RTW89_H2C_ARP_OFFLOAD_W0_ENABLE) |
|
||||
le32_encode_bits(0, RTW89_H2C_ARP_OFFLOAD_W0_ACTION) |
|
||||
le32_encode_bits(rtwvif->mac_id, RTW89_H2C_ARP_OFFLOAD_W0_MACID) |
|
||||
le32_encode_bits(pkt_id, RTW89_H2C_ARP_OFFLOAD_W0_PKT_ID);
|
||||
|
||||
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
|
||||
H2C_CAT_MAC,
|
||||
H2C_CL_MAC_WOW,
|
||||
H2C_FUNC_ARP_OFLD, 0, 1,
|
||||
len);
|
||||
|
||||
ret = rtw89_h2c_tx(rtwdev, skb, false);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to send h2c\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
dev_kfree_skb_any(skb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define H2C_DISCONNECT_DETECT_LEN 8
|
||||
int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif, bool enable)
|
||||
@ -6347,30 +6543,38 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define H2C_WOW_GLOBAL_LEN 8
|
||||
int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
|
||||
bool enable)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
struct rtw89_h2c_wow_global *h2c;
|
||||
u8 macid = rtwvif->mac_id;
|
||||
u32 len = sizeof(*h2c);
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WOW_GLOBAL_LEN);
|
||||
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
|
||||
if (!skb) {
|
||||
rtw89_err(rtwdev, "failed to alloc skb for keep alive\n");
|
||||
rtw89_err(rtwdev, "failed to alloc skb for wow global\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
skb_put(skb, H2C_WOW_GLOBAL_LEN);
|
||||
skb_put(skb, len);
|
||||
h2c = (struct rtw89_h2c_wow_global *)skb->data;
|
||||
|
||||
RTW89_SET_WOW_GLOBAL_ENABLE(skb->data, enable);
|
||||
RTW89_SET_WOW_GLOBAL_MAC_ID(skb->data, macid);
|
||||
h2c->w0 = le32_encode_bits(enable, RTW89_H2C_WOW_GLOBAL_W0_ENABLE) |
|
||||
le32_encode_bits(macid, RTW89_H2C_WOW_GLOBAL_W0_MAC_ID) |
|
||||
le32_encode_bits(rtw_wow->ptk_alg,
|
||||
RTW89_H2C_WOW_GLOBAL_W0_PAIRWISE_SEC_ALGO) |
|
||||
le32_encode_bits(rtw_wow->gtk_alg,
|
||||
RTW89_H2C_WOW_GLOBAL_W0_GROUP_SEC_ALGO);
|
||||
h2c->key_info = rtw_wow->key_info;
|
||||
|
||||
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
|
||||
H2C_CAT_MAC,
|
||||
H2C_CL_MAC_WOW,
|
||||
H2C_FUNC_WOW_GLOBAL, 0, 1,
|
||||
H2C_WOW_GLOBAL_LEN);
|
||||
len);
|
||||
|
||||
ret = rtw89_h2c_tx(rtwdev, skb, false);
|
||||
if (ret) {
|
||||
@ -6398,7 +6602,7 @@ int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev,
|
||||
|
||||
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WAKEUP_CTRL_LEN);
|
||||
if (!skb) {
|
||||
rtw89_err(rtwdev, "failed to alloc skb for keep alive\n");
|
||||
rtw89_err(rtwdev, "failed to alloc skb for wakeup ctrl\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -6485,6 +6689,112 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif,
|
||||
bool enable)
|
||||
{
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
struct rtw89_wow_gtk_info *gtk_info = &rtw_wow->gtk_info;
|
||||
struct rtw89_h2c_wow_gtk_ofld *h2c;
|
||||
u8 macid = rtwvif->mac_id;
|
||||
u32 len = sizeof(*h2c);
|
||||
u8 pkt_id_sa_query = 0;
|
||||
struct sk_buff *skb;
|
||||
u8 pkt_id_eapol = 0;
|
||||
int ret;
|
||||
|
||||
if (!rtw_wow->gtk_alg)
|
||||
return 0;
|
||||
|
||||
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
|
||||
if (!skb) {
|
||||
rtw89_err(rtwdev, "failed to alloc skb for gtk ofld\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
skb_put(skb, len);
|
||||
h2c = (struct rtw89_h2c_wow_gtk_ofld *)skb->data;
|
||||
|
||||
if (!enable) {
|
||||
skb_put_zero(skb, sizeof(*gtk_info));
|
||||
goto hdr;
|
||||
}
|
||||
|
||||
ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
|
||||
RTW89_PKT_OFLD_TYPE_EAPOL_KEY,
|
||||
&pkt_id_eapol);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
if (gtk_info->igtk_keyid) {
|
||||
ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
|
||||
RTW89_PKT_OFLD_TYPE_SA_QUERY,
|
||||
&pkt_id_sa_query);
|
||||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* not support TKIP yet */
|
||||
h2c->w0 = le32_encode_bits(enable, RTW89_H2C_WOW_GTK_OFLD_W0_EN) |
|
||||
le32_encode_bits(0, RTW89_H2C_WOW_GTK_OFLD_W0_TKIP_EN) |
|
||||
le32_encode_bits(gtk_info->igtk_keyid ? 1 : 0,
|
||||
RTW89_H2C_WOW_GTK_OFLD_W0_IEEE80211W_EN) |
|
||||
le32_encode_bits(macid, RTW89_H2C_WOW_GTK_OFLD_W0_MAC_ID) |
|
||||
le32_encode_bits(pkt_id_eapol, RTW89_H2C_WOW_GTK_OFLD_W0_GTK_RSP_ID);
|
||||
h2c->w1 = le32_encode_bits(gtk_info->igtk_keyid ? pkt_id_sa_query : 0,
|
||||
RTW89_H2C_WOW_GTK_OFLD_W1_PMF_SA_QUERY_ID) |
|
||||
le32_encode_bits(rtw_wow->akm, RTW89_H2C_WOW_GTK_OFLD_W1_ALGO_AKM_SUIT);
|
||||
h2c->gtk_info = rtw_wow->gtk_info;
|
||||
|
||||
hdr:
|
||||
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
|
||||
H2C_CAT_MAC,
|
||||
H2C_CL_MAC_WOW,
|
||||
H2C_FUNC_GTK_OFLD, 0, 1,
|
||||
len);
|
||||
|
||||
ret = rtw89_h2c_tx(rtwdev, skb, false);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to send h2c\n");
|
||||
goto fail;
|
||||
}
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
dev_kfree_skb_any(skb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rtw89_fw_h2c_wow_request_aoac(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
|
||||
struct rtw89_h2c_wow_aoac *h2c;
|
||||
u32 len = sizeof(*h2c);
|
||||
struct sk_buff *skb;
|
||||
unsigned int cond;
|
||||
|
||||
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
|
||||
if (!skb) {
|
||||
rtw89_err(rtwdev, "failed to alloc skb for aoac\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
skb_put(skb, len);
|
||||
|
||||
/* This H2C only nofity firmware to generate AOAC report C2H,
|
||||
* no need any parameter.
|
||||
*/
|
||||
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
|
||||
H2C_CAT_MAC,
|
||||
H2C_CL_MAC_WOW,
|
||||
H2C_FUNC_AOAC_REPORT_REQ, 1, 0,
|
||||
len);
|
||||
|
||||
cond = RTW89_WOW_WAIT_COND(H2C_FUNC_AOAC_REPORT_REQ);
|
||||
return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
|
||||
}
|
||||
|
||||
/* Return < 0, if failures happen during waiting for the condition.
|
||||
* Return 0, when waiting for the condition succeeds.
|
||||
* Return > 0, if the wait is considered unreachable due to driver/FW design,
|
||||
|
@ -48,6 +48,32 @@ struct rtw89_c2hreg_phycap {
|
||||
#define RTW89_C2HREG_PHYCAP_W3_ANT_TX_NUM GENMASK(15, 8)
|
||||
#define RTW89_C2HREG_PHYCAP_W3_ANT_RX_NUM GENMASK(23, 16)
|
||||
|
||||
#define RTW89_C2HREG_AOAC_RPT_1_W0_KEY_IDX GENMASK(23, 16)
|
||||
#define RTW89_C2HREG_AOAC_RPT_1_W1_IV_0 GENMASK(7, 0)
|
||||
#define RTW89_C2HREG_AOAC_RPT_1_W1_IV_1 GENMASK(15, 8)
|
||||
#define RTW89_C2HREG_AOAC_RPT_1_W1_IV_2 GENMASK(23, 16)
|
||||
#define RTW89_C2HREG_AOAC_RPT_1_W1_IV_3 GENMASK(31, 24)
|
||||
#define RTW89_C2HREG_AOAC_RPT_1_W2_IV_4 GENMASK(7, 0)
|
||||
#define RTW89_C2HREG_AOAC_RPT_1_W2_IV_5 GENMASK(15, 8)
|
||||
#define RTW89_C2HREG_AOAC_RPT_1_W2_IV_6 GENMASK(23, 16)
|
||||
#define RTW89_C2HREG_AOAC_RPT_1_W2_IV_7 GENMASK(31, 24)
|
||||
#define RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_0 GENMASK(7, 0)
|
||||
#define RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_1 GENMASK(15, 8)
|
||||
#define RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_2 GENMASK(23, 16)
|
||||
#define RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_3 GENMASK(31, 24)
|
||||
#define RTW89_C2HREG_AOAC_RPT_2_W0_PTK_IV_4 GENMASK(23, 16)
|
||||
#define RTW89_C2HREG_AOAC_RPT_2_W0_PTK_IV_5 GENMASK(31, 24)
|
||||
#define RTW89_C2HREG_AOAC_RPT_2_W1_PTK_IV_6 GENMASK(7, 0)
|
||||
#define RTW89_C2HREG_AOAC_RPT_2_W1_PTK_IV_7 GENMASK(15, 8)
|
||||
#define RTW89_C2HREG_AOAC_RPT_2_W1_IGTK_IPN_IV_0 GENMASK(23, 16)
|
||||
#define RTW89_C2HREG_AOAC_RPT_2_W1_IGTK_IPN_IV_1 GENMASK(31, 24)
|
||||
#define RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_2 GENMASK(7, 0)
|
||||
#define RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_3 GENMASK(15, 8)
|
||||
#define RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_4 GENMASK(23, 16)
|
||||
#define RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_5 GENMASK(31, 24)
|
||||
#define RTW89_C2HREG_AOAC_RPT_2_W3_IGTK_IPN_IV_6 GENMASK(7, 0)
|
||||
#define RTW89_C2HREG_AOAC_RPT_2_W3_IGTK_IPN_IV_7 GENMASK(15, 8)
|
||||
|
||||
struct rtw89_h2creg_hdr {
|
||||
u32 w0;
|
||||
};
|
||||
@ -98,8 +124,11 @@ enum rtw89_mac_h2c_type {
|
||||
RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE,
|
||||
RTW89_FWCMD_H2CREG_FUNC_GETPKT_INFORM,
|
||||
RTW89_FWCMD_H2CREG_FUNC_SCH_TX_EN,
|
||||
RTW89_FWCMD_H2CREG_FUNC_WOW_TRX_STOP = 0x6,
|
||||
RTW89_FWCMD_H2CREG_FUNC_WOW_CPUIO_RX_CTRL = 0xA,
|
||||
RTW89_FWCMD_H2CREG_FUNC_WOW_TRX_STOP,
|
||||
RTW89_FWCMD_H2CREG_FUNC_AOAC_RPT_1,
|
||||
RTW89_FWCMD_H2CREG_FUNC_AOAC_RPT_2,
|
||||
RTW89_FWCMD_H2CREG_FUNC_AOAC_RPT_3_REQ,
|
||||
RTW89_FWCMD_H2CREG_FUNC_WOW_CPUIO_RX_CTRL,
|
||||
};
|
||||
|
||||
enum rtw89_mac_c2h_type {
|
||||
@ -1433,308 +1462,6 @@ struct rtw89_h2c_cctlinfo_ud_g7 {
|
||||
#define CCTLINFO_G7_W15_MGNT_CURR_RATE GENMASK(27, 16)
|
||||
#define CCTLINFO_G7_W15_ALL GENMASK(27, 0)
|
||||
|
||||
static inline void SET_DCTL_MACID_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 0, val, GENMASK(6, 0));
|
||||
}
|
||||
|
||||
static inline void SET_DCTL_OPERATION_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 0, val, BIT(7));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_QOS_FIELD_V1 GENMASK(7, 0)
|
||||
static inline void SET_DCTL_QOS_FIELD_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(7, 0));
|
||||
le32p_replace_bits((__le32 *)(table) + 9, SET_DCTL_MASK_QOS_FIELD_V1,
|
||||
GENMASK(7, 0));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_SET_DCTL_HW_EXSEQ_MACID GENMASK(6, 0)
|
||||
static inline void SET_DCTL_HW_EXSEQ_MACID_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(14, 8));
|
||||
le32p_replace_bits((__le32 *)(table) + 9, SET_DCTL_MASK_SET_DCTL_HW_EXSEQ_MACID,
|
||||
GENMASK(14, 8));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_QOS_DATA BIT(0)
|
||||
static inline void SET_DCTL_QOS_DATA_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 1, val, BIT(15));
|
||||
le32p_replace_bits((__le32 *)(table) + 9, SET_DCTL_MASK_QOS_DATA,
|
||||
BIT(15));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_AES_IV_L GENMASK(15, 0)
|
||||
static inline void SET_DCTL_AES_IV_L_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(31, 16));
|
||||
le32p_replace_bits((__le32 *)(table) + 9, SET_DCTL_MASK_AES_IV_L,
|
||||
GENMASK(31, 16));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_AES_IV_H GENMASK(31, 0)
|
||||
static inline void SET_DCTL_AES_IV_H_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 2, val, GENMASK(31, 0));
|
||||
le32p_replace_bits((__le32 *)(table) + 10, SET_DCTL_MASK_AES_IV_H,
|
||||
GENMASK(31, 0));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_SEQ0 GENMASK(11, 0)
|
||||
static inline void SET_DCTL_SEQ0_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(11, 0));
|
||||
le32p_replace_bits((__le32 *)(table) + 11, SET_DCTL_MASK_SEQ0,
|
||||
GENMASK(11, 0));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_SEQ1 GENMASK(11, 0)
|
||||
static inline void SET_DCTL_SEQ1_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(23, 12));
|
||||
le32p_replace_bits((__le32 *)(table) + 11, SET_DCTL_MASK_SEQ1,
|
||||
GENMASK(23, 12));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_AMSDU_MAX_LEN GENMASK(2, 0)
|
||||
static inline void SET_DCTL_AMSDU_MAX_LEN_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(26, 24));
|
||||
le32p_replace_bits((__le32 *)(table) + 11, SET_DCTL_MASK_AMSDU_MAX_LEN,
|
||||
GENMASK(26, 24));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_STA_AMSDU_EN BIT(0)
|
||||
static inline void SET_DCTL_STA_AMSDU_EN_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 3, val, BIT(27));
|
||||
le32p_replace_bits((__le32 *)(table) + 11, SET_DCTL_MASK_STA_AMSDU_EN,
|
||||
BIT(27));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_CHKSUM_OFLD_EN BIT(0)
|
||||
static inline void SET_DCTL_CHKSUM_OFLD_EN_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 3, val, BIT(28));
|
||||
le32p_replace_bits((__le32 *)(table) + 11, SET_DCTL_MASK_CHKSUM_OFLD_EN,
|
||||
BIT(28));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_WITH_LLC BIT(0)
|
||||
static inline void SET_DCTL_WITH_LLC_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 3, val, BIT(29));
|
||||
le32p_replace_bits((__le32 *)(table) + 11, SET_DCTL_MASK_WITH_LLC,
|
||||
BIT(29));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_SEQ2 GENMASK(11, 0)
|
||||
static inline void SET_DCTL_SEQ2_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(11, 0));
|
||||
le32p_replace_bits((__le32 *)(table) + 12, SET_DCTL_MASK_SEQ2,
|
||||
GENMASK(11, 0));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_SEQ3 GENMASK(11, 0)
|
||||
static inline void SET_DCTL_SEQ3_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(23, 12));
|
||||
le32p_replace_bits((__le32 *)(table) + 12, SET_DCTL_MASK_SEQ3,
|
||||
GENMASK(23, 12));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_TGT_IND GENMASK(3, 0)
|
||||
static inline void SET_DCTL_TGT_IND_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(27, 24));
|
||||
le32p_replace_bits((__le32 *)(table) + 12, SET_DCTL_MASK_TGT_IND,
|
||||
GENMASK(27, 24));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_TGT_IND_EN BIT(0)
|
||||
static inline void SET_DCTL_TGT_IND_EN_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 4, val, BIT(28));
|
||||
le32p_replace_bits((__le32 *)(table) + 12, SET_DCTL_MASK_TGT_IND_EN,
|
||||
BIT(28));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_HTC_LB GENMASK(2, 0)
|
||||
static inline void SET_DCTL_HTC_LB_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(31, 29));
|
||||
le32p_replace_bits((__le32 *)(table) + 12, SET_DCTL_MASK_HTC_LB,
|
||||
GENMASK(31, 29));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_MHDR_LEN GENMASK(4, 0)
|
||||
static inline void SET_DCTL_MHDR_LEN_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(4, 0));
|
||||
le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_MHDR_LEN,
|
||||
GENMASK(4, 0));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_VLAN_TAG_VALID BIT(0)
|
||||
static inline void SET_DCTL_VLAN_TAG_VALID_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 5, val, BIT(5));
|
||||
le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_VLAN_TAG_VALID,
|
||||
BIT(5));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_VLAN_TAG_SEL GENMASK(1, 0)
|
||||
static inline void SET_DCTL_VLAN_TAG_SEL_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(7, 6));
|
||||
le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_VLAN_TAG_SEL,
|
||||
GENMASK(7, 6));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_HTC_ORDER BIT(0)
|
||||
static inline void SET_DCTL_HTC_ORDER_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 5, val, BIT(8));
|
||||
le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_HTC_ORDER,
|
||||
BIT(8));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_SEC_KEY_ID GENMASK(1, 0)
|
||||
static inline void SET_DCTL_SEC_KEY_ID_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(10, 9));
|
||||
le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_KEY_ID,
|
||||
GENMASK(10, 9));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_WAPI BIT(0)
|
||||
static inline void SET_DCTL_WAPI_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 5, val, BIT(15));
|
||||
le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_WAPI,
|
||||
BIT(15));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_SEC_ENT_MODE GENMASK(1, 0)
|
||||
static inline void SET_DCTL_SEC_ENT_MODE_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(17, 16));
|
||||
le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENT_MODE,
|
||||
GENMASK(17, 16));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_SEC_ENTX_KEYID GENMASK(1, 0)
|
||||
static inline void SET_DCTL_SEC_ENT0_KEYID_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(19, 18));
|
||||
le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID,
|
||||
GENMASK(19, 18));
|
||||
}
|
||||
|
||||
static inline void SET_DCTL_SEC_ENT1_KEYID_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(21, 20));
|
||||
le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID,
|
||||
GENMASK(21, 20));
|
||||
}
|
||||
|
||||
static inline void SET_DCTL_SEC_ENT2_KEYID_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(23, 22));
|
||||
le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID,
|
||||
GENMASK(23, 22));
|
||||
}
|
||||
|
||||
static inline void SET_DCTL_SEC_ENT3_KEYID_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(25, 24));
|
||||
le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID,
|
||||
GENMASK(25, 24));
|
||||
}
|
||||
|
||||
static inline void SET_DCTL_SEC_ENT4_KEYID_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(27, 26));
|
||||
le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID,
|
||||
GENMASK(27, 26));
|
||||
}
|
||||
|
||||
static inline void SET_DCTL_SEC_ENT5_KEYID_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(29, 28));
|
||||
le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID,
|
||||
GENMASK(29, 28));
|
||||
}
|
||||
|
||||
static inline void SET_DCTL_SEC_ENT6_KEYID_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(31, 30));
|
||||
le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID,
|
||||
GENMASK(31, 30));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_SEC_ENT_VALID GENMASK(7, 0)
|
||||
static inline void SET_DCTL_SEC_ENT_VALID_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(7, 0));
|
||||
le32p_replace_bits((__le32 *)(table) + 14, SET_DCTL_MASK_SEC_ENT_VALID,
|
||||
GENMASK(7, 0));
|
||||
}
|
||||
|
||||
#define SET_DCTL_MASK_SEC_ENTX GENMASK(7, 0)
|
||||
static inline void SET_DCTL_SEC_ENT0_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(15, 8));
|
||||
le32p_replace_bits((__le32 *)(table) + 14, SET_DCTL_MASK_SEC_ENTX,
|
||||
GENMASK(15, 8));
|
||||
}
|
||||
|
||||
static inline void SET_DCTL_SEC_ENT1_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(23, 16));
|
||||
le32p_replace_bits((__le32 *)(table) + 14, SET_DCTL_MASK_SEC_ENTX,
|
||||
GENMASK(23, 16));
|
||||
}
|
||||
|
||||
static inline void SET_DCTL_SEC_ENT2_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(31, 24));
|
||||
le32p_replace_bits((__le32 *)(table) + 14, SET_DCTL_MASK_SEC_ENTX,
|
||||
GENMASK(31, 24));
|
||||
}
|
||||
|
||||
static inline void SET_DCTL_SEC_ENT3_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(7, 0));
|
||||
le32p_replace_bits((__le32 *)(table) + 15, SET_DCTL_MASK_SEC_ENTX,
|
||||
GENMASK(7, 0));
|
||||
}
|
||||
|
||||
static inline void SET_DCTL_SEC_ENT4_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(15, 8));
|
||||
le32p_replace_bits((__le32 *)(table) + 15, SET_DCTL_MASK_SEC_ENTX,
|
||||
GENMASK(15, 8));
|
||||
}
|
||||
|
||||
static inline void SET_DCTL_SEC_ENT5_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(23, 16));
|
||||
le32p_replace_bits((__le32 *)(table) + 15, SET_DCTL_MASK_SEC_ENTX,
|
||||
GENMASK(23, 16));
|
||||
}
|
||||
|
||||
static inline void SET_DCTL_SEC_ENT6_V1(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(31, 24));
|
||||
le32p_replace_bits((__le32 *)(table) + 15, SET_DCTL_MASK_SEC_ENTX,
|
||||
GENMASK(31, 24));
|
||||
}
|
||||
|
||||
struct rtw89_h2c_bcn_upd {
|
||||
__le32 w0;
|
||||
__le32 w1;
|
||||
@ -2158,45 +1885,18 @@ static inline void RTW89_SET_DISCONNECT_DETECT_TRYOK_BCNFAIL_COUNT_LIMIT(void *h
|
||||
le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(7, 0));
|
||||
}
|
||||
|
||||
static inline void RTW89_SET_WOW_GLOBAL_ENABLE(void *h2c, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)h2c, val, BIT(0));
|
||||
}
|
||||
struct rtw89_h2c_wow_global {
|
||||
__le32 w0;
|
||||
struct rtw89_wow_key_info key_info;
|
||||
} __packed;
|
||||
|
||||
static inline void RTW89_SET_WOW_GLOBAL_DROP_ALL_PKT(void *h2c, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)h2c, val, BIT(1));
|
||||
}
|
||||
|
||||
static inline void RTW89_SET_WOW_GLOBAL_RX_PARSE_AFTER_WAKE(void *h2c, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)h2c, val, BIT(2));
|
||||
}
|
||||
|
||||
static inline void RTW89_SET_WOW_GLOBAL_WAKE_BAR_PULLED(void *h2c, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)h2c, val, BIT(3));
|
||||
}
|
||||
|
||||
static inline void RTW89_SET_WOW_GLOBAL_MAC_ID(void *h2c, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 8));
|
||||
}
|
||||
|
||||
static inline void RTW89_SET_WOW_GLOBAL_PAIRWISE_SEC_ALGO(void *h2c, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)h2c, val, GENMASK(23, 16));
|
||||
}
|
||||
|
||||
static inline void RTW89_SET_WOW_GLOBAL_GROUP_SEC_ALGO(void *h2c, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 24));
|
||||
}
|
||||
|
||||
static inline void RTW89_SET_WOW_GLOBAL_REMOTECTRL_INFO_CONTENT(void *h2c, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(31, 0));
|
||||
}
|
||||
#define RTW89_H2C_WOW_GLOBAL_W0_ENABLE BIT(0)
|
||||
#define RTW89_H2C_WOW_GLOBAL_W0_DROP_ALL_PKT BIT(1)
|
||||
#define RTW89_H2C_WOW_GLOBAL_W0_RX_PARSE_AFTER_WAKE BIT(2)
|
||||
#define RTW89_H2C_WOW_GLOBAL_W0_WAKE_BAR_PULLED BIT(3)
|
||||
#define RTW89_H2C_WOW_GLOBAL_W0_MAC_ID GENMASK(15, 8)
|
||||
#define RTW89_H2C_WOW_GLOBAL_W0_PAIRWISE_SEC_ALGO GENMASK(23, 16)
|
||||
#define RTW89_H2C_WOW_GLOBAL_W0_GROUP_SEC_ALGO GENMASK(31, 24)
|
||||
|
||||
static inline void RTW89_SET_WOW_WAKEUP_CTRL_PATTERN_MATCH_ENABLE(void *h2c, u32 val)
|
||||
{
|
||||
@ -2308,6 +2008,34 @@ static inline void RTW89_SET_WOW_CAM_UPD_VALID(void *h2c, u32 val)
|
||||
le32p_replace_bits((__le32 *)h2c + 5, val, BIT(31));
|
||||
}
|
||||
|
||||
struct rtw89_h2c_wow_gtk_ofld {
|
||||
__le32 w0;
|
||||
__le32 w1;
|
||||
struct rtw89_wow_gtk_info gtk_info;
|
||||
} __packed;
|
||||
|
||||
#define RTW89_H2C_WOW_GTK_OFLD_W0_EN BIT(0)
|
||||
#define RTW89_H2C_WOW_GTK_OFLD_W0_TKIP_EN BIT(1)
|
||||
#define RTW89_H2C_WOW_GTK_OFLD_W0_IEEE80211W_EN BIT(2)
|
||||
#define RTW89_H2C_WOW_GTK_OFLD_W0_PAIRWISE_WAKEUP BIT(3)
|
||||
#define RTW89_H2C_WOW_GTK_OFLD_W0_NOREKEY_WAKEUP BIT(4)
|
||||
#define RTW89_H2C_WOW_GTK_OFLD_W0_MAC_ID GENMASK(23, 16)
|
||||
#define RTW89_H2C_WOW_GTK_OFLD_W0_GTK_RSP_ID GENMASK(31, 24)
|
||||
#define RTW89_H2C_WOW_GTK_OFLD_W1_PMF_SA_QUERY_ID GENMASK(7, 0)
|
||||
#define RTW89_H2C_WOW_GTK_OFLD_W1_PMF_BIP_SEC_ALGO GENMASK(9, 8)
|
||||
#define RTW89_H2C_WOW_GTK_OFLD_W1_ALGO_AKM_SUIT GENMASK(17, 10)
|
||||
|
||||
struct rtw89_h2c_arp_offload {
|
||||
__le32 w0;
|
||||
__le32 w1;
|
||||
} __packed;
|
||||
|
||||
#define RTW89_H2C_ARP_OFFLOAD_W0_ENABLE BIT(0)
|
||||
#define RTW89_H2C_ARP_OFFLOAD_W0_ACTION BIT(1)
|
||||
#define RTW89_H2C_ARP_OFFLOAD_W0_MACID GENMASK(23, 16)
|
||||
#define RTW89_H2C_ARP_OFFLOAD_W0_PKT_ID GENMASK(31, 24)
|
||||
#define RTW89_H2C_ARP_OFFLOAD_W1_CONTENT GENMASK(31, 0)
|
||||
|
||||
enum rtw89_btc_btf_h2c_class {
|
||||
BTFC_SET = 0x10,
|
||||
BTFC_GET = 0x11,
|
||||
@ -3664,6 +3392,10 @@ struct rtw89_h2c_mrc_upd_duration {
|
||||
#define RTW89_H2C_MRC_UPD_DURATION_SLOT_SLOT_IDX GENMASK(7, 0)
|
||||
#define RTW89_H2C_MRC_UPD_DURATION_SLOT_DURATION GENMASK(31, 16)
|
||||
|
||||
struct rtw89_h2c_wow_aoac {
|
||||
__le32 w0;
|
||||
} __packed;
|
||||
|
||||
#define RTW89_C2H_HEADER_LEN 8
|
||||
|
||||
struct rtw89_c2h_hdr {
|
||||
@ -3892,6 +3624,30 @@ struct rtw89_c2h_pkt_ofld_rsp {
|
||||
#define RTW89_C2H_PKT_OFLD_RSP_W2_PTK_OP GENMASK(10, 8)
|
||||
#define RTW89_C2H_PKT_OFLD_RSP_W2_PTK_LEN GENMASK(31, 16)
|
||||
|
||||
struct rtw89_c2h_wow_aoac_report {
|
||||
struct rtw89_c2h_hdr c2h_hdr;
|
||||
u8 rpt_ver;
|
||||
u8 sec_type;
|
||||
u8 key_idx;
|
||||
u8 pattern_idx;
|
||||
u8 rekey_ok;
|
||||
u8 rsvd1[3];
|
||||
u8 ptk_tx_iv[8];
|
||||
u8 eapol_key_replay_count[8];
|
||||
u8 gtk[32];
|
||||
u8 ptk_rx_iv[8];
|
||||
u8 gtk_rx_iv[4][8];
|
||||
__le64 igtk_key_id;
|
||||
__le64 igtk_ipn;
|
||||
u8 igtk[32];
|
||||
u8 csa_pri_ch;
|
||||
u8 csa_bw_ch_offset;
|
||||
u8 csa_ch_band_chsw_failed;
|
||||
u8 csa_rsvd1;
|
||||
} __packed;
|
||||
|
||||
#define RTW89_C2H_WOW_AOAC_RPT_REKEY_IDX BIT(0)
|
||||
|
||||
struct rtw89_h2c_bcnfltr {
|
||||
__le32 w0;
|
||||
} __packed;
|
||||
@ -4169,11 +3925,21 @@ struct rtw89_fw_h2c_rf_reg_info {
|
||||
|
||||
/* CLASS 1 - WOW */
|
||||
#define H2C_CL_MAC_WOW 0x1
|
||||
#define H2C_FUNC_KEEP_ALIVE 0x0
|
||||
#define H2C_FUNC_DISCONNECT_DETECT 0x1
|
||||
#define H2C_FUNC_WOW_GLOBAL 0x2
|
||||
#define H2C_FUNC_WAKEUP_CTRL 0x8
|
||||
#define H2C_FUNC_WOW_CAM_UPD 0xC
|
||||
enum rtw89_wow_h2c_func {
|
||||
H2C_FUNC_KEEP_ALIVE = 0x0,
|
||||
H2C_FUNC_DISCONNECT_DETECT = 0x1,
|
||||
H2C_FUNC_WOW_GLOBAL = 0x2,
|
||||
H2C_FUNC_GTK_OFLD = 0x3,
|
||||
H2C_FUNC_ARP_OFLD = 0x4,
|
||||
H2C_FUNC_WAKEUP_CTRL = 0x8,
|
||||
H2C_FUNC_WOW_CAM_UPD = 0xC,
|
||||
H2C_FUNC_AOAC_REPORT_REQ = 0xD,
|
||||
|
||||
NUM_OF_RTW89_WOW_H2C_FUNC,
|
||||
};
|
||||
|
||||
#define RTW89_WOW_WAIT_COND(func) \
|
||||
(NUM_OF_RTW89_WOW_H2C_FUNC + (func))
|
||||
|
||||
/* CLASS 2 - PS */
|
||||
#define H2C_CL_MAC_PS 0x2
|
||||
@ -4682,6 +4448,8 @@ int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif, bool enable);
|
||||
int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
|
||||
bool enable);
|
||||
int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif, bool enable);
|
||||
int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif, bool enable);
|
||||
int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
|
||||
@ -4690,6 +4458,10 @@ int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif, bool enable);
|
||||
int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_wow_cam_info *cam_info);
|
||||
int rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif,
|
||||
bool enable);
|
||||
int rtw89_fw_h2c_wow_request_aoac(struct rtw89_dev *rtwdev);
|
||||
int rtw89_fw_h2c_add_mcc(struct rtw89_dev *rtwdev,
|
||||
const struct rtw89_fw_mcc_add_req *p);
|
||||
int rtw89_fw_h2c_start_mcc(struct rtw89_dev *rtwdev,
|
||||
|
@ -3644,6 +3644,7 @@ static int set_host_rpr_ax(struct rtw89_dev *rtwdev)
|
||||
|
||||
static int trx_init_ax(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
|
||||
enum rtw89_qta_mode qta_mode = rtwdev->mac.qta_mode;
|
||||
int ret;
|
||||
|
||||
@ -3687,6 +3688,10 @@ static int trx_init_ax(struct rtw89_dev *rtwdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (chip_id == RTL8852C)
|
||||
rtw89_write32_clr(rtwdev, R_AX_RSP_CHK_SIG,
|
||||
B_AX_RSP_STATIC_RTS_CHK_SERV_BW_EN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -5131,6 +5136,37 @@ rtw89_mac_c2h_mrc_tsf_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len
|
||||
rtw89_complete_cond(wait, RTW89_MRC_WAIT_COND_REQ_TSF, &data);
|
||||
}
|
||||
|
||||
static void
|
||||
rtw89_mac_c2h_wow_aoac_rpt(struct rtw89_dev *rtwdev, struct sk_buff *skb, u32 len)
|
||||
{
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
|
||||
struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
|
||||
const struct rtw89_c2h_wow_aoac_report *c2h =
|
||||
(const struct rtw89_c2h_wow_aoac_report *)skb->data;
|
||||
struct rtw89_completion_data data = {};
|
||||
unsigned int cond;
|
||||
|
||||
aoac_rpt->rpt_ver = c2h->rpt_ver;
|
||||
aoac_rpt->sec_type = c2h->sec_type;
|
||||
aoac_rpt->key_idx = c2h->key_idx;
|
||||
aoac_rpt->pattern_idx = c2h->pattern_idx;
|
||||
aoac_rpt->rekey_ok = u8_get_bits(c2h->rekey_ok,
|
||||
RTW89_C2H_WOW_AOAC_RPT_REKEY_IDX);
|
||||
memcpy(aoac_rpt->ptk_tx_iv, c2h->ptk_tx_iv, sizeof(aoac_rpt->ptk_tx_iv));
|
||||
memcpy(aoac_rpt->eapol_key_replay_count, c2h->eapol_key_replay_count,
|
||||
sizeof(aoac_rpt->eapol_key_replay_count));
|
||||
memcpy(aoac_rpt->gtk, c2h->gtk, sizeof(aoac_rpt->gtk));
|
||||
memcpy(aoac_rpt->ptk_rx_iv, c2h->ptk_rx_iv, sizeof(aoac_rpt->ptk_rx_iv));
|
||||
memcpy(aoac_rpt->gtk_rx_iv, c2h->gtk_rx_iv, sizeof(aoac_rpt->gtk_rx_iv));
|
||||
aoac_rpt->igtk_key_id = le64_to_cpu(c2h->igtk_key_id);
|
||||
aoac_rpt->igtk_ipn = le64_to_cpu(c2h->igtk_ipn);
|
||||
memcpy(aoac_rpt->igtk, c2h->igtk, sizeof(aoac_rpt->igtk));
|
||||
|
||||
cond = RTW89_WOW_WAIT_COND(H2C_FUNC_AOAC_REPORT_REQ);
|
||||
rtw89_complete_cond(wait, cond, &data);
|
||||
}
|
||||
|
||||
static void
|
||||
rtw89_mac_c2h_mrc_status_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
|
||||
{
|
||||
@ -5218,6 +5254,12 @@ void (* const rtw89_mac_c2h_mrc_handler[])(struct rtw89_dev *rtwdev,
|
||||
[RTW89_MAC_C2H_FUNC_MRC_STATUS_RPT] = rtw89_mac_c2h_mrc_status_rpt,
|
||||
};
|
||||
|
||||
static
|
||||
void (* const rtw89_mac_c2h_wow_handler[])(struct rtw89_dev *rtwdev,
|
||||
struct sk_buff *c2h, u32 len) = {
|
||||
[RTW89_MAC_C2H_FUNC_AOAC_REPORT] = rtw89_mac_c2h_wow_aoac_rpt,
|
||||
};
|
||||
|
||||
static void rtw89_mac_c2h_scanofld_rsp_atomic(struct rtw89_dev *rtwdev,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
@ -5270,6 +5312,8 @@ bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
|
||||
return true;
|
||||
case RTW89_MAC_C2H_CLASS_MRC:
|
||||
return true;
|
||||
case RTW89_MAC_C2H_CLASS_WOW:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5296,6 +5340,10 @@ void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
|
||||
if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MRC)
|
||||
handler = rtw89_mac_c2h_mrc_handler[func];
|
||||
break;
|
||||
case RTW89_MAC_C2H_CLASS_WOW:
|
||||
if (func < NUM_OF_RTW89_MAC_C2H_FUNC_WOW)
|
||||
handler = rtw89_mac_c2h_wow_handler[func];
|
||||
break;
|
||||
case RTW89_MAC_C2H_CLASS_FWDBG:
|
||||
return;
|
||||
default:
|
||||
@ -5705,7 +5753,7 @@ bool rtw89_mac_get_ctrl_path(struct rtw89_dev *rtwdev)
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
u8 val = 0;
|
||||
|
||||
if (chip->chip_id == RTL8852C)
|
||||
if (chip->chip_id == RTL8852C || chip->chip_id == RTL8922A)
|
||||
return false;
|
||||
else if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B ||
|
||||
chip->chip_id == RTL8851B)
|
||||
|
@ -419,6 +419,13 @@ enum rtw89_mac_c2h_mrc_func {
|
||||
NUM_OF_RTW89_MAC_C2H_FUNC_MRC,
|
||||
};
|
||||
|
||||
enum rtw89_mac_c2h_wow_func {
|
||||
RTW89_MAC_C2H_FUNC_AOAC_REPORT,
|
||||
RTW89_MAC_C2H_FUNC_READ_WOW_CAM,
|
||||
|
||||
NUM_OF_RTW89_MAC_C2H_FUNC_WOW,
|
||||
};
|
||||
|
||||
enum rtw89_mac_c2h_class {
|
||||
RTW89_MAC_C2H_CLASS_INFO = 0x0,
|
||||
RTW89_MAC_C2H_CLASS_OFLD = 0x1,
|
||||
|
@ -318,7 +318,7 @@ static u8 rtw89_aifsn_to_aifs(struct rtw89_dev *rtwdev,
|
||||
u8 sifs;
|
||||
|
||||
slot_time = vif->bss_conf.use_short_slot ? 9 : 20;
|
||||
sifs = chan->band_type == RTW89_BAND_5G ? 16 : 10;
|
||||
sifs = chan->band_type == RTW89_BAND_2G ? 10 : 16;
|
||||
|
||||
return aifsn * slot_time + sifs;
|
||||
}
|
||||
@ -473,6 +473,9 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
|
||||
if (changed & BSS_CHANGED_PS)
|
||||
rtw89_recalc_lps(rtwdev);
|
||||
|
||||
if (changed & BSS_CHANGED_ARP_FILTER)
|
||||
rtwvif->ip_addr = vif->cfg.arp_addr_list[0];
|
||||
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
}
|
||||
|
||||
@ -1106,6 +1109,28 @@ static void rtw89_ops_set_wakeup(struct ieee80211_hw *hw, bool enabled)
|
||||
|
||||
device_set_wakeup_enable(rtwdev->dev, enabled);
|
||||
}
|
||||
|
||||
static void rtw89_set_rekey_data(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct cfg80211_gtk_rekey_data *data)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
struct rtw89_wow_gtk_info *gtk_info = &rtw_wow->gtk_info;
|
||||
|
||||
if (data->kek_len > sizeof(gtk_info->kek) ||
|
||||
data->kck_len > sizeof(gtk_info->kck)) {
|
||||
rtw89_warn(rtwdev, "kek or kck length over fw limit\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
|
||||
memcpy(gtk_info->kek, data->kek, data->kek_len);
|
||||
memcpy(gtk_info->kck, data->kck, data->kck_len);
|
||||
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
const struct ieee80211_ops rtw89_ops = {
|
||||
@ -1151,6 +1176,7 @@ const struct ieee80211_ops rtw89_ops = {
|
||||
.suspend = rtw89_ops_suspend,
|
||||
.resume = rtw89_ops_resume,
|
||||
.set_wakeup = rtw89_ops_set_wakeup,
|
||||
.set_rekey_data = rtw89_set_rekey_data,
|
||||
#endif
|
||||
};
|
||||
EXPORT_SYMBOL(rtw89_ops);
|
||||
|
@ -1751,6 +1751,7 @@ static int set_host_rpr_be(struct rtw89_dev *rtwdev)
|
||||
|
||||
static int trx_init_be(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
|
||||
enum rtw89_qta_mode qta_mode = rtwdev->mac.qta_mode;
|
||||
int ret;
|
||||
|
||||
@ -1794,6 +1795,10 @@ static int trx_init_be(struct rtw89_dev *rtwdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (chip_id == RTL8922A)
|
||||
rtw89_write32_clr(rtwdev, R_BE_RSP_CHK_SIG,
|
||||
B_BE_RSP_STATIC_RTS_CHK_SERV_BW_EN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1114,7 +1114,8 @@ u32 __rtw89_pci_check_and_reclaim_tx_resource_noio(struct rtw89_dev *rtwdev,
|
||||
|
||||
spin_lock_bh(&rtwpci->trx_lock);
|
||||
cnt = rtw89_pci_get_avail_txbd_num(tx_ring);
|
||||
cnt = min(cnt, wd_ring->curr_num);
|
||||
if (txch != RTW89_TXCH_CH12)
|
||||
cnt = min(cnt, wd_ring->curr_num);
|
||||
spin_unlock_bh(&rtwpci->trx_lock);
|
||||
|
||||
return cnt;
|
||||
|
@ -6403,10 +6403,8 @@ enum rtw89_rf_path_bit rtw89_phy_get_kpath(struct rtw89_dev *rtwdev,
|
||||
return RF_D;
|
||||
case MLO_0_PLUS_2_1RF:
|
||||
case MLO_2_PLUS_0_1RF:
|
||||
if (phy_idx == RTW89_PHY_0)
|
||||
return RF_AB;
|
||||
else
|
||||
return RF_AB;
|
||||
/* for both PHY 0/1 */
|
||||
return RF_AB;
|
||||
case MLO_0_PLUS_2_2RF:
|
||||
case MLO_2_PLUS_0_2RF:
|
||||
case MLO_2_PLUS_2_2RF:
|
||||
|
@ -55,7 +55,8 @@ static void rtw89_ps_power_mode_change_with_hci(struct rtw89_dev *rtwdev,
|
||||
|
||||
static void rtw89_ps_power_mode_change(struct rtw89_dev *rtwdev, bool enter)
|
||||
{
|
||||
if (rtwdev->chip->low_power_hci_modes & BIT(rtwdev->ps_mode))
|
||||
if (rtwdev->chip->low_power_hci_modes & BIT(rtwdev->ps_mode) &&
|
||||
!test_bit(RTW89_FLAG_WOWLAN, rtwdev->flags))
|
||||
rtw89_ps_power_mode_change_with_hci(rtwdev, enter);
|
||||
else
|
||||
rtw89_mac_power_mode_change(rtwdev, enter);
|
||||
|
@ -235,6 +235,9 @@
|
||||
|
||||
#define R_AX_SPSANA_ON_CTRL1 0x0224
|
||||
|
||||
#define R_AX_SPS_ANA_ON_CTRL2 0x0228
|
||||
#define RTL8852B_RFE_05_SPS_ANA 0x4A82
|
||||
|
||||
#define R_AX_WLAN_XTAL_SI_CTRL 0x0270
|
||||
#define B_AX_WL_XTAL_SI_CMD_POLL BIT(31)
|
||||
#define B_AX_BT_XTAL_SI_ERR_FLAG BIT(30)
|
||||
|
@ -341,51 +341,60 @@ do { \
|
||||
static void rtw89_regd_setup_unii4(struct rtw89_dev *rtwdev,
|
||||
struct wiphy *wiphy)
|
||||
{
|
||||
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
bool regd_allow_unii_4 = chip->support_unii4;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct rtw89_acpi_dsm_result res = {};
|
||||
bool enable_by_fcc;
|
||||
bool enable_by_ic;
|
||||
int ret;
|
||||
u8 val;
|
||||
|
||||
if (!chip->support_unii4)
|
||||
goto bottom;
|
||||
|
||||
ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_59G_EN, &res);
|
||||
if (ret) {
|
||||
rtw89_debug(rtwdev, RTW89_DBG_REGD,
|
||||
"acpi: cannot eval unii 4: %d\n", ret);
|
||||
goto bottom;
|
||||
}
|
||||
|
||||
val = res.u.value;
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_REGD,
|
||||
"acpi: eval if allow unii 4: %d\n", val);
|
||||
|
||||
switch (val) {
|
||||
case 0:
|
||||
regd_allow_unii_4 = false;
|
||||
break;
|
||||
case 1:
|
||||
regd_allow_unii_4 = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
bottom:
|
||||
rtw89_debug(rtwdev, RTW89_DBG_REGD, "regd: allow unii 4: %d\n",
|
||||
regd_allow_unii_4);
|
||||
|
||||
if (regd_allow_unii_4)
|
||||
return;
|
||||
int i;
|
||||
|
||||
sband = wiphy->bands[NL80211_BAND_5GHZ];
|
||||
if (!sband)
|
||||
return;
|
||||
|
||||
sband->n_channels -= 3;
|
||||
if (!chip->support_unii4) {
|
||||
sband->n_channels -= RTW89_5GHZ_UNII4_CHANNEL_NUM;
|
||||
return;
|
||||
}
|
||||
|
||||
bitmap_fill(regulatory->block_unii4, RTW89_REGD_MAX_COUNTRY_NUM);
|
||||
|
||||
ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_UNII4_SUP, &res);
|
||||
if (ret) {
|
||||
rtw89_debug(rtwdev, RTW89_DBG_REGD,
|
||||
"acpi: cannot eval unii 4: %d\n", ret);
|
||||
enable_by_fcc = true;
|
||||
enable_by_ic = false;
|
||||
goto bottom;
|
||||
}
|
||||
|
||||
val = res.u.value;
|
||||
enable_by_fcc = u8_get_bits(val, RTW89_ACPI_CONF_UNII4_FCC);
|
||||
enable_by_ic = u8_get_bits(val, RTW89_ACPI_CONF_UNII4_IC);
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_REGD,
|
||||
"acpi: eval if allow unii-4: 0x%x\n", val);
|
||||
|
||||
bottom:
|
||||
for (i = 0; i < ARRAY_SIZE(rtw89_regd_map); i++) {
|
||||
const struct rtw89_regd *regd = &rtw89_regd_map[i];
|
||||
|
||||
switch (regd->txpwr_regd[RTW89_BAND_5G]) {
|
||||
case RTW89_FCC:
|
||||
if (enable_by_fcc)
|
||||
clear_bit(i, regulatory->block_unii4);
|
||||
break;
|
||||
case RTW89_IC:
|
||||
if (enable_by_ic)
|
||||
clear_bit(i, regulatory->block_unii4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void __rtw89_regd_setup_policy_6ghz(struct rtw89_dev *rtwdev, bool block,
|
||||
@ -459,6 +468,51 @@ out:
|
||||
kfree(ptr);
|
||||
}
|
||||
|
||||
static void rtw89_regd_setup_policy_6ghz_sp(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
|
||||
const struct rtw89_acpi_policy_6ghz_sp *ptr;
|
||||
struct rtw89_acpi_dsm_result res = {};
|
||||
bool enable_by_us;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP, &res);
|
||||
if (ret) {
|
||||
rtw89_debug(rtwdev, RTW89_DBG_REGD,
|
||||
"acpi: cannot eval policy 6ghz-sp: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ptr = res.u.policy_6ghz_sp;
|
||||
|
||||
switch (ptr->override) {
|
||||
default:
|
||||
rtw89_debug(rtwdev, RTW89_DBG_REGD,
|
||||
"%s: unknown override case: %d\n", __func__,
|
||||
ptr->override);
|
||||
fallthrough;
|
||||
case 0:
|
||||
goto out;
|
||||
case 1:
|
||||
break;
|
||||
}
|
||||
|
||||
bitmap_fill(regulatory->block_6ghz_sp, RTW89_REGD_MAX_COUNTRY_NUM);
|
||||
|
||||
enable_by_us = u8_get_bits(ptr->conf, RTW89_ACPI_CONF_6GHZ_SP_US);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rtw89_regd_map); i++) {
|
||||
const struct rtw89_regd *tmp = &rtw89_regd_map[i];
|
||||
|
||||
if (enable_by_us && memcmp(tmp->alpha2, "US", 2) == 0)
|
||||
clear_bit(i, regulatory->block_6ghz_sp);
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(ptr);
|
||||
}
|
||||
|
||||
static void rtw89_regd_setup_6ghz(struct rtw89_dev *rtwdev, struct wiphy *wiphy)
|
||||
{
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
@ -501,6 +555,7 @@ bottom:
|
||||
|
||||
if (regd_allow_6ghz) {
|
||||
rtw89_regd_setup_policy_6ghz(rtwdev);
|
||||
rtw89_regd_setup_policy_6ghz_sp(rtwdev);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -562,6 +617,35 @@ int rtw89_regd_init(struct rtw89_dev *rtwdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rtw89_regd_apply_policy_unii4(struct rtw89_dev *rtwdev,
|
||||
struct wiphy *wiphy)
|
||||
{
|
||||
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
const struct rtw89_regd *regd = regulatory->regd;
|
||||
struct ieee80211_supported_band *sband;
|
||||
u8 index;
|
||||
int i;
|
||||
|
||||
sband = wiphy->bands[NL80211_BAND_5GHZ];
|
||||
if (!sband)
|
||||
return;
|
||||
|
||||
if (!chip->support_unii4)
|
||||
return;
|
||||
|
||||
index = rtw89_regd_get_index(regd);
|
||||
if (index != RTW89_REGD_MAX_COUNTRY_NUM &&
|
||||
!test_bit(index, regulatory->block_unii4))
|
||||
return;
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c unii-4 is blocked by policy\n",
|
||||
regd->alpha2[0], regd->alpha2[1]);
|
||||
|
||||
for (i = RTW89_5GHZ_UNII4_START_INDEX; i < sband->n_channels; i++)
|
||||
sband->channels[i].flags |= IEEE80211_CHAN_DISABLED;
|
||||
}
|
||||
|
||||
static void rtw89_regd_apply_policy_6ghz(struct rtw89_dev *rtwdev,
|
||||
struct wiphy *wiphy)
|
||||
{
|
||||
@ -572,10 +656,8 @@ static void rtw89_regd_apply_policy_6ghz(struct rtw89_dev *rtwdev,
|
||||
int i;
|
||||
|
||||
index = rtw89_regd_get_index(regd);
|
||||
if (index == RTW89_REGD_MAX_COUNTRY_NUM)
|
||||
return;
|
||||
|
||||
if (!test_bit(index, regulatory->block_6ghz))
|
||||
if (index != RTW89_REGD_MAX_COUNTRY_NUM &&
|
||||
!test_bit(index, regulatory->block_6ghz))
|
||||
return;
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c 6 GHz is blocked by policy\n",
|
||||
@ -604,6 +686,7 @@ static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev,
|
||||
else
|
||||
wiphy->regulatory_flags &= ~REGULATORY_COUNTRY_IE_IGNORE;
|
||||
|
||||
rtw89_regd_apply_policy_unii4(rtwdev, wiphy);
|
||||
rtw89_regd_apply_policy_6ghz(rtwdev, wiphy);
|
||||
}
|
||||
|
||||
@ -634,10 +717,12 @@ exit:
|
||||
static void __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
|
||||
const struct rtw89_regd *regd = regulatory->regd;
|
||||
enum rtw89_reg_6ghz_power sel;
|
||||
const struct rtw89_chan *chan;
|
||||
struct rtw89_vif *rtwvif;
|
||||
int count = 0;
|
||||
u8 index;
|
||||
|
||||
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
|
||||
chan = rtw89_chan_get(rtwdev, rtwvif->sub_entity_idx);
|
||||
@ -654,6 +739,17 @@ static void __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev)
|
||||
if (count != 1)
|
||||
sel = RTW89_REG_6GHZ_POWER_DFLT;
|
||||
|
||||
if (sel == RTW89_REG_6GHZ_POWER_STD) {
|
||||
index = rtw89_regd_get_index(regd);
|
||||
if (index == RTW89_REGD_MAX_COUNTRY_NUM ||
|
||||
test_bit(index, regulatory->block_6ghz_sp)) {
|
||||
rtw89_debug(rtwdev, RTW89_DBG_REGD,
|
||||
"%c%c 6 GHz SP is blocked by policy\n",
|
||||
regd->alpha2[0], regd->alpha2[1]);
|
||||
sel = RTW89_REG_6GHZ_POWER_DFLT;
|
||||
}
|
||||
}
|
||||
|
||||
if (regulatory->reg_6ghz_power == sel)
|
||||
return;
|
||||
|
||||
|
@ -2320,6 +2320,7 @@ static int rtw8851b_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
|
||||
u8 wl_rfc_s1;
|
||||
int ret;
|
||||
|
||||
rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
|
||||
rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN,
|
||||
B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
|
||||
|
||||
|
@ -390,6 +390,14 @@ static const struct rtw89_btc_fbtc_mreg rtw89_btc_8852b_mon_reg[] = {
|
||||
static const u8 rtw89_btc_8852b_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {70, 60, 50, 40};
|
||||
static const u8 rtw89_btc_8852b_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {50, 40, 30, 20};
|
||||
|
||||
static void rtw8852b_pwr_sps_ana(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_efuse *efuse = &rtwdev->efuse;
|
||||
|
||||
if (efuse->rfe_type == 0x5)
|
||||
rtw89_write16(rtwdev, R_AX_SPS_ANA_ON_CTRL2, RTL8852B_RFE_05_SPS_ANA);
|
||||
}
|
||||
|
||||
static int rtw8852b_pwr_on_func(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
u32 val32;
|
||||
@ -522,6 +530,10 @@ static int rtw8852b_pwr_off_func(struct rtw89_dev *rtwdev)
|
||||
u32 val32;
|
||||
u32 ret;
|
||||
|
||||
/* Only do once during probe stage after reading efuse */
|
||||
if (!test_bit(RTW89_FLAG_PROBE_DONE, rtwdev->flags))
|
||||
rtw8852b_pwr_sps_ana(rtwdev);
|
||||
|
||||
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF,
|
||||
XTAL_SI_RFC2RF);
|
||||
if (ret)
|
||||
@ -550,6 +562,7 @@ static int rtw8852b_pwr_off_func(struct rtw89_dev *rtwdev)
|
||||
return ret;
|
||||
|
||||
rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON);
|
||||
rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
|
||||
rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, B_AX_FEN_BB_GLB_RSTN | B_AX_FEN_BBRSTB);
|
||||
rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3);
|
||||
|
||||
@ -2469,6 +2482,7 @@ static int rtw8852b_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
|
||||
u8 wl_rfc_s1;
|
||||
int ret;
|
||||
|
||||
rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
|
||||
rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN,
|
||||
B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
|
||||
|
||||
|
@ -203,6 +203,9 @@ static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
|
||||
rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APDM_HPDN);
|
||||
rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
|
||||
|
||||
rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0,
|
||||
B_AX_OCP_L1_MASK, 0x7);
|
||||
|
||||
ret = read_poll_timeout(rtw89_read32, val32, val32 & B_AX_RDY_SYSPWR,
|
||||
1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL);
|
||||
if (ret)
|
||||
@ -266,7 +269,7 @@ static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
|
||||
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SRAM2RFC);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_2, 0, XTAL_SI_LDO_LPS);
|
||||
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_2, 0x10, XTAL_SI_LDO_LPS);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_4, 0, XTAL_SI_LPS_CAP);
|
||||
@ -338,6 +341,7 @@ static int rtw8852c_pwr_off_func(struct rtw89_dev *rtwdev)
|
||||
return ret;
|
||||
|
||||
rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON);
|
||||
rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
|
||||
rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, B_AX_FEN_BB_GLB_RSTN | B_AX_FEN_BBRSTB);
|
||||
rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND,
|
||||
B_AX_R_SYM_FEN_WLBBGLB_1 | B_AX_R_SYM_FEN_WLBBFUN_1);
|
||||
@ -360,8 +364,11 @@ static int rtw8852c_pwr_off_func(struct rtw89_dev *rtwdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, 0x0001A0B0);
|
||||
rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, SW_LPS_OPTION);
|
||||
rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_XTAL_OFF_A_DIE);
|
||||
rtw89_write32_set(rtwdev, R_AX_SYS_SWR_CTRL1, B_AX_SYM_CTRL_SPS_PWMFREQ);
|
||||
rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0,
|
||||
B_AX_REG_ZCDC_H_MASK, 0x3);
|
||||
rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
|
||||
|
||||
return 0;
|
||||
@ -2816,6 +2823,7 @@ static int rtw8852c_mac_enable_bb_rf(struct rtw89_dev *rtwdev)
|
||||
|
||||
static int rtw8852c_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
|
||||
rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN,
|
||||
B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2126,7 +2126,7 @@ static void rtw8922a_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
|
||||
rtw8922a_hal_reset(rtwdev, RTW89_PHY_0, RTW89_MAC_0, band, &tx_en0, false);
|
||||
if (rtwdev->dbcc_en)
|
||||
rtw8922a_hal_reset(rtwdev, RTW89_PHY_1, RTW89_MAC_1, band,
|
||||
&tx_en0, false);
|
||||
&tx_en1, false);
|
||||
}
|
||||
|
||||
static u8 rtw8922a_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path)
|
||||
|
@ -7,8 +7,8 @@
|
||||
|
||||
#include "core.h"
|
||||
|
||||
#define RTW89_SAR_TXPWR_MAC_MAX S8_MAX
|
||||
#define RTW89_SAR_TXPWR_MAC_MIN S8_MIN
|
||||
#define RTW89_SAR_TXPWR_MAC_MAX 63
|
||||
#define RTW89_SAR_TXPWR_MAC_MIN -64
|
||||
|
||||
struct rtw89_sar_handler {
|
||||
const char *descr_sar_source;
|
||||
|
@ -12,6 +12,662 @@
|
||||
#include "util.h"
|
||||
#include "wow.h"
|
||||
|
||||
void rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
const u8 *rsn, *ies = mgmt->u.assoc_req.variable;
|
||||
struct rtw89_rsn_ie *rsn_ie;
|
||||
|
||||
rsn = cfg80211_find_ie(WLAN_EID_RSN, ies, skb->len);
|
||||
if (!rsn)
|
||||
return;
|
||||
|
||||
rsn_ie = (struct rtw89_rsn_ie *)rsn;
|
||||
rtw_wow->akm = rsn_ie->akm_cipher_suite.type;
|
||||
}
|
||||
|
||||
static const struct rtw89_cipher_info rtw89_cipher_info_defs[] = {
|
||||
{WLAN_CIPHER_SUITE_WEP40, .fw_alg = 1, .len = WLAN_KEY_LEN_WEP40,},
|
||||
{WLAN_CIPHER_SUITE_WEP104, .fw_alg = 2, .len = WLAN_KEY_LEN_WEP104,},
|
||||
{WLAN_CIPHER_SUITE_TKIP, .fw_alg = 3, .len = WLAN_KEY_LEN_TKIP,},
|
||||
{WLAN_CIPHER_SUITE_CCMP, .fw_alg = 6, .len = WLAN_KEY_LEN_CCMP,},
|
||||
{WLAN_CIPHER_SUITE_GCMP, .fw_alg = 8, .len = WLAN_KEY_LEN_GCMP,},
|
||||
{WLAN_CIPHER_SUITE_CCMP_256, .fw_alg = 7, .len = WLAN_KEY_LEN_CCMP_256,},
|
||||
{WLAN_CIPHER_SUITE_GCMP_256, .fw_alg = 23, .len = WLAN_KEY_LEN_GCMP_256,},
|
||||
{WLAN_CIPHER_SUITE_AES_CMAC, .fw_alg = 32, .len = WLAN_KEY_LEN_AES_CMAC,},
|
||||
};
|
||||
|
||||
static const
|
||||
struct rtw89_cipher_info *rtw89_cipher_alg_recognize(u32 cipher)
|
||||
{
|
||||
const struct rtw89_cipher_info *cipher_info_defs;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rtw89_cipher_info_defs); i++) {
|
||||
cipher_info_defs = &rtw89_cipher_info_defs[i];
|
||||
if (cipher_info_defs->cipher == cipher)
|
||||
return cipher_info_defs;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int _pn_to_iv(struct rtw89_dev *rtwdev, struct ieee80211_key_conf *key,
|
||||
u8 *iv, u64 pn, u8 key_idx)
|
||||
{
|
||||
switch (key->cipher) {
|
||||
case WLAN_CIPHER_SUITE_TKIP:
|
||||
iv[0] = u64_get_bits(pn, RTW89_KEY_PN_1);
|
||||
iv[1] = (u64_get_bits(pn, RTW89_KEY_PN_1) | 0x20) & 0x7f;
|
||||
iv[2] = u64_get_bits(pn, RTW89_KEY_PN_0);
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_CCMP:
|
||||
case WLAN_CIPHER_SUITE_GCMP:
|
||||
case WLAN_CIPHER_SUITE_CCMP_256:
|
||||
case WLAN_CIPHER_SUITE_GCMP_256:
|
||||
iv[0] = u64_get_bits(pn, RTW89_KEY_PN_0);
|
||||
iv[1] = u64_get_bits(pn, RTW89_KEY_PN_1);
|
||||
iv[2] = 0;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
iv[3] = BIT(5) | ((key_idx & 0x3) << 6);
|
||||
iv[4] = u64_get_bits(pn, RTW89_KEY_PN_2);
|
||||
iv[5] = u64_get_bits(pn, RTW89_KEY_PN_3);
|
||||
iv[6] = u64_get_bits(pn, RTW89_KEY_PN_4);
|
||||
iv[7] = u64_get_bits(pn, RTW89_KEY_PN_5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_rx_pn_to_iv(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_key_conf *key,
|
||||
u8 *iv)
|
||||
{
|
||||
struct ieee80211_key_seq seq;
|
||||
int err;
|
||||
u64 pn;
|
||||
|
||||
ieee80211_get_key_rx_seq(key, 0, &seq);
|
||||
|
||||
/* seq.ccmp.pn[] is BE order array */
|
||||
pn = u64_encode_bits(seq.ccmp.pn[0], RTW89_KEY_PN_5) |
|
||||
u64_encode_bits(seq.ccmp.pn[1], RTW89_KEY_PN_4) |
|
||||
u64_encode_bits(seq.ccmp.pn[2], RTW89_KEY_PN_3) |
|
||||
u64_encode_bits(seq.ccmp.pn[3], RTW89_KEY_PN_2) |
|
||||
u64_encode_bits(seq.ccmp.pn[4], RTW89_KEY_PN_1) |
|
||||
u64_encode_bits(seq.ccmp.pn[5], RTW89_KEY_PN_0);
|
||||
|
||||
err = _pn_to_iv(rtwdev, key, iv, pn, key->keyidx);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%llx to iv-%*ph\n",
|
||||
__func__, key->keyidx, pn, 8, iv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_tx_pn_to_iv(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_key_conf *key,
|
||||
u8 *iv)
|
||||
{
|
||||
int err;
|
||||
u64 pn;
|
||||
|
||||
pn = atomic64_inc_return(&key->tx_pn);
|
||||
err = _pn_to_iv(rtwdev, key, iv, pn, key->keyidx);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%llx to iv-%*ph\n",
|
||||
__func__, key->keyidx, pn, 8, iv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _iv_to_pn(struct rtw89_dev *rtwdev, u8 *iv, u64 *pn, u8 *key_id,
|
||||
struct ieee80211_key_conf *key)
|
||||
{
|
||||
switch (key->cipher) {
|
||||
case WLAN_CIPHER_SUITE_TKIP:
|
||||
*pn = u64_encode_bits(iv[2], RTW89_KEY_PN_0) |
|
||||
u64_encode_bits(iv[0], RTW89_KEY_PN_1);
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_CCMP:
|
||||
case WLAN_CIPHER_SUITE_GCMP:
|
||||
case WLAN_CIPHER_SUITE_CCMP_256:
|
||||
case WLAN_CIPHER_SUITE_GCMP_256:
|
||||
*pn = u64_encode_bits(iv[0], RTW89_KEY_PN_0) |
|
||||
u64_encode_bits(iv[1], RTW89_KEY_PN_1);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*pn |= u64_encode_bits(iv[4], RTW89_KEY_PN_2) |
|
||||
u64_encode_bits(iv[5], RTW89_KEY_PN_3) |
|
||||
u64_encode_bits(iv[6], RTW89_KEY_PN_4) |
|
||||
u64_encode_bits(iv[7], RTW89_KEY_PN_5);
|
||||
|
||||
if (key_id)
|
||||
*key_id = *(iv + 3) >> 6;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_rx_iv_to_pn(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_key_conf *key,
|
||||
u8 *iv)
|
||||
{
|
||||
struct ieee80211_key_seq seq;
|
||||
int err;
|
||||
u64 pn;
|
||||
|
||||
err = _iv_to_pn(rtwdev, iv, &pn, NULL, key);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* seq.ccmp.pn[] is BE order array */
|
||||
seq.ccmp.pn[0] = u64_get_bits(pn, RTW89_KEY_PN_5);
|
||||
seq.ccmp.pn[1] = u64_get_bits(pn, RTW89_KEY_PN_4);
|
||||
seq.ccmp.pn[2] = u64_get_bits(pn, RTW89_KEY_PN_3);
|
||||
seq.ccmp.pn[3] = u64_get_bits(pn, RTW89_KEY_PN_2);
|
||||
seq.ccmp.pn[4] = u64_get_bits(pn, RTW89_KEY_PN_1);
|
||||
seq.ccmp.pn[5] = u64_get_bits(pn, RTW89_KEY_PN_0);
|
||||
|
||||
ieee80211_set_key_rx_seq(key, 0, &seq);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d iv-%*ph to pn-%*ph\n",
|
||||
__func__, key->keyidx, 8, iv, 6, seq.ccmp.pn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_tx_iv_to_pn(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_key_conf *key,
|
||||
u8 *iv)
|
||||
{
|
||||
int err;
|
||||
u64 pn;
|
||||
|
||||
err = _iv_to_pn(rtwdev, iv, &pn, NULL, key);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
atomic64_set(&key->tx_pn, pn);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d iv-%*ph to pn-%llx\n",
|
||||
__func__, key->keyidx, 8, iv, pn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_rx_pn_get_pmf(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_key_conf *key,
|
||||
struct rtw89_wow_gtk_info *gtk_info)
|
||||
{
|
||||
struct ieee80211_key_seq seq;
|
||||
u64 pn;
|
||||
|
||||
if (key->keyidx == 4)
|
||||
memcpy(gtk_info->igtk[0], key->key, key->keylen);
|
||||
else if (key->keyidx == 5)
|
||||
memcpy(gtk_info->igtk[1], key->key, key->keylen);
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
ieee80211_get_key_rx_seq(key, 0, &seq);
|
||||
|
||||
/* seq.ccmp.pn[] is BE order array */
|
||||
pn = u64_encode_bits(seq.ccmp.pn[0], RTW89_KEY_PN_5) |
|
||||
u64_encode_bits(seq.ccmp.pn[1], RTW89_KEY_PN_4) |
|
||||
u64_encode_bits(seq.ccmp.pn[2], RTW89_KEY_PN_3) |
|
||||
u64_encode_bits(seq.ccmp.pn[3], RTW89_KEY_PN_2) |
|
||||
u64_encode_bits(seq.ccmp.pn[4], RTW89_KEY_PN_1) |
|
||||
u64_encode_bits(seq.ccmp.pn[5], RTW89_KEY_PN_0);
|
||||
gtk_info->ipn = cpu_to_le64(pn);
|
||||
gtk_info->igtk_keyid = cpu_to_le32(key->keyidx);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%llx\n",
|
||||
__func__, key->keyidx, pn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_rx_pn_set_pmf(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_key_conf *key,
|
||||
u64 pn)
|
||||
{
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
|
||||
struct ieee80211_key_seq seq;
|
||||
|
||||
if (key->keyidx != aoac_rpt->igtk_key_id)
|
||||
return 0;
|
||||
|
||||
/* seq.ccmp.pn[] is BE order array */
|
||||
seq.ccmp.pn[0] = u64_get_bits(pn, RTW89_KEY_PN_5);
|
||||
seq.ccmp.pn[1] = u64_get_bits(pn, RTW89_KEY_PN_4);
|
||||
seq.ccmp.pn[2] = u64_get_bits(pn, RTW89_KEY_PN_3);
|
||||
seq.ccmp.pn[3] = u64_get_bits(pn, RTW89_KEY_PN_2);
|
||||
seq.ccmp.pn[4] = u64_get_bits(pn, RTW89_KEY_PN_1);
|
||||
seq.ccmp.pn[5] = u64_get_bits(pn, RTW89_KEY_PN_0);
|
||||
|
||||
ieee80211_set_key_rx_seq(key, 0, &seq);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%*ph\n",
|
||||
__func__, key->keyidx, 6, seq.ccmp.pn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rtw89_wow_get_key_info_iter(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key,
|
||||
void *data)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
struct rtw89_wow_key_info *key_info = &rtw_wow->key_info;
|
||||
struct rtw89_wow_gtk_info *gtk_info = &rtw_wow->gtk_info;
|
||||
const struct rtw89_cipher_info *cipher_info;
|
||||
bool *err = data;
|
||||
int ret;
|
||||
|
||||
cipher_info = rtw89_cipher_alg_recognize(key->cipher);
|
||||
|
||||
switch (key->cipher) {
|
||||
case WLAN_CIPHER_SUITE_TKIP:
|
||||
case WLAN_CIPHER_SUITE_CCMP:
|
||||
case WLAN_CIPHER_SUITE_GCMP:
|
||||
case WLAN_CIPHER_SUITE_CCMP_256:
|
||||
case WLAN_CIPHER_SUITE_GCMP_256:
|
||||
if (sta) {
|
||||
ret = rtw89_tx_pn_to_iv(rtwdev, key,
|
||||
key_info->ptk_tx_iv);
|
||||
if (ret)
|
||||
goto err;
|
||||
ret = rtw89_rx_pn_to_iv(rtwdev, key,
|
||||
key_info->ptk_rx_iv);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
rtw_wow->ptk_alg = cipher_info->fw_alg;
|
||||
rtw_wow->ptk_keyidx = key->keyidx;
|
||||
} else {
|
||||
ret = rtw89_rx_pn_to_iv(rtwdev, key,
|
||||
key_info->gtk_rx_iv[key->keyidx]);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
rtw_wow->gtk_alg = cipher_info->fw_alg;
|
||||
key_info->gtk_keyidx = key->keyidx;
|
||||
}
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_AES_CMAC:
|
||||
ret = rtw89_rx_pn_get_pmf(rtwdev, key, gtk_info);
|
||||
if (ret)
|
||||
goto err;
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_WEP40:
|
||||
case WLAN_CIPHER_SUITE_WEP104:
|
||||
/* WEP only set group key in mac80211, but fw need to set
|
||||
* both of pairwise key and group key.
|
||||
*/
|
||||
rtw_wow->ptk_alg = cipher_info->fw_alg;
|
||||
rtw_wow->ptk_keyidx = key->keyidx;
|
||||
rtw_wow->gtk_alg = cipher_info->fw_alg;
|
||||
key_info->gtk_keyidx = key->keyidx;
|
||||
break;
|
||||
default:
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "unsupport cipher %x\n",
|
||||
key->cipher);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return;
|
||||
err:
|
||||
*err = true;
|
||||
}
|
||||
|
||||
static void rtw89_wow_set_key_info_iter(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key,
|
||||
void *data)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
|
||||
struct rtw89_set_key_info_iter_data *iter_data = data;
|
||||
bool update_tx_key_info = iter_data->rx_ready;
|
||||
int ret;
|
||||
|
||||
switch (key->cipher) {
|
||||
case WLAN_CIPHER_SUITE_TKIP:
|
||||
case WLAN_CIPHER_SUITE_CCMP:
|
||||
case WLAN_CIPHER_SUITE_GCMP:
|
||||
case WLAN_CIPHER_SUITE_CCMP_256:
|
||||
case WLAN_CIPHER_SUITE_GCMP_256:
|
||||
if (sta && !update_tx_key_info) {
|
||||
ret = rtw89_rx_iv_to_pn(rtwdev, key,
|
||||
aoac_rpt->ptk_rx_iv);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (sta && update_tx_key_info) {
|
||||
ret = rtw89_tx_iv_to_pn(rtwdev, key,
|
||||
aoac_rpt->ptk_tx_iv);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!sta && !update_tx_key_info) {
|
||||
ret = rtw89_rx_iv_to_pn(rtwdev, key,
|
||||
aoac_rpt->gtk_rx_iv[key->keyidx]);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!sta && update_tx_key_info && aoac_rpt->rekey_ok)
|
||||
iter_data->gtk_cipher = key->cipher;
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_AES_CMAC:
|
||||
if (update_tx_key_info) {
|
||||
if (aoac_rpt->rekey_ok)
|
||||
iter_data->igtk_cipher = key->cipher;
|
||||
} else {
|
||||
ret = rtw89_rx_pn_set_pmf(rtwdev, key,
|
||||
aoac_rpt->igtk_ipn);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_WEP40:
|
||||
case WLAN_CIPHER_SUITE_WEP104:
|
||||
break;
|
||||
default:
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "unsupport cipher %x\n",
|
||||
key->cipher);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
err:
|
||||
iter_data->error = true;
|
||||
}
|
||||
|
||||
static void rtw89_wow_key_clear(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
|
||||
memset(&rtw_wow->aoac_rpt, 0, sizeof(rtw_wow->aoac_rpt));
|
||||
memset(&rtw_wow->gtk_info, 0, sizeof(rtw_wow->gtk_info));
|
||||
memset(&rtw_wow->key_info, 0, sizeof(rtw_wow->key_info));
|
||||
rtw_wow->ptk_alg = 0;
|
||||
rtw_wow->gtk_alg = 0;
|
||||
}
|
||||
|
||||
static void rtw89_wow_construct_key_info(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
struct rtw89_wow_key_info *key_info = &rtw_wow->key_info;
|
||||
struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
|
||||
bool err = false;
|
||||
|
||||
rcu_read_lock();
|
||||
ieee80211_iter_keys_rcu(rtwdev->hw, wow_vif,
|
||||
rtw89_wow_get_key_info_iter, &err);
|
||||
rcu_read_unlock();
|
||||
|
||||
if (err) {
|
||||
rtw89_wow_key_clear(rtwdev);
|
||||
return;
|
||||
}
|
||||
|
||||
key_info->valid_check = RTW89_WOW_VALID_CHECK;
|
||||
key_info->symbol_check_en = RTW89_WOW_SYMBOL_CHK_PTK |
|
||||
RTW89_WOW_SYMBOL_CHK_GTK;
|
||||
}
|
||||
|
||||
static void rtw89_wow_debug_aoac_rpt(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
|
||||
|
||||
if (!rtw89_debug_is_enabled(rtwdev, RTW89_DBG_WOW))
|
||||
return;
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] rpt_ver = %d\n",
|
||||
aoac_rpt->rpt_ver);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] sec_type = %d\n",
|
||||
aoac_rpt->sec_type);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] key_idx = %d\n",
|
||||
aoac_rpt->key_idx);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] pattern_idx = %d\n",
|
||||
aoac_rpt->pattern_idx);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] rekey_ok = %d\n",
|
||||
aoac_rpt->rekey_ok);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] ptk_tx_iv = %*ph\n",
|
||||
8, aoac_rpt->ptk_tx_iv);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW,
|
||||
"[aoac_rpt] eapol_key_replay_count = %*ph\n",
|
||||
8, aoac_rpt->eapol_key_replay_count);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] ptk_rx_iv = %*ph\n",
|
||||
8, aoac_rpt->ptk_rx_iv);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] gtk_rx_iv[0] = %*ph\n",
|
||||
8, aoac_rpt->gtk_rx_iv[0]);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] gtk_rx_iv[1] = %*ph\n",
|
||||
8, aoac_rpt->gtk_rx_iv[1]);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] gtk_rx_iv[2] = %*ph\n",
|
||||
8, aoac_rpt->gtk_rx_iv[2]);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] gtk_rx_iv[3] = %*ph\n",
|
||||
8, aoac_rpt->gtk_rx_iv[3]);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] igtk_key_id = %llu\n",
|
||||
aoac_rpt->igtk_key_id);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] igtk_ipn = %llu\n",
|
||||
aoac_rpt->igtk_ipn);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] igtk = %*ph\n",
|
||||
32, aoac_rpt->igtk);
|
||||
}
|
||||
|
||||
static int rtw89_wow_get_aoac_rpt_reg(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
|
||||
struct rtw89_mac_c2h_info c2h_info = {};
|
||||
struct rtw89_mac_h2c_info h2c_info = {};
|
||||
u8 igtk_ipn[8];
|
||||
u8 key_idx;
|
||||
int ret;
|
||||
|
||||
h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_AOAC_RPT_1;
|
||||
h2c_info.content_len = 2;
|
||||
ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, &c2h_info);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
aoac_rpt->key_idx =
|
||||
u32_get_bits(c2h_info.u.c2hreg[0], RTW89_C2HREG_AOAC_RPT_1_W0_KEY_IDX);
|
||||
key_idx = aoac_rpt->key_idx;
|
||||
aoac_rpt->gtk_rx_iv[key_idx][0] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_1_W1_IV_0);
|
||||
aoac_rpt->gtk_rx_iv[key_idx][1] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_1_W1_IV_1);
|
||||
aoac_rpt->gtk_rx_iv[key_idx][2] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_1_W1_IV_2);
|
||||
aoac_rpt->gtk_rx_iv[key_idx][3] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_1_W1_IV_3);
|
||||
aoac_rpt->gtk_rx_iv[key_idx][4] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_1_W2_IV_4);
|
||||
aoac_rpt->gtk_rx_iv[key_idx][5] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_1_W2_IV_5);
|
||||
aoac_rpt->gtk_rx_iv[key_idx][6] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_1_W2_IV_6);
|
||||
aoac_rpt->gtk_rx_iv[key_idx][7] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_1_W2_IV_7);
|
||||
aoac_rpt->ptk_rx_iv[0] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_0);
|
||||
aoac_rpt->ptk_rx_iv[1] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_1);
|
||||
aoac_rpt->ptk_rx_iv[2] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_2);
|
||||
aoac_rpt->ptk_rx_iv[3] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_3);
|
||||
|
||||
h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_AOAC_RPT_2;
|
||||
h2c_info.content_len = 2;
|
||||
ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, &c2h_info);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
aoac_rpt->ptk_rx_iv[4] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[0], RTW89_C2HREG_AOAC_RPT_2_W0_PTK_IV_4);
|
||||
aoac_rpt->ptk_rx_iv[5] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[0], RTW89_C2HREG_AOAC_RPT_2_W0_PTK_IV_5);
|
||||
aoac_rpt->ptk_rx_iv[6] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_2_W1_PTK_IV_6);
|
||||
aoac_rpt->ptk_rx_iv[7] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_2_W1_PTK_IV_7);
|
||||
igtk_ipn[0] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_2_W1_IGTK_IPN_IV_0);
|
||||
igtk_ipn[1] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_2_W1_IGTK_IPN_IV_1);
|
||||
igtk_ipn[2] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_2);
|
||||
igtk_ipn[3] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_3);
|
||||
igtk_ipn[4] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_4);
|
||||
igtk_ipn[5] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_5);
|
||||
igtk_ipn[6] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_2_W3_IGTK_IPN_IV_6);
|
||||
igtk_ipn[7] =
|
||||
u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_2_W3_IGTK_IPN_IV_7);
|
||||
aoac_rpt->igtk_ipn = u64_encode_bits(igtk_ipn[0], RTW89_IGTK_IPN_0) |
|
||||
u64_encode_bits(igtk_ipn[1], RTW89_IGTK_IPN_1) |
|
||||
u64_encode_bits(igtk_ipn[2], RTW89_IGTK_IPN_2) |
|
||||
u64_encode_bits(igtk_ipn[3], RTW89_IGTK_IPN_3) |
|
||||
u64_encode_bits(igtk_ipn[4], RTW89_IGTK_IPN_4) |
|
||||
u64_encode_bits(igtk_ipn[5], RTW89_IGTK_IPN_5) |
|
||||
u64_encode_bits(igtk_ipn[6], RTW89_IGTK_IPN_6) |
|
||||
u64_encode_bits(igtk_ipn[7], RTW89_IGTK_IPN_7);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_wow_get_aoac_rpt(struct rtw89_dev *rtwdev, bool rx_ready)
|
||||
{
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
int ret;
|
||||
|
||||
if (!rtw_wow->ptk_alg)
|
||||
return -EPERM;
|
||||
|
||||
if (!rx_ready) {
|
||||
ret = rtw89_wow_get_aoac_rpt_reg(rtwdev);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "wow: failed to get aoac rpt by reg\n");
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
ret = rtw89_fw_h2c_wow_request_aoac(rtwdev);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "wow: failed to get aoac rpt by pkt\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
rtw89_wow_debug_aoac_rpt(rtwdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ieee80211_key_conf *rtw89_wow_gtk_rekey(struct rtw89_dev *rtwdev,
|
||||
u32 cipher, u8 keyidx, u8 *gtk)
|
||||
{
|
||||
struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
|
||||
const struct rtw89_cipher_info *cipher_info;
|
||||
struct ieee80211_key_conf *rekey_conf;
|
||||
struct ieee80211_key_conf *key;
|
||||
u8 sz;
|
||||
|
||||
cipher_info = rtw89_cipher_alg_recognize(cipher);
|
||||
sz = struct_size(rekey_conf, key, cipher_info->len);
|
||||
rekey_conf = kmalloc(sz, GFP_KERNEL);
|
||||
if (!rekey_conf)
|
||||
return NULL;
|
||||
|
||||
rekey_conf->cipher = cipher;
|
||||
rekey_conf->keyidx = keyidx;
|
||||
rekey_conf->keylen = cipher_info->len;
|
||||
memcpy(rekey_conf->key, gtk,
|
||||
flex_array_size(rekey_conf, key, cipher_info->len));
|
||||
|
||||
/* ieee80211_gtk_rekey_add() will call set_key(), therefore we
|
||||
* need to unlock mutex
|
||||
*/
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
key = ieee80211_gtk_rekey_add(wow_vif, rekey_conf, -1);
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
|
||||
kfree(rekey_conf);
|
||||
if (IS_ERR(key)) {
|
||||
rtw89_err(rtwdev, "ieee80211_gtk_rekey_add failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static void rtw89_wow_update_key_info(struct rtw89_dev *rtwdev, bool rx_ready)
|
||||
{
|
||||
struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
|
||||
struct rtw89_set_key_info_iter_data data = {.error = false,
|
||||
.rx_ready = rx_ready};
|
||||
struct ieee80211_key_conf *key;
|
||||
|
||||
rcu_read_lock();
|
||||
ieee80211_iter_keys_rcu(rtwdev->hw, wow_vif,
|
||||
rtw89_wow_set_key_info_iter, &data);
|
||||
rcu_read_unlock();
|
||||
|
||||
if (data.error) {
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s error\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.gtk_cipher)
|
||||
return;
|
||||
|
||||
key = rtw89_wow_gtk_rekey(rtwdev, data.gtk_cipher, aoac_rpt->key_idx,
|
||||
aoac_rpt->gtk);
|
||||
if (!key)
|
||||
return;
|
||||
|
||||
rtw89_rx_iv_to_pn(rtwdev, key,
|
||||
aoac_rpt->gtk_rx_iv[key->keyidx]);
|
||||
|
||||
if (!data.igtk_cipher)
|
||||
return;
|
||||
|
||||
key = rtw89_wow_gtk_rekey(rtwdev, data.igtk_cipher, aoac_rpt->igtk_key_id,
|
||||
aoac_rpt->igtk);
|
||||
if (!key)
|
||||
return;
|
||||
|
||||
rtw89_rx_pn_set_pmf(rtwdev, key, aoac_rpt->igtk_ipn);
|
||||
ieee80211_gtk_rekey_notify(wow_vif, wow_vif->bss_conf.bssid,
|
||||
aoac_rpt->eapol_key_replay_count,
|
||||
GFP_KERNEL);
|
||||
}
|
||||
|
||||
static void rtw89_wow_leave_deep_ps(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
__rtw89_leave_ps_mode(rtwdev);
|
||||
@ -59,6 +715,8 @@ static void rtw89_wow_set_rx_filter(struct rtw89_dev *rtwdev, bool enable)
|
||||
|
||||
static void rtw89_wow_show_wakeup_reason(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
|
||||
u32 wow_reason_reg = rtwdev->chip->wow_reason_reg;
|
||||
struct cfg80211_wowlan_nd_info nd_info;
|
||||
struct cfg80211_wowlan_wakeup wakeup = {
|
||||
@ -85,10 +743,7 @@ static void rtw89_wow_show_wakeup_reason(struct rtw89_dev *rtwdev)
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx gtk rekey\n");
|
||||
break;
|
||||
case RTW89_WOW_RSN_RX_PATTERN_MATCH:
|
||||
/* Current firmware and driver don't report pattern index
|
||||
* Use pattern_idx to 0 defaultly.
|
||||
*/
|
||||
wakeup.pattern_idx = 0;
|
||||
wakeup.pattern_idx = aoac_rpt->pattern_idx;
|
||||
rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx pattern match packet\n");
|
||||
break;
|
||||
case RTW89_WOW_RSN_RX_NLO:
|
||||
@ -454,17 +1109,21 @@ static int rtw89_wow_check_fw_status(struct rtw89_dev *rtwdev, bool wow_enable)
|
||||
static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
|
||||
{
|
||||
enum rtw89_fw_type fw_type = wow ? RTW89_FW_WOWLAN : RTW89_FW_NORMAL;
|
||||
enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen;
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;
|
||||
struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
|
||||
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
bool include_bb = !!chip->bbmcu_nr;
|
||||
bool disable_intr_for_dlfw = false;
|
||||
struct ieee80211_sta *wow_sta;
|
||||
struct rtw89_sta *rtwsta = NULL;
|
||||
bool is_conn = true;
|
||||
int ret;
|
||||
|
||||
rtw89_hci_disable_intr(rtwdev);
|
||||
if (chip_id == RTL8852C || chip_id == RTL8922A)
|
||||
disable_intr_for_dlfw = true;
|
||||
|
||||
wow_sta = ieee80211_find_sta(wow_vif, rtwvif->bssid);
|
||||
if (wow_sta)
|
||||
@ -472,12 +1131,18 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
|
||||
else
|
||||
is_conn = false;
|
||||
|
||||
if (disable_intr_for_dlfw)
|
||||
rtw89_hci_disable_intr(rtwdev);
|
||||
|
||||
ret = rtw89_fw_download(rtwdev, fw_type, include_bb);
|
||||
if (ret) {
|
||||
rtw89_warn(rtwdev, "download fw failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (disable_intr_for_dlfw)
|
||||
rtw89_hci_enable_intr(rtwdev);
|
||||
|
||||
rtw89_phy_init_rf_reg(rtwdev, true);
|
||||
|
||||
ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta,
|
||||
@ -519,8 +1184,10 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
|
||||
rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, wow_vif);
|
||||
}
|
||||
|
||||
if (chip_gen == RTW89_CHIP_BE)
|
||||
rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, RTW89_PHY_0, 5);
|
||||
|
||||
rtw89_mac_hw_mgnt_sec(rtwdev, wow);
|
||||
rtw89_hci_enable_intr(rtwdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -595,7 +1262,22 @@ static int rtw89_wow_disable_trx_pre(struct rtw89_dev *rtwdev)
|
||||
rtw89_err(rtwdev, "failed to config mac\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Before enabling interrupt, we need to get AOAC report by reg due to RX
|
||||
* not enabled yet. Also, we need to sync RX related IV from firmware to
|
||||
* mac80211 before receiving RX packets from driver.
|
||||
* After enabling interrupt, we can get AOAC report from h2c and c2h, and
|
||||
* can get TX IV and complete rekey info. We need to update TX related IV
|
||||
* and new GTK info if rekey happened.
|
||||
*/
|
||||
ret = rtw89_wow_get_aoac_rpt(rtwdev, false);
|
||||
if (!ret)
|
||||
rtw89_wow_update_key_info(rtwdev, false);
|
||||
|
||||
rtw89_hci_enable_intr(rtwdev);
|
||||
ret = rtw89_wow_get_aoac_rpt(rtwdev, true);
|
||||
if (!ret)
|
||||
rtw89_wow_update_key_info(rtwdev, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -618,6 +1300,7 @@ static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev)
|
||||
int ret;
|
||||
|
||||
rtw89_wow_pattern_write(rtwdev);
|
||||
rtw89_wow_construct_key_info(rtwdev);
|
||||
|
||||
ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif, true);
|
||||
if (ret) {
|
||||
@ -631,6 +1314,16 @@ static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif, true);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "wow: failed to enable GTK offload\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = rtw89_fw_h2c_arp_offload(rtwdev, rtwvif, true);
|
||||
if (ret)
|
||||
rtw89_warn(rtwdev, "wow: failed to enable arp offload\n");
|
||||
|
||||
ret = rtw89_wow_cfg_wake(rtwdev, true);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "wow: failed to config wake\n");
|
||||
@ -667,6 +1360,17 @@ static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif, false);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "wow: failed to disable GTK offload\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = rtw89_fw_h2c_arp_offload(rtwdev, rtwvif, false);
|
||||
if (ret)
|
||||
rtw89_warn(rtwdev, "wow: failed to disable arp offload\n");
|
||||
|
||||
rtw89_wow_key_clear(rtwdev);
|
||||
rtw89_fw_release_general_pkt_list(rtwdev, true);
|
||||
|
||||
ret = rtw89_wow_cfg_wake(rtwdev, false);
|
||||
|
@ -5,6 +5,26 @@
|
||||
#ifndef __RTW89_WOW_H__
|
||||
#define __RTW89_WOW_H__
|
||||
|
||||
#define RTW89_KEY_PN_0 GENMASK_ULL(7, 0)
|
||||
#define RTW89_KEY_PN_1 GENMASK_ULL(15, 8)
|
||||
#define RTW89_KEY_PN_2 GENMASK_ULL(23, 16)
|
||||
#define RTW89_KEY_PN_3 GENMASK_ULL(31, 24)
|
||||
#define RTW89_KEY_PN_4 GENMASK_ULL(39, 32)
|
||||
#define RTW89_KEY_PN_5 GENMASK_ULL(47, 40)
|
||||
|
||||
#define RTW89_IGTK_IPN_0 GENMASK_ULL(7, 0)
|
||||
#define RTW89_IGTK_IPN_1 GENMASK_ULL(15, 8)
|
||||
#define RTW89_IGTK_IPN_2 GENMASK_ULL(23, 16)
|
||||
#define RTW89_IGTK_IPN_3 GENMASK_ULL(31, 24)
|
||||
#define RTW89_IGTK_IPN_4 GENMASK_ULL(39, 32)
|
||||
#define RTW89_IGTK_IPN_5 GENMASK_ULL(47, 40)
|
||||
#define RTW89_IGTK_IPN_6 GENMASK_ULL(55, 48)
|
||||
#define RTW89_IGTK_IPN_7 GENMASK_ULL(63, 56)
|
||||
|
||||
#define RTW89_WOW_VALID_CHECK 0xDD
|
||||
#define RTW89_WOW_SYMBOL_CHK_PTK BIT(0)
|
||||
#define RTW89_WOW_SYMBOL_CHK_GTK BIT(1)
|
||||
|
||||
enum rtw89_wake_reason {
|
||||
RTW89_WOW_RSN_RX_PTK_REKEY = 0x1,
|
||||
RTW89_WOW_RSN_RX_GTK_REKEY = 0x2,
|
||||
@ -15,7 +35,44 @@ enum rtw89_wake_reason {
|
||||
RTW89_WOW_RSN_RX_NLO = 0x55,
|
||||
};
|
||||
|
||||
struct rtw89_cipher_suite {
|
||||
u8 oui[3];
|
||||
u8 type;
|
||||
} __packed;
|
||||
|
||||
struct rtw89_rsn_ie {
|
||||
u8 tag_number;
|
||||
u8 tag_length;
|
||||
__le16 rsn_version;
|
||||
struct rtw89_cipher_suite group_cipher_suite;
|
||||
__le16 pairwise_cipher_suite_cnt;
|
||||
struct rtw89_cipher_suite pairwise_cipher_suite;
|
||||
__le16 akm_cipher_suite_cnt;
|
||||
struct rtw89_cipher_suite akm_cipher_suite;
|
||||
} __packed;
|
||||
|
||||
struct rtw89_cipher_info {
|
||||
u32 cipher;
|
||||
u8 fw_alg;
|
||||
enum ieee80211_key_len len;
|
||||
};
|
||||
|
||||
struct rtw89_set_key_info_iter_data {
|
||||
u32 gtk_cipher;
|
||||
u32 igtk_cipher;
|
||||
bool rx_ready;
|
||||
bool error;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
int rtw89_wow_suspend(struct rtw89_dev *rtwdev, struct cfg80211_wowlan *wowlan);
|
||||
int rtw89_wow_resume(struct rtw89_dev *rtwdev);
|
||||
void rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb);
|
||||
#else
|
||||
static inline
|
||||
void rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user