root/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/mac.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rtl92c_read_chip_version
  2. rtl92c_llt_write
  3. rtl92c_init_llt_table
  4. rtl92c_set_key
  5. rtl92c_get_txdma_status
  6. rtl92c_enable_interrupt
  7. rtl92c_init_interrupt
  8. rtl92c_disable_interrupt
  9. rtl92c_set_qos
  10. rtl92c_init_driver_info_size
  11. rtl92c_set_network_type
  12. rtl92c_init_network_type
  13. rtl92c_init_adaptive_ctrl
  14. rtl92c_init_rate_fallback
  15. rtl92c_set_cck_sifs
  16. rtl92c_set_ofdm_sifs
  17. rtl92c_init_edca_param
  18. rtl92c_init_edca
  19. rtl92c_init_ampdu_aggregation
  20. rtl92c_init_beacon_max_error
  21. rtl92c_init_rdg_setting
  22. rtl92c_init_retry_function
  23. rtl92c_disable_fast_edca
  24. rtl92c_set_min_space
  25. _rtl92c_query_rxpwrpercentage
  26. _rtl92c_signal_scale_mapping
  27. _rtl92c_query_rxphystatus
  28. rtl92c_translate_rx_signal_stuff

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* Copyright(c) 2009-2012  Realtek Corporation.*/
   3 
   4 #include "../wifi.h"
   5 #include "../pci.h"
   6 #include "../usb.h"
   7 #include "../ps.h"
   8 #include "../cam.h"
   9 #include "../stats.h"
  10 #include "reg.h"
  11 #include "def.h"
  12 #include "phy.h"
  13 #include "rf.h"
  14 #include "dm.h"
  15 #include "mac.h"
  16 #include "trx.h"
  17 #include "../rtl8192c/fw_common.h"
  18 
  19 #include <linux/module.h>
  20 
  21 /* macro to shorten lines */
  22 
  23 #define LINK_Q  ui_link_quality
  24 #define RX_EVM  rx_evm_percentage
  25 #define RX_SIGQ rx_mimo_sig_qual
  26 
  27 void rtl92c_read_chip_version(struct ieee80211_hw *hw)
  28 {
  29         struct rtl_priv *rtlpriv = rtl_priv(hw);
  30         struct rtl_phy *rtlphy = &(rtlpriv->phy);
  31         struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
  32         enum version_8192c chip_version = VERSION_UNKNOWN;
  33         const char *versionid;
  34         u32 value32;
  35 
  36         value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
  37         if (value32 & TRP_VAUX_EN) {
  38                 chip_version = (value32 & TYPE_ID) ? VERSION_TEST_CHIP_92C :
  39                                VERSION_TEST_CHIP_88C;
  40         } else {
  41                 /* Normal mass production chip. */
  42                 chip_version = NORMAL_CHIP;
  43                 chip_version |= ((value32 & TYPE_ID) ? CHIP_92C : 0);
  44                 chip_version |= ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0);
  45                 if (IS_VENDOR_UMC(chip_version))
  46                         chip_version |= ((value32 & CHIP_VER_RTL_MASK) ?
  47                                          CHIP_VENDOR_UMC_B_CUT : 0);
  48                 if (IS_92C_SERIAL(chip_version)) {
  49                         value32 = rtl_read_dword(rtlpriv, REG_HPON_FSM);
  50                         chip_version |= ((CHIP_BONDING_IDENTIFIER(value32) ==
  51                                  CHIP_BONDING_92C_1T2R) ? CHIP_92C_1T2R : 0);
  52                 }
  53         }
  54         rtlhal->version  = (enum version_8192c)chip_version;
  55         pr_info("Chip version 0x%x\n", chip_version);
  56         switch (rtlhal->version) {
  57         case VERSION_NORMAL_TSMC_CHIP_92C_1T2R:
  58                 versionid = "NORMAL_B_CHIP_92C";
  59                 break;
  60         case VERSION_NORMAL_TSMC_CHIP_92C:
  61                 versionid = "NORMAL_TSMC_CHIP_92C";
  62                 break;
  63         case VERSION_NORMAL_TSMC_CHIP_88C:
  64                 versionid = "NORMAL_TSMC_CHIP_88C";
  65                 break;
  66         case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT:
  67                 versionid = "NORMAL_UMC_CHIP_i92C_1T2R_A_CUT";
  68                 break;
  69         case VERSION_NORMAL_UMC_CHIP_92C_A_CUT:
  70                 versionid = "NORMAL_UMC_CHIP_92C_A_CUT";
  71                 break;
  72         case VERSION_NORMAL_UMC_CHIP_88C_A_CUT:
  73                 versionid = "NORMAL_UMC_CHIP_88C_A_CUT";
  74                 break;
  75         case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT:
  76                 versionid = "NORMAL_UMC_CHIP_92C_1T2R_B_CUT";
  77                 break;
  78         case VERSION_NORMAL_UMC_CHIP_92C_B_CUT:
  79                 versionid = "NORMAL_UMC_CHIP_92C_B_CUT";
  80                 break;
  81         case VERSION_NORMAL_UMC_CHIP_88C_B_CUT:
  82                 versionid = "NORMAL_UMC_CHIP_88C_B_CUT";
  83                 break;
  84         case VERSION_TEST_CHIP_92C:
  85                 versionid = "TEST_CHIP_92C";
  86                 break;
  87         case VERSION_TEST_CHIP_88C:
  88                 versionid = "TEST_CHIP_88C";
  89                 break;
  90         default:
  91                 versionid = "UNKNOWN";
  92                 break;
  93         }
  94         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  95                  "Chip Version ID: %s\n", versionid);
  96 
  97         if (IS_92C_SERIAL(rtlhal->version))
  98                 rtlphy->rf_type =
  99                          (IS_92C_1T2R(rtlhal->version)) ? RF_1T2R : RF_2T2R;
 100         else
 101                 rtlphy->rf_type = RF_1T1R;
 102         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 103                  "Chip RF Type: %s\n",
 104                  rtlphy->rf_type == RF_2T2R ? "RF_2T2R" : "RF_1T1R");
 105         if (get_rf_type(rtlphy) == RF_1T1R)
 106                 rtlpriv->dm.rfpath_rxenable[0] = true;
 107         else
 108                 rtlpriv->dm.rfpath_rxenable[0] =
 109                     rtlpriv->dm.rfpath_rxenable[1] = true;
 110         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
 111                  rtlhal->version);
 112 }
 113 
 114 /**
 115  * writeLLT - LLT table write access
 116  * @io: io callback
 117  * @address: LLT logical address.
 118  * @data: LLT data content
 119  *
 120  * Realtek hardware access function.
 121  *
 122  */
 123 bool rtl92c_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
 124 {
 125         struct rtl_priv *rtlpriv = rtl_priv(hw);
 126         bool status = true;
 127         long count = 0;
 128         u32 value = _LLT_INIT_ADDR(address) |
 129             _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
 130 
 131         rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
 132         do {
 133                 value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
 134                 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
 135                         break;
 136                 if (count > POLLING_LLT_THRESHOLD) {
 137                         pr_err("Failed to polling write LLT done at address %d! _LLT_OP_VALUE(%x)\n",
 138                                address, _LLT_OP_VALUE(value));
 139                         status = false;
 140                         break;
 141                 }
 142         } while (++count);
 143         return status;
 144 }
 145 
 146 /**
 147  * rtl92c_init_LLT_table - Init LLT table
 148  * @io: io callback
 149  * @boundary:
 150  *
 151  * Realtek hardware access function.
 152  *
 153  */
 154 bool rtl92c_init_llt_table(struct ieee80211_hw *hw, u32 boundary)
 155 {
 156         bool rst = true;
 157         u32     i;
 158 
 159         for (i = 0; i < (boundary - 1); i++) {
 160                 rst = rtl92c_llt_write(hw, i , i + 1);
 161                 if (true != rst) {
 162                         pr_err("===> %s #1 fail\n", __func__);
 163                         return rst;
 164                 }
 165         }
 166         /* end of list */
 167         rst = rtl92c_llt_write(hw, (boundary - 1), 0xFF);
 168         if (true != rst) {
 169                 pr_err("===> %s #2 fail\n", __func__);
 170                 return rst;
 171         }
 172         /* Make the other pages as ring buffer
 173          * This ring buffer is used as beacon buffer if we config this MAC
 174          *  as two MAC transfer.
 175          * Otherwise used as local loopback buffer.
 176          */
 177         for (i = boundary; i < LLT_LAST_ENTRY_OF_TX_PKT_BUFFER; i++) {
 178                 rst = rtl92c_llt_write(hw, i, (i + 1));
 179                 if (true != rst) {
 180                         pr_err("===> %s #3 fail\n", __func__);
 181                         return rst;
 182                 }
 183         }
 184         /* Let last entry point to the start entry of ring buffer */
 185         rst = rtl92c_llt_write(hw, LLT_LAST_ENTRY_OF_TX_PKT_BUFFER, boundary);
 186         if (true != rst) {
 187                 pr_err("===> %s #4 fail\n", __func__);
 188                 return rst;
 189         }
 190         return rst;
 191 }
 192 
 193 void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index,
 194                      u8 *p_macaddr, bool is_group, u8 enc_algo,
 195                      bool is_wepkey, bool clear_all)
 196 {
 197         struct rtl_priv *rtlpriv = rtl_priv(hw);
 198         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 199         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 200         u8 *macaddr = p_macaddr;
 201         u32 entry_id = 0;
 202         bool is_pairwise = false;
 203         static u8 cam_const_addr[4][6] = {
 204                 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
 205                 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
 206                 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
 207                 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
 208         };
 209         static u8 cam_const_broad[] = {
 210                 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
 211         };
 212 
 213         if (clear_all) {
 214                 u8 idx = 0;
 215                 u8 cam_offset = 0;
 216                 u8 clear_number = 5;
 217 
 218                 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
 219                 for (idx = 0; idx < clear_number; idx++) {
 220                         rtl_cam_mark_invalid(hw, cam_offset + idx);
 221                         rtl_cam_empty_entry(hw, cam_offset + idx);
 222                         if (idx < 5) {
 223                                 memset(rtlpriv->sec.key_buf[idx], 0,
 224                                        MAX_KEY_LEN);
 225                                 rtlpriv->sec.key_len[idx] = 0;
 226                         }
 227                 }
 228         } else {
 229                 switch (enc_algo) {
 230                 case WEP40_ENCRYPTION:
 231                         enc_algo = CAM_WEP40;
 232                         break;
 233                 case WEP104_ENCRYPTION:
 234                         enc_algo = CAM_WEP104;
 235                         break;
 236                 case TKIP_ENCRYPTION:
 237                         enc_algo = CAM_TKIP;
 238                         break;
 239                 case AESCCMP_ENCRYPTION:
 240                         enc_algo = CAM_AES;
 241                         break;
 242                 default:
 243                         pr_err("illegal switch case\n");
 244                         enc_algo = CAM_TKIP;
 245                         break;
 246                 }
 247                 if (is_wepkey || rtlpriv->sec.use_defaultkey) {
 248                         macaddr = cam_const_addr[key_index];
 249                         entry_id = key_index;
 250                 } else {
 251                         if (is_group) {
 252                                 macaddr = cam_const_broad;
 253                                 entry_id = key_index;
 254                         } else {
 255                                 if (mac->opmode == NL80211_IFTYPE_AP ||
 256                                     mac->opmode == NL80211_IFTYPE_MESH_POINT) {
 257                                         entry_id = rtl_cam_get_free_entry(hw,
 258                                                                  p_macaddr);
 259                                         if (entry_id >=  TOTAL_CAM_ENTRY) {
 260                                                 pr_err("Can not find free hw security cam entry\n");
 261                                                 return;
 262                                         }
 263                                 } else {
 264                                         entry_id = CAM_PAIRWISE_KEY_POSITION;
 265                                 }
 266 
 267                                 key_index = PAIRWISE_KEYIDX;
 268                                 is_pairwise = true;
 269                         }
 270                 }
 271                 if (rtlpriv->sec.key_len[key_index] == 0) {
 272                         RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
 273                                  "delete one entry\n");
 274                         if (mac->opmode == NL80211_IFTYPE_AP ||
 275                             mac->opmode == NL80211_IFTYPE_MESH_POINT)
 276                                 rtl_cam_del_entry(hw, p_macaddr);
 277                         rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
 278                 } else {
 279                         RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
 280                                  "The insert KEY length is %d\n",
 281                                  rtlpriv->sec.key_len[PAIRWISE_KEYIDX]);
 282                         RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
 283                                  "The insert KEY is %x %x\n",
 284                                  rtlpriv->sec.key_buf[0][0],
 285                                  rtlpriv->sec.key_buf[0][1]);
 286                         RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
 287                                  "add one entry\n");
 288                         if (is_pairwise) {
 289                                 RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,
 290                                               "Pairwise Key content",
 291                                               rtlpriv->sec.pairwise_key,
 292                                               rtlpriv->sec.
 293                                               key_len[PAIRWISE_KEYIDX]);
 294                                 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
 295                                          "set Pairwise key\n");
 296 
 297                                 rtl_cam_add_one_entry(hw, macaddr, key_index,
 298                                                 entry_id, enc_algo,
 299                                                 CAM_CONFIG_NO_USEDK,
 300                                                 rtlpriv->sec.
 301                                                 key_buf[key_index]);
 302                         } else {
 303                                 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
 304                                          "set group key\n");
 305                                 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
 306                                         rtl_cam_add_one_entry(hw,
 307                                                 rtlefuse->dev_addr,
 308                                                 PAIRWISE_KEYIDX,
 309                                                 CAM_PAIRWISE_KEY_POSITION,
 310                                                 enc_algo,
 311                                                 CAM_CONFIG_NO_USEDK,
 312                                                 rtlpriv->sec.key_buf
 313                                                 [entry_id]);
 314                                 }
 315                                 rtl_cam_add_one_entry(hw, macaddr, key_index,
 316                                                 entry_id, enc_algo,
 317                                                 CAM_CONFIG_NO_USEDK,
 318                                                 rtlpriv->sec.key_buf[entry_id]);
 319                         }
 320                 }
 321         }
 322 }
 323 
 324 u32 rtl92c_get_txdma_status(struct ieee80211_hw *hw)
 325 {
 326         struct rtl_priv *rtlpriv = rtl_priv(hw);
 327 
 328         return rtl_read_dword(rtlpriv, REG_TXDMA_STATUS);
 329 }
 330 
 331 void rtl92c_enable_interrupt(struct ieee80211_hw *hw)
 332 {
 333         struct rtl_priv *rtlpriv = rtl_priv(hw);
 334         struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 335         struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
 336 
 337         if (IS_HARDWARE_TYPE_8192CE(rtlpriv)) {
 338                 rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] &
 339                                 0xFFFFFFFF);
 340                 rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] &
 341                                 0xFFFFFFFF);
 342         } else {
 343                 rtl_write_dword(rtlpriv, REG_HIMR, rtlusb->irq_mask[0] &
 344                                 0xFFFFFFFF);
 345                 rtl_write_dword(rtlpriv, REG_HIMRE, rtlusb->irq_mask[1] &
 346                                 0xFFFFFFFF);
 347         }
 348 }
 349 
 350 void rtl92c_init_interrupt(struct ieee80211_hw *hw)
 351 {
 352          rtl92c_enable_interrupt(hw);
 353 }
 354 
 355 void rtl92c_disable_interrupt(struct ieee80211_hw *hw)
 356 {
 357         struct rtl_priv *rtlpriv = rtl_priv(hw);
 358 
 359         rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED);
 360         rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED);
 361 }
 362 
 363 void rtl92c_set_qos(struct ieee80211_hw *hw, int aci)
 364 {
 365         struct rtl_priv *rtlpriv = rtl_priv(hw);
 366 
 367         rtl92c_dm_init_edca_turbo(hw);
 368         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, (u8 *)&aci);
 369 }
 370 
 371 void rtl92c_init_driver_info_size(struct ieee80211_hw *hw, u8 size)
 372 {
 373         struct rtl_priv *rtlpriv = rtl_priv(hw);
 374 
 375         rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, size);
 376 }
 377 
 378 int rtl92c_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
 379 {
 380         u8 value;
 381         struct rtl_priv *rtlpriv = rtl_priv(hw);
 382 
 383         switch (type) {
 384         case NL80211_IFTYPE_UNSPECIFIED:
 385                 value = NT_NO_LINK;
 386                 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
 387                          "Set Network type to NO LINK!\n");
 388                 break;
 389         case NL80211_IFTYPE_ADHOC:
 390                 value = NT_LINK_AD_HOC;
 391                 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
 392                          "Set Network type to Ad Hoc!\n");
 393                 break;
 394         case NL80211_IFTYPE_STATION:
 395                 value = NT_LINK_AP;
 396                 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
 397                          "Set Network type to STA!\n");
 398                 break;
 399         case NL80211_IFTYPE_AP:
 400                 value = NT_AS_AP;
 401                 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
 402                          "Set Network type to AP!\n");
 403                 break;
 404         default:
 405                 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
 406                          "Network type %d not supported!\n", type);
 407                 return -EOPNOTSUPP;
 408         }
 409         rtl_write_byte(rtlpriv, MSR, value);
 410         return 0;
 411 }
 412 
 413 void rtl92c_init_network_type(struct ieee80211_hw *hw)
 414 {
 415         rtl92c_set_network_type(hw, NL80211_IFTYPE_UNSPECIFIED);
 416 }
 417 
 418 void rtl92c_init_adaptive_ctrl(struct ieee80211_hw *hw)
 419 {
 420         u16     value16;
 421         u32     value32;
 422         struct rtl_priv *rtlpriv = rtl_priv(hw);
 423 
 424         /* Response Rate Set */
 425         value32 = rtl_read_dword(rtlpriv, REG_RRSR);
 426         value32 &= ~RATE_BITMAP_ALL;
 427         value32 |= RATE_RRSR_CCK_ONLY_1M;
 428         rtl_write_dword(rtlpriv, REG_RRSR, value32);
 429         /* SIFS (used in NAV) */
 430         value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10);
 431         rtl_write_word(rtlpriv,  REG_SPEC_SIFS, value16);
 432         /* Retry Limit */
 433         value16 = _LRL(0x30) | _SRL(0x30);
 434         rtl_write_dword(rtlpriv,  REG_RL, value16);
 435 }
 436 
 437 void rtl92c_init_rate_fallback(struct ieee80211_hw *hw)
 438 {
 439         struct rtl_priv *rtlpriv = rtl_priv(hw);
 440 
 441         /* Set Data Auto Rate Fallback Retry Count register. */
 442         rtl_write_dword(rtlpriv,  REG_DARFRC, 0x00000000);
 443         rtl_write_dword(rtlpriv,  REG_DARFRC+4, 0x10080404);
 444         rtl_write_dword(rtlpriv,  REG_RARFRC, 0x04030201);
 445         rtl_write_dword(rtlpriv,  REG_RARFRC+4, 0x08070605);
 446 }
 447 
 448 static void rtl92c_set_cck_sifs(struct ieee80211_hw *hw, u8 trx_sifs,
 449                                 u8 ctx_sifs)
 450 {
 451         struct rtl_priv *rtlpriv = rtl_priv(hw);
 452 
 453         rtl_write_byte(rtlpriv, REG_SIFS_CCK, trx_sifs);
 454         rtl_write_byte(rtlpriv, (REG_SIFS_CCK + 1), ctx_sifs);
 455 }
 456 
 457 static void rtl92c_set_ofdm_sifs(struct ieee80211_hw *hw, u8 trx_sifs,
 458                                  u8 ctx_sifs)
 459 {
 460         struct rtl_priv *rtlpriv = rtl_priv(hw);
 461 
 462         rtl_write_byte(rtlpriv, REG_SIFS_OFDM, trx_sifs);
 463         rtl_write_byte(rtlpriv, (REG_SIFS_OFDM + 1), ctx_sifs);
 464 }
 465 
 466 void rtl92c_init_edca_param(struct ieee80211_hw *hw,
 467                             u16 queue, u16 txop, u8 cw_min, u8 cw_max, u8 aifs)
 468 {
 469         /* sequence: VO, VI, BE, BK ==> the same as 92C hardware design.
 470          * referenc : enum nl80211_txq_q or ieee80211_set_wmm_default function.
 471          */
 472         u32 value;
 473         struct rtl_priv *rtlpriv = rtl_priv(hw);
 474 
 475         value = (u32)aifs;
 476         value |= ((u32)cw_min & 0xF) << 8;
 477         value |= ((u32)cw_max & 0xF) << 12;
 478         value |= (u32)txop << 16;
 479         /* 92C hardware register sequence is the same as queue number. */
 480         rtl_write_dword(rtlpriv, (REG_EDCA_VO_PARAM + (queue * 4)), value);
 481 }
 482 
 483 void rtl92c_init_edca(struct ieee80211_hw *hw)
 484 {
 485         u16 value16;
 486         struct rtl_priv *rtlpriv = rtl_priv(hw);
 487 
 488         /* disable EDCCA count down, to reduce collison and retry */
 489         value16 = rtl_read_word(rtlpriv, REG_RD_CTRL);
 490         value16 |= DIS_EDCA_CNT_DWN;
 491         rtl_write_word(rtlpriv, REG_RD_CTRL, value16);
 492         /* Update SIFS timing.  ??????????
 493          * pHalData->SifsTime = 0x0e0e0a0a; */
 494         rtl92c_set_cck_sifs(hw, 0xa, 0xa);
 495         rtl92c_set_ofdm_sifs(hw, 0xe, 0xe);
 496         /* Set CCK/OFDM SIFS to be 10us. */
 497         rtl_write_word(rtlpriv, REG_SIFS_CCK, 0x0a0a);
 498         rtl_write_word(rtlpriv, REG_SIFS_OFDM, 0x1010);
 499         rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x0204);
 500         rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x014004);
 501         /* TXOP */
 502         rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, 0x005EA42B);
 503         rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0x0000A44F);
 504         rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x005EA324);
 505         rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x002FA226);
 506         /* PIFS */
 507         rtl_write_byte(rtlpriv, REG_PIFS, 0x1C);
 508         /* AGGR BREAK TIME Register */
 509         rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16);
 510         rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040);
 511         rtl_write_byte(rtlpriv, REG_BCNDMATIM, 0x02);
 512         rtl_write_byte(rtlpriv, REG_ATIMWND, 0x02);
 513 }
 514 
 515 void rtl92c_init_ampdu_aggregation(struct ieee80211_hw *hw)
 516 {
 517         struct rtl_priv *rtlpriv = rtl_priv(hw);
 518 
 519         rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x99997631);
 520         rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16);
 521         /* init AMPDU aggregation number, tuning for Tx's TP, */
 522         rtl_write_word(rtlpriv, 0x4CA, 0x0708);
 523 }
 524 
 525 void rtl92c_init_beacon_max_error(struct ieee80211_hw *hw)
 526 {
 527         struct rtl_priv *rtlpriv = rtl_priv(hw);
 528 
 529         rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xFF);
 530 }
 531 
 532 void rtl92c_init_rdg_setting(struct ieee80211_hw *hw)
 533 {
 534         struct rtl_priv *rtlpriv = rtl_priv(hw);
 535 
 536         rtl_write_byte(rtlpriv, REG_RD_CTRL, 0xFF);
 537         rtl_write_word(rtlpriv, REG_RD_NAV_NXT, 0x200);
 538         rtl_write_byte(rtlpriv, REG_RD_RESP_PKT_TH, 0x05);
 539 }
 540 
 541 void rtl92c_init_retry_function(struct ieee80211_hw *hw)
 542 {
 543         u8      value8;
 544         struct rtl_priv *rtlpriv = rtl_priv(hw);
 545 
 546         value8 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL);
 547         value8 |= EN_AMPDU_RTY_NEW;
 548         rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL, value8);
 549         /* Set ACK timeout */
 550         rtl_write_byte(rtlpriv, REG_ACKTO, 0x40);
 551 }
 552 
 553 void rtl92c_disable_fast_edca(struct ieee80211_hw *hw)
 554 {
 555         struct rtl_priv *rtlpriv = rtl_priv(hw);
 556 
 557         rtl_write_word(rtlpriv, REG_FAST_EDCA_CTRL, 0);
 558 }
 559 
 560 void rtl92c_set_min_space(struct ieee80211_hw *hw, bool is2T)
 561 {
 562         struct rtl_priv *rtlpriv = rtl_priv(hw);
 563         u8 value = is2T ? MAX_MSS_DENSITY_2T : MAX_MSS_DENSITY_1T;
 564 
 565         rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, value);
 566 }
 567 
 568 /*==============================================================*/
 569 
 570 static u8 _rtl92c_query_rxpwrpercentage(s8 antpower)
 571 {
 572         if ((antpower <= -100) || (antpower >= 20))
 573                 return 0;
 574         else if (antpower >= 0)
 575                 return 100;
 576         else
 577                 return 100 + antpower;
 578 }
 579 
 580 static long _rtl92c_signal_scale_mapping(struct ieee80211_hw *hw,
 581                 long currsig)
 582 {
 583         long retsig;
 584 
 585         if (currsig >= 61 && currsig <= 100)
 586                 retsig = 90 + ((currsig - 60) / 4);
 587         else if (currsig >= 41 && currsig <= 60)
 588                 retsig = 78 + ((currsig - 40) / 2);
 589         else if (currsig >= 31 && currsig <= 40)
 590                 retsig = 66 + (currsig - 30);
 591         else if (currsig >= 21 && currsig <= 30)
 592                 retsig = 54 + (currsig - 20);
 593         else if (currsig >= 5 && currsig <= 20)
 594                 retsig = 42 + (((currsig - 5) * 2) / 3);
 595         else if (currsig == 4)
 596                 retsig = 36;
 597         else if (currsig == 3)
 598                 retsig = 27;
 599         else if (currsig == 2)
 600                 retsig = 18;
 601         else if (currsig == 1)
 602                 retsig = 9;
 603         else
 604                 retsig = currsig;
 605         return retsig;
 606 }
 607 
 608 static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw,
 609                                       struct rtl_stats *pstats,
 610                                       struct rx_desc_92c *p_desc,
 611                                       struct rx_fwinfo_92c *p_drvinfo,
 612                                       bool packet_match_bssid,
 613                                       bool packet_toself,
 614                                       bool packet_beacon)
 615 {
 616         struct rtl_priv *rtlpriv = rtl_priv(hw);
 617         struct rtl_phy *rtlphy = &(rtlpriv->phy);
 618         struct phy_sts_cck_8192s_t *cck_buf;
 619         s8 rx_pwr_all = 0, rx_pwr[4];
 620         u8 rf_rx_num = 0, evm, pwdb_all;
 621         u8 i, max_spatial_stream;
 622         u32 rssi, total_rssi = 0;
 623         bool in_powersavemode = false;
 624         bool is_cck_rate;
 625         __le32 *pdesc = (__le32 *)p_desc;
 626 
 627         is_cck_rate = RX_HAL_IS_CCK_RATE(p_desc->rxmcs);
 628         pstats->packet_matchbssid = packet_match_bssid;
 629         pstats->packet_toself = packet_toself;
 630         pstats->packet_beacon = packet_beacon;
 631         pstats->is_cck = is_cck_rate;
 632         pstats->RX_SIGQ[0] = -1;
 633         pstats->RX_SIGQ[1] = -1;
 634         if (is_cck_rate) {
 635                 u8 report, cck_highpwr;
 636 
 637                 cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
 638                 if (!in_powersavemode)
 639                         cck_highpwr = rtlphy->cck_high_power;
 640                 else
 641                         cck_highpwr = false;
 642                 if (!cck_highpwr) {
 643                         u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
 644 
 645                         report = cck_buf->cck_agc_rpt & 0xc0;
 646                         report = report >> 6;
 647                         switch (report) {
 648                         case 0x3:
 649                                 rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
 650                                 break;
 651                         case 0x2:
 652                                 rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
 653                                 break;
 654                         case 0x1:
 655                                 rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
 656                                 break;
 657                         case 0x0:
 658                                 rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
 659                                 break;
 660                         }
 661                 } else {
 662                         u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
 663 
 664                         report = p_drvinfo->cfosho[0] & 0x60;
 665                         report = report >> 5;
 666                         switch (report) {
 667                         case 0x3:
 668                                 rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1);
 669                                 break;
 670                         case 0x2:
 671                                 rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1);
 672                                 break;
 673                         case 0x1:
 674                                 rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1);
 675                                 break;
 676                         case 0x0:
 677                                 rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1);
 678                                 break;
 679                         }
 680                 }
 681                 pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
 682                 pstats->rx_pwdb_all = pwdb_all;
 683                 pstats->recvsignalpower = rx_pwr_all;
 684                 if (packet_match_bssid) {
 685                         u8 sq;
 686 
 687                         if (pstats->rx_pwdb_all > 40)
 688                                 sq = 100;
 689                         else {
 690                                 sq = cck_buf->sq_rpt;
 691                                 if (sq > 64)
 692                                         sq = 0;
 693                                 else if (sq < 20)
 694                                         sq = 100;
 695                                 else
 696                                         sq = ((64 - sq) * 100) / 44;
 697                         }
 698                         pstats->signalquality = sq;
 699                         pstats->RX_SIGQ[0] = sq;
 700                         pstats->RX_SIGQ[1] = -1;
 701                 }
 702         } else {
 703                 rtlpriv->dm.rfpath_rxenable[0] =
 704                     rtlpriv->dm.rfpath_rxenable[1] = true;
 705                 for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
 706                         if (rtlpriv->dm.rfpath_rxenable[i])
 707                                 rf_rx_num++;
 708                         rx_pwr[i] =
 709                             ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110;
 710                         rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]);
 711                         total_rssi += rssi;
 712                         rtlpriv->stats.rx_snr_db[i] =
 713                             (long)(p_drvinfo->rxsnr[i] / 2);
 714 
 715                         if (packet_match_bssid)
 716                                 pstats->rx_mimo_signalstrength[i] = (u8) rssi;
 717                 }
 718                 rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
 719                 pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
 720                 pstats->rx_pwdb_all = pwdb_all;
 721                 pstats->rxpower = rx_pwr_all;
 722                 pstats->recvsignalpower = rx_pwr_all;
 723                 if (get_rx_desc_rx_mcs(pdesc) &&
 724                     get_rx_desc_rx_mcs(pdesc) >= DESC_RATEMCS8 &&
 725                     get_rx_desc_rx_mcs(pdesc) <= DESC_RATEMCS15)
 726                         max_spatial_stream = 2;
 727                 else
 728                         max_spatial_stream = 1;
 729                 for (i = 0; i < max_spatial_stream; i++) {
 730                         evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]);
 731                         if (packet_match_bssid) {
 732                                 if (i == 0)
 733                                         pstats->signalquality =
 734                                             (u8) (evm & 0xff);
 735                                 pstats->RX_SIGQ[i] =
 736                                     (u8) (evm & 0xff);
 737                         }
 738                 }
 739         }
 740         if (is_cck_rate)
 741                 pstats->signalstrength =
 742                     (u8) (_rtl92c_signal_scale_mapping(hw, pwdb_all));
 743         else if (rf_rx_num != 0)
 744                 pstats->signalstrength =
 745                     (u8) (_rtl92c_signal_scale_mapping
 746                           (hw, total_rssi /= rf_rx_num));
 747 }
 748 
 749 void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw,
 750                                                struct sk_buff *skb,
 751                                                struct rtl_stats *pstats,
 752                                                struct rx_desc_92c *pdesc,
 753                                                struct rx_fwinfo_92c *p_drvinfo)
 754 {
 755         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 756         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 757         struct ieee80211_hdr *hdr;
 758         u8 *tmp_buf;
 759         u8 *praddr;
 760         __le16 fc;
 761         u16 type, cpu_fc;
 762         bool packet_matchbssid, packet_toself, packet_beacon = false;
 763 
 764         tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
 765         hdr = (struct ieee80211_hdr *)tmp_buf;
 766         fc = hdr->frame_control;
 767         cpu_fc = le16_to_cpu(fc);
 768         type = WLAN_FC_GET_TYPE(fc);
 769         praddr = hdr->addr1;
 770         packet_matchbssid =
 771             ((IEEE80211_FTYPE_CTL != type) &&
 772              ether_addr_equal(mac->bssid,
 773                               (cpu_fc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
 774                               (cpu_fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
 775                               hdr->addr3) &&
 776              (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
 777 
 778         packet_toself = packet_matchbssid &&
 779             ether_addr_equal(praddr, rtlefuse->dev_addr);
 780         if (ieee80211_is_beacon(fc))
 781                 packet_beacon = true;
 782         _rtl92c_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
 783                                    packet_matchbssid, packet_toself,
 784                                    packet_beacon);
 785         rtl_process_phyinfo(hw, tmp_buf, pstats);
 786 }

/* [<][>][^][v][top][bottom][index][help] */