rtlwifi: rtl818x: Move drivers into new realtek directory

Now that a new mac80211-based driver for Realtek devices has been submitted,
it is time to reorganize the directories. Rather than having directories
rtlwifi and rtl818x be in drivers/net/wireless/, they will now be in
drivers/net/wireless/realtek/. This change simplifies the directory
structure, but does not result in any configuration changes that are
visable to the user.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
Larry Finger
2015-09-07 15:59:16 -05:00
committed by Kalle Valo
orang tua 6623c60dc2
melakukan f1d2b4d338
288 mengubah file dengan 14 tambahan dan 8 penghapusan

Melihat File

@@ -0,0 +1,14 @@
rtl8192de-objs := \
dm.o \
fw.o \
hw.o \
led.o \
phy.o \
rf.o \
sw.o \
table.o \
trx.o
obj-$(CONFIG_RTL8192DE) += rtl8192de.o
ccflags-y += -D__CHECK_ENDIAN__

Melihat File

@@ -0,0 +1,232 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* 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 __RTL92D_DEF_H__
#define __RTL92D_DEF_H__
/* Min Spacing related settings. */
#define MAX_MSS_DENSITY_2T 0x13
#define MAX_MSS_DENSITY_1T 0x0A
#define RF6052_MAX_TX_PWR 0x3F
#define RF6052_MAX_PATH 2
#define PHY_RSSI_SLID_WIN_MAX 100
#define PHY_LINKQUALITY_SLID_WIN_MAX 20
#define PHY_BEACON_RSSI_SLID_WIN_MAX 10
#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
#define RX_SMOOTH_FACTOR 20
#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 RX_CMD_QUEUE 1
#define C2H_RX_CMD_HDR_LEN 8
#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 0, 16)
#define GET_C2H_CMD_ELEMENT_ID(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 16, 8)
#define GET_C2H_CMD_CMD_SEQ(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 24, 7)
#define GET_C2H_CMD_CONTINUE(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 31, 1)
#define GET_C2H_CMD_CONTENT(__prxhdr) \
((u8 *)(__prxhdr) + C2H_RX_CMD_HDR_LEN)
#define GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8)
#define GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8)
#define GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16)
#define GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5)
#define GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1)
#define GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5)
#define GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1)
#define GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4)
#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
enum version_8192d {
VERSION_TEST_CHIP_88C = 0x0000,
VERSION_TEST_CHIP_92C = 0x0020,
VERSION_TEST_UMC_CHIP_8723 = 0x0081,
VERSION_NORMAL_TSMC_CHIP_88C = 0x0008,
VERSION_NORMAL_TSMC_CHIP_92C = 0x0028,
VERSION_NORMAL_TSMC_CHIP_92C_1T2R = 0x0018,
VERSION_NORMAL_UMC_CHIP_88C_A_CUT = 0x0088,
VERSION_NORMAL_UMC_CHIP_92C_A_CUT = 0x00a8,
VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT = 0x0098,
VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT = 0x0089,
VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT = 0x1089,
VERSION_NORMAL_UMC_CHIP_88C_B_CUT = 0x1088,
VERSION_NORMAL_UMC_CHIP_92C_B_CUT = 0x10a8,
VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT = 0x1090,
VERSION_TEST_CHIP_92D_SINGLEPHY = 0x0022,
VERSION_TEST_CHIP_92D_DUALPHY = 0x0002,
VERSION_NORMAL_CHIP_92D_SINGLEPHY = 0x002a,
VERSION_NORMAL_CHIP_92D_DUALPHY = 0x000a,
VERSION_NORMAL_CHIP_92D_C_CUT_SINGLEPHY = 0x202a,
VERSION_NORMAL_CHIP_92D_C_CUT_DUALPHY = 0x200a,
VERSION_NORMAL_CHIP_92D_D_CUT_SINGLEPHY = 0x302a,
VERSION_NORMAL_CHIP_92D_D_CUT_DUALPHY = 0x300a,
VERSION_NORMAL_CHIP_92D_E_CUT_SINGLEPHY = 0x402a,
VERSION_NORMAL_CHIP_92D_E_CUT_DUALPHY = 0x400a,
};
/* for 92D */
#define CHIP_92D_SINGLEPHY BIT(9)
/* Chip specific */
#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3)
#define CHIP_BONDING_92C_1T2R 0x1
#define CHIP_BONDING_88C_USB_MCARD 0x2
#define CHIP_BONDING_88C_USB_HP 0x1
/* [15:12] IC version(CUT): A-cut=0, B-cut=1, C-cut=2, D-cut=3 */
/* [7] Manufacturer: TSMC=0, UMC=1 */
/* [6:4] RF type: 1T1R=0, 1T2R=1, 2T2R=2 */
/* [3] Chip type: TEST=0, NORMAL=1 */
/* [2:0] IC type: 81xxC=0, 8723=1, 92D=2 */
#define CHIP_8723 BIT(0)
#define CHIP_92D BIT(1)
#define NORMAL_CHIP BIT(3)
#define RF_TYPE_1T1R (~(BIT(4)|BIT(5)|BIT(6)))
#define RF_TYPE_1T2R BIT(4)
#define RF_TYPE_2T2R BIT(5)
#define CHIP_VENDOR_UMC BIT(7)
#define CHIP_92D_B_CUT BIT(12)
#define CHIP_92D_C_CUT BIT(13)
#define CHIP_92D_D_CUT (BIT(13)|BIT(12))
#define CHIP_92D_E_CUT BIT(14)
/* MASK */
#define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2))
#define CHIP_TYPE_MASK BIT(3)
#define RF_TYPE_MASK (BIT(4)|BIT(5)|BIT(6))
#define MANUFACTUER_MASK BIT(7)
#define ROM_VERSION_MASK (BIT(11)|BIT(10)|BIT(9)|BIT(8))
#define CUT_VERSION_MASK (BIT(15)|BIT(14)|BIT(13)|BIT(12))
/* Get element */
#define GET_CVID_IC_TYPE(version) ((version) & IC_TYPE_MASK)
#define GET_CVID_CHIP_TYPE(version) ((version) & CHIP_TYPE_MASK)
#define GET_CVID_RF_TYPE(version) ((version) & RF_TYPE_MASK)
#define GET_CVID_MANUFACTUER(version) ((version) & MANUFACTUER_MASK)
#define GET_CVID_ROM_VERSION(version) ((version) & ROM_VERSION_MASK)
#define GET_CVID_CUT_VERSION(version) ((version) & CUT_VERSION_MASK)
#define IS_1T1R(version) ((GET_CVID_RF_TYPE(version)) ? \
false : true)
#define IS_1T2R(version) ((GET_CVID_RF_TYPE(version) == \
RF_TYPE_1T2R) ? true : false)
#define IS_2T2R(version) ((GET_CVID_RF_TYPE(version) == \
RF_TYPE_2T2R) ? true : false)
#define IS_92D_SINGLEPHY(version) ((IS_92D(version)) ? \
(IS_2T2R(version) ? true : false) : false)
#define IS_92D(version) ((GET_CVID_IC_TYPE(version) == \
CHIP_92D) ? true : false)
#define IS_92D_C_CUT(version) ((IS_92D(version)) ? \
((GET_CVID_CUT_VERSION(version) == \
CHIP_92D_C_CUT) ? true : false) : false)
#define IS_92D_D_CUT(version) ((IS_92D(version)) ? \
((GET_CVID_CUT_VERSION(version) == \
CHIP_92D_D_CUT) ? true : false) : false)
#define IS_92D_E_CUT(version) ((IS_92D(version)) ? \
((GET_CVID_CUT_VERSION(version) == \
CHIP_92D_E_CUT) ? true : false) : false)
enum rf_optype {
RF_OP_BY_SW_3WIRE = 0,
RF_OP_BY_FW,
RF_OP_MAX
};
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 channel_plan {
CHPL_FCC = 0,
CHPL_IC = 1,
CHPL_ETSI = 2,
CHPL_SPAIN = 3,
CHPL_FRANCE = 4,
CHPL_MKK = 5,
CHPL_MKK1 = 6,
CHPL_ISRAEL = 7,
CHPL_TELEC = 8,
CHPL_GLOBAL = 9,
CHPL_WORLD = 10,
};
struct phy_sts_cck_8192d {
u8 adc_pwdb_X[4];
u8 sq_rpt;
u8 cck_agc_rpt;
};
struct h2c_cmd_8192c {
u8 element_id;
u32 cmd_len;
u8 *p_cmdbuffer;
};
struct txpower_info {
u8 cck_index[RF6052_MAX_PATH][CHANNEL_GROUP_MAX];
u8 ht40_1sindex[RF6052_MAX_PATH][CHANNEL_GROUP_MAX];
u8 ht40_2sindexdiff[RF6052_MAX_PATH][CHANNEL_GROUP_MAX];
u8 ht20indexdiff[RF6052_MAX_PATH][CHANNEL_GROUP_MAX];
u8 ofdmindexdiff[RF6052_MAX_PATH][CHANNEL_GROUP_MAX];
u8 ht40maxoffset[RF6052_MAX_PATH][CHANNEL_GROUP_MAX];
u8 ht20maxoffset[RF6052_MAX_PATH][CHANNEL_GROUP_MAX];
u8 tssi_a[3]; /* 5GL/5GM/5GH */
u8 tssi_b[3];
};
#endif

File diff ditekan karena terlalu besar Load Diff

Melihat File

@@ -0,0 +1,123 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* 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 __RTL92C_DM_H__
#define __RTL92C_DM_H__
#define HAL_DM_DIG_DISABLE BIT(0)
#define HAL_DM_HIPWR_DISABLE BIT(1)
#define OFDM_TABLE_LENGTH 37
#define OFDM_TABLE_SIZE_92D 43
#define CCK_TABLE_LENGTH 33
#define CCK_TABLE_SIZE 33
#define BW_AUTO_SWITCH_HIGH_LOW 25
#define BW_AUTO_SWITCH_LOW_HIGH 30
#define DM_DIG_FA_UPPER 0x32
#define DM_DIG_FA_LOWER 0x20
#define DM_DIG_FA_TH0 0x100
#define DM_DIG_FA_TH1 0x400
#define DM_DIG_FA_TH2 0x600
#define RXPATHSELECTION_SS_TH_lOW 30
#define RXPATHSELECTION_DIFF_TH 18
#define DM_RATR_STA_INIT 0
#define DM_RATR_STA_HIGH 1
#define DM_RATR_STA_MIDDLE 2
#define DM_RATR_STA_LOW 3
#define CTS2SELF_THVAL 30
#define REGC38_TH 20
#define WAIOTTHVAL 25
#define TXHIGHPWRLEVEL_NORMAL 0
#define TXHIGHPWRLEVEL_LEVEL1 1
#define TXHIGHPWRLEVEL_LEVEL2 2
#define TXHIGHPWRLEVEL_BT1 3
#define TXHIGHPWRLEVEL_BT2 4
#define DM_TYPE_BYFW 0
#define DM_TYPE_BYDRIVER 1
#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
#define INDEX_MAPPING_NUM 13
struct swat {
u8 failure_cnt;
u8 try_flag;
u8 stop_trying;
long pre_rssi;
long trying_threshold;
u8 cur_antenna;
u8 pre_antenna;
};
enum tag_dynamic_init_gain_operation_type_definition {
DIG_TYPE_THRESH_HIGH = 0,
DIG_TYPE_THRESH_LOW = 1,
DIG_TYPE_BACKOFF = 2,
DIG_TYPE_RX_GAIN_MIN = 3,
DIG_TYPE_RX_GAIN_MAX = 4,
DIG_TYPE_ENABLE = 5,
DIG_TYPE_DISABLE = 6,
DIG_OP_TYPE_MAX
};
enum dm_1r_cca {
CCA_1R = 0,
CCA_2R = 1,
CCA_MAX = 2,
};
enum dm_rf {
RF_SAVE = 0,
RF_NORMAL = 1,
RF_MAX = 2,
};
enum dm_sw_ant_switch {
ANS_ANTENNA_B = 1,
ANS_ANTENNA_A = 2,
ANS_ANTENNA_MAX = 3,
};
void rtl92d_dm_init(struct ieee80211_hw *hw);
void rtl92d_dm_watchdog(struct ieee80211_hw *hw);
void rtl92d_dm_init_edca_turbo(struct ieee80211_hw *hw);
void rtl92d_dm_write_dig(struct ieee80211_hw *hw);
void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw);
void rtl92d_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);
#endif

Melihat File

