diff options
author | Larry Finger <Larry.Finger@lwfinger.net> | 2013-03-24 22:06:42 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-04-01 16:20:13 -0400 |
commit | f0eb856e0b6cbd21244afc0f252cec718ecf88fb (patch) | |
tree | 77d5cb7faf46f7ffd6b79a6d97be72b4eef422b1 /drivers/net | |
parent | a269913c52ad37952a4d9953bb6d748f7299c304 (diff) |
rtlwifi: rtl8188ee: Add new driver
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: jcheung@suse.com
Cc: machen@suse.com
Cc: mmarek@suse.cz
Cc: page_he@realsil.com.cn
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
24 files changed, 14998 insertions, 0 deletions
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/def.h b/drivers/net/wireless/rtlwifi/rtl8188ee/def.h new file mode 100644 index 000000000000..c764fff9ebe6 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/def.h @@ -0,0 +1,324 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2013 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_DEF_H__ +#define __RTL92C_DEF_H__ + +#define HAL_RETRY_LIMIT_INFRA 48 +#define HAL_RETRY_LIMIT_AP_ADHOC 7 + +#define RESET_DELAY_8185 20 + +#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER) +#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK) + +#define NUM_OF_FIRMWARE_QUEUE 10 +#define NUM_OF_PAGES_IN_FW 0x100 +#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07 +#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07 +#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07 +#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07 +#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0 +#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0 +#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02 +#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02 +#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2 +#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1 + +#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026 +#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048 +#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048 +#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026 +#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00 + +#define MAX_LINES_HWCONFIG_TXT 1000 +#define MAX_BYTES_LINE_HWCONFIG_TXT 256 + +#define SW_THREE_WIRE 0 +#define HW_THREE_WIRE 2 + +#define BT_DEMO_BOARD 0 +#define BT_QA_BOARD 1 +#define BT_FPGA 2 + +#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 +#define HAL_PRIME_CHNL_OFFSET_LOWER 1 +#define HAL_PRIME_CHNL_OFFSET_UPPER 2 + +#define MAX_H2C_QUEUE_NUM 10 + +#define RX_MPDU_QUEUE 0 +#define RX_CMD_QUEUE 1 +#define RX_MAX_QUEUE 2 +#define AC2QUEUEID(_AC) (_AC) + +#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) + +#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3) + + +/* [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 B_CUT_VERSION BIT(12) +#define C_CUT_VERSION BIT(13) +#define D_CUT_VERSION ((BIT(12)|BIT(13))) +#define E_CUT_VERSION 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_81XXC(version) \ + ((GET_CVID_IC_TYPE(version) == 0) ? true : false) +#define IS_8723_SERIES(version) \ + ((GET_CVID_IC_TYPE(version) == CHIP_8723) ? true : false) +#define IS_92D(version) \ + ((GET_CVID_IC_TYPE(version) == CHIP_92D) ? true : false) + +#define IS_NORMAL_CHIP(version) \ + ((GET_CVID_CHIP_TYPE(version)) ? true : false) +#define IS_NORMAL_CHIP92D(version) \ + ((GET_CVID_CHIP_TYPE(version)) ? true : false) + +#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_CHIP_VENDOR_UMC(version) \ + ((GET_CVID_MANUFACTUER(version)) ? true : false) + +#define IS_92C_SERIAL(version) \ + ((IS_81XXC(version) && IS_2T2R(version)) ? true : false) +#define IS_81xxC_VENDOR_UMC_A_CUT(version) \ + (IS_81XXC(version) ? ((IS_CHIP_VENDOR_UMC(version)) ? \ + ((GET_CVID_CUT_VERSION(version)) ? false : true) : false) : false) +#define IS_81xxC_VENDOR_UMC_B_CUT(version) \ + (IS_81XXC(version) ? (IS_CHIP_VENDOR_UMC(version) ? \ + ((GET_CVID_CUT_VERSION(version) == B_CUT_VERSION) ? true \ + : false) : false) : false) + +enum version_8188e { + VERSION_TEST_CHIP_88E = 0x00, + VERSION_NORMAL_CHIP_88E = 0x01, + VERSION_UNKNOWN = 0xFF, +}; + +enum rx_packet_type { + NORMAL_RX, + TX_REPORT1, + TX_REPORT2, + HIS_REPORT, +}; + +enum rtl819x_loopback_e { + RTL819X_NO_LOOPBACK = 0, + RTL819X_MAC_LOOPBACK = 1, + RTL819X_DMA_LOOPBACK = 2, + RTL819X_CCK_LOOPBACK = 3, +}; + +enum rf_optype { + RF_OP_BY_SW_3WIRE = 0, + RF_OP_BY_FW, + RF_OP_MAX +}; + +enum rf_power_state { + RF_ON, + RF_OFF, + RF_SLEEP, + RF_SHUT_DOWN, +}; + +enum power_save_mode { + POWER_SAVE_MODE_ACTIVE, + POWER_SAVE_MODE_SAVE, +}; + +enum power_polocy_config { + POWERCFG_MAX_POWER_SAVINGS, + POWERCFG_GLOBAL_POWER_SAVINGS, + POWERCFG_LOCAL_POWER_SAVINGS, + POWERCFG_LENOVO, +}; + +enum interface_select_pci { + INTF_SEL1_MINICARD, + INTF_SEL0_PCIE, + INTF_SEL2_RSV, + INTF_SEL3_RSV, +}; + +enum hal_fw_c2h_cmd_id { + HAL_FW_C2H_CMD_Read_MACREG, + HAL_FW_C2H_CMD_Read_BBREG, + HAL_FW_C2H_CMD_Read_RFREG, + HAL_FW_C2H_CMD_Read_EEPROM, + HAL_FW_C2H_CMD_Read_EFUSE, + HAL_FW_C2H_CMD_Read_CAM, + HAL_FW_C2H_CMD_Get_BasicRate, + HAL_FW_C2H_CMD_Get_DataRate, + HAL_FW_C2H_CMD_Survey, + HAL_FW_C2H_CMD_SurveyDone, + HAL_FW_C2H_CMD_JoinBss, + HAL_FW_C2H_CMD_AddSTA, + HAL_FW_C2H_CMD_DelSTA, + HAL_FW_C2H_CMD_AtimDone, + HAL_FW_C2H_CMD_TX_Report, + HAL_FW_C2H_CMD_CCX_Report, + HAL_FW_C2H_CMD_DTM_Report, + HAL_FW_C2H_CMD_TX_Rate_Statistics, + HAL_FW_C2H_CMD_C2HLBK, + HAL_FW_C2H_CMD_C2HDBG, + HAL_FW_C2H_CMD_C2HFEEDBACK, + HAL_FW_C2H_CMD_MAX +}; + +enum wake_on_wlan_mode { + ewowlandisable, + ewakeonmagicpacketonly, + ewakeonpatternmatchonly, + ewakeonbothtypepacket +}; + +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 rtl_desc92c_rate { + DESC92C_RATE1M = 0x00, + DESC92C_RATE2M = 0x01, + DESC92C_RATE5_5M = 0x02, + DESC92C_RATE11M = 0x03, + + DESC92C_RATE6M = 0x04, + DESC92C_RATE9M = 0x05, + DESC92C_RATE12M = 0x06, + DESC92C_RATE18M = 0x07, + DESC92C_RATE24M = 0x08, + DESC92C_RATE36M = 0x09, + DESC92C_RATE48M = 0x0a, + DESC92C_RATE54M = 0x0b, + + DESC92C_RATEMCS0 = 0x0c, + DESC92C_RATEMCS1 = 0x0d, + DESC92C_RATEMCS2 = 0x0e, + DESC92C_RATEMCS3 = 0x0f, + DESC92C_RATEMCS4 = 0x10, + DESC92C_RATEMCS5 = 0x11, + DESC92C_RATEMCS6 = 0x12, + DESC92C_RATEMCS7 = 0x13, + DESC92C_RATEMCS8 = 0x14, + DESC92C_RATEMCS9 = 0x15, + DESC92C_RATEMCS10 = 0x16, + DESC92C_RATEMCS11 = 0x17, + DESC92C_RATEMCS12 = 0x18, + DESC92C_RATEMCS13 = 0x19, + DESC92C_RATEMCS14 = 0x1a, + DESC92C_RATEMCS15 = 0x1b, + DESC92C_RATEMCS15_SG = 0x1c, + DESC92C_RATEMCS32 = 0x20, +}; + +struct phy_sts_cck_8192s_t { + 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; +}; + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c new file mode 100644 index 000000000000..0a338cccbdfa --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c @@ -0,0 +1,1794 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2013 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 "base.h" +#include "pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "fw.h" +#include "trx.h" + +static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { + 0x7f8001fe, /* 0, +6.0dB */ + 0x788001e2, /* 1, +5.5dB */ + 0x71c001c7, /* 2, +5.0dB */ + 0x6b8001ae, /* 3, +4.5dB */ + 0x65400195, /* 4, +4.0dB */ + 0x5fc0017f, /* 5, +3.5dB */ + 0x5a400169, /* 6, +3.0dB */ + 0x55400155, /* 7, +2.5dB */ + 0x50800142, /* 8, +2.0dB */ + 0x4c000130, /* 9, +1.5dB */ + 0x47c0011f, /* 10, +1.0dB */ + 0x43c0010f, /* 11, +0.5dB */ + 0x40000100, /* 12, +0dB */ + 0x3c8000f2, /* 13, -0.5dB */ + 0x390000e4, /* 14, -1.0dB */ + 0x35c000d7, /* 15, -1.5dB */ + 0x32c000cb, /* 16, -2.0dB */ + 0x300000c0, /* 17, -2.5dB */ + 0x2d4000b5, /* 18, -3.0dB */ + 0x2ac000ab, /* 19, -3.5dB */ + 0x288000a2, /* 20, -4.0dB */ + 0x26000098, /* 21, -4.5dB */ + 0x24000090, /* 22, -5.0dB */ + 0x22000088, /* 23, -5.5dB */ + 0x20000080, /* 24, -6.0dB */ + 0x1e400079, /* 25, -6.5dB */ + 0x1c800072, /* 26, -7.0dB */ + 0x1b00006c, /* 27. -7.5dB */ + 0x19800066, /* 28, -8.0dB */ + 0x18000060, /* 29, -8.5dB */ + 0x16c0005b, /* 30, -9.0dB */ + 0x15800056, /* 31, -9.5dB */ + 0x14400051, /* 32, -10.0dB */ + 0x1300004c, /* 33, -10.5dB */ + 0x12000048, /* 34, -11.0dB */ + 0x11000044, /* 35, -11.5dB */ + 0x10000040, /* 36, -12.0dB */ + 0x0f00003c, /* 37, -12.5dB */ + 0x0e400039, /* 38, -13.0dB */ + 0x0d800036, /* 39, -13.5dB */ + 0x0cc00033, /* 40, -14.0dB */ + 0x0c000030, /* 41, -14.5dB */ + 0x0b40002d, /* 42, -15.0dB */ +}; + +static const u8 cck_tbl_ch1_13[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */ + {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */ + {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB */ + {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 3, -1.5dB */ + {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 4, -2.0dB */ + {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 5, -2.5dB */ + {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 6, -3.0dB */ + {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 7, -3.5dB */ + {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 8, -4.0dB */ + {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 9, -4.5dB */ + {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 10, -5.0dB */ + {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 11, -5.5dB */ + {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 12, -6.0dB */ + {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 13, -6.5dB */ + {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 14, -7.0dB */ + {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 15, -7.5dB */ + {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */ + {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 17, -8.5dB */ + {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 18, -9.0dB */ + {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 19, -9.5dB */ + {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 20, -10.0dB*/ + {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 21, -10.5dB*/ + {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 22, -11.0dB*/ + {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 23, -11.5dB*/ + {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 24, -12.0dB*/ + {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 25, -12.5dB*/ + {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 26, -13.0dB*/ + {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 27, -13.5dB*/ + {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 28, -14.0dB*/ + {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 29, -14.5dB*/ + {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 30, -15.0dB*/ + {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 31, -15.5dB*/ + {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB*/ +}; + +static const u8 cck_tbl_ch14[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */ + {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */ + {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */ + {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 3, -1.5dB */ + {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 4, -2.0dB */ + {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 5, -2.5dB */ + {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 6, -3.0dB */ + {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 7, -3.5dB */ + {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 8, -4.0dB */ + {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 9, -4.5dB */ + {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 10, -5.0dB */ + {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 11, -5.5dB */ + {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 12, -6.0dB */ + {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 13, -6.5dB */ + {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 14, -7.0dB */ + {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 15, -7.5dB */ + {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */ + {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 17, -8.5dB */ + {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 18, -9.0dB */ + {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 19, -9.5dB */ + {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 20, -10.0dB*/ + {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 21, -10.5dB*/ + {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 22, -11.0dB*/ + {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 23, -11.5dB*/ + {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 24, -12.0dB*/ + {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 25, -12.5dB*/ + {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 26, -13.0dB*/ + {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 27, -13.5dB*/ + {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 28, -14.0dB*/ + {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 29, -14.5dB*/ + {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 30, -15.0dB*/ + {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 31, -15.5dB*/ + {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB*/ +}; + +#define CAL_SWING_OFF(_off, _dir, _size, _del) \ + do { \ + for (_off = 0; _off < _size; _off++) { \ + if (_del < thermal_threshold[_dir][_off]) { \ + if (_off != 0) \ + _off--; \ + break; \ + } \ + } \ + if (_off >= _size) \ + _off = _size - 1; \ + } while (0) + +static void rtl88e_set_iqk_matrix(struct ieee80211_hw *hw, + u8 ofdm_index, u8 rfpath, + long iqk_result_x, long iqk_result_y) +{ + long ele_a = 0, ele_d, ele_c = 0, value32; + + ele_d = (ofdmswing_table[ofdm_index] & 0xFFC00000)>>22; + + if (iqk_result_x != 0) { + if ((iqk_result_x & 0x00000200) != 0) + iqk_result_x = iqk_result_x | 0xFFFFFC00; + ele_a = ((iqk_result_x * ele_d)>>8)&0x000003FF; + + if ((iqk_result_y & 0x00000200) != 0) + iqk_result_y = iqk_result_y | 0xFFFFFC00; + ele_c = ((iqk_result_y * ele_d)>>8)&0x000003FF; + + switch (rfpath) { + case RF90_PATH_A: + value32 = (ele_d << 22)|((ele_c & 0x3F)<<16) | ele_a; + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBAL, MASKDWORD, + value32); + value32 = (ele_c & 0x000003C0) >> 6; + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, value32); + value32 = ((iqk_result_x * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRES, BIT(24), value32); + break; + case RF90_PATH_B: + value32 = (ele_d << 22)|((ele_c & 0x3F)<<16) | ele_a; + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBAL, + MASKDWORD, value32); + value32 = (ele_c & 0x000003C0) >> 6; + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, MASKH4BITS, value32); + value32 = ((iqk_result_x * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRES, BIT(28), value32); + break; + default: + break; + } + } else { + switch (rfpath) { + case RF90_PATH_A: + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBAL, MASKDWORD, + ofdmswing_table[ofdm_index]); + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRES, BIT(24), 0x00); + break; + case RF90_PATH_B: + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBAL, MASKDWORD, + ofdmswing_table[ofdm_index]); + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, MASKH4BITS, 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRES, BIT(28), 0x00); + break; + default: + break; + } + } +} + +void rtl88e_dm_txpower_track_adjust(struct ieee80211_hw *hw, + u8 type, u8 *pdirection, u32 *poutwrite_val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + u8 pwr_val = 0; + u8 cck_base = rtldm->swing_idx_cck_base; + u8 cck_val = rtldm->swing_idx_cck; + u8 ofdm_base = rtldm->swing_idx_ofdm_base; + u8 ofdm_val = rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A]; + + if (type == 0) { + if (ofdm_val <= ofdm_base) { + *pdirection = 1; + pwr_val = ofdm_base - ofdm_val; + } else { + *pdirection = 2; + pwr_val = ofdm_val - ofdm_base; + } + } else if (type == 1) { + if (cck_val <= cck_base) { + *pdirection = 1; + pwr_val = cck_base - cck_val; + } else { + *pdirection = 2; + pwr_val = cck_val - cck_base; + } + } + + if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1)) + pwr_val = TXPWRTRACK_MAX_IDX; + + *poutwrite_val = pwr_val | (pwr_val << 8) | (pwr_val << 16) | + (pwr_val << 24); +} + + +static void rtl88e_chk_tx_track(struct ieee80211_hw *hw, + enum pwr_track_control_method method, + u8 rfpath, u8 index) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); + int jj = rtldm->swing_idx_cck; + int i; + + if (method == TXAGC) { + if (rtldm->swing_flag_ofdm == true || + rtldm->swing_flag_cck == true) { + u8 chan = rtlphy->current_channel; + rtl88e_phy_set_txpower_level(hw, chan); + rtldm->swing_flag_ofdm = false; + rtldm->swing_flag_cck = false; + } + } else if (method == BBSWING) { + if (!rtldm->cck_inch14) { + for (i = 0; i < 8; i++) + rtl_write_byte(rtlpriv, 0xa22 + i, + cck_tbl_ch1_13[jj][i]); + } else { + for (i = 0; i < 8; i++) + rtl_write_byte(rtlpriv, 0xa22 + i, + cck_tbl_ch14[jj][i]); + } + + if (rfpath == RF90_PATH_A) { + long x = rtlphy->iqk_matrix[index].value[0][0]; + long y = rtlphy->iqk_matrix[index].value[0][1]; + u8 indx = rtldm->swing_idx_ofdm[rfpath]; + rtl88e_set_iqk_matrix(hw, indx, rfpath, x, y); + } else if (rfpath == RF90_PATH_B) { + u8 indx = rtldm->swing_idx_ofdm[rfpath]; + long x = rtlphy->iqk_matrix[indx].value[0][4]; + long y = rtlphy->iqk_matrix[indx].value[0][5]; + rtl88e_set_iqk_matrix(hw, indx, rfpath, x, y); + } + } else { + return; + } +} + +static void rtl88e_dm_diginit(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_dig = &rtlpriv->dm_digtable; + + dm_dig->dig_enable_flag = true; + dm_dig->cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f); + dm_dig->pre_igvalue = 0; + dm_dig->cursta_cstate = DIG_STA_DISCONNECT; + dm_dig->presta_cstate = DIG_STA_DISCONNECT; + dm_dig->curmultista_cstate = DIG_MULTISTA_DISCONNECT; + dm_dig->rssi_lowthresh = DM_DIG_THRESH_LOW; + dm_dig->rssi_highthresh = DM_DIG_THRESH_HIGH; + dm_dig->fa_lowthresh = DM_FALSEALARM_THRESH_LOW; + dm_dig->fa_highthresh = DM_FALSEALARM_THRESH_HIGH; + dm_dig->rx_gain_max = DM_DIG_MAX; + dm_dig->rx_gain_min = DM_DIG_MIN; + dm_dig->back_val = DM_DIG_BACKOFF_DEFAULT; + dm_dig->back_range_max = DM_DIG_BACKOFF_MAX; + dm_dig->back_range_min = DM_DIG_BACKOFF_MIN; + dm_dig->pre_cck_cca_thres = 0xff; + dm_dig->cur_cck_cca_thres = 0x83; + dm_dig->forbidden_igi = DM_DIG_MIN; + dm_dig->large_fa_hit = 0; + dm_dig->recover_cnt = 0; + dm_dig->dig_min_0 = 0x25; + dm_dig->dig_min_1 = 0x25; + dm_dig->media_connect_0 = false; + dm_dig->media_connect_1 = false; + rtlpriv->dm.dm_initialgain_enable = true; +} + +static u8 rtl88e_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_dig = &rtlpriv->dm_digtable; + long rssi_val_min = 0; + + if ((dm_dig->curmultista_cstate == DIG_MULTISTA_CONNECT) && + (dm_dig->cursta_cstate == DIG_STA_CONNECT)) { + if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0) + rssi_val_min = + (rtlpriv->dm.entry_min_undec_sm_pwdb > + rtlpriv->dm.undec_sm_pwdb) ? + rtlpriv->dm.undec_sm_pwdb : + rtlpriv->dm.entry_min_undec_sm_pwdb; + else + rssi_val_min = rtlpriv->dm.undec_sm_pwdb; + } else if (dm_dig->cursta_cstate == DIG_STA_CONNECT || + dm_dig->cursta_cstate == DIG_STA_BEFORE_CONNECT) { + rssi_val_min = rtlpriv->dm.undec_sm_pwdb; + } else if (dm_dig->curmultista_cstate == + DIG_MULTISTA_CONNECT) { + rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb; + } + return (u8)rssi_val_min; +} + +static void rtl88e_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) +{ + u32 ret_value; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct false_alarm_statistics *alm_cnt = &(rtlpriv->falsealm_cnt); + + rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 1); + rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 1); + + ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD); + alm_cnt->cnt_fast_fsync_fail = (ret_value&0xffff); + alm_cnt->cnt_sb_search_fail = ((ret_value&0xffff0000)>>16); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); + alm_cnt->cnt_ofdm_cca = (ret_value&0xffff); + alm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); + alm_cnt->cnt_rate_illegal = (ret_value & 0xffff); + alm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); + alm_cnt->cnt_mcs_fail = (ret_value & 0xffff); + alm_cnt->cnt_ofdm_fail = alm_cnt->cnt_parity_fail + + alm_cnt->cnt_rate_illegal + + alm_cnt->cnt_crc8_fail + + alm_cnt->cnt_mcs_fail + + alm_cnt->cnt_fast_fsync_fail + + alm_cnt->cnt_sb_search_fail; + + ret_value = rtl_get_bbreg(hw, REG_SC_CNT, MASKDWORD); + alm_cnt->cnt_bw_lsc = (ret_value & 0xffff); + alm_cnt->cnt_bw_usc = ((ret_value & 0xffff0000) >> 16); + + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(12), 1); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); + + ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); + alm_cnt->cnt_cck_fail = ret_value; + + ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3); + alm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; + + ret_value = rtl_get_bbreg(hw, RCCK0_CCA_CNT, MASKDWORD); + alm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) | + ((ret_value&0xFF00)>>8); + + alm_cnt->cnt_all = alm_cnt->cnt_fast_fsync_fail + + alm_cnt->cnt_sb_search_fail + + alm_cnt->cnt_parity_fail + + alm_cnt->cnt_rate_illegal + + alm_cnt->cnt_crc8_fail + + alm_cnt->cnt_mcs_fail + + alm_cnt->cnt_cck_fail; + alm_cnt->cnt_cca_all = alm_cnt->cnt_ofdm_cca + alm_cnt->cnt_cck_cca; + + rtl_set_bbreg(hw, ROFDM0_TRSWISOLATION, BIT(31), 1); + rtl_set_bbreg(hw, ROFDM0_TRSWISOLATION, BIT(31), 0); + rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(27), 1); + rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(27), 0); + rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 0); + rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 0); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(13)|BIT(12), 0); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(13)|BIT(12), 2); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(15)|BIT(14), 0); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(15)|BIT(14), 2); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + "cnt_parity_fail = %d, cnt_rate_illegal = %d, " + "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", + alm_cnt->cnt_parity_fail, + alm_cnt->cnt_rate_illegal, + alm_cnt->cnt_crc8_fail, alm_cnt->cnt_mcs_fail); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", + alm_cnt->cnt_ofdm_fail, + alm_cnt->cnt_cck_fail, alm_cnt->cnt_all); +} + +static void rtl88e_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_dig = &rtlpriv->dm_digtable; + u8 cur_cck_cca_thresh; + + if (dm_dig->cursta_cstate == DIG_STA_CONNECT) { + dm_dig->rssi_val_min = rtl88e_dm_initial_gain_min_pwdb(hw); + if (dm_dig->rssi_val_min > 25) { + cur_cck_cca_thresh = 0xcd; + } else if ((dm_dig->rssi_val_min <= 25) && + (dm_dig->rssi_val_min > 10)) { + cur_cck_cca_thresh = 0x83; + } else { + if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000) + cur_cck_cca_thresh = 0x83; + else + cur_cck_cca_thresh = 0x40; + } + + } else { + if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000) + cur_cck_cca_thresh = 0x83; + else + cur_cck_cca_thresh = 0x40; + } + + if (dm_dig->cur_cck_cca_thres != cur_cck_cca_thresh) + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, cur_cck_cca_thresh); + + dm_dig->cur_cck_cca_thres = cur_cck_cca_thresh; + dm_dig->pre_cck_cca_thres = dm_dig->cur_cck_cca_thres; + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + "CCK cca thresh hold =%x\n", dm_dig->cur_cck_cca_thres); +} + +static void rtl88e_dm_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_dig = &rtlpriv->dm_digtable; + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 dig_min, dig_maxofmin; + bool bfirstconnect; + u8 dm_dig_max, dm_dig_min; + u8 current_igi = dm_dig->cur_igvalue; + + if (rtlpriv->dm.dm_initialgain_enable == false) + return; + if (dm_dig->dig_enable_flag == false) + return; + if (mac->act_scanning == true) + return; + + if (mac->link_state >= MAC80211_LINKED) + dm_dig->cursta_cstate = DIG_STA_CONNECT; + else + dm_dig->cursta_cstate = DIG_STA_DISCONNECT; + if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP || + rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) + dm_dig- |