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