@@ -0,0 +1,763 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* 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"
#include "sw.h"
static bool _rtl92d_is_fw_downloaded(struct rtl_priv *rtlpriv)
{
return (rtl_read_dword(rtlpriv, REG_MCUFWDL) & MCUFWDL_RDY) ?
true : false;
}
static void _rtl92d_enable_fw_download(struct ieee80211_hw *hw, bool enable)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 tmp;
if (enable) {
tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04);
tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
} else {
tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
/* Reserved for fw extension.
* 0x81[7] is used for mac0 status ,
* so don't write this reg here
* rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);*/
}
}
static void _rtl92d_fw_block_write(struct ieee80211_hw *hw,
const u8 *buffer, u32 size)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 blocksize = sizeof(u32);
u8 *bufferptr = (u8 *) buffer;
u32 *pu4BytePtr = (u32 *) buffer;
u32 i, offset, blockCount, remainSize;
blockCount = size / blocksize;
remainSize = size % blocksize;
for (i = 0; i < blockCount; i++) {
offset = i * blocksize;
rtl_write_dword(rtlpriv, (FW_8192D_START_ADDRESS + offset),
*(pu4BytePtr + i));
}
if (remainSize) {
offset = blockCount * blocksize;
bufferptr += offset;
for (i = 0; i < remainSize; i++) {
rtl_write_byte(rtlpriv, (FW_8192D_START_ADDRESS +
offset + i), *(bufferptr + i));
}
}
}
static void _rtl92d_fw_page_write(struct ieee80211_hw *hw,
u32 page, const u8 *buffer, u32 size)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 value8;
u8 u8page = (u8) (page & 0x07);
value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
_rtl92d_fw_block_write(hw, buffer, size);
}
static void _rtl92d_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
{
u32 fwlen = *pfwlen;
u8 remain = (u8) (fwlen % 4);
remain = (remain == 0) ? 0 : (4 - remain);
while (remain > 0) {
pfwbuf[fwlen] = 0;
fwlen++;
remain--;
}
*pfwlen = fwlen;
}
static void _rtl92d_write_fw(struct ieee80211_hw *hw,
enum version_8192d version, u8 *buffer, u32 size)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
u8 *bufferPtr = buffer;
u32 pagenums, remainSize;
u32 page, offset;
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size);
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE)
_rtl92d_fill_dummy(bufferPtr, &size);
pagenums = size / FW_8192D_PAGE_SIZE;
remainSize = size % FW_8192D_PAGE_SIZE;
if (pagenums > 8) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Page numbers should not greater then 8\n");
}
for (page = 0; page < pagenums; page++) {
offset = page * FW_8192D_PAGE_SIZE;
_rtl92d_fw_page_write(hw, page, (bufferPtr + offset),
FW_8192D_PAGE_SIZE);
}
if (remainSize) {
offset = pagenums * FW_8192D_PAGE_SIZE;
page = pagenums;
_rtl92d_fw_page_write(hw, page, (bufferPtr + offset),
remainSize);
}
}
static int _rtl92d_fw_free_to_go(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 counter = 0;
u32 value32;
do {
value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
} while ((counter++ < FW_8192D_POLLING_TIMEOUT_COUNT) &&
(!(value32 & FWDL_ChkSum_rpt)));
if (counter >= FW_8192D_POLLING_TIMEOUT_COUNT) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"chksum report faill ! REG_MCUFWDL:0x%08x\n",
value32);
return -EIO;
}
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
"Checksum report OK ! REG_MCUFWDL:0x%08x\n", value32);
value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
value32 |= MCUFWDL_RDY;
rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
return 0;
}
void rtl92d_firmware_selfreset(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 u1b_tmp;
u8 delay = 100;
/* Set (REG_HMETFR + 3) to 0x20 is reset 8051 */
rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
while (u1b_tmp & BIT(2)) {
delay--;
if (delay == 0)
break;
udelay(50);
u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
}
RT_ASSERT((delay > 0), "8051 reset failed!\n");
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
"=====> 8051 reset success (%d)\n", delay);
}
static int _rtl92d_fw_init(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
u32 counter;
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, "FW already have download\n");
/* polling for FW ready */
counter = 0;
do {
if (rtlhal->interfaceindex == 0) {
if (rtl_read_byte(rtlpriv, FW_MAC0_READY) &
MAC0_READY) {
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
"Polling FW ready success!! REG_MCUFWDL: 0x%x\n",
rtl_read_byte(rtlpriv,
FW_MAC0_READY));
return 0;
}
udelay(5);
} else {
if (rtl_read_byte(rtlpriv, FW_MAC1_READY) &
MAC1_READY) {
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
"Polling FW ready success!! REG_MCUFWDL: 0x%x\n",
rtl_read_byte(rtlpriv,
FW_MAC1_READY));
return 0;
}
udelay(5);
}
} while (counter++ < POLLING_READY_TIMEOUT_COUNT);
if (rtlhal->interfaceindex == 0) {
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
"Polling FW ready fail!! MAC0 FW init not ready: 0x%x\n",
rtl_read_byte(rtlpriv, FW_MAC0_READY));
} else {
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
"Polling FW ready fail!! MAC1 FW init not ready: 0x%x\n",
rtl_read_byte(rtlpriv, FW_MAC1_READY));
}
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
"Polling FW ready fail!! REG_MCUFWDL:0x%08ul\n",
rtl_read_dword(rtlpriv, REG_MCUFWDL));
return -1;
}
int rtl92d_download_fw(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
u8 *pfwheader;
u8 *pfwdata;
u32 fwsize;
int err;
enum version_8192d version = rtlhal->version;
u8 value;
u32 count;
bool fw_downloaded = false, fwdl_in_process = false;
unsigned long flags;
if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
return 1;
fwsize = rtlhal->fwsize;
pfwheader = rtlhal->pfirmware;
pfwdata = rtlhal->pfirmware;
rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader);
rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader);
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
"FirmwareVersion(%d), FirmwareSubVersion(%d), Signature(%#x)\n",
rtlhal->fw_version, rtlhal->fw_subversion,
GET_FIRMWARE_HDR_SIGNATURE(pfwheader));
if (IS_FW_HEADER_EXIST(pfwheader)) {
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
"Shift 32 bytes for FW header!!\n");
pfwdata = pfwdata + 32;
fwsize = fwsize - 32;
}
spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
fw_downloaded = _rtl92d_is_fw_downloaded(rtlpriv);
if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))
fwdl_in_process = true;
else
fwdl_in_process = false;
if (fw_downloaded) {
spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
goto exit;
} else if (fwdl_in_process) {
spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
for (count = 0; count < 5000; count++) {
udelay(500);
spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
fw_downloaded = _rtl92d_is_fw_downloaded(rtlpriv);
if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))
fwdl_in_process = true;
else
fwdl_in_process = false;
spin_unlock_irqrestore(&globalmutex_for_fwdownload,
flags);
if (fw_downloaded)
goto exit;
else if (!fwdl_in_process)
break;
else
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
"Wait for another mac download fw\n");
}
spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
value = rtl_read_byte(rtlpriv, 0x1f);
value |= BIT(5);
rtl_write_byte(rtlpriv, 0x1f, value);
spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
} else {
value = rtl_read_byte(rtlpriv, 0x1f);
value |= BIT(5);
rtl_write_byte(rtlpriv, 0x1f, value);
spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
}
/* If 8051 is running in RAM code, driver should
* inform Fw to reset by itself, or it will cause
* download Fw fail.*/
/* 8051 RAM code */
if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) {
rtl92d_firmware_selfreset(hw);
rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
}
_rtl92d_enable_fw_download(hw, true);
_rtl92d_write_fw(hw, version, pfwdata, fwsize);
_rtl92d_enable_fw_download(hw, false);
spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
err = _rtl92d_fw_free_to_go(hw);
/* download fw over,clear 0x1f[5] */
value = rtl_read_byte(rtlpriv, 0x1f);
value &= (~BIT(5));
rtl_write_byte(rtlpriv, 0x1f, value);
spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
if (err) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"fw is not ready to run!\n");
goto exit;
} else {
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "fw is ready to run!\n");
}
exit:
err = _rtl92d_fw_init(hw);
return err;
}
static bool _rtl92d_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 val_hmetfr;
bool result = false;
val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
result = true;
return result;
}
static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
u8 element_id, u32 cmd_len, u8 *cmdbuffer)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
u8 boxnum;
u16 box_reg = 0, box_extreg = 0;
u8 u1b_tmp;
bool isfw_read = false;
u8 buf_index = 0;
bool bwrite_success = false;
u8 wait_h2c_limmit = 100;
u8 wait_writeh2c_limmit = 100;
u8 boxcontent[4], boxextcontent[2];
u32 h2c_waitcounter = 0;
unsigned long flag;
u8 idx;
if (ppsc->rfpwr_state == ERFOFF || ppsc->inactive_pwrstate == ERFOFF) {
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"Return as RF is off!!!\n");
return;
}
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
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 to set..element_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) {
wait_writeh2c_limmit--;
if (wait_writeh2c_limmit == 0) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Write H2C fail because no trigger for FW INT!\n");
break;
}
boxnum = rtlhal->last_hmeboxnum;
switch (boxnum) {
case 0:
box_reg = REG_HMEBOX_0;
box_extreg = REG_HMEBOX_EXT_0;
break;
case 1:
box_reg = REG_HMEBOX_1;
box_extreg = REG_HMEBOX_EXT_1;
break;
case 2:
box_reg = REG_HMEBOX_2;
box_extreg = REG_HMEBOX_EXT_2;
break;
case 3:
box_reg = REG_HMEBOX_3;
box_extreg = REG_HMEBOX_EXT_3;
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"switch case not processed\n");
break;
}
isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
while (!isfw_read) {
wait_h2c_limmit--;
if (wait_h2c_limmit == 0) {
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"Waiting too long for FW read clear HMEBox(%d)!\n",
boxnum);
break;
}
udelay(10);
isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n",
boxnum, u1b_tmp);
}
if (!isfw_read) {
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
boxnum);
break;
}
memset(boxcontent, 0, sizeof(boxcontent));
memset(boxextcontent, 0, sizeof(boxextcontent));
boxcontent[0] = element_id;
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"Write element_id box_reg(%4x) = %2x\n",
box_reg, element_id);
switch (cmd_len) {
case 1:
boxcontent[0] &= ~(BIT(7));
memcpy(boxcontent + 1, cmdbuffer + buf_index, 1);
for (idx = 0; idx < 4; idx++)
rtl_write_byte(rtlpriv, box_reg + idx,
boxcontent[idx]);
break;
case 2:
boxcontent[0] &= ~(BIT(7));
memcpy(boxcontent + 1, cmdbuffer + buf_index, 2);
for (idx = 0; idx < 4; idx++)
rtl_write_byte(rtlpriv, box_reg + idx,
boxcontent[idx]);
break;
case 3:
boxcontent[0] &= ~(BIT(7));
memcpy(boxcontent + 1, cmdbuffer + buf_index, 3);
for (idx = 0; idx < 4; idx++)
rtl_write_byte(rtlpriv, box_reg + idx,
boxcontent[idx]);
break;
case 4:
boxcontent[0] |= (BIT(7));
memcpy(boxextcontent, cmdbuffer + buf_index, 2);
memcpy(boxcontent + 1, cmdbuffer + buf_index + 2, 2);
for (idx = 0; idx < 2; idx++)
rtl_write_byte(rtlpriv, box_extreg + idx,
boxextcontent[idx]);
for (idx = 0; idx < 4; idx++)
rtl_write_byte(rtlpriv, box_reg + idx,
boxcontent[idx]);
break;
case 5:
boxcontent[0] |= (BIT(7));
memcpy(boxextcontent, cmdbuffer + buf_index, 2);
memcpy(boxcontent + 1, cmdbuffer + buf_index + 2, 3);
for (idx = 0; idx < 2; idx++)
rtl_write_byte(rtlpriv, box_extreg + idx,
boxextcontent[idx]);
for (idx = 0; idx < 4; idx++)
rtl_write_byte(rtlpriv, box_reg + idx,
boxcontent[idx]);
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"switch case not processed\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 rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw,
u8 element_id, u32 cmd_len, u8 *cmdbuffer)
{
u32 tmp_cmdbuf[2];
memset(tmp_cmdbuf, 0, 8);
memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
_rtl92d_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
return;
}
static bool _rtl92d_cmd_send_packet(struct ieee80211_hw *hw,
struct sk_buff *skb)
{
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;
u8 idx = 0;
unsigned long flags;
struct sk_buff *pskb;
ring = &rtlpci->tx_ring[BEACON_QUEUE];
pskb = __skb_dequeue(&ring->queue);
kfree_skb(pskb);
spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
pdesc = &ring->desc[idx];
/* discard output from call below */
rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
__skb_queue_tail(&ring->queue, skb);
spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
return true;
}
#define BEACON_PG 0 /*->1 */
#define PSPOLL_PG 2
#define NULL_PG 3
#define PROBERSP_PG 4 /*->5 */
#define TOTAL_RESERVED_PKT_LEN 768
static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
/* page 0 beacon */
0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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 1 beacon */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 2 ps-poll */
0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 3 null */
0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x80, 0x01, 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,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool 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 u1RsvdPageLoc[3] = { 0 };
bool dlok = false;
u8 *beacon;
u8 *p_pspoll;
u8 *nullfunc;
u8 *p_probersp;
/*---------------------------------------------------------
(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(u1RsvdPageLoc, 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(u1RsvdPageLoc, 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(u1RsvdPageLoc, PROBERSP_PG);
totalpacketlen = TOTAL_RESERVED_PKT_LEN;
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
"rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
&reserved_page_packet[0], totalpacketlen);
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
"rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
u1RsvdPageLoc, 3);
skb = dev_alloc_skb(totalpacketlen);
if (!skb) {
dlok = false;
} else {
memcpy((u8 *) skb_put(skb, totalpacketlen),
&reserved_page_packet, totalpacketlen);
rtstatus = _rtl92d_cmd_send_packet(hw, skb);
if (rtstatus)
dlok = true;
}
if (dlok) {
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"Set RSVD page location to Fw\n");
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
"H2C_RSVDPAGE", u1RsvdPageLoc, 3);
rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE,
sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
} else
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
"Set RSVD page location to Fw FAIL!!!!!!\n");
}
void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
{
u8 u1_joinbssrpt_parm[1] = {0};
SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
rtl92d_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
}

Melihat File

@@ -0,0 +1,120 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* 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 __RTL92D__FW__H__
#define __RTL92D__FW__H__
#define FW_8192D_START_ADDRESS 0x1000
#define FW_8192D_PAGE_SIZE 4096
#define FW_8192D_POLLING_TIMEOUT_COUNT 1000
#define IS_FW_HEADER_EXIST(_pfwhdr) \
((GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFF0) == 0x92C0 || \
(GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFF0) == 0x88C0 || \
(GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D0 || \
(GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D1 || \
(GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D2 || \
(GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D3)
/* Define a macro that takes an le32 word, converts it to host ordering,
* right shifts by a specified count, creates a mask of the specified
* bit count, and extracts that number of bits.
*/
#define SHIFT_AND_MASK_LE(__pdesc, __shift, __mask) \
((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) & \
BIT_LEN_MASK_32(__mask))
/* Firmware Header(8-byte alinment required) */
/* --- LONG WORD 0 ---- */
#define GET_FIRMWARE_HDR_SIGNATURE(__fwhdr) \
SHIFT_AND_MASK_LE(__fwhdr, 0, 16)
#define GET_FIRMWARE_HDR_CATEGORY(__fwhdr) \
SHIFT_AND_MASK_LE(__fwhdr, 16, 8)
#define GET_FIRMWARE_HDR_FUNCTION(__fwhdr) \
SHIFT_AND_MASK_LE(__fwhdr, 24, 8)
#define GET_FIRMWARE_HDR_VERSION(__fwhdr) \
SHIFT_AND_MASK_LE(__fwhdr + 4, 0, 16)
#define GET_FIRMWARE_HDR_SUB_VER(__fwhdr) \
SHIFT_AND_MASK_LE(__fwhdr + 4, 16, 8)
#define GET_FIRMWARE_HDR_RSVD1(__fwhdr) \
SHIFT_AND_MASK_LE(__fwhdr + 4, 24, 8)
/* --- LONG WORD 1 ---- */
#define GET_FIRMWARE_HDR_MONTH(__fwhdr) \
SHIFT_AND_MASK_LE(__fwhdr + 8, 0, 8)
#define GET_FIRMWARE_HDR_DATE(__fwhdr) \
SHIFT_AND_MASK_LE(__fwhdr + 8, 8, 8)
#define GET_FIRMWARE_HDR_HOUR(__fwhdr) \
SHIFT_AND_MASK_LE(__fwhdr + 8, 16, 8)
#define GET_FIRMWARE_HDR_MINUTE(__fwhdr) \
SHIFT_AND_MASK_LE(__fwhdr + 8, 24, 8)
#define GET_FIRMWARE_HDR_ROMCODE_SIZE(__fwhdr) \
SHIFT_AND_MASK_LE(__fwhdr + 12, 0, 16)
#define GET_FIRMWARE_HDR_RSVD2(__fwhdr) \
SHIFT_AND_MASK_LE(__fwhdr + 12, 16, 16)
/* --- LONG WORD 2 ---- */
#define GET_FIRMWARE_HDR_SVN_IDX(__fwhdr) \
SHIFT_AND_MASK_LE(__fwhdr + 16, 0, 32)
#define GET_FIRMWARE_HDR_RSVD3(__fwhdr) \
SHIFT_AND_MASK_LE(__fwhdr + 20, 0, 32)
/* --- LONG WORD 3 ---- */
#define GET_FIRMWARE_HDR_RSVD4(__fwhdr) \
SHIFT_AND_MASK_LE(__fwhdr + 24, 0, 32)
#define GET_FIRMWARE_HDR_RSVD5(__fwhdr) \
SHIFT_AND_MASK_LE(__fwhdr + 28, 0, 32)
#define pagenum_128(_len) \
(u32)(((_len) >> 7) + ((_len) & 0x7F ? 1 : 0))
#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 1, 0, 8, __val)
#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 2, 0, 8, __val)
#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
#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)
int rtl92d_download_fw(struct ieee80211_hw *hw);
void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
u32 cmd_len, u8 *p_cmdbuffer);
void rtl92d_firmware_selfreset(struct ieee80211_hw *hw);
void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
#endif

