43 #include <linux/module.h>
47 #define LINK_Q ui_link_quality
48 #define RX_EVM rx_evm_percentage
49 #define RX_SIGQ rx_mimo_signalquality
58 const char *versionid;
81 chip_version |= ((value32 &
RF_RL_ID) ?
86 pr_info(
"Chip version 0x%x\n", chip_version);
89 versionid =
"NORMAL_B_CHIP_92C";
92 versionid =
"NORMAL_TSMC_CHIP_92C";
95 versionid =
"NORMAL_TSMC_CHIP_88C";
98 versionid =
"NORMAL_UMC_CHIP_i92C_1T2R_A_CUT";
101 versionid =
"NORMAL_UMC_CHIP_92C_A_CUT";
104 versionid =
"NORMAL_UMC_CHIP_88C_A_CUT";
107 versionid =
"NORMAL_UMC_CHIP_92C_1T2R_B_CUT";
110 versionid =
"NORMAL_UMC_CHIP_92C_B_CUT";
113 versionid =
"NORMAL_UMC_CHIP_88C_B_CUT";
116 versionid =
"NORMAL_UMC_CHIP_8723_1T1R_A_CUT";
119 versionid =
"NORMAL_UMC_CHIP_8723_1T1R_B_CUT";
122 versionid =
"TEST_CHIP_92C";
125 versionid =
"TEST_CHIP_88C";
128 versionid =
"UNKNOWN";
132 "Chip Version ID: %s\n", versionid);
140 "Chip RF Type: %s\n",
142 if (get_rf_type(rtlphy) ==
RF_1T1R)
143 rtlpriv->
dm.rfpath_rxenable[0] =
true;
145 rtlpriv->
dm.rfpath_rxenable[0] =
146 rtlpriv->
dm.rfpath_rxenable[1] =
true;
175 "Failed to polling write LLT done at address %d! _LLT_OP_VALUE(%x)\n",
196 for (i = 0; i < (boundary - 1); i++) {
199 pr_err(
"===> %s #1 fail\n", __func__);
206 pr_err(
"===> %s #2 fail\n", __func__);
217 pr_err(
"===> %s #3 fail\n", __func__);
224 pr_err(
"===> %s #4 fail\n", __func__);
230 u8 *p_macaddr,
bool is_group,
u8 enc_algo,
231 bool is_wepkey,
bool clear_all)
238 bool is_pairwise =
false;
239 static u8 cam_const_addr[4][6] = {
240 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
241 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
242 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
243 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
245 static u8 cam_const_broad[] = {
246 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
255 for (idx = 0; idx < clear_number; idx++) {
261 rtlpriv->
sec.key_len[
idx] = 0;
280 "illegal switch case\n");
284 if (is_wepkey || rtlpriv->
sec.use_defaultkey) {
289 macaddr = cam_const_broad;
297 if (rtlpriv->
sec.key_len[key_index] == 0) {
299 "delete one entry\n");
303 "The insert KEY length is %d\n",
306 "The insert KEY is %x %x\n",
307 rtlpriv->
sec.key_buf[0][0],
308 rtlpriv->
sec.key_buf[0][1]);
313 "Pairwise Key content",
314 rtlpriv->
sec.pairwise_key,
318 "set Pairwise key\n");
341 rtlpriv->
sec.key_buf[entry_id]);
394 u4b_ac_param = (
u32) mac->
ac[aci].aifs;
419 RT_ASSERT(
false,
"invalid aci: %d !\n", aci);
433 rtl_write_byte(rtlpriv, (
REG_MACID + i), *(addr+i));
436 "MAC Address: %02X-%02X-%02X-%02X-%02X-%02X\n",
460 "Set Network type to NO LINK!\n");
465 "Set Network type to Ad Hoc!\n");
470 "Set Network type to STA!\n");
475 "Set Network type to AP!\n");
479 "Network type %d not supported!\n", type);
482 rtl_write_byte(rtlpriv, (
REG_CR + 2), value);
498 value32 = rtl_read_dword(rtlpriv,
REG_RRSR);
501 rtl_write_dword(rtlpriv,
REG_RRSR, value32);
507 rtl_write_dword(rtlpriv,
REG_RL, value16);
515 rtl_write_dword(rtlpriv,
REG_DARFRC, 0x00000000);
516 rtl_write_dword(rtlpriv,
REG_DARFRC+4, 0x10080404);
517 rtl_write_dword(rtlpriv,
REG_RARFRC, 0x04030201);
518 rtl_write_dword(rtlpriv,
REG_RARFRC+4, 0x08070605);
530 static void rtl92c_set_ofdm_sifs(
struct ieee80211_hw *hw,
u8 trx_sifs,
549 value |= ((
u32)cw_min & 0xF) << 8;
550 value |= ((
u32)cw_max & 0xF) << 12;
551 value |= (
u32)txop << 16;
567 rtl92c_set_cck_sifs(hw, 0xa, 0xa);
568 rtl92c_set_ofdm_sifs(hw, 0
xe, 0
xe);
580 rtl_write_byte(rtlpriv,
REG_PIFS, 0x1C);
595 rtl_write_word(rtlpriv, 0x4CA, 0x0708);
623 rtl_write_byte(rtlpriv,
REG_ACKTO, 0x40);
699 static u8 _rtl92c_query_rxpwrpercentage(
char antpower)
701 if ((antpower <= -100) || (antpower >= 20))
703 else if (antpower >= 0)
706 return 100 + antpower;
709 static u8 _rtl92c_evm_db_to_percentage(
char value)
718 ret_val = 0 - ret_val;
725 static long _rtl92c_translate_todbm(
struct ieee80211_hw *hw,
726 u8 signal_strength_index)
730 signal_power = (
long)((signal_strength_index + 1) >> 1);
735 static long _rtl92c_signal_scale_mapping(
struct ieee80211_hw *hw,
740 if (currsig >= 61 && currsig <= 100)
741 retsig = 90 + ((currsig - 60) / 4);
742 else if (currsig >= 41 && currsig <= 60)
743 retsig = 78 + ((currsig - 40) / 2);
744 else if (currsig >= 31 && currsig <= 40)
745 retsig = 66 + (currsig - 30);
746 else if (currsig >= 21 && currsig <= 30)
747 retsig = 54 + (currsig - 20);
748 else if (currsig >= 5 && currsig <= 20)
749 retsig = 42 + (((currsig - 5) * 2) / 3);
750 else if (currsig == 4)
752 else if (currsig == 3)
754 else if (currsig == 2)
756 else if (currsig == 1)
763 static void _rtl92c_query_rxphystatus(
struct ieee80211_hw *hw,
767 bool packet_match_bssid,
774 s8 rx_pwr_all = 0, rx_pwr[4];
775 u8 rf_rx_num = 0, evm, pwdb_all;
776 u8 i, max_spatial_stream;
777 u32 rssi, total_rssi = 0;
778 bool in_powersavemode =
false;
784 pstats->
is_cck = is_cck_rate;
786 pstats->
is_cck = is_cck_rate;
787 pstats->RX_SIGQ[0] = -1;
788 pstats->RX_SIGQ[1] = -1;
792 if (!in_powersavemode)
799 report = report >> 6;
802 rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
805 rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
808 rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
811 rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
816 report = p_drvinfo->
cfosho[0] & 0x60;
817 report = report >> 5;
820 rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1);
823 rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1);
826 rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1);
829 rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1);
833 pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
836 if (packet_match_bssid) {
847 sq = ((64 - sq) * 100) / 44;
850 pstats->RX_SIGQ[0] = sq;
851 pstats->RX_SIGQ[1] = -1;
854 rtlpriv->
dm.rfpath_rxenable[0] =
855 rtlpriv->
dm.rfpath_rxenable[1] =
true;
857 if (rtlpriv->
dm.rfpath_rxenable[i])
861 rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]);
863 rtlpriv->
stats.rx_snr_db[
i] =
866 if (packet_match_bssid)
869 rx_pwr_all = ((p_drvinfo->
pwdb_all >> 1) & 0x7f) - 110;
870 pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
877 max_spatial_stream = 2;
879 max_spatial_stream = 1;
880 for (i = 0; i < max_spatial_stream; i++) {
881 evm = _rtl92c_evm_db_to_percentage(p_drvinfo->
rxevm[i]);
882 if (packet_match_bssid) {
893 (
u8) (_rtl92c_signal_scale_mapping(hw, pwdb_all));
894 else if (rf_rx_num != 0)
896 (
u8) (_rtl92c_signal_scale_mapping
897 (hw, total_rssi /= rf_rx_num));
900 static void _rtl92c_process_ui_rssi(
struct ieee80211_hw *hw,
906 u32 last_rssi, tmpval;
909 rtlpriv->
stats.rssi_calculate_cnt++;
910 if (rtlpriv->
stats.ui_rssi.total_num++ >=
912 rtlpriv->
stats.ui_rssi.total_num =
915 rtlpriv->
stats.ui_rssi.elements[rtlpriv->
916 stats.ui_rssi.index];
917 rtlpriv->
stats.ui_rssi.total_val -= last_rssi;
920 rtlpriv->
stats.ui_rssi.elements[rtlpriv->
stats.ui_rssi.
923 rtlpriv->
stats.ui_rssi.index = 0;
924 tmpval = rtlpriv->
stats.ui_rssi.total_val /
925 rtlpriv->
stats.ui_rssi.total_num;
926 rtlpriv->
stats.signal_strength =
927 _rtl92c_translate_todbm(hw, (
u8) tmpval);
928 pstats->
rssi = rtlpriv->
stats.signal_strength;
935 if (rtlpriv->
stats.rx_rssi_percentage[rfpath] == 0) {
936 rtlpriv->
stats.rx_rssi_percentage[rfpath] =
940 rtlpriv->
stats.rx_rssi_percentage[rfpath]) {
941 rtlpriv->
stats.rx_rssi_percentage[rfpath] =
943 rx_rssi_percentage[rfpath] *
948 rtlpriv->
stats.rx_rssi_percentage[rfpath] =
949 rtlpriv->
stats.rx_rssi_percentage[rfpath] +
952 rtlpriv->
stats.rx_rssi_percentage[rfpath] =
954 rx_rssi_percentage[rfpath] *
963 static void _rtl92c_update_rxsignalstatistics(
struct ieee80211_hw *hw,
969 if (rtlpriv->
stats.recv_signal_power == 0)
975 rtlpriv->
stats.recv_signal_power =
976 (rtlpriv->
stats.recv_signal_power * 5 +
980 static void _rtl92c_process_pwdb(
struct ieee80211_hw *hw,
985 long undecorated_smoothed_pwdb = 0;
990 undecorated_smoothed_pwdb =
991 rtlpriv->
dm.undecorated_smoothed_pwdb;
994 if (undecorated_smoothed_pwdb < 0)
997 undecorated_smoothed_pwdb =
998 (((undecorated_smoothed_pwdb) *
1001 undecorated_smoothed_pwdb = undecorated_smoothed_pwdb
1004 undecorated_smoothed_pwdb =
1005 (((undecorated_smoothed_pwdb) *
1009 rtlpriv->
dm.undecorated_smoothed_pwdb =
1010 undecorated_smoothed_pwdb;
1011 _rtl92c_update_rxsignalstatistics(hw, pstats);
1015 static void _rtl92c_process_LINK_Q(
struct ieee80211_hw *hw,
1019 u32 last_evm = 0, n_stream, tmpval;
1023 if (rtlpriv->
stats.LINK_Q.total_num++ >=
1025 rtlpriv->
stats.LINK_Q.total_num =
1028 rtlpriv->
stats.LINK_Q.elements
1029 [rtlpriv->
stats.LINK_Q.index];
1030 rtlpriv->
stats.LINK_Q.total_val -=
1033 rtlpriv->
stats.LINK_Q.total_val +=
1035 rtlpriv->
stats.LINK_Q.elements
1036 [rtlpriv->
stats.LINK_Q.index++] =
1038 if (rtlpriv->
stats.LINK_Q.index >=
1040 rtlpriv->
stats.LINK_Q.index = 0;
1041 tmpval = rtlpriv->
stats.LINK_Q.total_val /
1042 rtlpriv->
stats.LINK_Q.total_num;
1043 rtlpriv->
stats.signal_quality = tmpval;
1044 rtlpriv->
stats.last_sigstrength_inpercent = tmpval;
1045 for (n_stream = 0; n_stream < 2;
1047 if (pstats->RX_SIGQ[n_stream] != -1) {
1048 if (!rtlpriv->
stats.RX_EVM[n_stream]) {
1049 rtlpriv->
stats.RX_EVM[n_stream]
1050 = pstats->RX_SIGQ[n_stream];
1052 rtlpriv->
stats.RX_EVM[n_stream] =
1053 ((rtlpriv->
stats.RX_EVM
1067 static void _rtl92c_process_phyinfo(
struct ieee80211_hw *hw,
1074 _rtl92c_process_ui_rssi(hw, pcurrent_stats);
1075 _rtl92c_process_pwdb(hw, pcurrent_stats);
1076 _rtl92c_process_LINK_Q(hw, pcurrent_stats);
1092 bool packet_matchbssid, packet_toself, packet_beacon;
1099 praddr = hdr->
addr1;
1102 ether_addr_equal(mac->
bssid,
1108 packet_toself = packet_matchbssid &&
1109 ether_addr_equal(praddr, rtlefuse->
dev_addr);
1110 if (ieee80211_is_beacon(fc))
1111 packet_beacon =
true;
1112 _rtl92c_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
1113 packet_matchbssid, packet_toself,
1115 _rtl92c_process_phyinfo(hw, tmp_buf, pstats);