staging: r8822be: Add the driver code

The RTL8822BE, an 802.11ac wireless network card, is now appearing in
new computers. Its driver is being placed in staging to reduce the time
that users of this new card will have access to in-kernel drivers.

This commit adds the code for the new r8822be driver.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Yan-Hsuan Chuang <yhchuang@realtek.com>
Cc: Birming Chiu <birming@realtek.com>
Cc: Shaofu <shaofu@realtek.com>
Cc: Steven Ting <steventing@realtek.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Ping-Ke Shih 2017-08-17 12:46:50 -05:00 committed by Greg Kroah-Hartman
parent 9ce99b04b5
commit 7e5b796cde
14 changed files with 9647 additions and 0 deletions

View File

@ -0,0 +1,82 @@
/******************************************************************************
*
* Copyright(c) 2016 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL8822B_DEF_H__
#define __RTL8822B_DEF_H__
#define RX_DESC_NUM_8822BE 512
#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
#define HAL_PRIME_CHNL_OFFSET_LOWER 1
#define HAL_PRIME_CHNL_OFFSET_UPPER 2
#define RX_MPDU_QUEUE 0
#define IS_HT_RATE(_rate) (_rate >= DESC_RATEMCS0)
#define IS_CCK_RATE(_rate) (_rate >= DESC_RATE1M && _rate <= DESC_RATE11M)
#define IS_OFDM_RATE(_rate) (_rate >= DESC_RATE6M && _rate <= DESC_RATE54M)
#define IS_1T_RATE(_rate) \
((_rate >= DESC_RATE1M && _rate <= DESC_RATEMCS7) || \
(_rate >= DESC_RATEVHT1SS_MCS0 && _rate <= DESC_RATEVHT1SS_MCS9))
#define IS_2T_RATE(_rate) \
((_rate >= DESC_RATEMCS8 && _rate <= DESC_RATEMCS15) || \
(_rate >= DESC_RATEVHT2SS_MCS0 && _rate <= DESC_RATEVHT2SS_MCS9))
#define IS_1T_RATESEC(_rs) \
((_rs == CCK) || (_rs == OFDM) || (_rs == HT_MCS0_MCS7) || \
(_rs == VHT_1SSMCS0_1SSMCS9))
#define IS_2T_RATESEC(_rs) \
((_rs == HT_MCS8_MCS15) || (_rs == VHT_2SSMCS0_2SSMCS9))
enum rx_packet_type {
NORMAL_RX,
C2H_PACKET,
};
enum rtl_desc_qsel {
QSLT_BK = 0x2,
QSLT_BE = 0x0,
QSLT_VI = 0x5,
QSLT_VO = 0x7,
QSLT_BEACON = 0x10,
QSLT_HIGH = 0x11,
QSLT_MGNT = 0x12,
QSLT_CMD = 0x13,
};
enum vht_data_sc {
VHT_DATA_SC_DONOT_CARE = 0,
VHT_DATA_SC_20_UPPER_OF_80MHZ = 1,
VHT_DATA_SC_20_LOWER_OF_80MHZ = 2,
VHT_DATA_SC_20_UPPERST_OF_80MHZ = 3,
VHT_DATA_SC_20_LOWEST_OF_80MHZ = 4,
VHT_DATA_SC_20_RECV1 = 5,
VHT_DATA_SC_20_RECV2 = 6,
VHT_DATA_SC_20_RECV3 = 7,
VHT_DATA_SC_20_RECV4 = 8,
VHT_DATA_SC_40_UPPER_OF_80MHZ = 9,
VHT_DATA_SC_40_LOWER_OF_80MHZ = 10,
};
#endif

View File

@ -0,0 +1,968 @@
/******************************************************************************
*
* Copyright(c) 2016 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "../pci.h"
#include "../base.h"
#include "reg.h"
#include "def.h"
#include "fw.h"
static bool _rtl8822be_check_fw_read_last_h2c(struct ieee80211_hw *hw,
u8 boxnum)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 val_hmetfr;
bool result = false;
val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR_8822B);
if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
result = true;
return result;
}
static void _rtl8822be_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
u32 cmd_len, u8 *cmdbuffer)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
u8 boxnum;
u16 box_reg = 0, box_extreg = 0;
u8 u1b_tmp;
bool isfw_read;
u8 buf_index = 0;
bool bwrite_success = false;
u8 wait_h2c_limmit = 100;
u8 boxcontent[4], boxextcontent[4];
u32 h2c_waitcounter = 0;
unsigned long flag;
u8 idx;
/* 1. Prevent race condition in setting H2C cmd.
* (copy from MgntActSet_RF_State().)
*/
while (true) {
spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
if (rtlhal->h2c_setinprogress) {
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"H2C set in progress! wait..H2C_ID=%d.\n",
element_id);
while (rtlhal->h2c_setinprogress) {
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
flag);
h2c_waitcounter++;
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"Wait 100 us (%d times)...\n",
h2c_waitcounter);
udelay(100);
if (h2c_waitcounter > 1000)
return;
spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
flag);
}
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
} else {
rtlhal->h2c_setinprogress = true;
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
break;
}
}
while (!bwrite_success) {
/* 2. Find the last BOX number which has been writen. */
boxnum = rtlhal->last_hmeboxnum;
switch (boxnum) {
case 0:
box_reg = REG_HMEBOX0_8822B;
box_extreg = REG_HMEBOX_E0_8822B;
break;
case 1:
box_reg = REG_HMEBOX1_8822B;
box_extreg = REG_HMEBOX_E1_8822B;
break;
case 2:
box_reg = REG_HMEBOX2_8822B;
box_extreg = REG_HMEBOX_E2_8822B;
break;
case 3:
box_reg = REG_HMEBOX3_8822B;
box_extreg = REG_HMEBOX_E3_8822B;
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
"switch case not process\n");
break;
}
/* 3. Check if the box content is empty. */
u1b_tmp = rtl_read_byte(rtlpriv, REG_CR_8822B);
if (u1b_tmp == 0xea) {
if (rtl_read_byte(rtlpriv, REG_TXDMA_STATUS_8822B) ==
0xea ||
rtl_read_byte(rtlpriv, REG_TXPKT_EMPTY_8822B) ==
0xea)
rtl_write_byte(rtlpriv, REG_SYS_CFG1_8822B + 3,
0xff);
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"REG_CR is unavaliable\n");
break;
}
wait_h2c_limmit = 100;
isfw_read = _rtl8822be_check_fw_read_last_h2c(hw, boxnum);
while (!isfw_read) {
wait_h2c_limmit--;
if (wait_h2c_limmit == 0) {
RT_TRACE(rtlpriv, COMP_CMD, DBG_WARNING,
"Wait too long for FW clear MB%d!!!\n",
boxnum);
break;
}
udelay(10);
isfw_read =
_rtl8822be_check_fw_read_last_h2c(hw, boxnum);
u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"Waiting for FW clear MB%d!!! 0x130 = %2x\n",
boxnum, u1b_tmp);
}
/* If Fw has not read the last H2C cmd,
* break and give up this H2C.
*/
if (!isfw_read) {
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"Write H2C reg BOX[%d] fail,Fw don't read.\n",
boxnum);
break;
}
/* 4. Fill the H2C cmd into box */
memset(boxcontent, 0, sizeof(boxcontent));
memset(boxextcontent, 0, sizeof(boxextcontent));
boxcontent[0] = element_id;
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"Write element_id box_reg(%4x) = %2x\n", box_reg,
element_id);
switch (cmd_len) {
case 1:
case 2:
case 3:
/*boxcontent[0] &= ~(BIT(7));*/
memcpy((u8 *)(boxcontent) + 1, cmdbuffer + buf_index,
cmd_len);
for (idx = 0; idx < 4; idx++) {
rtl_write_byte(rtlpriv, box_reg + idx,
boxcontent[idx]);
}
break;
case 4:
case 5:
case 6:
case 7:
/*boxcontent[0] |= (BIT(7));*/
memcpy((u8 *)(boxextcontent), cmdbuffer + buf_index + 3,
cmd_len - 3);
memcpy((u8 *)(boxcontent) + 1, cmdbuffer + buf_index,
3);
for (idx = 0; idx < 4; idx++) {
rtl_write_byte(rtlpriv, box_extreg + idx,
boxextcontent[idx]);
}
for (idx = 0; idx < 4; idx++) {
rtl_write_byte(rtlpriv, box_reg + idx,
boxcontent[idx]);
}
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
"switch case not process\n");
break;
}
bwrite_success = true;
rtlhal->last_hmeboxnum = boxnum + 1;
if (rtlhal->last_hmeboxnum == 4)
rtlhal->last_hmeboxnum = 0;
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"pHalData->last_hmeboxnum = %d\n",
rtlhal->last_hmeboxnum);
}
spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
rtlhal->h2c_setinprogress = false;
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
}
void rtl8822be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, u32 cmd_len,
u8 *cmdbuffer)
{
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 tmp_cmdbuf[8];
if (!rtlhal->fw_ready) {
WARN_ONCE(true,
"return H2C cmd because of Fw download fail!!!\n");
return;
}
memset(tmp_cmdbuf, 0, 8);
memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
"h2c cmd: len=%d %02X%02X%02X%02X %02X%02X%02X%02X\n", cmd_len,
tmp_cmdbuf[2], tmp_cmdbuf[1], tmp_cmdbuf[0], element_id,
tmp_cmdbuf[6], tmp_cmdbuf[5], tmp_cmdbuf[4], tmp_cmdbuf[3]);
_rtl8822be_fill_h2c_command(hw, element_id, cmd_len, tmp_cmdbuf);
}
void rtl8822be_set_default_port_id_cmd(struct ieee80211_hw *hw)
{
u8 h2c_set_default_port_id[H2C_DEFAULT_PORT_ID_LEN];
SET_H2CCMD_DFTPID_PORT_ID(h2c_set_default_port_id, 0);
SET_H2CCMD_DFTPID_MAC_ID(h2c_set_default_port_id, 0);
rtl8822be_fill_h2c_cmd(hw, H2C_8822B_DEFAULT_PORT_ID,
H2C_DEFAULT_PORT_ID_LEN,
h2c_set_default_port_id);
}
void rtl8822be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 u1_h2c_set_pwrmode[H2C_8822B_PWEMODE_LENGTH] = {0};
static u8 prev_h2c[H2C_8822B_PWEMODE_LENGTH] = {0};
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
u8 rlbm, power_state = 0, byte5 = 0;
u8 awake_intvl; /* DTIM = (awake_intvl - 1) */
u8 smart_ps = 0;
struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ?
btc_ops->btc_is_bt_lps_on(rtlpriv) : false);
memset(u1_h2c_set_pwrmode, 0, H2C_8822B_PWEMODE_LENGTH);
if (bt_ctrl_lps)
mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE);
RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
mode, bt_ctrl_lps);
switch (mode) {
case FW_PS_MIN_MODE:
rlbm = 0;
awake_intvl = 2;
smart_ps = ppsc->smart_ps;
break;
case FW_PS_MAX_MODE:
rlbm = 1;
awake_intvl = 2;
smart_ps = ppsc->smart_ps;
break;
case FW_PS_DTIM_MODE:
rlbm = 2;
awake_intvl = ppsc->reg_max_lps_awakeintvl;
/*
* hw->conf.ps_dtim_period or mac->vif->bss_conf.dtim_period
* is only used in swlps.
*/
smart_ps = ppsc->smart_ps;
break;
case FW_PS_ACTIVE_MODE:
rlbm = 0;
awake_intvl = 1;
break;
default:
rlbm = 2;
awake_intvl = 4;
smart_ps = ppsc->smart_ps;
break;
}
if (rtlpriv->mac80211.p2p) {
awake_intvl = 2;
rlbm = 1;
}
if (mode == FW_PS_ACTIVE_MODE) {
byte5 = 0x40;
power_state = FW_PWR_STATE_ACTIVE;
} else {
if (bt_ctrl_lps) {
byte5 = btc_ops->btc_get_lps_val(rtlpriv);
power_state = btc_ops->btc_get_rpwm_val(rtlpriv);
if ((rlbm == 2) && (byte5 & BIT(4))) {
/* Keep awake interval to 1 to prevent from
* decreasing coex performance
*/
awake_intvl = 2;
rlbm = 2;
}
smart_ps = 0;
} else {
byte5 = 0x40;
power_state = FW_PWR_STATE_RF_OFF;
}
}
SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, smart_ps);
SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode, awake_intvl);
SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5);
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
"rtl8822be_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
u1_h2c_set_pwrmode, H2C_8822B_PWEMODE_LENGTH);
if (rtlpriv->cfg->ops->get_btc_status())
btc_ops->btc_record_pwr_mode(rtlpriv, u1_h2c_set_pwrmode,
H2C_8822B_PWEMODE_LENGTH);
if (!memcmp(prev_h2c, u1_h2c_set_pwrmode, H2C_8822B_PWEMODE_LENGTH))
return;
memcpy(prev_h2c, u1_h2c_set_pwrmode, H2C_8822B_PWEMODE_LENGTH);
rtl8822be_set_default_port_id_cmd(hw);
rtl8822be_fill_h2c_cmd(hw, H2C_8822B_SETPWRMODE,
H2C_8822B_PWEMODE_LENGTH, u1_h2c_set_pwrmode);
}
void rtl8822be_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
{
u8 parm[4] = {0, 0, 0, 0};
/* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect
* bit1=0-->update Media Status to MACID
* bit1=1-->update Media Status from MACID to MACID_End
* parm[1]: MACID, if this is INFRA_STA, MacID = 0
* parm[2]: MACID_End
* parm[3]: bit2-0: port ID
*/
SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus);
SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
rtl8822be_fill_h2c_cmd(hw, H2C_8822B_MSRRPT, 4, parm);
}
static bool _rtl8822be_send_bcn_or_cmd_packet(struct ieee80211_hw *hw,
struct sk_buff *skb, u8 hw_queue)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl8192_tx_ring *ring;
struct rtl_tx_desc *pdesc;
struct rtl_tx_buffer_desc *pbd_desc;
unsigned long flags;
struct sk_buff *pskb = NULL;
u8 *pdesc_or_bddesc;
dma_addr_t dma_addr;
if (hw_queue != BEACON_QUEUE && hw_queue != H2C_QUEUE)
return false;
ring = &rtlpci->tx_ring[hw_queue];
spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
if (hw_queue == BEACON_QUEUE) {
pdesc = &ring->desc[0];
pbd_desc = &ring->buffer_desc[0];
pdesc_or_bddesc = (u8 *)pbd_desc;
/* free previous beacon queue */
pskb = __skb_dequeue(&ring->queue);
if (!pskb)
goto free_prev_skb_done;
dma_addr = rtlpriv->cfg->ops->get_desc(
hw, (u8 *)pbd_desc, true, HW_DESC_TXBUFF_ADDR);
pci_unmap_single(rtlpci->pdev, dma_addr, skb->len,
PCI_DMA_TODEVICE);
kfree_skb(pskb);
free_prev_skb_done:
;
} else { /* hw_queue == TXCMD_QUEUE */
if (rtlpriv->cfg->ops->get_available_desc(hw, hw_queue) == 0) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
"get_available_desc fail hw_queue=%d\n",
hw_queue);
spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock,
flags);
return false;
}
pdesc = &ring->desc[ring->cur_tx_wp];
pbd_desc = &ring->buffer_desc[ring->cur_tx_wp];
pdesc_or_bddesc = (u8 *)pdesc;
}
rtlpriv->cfg->ops->fill_tx_special_desc(hw, (u8 *)pdesc, (u8 *)pbd_desc,
skb, hw_queue);
__skb_queue_tail(&ring->queue, skb);
rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc_or_bddesc, true,
HW_DESC_OWN, (u8 *)&hw_queue);
spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
rtlpriv->cfg->ops->tx_polling(hw, hw_queue);
return true;
}
bool rtl8822b_halmac_cb_write_data_rsvd_page(struct rtl_priv *rtlpriv, u8 *buf,
u32 size)
{
struct sk_buff *skb = NULL;
u8 u1b_tmp;
int count;
skb = dev_alloc_skb(size);
memcpy((u8 *)skb_put(skb, size), buf, size);
if (!_rtl8822be_send_bcn_or_cmd_packet(rtlpriv->hw, skb, BEACON_QUEUE))
return false;
/* These code isn't actually need, because halmac will check
* BCN_VALID
*/
/* Polling Beacon Queue to send Beacon */
u1b_tmp = rtl_read_byte(rtlpriv, REG_RX_RXBD_NUM_8822B + 1);
count = 0;
while ((count < 20) && (u1b_tmp & BIT(4))) {
count++;
udelay(10);
u1b_tmp = rtl_read_byte(rtlpriv, REG_RX_RXBD_NUM_8822B + 1);
}
if (count >= 20)
pr_err("%s polling beacon fail\n", __func__);
return true;
}
bool rtl8822b_halmac_cb_write_data_h2c(struct rtl_priv *rtlpriv, u8 *buf,
u32 size)
{
struct sk_buff *skb = NULL;
/* without GFP_DMA, pci_map_single() may not work */
skb = __netdev_alloc_skb(NULL, size, GFP_ATOMIC | GFP_DMA);
memcpy((u8 *)skb_put(skb, size), buf, size);
return _rtl8822be_send_bcn_or_cmd_packet(rtlpriv->hw, skb, H2C_QUEUE);
}
/* Rsvd page HALMAC_RSVD_DRV_PGNUM_8822B occupies 16 page (2048 byte) */
#define BEACON_PG 0 /* ->1 */
#define PSPOLL_PG 2
#define NULL_PG 3
#define PROBERSP_PG 4 /* ->5 */
#define QOS_NULL_PG 6
#define BT_QOS_NULL_PG 7
#define TOTAL_RESERVED_PKT_LEN 1024
static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {/* page size = 128 */
/* page 0 beacon */
0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
/* page 1 beacon */
0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x10, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 2 ps-poll */
0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 3 null */
0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x72, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 4 probe_resp */
0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 5 probe_resp */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1A, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 6 qos null data */
0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1A, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 7 BT-qos null data */
0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
void rtl8822be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct sk_buff *skb = NULL;
u32 totalpacketlen;
bool rtstatus;
u8 u1_rsvd_page_loc[7] = {0};
bool b_dlok = false;
u8 *beacon;
u8 *p_pspoll;
u8 *nullfunc;
u8 *p_probersp;
u8 *qosnull;
u8 *btqosnull;
memset(u1_rsvd_page_loc, 0, sizeof(u1_rsvd_page_loc));
/*---------------------------------------------------------
* (1) beacon
*---------------------------------------------------------
*/
beacon = &reserved_page_packet[BEACON_PG * 128];
SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
/*-------------------------------------------------------
* (2) ps-poll
*--------------------------------------------------------
*/
p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1_rsvd_page_loc, PSPOLL_PG);
/*--------------------------------------------------------
* (3) null data
*---------------------------------------------------------
*/
nullfunc = &reserved_page_packet[NULL_PG * 128];
SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1_rsvd_page_loc, NULL_PG);
/*---------------------------------------------------------
* (4) probe response
*----------------------------------------------------------
*/
p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1_rsvd_page_loc, PROBERSP_PG);
/*---------------------------------------------------------
* (5) QoS null data
*----------------------------------------------------------
*/
qosnull = &reserved_page_packet[QOS_NULL_PG * 128];
SET_80211_HDR_ADDRESS1(qosnull, mac->bssid);
SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr);
SET_80211_HDR_ADDRESS3(qosnull, mac->bssid);
SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1_rsvd_page_loc, QOS_NULL_PG);
/*---------------------------------------------------------
* (6) BT QoS null data
*----------------------------------------------------------
*/
btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128];
SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1_rsvd_page_loc,
BT_QOS_NULL_PG);
totalpacketlen = TOTAL_RESERVED_PKT_LEN;
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
"rtl8822be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
&reserved_page_packet[0], totalpacketlen);
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
"rtl8822be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
u1_rsvd_page_loc, 3);
skb = dev_alloc_skb(totalpacketlen);
memcpy((u8 *)skb_put(skb, totalpacketlen), &reserved_page_packet,
totalpacketlen);
rtstatus = _rtl8822be_send_bcn_or_cmd_packet(hw, skb, BEACON_QUEUE);
if (rtstatus)
b_dlok = true;
if (b_dlok) {
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"Set RSVD page location to Fw.\n");
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C_RSVDPAGE:\n",
u1_rsvd_page_loc, 3);
rtl8822be_fill_h2c_cmd(hw, H2C_8822B_RSVDPAGE,
sizeof(u1_rsvd_page_loc),
u1_rsvd_page_loc);
} else
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
"Set RSVD page location to Fw FAIL!!!!!!.\n");
}
/* Should check FW support p2p or not. */
static void rtl8822be_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
u8 ctwindow)
{
u8 u1_ctwindow_period[1] = {ctwindow};
rtl8822be_fill_h2c_cmd(hw, H2C_8822B_P2P_PS_CTW_CMD, 1,
u1_ctwindow_period);
}
void rtl8822be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_p2p_ps_info *p2pinfo = &rtlps->p2p_ps_info;
struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
u8 i;
u16 ctwindow;
u32 start_time, tsf_low;
switch (p2p_ps_state) {
case P2P_PS_DISABLE:
RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
break;
case P2P_PS_ENABLE:
RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
/* update CTWindow value. */
if (p2pinfo->ctwindow > 0) {
p2p_ps_offload->ctwindow_en = 1;
ctwindow = p2pinfo->ctwindow;
rtl8822be_set_p2p_ctw_period_cmd(hw, ctwindow);
}
/* hw only support 2 set of NoA */
for (i = 0; i < p2pinfo->noa_num; i++) {
/* To control the register setting for which NOA*/
rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
if (i == 0)
p2p_ps_offload->noa0_en = 1;
else
p2p_ps_offload->noa1_en = 1;
/* config P2P NoA Descriptor Register */
rtl_write_dword(rtlpriv, 0x5E0,
p2pinfo->noa_duration[i]);
rtl_write_dword(rtlpriv, 0x5E4,
p2pinfo->noa_interval[i]);
/*Get Current TSF value */
tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR_8822B);
start_time = p2pinfo->noa_start_time[i];
if (p2pinfo->noa_count_type[i] != 1) {
while (start_time <= (tsf_low + (50 * 1024))) {
start_time += p2pinfo->noa_interval[i];
if (p2pinfo->noa_count_type[i] != 255)
p2pinfo->noa_count_type[i]--;
}
}
rtl_write_dword(rtlpriv, 0x5E8, start_time);
rtl_write_dword(rtlpriv, 0x5EC,
p2pinfo->noa_count_type[i]);
}
if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
/* rst p2p circuit */
rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST_8822B, BIT(4));
p2p_ps_offload->offload_en = 1;
if (rtlpriv->mac80211.p2p == P2P_ROLE_GO) {
p2p_ps_offload->role = 1;
p2p_ps_offload->allstasleep = 0;
} else {
p2p_ps_offload->role = 0;
}
p2p_ps_offload->discovery = 0;
}
break;
case P2P_PS_SCAN:
RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
p2p_ps_offload->discovery = 1;
break;
case P2P_PS_SCAN_DONE:
RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
p2p_ps_offload->discovery = 0;
p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
break;
default:
break;
}
rtl8822be_fill_h2c_cmd(hw, H2C_8822B_P2P_PS_OFFLOAD, 1,
(u8 *)p2p_ps_offload);
}
static
void rtl8822be_c2h_content_parsing_ext(struct ieee80211_hw *hw,
u8 c2h_sub_cmd_id,
u8 c2h_cmd_len,
u8 *c2h_content_buf)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_halmac_ops *halmac_ops;
switch (c2h_sub_cmd_id) {
case 0x0F:
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
"[C2H], C2H_8822BE_TX_REPORT!\n");
rtl_tx_report_handler(hw, c2h_content_buf, c2h_cmd_len);
break;
default:
/* indicate c2h pkt + rx desc to halmac */
halmac_ops = rtlpriv->halmac.ops;
halmac_ops->halmac_c2h_handle(rtlpriv,
c2h_content_buf - 24 - 2 - 2,
c2h_cmd_len + 24 + 2 + 2);
break;
}
}
void rtl8822be_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id,
u8 c2h_cmd_len, u8 *tmp_buf)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
if (c2h_cmd_id == 0xFF) {
rtl8822be_c2h_content_parsing_ext(hw, tmp_buf[0],
c2h_cmd_len - 2,
tmp_buf + 2);
return;
}
switch (c2h_cmd_id) {
case C2H_8822B_DBG:
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
"[C2H], C2H_8822BE_DBG!!\n");
break;
case C2H_8822B_TXBF:
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
"[C2H], C2H_8822B_TXBF!!\n");
break;
case C2H_8822B_BT_INFO:
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
"[C2H], C2H_8822BE_BT_INFO!!\n");
if (rtlpriv->cfg->ops->get_btc_status())
btc_ops->btc_btinfo_notify(rtlpriv, tmp_buf,
c2h_cmd_len);
break;
case C2H_8822B_BT_MP:
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
"[C2H], C2H_8822BE_BT_MP!!\n");
if (rtlpriv->cfg->ops->get_btc_status())
btc_ops->btc_btmpinfo_notify(rtlpriv, tmp_buf,
c2h_cmd_len);
break;
default:
if (!rtlpriv->phydm.ops->phydm_c2h_content_parsing(
rtlpriv, c2h_cmd_id, c2h_cmd_len, tmp_buf))
break;
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
"[C2H], Unknown packet!! CmdId(%#X)!\n", c2h_cmd_id);
break;
}
}
void rtl8822be_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 c2h_cmd_id = 0, c2h_cmd_seq = 0, c2h_cmd_len = 0;
u8 *tmp_buf = NULL;
c2h_cmd_id = buffer[0];
c2h_cmd_seq = buffer[1];
c2h_cmd_len = len - 2;
tmp_buf = buffer + 2;
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
"[C2H packet], c2hCmdId=0x%x, c2hCmdSeq=0x%x, c2hCmdLen=%d\n",
c2h_cmd_id, c2h_cmd_seq, c2h_cmd_len);
RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_TRACE,
"[C2H packet], Content Hex:\n", tmp_buf, c2h_cmd_len);
switch (c2h_cmd_id) {
case C2H_8822B_BT_INFO:
case C2H_8822B_BT_MP:
rtl_c2hcmd_enqueue(hw, c2h_cmd_id, c2h_cmd_len, tmp_buf);
break;
default:
rtl8822be_c2h_content_parsing(hw, c2h_cmd_id, c2h_cmd_len,
tmp_buf);
break;
}
}