File diff ditekan karena terlalu besar Load Diff

Melihat File

@@ -0,0 +1,65 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* 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 __RTL92DE_HW_H__
#define __RTL92DE_HW_H__
void rtl92de_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
void rtl92de_read_eeprom_info(struct ieee80211_hw *hw);
void rtl92de_interrupt_recognized(struct ieee80211_hw *hw,
u32 *p_inta, u32 *p_intb);
int rtl92de_hw_init(struct ieee80211_hw *hw);
void rtl92de_card_disable(struct ieee80211_hw *hw);
void rtl92de_enable_interrupt(struct ieee80211_hw *hw);
void rtl92de_disable_interrupt(struct ieee80211_hw *hw);
int rtl92de_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type);
void rtl92de_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
void rtl92de_set_qos(struct ieee80211_hw *hw, int aci);
void rtl92de_set_beacon_related_registers(struct ieee80211_hw *hw);
void rtl92de_set_beacon_interval(struct ieee80211_hw *hw);
void rtl92de_update_interrupt_mask(struct ieee80211_hw *hw,
u32 add_msr, u32 rm_msr);
void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
void rtl92de_update_hal_rate_tbl(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, u8 rssi_level);
void rtl92de_update_channel_access_setting(struct ieee80211_hw *hw);
bool rtl92de_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
void rtl92de_enable_hw_security_config(struct ieee80211_hw *hw);
void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index,
u8 *p_macaddr, bool is_group, u8 enc_algo,
bool is_wepkey, bool clear_all);
void rtl92de_write_dword_dbi(struct ieee80211_hw *hw, u16 offset, u32 value,
u8 direct);
u32 rtl92de_read_dword_dbi(struct ieee80211_hw *hw, u16 offset, u8 direct);
void rtl92de_suspend(struct ieee80211_hw *hw);
void rtl92de_resume(struct ieee80211_hw *hw);
void rtl92d_linked_set_reg(struct ieee80211_hw *hw);
#endif

Melihat File

@@ -0,0 +1,159 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* 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 _rtl92ce_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 rtl92de_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
{
u8 ledcfg;
struct rtl_priv *rtlpriv = rtl_priv(hw);
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
REG_LEDCFG2, pled->ledpin);
switch (pled->ledpin) {
case LED_PIN_GPIO0:
break;
case LED_PIN_LED0:
ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
if ((rtlpriv->efuse.eeprom_did == 0x8176) ||
(rtlpriv->efuse.eeprom_did == 0x8193))
/* BIT7 of REG_LEDCFG2 should be set to
* make sure we could emit the led2. */
rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0xf0) |
BIT(7) | BIT(5) | BIT(6));
else
rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0xf0) |
BIT(7) | BIT(5));
break;
case LED_PIN_LED1:
ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5));
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"switch case not processed\n");
break;
}
pled->ledon = true;
}
void rtl92de_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
u8 ledcfg;
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
REG_LEDCFG2, pled->ledpin);
ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
switch (pled->ledpin) {
case LED_PIN_GPIO0:
break;
case LED_PIN_LED0:
ledcfg &= 0xf0;
if (pcipriv->ledctl.led_opendrain)
rtl_write_byte(rtlpriv, REG_LEDCFG2,
(ledcfg | BIT(1) | BIT(5) | BIT(6)));
else
rtl_write_byte(rtlpriv, REG_LEDCFG2,
(ledcfg | BIT(3) | BIT(5) | BIT(6)));
break;
case LED_PIN_LED1:
ledcfg &= 0x0f;
rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3)));
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"switch case not processed\n");
break;
}
pled->ledon = false;
}
void rtl92de_init_sw_leds(struct ieee80211_hw *hw)
{
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
_rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0);
_rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1);
}
static void _rtl92ce_sw_led_control(struct ieee80211_hw *hw,
enum led_ctl_mode ledaction)
{
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
switch (ledaction) {
case LED_CTL_POWER_ON:
case LED_CTL_LINK:
case LED_CTL_NO_LINK:
rtl92de_sw_led_on(hw, pLed0);
break;
case LED_CTL_POWER_OFF:
rtl92de_sw_led_off(hw, pLed0);
break;
default:
break;
}
}
void rtl92de_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_LOUD, "ledaction %d,\n", ledaction);
_rtl92ce_sw_led_control(hw, ledaction);
}

Melihat File

@@ -0,0 +1,38 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* 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 __RTL92CE_LED_H__
#define __RTL92CE_LED_H__
void rtl92de_init_sw_leds(struct ieee80211_hw *hw);
void rtl92de_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
void rtl92de_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
void rtl92de_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction);
#endif

File diff ditekan karena terlalu besar Load Diff

Melihat File

@@ -0,0 +1,173 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* 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 __RTL92D_PHY_H__
#define __RTL92D_PHY_H__
#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 MAX_TOLERANCE 5
#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_BB_REG_NUM 10
#define IQK_BB_REG_NUM_test 6
#define IQK_MAC_REG_NUM 4
#define RX_INDEX_MAPPING_NUM 15
#define IQK_DELAY_TIME 1
#define CT_OFFSET_MAC_ADDR 0X16
#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
enum swchnlcmd_id {
CMDID_END,
CMDID_SET_TXPOWEROWER_LEVEL,
CMDID_BBREGWRITE10,
CMDID_WRITEPORT_ULONG,
CMDID_WRITEPORT_USHORT,
CMDID_WRITEPORT_UCHAR,
CMDID_RF_WRITEREG,
};
struct swchnlcmd {
enum swchnlcmd_id cmdid;
u32 para1;
u32 para2;
u32 msdelay;
};
enum baseband_config_type {
BASEBAND_CONFIG_PHY_REG = 0,
BASEBAND_CONFIG_AGC_TAB = 1,
};
enum rf_content {
radioa_txt = 0,
radiob_txt = 1,
radioc_txt = 2,
radiod_txt = 3
};
static inline void rtl92d_acquire_cckandrw_pagea_ctl(struct ieee80211_hw *hw,
unsigned long *flag)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
if (rtlpriv->rtlhal.interfaceindex == 1)
spin_lock_irqsave(&rtlpriv->locks.cck_and_rw_pagea_lock, *flag);
}
static inline void rtl92d_release_cckandrw_pagea_ctl(struct ieee80211_hw *hw,
unsigned long *flag)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
if (rtlpriv->rtlhal.interfaceindex == 1)
spin_unlock_irqrestore(&rtlpriv->locks.cck_and_rw_pagea_lock,
*flag);
}
u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw,
u32 regaddr, u32 bitmask);
void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw,
u32 regaddr, u32 bitmask, u32 data);
u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 regaddr,
u32 bitmask);
void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 regaddr,
u32 bitmask, u32 data);
bool rtl92d_phy_mac_config(struct ieee80211_hw *hw);
bool rtl92d_phy_bb_config(struct ieee80211_hw *hw);
bool rtl92d_phy_rf_config(struct ieee80211_hw *hw);
bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
enum radio_path rfpath);
void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw,
enum nl80211_channel_type ch_type);
u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw);
bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
enum rf_content content,
enum radio_path rfpath);
bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw,
enum rf_pwrstate rfpwr_state);
void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw);
void rtl92d_phy_config_macphymode_info(struct ieee80211_hw *hw);
u8 rtl92d_get_chnlgroup_fromarray(u8 chnl);
void rtl92d_phy_set_poweron(struct ieee80211_hw *hw);
void rtl92d_phy_config_maccoexist_rfpage(struct ieee80211_hw *hw);
bool rtl92d_phy_check_poweroff(struct ieee80211_hw *hw);
void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw);
void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw);
void rtl92d_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);
void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw);
void rtl92d_phy_reset_iqk_result(struct ieee80211_hw *hw);
void rtl92d_release_cckandrw_pagea_ctl(struct ieee80211_hw *hw,
unsigned long *flag);
void rtl92d_acquire_cckandrw_pagea_ctl(struct ieee80211_hw *hw,
unsigned long *flag);
u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl);
void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel);
#endif

File diff ditekan karena terlalu besar Load Diff

Melihat File

