summaryrefslogtreecommitdiffstats
path: root/target/linux/realtek/files/drivers/net/wireless/rtl8192cd/8812_hw.c
diff options
context:
space:
mode:
authorArtur Artamonov <freeartman@wechall.net>2013-08-21 16:52:55 +0300
committerArtur Artamonov <freeartman@wechall.net>2013-08-21 16:52:55 +0300
commitd4bc867ac3afd260e4256e1463b273083769a363 (patch)
tree81c868f33d397d9b61de9ef00c8303fecc9195ca /target/linux/realtek/files/drivers/net/wireless/rtl8192cd/8812_hw.c
parent2789830761da86a4537ab198203138c082b3058e (diff)
parent6e8428d78c98c653f625aa0839437359306f99db (diff)
Merge branch 'realtek-unstable' of git://213.175.90.206/openwrt-realtek into realtek-unstable
Diffstat (limited to 'target/linux/realtek/files/drivers/net/wireless/rtl8192cd/8812_hw.c')
-rw-r--r--target/linux/realtek/files/drivers/net/wireless/rtl8192cd/8812_hw.c2771
1 files changed, 2771 insertions, 0 deletions
diff --git a/target/linux/realtek/files/drivers/net/wireless/rtl8192cd/8812_hw.c b/target/linux/realtek/files/drivers/net/wireless/rtl8192cd/8812_hw.c
new file mode 100644
index 000000000..91ad94b56
--- /dev/null
+++ b/target/linux/realtek/files/drivers/net/wireless/rtl8192cd/8812_hw.c
@@ -0,0 +1,2771 @@
+
+#define _8812_HW_C_
+
+#include "8192cd.h"
+#include "8192cd_cfg.h"
+#include "8192cd_util.h"
+
+#include "8192c_reg.h"
+#include "8812_reg.h"
+#include "8812_vht_gen.h"
+
+#ifdef __KERNEL__
+#include <linux/kernel.h>
+#endif
+//eric_8812 #include "8192cd_debug.h"
+#include "8192cd_headers.h"
+
+#ifdef CONFIG_RTL_8812_SUPPORT
+
+typedef struct _C2H_EVT_HDR{
+ u1Byte CmdID: 4;
+ u1Byte CmdLen: 4;
+ u1Byte CmdSeq;
+}C2H_EVT_HDR, *PC2H_EVT_HDR;
+
+typedef enum _RTL8812_C2H_EVT
+{
+ C2H_8812_DBG = 0,
+ C2H_8812_LB = 1,
+ C2H_8812_TXBF = 2,
+ MAX_8812_C2HEVENT
+}RTL8812_C2H_EVT;
+void UpdateBBRFVal8812(struct rtl8192cd_priv *priv, unsigned char channel)
+{
+ unsigned char current_is_5g = 0, switch_bw = 0;
+ unsigned char bTmp = 0;
+ unsigned int dwTmp = 0;
+ unsigned int tmp_cb0=0, tmp_eb0 = 0; //for_8812_mp_chip
+ unsigned int eRFPath, curMaxRFPath;
+
+ curMaxRFPath = RF92CD_PATH_MAX;
+
+ //check CCK_CHECK_en BIT7
+ if ( RTL_R8(0x454) & BIT(7) )
+ current_is_5g = 1;
+ else
+ current_is_5g = 0;
+
+ if (((channel > 14) && (current_is_5g == 0)) || ((channel <= 14) && (current_is_5g == 1)))
+ switch_bw = 1;
+
+ //printk("\n\n eric-current_is_5g = %d switch_bw = %d pre= %d\n\n", current_is_5g, switch_bw, priv->pshare->pre_channel);
+
+ if (channel > 14 && (switch_bw || (priv->pshare->pre_channel == 0))) //2.4G to 5G
+ RTL_W8(0x454, (RTL_R8(0x454) | BIT(7)));
+
+ //Set fc_area 0x860
+ dwTmp = RTL_R32(0x860);
+ dwTmp &= ~(BIT(17) | BIT(18) | BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23) | BIT(24) | BIT(25) | BIT(26) | BIT(27) | BIT(28));
+
+ if (channel <= 14)
+ dwTmp |= (0x96a << 17);
+ else if (channel <= 48)
+ dwTmp |= (0x494 << 17);
+ else if (channel <= 64)
+ dwTmp |= (0x453 << 17);
+ else if (channel <= 116)
+ dwTmp |= (0x452 << 17);
+ else if (channel <= 177)
+ dwTmp |= (0x412 << 17);
+
+ RTL_W32(0x860, dwTmp);
+
+ //Set RF MOD AG rf_0x18
+ for (eRFPath = RF92CD_PATH_A; eRFPath < curMaxRFPath; eRFPath++) {
+ dwTmp = PHY_QueryRFReg(priv, eRFPath, rRfChannel, bMask20Bits, 1);
+ dwTmp &= ~(BIT(8) | BIT(9) | BIT(16) | BIT(17) | BIT(18));
+
+ if (channel <= 14)
+ dwTmp |= 0x0;
+ else if (channel <= 64)
+ dwTmp |= (BIT(8) | BIT(16));
+ else if (channel <= 140)
+ dwTmp |= (BIT(8) | BIT(16) | BIT(17));
+ else
+ dwTmp |= (BIT(8) | BIT(16) | BIT(18));
+
+ PHY_SetRFReg(priv, eRFPath, rRfChannel, bMask20Bits, dwTmp);
+ }
+
+ //Set BB registers //for_8812_mp_chip
+ if (switch_bw) {
+ if (!IS_TEST_CHIP(priv)) {
+ tmp_cb0 = RTL_R32(0xcb0);
+ tmp_cb0 &= ~(BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23));
+ tmp_eb0 = RTL_R32(0xeb0);
+ tmp_eb0 &= ~(BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23));
+ }
+
+ if (!current_is_5g) {
+ bTmp = RTL_R8(0x82c);
+ bTmp &= ~(BIT(0) | BIT(1));
+ bTmp |= BIT(0);
+ RTL_W8(0x82c, bTmp);
+ if (GET_CHIP_VER(priv) == VERSION_8881A) {
+ PHY_SetBBReg(priv, 0xcb0, 0xff, 0x55);
+ PHY_SetBBReg(priv, 0xcb0, 0xf000, 0x1);
+ } else {
+ if (IS_TEST_CHIP(priv)) {
+ RTL_W32(0xcb8, RTL_R32(0xcb8) | BIT(12));
+ RTL_W32(0xeb8, RTL_R32(0xcb8) | BIT(12));
+ RTL_W32(0xcb8, RTL_R32(0xcb8) & (~BIT(15)));
+ RTL_W32(0xeb8, RTL_R32(0xeb8) & (~BIT(15)));
+ } else {
+ if (priv->pmib->dot11RFEntry.pa_type == 1) {
+ RTL_W32(0xcb0, tmp_cb0 | (0x53 << 16));
+ RTL_W32(0xeb0, tmp_eb0 | (0x53 << 16));
+ } else {
+ RTL_W32(0xcb0, tmp_cb0 | (0x54 << 16));
+ RTL_W32(0xeb0, tmp_eb0 | (0x54 << 16));
+ }
+ }
+ }
+
+ RTL_W32(0x808, RTL_R32(0x808) & (~BIT(28)));
+ RTL_W32(0x8c0, RTL_R32(0x8c0) & (~BIT(17)));
+ } else {
+ bTmp = RTL_R8(0x82c);
+ bTmp &= ~(BIT(0) | BIT(1));
+ RTL_W8(0x82c, bTmp);
+
+ if (IS_TEST_CHIP(priv)) {
+ RTL_W32(0xcb8, RTL_R32(0xcb8) & (~BIT(12)));
+ RTL_W32(0xeb8, RTL_R32(0xcb8) & (~BIT(12)));
+ RTL_W32(0xcb8, RTL_R32(0xcb8) | BIT(15));
+ RTL_W32(0xeb8, RTL_R32(0xeb8) | BIT(15));
+ } else {
+ RTL_W32(0xcb0, tmp_cb0 | (0x77 << 16));
+ RTL_W32(0xeb0, tmp_eb0 | (0x77 << 16));
+ }
+
+ RTL_W32(0x808, RTL_R32(0x808) | BIT(28));
+ RTL_W32(0x8c0, RTL_R32(0x8c0) | BIT(17));
+ }
+ } else if (priv->pshare->pre_channel == 0) { //first launch
+ if (channel > 14) {
+ bTmp = RTL_R8(0x82c);
+ bTmp &= ~(BIT(0) | BIT(1));
+ bTmp |= BIT(0);
+ RTL_W8(0x82c, bTmp);
+
+ if (IS_TEST_CHIP(priv)) {
+ RTL_W32(0xcb8, RTL_R32(0xcb8) | BIT(12));
+ RTL_W32(0xeb8, RTL_R32(0xcb8) | BIT(12));
+ RTL_W32(0xcb8, RTL_R32(0xcb8) & (~BIT(15)));
+ RTL_W32(0xeb8, RTL_R32(0xeb8) & (~BIT(15)));
+ } else {
+ if (priv->pmib->dot11RFEntry.pa_type == 1) {
+ RTL_W32(0xcb0, tmp_cb0 | (0x53 << 16));
+ RTL_W32(0xeb0, tmp_eb0 | (0x53 << 16));
+ } else {
+ RTL_W32(0xcb0, tmp_cb0 | (0x54 << 16));
+ RTL_W32(0xeb0, tmp_eb0 | (0x54 << 16));
+ }
+ }
+
+ RTL_W32(0x808, RTL_R32(0x808) & (~BIT(28)));
+ RTL_W32(0x8c0, RTL_R32(0x8c0) & (~BIT(17)));
+ } else {
+ bTmp = RTL_R8(0x82c);
+ bTmp &= ~(BIT(0) | BIT(1));
+ RTL_W8(0x82c, bTmp);
+ if (GET_CHIP_VER(priv) == VERSION_8881A) {
+ PHY_SetBBReg(priv, 0xcb0, 0xff, 0x00);
+ PHY_SetBBReg(priv, 0xcb0, 0xf000, 0x0);
+ } else {
+
+ if (IS_TEST_CHIP(priv)) {
+ RTL_W32(0xcb8, RTL_R32(0xcb8) & (~BIT(12)));
+ RTL_W32(0xeb8, RTL_R32(0xcb8) & (~BIT(12)));
+ RTL_W32(0xcb8, RTL_R32(0xcb8) | BIT(15));
+ RTL_W32(0xeb8, RTL_R32(0xeb8) | BIT(15));
+ } else {
+ RTL_W32(0xcb0, tmp_cb0 | (0x77 << 16));
+ RTL_W32(0xeb0, tmp_eb0 | (0x77 << 16));
+ }
+ }
+ RTL_W32(0x808, RTL_R32(0x808) | BIT(28));
+ RTL_W32(0x8c0, RTL_R32(0x8c0) | BIT(17));
+ }
+ }
+
+ if (channel <= 14 && (switch_bw || (priv->pshare->pre_channel == 0)))
+ RTL_W8(0x454, (RTL_R8(0x454) & ~(BIT(7))));
+
+ priv->pshare->pre_channel = channel;
+
+}
+
+signed char convert_diff(signed char value)
+{
+ // range from -8 ~ 7
+ if (value <= 7)
+ return value;
+ else
+ return (value - 16);
+}
+
+void Write_OFDM_A(struct rtl8192cd_priv *priv, unsigned int writeVal)
+{
+ RTL_W32(rTxAGC_A_Ofdm18_Ofdm6_JAguar, writeVal);
+ RTL_W32(rTxAGC_A_Ofdm54_Ofdm24_JAguar, writeVal);
+}
+
+void Write_1S_A(struct rtl8192cd_priv *priv, unsigned int writeVal)
+{
+ RTL_W32(rTxAGC_A_MCS3_MCS0_JAguar, writeVal);
+ RTL_W32(rTxAGC_A_MCS7_MCS4_JAguar, writeVal);
+ RTL_W32(rTxAGC_A_Nss1Index3_Nss1Index0_JAguar, writeVal);
+ RTL_W32(rTxAGC_A_Nss1Index7_Nss1Index4_JAguar, writeVal);
+ RTL_W32(rTxAGC_A_Nss2Index1_Nss1Index8_JAguar, writeVal);
+}
+
+void Write_2S_A(struct rtl8192cd_priv *priv, unsigned int writeVal)
+{
+ RTL_W32(rTxAGC_A_MCS11_MCS8_JAguar, writeVal);
+ RTL_W32(rTxAGC_A_MCS15_MCS12_JAguar, writeVal);
+ RTL_W32(rTxAGC_A_Nss2Index5_Nss2Index2_JAguar, writeVal);
+ RTL_W32(rTxAGC_A_Nss2Index9_Nss2Index6_JAguar, writeVal);
+ writeVal = (writeVal & 0xffff0000) | (RTL_R32(rTxAGC_A_Nss2Index1_Nss1Index8_JAguar) & 0xffff);
+ RTL_W32(rTxAGC_A_Nss2Index1_Nss1Index8_JAguar, writeVal);
+}
+
+void Write_OFDM_B(struct rtl8192cd_priv *priv, unsigned int writeVal)
+{
+ RTL_W32(rTxAGC_B_Ofdm18_Ofdm6_JAguar, writeVal);
+ RTL_W32(rTxAGC_B_Ofdm54_Ofdm24_JAguar, writeVal);
+}
+
+
+void Write_1S_B(struct rtl8192cd_priv *priv, unsigned int writeVal)
+{
+ RTL_W32(rTxAGC_B_MCS3_MCS0_JAguar, writeVal);
+ RTL_W32(rTxAGC_B_MCS7_MCS4_JAguar, writeVal);
+ RTL_W32(rTxAGC_B_Nss1Index3_Nss1Index0_JAguar, writeVal);
+ RTL_W32(rTxAGC_B_Nss1Index7_Nss1Index4_JAguar, writeVal);
+ RTL_W32(rTxAGC_B_Nss2Index1_Nss1Index8_JAguar, writeVal);
+}
+
+void Write_2S_B(struct rtl8192cd_priv *priv, unsigned int writeVal)
+{
+ RTL_W32(rTxAGC_B_MCS11_MCS8_JAguar, writeVal);
+ RTL_W32(rTxAGC_B_MCS15_MCS12_JAguar, writeVal);
+ RTL_W32(rTxAGC_B_Nss2Index5_Nss2Index2_JAguar, writeVal);
+ RTL_W32(rTxAGC_B_Nss2Index9_Nss2Index6_JAguar, writeVal);
+ writeVal = (writeVal & 0xffff0000) | (RTL_R32(rTxAGC_A_Nss2Index1_Nss1Index8_JAguar) & 0xffff);
+ RTL_W32(rTxAGC_B_Nss2Index1_Nss1Index8_JAguar, writeVal);
+}
+
+void use_DefaultOFDMTxPower_8812(struct rtl8192cd_priv *priv)
+{
+
+ unsigned int def_power = 0x20202020;//0x12121212;
+ //printk("NO Calibration data, use default OFDM power = 0x%x\n", def_power);
+
+ RTL_W32(rTxAGC_A_Ofdm18_Ofdm6_JAguar, def_power);
+ RTL_W32(rTxAGC_A_Ofdm54_Ofdm24_JAguar, def_power);
+ RTL_W32(rTxAGC_A_MCS3_MCS0_JAguar, def_power);
+ RTL_W32(rTxAGC_A_MCS7_MCS4_JAguar, def_power);
+ RTL_W32(rTxAGC_A_MCS11_MCS8_JAguar, def_power);
+ RTL_W32(rTxAGC_A_MCS15_MCS12_JAguar, def_power);
+ RTL_W32(rTxAGC_A_Nss1Index3_Nss1Index0_JAguar, def_power);
+ RTL_W32(rTxAGC_A_Nss1Index7_Nss1Index4_JAguar, def_power);
+ RTL_W32(rTxAGC_A_Nss2Index1_Nss1Index8_JAguar, def_power);
+ RTL_W32(rTxAGC_A_Nss2Index5_Nss2Index2_JAguar, def_power);
+ RTL_W32(rTxAGC_A_Nss2Index9_Nss2Index6_JAguar, def_power);
+
+ RTL_W32(rTxAGC_B_Ofdm18_Ofdm6_JAguar, def_power);
+ RTL_W32(rTxAGC_B_Ofdm54_Ofdm24_JAguar, def_power);
+ RTL_W32(rTxAGC_B_MCS3_MCS0_JAguar, def_power);
+ RTL_W32(rTxAGC_B_MCS7_MCS4_JAguar, def_power);
+ RTL_W32(rTxAGC_B_MCS11_MCS8_JAguar, def_power);
+ RTL_W32(rTxAGC_B_MCS15_MCS12_JAguar, def_power);
+ RTL_W32(rTxAGC_B_Nss1Index3_Nss1Index0_JAguar, def_power);
+ RTL_W32(rTxAGC_B_Nss1Index7_Nss1Index4_JAguar, def_power);
+ RTL_W32(rTxAGC_B_Nss2Index1_Nss1Index8_JAguar, def_power);
+ RTL_W32(rTxAGC_B_Nss2Index5_Nss2Index2_JAguar, def_power);
+ RTL_W32(rTxAGC_B_Nss2Index9_Nss2Index6_JAguar, def_power);
+
+}
+
+
+void Cal_OFDMTxPower_5G(struct rtl8192cd_priv *priv, unsigned char ch_idx)
+{
+ unsigned char tmp_TPI = 0;
+ unsigned char pwr_40_1s = 0;
+ signed char diff_ofdm_1t = 0;
+ signed char diff_bw40_2s = 0;
+ signed char diff_bw20_1s = 0;
+ signed char diff_bw20_2s = 0;
+ signed char diff_bw80_1s = 0;
+ signed char diff_bw80_2s = 0;
+
+ unsigned int writeVal = 0;
+
+ if ((priv->pmib->dot11RFEntry.pwrlevel5GHT40_1S_A[ch_idx] == 0)
+ || (priv->pmib->dot11RFEntry.pwrlevel5GHT40_1S_B[ch_idx] == 0)) {
+ use_DefaultOFDMTxPower_8812(priv);
+ return;
+ }
+
+ // PATH A, OFDM
+ pwr_40_1s = priv->pmib->dot11RFEntry.pwrlevel5GHT40_1S_A[ch_idx];
+ diff_ofdm_1t = (priv->pmib->dot11RFEntry.pwrdiff_5G_20BW1S_OFDM1T_A[ch_idx] & 0x0f);
+ diff_ofdm_1t = convert_diff(diff_ofdm_1t);
+ tmp_TPI = pwr_40_1s + diff_ofdm_1t;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_OFDM_A(priv, writeVal);
+
+ //printk("Write_OFDM_A %d = %d + %d \n", tmp_TPI, pwr_40_1s , diff_ofdm_1t);
+
+
+ // PATH B, OFDM
+ pwr_40_1s = priv->pmib->dot11RFEntry.pwrlevel5GHT40_1S_B[ch_idx];
+ diff_ofdm_1t = (priv->pmib->dot11RFEntry.pwrdiff_5G_20BW1S_OFDM1T_B[ch_idx] & 0x0f);
+ diff_ofdm_1t = convert_diff(diff_ofdm_1t);
+ tmp_TPI = pwr_40_1s + diff_ofdm_1t;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_OFDM_B(priv, writeVal);
+
+ //printk("Write_OFDM_A %d = %d + %d \n", tmp_TPI, pwr_40_1s , diff_ofdm_1t);
+
+
+ if (priv->pmib->dot11nConfigEntry.dot11nUse40M == 0) {
+ //PATH A, BW20-1S
+ pwr_40_1s = priv->pmib->dot11RFEntry.pwrlevel5GHT40_1S_A[ch_idx];
+ diff_bw20_1s = ((priv->pmib->dot11RFEntry.pwrdiff_5G_20BW1S_OFDM1T_A[ch_idx] & 0xf0) >> 4);
+ diff_bw20_1s = convert_diff(diff_bw20_1s);
+ tmp_TPI = pwr_40_1s + diff_bw20_1s;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_1S_A(priv, writeVal);
+
+ //printk("Write_1S_A %d = %d + %d \n", tmp_TPI, pwr_40_1s , diff_bw20_1s);
+
+
+ //PATH A, BW20-2S
+ diff_bw20_2s = (priv->pmib->dot11RFEntry.pwrdiff_5G_40BW2S_20BW2S_A[ch_idx] & 0x0f);
+ diff_bw20_2s = convert_diff(diff_bw20_2s);
+ tmp_TPI = pwr_40_1s + diff_bw20_1s + diff_bw20_2s;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_2S_A(priv, writeVal);
+
+ //printk("Write_2S_A %d = %d + %d + %d\n", tmp_TPI, pwr_40_1s , diff_bw20_1s, diff_bw20_2s);
+
+ // ==== //
+
+ //PATH B, BW20-1S
+ pwr_40_1s = priv->pmib->dot11RFEntry.pwrlevel5GHT40_1S_B[ch_idx];
+ diff_bw20_1s = ((priv->pmib->dot11RFEntry.pwrdiff_5G_20BW1S_OFDM1T_B[ch_idx] & 0xf0) >> 4);
+ diff_bw20_1s = convert_diff(diff_bw20_1s);
+ tmp_TPI = pwr_40_1s + diff_bw20_1s;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_1S_B(priv, writeVal);
+
+ //printk("Write_1S_B %d = %d + %d \n", tmp_TPI, pwr_40_1s , diff_bw20_1s);
+
+ //PATH B, BW20-2S
+ diff_bw20_2s = (priv->pmib->dot11RFEntry.pwrdiff_5G_40BW2S_20BW2S_B[ch_idx] & 0x0f);
+ diff_bw20_2s = convert_diff(diff_bw20_2s);
+ tmp_TPI = pwr_40_1s + diff_bw20_1s + diff_bw20_2s;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_2S_B(priv, writeVal);
+
+ //printk("Write_2S_B %d = %d + %d + %d\n", tmp_TPI, pwr_40_1s , diff_bw20_1s, diff_bw20_2s);
+
+ } else if (priv->pmib->dot11nConfigEntry.dot11nUse40M == 1) {
+ //PATH A, BW40-1S
+ pwr_40_1s = priv->pmib->dot11RFEntry.pwrlevel5GHT40_1S_A[ch_idx];
+ tmp_TPI = pwr_40_1s ;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_1S_A(priv, writeVal);
+
+ //printk("Write_1S_A %d = %d \n", tmp_TPI, pwr_40_1s);
+
+
+ //PATH A, BW40-2S
+ diff_bw40_2s = ((priv->pmib->dot11RFEntry.pwrdiff_5G_40BW2S_20BW2S_A[ch_idx] & 0xf0) >> 4);
+ diff_bw40_2s = convert_diff(diff_bw40_2s);
+ tmp_TPI = pwr_40_1s + diff_bw40_2s;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_2S_A(priv, writeVal);
+
+ //printk("Write_2S_A %d = %d + %d \n", tmp_TPI, pwr_40_1s , diff_bw40_2s);
+
+ // ==== //
+
+ //PATH B, BW40-1S
+ pwr_40_1s = priv->pmib->dot11RFEntry.pwrlevel5GHT40_1S_B[ch_idx];
+ tmp_TPI = pwr_40_1s ;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_1S_B(priv, writeVal);
+
+ //printk("Write_1S_B %d = %d \n", tmp_TPI, pwr_40_1s);
+
+
+ //PATH A, BW40-2S
+ diff_bw40_2s = ((priv->pmib->dot11RFEntry.pwrdiff_5G_40BW2S_20BW2S_B[ch_idx] & 0xf0) >> 4);
+ diff_bw40_2s = convert_diff(diff_bw40_2s);
+ tmp_TPI = pwr_40_1s + diff_bw40_2s;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_2S_B(priv, writeVal);
+
+ //printk("Write_2S_B %d = %d + %d \n", tmp_TPI, pwr_40_1s , diff_bw40_2s);
+
+ } else if (priv->pmib->dot11nConfigEntry.dot11nUse40M == 2) {
+ //PATH A, BW80-1S
+ pwr_40_1s = (priv->pmib->dot11RFEntry.pwrlevel5GHT40_1S_A[ch_idx - 4] +
+ priv->pmib->dot11RFEntry.pwrlevel5GHT40_1S_A[ch_idx + 4]) / 2 ;
+ diff_bw80_1s = ((priv->pmib->dot11RFEntry.pwrdiff_5G_80BW1S_160BW1S_A[ch_idx] & 0xf0) >> 4);
+ diff_bw80_1s = convert_diff(diff_bw80_1s);
+ tmp_TPI = pwr_40_1s + diff_bw80_1s;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_1S_A(priv, writeVal);
+
+ //printk("Write_1S_A %d = %d + %d \n", tmp_TPI, pwr_40_1s , diff_bw80_1s);
+
+
+ //PATH A, BW80-2S
+ diff_bw80_2s = ((priv->pmib->dot11RFEntry.pwrdiff_5G_80BW2S_160BW2S_A[ch_idx] & 0xf0) >> 4);
+ diff_bw80_2s = convert_diff(diff_bw80_2s);
+ tmp_TPI = pwr_40_1s + diff_bw80_1s + diff_bw80_1s;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_2S_A(priv, writeVal);
+
+ //printk("Write_2S_A %d = %d + %d + %d \n", tmp_TPI, pwr_40_1s , diff_bw80_1s, diff_bw80_1s);
+
+
+ //PATH B, BW80-1S
+ pwr_40_1s = (priv->pmib->dot11RFEntry.pwrlevel5GHT40_1S_B[ch_idx - 4] +
+ priv->pmib->dot11RFEntry.pwrlevel5GHT40_1S_B[ch_idx + 4]) / 2 ;
+ diff_bw80_1s = ((priv->pmib->dot11RFEntry.pwrdiff_5G_80BW1S_160BW1S_B[ch_idx] & 0xf0) >> 4);
+ diff_bw80_1s = convert_diff(diff_bw80_1s);
+ tmp_TPI = pwr_40_1s + diff_bw80_1s;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_1S_B(priv, writeVal);
+
+ //printk("Write_1S_B %d = %d + %d \n", tmp_TPI, pwr_40_1s , diff_bw80_1s);
+
+
+ //PATH B, BW80-2S
+ diff_bw80_2s = ((priv->pmib->dot11RFEntry.pwrdiff_5G_80BW2S_160BW2S_B[ch_idx] & 0xf0) >> 4);
+ diff_bw80_2s = convert_diff(diff_bw80_2s);
+ tmp_TPI = pwr_40_1s + diff_bw80_1s + diff_bw80_1s;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_2S_B(priv, writeVal);
+
+ //printk("Write_2S_B %d = %d + %d + %d \n", tmp_TPI, pwr_40_1s , diff_bw80_1s, diff_bw80_1s);
+
+ }
+}
+
+void Cal_OFDMTxPower_2G(struct rtl8192cd_priv *priv, unsigned char ch_idx)
+{
+ unsigned char tmp_TPI = 0;
+ unsigned char pwr_40_1s = 0;
+ signed char diff_ofdm_1t = 0;
+ signed char diff_bw40_2s = 0;
+ signed char diff_bw20_1s = 0;
+ signed char diff_bw20_2s = 0;
+
+ unsigned int writeVal = 0;
+
+ if ((priv->pmib->dot11RFEntry.pwrlevelHT40_1S_A[ch_idx] == 0)
+ || (priv->pmib->dot11RFEntry.pwrlevelHT40_1S_B[ch_idx] == 0)) {
+ use_DefaultOFDMTxPower_8812(priv);
+ return;
+ }
+
+ // PATH A, OFDM
+ pwr_40_1s = priv->pmib->dot11RFEntry.pwrlevelHT40_1S_A[ch_idx];
+ diff_ofdm_1t = (priv->pmib->dot11RFEntry.pwrdiff_20BW1S_OFDM1T_A[ch_idx] & 0x0f);
+ diff_ofdm_1t = convert_diff(diff_ofdm_1t);
+ tmp_TPI = pwr_40_1s + diff_ofdm_1t;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_OFDM_A(priv, writeVal);
+
+
+ // PATH B, OFDM
+ pwr_40_1s = priv->pmib->dot11RFEntry.pwrlevelHT40_1S_B[ch_idx];
+ diff_ofdm_1t = (priv->pmib->dot11RFEntry.pwrdiff_20BW1S_OFDM1T_B[ch_idx] & 0x0f);
+ diff_ofdm_1t = convert_diff(diff_ofdm_1t);
+ tmp_TPI = pwr_40_1s + diff_ofdm_1t;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_OFDM_B(priv, writeVal);
+
+ if (priv->pmib->dot11nConfigEntry.dot11nUse40M == 0) {
+ //PATH A, BW20-1S
+ pwr_40_1s = priv->pmib->dot11RFEntry.pwrlevelHT40_1S_A[ch_idx];
+ diff_bw20_1s = ((priv->pmib->dot11RFEntry.pwrdiff_20BW1S_OFDM1T_A[ch_idx] & 0xf0) >> 4);
+ diff_bw20_1s = convert_diff(diff_bw20_1s);
+ tmp_TPI = pwr_40_1s + diff_bw20_1s;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_1S_A(priv, writeVal);
+
+
+ //PATH A, BW20-2S
+ diff_bw20_2s = (priv->pmib->dot11RFEntry.pwrdiff_40BW2S_20BW2S_A[ch_idx] & 0x0f);
+ diff_bw20_2s = convert_diff(diff_bw20_2s);
+ tmp_TPI = pwr_40_1s + diff_bw20_1s + diff_bw20_2s;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_2S_A(priv, writeVal);
+
+ // ==== //
+
+ //PATH B, BW20-1S
+ pwr_40_1s = priv->pmib->dot11RFEntry.pwrlevelHT40_1S_B[ch_idx];
+ diff_bw20_1s = ((priv->pmib->dot11RFEntry.pwrdiff_20BW1S_OFDM1T_B[ch_idx] & 0xf0) >> 4);
+ diff_bw20_1s = convert_diff(diff_bw20_1s);
+ tmp_TPI = pwr_40_1s + diff_bw20_1s;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_1S_B(priv, writeVal);
+
+ //PATH B, BW20-2S
+ diff_bw20_2s = (priv->pmib->dot11RFEntry.pwrdiff_40BW2S_20BW2S_B[ch_idx] & 0x0f);
+ diff_bw20_2s = convert_diff(diff_bw20_2s);
+ tmp_TPI = pwr_40_1s + diff_bw20_1s + diff_bw20_2s;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_2S_B(priv, writeVal);
+
+ } else if (priv->pmib->dot11nConfigEntry.dot11nUse40M == 1) {
+ //PATH A, BW40-1S
+ pwr_40_1s = priv->pmib->dot11RFEntry.pwrlevelHT40_1S_A[ch_idx];
+ tmp_TPI = pwr_40_1s ;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_1S_A(priv, writeVal);
+
+
+ //PATH A, BW40-2S
+ diff_bw40_2s = ((priv->pmib->dot11RFEntry.pwrdiff_40BW2S_20BW2S_A[ch_idx] & 0xf0) >> 4);
+ diff_bw40_2s = convert_diff(diff_bw40_2s);
+ tmp_TPI = pwr_40_1s + diff_bw40_2s;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_2S_A(priv, writeVal);
+
+ // ==== //
+
+ //PATH B, BW40-1S
+ pwr_40_1s = priv->pmib->dot11RFEntry.pwrlevelHT40_1S_B[ch_idx];
+ tmp_TPI = pwr_40_1s ;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_1S_B(priv, writeVal);
+
+
+ //PATH A, BW40-2S
+ diff_bw40_2s = ((priv->pmib->dot11RFEntry.pwrdiff_40BW2S_20BW2S_B[ch_idx] & 0xf0) >> 4);
+ diff_bw40_2s = convert_diff(diff_bw40_2s);
+ tmp_TPI = pwr_40_1s + diff_bw40_2s;
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ Write_2S_B(priv, writeVal);
+
+ }
+}
+#ifdef TX_PG_8812
+void get_tx_pwr(unsigned int tmp_dw, unsigned char *tmp_b1, unsigned char *tmp_b2,
+ unsigned char *tmp_b3, unsigned char *tmp_b4)
+{
+ *tmp_b1 = (tmp_dw & (0xff));
+ *tmp_b2 = ((tmp_dw & (0xff00)) >> 8);
+ *tmp_b3 = ((tmp_dw & (0xff0000)) >> 16);
+ *tmp_b4 = ((tmp_dw & (0xff000000)) >> 24);
+}
+
+void TxPG_CCK_8812(struct rtl8192cd_priv *priv)
+{
+ unsigned char b1, b2, b3, b4;
+ unsigned char* tmp_b1 = &b1;
+ unsigned char* tmp_b2 = &b2;
+ unsigned char* tmp_b3 = &b3;
+ unsigned char* tmp_b4 = &b4;
+ unsigned int tmp_dw = 0;
+ unsigned int writeVal = 0;
+
+ tmp_dw = RTL_R32(rTxAGC_A_CCK11_CCK1_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = (unsigned char)(POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->CCKTxAgc_A[3]));
+ *tmp_b2 = (unsigned char)(POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->CCKTxAgc_A[2]));
+ *tmp_b3 = (unsigned char)(POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->CCKTxAgc_A[1]));
+ *tmp_b4 = (unsigned char)(POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->CCKTxAgc_A[0]));
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_A_CCK11_CCK1_JAguar, writeVal);
+
+ tmp_dw = RTL_R32(rTxAGC_B_CCK11_CCK1_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = (unsigned char)(POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->CCKTxAgc_B[3]));
+ *tmp_b2 = (unsigned char)(POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->CCKTxAgc_B[2]));
+ *tmp_b3 = (unsigned char)(POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->CCKTxAgc_B[1]));
+ *tmp_b4 = (unsigned char)(POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->CCKTxAgc_B[0]));
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_B_CCK11_CCK1_JAguar, writeVal);
+}
+void TxPG_OFDM_8812_A(struct rtl8192cd_priv *priv)
+{
+ unsigned char b1, b2, b3, b4, b5;
+ unsigned char* tmp_b1 = &b1;
+ unsigned char* tmp_b2 = &b2;
+ unsigned char* tmp_b3 = &b3;
+ unsigned char* tmp_b4 = &b4;
+ unsigned char* tmp_b5 = &b5;
+ unsigned int tmp_dw = 0;
+ unsigned int tmp_dw1 =0;
+ unsigned int writeVal = 0;
+ //printk("TxPG_OFDM_8812_A!!\n");
+ tmp_dw = RTL_R32(rTxAGC_A_Ofdm18_Ofdm6_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->OFDMTxAgcOffset_A[3]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->OFDMTxAgcOffset_A[2]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->OFDMTxAgcOffset_A[1]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->OFDMTxAgcOffset_A[0]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_A_Ofdm18_Ofdm6_JAguar, writeVal);
+ tmp_dw = RTL_R32(rTxAGC_A_Ofdm54_Ofdm24_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->OFDMTxAgcOffset_A[7]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->OFDMTxAgcOffset_A[6]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->OFDMTxAgcOffset_A[5]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->OFDMTxAgcOffset_A[4]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_A_Ofdm54_Ofdm24_JAguar, writeVal);
+ tmp_dw = RTL_R32(rTxAGC_A_MCS3_MCS0_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->MCSTxAgcOffset_A[3]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->MCSTxAgcOffset_A[2]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->MCSTxAgcOffset_A[1]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->MCSTxAgcOffset_A[0]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_A_MCS3_MCS0_JAguar, writeVal);
+ tmp_dw = RTL_R32(rTxAGC_A_MCS7_MCS4_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->MCSTxAgcOffset_A[7]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->MCSTxAgcOffset_A[6]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->MCSTxAgcOffset_A[5]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->MCSTxAgcOffset_A[4]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_A_MCS7_MCS4_JAguar, writeVal);
+ tmp_dw = RTL_R32(rTxAGC_A_MCS11_MCS8_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->MCSTxAgcOffset_A[11]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->MCSTxAgcOffset_A[10]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->MCSTxAgcOffset_A[9]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->MCSTxAgcOffset_A[8]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_A_MCS11_MCS8_JAguar, writeVal);
+ tmp_dw = RTL_R32(rTxAGC_A_MCS15_MCS12_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->MCSTxAgcOffset_A[15]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->MCSTxAgcOffset_A[14]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->MCSTxAgcOffset_A[13]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->MCSTxAgcOffset_A[12]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_A_MCS15_MCS12_JAguar, writeVal);
+ tmp_dw = RTL_R32(rTxAGC_A_Nss1Index3_Nss1Index0_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->VHTTxAgcOffset_A[3]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->VHTTxAgcOffset_A[2]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->VHTTxAgcOffset_A[1]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->VHTTxAgcOffset_A[0]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_A_Nss1Index3_Nss1Index0_JAguar, writeVal);
+ tmp_dw = RTL_R32(rTxAGC_A_Nss1Index7_Nss1Index4_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->VHTTxAgcOffset_A[7]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->VHTTxAgcOffset_A[6]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->VHTTxAgcOffset_A[5]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->VHTTxAgcOffset_A[4]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_A_Nss1Index7_Nss1Index4_JAguar, writeVal);
+
+ tmp_dw = RTL_R32(rTxAGC_A_Nss2Index1_Nss1Index8_JAguar);
+ tmp_dw1= RTL_R32(rTxAGC_A_Nss1Index7_Nss1Index4_JAguar);
+ get_tx_pwr(tmp_dw1, tmp_b1, tmp_b2, tmp_b3, tmp_b5);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b5 - priv->pshare->phw->VHTTxAgcOffset_A[11]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b5 - priv->pshare->phw->VHTTxAgcOffset_A[10]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->VHTTxAgcOffset_A[9]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->VHTTxAgcOffset_A[8]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_A_Nss2Index1_Nss1Index8_JAguar, writeVal);
+
+ tmp_dw = RTL_R32(rTxAGC_A_Nss2Index5_Nss2Index2_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->VHTTxAgcOffset_A[15]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->VHTTxAgcOffset_A[14]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->VHTTxAgcOffset_A[13]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->VHTTxAgcOffset_A[12]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_A_Nss2Index5_Nss2Index2_JAguar, writeVal);
+
+ tmp_dw = RTL_R32(rTxAGC_A_Nss2Index9_Nss2Index6_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->VHTTxAgcOffset_A[19]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->VHTTxAgcOffset_A[18]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 - priv->pshare->phw->VHTTxAgcOffset_A[17]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 - priv->pshare->phw->VHTTxAgcOffset_A[16]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_A_Nss2Index9_Nss2Index6_JAguar, writeVal);
+}
+void TxPG_OFDM_8812_B(struct rtl8192cd_priv *priv)
+{
+ unsigned char b1, b2, b3, b4, b5;
+ unsigned char* tmp_b1 = &b1;
+ unsigned char* tmp_b2 = &b2;
+ unsigned char* tmp_b3 = &b3;
+ unsigned char* tmp_b4 = &b4;
+ unsigned char* tmp_b5 = &b5;
+ unsigned int tmp_dw = 0;
+ unsigned int tmp_dw1 =0;
+ unsigned int writeVal = 0;
+
+ //printk("TxPG_OFDM_8812_B!!\n");
+ tmp_dw = RTL_R32(rTxAGC_B_Ofdm18_Ofdm6_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->OFDMTxAgcOffset_B[3]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->OFDMTxAgcOffset_B[2]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->OFDMTxAgcOffset_B[1]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->OFDMTxAgcOffset_B[0]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_B_Ofdm18_Ofdm6_JAguar, writeVal);
+ tmp_dw = RTL_R32(rTxAGC_B_Ofdm54_Ofdm24_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->OFDMTxAgcOffset_B[7]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->OFDMTxAgcOffset_B[6]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->OFDMTxAgcOffset_B[5]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->OFDMTxAgcOffset_B[4]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_B_Ofdm54_Ofdm24_JAguar, writeVal);
+ tmp_dw = RTL_R32(rTxAGC_B_MCS3_MCS0_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->MCSTxAgcOffset_B[3]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->MCSTxAgcOffset_B[2]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->MCSTxAgcOffset_B[1]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->MCSTxAgcOffset_B[0]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_B_MCS3_MCS0_JAguar, writeVal);
+ tmp_dw = RTL_R32(rTxAGC_B_MCS7_MCS4_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->MCSTxAgcOffset_B[7]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->MCSTxAgcOffset_B[6]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->MCSTxAgcOffset_B[5]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->MCSTxAgcOffset_B[4]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_B_MCS7_MCS4_JAguar, writeVal);
+ tmp_dw = RTL_R32(rTxAGC_B_MCS11_MCS8_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->MCSTxAgcOffset_B[11]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->MCSTxAgcOffset_B[10]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->MCSTxAgcOffset_B[9]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->MCSTxAgcOffset_B[8]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_B_MCS11_MCS8_JAguar, writeVal);
+ tmp_dw = RTL_R32(rTxAGC_B_MCS15_MCS12_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->MCSTxAgcOffset_B[15]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->MCSTxAgcOffset_B[14]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->MCSTxAgcOffset_B[13]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->MCSTxAgcOffset_B[12]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_B_MCS15_MCS12_JAguar, writeVal);
+ tmp_dw = RTL_R32(rTxAGC_B_Nss1Index3_Nss1Index0_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->VHTTxAgcOffset_B[3]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->VHTTxAgcOffset_B[2]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->VHTTxAgcOffset_B[1]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->VHTTxAgcOffset_B[0]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_B_Nss1Index3_Nss1Index0_JAguar, writeVal);
+ tmp_dw = RTL_R32(rTxAGC_B_Nss1Index7_Nss1Index4_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->VHTTxAgcOffset_B[7]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->VHTTxAgcOffset_B[6]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->VHTTxAgcOffset_B[5]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->VHTTxAgcOffset_B[4]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_B_Nss1Index7_Nss1Index4_JAguar, writeVal);
+ tmp_dw = RTL_R32(rTxAGC_B_Nss2Index1_Nss1Index8_JAguar);
+ tmp_dw1= RTL_R32(rTxAGC_B_Nss1Index7_Nss1Index4_JAguar);
+ get_tx_pwr(tmp_dw1, tmp_b1, tmp_b2, tmp_b3, tmp_b5);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b5 - priv->pshare->phw->VHTTxAgcOffset_B[11]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b5 - priv->pshare->phw->VHTTxAgcOffset_B[10]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->VHTTxAgcOffset_B[9]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->VHTTxAgcOffset_B[8]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_B_Nss2Index1_Nss1Index8_JAguar, writeVal);
+ tmp_dw = RTL_R32(rTxAGC_B_Nss2Index5_Nss2Index2_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->VHTTxAgcOffset_B[15]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->VHTTxAgcOffset_B[14]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 + priv->pshare->phw->VHTTxAgcOffset_B[13]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 + priv->pshare->phw->VHTTxAgcOffset_B[12]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_B_Nss2Index5_Nss2Index2_JAguar, writeVal);
+ tmp_dw = RTL_R32(rTxAGC_B_Nss2Index9_Nss2Index6_JAguar);
+ get_tx_pwr(tmp_dw, tmp_b1, tmp_b2, tmp_b3, tmp_b4);
+ *tmp_b1 = POWER_RANGE_CHECK(*tmp_b1 + priv->pshare->phw->VHTTxAgcOffset_B[19]);
+ *tmp_b2 = POWER_RANGE_CHECK(*tmp_b2 + priv->pshare->phw->VHTTxAgcOffset_B[18]);
+ *tmp_b3 = POWER_RANGE_CHECK(*tmp_b3 - priv->pshare->phw->VHTTxAgcOffset_B[17]);
+ *tmp_b4 = POWER_RANGE_CHECK(*tmp_b4 - priv->pshare->phw->VHTTxAgcOffset_B[16]);
+ writeVal = (*tmp_b4 << 24) | (*tmp_b3 << 16) | (*tmp_b2 << 8) | *tmp_b1;
+ RTL_W32(rTxAGC_B_Nss2Index9_Nss2Index6_JAguar, writeVal);
+}
+#endif
+
+
+#ifdef TXPWR_LMT_8812
+
+unsigned char get_byte_from_dw(unsigned int tmp_dw, unsigned char byte_num)
+{
+
+ if (byte_num == 0)
+ return (tmp_dw & (0xff));
+ else if (byte_num == 1)
+ return ((tmp_dw & (0xff00)) >> 8);
+ else if (byte_num == 2)
+ return ((tmp_dw & (0xff0000)) >> 16);
+ else if (byte_num == 3)
+ return ((tmp_dw & (0xff000000)) >> 24);
+ else
+ return 0;
+}
+
+unsigned int assign_lmt_reg_value(struct rtl8192cd_priv *priv, unsigned int reg_offset, unsigned char max_idx, unsigned char max_idx2)
+{
+
+ unsigned int tmp_dw;
+ unsigned char reg_val[4];
+ unsigned char i=0;
+
+ tmp_dw = RTL_R32(reg_offset);
+
+ //printk("[0x%03x] 0x%08x >> ", reg_offset, tmp_dw);
+
+ get_tx_pwr(tmp_dw, (unsigned char *)&reg_val[0], (unsigned char *)&reg_val[1],
+ (unsigned char *)&reg_val[2], (unsigned char *)&reg_val[3]);
+
+ if((reg_offset == rTxAGC_A_Nss2Index1_Nss1Index8_JAguar) ||
+ (reg_offset == rTxAGC_B_Nss2Index1_Nss1Index8_JAguar))
+ {
+ reg_val[0] = POWER_MIN_CHECK(reg_val[0], max_idx);
+ reg_val[1] = POWER_MIN_CHECK(reg_val[1], max_idx);
+ reg_val[2] = POWER_MIN_CHECK(reg_val[2], max_idx2);
+ reg_val[3] = POWER_MIN_CHECK(reg_val[3], max_idx2);
+ }
+ else
+ {
+ for(i=0; i<4; i++)
+ {
+ reg_val[i] = POWER_MIN_CHECK(reg_val[i], max_idx);
+ }
+ }
+
+ for(i=0; i<4; i++)
+ {
+ reg_val[i] = POWER_RANGE_CHECK(reg_val[i]);
+ }
+
+ tmp_dw = (reg_val[3] << 24) | (reg_val[2] << 16) | (reg_val[1] << 8) | reg_val[0];
+
+ //printk("0x%08x\n", tmp_dw);
+
+ RTL_W32(reg_offset, tmp_dw);
+
+}
+
+void TxLMT_OFDM_8812_A(struct rtl8192cd_priv *priv)
+{
+
+ unsigned int tmp_dw = 0;
+
+ unsigned char idx_cck_11m = 0;
+ unsigned char idx_odfm_54m = 0;
+ unsigned char idx_ht_mcs7 = 0;
+ unsigned char idx_ht_mcs15 = 0;
+ unsigned char idx_vht_1ss_mcs7 =0;
+ unsigned char idx_vht_2ss_mcs7 =0;
+
+ char lmt_pg_idx_cck, lmt_pg_idx_ofdm = 0;
+ char lmt_pg_idx_ht1s, lmt_pg_idx_ht2s = 0;
+ char lmt_pg_idx_vht1s, lmt_pg_idx_vht2s = 0;
+
+ unsigned char max_lmt_idx_cck, max_lmt_idx_ofdm = 0;
+ unsigned char max_lmt_idx_ht1s, max_lmt_idx_ht2s = 0;
+ unsigned char max_lmt_idx_vht1s, max_lmt_idx_vht2s = 0;
+
+ lmt_pg_idx_cck = priv->pshare->txpwr_lmt_CCK - priv->pshare->tgpwr_CCK_new[0];
+ lmt_pg_idx_ofdm = priv->pshare->txpwr_lmt_OFDM - priv->pshare->tgpwr_OFDM_new[0];
+ lmt_pg_idx_ht1s = priv->pshare->txpwr_lmt_HT1S - priv->pshare->tgpwr_HT1S_new[0];
+ lmt_pg_idx_ht2s = priv->pshare->txpwr_lmt_HT2S - priv->pshare->tgpwr_HT2S_new[0];
+ lmt_pg_idx_vht1s = priv->pshare->txpwr_lmt_VHT1S - priv->pshare->tgpwr_VHT1S_new[0];
+ lmt_pg_idx_vht2s = priv->pshare->txpwr_lmt_VHT2S - priv->pshare->tgpwr_VHT2S_new[0];
+
+ //printk("%d %d %d %d %d %d\n", lmt_pg_idx_cck, lmt_pg_idx_ofdm,
+ //lmt_pg_idx_ht1s, lmt_pg_idx_ht2s, lmt_pg_idx_vht1s, lmt_pg_idx_vht2s);
+
+
+ //Cal Max tx pwr idx for CCK
+ tmp_dw = RTL_R32(rTxAGC_A_CCK11_CCK1_JAguar);
+ idx_cck_11m = get_byte_from_dw(tmp_dw, 3);
+ max_lmt_idx_cck = idx_cck_11m + lmt_pg_idx_cck;
+
+ //Cal Max tx pwr idx for OFDM
+ tmp_dw = RTL_R32(rTxAGC_A_Ofdm54_Ofdm24_JAguar);
+ idx_odfm_54m = get_byte_from_dw(tmp_dw, 3);
+ max_lmt_idx_ofdm = idx_odfm_54m + lmt_pg_idx_ofdm;
+
+ //Cal Max tx pwr idx for HT1S
+ tmp_dw = RTL_R32(rTxAGC_A_MCS7_MCS4_JAguar);
+ idx_ht_mcs7 = get_byte_from_dw(tmp_dw, 3);
+ max_lmt_idx_ht1s = idx_ht_mcs7 + lmt_pg_idx_ht1s;
+
+ //Cal Max tx pwr idx for HT2S
+ tmp_dw = RTL_R32(rTxAGC_A_MCS15_MCS12_JAguar);
+ idx_ht_mcs15 = get_byte_from_dw(tmp_dw, 3);
+ max_lmt_idx_ht2s = idx_ht_mcs15 + lmt_pg_idx_ht2s;
+
+ //Cal Max tx pwr idx for VHT1S
+ tmp_dw = RTL_R32(rTxAGC_A_Nss1Index7_Nss1Index4_JAguar);
+ idx_vht_1ss_mcs7 = get_byte_from_dw(tmp_dw, 3);
+ max_lmt_idx_vht1s = idx_vht_1ss_mcs7 + lmt_pg_idx_vht1s;
+
+ //Cal Max tx pwr idx for VHT2S
+ tmp_dw = RTL_R32(rTxAGC_A_Nss2Index9_Nss2Index6_JAguar);
+ idx_vht_2ss_mcs7 = get_byte_from_dw(tmp_dw, 1);
+ max_lmt_idx_vht2s = idx_vht_2ss_mcs7 + lmt_pg_idx_vht2s;
+
+ assign_lmt_reg_value(priv, rTxAGC_A_CCK11_CCK1_JAguar, max_lmt_idx_cck, 0);
+
+ assign_lmt_reg_value(priv, rTxAGC_A_Ofdm18_Ofdm6_JAguar, max_lmt_idx_ofdm, 0);
+ assign_lmt_reg_value(priv, rTxAGC_A_Ofdm54_Ofdm24_JAguar, max_lmt_idx_ofdm, 0);
+
+ assign_lmt_reg_value(priv, rTxAGC_A_MCS3_MCS0_JAguar, max_lmt_idx_ht1s, 0);
+ assign_lmt_reg_value(priv, rTxAGC_A_MCS7_MCS4_JAguar, max_lmt_idx_ht1s, 0);
+ assign_lmt_reg_value(priv, rTxAGC_A_MCS11_MCS8_JAguar, max_lmt_idx_ht2s, 0);
+ assign_lmt_reg_value(priv, rTxAGC_A_MCS15_MCS12_JAguar, max_lmt_idx_ht2s, 0);
+
+ assign_lmt_reg_value(priv, rTxAGC_A_Nss1Index3_Nss1Index0_JAguar, max_lmt_idx_vht1s, 0);
+ assign_lmt_reg_value(priv, rTxAGC_A_Nss1Index7_Nss1Index4_JAguar, max_lmt_idx_vht1s, 0);
+ assign_lmt_reg_value(priv, rTxAGC_A_Nss2Index1_Nss1Index8_JAguar, max_lmt_idx_vht1s, max_lmt_idx_vht2s);
+ assign_lmt_reg_value(priv, rTxAGC_A_Nss2Index5_Nss2Index2_JAguar, max_lmt_idx_vht2s, 0);
+ assign_lmt_reg_value(priv, rTxAGC_A_Nss2Index9_Nss2Index6_JAguar, max_lmt_idx_vht2s, 0);
+
+}
+
+
+unsigned char check_lmt_valid(struct rtl8192cd_priv *priv, unsigned char phy_band)
+{
+ unsigned char lmt_valid = 1;
+
+ if(phy_band == PHY_BAND_2G)
+ if(priv->pshare->txpwr_lmt_CCK == 0)
+ lmt_valid = 0;
+
+ if(priv->pshare->txpwr_lmt_OFDM == 0)
+ lmt_valid = 0;
+
+ if(priv->pshare->txpwr_lmt_HT1S == 0)
+ lmt_valid = 0;
+
+ if(priv->pshare->txpwr_lmt_HT2S == 0)
+ lmt_valid = 0;
+
+ if(phy_band == PHY_BAND_5G)
+ {
+ if(priv->pshare->txpwr_lmt_VHT1S == 0)
+ lmt_valid = 0;
+
+ if(priv->pshare->txpwr_lmt_VHT2S == 0)
+ lmt_valid = 0;
+ }
+
+ if(lmt_valid == 0)
+ printk("NO Limit Value, NO limit TX POWER !!!\n limit for cck=%d, ofdm=%d, ht1s=%d, ht2s=%d, vht1s=%d, vht2s=%d\n",
+ priv->pshare->txpwr_lmt_CCK,
+ priv->pshare->txpwr_lmt_OFDM,
+ priv->pshare->txpwr_lmt_HT1S,
+ priv->pshare->txpwr_lmt_HT2S,
+ priv->pshare->txpwr_lmt_VHT1S,
+ priv->pshare->txpwr_lmt_VHT2S
+ );
+
+ return lmt_valid;
+
+}
+
+void TxLMT_OFDM_8812_B(struct rtl8192cd_priv *priv)
+{
+
+ unsigned int tmp_dw = 0;
+
+ unsigned char idx_cck_11m = 0;
+ unsigned char idx_odfm_54m = 0;
+ unsigned char idx_ht_mcs7 = 0;
+ unsigned char idx_ht_mcs15 = 0;
+ unsigned char idx_vht_1ss_mcs7 =0;
+ unsigned char idx_vht_2ss_mcs7 =0;
+
+ char lmt_pg_idx_cck, lmt_pg_idx_ofdm = 0;
+ char lmt_pg_idx_ht1s, lmt_pg_idx_ht2s = 0;
+ char lmt_pg_idx_vht1s, lmt_pg_idx_vht2s = 0;
+
+ unsigned char max_lmt_idx_cck, max_lmt_idx_ofdm = 0;
+ unsigned char max_lmt_idx_ht1s, max_lmt_idx_ht2s = 0;
+ unsigned char max_lmt_idx_vht1s, max_lmt_idx_vht2s = 0;
+
+ lmt_pg_idx_cck = priv->pshare->txpwr_lmt_CCK - priv->pshare->tgpwr_CCK_new[1];
+ lmt_pg_idx_ofdm = priv->pshare->txpwr_lmt_OFDM - priv->pshare->tgpwr_OFDM_new[1];
+ lmt_pg_idx_ht1s = priv->pshare->txpwr_lmt_HT1S - priv->pshare->tgpwr_HT1S_new[1];
+ lmt_pg_idx_ht2s = priv->pshare->txpwr_lmt_HT2S - priv->pshare->tgpwr_HT2S_new[1];
+ lmt_pg_idx_vht1s = priv->pshare->txpwr_lmt_VHT1S - priv->pshare->tgpwr_VHT1S_new[1];
+ lmt_pg_idx_vht2s = priv->pshare->txpwr_lmt_VHT2S - priv->pshare->tgpwr_VHT2S_new[1];
+
+ //printk("%d %d %d %d %d %d\n", lmt_pg_idx_cck, lmt_pg_idx_ofdm,
+ //lmt_pg_idx_ht1s, lmt_pg_idx_ht2s, lmt_pg_idx_vht1s, lmt_pg_idx_vht2s);
+
+ //Cal Max tx pwr idx for CCK
+ tmp_dw = RTL_R32(rTxAGC_B_CCK11_CCK1_JAguar);
+ idx_cck_11m = get_byte_from_dw(tmp_dw, 3);
+ max_lmt_idx_cck = idx_cck_11m + lmt_pg_idx_cck;
+
+ //Cal Max tx pwr idx for OFDM
+ tmp_dw = RTL_R32(rTxAGC_B_Ofdm54_Ofdm24_JAguar);
+ idx_odfm_54m = get_byte_from_dw(tmp_dw, 3);
+ max_lmt_idx_ofdm = idx_odfm_54m + lmt_pg_idx_ofdm;
+
+ //Cal Max tx pwr idx for HT1S
+ tmp_dw = RTL_R32(rTxAGC_B_MCS7_MCS4_JAguar);
+ idx_ht_mcs7 = get_byte_from_dw(tmp_dw, 3);
+ max_lmt_idx_ht1s = idx_ht_mcs7 + lmt_pg_idx_ht1s;
+
+ //Cal Max tx pwr idx for HT2S
+ tmp_dw = RTL_R32(rTxAGC_B_MCS15_MCS12_JAguar);
+ idx_ht_mcs15 = get_byte_from_dw(tmp_dw, 3);
+ max_lmt_idx_ht2s = idx_ht_mcs15 + lmt_pg_idx_ht2s;
+
+ //Cal Max tx pwr idx for VHT1S
+ tmp_dw = RTL_R32(rTxAGC_B_Nss1Index7_Nss1Index4_JAguar);
+ idx_vht_1ss_mcs7 = get_byte_from_dw(tmp_dw, 3);
+ max_lmt_idx_vht1s = idx_vht_1ss_mcs7 + lmt_pg_idx_vht1s;
+
+ //Cal Max tx pwr idx for VHT2S
+ tmp_dw = RTL_R32(rTxAGC_B_Nss2Index9_Nss2Index6_JAguar);
+ idx_vht_2ss_mcs7 = get_byte_from_dw(tmp_dw, 1);
+ max_lmt_idx_vht2s = idx_vht_2ss_mcs7 + lmt_pg_idx_vht2s;
+
+ assign_lmt_reg_value(priv, rTxAGC_B_CCK11_CCK1_JAguar, max_lmt_idx_cck, 0);
+
+ assign_lmt_reg_value(priv, rTxAGC_B_Ofdm18_Ofdm6_JAguar, max_lmt_idx_ofdm, 0);
+ assign_lmt_reg_value(priv, rTxAGC_B_Ofdm54_Ofdm24_JAguar, max_lmt_idx_ofdm, 0);
+
+ assign_lmt_reg_value(priv, rTxAGC_B_MCS3_MCS0_JAguar, max_lmt_idx_ht1s, 0);
+ assign_lmt_reg_value(priv, rTxAGC_B_MCS7_MCS4_JAguar, max_lmt_idx_ht1s, 0);
+ assign_lmt_reg_value(priv, rTxAGC_B_MCS11_MCS8_JAguar, max_lmt_idx_ht2s, 0);
+ assign_lmt_reg_value(priv, rTxAGC_B_MCS15_MCS12_JAguar, max_lmt_idx_ht2s, 0);
+
+ assign_lmt_reg_value(priv, rTxAGC_B_Nss1Index3_Nss1Index0_JAguar, max_lmt_idx_vht1s, 0);
+ assign_lmt_reg_value(priv, rTxAGC_B_Nss1Index7_Nss1Index4_JAguar, max_lmt_idx_vht1s, 0);
+ assign_lmt_reg_value(priv, rTxAGC_B_Nss2Index1_Nss1Index8_JAguar, max_lmt_idx_vht1s, max_lmt_idx_vht2s);
+ assign_lmt_reg_value(priv, rTxAGC_B_Nss2Index5_Nss2Index2_JAguar, max_lmt_idx_vht2s, 0);
+ assign_lmt_reg_value(priv, rTxAGC_B_Nss2Index9_Nss2Index6_JAguar, max_lmt_idx_vht2s, 0);
+
+}
+
+
+#endif
+
+void PHY_SetOFDMTxPower_8812(struct rtl8192cd_priv *priv, unsigned char channel)
+{
+ unsigned char ch_idx = 0;
+ // unsigned char tmp_TPI = 0;
+ unsigned char phy_band = 0;
+
+ if (channel > 0)
+ ch_idx = (channel - 1);
+ else {
+ printk("Error Channel !!\n");
+ return;
+ }
+
+ if (channel > 14)
+ phy_band = PHY_BAND_5G;
+ else
+ phy_band = PHY_BAND_2G;
+
+#if 0
+ printk("pwrlevel5GHT40_1S_A[%d]= %d \n", channel, priv->pmib->dot11RFEntry.pwrlevel5GHT40_1S_A[ch_idx]);
+ printk("pwrdiff_5G_20BW1S_OFDM1T_A[%d]= 0x%x \n", channel, priv->pmib->dot11RFEntry.pwrdiff_5G_20BW1S_OFDM1T_A[ch_idx]);
+ printk("pwrdiff_40BW2S_20BW2S_A[%d]= 0x%x \n", channel, priv->pmib->dot11RFEntry.pwrdiff_40BW2S_20BW2S_A[ch_idx]);
+ printk("pwrdiff_5G_20BW1S_OFDM1T_A[%d]= 0x%x \n", channel, priv->pmib->dot11RFEntry.pwrdiff_5G_20BW1S_OFDM1T_A[ch_idx]);
+ printk("pwrdiff_5G_40BW2S_20BW2S_A[%d]= 0x%x \n", channel, priv->pmib->dot11RFEntry.pwrdiff_5G_40BW2S_20BW2S_A[ch_idx]);
+ printk("pwrdiff_5G_80BW1S_160BW1S_A[%d]= 0x%x \n", channel, priv->pmib->dot11RFEntry.pwrdiff_5G_80BW1S_160BW1S_A[ch_idx]);
+ printk("pwrdiff_5G_80BW2S_160BW2S_A[%d]= 0x%x \n", channel, priv->pmib->dot11RFEntry.pwrdiff_5G_80BW2S_160BW2S_A[ch_idx]);
+
+ printk("pwrlevel5GHT40_1S_B[%d]= %d \n", channel, priv->pmib->dot11RFEntry.pwrlevel5GHT40_1S_B[ch_idx]);
+ printk("pwrdiff_5G_20BW1S_OFDM1T_B[%d]= 0x%x \n", channel, priv->pmib->dot11RFEntry.pwrdiff_5G_20BW1S_OFDM1T_B[ch_idx]);
+ printk("pwrdiff_40BW2S_20BW2S_B[%d]= 0x%x \n", channel, priv->pmib->dot11RFEntry.pwrdiff_40BW2S_20BW2S_B[ch_idx]);
+ printk("pwrdiff_5G_20BW1S_OFDM1T_B[%d]= 0x%x \n", channel, priv->pmib->dot11RFEntry.pwrdiff_5G_20BW1S_OFDM1T_B[ch_idx]);
+ printk("pwrdiff_5G_40BW2S_20BW2S_B[%d]= 0x%x \n", channel, priv->pmib->dot11RFEntry.pwrdiff_5G_40BW2S_20BW2S_B[ch_idx]);
+ printk("pwrdiff_5G_80BW1S_160BW1S_B[%d]= 0x%x \n", channel, priv->pmib->dot11RFEntry.pwrdiff_5G_80BW1S_160BW1S_B[ch_idx]);
+ printk("pwrdiff_5G_80BW2S_160BW2S_B[%d]= 0x%x \n", channel, priv->pmib->dot11RFEntry.pwrdiff_5G_80BW2S_160BW2S_B[ch_idx]);
+#endif
+
+ if (phy_band == PHY_BAND_5G)
+ Cal_OFDMTxPower_5G(priv, ch_idx);
+ else if (phy_band == PHY_BAND_2G)
+ Cal_OFDMTxPower_2G(priv, ch_idx);
+#ifdef TX_PG_8812
+ TxPG_OFDM_8812_A(priv);
+ TxPG_OFDM_8812_B(priv);
+#endif
+
+#ifdef TXPWR_LMT_8812
+
+ if(!priv->pshare->rf_ft_var.disable_txpwrlmt)
+ {
+ if(check_lmt_valid(priv, phy_band))
+ {
+ TxLMT_OFDM_8812_A(priv);
+ TxLMT_OFDM_8812_B(priv);
+ }
+ }
+
+#endif
+
+}
+
+void PHY_SetCCKTxPower_8812(struct rtl8192cd_priv *priv, unsigned char channel)
+{
+ unsigned int def_power = 0x20202020;//0x12121212;
+ unsigned char ch_idx = 0;
+ unsigned char tmp_TPI = 0;
+ unsigned char phy_band = 0;
+ unsigned int writeVal = 0;
+
+ if (channel > 0)
+ ch_idx = (channel - 1);
+ else {
+ printk("Error Channel !!\n");
+ return;
+ }
+
+ if (channel > 14)
+ phy_band = PHY_BAND_5G;
+ else
+ phy_band = PHY_BAND_2G;
+
+ if ((priv->pmib->dot11RFEntry.pwrlevelCCK_A[ch_idx] == 0)
+ || (priv->pmib->dot11RFEntry.pwrlevelCCK_B[ch_idx] == 0)) {
+ //printk("NO Calibration data, use default CCK power = 0x%x\n", def_power);
+ RTL_W32(rTxAGC_A_CCK11_CCK1_JAguar, def_power);
+ RTL_W32(rTxAGC_B_CCK11_CCK1_JAguar, def_power);
+ }
+
+ if (phy_band == PHY_BAND_2G) {
+ //printk("pwrlevelCCK_A[%d]= %d \n", ch_idx, priv->pmib->dot11RFEntry.pwrlevelCCK_A[ch_idx]);
+ //printk("pwrlevelCCK_B[%d]= %d \n", ch_idx, priv->pmib->dot11RFEntry.pwrlevelCCK_B[ch_idx]);
+
+ //PATH A
+ tmp_TPI = priv->pmib->dot11RFEntry.pwrlevelCCK_A[ch_idx];
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ RTL_W32(rTxAGC_A_CCK11_CCK1_JAguar, writeVal);
+
+ //PATH B
+ tmp_TPI = priv->pmib->dot11RFEntry.pwrlevelCCK_B[ch_idx];
+ writeVal = (tmp_TPI << 24) | (tmp_TPI << 16) | (tmp_TPI << 8) | tmp_TPI;
+ RTL_W32(rTxAGC_B_CCK11_CCK1_JAguar, writeVal);
+ }
+#ifdef TX_PG_8812
+ TxPG_CCK_8812(priv);
+#endif
+
+}
+
+
+
+
+
+
+
+
+// Firmware
+
+#define MAX_PAGE_SIZE 4096 // @ page : 4k bytes
+#define FW_START_ADDRESS 0x1000
+#define FWDL_ChkSum_rpt BIT(2)
+
+extern unsigned char *data_rtl8812fw_start, *data_rtl8812fw_end;
+extern unsigned char *data_rtl8812fw_n_start, *data_rtl8812fw_n_end; //for_8812_mp_chip
+
+
+
+VOID
+_8051Reset8812(
+ struct rtl8192cd_priv *priv
+)
+{
+ u1Byte u1bTmp;
+ u1bTmp = RTL_R8(REG_SYS_FUNC_EN_8812 + 1);
+ RTL_W8(REG_SYS_FUNC_EN_8812 + 1, u1bTmp & (~BIT2));
+ RTL_W8( REG_SYS_FUNC_EN_8812 + 1, u1bTmp | (BIT2));
+// RT_TRACE(COMP_INIT, DBG_LOUD, ("=====> _8051Reset8812(): 8051 reset success .\n"));
+}
+
+
+VOID
+_FWDownloadEnable_8812(
+ struct rtl8192cd_priv *priv,
+ BOOLEAN enable
+)
+{
+ u1Byte tmp;
+
+ if (enable) {
+ // MCU firmware download enable.
+ RTL_W8( REG_MCUFWDL_8812, 0x05);
+
+ // Clear Rom DL enable
+ tmp = RTL_R8( REG_MCUFWDL_8812 + 2);
+ RTL_W8( REG_MCUFWDL_8812 + 2, tmp & 0xf7);
+ } else {
+ // MCU firmware download enable.
+ tmp = RTL_R8( REG_MCUFWDL_8812);
+ RTL_W8( REG_MCUFWDL_8812, tmp & 0xfe);
+ }
+}
+
+VOID
+_FillDummy_8812(
+ pu1Byte pFwBuf,
+ pu4Byte pFwLen
+)
+{
+ u4Byte FwLen = *pFwLen;
+ u1Byte remain = (u1Byte)(FwLen % 4);
+ remain = (remain == 0) ? 0 : (4 - remain);
+
+ while (remain > 0) {
+ pFwBuf[FwLen] = 0;
+ FwLen++;
+ remain--;
+ }
+
+ *pFwLen = FwLen;
+}
+
+
+
+// BlockWrite:
+// 92DU----------use 64-Byte/8-Byte/1-Byte (PlatformIOWriteNByte)
+// 92CU/8723U----use 4-Byte/1-Byte (PlatformIOWriteNByte)
+// PCI/SDIO------use 4-Byte/1-Byte (PlatformEFIOWrite4Byte)
+// 92CU [MacOS]-- use 196-Byte/8-Byte/1-Byte (PlatformIOWriteNByte)
+
+VOID
+_BlockWrite_8812(
+ struct rtl8192cd_priv *priv,
+ IN PVOID buffer,
+ IN u4Byte buffSize
+)
+{
+ u4Byte blockSize_p1 = 4; // (Default) Phase #1 : PCI muse use 4-byte write to download FW
+ u4Byte blockSize_p2 = 8; // Phase #2 : Use 8-byte, if Phase#1 use big size to write FW.
+ u4Byte blockSize_p3 = 1; // Phase #3 : Use 1-byte, the remnant of FW image.
+ u4Byte blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
+ u4Byte remainSize_p1 = 0, remainSize_p2 = 0;
+ pu1Byte bufferPtr = (pu1Byte)buffer;
+ u4Byte i = 0, offset = 0;
+
+
+ //3 Phase #1
+ blockCount_p1 = buffSize / blockSize_p1;
+ remainSize_p1 = buffSize % blockSize_p1;
+
+
+ for (i = 0 ; i < blockCount_p1 ; i++) {
+ RTL_W32( (FW_START_ADDRESS + i * blockSize_p1), cpu_to_le32(*((pu4Byte)(bufferPtr + i * blockSize_p1))));
+ }
+
+ //3 Phase #2
+ if (remainSize_p1) {
+ offset = blockCount_p1 * blockSize_p1;
+
+ blockCount_p2 = remainSize_p1 / blockSize_p2;
+ remainSize_p2 = remainSize_p1 % blockSize_p2;
+
+ }
+
+ //3 Phase #3
+ if (remainSize_p2) {
+ offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2);
+ blockCount_p3 = remainSize_p2 / blockSize_p3;
+
+ // RT_TRACE(COMP_INIT,DBG_LOUD,("_BlockWrite_8812[P3] ::buffSize_p3( %d) blockSize_p3( %d) blockCount_p3( %d) \n",(buffSize-offset),blockSize_p3, blockCount_p3));
+
+ for (i = 0 ; i < blockCount_p3 ; i++) {
+ RTL_W8( (FW_START_ADDRESS + offset + i), *(bufferPtr + offset + i));
+ }
+ }
+}
+
+
+VOID
+_PageWrite_8812(
+ struct rtl8192cd_priv *priv,
+ IN u4Byte page,
+ IN PVOID buffer,
+ IN u4Byte size
+)
+{
+ u1Byte value8;
+ u1Byte u8Page = (u1Byte) (page & 0x07) ;
+
+ value8 = (RTL_R8(REG_MCUFWDL_8812 + 2) & 0xF8 ) | u8Page ;
+ RTL_W8(REG_MCUFWDL_8812 + 2, value8);
+
+ _BlockWrite_8812(priv, buffer, size);
+}
+
+
+VOID
+_WriteFW_8812(
+ struct rtl8192cd_priv *priv,
+ IN PVOID buffer,
+ IN u4Byte size
+)
+{
+ // Since we need dynamic decide method of dwonload fw, so we call this function to get chip version.
+ // We can remove _ReadChipVersion from ReadAdapterInfo8192C later.
+ u4Byte pageNums, remainSize ;
+ u4Byte page, offset;
+ pu1Byte bufferPtr = (pu1Byte)buffer;
+
+#if 1//DEV_BUS_TYPE==RT_PCI_INTERFACE
+ // 20100120 Joseph: Add for 88CE normal chip.
+ // Fill in zero to make firmware image to dword alignment.
+ // _FillDummy_8812(bufferPtr, &size);
+#endif
+
+ pageNums = size / MAX_PAGE_SIZE ;
+
+ // RT_ASSERT((pageNums <= 8), ("Page numbers should not greater then 8 \n"));
+
+ remainSize = size % MAX_PAGE_SIZE;
+
+ for (page = 0; page < pageNums; page++) {
+ offset = page * MAX_PAGE_SIZE;
+ _PageWrite_8812(priv, page, (bufferPtr + offset), MAX_PAGE_SIZE);
+ }
+ if (remainSize) {
+ offset = pageNums * MAX_PAGE_SIZE;
+ page = pageNums;
+ _PageWrite_8812(priv, page, (bufferPtr + offset), remainSize);
+ }
+ // RT_TRACE(COMP_INIT, DBG_LOUD, ("_WriteFW_8812 Done- for Normal chip.\n"));
+}
+
+
+RT_STATUS
+_FWFreeToGo8812(
+ struct rtl8192cd_priv *priv
+
+)
+{
+ u4Byte counter = 0;
+ u4Byte value32;
+
+ // polling CheckSum report
+ do {
+ value32 = RTL_R32( REG_MCUFWDL_8812);
+ } while ((counter ++ < 6000) && (!(value32 & FWDL_ChkSum_rpt )));
+
+ if (counter >= 6000) {
+ // RT_TRACE(COMP_INIT, DBG_SERIOUS, ("_FWFreeToGo8812:: chksum report faill ! REG_MCUFWDL:0x%08x .\n",value32));
+ return RT_STATUS_FAILURE;
+ }
+ // RT_TRACE(COMP_INIT, DBG_LOUD, ("_FWFreeToGo8812:: Checksum report OK ! REG_MCUFWDL:0x%08x .\n",value32));
+
+ value32 = RTL_R32( REG_MCUFWDL_8812);
+ value32 |= MCUFWDL_RDY;
+ value32 &= ~WINTINI_RDY;
+ RTL_W32( REG_MCUFWDL_8812, value32);
+
+ _8051Reset8812(priv);
+
+ // polling for FW ready
+ counter = 0;
+ do {
+ if (RTL_R32( REG_MCUFWDL_8812) & WINTINI_RDY) {
+ // RT_TRACE(COMP_INIT, DBG_SERIOUS, ("Polling FW ready success!! REG_MCUFWDL:0x%08x in %d times.\n",PlatformEFIORead4Byte(Adapter, REG_MCUFWDL_8812),counter));
+ return RT_STATUS_SUCCESS;
+ }
+ // PlatformStallExecution(5);
+ delay_us(5);
+ } while (counter++ < 6000);
+
+ panic_printk("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", RTL_R32( REG_MCUFWDL_8812) );
+ return RT_STATUS_FAILURE;
+}
+
+
+RT_STATUS
+FirmwareDownload8812(
+ struct rtl8192cd_priv *priv
+)
+{
+ RT_STATUS rtStatus = RT_STATUS_SUCCESS;
+
+ //u4Byte FwImageLen = 0;
+ u1Byte *pFirmwareBuf;
+ u4Byte FirmwareLen;
+
+ RTL_W8( 0xf0, (RTL_R8(0xf0)& ~BIT(7)));
+
+ if (IS_TEST_CHIP(priv)) { //for_8812_mp_chip
+ pFirmwareBuf = data_rtl8812fw_start + 32;
+ FirmwareLen = data_rtl8812fw_end - data_rtl8812fw_start - 32;
+ } else {
+ pFirmwareBuf = data_rtl8812fw_n_start + 32;
+ FirmwareLen = data_rtl8812fw_n_end - data_rtl8812fw_n_start - 32;
+ }
+
+ // panic_printk("%s, %d%x, %x\n", __FUNCTION__, __LINE__, pFirmwareBuf, FirmwareLen);
+
+
+ {
+ if (RTL_R8( REG_MCUFWDL_8812)&BIT7) { //8051 RAM code
+ RTL_W8(REG_MCUFWDL_8812, 0x00);
+ _8051Reset8812(priv);
+ }
+ }
+
+
+
+ _FWDownloadEnable_8812(priv, TRUE);
+
+ _WriteFW_8812(priv, pFirmwareBuf, FirmwareLen);
+
+ _FWDownloadEnable_8812(priv, FALSE);
+
+
+ rtStatus = _FWFreeToGo8812(priv);
+
+ if (RT_STATUS_SUCCESS != rtStatus) {
+ panic_printk("Firmware is not ready to run!\n") ;
+ goto Exit;
+ }
+
+
+Exit:
+
+ panic_printk(" <=== FirmwareDownload8812()\n");
+ return rtStatus;
+
+}
+
+
+// 8812 H2C
+
+BOOLEAN
+CheckFwReadLastH2C_8812(
+ struct rtl8192cd_priv *priv,
+ IN u1Byte BoxNum
+)
+{
+ u1Byte valHMETFR;
+ BOOLEAN Result = FALSE;
+
+ valHMETFR = RTL_R8( REG_HMETFR_8812);
+
+ // Do not seperate to 91C and 88C, we use the same setting. Suggested by SD4 Filen. 2009.12.03.
+ if (((valHMETFR >> BoxNum)&BIT0) == 0)
+ Result = TRUE;
+
+ return Result;
+}
+
+
+u1Byte
+FillH2CCmd8812(
+ struct rtl8192cd_priv *priv,
+ IN u1Byte ElementID,
+ IN u4Byte CmdLen,
+ IN pu1Byte pCmdBuffer
+)
+{
+
+ u1Byte ioStatus = 0;
+ u1Byte BoxNum;
+ u2Byte BOXReg = 0, BOXExtReg = 0;
+ // u1Byte U1btmp; //Read 0x1bf
+ BOOLEAN bFwReadClear = FALSE;
+ u1Byte BufIndex = 0;
+ u1Byte WaitH2cLimmit = 0;
+ u1Byte BoxContent[4], BoxExtContent[4];
+ u1Byte idx = 0;
+
+ if (!GET_ROOT(priv)->bFWReady)
+ return 1;
+
+ // 1. Find the last BOX number which has been writen.
+ BoxNum = priv->pshare->fw_q_fifo_count; //pHalData->LastHMEBoxNum;
+ switch (BoxNum) {
+ case 0:
+ BOXReg = REG_HMEBOX_0_8812;
+ BOXExtReg = REG_HMEBOX_EXT0_8812;
+ break;
+ case 1:
+ BOXReg = REG_HMEBOX_1_8812;
+ BOXExtReg = REG_HMEBOX_EXT1_8812;
+ break;
+ case 2:
+ BOXReg = REG_HMEBOX_2_8812;
+ BOXExtReg = REG_HMEBOX_EXT2_8812;
+ break;
+ case 3:
+ BOXReg = REG_HMEBOX_3_8812;
+ BOXExtReg = REG_HMEBOX_EXT3_8812;
+ break;
+ default:
+ break;
+ }
+
+ // 2. Check if the box content is empty.
+ while (!bFwReadClear) {
+ bFwReadClear = CheckFwReadLastH2C_8812(priv, BoxNum);
+ if (WaitH2cLimmit++ >= 100) {
+ ioStatus = 1;
+ return ioStatus;
+ } else if (!bFwReadClear) {
+ delay_us(10); //us
+ }
+ }
+
+ // 4. Fill the H2C cmd into box
+ memset(BoxContent, 0, sizeof(BoxContent));
+ memset(BoxExtContent, 0, sizeof(BoxExtContent));
+
+ BoxContent[0] = ElementID; // Fill element ID
+ // RTPRINT(FFW, FW_MSG_H2C_CONTENT, ("[FW], Write ElementID BOXReg(%4x) = %2x \n", BOXReg, ElementID));
+
+ switch (CmdLen) {
+ case 1:
+ case 2:
+ case 3: {
+ //BoxContent[0] &= ~(BIT7);
+ memcpy((pu1Byte)(BoxContent) + 1, pCmdBuffer + BufIndex, CmdLen);
+ //For Endian Free.
+ for (idx = 0; idx < 4; idx++) {
+ RTL_W8(BOXReg + idx, BoxContent[idx]);
+ }
+ break;
+ }
+ case 4:
+ case 5:
+ case 6:
+ case 7: {
+ //BoxContent[0] |= (BIT7);
+ memcpy((pu1Byte)(BoxExtContent), pCmdBuffer + BufIndex + 3, (CmdLen - 3));
+ memcpy((pu1Byte)(BoxContent) + 1, pCmdBuffer + BufIndex, 3);
+ //For Endian Free.
+ for (idx = 0 ; idx < 4 ; idx ++) {
+ RTL_W8( BOXExtReg + idx, BoxExtContent[idx]);
+ }
+ for (idx = 0 ; idx < 4 ; idx ++) {
+ RTL_W8( BOXReg + idx, BoxContent[idx]);
+ }
+ break;
+ }
+
+ default:
+ // RTPRINT(FFW, FW_MSG_H2C_STATE, ("[FW], Invalid command len=%d!!!\n", CmdLen));
+ ioStatus = 2;
+ return ioStatus;
+ break;
+ }
+
+ if (++priv->pshare->fw_q_fifo_count > 3)
+ priv->pshare->fw_q_fifo_count = 0;
+
+ // RTPRINT(FFW, FW_MSG_H2C_CONTENT, ("[FW], pHalData->LastHMEBoxNum = %d\n", pHalData->LastHMEBoxNum));
+ return ioStatus;
+}
+
+
+
+
+
+
+
+VOID
+SetBcnCtrlReg_8812(
+ struct rtl8192cd_priv *priv,
+ IN u1Byte SetBits,
+ IN u1Byte ClearBits
+)
+{
+ u1Byte tmp = RTL_R8(REG_BCN_CTRL_8812);
+
+ tmp |= SetBits;
+ tmp &= ~ClearBits;
+
+ RTL_W8(REG_BCN_CTRL_8812, tmp);
+}
+
+
+u1Byte
+MRateIdxToARFRId8812(
+ struct rtl8192cd_priv *priv,
+ u1Byte RateIdx,
+ u1Byte RfType
+)
+{
+ u1Byte Ret = 0;
+
+ switch (RateIdx) {
+
+ case RATR_INX_WIRELESS_NGB:
+ if (RfType == MIMO_1T1R)
+ Ret = 1;
+ else
+ Ret = 0;
+ break;
+
+ case RATR_INX_WIRELESS_N:
+ case RATR_INX_WIRELESS_NG:
+ if (RfType == MIMO_1T1R)
+ Ret = 5;
+ else
+ Ret = 4;
+ break;
+
+ case RATR_INX_WIRELESS_NB:
+ if (RfType == MIMO_1T1R)
+ Ret = 3;
+ else
+ Ret = 2;
+ break;
+
+ case RATR_INX_WIRELESS_GB:
+ Ret = 6;
+ break;
+
+ case RATR_INX_WIRELESS_G:
+ Ret = 7;
+ break;
+
+ case RATR_INX_WIRELESS_B:
+ Ret = 8;
+ break;
+
+ case RATR_INX_WIRELESS_MC:
+ if (!(priv->pmib->dot11BssType.net_work_type & WIRELESS_11A))
+ Ret = 6;
+ else
+ Ret = 7;
+ break;
+ case RATR_INX_WIRELESS_AC_N:
+ if (RfType == MIMO_1T1R)
+ Ret = 10;
+ else
+ Ret = 9;
+ break;
+
+ default:
+ Ret = 0;
+ break;
+ }
+
+ return Ret;
+}
+
+u1Byte
+Get_RA_BW(
+ BOOLEAN bCurTxBW80MHz,
+ BOOLEAN bCurTxBW40MHz
+)
+{
+ u1Byte BW = 0;
+ if (bCurTxBW80MHz)
+ BW = 2;
+ else if (bCurTxBW40MHz)
+ BW = 1;
+ else
+ BW = 0;
+
+ return BW;
+}
+
+
+
+#ifndef CONFIG_WLAN_HAL
+typedef enum _WIRELESS_MODE {
+ WIRELESS_MODE_UNKNOWN = 0x00,
+ WIRELESS_MODE_A = 0x01,
+ WIRELESS_MODE_B = 0x02,
+ WIRELESS_MODE_G = 0x04,
+ WIRELESS_MODE_AUTO = 0x08,
+ WIRELESS_MODE_N_24G = 0x10,
+ WIRELESS_MODE_N_5G = 0x20,
+ WIRELESS_MODE_AC_5G = 0x40
+} WIRELESS_MODE;
+#endif
+
+#define MIMO_PS_STATIC 0
+#define MIMO_PS_DYNAMIC 1
+#define MIMO_PS_NOLIMIT 3
+
+#define FillOctetString(_os,_octet,_len) \
+ (_os).Octet=(pu1Byte)(_octet); \
+ (_os).Length=(_len);
+
+
+u1Byte
+Get_VHT_ENI(
+ u4Byte IOTAction,
+ u1Byte WirelessMode,
+ u4Byte ratr_bitmap
+)
+{
+ u1Byte Ret = 0;
+ if (WirelessMode < WIRELESS_MODE_N_24G)
+ Ret = 0;
+ else if (WirelessMode == WIRELESS_MODE_N_24G || WirelessMode == WIRELESS_MODE_N_5G) {
+#if 0
+ //if(IOTAction == HT_IOT_VHT_HT_MIX_MODE)
+ {
+ if (ratr_bitmap & BIT20) // Mix , 2SS
+ Ret = 3;
+ else // Mix, 1SS
+ Ret = 2;
+ }
+#else
+ Ret = 0;
+#endif
+
+ } else if (WirelessMode == WIRELESS_MODE_AC_5G)
+ Ret = 1; // VHT
+
+ return (Ret << 4);
+}
+
+
+
+BOOLEAN
+Get_RA_ShortGI(
+ struct rtl8192cd_priv *priv,
+ struct stat_info * pEntry,
+ IN WIRELESS_MODE WirelessMode,
+ IN u1Byte ChnlBW
+)
+{
+ BOOLEAN bShortGI;
+
+ BOOLEAN bShortGI20MHz = FALSE, bShortGI40MHz = FALSE, bShortGI80MHz = FALSE;
+
+ if ( WirelessMode == WIRELESS_MODE_N_24G ||
+ WirelessMode == WIRELESS_MODE_N_5G ||
+ WirelessMode == WIRELESS_MODE_AC_5G ) {
+ if (pEntry->ht_cap_buf.ht_cap_info & cpu_to_le16(_HTCAP_SHORTGI_20M_) &&
+ priv->pmib->dot11nConfigEntry.dot11nShortGIfor20M) {
+ bShortGI20MHz = TRUE;
+ }
+ if (pEntry->ht_cap_buf.ht_cap_info & cpu_to_le16(_HTCAP_SHORTGI_40M_)
+ && priv->pmib->dot11nConfigEntry.dot11nShortGIfor40M) {
+ bShortGI40MHz = TRUE;
+ }
+ if (WirelessMode == WIRELESS_MODE_AC_5G) {
+ if ( cpu_to_le32(pEntry->vht_cap_buf.vht_cap_info) & BIT(SHORT_GI80M_E))
+ bShortGI80MHz = TRUE;
+
+// disable SGI when LDPC is enabled in AC mode
+ if((pEntry->is_realtek_sta) && (priv->pmib->dot11nConfigEntry.dot11nLDPC == 1) &&
+ ((pEntry->ht_cap_len && cpu_to_le16(pEntry->ht_cap_buf.ht_cap_info) & _HTCAP_SUPPORT_RX_LDPC_) ||
+ (pEntry->vht_cap_len && (cpu_to_le32(pEntry->vht_cap_buf.vht_cap_info) & BIT(RX_LDPC_E)))) ) {
+ bShortGI80MHz = bShortGI40MHz = bShortGI20MHz = 0;
+ }
+ }
+ }
+
+ switch (ChnlBW) {
+ case HT_CHANNEL_WIDTH_20_40:
+ bShortGI = bShortGI40MHz;
+ break;
+ case HT_CHANNEL_WIDTH_80:
+ bShortGI = bShortGI80MHz;
+ break;
+ default:
+ case HT_CHANNEL_WIDTH_20:
+ bShortGI = bShortGI20MHz;
+ break;
+ }
+ return bShortGI;
+}
+
+
+u4Byte
+RateToBitmap_2SSVHT(
+ pu1Byte pVHTRate
+)
+{
+
+ u1Byte i, j , tmpRate;
+ u4Byte RateBitmap = 0;
+
+ for (i = j = 0; i < 4; i += 2, j += 10) {
+ tmpRate = (pVHTRate[0] >> i) & 3;
+
+ switch (tmpRate) {
+ case 2:
+ RateBitmap = RateBitmap | (0x03ff << j);
+ break;
+ case 1:
+ RateBitmap = RateBitmap | (0x01ff << j);
+ break;
+
+ case 0:
+ RateBitmap = RateBitmap | (0x00ff << j);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return RateBitmap;
+}
+
+
+u4Byte
+Get_VHT_HT_Mix_Ratrbitmap(
+ u4Byte IOTAction,
+ WIRELESS_MODE WirelessMode,
+ u4Byte HT_ratr_bitmap,
+ u4Byte VHT_ratr_bitmap
+)
+{
+ u4Byte ratr_bitmap = 0;
+ if (WirelessMode == WIRELESS_MODE_N_24G || WirelessMode == WIRELESS_MODE_N_5G) {
+ /*
+ if(IOTAction == HT_IOT_VHT_HT_MIX_MODE)
+ ratr_bitmap = HT_ratr_bitmap | BIT28 | BIT29;
+ else
+ ratr_bitmap = HT_ratr_bitmap;
+ */
+ } else
+ ratr_bitmap = VHT_ratr_bitmap;
+
+ return ratr_bitmap;
+}
+
+
+VOID
+UpdateHalRAMask8812(
+ struct rtl8192cd_priv *priv,
+ struct stat_info *pEntry,
+ u1Byte rssi_level
+)
+{
+
+ u1Byte WirelessMode = WIRELESS_MODE_A;
+ u1Byte BW = HT_CHANNEL_WIDTH_20;
+ // u2Byte RateSet=0, i;
+ u1Byte MimoPs = MIMO_PS_NOLIMIT, ratr_index = 8, H2CCommand[7] = { 0};
+ u4Byte ratr_bitmap = 0, IOTAction = 0;
+ BOOLEAN bShortGI = FALSE, bCurTxBW80MHz = FALSE, bCurTxBW40MHz = FALSE;
+ struct stat_info *pstat = pEntry;
+ u1Byte rf_mimo_mode = get_rf_mimo_mode(priv);
+
+ if (pEntry == NULL) {
+ return;
+ }
+ {
+ if (pEntry->MIMO_ps & _HT_MIMO_PS_STATIC_)
+ MimoPs = MIMO_PS_STATIC;
+ else if (pEntry->MIMO_ps & _HT_MIMO_PS_DYNAMIC_)
+ MimoPs = MIMO_PS_DYNAMIC;
+
+#if 1
+ if(pstat->tx_bw > priv->pshare->CurrentChannelBW)
+ pstat->tx_bw = priv->pshare->CurrentChannelBW;
+#endif
+ add_RATid(priv, pEntry);
+ ratr_bitmap = 0xfffffff;
+ //
+ // if(pstat->vht_cap_len && ( priv->pshare->rf_ft_var.support_11ac)) {
+ if (pstat->vht_cap_len && (priv->pmib->dot11BssType.net_work_type & WIRELESS_11AC)) {
+
+ if( (IS_B_CUT_8812(priv))
+ && ((priv->pmib->dot11nConfigEntry.dot11nUse40M==0)||(pstat->tx_bw == 0)) )
+ {
+ //printk("\n !!! B CUT + AC STA + 20M, NO AC RATES !!!\n");
+ //printk("AP=%dM, STA=%dM\n", (0x1<<(priv->pmib->dot11nConfigEntry.dot11nUse40M))*20 , (0x1<<(pstat->tx_bw))*20 );
+ WirelessMode = WIRELESS_MODE_N_5G;
+ }
+ else{
+ WirelessMode = WIRELESS_MODE_AC_5G;
+ }
+
+ if (((le32_to_cpu(pstat->vht_cap_buf.vht_support_mcs[0]) >> 2) & 3) == 3)
+ rf_mimo_mode = MIMO_1T1R;
+ if (pstat->nss == 1)
+ rf_mimo_mode = MIMO_1T1R;
+ } else if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) && pstat->ht_cap_len && (!should_restrict_Nrate(priv, pstat))) {
+ if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A)
+ WirelessMode = WIRELESS_MODE_N_5G;
+ else
+ WirelessMode = WIRELESS_MODE_N_24G;
+ if ((pstat->tx_ra_bitmap & 0xff00000) == 0)
+ rf_mimo_mode = MIMO_1T1R;
+ } else if (((priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) && isErpSta(pstat))) {
+ WirelessMode = WIRELESS_MODE_G;
+ } else if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) &&
+ ((OPMODE & WIFI_AP_STATE) || (priv->pmib->dot11RFEntry.phyBandSelect & PHY_BAND_5G))) {
+ WirelessMode = WIRELESS_MODE_A;
+ } else if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11B) {
+ WirelessMode = WIRELESS_MODE_B;
+ }
+
+ pstat->WirelessMode = WirelessMode;
+
+ if (WirelessMode == WIRELESS_MODE_AC_5G) {
+ int tmp32 = (pstat->vht_cap_buf.vht_support_mcs[0]);
+ ratr_bitmap &= 0xfff;
+ // special 1SS & 2SS
+ if (pstat->nss == 1)
+ tmp32 |= cpu_to_le32(0xfffc);
+ else if ((pstat->nss == 2) && (le32_to_cpu(tmp32) & 0x0c) == 0x0c)
+ tmp32 &= cpu_to_le32(0xfffffff3);
+ //
+ ratr_bitmap |= RateToBitmap_2SSVHT((pu1Byte)&tmp32) << 12;
+
+ if (IS_TEST_CHIP(priv)) { // Test Chip... 2SS MCS7
+ if (rf_mimo_mode == MIMO_1T1R)
+ ratr_bitmap &= 0x000fffff;
+ else
+ ratr_bitmap &= 0x3FCFFFFF;
+ } else { // MP Chip... MCS0~9
+ if (rf_mimo_mode == MIMO_1T1R)
+ ratr_bitmap &= 0x003fffff;
+ }
+
+ if (pstat->tx_bw == HT_CHANNEL_WIDTH_80)
+ bCurTxBW80MHz = TRUE;
+ }
+// if (priv->pshare->is_40m_bw && (pstat->tx_bw == HT_CHANNEL_WIDTH_20_40))
+// bCurTxBW40MHz = TRUE;
+
+ if (priv->pshare->is_40m_bw && (pstat->tx_bw == HT_CHANNEL_WIDTH_20_40)
+#ifdef WIFI_11N_2040_COEXIST
+ && !((((GET_MIB(priv))->dot11OperationEntry.opmode) & WIFI_AP_STATE)
+ && priv->pmib->dot11nConfigEntry.dot11nCoexist
+ && (priv->bg_ap_timeout || priv->force_20_sta || priv->switch_20_sta
+#ifdef STA_EXT
+ || priv->force_20_sta_ext || priv->switch_20_sta_ext
+#endif
+ ))
+#endif
+ )
+
+ bCurTxBW40MHz = TRUE;
+
+ }
+
+ // assign band mask and rate bitmap
+ switch (WirelessMode) {
+ case WIRELESS_MODE_B: {
+ ratr_index = RATR_INX_WIRELESS_B;
+ if (ratr_bitmap & 0x0000000c) //11M or 5.5M enable
+ ratr_bitmap &= 0x0000000d;
+ else
+ ratr_bitmap &= 0x0000000f;
+ }
+ break;
+
+ case WIRELESS_MODE_G: {
+ ratr_index = RATR_INX_WIRELESS_GB;
+
+ if (rssi_level == 1)
+ ratr_bitmap &= 0x00000f00;
+ else if (rssi_level == 2)
+ ratr_bitmap &= 0x00000ff0;
+ else
+ ratr_bitmap &= 0x00000ff5;
+ }
+ break;
+
+ case WIRELESS_MODE_A: {
+ ratr_index = RATR_INX_WIRELESS_G;
+ ratr_bitmap &= 0x00000ff0;
+ }
+ break;
+
+ case WIRELESS_MODE_N_24G:
+ case WIRELESS_MODE_N_5G: {
+ if (WirelessMode == WIRELESS_MODE_N_24G)
+ ratr_index = RATR_INX_WIRELESS_NGB;
+ else
+ ratr_index = RATR_INX_WIRELESS_NG;
+
+ // if(MimoPs <= MIMO_PS_DYNAMIC)
+ if (MimoPs < MIMO_PS_DYNAMIC) {
+ if (rssi_level == 1)
+ ratr_bitmap &= 0x000f0000;
+ else if (rssi_level == 2)
+ ratr_bitmap &= 0x000ff000;
+ else
+ ratr_bitmap &= 0x000ff005;
+ } else {
+ if (rf_mimo_mode == MIMO_1T1R) {
+ if (bCurTxBW40MHz) {
+ if (rssi_level == 1)
+ ratr_bitmap &= 0x000f0000;
+ else if (rssi_level == 2)
+ ratr_bitmap &= 0x000ff000;
+ else
+ ratr_bitmap &= 0x000ff015;
+ } else {
+ if (rssi_level == 1)
+ ratr_bitmap &= 0x000f0000;
+ else if (rssi_level == 2)
+ ratr_bitmap &= 0x000ff000;
+ else
+ ratr_bitmap &= 0x000ff005;
+ }
+ } else {
+ if (bCurTxBW40MHz) {
+ if (rssi_level == 1)
+ ratr_bitmap &= 0x0f8f0000;
+ else if (rssi_level == 2)
+ ratr_bitmap &= 0x0f8ff000;
+ else
+ ratr_bitmap &= 0x0f8ff015;
+ } else {
+ if (rssi_level == 1)
+ ratr_bitmap &= 0x0f8f0000;
+ else if (rssi_level == 2)
+ ratr_bitmap &= 0x0f8ff000;
+ else
+ ratr_bitmap &= 0x0f8ff005;
+ }
+ }
+ }
+ }
+ break;
+
+ case WIRELESS_MODE_AC_5G: {
+ ratr_index = RATR_INX_WIRELESS_AC_N;
+
+ if (rf_mimo_mode == MIMO_1T1R)
+ ratr_bitmap &= 0x003ff010;
+ else
+ ratr_bitmap &= 0xfffff010;
+
+ ratr_bitmap &= (priv->pmib->dot11acConfigEntry.dot11VHT_TxMap << 12)|0xff0;
+
+ }
+ break;
+
+ default:
+ ratr_index = RATR_INX_WIRELESS_NGB;
+
+ if (rf_mimo_mode == MIMO_1T1R)
+ ratr_bitmap &= 0x000ff0ff;
+ else
+ ratr_bitmap &= 0x0f8ff0ff;
+ break;
+ }
+
+ BW = Get_RA_BW(bCurTxBW80MHz, bCurTxBW40MHz);
+ bShortGI = Get_RA_ShortGI(priv, pEntry, WirelessMode, BW);
+
+
+
+ pstat->ratr_idx = MRateIdxToARFRId8812(priv, ratr_index, rf_mimo_mode) ;
+ pstat->tx_bw_fw = BW;
+
+ H2CCommand[0] = (pstat->aid);
+ H2CCommand[1] = (pstat->ratr_idx) | (bShortGI ? 0x80 : 0x00) ;
+ H2CCommand[2] = BW | Get_VHT_ENI(IOTAction, WirelessMode, ratr_bitmap);
+
+
+ H2CCommand[2] |= BIT6; // DisableTXPowerTraining
+
+ H2CCommand[3] = (u1Byte)(ratr_bitmap & 0x000000ff);
+ H2CCommand[4] = (u1Byte)((ratr_bitmap & 0x0000ff00) >> 8);
+ H2CCommand[5] = (u1Byte)((ratr_bitmap & 0x00ff0000) >> 16);
+ H2CCommand[6] = (u1Byte)((ratr_bitmap & 0xff000000) >> 24);
+
+ FillH2CCmd8812(priv, H2C_8812_RA_MASK, 7, H2CCommand);
+
+ SetBcnCtrlReg_8812(priv, BIT3, 0);
+ /*
+ panic_printk("UpdateHalRAMask8812E(): bitmap = %x ratr_index = %1x, MacID:%x, ShortGI:%x, MimoPs=%d\n",
+ ratr_bitmap, pstat->ratr_idx, (pstat->aid), bShortGI, MimoPs);
+
+ panic_printk("Cmd: %02x, %02x, %02x, %02x, %02x, %02x, %02x \n",
+ H2CCommand[0] ,H2CCommand[1], H2CCommand[2],
+ H2CCommand[3] ,H2CCommand[4], H2CCommand[5], H2CCommand[6] );
+ */
+}
+void
+UpdateHalMSRRPT8812(
+ struct rtl8192cd_priv *priv,
+ unsigned short aid,
+ unsigned char opmode
+)
+{
+ u1Byte H2CCommand[3] = { 0};
+
+ H2CCommand[0] = opmode & 0x01;
+ H2CCommand[1] = aid & 0xff;
+ H2CCommand[2] = 0;
+ FillH2CCmd8812(priv, H2C_8812_MSRRPT, 3, H2CCommand);
+
+ // panic_printk("UpdateHalMSRRPT8812 Cmd: %02x, %02x, %02x \n",
+ // H2CCommand[0] ,H2CCommand[1], H2CCommand[2]);
+}
+#if 0
+void check_txrate_by_reg_8812(struct rtl8192cd_priv *priv, struct stat_info *pstat)
+{
+ unsigned char initial_rate = 0x7f;
+ unsigned char legacyRA = 0 ;
+ unsigned int autoRate1 = 0;
+
+// if (!priv->pshare->rf_ft_var.update_rainfo)
+// return;
+
+ RTL_W8(0x8d, 0x01);
+ RTL_W8(0x8f, 0x40);
+
+ if ( should_restrict_Nrate(priv, pstat) && is_fixedMCSTxRate(priv))
+ legacyRA = 1;
+
+ if (pstat->aid && (pstat->aid < FW_NUM_STAT - 1)) {
+
+
+#ifdef WDS
+ if (pstat->state & WIFI_WDS) {
+ autoRate1 = (priv->pmib->dot11WdsInfo.entry[pstat->wds_idx].txRate == 0) ? 1 : 0;
+ } else
+#endif
+ {
+ autoRate1 = priv->pmib->dot11StationConfigEntry.autoRate;
+ }
+
+ if (autoRate1 || legacyRA) {
+ RTL_W8(0x8c, REMAP_AID(pstat) & 0x1f);
+ initial_rate = RTL_R8(0x2f0);
+ if ((initial_rate & 0x7f) == 0x7f)
+ return;
+
+
+ if ((initial_rate & 0x3f) < 12) {
+ pstat->current_tx_rate = dot11_rate_table[initial_rate & 0x3f];
+ pstat->ht_current_tx_info &= ~TX_USE_SHORT_GI;
+ } else {
+ if ((initial_rate & 0x3f) >= 44)
+ pstat->current_tx_rate = 0x90 + ((initial_rate & 0x3f) - 44);
+ else
+ pstat->current_tx_rate = 0x80 + ((initial_rate & 0x3f) - 12);
+
+ if (initial_rate & BIT(7))
+ pstat->ht_current_tx_info |= TX_USE_SHORT_GI;
+ else
+ pstat->ht_current_tx_info &= ~TX_USE_SHORT_GI;
+ }
+
+ priv->pshare->current_tx_rate = pstat->current_tx_rate;
+ priv->pshare->ht_current_tx_info = pstat->ht_current_tx_info;
+ }
+ }
+}
+#endif
+
+
+void odm_TXPowerTrackingCallback_ThermalMeter_8812E(struct rtl8192cd_priv * priv)
+{
+ unsigned char ThermalValue = 0, delta, channel, is_decrease, rf_mimo_mode;
+ unsigned char ThermalValue_AVG_count = 0;
+ unsigned int ThermalValue_AVG = 0;
+ int ele_D, value32;
+ char OFDM_index[2], index;
+ unsigned int i = 0, j = 0, rf;
+
+ unsigned char OFDM_min_index = 7; //OFDM BB Swing should be less than +2.5dB, which is required by Arthur
+
+ rf_mimo_mode = get_rf_mimo_mode(priv);
+
+#ifdef MP_TEST
+ if ((OPMODE & WIFI_MP_STATE) || priv->pshare->rf_ft_var.mp_specific) {
+ channel = priv->pshare->working_channel;
+ if (priv->pshare->mp_txpwr_tracking == FALSE)
+ return;
+ } else
+#endif
+ {
+ channel = (priv->pmib->dot11RFEntry.dot11channel);
+ }
+
+ if (priv->pshare->Power_tracking_on_8812 == 0) {
+ priv->pshare->Power_tracking_on_8812 = 1;
+ PHY_SetRFReg(priv, RF92CD_PATH_A, 0x42, (BIT(17) | BIT(16)), 0x03);
+ return;
+ } else {
+ priv->pshare->Power_tracking_on_8812 = 0;
+ ThermalValue = (unsigned char)PHY_QueryRFReg(priv, RF_PATH_A, 0x42, 0xfc00, 1); //0x42: RF Reg[15:10] 88E
+ //printk("\nReadback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n", ThermalValue, priv->pshare->ThermalValue, priv->pmib->dot11RFEntry.ther);
+ }
+
+ switch (rf_mimo_mode) {
+ case MIMO_1T1R:
+ rf = 1;
+ break;
+ case MIMO_2T2R:
+ rf = 2;
+ break;
+ default:
+ panic_printk("%s:%d get_rf_mimo_mode error!\n", __FUNCTION__, __LINE__);
+ break;
+ }
+
+ //Query OFDM path A default setting Bit[31:21]
+ ele_D = PHY_QueryBBReg(priv, 0xc1c, 0xffe00000);
+ for (i = 0; i < OFDM_TABLE_SIZE_8812; i++) {
+ if (ele_D == OFDMSwingTable_8812[i]) {
+ OFDM_index[0] = (unsigned char)i;
+ //printk("PathA 0xc1c[32:21] = 0x%x, OFDM_index=%d\n", ele_D, OFDM_index[0]);
+ break;
+ }
+ }
+
+ //Query OFDM path B default setting
+ if (rf_mimo_mode == MIMO_2T2R) {
+ ele_D = PHY_QueryBBReg(priv, 0xe1c, 0xffe00000);
+ for (i = 0; i < OFDM_TABLE_SIZE_8812; i++) {
+ if (ele_D == OFDMSwingTable_8812[i]) {
+ OFDM_index[1] = (unsigned char)i;
+ //printk("PathB 0xe1c[31:21] = 0x%x, OFDM_index=%d\n", ele_D, OFDM_index[1]);
+ break;
+ }
+ }
+ }
+
+ /* Initialize */
+ if (!priv->pshare->ThermalValue) {
+ priv->pshare->ThermalValue = priv->pmib->dot11RFEntry.ther;
+
+ }
+
+ /* calculate average thermal meter */
+ {
+ priv->pshare->ThermalValue_AVG_8812[priv->pshare->ThermalValue_AVG_index_8812] = ThermalValue;
+ priv->pshare->ThermalValue_AVG_index_8812++;
+ if (priv->pshare->ThermalValue_AVG_index_8812 == AVG_THERMAL_NUM_8812)
+ priv->pshare->ThermalValue_AVG_index_8812 = 0;
+
+ for (i = 0; i < AVG_THERMAL_NUM_8812; i++) {
+ if (priv->pshare->ThermalValue_AVG_8812[i]) {
+ ThermalValue_AVG += priv->pshare->ThermalValue_AVG_8812[i];
+ ThermalValue_AVG_count++;
+ }
+ }
+
+ if (ThermalValue_AVG_count) {
+ ThermalValue = (unsigned char)(ThermalValue_AVG / ThermalValue_AVG_count);
+ //printk("AVG Thermal Meter = 0x%x \n", ThermalValue);
+ }
+ }
+
+ if (ThermalValue != priv->pshare->ThermalValue) {
+ //printk("\n******** START:%s() ********\n", __FUNCTION__);
+ //printk("\nReadback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n", ThermalValue, priv->pshare->ThermalValue, priv->pmib->dot11RFEntry.ther);
+
+ delta = RTL_ABS(ThermalValue, priv->pmib->dot11RFEntry.ther);
+ is_decrease = ((ThermalValue < priv->pmib->dot11RFEntry.ther) ? 1 : 0);
+ if (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G) {
+#ifdef _TRACKING_TABLE_FILE
+ if (priv->pshare->rf_ft_var.pwr_track_file) {
+ if (is_decrease) {
+ for (i = 0; i < rf; i++) {
+ OFDM_index[i] = priv->pshare->OFDM_index0[i] + get_tx_tracking_index(priv, channel, i, delta, is_decrease, 0);
+ OFDM_index[i] = ((OFDM_index[i] > (OFDM_TABLE_SIZE_8812 - 1)) ? (OFDM_TABLE_SIZE_8812 - 1) : OFDM_index[i]);
+ //printk(">>> decrese power ---> new OFDM_INDEX:%d (%d + %d)\n", OFDM_index[i], priv->pshare->OFDM_index0[i], get_tx_tracking_index(priv, channel, i, delta, is_decrease, 0));
+ }
+ } else {
+ for (i = 0; i < rf; i++) {
+ OFDM_index[i] = priv->pshare->OFDM_index0[i] - get_tx_tracking_index(priv, channel, i, delta, is_decrease, 0);
+ OFDM_index[i] = ((OFDM_index[i] < OFDM_min_index) ? OFDM_min_index : OFDM_index[i]);
+ //printk(">>> increse power ---> new OFDM_INDEX:%d (%d - %d)\n", OFDM_index[i], priv->pshare->OFDM_index0[i], get_tx_tracking_index(priv, channel, i, delta, is_decrease, 0));
+ }
+ }
+ }
+#endif
+ PHY_SetBBReg(priv, 0xc1c, 0xffe00000, OFDMSwingTable_8812[(unsigned int)OFDM_index[0]]);
+ if (rf_mimo_mode == MIMO_2T2R)
+ PHY_SetBBReg(priv, 0xe1c, 0xffe00000, OFDMSwingTable_8812[(unsigned int)OFDM_index[1]]);
+
+
+ }
+/*
+ printk("PathA >>>>> 0xc1c[31:21] = 0x%x, OFDM_index:%d\n", PHY_QueryBBReg(priv, 0xc1c, 0xffe00000), OFDM_index[0]);
+ if (rf_mimo_mode == MIMO_2T2R)
+ printk("PathB >>>>> 0xe1c[31:21] = 0x%x, OFDM_index:%d\n", PHY_QueryBBReg(priv, 0xe1c, 0xffe00000), OFDM_index[1]);
+ printk("\n******** END:%s() ********\n", __FUNCTION__);
+*/
+ //update thermal meter value
+ priv->pshare->ThermalValue = ThermalValue;
+ for (i = 0 ; i < rf ; i++)
+ priv->pshare->OFDM_index[i] = OFDM_index[i];
+ }
+}
+
+
+void requestTxReport_8812(struct rtl8192cd_priv *priv)
+{
+ unsigned char h2cresult, counter = 20;
+ struct stat_info *sta;
+ unsigned char H2CCommand[2] = {0xff, 0xff};
+
+ if ( priv->pshare->sta_query_idx == -1)
+ return;
+
+ while (is_h2c_buf_occupy(priv)) {
+ delay_ms(2);
+ if (--counter == 0)
+ break;
+ }
+
+ if (!counter)
+ return;
+
+ sta = findNextSTA(priv, &priv->pshare->sta_query_idx);
+ if (sta)
+ H2CCommand[0] = REMAP_AID(sta);
+ else {
+ priv->pshare->sta_query_idx = -1;
+ return;
+ }
+
+ sta = findNextSTA(priv, &priv->pshare->sta_query_idx);
+ if (sta) {
+ H2CCommand[1] = REMAP_AID(sta);
+ } else {
+ priv->pshare->sta_query_idx = -1;
+ }
+
+ //WDEBUG("\n");
+ h2cresult = FillH2CCmd8812(priv, H2C_8812_TX_REPORT, 2 , H2CCommand);
+ //WDEBUG("h2cresult=%d\n",h2cresult);
+
+
+}
+
+
+/*C2H_isr_8812()
+AP Req Txrpt
+"Start Address:USB:0xFD20PCIe/USB: 0x01A0"
+|ID|SEQ |CONTENT |LEN|TRIGGER|
+-----------------------------------------
+|0 | 1 |2~13 |14 |15 |
+-----------------------------------------
+
+|ID=0x04|SEQ|STA1 MACID(1B)|Tx_ok1(2B)|Tx_fail1(2B)|initial rate1(1B)|STA2 MACID(1B)|Tx_ok2(2B)|Tx_fail2(2B)|Initial rate2(1B)|Len=12(1B)|FF(1B)|
+*/
+void C2H_isr_8812(struct rtl8192cd_priv *priv)
+{
+ struct tx_rpt rpt1;
+ int j, C2H_ID;
+ unsigned char MacID = 0xff;
+ int idx = 0x1a2;
+ unsigned long flags=0;
+
+ //WDEBUG("\n");
+
+ SAVE_INT_AND_CLI(flags);
+ C2H_ID = RTL_R8(0x1a0);
+
+ if ( (C2H_ID) == C2H_8812_TX_REPORT ) {
+
+ for (j = 0; j < 2; j++) {
+
+ MacID = RTL_R8(idx);
+ if (MacID == 0xff)
+ continue;
+
+ rpt1.macid = MacID & TXdesc_92E_MacIdMask;
+
+ if (rpt1.macid) {
+
+ rpt1.txok = (RTL_R8(idx + 2)<<8) | RTL_R8(idx + 1);
+ rpt1.txfail = (RTL_R8(idx + 4)<<8) | RTL_R8(idx + 3);
+/*
+#ifdef _BIG_ENDIAN_
+ rpt1.txok = le16_to_cpu(RTL_R16(idx + 1));
+ rpt1.txfail = le16_to_cpu(RTL_R16(idx + 3));
+#else
+ rpt1.txok = be16_to_cpu(RTL_R16(idx + 1));
+ rpt1.txfail = be16_to_cpu(RTL_R16(idx + 3));
+#endif
+*/
+ rpt1.initil_tx_rate = RTL_R8(idx + 5);
+ txrpt_handler(priv, &rpt1); // add inital tx rate handle for 8812E
+ }
+ idx += 6;
+ }
+ }
+
+#ifdef BEAMFORMING_SUPPORT
+ if((C2H_ID & 0xF) == C2H_8812_TXBF) {
+ u1Byte tmpBuf = RTL_R8(REG_C2HEVT_MSG_NORMAL_8812+2);
+ if(tmpBuf& BIT0) {
+// check sounding BW also...
+ if(priv->pshare->BeamformingCurIdx)
+ RTL_W16(REG_TXBF_CTRL_8812+2, RTL_R16(REG_TXBF_CTRL_8812+2) | BIT11);
+ else
+ RTL_W16(REG_TXBF_CTRL_8812, RTL_R16(REG_TXBF_CTRL_8812) | BIT11);
+ } else {
+ BeamformingEnd(priv, tmpBuf& BIT0);
+ }
+ }
+#endif
+
+ RTL_W8( 0x1af, 0);
+ if ( (C2H_ID) == C2H_8812_TX_REPORT )
+ requestTxReport_8812(priv);
+ RESTORE_INT(flags);
+}
+
+#ifdef BEAMFORMING_SUPPORT
+VOID
+SetBeamformEnter8812(
+ struct rtl8192cd_priv *priv,
+ IN u1Byte Idx
+ )
+{
+ u1Byte i = 0;
+ RT_BEAMFORMING_INFO BeamformInfo = priv->pshare->BeamformingInfo[Idx];
+ u2Byte STAid = 0;
+
+ if(OPMODE & WIFI_ADHOC_STATE)
+ STAid = BeamformInfo.AID + 1;
+ else
+ STAid = BeamformInfo.P_AID;
+
+ if (!IS_TEST_CHIP(priv)) {
+ if (IS_C_CUT_8812(priv))
+ RTL_W16( REG_SND_PTCL_CTRL_8812, 0x2CB); // Disable SIG-B CRC8 check
+ else
+ RTL_W16( REG_SND_PTCL_CTRL_8812, 0x0B);
+ }
+ else
+ RTL_W16( REG_SND_PTCL_CTRL_8812, 0x1B);
+
+ // MAC addresss/Partial AID of Beamformer
+ if(Idx == 0)
+ {
+ for(i = 0; i < 6 ; i++)
+ RTL_W8( (REG_BFMER0_INFO_8812+i), BeamformInfo.MacAddr[i]);
+
+ RTL_W16( REG_BFMER0_INFO_8812+6, BeamformInfo.P_AID);
+ }
+ else
+ {
+ for(i = 0; i < 6 ; i++)
+ RTL_W8( (REG_BFMER1_INFO_8812+i), BeamformInfo.MacAddr[i]);
+
+ RTL_W16( REG_BFMER1_INFO_8812+6, BeamformInfo.P_AID);
+ }
+
+ // CSI report parameters of Beamformer
+ RTL_W32( REG_CSI_RPT_PARAM_BW20_8812, 0x05090509);
+ RTL_W32( REG_CSI_RPT_PARAM_BW40_8812, 0x05090509);
+ RTL_W32( REG_CSI_RPT_PARAM_BW80_8812, 0x05090509);
+
+ // P_AID of Beamformee & enable NDPA transmission
+ if(Idx == 0)
+ {
+ RTL_W16( REG_TXBF_CTRL_8812, STAid);
+ RTL_W8( REG_TXBF_CTRL_8812+3, RTL_R8( REG_TXBF_CTRL_8812+3)|BIT6|BIT7|BIT4);
+ }
+ else
+ {
+ RTL_W16( REG_TXBF_CTRL_8812+2, STAid |BIT14| BIT15|BIT12);
+ }
+
+ // CSI report parameters of Beamformee
+ if(Idx == 0)
+ {
+ // Get BIT24 & BIT25
+ u1Byte tmp = RTL_R8( REG_BFMEE_SEL_8812+3) & 0x3;
+ RTL_W8( REG_BFMEE_SEL_8812+3, tmp | 0x60);
+ RTL_W16( REG_BFMEE_SEL_8812, STAid | BIT9);
+ }
+ else
+ {
+ // Set BIT25
+ RTL_W16( REG_BFMEE_SEL_8812+2, STAid | 0xE2);
+ }
+
+ // Timeout value for MAC to leave NDP_RX_standby_state 60 us
+// RTL_W8( REG_SND_PTCL_CTRL_8812+3, 0x3C);
+ RTL_W8( REG_SND_PTCL_CTRL_8812+3, 0x50); // // ndp_rx_standby_timer
+
+
+// if(pHalData->bIsMPChip == FALSE)
+ if (IS_TEST_CHIP(priv))
+ {
+ // VHT category value
+ RTL_W8( REG_SND_PTCL_CTRL_8812+1, ACT_CAT_VHT);
+ // NDPA subtype
+ RTL_W8( REG_SND_PTCL_CTRL_8812+2, Type_NDPA >> 4);
+ }
+}
+
+
+VOID
+SetBeamformLeave8812(
+ struct rtl8192cd_priv *priv,
+ IN u1Byte Idx
+ )
+{
+// RT_BEAMFORMING_INFO BeamformInfo = Adapter->MgntInfo.BeamformingInfo[Idx];
+
+ /* Clear P_AID of Beamformee
+ * Clear MAC addresss of Beamformer
+ * Clear Associated Bfmee Sel
+ */
+ if(Idx == 0)
+ {
+ RTL_W16( REG_TXBF_CTRL_8812, 0);
+
+ RTL_W32( REG_BFMER0_INFO_8812, 0);
+ RTL_W16( REG_BFMER0_INFO_8812+4, 0);
+
+ RTL_W16( REG_BFMEE_SEL_8812, 0);
+ }
+ else
+ {
+ RTL_W16( REG_TXBF_CTRL_8812+2,
+ RTL_R8( REG_TXBF_CTRL_8812+3) & 0xE0);
+
+ RTL_W32( REG_BFMER1_INFO_8812, 0);
+ RTL_W16( REG_BFMER1_INFO_8812+4, 0);
+
+ RTL_W16( REG_BFMEE_SEL_8812+2,
+ RTL_R16( REG_BFMEE_SEL_8812+2) & 0x60);
+ }
+}
+
+
+
+//2REG_C2HEVT_CLEAR
+#define C2H_EVT_HOST_CLOSE 0x00 // Set by driver and notify FW that the driver has read the C2H command message
+#define C2H_EVT_FW_CLOSE 0xFF // Set by FW indicating that FW had set the C2H command message and it's not yet read by driver.
+
+
+
+VOID Beamforming_NDPARate(
+ struct rtl8192cd_priv *priv,
+ BOOLEAN mode,
+ u1Byte BW,
+ u1Byte rate)
+{
+ {
+ if(mode ==0) {
+#if 1
+ rate = 11; // 54M
+ BW = 0;
+#else
+ rate = 0x0c; //_MCS0_RATE_;
+ if(BW ==3)
+ BW= 2;
+#endif
+ }
+ else {
+ rate = 0x2c; //_NSS1_MCS0_RATE_;
+
+ }
+ }
+ RTL_W8(0x45f, (rate<<2) | (BW & 0x03));
+
+}
+
+
+#endif
+
+
+VOID RTL8812_MACID_PAUSE(
+ struct rtl8192cd_priv *priv,
+ BOOLEAN bSleep,
+ u4Byte aid
+)
+{
+ if (priv->pshare->rf_ft_var.enable_macid_sleep) {
+ if (bSleep) {
+ if (aid > MACID_REGION3_LIMIT)
+ RTL_W32(REG_MACID_PKT_SLEEP_3, RTL_R32(REG_MACID_PKT_SLEEP_3) | BIT(aid-MACID_REGION3_LIMIT));
+ else if(aid > MACID_REGION2_LIMIT)
+ RTL_W32(REG_MACID_PKT_SLEEP_2, RTL_R32(REG_MACID_PKT_SLEEP_2) | BIT(aid-MACID_REGION2_LIMIT));
+ else if(aid > MACID_REGION1_LIMIT)
+ RTL_W32(REG_MACID_PKT_SLEEP_1, RTL_R32(REG_MACID_PKT_SLEEP_1) | BIT(aid-MACID_REGION1_LIMIT));
+ else
+ RTL_W32(REG_MACID_PKT_SLEEP_0, RTL_R32(REG_MACID_PKT_SLEEP_0) | BIT(aid));
+ } else {
+ if (aid > MACID_REGION3_LIMIT)
+ RTL_W32(REG_MACID_PKT_SLEEP_3, RTL_R32(REG_MACID_PKT_SLEEP_3) & ~BIT(aid-MACID_REGION3_LIMIT));
+ else if(aid > MACID_REGION2_LIMIT)
+ RTL_W32(REG_MACID_PKT_SLEEP_2, RTL_R32(REG_MACID_PKT_SLEEP_2) & ~BIT(aid-MACID_REGION2_LIMIT));
+ else if(aid > MACID_REGION1_LIMIT)
+ RTL_W32(REG_MACID_PKT_SLEEP_1, RTL_R32(REG_MACID_PKT_SLEEP_1) & ~BIT(aid-MACID_REGION1_LIMIT));
+ else
+ RTL_W32(REG_MACID_PKT_SLEEP_0, RTL_R32(REG_MACID_PKT_SLEEP_0) & ~BIT(aid));
+ }
+ }
+}
+
+
+#endif //CONFIG_RTL_8812_SUPPORT
+
+
+#if defined(DFS) || defined(FOR_VHT5G_PF)
+void SwitchChannel(struct rtl8192cd_priv *priv)
+{
+
+ int ch = priv->pshare->dfsSwitchChannel;
+ int staidx = 0;
+ struct stat_info *pstat = findNextSTA(priv, &staidx);
+
+ priv->pmib->dot11RFEntry.dot11channel = ch;
+ priv->pshare->dfsSwitchChannel = 0;
+ RTL_W8(TXPAUSE, 0xff);
+
+ PHY_SetBBReg(priv, 0x924, BIT(15), 0); // disable HW DFS report
+#ifdef DFS
+ if (!priv->pmib->dot11DFSEntry.disable_DFS &&
+ (OPMODE & WIFI_AP_STATE)) {
+ if (timer_pending(&priv->DFS_timer))
+ del_timer_sync(&priv->DFS_timer);
+
+ if (timer_pending(&priv->ch_avail_chk_timer))
+ del_timer_sync(&priv->ch_avail_chk_timer);
+
+ if (timer_pending(&priv->dfs_det_chk_timer))
+ del_timer_sync(&priv->dfs_det_chk_timer);
+ }
+#endif
+
+ priv->pshare->CurrentChannelBW = priv->pshare->is_40m_bw = priv->pmib->dot11nConfigEntry.dot11nUse40M;
+
+ if (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_80 &&
+ priv->pmib->dot11RFEntry.band5GSelected == PHY_BAND_5G_3)
+ {
+ int channel = priv->pmib->dot11RFEntry.dot11channel;
+
+ if (!is80MChannel(priv->available_chnl, priv->available_chnl_num, channel)) {
+ priv->pshare->CurrentChannelBW = priv->pshare->is_40m_bw = HT_CHANNEL_WIDTH_AC_20;
+ }
+ }
+ panic_printk("4. Swiching channel to %d! BW %dM mode\n", priv->pmib->dot11RFEntry.dot11channel,
+ (priv->pshare->CurrentChannelBW == 2)? 80 : ((priv->pshare->CurrentChannelBW == 1)? 40 : 20));
+
+ if ((ch>144) ? ((ch-1)%8) : (ch%8)) {
+ GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_ABOVE;
+ priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_ABOVE;
+ } else {
+ GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW;
+ priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_BELOW;
+ }
+
+ SwBWMode(priv, priv->pshare->CurrentChannelBW, priv->pshare->offset_2nd_chan);
+ SwChnl(priv, priv->pmib->dot11RFEntry.dot11channel, priv->pshare->offset_2nd_chan);
+ PHY_IQCalibrate(priv); //FOR_8812_IQK
+
+ priv->pmib->dot11DFSEntry.DFS_detected = 0;
+ priv->ht_cap_len = 0;
+
+#ifdef MBSSID
+ if (priv->pmib->miscEntry.vap_enable) {
+ int i;
+ for (i=0; i<RTL8192CD_NUM_VWLAN; i++) {
+ if (IS_DRV_OPEN(priv->pvap_priv[i])) {
+ priv->pvap_priv[i]->pmib->dot11RFEntry.dot11channel = ch;
+ priv->pvap_priv[i]->ht_cap_len = 0;
+ }
+ }
+ }
+#endif
+
+ RTL_W8(TXPAUSE, 0x00);
+
+
+ while(pstat)
+ {
+#ifdef TX_SHORTCUT
+ if (!priv->pmib->dot11OperationEntry.disable_txsc) {
+ int i;
+ for (i=0; i<TX_SC_ENTRY_NUM; i++)
+ pstat->tx_sc_ent[i].hwdesc1.Dword7 &= ~(TX_TxBufSizeMask);
+ }
+#endif
+
+#ifdef CONFIG_RTL_8812_SUPPORT
+ if (GET_CHIP_VER(priv) == VERSION_8812E) {
+ UpdateHalRAMask8812(priv, pstat, 3);
+ }
+#endif
+#ifdef CONFIG_WLAN_HAL
+ if (IS_HAL_CHIP(priv)) {
+ GET_HAL_INTERFACE(priv)->UpdateHalRAMaskHandler(priv, pstat, 3);
+ }
+#endif
+
+ pstat = findNextSTA(priv, &staidx);
+
+ }
+
+#ifdef DFS
+ if (!priv->pmib->dot11DFSEntry.disable_DFS &&
+ (OPMODE & WIFI_AP_STATE) &&
+ (((priv->pmib->dot11RFEntry.dot11channel >= 52) &&
+ (priv->pmib->dot11RFEntry.dot11channel <= 64)) ||
+ ((priv->pmib->dot11RFEntry.dot11channel >= 100) &&
+ (priv->pmib->dot11RFEntry.dot11channel <= 140)))) {
+
+ init_timer(&priv->ch_avail_chk_timer);
+ priv->ch_avail_chk_timer.data = (unsigned long) priv;
+ priv->ch_avail_chk_timer.function = rtl8192cd_ch_avail_chk_timer;
+
+ if ((priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_ETSI) &&
+ ((priv->pmib->dot11RFEntry.dot11channel >= 120) &&
+ (priv->pmib->dot11RFEntry.dot11channel <= 130)))
+ mod_timer(&priv->ch_avail_chk_timer, jiffies + CH_AVAIL_CHK_TO_CE);
+ else
+ mod_timer(&priv->ch_avail_chk_timer, jiffies + CH_AVAIL_CHK_TO);
+
+ init_timer(&priv->DFS_timer);
+ priv->DFS_timer.data = (unsigned long) priv;
+ priv->DFS_timer.function = rtl8192cd_DFS_timer;
+
+ init_timer(&priv->DFS_TXPAUSE_timer);
+ priv->DFS_TXPAUSE_timer.data = (unsigned long) priv;
+ priv->DFS_TXPAUSE_timer.function = rtl8192cd_DFS_TXPAUSE_timer;
+
+ /* DFS activated after 5 sec; prevent switching channel due to DFS false alarm */
+ mod_timer(&priv->DFS_timer, jiffies + RTL_SECONDS_TO_JIFFIES(5));
+
+ if (priv->pshare->rf_ft_var.dfs_det_off == 0) {
+ init_timer(&priv->dfs_det_chk_timer);
+ priv->dfs_det_chk_timer.data = (unsigned long) priv;
+ priv->dfs_det_chk_timer.function = rtl8192cd_dfs_det_chk_timer;
+ mod_timer(&priv->dfs_det_chk_timer, jiffies + RTL_MILISECONDS_TO_JIFFIES(priv->pshare->rf_ft_var.dfs_det_period*10));
+ }
+
+ DFS_SetReg(priv);
+
+ priv->pmib->dot11DFSEntry.disable_tx = 1;
+ }
+ else
+ priv->pmib->dot11DFSEntry.disable_tx = 0;
+#endif
+}
+#endif
+