View File

@ -0,0 +1,198 @@
/******************************************************************************
*
* Copyright(c) 2016 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL8822B__FW__H__
#define __RTL8822B__FW__H__
#define USE_OLD_WOWLAN_DEBUG_FW 0
#define H2C_8822B_RSVDPAGE_LOC_LEN 5
#define H2C_8822B_PWEMODE_LENGTH 7
#define H2C_8822B_JOINBSSRPT_LENGTH 1
#define H2C_8822B_AP_OFFLOAD_LENGTH 3
#define H2C_8822B_WOWLAN_LENGTH 3
#define H2C_8822B_KEEP_ALIVE_CTRL_LENGTH 3
#if (USE_OLD_WOWLAN_DEBUG_FW == 0)
#define H2C_8822B_REMOTE_WAKE_CTRL_LEN 1
#else
#define H2C_8822B_REMOTE_WAKE_CTRL_LEN 3
#endif
#define H2C_8822B_AOAC_GLOBAL_INFO_LEN 2
#define H2C_8822B_AOAC_RSVDPAGE_LOC_LEN 7
#define H2C_DEFAULT_PORT_ID_LEN 2
/* Fw PS state for RPWM.
*BIT[2:0] = HW state
*BIT[3] = Protocol PS state, 1: register active state, 0: register sleep state
*BIT[4] = sub-state
*/
#define FW_PS_RF_ON BIT(2)
#define FW_PS_REGISTER_ACTIVE BIT(3)
#define FW_PS_ACK BIT(6)
#define FW_PS_TOGGLE BIT(7)
/* 8822B RPWM value*/
/* BIT[0] = 1: 32k, 0: 40M*/
#define FW_PS_CLOCK_OFF BIT(0) /* 32k */
#define FW_PS_CLOCK_ON 0 /* 40M */
#define FW_PS_STATE_MASK (0x0F)
#define FW_PS_STATE_HW_MASK (0x07)
#define FW_PS_STATE_INT_MASK (0x3F)
#define FW_PS_STATE(x) (FW_PS_STATE_MASK & (x))
#define FW_PS_STATE_ALL_ON_8822B (FW_PS_CLOCK_ON)
#define FW_PS_STATE_RF_ON_8822B (FW_PS_CLOCK_ON)
#define FW_PS_STATE_RF_OFF_8822B (FW_PS_CLOCK_ON)
#define FW_PS_STATE_RF_OFF_LOW_PWR (FW_PS_CLOCK_OFF)
/* For 8822B H2C PwrMode Cmd ID 5.*/
#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))
#define FW_PWR_STATE_RF_OFF 0
#define FW_PS_IS_ACK(x) ((x) & FW_PS_ACK)
#define IS_IN_LOW_POWER_STATE_8822B(fw_ps_state) \
(FW_PS_STATE(fw_ps_state) == FW_PS_CLOCK_OFF)
#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))
#define FW_PWR_STATE_RF_OFF 0
enum rtl8822b_h2c_cmd {
H2C_8822B_RSVDPAGE = 0,
H2C_8822B_MSRRPT = 1,
H2C_8822B_SCAN = 2,
H2C_8822B_KEEP_ALIVE_CTRL = 3,
H2C_8822B_DISCONNECT_DECISION = 4,
#if (USE_OLD_WOWLAN_DEBUG_FW == 1)
H2C_8822B_WO_WLAN = 5,
#endif
H2C_8822B_INIT_OFFLOAD = 6,
#if (USE_OLD_WOWLAN_DEBUG_FW == 1)
H2C_8822B_REMOTE_WAKE_CTRL = 7,
#endif
H2C_8822B_AP_OFFLOAD = 8,
H2C_8822B_BCN_RSVDPAGE = 9,
H2C_8822B_PROBERSP_RSVDPAGE = 10,
H2C_8822B_SETPWRMODE = 0x20,
H2C_8822B_PS_TUNING_PARA = 0x21,
H2C_8822B_PS_TUNING_PARA2 = 0x22,
H2C_8822B_PS_LPS_PARA = 0x23,
H2C_8822B_P2P_PS_OFFLOAD = 024,
H2C_8822B_DEFAULT_PORT_ID = 0x2C,
#if (USE_OLD_WOWLAN_DEBUG_FW == 0)
H2C_8822B_WO_WLAN = 0x80,
H2C_8822B_REMOTE_WAKE_CTRL = 0x81,
H2C_8822B_AOAC_GLOBAL_INFO = 0x82,
H2C_8822B_AOAC_RSVDPAGE = 0x83,
#endif
H2C_8822B_MACID_CFG = 0x40,
H2C_8822B_RSSI_REPORT = 0x42,
H2C_8822B_MACID_CFG_3SS = 0x46,
/*Not defined CTW CMD for P2P yet*/
H2C_8822B_P2P_PS_CTW_CMD = 0x99,
MAX_8822B_H2CCMD
};
enum rtl8822b_c2h_evt {
C2H_8822B_DBG = 0x00,
C2H_8822B_LB = 0x01,
C2H_8822B_TXBF = 0x02,
C2H_8822B_TX_REPORT = 0x03,
C2H_8822B_BT_INFO = 0x09,
C2H_8822B_BT_MP = 0x0B,
C2H_8822B_RA_RPT = 0x0C,
MAX_8822B_C2HEVENT
};
/* H2C: 0x20 */
#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 7, __val)
#define SET_H2CCMD_PWRMODE_PARM_CLK_REQ(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE(__ph2ccmd, 7, 1, __val)
#define SET_H2CCMD_PWRMODE_PARM_RLBM(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 1, 0, 4, __val)
#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 1, 4, 4, __val)
#define SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 2, 0, 8, __val)
#define SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 3, 0, 1, __val)
#define SET_H2CCMD_PWRMODE_PARM_BCN_EARLY_RPT(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 3, 2, 1, __val)
#define SET_H2CCMD_PWRMODE_PARM_PORT_ID(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 3, 5, 3, __val)
#define SET_H2CCMD_PWRMODE_PARM_PWR_STATE(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 4, 0, 8, __val)
#define SET_H2CCMD_PWRMODE_PARM_BYTE5(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 5, 0, 8, __val)
/* H2C: 0x00 */
#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 1, 0, 8, __val)
#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 2, 0, 8, __val)
#define SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 3, 0, 8, __val)
#define SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 4, 0, 8, __val)
/* H2C: 0x01 */
#define SET_H2CCMD_MSRRPT_PARM_OPMODE(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 1, __val)
#define SET_H2CCMD_MSRRPT_PARM_MACID_IND(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE(__ph2ccmd, 1, 1, __val)
#define SET_H2CCMD_MSRRPT_PARM_MACID(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE(__ph2ccmd + 1, 0, 8, __val)
#define SET_H2CCMD_MSRRPT_PARM_MACID_END(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE(__ph2ccmd + 2, 0, 8, __val)
/* H2C: 0x2C */
#define SET_H2CCMD_DFTPID_PORT_ID(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE(((u8 *)(__ph2ccmd)), 0, 8, (__val))
#define SET_H2CCMD_DFTPID_MAC_ID(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE(((u8 *)(__ph2ccmd)) + 1, 0, 8, (__val))
void rtl8822be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, u32 cmd_len,
u8 *cmdbuffer);
void rtl8822be_set_default_port_id_cmd(struct ieee80211_hw *hw);
void rtl8822be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
void rtl8822be_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus);
void rtl8822be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
void rtl8822be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state);
void rtl8822be_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len);
void rtl8822be_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id,
u8 c2h_cmd_len, u8 *tmp_buf);
bool rtl8822b_halmac_cb_write_data_rsvd_page(struct rtl_priv *rtlpriv, u8 *buf,
u32 size);
bool rtl8822b_halmac_cb_write_data_h2c(struct rtl_priv *rtlpriv, u8 *buf,
u32 size);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,66 @@
/******************************************************************************
*
* Copyright(c) 2016 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL8822B_HW_H__
#define __RTL8822B_HW_H__
extern u8 rtl_channel5g[CHANNEL_MAX_NUMBER_5G];
extern u8 rtl_channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M];
void rtl8822be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
void rtl8822be_read_eeprom_info(struct ieee80211_hw *hw,
struct rtl_phydm_params *params);
void rtl8822be_read_eeprom_info_dummy(struct ieee80211_hw *hw);
void rtl8822be_interrupt_recognized(struct ieee80211_hw *hw, u32 *p_inta,
u32 *p_intb, u32 *p_intc, u32 *p_intd);
int rtl8822be_hw_init(struct ieee80211_hw *hw);
void rtl8822be_card_disable(struct ieee80211_hw *hw);
void rtl8822be_enable_interrupt(struct ieee80211_hw *hw);
void rtl8822be_disable_interrupt(struct ieee80211_hw *hw);
int rtl8822be_set_network_type(struct ieee80211_hw *hw,
enum nl80211_iftype type);
void rtl8822be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
void rtl8822be_set_qos(struct ieee80211_hw *hw, int aci);
void rtl8822be_set_beacon_related_registers(struct ieee80211_hw *hw);
void rtl8822be_set_beacon_interval(struct ieee80211_hw *hw);
void rtl8822be_update_interrupt_mask(struct ieee80211_hw *hw, u32 add_msr,
u32 rm_msr);
void rtl8822be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
void rtl8822be_update_hal_rate_tbl(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, u8 rssi_level,
bool update_bw);
void rtl8822be_update_channel_access_setting(struct ieee80211_hw *hw);
bool rtl8822be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
void rtl8822be_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr,
bool is_group, u8 enc_algo, bool is_wepkey,
bool clear_all);
void rtl8822be_enable_hw_security_config(struct ieee80211_hw *hw);
void rtl8822be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
bool autoload_fail, u8 *hwinfo);
void rtl8822be_bt_reg_init(struct ieee80211_hw *hw);
void rtl8822be_suspend(struct ieee80211_hw *hw);
void rtl8822be_resume(struct ieee80211_hw *hw);
void rtl8822be_fw_clk_off_timer_callback(unsigned long data);
#endif

View File

@ -0,0 +1,127 @@
/******************************************************************************
*
* Copyright(c) 2016 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "../pci.h"
#include "reg.h"
#include "led.h"
static void _rtl8822be_init_led(struct ieee80211_hw *hw, struct rtl_led *pled,
enum rtl_led_pin ledpin)
{
pled->hw = hw;
pled->ledpin = ledpin;
pled->ledon = false;
}
void rtl8822be_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
REG_LEDCFG2_8822B, pled->ledpin);
switch (pled->ledpin) {
case LED_PIN_GPIO0:
break;
case LED_PIN_LED0:
break;
case LED_PIN_LED1:
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
"switch case not process\n");
break;
}
pled->ledon = true;
}
void rtl8822be_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
REG_LEDCFG2_8822B, pled->ledpin);
switch (pled->ledpin) {
case LED_PIN_GPIO0:
break;
case LED_PIN_LED0:
break;
case LED_PIN_LED1:
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
"switch case not process\n");
break;
}
pled->ledon = false;
}
void rtl8822be_init_sw_leds(struct ieee80211_hw *hw)
{
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
_rtl8822be_init_led(hw, &pcipriv->ledctl.sw_led0, LED_PIN_LED0);
_rtl8822be_init_led(hw, &pcipriv->ledctl.sw_led1, LED_PIN_LED1);
}
static void _rtl8822be_sw_led_control(struct ieee80211_hw *hw,
enum led_ctl_mode ledaction)
{
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
struct rtl_led *led0 = &pcipriv->ledctl.sw_led0;
switch (ledaction) {
case LED_CTL_POWER_ON:
case LED_CTL_LINK:
case LED_CTL_NO_LINK:
rtl8822be_sw_led_on(hw, led0);
break;
case LED_CTL_POWER_OFF:
rtl8822be_sw_led_off(hw, led0);
break;
default:
break;
}
}
void rtl8822be_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
(ledaction == LED_CTL_TX || ledaction == LED_CTL_RX ||
ledaction == LED_CTL_SITE_SURVEY || ledaction == LED_CTL_LINK ||
ledaction == LED_CTL_NO_LINK ||
ledaction == LED_CTL_START_TO_LINK ||
ledaction == LED_CTL_POWER_ON)) {
return;
}
RT_TRACE(rtlpriv, COMP_LED, DBG_TRACE, "ledaction %d,\n", ledaction);
_rtl8822be_sw_led_control(hw, ledaction);
}

View File

@ -0,0 +1,34 @@
/******************************************************************************
*
* Copyright(c) 2016 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL8822B_LED_H__
#define __RTL8822B_LED_H__
void rtl8822be_init_sw_leds(struct ieee80211_hw *hw);
void rtl8822be_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
void rtl8822be_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
void rtl8822be_led_control(struct ieee80211_hw *hw,
enum led_ctl_mode ledaction);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,145 @@
/******************************************************************************
*
* Copyright(c) 2016 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL8822BE_PHY_H__
#define __RTL8822BE_PHY_H__
/* It must always set to 4, otherwise read
* efuse table sequence will be wrong.
*/
#define MAX_TX_COUNT 4
#define TX_1S 0
#define TX_2S 1
#define TX_3S 2
#define TX_4S 3
#define MAX_POWER_INDEX 0x3F
#define MAX_PRECMD_CNT 16
#define MAX_RFDEPENDCMD_CNT 16
#define MAX_POSTCMD_CNT 16
#define MAX_DOZE_WAITING_TIMES_9x 64
#define RT_CANNOT_IO(hw) false
#define HIGHPOWER_RADIOA_ARRAYLEN 22
#define IQK_ADDA_REG_NUM 16
#define IQK_BB_REG_NUM 9
#define MAX_TOLERANCE 5
#define IQK_DELAY_TIME 10
#define index_mapping_NUM 15
#define APK_BB_REG_NUM 5
#define APK_AFE_REG_NUM 16
#define APK_CURVE_REG_NUM 4
#define PATH_NUM 2
#define LOOP_LIMIT 5
#define MAX_STALL_TIME 50
#define ANTENNA_DIVERSITY_VALUE 0x80
#define MAX_TXPWR_IDX_NMODE_92S 63
#define RESET_CNT_LIMIT 3
#define IQK_ADDA_REG_NUM 16
#define IQK_MAC_REG_NUM 4
#define RF6052_MAX_PATH 2
#define CT_OFFSET_MAC_ADDR 0X16
#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A
#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60
#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66
#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69
#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C
#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F
#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72
#define CT_OFFSET_CHANNEL_PLAH 0x75
#define CT_OFFSET_THERMAL_METER 0x78
#define CT_OFFSET_RF_OPTION 0x79
#define CT_OFFSET_VERSION 0x7E
#define CT_OFFSET_CUSTOMER_ID 0x7F
#define RTL8822BE_MAX_PATH_NUM 2
#define TARGET_CHNL_NUM_2G_5G_8822B 59
u32 rtl8822be_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
u32 bitmask);
void rtl8822be_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
u32 data);
u32 rtl8822be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
u32 regaddr, u32 bitmask);
void rtl8822be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
u32 regaddr, u32 bitmask, u32 data);
bool rtl8822be_phy_bb_config(struct ieee80211_hw *hw);
bool rtl8822be_phy_rf_config(struct ieee80211_hw *hw);
bool rtl8822be_halmac_cb_init_mac_register(struct rtl_priv *rtlpriv);
bool rtl8822be_halmac_cb_init_bb_rf_register(struct rtl_priv *rtlpriv);
void rtl8822be_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel);
void rtl8822be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
void rtl8822be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
void rtl8822be_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
void rtl8822be_phy_set_bw_mode(struct ieee80211_hw *hw,
enum nl80211_channel_type ch_type);
u8 rtl8822be_phy_sw_chnl(struct ieee80211_hw *hw);
void rtl8822be_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
void rtl8822be_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
void rtl8822be_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);
void rtl8822be_phy_lc_calibrate(struct ieee80211_hw *hw);
void rtl8822be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
bool rtl8822be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
enum radio_path rfpath);
bool rtl8822be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
enum radio_path rfpath);
bool rtl8822be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
bool rtl8822be_phy_set_rf_power_state(struct ieee80211_hw *hw,
enum rf_pwrstate rfpwr_state);
void rtl8822be_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
u8 channel, u8 path);
void rtl8822be_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
u8 thermal_value, u8 threshold);
void rtl8822be_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
u8 thermal_value, u8 threshold);
void rtl8822be_reset_iqk_result(struct ieee80211_hw *hw);
u8 rtl8822be_get_txpower_index(struct ieee80211_hw *hw, u8 path, u8 rate,
u8 bandwidth, u8 channel);
void rtl8822be_phy_set_tx_power_index_by_rs(struct ieee80211_hw *hw, u8 channel,
u8 path, enum rate_section rs);
void rtl8822be_store_tx_power_by_rate(struct ieee80211_hw *hw, u32 band,
u32 rfpath, u32 txnum, u32 regaddr,
u32 bitmask, u32 data);
void rtl8822be_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation,
u8 *pband, u8 *pbandwidth,
u8 *prate_section, u8 *prf_path,
u8 *pchannel, u8 *ppower_limit);
bool rtl8822be_load_txpower_by_rate(struct ieee80211_hw *hw);
bool rtl8822be_load_txpower_limit(struct ieee80211_hw *hw);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,481 @@
/******************************************************************************
*
* Copyright(c) 2016 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "../core.h"
#include "../pci.h"
#include "../base.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "hw.h"
#include "sw.h"
#include "fw.h"
#include "trx.h"
#include "led.h"
#include "../btcoexist/rtl_btc.h"
#include "../halmac/rtl_halmac.h"
#include "../phydm/rtl_phydm.h"
#include <linux/vmalloc.h>
#include <linux/module.h>
static void rtl8822be_init_aspm_vars(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
/*close ASPM for AMD defaultly */
rtlpci->const_amdpci_aspm = 0;
/*
* ASPM PS mode.
* 0 - Disable ASPM,
* 1 - Enable ASPM without Clock Req,
* 2 - Enable ASPM with Clock Req,
* 3 - Alwyas Enable ASPM with Clock Req,
* 4 - Always Enable ASPM without Clock Req.
* set default to RTL8822BE:3 RTL8822B:2
*
*/
rtlpci->const_pci_aspm = 3;
/*Setting for PCI-E device */
rtlpci->const_devicepci_aspm_setting = 0x03;
/*Setting for PCI-E bridge */
rtlpci->const_hostpci_aspm_setting = 0x02;
/*
* In Hw/Sw Radio Off situation.
* 0 - Default,
* 1 - From ASPM setting without low Mac Pwr,
* 2 - From ASPM setting with low Mac Pwr,
* 3 - Bus D3
* set default to RTL8822BE:0 RTL8192SE:2
*/
rtlpci->const_hwsw_rfoff_d3 = 0;
/*
* This setting works for those device with
* backdoor ASPM setting such as EPHY setting.
* 0 - Not support ASPM,
* 1 - Support ASPM,
* 2 - According to chipset.
*/
rtlpci->const_support_pciaspm = rtlpriv->cfg->mod_params->aspm_support;
}
int rtl8822be_init_sw_vars(struct ieee80211_hw *hw)
{
int err = 0;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
const char *fw_name;
struct rtl_phydm_params params;
rtl8822be_bt_reg_init(hw);
rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer();
rtlpriv->halmac.ops = rtl_halmac_get_ops_pointer();
rtlpriv->halmac.ops->halmac_init_adapter(rtlpriv);
/* should after halmac_init_adapter() */
rtl8822be_read_eeprom_info(hw, &params);
/* need eeprom info */
rtlpriv->phydm.ops = rtl_phydm_get_ops_pointer();
rtlpriv->phydm.ops->phydm_init_priv(rtlpriv, &params);
rtlpriv->dm.dm_initialgain_enable = 1;
rtlpriv->dm.dm_flag = 0;
rtlpriv->dm.disable_framebursting = 0;
/*rtlpriv->dm.thermalvalue = 0;*/
rtlpriv->dm.useramask = 1; /* turn on RA */
rtlpci->transmit_config = CFENDFORM | BIT(15);
rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G;
/*following 2 is for register 5G band, refer to _rtl_init_mac80211()*/
rtlpriv->rtlhal.bandset = BAND_ON_BOTH;
rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY;
rtlpci->receive_config = (RCR_APPFCS |
RCR_APP_MIC |
RCR_APP_ICV |
RCR_APP_PHYST_RXFF |
RCR_VHT_DACK |
RCR_HTC_LOC_CTRL |
/*RCR_AMF |*/
RCR_CBSSID_BCN |
RCR_CBSSID_DATA |
/*RCR_ACF |*/
/*RCR_ADF |*/
/*RCR_AICV |*/
/*RCR_ACRC32 |*/
RCR_AB |
RCR_AM |
RCR_APM |
0);
rtlpci->irq_mask[0] = (u32)(IMR_PSTIMEOUT |
/*IMR_TBDER |*/
/*IMR_TBDOK |*/
/*IMR_BCNDMAINT0 |*/
IMR_GTINT3 |
IMR_HSISR_IND_ON_INT |
IMR_C2HCMD |
IMR_HIGHDOK |
IMR_MGNTDOK |
IMR_BKDOK |
IMR_BEDOK |
IMR_VIDOK |
IMR_VODOK |
IMR_RDU |
IMR_ROK |
0);
rtlpci->irq_mask[1] = (u32)(IMR_RXFOVW | IMR_TXFOVW | 0);
rtlpci->irq_mask[3] = (u32)(BIT_SETH2CDOK_MASK | 0);
/* for LPS & IPS */
rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
if (rtlpriv->cfg->mod_params->disable_watchdog)
pr_info("watchdog disabled\n");
rtlpriv->psc.reg_fwctrl_lps = 2;
rtlpriv->psc.reg_max_lps_awakeintvl = 2;
/* for ASPM, you can close aspm through
* set const_support_pciaspm = 0
*/
rtl8822be_init_aspm_vars(hw);
if (rtlpriv->psc.reg_fwctrl_lps == 1)
rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE;
else if (rtlpriv->psc.reg_fwctrl_lps == 2)
rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE;
else if (rtlpriv->psc.reg_fwctrl_lps == 3)
rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
/* for early mode */
rtlpriv->rtlhal.earlymode_enable = false;
/*low power */
rtlpriv->psc.low_power_enable = false;
/* for firmware buf */
rtlpriv->rtlhal.pfirmware = vzalloc(0x40000);
if (!rtlpriv->rtlhal.pfirmware) {
/*pr_err("Can't alloc buffer for fw\n");*/
return 1;
}
/* request fw */
fw_name = "rtlwifi/rtl8822befw.bin";
rtlpriv->max_fw_size = 0x40000;
pr_info("Using firmware %s\n", fw_name);
err = request_firmware_nowait(THIS_MODULE, 1, fw_name, rtlpriv->io.dev,
GFP_KERNEL, hw, rtl_fw_cb);
if (err) {
pr_err("Failed to request firmware!\n");
return 1;
}
/* init table of tx power by rate & limit */
rtl8822be_load_txpower_by_rate(hw);
rtl8822be_load_txpower_limit(hw);
return 0;
}
void rtl8822be_deinit_sw_vars(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtlpriv->halmac.ops->halmac_deinit_adapter(rtlpriv);
rtlpriv->phydm.ops->phydm_deinit_priv(rtlpriv);
if (rtlpriv->rtlhal.pfirmware) {
vfree(rtlpriv->rtlhal.pfirmware);
rtlpriv->rtlhal.pfirmware = NULL;
}
}
/* get bt coexist status */
bool rtl8822be_get_btc_status(void)
{
return true;
}
static void rtl8822be_phydm_watchdog(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 tmp;
tmp = rtl_read_dword(rtlpriv, 0xc00);
if (tmp & 0xFF000000) { /* Recover 0xC00: 0xF800000C --> 0x0000000C */
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
"found regaddr_c00=%08X\n", tmp);
tmp &= ~0xFF000000;
rtl_write_dword(rtlpriv, 0xc00, tmp);
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
"apply regaddr_c00=%08X\n", tmp);
}
rtlpriv->phydm.ops->phydm_watchdog(rtlpriv);
}
static struct rtl_hal_ops rtl8822be_hal_ops = {
.init_sw_vars = rtl8822be_init_sw_vars,
.deinit_sw_vars = rtl8822be_deinit_sw_vars,
.read_eeprom_info = rtl8822be_read_eeprom_info_dummy,
.interrupt_recognized = rtl8822be_interrupt_recognized,
.hw_init = rtl8822be_hw_init,
.hw_disable = rtl8822be_card_disable,
.hw_suspend = rtl8822be_suspend,
.hw_resume = rtl8822be_resume,
.enable_interrupt = rtl8822be_enable_interrupt,
.disable_interrupt = rtl8822be_disable_interrupt,
.set_network_type = rtl8822be_set_network_type,
.set_chk_bssid = rtl8822be_set_check_bssid,
.set_qos = rtl8822be_set_qos,
.set_bcn_reg = rtl8822be_set_beacon_related_registers,
.set_bcn_intv = rtl8822be_set_beacon_interval,
.update_interrupt_mask = rtl8822be_update_interrupt_mask,
.get_hw_reg = rtl8822be_get_hw_reg,
.set_hw_reg = rtl8822be_set_hw_reg,
.update_rate_tbl = rtl8822be_update_hal_rate_tbl,
.pre_fill_tx_bd_desc = rtl8822be_pre_fill_tx_bd_desc,
.rx_desc_buff_remained_cnt = rtl8822be_rx_desc_buff_remained_cnt,
.rx_check_dma_ok = rtl8822be_rx_check_dma_ok,
.fill_tx_desc = rtl8822be_tx_fill_desc,
.fill_tx_special_desc = rtl8822be_tx_fill_special_desc,
.query_rx_desc = rtl8822be_rx_query_desc,
.radio_onoff_checking = rtl8822be_gpio_radio_on_off_checking,
.switch_channel = rtl8822be_phy_sw_chnl,
.set_channel_access = rtl8822be_update_channel_access_setting,
.set_bw_mode = rtl8822be_phy_set_bw_mode,
.dm_watchdog = rtl8822be_phydm_watchdog,
.scan_operation_backup = rtl8822be_phy_scan_operation_backup,
.set_rf_power_state = rtl8822be_phy_set_rf_power_state,
.led_control = rtl8822be_led_control,
.set_desc = rtl8822be_set_desc,
.get_desc = rtl8822be_get_desc,
.is_tx_desc_closed = rtl8822be_is_tx_desc_closed,
.get_available_desc = rtl8822be_get_available_desc,
.tx_polling = rtl8822be_tx_polling,
.enable_hw_sec = rtl8822be_enable_hw_security_config,
.set_key = rtl8822be_set_key,
.init_sw_leds = rtl8822be_init_sw_leds,
.get_bbreg = rtl8822be_phy_query_bb_reg,
.set_bbreg = rtl8822be_phy_set_bb_reg,
.get_rfreg = rtl8822be_phy_query_rf_reg,
.set_rfreg = rtl8822be_phy_set_rf_reg,
.fill_h2c_cmd = rtl8822be_fill_h2c_cmd,
.set_default_port_id_cmd = rtl8822be_set_default_port_id_cmd,
.get_btc_status = rtl8822be_get_btc_status,
.rx_command_packet = rtl8822be_rx_command_packet,
.c2h_content_parsing = rtl8822be_c2h_content_parsing,
/* ops for halmac cb */
.halmac_cb_init_mac_register = rtl8822be_halmac_cb_init_mac_register,
.halmac_cb_init_bb_rf_register =
rtl8822be_halmac_cb_init_bb_rf_register,
.halmac_cb_write_data_rsvd_page =
rtl8822b_halmac_cb_write_data_rsvd_page,
.halmac_cb_write_data_h2c = rtl8822b_halmac_cb_write_data_h2c,
/* ops for phydm cb */
.get_txpower_index = rtl8822be_get_txpower_index,
.set_tx_power_index_by_rs = rtl8822be_phy_set_tx_power_index_by_rs,
.store_tx_power_by_rate = rtl8822be_store_tx_power_by_rate,
.phy_set_txpower_limit = rtl8822be_phy_set_txpower_limit,
};
static struct rtl_mod_params rtl8822be_mod_params = {
.sw_crypto = false,
.inactiveps = true,
.swctrl_lps = false,
.fwctrl_lps = true,
.msi_support = true,
.dma64 = false,
.aspm_support = 1,
.disable_watchdog = false,
.debug_level = 0,
.debug_mask = 0,
};
static struct rtl_hal_cfg rtl8822be_hal_cfg = {
.bar_id = 2,
.write_readback = false,
.name = "rtl8822be_pci",
.ops = &rtl8822be_hal_ops,
.mod_params = &rtl8822be_mod_params,
.spec_ver = RTL_SPEC_NEW_RATEID | RTL_SPEC_SUPPORT_VHT |
RTL_SPEC_NEW_FW_C2H,
.maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL_8822B,
.maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN_8822B,
.maps[SYS_CLK] = REG_SYS_CLK_CTRL_8822B,
.maps[MAC_RCR_AM] = AM,
.maps[MAC_RCR_AB] = AB,
.maps[MAC_RCR_ACRC32] = ACRC32,
.maps[MAC_RCR_ACF] = ACF,
.maps[MAC_RCR_AAP] = AAP,
.maps[MAC_HIMR] = REG_HIMR0_8822B,
.maps[MAC_HIMRE] = REG_HIMR1_8822B,
.maps[EFUSE_ACCESS] = REG_EFUSE_ACCESS_8822B,
.maps[EFUSE_TEST] = REG_LDO_EFUSE_CTRL_8822B,
.maps[EFUSE_CTRL] = REG_EFUSE_CTRL_8822B,
.maps[EFUSE_CLK] = 0,
.maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL_8822B,
.maps[EFUSE_PWC_EV12V] = PWC_EV12V,
.maps[EFUSE_FEN_ELDR] = FEN_ELDR,
.maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,
.maps[EFUSE_ANA8M] = ANA8M,
.maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
.maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
.maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
.maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES,
.maps[RWCAM] = REG_CAMCMD_8822B,
.maps[WCAMI] = REG_CAMWRITE_8822B,
.maps[RCAMO] = REG_CAMREAD_8822B,
.maps[CAMDBG] = REG_CAMDBG_8822B,
.maps[SECR] = REG_SECCFG_8822B,
.maps[SEC_CAM_NONE] = CAM_NONE,
.maps[SEC_CAM_WEP40] = CAM_WEP40,
.maps[SEC_CAM_TKIP] = CAM_TKIP,
.maps[SEC_CAM_AES] = CAM_AES,
.maps[SEC_CAM_WEP104] = CAM_WEP104,
.maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
.maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
.maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
.maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
.maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
.maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
/* .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, */ /*need check*/
.maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
.maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
.maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
.maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
.maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
.maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
.maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
/* .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,*/
/* .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,*/
.maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
.maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
.maps[RTL_IMR_BCNINT] = IMR_BCNDMAINT0,
.maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
.maps[RTL_IMR_RDU] = IMR_RDU,
.maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
.maps[RTL_IMR_H2CDOK] = IMR_H2CDOK,
.maps[RTL_IMR_BDOK] = IMR_BCNDOK0,
.maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK,
.maps[RTL_IMR_TBDER] = IMR_TBDER,
.maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK,
.maps[RTL_IMR_TBDOK] = IMR_TBDOK,
.maps[RTL_IMR_BKDOK] = IMR_BKDOK,
.maps[RTL_IMR_BEDOK] = IMR_BEDOK,
.maps[RTL_IMR_VIDOK] = IMR_VIDOK,
.maps[RTL_IMR_VODOK] = IMR_VODOK,
.maps[RTL_IMR_ROK] = IMR_ROK,
.maps[RTL_IBSS_INT_MASKS] = (IMR_BCNDMAINT0 | IMR_TBDOK | IMR_TBDER),
.maps[RTL_RC_CCK_RATE1M] = DESC_RATE1M,
.maps[RTL_RC_CCK_RATE2M] = DESC_RATE2M,
.maps[RTL_RC_CCK_RATE5_5M] = DESC_RATE5_5M,
.maps[RTL_RC_CCK_RATE11M] = DESC_RATE11M,
.maps[RTL_RC_OFDM_RATE6M] = DESC_RATE6M,
.maps[RTL_RC_OFDM_RATE9M] = DESC_RATE9M,
.maps[RTL_RC_OFDM_RATE12M] = DESC_RATE12M,
.maps[RTL_RC_OFDM_RATE18M] = DESC_RATE18M,
.maps[RTL_RC_OFDM_RATE24M] = DESC_RATE24M,
.maps[RTL_RC_OFDM_RATE36M] = DESC_RATE36M,
.maps[RTL_RC_OFDM_RATE48M] = DESC_RATE48M,
.maps[RTL_RC_OFDM_RATE54M] = DESC_RATE54M,
.maps[RTL_RC_HT_RATEMCS7] = DESC_RATEMCS7,
.maps[RTL_RC_HT_RATEMCS15] = DESC_RATEMCS15,
/*VHT hightest rate*/
.maps[RTL_RC_VHT_RATE_1SS_MCS7] = DESC_RATEVHT1SS_MCS7,
.maps[RTL_RC_VHT_RATE_1SS_MCS8] = DESC_RATEVHT1SS_MCS8,
.maps[RTL_RC_VHT_RATE_1SS_MCS9] = DESC_RATEVHT1SS_MCS9,
.maps[RTL_RC_VHT_RATE_2SS_MCS7] = DESC_RATEVHT2SS_MCS7,
.maps[RTL_RC_VHT_RATE_2SS_MCS8] = DESC_RATEVHT2SS_MCS8,
.maps[RTL_RC_VHT_RATE_2SS_MCS9] = DESC_RATEVHT2SS_MCS9,
};
static struct pci_device_id rtl8822be_pci_ids[] = {
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xB822, rtl8822be_hal_cfg)},
{},
};
MODULE_DEVICE_TABLE(pci, rtl8822be_pci_ids);
MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek 8822BE 802.11n PCI wireless");
MODULE_FIRMWARE("rtlwifi/rtl8822befw.bin");
module_param_named(swenc, rtl8822be_mod_params.sw_crypto, bool, 0444);
module_param_named(debug_level, rtl8822be_mod_params.debug_level, int, 0644);
module_param_named(debug_mask, rtl8822be_mod_params.debug_mask, ullong, 0644);
module_param_named(ips, rtl8822be_mod_params.inactiveps, bool, 0444);
module_param_named(swlps, rtl8822be_mod_params.swctrl_lps, bool, 0444);
module_param_named(fwlps, rtl8822be_mod_params.fwctrl_lps, bool, 0444);
module_param_named(msi, rtl8822be_mod_params.msi_support, bool, 0444);
module_param_named(dma64, rtl8822be_mod_params.dma64, bool, 0444);
module_param_named(aspm, rtl8822be_mod_params.aspm_support, int, 0444);
module_param_named(disable_watchdog, rtl8822be_mod_params.disable_watchdog,
bool, 0444);
MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n");
MODULE_PARM_DESC(dma64, "Set to 1 to use DMA 64 (default 0)\n");
MODULE_PARM_DESC(aspm, "Set to 1 to enable ASPM (default 1)\n");
MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
MODULE_PARM_DESC(disable_watchdog,
"Set to 1 to disable the watchdog (default 0)\n");
static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
static struct pci_driver rtl8822be_driver = {
.name = KBUILD_MODNAME,
.id_table = rtl8822be_pci_ids,
.probe = rtl_pci_probe,
.remove = rtl_pci_disconnect,
.driver.pm = &rtlwifi_pm_ops,
};
module_pci_driver(rtl8822be_driver);