@@ -0,0 +1,623 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* 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 "reg.h"
#include "def.h"
#include "phy.h"
#include "rf.h"
#include "dm.h"
#include "hw.h"
void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
u8 rfpath;
switch (bandwidth) {
case HT_CHANNEL_WIDTH_20:
for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
rtlphy->rfreg_chnlval[rfpath] = ((rtlphy->rfreg_chnlval
[rfpath] & 0xfffff3ff) | 0x0400);
rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(10) |
BIT(11), 0x01);
RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
"20M RF 0x18 = 0x%x\n",
rtlphy->rfreg_chnlval[rfpath]);
}
break;
case HT_CHANNEL_WIDTH_20_40:
for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
rtlphy->rfreg_chnlval[rfpath] =
((rtlphy->rfreg_chnlval[rfpath] & 0xfffff3ff));
rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(10) | BIT(11),
0x00);
RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
"40M RF 0x18 = 0x%x\n",
rtlphy->rfreg_chnlval[rfpath]);
}
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"unknown bandwidth: %#X\n", bandwidth);
break;
}
}
void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
u8 *ppowerlevel)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
u32 tx_agc[2] = {0, 0}, tmpval;
bool turbo_scanoff = false;
u8 idx1, idx2;
u8 *ptr;
if (rtlefuse->eeprom_regulatory != 0)
turbo_scanoff = true;
if (mac->act_scanning) {
tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
if (turbo_scanoff) {
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
tx_agc[idx1] = ppowerlevel[idx1] |
(ppowerlevel[idx1] << 8) |
(ppowerlevel[idx1] << 16) |
(ppowerlevel[idx1] << 24);
}
}
} else {
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
tx_agc[idx1] = ppowerlevel[idx1] |
(ppowerlevel[idx1] << 8) |
(ppowerlevel[idx1] << 16) |
(ppowerlevel[idx1] << 24);
}
if (rtlefuse->eeprom_regulatory == 0) {
tmpval = (rtlphy->mcs_offset[0][6]) +
(rtlphy->mcs_offset[0][7] << 8);
tx_agc[RF90_PATH_A] += tmpval;
tmpval = (rtlphy->mcs_offset[0][14]) +
(rtlphy->mcs_offset[0][15] << 24);
tx_agc[RF90_PATH_B] += tmpval;
}
}
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
ptr = (u8 *) (&(tx_agc[idx1]));
for (idx2 = 0; idx2 < 4; idx2++) {
if (*ptr > RF6052_MAX_TX_PWR)
*ptr = RF6052_MAX_TX_PWR;
ptr++;
}
}
tmpval = tx_agc[RF90_PATH_A] & 0xff;
rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n",
tmpval, RTXAGC_A_CCK1_MCS32);
tmpval = tx_agc[RF90_PATH_A] >> 8;
rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n",
tmpval, RTXAGC_B_CCK11_A_CCK2_11);
tmpval = tx_agc[RF90_PATH_B] >> 24;
rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n",
tmpval, RTXAGC_B_CCK11_A_CCK2_11);
tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n",
tmpval, RTXAGC_B_CCK1_55_MCS32);
}
static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw,
u8 *ppowerlevel, u8 channel,
u32 *ofdmbase, u32 *mcsbase)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
u32 powerbase0, powerbase1;
u8 legacy_pwrdiff, ht20_pwrdiff;
u8 i, powerlevel[2];
for (i = 0; i < 2; i++) {
powerlevel[i] = ppowerlevel[i];
legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1];
powerbase0 = powerlevel[i] + legacy_pwrdiff;
powerbase0 = (powerbase0 << 24) | (powerbase0 << 16) |
(powerbase0 << 8) | powerbase0;
*(ofdmbase + i) = powerbase0;
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
" [OFDM power base index rf(%c) = 0x%x]\n",
i == 0 ? 'A' : 'B', *(ofdmbase + i));
}
for (i = 0; i < 2; i++) {
if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1];
powerlevel[i] += ht20_pwrdiff;
}
powerbase1 = powerlevel[i];
powerbase1 = (powerbase1 << 24) | (powerbase1 << 16) |
(powerbase1 << 8) | powerbase1;
*(mcsbase + i) = powerbase1;
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
" [MCS power base index rf(%c) = 0x%x]\n",
i == 0 ? 'A' : 'B', *(mcsbase + i));
}
}
static u8 _rtl92d_phy_get_chnlgroup_bypg(u8 chnlindex)
{
u8 group;
u8 channel_info[59] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
114, 116, 118, 120, 122, 124, 126, 128, 130, 132,
134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
161, 163, 165
};
if (channel_info[chnlindex] <= 3) /* Chanel 1-3 */
group = 0;
else if (channel_info[chnlindex] <= 9) /* Channel 4-9 */
group = 1;
else if (channel_info[chnlindex] <= 14) /* Channel 10-14 */
group = 2;
else if (channel_info[chnlindex] <= 64)
group = 6;
else if (channel_info[chnlindex] <= 140)
group = 7;
else
group = 8;
return group;
}
static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
u8 channel, u8 index,
u32 *powerbase0,
u32 *powerbase1,
u32 *p_outwriteval)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
u8 i, chnlgroup = 0, pwr_diff_limit[4];
u32 writeval = 0, customer_limit, rf;
for (rf = 0; rf < 2; rf++) {
switch (rtlefuse->eeprom_regulatory) {
case 0:
chnlgroup = 0;
writeval = rtlphy->mcs_offset
[chnlgroup][index +
(rf ? 8 : 0)] + ((index < 2) ?
powerbase0[rf] :
powerbase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"RTK better performance, writeval(%c) = 0x%x\n",
rf == 0 ? 'A' : 'B', writeval);
break;
case 1:
if (rtlphy->pwrgroup_cnt == 1)
chnlgroup = 0;
if (rtlphy->pwrgroup_cnt >= MAX_PG_GROUP) {
chnlgroup = _rtl92d_phy_get_chnlgroup_bypg(
channel - 1);
if (rtlphy->current_chan_bw ==
HT_CHANNEL_WIDTH_20)
chnlgroup++;
else
chnlgroup += 4;
writeval = rtlphy->mcs_offset
[chnlgroup][index +
(rf ? 8 : 0)] + ((index < 2) ?
powerbase0[rf] :
powerbase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"Realtek regulatory, 20MHz, writeval(%c) = 0x%x\n",
rf == 0 ? 'A' : 'B', writeval);
}
break;
case 2:
writeval = ((index < 2) ? powerbase0[rf] :
powerbase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"Better regulatory, writeval(%c) = 0x%x\n",
rf == 0 ? 'A' : 'B', writeval);
break;
case 3:
chnlgroup = 0;
if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"customer's limit, 40MHz rf(%c) = 0x%x\n",
rf == 0 ? 'A' : 'B',
rtlefuse->pwrgroup_ht40[rf]
[channel - 1]);
} else {
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"customer's limit, 20MHz rf(%c) = 0x%x\n",
rf == 0 ? 'A' : 'B',
rtlefuse->pwrgroup_ht20[rf]
[channel - 1]);
}
for (i = 0; i < 4; i++) {
pwr_diff_limit[i] = (u8)((rtlphy->mcs_offset
[chnlgroup][index + (rf ? 8 : 0)] &
(0x7f << (i * 8))) >> (i * 8));
if (rtlphy->current_chan_bw ==
HT_CHANNEL_WIDTH_20_40) {
if (pwr_diff_limit[i] >
rtlefuse->pwrgroup_ht40[rf]
[channel - 1])
pwr_diff_limit[i] =
rtlefuse->pwrgroup_ht40
[rf][channel - 1];
} else {
if (pwr_diff_limit[i] >
rtlefuse->pwrgroup_ht20[rf][
channel - 1])
pwr_diff_limit[i] =
rtlefuse->pwrgroup_ht20[rf]
[channel - 1];
}
}
customer_limit = (pwr_diff_limit[3] << 24) |
(pwr_diff_limit[2] << 16) |
(pwr_diff_limit[1] << 8) |
(pwr_diff_limit[0]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"Customer's limit rf(%c) = 0x%x\n",
rf == 0 ? 'A' : 'B', customer_limit);
writeval = customer_limit + ((index < 2) ?
powerbase0[rf] : powerbase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"Customer, writeval rf(%c)= 0x%x\n",
rf == 0 ? 'A' : 'B', writeval);
break;
default:
chnlgroup = 0;
writeval = rtlphy->mcs_offset[chnlgroup][index +
(rf ? 8 : 0)] + ((index < 2) ?
powerbase0[rf] : powerbase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"RTK better performance, writeval rf(%c) = 0x%x\n",
rf == 0 ? 'A' : 'B', writeval);
break;
}
*(p_outwriteval + rf) = writeval;
}
}
static void _rtl92d_write_ofdm_power_reg(struct ieee80211_hw *hw,
u8 index, u32 *pvalue)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
static u16 regoffset_a[6] = {
RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24,
RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
};
static u16 regoffset_b[6] = {
RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24,
RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
};
u8 i, rf, pwr_val[4];
u32 writeval;
u16 regoffset;
for (rf = 0; rf < 2; rf++) {
writeval = pvalue[rf];
for (i = 0; i < 4; i++) {
pwr_val[i] = (u8) ((writeval & (0x7f <<
(i * 8))) >> (i * 8));
if (pwr_val[i] > RF6052_MAX_TX_PWR)
pwr_val[i] = RF6052_MAX_TX_PWR;
}
writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) |
(pwr_val[1] << 8) | pwr_val[0];
if (rf == 0)
regoffset = regoffset_a[index];
else
regoffset = regoffset_b[index];
rtl_set_bbreg(hw, regoffset, MASKDWORD, writeval);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"Set 0x%x = %08x\n", regoffset, writeval);
if (((get_rf_type(rtlphy) == RF_2T2R) &&
(regoffset == RTXAGC_A_MCS15_MCS12 ||
regoffset == RTXAGC_B_MCS15_MCS12)) ||
((get_rf_type(rtlphy) != RF_2T2R) &&
(regoffset == RTXAGC_A_MCS07_MCS04 ||
regoffset == RTXAGC_B_MCS07_MCS04))) {
writeval = pwr_val[3];
if (regoffset == RTXAGC_A_MCS15_MCS12 ||
regoffset == RTXAGC_A_MCS07_MCS04)
regoffset = 0xc90;
if (regoffset == RTXAGC_B_MCS15_MCS12 ||
regoffset == RTXAGC_B_MCS07_MCS04)
regoffset = 0xc98;
for (i = 0; i < 3; i++) {
if (i != 2)
writeval = (writeval > 8) ?
(writeval - 8) : 0;
else
writeval = (writeval > 6) ?
(writeval - 6) : 0;
rtl_write_byte(rtlpriv, (u32) (regoffset + i),
(u8) writeval);
}
}
}
}
void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
u8 *ppowerlevel, u8 channel)
{
u32 writeval[2], powerbase0[2], powerbase1[2];
u8 index;
_rtl92d_phy_get_power_base(hw, ppowerlevel, channel,
&powerbase0[0], &powerbase1[0]);
for (index = 0; index < 6; index++) {
_rtl92d_get_txpower_writeval_by_regulatory(hw,
channel, index, &powerbase0[0],
&powerbase1[0], &writeval[0]);
_rtl92d_write_ofdm_power_reg(hw, index, &writeval[0]);
}
}
bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
u8 u1btmp;
u8 direct = bmac0 ? BIT(3) | BIT(2) : BIT(3);
u8 mac_reg = bmac0 ? REG_MAC1 : REG_MAC0;
u8 mac_on_bit = bmac0 ? MAC1_ON : MAC0_ON;
bool bresult = true; /* true: need to enable BB/RF power */
rtlhal->during_mac0init_radiob = false;
rtlhal->during_mac1init_radioa = false;
RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "===>\n");
/* MAC0 Need PHY1 load radio_b.txt . Driver use DBI to write. */
u1btmp = rtl_read_byte(rtlpriv, mac_reg);
if (!(u1btmp & mac_on_bit)) {
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "enable BB & RF\n");
/* Enable BB and RF power */
rtl92de_write_dword_dbi(hw, REG_SYS_ISO_CTRL,
rtl92de_read_dword_dbi(hw, REG_SYS_ISO_CTRL, direct) |
BIT(29) | BIT(16) | BIT(17), direct);
} else {
/* We think if MAC1 is ON,then radio_a.txt
* and radio_b.txt has been load. */
bresult = false;
}
RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<===\n");
return bresult;
}
void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
u8 u1btmp;
u8 direct = bmac0 ? BIT(3) | BIT(2) : BIT(3);
u8 mac_reg = bmac0 ? REG_MAC1 : REG_MAC0;
u8 mac_on_bit = bmac0 ? MAC1_ON : MAC0_ON;
rtlhal->during_mac0init_radiob = false;
rtlhal->during_mac1init_radioa = false;
RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "====>\n");
/* check MAC0 enable or not again now, if
* enabled, not power down radio A. */
u1btmp = rtl_read_byte(rtlpriv, mac_reg);
if (!(u1btmp & mac_on_bit)) {
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "power down\n");
/* power down RF radio A according to YuNan's advice. */
rtl92de_write_dword_dbi(hw, RFPGA0_XA_LSSIPARAMETER,
0x00000000, direct);
}
RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<====\n");
}
bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
bool rtstatus = true;
struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
u32 u4_regvalue = 0;
u8 rfpath;
struct bb_reg_def *pphyreg;
bool mac1_initradioa_first = false, mac0_initradiob_first = false;
bool need_pwrdown_radioa = false, need_pwrdown_radiob = false;
bool true_bpath = false;
if (rtlphy->rf_type == RF_1T1R)
rtlphy->num_total_rfpath = 1;
else
rtlphy->num_total_rfpath = 2;
/* Single phy mode: use radio_a radio_b config path_A path_B */
/* seperately by MAC0, and MAC1 needn't configure RF; */
/* Dual PHY mode:MAC0 use radio_a config 1st phy path_A, */
/* MAC1 use radio_b config 2nd PHY path_A. */
/* DMDP,MAC0 on G band,MAC1 on A band. */
if (rtlhal->macphymode == DUALMAC_DUALPHY) {
if (rtlhal->current_bandtype == BAND_ON_2_4G &&
rtlhal->interfaceindex == 0) {
/* MAC0 needs PHY1 load radio_b.txt.
* Driver use DBI to write. */
if (rtl92d_phy_enable_anotherphy(hw, true)) {
rtlphy->num_total_rfpath = 2;
mac0_initradiob_first = true;
} else {
/* We think if MAC1 is ON,then radio_a.txt and
* radio_b.txt has been load. */
return rtstatus;
}
} else if (rtlhal->current_bandtype == BAND_ON_5G &&
rtlhal->interfaceindex == 1) {
/* MAC1 needs PHY0 load radio_a.txt.
* Driver use DBI to write. */
if (rtl92d_phy_enable_anotherphy(hw, false)) {
rtlphy->num_total_rfpath = 2;
mac1_initradioa_first = true;
} else {
/* We think if MAC0 is ON,then radio_a.txt and
* radio_b.txt has been load. */
return rtstatus;
}
} else if (rtlhal->interfaceindex == 1) {
/* MAC0 enabled, only init radia B. */
true_bpath = true;
}
}
for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
/* Mac1 use PHY0 write */
if (mac1_initradioa_first) {
if (rfpath == RF90_PATH_A) {
rtlhal->during_mac1init_radioa = true;
need_pwrdown_radioa = true;
} else if (rfpath == RF90_PATH_B) {
rtlhal->during_mac1init_radioa = false;
mac1_initradioa_first = false;
rfpath = RF90_PATH_A;
true_bpath = true;
rtlphy->num_total_rfpath = 1;
}
} else if (mac0_initradiob_first) {
/* Mac0 use PHY1 write */
if (rfpath == RF90_PATH_A)
rtlhal->during_mac0init_radiob = false;
if (rfpath == RF90_PATH_B) {
rtlhal->during_mac0init_radiob = true;
mac0_initradiob_first = false;
need_pwrdown_radiob = true;
rfpath = RF90_PATH_A;
true_bpath = true;
rtlphy->num_total_rfpath = 1;
}
}
pphyreg = &rtlphy->phyreg_def[rfpath];
switch (rfpath) {
case RF90_PATH_A:
case RF90_PATH_C:
u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
BRFSI_RFENV);
break;
case RF90_PATH_B:
case RF90_PATH_D:
u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
BRFSI_RFENV << 16);
break;
}
rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
udelay(1);
rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
udelay(1);
/* Set bit number of Address and Data for RF register */
/* Set 1 to 4 bits for 8255 */
rtl_set_bbreg(hw, pphyreg->rfhssi_para2,
B3WIREADDRESSLENGTH, 0x0);
udelay(1);
/* Set 0 to 12 bits for 8255 */
rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
udelay(1);
switch (rfpath) {
case RF90_PATH_A:
if (true_bpath)
rtstatus = rtl92d_phy_config_rf_with_headerfile(
hw, radiob_txt,
(enum radio_path)rfpath);
else
rtstatus = rtl92d_phy_config_rf_with_headerfile(
hw, radioa_txt,
(enum radio_path)rfpath);
break;
case RF90_PATH_B:
rtstatus =
rtl92d_phy_config_rf_with_headerfile(hw, radiob_txt,
(enum radio_path) rfpath);
break;
case RF90_PATH_C:
break;
case RF90_PATH_D:
break;
}
switch (rfpath) {
case RF90_PATH_A:
case RF90_PATH_C:
rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV,
u4_regvalue);
break;
case RF90_PATH_B:
case RF90_PATH_D:
rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16,
u4_regvalue);
break;
}
if (!rtstatus) {
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"Radio[%d] Fail!!", rfpath);
goto phy_rf_cfg_fail;
}
}
/* check MAC0 enable or not again, if enabled,
* not power down radio A. */
/* check MAC1 enable or not again, if enabled,
* not power down radio B. */
if (need_pwrdown_radioa)
rtl92d_phy_powerdown_anotherphy(hw, false);
else if (need_pwrdown_radiob)
rtl92d_phy_powerdown_anotherphy(hw, true);
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n");
return rtstatus;
phy_rf_cfg_fail:
return rtstatus;
}

Melihat File

@@ -0,0 +1,42 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* 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 __RTL92D_RF_H__
#define __RTL92D_RF_H__
void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth);
void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
u8 *ppowerlevel);
void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
u8 *ppowerlevel, u8 channel);
bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw);
bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0);
void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0);
#endif

Melihat File

