mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
Merge tag 'rtw-next-2025-11-21-v2' of https://github.com/pkshih/rtw
Ping-Ke Shih says: ================== rtw-next patches for v6.19 Main changes are about rtw89 USB support, which two USB devices are added with proper TX status, and other notable items are listed below. rtl8xxxu: - fix 40MHz bandwidth connection rtw89: - support USB devices RTL8852AU and RTL8852CU - report TX status from air for USB devices - resolve racing between processes of TX and TX report - resolve racing of skb queue of C2H events - support injected packets with bandwidth and data rate - more materials for coming RTL8922DE ================== Link: https://patch.msgid.link/45eed1763a354460acba15a8e69f9e3e@realtek.com Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
@@ -1023,9 +1023,6 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev)
|
||||
dma_addr_t *mapping;
|
||||
entry = priv->rx_ring + priv->rx_ring_sz*i;
|
||||
if (!skb) {
|
||||
dma_free_coherent(&priv->pdev->dev,
|
||||
priv->rx_ring_sz * 32,
|
||||
priv->rx_ring, priv->rx_ring_dma);
|
||||
wiphy_err(dev->wiphy, "Cannot allocate RX skb\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -1037,9 +1034,7 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev)
|
||||
|
||||
if (dma_mapping_error(&priv->pdev->dev, *mapping)) {
|
||||
kfree_skb(skb);
|
||||
dma_free_coherent(&priv->pdev->dev,
|
||||
priv->rx_ring_sz * 32,
|
||||
priv->rx_ring, priv->rx_ring_dma);
|
||||
priv->rx_buf[i] = NULL;
|
||||
wiphy_err(dev->wiphy, "Cannot map DMA for RX skb\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -1130,7 +1125,7 @@ static int rtl8180_start(struct ieee80211_hw *dev)
|
||||
|
||||
ret = rtl8180_init_rx_ring(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_free_rings;
|
||||
|
||||
for (i = 0; i < (dev->queues + 1); i++)
|
||||
if ((ret = rtl8180_init_tx_ring(dev, i, 16)))
|
||||
|
||||
@@ -338,14 +338,16 @@ static void rtl8187_rx_cb(struct urb *urb)
|
||||
spin_unlock_irqrestore(&priv->rx_queue.lock, f);
|
||||
skb_put(skb, urb->actual_length);
|
||||
|
||||
if (unlikely(urb->status)) {
|
||||
dev_kfree_skb_irq(skb);
|
||||
return;
|
||||
}
|
||||
if (unlikely(urb->status))
|
||||
goto free_skb;
|
||||
|
||||
if (!priv->is_rtl8187b) {
|
||||
struct rtl8187_rx_hdr *hdr =
|
||||
(typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
|
||||
struct rtl8187_rx_hdr *hdr;
|
||||
|
||||
if (skb->len < sizeof(struct rtl8187_rx_hdr))
|
||||
goto free_skb;
|
||||
|
||||
hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
|
||||
flags = le32_to_cpu(hdr->flags);
|
||||
/* As with the RTL8187B below, the AGC is used to calculate
|
||||
* signal strength. In this case, the scaling
|
||||
@@ -355,8 +357,12 @@ static void rtl8187_rx_cb(struct urb *urb)
|
||||
rx_status.antenna = (hdr->signal >> 7) & 1;
|
||||
rx_status.mactime = le64_to_cpu(hdr->mac_time);
|
||||
} else {
|
||||
struct rtl8187b_rx_hdr *hdr =
|
||||
(typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
|
||||
struct rtl8187b_rx_hdr *hdr;
|
||||
|
||||
if (skb->len < sizeof(struct rtl8187b_rx_hdr))
|
||||
goto free_skb;
|
||||
|
||||
hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
|
||||
/* The Realtek datasheet for the RTL8187B shows that the RX
|
||||
* header contains the following quantities: signal quality,
|
||||
* RSSI, AGC, the received power in dB, and the measured SNR.
|
||||
@@ -409,6 +415,11 @@ static void rtl8187_rx_cb(struct urb *urb)
|
||||
skb_unlink(skb, &priv->rx_queue);
|
||||
dev_kfree_skb_irq(skb);
|
||||
}
|
||||
return;
|
||||
|
||||
free_skb:
|
||||
dev_kfree_skb_irq(skb);
|
||||
return;
|
||||
}
|
||||
|
||||
static int rtl8187_init_urbs(struct ieee80211_hw *dev)
|
||||
|
||||
@@ -593,6 +593,84 @@ static int rtl8192cu_power_on(struct rtl8xxxu_priv *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rtl8192cu_power_off(struct rtl8xxxu_priv *priv)
|
||||
{
|
||||
u32 val32;
|
||||
u16 val16;
|
||||
u8 val8;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Workaround for 8188RU LNA power leakage problem.
|
||||
*/
|
||||
if (priv->rtl_chip == RTL8188R) {
|
||||
val32 = rtl8xxxu_read32(priv, REG_FPGA0_XCD_RF_PARM);
|
||||
val32 |= BIT(1);
|
||||
rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_PARM, val32);
|
||||
}
|
||||
|
||||
/* _DisableRFAFEAndResetBB */
|
||||
rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff);
|
||||
rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_AC, 0xff, 0);
|
||||
|
||||
rtl8xxxu_write8_set(priv, REG_APSD_CTRL, APSD_CTRL_OFF);
|
||||
rtl8xxxu_write32_set(priv, REG_FPGA0_XCD_RF_PARM, FPGA0_RF_PARM_CLK_GATE);
|
||||
|
||||
rtl8xxxu_write8(priv, REG_SYS_FUNC,
|
||||
SYS_FUNC_USBA | SYS_FUNC_USBD | SYS_FUNC_BB_GLB_RSTN);
|
||||
rtl8xxxu_write8(priv, REG_SYS_FUNC, SYS_FUNC_USBA | SYS_FUNC_USBD);
|
||||
|
||||
/* _ResetDigitalProcedure1 */
|
||||
if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_DL_READY) {
|
||||
rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00);
|
||||
|
||||
rtl8xxxu_write8(priv, REG_FWIMR, 0x20);
|
||||
|
||||
rtl8xxxu_write8(priv, REG_HMTFR + 3, 0x20);
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC);
|
||||
if (!(val16 & SYS_FUNC_CPU_ENABLE))
|
||||
break;
|
||||
|
||||
fsleep(50);
|
||||
}
|
||||
|
||||
if (i == 100) {
|
||||
rtl8xxxu_write8(priv, REG_SYS_FUNC + 1,
|
||||
(SYS_FUNC_HWPDN | SYS_FUNC_ELDR) >> 8);
|
||||
msleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
val8 = (SYS_FUNC_HWPDN | SYS_FUNC_ELDR | SYS_FUNC_CPU_ENABLE) >> 8;
|
||||
rtl8xxxu_write8(priv, REG_SYS_FUNC + 1, val8);
|
||||
|
||||
/* _DisableGPIO */
|
||||
rtl8xxxu_write16(priv, REG_GPIO_PIN_CTRL + 2, 0);
|
||||
val32 = rtl8xxxu_read32(priv, REG_GPIO_PIN_CTRL) & 0xffff00ff;
|
||||
val32 |= (val32 & 0xff) << 8;
|
||||
val32 |= 0x00ff0000;
|
||||
rtl8xxxu_write32(priv, REG_GPIO_PIN_CTRL, val32);
|
||||
|
||||
rtl8xxxu_write8(priv, REG_GPIO_MUXCFG + 3, 0);
|
||||
val16 = rtl8xxxu_read16(priv, REG_GPIO_MUXCFG + 2) & 0xff0f;
|
||||
val16 |= (val16 & 0xf) << 4;
|
||||
val16 |= 0x0780;
|
||||
rtl8xxxu_write16(priv, REG_GPIO_MUXCFG + 2, val16);
|
||||
|
||||
/* _DisableAnalog */
|
||||
val8 = 0x23;
|
||||
if (priv->vendor_umc && priv->chip_cut == 1)
|
||||
val8 |= BIT(3);
|
||||
rtl8xxxu_write8(priv, REG_SPS0_CTRL, val8);
|
||||
|
||||
val16 = APS_FSMCO_HOST | APS_FSMCO_HW_SUSPEND | APS_FSMCO_PFM_ALDN;
|
||||
rtl8xxxu_write16(priv, REG_APS_FSMCO, val16);
|
||||
|
||||
rtl8xxxu_write8(priv, REG_RSV_CTRL, 0x0e);
|
||||
}
|
||||
|
||||
static int rtl8192cu_led_brightness_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
@@ -618,7 +696,7 @@ struct rtl8xxxu_fileops rtl8192cu_fops = {
|
||||
.parse_efuse = rtl8192cu_parse_efuse,
|
||||
.load_firmware = rtl8192cu_load_firmware,
|
||||
.power_on = rtl8192cu_power_on,
|
||||
.power_off = rtl8xxxu_power_off,
|
||||
.power_off = rtl8192cu_power_off,
|
||||
.read_efuse = rtl8xxxu_read_efuse,
|
||||
.reset_8051 = rtl8xxxu_reset_8051,
|
||||
.llt_init = rtl8xxxu_init_llt_table,
|
||||
|
||||
@@ -411,6 +411,119 @@ exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtl8723au_active_to_emu(struct rtl8xxxu_priv *priv)
|
||||
{
|
||||
u8 val8;
|
||||
int count, ret = 0;
|
||||
|
||||
/* Start of rtl8723AU_card_enable_flow */
|
||||
/* Act to Cardemu sequence*/
|
||||
/* Turn off RF */
|
||||
rtl8xxxu_write8(priv, REG_RF_CTRL, 0);
|
||||
|
||||
/* 0x004E[7] = 0, switch DPDT_SEL_P output from register 0x0065[2] */
|
||||
val8 = rtl8xxxu_read8(priv, REG_LEDCFG2);
|
||||
val8 &= ~LEDCFG2_DPDT_SELECT;
|
||||
rtl8xxxu_write8(priv, REG_LEDCFG2, val8);
|
||||
|
||||
/* 0x0005[1] = 1 turn off MAC by HW state machine*/
|
||||
val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
|
||||
val8 |= BIT(1);
|
||||
rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
|
||||
|
||||
for (count = RTL8XXXU_MAX_REG_POLL; count; count--) {
|
||||
val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
|
||||
if ((val8 & BIT(1)) == 0)
|
||||
break;
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
if (!count) {
|
||||
dev_warn(&priv->udev->dev, "%s: Disabling MAC timed out\n",
|
||||
__func__);
|
||||
ret = -EBUSY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* 0x0000[5] = 1 analog Ips to digital, 1:isolation */
|
||||
val8 = rtl8xxxu_read8(priv, REG_SYS_ISO_CTRL);
|
||||
val8 |= SYS_ISO_ANALOG_IPS;
|
||||
rtl8xxxu_write8(priv, REG_SYS_ISO_CTRL, val8);
|
||||
|
||||
/* 0x0020[0] = 0 disable LDOA12 MACRO block*/
|
||||
val8 = rtl8xxxu_read8(priv, REG_LDOA15_CTRL);
|
||||
val8 &= ~LDOA15_ENABLE;
|
||||
rtl8xxxu_write8(priv, REG_LDOA15_CTRL, val8);
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtl8723au_emu_to_disabled(struct rtl8xxxu_priv *priv)
|
||||
{
|
||||
u8 val8;
|
||||
|
||||
/* 0x0007[7:0] = 0x20 SOP option to disable BG/MB */
|
||||
rtl8xxxu_write8(priv, REG_APS_FSMCO + 3, 0x20);
|
||||
|
||||
/* 0x04[12:11] = 01 enable WL suspend */
|
||||
val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
|
||||
val8 &= ~BIT(4);
|
||||
val8 |= BIT(3);
|
||||
rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
|
||||
|
||||
val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
|
||||
val8 |= BIT(7);
|
||||
rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
|
||||
|
||||
/* 0x48[16] = 1 to enable GPIO9 as EXT wakeup */
|
||||
val8 = rtl8xxxu_read8(priv, REG_GPIO_INTM + 2);
|
||||
val8 |= BIT(0);
|
||||
rtl8xxxu_write8(priv, REG_GPIO_INTM + 2, val8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rtl8723au_power_off(struct rtl8xxxu_priv *priv)
|
||||
{
|
||||
u8 val8;
|
||||
u16 val16;
|
||||
|
||||
rtl8xxxu_flush_fifo(priv);
|
||||
|
||||
rtl8xxxu_active_to_lps(priv);
|
||||
|
||||
/* Turn off RF */
|
||||
rtl8xxxu_write8(priv, REG_RF_CTRL, 0x00);
|
||||
|
||||
/* Reset Firmware if running in RAM */
|
||||
if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_RAM_SEL)
|
||||
rtl8xxxu_firmware_self_reset(priv);
|
||||
|
||||
/* Reset MCU */
|
||||
val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC);
|
||||
val16 &= ~SYS_FUNC_CPU_ENABLE;
|
||||
rtl8xxxu_write16(priv, REG_SYS_FUNC, val16);
|
||||
|
||||
/* Reset MCU ready status */
|
||||
rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00);
|
||||
|
||||
rtl8723au_active_to_emu(priv);
|
||||
rtl8723au_emu_to_disabled(priv);
|
||||
|
||||
/* Reset MCU IO Wrapper */
|
||||
val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1);
|
||||
val8 &= ~BIT(0);
|
||||
rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8);
|
||||
|
||||
val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1);
|
||||
val8 |= BIT(0);
|
||||
rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8);
|
||||
|
||||
/* RSV_CTRL 0x1C[7:0] = 0x0e lock ISO/CLK/Power control register */
|
||||
rtl8xxxu_write8(priv, REG_RSV_CTRL, 0x0e);
|
||||
}
|
||||
|
||||
#define XTAL1 GENMASK(23, 18)
|
||||
#define XTAL0 GENMASK(17, 12)
|
||||
|
||||
@@ -492,7 +605,7 @@ struct rtl8xxxu_fileops rtl8723au_fops = {
|
||||
.parse_efuse = rtl8723au_parse_efuse,
|
||||
.load_firmware = rtl8723au_load_firmware,
|
||||
.power_on = rtl8723au_power_on,
|
||||
.power_off = rtl8xxxu_power_off,
|
||||
.power_off = rtl8723au_power_off,
|
||||
.read_efuse = rtl8xxxu_read_efuse,
|
||||
.reset_8051 = rtl8xxxu_reset_8051,
|
||||
.llt_init = rtl8xxxu_init_llt_table,
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#define DRIVER_NAME "rtl8xxxu"
|
||||
|
||||
int rtl8xxxu_debug;
|
||||
static bool rtl8xxxu_ht40_2g;
|
||||
static bool rtl8xxxu_dma_aggregation;
|
||||
static int rtl8xxxu_dma_agg_timeout = -1;
|
||||
static int rtl8xxxu_dma_agg_pages = -1;
|
||||
@@ -45,8 +44,6 @@ MODULE_FIRMWARE("rtlwifi/rtl8192fufw.bin");
|
||||
|
||||
module_param_named(debug, rtl8xxxu_debug, int, 0600);
|
||||
MODULE_PARM_DESC(debug, "Set debug mask");
|
||||
module_param_named(ht40_2g, rtl8xxxu_ht40_2g, bool, 0600);
|
||||
MODULE_PARM_DESC(ht40_2g, "Enable HT40 support on the 2.4GHz band");
|
||||
module_param_named(dma_aggregation, rtl8xxxu_dma_aggregation, bool, 0600);
|
||||
MODULE_PARM_DESC(dma_aggregation, "Enable DMA packet aggregation");
|
||||
module_param_named(dma_agg_timeout, rtl8xxxu_dma_agg_timeout, int, 0600);
|
||||
@@ -1252,7 +1249,7 @@ void rtl8xxxu_gen1_config_channel(struct ieee80211_hw *hw)
|
||||
opmode &= ~BW_OPMODE_20MHZ;
|
||||
rtl8xxxu_write8(priv, REG_BW_OPMODE, opmode);
|
||||
rsr &= ~RSR_RSC_BANDWIDTH_40M;
|
||||
if (sec_ch_above)
|
||||
if (!sec_ch_above)
|
||||
rsr |= RSR_RSC_UPPER_SUB_CHANNEL;
|
||||
else
|
||||
rsr |= RSR_RSC_LOWER_SUB_CHANNEL;
|
||||
@@ -1321,9 +1318,8 @@ void rtl8xxxu_gen1_config_channel(struct ieee80211_hw *hw)
|
||||
|
||||
for (i = RF_A; i < priv->rf_paths; i++) {
|
||||
val32 = rtl8xxxu_read_rfreg(priv, i, RF6052_REG_MODE_AG);
|
||||
if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40)
|
||||
val32 &= ~MODE_AG_CHANNEL_20MHZ;
|
||||
else
|
||||
val32 &= ~MODE_AG_BW_MASK;
|
||||
if (hw->conf.chandef.width != NL80211_CHAN_WIDTH_40)
|
||||
val32 |= MODE_AG_CHANNEL_20MHZ;
|
||||
rtl8xxxu_write_rfreg(priv, i, RF6052_REG_MODE_AG, val32);
|
||||
}
|
||||
@@ -1374,9 +1370,11 @@ void rtl8xxxu_gen2_config_channel(struct ieee80211_hw *hw)
|
||||
hw->conf.chandef.chan->center_freq) {
|
||||
sec_ch_above = 1;
|
||||
channel += 2;
|
||||
subchannel = 2;
|
||||
} else {
|
||||
sec_ch_above = 0;
|
||||
channel -= 2;
|
||||
subchannel = 1;
|
||||
}
|
||||
|
||||
val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE);
|
||||
@@ -3637,54 +3635,6 @@ static void rtl8xxxu_set_ampdu_min_space(struct rtl8xxxu_priv *priv, u8 density)
|
||||
rtl8xxxu_write8(priv, REG_AMPDU_MIN_SPACE, val8);
|
||||
}
|
||||
|
||||
static int rtl8xxxu_active_to_emu(struct rtl8xxxu_priv *priv)
|
||||
{
|
||||
u8 val8;
|
||||
int count, ret = 0;
|
||||
|
||||
/* Start of rtl8723AU_card_enable_flow */
|
||||
/* Act to Cardemu sequence*/
|
||||
/* Turn off RF */
|
||||
rtl8xxxu_write8(priv, REG_RF_CTRL, 0);
|
||||
|
||||
/* 0x004E[7] = 0, switch DPDT_SEL_P output from register 0x0065[2] */
|
||||
val8 = rtl8xxxu_read8(priv, REG_LEDCFG2);
|
||||
val8 &= ~LEDCFG2_DPDT_SELECT;
|
||||
rtl8xxxu_write8(priv, REG_LEDCFG2, val8);
|
||||
|
||||
/* 0x0005[1] = 1 turn off MAC by HW state machine*/
|
||||
val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
|
||||
val8 |= BIT(1);
|
||||
rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
|
||||
|
||||
for (count = RTL8XXXU_MAX_REG_POLL; count; count--) {
|
||||
val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
|
||||
if ((val8 & BIT(1)) == 0)
|
||||
break;
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
if (!count) {
|
||||
dev_warn(&priv->udev->dev, "%s: Disabling MAC timed out\n",
|
||||
__func__);
|
||||
ret = -EBUSY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* 0x0000[5] = 1 analog Ips to digital, 1:isolation */
|
||||
val8 = rtl8xxxu_read8(priv, REG_SYS_ISO_CTRL);
|
||||
val8 |= SYS_ISO_ANALOG_IPS;
|
||||
rtl8xxxu_write8(priv, REG_SYS_ISO_CTRL, val8);
|
||||
|
||||
/* 0x0020[0] = 0 disable LDOA12 MACRO block*/
|
||||
val8 = rtl8xxxu_read8(priv, REG_LDOA15_CTRL);
|
||||
val8 &= ~LDOA15_ENABLE;
|
||||
rtl8xxxu_write8(priv, REG_LDOA15_CTRL, val8);
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rtl8xxxu_active_to_lps(struct rtl8xxxu_priv *priv)
|
||||
{
|
||||
u8 val8;
|
||||
@@ -3761,31 +3711,6 @@ void rtl8xxxu_disabled_to_emu(struct rtl8xxxu_priv *priv)
|
||||
rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
|
||||
}
|
||||
|
||||
static int rtl8xxxu_emu_to_disabled(struct rtl8xxxu_priv *priv)
|
||||
{
|
||||
u8 val8;
|
||||
|
||||
/* 0x0007[7:0] = 0x20 SOP option to disable BG/MB */
|
||||
rtl8xxxu_write8(priv, REG_APS_FSMCO + 3, 0x20);
|
||||
|
||||
/* 0x04[12:11] = 01 enable WL suspend */
|
||||
val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
|
||||
val8 &= ~BIT(4);
|
||||
val8 |= BIT(3);
|
||||
rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
|
||||
|
||||
val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
|
||||
val8 |= BIT(7);
|
||||
rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
|
||||
|
||||
/* 0x48[16] = 1 to enable GPIO9 as EXT wakeup */
|
||||
val8 = rtl8xxxu_read8(priv, REG_GPIO_INTM + 2);
|
||||
val8 |= BIT(0);
|
||||
rtl8xxxu_write8(priv, REG_GPIO_INTM + 2, val8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtl8xxxu_flush_fifo(struct rtl8xxxu_priv *priv)
|
||||
{
|
||||
struct device *dev = &priv->udev->dev;
|
||||
@@ -3863,56 +3788,6 @@ void rtl8xxxu_gen2_usb_quirks(struct rtl8xxxu_priv *priv)
|
||||
rtl8xxxu_write32(priv, REG_TXDMA_OFFSET_CHK, val32);
|
||||
}
|
||||
|
||||
void rtl8xxxu_power_off(struct rtl8xxxu_priv *priv)
|
||||
{
|
||||
u8 val8;
|
||||
u16 val16;
|
||||
u32 val32;
|
||||
|
||||
/*
|
||||
* Workaround for 8188RU LNA power leakage problem.
|
||||
*/
|
||||
if (priv->rtl_chip == RTL8188R) {
|
||||
val32 = rtl8xxxu_read32(priv, REG_FPGA0_XCD_RF_PARM);
|
||||
val32 |= BIT(1);
|
||||
rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_PARM, val32);
|
||||
}
|
||||
|
||||
rtl8xxxu_flush_fifo(priv);
|
||||
|
||||
rtl8xxxu_active_to_lps(priv);
|
||||
|
||||
/* Turn off RF */
|
||||
rtl8xxxu_write8(priv, REG_RF_CTRL, 0x00);
|
||||
|
||||
/* Reset Firmware if running in RAM */
|
||||
if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_RAM_SEL)
|
||||
rtl8xxxu_firmware_self_reset(priv);
|
||||
|
||||
/* Reset MCU */
|
||||
val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC);
|
||||
val16 &= ~SYS_FUNC_CPU_ENABLE;
|
||||
rtl8xxxu_write16(priv, REG_SYS_FUNC, val16);
|
||||
|
||||
/* Reset MCU ready status */
|
||||
rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00);
|
||||
|
||||
rtl8xxxu_active_to_emu(priv);
|
||||
rtl8xxxu_emu_to_disabled(priv);
|
||||
|
||||
/* Reset MCU IO Wrapper */
|
||||
val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1);
|
||||
val8 &= ~BIT(0);
|
||||
rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8);
|
||||
|
||||
val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1);
|
||||
val8 |= BIT(0);
|
||||
rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8);
|
||||
|
||||
/* RSV_CTRL 0x1C[7:0] = 0x0e lock ISO/CLK/Power control register */
|
||||
rtl8xxxu_write8(priv, REG_RSV_CTRL, 0x0e);
|
||||
}
|
||||
|
||||
void rtl8723bu_set_ps_tdma(struct rtl8xxxu_priv *priv,
|
||||
u8 arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5)
|
||||
{
|
||||
@@ -5018,8 +4893,7 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
sgi = 1;
|
||||
|
||||
highest_rate = fls(ramask) - 1;
|
||||
if (rtl8xxxu_ht40_2g &&
|
||||
(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
|
||||
if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
|
||||
bw = RATE_INFO_BW_40;
|
||||
else
|
||||
bw = RATE_INFO_BW_20;
|
||||
@@ -5345,9 +5219,19 @@ rtl8xxxu_fill_txdesc_v1(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
|
||||
tx_desc->txdw5 |= cpu_to_le32(TXDESC32_RETRY_LIMIT_ENABLE);
|
||||
}
|
||||
|
||||
if (ieee80211_is_data_qos(hdr->frame_control))
|
||||
if (ieee80211_is_data_qos(hdr->frame_control)) {
|
||||
tx_desc->txdw4 |= cpu_to_le32(TXDESC32_QOS);
|
||||
|
||||
if (conf_is_ht40(&hw->conf)) {
|
||||
tx_desc->txdw4 |= cpu_to_le32(TXDESC_DATA_BW);
|
||||
|
||||
if (conf_is_ht40_minus(&hw->conf))
|
||||
tx_desc->txdw4 |= cpu_to_le32(TXDESC_PRIME_CH_OFF_UPPER);
|
||||
else
|
||||
tx_desc->txdw4 |= cpu_to_le32(TXDESC_PRIME_CH_OFF_LOWER);
|
||||
}
|
||||
}
|
||||
|
||||
if (short_preamble)
|
||||
tx_desc->txdw4 |= cpu_to_le32(TXDESC32_SHORT_PREAMBLE);
|
||||
|
||||
@@ -5813,7 +5697,7 @@ static void jaguar2_rx_parse_phystats_type1(struct rtl8xxxu_priv *priv,
|
||||
!rtl8xxxu_is_sta_sta(priv) &&
|
||||
(rtl8xxxu_is_packet_match_bssid(priv, hdr, 0) ||
|
||||
rtl8xxxu_is_packet_match_bssid(priv, hdr, 1));
|
||||
u8 pwdb_max = 0;
|
||||
u8 pwdb_max = 0, rxsc;
|
||||
int rx_path;
|
||||
|
||||
if (parse_cfo) {
|
||||
@@ -5828,6 +5712,16 @@ static void jaguar2_rx_parse_phystats_type1(struct rtl8xxxu_priv *priv,
|
||||
pwdb_max = max(pwdb_max, phy_stats1->pwdb[rx_path]);
|
||||
|
||||
rx_status->signal = pwdb_max - 110;
|
||||
|
||||
if (rxmcs >= DESC_RATE_6M && rxmcs <= DESC_RATE_54M)
|
||||
rxsc = phy_stats1->l_rxsc;
|
||||
else
|
||||
rxsc = phy_stats1->ht_rxsc;
|
||||
|
||||
if (phy_stats1->rf_mode == 0 || rxsc == 1 || rxsc == 2)
|
||||
rx_status->bw = RATE_INFO_BW_20;
|
||||
else
|
||||
rx_status->bw = RATE_INFO_BW_40;
|
||||
}
|
||||
|
||||
static void jaguar2_rx_parse_phystats_type2(struct rtl8xxxu_priv *priv,
|
||||
@@ -6454,6 +6348,8 @@ int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb)
|
||||
rtl8xxxu_rx_update_rssi(priv,
|
||||
rx_status,
|
||||
hdr);
|
||||
} else {
|
||||
rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
|
||||
}
|
||||
|
||||
rx_status->mactime = rx_desc->tsfl;
|
||||
@@ -6560,6 +6456,8 @@ int rtl8xxxu_parse_rxdesc24(struct rtl8xxxu_priv *priv, struct sk_buff *skb)
|
||||
rtl8xxxu_rx_update_rssi(priv,
|
||||
rx_status,
|
||||
hdr);
|
||||
} else {
|
||||
rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
|
||||
}
|
||||
|
||||
rx_status->mactime = rx_desc->tsfl;
|
||||
@@ -7906,15 +7804,15 @@ static int rtl8xxxu_probe(struct usb_interface *interface,
|
||||
goto err_set_intfdata;
|
||||
}
|
||||
|
||||
if (rtl8xxxu_debug & RTL8XXXU_DEBUG_EFUSE)
|
||||
rtl8xxxu_dump_efuse(priv);
|
||||
|
||||
ret = priv->fops->parse_efuse(priv);
|
||||
if (ret) {
|
||||
dev_err(&udev->dev, "Fatal - failed to parse EFuse\n");
|
||||
goto err_set_intfdata;
|
||||
}
|
||||
|
||||
if (rtl8xxxu_debug & RTL8XXXU_DEBUG_EFUSE)
|
||||
rtl8xxxu_dump_efuse(priv);
|
||||
|
||||
rtl8xxxu_print_chipinfo(priv);
|
||||
|
||||
ret = priv->fops->load_firmware(priv);
|
||||
@@ -7949,7 +7847,8 @@ static int rtl8xxxu_probe(struct usb_interface *interface,
|
||||
sband->ht_cap.ht_supported = true;
|
||||
sband->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
|
||||
sband->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
|
||||
sband->ht_cap.cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40;
|
||||
sband->ht_cap.cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
|
||||
IEEE80211_HT_CAP_SUP_WIDTH_20_40;
|
||||
memset(&sband->ht_cap.mcs, 0, sizeof(sband->ht_cap.mcs));
|
||||
sband->ht_cap.mcs.rx_mask[0] = 0xff;
|
||||
sband->ht_cap.mcs.rx_mask[4] = 0x01;
|
||||
@@ -7958,15 +7857,7 @@ static int rtl8xxxu_probe(struct usb_interface *interface,
|
||||
sband->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
|
||||
}
|
||||
sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
|
||||
/*
|
||||
* Some APs will negotiate HT20_40 in a noisy environment leading
|
||||
* to miserable performance. Rather than defaulting to this, only
|
||||
* enable it if explicitly requested at module load time.
|
||||
*/
|
||||
if (rtl8xxxu_ht40_2g) {
|
||||
dev_info(&udev->dev, "Enabling HT_20_40 on the 2.4GHz band\n");
|
||||
sband->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
|
||||
}
|
||||
|
||||
hw->wiphy->bands[NL80211_BAND_2GHZ] = sband;
|
||||
|
||||
hw->wiphy->rts_threshold = 2347;
|
||||
@@ -8136,6 +8027,9 @@ static const struct usb_device_id dev_table[] = {
|
||||
/* TP-Link TL-WN823N V2 */
|
||||
{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0135, 0xff, 0xff, 0xff),
|
||||
.driver_info = (unsigned long)&rtl8192fu_fops},
|
||||
/* D-Link AN3U rev. A1 */
|
||||
{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3328, 0xff, 0xff, 0xff),
|
||||
.driver_info = (unsigned long)&rtl8192fu_fops},
|
||||
#ifdef CONFIG_RTL8XXXU_UNTESTED
|
||||
/* Still supported by rtlwifi */
|
||||
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8176, 0xff, 0xff, 0xff),
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#define APS_FSMCO_SW_LPS BIT(10)
|
||||
#define APS_FSMCO_HW_SUSPEND BIT(11)
|
||||
#define APS_FSMCO_PCIE BIT(12)
|
||||
#define APS_FSMCO_HOST BIT(14)
|
||||
#define APS_FSMCO_HW_POWERDOWN BIT(15)
|
||||
#define APS_FSMCO_WLON_RESET BIT(16)
|
||||
|
||||
|
||||
@@ -2078,7 +2078,6 @@ int rtl8xxxu_init_phy_regs(struct rtl8xxxu_priv *priv,
|
||||
const struct rtl8xxxu_reg32val *array);
|
||||
int rtl8xxxu_load_firmware(struct rtl8xxxu_priv *priv, const char *fw_name);
|
||||
void rtl8xxxu_firmware_self_reset(struct rtl8xxxu_priv *priv);
|
||||
void rtl8xxxu_power_off(struct rtl8xxxu_priv *priv);
|
||||
void rtl8xxxu_identify_vendor_1bit(struct rtl8xxxu_priv *priv, u32 vendor);
|
||||
void rtl8xxxu_identify_vendor_2bits(struct rtl8xxxu_priv *priv, u32 vendor);
|
||||
void rtl8xxxu_config_endpoints_sie(struct rtl8xxxu_priv *priv);
|
||||
|
||||
@@ -445,7 +445,7 @@ static int _rtl_init_deferred_work(struct ieee80211_hw *hw)
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct workqueue_struct *wq;
|
||||
|
||||
wq = alloc_workqueue("%s", 0, 0, rtlpriv->cfg->name);
|
||||
wq = alloc_workqueue("%s", WQ_UNBOUND, 0, rtlpriv->cfg->name);
|
||||
if (!wq)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@@ -694,7 +694,7 @@ void rtl88e_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
|
||||
|
||||
if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
|
||||
p2p_ps_offload->role = 1;
|
||||
p2p_ps_offload->allstasleep = -1;
|
||||
p2p_ps_offload->allstasleep = 0;
|
||||
} else {
|
||||
p2p_ps_offload->role = 0;
|
||||
}
|
||||
|
||||
@@ -124,8 +124,11 @@ void rtw_bf_init_bfer_entry_mu(struct rtw_dev *rtwdev,
|
||||
void rtw_bf_cfg_sounding(struct rtw_dev *rtwdev, struct rtw_vif *vif,
|
||||
enum rtw_trx_desc_rate rate)
|
||||
{
|
||||
u8 csi_rsc = CSI_RSC_FOLLOW_RX_PACKET_BW;
|
||||
u32 psf_ctl = 0;
|
||||
u8 csi_rsc = 0x1;
|
||||
|
||||
if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C)
|
||||
csi_rsc = CSI_RSC_PRIMARY_20M_BW;
|
||||
|
||||
psf_ctl = rtw_read32(rtwdev, REG_BBPSF_CTRL) |
|
||||
BIT_WMAC_USE_NDPARATE |
|
||||
@@ -387,6 +390,9 @@ void rtw_bf_cfg_csi_rate(struct rtw_dev *rtwdev, u8 rssi, u8 cur_rate,
|
||||
csi_cfg = rtw_read32(rtwdev, REG_BBPSF_CTRL) & ~BIT_MASK_CSI_RATE;
|
||||
cur_rrsr = rtw_read16(rtwdev, REG_RRSR);
|
||||
|
||||
if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C)
|
||||
csi_cfg |= BIT_CSI_FORCE_RATE;
|
||||
|
||||
if (rssi >= 40) {
|
||||
if (cur_rate != DESC_RATE54M) {
|
||||
cur_rrsr |= BIT(DESC_RATE54M);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#define BIT_SHIFT_R_MU_RL 12
|
||||
#define BIT_SHIFT_WMAC_TXMU_ACKPOLICY 4
|
||||
#define BIT_SHIFT_CSI_RATE 24
|
||||
#define BIT_CSI_FORCE_RATE BIT(15)
|
||||
|
||||
#define BIT_MASK_R_MU_RL (R_MU_RL << BIT_SHIFT_R_MU_RL)
|
||||
#define BIT_MASK_R_MU_TABLE_VALID 0x3f
|
||||
@@ -48,6 +49,12 @@
|
||||
#define RTW_SND_CTRL_REMOVE 0x98
|
||||
#define RTW_SND_CTRL_SOUNDING 0x9B
|
||||
|
||||
enum csi_rsc {
|
||||
CSI_RSC_PRIMARY_20M_BW = 0,
|
||||
CSI_RSC_FOLLOW_RX_PACKET_BW = 1,
|
||||
CSI_RSC_DUPLICATE_MODE = 2,
|
||||
};
|
||||
|
||||
enum csi_seg_len {
|
||||
HAL_CSI_SEG_4K = 0,
|
||||
HAL_CSI_SEG_8K = 1,
|
||||
|
||||
@@ -79,6 +79,8 @@ static const struct usb_device_id rtw_8822bu_id_table[] = {
|
||||
.driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* D-Link DWA-T185 rev. A1 */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x03d1, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* BUFFALO WI-U2-866DM */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x03d0, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* BUFFALO WI-U3-866DHP */
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, rtw_8822bu_id_table);
|
||||
|
||||
@@ -21,6 +21,8 @@ static const struct usb_device_id rtw_8822cu_id_table[] = {
|
||||
.driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0043, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, /* Alpha - Alpha */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3329, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, /* D-Link AC13U rev. A1 */
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, rtw_8822cu_id_table);
|
||||
|
||||
@@ -965,7 +965,8 @@ static int rtw_usb_init_rx(struct rtw_dev *rtwdev)
|
||||
struct sk_buff *rx_skb;
|
||||
int i;
|
||||
|
||||
rtwusb->rxwq = alloc_workqueue("rtw88_usb: rx wq", WQ_BH, 0);
|
||||
rtwusb->rxwq = alloc_workqueue("rtw88_usb: rx wq", WQ_BH | WQ_UNBOUND,
|
||||
0);
|
||||
if (!rtwusb->rxwq) {
|
||||
rtw_err(rtwdev, "failed to create RX work queue\n");
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -74,6 +74,17 @@ config RTW89_8852AE
|
||||
|
||||
802.11ax PCIe wireless network (Wi-Fi 6) adapter
|
||||
|
||||
config RTW89_8852AU
|
||||
tristate "Realtek 8852AU USB wireless network (Wi-Fi 6) adapter"
|
||||
depends on USB
|
||||
select RTW89_CORE
|
||||
select RTW89_USB
|
||||
select RTW89_8852A
|
||||
help
|
||||
Select this option will enable support for 8852AU chipset
|
||||
|
||||
802.11ax USB wireless network (Wi-Fi 6) adapter
|
||||
|
||||
config RTW89_8852BE
|
||||
tristate "Realtek 8852BE PCI wireless network (Wi-Fi 6) adapter"
|
||||
depends on PCI
|
||||
@@ -121,6 +132,17 @@ config RTW89_8852CE
|
||||
|
||||
802.11ax PCIe wireless network (Wi-Fi 6E) adapter
|
||||
|
||||
config RTW89_8852CU
|
||||
tristate "Realtek 8852CU USB wireless network (Wi-Fi 6E) adapter"
|
||||
depends on USB
|
||||
select RTW89_CORE
|
||||
select RTW89_USB
|
||||
select RTW89_8852C
|
||||
help
|
||||
Select this option will enable support for 8852CU chipset
|
||||
|
||||
802.11ax USB wireless network (Wi-Fi 6E) adapter
|
||||
|
||||
config RTW89_8922AE
|
||||
tristate "Realtek 8922AE/8922AE-VS PCI wireless network (Wi-Fi 7) adapter"
|
||||
depends on PCI
|
||||
|
||||
@@ -43,6 +43,9 @@ rtw89_8852a-objs := rtw8852a.o \
|
||||
obj-$(CONFIG_RTW89_8852AE) += rtw89_8852ae.o
|
||||
rtw89_8852ae-objs := rtw8852ae.o
|
||||
|
||||
obj-$(CONFIG_RTW89_8852AU) += rtw89_8852au.o
|
||||
rtw89_8852au-objs := rtw8852au.o
|
||||
|
||||
obj-$(CONFIG_RTW89_8852B_COMMON) += rtw89_8852b_common.o
|
||||
rtw89_8852b_common-objs := rtw8852b_common.o
|
||||
|
||||
@@ -75,6 +78,9 @@ rtw89_8852c-objs := rtw8852c.o \
|
||||
obj-$(CONFIG_RTW89_8852CE) += rtw89_8852ce.o
|
||||
rtw89_8852ce-objs := rtw8852ce.o
|
||||
|
||||
obj-$(CONFIG_RTW89_8852CU) += rtw89_8852cu.o
|
||||
rtw89_8852cu-objs := rtw8852cu.o
|
||||
|
||||
obj-$(CONFIG_RTW89_8922A) += rtw89_8922a.o
|
||||
rtw89_8922a-objs := rtw8922a.o \
|
||||
rtw8922a_rfk.o
|
||||
|
||||
@@ -236,7 +236,8 @@ static int __rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev,
|
||||
if (ret)
|
||||
rtw89_err(rtwdev,
|
||||
"failed to update dctl cam del key: %d\n", ret);
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL,
|
||||
RTW89_ROLE_INFO_CHANGE);
|
||||
if (ret)
|
||||
rtw89_err(rtwdev, "failed to update cam del key: %d\n", ret);
|
||||
}
|
||||
@@ -276,7 +277,8 @@ static int __rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL,
|
||||
RTW89_ROLE_INFO_CHANGE);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to update addr cam sec entry: %d\n",
|
||||
ret);
|
||||
@@ -760,7 +762,8 @@ int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
|
||||
|
||||
int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_sta_link *rtwsta_link, u8 *cmd)
|
||||
struct rtw89_sta_link *rtwsta_link,
|
||||
struct rtw89_h2c_addr_cam_v0 *h2c)
|
||||
{
|
||||
struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif_link,
|
||||
rtwsta_link);
|
||||
@@ -780,20 +783,19 @@ int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev,
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
FWCMD_SET_ADDR_BSSID_IDX(cmd, bssid_cam->bssid_cam_idx);
|
||||
FWCMD_SET_ADDR_BSSID_OFFSET(cmd, bssid_cam->offset);
|
||||
FWCMD_SET_ADDR_BSSID_LEN(cmd, bssid_cam->len);
|
||||
FWCMD_SET_ADDR_BSSID_VALID(cmd, bssid_cam->valid);
|
||||
FWCMD_SET_ADDR_BSSID_MASK(cmd, bss_mask);
|
||||
FWCMD_SET_ADDR_BSSID_BB_SEL(cmd, bssid_cam->phy_idx);
|
||||
FWCMD_SET_ADDR_BSSID_BSS_COLOR(cmd, bss_color);
|
||||
|
||||
FWCMD_SET_ADDR_BSSID_BSSID0(cmd, bssid_cam->bssid[0]);
|
||||
FWCMD_SET_ADDR_BSSID_BSSID1(cmd, bssid_cam->bssid[1]);
|
||||
FWCMD_SET_ADDR_BSSID_BSSID2(cmd, bssid_cam->bssid[2]);
|
||||
FWCMD_SET_ADDR_BSSID_BSSID3(cmd, bssid_cam->bssid[3]);
|
||||
FWCMD_SET_ADDR_BSSID_BSSID4(cmd, bssid_cam->bssid[4]);
|
||||
FWCMD_SET_ADDR_BSSID_BSSID5(cmd, bssid_cam->bssid[5]);
|
||||
h2c->w12 = le32_encode_bits(bssid_cam->bssid_cam_idx, ADDR_CAM_W12_BSSID_IDX) |
|
||||
le32_encode_bits(bssid_cam->offset, ADDR_CAM_W12_BSSID_OFFSET) |
|
||||
le32_encode_bits(bssid_cam->len, ADDR_CAM_W12_BSSID_LEN);
|
||||
h2c->w13 = le32_encode_bits(bssid_cam->valid, ADDR_CAM_W13_BSSID_VALID) |
|
||||
le32_encode_bits(bss_mask, ADDR_CAM_W13_BSSID_MASK) |
|
||||
le32_encode_bits(bssid_cam->phy_idx, ADDR_CAM_W13_BSSID_BB_SEL) |
|
||||
le32_encode_bits(bss_color, ADDR_CAM_W13_BSSID_BSS_COLOR) |
|
||||
le32_encode_bits(bssid_cam->bssid[0], ADDR_CAM_W13_BSSID_BSSID0) |
|
||||
le32_encode_bits(bssid_cam->bssid[1], ADDR_CAM_W13_BSSID_BSSID1);
|
||||
h2c->w14 = le32_encode_bits(bssid_cam->bssid[2], ADDR_CAM_W14_BSSID_BSSID2) |
|
||||
le32_encode_bits(bssid_cam->bssid[3], ADDR_CAM_W14_BSSID_BSSID3) |
|
||||
le32_encode_bits(bssid_cam->bssid[4], ADDR_CAM_W14_BSSID_BSSID4) |
|
||||
le32_encode_bits(bssid_cam->bssid[5], ADDR_CAM_W14_BSSID_BSSID5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -813,18 +815,21 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_sta_link *rtwsta_link,
|
||||
const u8 *scan_mac_addr,
|
||||
u8 *cmd)
|
||||
struct rtw89_h2c_addr_cam_v0 *h2c)
|
||||
{
|
||||
struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
|
||||
struct rtw89_addr_cam_entry *addr_cam =
|
||||
rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
|
||||
struct ieee80211_sta *sta = rtwsta_link_to_sta_safe(rtwsta_link);
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
struct ieee80211_link_sta *link_sta;
|
||||
const u8 *sma = scan_mac_addr ? scan_mac_addr : rtwvif_link->mac_addr;
|
||||
u8 sma_hash, tma_hash, addr_msk_start;
|
||||
u8 ver = chip->addrcam_ver;
|
||||
u8 sma_start = 0;
|
||||
u8 tma_start = 0;
|
||||
const u8 *tma;
|
||||
u8 mac_id;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
@@ -845,69 +850,79 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
|
||||
sma_hash = rtw89_cam_addr_hash(sma_start, sma);
|
||||
tma_hash = rtw89_cam_addr_hash(tma_start, tma);
|
||||
|
||||
FWCMD_SET_ADDR_IDX(cmd, addr_cam->addr_cam_idx);
|
||||
FWCMD_SET_ADDR_OFFSET(cmd, addr_cam->offset);
|
||||
FWCMD_SET_ADDR_LEN(cmd, addr_cam->len);
|
||||
mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
|
||||
|
||||
FWCMD_SET_ADDR_VALID(cmd, addr_cam->valid);
|
||||
FWCMD_SET_ADDR_NET_TYPE(cmd, rtwvif_link->net_type);
|
||||
FWCMD_SET_ADDR_BCN_HIT_COND(cmd, rtwvif_link->bcn_hit_cond);
|
||||
FWCMD_SET_ADDR_HIT_RULE(cmd, rtwvif_link->hit_rule);
|
||||
FWCMD_SET_ADDR_BB_SEL(cmd, rtwvif_link->phy_idx);
|
||||
FWCMD_SET_ADDR_ADDR_MASK(cmd, addr_cam->addr_mask);
|
||||
FWCMD_SET_ADDR_MASK_SEL(cmd, addr_cam->mask_sel);
|
||||
FWCMD_SET_ADDR_SMA_HASH(cmd, sma_hash);
|
||||
FWCMD_SET_ADDR_TMA_HASH(cmd, tma_hash);
|
||||
if (ver == 0)
|
||||
h2c->w1 = le32_encode_bits(addr_cam->addr_cam_idx, ADDR_CAM_W1_IDX) |
|
||||
le32_encode_bits(addr_cam->offset, ADDR_CAM_W1_OFFSET) |
|
||||
le32_encode_bits(addr_cam->len, ADDR_CAM_W1_LEN);
|
||||
else
|
||||
h2c->w1 = le32_encode_bits(addr_cam->addr_cam_idx, ADDR_CAM_W1_V1_IDX) |
|
||||
le32_encode_bits(addr_cam->offset, ADDR_CAM_W1_V1_OFFSET) |
|
||||
le32_encode_bits(addr_cam->len, ADDR_CAM_W1_V1_LEN);
|
||||
|
||||
FWCMD_SET_ADDR_BSSID_CAM_IDX(cmd, addr_cam->bssid_cam_idx);
|
||||
h2c->w2 = le32_encode_bits(addr_cam->valid, ADDR_CAM_W2_VALID) |
|
||||
le32_encode_bits(rtwvif_link->net_type, ADDR_CAM_W2_NET_TYPE) |
|
||||
le32_encode_bits(rtwvif_link->bcn_hit_cond, ADDR_CAM_W2_BCN_HIT_COND) |
|
||||
le32_encode_bits(rtwvif_link->hit_rule, ADDR_CAM_W2_HIT_RULE) |
|
||||
le32_encode_bits(rtwvif_link->phy_idx, ADDR_CAM_W2_BB_SEL) |
|
||||
le32_encode_bits(addr_cam->addr_mask, ADDR_CAM_W2_ADDR_MASK) |
|
||||
le32_encode_bits(addr_cam->mask_sel, ADDR_CAM_W2_MASK_SEL) |
|
||||
le32_encode_bits(sma_hash, ADDR_CAM_W2_SMA_HASH) |
|
||||
le32_encode_bits(tma_hash, ADDR_CAM_W2_TMA_HASH);
|
||||
h2c->w3 = le32_encode_bits(addr_cam->bssid_cam_idx, ADDR_CAM_W3_BSSID_CAM_IDX);
|
||||
h2c->w4 = le32_encode_bits(sma[0], ADDR_CAM_W4_SMA0) |
|
||||
le32_encode_bits(sma[1], ADDR_CAM_W4_SMA1) |
|
||||
le32_encode_bits(sma[2], ADDR_CAM_W4_SMA2) |
|
||||
le32_encode_bits(sma[3], ADDR_CAM_W4_SMA3);
|
||||
h2c->w5 = le32_encode_bits(sma[4], ADDR_CAM_W5_SMA4) |
|
||||
le32_encode_bits(sma[5], ADDR_CAM_W5_SMA5) |
|
||||
le32_encode_bits(tma[0], ADDR_CAM_W5_TMA0) |
|
||||
le32_encode_bits(tma[1], ADDR_CAM_W5_TMA1);
|
||||
h2c->w6 = le32_encode_bits(tma[2], ADDR_CAM_W6_TMA2) |
|
||||
le32_encode_bits(tma[3], ADDR_CAM_W6_TMA3) |
|
||||
le32_encode_bits(tma[4], ADDR_CAM_W6_TMA4) |
|
||||
le32_encode_bits(tma[5], ADDR_CAM_W6_TMA5);
|
||||
if (ver == 0)
|
||||
h2c->w8 = le32_encode_bits(rtwvif_link->port, ADDR_CAM_W8_PORT_INT) |
|
||||
le32_encode_bits(rtwvif_link->port, ADDR_CAM_W8_TSF_SYNC) |
|
||||
le32_encode_bits(rtwvif_link->trigger, ADDR_CAM_W8_TF_TRS) |
|
||||
le32_encode_bits(rtwvif_link->lsig_txop, ADDR_CAM_W8_LSIG_TXOP) |
|
||||
le32_encode_bits(rtwvif_link->tgt_ind, ADDR_CAM_W8_TGT_IND) |
|
||||
le32_encode_bits(rtwvif_link->frm_tgt_ind, ADDR_CAM_W8_FRM_TGT_IND) |
|
||||
le32_encode_bits(mac_id, ADDR_CAM_W8_MACID);
|
||||
else
|
||||
h2c->w8 = le32_encode_bits(rtwvif_link->port, ADDR_CAM_W8_V1_PORT_INT) |
|
||||
le32_encode_bits(rtwvif_link->port, ADDR_CAM_W8_V1_TSF_SYNC) |
|
||||
le32_encode_bits(rtwvif_link->trigger, ADDR_CAM_W8_V1_TF_TRS) |
|
||||
le32_encode_bits(rtwvif_link->lsig_txop, ADDR_CAM_W8_V1_LSIG_TXOP) |
|
||||
le32_encode_bits(mac_id, ADDR_CAM_W8_V1_MACID);
|
||||
|
||||
FWCMD_SET_ADDR_SMA0(cmd, sma[0]);
|
||||
FWCMD_SET_ADDR_SMA1(cmd, sma[1]);
|
||||
FWCMD_SET_ADDR_SMA2(cmd, sma[2]);
|
||||
FWCMD_SET_ADDR_SMA3(cmd, sma[3]);
|
||||
FWCMD_SET_ADDR_SMA4(cmd, sma[4]);
|
||||
FWCMD_SET_ADDR_SMA5(cmd, sma[5]);
|
||||
|
||||
FWCMD_SET_ADDR_TMA0(cmd, tma[0]);
|
||||
FWCMD_SET_ADDR_TMA1(cmd, tma[1]);
|
||||
FWCMD_SET_ADDR_TMA2(cmd, tma[2]);
|
||||
FWCMD_SET_ADDR_TMA3(cmd, tma[3]);
|
||||
FWCMD_SET_ADDR_TMA4(cmd, tma[4]);
|
||||
FWCMD_SET_ADDR_TMA5(cmd, tma[5]);
|
||||
|
||||
FWCMD_SET_ADDR_PORT_INT(cmd, rtwvif_link->port);
|
||||
FWCMD_SET_ADDR_TSF_SYNC(cmd, rtwvif_link->port);
|
||||
FWCMD_SET_ADDR_TF_TRS(cmd, rtwvif_link->trigger);
|
||||
FWCMD_SET_ADDR_LSIG_TXOP(cmd, rtwvif_link->lsig_txop);
|
||||
FWCMD_SET_ADDR_TGT_IND(cmd, rtwvif_link->tgt_ind);
|
||||
FWCMD_SET_ADDR_FRM_TGT_IND(cmd, rtwvif_link->frm_tgt_ind);
|
||||
FWCMD_SET_ADDR_MACID(cmd, rtwsta_link ? rtwsta_link->mac_id :
|
||||
rtwvif_link->mac_id);
|
||||
if (rtwvif_link->net_type == RTW89_NET_TYPE_INFRA)
|
||||
FWCMD_SET_ADDR_AID12(cmd, vif->cfg.aid & 0xfff);
|
||||
h2c->w9 = le32_encode_bits(vif->cfg.aid & 0xfff, ADDR_CAM_W9_AID12);
|
||||
else if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
|
||||
FWCMD_SET_ADDR_AID12(cmd, sta ? sta->aid & 0xfff : 0);
|
||||
FWCMD_SET_ADDR_WOL_PATTERN(cmd, rtwvif_link->wowlan_pattern);
|
||||
FWCMD_SET_ADDR_WOL_UC(cmd, rtwvif_link->wowlan_uc);
|
||||
FWCMD_SET_ADDR_WOL_MAGIC(cmd, rtwvif_link->wowlan_magic);
|
||||
FWCMD_SET_ADDR_WAPI(cmd, addr_cam->wapi);
|
||||
FWCMD_SET_ADDR_SEC_ENT_MODE(cmd, addr_cam->sec_ent_mode);
|
||||
FWCMD_SET_ADDR_SEC_ENT0_KEYID(cmd, addr_cam->sec_ent_keyid[0]);
|
||||
FWCMD_SET_ADDR_SEC_ENT1_KEYID(cmd, addr_cam->sec_ent_keyid[1]);
|
||||
FWCMD_SET_ADDR_SEC_ENT2_KEYID(cmd, addr_cam->sec_ent_keyid[2]);
|
||||
FWCMD_SET_ADDR_SEC_ENT3_KEYID(cmd, addr_cam->sec_ent_keyid[3]);
|
||||
FWCMD_SET_ADDR_SEC_ENT4_KEYID(cmd, addr_cam->sec_ent_keyid[4]);
|
||||
FWCMD_SET_ADDR_SEC_ENT5_KEYID(cmd, addr_cam->sec_ent_keyid[5]);
|
||||
FWCMD_SET_ADDR_SEC_ENT6_KEYID(cmd, addr_cam->sec_ent_keyid[6]);
|
||||
h2c->w9 = le32_encode_bits(sta ? sta->aid & 0xfff : 0, ADDR_CAM_W9_AID12);
|
||||
|
||||
FWCMD_SET_ADDR_SEC_ENT_VALID(cmd, addr_cam->sec_cam_map[0] & 0xff);
|
||||
FWCMD_SET_ADDR_SEC_ENT0(cmd, addr_cam->sec_ent[0]);
|
||||
FWCMD_SET_ADDR_SEC_ENT1(cmd, addr_cam->sec_ent[1]);
|
||||
FWCMD_SET_ADDR_SEC_ENT2(cmd, addr_cam->sec_ent[2]);
|
||||
FWCMD_SET_ADDR_SEC_ENT3(cmd, addr_cam->sec_ent[3]);
|
||||
FWCMD_SET_ADDR_SEC_ENT4(cmd, addr_cam->sec_ent[4]);
|
||||
FWCMD_SET_ADDR_SEC_ENT5(cmd, addr_cam->sec_ent[5]);
|
||||
FWCMD_SET_ADDR_SEC_ENT6(cmd, addr_cam->sec_ent[6]);
|
||||
h2c->w9 |= le32_encode_bits(rtwvif_link->wowlan_pattern, ADDR_CAM_W9_WOL_PATTERN) |
|
||||
le32_encode_bits(rtwvif_link->wowlan_uc, ADDR_CAM_W9_WOL_UC) |
|
||||
le32_encode_bits(rtwvif_link->wowlan_magic, ADDR_CAM_W9_WOL_MAGIC) |
|
||||
le32_encode_bits(addr_cam->wapi, ADDR_CAM_W9_WAPI) |
|
||||
le32_encode_bits(addr_cam->sec_ent_mode, ADDR_CAM_W9_SEC_ENT_MODE) |
|
||||
le32_encode_bits(addr_cam->sec_ent_keyid[0], ADDR_CAM_W9_SEC_ENT0_KEYID) |
|
||||
le32_encode_bits(addr_cam->sec_ent_keyid[1], ADDR_CAM_W9_SEC_ENT1_KEYID) |
|
||||
le32_encode_bits(addr_cam->sec_ent_keyid[2], ADDR_CAM_W9_SEC_ENT2_KEYID) |
|
||||
le32_encode_bits(addr_cam->sec_ent_keyid[3], ADDR_CAM_W9_SEC_ENT3_KEYID) |
|
||||
le32_encode_bits(addr_cam->sec_ent_keyid[4], ADDR_CAM_W9_SEC_ENT4_KEYID) |
|
||||
le32_encode_bits(addr_cam->sec_ent_keyid[5], ADDR_CAM_W9_SEC_ENT5_KEYID) |
|
||||
le32_encode_bits(addr_cam->sec_ent_keyid[6], ADDR_CAM_W9_SEC_ENT6_KEYID);
|
||||
h2c->w10 = le32_encode_bits(addr_cam->sec_cam_map[0] & 0xff, ADDR_CAM_W10_SEC_ENT_VALID) |
|
||||
le32_encode_bits(addr_cam->sec_ent[0], ADDR_CAM_W10_SEC_ENT0) |
|
||||
le32_encode_bits(addr_cam->sec_ent[1], ADDR_CAM_W10_SEC_ENT1) |
|
||||
le32_encode_bits(addr_cam->sec_ent[2], ADDR_CAM_W10_SEC_ENT2);
|
||||
h2c->w11 = le32_encode_bits(addr_cam->sec_ent[3], ADDR_CAM_W11_SEC_ENT3) |
|
||||
le32_encode_bits(addr_cam->sec_ent[4], ADDR_CAM_W11_SEC_ENT4) |
|
||||
le32_encode_bits(addr_cam->sec_ent[5], ADDR_CAM_W11_SEC_ENT5) |
|
||||
le32_encode_bits(addr_cam->sec_ent[6], ADDR_CAM_W11_SEC_ENT6);
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
@@ -12,345 +12,109 @@
|
||||
#define RTW89_BSSID_MATCH_ALL GENMASK(5, 0)
|
||||
#define RTW89_BSSID_MATCH_5_BYTES GENMASK(4, 0)
|
||||
|
||||
static inline void FWCMD_SET_ADDR_IDX(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 1, value, GENMASK(7, 0));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_OFFSET(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 1, value, GENMASK(15, 8));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_LEN(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 1, value, GENMASK(23, 16));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_VALID(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 2, value, BIT(0));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_NET_TYPE(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(2, 1));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_BCN_HIT_COND(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(4, 3));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_HIT_RULE(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(6, 5));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_BB_SEL(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 2, value, BIT(7));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_ADDR_MASK(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(13, 8));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_MASK_SEL(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(15, 14));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SMA_HASH(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(23, 16));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_TMA_HASH(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(31, 24));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_BSSID_CAM_IDX(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 3, value, GENMASK(5, 0));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SMA0(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 4, value, GENMASK(7, 0));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SMA1(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 4, value, GENMASK(15, 8));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SMA2(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 4, value, GENMASK(23, 16));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SMA3(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 4, value, GENMASK(31, 24));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SMA4(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 5, value, GENMASK(7, 0));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SMA5(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 5, value, GENMASK(15, 8));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_TMA0(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 5, value, GENMASK(23, 16));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_TMA1(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 5, value, GENMASK(31, 24));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_TMA2(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 6, value, GENMASK(7, 0));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_TMA3(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 6, value, GENMASK(15, 8));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_TMA4(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 6, value, GENMASK(23, 16));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_TMA5(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 6, value, GENMASK(31, 24));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_MACID(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 8, value, GENMASK(7, 0));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_PORT_INT(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 8, value, GENMASK(10, 8));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_TSF_SYNC(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 8, value, GENMASK(13, 11));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_TF_TRS(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 8, value, BIT(14));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_LSIG_TXOP(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 8, value, BIT(15));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_TGT_IND(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 8, value, GENMASK(26, 24));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_FRM_TGT_IND(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 8, value, GENMASK(29, 27));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_AID12(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(11, 0));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_AID12_0(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(7, 0));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_AID12_1(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(11, 8));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_WOL_PATTERN(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, BIT(12));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_WOL_UC(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, BIT(13));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_WOL_MAGIC(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, BIT(14));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_WAPI(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, BIT(15));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SEC_ENT_MODE(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(17, 16));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SEC_ENT0_KEYID(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(19, 18));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SEC_ENT1_KEYID(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(21, 20));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SEC_ENT2_KEYID(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(23, 22));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SEC_ENT3_KEYID(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(25, 24));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SEC_ENT4_KEYID(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(27, 26));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SEC_ENT5_KEYID(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(29, 28));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SEC_ENT6_KEYID(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(31, 30));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SEC_ENT_VALID(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 10, value, GENMASK(7, 0));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SEC_ENT0(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 10, value, GENMASK(15, 8));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SEC_ENT1(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 10, value, GENMASK(23, 16));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SEC_ENT2(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 10, value, GENMASK(31, 24));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SEC_ENT3(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 11, value, GENMASK(7, 0));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SEC_ENT4(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 11, value, GENMASK(15, 8));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SEC_ENT5(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 11, value, GENMASK(23, 16));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_SEC_ENT6(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 11, value, GENMASK(31, 24));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_BSSID_IDX(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 12, value, GENMASK(7, 0));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_BSSID_OFFSET(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 12, value, GENMASK(15, 8));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_BSSID_LEN(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 12, value, GENMASK(23, 16));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_BSSID_VALID(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 13, value, BIT(0));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_BSSID_BB_SEL(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 13, value, BIT(1));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_BSSID_MASK(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 13, value, GENMASK(7, 2));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_BSSID_BSS_COLOR(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 13, value, GENMASK(13, 8));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_BSSID_BSSID0(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 13, value, GENMASK(23, 16));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_BSSID_BSSID1(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 13, value, GENMASK(31, 24));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_BSSID_BSSID2(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 14, value, GENMASK(7, 0));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_BSSID_BSSID3(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 14, value, GENMASK(15, 8));
|
||||
}
|
||||
|
||||
static inline void FWCMD_SET_ADDR_BSSID_BSSID4(void *cmd, u32 value)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(cmd) + 14, value, GENMASK(23, 16));
|
||||
}
|
||||
|
||||
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_addr_cam_v0 {
|
||||
__le32 w0;
|
||||
__le32 w1;
|
||||
__le32 w2;
|
||||
__le32 w3;
|
||||
__le32 w4;
|
||||
__le32 w5;
|
||||
__le32 w6;
|
||||
__le32 w7;
|
||||
__le32 w8;
|
||||
__le32 w9;
|
||||
__le32 w10;
|
||||
__le32 w11;
|
||||
__le32 w12;
|
||||
__le32 w13;
|
||||
__le32 w14;
|
||||
} __packed;
|
||||
|
||||
struct rtw89_h2c_addr_cam {
|
||||
struct rtw89_h2c_addr_cam_v0 v0;
|
||||
__le32 w15;
|
||||
} __packed;
|
||||
|
||||
#define ADDR_CAM_W1_IDX GENMASK(7, 0)
|
||||
#define ADDR_CAM_W1_OFFSET GENMASK(15, 8)
|
||||
#define ADDR_CAM_W1_LEN GENMASK(23, 16)
|
||||
#define ADDR_CAM_W1_V1_IDX GENMASK(9, 0)
|
||||
#define ADDR_CAM_W1_V1_OFFSET GENMASK(23, 16)
|
||||
#define ADDR_CAM_W1_V1_LEN GENMASK(31, 24)
|
||||
#define ADDR_CAM_W2_VALID BIT(0)
|
||||
#define ADDR_CAM_W2_NET_TYPE GENMASK(2, 1)
|
||||
#define ADDR_CAM_W2_BCN_HIT_COND GENMASK(4, 3)
|
||||
#define ADDR_CAM_W2_HIT_RULE GENMASK(6, 5)
|
||||
#define ADDR_CAM_W2_BB_SEL BIT(7)
|
||||
#define ADDR_CAM_W2_ADDR_MASK GENMASK(13, 8)
|
||||
#define ADDR_CAM_W2_MASK_SEL GENMASK(15, 14)
|
||||
#define ADDR_CAM_W2_SMA_HASH GENMASK(23, 16)
|
||||
#define ADDR_CAM_W2_TMA_HASH GENMASK(31, 24)
|
||||
#define ADDR_CAM_W3_BSSID_CAM_IDX GENMASK(5, 0)
|
||||
#define ADDR_CAM_W4_SMA0 GENMASK(7, 0)
|
||||
#define ADDR_CAM_W4_SMA1 GENMASK(15, 8)
|
||||
#define ADDR_CAM_W4_SMA2 GENMASK(23, 16)
|
||||
#define ADDR_CAM_W4_SMA3 GENMASK(31, 24)
|
||||
#define ADDR_CAM_W5_SMA4 GENMASK(7, 0)
|
||||
#define ADDR_CAM_W5_SMA5 GENMASK(15, 8)
|
||||
#define ADDR_CAM_W5_TMA0 GENMASK(23, 16)
|
||||
#define ADDR_CAM_W5_TMA1 GENMASK(31, 24)
|
||||
#define ADDR_CAM_W6_TMA2 GENMASK(7, 0)
|
||||
#define ADDR_CAM_W6_TMA3 GENMASK(15, 8)
|
||||
#define ADDR_CAM_W6_TMA4 GENMASK(23, 16)
|
||||
#define ADDR_CAM_W6_TMA5 GENMASK(31, 24)
|
||||
#define ADDR_CAM_W8_MACID GENMASK(7, 0)
|
||||
#define ADDR_CAM_W8_PORT_INT GENMASK(10, 8)
|
||||
#define ADDR_CAM_W8_TSF_SYNC GENMASK(13, 11)
|
||||
#define ADDR_CAM_W8_TF_TRS BIT(14)
|
||||
#define ADDR_CAM_W8_LSIG_TXOP BIT(15)
|
||||
#define ADDR_CAM_W8_TGT_IND GENMASK(26, 24)
|
||||
#define ADDR_CAM_W8_FRM_TGT_IND GENMASK(29, 27)
|
||||
#define ADDR_CAM_W8_V1_MACID GENMASK(9, 0)
|
||||
#define ADDR_CAM_W8_V1_PORT_INT GENMASK(18, 16)
|
||||
#define ADDR_CAM_W8_V1_TSF_SYNC GENMASK(21, 19)
|
||||
#define ADDR_CAM_W8_V1_TF_TRS BIT(22)
|
||||
#define ADDR_CAM_W8_V1_LSIG_TXOP BIT(23)
|
||||
#define ADDR_CAM_W8_V1_TB_RANGING BIT(24)
|
||||
#define ADDR_CAM_W8_V1_TB_SENSING BIT(25)
|
||||
#define ADDR_CAM_W8_V1_SENS_EN BIT(26)
|
||||
#define ADDR_CAM_W9_AID12 GENMASK(11, 0)
|
||||
#define ADDR_CAM_W9_AID12_0 GENMASK(7, 0)
|
||||
#define ADDR_CAM_W9_AID12_1 GENMASK(11, 8)
|
||||
#define ADDR_CAM_W9_WOL_PATTERN BIT(12)
|
||||
#define ADDR_CAM_W9_WOL_UC BIT(13)
|
||||
#define ADDR_CAM_W9_WOL_MAGIC BIT(14)
|
||||
#define ADDR_CAM_W9_WAPI BIT(15)
|
||||
#define ADDR_CAM_W9_SEC_ENT_MODE GENMASK(17, 16)
|
||||
#define ADDR_CAM_W9_SEC_ENT0_KEYID GENMASK(19, 18)
|
||||
#define ADDR_CAM_W9_SEC_ENT1_KEYID GENMASK(21, 20)
|
||||
#define ADDR_CAM_W9_SEC_ENT2_KEYID GENMASK(23, 22)
|
||||
#define ADDR_CAM_W9_SEC_ENT3_KEYID GENMASK(25, 24)
|
||||
#define ADDR_CAM_W9_SEC_ENT4_KEYID GENMASK(27, 26)
|
||||
#define ADDR_CAM_W9_SEC_ENT5_KEYID GENMASK(29, 28)
|
||||
#define ADDR_CAM_W9_SEC_ENT6_KEYID GENMASK(31, 30)
|
||||
#define ADDR_CAM_W10_SEC_ENT_VALID GENMASK(7, 0)
|
||||
#define ADDR_CAM_W10_SEC_ENT0 GENMASK(15, 8)
|
||||
#define ADDR_CAM_W10_SEC_ENT1 GENMASK(23, 16)
|
||||
#define ADDR_CAM_W10_SEC_ENT2 GENMASK(31, 24)
|
||||
#define ADDR_CAM_W11_SEC_ENT3 GENMASK(7, 0)
|
||||
#define ADDR_CAM_W11_SEC_ENT4 GENMASK(15, 8)
|
||||
#define ADDR_CAM_W11_SEC_ENT5 GENMASK(23, 16)
|
||||
#define ADDR_CAM_W11_SEC_ENT6 GENMASK(31, 24)
|
||||
#define ADDR_CAM_W12_BSSID_IDX GENMASK(7, 0)
|
||||
#define ADDR_CAM_W12_BSSID_OFFSET GENMASK(15, 8)
|
||||
#define ADDR_CAM_W12_BSSID_LEN GENMASK(23, 16)
|
||||
#define ADDR_CAM_W13_BSSID_VALID BIT(0)
|
||||
#define ADDR_CAM_W13_BSSID_BB_SEL BIT(1)
|
||||
#define ADDR_CAM_W13_BSSID_MASK GENMASK(7, 2)
|
||||
#define ADDR_CAM_W13_BSSID_BSS_COLOR GENMASK(13, 8)
|
||||
#define ADDR_CAM_W13_BSSID_BSSID0 GENMASK(23, 16)
|
||||
#define ADDR_CAM_W13_BSSID_BSSID1 GENMASK(31, 24)
|
||||
#define ADDR_CAM_W14_BSSID_BSSID2 GENMASK(7, 0)
|
||||
#define ADDR_CAM_W14_BSSID_BSSID3 GENMASK(15, 8)
|
||||
#define ADDR_CAM_W14_BSSID_BSSID4 GENMASK(23, 16)
|
||||
#define ADDR_CAM_W14_BSSID_BSSID5 GENMASK(31, 24)
|
||||
#define ADDR_CAM_W15_UPD_MODE GENMASK(2, 0)
|
||||
|
||||
struct rtw89_h2c_dctlinfo_ud_v1 {
|
||||
__le32 c0;
|
||||
@@ -552,9 +316,10 @@ int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
|
||||
void rtw89_cam_deinit_bssid_cam(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_bssid_cam_entry *bssid_cam);
|
||||
void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif_link *vif,
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_sta_link *rtwsta_link,
|
||||
const u8 *scan_mac_addr, u8 *cmd);
|
||||
const u8 *scan_mac_addr,
|
||||
struct rtw89_h2c_addr_cam_v0 *h2c);
|
||||
void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_sta_link *rtwsta_link,
|
||||
@@ -565,7 +330,8 @@ void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_h2c_dctlinfo_ud_v2 *h2c);
|
||||
int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_sta_link *rtwsta_link, u8 *cmd);
|
||||
struct rtw89_sta_link *rtwsta_link,
|
||||
struct rtw89_h2c_addr_cam_v0 *h2c);
|
||||
int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
|
||||
@@ -321,6 +321,26 @@ static const struct ieee80211_supported_band rtw89_sband_6ghz = {
|
||||
.n_bitrates = ARRAY_SIZE(rtw89_bitrates) - 4,
|
||||
};
|
||||
|
||||
static const struct rtw89_hw_rate_def {
|
||||
enum rtw89_hw_rate ht;
|
||||
enum rtw89_hw_rate vht[RTW89_NSS_NUM];
|
||||
} rtw89_hw_rate[RTW89_CHIP_GEN_NUM] = {
|
||||
[RTW89_CHIP_AX] = {
|
||||
.ht = RTW89_HW_RATE_MCS0,
|
||||
.vht = {RTW89_HW_RATE_VHT_NSS1_MCS0,
|
||||
RTW89_HW_RATE_VHT_NSS2_MCS0,
|
||||
RTW89_HW_RATE_VHT_NSS3_MCS0,
|
||||
RTW89_HW_RATE_VHT_NSS4_MCS0},
|
||||
},
|
||||
[RTW89_CHIP_BE] = {
|
||||
.ht = RTW89_HW_RATE_V1_MCS0,
|
||||
.vht = {RTW89_HW_RATE_V1_VHT_NSS1_MCS0,
|
||||
RTW89_HW_RATE_V1_VHT_NSS2_MCS0,
|
||||
RTW89_HW_RATE_V1_VHT_NSS3_MCS0,
|
||||
RTW89_HW_RATE_V1_VHT_NSS4_MCS0},
|
||||
},
|
||||
};
|
||||
|
||||
static void __rtw89_traffic_stats_accu(struct rtw89_traffic_stats *stats,
|
||||
struct sk_buff *skb, bool tx)
|
||||
{
|
||||
@@ -450,6 +470,22 @@ void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)
|
||||
__rtw89_core_set_chip_txpwr(rtwdev, chan, RTW89_PHY_1);
|
||||
}
|
||||
|
||||
static void rtw89_chip_rfk_channel_for_pure_mon_vif(struct rtw89_dev *rtwdev,
|
||||
enum rtw89_phy_idx phy_idx)
|
||||
{
|
||||
struct rtw89_vif *rtwvif = rtwdev->pure_monitor_mode_vif;
|
||||
struct rtw89_vif_link *rtwvif_link;
|
||||
|
||||
if (!rtwvif)
|
||||
return;
|
||||
|
||||
rtwvif_link = rtw89_vif_get_link_inst(rtwvif, phy_idx);
|
||||
if (!rtwvif_link)
|
||||
return;
|
||||
|
||||
rtw89_chip_rfk_channel(rtwdev, rtwvif_link);
|
||||
}
|
||||
|
||||
static void __rtw89_set_channel(struct rtw89_dev *rtwdev,
|
||||
const struct rtw89_chan *chan,
|
||||
enum rtw89_mac_idx mac_idx,
|
||||
@@ -478,6 +514,8 @@ static void __rtw89_set_channel(struct rtw89_dev *rtwdev,
|
||||
}
|
||||
|
||||
rtw89_set_entity_state(rtwdev, phy_idx, true);
|
||||
|
||||
rtw89_chip_rfk_channel_for_pure_mon_vif(rtwdev, phy_idx);
|
||||
}
|
||||
|
||||
int rtw89_set_channel(struct rtw89_dev *rtwdev)
|
||||
@@ -759,6 +797,25 @@ u8 rtw89_core_get_ch_dma_v1(struct rtw89_dev *rtwdev, u8 qsel)
|
||||
}
|
||||
EXPORT_SYMBOL(rtw89_core_get_ch_dma_v1);
|
||||
|
||||
u8 rtw89_core_get_ch_dma_v2(struct rtw89_dev *rtwdev, u8 qsel)
|
||||
{
|
||||
switch (qsel) {
|
||||
default:
|
||||
rtw89_warn(rtwdev, "Cannot map qsel to dma v2: %d\n", qsel);
|
||||
fallthrough;
|
||||
case RTW89_TX_QSEL_BE_0:
|
||||
case RTW89_TX_QSEL_VO_0:
|
||||
return RTW89_TXCH_ACH0;
|
||||
case RTW89_TX_QSEL_BK_0:
|
||||
case RTW89_TX_QSEL_VI_0:
|
||||
return RTW89_TXCH_ACH2;
|
||||
case RTW89_TX_QSEL_B0_MGMT:
|
||||
case RTW89_TX_QSEL_B0_HI:
|
||||
return RTW89_TXCH_CH8;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(rtw89_core_get_ch_dma_v2);
|
||||
|
||||
static void
|
||||
rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_core_tx_request *tx_req)
|
||||
@@ -1078,6 +1135,44 @@ notify:
|
||||
rtw89_mac_notify_wake(rtwdev);
|
||||
}
|
||||
|
||||
static void rtw89_core_tx_update_injection(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_core_tx_request *tx_req,
|
||||
struct ieee80211_tx_info *info)
|
||||
{
|
||||
const struct rtw89_hw_rate_def *hw_rate = &rtw89_hw_rate[rtwdev->chip->chip_gen];
|
||||
enum mac80211_rate_control_flags flags = info->control.rates[0].flags;
|
||||
struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
|
||||
const struct rtw89_chan *chan;
|
||||
u8 idx = info->control.rates[0].idx;
|
||||
u8 nss, mcs;
|
||||
|
||||
desc_info->use_rate = true;
|
||||
desc_info->dis_data_fb = true;
|
||||
|
||||
if (flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
|
||||
desc_info->data_bw = 3;
|
||||
else if (flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
|
||||
desc_info->data_bw = 2;
|
||||
else if (flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
||||
desc_info->data_bw = 1;
|
||||
|
||||
if (flags & IEEE80211_TX_RC_SHORT_GI)
|
||||
desc_info->gi_ltf = 1;
|
||||
|
||||
if (flags & IEEE80211_TX_RC_VHT_MCS) {
|
||||
nss = umin(idx >> 4, ARRAY_SIZE(hw_rate->vht) - 1);
|
||||
mcs = idx & 0xf;
|
||||
desc_info->data_rate = hw_rate->vht[nss] + mcs;
|
||||
} else if (flags & IEEE80211_TX_RC_MCS) {
|
||||
desc_info->data_rate = hw_rate->ht + idx;
|
||||
} else {
|
||||
chan = rtw89_chan_get(rtwdev, tx_req->rtwvif_link->chanctx_idx);
|
||||
|
||||
desc_info->data_rate = idx + (chan->band_type == RTW89_BAND_2G ?
|
||||
RTW89_HW_RATE_CCK1 : RTW89_HW_RATE_OFDM6);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_core_tx_request *tx_req)
|
||||
@@ -1087,32 +1182,38 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
struct rtw89_addr_cam_entry *addr_cam;
|
||||
enum rtw89_core_tx_type tx_type;
|
||||
enum btc_pkt_type pkt_type;
|
||||
bool upd_wlan_hdr = false;
|
||||
bool is_bmc;
|
||||
u16 seq;
|
||||
|
||||
desc_info->pkt_size = skb->len;
|
||||
|
||||
if (unlikely(tx_req->tx_type == RTW89_CORE_TX_TYPE_FWCMD)) {
|
||||
rtw89_core_tx_update_h2c_info(rtwdev, tx_req);
|
||||
return;
|
||||
}
|
||||
|
||||
tx_req->tx_type = rtw89_core_get_tx_type(rtwdev, skb);
|
||||
|
||||
if (tx_req->sta)
|
||||
desc_info->mlo = tx_req->sta->mlo;
|
||||
else if (tx_req->vif)
|
||||
desc_info->mlo = ieee80211_vif_is_mld(tx_req->vif);
|
||||
|
||||
seq = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
|
||||
if (tx_req->tx_type != RTW89_CORE_TX_TYPE_FWCMD) {
|
||||
tx_type = rtw89_core_get_tx_type(rtwdev, skb);
|
||||
tx_req->tx_type = tx_type;
|
||||
addr_cam = rtw89_get_addr_cam_of(tx_req->rtwvif_link,
|
||||
tx_req->rtwsta_link);
|
||||
if (addr_cam->valid && desc_info->mlo)
|
||||
upd_wlan_hdr = true;
|
||||
|
||||
if (rtw89_is_tx_rpt_skb(rtwdev, tx_req->skb))
|
||||
rtw89_tx_rpt_init(rtwdev, tx_req);
|
||||
|
||||
addr_cam = rtw89_get_addr_cam_of(tx_req->rtwvif_link,
|
||||
tx_req->rtwsta_link);
|
||||
if (addr_cam->valid && desc_info->mlo)
|
||||
upd_wlan_hdr = true;
|
||||
}
|
||||
is_bmc = (is_broadcast_ether_addr(hdr->addr1) ||
|
||||
is_multicast_ether_addr(hdr->addr1));
|
||||
|
||||
desc_info->seq = seq;
|
||||
desc_info->pkt_size = skb->len;
|
||||
desc_info->is_bmc = is_bmc;
|
||||
desc_info->wd_page = true;
|
||||
desc_info->hiq = info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM;
|
||||
@@ -1129,10 +1230,12 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev,
|
||||
rtw89_core_tx_update_ampdu_info(rtwdev, tx_req, pkt_type);
|
||||
rtw89_core_tx_update_llc_hdr(rtwdev, desc_info, skb);
|
||||
break;
|
||||
case RTW89_CORE_TX_TYPE_FWCMD:
|
||||
rtw89_core_tx_update_h2c_info(rtwdev, tx_req);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED))
|
||||
rtw89_core_tx_update_injection(rtwdev, tx_req, info);
|
||||
}
|
||||
|
||||
static void rtw89_tx_wait_work(struct wiphy *wiphy, struct wiphy_work *work)
|
||||
@@ -1239,14 +1342,13 @@ static int rtw89_core_tx_write_link(struct rtw89_dev *rtwdev,
|
||||
tx_req.rtwvif_link = rtwvif_link;
|
||||
tx_req.rtwsta_link = rtwsta_link;
|
||||
tx_req.desc_info.sw_mld = sw_mld;
|
||||
rcu_assign_pointer(skb_data->wait, wait);
|
||||
|
||||
rtw89_traffic_stats_accu(rtwdev, rtwvif, skb, true, true);
|
||||
rtw89_wow_parse_akm(rtwdev, skb);
|
||||
rtw89_core_tx_update_desc_info(rtwdev, &tx_req);
|
||||
rtw89_core_tx_wake(rtwdev, &tx_req);
|
||||
|
||||
rcu_assign_pointer(skb_data->wait, wait);
|
||||
|
||||
ret = rtw89_hci_tx_write(rtwdev, &tx_req);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to transmit skb to HCI\n");
|
||||
@@ -1362,6 +1464,8 @@ static __le32 rtw89_build_txwd_body5(struct rtw89_tx_desc_info *desc_info)
|
||||
static __le32 rtw89_build_txwd_body7_v1(struct rtw89_tx_desc_info *desc_info)
|
||||
{
|
||||
u32 dword = FIELD_PREP(RTW89_TXWD_BODY7_USE_RATE_V1, desc_info->use_rate) |
|
||||
FIELD_PREP(RTW89_TXWD_BODY7_DATA_BW, desc_info->data_bw) |
|
||||
FIELD_PREP(RTW89_TXWD_BODY7_GI_LTF, desc_info->gi_ltf) |
|
||||
FIELD_PREP(RTW89_TXWD_BODY7_DATA_RATE, desc_info->data_rate);
|
||||
|
||||
return cpu_to_le32(dword);
|
||||
@@ -1370,6 +1474,8 @@ static __le32 rtw89_build_txwd_body7_v1(struct rtw89_tx_desc_info *desc_info)
|
||||
static __le32 rtw89_build_txwd_info0(struct rtw89_tx_desc_info *desc_info)
|
||||
{
|
||||
u32 dword = FIELD_PREP(RTW89_TXWD_INFO0_USE_RATE, desc_info->use_rate) |
|
||||
FIELD_PREP(RTW89_TXWD_INFO0_DATA_BW, desc_info->data_bw) |
|
||||
FIELD_PREP(RTW89_TXWD_INFO0_GI_LTF, desc_info->gi_ltf) |
|
||||
FIELD_PREP(RTW89_TXWD_INFO0_DATA_RATE, desc_info->data_rate) |
|
||||
FIELD_PREP(RTW89_TXWD_INFO0_DATA_STBC, desc_info->stbc) |
|
||||
FIELD_PREP(RTW89_TXWD_INFO0_DATA_LDPC, desc_info->ldpc) |
|
||||
@@ -1396,7 +1502,10 @@ static __le32 rtw89_build_txwd_info1(struct rtw89_tx_desc_info *desc_info)
|
||||
u32 dword = FIELD_PREP(RTW89_TXWD_INFO1_MAX_AGGNUM, desc_info->ampdu_num) |
|
||||
FIELD_PREP(RTW89_TXWD_INFO1_A_CTRL_BSR, desc_info->a_ctrl_bsr) |
|
||||
FIELD_PREP(RTW89_TXWD_INFO1_DATA_RTY_LOWEST_RATE,
|
||||
desc_info->data_retry_lowest_rate);
|
||||
desc_info->data_retry_lowest_rate) |
|
||||
FIELD_PREP(RTW89_TXWD_INFO1_DATA_TXCNT_LMT_SEL,
|
||||
desc_info->tx_cnt_lmt_en) |
|
||||
FIELD_PREP(RTW89_TXWD_INFO1_DATA_TXCNT_LMT, desc_info->tx_cnt_lmt);
|
||||
|
||||
return cpu_to_le32(dword);
|
||||
}
|
||||
@@ -1420,11 +1529,19 @@ static __le32 rtw89_build_txwd_info2_v1(struct rtw89_tx_desc_info *desc_info)
|
||||
return cpu_to_le32(dword);
|
||||
}
|
||||
|
||||
static __le32 rtw89_build_txwd_info3(struct rtw89_tx_desc_info *desc_info)
|
||||
{
|
||||
u32 dword = FIELD_PREP(RTW89_TXWD_INFO3_SPE_RPT, desc_info->report);
|
||||
|
||||
return cpu_to_le32(dword);
|
||||
}
|
||||
|
||||
static __le32 rtw89_build_txwd_info4(struct rtw89_tx_desc_info *desc_info)
|
||||
{
|
||||
bool rts_en = !desc_info->is_bmc;
|
||||
u32 dword = FIELD_PREP(RTW89_TXWD_INFO4_RTS_EN, rts_en) |
|
||||
FIELD_PREP(RTW89_TXWD_INFO4_HW_RTS_EN, 1);
|
||||
FIELD_PREP(RTW89_TXWD_INFO4_HW_RTS_EN, 1) |
|
||||
FIELD_PREP(RTW89_TXWD_INFO4_SW_DEFINE, desc_info->sn);
|
||||
|
||||
return cpu_to_le32(dword);
|
||||
}
|
||||
@@ -1447,6 +1564,7 @@ void rtw89_core_fill_txdesc(struct rtw89_dev *rtwdev,
|
||||
txwd_info->dword0 = rtw89_build_txwd_info0(desc_info);
|
||||
txwd_info->dword1 = rtw89_build_txwd_info1(desc_info);
|
||||
txwd_info->dword2 = rtw89_build_txwd_info2(desc_info);
|
||||
txwd_info->dword3 = rtw89_build_txwd_info3(desc_info);
|
||||
txwd_info->dword4 = rtw89_build_txwd_info4(desc_info);
|
||||
|
||||
}
|
||||
@@ -1476,6 +1594,7 @@ void rtw89_core_fill_txdesc_v1(struct rtw89_dev *rtwdev,
|
||||
txwd_info->dword0 = rtw89_build_txwd_info0_v1(desc_info);
|
||||
txwd_info->dword1 = rtw89_build_txwd_info1(desc_info);
|
||||
txwd_info->dword2 = rtw89_build_txwd_info2_v1(desc_info);
|
||||
txwd_info->dword3 = rtw89_build_txwd_info3(desc_info);
|
||||
txwd_info->dword4 = rtw89_build_txwd_info4(desc_info);
|
||||
}
|
||||
EXPORT_SYMBOL(rtw89_core_fill_txdesc_v1);
|
||||
@@ -1549,6 +1668,8 @@ static __le32 rtw89_build_txwd_body6_v2(struct rtw89_tx_desc_info *desc_info)
|
||||
static __le32 rtw89_build_txwd_body7_v2(struct rtw89_tx_desc_info *desc_info)
|
||||
{
|
||||
u32 dword = FIELD_PREP(BE_TXD_BODY7_USERATE_SEL, desc_info->use_rate) |
|
||||
FIELD_PREP(BE_TXD_BODY7_DATA_BW, desc_info->data_bw) |
|
||||
FIELD_PREP(BE_TXD_BODY7_GI_LTF, desc_info->gi_ltf) |
|
||||
FIELD_PREP(BE_TXD_BODY7_DATA_ER, desc_info->er_cap) |
|
||||
FIELD_PREP(BE_TXD_BODY7_DATA_BW_ER, 0) |
|
||||
FIELD_PREP(BE_TXD_BODY7_DATARATE, desc_info->data_rate);
|
||||
@@ -1561,7 +1682,10 @@ static __le32 rtw89_build_txwd_info0_v2(struct rtw89_tx_desc_info *desc_info)
|
||||
u32 dword = FIELD_PREP(BE_TXD_INFO0_DATA_STBC, desc_info->stbc) |
|
||||
FIELD_PREP(BE_TXD_INFO0_DATA_LDPC, desc_info->ldpc) |
|
||||
FIELD_PREP(BE_TXD_INFO0_DISDATAFB, desc_info->dis_data_fb) |
|
||||
FIELD_PREP(BE_TXD_INFO0_MULTIPORT_ID, desc_info->port);
|
||||
FIELD_PREP(BE_TXD_INFO0_MULTIPORT_ID, desc_info->port) |
|
||||
FIELD_PREP(BE_TXD_INFO0_DATA_TXCNT_LMT_SEL,
|
||||
desc_info->tx_cnt_lmt_en) |
|
||||
FIELD_PREP(BE_TXD_INFO0_DATA_TXCNT_LMT, desc_info->tx_cnt_lmt);
|
||||
|
||||
return cpu_to_le32(dword);
|
||||
}
|
||||
@@ -1571,7 +1695,8 @@ static __le32 rtw89_build_txwd_info1_v2(struct rtw89_tx_desc_info *desc_info)
|
||||
u32 dword = FIELD_PREP(BE_TXD_INFO1_MAX_AGG_NUM, desc_info->ampdu_num) |
|
||||
FIELD_PREP(BE_TXD_INFO1_A_CTRL_BSR, desc_info->a_ctrl_bsr) |
|
||||
FIELD_PREP(BE_TXD_INFO1_DATA_RTY_LOWEST_RATE,
|
||||
desc_info->data_retry_lowest_rate);
|
||||
desc_info->data_retry_lowest_rate) |
|
||||
FIELD_PREP(BE_TXD_INFO1_SW_DEFINE, desc_info->sn);
|
||||
|
||||
return cpu_to_le32(dword);
|
||||
}
|
||||
@@ -1580,7 +1705,8 @@ static __le32 rtw89_build_txwd_info2_v2(struct rtw89_tx_desc_info *desc_info)
|
||||
{
|
||||
u32 dword = FIELD_PREP(BE_TXD_INFO2_AMPDU_DENSITY, desc_info->ampdu_density) |
|
||||
FIELD_PREP(BE_TXD_INFO2_FORCE_KEY_EN, desc_info->sec_en) |
|
||||
FIELD_PREP(BE_TXD_INFO2_SEC_CAM_IDX, desc_info->sec_cam_idx);
|
||||
FIELD_PREP(BE_TXD_INFO2_SEC_CAM_IDX, desc_info->sec_cam_idx) |
|
||||
FIELD_PREP(BE_TXD_INFO2_SPE_RPT_V1, desc_info->report);
|
||||
|
||||
return cpu_to_le32(dword);
|
||||
}
|
||||
@@ -1708,9 +1834,13 @@ static int rtw89_core_rx_process_mac_ppdu(struct rtw89_dev *rtwdev,
|
||||
/* For WiFi 7 chips, RXWD.mac_id of PPDU status is not set
|
||||
* by hardware, so update mac_id by rxinfo_user[].mac_id.
|
||||
*/
|
||||
if (chip_gen == RTW89_CHIP_BE)
|
||||
if (chip->chip_id == RTL8922A)
|
||||
phy_ppdu->mac_id =
|
||||
le32_get_bits(user->w0, RTW89_RXINFO_USER_MACID);
|
||||
else if (chip->chip_id == RTL8922D)
|
||||
phy_ppdu->mac_id =
|
||||
le32_get_bits(user->w0, RTW89_RXINFO_USER_MACID_V1);
|
||||
|
||||
phy_ppdu->has_data =
|
||||
le32_get_bits(user->w0, RTW89_RXINFO_USER_DATA);
|
||||
phy_ppdu->has_bcn =
|
||||
@@ -3632,12 +3762,10 @@ void rtw89_core_free_sta_pending_roc_tx(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
|
||||
struct sk_buff *skb, *tmp;
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb_queue_walk_safe(&rtwsta->roc_queue, skb, tmp) {
|
||||
skb_unlink(skb, &rtwsta->roc_queue);
|
||||
while ((skb = skb_dequeue(&rtwsta->roc_queue)))
|
||||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
}
|
||||
|
||||
static void rtw89_core_stop_tx_ba_session(struct rtw89_dev *rtwdev,
|
||||
@@ -3881,8 +4009,8 @@ static void rtw89_core_sta_pending_tx_iter(void *data,
|
||||
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
|
||||
struct rtw89_vif_link *target = data;
|
||||
struct rtw89_vif_link *rtwvif_link;
|
||||
struct sk_buff *skb, *tmp;
|
||||
unsigned int link_id;
|
||||
struct sk_buff *skb;
|
||||
int qsel, ret;
|
||||
|
||||
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
|
||||
@@ -3895,9 +4023,7 @@ bottom:
|
||||
if (skb_queue_len(&rtwsta->roc_queue) == 0)
|
||||
return;
|
||||
|
||||
skb_queue_walk_safe(&rtwsta->roc_queue, skb, tmp) {
|
||||
skb_unlink(skb, &rtwsta->roc_queue);
|
||||
|
||||
while ((skb = skb_dequeue(&rtwsta->roc_queue))) {
|
||||
ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, &qsel);
|
||||
if (ret) {
|
||||
rtw89_warn(rtwdev, "pending tx failed with %d\n", ret);
|
||||
@@ -4047,12 +4173,10 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
|
||||
|
||||
void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
|
||||
{
|
||||
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
|
||||
struct ieee80211_hw *hw = rtwdev->hw;
|
||||
struct rtw89_roc *roc = &rtwvif->roc;
|
||||
struct rtw89_vif_link *rtwvif_link;
|
||||
struct rtw89_vif *tmp_vif;
|
||||
u32 reg;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_wiphy(hw->wiphy);
|
||||
@@ -4069,8 +4193,7 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
|
||||
return;
|
||||
}
|
||||
|
||||
reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx);
|
||||
rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rtwdev->hal.rx_fltr);
|
||||
rtw89_mac_set_rx_fltr(rtwdev, rtwvif_link->mac_idx, rtwdev->hal.rx_fltr);
|
||||
|
||||
roc->state = RTW89_ROC_IDLE;
|
||||
rtw89_config_roc_chandef(rtwdev, rtwvif_link, NULL);
|
||||
@@ -4701,7 +4824,8 @@ int rtw89_core_sta_link_disconnect(struct rtw89_dev *rtwdev,
|
||||
}
|
||||
|
||||
/* update cam aid mac_id net_type */
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL,
|
||||
RTW89_ROLE_CON_DISCONN);
|
||||
if (ret) {
|
||||
rtw89_warn(rtwdev, "failed to send h2c cam\n");
|
||||
return ret;
|
||||
@@ -4775,7 +4899,8 @@ int rtw89_core_sta_link_assoc(struct rtw89_dev *rtwdev,
|
||||
}
|
||||
|
||||
/* update cam aid mac_id net_type */
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL,
|
||||
RTW89_ROLE_CON_DISCONN);
|
||||
if (ret) {
|
||||
rtw89_warn(rtwdev, "failed to send h2c cam\n");
|
||||
return ret;
|
||||
@@ -5493,10 +5618,22 @@ EXPORT_SYMBOL(rtw89_check_quirks);
|
||||
|
||||
int rtw89_core_start(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
bool no_bbmcu = !rtwdev->chip->bbmcu_nr;
|
||||
int ret;
|
||||
|
||||
ret = rtw89_mac_preinit(rtwdev);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "mac preinit fail, ret: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (no_bbmcu)
|
||||
rtw89_chip_bb_preinit(rtwdev);
|
||||
|
||||
rtw89_phy_init_bb_afe(rtwdev);
|
||||
|
||||
/* above do preinit before downloading firmware */
|
||||
|
||||
ret = rtw89_mac_init(rtwdev);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "mac init fail, ret:%d\n", ret);
|
||||
@@ -5542,6 +5679,7 @@ int rtw89_core_start(struct rtw89_dev *rtwdev)
|
||||
rtw89_fw_h2c_fw_log(rtwdev, rtwdev->fw.log.enable);
|
||||
rtw89_fw_h2c_init_ba_cam(rtwdev);
|
||||
rtw89_tas_fw_timer_enable(rtwdev, true);
|
||||
rtwdev->ps_hang_cnt = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -5829,6 +5967,7 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
|
||||
wiphy_work_init(&rtwdev->cancel_6ghz_probe_work, rtw89_cancel_6ghz_probe_work);
|
||||
INIT_WORK(&rtwdev->load_firmware_work, rtw89_load_firmware_work);
|
||||
|
||||
spin_lock_init(&rtwdev->tx_rpt.skb_lock);
|
||||
skb_queue_head_init(&rtwdev->c2h_queue);
|
||||
rtw89_core_ppdu_sts_init(rtwdev);
|
||||
rtw89_traffic_stats_init(rtwdev, &rtwdev->stats);
|
||||
@@ -5893,7 +6032,8 @@ void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwv
|
||||
rtw89_phy_config_edcca(rtwdev, bb, true);
|
||||
rtw89_tas_scan(rtwdev, true);
|
||||
|
||||
rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, mac_addr);
|
||||
rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, mac_addr,
|
||||
RTW89_ROLE_INFO_CHANGE);
|
||||
}
|
||||
|
||||
void rtw89_core_scan_complete(struct rtw89_dev *rtwdev,
|
||||
@@ -5913,7 +6053,8 @@ void rtw89_core_scan_complete(struct rtw89_dev *rtwdev,
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL);
|
||||
rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL,
|
||||
RTW89_ROLE_INFO_CHANGE);
|
||||
|
||||
rtw89_chip_rfk_scan(rtwdev, rtwvif_link, false);
|
||||
rtw89_btc_ntfy_scan_finish(rtwdev, rtwvif_link->phy_idx);
|
||||
@@ -6014,7 +6155,7 @@ int rtw89_core_mlsr_switch(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
|
||||
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
|
||||
u16 usable_links = ieee80211_vif_usable_links(vif);
|
||||
u16 active_links = vif->active_links;
|
||||
struct rtw89_vif_link *target, *cur;
|
||||
struct rtw89_vif_link *target;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_wiphy(rtwdev->hw->wiphy);
|
||||
@@ -6040,11 +6181,9 @@ int rtw89_core_mlsr_switch(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
|
||||
ieee80211_stop_queues(rtwdev->hw);
|
||||
flush_work(&rtwdev->txq_work);
|
||||
|
||||
cur = rtw89_get_designated_link(rtwvif);
|
||||
|
||||
ret = ieee80211_set_active_links(vif, active_links | BIT(link_id));
|
||||
ret = ieee80211_set_active_links(vif, BIT(link_id));
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "%s: failed to activate link id %u\n",
|
||||
rtw89_err(rtwdev, "%s: failed to work on link id %u\n",
|
||||
__func__, link_id);
|
||||
goto wake_queue;
|
||||
}
|
||||
@@ -6059,16 +6198,6 @@ int rtw89_core_mlsr_switch(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
|
||||
goto wake_queue;
|
||||
}
|
||||
|
||||
if (likely(cur))
|
||||
rtw89_fw_h2c_mlo_link_cfg(rtwdev, cur, false);
|
||||
|
||||
rtw89_fw_h2c_mlo_link_cfg(rtwdev, target, true);
|
||||
|
||||
ret = ieee80211_set_active_links(vif, BIT(link_id));
|
||||
if (ret)
|
||||
rtw89_err(rtwdev, "%s: failed to inactivate links 0x%x\n",
|
||||
__func__, active_links);
|
||||
|
||||
rtw89_chip_rfk_channel(rtwdev, target);
|
||||
|
||||
rtwvif->mlo_mode = RTW89_MLO_MODE_MLSR;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
struct rtw89_dev;
|
||||
struct rtw89_pci_info;
|
||||
struct rtw89_usb_info;
|
||||
struct rtw89_mac_gen_def;
|
||||
struct rtw89_phy_gen_def;
|
||||
struct rtw89_fw_blacklist;
|
||||
@@ -38,10 +39,13 @@ extern const struct ieee80211_ops rtw89_ops;
|
||||
#define RFREG_MASK 0xfffff
|
||||
#define INV_RF_DATA 0xffffffff
|
||||
#define BYPASS_CR_DATA 0xbabecafe
|
||||
#define RTW89_R32_EA 0xEAEAEAEA
|
||||
#define RTW89_R32_DEAD 0xDEADBEEF
|
||||
|
||||
#define RTW89_TRACK_WORK_PERIOD round_jiffies_relative(HZ * 2)
|
||||
#define RTW89_TRACK_PS_WORK_PERIOD msecs_to_jiffies(100)
|
||||
#define RTW89_FORBID_BA_TIMER round_jiffies_relative(HZ * 4)
|
||||
#define RTW89_PS_HANG_MAX_CNT 3
|
||||
#define CFO_TRACK_MAX_USER 64
|
||||
#define MAX_RSSI 110
|
||||
#define RSSI_FACTOR 1
|
||||
@@ -151,6 +155,7 @@ enum rtw89_core_chip_id {
|
||||
RTL8852C,
|
||||
RTL8851B,
|
||||
RTL8922A,
|
||||
RTL8922D,
|
||||
};
|
||||
|
||||
enum rtw89_chip_gen {
|
||||
@@ -1167,6 +1172,10 @@ struct rtw89_tx_desc_info {
|
||||
u8 ampdu_density;
|
||||
u8 ampdu_num;
|
||||
bool sec_en;
|
||||
bool report;
|
||||
bool tx_cnt_lmt_en;
|
||||
u8 sn: 4;
|
||||
u8 tx_cnt_lmt: 6;
|
||||
u8 addr_info_nr;
|
||||
u8 sec_keyid;
|
||||
u8 sec_type;
|
||||
@@ -1174,6 +1183,8 @@ struct rtw89_tx_desc_info {
|
||||
u8 sec_seq[6];
|
||||
u16 data_rate;
|
||||
u16 data_retry_lowest_rate;
|
||||
u8 data_bw;
|
||||
u8 gi_ltf;
|
||||
bool fw_dl;
|
||||
u16 seq;
|
||||
bool a_ctrl_bsr;
|
||||
@@ -3374,11 +3385,18 @@ struct rtw89_ra_info {
|
||||
u8 cr_tbl_sel:1;
|
||||
u8 fix_giltf_en:1;
|
||||
u8 fix_giltf:3;
|
||||
u8 rsvd2:1;
|
||||
u8 partial_bw_er:1;
|
||||
u8 csi_mcs_ss_idx;
|
||||
u8 csi_mode:2;
|
||||
u8 csi_gi_ltf:3;
|
||||
u8 csi_bw:3;
|
||||
/* after v1 */
|
||||
u8 is_noisy:1;
|
||||
u8 psra_en:1;
|
||||
u8 rsvd0:1;
|
||||
u8 macid_msb:2;
|
||||
u8 band:2; /* enum rtw89_band */
|
||||
u8 is_new_dbgreg:1;
|
||||
};
|
||||
|
||||
#define RTW89_PPDU_MAC_INFO_USR_SIZE 4
|
||||
@@ -3507,6 +3525,20 @@ struct rtw89_phy_rate_pattern {
|
||||
bool enable;
|
||||
};
|
||||
|
||||
#define RTW89_TX_DONE 0x0
|
||||
#define RTW89_TX_RETRY_LIMIT 0x1
|
||||
#define RTW89_TX_LIFE_TIME 0x2
|
||||
#define RTW89_TX_MACID_DROP 0x3
|
||||
|
||||
#define RTW89_MAX_TX_RPTS 16
|
||||
#define RTW89_MAX_TX_RPTS_MASK (RTW89_MAX_TX_RPTS - 1)
|
||||
struct rtw89_tx_rpt {
|
||||
struct sk_buff *skbs[RTW89_MAX_TX_RPTS];
|
||||
/* protect skbs array access/modification */
|
||||
spinlock_t skb_lock;
|
||||
atomic_t sn;
|
||||
};
|
||||
|
||||
#define RTW89_TX_WAIT_WORK_TIMEOUT msecs_to_jiffies(500)
|
||||
struct rtw89_tx_wait_info {
|
||||
struct rcu_head rcu_head;
|
||||
@@ -3518,6 +3550,8 @@ struct rtw89_tx_wait_info {
|
||||
|
||||
struct rtw89_tx_skb_data {
|
||||
struct rtw89_tx_wait_info __rcu *wait;
|
||||
u8 tx_rpt_sn;
|
||||
u8 tx_pkt_cnt_lmt;
|
||||
u8 hci_priv[];
|
||||
};
|
||||
|
||||
@@ -3652,6 +3686,8 @@ struct rtw89_hci_ops {
|
||||
void (*write16)(struct rtw89_dev *rtwdev, u32 addr, u16 data);
|
||||
void (*write32)(struct rtw89_dev *rtwdev, u32 addr, u32 data);
|
||||
|
||||
u32 (*read32_pci_cfg)(struct rtw89_dev *rtwdev, u32 addr);
|
||||
|
||||
int (*mac_pre_init)(struct rtw89_dev *rtwdev);
|
||||
int (*mac_pre_deinit)(struct rtw89_dev *rtwdev);
|
||||
int (*mac_post_init)(struct rtw89_dev *rtwdev);
|
||||
@@ -3687,6 +3723,7 @@ struct rtw89_hci_info {
|
||||
u32 rpwm_addr;
|
||||
u32 cpwm_addr;
|
||||
bool paused;
|
||||
bool tx_rpt_enabled;
|
||||
};
|
||||
|
||||
struct rtw89_chip_ops {
|
||||
@@ -3763,7 +3800,7 @@ struct rtw89_chip_ops {
|
||||
void (*fill_txdesc_fwcmd)(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_tx_desc_info *desc_info,
|
||||
void *txdesc);
|
||||
u8 (*get_ch_dma)(struct rtw89_dev *rtwdev, u8 qsel);
|
||||
u8 (*get_ch_dma[RTW89_HCI_TYPE_NUM])(struct rtw89_dev *rtwdev, u8 qsel);
|
||||
int (*cfg_ctrl_path)(struct rtw89_dev *rtwdev, bool wl);
|
||||
int (*mac_cfg_gnt)(struct rtw89_dev *rtwdev,
|
||||
const struct rtw89_mac_ax_coex_gnt *gnt_cfg);
|
||||
@@ -4422,6 +4459,7 @@ struct rtw89_chip_info {
|
||||
u8 bacam_num;
|
||||
u8 bacam_dynamic_num;
|
||||
enum rtw89_bacam_ver bacam_ver;
|
||||
u8 addrcam_ver;
|
||||
u8 ppdu_max_usr;
|
||||
|
||||
u8 sec_ctrl_efuse_size;
|
||||
@@ -4513,6 +4551,7 @@ struct rtw89_chip_variant {
|
||||
|
||||
union rtw89_bus_info {
|
||||
const struct rtw89_pci_info *pci;
|
||||
const struct rtw89_usb_info *usb;
|
||||
};
|
||||
|
||||
struct rtw89_driver_info {
|
||||
@@ -4640,6 +4679,7 @@ enum rtw89_fw_feature {
|
||||
RTW89_FW_FEATURE_RFK_NTFY_MCC_V0,
|
||||
RTW89_FW_FEATURE_LPS_DACK_BY_C2H_REG,
|
||||
RTW89_FW_FEATURE_BEACON_TRACKING,
|
||||
RTW89_FW_FEATURE_ADDR_CAM_V0,
|
||||
};
|
||||
|
||||
struct rtw89_fw_suit {
|
||||
@@ -4700,6 +4740,7 @@ struct rtw89_fw_elm_info {
|
||||
struct rtw89_phy_rfk_log_fmt *rfk_log_fmt;
|
||||
const struct rtw89_regd_data *regd;
|
||||
const struct rtw89_fw_element_hdr *afe;
|
||||
const struct rtw89_fw_element_hdr *diag_mac;
|
||||
};
|
||||
|
||||
enum rtw89_fw_mss_dev_type {
|
||||
@@ -5449,6 +5490,8 @@ struct rtw89_regd_ctrl {
|
||||
struct rtw89_regulatory_info {
|
||||
struct rtw89_regd_ctrl ctrl;
|
||||
const struct rtw89_regd *regd;
|
||||
bool programmed;
|
||||
|
||||
enum rtw89_reg_6ghz_power reg_6ghz_power;
|
||||
struct rtw89_reg_6ghz_tpe reg_6ghz_tpe;
|
||||
bool txpwr_uk_follow_etsi;
|
||||
@@ -5933,6 +5976,7 @@ struct rtw89_mcc_info {
|
||||
|
||||
enum rtw89_mlo_mode {
|
||||
RTW89_MLO_MODE_MLSR = 0,
|
||||
RTW89_MLO_MODE_EMLSR = 1,
|
||||
|
||||
NUM_OF_RTW89_MLO_MODE,
|
||||
};
|
||||
@@ -6006,6 +6050,8 @@ struct rtw89_dev {
|
||||
struct list_head tx_waits;
|
||||
struct wiphy_delayed_work tx_wait_work;
|
||||
|
||||
struct rtw89_tx_rpt tx_rpt;
|
||||
|
||||
struct rtw89_cam_info cam_info;
|
||||
|
||||
struct sk_buff_head c2h_queue;
|
||||
@@ -6079,6 +6125,7 @@ struct rtw89_dev {
|
||||
struct rtw89_btc btc;
|
||||
enum rtw89_ps_mode ps_mode;
|
||||
bool lps_enabled;
|
||||
u8 ps_hang_cnt;
|
||||
|
||||
struct rtw89_wow_param wow;
|
||||
|
||||
@@ -6088,6 +6135,7 @@ struct rtw89_dev {
|
||||
int napi_budget_countdown;
|
||||
|
||||
struct rtw89_debugfs *debugfs;
|
||||
struct rtw89_vif *pure_monitor_mode_vif;
|
||||
|
||||
/* HCI related data, keep last */
|
||||
u8 priv[] __aligned(sizeof(void *));
|
||||
@@ -6097,6 +6145,12 @@ struct rtw89_link_conf_container {
|
||||
struct ieee80211_bss_conf *link_conf[IEEE80211_MLD_MAX_NUM_LINKS];
|
||||
};
|
||||
|
||||
struct rtw89_vif_ml_trans {
|
||||
u16 mediate_links;
|
||||
u16 links_to_del;
|
||||
u16 links_to_add;
|
||||
};
|
||||
|
||||
#define RTW89_VIF_IDLE_LINK_ID 0
|
||||
|
||||
struct rtw89_vif {
|
||||
@@ -6119,6 +6173,7 @@ struct rtw89_vif {
|
||||
bool offchan;
|
||||
|
||||
enum rtw89_mlo_mode mlo_mode;
|
||||
struct rtw89_vif_ml_trans ml_trans;
|
||||
|
||||
struct list_head dlink_pool;
|
||||
u8 links_inst_valid_num;
|
||||
@@ -6291,6 +6346,7 @@ static inline int rtw89_hci_tx_write(struct rtw89_dev *rtwdev,
|
||||
static inline void rtw89_hci_reset(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
rtwdev->hci.ops->reset(rtwdev);
|
||||
/* hci.ops->reset must complete all pending TX wait SKBs */
|
||||
rtw89_tx_wait_list_clear(rtwdev);
|
||||
}
|
||||
|
||||
@@ -6620,6 +6676,15 @@ rtw89_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
|
||||
mutex_unlock(&rtwdev->rf_mutex);
|
||||
}
|
||||
|
||||
static inline u32 rtw89_read32_pci_cfg(struct rtw89_dev *rtwdev, u32 addr)
|
||||
{
|
||||
if (rtwdev->hci.type != RTW89_HCI_TYPE_PCIE ||
|
||||
!rtwdev->hci.ops->read32_pci_cfg)
|
||||
return RTW89_R32_EA;
|
||||
|
||||
return rtwdev->hci.ops->read32_pci_cfg(rtwdev, addr);
|
||||
}
|
||||
|
||||
static inline struct ieee80211_txq *rtw89_txq_to_txq(struct rtw89_txq *rtwtxq)
|
||||
{
|
||||
void *p = rtwtxq;
|
||||
@@ -6984,12 +7049,17 @@ static inline void rtw89_chip_rfk_hw_init(struct rtw89_dev *rtwdev)
|
||||
}
|
||||
|
||||
static inline
|
||||
void rtw89_chip_bb_preinit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
|
||||
void rtw89_chip_bb_preinit(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
|
||||
if (chip->ops->bb_preinit)
|
||||
chip->ops->bb_preinit(rtwdev, phy_idx);
|
||||
if (!chip->ops->bb_preinit)
|
||||
return;
|
||||
|
||||
chip->ops->bb_preinit(rtwdev, RTW89_PHY_0);
|
||||
|
||||
if (rtwdev->dbcc_en)
|
||||
chip->ops->bb_preinit(rtwdev, RTW89_PHY_1);
|
||||
}
|
||||
|
||||
static inline
|
||||
@@ -7241,7 +7311,7 @@ u8 rtw89_chip_get_ch_dma(struct rtw89_dev *rtwdev, u8 qsel)
|
||||
{
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
|
||||
return chip->ops->get_ch_dma(rtwdev, qsel);
|
||||
return chip->ops->get_ch_dma[rtwdev->hci.type](rtwdev, qsel);
|
||||
}
|
||||
|
||||
static inline
|
||||
@@ -7372,27 +7442,28 @@ static inline struct sk_buff *rtw89_alloc_skb_for_rx(struct rtw89_dev *rtwdev,
|
||||
return dev_alloc_skb(length);
|
||||
}
|
||||
|
||||
static inline bool rtw89_core_is_tx_wait(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_tx_skb_data *skb_data)
|
||||
{
|
||||
return rcu_access_pointer(skb_data->wait);
|
||||
}
|
||||
|
||||
static inline bool rtw89_core_tx_wait_complete(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_tx_skb_data *skb_data,
|
||||
bool tx_done)
|
||||
u8 tx_status)
|
||||
{
|
||||
struct rtw89_tx_wait_info *wait;
|
||||
bool ret = false;
|
||||
|
||||
rcu_read_lock();
|
||||
guard(rcu)();
|
||||
|
||||
wait = rcu_dereference(skb_data->wait);
|
||||
if (!wait)
|
||||
goto out;
|
||||
return false;
|
||||
|
||||
ret = true;
|
||||
wait->tx_done = tx_done;
|
||||
wait->tx_done = tx_status == RTW89_TX_DONE;
|
||||
/* Don't access skb anymore after completion */
|
||||
complete_all(&wait->completion);
|
||||
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool rtw89_is_mlo_1_1(struct rtw89_dev *rtwdev)
|
||||
@@ -7495,6 +7566,7 @@ void rtw89_core_fill_txdesc_fwcmd_v2(struct rtw89_dev *rtwdev,
|
||||
void *txdesc);
|
||||
u8 rtw89_core_get_ch_dma(struct rtw89_dev *rtwdev, u8 qsel);
|
||||
u8 rtw89_core_get_ch_dma_v1(struct rtw89_dev *rtwdev, u8 qsel);
|
||||
u8 rtw89_core_get_ch_dma_v2(struct rtw89_dev *rtwdev, u8 qsel);
|
||||
void rtw89_core_rx(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_rx_desc_info *desc_info,
|
||||
struct sk_buff *skb);
|
||||
|
||||
@@ -87,6 +87,7 @@ struct rtw89_debugfs {
|
||||
struct rtw89_debugfs_priv disable_dm;
|
||||
struct rtw89_debugfs_priv mlo_mode;
|
||||
struct rtw89_debugfs_priv beacon_info;
|
||||
struct rtw89_debugfs_priv diag_mac;
|
||||
};
|
||||
|
||||
struct rtw89_debugfs_iter_data {
|
||||
@@ -4361,6 +4362,302 @@ rtw89_debug_priv_mlo_mode_set(struct rtw89_dev *rtwdev,
|
||||
return count;
|
||||
}
|
||||
|
||||
enum __diag_mac_cmd {
|
||||
__CMD_EQUALV,
|
||||
__CMD_EQUALO,
|
||||
__CMD_NEQUALV,
|
||||
__CMD_NEQUALO,
|
||||
__CMD_SETEQUALV,
|
||||
__CMD_SETEQUALO,
|
||||
__CMD_CMPWCR,
|
||||
__CMD_CMPWWD,
|
||||
__CMD_NEQ_CMPWCR,
|
||||
__CMD_NEQ_CMPWWD,
|
||||
__CMD_INCREMENT,
|
||||
__CMD_MESSAGE,
|
||||
};
|
||||
|
||||
enum __diag_mac_io {
|
||||
__IO_NORMAL,
|
||||
__IO_NORMAL_PCIE,
|
||||
__IO_NORMAL_USB,
|
||||
__IO_NORMAL_SDIO,
|
||||
__IO_PCIE_CFG,
|
||||
__IO_SDIO_CCCR,
|
||||
};
|
||||
|
||||
struct __diag_mac_rule_header {
|
||||
u8 sheet;
|
||||
u8 cmd;
|
||||
u8 seq_major;
|
||||
u8 seq_minor;
|
||||
u8 io_band;
|
||||
#define __DIAG_MAC_IO GENMASK(3, 0)
|
||||
#define __DIAG_MAC_N_BAND BIT(4)
|
||||
#define __DIAG_MAC_HAS_BAND BIT(5)
|
||||
u8 len; /* include header. Unit: 4 bytes */
|
||||
u8 rsvd[2];
|
||||
} __packed;
|
||||
|
||||
struct __diag_mac_rule_equal {
|
||||
struct __diag_mac_rule_header header;
|
||||
__le32 addr;
|
||||
__le32 addr_name_offset;
|
||||
__le32 mask;
|
||||
__le32 val;
|
||||
__le32 msg_offset;
|
||||
u8 rsvd[4];
|
||||
} __packed;
|
||||
|
||||
struct __diag_mac_rule_increment {
|
||||
struct __diag_mac_rule_header header;
|
||||
__le32 addr;
|
||||
__le32 addr_name_offset;
|
||||
__le32 mask;
|
||||
__le16 sel;
|
||||
__le16 delay;
|
||||
__le32 msg_offset;
|
||||
u8 rsvd[4];
|
||||
} __packed;
|
||||
|
||||
struct __diag_mac_msg_buf {
|
||||
__le16 len;
|
||||
char string[];
|
||||
} __packed;
|
||||
|
||||
static ssize_t rtw89_mac_diag_do_equalv(struct rtw89_dev *rtwdev,
|
||||
char *buf, size_t bufsz,
|
||||
const struct __diag_mac_rule_equal *r,
|
||||
const void *msg_start,
|
||||
u64 *positive_bmp)
|
||||
{
|
||||
const struct __diag_mac_msg_buf *name = msg_start +
|
||||
le32_to_cpu(r->addr_name_offset);
|
||||
const struct __diag_mac_msg_buf *msg = msg_start +
|
||||
le32_to_cpu(r->msg_offset);
|
||||
bool want_eq = r->header.cmd == __CMD_EQUALV;
|
||||
char *p = buf, *end = buf + bufsz;
|
||||
bool equal = false;
|
||||
u32 val;
|
||||
|
||||
*positive_bmp <<= 1;
|
||||
|
||||
if (u8_get_bits(r->header.io_band, __DIAG_MAC_IO) == __IO_PCIE_CFG)
|
||||
val = rtw89_read32_pci_cfg(rtwdev, le32_to_cpu(r->addr));
|
||||
else
|
||||
val = rtw89_read32(rtwdev, le32_to_cpu(r->addr));
|
||||
|
||||
if ((val & le32_to_cpu(r->mask)) == le32_to_cpu(r->val))
|
||||
equal = true;
|
||||
|
||||
if (want_eq == equal) {
|
||||
*positive_bmp |= BIT(0);
|
||||
return p - buf;
|
||||
}
|
||||
|
||||
p += scnprintf(p, end - p, "sheet: %d, cmd: %d, Reg: %.*s => %x, %.*s\n",
|
||||
r->header.sheet, r->header.cmd, le16_to_cpu(name->len),
|
||||
name->string, val, le16_to_cpu(msg->len), msg->string);
|
||||
|
||||
return p - buf;
|
||||
}
|
||||
|
||||
static ssize_t rtw89_mac_diag_do_increment(struct rtw89_dev *rtwdev,
|
||||
char *buf, size_t bufsz,
|
||||
const struct __diag_mac_rule_increment *r,
|
||||
const void *msg_start,
|
||||
u64 *positive_bmp)
|
||||
{
|
||||
const struct __diag_mac_msg_buf *name = msg_start +
|
||||
le32_to_cpu(r->addr_name_offset);
|
||||
const struct __diag_mac_msg_buf *msg = msg_start +
|
||||
le32_to_cpu(r->msg_offset);
|
||||
char *p = buf, *end = buf + bufsz;
|
||||
u32 addr = le32_to_cpu(r->addr);
|
||||
u32 mask = le32_to_cpu(r->mask);
|
||||
u16 sel = le16_to_cpu(r->sel);
|
||||
u32 val1, val2;
|
||||
|
||||
*positive_bmp <<= 1;
|
||||
|
||||
rtw89_write32(rtwdev, addr, sel);
|
||||
|
||||
if (u8_get_bits(r->header.io_band, __DIAG_MAC_IO) == __IO_PCIE_CFG)
|
||||
val1 = rtw89_read32_pci_cfg(rtwdev, addr);
|
||||
else
|
||||
val1 = rtw89_read32(rtwdev, addr);
|
||||
|
||||
mdelay(le16_to_cpu(r->delay));
|
||||
|
||||
if (u8_get_bits(r->header.io_band, __DIAG_MAC_IO) == __IO_PCIE_CFG)
|
||||
val2 = rtw89_read32_pci_cfg(rtwdev, addr);
|
||||
else
|
||||
val2 = rtw89_read32(rtwdev, addr);
|
||||
|
||||
if ((val2 & mask) > (val1 & mask)) {
|
||||
*positive_bmp |= BIT(0);
|
||||
return p - buf;
|
||||
}
|
||||
|
||||
p += scnprintf(p, end - p, "sheet: %d, cmd: %d, Reg: %.*s [%d]=> %x, %.*s\n",
|
||||
r->header.sheet, r->header.cmd, le16_to_cpu(name->len),
|
||||
name->string, le16_to_cpu(r->sel), val1,
|
||||
le16_to_cpu(msg->len), msg->string);
|
||||
|
||||
return p - buf;
|
||||
}
|
||||
|
||||
static bool rtw89_mac_diag_match_hci(struct rtw89_dev *rtwdev,
|
||||
const struct __diag_mac_rule_header *rh)
|
||||
{
|
||||
switch (u8_get_bits(rh->io_band, __DIAG_MAC_IO)) {
|
||||
case __IO_NORMAL:
|
||||
default:
|
||||
return true;
|
||||
case __IO_NORMAL_PCIE:
|
||||
case __IO_PCIE_CFG:
|
||||
if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE)
|
||||
return true;
|
||||
break;
|
||||
case __IO_NORMAL_USB:
|
||||
if (rtwdev->hci.type == RTW89_HCI_TYPE_USB)
|
||||
return true;
|
||||
break;
|
||||
case __IO_NORMAL_SDIO:
|
||||
case __IO_SDIO_CCCR:
|
||||
if (rtwdev->hci.type == RTW89_HCI_TYPE_SDIO)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool rtw89_mac_diag_match_band(struct rtw89_dev *rtwdev,
|
||||
const struct __diag_mac_rule_header *rh)
|
||||
{
|
||||
u8 active_bands;
|
||||
bool has_band;
|
||||
u8 band;
|
||||
|
||||
has_band = u8_get_bits(rh->io_band, __DIAG_MAC_HAS_BAND);
|
||||
if (!has_band)
|
||||
return true;
|
||||
|
||||
band = u8_get_bits(rh->io_band, __DIAG_MAC_N_BAND);
|
||||
active_bands = rtw89_get_active_phy_bitmap(rtwdev);
|
||||
|
||||
if (active_bands & BIT(band))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static ssize_t rtw89_mac_diag_iter_all(struct rtw89_dev *rtwdev,
|
||||
char *buf, size_t bufsz)
|
||||
{
|
||||
const struct rtw89_fw_element_hdr *elm = rtwdev->fw.elm_info.diag_mac;
|
||||
u32 n_plains = 0, n_rules = 0, n_positive = 0, n_ignore = 0;
|
||||
char *p = buf, *end = buf + bufsz, *p_rewind;
|
||||
const void *rule, *rule_end;
|
||||
u32 elm_size, rule_size;
|
||||
const void *msg_start;
|
||||
u64 positive_bmp = 0;
|
||||
u8 prev_sheet = 0;
|
||||
u8 prev_seq = 0;
|
||||
int limit;
|
||||
|
||||
if (!elm) {
|
||||
p += scnprintf(p, end - p, "No diag_mac entry\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rule_size = le32_to_cpu(elm->u.diag_mac.rule_size);
|
||||
elm_size = le32_to_cpu(elm->size);
|
||||
|
||||
if (ALIGN(rule_size, 16) > elm_size) {
|
||||
p += scnprintf(p, end - p, "rule size (%u) exceed elm_size (%u)\n",
|
||||
ALIGN(rule_size, 16), elm_size);
|
||||
goto out;
|
||||
}
|
||||
|
||||
rule = &elm->u.diag_mac.rules_and_msgs[0];
|
||||
rule_end = &elm->u.diag_mac.rules_and_msgs[rule_size];
|
||||
msg_start = &elm->u.diag_mac.rules_and_msgs[ALIGN(rule_size, 16)];
|
||||
|
||||
for (limit = 0; limit < 5000 && rule < rule_end; limit++) {
|
||||
const struct __diag_mac_rule_header *rh = rule;
|
||||
u8 sheet = rh->sheet;
|
||||
u8 seq = rh->seq_major;
|
||||
|
||||
if (!rtw89_mac_diag_match_hci(rtwdev, rh) ||
|
||||
!rtw89_mac_diag_match_band(rtwdev, rh)) {
|
||||
n_ignore++;
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (!seq || prev_sheet != sheet || prev_seq != seq) {
|
||||
if (positive_bmp) {
|
||||
n_positive++;
|
||||
/*
|
||||
* discard output for negative results if one in
|
||||
* a sequence set is positive.
|
||||
*/
|
||||
if (p_rewind)
|
||||
p = p_rewind;
|
||||
}
|
||||
p_rewind = seq ? p : NULL;
|
||||
positive_bmp = 0;
|
||||
n_rules++;
|
||||
}
|
||||
|
||||
switch (rh->cmd) {
|
||||
case __CMD_EQUALV:
|
||||
case __CMD_NEQUALV:
|
||||
p += rtw89_mac_diag_do_equalv(rtwdev, p, end - p, rule,
|
||||
msg_start, &positive_bmp);
|
||||
break;
|
||||
case __CMD_INCREMENT:
|
||||
p += rtw89_mac_diag_do_increment(rtwdev, p, end - p, rule,
|
||||
msg_start, &positive_bmp);
|
||||
break;
|
||||
default:
|
||||
p += scnprintf(p, end - p, "unknown rule cmd %u\n", rh->cmd);
|
||||
break;
|
||||
}
|
||||
|
||||
next:
|
||||
n_plains++;
|
||||
rule += rh->len * 4;
|
||||
prev_seq = seq;
|
||||
prev_sheet = sheet;
|
||||
}
|
||||
|
||||
if (positive_bmp) {
|
||||
n_positive++;
|
||||
if (p_rewind)
|
||||
p = p_rewind;
|
||||
}
|
||||
|
||||
p += scnprintf(p, end - p, "\nPlain(Ignore)/Rules/Positive: %u(%u)/%u/%u\n",
|
||||
n_plains, n_ignore, n_rules, n_positive);
|
||||
|
||||
out:
|
||||
return p - buf;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
rtw89_debug_priv_diag_mac_get(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_debugfs_priv *debugfs_priv,
|
||||
char *buf, size_t bufsz)
|
||||
{
|
||||
lockdep_assert_wiphy(rtwdev->hw->wiphy);
|
||||
|
||||
rtw89_leave_lps(rtwdev);
|
||||
|
||||
return rtw89_mac_diag_iter_all(rtwdev, buf, bufsz);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
rtw89_debug_priv_beacon_info_get(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_debugfs_priv *debugfs_priv,
|
||||
@@ -4478,6 +4775,7 @@ static const struct rtw89_debugfs rtw89_debugfs_templ = {
|
||||
.disable_dm = rtw89_debug_priv_set_and_get(disable_dm, RWLOCK),
|
||||
.mlo_mode = rtw89_debug_priv_set_and_get(mlo_mode, RWLOCK),
|
||||
.beacon_info = rtw89_debug_priv_get(beacon_info),
|
||||
.diag_mac = rtw89_debug_priv_get(diag_mac, RSIZE_16K, RLOCK),
|
||||
};
|
||||
|
||||
#define rtw89_debugfs_add(name, mode, fopname, parent) \
|
||||
@@ -4524,6 +4822,7 @@ void rtw89_debugfs_add_sec1(struct rtw89_dev *rtwdev, struct dentry *debugfs_top
|
||||
rtw89_debugfs_add_rw(disable_dm);
|
||||
rtw89_debugfs_add_rw(mlo_mode);
|
||||
rtw89_debugfs_add_r(beacon_info);
|
||||
rtw89_debugfs_add_r(diag_mac);
|
||||
}
|
||||
|
||||
void rtw89_debugfs_init(struct rtw89_dev *rtwdev)
|
||||
|
||||
@@ -161,6 +161,11 @@ static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
|
||||
info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_W7_DYN_HDR);
|
||||
info->idmem_share_mode = le32_get_bits(fw_hdr->w7, FW_HDR_W7_IDMEM_SHARE_MODE);
|
||||
|
||||
if (chip->chip_gen == RTW89_CHIP_AX)
|
||||
info->part_size = FWDL_SECTION_PER_PKT_LEN;
|
||||
else
|
||||
info->part_size = le32_get_bits(fw_hdr->w7, FW_HDR_W7_PART_SIZE);
|
||||
|
||||
if (info->dynamic_hdr_en) {
|
||||
info->hdr_len = le32_get_bits(fw_hdr->w3, FW_HDR_W3_LEN);
|
||||
info->dynamic_hdr_len = info->hdr_len - base_hdr_len;
|
||||
@@ -439,6 +444,7 @@ static int rtw89_fw_hdr_parser_v1(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
|
||||
struct rtw89_fw_bin_info *info)
|
||||
{
|
||||
const struct rtw89_fw_hdr_v1 *fw_hdr = (const struct rtw89_fw_hdr_v1 *)fw;
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
struct rtw89_fw_hdr_section_info *section_info;
|
||||
const struct rtw89_fw_dynhdr_hdr *fwdynhdr;
|
||||
const struct rtw89_fw_hdr_section_v1 *section;
|
||||
@@ -455,6 +461,11 @@ static int rtw89_fw_hdr_parser_v1(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
|
||||
info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_DYN_HDR);
|
||||
info->idmem_share_mode = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_IDMEM_SHARE_MODE);
|
||||
|
||||
if (chip->chip_gen == RTW89_CHIP_AX)
|
||||
info->part_size = FWDL_SECTION_PER_PKT_LEN;
|
||||
else
|
||||
info->part_size = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_PART_SIZE);
|
||||
|
||||
if (info->dynamic_hdr_en) {
|
||||
info->hdr_len = le32_get_bits(fw_hdr->w5, FW_HDR_V1_W5_HDR_SIZE);
|
||||
info->dynamic_hdr_len = info->hdr_len - base_hdr_len;
|
||||
@@ -870,6 +881,7 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
|
||||
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 76, 0, LPS_DACK_BY_C2H_REG),
|
||||
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 79, 0, CRASH_TRIGGER_TYPE_1),
|
||||
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 80, 0, BEACON_TRACKING),
|
||||
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 84, 0, ADDR_CAM_V0),
|
||||
};
|
||||
|
||||
static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw,
|
||||
@@ -1298,6 +1310,18 @@ int rtw89_build_afe_pwr_seq_from_elm(struct rtw89_dev *rtwdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int rtw89_recognize_diag_mac_from_elm(struct rtw89_dev *rtwdev,
|
||||
const struct rtw89_fw_element_hdr *elm,
|
||||
const union rtw89_fw_element_arg arg)
|
||||
{
|
||||
struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
|
||||
|
||||
elm_info->diag_mac = elm;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct rtw89_fw_element_handler __fw_element_handlers[] = {
|
||||
[RTW89_FW_ELEMENT_ID_BBMCU0] = {__rtw89_fw_recognize_from_elm,
|
||||
{ .fw_type = RTW89_FW_BBMCU0 }, NULL},
|
||||
@@ -1386,6 +1410,9 @@ static const struct rtw89_fw_element_handler __fw_element_handlers[] = {
|
||||
[RTW89_FW_ELEMENT_ID_AFE_PWR_SEQ] = {
|
||||
rtw89_build_afe_pwr_seq_from_elm, {}, "AFE",
|
||||
},
|
||||
[RTW89_FW_ELEMENT_ID_DIAG_MAC] = {
|
||||
rtw89_recognize_diag_mac_from_elm, {}, NULL,
|
||||
},
|
||||
};
|
||||
|
||||
int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev)
|
||||
@@ -1501,8 +1528,7 @@ static u32 __rtw89_fw_download_tweak_hdr_v0(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_fw_hdr_section *section;
|
||||
int i;
|
||||
|
||||
le32p_replace_bits(&fw_hdr->w7, FWDL_SECTION_PER_PKT_LEN,
|
||||
FW_HDR_W7_PART_SIZE);
|
||||
le32p_replace_bits(&fw_hdr->w7, info->part_size, FW_HDR_W7_PART_SIZE);
|
||||
|
||||
for (i = 0; i < info->section_num; i++) {
|
||||
section_info = &info->section_info[i];
|
||||
@@ -1527,8 +1553,7 @@ static u32 __rtw89_fw_download_tweak_hdr_v1(struct rtw89_dev *rtwdev,
|
||||
u8 dst_sec_idx = 0;
|
||||
u8 sec_idx;
|
||||
|
||||
le32p_replace_bits(&fw_hdr->w7, FWDL_SECTION_PER_PKT_LEN,
|
||||
FW_HDR_V1_W7_PART_SIZE);
|
||||
le32p_replace_bits(&fw_hdr->w7, info->part_size, FW_HDR_V1_W7_PART_SIZE);
|
||||
|
||||
for (sec_idx = 0; sec_idx < info->section_num; sec_idx++) {
|
||||
section_info = &info->section_info[sec_idx];
|
||||
@@ -1630,7 +1655,8 @@ static int rtw89_fw_download_hdr(struct rtw89_dev *rtwdev,
|
||||
}
|
||||
|
||||
static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_fw_hdr_section_info *info)
|
||||
struct rtw89_fw_hdr_section_info *info,
|
||||
u32 part_size)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
const u8 *section = info->addr;
|
||||
@@ -1651,20 +1677,17 @@ static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev,
|
||||
}
|
||||
|
||||
if (info->key_addr && info->key_len) {
|
||||
if (residue_len > FWDL_SECTION_PER_PKT_LEN || info->len < info->key_len)
|
||||
if (residue_len > part_size || info->len < info->key_len)
|
||||
rtw89_warn(rtwdev,
|
||||
"ignore to copy key data because of len %d, %d, %d, %d\n",
|
||||
info->len, FWDL_SECTION_PER_PKT_LEN,
|
||||
info->len, part_size,
|
||||
info->key_len, residue_len);
|
||||
else
|
||||
copy_key = true;
|
||||
}
|
||||
|
||||
while (residue_len) {
|
||||
if (residue_len >= FWDL_SECTION_PER_PKT_LEN)
|
||||
pkt_len = FWDL_SECTION_PER_PKT_LEN;
|
||||
else
|
||||
pkt_len = residue_len;
|
||||
pkt_len = min(residue_len, part_size);
|
||||
|
||||
skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, pkt_len);
|
||||
if (!skb) {
|
||||
@@ -1719,7 +1742,7 @@ static int rtw89_fw_download_main(struct rtw89_dev *rtwdev,
|
||||
int ret;
|
||||
|
||||
while (section_num--) {
|
||||
ret = __rtw89_fw_download_main(rtwdev, section_info);
|
||||
ret = __rtw89_fw_download_main(rtwdev, section_info, info->part_size);
|
||||
if (ret)
|
||||
return ret;
|
||||
section_info++;
|
||||
@@ -2110,28 +2133,48 @@ plain_log:
|
||||
|
||||
}
|
||||
|
||||
#define H2C_CAM_LEN 60
|
||||
int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr)
|
||||
struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr,
|
||||
enum rtw89_upd_mode upd_mode)
|
||||
{
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
struct rtw89_h2c_addr_cam_v0 *h2c_v0;
|
||||
struct rtw89_h2c_addr_cam *h2c;
|
||||
u32 len = sizeof(*h2c);
|
||||
struct sk_buff *skb;
|
||||
u8 ver = U8_MAX;
|
||||
int ret;
|
||||
|
||||
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CAM_LEN);
|
||||
if (RTW89_CHK_FW_FEATURE(ADDR_CAM_V0, &rtwdev->fw) ||
|
||||
chip->chip_gen == RTW89_CHIP_AX) {
|
||||
len = sizeof(*h2c_v0);
|
||||
ver = 0;
|
||||
}
|
||||
|
||||
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
|
||||
if (!skb) {
|
||||
rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
skb_put(skb, H2C_CAM_LEN);
|
||||
rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif_link, rtwsta_link, scan_mac_addr,
|
||||
skb->data);
|
||||
rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif_link, rtwsta_link, skb->data);
|
||||
skb_put(skb, len);
|
||||
h2c_v0 = (struct rtw89_h2c_addr_cam_v0 *)skb->data;
|
||||
|
||||
rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif_link, rtwsta_link,
|
||||
scan_mac_addr, h2c_v0);
|
||||
rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif_link, rtwsta_link, h2c_v0);
|
||||
|
||||
if (ver == 0)
|
||||
goto hdr;
|
||||
|
||||
h2c = (struct rtw89_h2c_addr_cam *)skb->data;
|
||||
h2c->w15 = le32_encode_bits(upd_mode, ADDR_CAM_W15_UPD_MODE);
|
||||
|
||||
hdr:
|
||||
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
|
||||
H2C_CAT_MAC,
|
||||
H2C_CL_MAC_ADDR_CAM_UPDATE,
|
||||
H2C_FUNC_MAC_ADDR_CAM_UPD, 0, 1,
|
||||
H2C_CAM_LEN);
|
||||
len);
|
||||
|
||||
ret = rtw89_h2c_tx(rtwdev, skb, false);
|
||||
if (ret) {
|
||||
@@ -3165,6 +3208,7 @@ int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev,
|
||||
SET_CMC_TBL_ANTSEL_C(skb->data, 0);
|
||||
SET_CMC_TBL_ANTSEL_D(skb->data, 0);
|
||||
}
|
||||
SET_CMC_TBL_MGQ_RPT_EN(skb->data, rtwdev->hci.tx_rpt_enabled);
|
||||
SET_CMC_TBL_DOPPLER_CTRL(skb->data, 0);
|
||||
SET_CMC_TBL_TXPWR_TOLERENCE(skb->data, 0);
|
||||
if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
|
||||
@@ -3210,7 +3254,8 @@ int rtw89_fw_h2c_default_cmac_tbl_g7(struct rtw89_dev *rtwdev,
|
||||
h2c->c0 = le32_encode_bits(mac_id, CCTLINFO_G7_C0_MACID) |
|
||||
le32_encode_bits(1, CCTLINFO_G7_C0_OP);
|
||||
|
||||
h2c->w0 = le32_encode_bits(4, CCTLINFO_G7_W0_DATARATE);
|
||||
h2c->w0 = le32_encode_bits(4, CCTLINFO_G7_W0_DATARATE) |
|
||||
le32_encode_bits(rtwdev->hci.tx_rpt_enabled, CCTLINFO_G7_W0_MGQ_RPT_EN);
|
||||
h2c->m0 = cpu_to_le32(CCTLINFO_G7_W0_ALL);
|
||||
|
||||
h2c->w1 = le32_encode_bits(4, CCTLINFO_G7_W1_DATA_RTY_LOWEST_RATE) |
|
||||
@@ -4715,13 +4760,16 @@ int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi
|
||||
struct rtw89_h2c_ra_v1 *h2c_v1;
|
||||
struct rtw89_h2c_ra *h2c;
|
||||
u32 len = sizeof(*h2c);
|
||||
bool format_v1 = false;
|
||||
struct sk_buff *skb;
|
||||
u8 ver = U8_MAX;
|
||||
int ret;
|
||||
|
||||
if (chip->chip_gen == RTW89_CHIP_BE) {
|
||||
if (chip->chip_gen == RTW89_CHIP_AX) {
|
||||
len = sizeof(*h2c);
|
||||
ver = 0;
|
||||
} else {
|
||||
len = sizeof(*h2c_v1);
|
||||
format_v1 = true;
|
||||
ver = 1;
|
||||
}
|
||||
|
||||
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
|
||||
@@ -4753,16 +4801,8 @@ int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi
|
||||
h2c->w3 = le32_encode_bits(ra->fix_giltf_en, RTW89_H2C_RA_W3_FIX_GILTF_EN) |
|
||||
le32_encode_bits(ra->fix_giltf, RTW89_H2C_RA_W3_FIX_GILTF);
|
||||
|
||||
if (!format_v1)
|
||||
goto csi;
|
||||
|
||||
h2c_v1 = (struct rtw89_h2c_ra_v1 *)h2c;
|
||||
h2c_v1->w4 = le32_encode_bits(ra->mode_ctrl, RTW89_H2C_RA_V1_W4_MODE_EHT) |
|
||||
le32_encode_bits(ra->bw_cap, RTW89_H2C_RA_V1_W4_BW_EHT);
|
||||
|
||||
csi:
|
||||
if (!csi)
|
||||
goto done;
|
||||
if (!csi || ver >= 1)
|
||||
goto next_v1;
|
||||
|
||||
h2c->w2 |= le32_encode_bits(1, RTW89_H2C_RA_W2_BFEE_CSI_CTL);
|
||||
h2c->w3 |= le32_encode_bits(ra->band_num, RTW89_H2C_RA_W3_BAND_NUM) |
|
||||
@@ -4774,6 +4814,18 @@ csi:
|
||||
le32_encode_bits(ra->csi_gi_ltf, RTW89_H2C_RA_W3_FIXED_CSI_GI_LTF) |
|
||||
le32_encode_bits(ra->csi_bw, RTW89_H2C_RA_W3_FIXED_CSI_BW);
|
||||
|
||||
next_v1:
|
||||
if (ver < 1)
|
||||
goto done;
|
||||
|
||||
h2c->w3 |= le32_encode_bits(ra->partial_bw_er,
|
||||
RTW89_H2C_RA_V1_W3_PARTIAL_BW_SU_ER) |
|
||||
le32_encode_bits(ra->band, RTW89_H2C_RA_V1_W3_BAND);
|
||||
|
||||
h2c_v1 = (struct rtw89_h2c_ra_v1 *)h2c;
|
||||
h2c_v1->w4 = le32_encode_bits(ra->mode_ctrl, RTW89_H2C_RA_V1_W4_MODE_EHT) |
|
||||
le32_encode_bits(ra->bw_cap, RTW89_H2C_RA_V1_W4_BW_EHT);
|
||||
|
||||
done:
|
||||
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
|
||||
H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RA,
|
||||
@@ -6891,11 +6943,18 @@ void rtw89_fw_c2h_work(struct wiphy *wiphy, struct wiphy_work *work)
|
||||
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
|
||||
c2h_work);
|
||||
struct sk_buff *skb, *tmp;
|
||||
struct sk_buff_head c2hq;
|
||||
unsigned long flags;
|
||||
|
||||
lockdep_assert_wiphy(rtwdev->hw->wiphy);
|
||||
|
||||
skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) {
|
||||
skb_unlink(skb, &rtwdev->c2h_queue);
|
||||
__skb_queue_head_init(&c2hq);
|
||||
|
||||
spin_lock_irqsave(&rtwdev->c2h_queue.lock, flags);
|
||||
skb_queue_splice_init(&rtwdev->c2h_queue, &c2hq);
|
||||
spin_unlock_irqrestore(&rtwdev->c2h_queue.lock, flags);
|
||||
|
||||
skb_queue_walk_safe(&c2hq, skb, tmp) {
|
||||
rtw89_fw_c2h_cmd_handle(rtwdev, skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
@@ -6905,18 +6964,20 @@ void rtw89_fw_c2h_purge_obsoleted_scan_events(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
|
||||
struct sk_buff *skb, *tmp;
|
||||
int limit;
|
||||
struct sk_buff_head c2hq;
|
||||
unsigned long flags;
|
||||
|
||||
lockdep_assert_wiphy(rtwdev->hw->wiphy);
|
||||
|
||||
limit = skb_queue_len(&rtwdev->c2h_queue);
|
||||
__skb_queue_head_init(&c2hq);
|
||||
|
||||
skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) {
|
||||
spin_lock_irqsave(&rtwdev->c2h_queue.lock, flags);
|
||||
skb_queue_splice_init(&rtwdev->c2h_queue, &c2hq);
|
||||
spin_unlock_irqrestore(&rtwdev->c2h_queue.lock, flags);
|
||||
|
||||
skb_queue_walk_safe(&c2hq, skb, tmp) {
|
||||
struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb);
|
||||
|
||||
if (--limit < 0)
|
||||
return;
|
||||
|
||||
if (!attr->is_scan_event || attr->scan_seq == scan_info->seq)
|
||||
continue;
|
||||
|
||||
@@ -6924,9 +6985,13 @@ void rtw89_fw_c2h_purge_obsoleted_scan_events(struct rtw89_dev *rtwdev)
|
||||
"purge obsoleted scan event with seq=%d (cur=%d)\n",
|
||||
attr->scan_seq, scan_info->seq);
|
||||
|
||||
skb_unlink(skb, &rtwdev->c2h_queue);
|
||||
__skb_unlink(skb, &c2hq);
|
||||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&rtwdev->c2h_queue.lock, flags);
|
||||
skb_queue_splice(&c2hq, &rtwdev->c2h_queue);
|
||||
spin_unlock_irqrestore(&rtwdev->c2h_queue.lock, flags);
|
||||
}
|
||||
|
||||
static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev,
|
||||
@@ -7774,15 +7839,23 @@ int rtw89_hw_scan_prep_chan_list_be(struct rtw89_dev *rtwdev,
|
||||
struct ieee80211_channel *channel;
|
||||
struct list_head chan_list;
|
||||
enum rtw89_chan_type type;
|
||||
bool chan_by_rnr;
|
||||
bool random_seq;
|
||||
int ret;
|
||||
u32 idx;
|
||||
|
||||
random_seq = !!(req->flags & NL80211_SCAN_FLAG_RANDOM_SN);
|
||||
chan_by_rnr = rtwdev->chip->support_rnr &&
|
||||
(req->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ);
|
||||
INIT_LIST_HEAD(&chan_list);
|
||||
|
||||
for (idx = 0; idx < req->n_channels; idx++) {
|
||||
channel = req->channels[idx];
|
||||
|
||||
if (channel->band == NL80211_BAND_6GHZ &&
|
||||
!cfg80211_channel_is_psc(channel) && chan_by_rnr)
|
||||
continue;
|
||||
|
||||
ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
|
||||
if (!ch_info) {
|
||||
ret = -ENOMEM;
|
||||
@@ -8030,7 +8103,6 @@ int rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct ieee80211_scan_request *scan_req)
|
||||
{
|
||||
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
|
||||
enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev);
|
||||
struct cfg80211_scan_request *req = &scan_req->req;
|
||||
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
|
||||
@@ -8042,7 +8114,6 @@ int rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
|
||||
};
|
||||
u32 rx_fltr = rtwdev->hal.rx_fltr;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u32 reg;
|
||||
int ret;
|
||||
|
||||
/* clone op and keep it during scan */
|
||||
@@ -8082,8 +8153,7 @@ int rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
|
||||
rx_fltr &= ~B_AX_A_BC;
|
||||
rx_fltr &= ~B_AX_A_A1_MATCH;
|
||||
|
||||
reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx);
|
||||
rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rx_fltr);
|
||||
rtw89_mac_set_rx_fltr(rtwdev, rtwvif_link->mac_idx, rx_fltr);
|
||||
|
||||
rtw89_chanctx_pause(rtwdev, &pause_parm);
|
||||
rtw89_phy_dig_suspend(rtwdev);
|
||||
@@ -8101,20 +8171,17 @@ struct rtw89_hw_scan_complete_cb_data {
|
||||
|
||||
static int rtw89_hw_scan_complete_cb(struct rtw89_dev *rtwdev, void *data)
|
||||
{
|
||||
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
|
||||
enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev);
|
||||
struct rtw89_hw_scan_complete_cb_data *cb_data = data;
|
||||
struct rtw89_vif_link *rtwvif_link = cb_data->rtwvif_link;
|
||||
struct cfg80211_scan_info info = {
|
||||
.aborted = cb_data->aborted,
|
||||
};
|
||||
u32 reg;
|
||||
|
||||
if (!rtwvif_link)
|
||||
return -EINVAL;
|
||||
|
||||
reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx);
|
||||
rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rtwdev->hal.rx_fltr);
|
||||
rtw89_mac_set_rx_fltr(rtwdev, rtwvif_link->mac_idx, rtwdev->hal.rx_fltr);
|
||||
|
||||
rtw89_core_scan_complete(rtwdev, rtwvif_link, true);
|
||||
ieee80211_scan_completed(rtwdev->hw, &info);
|
||||
|
||||
@@ -297,6 +297,7 @@ struct rtw89_fw_hdr_section_info {
|
||||
|
||||
struct rtw89_fw_bin_info {
|
||||
u8 section_num;
|
||||
u32 part_size;
|
||||
u32 hdr_len;
|
||||
bool dynamic_hdr_en;
|
||||
u32 dynamic_hdr_len;
|
||||
@@ -446,6 +447,13 @@ struct rtw89_h2c_ra {
|
||||
#define RTW89_H2C_RA_W3_FIXED_CSI_MODE GENMASK(25, 24)
|
||||
#define RTW89_H2C_RA_W3_FIXED_CSI_GI_LTF GENMASK(28, 26)
|
||||
#define RTW89_H2C_RA_W3_FIXED_CSI_BW GENMASK(31, 29)
|
||||
#define RTW89_H2C_RA_V1_W3_PARTIAL_BW_SU_ER BIT(15)
|
||||
#define RTW89_H2C_RA_V1_W3_FIXED_CSI_RATE_L GENMASK(23, 16)
|
||||
#define RTW89_H2C_RA_V1_W3_IS_NOISY BIT(24)
|
||||
#define RTW89_H2C_RA_V1_W3_PSRA_EN BIT(25)
|
||||
#define RTW89_H2C_RA_V1_W3_MACID_MSB GENMASK(28, 27)
|
||||
#define RTW89_H2C_RA_V1_W3_BAND GENMASK(30, 29)
|
||||
#define RTW89_H2C_RA_V1_W3_NEW_DBGREG BIT(31)
|
||||
|
||||
struct rtw89_h2c_ra_v1 {
|
||||
struct rtw89_h2c_ra v0;
|
||||
@@ -3647,6 +3655,15 @@ struct rtw89_fw_c2h_log_fmt {
|
||||
#define RTW89_C2H_FW_LOG_SIGNATURE 0xA5A5
|
||||
#define RTW89_C2H_FW_LOG_STR_BUF_SIZE 512
|
||||
|
||||
struct rtw89_c2h_bcn_upd_done {
|
||||
struct rtw89_c2h_hdr hdr;
|
||||
__le32 w2;
|
||||
} __packed;
|
||||
|
||||
#define RTW89_C2H_BCN_UPD_DONE_W2_PORT GENMASK(2, 0)
|
||||
#define RTW89_C2H_BCN_UPD_DONE_W2_MBSSID GENMASK(6, 3)
|
||||
#define RTW89_C2H_BCN_UPD_DONE_W2_BAND_IDX BIT(7)
|
||||
|
||||
struct rtw89_c2h_mac_bcnfltr_rpt {
|
||||
__le32 w0;
|
||||
__le32 w1;
|
||||
@@ -3747,6 +3764,47 @@ struct rtw89_c2h_scanofld {
|
||||
#define RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_FUNC(c2h) \
|
||||
le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(15, 8))
|
||||
|
||||
struct rtw89_c2h_mac_tx_rpt {
|
||||
struct rtw89_c2h_hdr hdr;
|
||||
__le32 w2;
|
||||
__le32 w3;
|
||||
__le32 w4;
|
||||
__le32 w5;
|
||||
__le32 w6;
|
||||
__le32 w7;
|
||||
} __packed;
|
||||
|
||||
#define RTW89_C2H_MAC_TX_RPT_W2_TX_STATE GENMASK(7, 6)
|
||||
#define RTW89_C2H_MAC_TX_RPT_W2_SW_DEFINE GENMASK(11, 8)
|
||||
#define RTW89_C2H_MAC_TX_RPT_W5_DATA_TX_CNT GENMASK(13, 8)
|
||||
#define RTW89_C2H_MAC_TX_RPT_W5_DATA_TX_CNT_V1 GENMASK(15, 10)
|
||||
|
||||
struct rtw89_c2h_mac_tx_rpt_v2 {
|
||||
struct rtw89_c2h_hdr hdr;
|
||||
__le32 w2;
|
||||
__le32 w3;
|
||||
__le32 w4;
|
||||
__le32 w5;
|
||||
__le32 w6;
|
||||
__le32 w7;
|
||||
__le32 w8;
|
||||
__le32 w9;
|
||||
__le32 w10;
|
||||
__le32 w11;
|
||||
__le32 w12;
|
||||
__le32 w13;
|
||||
__le32 w14;
|
||||
__le32 w15;
|
||||
__le32 w16;
|
||||
__le32 w17;
|
||||
__le32 w18;
|
||||
__le32 w19;
|
||||
} __packed;
|
||||
|
||||
#define RTW89_C2H_MAC_TX_RPT_W12_TX_STATE_V2 GENMASK(9, 8)
|
||||
#define RTW89_C2H_MAC_TX_RPT_W12_SW_DEFINE_V2 GENMASK(15, 12)
|
||||
#define RTW89_C2H_MAC_TX_RPT_W14_DATA_TX_CNT_V2 GENMASK(15, 10)
|
||||
|
||||
struct rtw89_mac_mcc_tsf_rpt {
|
||||
u32 macid_x;
|
||||
u32 macid_y;
|
||||
@@ -3985,6 +4043,7 @@ enum rtw89_fw_element_id {
|
||||
RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_5GHZ = 25,
|
||||
RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_6GHZ = 26,
|
||||
RTW89_FW_ELEMENT_ID_AFE_PWR_SEQ = 27,
|
||||
RTW89_FW_ELEMENT_ID_DIAG_MAC = 28,
|
||||
|
||||
RTW89_FW_ELEMENT_ID_NUM,
|
||||
};
|
||||
@@ -4162,6 +4221,11 @@ struct rtw89_fw_element_hdr {
|
||||
__le32 val;
|
||||
} __packed infos[];
|
||||
} __packed afe;
|
||||
struct {
|
||||
__le32 rule_size;
|
||||
u8 rsvd[4];
|
||||
u8 rules_and_msgs[];
|
||||
} __packed diag_mac;
|
||||
struct __rtw89_fw_txpwr_element txpwr;
|
||||
struct __rtw89_fw_regd_element regd;
|
||||
} __packed u;
|
||||
@@ -4823,7 +4887,8 @@ int rtw89_fw_h2c_tbtt_tuning(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif_link *rtwvif_link, u32 offset);
|
||||
int rtw89_fw_h2c_pwr_lvl(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
|
||||
int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif,
|
||||
struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr);
|
||||
struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr,
|
||||
enum rtw89_upd_mode upd_mode);
|
||||
int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_sta_link *rtwsta_link);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "phy.h"
|
||||
#include "ps.h"
|
||||
#include "reg.h"
|
||||
#include "ser.h"
|
||||
#include "util.h"
|
||||
|
||||
static const u32 rtw89_mac_mem_base_addrs_ax[RTW89_MAC_MEM_NUM] = {
|
||||
@@ -1294,11 +1295,26 @@ static int rtw89_mac_sub_pwr_seq(struct rtw89_dev *rtwdev, u8 cv_msk,
|
||||
static int rtw89_mac_pwr_seq(struct rtw89_dev *rtwdev,
|
||||
const struct rtw89_pwr_cfg * const *cfg_seq)
|
||||
{
|
||||
u8 intf_msk;
|
||||
int ret;
|
||||
|
||||
switch (rtwdev->hci.type) {
|
||||
case RTW89_HCI_TYPE_PCIE:
|
||||
intf_msk = PWR_INTF_MSK_PCIE;
|
||||
break;
|
||||
case RTW89_HCI_TYPE_USB:
|
||||
intf_msk = PWR_INTF_MSK_USB;
|
||||
break;
|
||||
case RTW89_HCI_TYPE_SDIO:
|
||||
intf_msk = PWR_INTF_MSK_SDIO;
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
for (; *cfg_seq; cfg_seq++) {
|
||||
ret = rtw89_mac_sub_pwr_seq(rtwdev, BIT(rtwdev->hal.cv),
|
||||
PWR_INTF_MSK_PCIE, *cfg_seq);
|
||||
intf_msk, *cfg_seq);
|
||||
if (ret)
|
||||
return -EBUSY;
|
||||
}
|
||||
@@ -1423,13 +1439,15 @@ void rtw89_mac_power_mode_change(struct rtw89_dev *rtwdev, bool enter)
|
||||
if (!ret)
|
||||
break;
|
||||
|
||||
if (i == RPWM_TRY_CNT - 1)
|
||||
if (i == RPWM_TRY_CNT - 1) {
|
||||
rtw89_err(rtwdev, "firmware failed to ack for %s ps mode\n",
|
||||
enter ? "entering" : "leaving");
|
||||
else
|
||||
rtw89_ser_notify(rtwdev, MAC_AX_ERR_ASSERTION);
|
||||
} else {
|
||||
rtw89_debug(rtwdev, RTW89_DBG_UNEXP,
|
||||
"%d time firmware failed to ack for %s ps mode\n",
|
||||
i + 1, enter ? "entering" : "leaving");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1651,6 +1669,8 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
|
||||
/* PCIE 64 */
|
||||
.wde_size0 = {RTW89_WDE_PG_64, 4095, 1,},
|
||||
.wde_size0_v1 = {RTW89_WDE_PG_64, 3328, 0, 0,},
|
||||
/* 8852A USB */
|
||||
.wde_size1 = {RTW89_WDE_PG_64, 768, 0,},
|
||||
/* DLFW */
|
||||
.wde_size4 = {RTW89_WDE_PG_64, 0, 4096,},
|
||||
.wde_size4_v1 = {RTW89_WDE_PG_64, 0, 3328, 0,},
|
||||
@@ -1660,6 +1680,8 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
|
||||
.wde_size7 = {RTW89_WDE_PG_64, 510, 2,},
|
||||
/* DLFW */
|
||||
.wde_size9 = {RTW89_WDE_PG_64, 0, 1024,},
|
||||
/* 8852C USB3.0 */
|
||||
.wde_size17 = {RTW89_WDE_PG_64, 354, 30,},
|
||||
/* 8852C DLFW */
|
||||
.wde_size18 = {RTW89_WDE_PG_64, 0, 2048,},
|
||||
/* 8852C PCIE SCC */
|
||||
@@ -1667,9 +1689,13 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
|
||||
.wde_size23 = {RTW89_WDE_PG_64, 1022, 2,},
|
||||
/* 8852B USB2.0/USB3.0 SCC */
|
||||
.wde_size25 = {RTW89_WDE_PG_64, 162, 94,},
|
||||
/* 8852C USB2.0 */
|
||||
.wde_size31 = {RTW89_WDE_PG_64, 384, 0,},
|
||||
/* PCIE */
|
||||
.ple_size0 = {RTW89_PLE_PG_128, 1520, 16,},
|
||||
.ple_size0_v1 = {RTW89_PLE_PG_128, 2688, 240, 212992,},
|
||||
/* 8852A USB */
|
||||
.ple_size1 = {RTW89_PLE_PG_128, 3184, 16,},
|
||||
.ple_size3_v1 = {RTW89_PLE_PG_128, 2928, 0, 212992,},
|
||||
/* DLFW */
|
||||
.ple_size4 = {RTW89_PLE_PG_128, 64, 1472,},
|
||||
@@ -1678,6 +1704,8 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
|
||||
/* DLFW */
|
||||
.ple_size8 = {RTW89_PLE_PG_128, 64, 960,},
|
||||
.ple_size9 = {RTW89_PLE_PG_128, 2288, 16,},
|
||||
/* 8852C USB */
|
||||
.ple_size17 = {RTW89_PLE_PG_128, 3368, 24,},
|
||||
/* 8852C DLFW */
|
||||
.ple_size18 = {RTW89_PLE_PG_128, 2544, 16,},
|
||||
/* 8852C PCIE SCC */
|
||||
@@ -1686,15 +1714,21 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
|
||||
.ple_size32 = {RTW89_PLE_PG_128, 620, 20,},
|
||||
/* 8852B USB3.0 SCC */
|
||||
.ple_size33 = {RTW89_PLE_PG_128, 632, 8,},
|
||||
/* 8852C USB2.0 */
|
||||
.ple_size34 = {RTW89_PLE_PG_128, 3374, 18,},
|
||||
/* PCIE 64 */
|
||||
.wde_qt0 = {3792, 196, 0, 107,},
|
||||
.wde_qt0_v1 = {3302, 6, 0, 20,},
|
||||
/* 8852A USB */
|
||||
.wde_qt1 = {512, 196, 0, 60,},
|
||||
/* DLFW */
|
||||
.wde_qt4 = {0, 0, 0, 0,},
|
||||
/* PCIE 64 */
|
||||
.wde_qt6 = {448, 48, 0, 16,},
|
||||
/* 8852B PCIE SCC */
|
||||
.wde_qt7 = {446, 48, 0, 16,},
|
||||
/* 8852C USB3.0 */
|
||||
.wde_qt16 = {344, 2, 0, 8,},
|
||||
/* 8852C DLFW */
|
||||
.wde_qt17 = {0, 0, 0, 0,},
|
||||
/* 8852C PCIE SCC */
|
||||
@@ -1702,6 +1736,8 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
|
||||
.wde_qt23 = {958, 48, 0, 16,},
|
||||
/* 8852B USB2.0/USB3.0 SCC */
|
||||
.wde_qt25 = {152, 2, 0, 8,},
|
||||
/* 8852C USB2.0 */
|
||||
.wde_qt31 = {338, 6, 0, 40,},
|
||||
.ple_qt0 = {320, 320, 32, 16, 13, 13, 292, 292, 64, 18, 1, 4, 0,},
|
||||
.ple_qt1 = {320, 320, 32, 16, 1316, 1316, 1595, 1595, 1367, 1321, 1, 1307, 0,},
|
||||
/* PCIE SCC */
|
||||
@@ -1713,6 +1749,13 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
|
||||
.ple_qt13 = {0, 0, 16, 48, 0, 0, 0, 0, 0, 0, 0,},
|
||||
/* PCIE 64 */
|
||||
.ple_qt18 = {147, 0, 16, 20, 17, 13, 89, 0, 32, 14, 8, 0,},
|
||||
/* 8852A USB SCC */
|
||||
.ple_qt25 = {1536, 0, 16, 48, 13, 13, 360, 0, 32, 40, 8, 0,},
|
||||
.ple_qt26 = {2654, 0, 1134, 48, 64, 13, 1478, 0, 64, 128, 120, 0,},
|
||||
/* USB 52C USB3.0 */
|
||||
.ple_qt42 = {1068, 0, 16, 48, 4, 13, 178, 0, 16, 1, 8, 16, 0,},
|
||||
/* USB 52C USB3.0 */
|
||||
.ple_qt43 = {3068, 0, 32, 48, 4, 13, 178, 0, 16, 1, 8, 16, 0,},
|
||||
/* DLFW 52C */
|
||||
.ple_qt44 = {0, 0, 16, 256, 0, 0, 0, 0, 0, 0, 0, 0,},
|
||||
/* DLFW 52C */
|
||||
@@ -1732,6 +1775,10 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
|
||||
/* USB3.0 52B 92K */
|
||||
.ple_qt74 = {286, 0, 16, 48, 4, 13, 178, 0, 32, 14, 8, 0, 0,},
|
||||
.ple_qt75 = {286, 0, 32, 48, 37, 13, 211, 0, 65, 14, 24, 0, 0,},
|
||||
/* USB2.0 52C */
|
||||
.ple_qt78 = {1560, 0, 16, 48, 13, 13, 390, 0, 32, 38, 8, 16, 0,},
|
||||
/* USB2.0 52C */
|
||||
.ple_qt79 = {1560, 0, 32, 48, 1253, 13, 1630, 0, 1272, 38, 120, 1256, 0,},
|
||||
/* 8852A PCIE WOW */
|
||||
.ple_qt_52a_wow = {264, 0, 32, 20, 64, 13, 1005, 0, 64, 128, 120,},
|
||||
/* 8852B PCIE WOW */
|
||||
@@ -2324,7 +2371,8 @@ static int sec_eng_init_ax(struct rtw89_dev *rtwdev)
|
||||
if (chip->chip_id == RTL8852C)
|
||||
val |= B_AX_UC_MGNT_DEC;
|
||||
if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B ||
|
||||
chip->chip_id == RTL8851B)
|
||||
chip->chip_id == RTL8851B ||
|
||||
(chip->chip_id == RTL8852C && rtwdev->hci.type == RTW89_HCI_TYPE_USB))
|
||||
val &= ~B_AX_TX_PARTIAL_MODE;
|
||||
rtw89_write32(rtwdev, R_AX_SEC_ENG_CTRL, val);
|
||||
|
||||
@@ -2495,6 +2543,20 @@ static int rtw89_mac_typ_fltr_opt_ax(struct rtw89_dev *rtwdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtw89_mac_set_rx_fltr(struct rtw89_dev *rtwdev, u8 mac_idx, u32 rx_fltr)
|
||||
{
|
||||
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
|
||||
u32 reg;
|
||||
u32 val;
|
||||
|
||||
reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, mac_idx);
|
||||
|
||||
val = rtw89_read32(rtwdev, reg);
|
||||
/* B_AX_RX_FLTR_CFG_MASK is not a consecutive bit mask */
|
||||
val = (val & ~B_AX_RX_FLTR_CFG_MASK) | (rx_fltr & B_AX_RX_FLTR_CFG_MASK);
|
||||
rtw89_write32(rtwdev, reg, val);
|
||||
}
|
||||
|
||||
static int rx_fltr_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
|
||||
{
|
||||
int ret, i;
|
||||
@@ -3980,8 +4042,15 @@ static void rtw89_mac_dmac_func_pre_en_ax(struct rtw89_dev *rtwdev)
|
||||
|
||||
val = rtw89_read32(rtwdev, R_AX_HAXI_INIT_CFG1);
|
||||
val &= ~(B_AX_DMA_MODE_MASK | B_AX_STOP_AXI_MST);
|
||||
val |= FIELD_PREP(B_AX_DMA_MODE_MASK, DMA_MOD_PCIE_1B) |
|
||||
B_AX_TXHCI_EN_V1 | B_AX_RXHCI_EN_V1;
|
||||
val |= B_AX_TXHCI_EN_V1 | B_AX_RXHCI_EN_V1;
|
||||
|
||||
if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE)
|
||||
val |= FIELD_PREP(B_AX_DMA_MODE_MASK, DMA_MOD_PCIE_1B);
|
||||
else if (rtwdev->hci.type == RTW89_HCI_TYPE_USB)
|
||||
val |= FIELD_PREP(B_AX_DMA_MODE_MASK, DMA_MOD_USB);
|
||||
else
|
||||
val |= FIELD_PREP(B_AX_DMA_MODE_MASK, DMA_MOD_SDIO);
|
||||
|
||||
rtw89_write32(rtwdev, R_AX_HAXI_INIT_CFG1, val);
|
||||
|
||||
rtw89_write32_clr(rtwdev, R_AX_HAXI_DMA_STOP1,
|
||||
@@ -4049,9 +4118,12 @@ int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb)
|
||||
rtw89_mac_ctrl_hci_dma_trx(rtwdev, true);
|
||||
|
||||
if (include_bb) {
|
||||
rtw89_chip_bb_preinit(rtwdev, RTW89_PHY_0);
|
||||
if (rtwdev->dbcc_en)
|
||||
rtw89_chip_bb_preinit(rtwdev, RTW89_PHY_1);
|
||||
/* Only call BB preinit including configuration of BB MCU for
|
||||
* the chips which need to download BB MCU firmware. Otherwise,
|
||||
* calling preinit later to prevent touching registers affecting
|
||||
* download firmware.
|
||||
*/
|
||||
rtw89_chip_bb_preinit(rtwdev);
|
||||
}
|
||||
|
||||
ret = rtw89_mac_dmac_pre_init(rtwdev);
|
||||
@@ -4071,6 +4143,17 @@ int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtw89_mac_preinit(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = rtw89_mac_pwr_on(rtwdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtw89_mac_init(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
|
||||
@@ -4078,10 +4161,6 @@ int rtw89_mac_init(struct rtw89_dev *rtwdev)
|
||||
bool include_bb = !!chip->bbmcu_nr;
|
||||
int ret;
|
||||
|
||||
ret = rtw89_mac_pwr_on(rtwdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = rtw89_mac_partial_init(rtwdev, include_bb);
|
||||
if (ret)
|
||||
goto fail;
|
||||
@@ -4770,7 +4849,7 @@ int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_l
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL);
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL, RTW89_ROLE_CREATE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -4795,7 +4874,7 @@ int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif
|
||||
|
||||
rtw89_cam_deinit(rtwdev, rtwvif_link);
|
||||
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL);
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL, RTW89_ROLE_REMOVE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -5244,8 +5323,19 @@ rtw89_mac_c2h_bcn_cnt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
|
||||
}
|
||||
|
||||
static void
|
||||
rtw89_mac_c2h_bcn_upd_done(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
|
||||
rtw89_mac_c2h_bcn_upd_done(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 len)
|
||||
{
|
||||
const struct rtw89_c2h_bcn_upd_done *c2h =
|
||||
(const struct rtw89_c2h_bcn_upd_done *)skb_c2h->data;
|
||||
u8 band, port, mbssid;
|
||||
|
||||
port = le32_get_bits(c2h->w2, RTW89_C2H_BCN_UPD_DONE_W2_PORT);
|
||||
mbssid = le32_get_bits(c2h->w2, RTW89_C2H_BCN_UPD_DONE_W2_MBSSID);
|
||||
band = le32_get_bits(c2h->w2, RTW89_C2H_BCN_UPD_DONE_W2_BAND_IDX);
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_FW,
|
||||
"BCN update done on port:%d mbssid:%d band:%d\n",
|
||||
port, mbssid, band);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -5457,6 +5547,72 @@ rtw89_mac_c2h_mcc_status_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32
|
||||
rtw89_complete_cond(&rtwdev->mcc.wait, cond, &data);
|
||||
}
|
||||
|
||||
static void
|
||||
rtw89_mac_c2h_tx_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
|
||||
{
|
||||
struct rtw89_tx_rpt *tx_rpt = &rtwdev->tx_rpt;
|
||||
struct rtw89_tx_skb_data *skb_data;
|
||||
u8 sw_define, tx_status, txcnt;
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (rtwdev->chip->chip_id == RTL8922A) {
|
||||
const struct rtw89_c2h_mac_tx_rpt_v2 *rpt_v2;
|
||||
|
||||
rpt_v2 = (const struct rtw89_c2h_mac_tx_rpt_v2 *)c2h->data;
|
||||
sw_define = le32_get_bits(rpt_v2->w12,
|
||||
RTW89_C2H_MAC_TX_RPT_W12_SW_DEFINE_V2);
|
||||
tx_status = le32_get_bits(rpt_v2->w12,
|
||||
RTW89_C2H_MAC_TX_RPT_W12_TX_STATE_V2);
|
||||
txcnt = le32_get_bits(rpt_v2->w14,
|
||||
RTW89_C2H_MAC_TX_RPT_W14_DATA_TX_CNT_V2);
|
||||
} else {
|
||||
const struct rtw89_c2h_mac_tx_rpt *rpt;
|
||||
|
||||
rpt = (const struct rtw89_c2h_mac_tx_rpt *)c2h->data;
|
||||
sw_define = le32_get_bits(rpt->w2, RTW89_C2H_MAC_TX_RPT_W2_SW_DEFINE);
|
||||
tx_status = le32_get_bits(rpt->w2, RTW89_C2H_MAC_TX_RPT_W2_TX_STATE);
|
||||
if (rtwdev->chip->chip_id == RTL8852C)
|
||||
txcnt = le32_get_bits(rpt->w5,
|
||||
RTW89_C2H_MAC_TX_RPT_W5_DATA_TX_CNT_V1);
|
||||
else
|
||||
txcnt = le32_get_bits(rpt->w5,
|
||||
RTW89_C2H_MAC_TX_RPT_W5_DATA_TX_CNT);
|
||||
}
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_TXRX,
|
||||
"C2H TX RPT: sn %d, tx_status %d, txcnt %d\n",
|
||||
sw_define, tx_status, txcnt);
|
||||
|
||||
/* claim sw_define is not over size of tx_rpt->skbs[] */
|
||||
static_assert(hweight32(RTW89_MAX_TX_RPTS_MASK) ==
|
||||
hweight32(RTW89_C2H_MAC_TX_RPT_W12_SW_DEFINE_V2) &&
|
||||
hweight32(RTW89_MAX_TX_RPTS_MASK) ==
|
||||
hweight32(RTW89_C2H_MAC_TX_RPT_W2_SW_DEFINE));
|
||||
|
||||
scoped_guard(spinlock_irqsave, &tx_rpt->skb_lock) {
|
||||
skb = tx_rpt->skbs[sw_define];
|
||||
|
||||
/* skip if no skb (normally shouldn't happen) */
|
||||
if (!skb) {
|
||||
rtw89_debug(rtwdev, RTW89_DBG_TXRX,
|
||||
"C2H TX RPT: no skb found in queue\n");
|
||||
return;
|
||||
}
|
||||
|
||||
skb_data = RTW89_TX_SKB_CB(skb);
|
||||
|
||||
/* skip if TX attempt has failed and retry limit has not been
|
||||
* reached yet
|
||||
*/
|
||||
if (tx_status != RTW89_TX_DONE &&
|
||||
txcnt != skb_data->tx_pkt_cnt_lmt)
|
||||
return;
|
||||
|
||||
tx_rpt->skbs[sw_define] = NULL;
|
||||
rtw89_tx_rpt_tx_status(rtwdev, skb, tx_status);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rtw89_mac_c2h_mrc_tsf_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
|
||||
{
|
||||
@@ -5691,6 +5847,12 @@ void (* const rtw89_mac_c2h_mcc_handler[])(struct rtw89_dev *rtwdev,
|
||||
[RTW89_MAC_C2H_FUNC_MCC_STATUS_RPT] = rtw89_mac_c2h_mcc_status_rpt,
|
||||
};
|
||||
|
||||
static
|
||||
void (* const rtw89_mac_c2h_misc_handler[])(struct rtw89_dev *rtwdev,
|
||||
struct sk_buff *c2h, u32 len) = {
|
||||
[RTW89_MAC_C2H_FUNC_TX_REPORT] = rtw89_mac_c2h_tx_rpt,
|
||||
};
|
||||
|
||||
static
|
||||
void (* const rtw89_mac_c2h_mlo_handler[])(struct rtw89_dev *rtwdev,
|
||||
struct sk_buff *c2h, u32 len) = {
|
||||
@@ -5777,6 +5939,8 @@ bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
|
||||
}
|
||||
case RTW89_MAC_C2H_CLASS_MCC:
|
||||
return true;
|
||||
case RTW89_MAC_C2H_CLASS_MISC:
|
||||
return true;
|
||||
case RTW89_MAC_C2H_CLASS_MLO:
|
||||
return true;
|
||||
case RTW89_MAC_C2H_CLASS_MRC:
|
||||
@@ -5812,6 +5976,10 @@ void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
|
||||
if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MCC)
|
||||
handler = rtw89_mac_c2h_mcc_handler[func];
|
||||
break;
|
||||
case RTW89_MAC_C2H_CLASS_MISC:
|
||||
if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MISC)
|
||||
handler = rtw89_mac_c2h_misc_handler[func];
|
||||
break;
|
||||
case RTW89_MAC_C2H_CLASS_MLO:
|
||||
if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MLO)
|
||||
handler = rtw89_mac_c2h_mlo_handler[func];
|
||||
|
||||
@@ -432,6 +432,12 @@ enum rtw89_mac_c2h_mcc_func {
|
||||
NUM_OF_RTW89_MAC_C2H_FUNC_MCC,
|
||||
};
|
||||
|
||||
enum rtw89_mac_c2h_misc_func {
|
||||
RTW89_MAC_C2H_FUNC_TX_REPORT = 1,
|
||||
|
||||
NUM_OF_RTW89_MAC_C2H_FUNC_MISC,
|
||||
};
|
||||
|
||||
enum rtw89_mac_c2h_mlo_func {
|
||||
RTW89_MAC_C2H_FUNC_MLO_GET_TBL = 0x0,
|
||||
RTW89_MAC_C2H_FUNC_MLO_EMLSR_TRANS_DONE = 0x1,
|
||||
@@ -470,6 +476,7 @@ enum rtw89_mac_c2h_class {
|
||||
RTW89_MAC_C2H_CLASS_WOW = 0x3,
|
||||
RTW89_MAC_C2H_CLASS_MCC = 0x4,
|
||||
RTW89_MAC_C2H_CLASS_FWDBG = 0x5,
|
||||
RTW89_MAC_C2H_CLASS_MISC = 0x9,
|
||||
RTW89_MAC_C2H_CLASS_MLO = 0xc,
|
||||
RTW89_MAC_C2H_CLASS_MRC = 0xe,
|
||||
RTW89_MAC_C2H_CLASS_AP = 0x18,
|
||||
@@ -574,8 +581,6 @@ enum rtw89_mac_bf_rrsc_rate {
|
||||
RTW89_MAC_BF_RRSC_MAX = 32
|
||||
};
|
||||
|
||||
#define RTW89_R32_EA 0xEAEAEAEA
|
||||
#define RTW89_R32_DEAD 0xDEADBEEF
|
||||
#define MAC_REG_POOL_COUNT 10
|
||||
#define ACCESS_CMAC(_addr) \
|
||||
({typeof(_addr) __addr = (_addr); \
|
||||
@@ -917,36 +922,45 @@ struct rtw89_mac_size_set {
|
||||
const struct rtw89_hfc_prec_cfg hfc_prec_cfg_c0;
|
||||
const struct rtw89_hfc_prec_cfg hfc_prec_cfg_c2;
|
||||
const struct rtw89_dle_size wde_size0;
|
||||
const struct rtw89_dle_size wde_size1;
|
||||
const struct rtw89_dle_size wde_size0_v1;
|
||||
const struct rtw89_dle_size wde_size4;
|
||||
const struct rtw89_dle_size wde_size4_v1;
|
||||
const struct rtw89_dle_size wde_size6;
|
||||
const struct rtw89_dle_size wde_size7;
|
||||
const struct rtw89_dle_size wde_size9;
|
||||
const struct rtw89_dle_size wde_size17;
|
||||
const struct rtw89_dle_size wde_size18;
|
||||
const struct rtw89_dle_size wde_size19;
|
||||
const struct rtw89_dle_size wde_size23;
|
||||
const struct rtw89_dle_size wde_size25;
|
||||
const struct rtw89_dle_size wde_size31;
|
||||
const struct rtw89_dle_size ple_size0;
|
||||
const struct rtw89_dle_size ple_size1;
|
||||
const struct rtw89_dle_size ple_size0_v1;
|
||||
const struct rtw89_dle_size ple_size3_v1;
|
||||
const struct rtw89_dle_size ple_size4;
|
||||
const struct rtw89_dle_size ple_size6;
|
||||
const struct rtw89_dle_size ple_size8;
|
||||
const struct rtw89_dle_size ple_size9;
|
||||
const struct rtw89_dle_size ple_size17;
|
||||
const struct rtw89_dle_size ple_size18;
|
||||
const struct rtw89_dle_size ple_size19;
|
||||
const struct rtw89_dle_size ple_size32;
|
||||
const struct rtw89_dle_size ple_size33;
|
||||
const struct rtw89_dle_size ple_size34;
|
||||
const struct rtw89_wde_quota wde_qt0;
|
||||
const struct rtw89_wde_quota wde_qt1;
|
||||
const struct rtw89_wde_quota wde_qt0_v1;
|
||||
const struct rtw89_wde_quota wde_qt4;
|
||||
const struct rtw89_wde_quota wde_qt6;
|
||||
const struct rtw89_wde_quota wde_qt7;
|
||||
const struct rtw89_wde_quota wde_qt16;
|
||||
const struct rtw89_wde_quota wde_qt17;
|
||||
const struct rtw89_wde_quota wde_qt18;
|
||||
const struct rtw89_wde_quota wde_qt23;
|
||||
const struct rtw89_wde_quota wde_qt25;
|
||||
const struct rtw89_wde_quota wde_qt31;
|
||||
const struct rtw89_ple_quota ple_qt0;
|
||||
const struct rtw89_ple_quota ple_qt1;
|
||||
const struct rtw89_ple_quota ple_qt4;
|
||||
@@ -954,6 +968,10 @@ struct rtw89_mac_size_set {
|
||||
const struct rtw89_ple_quota ple_qt9;
|
||||
const struct rtw89_ple_quota ple_qt13;
|
||||
const struct rtw89_ple_quota ple_qt18;
|
||||
const struct rtw89_ple_quota ple_qt25;
|
||||
const struct rtw89_ple_quota ple_qt26;
|
||||
const struct rtw89_ple_quota ple_qt42;
|
||||
const struct rtw89_ple_quota ple_qt43;
|
||||
const struct rtw89_ple_quota ple_qt44;
|
||||
const struct rtw89_ple_quota ple_qt45;
|
||||
const struct rtw89_ple_quota ple_qt46;
|
||||
@@ -965,6 +983,8 @@ struct rtw89_mac_size_set {
|
||||
const struct rtw89_ple_quota ple_qt73;
|
||||
const struct rtw89_ple_quota ple_qt74;
|
||||
const struct rtw89_ple_quota ple_qt75;
|
||||
const struct rtw89_ple_quota ple_qt78;
|
||||
const struct rtw89_ple_quota ple_qt79;
|
||||
const struct rtw89_ple_quota ple_qt_52a_wow;
|
||||
const struct rtw89_ple_quota ple_qt_52b_wow;
|
||||
const struct rtw89_ple_quota ple_qt_52bt_wow;
|
||||
@@ -1181,6 +1201,7 @@ rtw89_write32_port_set(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_l
|
||||
int rtw89_mac_pwr_on(struct rtw89_dev *rtwdev);
|
||||
void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev);
|
||||
int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb);
|
||||
int rtw89_mac_preinit(struct rtw89_dev *rtwdev);
|
||||
int rtw89_mac_init(struct rtw89_dev *rtwdev);
|
||||
int rtw89_mac_dle_init(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode,
|
||||
enum rtw89_qta_mode ext_mode);
|
||||
@@ -1319,6 +1340,7 @@ int rtw89_mac_cfg_ppdu_status_bands(struct rtw89_dev *rtwdev, bool enable)
|
||||
return rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_1, enable);
|
||||
}
|
||||
|
||||
void rtw89_mac_set_rx_fltr(struct rtw89_dev *rtwdev, u8 mac_idx, u32 rx_fltr);
|
||||
void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev);
|
||||
void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop);
|
||||
int rtw89_mac_coex_init(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex *coex);
|
||||
@@ -1609,4 +1631,92 @@ int rtw89_mac_scan_offload(struct rtw89_dev *rtwdev,
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline
|
||||
void rtw89_tx_rpt_init(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_core_tx_request *tx_req)
|
||||
{
|
||||
struct rtw89_tx_rpt *tx_rpt = &rtwdev->tx_rpt;
|
||||
|
||||
if (!rtwdev->hci.tx_rpt_enabled)
|
||||
return;
|
||||
|
||||
tx_req->desc_info.report = true;
|
||||
/* firmware maintains a 4-bit sequence number */
|
||||
tx_req->desc_info.sn = atomic_inc_return(&tx_rpt->sn) &
|
||||
RTW89_MAX_TX_RPTS_MASK;
|
||||
tx_req->desc_info.tx_cnt_lmt_en = true;
|
||||
tx_req->desc_info.tx_cnt_lmt = 8;
|
||||
}
|
||||
|
||||
static inline
|
||||
bool rtw89_is_tx_rpt_skb(struct rtw89_dev *rtwdev, struct sk_buff *skb)
|
||||
{
|
||||
struct rtw89_tx_skb_data *skb_data = RTW89_TX_SKB_CB(skb);
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
|
||||
return rtw89_core_is_tx_wait(rtwdev, skb_data) ||
|
||||
(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS);
|
||||
}
|
||||
|
||||
static inline
|
||||
void rtw89_tx_rpt_tx_status(struct rtw89_dev *rtwdev, struct sk_buff *skb,
|
||||
u8 tx_status)
|
||||
{
|
||||
struct rtw89_tx_skb_data *skb_data = RTW89_TX_SKB_CB(skb);
|
||||
struct ieee80211_tx_info *info;
|
||||
|
||||
if (rtw89_core_tx_wait_complete(rtwdev, skb_data, tx_status))
|
||||
return;
|
||||
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
ieee80211_tx_info_clear_status(info);
|
||||
|
||||
if (tx_status == RTW89_TX_DONE)
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
else
|
||||
info->flags &= ~IEEE80211_TX_STAT_ACK;
|
||||
|
||||
ieee80211_tx_status_irqsafe(rtwdev->hw, skb);
|
||||
}
|
||||
|
||||
static inline
|
||||
void rtw89_tx_rpt_skb_add(struct rtw89_dev *rtwdev, struct sk_buff *skb)
|
||||
{
|
||||
struct rtw89_tx_rpt *tx_rpt = &rtwdev->tx_rpt;
|
||||
struct rtw89_tx_skb_data *skb_data;
|
||||
u8 idx;
|
||||
|
||||
skb_data = RTW89_TX_SKB_CB(skb);
|
||||
idx = skb_data->tx_rpt_sn;
|
||||
|
||||
scoped_guard(spinlock_irqsave, &tx_rpt->skb_lock) {
|
||||
/* if skb having the similar seq number is still in the queue,
|
||||
* this means the queue is overflowed - it isn't normal and
|
||||
* should indicate firmware doesn't provide TX reports in time;
|
||||
* report the old skb as dropped, we can't do much more here
|
||||
*/
|
||||
if (tx_rpt->skbs[idx])
|
||||
rtw89_tx_rpt_tx_status(rtwdev, tx_rpt->skbs[idx],
|
||||
RTW89_TX_MACID_DROP);
|
||||
tx_rpt->skbs[idx] = skb;
|
||||
}
|
||||
}
|
||||
|
||||
static inline
|
||||
void rtw89_tx_rpt_skbs_purge(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_tx_rpt *tx_rpt = &rtwdev->tx_rpt;
|
||||
struct sk_buff *skbs[RTW89_MAX_TX_RPTS];
|
||||
|
||||
scoped_guard(spinlock_irqsave, &tx_rpt->skb_lock) {
|
||||
memcpy(skbs, tx_rpt->skbs, sizeof(tx_rpt->skbs));
|
||||
memset(tx_rpt->skbs, 0, sizeof(tx_rpt->skbs));
|
||||
}
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(skbs); i++)
|
||||
if (skbs[i])
|
||||
rtw89_tx_rpt_tx_status(rtwdev, skbs[i],
|
||||
RTW89_TX_MACID_DROP);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -220,6 +220,8 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
|
||||
if (ret)
|
||||
goto unset_link;
|
||||
|
||||
rtwdev->pure_monitor_mode_vif = vif->type == NL80211_IFTYPE_MONITOR ?
|
||||
rtwvif : NULL;
|
||||
rtw89_recalc_lps(rtwdev);
|
||||
return 0;
|
||||
|
||||
@@ -267,6 +269,8 @@ bottom:
|
||||
rtw89_core_release_bit_map(rtwdev->hw_port, port);
|
||||
rtw89_release_mac_id(rtwdev, macid);
|
||||
|
||||
rtwdev->pure_monitor_mode_vif = NULL;
|
||||
|
||||
rtw89_recalc_lps(rtwdev);
|
||||
rtw89_enter_ips_by_hwflags(rtwdev);
|
||||
}
|
||||
@@ -303,7 +307,6 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,
|
||||
u64 multicast)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
|
||||
u32 rx_fltr;
|
||||
|
||||
lockdep_assert_wiphy(hw->wiphy);
|
||||
@@ -365,16 +368,10 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,
|
||||
rx_fltr &= ~B_AX_A_A1_MATCH;
|
||||
}
|
||||
|
||||
rtw89_write32_mask(rtwdev,
|
||||
rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0),
|
||||
B_AX_RX_FLTR_CFG_MASK,
|
||||
rx_fltr);
|
||||
rtw89_mac_set_rx_fltr(rtwdev, RTW89_MAC_0, rx_fltr);
|
||||
if (!rtwdev->dbcc_en)
|
||||
return;
|
||||
rtw89_write32_mask(rtwdev,
|
||||
rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_1),
|
||||
B_AX_RX_FLTR_CFG_MASK,
|
||||
rx_fltr);
|
||||
rtw89_mac_set_rx_fltr(rtwdev, RTW89_MAC_1, rx_fltr);
|
||||
}
|
||||
|
||||
static const u8 ac_to_fw_idx[IEEE80211_NUM_ACS] = {
|
||||
@@ -718,6 +715,17 @@ static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw,
|
||||
|
||||
if (changed & BSS_CHANGED_ARP_FILTER)
|
||||
rtwvif->ip_addr = vif->cfg.arp_addr_list[0];
|
||||
|
||||
if (changed & BSS_CHANGED_MLD_VALID_LINKS) {
|
||||
struct rtw89_vif_link *cur = rtw89_get_designated_link(rtwvif);
|
||||
|
||||
rtw89_chip_rfk_channel(rtwdev, cur);
|
||||
|
||||
if (hweight16(vif->active_links) == 1)
|
||||
rtwvif->mlo_mode = RTW89_MLO_MODE_MLSR;
|
||||
else
|
||||
rtwvif->mlo_mode = RTW89_MLO_MODE_EMLSR;
|
||||
}
|
||||
}
|
||||
|
||||
static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw,
|
||||
@@ -744,7 +752,7 @@ static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw,
|
||||
if (changed & BSS_CHANGED_BSSID) {
|
||||
ether_addr_copy(rtwvif_link->bssid, conf->bssid);
|
||||
rtw89_cam_bssid_changed(rtwdev, rtwvif_link);
|
||||
rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL);
|
||||
rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL, RTW89_ROLE_INFO_CHANGE);
|
||||
WRITE_ONCE(rtwvif_link->sync_bcn_tsf, 0);
|
||||
}
|
||||
|
||||
@@ -803,7 +811,7 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw,
|
||||
rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, NULL);
|
||||
rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, NULL, RTW89_ROLE_TYPE_CHANGE);
|
||||
rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true);
|
||||
rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL);
|
||||
rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL, RTW89_ROLE_TYPE_CHANGE);
|
||||
rtw89_chip_rfk_channel(rtwdev, rtwvif_link);
|
||||
|
||||
if (RTW89_CHK_FW_FEATURE(NOTIFY_AP_INFO, &rtwdev->fw)) {
|
||||
@@ -954,6 +962,7 @@ static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
}
|
||||
break;
|
||||
case DISABLE_KEY:
|
||||
flush_work(&rtwdev->txq_work);
|
||||
rtw89_hci_flush_queues(rtwdev, BIT(rtwdev->hw->queues) - 1,
|
||||
false);
|
||||
rtw89_mac_flush_txq(rtwdev, BIT(rtwdev->hw->queues) - 1, false);
|
||||
@@ -1132,12 +1141,17 @@ int rtw89_ops_set_antenna(struct ieee80211_hw *hw, int radio_idx, u32 tx_ant, u3
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
struct rtw89_hal *hal = &rtwdev->hal;
|
||||
const struct rtw89_chip_info *chip;
|
||||
|
||||
lockdep_assert_wiphy(hw->wiphy);
|
||||
|
||||
chip = rtwdev->chip;
|
||||
|
||||
if (hal->ant_diversity) {
|
||||
if (tx_ant != rx_ant || hweight32(tx_ant) != 1)
|
||||
return -EINVAL;
|
||||
} else if (chip->ops->cfg_txrx_path) {
|
||||
/* With cfg_txrx_path ops, chips can configure rx_ant */
|
||||
} else if (rx_ant != hw->wiphy->available_antennas_rx && rx_ant != hal->antenna_rx) {
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1531,10 +1545,29 @@ static bool rtw89_ops_can_activate_links(struct ieee80211_hw *hw,
|
||||
u16 active_links)
|
||||
{
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
|
||||
u16 current_links = vif->active_links;
|
||||
struct rtw89_vif_ml_trans trans = {
|
||||
.mediate_links = current_links | active_links,
|
||||
.links_to_del = current_links & ~active_links,
|
||||
.links_to_add = active_links & ~current_links,
|
||||
};
|
||||
|
||||
lockdep_assert_wiphy(hw->wiphy);
|
||||
|
||||
return rtw89_can_work_on_links(rtwdev, vif, active_links);
|
||||
if (!rtw89_can_work_on_links(rtwdev, vif, active_links))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Leave LPS at the beginning of ieee80211_set_active_links().
|
||||
* Because the entire process takes the same lock as our track
|
||||
* work, LPS will not enter during ieee80211_set_active_links().
|
||||
*/
|
||||
rtw89_leave_lps(rtwdev);
|
||||
|
||||
rtwvif->ml_trans = trans;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __rtw89_ops_clr_vif_links(struct rtw89_dev *rtwdev,
|
||||
@@ -1579,6 +1612,36 @@ static int __rtw89_ops_set_vif_links(struct rtw89_dev *rtwdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rtw89_vif_cfg_fw_links(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif,
|
||||
unsigned long links, bool en)
|
||||
{
|
||||
struct rtw89_vif_link *rtwvif_link;
|
||||
unsigned int link_id;
|
||||
|
||||
for_each_set_bit(link_id, &links, IEEE80211_MLD_MAX_NUM_LINKS) {
|
||||
rtwvif_link = rtwvif->links[link_id];
|
||||
if (unlikely(!rtwvif_link))
|
||||
continue;
|
||||
|
||||
rtw89_fw_h2c_mlo_link_cfg(rtwdev, rtwvif_link, en);
|
||||
}
|
||||
}
|
||||
|
||||
static void rtw89_vif_update_fw_links(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif,
|
||||
u16 current_links)
|
||||
{
|
||||
struct rtw89_vif_ml_trans *trans = &rtwvif->ml_trans;
|
||||
|
||||
/* Do follow-up when all updating links exist. */
|
||||
if (current_links != trans->mediate_links)
|
||||
return;
|
||||
|
||||
rtw89_vif_cfg_fw_links(rtwdev, rtwvif, trans->links_to_del, false);
|
||||
rtw89_vif_cfg_fw_links(rtwdev, rtwvif, trans->links_to_add, true);
|
||||
}
|
||||
|
||||
static
|
||||
int rtw89_ops_change_vif_links(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
@@ -1620,6 +1683,8 @@ int rtw89_ops_change_vif_links(struct ieee80211_hw *hw,
|
||||
if (rtwdev->scanning)
|
||||
rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif);
|
||||
|
||||
rtw89_vif_update_fw_links(rtwdev, rtwvif, old_links);
|
||||
|
||||
if (!old_links)
|
||||
__rtw89_ops_clr_vif_links(rtwdev, rtwvif,
|
||||
BIT(RTW89_VIF_IDLE_LINK_ID));
|
||||
|
||||
@@ -458,6 +458,7 @@ static void set_cpu_en(struct rtw89_dev *rtwdev, bool include_bb)
|
||||
|
||||
static int wcpu_on(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw)
|
||||
{
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
u32 val32;
|
||||
int ret;
|
||||
|
||||
@@ -479,6 +480,7 @@ static int wcpu_on(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw)
|
||||
|
||||
rtw89_write32(rtwdev, R_BE_UDM1, 0);
|
||||
rtw89_write32(rtwdev, R_BE_UDM2, 0);
|
||||
rtw89_write32(rtwdev, R_BE_BOOT_DBG, 0x0);
|
||||
rtw89_write32(rtwdev, R_BE_HALT_H2C, 0);
|
||||
rtw89_write32(rtwdev, R_BE_HALT_C2H, 0);
|
||||
rtw89_write32(rtwdev, R_BE_HALT_H2C_CTRL, 0);
|
||||
@@ -493,6 +495,11 @@ static int wcpu_on(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw)
|
||||
B_BE_WDT_WAKE_PCIE_EN | B_BE_WDT_WAKE_USB_EN);
|
||||
rtw89_write32_clr(rtwdev, R_BE_WCPU_FW_CTRL,
|
||||
B_BE_WDT_PLT_RST_EN | B_BE_WCPU_ROM_CUT_GET);
|
||||
rtw89_write32(rtwdev, R_BE_SECURE_BOOT_MALLOC_INFO, 0);
|
||||
rtw89_write32_clr(rtwdev, R_BE_GPIO_MUXCFG, B_BE_BOOT_MODE);
|
||||
|
||||
if (chip->chip_id != RTL8922A)
|
||||
rtw89_write32_set(rtwdev, R_BE_WCPU_FW_CTRL, B_BE_HOST_EXIST);
|
||||
|
||||
rtw89_write16_mask(rtwdev, R_BE_BOOT_REASON, B_BE_BOOT_REASON_MASK, boot_reason);
|
||||
rtw89_write32_clr(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_WCPU_EN);
|
||||
@@ -2020,7 +2027,7 @@ int rtw89_mac_cfg_ppdu_status_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool enab
|
||||
}
|
||||
|
||||
rtw89_write32_mask(rtwdev, R_BE_HW_PPDU_STATUS, B_BE_FWD_PPDU_STAT_MASK, 3);
|
||||
rtw89_write32(rtwdev, reg, B_BE_PPDU_STAT_RPT_EN | B_BE_PPDU_MAC_INFO |
|
||||
rtw89_write32(rtwdev, reg, B_BE_PPDU_STAT_RPT_EN |
|
||||
B_BE_APP_RX_CNT_RPT | B_BE_APP_PLCP_HDR_RPT |
|
||||
B_BE_PPDU_STAT_RPT_CRC32 | B_BE_PPDU_STAT_RPT_DMA);
|
||||
|
||||
|
||||
@@ -464,7 +464,7 @@ static void rtw89_pci_tx_status(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_tx_skb_data *skb_data = RTW89_TX_SKB_CB(skb);
|
||||
struct ieee80211_tx_info *info;
|
||||
|
||||
if (rtw89_core_tx_wait_complete(rtwdev, skb_data, tx_status == RTW89_TX_DONE))
|
||||
if (rtw89_core_tx_wait_complete(rtwdev, skb_data, tx_status))
|
||||
return;
|
||||
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
@@ -2064,6 +2064,20 @@ static void rtw89_pci_ops_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data)
|
||||
writel(data, rtwpci->mmap + addr);
|
||||
}
|
||||
|
||||
static u32 rtw89_pci_ops_read32_pci_cfg(struct rtw89_dev *rtwdev, u32 addr)
|
||||
{
|
||||
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
|
||||
struct pci_dev *pdev = rtwpci->pdev;
|
||||
u32 value;
|
||||
int ret;
|
||||
|
||||
ret = pci_read_config_dword(pdev, addr, &value);
|
||||
if (ret)
|
||||
return RTW89_R32_EA;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static void rtw89_pci_ctrl_dma_trx(struct rtw89_dev *rtwdev, bool enable)
|
||||
{
|
||||
const struct rtw89_pci_info *info = rtwdev->pci_info;
|
||||
@@ -4683,6 +4697,8 @@ static const struct rtw89_hci_ops rtw89_pci_ops = {
|
||||
.write16 = rtw89_pci_ops_write16,
|
||||
.write32 = rtw89_pci_ops_write32,
|
||||
|
||||
.read32_pci_cfg = rtw89_pci_ops_read32_pci_cfg,
|
||||
|
||||
.mac_pre_init = rtw89_pci_ops_mac_pre_init,
|
||||
.mac_pre_deinit = rtw89_pci_ops_mac_pre_deinit,
|
||||
.mac_post_init = rtw89_pci_ops_mac_post_init,
|
||||
|
||||
@@ -1487,10 +1487,6 @@ struct rtw89_pci_tx_addr_info_32_v1 {
|
||||
#define RTW89_PCI_RPP_POLLUTED BIT(31)
|
||||
#define RTW89_PCI_RPP_SEQ GENMASK(30, 16)
|
||||
#define RTW89_PCI_RPP_TX_STATUS GENMASK(15, 13)
|
||||
#define RTW89_TX_DONE 0x0
|
||||
#define RTW89_TX_RETRY_LIMIT 0x1
|
||||
#define RTW89_TX_LIFE_TIME 0x2
|
||||
#define RTW89_TX_MACID_DROP 0x3
|
||||
#define RTW89_PCI_RPP_QSEL GENMASK(12, 8)
|
||||
#define RTW89_PCI_RPP_MACID GENMASK(7, 0)
|
||||
|
||||
|
||||
@@ -231,7 +231,12 @@ static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (link_sta->he_cap.has_he) {
|
||||
if (link_sta->eht_cap.has_eht) {
|
||||
cfg_mask |= u64_encode_bits(mask->control[band].eht_mcs[0],
|
||||
RA_MASK_EHT_1SS_RATES);
|
||||
cfg_mask |= u64_encode_bits(mask->control[band].eht_mcs[1],
|
||||
RA_MASK_EHT_2SS_RATES);
|
||||
} else if (link_sta->he_cap.has_he) {
|
||||
cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[0],
|
||||
RA_MASK_HE_1SS_RATES);
|
||||
cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[1],
|
||||
@@ -471,6 +476,10 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
|
||||
ra->ra_mask = ra_mask;
|
||||
ra->fix_giltf_en = fix_giltf_en;
|
||||
ra->fix_giltf = fix_giltf;
|
||||
ra->partial_bw_er = link_sta->he_cap.has_he ?
|
||||
!!(link_sta->he_cap.he_cap_elem.phy_cap_info[6] &
|
||||
IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE) : 0;
|
||||
ra->band = chan->band_type;
|
||||
|
||||
if (!csi)
|
||||
return;
|
||||
@@ -557,6 +566,14 @@ static bool __check_rate_pattern(struct rtw89_phy_rate_pattern *next,
|
||||
return true;
|
||||
}
|
||||
|
||||
enum __rtw89_hw_rate_invalid_bases {
|
||||
/* no EHT rate for ax chip */
|
||||
RTW89_HW_RATE_EHT_NSS1_MCS0 = RTW89_HW_RATE_INVAL,
|
||||
RTW89_HW_RATE_EHT_NSS2_MCS0 = RTW89_HW_RATE_INVAL,
|
||||
RTW89_HW_RATE_EHT_NSS3_MCS0 = RTW89_HW_RATE_INVAL,
|
||||
RTW89_HW_RATE_EHT_NSS4_MCS0 = RTW89_HW_RATE_INVAL,
|
||||
};
|
||||
|
||||
#define RTW89_HW_RATE_BY_CHIP_GEN(rate) \
|
||||
{ \
|
||||
[RTW89_CHIP_AX] = RTW89_HW_RATE_ ## rate, \
|
||||
@@ -572,6 +589,12 @@ void __rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_phy_rate_pattern next_pattern = {0};
|
||||
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
|
||||
rtwvif_link->chanctx_idx);
|
||||
static const u16 hw_rate_eht[][RTW89_CHIP_GEN_NUM] = {
|
||||
RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS1_MCS0),
|
||||
RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS2_MCS0),
|
||||
RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS3_MCS0),
|
||||
RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS4_MCS0),
|
||||
};
|
||||
static const u16 hw_rate_he[][RTW89_CHIP_GEN_NUM] = {
|
||||
RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS1_MCS0),
|
||||
RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS2_MCS0),
|
||||
@@ -596,6 +619,17 @@ void __rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
|
||||
u8 tx_nss = rtwdev->hal.tx_nss;
|
||||
u8 i;
|
||||
|
||||
if (chip_gen == RTW89_CHIP_AX)
|
||||
goto rs_11ax;
|
||||
|
||||
for (i = 0; i < tx_nss; i++)
|
||||
if (!__check_rate_pattern(&next_pattern, hw_rate_eht[i][chip_gen],
|
||||
RA_MASK_EHT_RATES, RTW89_RA_MODE_EHT,
|
||||
mask->control[nl_band].eht_mcs[i],
|
||||
0, true))
|
||||
goto out;
|
||||
|
||||
rs_11ax:
|
||||
for (i = 0; i < tx_nss; i++)
|
||||
if (!__check_rate_pattern(&next_pattern, hw_rate_he[i][chip_gen],
|
||||
RA_MASK_HE_RATES, RTW89_RA_MODE_HE,
|
||||
@@ -640,6 +674,13 @@ void __rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
|
||||
if (!next_pattern.enable)
|
||||
goto out;
|
||||
|
||||
if (unlikely(next_pattern.rate >= RTW89_HW_RATE_INVAL)) {
|
||||
rtw89_debug(rtwdev, RTW89_DBG_RA,
|
||||
"pattern invalid target: chip_gen %d, mode 0x%x\n",
|
||||
chip_gen, next_pattern.ra_mode);
|
||||
goto out;
|
||||
}
|
||||
|
||||
rtwvif_link->rate_pattern = next_pattern;
|
||||
rtw89_debug(rtwdev, RTW89_DBG_RA,
|
||||
"configure pattern: rate 0x%x, mask 0x%llx, mode 0x%x\n",
|
||||
@@ -2339,6 +2380,21 @@ static u8 rtw89_channel_to_idx(struct rtw89_dev *rtwdev, u8 band, u8 channel)
|
||||
}
|
||||
}
|
||||
|
||||
static bool rtw89_phy_validate_txpwr_limit_bw(struct rtw89_dev *rtwdev,
|
||||
u8 band, u8 bw)
|
||||
{
|
||||
switch (band) {
|
||||
case RTW89_BAND_2G:
|
||||
return bw < RTW89_2G_BW_NUM;
|
||||
case RTW89_BAND_5G:
|
||||
return bw < RTW89_5G_BW_NUM;
|
||||
case RTW89_BAND_6G:
|
||||
return bw < RTW89_6G_BW_NUM;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band,
|
||||
u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch)
|
||||
{
|
||||
@@ -2363,6 +2419,11 @@ s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band,
|
||||
};
|
||||
s8 cstr;
|
||||
|
||||
if (!rtw89_phy_validate_txpwr_limit_bw(rtwdev, band, bw)) {
|
||||
rtw89_warn(rtwdev, "invalid band %u bandwidth %u\n", band, bw);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (band) {
|
||||
case RTW89_BAND_2G:
|
||||
if (has_ant_gain)
|
||||
@@ -4551,7 +4612,7 @@ static void rtw89_dcfo_comp(struct rtw89_dev *rtwdev, s32 curr_cfo)
|
||||
s32 dcfo_comp_val;
|
||||
int sign;
|
||||
|
||||
if (rtwdev->chip->chip_id == RTL8922A)
|
||||
if (!dcfo_comp)
|
||||
return;
|
||||
|
||||
if (!is_linked) {
|
||||
|
||||
@@ -266,6 +266,10 @@ static void rtw89_phy_config_bb_gain_be(struct rtw89_dev *rtwdev,
|
||||
case 3:
|
||||
rtw89_phy_cfg_bb_gain_op1db_be(rtwdev, arg, reg->data);
|
||||
break;
|
||||
case 15:
|
||||
rtw89_phy_write32_idx(rtwdev, reg->addr & 0xFFFFF, MASKHWORD,
|
||||
reg->data, RTW89_PHY_0);
|
||||
break;
|
||||
case 4:
|
||||
/* This cfg_type is only used by rfe_type >= 50 with eFEM */
|
||||
if (efuse->rfe_type < 50)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "phy.h"
|
||||
#include "ps.h"
|
||||
#include "reg.h"
|
||||
#include "ser.h"
|
||||
#include "util.h"
|
||||
|
||||
static int rtw89_fw_receive_lps_h2c_check(struct rtw89_dev *rtwdev, u8 macid)
|
||||
@@ -26,16 +27,27 @@ static int rtw89_fw_receive_lps_h2c_check(struct rtw89_dev *rtwdev, u8 macid)
|
||||
c2h_info.id = RTW89_FWCMD_C2HREG_FUNC_PS_LEAVE_ACK;
|
||||
ret = rtw89_fw_msg_reg(rtwdev, NULL, &c2h_info);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto fw_fail;
|
||||
|
||||
c2hreg_macid = u32_get_bits(c2h_info.u.c2hreg[0],
|
||||
RTW89_C2HREG_PS_LEAVE_ACK_MACID);
|
||||
c2hreg_ret = u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_PS_LEAVE_ACK_RET);
|
||||
|
||||
if (macid != c2hreg_macid || c2hreg_ret)
|
||||
if (macid != c2hreg_macid || c2hreg_ret) {
|
||||
rtw89_warn(rtwdev, "rtw89: check lps h2c received by firmware fail\n");
|
||||
ret = -EINVAL;
|
||||
goto fw_fail;
|
||||
}
|
||||
rtwdev->ps_hang_cnt = 0;
|
||||
|
||||
return 0;
|
||||
|
||||
fw_fail:
|
||||
rtwdev->ps_hang_cnt++;
|
||||
if (rtwdev->ps_hang_cnt >= RTW89_PS_HANG_MAX_CNT)
|
||||
rtw89_ser_notify(rtwdev, MAC_AX_ERR_ASSERTION);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtw89_fw_leave_lps_check(struct rtw89_dev *rtwdev, u8 macid)
|
||||
@@ -51,9 +63,16 @@ static int rtw89_fw_leave_lps_check(struct rtw89_dev *rtwdev, u8 macid)
|
||||
mac->ps_status, chk_msk);
|
||||
if (ret) {
|
||||
rtw89_info(rtwdev, "rtw89: failed to leave lps state\n");
|
||||
|
||||
rtwdev->ps_hang_cnt++;
|
||||
if (rtwdev->ps_hang_cnt >= RTW89_PS_HANG_MAX_CNT)
|
||||
rtw89_ser_notify(rtwdev, MAC_AX_ERR_ASSERTION);
|
||||
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
rtwdev->ps_hang_cnt = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -3963,6 +3963,24 @@
|
||||
#define R_BE_EFUSE_CTRL_1_V1 0x0034
|
||||
#define B_BE_EF_DATA_MASK GENMASK(31, 0)
|
||||
|
||||
#define R_BE_GPIO_MUXCFG 0x0040
|
||||
#define B_BE_WCPU_AUTO_EN BIT(26)
|
||||
#define B_BE_WCPU_JTAG_EN BIT(24)
|
||||
#define B_BE_WCPU_DBG_EN BIT(23)
|
||||
#define B_BE_JTAG_CHAIN_EN BIT(20)
|
||||
#define B_BE_BOOT_MODE BIT(19)
|
||||
#define B_BE_WL_EECS_EXT_32K_SEL BIT(18)
|
||||
#define B_BE_WL_SEC_BONDING_OPT_STS BIT(17)
|
||||
#define B_BE_SECSIC_SEL BIT(16)
|
||||
#define B_BE_ENHTP BIT(14)
|
||||
#define B_BE_ENSIC BIT(12)
|
||||
#define B_BE_SIC_SWRST BIT(11)
|
||||
#define B_BE_PINMUX_PTA_EN BIT(10)
|
||||
#define B_BE_WL_BT_PTA_SEC BIT(9)
|
||||
#define B_BE_ENUARTTX BIT(8)
|
||||
#define B_BE_DBG_GNT_BT_S1_POLARITY BIT(4)
|
||||
#define B_BE_ENUARTRX BIT(2)
|
||||
|
||||
#define R_BE_GPIO_EXT_CTRL 0x0060
|
||||
#define B_BE_GPIO_MOD_15_TO_8_MASK GENMASK(31, 24)
|
||||
#define B_BE_GPIO_MOD_9 BIT(25)
|
||||
@@ -4323,6 +4341,7 @@
|
||||
#define B_BE_RUN_ENV_MASK GENMASK(31, 30)
|
||||
#define B_BE_WCPU_FWDL_STATUS_MASK GENMASK(29, 26)
|
||||
#define B_BE_WDT_PLT_RST_EN BIT(17)
|
||||
#define B_BE_HOST_EXIST BIT(16)
|
||||
#define B_BE_FW_SEC_AUTH_DONE BIT(14)
|
||||
#define B_BE_FW_CPU_UTIL_STS_EN BIT(13)
|
||||
#define B_BE_BBMCU1_FWDL_EN BIT(12)
|
||||
@@ -4599,6 +4618,10 @@
|
||||
#define B_BE_HCI_RXDMA_EN BIT(1)
|
||||
#define B_BE_HCI_TXDMA_EN BIT(0)
|
||||
|
||||
#define R_BE_BOOT_DBG 0x78F0
|
||||
#define B_BE_BOOT_STATUS_MASK GENMASK(31, 16)
|
||||
#define B_BE_SECUREBOOT_STATUS_MASK GENMASK(15, 0)
|
||||
|
||||
#define R_BE_DBG_WOW_READY 0x815E
|
||||
#define B_BE_DBG_WOW_READY GENMASK(7, 0)
|
||||
|
||||
@@ -7476,7 +7499,6 @@
|
||||
#define B_BE_PPDU_STAT_RPT_ADDR BIT(4)
|
||||
#define B_BE_APP_PLCP_HDR_RPT BIT(3)
|
||||
#define B_BE_APP_RX_CNT_RPT BIT(2)
|
||||
#define B_BE_PPDU_MAC_INFO BIT(1)
|
||||
#define B_BE_PPDU_STAT_RPT_EN BIT(0)
|
||||
|
||||
#define R_BE_RX_SR_CTRL 0x1144A
|
||||
|
||||
@@ -723,6 +723,8 @@ int rtw89_regd_init_hint(struct rtw89_dev *rtwdev)
|
||||
chip_regd = rtw89_regd_find_reg_by_name(rtwdev, rtwdev->efuse.country_code);
|
||||
if (!rtw89_regd_is_ww(chip_regd)) {
|
||||
rtwdev->regulatory.regd = chip_regd;
|
||||
rtwdev->regulatory.programmed = true;
|
||||
|
||||
/* Ignore country ie if there is a country domain programmed in chip */
|
||||
wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
|
||||
wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
|
||||
@@ -867,11 +869,6 @@ static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev,
|
||||
wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
|
||||
else
|
||||
wiphy->regulatory_flags &= ~REGULATORY_COUNTRY_IE_IGNORE;
|
||||
|
||||
rtw89_regd_apply_policy_unii4(rtwdev, wiphy);
|
||||
rtw89_regd_apply_policy_6ghz(rtwdev, wiphy);
|
||||
rtw89_regd_apply_policy_tas(rtwdev);
|
||||
rtw89_regd_apply_policy_ant_gain(rtwdev);
|
||||
}
|
||||
|
||||
static
|
||||
@@ -883,19 +880,22 @@ void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request
|
||||
wiphy_lock(wiphy);
|
||||
rtw89_leave_ps_mode(rtwdev);
|
||||
|
||||
if (wiphy->regd) {
|
||||
rtw89_debug(rtwdev, RTW89_DBG_REGD,
|
||||
"There is a country domain programmed in chip, ignore notifications\n");
|
||||
goto exit;
|
||||
}
|
||||
if (rtwdev->regulatory.programmed)
|
||||
goto policy;
|
||||
|
||||
rtw89_regd_notifier_apply(rtwdev, wiphy, request);
|
||||
rtw89_debug_regd(rtwdev, rtwdev->regulatory.regd,
|
||||
"get from initiator %d, alpha2",
|
||||
request->initiator);
|
||||
|
||||
policy:
|
||||
rtw89_regd_apply_policy_unii4(rtwdev, wiphy);
|
||||
rtw89_regd_apply_policy_6ghz(rtwdev, wiphy);
|
||||
rtw89_regd_apply_policy_tas(rtwdev);
|
||||
rtw89_regd_apply_policy_ant_gain(rtwdev);
|
||||
|
||||
rtw89_core_set_chip_txpwr(rtwdev);
|
||||
|
||||
exit:
|
||||
wiphy_unlock(wiphy);
|
||||
}
|
||||
|
||||
|
||||
@@ -2537,7 +2537,9 @@ static const struct rtw89_chip_ops rtw8851b_chip_ops = {
|
||||
.query_rxdesc = rtw89_core_query_rxdesc,
|
||||
.fill_txdesc = rtw89_core_fill_txdesc,
|
||||
.fill_txdesc_fwcmd = rtw89_core_fill_txdesc,
|
||||
.get_ch_dma = rtw89_core_get_ch_dma,
|
||||
.get_ch_dma = {rtw89_core_get_ch_dma,
|
||||
rtw89_core_get_ch_dma,
|
||||
NULL,},
|
||||
.cfg_ctrl_path = rtw89_mac_cfg_ctrl_path,
|
||||
.mac_cfg_gnt = rtw89_mac_cfg_gnt,
|
||||
.stop_sch_tx = rtw89_mac_stop_sch_tx,
|
||||
@@ -2646,6 +2648,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
|
||||
.bacam_num = 2,
|
||||
.bacam_dynamic_num = 4,
|
||||
.bacam_ver = RTW89_BACAM_V0,
|
||||
.addrcam_ver = 0,
|
||||
.ppdu_max_usr = 4,
|
||||
.sec_ctrl_efuse_size = 4,
|
||||
.physical_efuse_size = 1216,
|
||||
|
||||
@@ -1626,7 +1626,7 @@ static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
|
||||
iqk_info->iqk_table_idx[path] = idx;
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d (PHY%d): / DBCC %s/ %s/ CH%d/ %s\n",
|
||||
path, phy, rtwdev->dbcc_en ? "on" : "off",
|
||||
path, phy, str_on_off(rtwdev->dbcc_en),
|
||||
iqk_info->iqk_band[path] == 0 ? "2G" :
|
||||
iqk_info->iqk_band[path] == 1 ? "5G" : "6G",
|
||||
iqk_info->iqk_ch[path],
|
||||
@@ -1901,8 +1901,8 @@ static void _dpk_information(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
|
||||
rtw89_debug(rtwdev, RTW89_DBG_RFK,
|
||||
"[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n",
|
||||
path, dpk->cur_idx[path], phy,
|
||||
rtwdev->is_tssi_mode[path] ? "on" : "off",
|
||||
rtwdev->dbcc_en ? "on" : "off",
|
||||
str_on_off(rtwdev->is_tssi_mode[path]),
|
||||
str_on_off(rtwdev->dbcc_en),
|
||||
dpk->bp[path][kidx].band == 0 ? "2G" :
|
||||
dpk->bp[path][kidx].band == 1 ? "5G" : "6G",
|
||||
dpk->bp[path][kidx].ch,
|
||||
@@ -2016,7 +2016,7 @@ static void _dpk_txpwr_bb_force(struct rtw89_dev *rtwdev,
|
||||
rtw89_phy_write32_mask(rtwdev, R_TXPWRB_H + (path << 13), B_TXPWRB_RDY, force);
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d txpwr_bb_force %s\n",
|
||||
path, force ? "on" : "off");
|
||||
path, str_on_off(force));
|
||||
}
|
||||
|
||||
static void _dpk_kip_pwr_clk_onoff(struct rtw89_dev *rtwdev, bool turn_on)
|
||||
|
||||
@@ -5,15 +5,39 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/usb.h>
|
||||
#include "rtw8851b.h"
|
||||
#include "reg.h"
|
||||
#include "usb.h"
|
||||
|
||||
static const struct rtw89_usb_info rtw8851b_usb_info = {
|
||||
.usb_host_request_2 = R_AX_USB_HOST_REQUEST_2,
|
||||
.usb_wlan0_1 = R_AX_USB_WLAN0_1,
|
||||
.hci_func_en = R_AX_HCI_FUNC_EN,
|
||||
.usb3_mac_npi_config_intf_0 = R_AX_USB3_MAC_NPI_CONFIG_INTF_0,
|
||||
.usb_endpoint_0 = R_AX_USB_ENDPOINT_0,
|
||||
.usb_endpoint_2 = R_AX_USB_ENDPOINT_2,
|
||||
.bulkout_id = {
|
||||
[RTW89_DMA_ACH0] = 3,
|
||||
[RTW89_DMA_ACH1] = 4,
|
||||
[RTW89_DMA_ACH2] = 5,
|
||||
[RTW89_DMA_ACH3] = 6,
|
||||
[RTW89_DMA_B0MG] = 0,
|
||||
[RTW89_DMA_B0HI] = 1,
|
||||
[RTW89_DMA_H2C] = 2,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct rtw89_driver_info rtw89_8851bu_info = {
|
||||
.chip = &rtw8851b_chip_info,
|
||||
.variant = NULL,
|
||||
.quirks = NULL,
|
||||
.bus = {
|
||||
.usb = &rtw8851b_usb_info,
|
||||
}
|
||||
};
|
||||
|
||||
static const struct usb_device_id rtw_8851bu_id_table[] = {
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xb831, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8851bu_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xb851, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8851bu_info },
|
||||
/* D-Link AX9U rev. A1 */
|
||||
|
||||
@@ -48,6 +48,48 @@ static const struct rtw89_hfc_param_ini rtw8852a_hfc_param_ini_pcie[] = {
|
||||
[RTW89_QTA_INVALID] = {NULL},
|
||||
};
|
||||
|
||||
static const struct rtw89_hfc_ch_cfg rtw8852a_hfc_chcfg_usb[] = {
|
||||
{22, 402, grp_0}, /* ACH 0 */
|
||||
{0, 0, grp_0}, /* ACH 1 */
|
||||
{22, 402, grp_0}, /* ACH 2 */
|
||||
{0, 0, grp_0}, /* ACH 3 */
|
||||
{22, 402, grp_0}, /* ACH 4 */
|
||||
{0, 0, grp_0}, /* ACH 5 */
|
||||
{22, 402, grp_0}, /* ACH 6 */
|
||||
{0, 0, grp_0}, /* ACH 7 */
|
||||
{22, 402, grp_0}, /* B0MGQ */
|
||||
{0, 0, grp_0}, /* B0HIQ */
|
||||
{22, 402, grp_0}, /* B1MGQ */
|
||||
{0, 0, grp_0}, /* B1HIQ */
|
||||
{0, 0, 0} /* FWCMDQ */
|
||||
};
|
||||
|
||||
static const struct rtw89_hfc_pub_cfg rtw8852a_hfc_pubcfg_usb = {
|
||||
512, /* Group 0 */
|
||||
0, /* Group 1 */
|
||||
512, /* Public Max */
|
||||
104 /* WP threshold */
|
||||
};
|
||||
|
||||
static const struct rtw89_hfc_prec_cfg rtw8852a_hfc_preccfg_usb = {
|
||||
11, /* CH 0-11 pre-cost */
|
||||
32, /* H2C pre-cost */
|
||||
76, /* WP CH 0-7 pre-cost */
|
||||
25, /* WP CH 8-11 pre-cost */
|
||||
1, /* CH 0-11 full condition */
|
||||
1, /* H2C full condition */
|
||||
1, /* WP CH 0-7 full condition */
|
||||
1, /* WP CH 8-11 full condition */
|
||||
};
|
||||
|
||||
static const struct rtw89_hfc_param_ini rtw8852a_hfc_param_ini_usb[] = {
|
||||
[RTW89_QTA_SCC] = {rtw8852a_hfc_chcfg_usb, &rtw8852a_hfc_pubcfg_usb,
|
||||
&rtw8852a_hfc_preccfg_usb, RTW89_HCIFC_STF},
|
||||
[RTW89_QTA_DLFW] = {NULL, NULL,
|
||||
&rtw8852a_hfc_preccfg_usb, RTW89_HCIFC_STF},
|
||||
[RTW89_QTA_INVALID] = {NULL},
|
||||
};
|
||||
|
||||
static const struct rtw89_dle_mem rtw8852a_dle_mem_pcie[] = {
|
||||
[RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size0,
|
||||
&rtw89_mac_size.ple_size0, &rtw89_mac_size.wde_qt0,
|
||||
@@ -65,6 +107,19 @@ static const struct rtw89_dle_mem rtw8852a_dle_mem_pcie[] = {
|
||||
NULL},
|
||||
};
|
||||
|
||||
static const struct rtw89_dle_mem rtw8852a_dle_mem_usb[] = {
|
||||
[RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size1,
|
||||
&rtw89_mac_size.ple_size1, &rtw89_mac_size.wde_qt1,
|
||||
&rtw89_mac_size.wde_qt1, &rtw89_mac_size.ple_qt25,
|
||||
&rtw89_mac_size.ple_qt26},
|
||||
[RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size4,
|
||||
&rtw89_mac_size.ple_size4, &rtw89_mac_size.wde_qt4,
|
||||
&rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt13,
|
||||
&rtw89_mac_size.ple_qt13},
|
||||
[RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL},
|
||||
};
|
||||
|
||||
static const struct rtw89_reg2_def rtw8852a_pmac_ht20_mcs7_tbl[] = {
|
||||
{0x44AC, 0x00000000},
|
||||
{0x44B0, 0x00000000},
|
||||
@@ -566,14 +621,6 @@ static const struct rtw89_edcca_regs rtw8852a_edcca_regs = {
|
||||
.tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M,
|
||||
};
|
||||
|
||||
static void rtw8852ae_efuse_parsing(struct rtw89_efuse *efuse,
|
||||
struct rtw8852a_efuse *map)
|
||||
{
|
||||
ether_addr_copy(efuse->addr, map->e.mac_addr);
|
||||
efuse->rfe_type = map->rfe_type;
|
||||
efuse->xtal_cap = map->xtal_k;
|
||||
}
|
||||
|
||||
static void rtw8852a_efuse_parsing_tssi(struct rtw89_dev *rtwdev,
|
||||
struct rtw8852a_efuse *map)
|
||||
{
|
||||
@@ -619,12 +666,18 @@ static int rtw8852a_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map,
|
||||
|
||||
switch (rtwdev->hci.type) {
|
||||
case RTW89_HCI_TYPE_PCIE:
|
||||
rtw8852ae_efuse_parsing(efuse, map);
|
||||
ether_addr_copy(efuse->addr, map->e.mac_addr);
|
||||
break;
|
||||
case RTW89_HCI_TYPE_USB:
|
||||
ether_addr_copy(efuse->addr, map->u.mac_addr);
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
efuse->rfe_type = map->rfe_type;
|
||||
efuse->xtal_cap = map->xtal_k;
|
||||
|
||||
rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type);
|
||||
|
||||
return 0;
|
||||
@@ -2178,7 +2231,9 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = {
|
||||
.query_rxdesc = rtw89_core_query_rxdesc,
|
||||
.fill_txdesc = rtw89_core_fill_txdesc,
|
||||
.fill_txdesc_fwcmd = rtw89_core_fill_txdesc,
|
||||
.get_ch_dma = rtw89_core_get_ch_dma,
|
||||
.get_ch_dma = {rtw89_core_get_ch_dma,
|
||||
rtw89_core_get_ch_dma_v2,
|
||||
NULL,},
|
||||
.cfg_ctrl_path = rtw89_mac_cfg_ctrl_path,
|
||||
.mac_cfg_gnt = rtw89_mac_cfg_gnt,
|
||||
.stop_sch_tx = rtw89_mac_stop_sch_tx,
|
||||
@@ -2222,8 +2277,13 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
|
||||
.max_amsdu_limit = 3500,
|
||||
.dis_2g_40m_ul_ofdma = true,
|
||||
.rsvd_ple_ofst = 0x6f800,
|
||||
.hfc_param_ini = {rtw8852a_hfc_param_ini_pcie, NULL, NULL},
|
||||
.dle_mem = {rtw8852a_dle_mem_pcie, NULL, NULL, NULL},
|
||||
.hfc_param_ini = {rtw8852a_hfc_param_ini_pcie,
|
||||
rtw8852a_hfc_param_ini_usb,
|
||||
NULL},
|
||||
.dle_mem = {rtw8852a_dle_mem_pcie,
|
||||
rtw8852a_dle_mem_usb,
|
||||
rtw8852a_dle_mem_usb,
|
||||
NULL},
|
||||
.wde_qempty_acq_grpnum = 16,
|
||||
.wde_qempty_mgq_grpsel = 16,
|
||||
.rf_base_addr = {0xc000, 0xd000},
|
||||
@@ -2274,6 +2334,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
|
||||
.bacam_num = 2,
|
||||
.bacam_dynamic_num = 4,
|
||||
.bacam_ver = RTW89_BACAM_V0,
|
||||
.addrcam_ver = 0,
|
||||
.ppdu_max_usr = 4,
|
||||
.sec_ctrl_efuse_size = 4,
|
||||
.physical_efuse_size = 1216,
|
||||
|
||||
@@ -756,8 +756,8 @@ static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path)
|
||||
rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x1);
|
||||
rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H2, 0x0);
|
||||
udelay(1);
|
||||
rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0303);
|
||||
rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0000);
|
||||
rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0303);
|
||||
rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0000);
|
||||
|
||||
switch (iqk_info->iqk_band[path]) {
|
||||
case RTW89_BAND_2G:
|
||||
@@ -1239,8 +1239,8 @@ static void _iqk_txk_setting(struct rtw89_dev *rtwdev, u8 path)
|
||||
udelay(1);
|
||||
rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0041);
|
||||
udelay(1);
|
||||
rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0303);
|
||||
rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0000);
|
||||
rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0303);
|
||||
rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0000);
|
||||
switch (iqk_info->iqk_band[path]) {
|
||||
case RTW89_BAND_2G:
|
||||
rtw89_write_rf(rtwdev, path, RR_XALNA2, RR_XALNA2_SW, 0x00);
|
||||
@@ -1403,7 +1403,7 @@ static void _iqk_get_ch_info(struct rtw89_dev *rtwdev,
|
||||
path, iqk_info->iqk_ch[path]);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_RFK,
|
||||
"[IQK]S%d (PHY%d): / DBCC %s/ %s/ CH%d/ %s\n", path, phy,
|
||||
rtwdev->dbcc_en ? "on" : "off",
|
||||
str_on_off(rtwdev->dbcc_en),
|
||||
iqk_info->iqk_band[path] == 0 ? "2G" :
|
||||
iqk_info->iqk_band[path] == 1 ? "5G" : "6G",
|
||||
iqk_info->iqk_ch[path],
|
||||
@@ -1881,8 +1881,8 @@ static void _dpk_information(struct rtw89_dev *rtwdev,
|
||||
rtw89_debug(rtwdev, RTW89_DBG_RFK,
|
||||
"[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n",
|
||||
path, dpk->cur_idx[path], phy,
|
||||
rtwdev->is_tssi_mode[path] ? "on" : "off",
|
||||
rtwdev->dbcc_en ? "on" : "off",
|
||||
str_on_off(rtwdev->is_tssi_mode[path]),
|
||||
str_on_off(rtwdev->dbcc_en),
|
||||
dpk->bp[path][kidx].band == 0 ? "2G" :
|
||||
dpk->bp[path][kidx].band == 1 ? "5G" : "6G",
|
||||
dpk->bp[path][kidx].ch,
|
||||
@@ -2736,7 +2736,7 @@ static void _dpk_onoff(struct rtw89_dev *rtwdev,
|
||||
MASKBYTE3, 0x6 | val);
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s !!!\n", path,
|
||||
kidx, dpk->is_dpk_enable && !off ? "enable" : "disable");
|
||||
kidx, str_enable_disable(dpk->is_dpk_enable && !off));
|
||||
}
|
||||
|
||||
static void _dpk_track(struct rtw89_dev *rtwdev)
|
||||
|
||||
79
drivers/net/wireless/realtek/rtw89/rtw8852au.c
Normal file
79
drivers/net/wireless/realtek/rtw89/rtw8852au.c
Normal file
@@ -0,0 +1,79 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/* Copyright(c) 2025 Realtek Corporation
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/usb.h>
|
||||
#include "rtw8852a.h"
|
||||
#include "reg.h"
|
||||
#include "usb.h"
|
||||
|
||||
static const struct rtw89_usb_info rtw8852a_usb_info = {
|
||||
.usb_host_request_2 = R_AX_USB_HOST_REQUEST_2,
|
||||
.usb_wlan0_1 = R_AX_USB_WLAN0_1,
|
||||
.hci_func_en = R_AX_HCI_FUNC_EN,
|
||||
.usb3_mac_npi_config_intf_0 = R_AX_USB3_MAC_NPI_CONFIG_INTF_0,
|
||||
.usb_endpoint_0 = R_AX_USB_ENDPOINT_0,
|
||||
.usb_endpoint_2 = R_AX_USB_ENDPOINT_2,
|
||||
.bulkout_id = {
|
||||
[RTW89_DMA_ACH0] = 3,
|
||||
[RTW89_DMA_ACH2] = 5,
|
||||
[RTW89_DMA_ACH4] = 4,
|
||||
[RTW89_DMA_ACH6] = 6,
|
||||
[RTW89_DMA_B0MG] = 0,
|
||||
[RTW89_DMA_B0HI] = 0,
|
||||
[RTW89_DMA_B1MG] = 1,
|
||||
[RTW89_DMA_B1HI] = 1,
|
||||
[RTW89_DMA_H2C] = 2,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct rtw89_driver_info rtw89_8852au_info = {
|
||||
.chip = &rtw8852a_chip_info,
|
||||
.variant = NULL,
|
||||
.quirks = NULL,
|
||||
.bus = {
|
||||
.usb = &rtw8852a_usb_info,
|
||||
}
|
||||
};
|
||||
|
||||
static const struct usb_device_id rtw_8852au_id_table[] = {
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x0312, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4020, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1997, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0x8832, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0x885a, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0x885c, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3321, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x332c, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x013f, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0140, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0141, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3625, 0x010f, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, rtw_8852au_id_table);
|
||||
|
||||
static struct usb_driver rtw_8852au_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = rtw_8852au_id_table,
|
||||
.probe = rtw89_usb_probe,
|
||||
.disconnect = rtw89_usb_disconnect,
|
||||
};
|
||||
module_usb_driver(rtw_8852au_driver);
|
||||
|
||||
MODULE_AUTHOR("Bitterblue Smith <rtl8821cerfe2@gmail.com>");
|
||||
MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852AU driver");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
@@ -842,7 +842,9 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = {
|
||||
.query_rxdesc = rtw89_core_query_rxdesc,
|
||||
.fill_txdesc = rtw89_core_fill_txdesc,
|
||||
.fill_txdesc_fwcmd = rtw89_core_fill_txdesc,
|
||||
.get_ch_dma = rtw89_core_get_ch_dma,
|
||||
.get_ch_dma = {rtw89_core_get_ch_dma,
|
||||
rtw89_core_get_ch_dma,
|
||||
NULL,},
|
||||
.cfg_ctrl_path = rtw89_mac_cfg_ctrl_path,
|
||||
.mac_cfg_gnt = rtw89_mac_cfg_gnt,
|
||||
.stop_sch_tx = rtw89_mac_stop_sch_tx,
|
||||
@@ -957,6 +959,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
|
||||
.bacam_num = 2,
|
||||
.bacam_dynamic_num = 4,
|
||||
.bacam_ver = RTW89_BACAM_V0,
|
||||
.addrcam_ver = 0,
|
||||
.ppdu_max_usr = 4,
|
||||
.sec_ctrl_efuse_size = 4,
|
||||
.physical_efuse_size = 1216,
|
||||
|
||||
@@ -1747,11 +1747,15 @@ static void __rtw8852bx_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
|
||||
struct rtw89_hal *hal = &rtwdev->hal;
|
||||
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
|
||||
enum rtw89_rf_path_bit rx_path = hal->antenna_rx ? hal->antenna_rx : RF_AB;
|
||||
u8 rx_nss = rtwdev->hal.rx_nss;
|
||||
|
||||
if (rx_path != RF_AB)
|
||||
rx_nss = 1;
|
||||
|
||||
rtw8852bx_bb_ctrl_rx_path(rtwdev, rx_path, chan);
|
||||
rtw8852bx_bb_ctrl_rf_mode_rx_path(rtwdev, rx_path);
|
||||
|
||||
if (rtwdev->hal.rx_nss == 1) {
|
||||
if (rx_nss == 1) {
|
||||
rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0);
|
||||
rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0);
|
||||
rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0);
|
||||
|
||||
@@ -1696,7 +1696,7 @@ static void _dpk_onoff(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, bool o
|
||||
MASKBYTE3, _dpk_order_convert(rtwdev) << 1 | val);
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s !!!\n", path,
|
||||
kidx, dpk->is_dpk_enable && !off ? "enable" : "disable");
|
||||
kidx, str_enable_disable(dpk->is_dpk_enable && !off));
|
||||
}
|
||||
|
||||
static void _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
|
||||
@@ -1763,8 +1763,8 @@ static void _dpk_information(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
|
||||
rtw89_debug(rtwdev, RTW89_DBG_RFK,
|
||||
"[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n",
|
||||
path, dpk->cur_idx[path], phy,
|
||||
rtwdev->is_tssi_mode[path] ? "on" : "off",
|
||||
rtwdev->dbcc_en ? "on" : "off",
|
||||
str_on_off(rtwdev->is_tssi_mode[path]),
|
||||
str_on_off(rtwdev->dbcc_en),
|
||||
dpk->bp[path][kidx].band == 0 ? "2G" :
|
||||
dpk->bp[path][kidx].band == 1 ? "5G" : "6G",
|
||||
dpk->bp[path][kidx].ch,
|
||||
|
||||
@@ -708,7 +708,9 @@ static const struct rtw89_chip_ops rtw8852bt_chip_ops = {
|
||||
.query_rxdesc = rtw89_core_query_rxdesc,
|
||||
.fill_txdesc = rtw89_core_fill_txdesc,
|
||||
.fill_txdesc_fwcmd = rtw89_core_fill_txdesc,
|
||||
.get_ch_dma = rtw89_core_get_ch_dma,
|
||||
.get_ch_dma = {rtw89_core_get_ch_dma,
|
||||
NULL,
|
||||
NULL,},
|
||||
.cfg_ctrl_path = rtw89_mac_cfg_ctrl_path,
|
||||
.mac_cfg_gnt = rtw89_mac_cfg_gnt,
|
||||
.stop_sch_tx = rtw89_mac_stop_sch_tx,
|
||||
@@ -816,6 +818,7 @@ const struct rtw89_chip_info rtw8852bt_chip_info = {
|
||||
.bacam_num = 2,
|
||||
.bacam_dynamic_num = 4,
|
||||
.bacam_ver = RTW89_BACAM_V0,
|
||||
.addrcam_ver = 0,
|
||||
.ppdu_max_usr = 4,
|
||||
.sec_ctrl_efuse_size = 4,
|
||||
.physical_efuse_size = 1216,
|
||||
|
||||
@@ -5,12 +5,34 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/usb.h>
|
||||
#include "rtw8852b.h"
|
||||
#include "reg.h"
|
||||
#include "usb.h"
|
||||
|
||||
static const struct rtw89_usb_info rtw8852b_usb_info = {
|
||||
.usb_host_request_2 = R_AX_USB_HOST_REQUEST_2,
|
||||
.usb_wlan0_1 = R_AX_USB_WLAN0_1,
|
||||
.hci_func_en = R_AX_HCI_FUNC_EN,
|
||||
.usb3_mac_npi_config_intf_0 = R_AX_USB3_MAC_NPI_CONFIG_INTF_0,
|
||||
.usb_endpoint_0 = R_AX_USB_ENDPOINT_0,
|
||||
.usb_endpoint_2 = R_AX_USB_ENDPOINT_2,
|
||||
.bulkout_id = {
|
||||
[RTW89_DMA_ACH0] = 3,
|
||||
[RTW89_DMA_ACH1] = 4,
|
||||
[RTW89_DMA_ACH2] = 5,
|
||||
[RTW89_DMA_ACH3] = 6,
|
||||
[RTW89_DMA_B0MG] = 0,
|
||||
[RTW89_DMA_B0HI] = 1,
|
||||
[RTW89_DMA_H2C] = 2,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct rtw89_driver_info rtw89_8852bu_info = {
|
||||
.chip = &rtw8852b_chip_info,
|
||||
.variant = NULL,
|
||||
.quirks = NULL,
|
||||
.bus = {
|
||||
.usb = &rtw8852b_usb_info,
|
||||
}
|
||||
};
|
||||
|
||||
static const struct usb_device_id rtw_8852bu_id_table[] = {
|
||||
@@ -28,6 +50,8 @@ static const struct usb_device_id rtw_8852bu_id_table[] = {
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852bu_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1a62, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852bu_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1cb6, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852bu_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0db0, 0x6931, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852bu_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3327, 0xff, 0xff, 0xff),
|
||||
|
||||
@@ -51,6 +51,48 @@ static const struct rtw89_hfc_param_ini rtw8852c_hfc_param_ini_pcie[] = {
|
||||
[RTW89_QTA_INVALID] = {NULL},
|
||||
};
|
||||
|
||||
static const struct rtw89_hfc_ch_cfg rtw8852c_hfc_chcfg_usb[] = {
|
||||
{18, 344, grp_0}, /* ACH 0 */
|
||||
{0, 0, grp_0}, /* ACH 1 */
|
||||
{18, 344, grp_0}, /* ACH 2 */
|
||||
{0, 0, grp_0}, /* ACH 3 */
|
||||
{18, 344, grp_0}, /* ACH 4 */
|
||||
{0, 0, grp_0}, /* ACH 5 */
|
||||
{18, 344, grp_0}, /* ACH 6 */
|
||||
{0, 0, grp_0}, /* ACH 7 */
|
||||
{18, 344, grp_0}, /* B0MGQ */
|
||||
{0, 0, grp_0}, /* B0HIQ */
|
||||
{18, 344, grp_0}, /* B1MGQ */
|
||||
{0, 0, grp_0}, /* B1HIQ */
|
||||
{0, 0, 0} /* FWCMDQ */
|
||||
};
|
||||
|
||||
static const struct rtw89_hfc_pub_cfg rtw8852c_hfc_pubcfg_usb = {
|
||||
344, /* Group 0 */
|
||||
0, /* Group 1 */
|
||||
344, /* Public Max */
|
||||
0 /* WP threshold */
|
||||
};
|
||||
|
||||
static const struct rtw89_hfc_prec_cfg rtw8852c_hfc_preccfg_usb = {
|
||||
9, /* CH 0-11 pre-cost */
|
||||
32, /* H2C pre-cost */
|
||||
146, /* WP CH 0-7 pre-cost */
|
||||
146, /* WP CH 8-11 pre-cost */
|
||||
1, /* CH 0-11 full condition */
|
||||
1, /* H2C full condition */
|
||||
1, /* WP CH 0-7 full condition */
|
||||
1, /* WP CH 8-11 full condition */
|
||||
};
|
||||
|
||||
static const struct rtw89_hfc_param_ini rtw8852c_hfc_param_ini_usb[] = {
|
||||
[RTW89_QTA_SCC] = {rtw8852c_hfc_chcfg_usb, &rtw8852c_hfc_pubcfg_usb,
|
||||
&rtw8852c_hfc_preccfg_usb, RTW89_HCIFC_STF},
|
||||
[RTW89_QTA_DLFW] = {NULL, NULL,
|
||||
&rtw8852c_hfc_preccfg_usb, RTW89_HCIFC_STF},
|
||||
[RTW89_QTA_INVALID] = {NULL},
|
||||
};
|
||||
|
||||
static const struct rtw89_dle_mem rtw8852c_dle_mem_pcie[] = {
|
||||
[RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size19,
|
||||
&rtw89_mac_size.ple_size19, &rtw89_mac_size.wde_qt18,
|
||||
@@ -64,6 +106,32 @@ static const struct rtw89_dle_mem rtw8852c_dle_mem_pcie[] = {
|
||||
NULL},
|
||||
};
|
||||
|
||||
static const struct rtw89_dle_mem rtw8852c_dle_mem_usb2[] = {
|
||||
[RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size31,
|
||||
&rtw89_mac_size.ple_size34, &rtw89_mac_size.wde_qt31,
|
||||
&rtw89_mac_size.wde_qt31, &rtw89_mac_size.ple_qt78,
|
||||
&rtw89_mac_size.ple_qt79},
|
||||
[RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size18,
|
||||
&rtw89_mac_size.ple_size18, &rtw89_mac_size.wde_qt17,
|
||||
&rtw89_mac_size.wde_qt17, &rtw89_mac_size.ple_qt44,
|
||||
&rtw89_mac_size.ple_qt45},
|
||||
[RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL},
|
||||
};
|
||||
|
||||
static const struct rtw89_dle_mem rtw8852c_dle_mem_usb3[] = {
|
||||
[RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size17,
|
||||
&rtw89_mac_size.ple_size17, &rtw89_mac_size.wde_qt16,
|
||||
&rtw89_mac_size.wde_qt16, &rtw89_mac_size.ple_qt42,
|
||||
&rtw89_mac_size.ple_qt43},
|
||||
[RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size18,
|
||||
&rtw89_mac_size.ple_size18, &rtw89_mac_size.wde_qt17,
|
||||
&rtw89_mac_size.wde_qt17, &rtw89_mac_size.ple_qt44,
|
||||
&rtw89_mac_size.ple_qt45},
|
||||
[RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL},
|
||||
};
|
||||
|
||||
static const u32 rtw8852c_h2c_regs[RTW89_H2CREG_MAX] = {
|
||||
R_AX_H2CREG_DATA0_V1, R_AX_H2CREG_DATA1_V1, R_AX_H2CREG_DATA2_V1,
|
||||
R_AX_H2CREG_DATA3_V1
|
||||
@@ -214,7 +282,8 @@ static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
|
||||
int ret;
|
||||
|
||||
val32 = rtw89_read32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_PAD_HCI_SEL_V2_MASK);
|
||||
if (val32 == MAC_AX_HCI_SEL_PCIE_USB)
|
||||
if (val32 == MAC_AX_HCI_SEL_PCIE_USB ||
|
||||
rtwdev->hci.type == RTW89_HCI_TYPE_USB)
|
||||
rtw89_write32_set(rtwdev, R_AX_LDO_AON_CTRL0, B_AX_PD_REGU_L);
|
||||
|
||||
rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_AFSM_WLSUS_EN |
|
||||
@@ -246,7 +315,9 @@ static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
|
||||
rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
|
||||
|
||||
rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
|
||||
rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_CALIB_EN_V1);
|
||||
|
||||
if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE)
|
||||
rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_CALIB_EN_V1);
|
||||
|
||||
rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, B_AX_CMAC1_FEN);
|
||||
rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, B_AX_R_SYM_ISO_CMAC12PP);
|
||||
@@ -305,9 +376,11 @@ static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
|
||||
|
||||
rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14);
|
||||
rtw89_write32_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK);
|
||||
rtw89_write32_set(rtwdev, R_AX_GPIO0_15_EECS_EESK_LED1_PULL_LOW_EN,
|
||||
B_AX_EECS_PULL_LOW_EN | B_AX_EESK_PULL_LOW_EN |
|
||||
B_AX_LED1_PULL_LOW_EN);
|
||||
|
||||
if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE)
|
||||
rtw89_write32_set(rtwdev, R_AX_GPIO0_15_EECS_EESK_LED1_PULL_LOW_EN,
|
||||
B_AX_EECS_PULL_LOW_EN | B_AX_EESK_PULL_LOW_EN |
|
||||
B_AX_LED1_PULL_LOW_EN);
|
||||
|
||||
rtw89_write32_set(rtwdev, R_AX_DMAC_FUNC_EN,
|
||||
B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_MPDU_PROC_EN |
|
||||
@@ -385,24 +458,28 @@ static int rtw8852c_pwr_off_func(struct rtw89_dev *rtwdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, SW_LPS_OPTION);
|
||||
if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE)
|
||||
rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, SW_LPS_OPTION);
|
||||
else if (rtwdev->hci.type == RTW89_HCI_TYPE_USB)
|
||||
rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_SOP_EDSWR);
|
||||
|
||||
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);
|
||||
|
||||
if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) {
|
||||
rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
|
||||
} else if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) {
|
||||
val32 = rtw89_read32(rtwdev, R_AX_SYS_PW_CTRL);
|
||||
val32 &= ~B_AX_AFSM_PCIE_SUS_EN;
|
||||
val32 |= B_AX_AFSM_WLSUS_EN;
|
||||
rtw89_write32(rtwdev, R_AX_SYS_PW_CTRL, val32);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rtw8852c_e_efuse_parsing(struct rtw89_efuse *efuse,
|
||||
struct rtw8852c_efuse *map)
|
||||
{
|
||||
ether_addr_copy(efuse->addr, map->e.mac_addr);
|
||||
efuse->rfe_type = map->rfe_type;
|
||||
efuse->xtal_cap = map->xtal_k;
|
||||
}
|
||||
|
||||
static void rtw8852c_efuse_parsing_tssi(struct rtw89_dev *rtwdev,
|
||||
struct rtw8852c_efuse *map)
|
||||
{
|
||||
@@ -511,12 +588,18 @@ static int rtw8852c_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map,
|
||||
|
||||
switch (rtwdev->hci.type) {
|
||||
case RTW89_HCI_TYPE_PCIE:
|
||||
rtw8852c_e_efuse_parsing(efuse, map);
|
||||
ether_addr_copy(efuse->addr, map->e.mac_addr);
|
||||
break;
|
||||
case RTW89_HCI_TYPE_USB:
|
||||
ether_addr_copy(efuse->addr, map->u.mac_addr);
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
efuse->rfe_type = map->rfe_type;
|
||||
efuse->xtal_cap = map->xtal_k;
|
||||
|
||||
rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type);
|
||||
|
||||
return 0;
|
||||
@@ -587,12 +670,16 @@ static void rtw8852c_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev,
|
||||
}
|
||||
}
|
||||
|
||||
#define __THM_MASK_SIGN BIT(0)
|
||||
#define __THM_MASK_3BITS GENMASK(3, 1)
|
||||
#define __THM_MASK_VAL8 BIT(4)
|
||||
|
||||
static void rtw8852c_thermal_trim(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
#define __thm_setting(raw) \
|
||||
({ \
|
||||
u8 __v = (raw); \
|
||||
((__v & 0x1) << 3) | ((__v & 0x1f) >> 1); \
|
||||
#define __thm_setting(raw) \
|
||||
({ \
|
||||
u8 __v = (raw); \
|
||||
((__v & __THM_MASK_SIGN) << 3) | ((__v & __THM_MASK_3BITS) >> 1); \
|
||||
})
|
||||
struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
|
||||
u8 i, val;
|
||||
@@ -2415,10 +2502,20 @@ static void rtw8852c_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en,
|
||||
static void rtw8852c_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_hal *hal = &rtwdev->hal;
|
||||
u8 nrx_path = RF_PATH_AB;
|
||||
u8 rx_nss = hal->rx_nss;
|
||||
|
||||
rtw8852c_bb_cfg_rx_path(rtwdev, RF_PATH_AB);
|
||||
if (hal->antenna_rx == RF_A)
|
||||
nrx_path = RF_PATH_A;
|
||||
else if (hal->antenna_rx == RF_B)
|
||||
nrx_path = RF_PATH_B;
|
||||
|
||||
if (hal->rx_nss == 1) {
|
||||
if (nrx_path != RF_PATH_AB)
|
||||
rx_nss = 1;
|
||||
|
||||
rtw8852c_bb_cfg_rx_path(rtwdev, nrx_path);
|
||||
|
||||
if (rx_nss == 1) {
|
||||
rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0);
|
||||
rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0);
|
||||
rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0);
|
||||
@@ -2433,13 +2530,26 @@ static void rtw8852c_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
|
||||
|
||||
static u8 rtw8852c_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path)
|
||||
{
|
||||
struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
|
||||
s8 comp = 0;
|
||||
u8 val;
|
||||
|
||||
rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1);
|
||||
rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x0);
|
||||
rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1);
|
||||
|
||||
fsleep(200);
|
||||
|
||||
return rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL);
|
||||
val = rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL);
|
||||
|
||||
if (info->pg_thermal_trim) {
|
||||
u8 trim = info->thermal_trim[rf_path];
|
||||
|
||||
if (trim & __THM_MASK_VAL8)
|
||||
comp = 8 * (trim & __THM_MASK_SIGN ? -1 : 1);
|
||||
}
|
||||
|
||||
return val + comp;
|
||||
}
|
||||
|
||||
static void rtw8852c_btc_set_rfe(struct rtw89_dev *rtwdev)
|
||||
@@ -2962,7 +3072,9 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = {
|
||||
.query_rxdesc = rtw89_core_query_rxdesc,
|
||||
.fill_txdesc = rtw89_core_fill_txdesc_v1,
|
||||
.fill_txdesc_fwcmd = rtw89_core_fill_txdesc_fwcmd_v1,
|
||||
.get_ch_dma = rtw89_core_get_ch_dma,
|
||||
.get_ch_dma = {rtw89_core_get_ch_dma,
|
||||
rtw89_core_get_ch_dma_v2,
|
||||
NULL,},
|
||||
.cfg_ctrl_path = rtw89_mac_cfg_ctrl_path_v1,
|
||||
.mac_cfg_gnt = rtw89_mac_cfg_gnt_v1,
|
||||
.stop_sch_tx = rtw89_mac_stop_sch_tx_v1,
|
||||
@@ -3006,8 +3118,13 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
|
||||
.max_amsdu_limit = 8000,
|
||||
.dis_2g_40m_ul_ofdma = false,
|
||||
.rsvd_ple_ofst = 0x6f800,
|
||||
.hfc_param_ini = {rtw8852c_hfc_param_ini_pcie, NULL, NULL},
|
||||
.dle_mem = {rtw8852c_dle_mem_pcie, NULL, NULL, NULL},
|
||||
.hfc_param_ini = {rtw8852c_hfc_param_ini_pcie,
|
||||
rtw8852c_hfc_param_ini_usb,
|
||||
NULL},
|
||||
.dle_mem = {rtw8852c_dle_mem_pcie,
|
||||
rtw8852c_dle_mem_usb2,
|
||||
rtw8852c_dle_mem_usb3,
|
||||
NULL},
|
||||
.wde_qempty_acq_grpnum = 16,
|
||||
.wde_qempty_mgq_grpsel = 16,
|
||||
.rf_base_addr = {0xe000, 0xf000},
|
||||
@@ -3061,6 +3178,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
|
||||
.bacam_num = 8,
|
||||
.bacam_dynamic_num = 8,
|
||||
.bacam_ver = RTW89_BACAM_V0_EXT,
|
||||
.addrcam_ver = 0,
|
||||
.ppdu_max_usr = 8,
|
||||
.sec_ctrl_efuse_size = 4,
|
||||
.physical_efuse_size = 1216,
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#define BB_PATH_NUM_8852C 2
|
||||
|
||||
struct rtw8852c_u_efuse {
|
||||
u8 rsvd[0x38];
|
||||
u8 rsvd[0x88];
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
};
|
||||
|
||||
|
||||
@@ -1344,7 +1344,7 @@ static void _iqk_get_ch_info(struct rtw89_dev *rtwdev,
|
||||
path, iqk_info->iqk_ch[path]);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_RFK,
|
||||
"[IQK]S%d (PHY%d): / DBCC %s/ %s/ CH%d/ %s\n", path, phy,
|
||||
rtwdev->dbcc_en ? "on" : "off",
|
||||
str_on_off(rtwdev->dbcc_en),
|
||||
iqk_info->iqk_band[path] == 0 ? "2G" :
|
||||
iqk_info->iqk_band[path] == 1 ? "5G" : "6G",
|
||||
iqk_info->iqk_ch[path],
|
||||
@@ -1920,8 +1920,8 @@ static void _dpk_information(struct rtw89_dev *rtwdev,
|
||||
rtw89_debug(rtwdev, RTW89_DBG_RFK,
|
||||
"[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n",
|
||||
path, dpk->cur_idx[path], phy,
|
||||
rtwdev->is_tssi_mode[path] ? "on" : "off",
|
||||
rtwdev->dbcc_en ? "on" : "off",
|
||||
str_on_off(rtwdev->is_tssi_mode[path]),
|
||||
str_on_off(rtwdev->dbcc_en),
|
||||
dpk->bp[path][kidx].band == 0 ? "2G" :
|
||||
dpk->bp[path][kidx].band == 1 ? "5G" : "6G",
|
||||
dpk->bp[path][kidx].ch,
|
||||
@@ -2000,7 +2000,7 @@ static void _dpk_txpwr_bb_force(struct rtw89_dev *rtwdev, u8 path, bool force)
|
||||
rtw89_phy_write32_mask(rtwdev, R_TXPWRB_H + (path << 13), B_TXPWRB_RDY, force);
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d txpwr_bb_force %s\n",
|
||||
path, force ? "on" : "off");
|
||||
path, str_on_off(force));
|
||||
}
|
||||
|
||||
static void _dpk_kip_restore(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
|
||||
@@ -2828,7 +2828,7 @@ static void _dpk_onoff(struct rtw89_dev *rtwdev,
|
||||
B_DPD_MEN, val);
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s !!!\n", path,
|
||||
kidx, dpk->is_dpk_enable && !off ? "enable" : "disable");
|
||||
kidx, str_enable_disable(dpk->is_dpk_enable && !off));
|
||||
}
|
||||
|
||||
static void _dpk_track(struct rtw89_dev *rtwdev)
|
||||
@@ -3987,37 +3987,56 @@ static void _ctrl_ch(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
|
||||
}
|
||||
}
|
||||
|
||||
static void _set_rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
|
||||
enum rtw89_bandwidth bw)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x1);
|
||||
rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M2, 0xa);
|
||||
|
||||
switch (bw) {
|
||||
case RTW89_CHANNEL_WIDTH_20:
|
||||
val = 0x1b;
|
||||
break;
|
||||
case RTW89_CHANNEL_WIDTH_40:
|
||||
val = 0x13;
|
||||
break;
|
||||
case RTW89_CHANNEL_WIDTH_80:
|
||||
val = 0xb;
|
||||
break;
|
||||
case RTW89_CHANNEL_WIDTH_160:
|
||||
default:
|
||||
val = 0x3;
|
||||
break;
|
||||
}
|
||||
|
||||
rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, val);
|
||||
rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x0);
|
||||
}
|
||||
|
||||
static void _set_tia_bw(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
|
||||
enum rtw89_bandwidth bw)
|
||||
{
|
||||
if (bw == RTW89_CHANNEL_WIDTH_160)
|
||||
rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_EBW, 0x0);
|
||||
else
|
||||
rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_EBW, 0x2);
|
||||
}
|
||||
|
||||
static void _rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
|
||||
enum rtw89_bandwidth bw)
|
||||
{
|
||||
u8 kpath;
|
||||
u8 path;
|
||||
u32 val;
|
||||
|
||||
kpath = _kpath(rtwdev, phy);
|
||||
for (path = 0; path < 2; path++) {
|
||||
if (!(kpath & BIT(path)))
|
||||
continue;
|
||||
|
||||
rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x1);
|
||||
rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M2, 0xa);
|
||||
switch (bw) {
|
||||
case RTW89_CHANNEL_WIDTH_20:
|
||||
val = 0x1b;
|
||||
break;
|
||||
case RTW89_CHANNEL_WIDTH_40:
|
||||
val = 0x13;
|
||||
break;
|
||||
case RTW89_CHANNEL_WIDTH_80:
|
||||
val = 0xb;
|
||||
break;
|
||||
case RTW89_CHANNEL_WIDTH_160:
|
||||
default:
|
||||
val = 0x3;
|
||||
break;
|
||||
}
|
||||
rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, val);
|
||||
rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x0);
|
||||
_set_rxbb_bw(rtwdev, path, bw);
|
||||
_set_tia_bw(rtwdev, path, bw);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
69
drivers/net/wireless/realtek/rtw89/rtw8852cu.c
Normal file
69
drivers/net/wireless/realtek/rtw89/rtw8852cu.c
Normal file
@@ -0,0 +1,69 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/* Copyright(c) 2025 Realtek Corporation
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/usb.h>
|
||||
#include "rtw8852c.h"
|
||||
#include "reg.h"
|
||||
#include "usb.h"
|
||||
|
||||
static const struct rtw89_usb_info rtw8852c_usb_info = {
|
||||
.usb_host_request_2 = R_AX_USB_HOST_REQUEST_2_V1,
|
||||
.usb_wlan0_1 = R_AX_USB_WLAN0_1_V1,
|
||||
.hci_func_en = R_AX_HCI_FUNC_EN_V1,
|
||||
.usb3_mac_npi_config_intf_0 = R_AX_USB3_MAC_NPI_CONFIG_INTF_0_V1,
|
||||
.usb_endpoint_0 = R_AX_USB_ENDPOINT_0_V1,
|
||||
.usb_endpoint_2 = R_AX_USB_ENDPOINT_2_V1,
|
||||
.bulkout_id = {
|
||||
[RTW89_DMA_ACH0] = 3,
|
||||
[RTW89_DMA_ACH2] = 5,
|
||||
[RTW89_DMA_ACH4] = 4,
|
||||
[RTW89_DMA_ACH6] = 6,
|
||||
[RTW89_DMA_B0MG] = 0,
|
||||
[RTW89_DMA_B0HI] = 0,
|
||||
[RTW89_DMA_B1MG] = 1,
|
||||
[RTW89_DMA_B1HI] = 1,
|
||||
[RTW89_DMA_H2C] = 2,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct rtw89_driver_info rtw89_8852cu_info = {
|
||||
.chip = &rtw8852c_chip_info,
|
||||
.variant = NULL,
|
||||
.quirks = NULL,
|
||||
.bus = {
|
||||
.usb = &rtw8852c_usb_info,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct usb_device_id rtw_8852cu_id_table[] = {
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xc832, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xc85a, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xc85d, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0db0, 0x991d, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x35b2, 0x0502, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x35bc, 0x0101, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x35bc, 0x0102, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, rtw_8852cu_id_table);
|
||||
|
||||
static struct usb_driver rtw_8852cu_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = rtw_8852cu_id_table,
|
||||
.probe = rtw89_usb_probe,
|
||||
.disconnect = rtw89_usb_disconnect,
|
||||
};
|
||||
module_usb_driver(rtw_8852cu_driver);
|
||||
|
||||
MODULE_AUTHOR("Bitterblue Smith <rtl8821cerfe2@gmail.com>");
|
||||
MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852CU driver");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
@@ -2347,19 +2347,29 @@ static void rtw8922a_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
|
||||
enum rtw89_band band = chan->band_type;
|
||||
struct rtw89_hal *hal = &rtwdev->hal;
|
||||
u8 ntx_path = RF_PATH_AB;
|
||||
u8 nrx_path = RF_PATH_AB;
|
||||
u32 tx_en0, tx_en1;
|
||||
u8 rx_nss = 2;
|
||||
|
||||
if (hal->antenna_tx == RF_A)
|
||||
ntx_path = RF_PATH_A;
|
||||
else if (hal->antenna_tx == RF_B)
|
||||
ntx_path = RF_PATH_B;
|
||||
|
||||
if (hal->antenna_rx == RF_A)
|
||||
nrx_path = RF_PATH_A;
|
||||
else if (hal->antenna_rx == RF_B)
|
||||
nrx_path = RF_PATH_B;
|
||||
|
||||
if (nrx_path != RF_PATH_AB)
|
||||
rx_nss = 1;
|
||||
|
||||
rtw8922a_hal_reset(rtwdev, RTW89_PHY_0, RTW89_MAC_0, band, &tx_en0, true);
|
||||
if (rtwdev->dbcc_en)
|
||||
rtw8922a_hal_reset(rtwdev, RTW89_PHY_1, RTW89_MAC_1, band,
|
||||
&tx_en1, true);
|
||||
|
||||
rtw8922a_ctrl_trx_path(rtwdev, ntx_path, 2, RF_PATH_AB, 2);
|
||||
rtw8922a_ctrl_trx_path(rtwdev, ntx_path, 2, nrx_path, rx_nss);
|
||||
|
||||
rtw8922a_hal_reset(rtwdev, RTW89_PHY_0, RTW89_MAC_0, band, &tx_en0, false);
|
||||
if (rtwdev->dbcc_en)
|
||||
@@ -2821,7 +2831,9 @@ static const struct rtw89_chip_ops rtw8922a_chip_ops = {
|
||||
.query_rxdesc = rtw89_core_query_rxdesc_v2,
|
||||
.fill_txdesc = rtw89_core_fill_txdesc_v2,
|
||||
.fill_txdesc_fwcmd = rtw89_core_fill_txdesc_fwcmd_v2,
|
||||
.get_ch_dma = rtw89_core_get_ch_dma,
|
||||
.get_ch_dma = {rtw89_core_get_ch_dma,
|
||||
rtw89_core_get_ch_dma_v2,
|
||||
NULL,},
|
||||
.cfg_ctrl_path = rtw89_mac_cfg_ctrl_path_v2,
|
||||
.mac_cfg_gnt = rtw89_mac_cfg_gnt_v2,
|
||||
.stop_sch_tx = rtw89_mac_stop_sch_tx_v2,
|
||||
@@ -2919,6 +2931,7 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
|
||||
.bacam_num = 24,
|
||||
.bacam_dynamic_num = 8,
|
||||
.bacam_ver = RTW89_BACAM_V1,
|
||||
.addrcam_ver = 0,
|
||||
.ppdu_max_usr = 16,
|
||||
.sec_ctrl_efuse_size = 4,
|
||||
.physical_efuse_size = 0x1300,
|
||||
|
||||
@@ -127,6 +127,8 @@ static inline u8 rtw89_get_data_nss(struct rtw89_dev *rtwdev, u16 hw_rate)
|
||||
#define RTW89_TXWD_INFO0_MULTIPORT_ID GENMASK(6, 4)
|
||||
|
||||
/* TX WD INFO DWORD 1 */
|
||||
#define RTW89_TXWD_INFO1_DATA_TXCNT_LMT_SEL BIT(31)
|
||||
#define RTW89_TXWD_INFO1_DATA_TXCNT_LMT GENMASK(30, 25)
|
||||
#define RTW89_TXWD_INFO1_DATA_RTY_LOWEST_RATE GENMASK(24, 16)
|
||||
#define RTW89_TXWD_INFO1_A_CTRL_BSR BIT(14)
|
||||
#define RTW89_TXWD_INFO1_MAX_AGGNUM GENMASK(7, 0)
|
||||
@@ -139,10 +141,12 @@ static inline u8 rtw89_get_data_nss(struct rtw89_dev *rtwdev, u16 hw_rate)
|
||||
#define RTW89_TXWD_INFO2_SEC_CAM_IDX GENMASK(7, 0)
|
||||
|
||||
/* TX WD INFO DWORD 3 */
|
||||
#define RTW89_TXWD_INFO3_SPE_RPT BIT(10)
|
||||
|
||||
/* TX WD INFO DWORD 4 */
|
||||
#define RTW89_TXWD_INFO4_RTS_EN BIT(27)
|
||||
#define RTW89_TXWD_INFO4_HW_RTS_EN BIT(31)
|
||||
#define RTW89_TXWD_INFO4_RTS_EN BIT(27)
|
||||
#define RTW89_TXWD_INFO4_SW_DEFINE GENMASK(3, 0)
|
||||
|
||||
/* TX WD INFO DWORD 5 */
|
||||
|
||||
@@ -417,6 +421,7 @@ struct rtw89_rxinfo_user {
|
||||
#define RTW89_RXINFO_USER_MGMT BIT(3)
|
||||
#define RTW89_RXINFO_USER_BCN BIT(4)
|
||||
#define RTW89_RXINFO_USER_MACID GENMASK(15, 8)
|
||||
#define RTW89_RXINFO_USER_MACID_V1 GENMASK(31, 20)
|
||||
|
||||
struct rtw89_rxinfo {
|
||||
__le32 w0;
|
||||
|
||||
@@ -55,7 +55,7 @@ static void rtw89_usb_vendorreq(struct rtw89_dev *rtwdev, u32 addr,
|
||||
else if (ret < 0)
|
||||
rtw89_warn(rtwdev,
|
||||
"usb %s%u 0x%x fail ret=%d value=0x%x attempt=%d\n",
|
||||
reqtype == RTW89_USB_VENQT_READ ? "read" : "write",
|
||||
str_read_write(reqtype == RTW89_USB_VENQT_READ),
|
||||
len * 8, addr, ret,
|
||||
le32_to_cpup(rtwusb->vendor_req_buf),
|
||||
attempt);
|
||||
@@ -167,27 +167,6 @@ rtw89_usb_ops_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev,
|
||||
return 42; /* TODO some kind of calculation? */
|
||||
}
|
||||
|
||||
static u8 rtw89_usb_get_bulkout_id(u8 ch_dma)
|
||||
{
|
||||
switch (ch_dma) {
|
||||
case RTW89_DMA_ACH0:
|
||||
return 3;
|
||||
case RTW89_DMA_ACH1:
|
||||
return 4;
|
||||
case RTW89_DMA_ACH2:
|
||||
return 5;
|
||||
case RTW89_DMA_ACH3:
|
||||
return 6;
|
||||
default:
|
||||
case RTW89_DMA_B0MG:
|
||||
return 0;
|
||||
case RTW89_DMA_B0HI:
|
||||
return 1;
|
||||
case RTW89_DMA_H2C:
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void rtw89_usb_write_port_complete(struct urb *urb)
|
||||
{
|
||||
struct rtw89_usb_tx_ctrl_block *txcb = urb->context;
|
||||
@@ -215,6 +194,15 @@ static void rtw89_usb_write_port_complete(struct urb *urb)
|
||||
|
||||
skb_pull(skb, txdesc_size);
|
||||
|
||||
if (rtw89_is_tx_rpt_skb(rtwdev, skb)) {
|
||||
if (urb->status == 0)
|
||||
rtw89_tx_rpt_skb_add(rtwdev, skb);
|
||||
else
|
||||
rtw89_tx_rpt_tx_status(rtwdev, skb,
|
||||
RTW89_TX_MACID_DROP);
|
||||
continue;
|
||||
}
|
||||
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
ieee80211_tx_info_clear_status(info);
|
||||
|
||||
@@ -242,21 +230,21 @@ static void rtw89_usb_write_port_complete(struct urb *urb)
|
||||
}
|
||||
|
||||
kfree(txcb);
|
||||
usb_free_urb(urb);
|
||||
}
|
||||
|
||||
static int rtw89_usb_write_port(struct rtw89_dev *rtwdev, u8 ch_dma,
|
||||
void *data, int len, void *context)
|
||||
{
|
||||
struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev);
|
||||
const struct rtw89_usb_info *info = rtwusb->info;
|
||||
struct usb_device *usbd = rtwusb->udev;
|
||||
struct urb *urb;
|
||||
u8 bulkout_id = rtw89_usb_get_bulkout_id(ch_dma);
|
||||
u8 bulkout_id = info->bulkout_id[ch_dma];
|
||||
unsigned int pipe;
|
||||
int ret;
|
||||
|
||||
if (test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags))
|
||||
return 0;
|
||||
return -ENODEV;
|
||||
|
||||
urb = usb_alloc_urb(0, GFP_ATOMIC);
|
||||
if (!urb)
|
||||
@@ -267,10 +255,17 @@ static int rtw89_usb_write_port(struct rtw89_dev *rtwdev, u8 ch_dma,
|
||||
usb_fill_bulk_urb(urb, usbd, pipe, data, len,
|
||||
rtw89_usb_write_port_complete, context);
|
||||
urb->transfer_flags |= URB_ZERO_PACKET;
|
||||
ret = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
usb_anchor_urb(urb, &rtwusb->tx_submitted);
|
||||
|
||||
ret = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (ret)
|
||||
usb_free_urb(urb);
|
||||
usb_unanchor_urb(urb);
|
||||
|
||||
/* release our reference to this URB, USB core will eventually free it
|
||||
* on its own after the completion callback finishes (or URB is
|
||||
* immediately freed here if its submission has failed)
|
||||
*/
|
||||
usb_free_urb(urb);
|
||||
|
||||
if (ret == -ENODEV)
|
||||
set_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags);
|
||||
@@ -278,6 +273,15 @@ static int rtw89_usb_write_port(struct rtw89_dev *rtwdev, u8 ch_dma,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rtw89_usb_tx_free_skb(struct rtw89_dev *rtwdev, u8 txch,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
if (txch == RTW89_TXCH_CH12)
|
||||
dev_kfree_skb_any(skb);
|
||||
else
|
||||
ieee80211_free_txskb(rtwdev->hw, skb);
|
||||
}
|
||||
|
||||
static void rtw89_usb_ops_tx_kick_off(struct rtw89_dev *rtwdev, u8 txch)
|
||||
{
|
||||
struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev);
|
||||
@@ -292,7 +296,7 @@ static void rtw89_usb_ops_tx_kick_off(struct rtw89_dev *rtwdev, u8 txch)
|
||||
|
||||
txcb = kmalloc(sizeof(*txcb), GFP_ATOMIC);
|
||||
if (!txcb) {
|
||||
dev_kfree_skb_any(skb);
|
||||
rtw89_usb_tx_free_skb(rtwdev, txch, skb);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -305,12 +309,13 @@ static void rtw89_usb_ops_tx_kick_off(struct rtw89_dev *rtwdev, u8 txch)
|
||||
ret = rtw89_usb_write_port(rtwdev, txch, skb->data, skb->len,
|
||||
txcb);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "write port txch %d failed: %d\n",
|
||||
txch, ret);
|
||||
if (ret != -ENODEV)
|
||||
rtw89_err(rtwdev, "write port txch %d failed: %d\n",
|
||||
txch, ret);
|
||||
|
||||
skb_dequeue(&txcb->tx_ack_queue);
|
||||
kfree(txcb);
|
||||
dev_kfree_skb_any(skb);
|
||||
rtw89_usb_tx_free_skb(rtwdev, txch, skb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -362,6 +367,7 @@ static int rtw89_usb_ops_tx_write(struct rtw89_dev *rtwdev,
|
||||
{
|
||||
struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
|
||||
struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev);
|
||||
struct rtw89_tx_skb_data *skb_data;
|
||||
struct sk_buff *skb = tx_req->skb;
|
||||
struct rtw89_txwd_body *txdesc;
|
||||
u32 txdesc_size;
|
||||
@@ -388,6 +394,12 @@ static int rtw89_usb_ops_tx_write(struct rtw89_dev *rtwdev,
|
||||
|
||||
le32p_replace_bits(&txdesc->dword0, 1, RTW89_TXWD_BODY0_STF_MODE);
|
||||
|
||||
skb_data = RTW89_TX_SKB_CB(skb);
|
||||
if (tx_req->desc_info.sn)
|
||||
skb_data->tx_rpt_sn = tx_req->desc_info.sn;
|
||||
if (tx_req->desc_info.tx_cnt_lmt)
|
||||
skb_data->tx_pkt_cnt_lmt = tx_req->desc_info.tx_cnt_lmt;
|
||||
|
||||
skb_queue_tail(&rtwusb->tx_queue[desc_info->ch_dma], skb);
|
||||
|
||||
return 0;
|
||||
@@ -410,8 +422,7 @@ static void rtw89_usb_rx_handler(struct work_struct *work)
|
||||
|
||||
if (skb_queue_len(&rtwusb->rx_queue) >= RTW89_USB_MAX_RXQ_LEN) {
|
||||
rtw89_warn(rtwdev, "rx_queue overflow\n");
|
||||
dev_kfree_skb_any(rx_skb);
|
||||
continue;
|
||||
goto free_or_reuse;
|
||||
}
|
||||
|
||||
memset(&desc_info, 0, sizeof(desc_info));
|
||||
@@ -422,7 +433,7 @@ static void rtw89_usb_rx_handler(struct work_struct *work)
|
||||
rtw89_debug(rtwdev, RTW89_DBG_HCI,
|
||||
"failed to allocate RX skb of size %u\n",
|
||||
desc_info.pkt_size);
|
||||
continue;
|
||||
goto free_or_reuse;
|
||||
}
|
||||
|
||||
pkt_offset = desc_info.offset + desc_info.rxd_len;
|
||||
@@ -432,6 +443,7 @@ static void rtw89_usb_rx_handler(struct work_struct *work)
|
||||
|
||||
rtw89_core_rx(rtwdev, &desc_info, skb);
|
||||
|
||||
free_or_reuse:
|
||||
if (skb_queue_len(&rtwusb->rx_free_queue) >= RTW89_USB_RX_SKB_NUM)
|
||||
dev_kfree_skb_any(rx_skb);
|
||||
else
|
||||
@@ -567,6 +579,11 @@ static void rtw89_usb_cancel_rx_bufs(struct rtw89_usb *rtwusb)
|
||||
}
|
||||
}
|
||||
|
||||
static void rtw89_usb_cancel_tx_bufs(struct rtw89_usb *rtwusb)
|
||||
{
|
||||
usb_kill_anchored_urbs(&rtwusb->tx_submitted);
|
||||
}
|
||||
|
||||
static void rtw89_usb_free_rx_bufs(struct rtw89_usb *rtwusb)
|
||||
{
|
||||
struct rtw89_usb_rx_ctrl_block *rxcb;
|
||||
@@ -668,7 +685,10 @@ static void rtw89_usb_deinit_tx(struct rtw89_dev *rtwdev)
|
||||
|
||||
static void rtw89_usb_ops_reset(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
/* TODO: anything to do here? */
|
||||
struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev);
|
||||
|
||||
rtw89_usb_cancel_tx_bufs(rtwusb);
|
||||
rtw89_tx_rpt_skbs_purge(rtwdev);
|
||||
}
|
||||
|
||||
static int rtw89_usb_ops_start(struct rtw89_dev *rtwdev)
|
||||
@@ -698,20 +718,23 @@ static int rtw89_usb_ops_deinit(struct rtw89_dev *rtwdev)
|
||||
|
||||
static int rtw89_usb_ops_mac_pre_init(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev);
|
||||
const struct rtw89_usb_info *info = rtwusb->info;
|
||||
u32 val32;
|
||||
|
||||
rtw89_write32_set(rtwdev, R_AX_USB_HOST_REQUEST_2, B_AX_R_USBIO_MODE);
|
||||
rtw89_write32_set(rtwdev, info->usb_host_request_2,
|
||||
B_AX_R_USBIO_MODE);
|
||||
|
||||
/* fix USB IO hang suggest by chihhanli@realtek.com */
|
||||
rtw89_write32_clr(rtwdev, R_AX_USB_WLAN0_1,
|
||||
rtw89_write32_clr(rtwdev, info->usb_wlan0_1,
|
||||
B_AX_USBRX_RST | B_AX_USBTX_RST);
|
||||
|
||||
val32 = rtw89_read32(rtwdev, R_AX_HCI_FUNC_EN);
|
||||
val32 = rtw89_read32(rtwdev, info->hci_func_en);
|
||||
val32 &= ~(B_AX_HCI_RXDMA_EN | B_AX_HCI_TXDMA_EN);
|
||||
rtw89_write32(rtwdev, R_AX_HCI_FUNC_EN, val32);
|
||||
rtw89_write32(rtwdev, info->hci_func_en, val32);
|
||||
|
||||
val32 |= B_AX_HCI_RXDMA_EN | B_AX_HCI_TXDMA_EN;
|
||||
rtw89_write32(rtwdev, R_AX_HCI_FUNC_EN, val32);
|
||||
rtw89_write32(rtwdev, info->hci_func_en, val32);
|
||||
/* fix USB TRX hang suggest by chihhanli@realtek.com */
|
||||
|
||||
return 0;
|
||||
@@ -725,10 +748,11 @@ static int rtw89_usb_ops_mac_pre_deinit(struct rtw89_dev *rtwdev)
|
||||
static int rtw89_usb_ops_mac_post_init(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev);
|
||||
const struct rtw89_usb_info *info = rtwusb->info;
|
||||
enum usb_device_speed speed;
|
||||
u32 ep;
|
||||
|
||||
rtw89_write32_clr(rtwdev, R_AX_USB3_MAC_NPI_CONFIG_INTF_0,
|
||||
rtw89_write32_clr(rtwdev, info->usb3_mac_npi_config_intf_0,
|
||||
B_AX_SSPHY_LFPS_FILTER);
|
||||
|
||||
speed = rtwusb->udev->speed;
|
||||
@@ -744,9 +768,9 @@ static int rtw89_usb_ops_mac_post_init(struct rtw89_dev *rtwdev)
|
||||
if (ep == 8)
|
||||
continue;
|
||||
|
||||
rtw89_write8_mask(rtwdev, R_AX_USB_ENDPOINT_0,
|
||||
rtw89_write8_mask(rtwdev, info->usb_endpoint_0,
|
||||
B_AX_EP_IDX, ep);
|
||||
rtw89_write8(rtwdev, R_AX_USB_ENDPOINT_2 + 1, NUMP);
|
||||
rtw89_write8(rtwdev, info->usb_endpoint_2 + 1, NUMP);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -901,6 +925,8 @@ static int rtw89_usb_intf_init(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev);
|
||||
int ret;
|
||||
|
||||
init_usb_anchor(&rtwusb->tx_submitted);
|
||||
|
||||
ret = rtw89_usb_parse(rtwdev, intf);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -949,9 +975,11 @@ int rtw89_usb_probe(struct usb_interface *intf,
|
||||
|
||||
rtwusb = rtw89_usb_priv(rtwdev);
|
||||
rtwusb->rtwdev = rtwdev;
|
||||
rtwusb->info = info->bus.usb;
|
||||
|
||||
rtwdev->hci.ops = &rtw89_usb_ops;
|
||||
rtwdev->hci.type = RTW89_HCI_TYPE_USB;
|
||||
rtwdev->hci.tx_rpt_enabled = true;
|
||||
|
||||
ret = rtw89_usb_intf_init(rtwdev, intf);
|
||||
if (ret) {
|
||||
@@ -1026,6 +1054,7 @@ void rtw89_usb_disconnect(struct usb_interface *intf)
|
||||
rtwusb = rtw89_usb_priv(rtwdev);
|
||||
|
||||
rtw89_usb_cancel_rx_bufs(rtwusb);
|
||||
rtw89_usb_cancel_tx_bufs(rtwusb);
|
||||
|
||||
rtw89_core_unregister(rtwdev);
|
||||
rtw89_core_deinit(rtwdev);
|
||||
|
||||
@@ -20,6 +20,16 @@
|
||||
#define RTW89_MAX_ENDPOINT_NUM 9
|
||||
#define RTW89_MAX_BULKOUT_NUM 7
|
||||
|
||||
struct rtw89_usb_info {
|
||||
u32 usb_host_request_2;
|
||||
u32 usb_wlan0_1;
|
||||
u32 hci_func_en;
|
||||
u32 usb3_mac_npi_config_intf_0;
|
||||
u32 usb_endpoint_0;
|
||||
u32 usb_endpoint_2;
|
||||
u8 bulkout_id[RTW89_DMA_CH_NUM];
|
||||
};
|
||||
|
||||
struct rtw89_usb_rx_ctrl_block {
|
||||
struct rtw89_dev *rtwdev;
|
||||
struct urb *rx_urb;
|
||||
@@ -35,6 +45,7 @@ struct rtw89_usb_tx_ctrl_block {
|
||||
struct rtw89_usb {
|
||||
struct rtw89_dev *rtwdev;
|
||||
struct usb_device *udev;
|
||||
const struct rtw89_usb_info *info;
|
||||
|
||||
__le32 *vendor_req_buf;
|
||||
|
||||
@@ -49,6 +60,7 @@ struct rtw89_usb {
|
||||
struct sk_buff_head rx_free_queue;
|
||||
struct work_struct rx_work;
|
||||
struct work_struct rx_urb_work;
|
||||
struct usb_anchor tx_submitted;
|
||||
|
||||
struct sk_buff_head tx_queue[RTW89_TXCH_NUM];
|
||||
};
|
||||
|
||||
@@ -1221,7 +1221,8 @@ static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow)
|
||||
}
|
||||
}
|
||||
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL,
|
||||
RTW89_ROLE_INFO_CHANGE);
|
||||
if (ret) {
|
||||
rtw89_warn(rtwdev, "failed to send h2c cam\n");
|
||||
return ret;
|
||||
@@ -1248,7 +1249,7 @@ static int rtw89_wow_check_fw_status(struct rtw89_dev *rtwdev, bool wow_enable)
|
||||
mac->wow_ctrl.addr, mac->wow_ctrl.mask);
|
||||
if (ret)
|
||||
rtw89_err(rtwdev, "failed to check wow status %s\n",
|
||||
wow_enable ? "enabled" : "disabled");
|
||||
str_enabled_disabled(wow_enable));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1318,7 +1319,8 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
|
||||
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL,
|
||||
RTW89_ROLE_FW_RESTORE);
|
||||
if (ret) {
|
||||
rtw89_warn(rtwdev, "failed to send h2c cam\n");
|
||||
return ret;
|
||||
|
||||
Reference in New Issue
Block a user