View File

@ -0,0 +1,32 @@
/******************************************************************************
*
* Copyright(c) 2016 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL8822B_SW_H__
#define __RTL8822B_SW_H__
int rtl8822be_init_sw_vars(struct ieee80211_hw *hw);
void rtl8822be_deinit_sw_vars(struct ieee80211_hw *hw);
bool rtl8822be_get_btc_status(void);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,165 @@
/******************************************************************************
*
* Copyright(c) 2016 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL8822B_TRX_H__
#define __RTL8822B_TRX_H__
#include "../halmac/halmac_tx_desc_nic.h"
#include "../halmac/halmac_rx_desc_nic.h"
#define TX_DESC_SIZE 64
#define RX_DRV_INFO_SIZE_UNIT 8
#define TX_DESC_NEXT_DESC_OFFSET 48
#define USB_HWDESC_HEADER_LEN 48
#define RX_DESC_SIZE 24
#define MAX_RECEIVE_BUFFER_SIZE 8192
#define SET_EARLYMODE_PKTNUM(__paddr, __val) \
SET_BITS_TO_LE_4BYTE(__paddr, 0, 4, __val)
#define SET_EARLYMODE_LEN0(__paddr, __val) \
SET_BITS_TO_LE_4BYTE(__paddr, 4, 15, __val)
#define SET_EARLYMODE_LEN1(__paddr, __val) \
SET_BITS_TO_LE_4BYTE(__paddr, 16, 2, __val)
#define SET_EARLYMODE_LEN1_1(__paddr, __val) \
SET_BITS_TO_LE_4BYTE(__paddr, 19, 13, __val)
#define SET_EARLYMODE_LEN1_2(__paddr, __val) \
SET_BITS_TO_LE_4BYTE(__paddr + 4, 0, 2, __val)
#define SET_EARLYMODE_LEN2(__paddr, __val) \
SET_BITS_TO_LE_4BYTE(__paddr + 4, 2, 15, __val)
#define SET_EARLYMODE_LEN2_1(__paddr, __val) \
SET_BITS_TO_LE_4BYTE(__paddr, 2, 4, __val)
#define SET_EARLYMODE_LEN2_2(__paddr, __val) \
SET_BITS_TO_LE_4BYTE(__paddr + 4, 0, 8, __val)
#define SET_EARLYMODE_LEN3(__paddr, __val) \
SET_BITS_TO_LE_4BYTE(__paddr + 4, 17, 15, __val)
#define SET_EARLYMODE_LEN4(__paddr, __val) \
SET_BITS_TO_LE_4BYTE(__paddr + 4, 20, 12, __val)
/* TX/RX buffer descriptor */
/* for Txfilldescroptor8822be, fill the desc content. */
#define SET_TXBUFFER_DESC_LEN_WITH_OFFSET(__pdesc, __offset, __val) \
SET_BITS_TO_LE_4BYTE((__pdesc) + ((__offset) * 16), 0, 16, __val)
#define SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(__pdesc, __offset, __val) \
SET_BITS_TO_LE_4BYTE((__pdesc) + ((__offset) * 16), 31, 1, __val)
#define SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(__pdesc, __offset, __val) \
SET_BITS_TO_LE_4BYTE((__pdesc) + ((__offset) * 16) + 4, 0, 32, __val)
#define SET_TXBUFFER_DESC_ADD_HIGH_WITH_OFFSET(pbd, off, val, dma64) \
(dma64 ? SET_BITS_TO_LE_4BYTE((pbd) + ((off) * 16) + 8, 0, 32, val) : 0)
#define GET_TXBUFFER_DESC_ADDR_LOW(__pdesc, __offset) \
LE_BITS_TO_4BYTE((__pdesc) + ((__offset) * 16) + 4, 0, 32)
#define GET_TXBUFFER_DESC_ADDR_HIGH(pbd, off, dma64) \
(dma64 ? LE_BITS_TO_4BYTE((pbd) + ((off) * 16) + 8, 0, 32) : 0)
/* Dword 0 */
#define SET_TX_BUFF_DESC_LEN_0(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val)
#define SET_TX_BUFF_DESC_PSB(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 16, 15, __val)
#define SET_TX_BUFF_DESC_OWN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
/* Dword 1 */
#define SET_TX_BUFF_DESC_ADDR_LOW_0(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE((__pdesc) + 4, 0, 32, __val)
/* Dword 2 */
#define SET_TX_BUFF_DESC_ADDR_HIGH_0(bdesc, val, dma64) \
SET_TXBUFFER_DESC_ADD_HIGH_WITH_OFFSET(bdesc, 0, val, dma64)
/* Dword 3 / RESERVED 0 */
/* RX buffer */
/* DWORD 0 */
#define SET_RX_BUFFER_DESC_DATA_LENGTH(__rx_status_desc, __val) \
SET_BITS_TO_LE_4BYTE(__rx_status_desc, 0, 14, __val)
#define SET_RX_BUFFER_DESC_LS(__rx_status_desc, __val) \
SET_BITS_TO_LE_4BYTE(__rx_status_desc, 15, 1, __val)
#define SET_RX_BUFFER_DESC_FS(__rx_status_desc, __val) \
SET_BITS_TO_LE_4BYTE(__rx_status_desc, 16, 1, __val)
#define SET_RX_BUFFER_DESC_TOTAL_LENGTH(__rx_status_desc, __val) \
SET_BITS_TO_LE_4BYTE(__rx_status_desc, 16, 15, __val)
#define GET_RX_BUFFER_DESC_OWN(__rx_status_desc) \
LE_BITS_TO_4BYTE(__rx_status_desc, 31, 1)
#define GET_RX_BUFFER_DESC_LS(__rx_status_desc) \
LE_BITS_TO_4BYTE(__rx_status_desc, 15, 1)
#define GET_RX_BUFFER_DESC_FS(__rx_status_desc) \
LE_BITS_TO_4BYTE(__rx_status_desc, 16, 1)
#define GET_RX_BUFFER_DESC_TOTAL_LENGTH(__rx_status_desc) \
LE_BITS_TO_4BYTE(__rx_status_desc, 16, 15)
/* DWORD 1 */
#define SET_RX_BUFFER_PHYSICAL_LOW(__rx_status_desc, __val) \
SET_BITS_TO_LE_4BYTE(__rx_status_desc + 4, 0, 32, __val)
/* DWORD 2 */
#define SET_RX_BUFFER_PHYSICAL_HIGH(__rx_status_desc, __val, dma64) \
(dma64 ? SET_BITS_TO_LE_4BYTE((__rx_status_desc) + 8, 0, 32, __val) : 0)
#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \
do { \
if (_size > TX_DESC_NEXT_DESC_OFFSET) \
memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \
else \
memset(__pdesc, 0, _size); \
} while (0)
void rtl8822be_rx_check_dma_ok(struct ieee80211_hw *hw, u8 *header_desc,
u8 queue_index);
u16 rtl8822be_rx_desc_buff_remained_cnt(struct ieee80211_hw *hw,
u8 queue_index);
u16 rtl8822be_get_available_desc(struct ieee80211_hw *hw, u8 queue_index);
void rtl8822be_pre_fill_tx_bd_desc(struct ieee80211_hw *hw, u8 *tx_bd_desc,
u8 *desc, u8 queue_index,
struct sk_buff *skb, dma_addr_t addr);
void rtl8822be_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
u8 *pdesc_tx, u8 *pbd_desc_tx,
struct ieee80211_tx_info *info,
struct ieee80211_sta *sta, struct sk_buff *skb,
u8 hw_queue, struct rtl_tcb_desc *ptcb_desc);
void rtl8822be_tx_fill_special_desc(struct ieee80211_hw *hw, u8 *pdesc,
u8 *pbd_desc, struct sk_buff *skb,
u8 hw_queue);
bool rtl8822be_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *status,
struct ieee80211_rx_status *rx_status, u8 *pdesc,
struct sk_buff *skb);
void rtl8822be_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
u8 desc_name, u8 *val);
u64 rtl8822be_get_desc(struct ieee80211_hw *hw,
u8 *pdesc, bool istx, u8 desc_name);
bool rtl8822be_is_tx_desc_closed(struct ieee80211_hw *hw, u8 hw_queue,
u16 index);
void rtl8822be_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
void rtl8822be_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
bool firstseg, bool lastseg,
struct sk_buff *skb);
u32 rtl8822be_rx_command_packet(struct ieee80211_hw *hw,
const struct rtl_stats *status,
struct sk_buff *skb);
#endif