@@ -0,0 +1,419 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* 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 "dm.h"
#include "hw.h"
#include "sw.h"
#include "trx.h"
#include "led.h"
#include <linux/module.h>
static void rtl92d_init_aspm_vars(struct ieee80211_hw *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 defult to RTL8192CE:3 RTL8192E: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 RTL8192CE: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 = 1;
}
static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
{
int err;
u8 tid;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
rtlpriv->dm.dm_initialgain_enable = true;
rtlpriv->dm.dm_flag = 0;
rtlpriv->dm.disable_framebursting = false;
rtlpriv->dm.thermalvalue = 0;
rtlpriv->dm.useramask = true;
/* dual mac */
if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G)
rtlpriv->phy.current_channel = 36;
else
rtlpriv->phy.current_channel = 1;
if (rtlpriv->rtlhal.macphymode != SINGLEMAC_SINGLEPHY) {
rtlpriv->rtlhal.disable_amsdu_8k = true;
/* No long RX - reduce fragmentation */
rtlpci->rxbuffersize = 4096;
}
rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13);
rtlpci->receive_config = (
RCR_APPFCS
| RCR_AMF
| RCR_ADF
| RCR_APP_MIC
| RCR_APP_ICV
| RCR_AICV
| RCR_ACRC32
| RCR_AB
| RCR_AM
| RCR_APM
| RCR_APP_PHYST_RXFF
| RCR_HTC_LOC_CTRL
);
rtlpci->irq_mask[0] = (u32) (
IMR_ROK
| IMR_VODOK
| IMR_VIDOK
| IMR_BEDOK
| IMR_BKDOK
| IMR_MGNTDOK
| IMR_HIGHDOK
| IMR_BDOK
| IMR_RDU
| IMR_RXFOVW
);
rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD);
/* for debug level */
rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
/* 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;
if (!rtlpriv->psc.inactiveps)
pr_info("Power Save off (module option)\n");
if (!rtlpriv->psc.fwctrl_lps)
pr_info("FW Power Save off (module option)\n");
rtlpriv->psc.reg_fwctrl_lps = 3;
rtlpriv->psc.reg_max_lps_awakeintvl = 5;
/* for ASPM, you can close aspm through
* set const_support_pciaspm = 0 */
rtl92d_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;
for (tid = 0; tid < 8; tid++)
skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]);
/* for firmware buf */
rtlpriv->rtlhal.pfirmware = vzalloc(0x8000);
if (!rtlpriv->rtlhal.pfirmware) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Can't alloc buffer for fw\n");
return 1;
}
rtlpriv->max_fw_size = 0x8000;
pr_info("Driver for Realtek RTL8192DE WLAN interface\n");
pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
/* request fw */
err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
rtlpriv->io.dev, GFP_KERNEL, hw,
rtl_fw_cb);
if (err) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Failed to request firmware!\n");
return 1;
}
return 0;
}
static void rtl92d_deinit_sw_vars(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 tid;
if (rtlpriv->rtlhal.pfirmware) {
vfree(rtlpriv->rtlhal.pfirmware);
rtlpriv->rtlhal.pfirmware = NULL;
}
for (tid = 0; tid < 8; tid++)
skb_queue_purge(&rtlpriv->mac80211.skb_waitq[tid]);
}
static struct rtl_hal_ops rtl8192de_hal_ops = {
.init_sw_vars = rtl92d_init_sw_vars,
.deinit_sw_vars = rtl92d_deinit_sw_vars,
.read_eeprom_info = rtl92de_read_eeprom_info,
.interrupt_recognized = rtl92de_interrupt_recognized,
.hw_init = rtl92de_hw_init,
.hw_disable = rtl92de_card_disable,
.hw_suspend = rtl92de_suspend,
.hw_resume = rtl92de_resume,
.enable_interrupt = rtl92de_enable_interrupt,
.disable_interrupt = rtl92de_disable_interrupt,
.set_network_type = rtl92de_set_network_type,
.set_chk_bssid = rtl92de_set_check_bssid,
.set_qos = rtl92de_set_qos,
.set_bcn_reg = rtl92de_set_beacon_related_registers,
.set_bcn_intv = rtl92de_set_beacon_interval,
.update_interrupt_mask = rtl92de_update_interrupt_mask,
.get_hw_reg = rtl92de_get_hw_reg,
.set_hw_reg = rtl92de_set_hw_reg,
.update_rate_tbl = rtl92de_update_hal_rate_tbl,
.fill_tx_desc = rtl92de_tx_fill_desc,
.fill_tx_cmddesc = rtl92de_tx_fill_cmddesc,
.query_rx_desc = rtl92de_rx_query_desc,
.set_channel_access = rtl92de_update_channel_access_setting,
.radio_onoff_checking = rtl92de_gpio_radio_on_off_checking,
.set_bw_mode = rtl92d_phy_set_bw_mode,
.switch_channel = rtl92d_phy_sw_chnl,
.dm_watchdog = rtl92d_dm_watchdog,
.scan_operation_backup = rtl_phy_scan_operation_backup,
.set_rf_power_state = rtl92d_phy_set_rf_power_state,
.led_control = rtl92de_led_control,
.set_desc = rtl92de_set_desc,
.get_desc = rtl92de_get_desc,
.tx_polling = rtl92de_tx_polling,
.enable_hw_sec = rtl92de_enable_hw_security_config,
.set_key = rtl92de_set_key,
.init_sw_leds = rtl92de_init_sw_leds,
.get_bbreg = rtl92d_phy_query_bb_reg,
.set_bbreg = rtl92d_phy_set_bb_reg,
.get_rfreg = rtl92d_phy_query_rf_reg,
.set_rfreg = rtl92d_phy_set_rf_reg,
.linked_set_reg = rtl92d_linked_set_reg,
.get_btc_status = rtl_btc_status_false,
};
static struct rtl_mod_params rtl92de_mod_params = {
.sw_crypto = false,
.inactiveps = true,
.swctrl_lps = true,
.fwctrl_lps = false,
.debug = DBG_EMERG,
};
static struct rtl_hal_cfg rtl92de_hal_cfg = {
.bar_id = 2,
.write_readback = true,
.name = "rtl8192de",
.fw_name = "rtlwifi/rtl8192defw.bin",
.ops = &rtl8192de_hal_ops,
.mod_params = &rtl92de_mod_params,
.maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
.maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
.maps[SYS_CLK] = REG_SYS_CLKR,
.maps[MAC_RCR_AM] = RCR_AM,
.maps[MAC_RCR_AB] = RCR_AB,
.maps[MAC_RCR_ACRC32] = RCR_ACRC32,
.maps[MAC_RCR_ACF] = RCR_ACF,
.maps[MAC_RCR_AAP] = RCR_AAP,
.maps[EFUSE_TEST] = REG_EFUSE_TEST,
.maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
.maps[EFUSE_CLK] = 0, /* just for 92se */
.maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL,
.maps[EFUSE_PWC_EV12V] = PWC_EV12V,
.maps[EFUSE_FEN_ELDR] = FEN_ELDR,
.maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,
.maps[EFUSE_ANA8M] = 0, /* just for 92se */
.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[RWCAM] = REG_CAMCMD,
.maps[WCAMI] = REG_CAMWRITE,
.maps[RCAMO] = REG_CAMREAD,
.maps[CAMDBG] = REG_CAMDBG,
.maps[SECR] = REG_SECCFG,
.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,
.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_BCNINT,
.maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
.maps[RTL_IMR_RDU] = IMR_RDU,
.maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
.maps[RTL_IMR_BDOK] = IMR_BDOK,
.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_BCNINT | 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,
};
static struct pci_device_id rtl92de_pci_ids[] = {
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8193, rtl92de_hal_cfg)},
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x002B, rtl92de_hal_cfg)},
{},
};
MODULE_DEVICE_TABLE(pci, rtl92de_pci_ids);
MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek 8192DE 802.11n Dual Mac PCI wireless");
MODULE_FIRMWARE("rtlwifi/rtl8192defw.bin");
module_param_named(swenc, rtl92de_mod_params.sw_crypto, bool, 0444);
module_param_named(debug, rtl92de_mod_params.debug, int, 0444);
module_param_named(ips, rtl92de_mod_params.inactiveps, bool, 0444);
module_param_named(swlps, rtl92de_mod_params.swctrl_lps, bool, 0444);
module_param_named(fwlps, rtl92de_mod_params.fwctrl_lps, 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(debug, "Set debug level (0-5) (default 0)");
static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
static struct pci_driver rtl92de_driver = {
.name = KBUILD_MODNAME,
.id_table = rtl92de_pci_ids,
.probe = rtl_pci_probe,
.remove = rtl_pci_disconnect,
.driver.pm = &rtlwifi_pm_ops,
};
/* add global spin lock to solve the problem that
* Dul mac register operation on the same time */
spinlock_t globalmutex_power;
spinlock_t globalmutex_for_fwdownload;
spinlock_t globalmutex_for_power_and_efuse;
static int __init rtl92de_module_init(void)
{
int ret = 0;
spin_lock_init(&globalmutex_power);
spin_lock_init(&globalmutex_for_fwdownload);
spin_lock_init(&globalmutex_for_power_and_efuse);
ret = pci_register_driver(&rtl92de_driver);
if (ret)
RT_ASSERT(false, "No device found\n");
return ret;
}
static void __exit rtl92de_module_exit(void)
{
pci_unregister_driver(&rtl92de_driver);
}
module_init(rtl92de_module_init);
module_exit(rtl92de_module_exit);

Melihat File

@@ -0,0 +1,37 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* 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 __RTL92DE_SW_H__
#define __RTL92DE_SW_H__
extern spinlock_t globalmutex_power;
extern spinlock_t globalmutex_for_fwdownload;
extern spinlock_t globalmutex_for_power_and_efuse;
#endif

File diff ditekan karena terlalu besar Load Diff

Melihat File

@@ -0,0 +1,57 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* 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>
*
* Created on 2010/ 5/18, 1:41
*****************************************************************************/
#ifndef __RTL92DE_TABLE__H_
#define __RTL92DE_TABLE__H_
/*Created on 2011/ 1/14, 1:35*/
#define PHY_REG_2T_ARRAYLENGTH 380
extern u32 rtl8192de_phy_reg_2tarray[PHY_REG_2T_ARRAYLENGTH];
#define PHY_REG_ARRAY_PG_LENGTH 624
extern u32 rtl8192de_phy_reg_array_pg[PHY_REG_ARRAY_PG_LENGTH];
#define RADIOA_2T_ARRAYLENGTH 378
extern u32 rtl8192de_radioa_2tarray[RADIOA_2T_ARRAYLENGTH];
#define RADIOB_2T_ARRAYLENGTH 384
extern u32 rtl8192de_radiob_2tarray[RADIOB_2T_ARRAYLENGTH];
#define RADIOA_2T_INT_PA_ARRAYLENGTH 378
extern u32 rtl8192de_radioa_2t_int_paarray[RADIOA_2T_INT_PA_ARRAYLENGTH];
#define RADIOB_2T_INT_PA_ARRAYLENGTH 384
extern u32 rtl8192de_radiob_2t_int_paarray[RADIOB_2T_INT_PA_ARRAYLENGTH];
#define MAC_2T_ARRAYLENGTH 160
extern u32 rtl8192de_mac_2tarray[MAC_2T_ARRAYLENGTH];
#define AGCTAB_ARRAYLENGTH 386
extern u32 rtl8192de_agctab_array[AGCTAB_ARRAYLENGTH];
#define AGCTAB_5G_ARRAYLENGTH 194
extern u32 rtl8192de_agctab_5garray[AGCTAB_5G_ARRAYLENGTH];
#define AGCTAB_2G_ARRAYLENGTH 194
extern u32 rtl8192de_agctab_2garray[AGCTAB_2G_ARRAYLENGTH];
#endif

Melihat File

@@ -0,0 +1,871 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* 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 "phy.h"
#include "trx.h"
#include "led.h"
static u8 _rtl92de_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
{
__le16 fc = rtl_get_fc(skb);
if (unlikely(ieee80211_is_beacon(fc)))
return QSLT_BEACON;
if (ieee80211_is_mgmt(fc))
return QSLT_MGNT;
return skb->priority;
}
static u8 _rtl92d_query_rxpwrpercentage(char antpower)
{
if ((antpower <= -100) || (antpower >= 20))
return 0;
else if (antpower >= 0)
return 100;
else
return 100 + antpower;
}
static u8 _rtl92d_evm_db_to_percentage(char value)
{
char ret_val = value;
if (ret_val >= 0)
ret_val = 0;
if (ret_val <= -33)
ret_val = -33;
ret_val = 0 - ret_val;
ret_val *= 3;
if (ret_val == 99)
ret_val = 100;
return ret_val;
}
static long _rtl92de_translate_todbm(struct ieee80211_hw *hw,
u8 signal_strength_index)
{
long signal_power;
signal_power = (long)((signal_strength_index + 1) >> 1);
signal_power -= 95;
return signal_power;
}
static long _rtl92de_signal_scale_mapping(struct ieee80211_hw *hw, long currsig)
{
long retsig;
if (currsig >= 61 && currsig <= 100)
retsig = 90 + ((currsig - 60) / 4);
else if (currsig >= 41 && currsig <= 60)
retsig = 78 + ((currsig - 40) / 2);
else if (currsig >= 31 && currsig <= 40)
retsig = 66 + (currsig - 30);
else if (currsig >= 21 && currsig <= 30)
retsig = 54 + (currsig - 20);
else if (currsig >= 5 && currsig <= 20)
retsig = 42 + (((currsig - 5) * 2) / 3);
else if (currsig == 4)
retsig = 36;
else if (currsig == 3)
retsig = 27;
else if (currsig == 2)
retsig = 18;
else if (currsig == 1)
retsig = 9;
else
retsig = currsig;
return retsig;
}
static void _rtl92de_query_rxphystatus(struct ieee80211_hw *hw,
struct rtl_stats *pstats,
struct rx_desc_92d *pdesc,
struct rx_fwinfo_92d *p_drvinfo,
bool packet_match_bssid,
bool packet_toself,
bool packet_beacon)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
struct phy_sts_cck_8192d *cck_buf;
s8 rx_pwr_all, rx_pwr[4];
u8 rf_rx_num = 0, evm, pwdb_all;
u8 i, max_spatial_stream;
u32 rssi, total_rssi = 0;
bool is_cck_rate;
is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc->rxmcs);
pstats->packet_matchbssid = packet_match_bssid;
pstats->packet_toself = packet_toself;
pstats->packet_beacon = packet_beacon;
pstats->is_cck = is_cck_rate;
pstats->rx_mimo_sig_qual[0] = -1;
pstats->rx_mimo_sig_qual[1] = -1;
if (is_cck_rate) {
u8 report, cck_highpwr;
cck_buf = (struct phy_sts_cck_8192d *)p_drvinfo;
if (ppsc->rfpwr_state == ERFON)
cck_highpwr = (u8) rtl_get_bbreg(hw,
RFPGA0_XA_HSSIPARAMETER2,
BIT(9));
else
cck_highpwr = false;
if (!cck_highpwr) {
u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
report = cck_buf->cck_agc_rpt & 0xc0;
report = report >> 6;
switch (report) {
case 0x3:
rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
break;
case 0x2:
rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
break;
case 0x1:
rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
break;
case 0x0:
rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
break;
}
} else {
u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
report = p_drvinfo->cfosho[0] & 0x60;
report = report >> 5;
switch (report) {
case 0x3:
rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1);
break;
case 0x2:
rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1);
break;
case 0x1:
rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1);
break;
case 0x0:
rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1);
break;
}
}
pwdb_all = _rtl92d_query_rxpwrpercentage(rx_pwr_all);
/* CCK gain is smaller than OFDM/MCS gain, */
/* so we add gain diff by experiences, the val is 6 */
pwdb_all += 6;
if (pwdb_all > 100)
pwdb_all = 100;
/* modify the offset to make the same gain index with OFDM. */
if (pwdb_all > 34 && pwdb_all <= 42)
pwdb_all -= 2;
else if (pwdb_all > 26 && pwdb_all <= 34)
pwdb_all -= 6;
else if (pwdb_all > 14 && pwdb_all <= 26)
pwdb_all -= 8;
else if (pwdb_all > 4 && pwdb_all <= 14)
pwdb_all -= 4;
pstats->rx_pwdb_all = pwdb_all;
pstats->recvsignalpower = rx_pwr_all;
if (packet_match_bssid) {
u8 sq;
if (pstats->rx_pwdb_all > 40) {
sq = 100;
} else {
sq = cck_buf->sq_rpt;
if (sq > 64)
sq = 0;
else if (sq < 20)
sq = 100;
else
sq = ((64 - sq) * 100) / 44;
}
pstats->signalquality = sq;
pstats->rx_mimo_sig_qual[0] = sq;
pstats->rx_mimo_sig_qual[1] = -1;
}
} else {
rtlpriv->dm.rfpath_rxenable[0] = true;
rtlpriv->dm.rfpath_rxenable[1] = true;
for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) {
if (rtlpriv->dm.rfpath_rxenable[i])
rf_rx_num++;
rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & 0x3f) * 2)
- 110;
rssi = _rtl92d_query_rxpwrpercentage(rx_pwr[i]);
total_rssi += rssi;
rtlpriv->stats.rx_snr_db[i] =
(long)(p_drvinfo->rxsnr[i] / 2);
if (packet_match_bssid)
pstats->rx_mimo_signalstrength[i] = (u8) rssi;
}
rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 106;
pwdb_all = _rtl92d_query_rxpwrpercentage(rx_pwr_all);
pstats->rx_pwdb_all = pwdb_all;
pstats->rxpower = rx_pwr_all;
pstats->recvsignalpower = rx_pwr_all;
if (pdesc->rxht && pdesc->rxmcs >= DESC_RATEMCS8 &&
pdesc->rxmcs <= DESC_RATEMCS15)
max_spatial_stream = 2;
else
max_spatial_stream = 1;
for (i = 0; i < max_spatial_stream; i++) {
evm = _rtl92d_evm_db_to_percentage(p_drvinfo->rxevm[i]);
if (packet_match_bssid) {
if (i == 0)
pstats->signalquality =
(u8)(evm & 0xff);
pstats->rx_mimo_sig_qual[i] =
(u8)(evm & 0xff);
}
}
}
if (is_cck_rate)
pstats->signalstrength = (u8)(_rtl92de_signal_scale_mapping(hw,
pwdb_all));
else if (rf_rx_num != 0)
pstats->signalstrength = (u8)(_rtl92de_signal_scale_mapping(hw,
total_rssi /= rf_rx_num));
}
static void rtl92d_loop_over_paths(struct ieee80211_hw *hw,
struct rtl_stats *pstats)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
u8 rfpath;
for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
rfpath++) {
if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
rtlpriv->stats.rx_rssi_percentage[rfpath] =
pstats->rx_mimo_signalstrength[rfpath];
}
if (pstats->rx_mimo_signalstrength[rfpath] >
rtlpriv->stats.rx_rssi_percentage[rfpath]) {
rtlpriv->stats.rx_rssi_percentage[rfpath] =
((rtlpriv->stats.rx_rssi_percentage[rfpath] *
(RX_SMOOTH_FACTOR - 1)) +
(pstats->rx_mimo_signalstrength[rfpath])) /
(RX_SMOOTH_FACTOR);
rtlpriv->stats.rx_rssi_percentage[rfpath] =
rtlpriv->stats.rx_rssi_percentage[rfpath] + 1;
} else {
rtlpriv->stats.rx_rssi_percentage[rfpath] =
((rtlpriv->stats.rx_rssi_percentage[rfpath] *
(RX_SMOOTH_FACTOR - 1)) +
(pstats->rx_mimo_signalstrength[rfpath])) /
(RX_SMOOTH_FACTOR);
}
}
}
static void _rtl92de_process_ui_rssi(struct ieee80211_hw *hw,
struct rtl_stats *pstats)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 last_rssi, tmpval;
if (pstats->packet_toself || pstats->packet_beacon) {
rtlpriv->stats.rssi_calculate_cnt++;
if (rtlpriv->stats.ui_rssi.total_num++ >=
PHY_RSSI_SLID_WIN_MAX) {
rtlpriv->stats.ui_rssi.total_num =
PHY_RSSI_SLID_WIN_MAX;
last_rssi = rtlpriv->stats.ui_rssi.elements[
rtlpriv->stats.ui_rssi.index];
rtlpriv->stats.ui_rssi.total_val -= last_rssi;
}
rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength;
rtlpriv->stats.ui_rssi.elements
[rtlpriv->stats.ui_rssi.index++] =
pstats->signalstrength;
if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
rtlpriv->stats.ui_rssi.index = 0;
tmpval = rtlpriv->stats.ui_rssi.total_val /
rtlpriv->stats.ui_rssi.total_num;
rtlpriv->stats.signal_strength = _rtl92de_translate_todbm(hw,
(u8) tmpval);
pstats->rssi = rtlpriv->stats.signal_strength;
}
if (!pstats->is_cck && pstats->packet_toself)
rtl92d_loop_over_paths(hw, pstats);
}
static void _rtl92de_update_rxsignalstatistics(struct ieee80211_hw *hw,
struct rtl_stats *pstats)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
int weighting = 0;
if (rtlpriv->stats.recv_signal_power == 0)
rtlpriv->stats.recv_signal_power = pstats->recvsignalpower;
if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power)
weighting = 5;
else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power)
weighting = (-5);
rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power *
5 + pstats->recvsignalpower + weighting) / 6;
}
static void _rtl92de_process_pwdb(struct ieee80211_hw *hw,
struct rtl_stats *pstats)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
long undec_sm_pwdb;
if (mac->opmode == NL80211_IFTYPE_ADHOC ||
mac->opmode == NL80211_IFTYPE_AP)
return;
else
undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
if (pstats->packet_toself || pstats->packet_beacon) {
if (undec_sm_pwdb < 0)
undec_sm_pwdb = pstats->rx_pwdb_all;
if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) {
undec_sm_pwdb = (((undec_sm_pwdb) *
(RX_SMOOTH_FACTOR - 1)) +
(pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
undec_sm_pwdb = undec_sm_pwdb + 1;
} else {
undec_sm_pwdb = (((undec_sm_pwdb) *
(RX_SMOOTH_FACTOR - 1)) +
(pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
}
rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb;
_rtl92de_update_rxsignalstatistics(hw, pstats);
}
}
static void rtl92d_loop_over_streams(struct ieee80211_hw *hw,
struct rtl_stats *pstats)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
int stream;
for (stream = 0; stream < 2; stream++) {
if (pstats->rx_mimo_sig_qual[stream] != -1) {
if (rtlpriv->stats.rx_evm_percentage[stream] == 0) {
rtlpriv->stats.rx_evm_percentage[stream] =
pstats->rx_mimo_sig_qual[stream];
}
rtlpriv->stats.rx_evm_percentage[stream] =
((rtlpriv->stats.rx_evm_percentage[stream]
* (RX_SMOOTH_FACTOR - 1)) +
(pstats->rx_mimo_sig_qual[stream] * 1)) /
(RX_SMOOTH_FACTOR);
}
}
}
static void _rtl92de_process_ui_link_quality(struct ieee80211_hw *hw,
struct rtl_stats *pstats)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 last_evm, tmpval;
if (pstats->signalquality == 0)
return;
if (pstats->packet_toself || pstats->packet_beacon) {
if (rtlpriv->stats.ui_link_quality.total_num++ >=
PHY_LINKQUALITY_SLID_WIN_MAX) {
rtlpriv->stats.ui_link_quality.total_num =
PHY_LINKQUALITY_SLID_WIN_MAX;
last_evm = rtlpriv->stats.ui_link_quality.elements[
rtlpriv->stats.ui_link_quality.index];
rtlpriv->stats.ui_link_quality.total_val -= last_evm;
}
rtlpriv->stats.ui_link_quality.total_val +=
pstats->signalquality;
rtlpriv->stats.ui_link_quality.elements[
rtlpriv->stats.ui_link_quality.index++] =
pstats->signalquality;
if (rtlpriv->stats.ui_link_quality.index >=
PHY_LINKQUALITY_SLID_WIN_MAX)
rtlpriv->stats.ui_link_quality.index = 0;
tmpval = rtlpriv->stats.ui_link_quality.total_val /
rtlpriv->stats.ui_link_quality.total_num;
rtlpriv->stats.signal_quality = tmpval;
rtlpriv->stats.last_sigstrength_inpercent = tmpval;
rtl92d_loop_over_streams(hw, pstats);
}
}
static void _rtl92de_process_phyinfo(struct ieee80211_hw *hw,
u8 *buffer,
struct rtl_stats *pcurrent_stats)
{
if (!pcurrent_stats->packet_matchbssid &&
!pcurrent_stats->packet_beacon)
return;
_rtl92de_process_ui_rssi(hw, pcurrent_stats);
_rtl92de_process_pwdb(hw, pcurrent_stats);
_rtl92de_process_ui_link_quality(hw, pcurrent_stats);
}
static void _rtl92de_translate_rx_signal_stuff(struct ieee80211_hw *hw,
struct sk_buff *skb,
struct rtl_stats *pstats,
struct rx_desc_92d *pdesc,
struct rx_fwinfo_92d *p_drvinfo)
{
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
struct ieee80211_hdr *hdr;
u8 *tmp_buf;
u8 *praddr;
u16 type, cfc;
__le16 fc;
bool packet_matchbssid, packet_toself, packet_beacon = false;
tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
hdr = (struct ieee80211_hdr *)tmp_buf;
fc = hdr->frame_control;
cfc = le16_to_cpu(fc);
type = WLAN_FC_GET_TYPE(fc);
praddr = hdr->addr1;
packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
ether_addr_equal(mac->bssid,
(cfc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
(cfc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
hdr->addr3) &&
(!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
packet_toself = packet_matchbssid &&
ether_addr_equal(praddr, rtlefuse->dev_addr);
if (ieee80211_is_beacon(fc))
packet_beacon = true;
_rtl92de_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
packet_matchbssid, packet_toself,
packet_beacon);
_rtl92de_process_phyinfo(hw, tmp_buf, pstats);
}
bool rtl92de_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
struct ieee80211_rx_status *rx_status,
u8 *p_desc, struct sk_buff *skb)
{
struct rx_fwinfo_92d *p_drvinfo;
struct rx_desc_92d *pdesc = (struct rx_desc_92d *)p_desc;
u32 phystatus = GET_RX_DESC_PHYST(pdesc);
stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
RX_DRV_INFO_SIZE_UNIT;
stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
stats->icv = (u16) GET_RX_DESC_ICV(pdesc);
stats->crc = (u16) GET_RX_DESC_CRC32(pdesc);
stats->hwerror = (stats->crc | stats->icv);
stats->decrypted = !GET_RX_DESC_SWDEC(pdesc);
stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
stats->isfirst_ampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
&& (GET_RX_DESC_FAGGR(pdesc) == 1));
stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
stats->is_ht = (bool)GET_RX_DESC_RXHT(pdesc);
rx_status->freq = hw->conf.chandef.chan->center_freq;
rx_status->band = hw->conf.chandef.chan->band;
if (GET_RX_DESC_CRC32(pdesc))
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
if (!GET_RX_DESC_SWDEC(pdesc))
rx_status->flag |= RX_FLAG_DECRYPTED;
if (GET_RX_DESC_BW(pdesc))
rx_status->flag |= RX_FLAG_40MHZ;
if (GET_RX_DESC_RXHT(pdesc))
rx_status->flag |= RX_FLAG_HT;
rx_status->flag |= RX_FLAG_MACTIME_START;
if (stats->decrypted)
rx_status->flag |= RX_FLAG_DECRYPTED;
rx_status->rate_idx = rtlwifi_rate_mapping(hw, stats->is_ht,
false, stats->rate);
rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
if (phystatus) {
p_drvinfo = (struct rx_fwinfo_92d *)(skb->data +
stats->rx_bufshift);
_rtl92de_translate_rx_signal_stuff(hw,
skb, stats, pdesc,
p_drvinfo);
}
/*rx_status->qual = stats->signal; */
rx_status->signal = stats->recvsignalpower + 10;
return true;
}
static void _rtl92de_insert_emcontent(struct rtl_tcb_desc *ptcb_desc,
u8 *virtualaddress)
{
memset(virtualaddress, 0, 8);
SET_EARLYMODE_PKTNUM(virtualaddress, ptcb_desc->empkt_num);
SET_EARLYMODE_LEN0(virtualaddress, ptcb_desc->empkt_len[0]);
SET_EARLYMODE_LEN1(virtualaddress, ptcb_desc->empkt_len[1]);
SET_EARLYMODE_LEN2_1(virtualaddress, ptcb_desc->empkt_len[2] & 0xF);
SET_EARLYMODE_LEN2_2(virtualaddress, ptcb_desc->empkt_len[2] >> 4);
SET_EARLYMODE_LEN3(virtualaddress, ptcb_desc->empkt_len[3]);
SET_EARLYMODE_LEN4(virtualaddress, ptcb_desc->empkt_len[4]);
}
void rtl92de_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)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
u8 *pdesc = pdesc_tx;
u16 seq_number;
__le16 fc = hdr->frame_control;
unsigned int buf_len = 0;
unsigned int skb_len = skb->len;
u8 fw_qsel = _rtl92de_map_hwqueue_to_fwqueue(skb, hw_queue);
bool firstseg = ((hdr->seq_ctrl &
cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
bool lastseg = ((hdr->frame_control &
cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
dma_addr_t mapping;
u8 bw_40 = 0;
if (mac->opmode == NL80211_IFTYPE_STATION) {
bw_40 = mac->bw_40;
} else if (mac->opmode == NL80211_IFTYPE_AP ||
mac->opmode == NL80211_IFTYPE_ADHOC) {
if (sta)
bw_40 = sta->bandwidth >= IEEE80211_STA_RX_BW_40;
}
seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc);
/* reserve 8 byte for AMPDU early mode */
if (rtlhal->earlymode_enable) {
skb_push(skb, EM_HDR_LEN);
memset(skb->data, 0, EM_HDR_LEN);
}
buf_len = skb->len;
mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
PCI_DMA_TODEVICE);
if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
"DMA mapping error");
return;
}
CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92d));
if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
firstseg = true;
lastseg = true;
}
if (firstseg) {
if (rtlhal->earlymode_enable) {
SET_TX_DESC_PKT_OFFSET(pdesc, 1);
SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN +
EM_HDR_LEN);
if (ptcb_desc->empkt_num) {
RT_TRACE(rtlpriv, COMP_SEND, DBG_LOUD,
"Insert 8 byte.pTcb->EMPktNum:%d\n",
ptcb_desc->empkt_num);
_rtl92de_insert_emcontent(ptcb_desc,
(u8 *)(skb->data));
}
} else {
SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
}
/* 5G have no CCK rate */
if (rtlhal->current_bandtype == BAND_ON_5G)
if (ptcb_desc->hw_rate < DESC_RATE6M)
ptcb_desc->hw_rate = DESC_RATE6M;
SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble)
SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
if (rtlhal->macphymode == DUALMAC_DUALPHY &&
ptcb_desc->hw_rate == DESC_RATEMCS7)
SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
if (info->flags & IEEE80211_TX_CTL_AMPDU) {
SET_TX_DESC_AGG_ENABLE(pdesc, 1);
SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
}
SET_TX_DESC_SEQ(pdesc, seq_number);
SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable &&
!ptcb_desc->cts_enable) ? 1 : 0));
SET_TX_DESC_HW_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable
|| ptcb_desc->cts_enable) ? 1 : 0));
SET_TX_DESC_CTS2SELF(pdesc, ((ptcb_desc->cts_enable) ? 1 : 0));
SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0));
/* 5G have no CCK rate */
if (rtlhal->current_bandtype == BAND_ON_5G)
if (ptcb_desc->rts_rate < DESC_RATE6M)
ptcb_desc->rts_rate = DESC_RATE6M;
SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
SET_TX_DESC_RTS_BW(pdesc, 0);
SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc);
SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <=
DESC_RATE54M) ?
(ptcb_desc->rts_use_shortpreamble ? 1 : 0) :
(ptcb_desc->rts_use_shortgi ? 1 : 0)));
if (bw_40) {
if (ptcb_desc->packet_bw) {
SET_TX_DESC_DATA_BW(pdesc, 1);
SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
} else {
SET_TX_DESC_DATA_BW(pdesc, 0);
SET_TX_DESC_TX_SUB_CARRIER(pdesc,
mac->cur_40_prime_sc);
}
} else {
SET_TX_DESC_DATA_BW(pdesc, 0);
SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
}
SET_TX_DESC_LINIP(pdesc, 0);
SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb_len);
if (sta) {
u8 ampdu_density = sta->ht_cap.ampdu_density;
SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
}
if (info->control.hw_key) {
struct ieee80211_key_conf *keyconf;
keyconf = info->control.hw_key;
switch (keyconf->cipher) {
case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104:
case WLAN_CIPHER_SUITE_TKIP:
SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
break;
case WLAN_CIPHER_SUITE_CCMP:
SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
break;
default:
SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
break;
}
}
SET_TX_DESC_PKT_ID(pdesc, 0);
SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
SET_TX_DESC_DISABLE_FB(pdesc, ptcb_desc->disable_ratefallback ?
1 : 0);
SET_TX_DESC_USE_RATE(pdesc, ptcb_desc->use_driver_rate ? 1 : 0);
/* Set TxRate and RTSRate in TxDesc */
/* This prevent Tx initial rate of new-coming packets */
/* from being overwritten by retried packet rate.*/
if (!ptcb_desc->use_driver_rate) {
SET_TX_DESC_RTS_RATE(pdesc, 0x08);
/* SET_TX_DESC_TX_RATE(pdesc, 0x0b); */
}
if (ieee80211_is_data_qos(fc)) {
if (mac->rdg_en) {
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
"Enable RDG function\n");
SET_TX_DESC_RDG_ENABLE(pdesc, 1);
SET_TX_DESC_HTC(pdesc, 1);
}
}
}
SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) buf_len);
SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
if (rtlpriv->dm.useramask) {
SET_TX_DESC_RATE_ID(pdesc, ptcb_desc->ratr_index);
SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
} else {
SET_TX_DESC_RATE_ID(pdesc, 0xC + ptcb_desc->ratr_index);
SET_TX_DESC_MACID(pdesc, ptcb_desc->ratr_index);
}
if (ieee80211_is_data_qos(fc))
SET_TX_DESC_QOS(pdesc, 1);
if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) {
SET_TX_DESC_HWSEQ_EN(pdesc, 1);
SET_TX_DESC_PKT_ID(pdesc, 8);
}
SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
}
void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw,
u8 *pdesc, bool firstseg,
bool lastseg, struct sk_buff *skb)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
u8 fw_queue = QSLT_BEACON;
dma_addr_t mapping = pci_map_single(rtlpci->pdev,
skb->data, skb->len, PCI_DMA_TODEVICE);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
__le16 fc = hdr->frame_control;
if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
"DMA mapping error");
return;
}
CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
if (firstseg)
SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
/* 5G have no CCK rate
* Caution: The macros below are multi-line expansions.
* The braces are needed no matter what checkpatch says
*/
if (rtlhal->current_bandtype == BAND_ON_5G) {
SET_TX_DESC_TX_RATE(pdesc, DESC_RATE6M);
} else {
SET_TX_DESC_TX_RATE(pdesc, DESC_RATE1M);
}
SET_TX_DESC_SEQ(pdesc, 0);
SET_TX_DESC_LINIP(pdesc, 0);
SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
SET_TX_DESC_FIRST_SEG(pdesc, 1);
SET_TX_DESC_LAST_SEG(pdesc, 1);
SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)skb->len);
SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
SET_TX_DESC_RATE_ID(pdesc, 7);
SET_TX_DESC_MACID(pdesc, 0);
SET_TX_DESC_PKT_SIZE(pdesc, (u16) (skb->len));
SET_TX_DESC_FIRST_SEG(pdesc, 1);
SET_TX_DESC_LAST_SEG(pdesc, 1);
SET_TX_DESC_OFFSET(pdesc, 0x20);
SET_TX_DESC_USE_RATE(pdesc, 1);
if (!ieee80211_is_data_qos(fc) && ppsc->fwctrl_lps) {
SET_TX_DESC_HWSEQ_EN(pdesc, 1);
SET_TX_DESC_PKT_ID(pdesc, 8);
}
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
"H2C Tx Cmd Content", pdesc, TX_DESC_SIZE);
wmb();
SET_TX_DESC_OWN(pdesc, 1);
}
void rtl92de_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
u8 desc_name, u8 *val)
{
if (istx) {
switch (desc_name) {
case HW_DESC_OWN:
wmb();
SET_TX_DESC_OWN(pdesc, 1);
break;
case HW_DESC_TX_NEXTDESC_ADDR:
SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
break;
default:
RT_ASSERT(false, "ERR txdesc :%d not process\n",
desc_name);
break;
}
} else {
switch (desc_name) {
case HW_DESC_RXOWN:
wmb();
SET_RX_DESC_OWN(pdesc, 1);
break;
case HW_DESC_RXBUFF_ADDR:
SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
break;
case HW_DESC_RXPKT_LEN:
SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
break;
case HW_DESC_RXERO:
SET_RX_DESC_EOR(pdesc, 1);
break;
default:
RT_ASSERT(false, "ERR rxdesc :%d not process\n",
desc_name);
break;
}
}
}
u32 rtl92de_get_desc(u8 *p_desc, bool istx, u8 desc_name)
{
u32 ret = 0;
if (istx) {
switch (desc_name) {
case HW_DESC_OWN:
ret = GET_TX_DESC_OWN(p_desc);
break;
case HW_DESC_TXBUFF_ADDR:
ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
break;
default:
RT_ASSERT(false, "ERR txdesc :%d not process\n",
desc_name);
break;
}
} else {
struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
switch (desc_name) {
case HW_DESC_OWN:
ret = GET_RX_DESC_OWN(pdesc);
break;
case HW_DESC_RXPKT_LEN:
ret = GET_RX_DESC_PKT_LEN(pdesc);
break;
default:
RT_ASSERT(false, "ERR rxdesc :%d not process\n",
desc_name);
break;
}
}
return ret;
}
void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
if (hw_queue == BEACON_QUEUE)
rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
else
rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
BIT(0) << (hw_queue));
}

Melihat File

@@ -0,0 +1,748 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* 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 __RTL92DE_TRX_H__
#define __RTL92DE_TRX_H__
#define TX_DESC_SIZE 64
#define TX_DESC_AGGR_SUBFRAME_SIZE 32
#define RX_DESC_SIZE 32
#define RX_DRV_INFO_SIZE_UNIT 8
#define TX_DESC_NEXT_DESC_OFFSET 40
#define USB_HWDESC_HEADER_LEN 32
#define CRCLENGTH 4
/* Define a macro that takes a le32 word, converts it to host ordering,
* right shifts by a specified count, creates a mask of the specified
* bit count, and extracts that number of bits.
*/
#define SHIFT_AND_MASK_LE(__pdesc, __shift, __mask) \
((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) & \
BIT_LEN_MASK_32(__mask))
/* Define a macro that clears a bit field in an le32 word and
* sets the specified value into that bit field. The resulting
* value remains in le32 ordering; however, it is properly converted
* to host ordering for the clear and set operations before conversion
* back to le32.
*/
#define SET_BITS_OFFSET_LE(__pdesc, __shift, __len, __val) \
(*(__le32 *)(__pdesc) = \
(cpu_to_le32((le32_to_cpu(*((__le32 *)(__pdesc))) & \
(~(BIT_OFFSET_LEN_MASK_32((__shift), __len)))) | \
(((u32)(__val) & BIT_LEN_MASK_32(__len)) << (__shift)))));
/* macros to read/write various fields in RX or TX descriptors */
#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 0, 16, __val)
#define SET_TX_DESC_OFFSET(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 16, 8, __val)
#define SET_TX_DESC_BMC(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 24, 1, __val)
#define SET_TX_DESC_HTC(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 25, 1, __val)
#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 26, 1, __val)
#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 27, 1, __val)
#define SET_TX_DESC_LINIP(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 28, 1, __val)
#define SET_TX_DESC_NO_ACM(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 29, 1, __val)
#define SET_TX_DESC_GF(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val)
#define SET_TX_DESC_OWN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val)
#define GET_TX_DESC_PKT_SIZE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 0, 16)
#define GET_TX_DESC_OFFSET(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 16, 8)
#define GET_TX_DESC_BMC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 24, 1)
#define GET_TX_DESC_HTC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 25, 1)
#define GET_TX_DESC_LAST_SEG(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 26, 1)
#define GET_TX_DESC_FIRST_SEG(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 27, 1)
#define GET_TX_DESC_LINIP(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 28, 1)
#define GET_TX_DESC_NO_ACM(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 29, 1)
#define GET_TX_DESC_GF(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 30, 1)
#define GET_TX_DESC_OWN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 31, 1)
#define SET_TX_DESC_MACID(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 0, 5, __val)
#define SET_TX_DESC_AGG_ENABLE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 5, 1, __val)
#define SET_TX_DESC_BK(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 6, 1, __val)
#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 7, 1, __val)
#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 8, 5, __val)
#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 13, 1, __val)
#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 14, 1, __val)
#define SET_TX_DESC_PIFS(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 15, 1, __val)
#define SET_TX_DESC_RATE_ID(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 16, 4, __val)
#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 20, 1, __val)
#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 21, 1, __val)
#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 22, 2, __val)
#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 26, 8, __val)
#define GET_TX_DESC_MACID(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 0, 5)
#define GET_TX_DESC_AGG_ENABLE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 5, 1)
#define GET_TX_DESC_AGG_BREAK(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 6, 1)
#define GET_TX_DESC_RDG_ENABLE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 7, 1)
#define GET_TX_DESC_QUEUE_SEL(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 8, 5)
#define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 13, 1)
#define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 14, 1)
#define GET_TX_DESC_PIFS(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 15, 1)
#define GET_TX_DESC_RATE_ID(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 16, 4)
#define GET_TX_DESC_NAV_USE_HDR(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 20, 1)
#define GET_TX_DESC_EN_DESC_ID(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 21, 1)
#define GET_TX_DESC_SEC_TYPE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 22, 2)
#define GET_TX_DESC_PKT_OFFSET(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 24, 8)
#define SET_TX_DESC_RTS_RC(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 0, 6, __val)
#define SET_TX_DESC_DATA_RC(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 6, 6, __val)
#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 14, 2, __val)
#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 17, 1, __val)
#define SET_TX_DESC_RAW(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 18, 1, __val)
#define SET_TX_DESC_CCX(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 19, 1, __val)
#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 20, 3, __val)
#define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 24, 1, __val)
#define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 25, 1, __val)
#define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 26, 2, __val)
#define SET_TX_DESC_TX_ANTL(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 28, 2, __val)
#define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 30, 2, __val)
#define GET_TX_DESC_RTS_RC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 0, 6)
#define GET_TX_DESC_DATA_RC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 6, 6)
#define GET_TX_DESC_BAR_RTY_TH(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 14, 2)
#define GET_TX_DESC_MORE_FRAG(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 17, 1)
#define GET_TX_DESC_RAW(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 18, 1)
#define GET_TX_DESC_CCX(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 19, 1)
#define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 20, 3)
#define GET_TX_DESC_ANTSEL_A(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 24, 1)
#define GET_TX_DESC_ANTSEL_B(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 25, 1)
#define GET_TX_DESC_TX_ANT_CCK(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 26, 2)
#define GET_TX_DESC_TX_ANTL(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 28, 2)
#define GET_TX_DESC_TX_ANT_HT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 30, 2)
#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+12, 0, 8, __val)
#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+12, 8, 8, __val)
#define SET_TX_DESC_SEQ(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+12, 16, 12, __val)
#define SET_TX_DESC_PKT_ID(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+12, 28, 4, __val)
#define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 0, 8)
#define GET_TX_DESC_TAIL_PAGE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 8, 8)
#define GET_TX_DESC_SEQ(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 16, 12)
#define GET_TX_DESC_PKT_ID(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 28, 4)
#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 0, 5, __val)
#define SET_TX_DESC_AP_DCFE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 5, 1, __val)
#define SET_TX_DESC_QOS(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 6, 1, __val)
#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 7, 1, __val)
#define SET_TX_DESC_USE_RATE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 8, 1, __val)
#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 9, 1, __val)
#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 10, 1, __val)
#define SET_TX_DESC_CTS2SELF(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 11, 1, __val)
#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 12, 1, __val)
#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 13, 1, __val)
#define SET_TX_DESC_PORT_ID(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 14, 1, __val)
#define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 18, 1, __val)
#define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 19, 1, __val)
#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 20, 2, __val)
#define SET_TX_DESC_TX_STBC(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 22, 2, __val)
#define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 24, 1, __val)
#define SET_TX_DESC_DATA_BW(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 25, 1, __val)
#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 26, 1, __val)
#define SET_TX_DESC_RTS_BW(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 27, 1, __val)
#define SET_TX_DESC_RTS_SC(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 28, 2, __val)
#define SET_TX_DESC_RTS_STBC(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 30, 2, __val)
#define GET_TX_DESC_RTS_RATE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 0, 5)
#define GET_TX_DESC_AP_DCFE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 5, 1)
#define GET_TX_DESC_QOS(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 6, 1)
#define GET_TX_DESC_HWSEQ_EN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 7, 1)
#define GET_TX_DESC_USE_RATE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 8, 1)
#define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 9, 1)
#define GET_TX_DESC_DISABLE_FB(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 10, 1)
#define GET_TX_DESC_CTS2SELF(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 11, 1)
#define GET_TX_DESC_RTS_ENABLE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 12, 1)
#define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 13, 1)
#define GET_TX_DESC_PORT_ID(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 14, 1)
#define GET_TX_DESC_WAIT_DCTS(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 18, 1)
#define GET_TX_DESC_CTS2AP_EN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 19, 1)
#define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 20, 2)
#define GET_TX_DESC_TX_STBC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 22, 2)
#define GET_TX_DESC_DATA_SHORT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 24, 1)
#define GET_TX_DESC_DATA_BW(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 25, 1)
#define GET_TX_DESC_RTS_SHORT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 26, 1)
#define GET_TX_DESC_RTS_BW(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 27, 1)
#define GET_TX_DESC_RTS_SC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 28, 2)
#define GET_TX_DESC_RTS_STBC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 30, 2)
#define SET_TX_DESC_TX_RATE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 0, 6, __val)
#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 6, 1, __val)
#define SET_TX_DESC_CCX_TAG(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 7, 1, __val)
#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 8, 5, __val)
#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 13, 4, __val)
#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 17, 1, __val)
#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 18, 6, __val)
#define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 24, 8, __val)
#define GET_TX_DESC_TX_RATE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+20, 0, 6)
#define GET_TX_DESC_DATA_SHORTGI(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+20, 6, 1)
#define GET_TX_DESC_CCX_TAG(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+20, 7, 1)
#define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+20, 8, 5)
#define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+20, 13, 4)
#define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+20, 17, 1)
#define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+20, 18, 6)
#define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+20, 24, 8)
#define SET_TX_DESC_TXAGC_A(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+24, 0, 5, __val)
#define SET_TX_DESC_TXAGC_B(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+24, 5, 5, __val)
#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+24, 10, 1, __val)
#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+24, 11, 5, __val)
#define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+24, 16, 4, __val)
#define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+24, 20, 4, __val)
#define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+24, 24, 4, __val)
#define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+24, 28, 4, __val)
#define GET_TX_DESC_TXAGC_A(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+24, 0, 5)
#define GET_TX_DESC_TXAGC_B(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+24, 5, 5)
#define GET_TX_DESC_USE_MAX_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+24, 10, 1)
#define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+24, 11, 5)
#define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+24, 16, 4)
#define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+24, 20, 4)
#define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+24, 24, 4)
#define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+24, 28, 4)
#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+28, 0, 16, __val)
#define SET_TX_DESC_MCSG4_MAX_LEN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+28, 16, 4, __val)
#define SET_TX_DESC_MCSG5_MAX_LEN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+28, 20, 4, __val)
#define SET_TX_DESC_MCSG6_MAX_LEN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+28, 24, 4, __val)
#define SET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+28, 28, 4, __val)
#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+28, 0, 16)
#define GET_TX_DESC_MCSG4_MAX_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+28, 16, 4)
#define GET_TX_DESC_MCSG5_MAX_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+28, 20, 4)
#define GET_TX_DESC_MCSG6_MAX_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+28, 24, 4)
#define GET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+28, 28, 4)
#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+32, 0, 32, __val)
#define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+36, 0, 32, __val)
#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+32, 0, 32)
#define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+36, 0, 32)
#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+40, 0, 32, __val)
#define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+44, 0, 32, __val)
#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+40, 0, 32)
#define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+44, 0, 32)
#define GET_RX_DESC_PKT_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 0, 14)
#define GET_RX_DESC_CRC32(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 14, 1)
#define GET_RX_DESC_ICV(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 15, 1)
#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 16, 4)
#define GET_RX_DESC_SECURITY(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 20, 3)
#define GET_RX_DESC_QOS(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 23, 1)
#define GET_RX_DESC_SHIFT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 24, 2)
#define GET_RX_DESC_PHYST(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 26, 1)
#define GET_RX_DESC_SWDEC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 27, 1)
#define GET_RX_DESC_LS(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 28, 1)
#define GET_RX_DESC_FS(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 29, 1)
#define GET_RX_DESC_EOR(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 30, 1)
#define GET_RX_DESC_OWN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 31, 1)
#define SET_RX_DESC_PKT_LEN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 0, 14, __val)
#define SET_RX_DESC_EOR(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val)
#define SET_RX_DESC_OWN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val)
#define GET_RX_DESC_MACID(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 0, 5)
#define GET_RX_DESC_TID(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 5, 4)
#define GET_RX_DESC_HWRSVD(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 9, 5)
#define GET_RX_DESC_PAGGR(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 14, 1)
#define GET_RX_DESC_FAGGR(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 15, 1)
#define GET_RX_DESC_A1_FIT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 16, 4)
#define GET_RX_DESC_A2_FIT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 20, 4)
#define GET_RX_DESC_PAM(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 24, 1)
#define GET_RX_DESC_PWR(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 25, 1)
#define GET_RX_DESC_MD(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 26, 1)
#define GET_RX_DESC_MF(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 27, 1)
#define GET_RX_DESC_TYPE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 28, 2)
#define GET_RX_DESC_MC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 30, 1)
#define GET_RX_DESC_BC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 31, 1)
#define GET_RX_DESC_SEQ(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 0, 12)
#define GET_RX_DESC_FRAG(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 12, 4)
#define GET_RX_DESC_NEXT_PKT_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 16, 14)
#define GET_RX_DESC_NEXT_IND(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 30, 1)
#define GET_RX_DESC_RSVD(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 31, 1)
#define GET_RX_DESC_RXMCS(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 0, 6)
#define GET_RX_DESC_RXHT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 6, 1)
#define GET_RX_DESC_SPLCP(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 8, 1)
#define GET_RX_DESC_BW(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 9, 1)
#define GET_RX_DESC_HTC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 10, 1)
#define GET_RX_DESC_HWPC_ERR(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 14, 1)
#define GET_RX_DESC_HWPC_IND(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 15, 1)
#define GET_RX_DESC_IV0(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 16, 16)
#define GET_RX_DESC_IV1(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 0, 32)
#define GET_RX_DESC_TSFL(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+20, 0, 32)
#define GET_RX_DESC_BUFF_ADDR(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+24, 0, 32)
#define GET_RX_DESC_BUFF_ADDR64(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+28, 0, 32)
#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+24, 0, 32, __val)
#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+28, 0, 32, __val)
#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \
memset((void *)__pdesc, 0, \
min_t(size_t, _size, TX_DESC_NEXT_DESC_OFFSET))
/* For 92D early mode */
#define SET_EARLYMODE_PKTNUM(__paddr, __value) \
SET_BITS_OFFSET_LE(__paddr, 0, 3, __value)
#define SET_EARLYMODE_LEN0(__paddr, __value) \
SET_BITS_OFFSET_LE(__paddr, 4, 12, __value)
#define SET_EARLYMODE_LEN1(__paddr, __value) \
SET_BITS_OFFSET_LE(__paddr, 16, 12, __value)
#define SET_EARLYMODE_LEN2_1(__paddr, __value) \
SET_BITS_OFFSET_LE(__paddr, 28, 4, __value)
#define SET_EARLYMODE_LEN2_2(__paddr, __value) \
SET_BITS_OFFSET_LE(__paddr+4, 0, 8, __value)
#define SET_EARLYMODE_LEN3(__paddr, __value) \
SET_BITS_OFFSET_LE(__paddr+4, 8, 12, __value)
#define SET_EARLYMODE_LEN4(__paddr, __value) \
SET_BITS_OFFSET_LE(__paddr+4, 20, 12, __value)
struct rx_fwinfo_92d {
u8 gain_trsw[4];
u8 pwdb_all;
u8 cfosho[4];
u8 cfotail[4];
char rxevm[2];
char rxsnr[4];
u8 pdsnr[2];
u8 csi_current[2];
u8 csi_target[2];
u8 sigevm;
u8 max_ex_pwr;
u8 ex_intf_flag:1;
u8 sgi_en:1;
u8 rxsc:2;
u8 reserve:4;
} __packed;
struct tx_desc_92d {
u32 pktsize:16;
u32 offset:8;
u32 bmc:1;
u32 htc:1;
u32 lastseg:1;
u32 firstseg:1;
u32 linip:1;
u32 noacm:1;
u32 gf:1;
u32 own:1;
u32 macid:5;
u32 agg_en:1;
u32 bk:1;
u32 rdg_en:1;
u32 queuesel:5;
u32 rd_nav_ext:1;
u32 lsig_txop_en:1;
u32 pifs:1;
u32 rateid:4;
u32 nav_usehdr:1;
u32 en_descid:1;
u32 sectype:2;
u32 pktoffset:8;
u32 rts_rc:6;
u32 data_rc:6;
u32 rsvd0:2;
u32 bar_retryht:2;
u32 rsvd1:1;
u32 morefrag:1;
u32 raw:1;
u32 ccx:1;
u32 ampdudensity:3;
u32 rsvd2:1;
u32 ant_sela:1;
u32 ant_selb:1;
u32 txant_cck:2;
u32 txant_l:2;
u32 txant_ht:2;
u32 nextheadpage:8;
u32 tailpage:8;
u32 seq:12;
u32 pktid:4;
u32 rtsrate:5;
u32 apdcfe:1;
u32 qos:1;
u32 hwseq_enable:1;
u32 userrate:1;
u32 dis_rtsfb:1;
u32 dis_datafb:1;
u32 cts2self:1;
u32 rts_en:1;
u32 hwrts_en:1;
u32 portid:1;
u32 rsvd3:3;
u32 waitdcts:1;
u32 cts2ap_en:1;
u32 txsc:2;
u32 stbc:2;
u32 txshort:1;
u32 txbw:1;
u32 rtsshort:1;
u32 rtsbw:1;
u32 rtssc:2;
u32 rtsstbc:2;
u32 txrate:6;
u32 shortgi:1;
u32 ccxt:1;
u32 txrate_fb_lmt:5;
u32 rtsrate_fb_lmt:4;
u32 retrylmt_en:1;
u32 txretrylmt:6;
u32 usb_txaggnum:8;
u32 txagca:5;
u32 txagcb:5;
u32 usemaxlen:1;
u32 maxaggnum:5;
u32 mcsg1maxlen:4;
u32 mcsg2maxlen:4;
u32 mcsg3maxlen:4;
u32 mcs7sgimaxlen:4;
u32 txbuffersize:16;
u32 mcsg4maxlen:4;
u32 mcsg5maxlen:4;
u32 mcsg6maxlen:4;
u32 mcsg15sgimaxlen:4;
u32 txbuffaddr;
u32 txbufferaddr64;
u32 nextdescaddress;
u32 nextdescaddress64;
u32 reserve_pass_pcie_mm_limit[4];
} __packed;
struct rx_desc_92d {
u32 length:14;
u32 crc32:1;
u32 icverror:1;
u32 drv_infosize:4;
u32 security:3;
u32 qos:1;
u32 shift:2;
u32 phystatus:1;
u32 swdec:1;
u32 lastseg:1;
u32 firstseg:1;
u32 eor:1;
u32 own:1;
u32 macid:5;
u32 tid:4;
u32 hwrsvd:5;
u32 paggr:1;
u32 faggr:1;
u32 a1_fit:4;
u32 a2_fit:4;
u32 pam:1;
u32 pwr:1;
u32 moredata:1;
u32 morefrag:1;
u32 type:2;
u32 mc:1;
u32 bc:1;
u32 seq:12;
u32 frag:4;
u32 nextpktlen:14;
u32 nextind:1;
u32 rsvd:1;
u32 rxmcs:6;
u32 rxht:1;
u32 amsdu:1;
u32 splcp:1;
u32 bandwidth:1;
u32 htc:1;
u32 tcpchk_rpt:1;
u32 ipcchk_rpt:1;
u32 tcpchk_valid:1;
u32 hwpcerr:1;
u32 hwpcind:1;
u32 iv0:16;
u32 iv1;
u32 tsfl;
u32 bufferaddress;
u32 bufferaddress64;
} __packed;
void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr, u8 *pdesc,
u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
struct ieee80211_sta *sta,
struct sk_buff *skb, u8 hw_queue,
struct rtl_tcb_desc *ptcb_desc);
bool rtl92de_rx_query_desc(struct ieee80211_hw *hw,
struct rtl_stats *stats,
struct ieee80211_rx_status *rx_status,
u8 *pdesc, struct sk_buff *skb);
void rtl92de_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
u8 desc_name, u8 *val);
u32 rtl92de_get_desc(u8 *pdesc, bool istx, u8 desc_name);
void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
bool b_firstseg, bool b_lastseg,
struct sk_buff *skb);
#endif