1226 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright(c) 2009-2012 Realtek Corporation.*/3 4#include "../wifi.h"5#include "../base.h"6#include "../cam.h"7#include "../efuse.h"8#include "../pci.h"9#include "../regd.h"10#include "def.h"11#include "reg.h"12#include "dm_common.h"13#include "fw_common.h"14#include "hw_common.h"15#include "phy_common.h"16 17void rtl92d_stop_tx_beacon(struct ieee80211_hw *hw)18{19 struct rtl_priv *rtlpriv = rtl_priv(hw);20 u8 tmp1byte;21 22 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);23 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6)));24 rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff);25 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64);26 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);27 tmp1byte &= ~(BIT(0));28 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);29}30EXPORT_SYMBOL_GPL(rtl92d_stop_tx_beacon);31 32void rtl92d_resume_tx_beacon(struct ieee80211_hw *hw)33{34 struct rtl_priv *rtlpriv = rtl_priv(hw);35 u8 tmp1byte;36 37 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);38 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6));39 rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0x0a);40 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);41 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);42 tmp1byte |= BIT(0);43 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);44}45EXPORT_SYMBOL_GPL(rtl92d_resume_tx_beacon);46 47void rtl92d_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)48{49 struct rtl_priv *rtlpriv = rtl_priv(hw);50 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));51 52 switch (variable) {53 case HW_VAR_RF_STATE:54 *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;55 break;56 case HW_VAR_FWLPS_RF_ON:{57 enum rf_pwrstate rfstate;58 u32 val_rcr;59 60 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE,61 (u8 *)(&rfstate));62 if (rfstate == ERFOFF) {63 *((bool *)(val)) = true;64 } else {65 val_rcr = rtl_read_dword(rtlpriv, REG_RCR);66 val_rcr &= 0x00070000;67 if (val_rcr)68 *((bool *)(val)) = false;69 else70 *((bool *)(val)) = true;71 }72 break;73 }74 case HW_VAR_FW_PSMODE_STATUS:75 *((bool *)(val)) = ppsc->fw_current_inpsmode;76 break;77 case HW_VAR_CORRECT_TSF:{78 u64 tsf;79 u32 *ptsf_low = (u32 *)&tsf;80 u32 *ptsf_high = ((u32 *)&tsf) + 1;81 82 *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4));83 *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);84 *((u64 *)(val)) = tsf;85 break;86 }87 case HW_VAR_INT_MIGRATION:88 *((bool *)(val)) = rtlpriv->dm.interrupt_migration;89 break;90 case HW_VAR_INT_AC:91 *((bool *)(val)) = rtlpriv->dm.disable_tx_int;92 break;93 case HAL_DEF_WOWLAN:94 break;95 default:96 pr_err("switch case %#x not processed\n", variable);97 break;98 }99}100EXPORT_SYMBOL_GPL(rtl92d_get_hw_reg);101 102void rtl92d_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)103{104 struct rtl_priv *rtlpriv = rtl_priv(hw);105 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));106 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));107 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));108 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));109 u8 idx;110 111 switch (variable) {112 case HW_VAR_ETHER_ADDR:113 for (idx = 0; idx < ETH_ALEN; idx++) {114 rtl_write_byte(rtlpriv, (REG_MACID + idx),115 val[idx]);116 }117 break;118 case HW_VAR_BASIC_RATE: {119 u16 rate_cfg = ((u16 *)val)[0];120 u8 rate_index = 0;121 122 rate_cfg = rate_cfg & 0x15f;123 if (mac->vendor == PEER_CISCO &&124 ((rate_cfg & 0x150) == 0))125 rate_cfg |= 0x01;126 rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff);127 rtl_write_byte(rtlpriv, REG_RRSR + 1,128 (rate_cfg >> 8) & 0xff);129 while (rate_cfg > 0x1) {130 rate_cfg = (rate_cfg >> 1);131 rate_index++;132 }133 if (rtlhal->fw_version > 0xe)134 rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL,135 rate_index);136 break;137 }138 case HW_VAR_BSSID:139 for (idx = 0; idx < ETH_ALEN; idx++) {140 rtl_write_byte(rtlpriv, (REG_BSSID + idx),141 val[idx]);142 }143 break;144 case HW_VAR_SIFS:145 rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]);146 rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]);147 rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);148 rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);149 if (!mac->ht_enable)150 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,151 0x0e0e);152 else153 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,154 *((u16 *)val));155 break;156 case HW_VAR_SLOT_TIME: {157 u8 e_aci;158 159 rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD,160 "HW_VAR_SLOT_TIME %x\n", val[0]);161 rtl_write_byte(rtlpriv, REG_SLOT, val[0]);162 for (e_aci = 0; e_aci < AC_MAX; e_aci++)163 rtlpriv->cfg->ops->set_hw_reg(hw,164 HW_VAR_AC_PARAM,165 (&e_aci));166 break;167 }168 case HW_VAR_ACK_PREAMBLE: {169 u8 reg_tmp;170 u8 short_preamble = (bool)(*val);171 172 reg_tmp = (mac->cur_40_prime_sc) << 5;173 if (short_preamble)174 reg_tmp |= 0x80;175 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp);176 break;177 }178 case HW_VAR_AMPDU_MIN_SPACE: {179 u8 min_spacing_to_set;180 181 min_spacing_to_set = *val;182 if (min_spacing_to_set <= 7) {183 mac->min_space_cfg = ((mac->min_space_cfg & 0xf8) |184 min_spacing_to_set);185 *val = min_spacing_to_set;186 rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD,187 "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",188 mac->min_space_cfg);189 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,190 mac->min_space_cfg);191 }192 break;193 }194 case HW_VAR_SHORTGI_DENSITY: {195 u8 density_to_set;196 197 density_to_set = *val;198 mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg;199 mac->min_space_cfg |= (density_to_set << 3);200 rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD,201 "Set HW_VAR_SHORTGI_DENSITY: %#x\n",202 mac->min_space_cfg);203 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,204 mac->min_space_cfg);205 break;206 }207 case HW_VAR_AMPDU_FACTOR: {208 u8 factor_toset;209 u32 regtoset;210 u8 *ptmp_byte = NULL;211 u8 index;212 213 if (rtlhal->macphymode == DUALMAC_DUALPHY)214 regtoset = 0xb9726641;215 else if (rtlhal->macphymode == DUALMAC_SINGLEPHY)216 regtoset = 0x66626641;217 else218 regtoset = 0xb972a841;219 factor_toset = *val;220 if (factor_toset <= 3) {221 factor_toset = (1 << (factor_toset + 2));222 if (factor_toset > 0xf)223 factor_toset = 0xf;224 for (index = 0; index < 4; index++) {225 ptmp_byte = (u8 *)(®toset) + index;226 if ((*ptmp_byte & 0xf0) >227 (factor_toset << 4))228 *ptmp_byte = (*ptmp_byte & 0x0f)229 | (factor_toset << 4);230 if ((*ptmp_byte & 0x0f) > factor_toset)231 *ptmp_byte = (*ptmp_byte & 0xf0)232 | (factor_toset);233 }234 rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, regtoset);235 rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD,236 "Set HW_VAR_AMPDU_FACTOR: %#x\n",237 factor_toset);238 }239 break;240 }241 case HW_VAR_RETRY_LIMIT: {242 u8 retry_limit = val[0];243 244 rtl_write_word(rtlpriv, REG_RL,245 retry_limit << RETRY_LIMIT_SHORT_SHIFT |246 retry_limit << RETRY_LIMIT_LONG_SHIFT);247 break;248 }249 case HW_VAR_DUAL_TSF_RST:250 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));251 break;252 case HW_VAR_EFUSE_BYTES:253 rtlefuse->efuse_usedbytes = *((u16 *)val);254 break;255 case HW_VAR_EFUSE_USAGE:256 rtlefuse->efuse_usedpercentage = *val;257 break;258 case HW_VAR_IO_CMD:259 rtl92d_phy_set_io_cmd(hw, (*(enum io_type *)val));260 break;261 case HW_VAR_WPA_CONFIG:262 rtl_write_byte(rtlpriv, REG_SECCFG, *val);263 break;264 case HW_VAR_SET_RPWM:265 rtl92d_fill_h2c_cmd(hw, H2C_PWRM, 1, (val));266 break;267 case HW_VAR_H2C_FW_PWRMODE:268 break;269 case HW_VAR_FW_PSMODE_STATUS:270 ppsc->fw_current_inpsmode = *((bool *)val);271 break;272 case HW_VAR_AID: {273 u16 u2btmp;274 275 u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);276 u2btmp &= 0xC000;277 rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp |278 mac->assoc_id));279 break;280 }281 default:282 pr_err("switch case %#x not processed\n", variable);283 break;284 }285}286EXPORT_SYMBOL_GPL(rtl92d_set_hw_reg);287 288bool rtl92d_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)289{290 struct rtl_priv *rtlpriv = rtl_priv(hw);291 bool status = true;292 long count = 0;293 u32 value = _LLT_INIT_ADDR(address) |294 _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);295 296 rtl_write_dword(rtlpriv, REG_LLT_INIT, value);297 do {298 value = rtl_read_dword(rtlpriv, REG_LLT_INIT);299 if (_LLT_OP_VALUE(value) == _LLT_NO_ACTIVE)300 break;301 if (count > POLLING_LLT_THRESHOLD) {302 pr_err("Failed to polling write LLT done at address %d!\n",303 address);304 status = false;305 break;306 }307 } while (++count);308 return status;309}310EXPORT_SYMBOL_GPL(rtl92d_llt_write);311 312void rtl92d_enable_hw_security_config(struct ieee80211_hw *hw)313{314 struct rtl_priv *rtlpriv = rtl_priv(hw);315 u8 sec_reg_value;316 317 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,318 "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",319 rtlpriv->sec.pairwise_enc_algorithm,320 rtlpriv->sec.group_enc_algorithm);321 if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {322 rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,323 "not open hw encryption\n");324 return;325 }326 sec_reg_value = SCR_TXENCENABLE | SCR_RXENCENABLE;327 if (rtlpriv->sec.use_defaultkey) {328 sec_reg_value |= SCR_TXUSEDK;329 sec_reg_value |= SCR_RXUSEDK;330 }331 sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);332 rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);333 rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD,334 "The SECR-value %x\n", sec_reg_value);335 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);336}337EXPORT_SYMBOL_GPL(rtl92d_enable_hw_security_config);338 339/* don't set REG_EDCA_BE_PARAM here because340 * mac80211 will send pkt when scan341 */342void rtl92d_set_qos(struct ieee80211_hw *hw, int aci)343{344 rtl92d_dm_init_edca_turbo(hw);345}346EXPORT_SYMBOL_GPL(rtl92d_set_qos);347 348static enum version_8192d _rtl92d_read_chip_version(struct ieee80211_hw *hw)349{350 struct rtl_priv *rtlpriv = rtl_priv(hw);351 enum version_8192d version = VERSION_NORMAL_CHIP_92D_SINGLEPHY;352 u32 value32;353 354 value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);355 if (!(value32 & 0x000f0000)) {356 version = VERSION_TEST_CHIP_92D_SINGLEPHY;357 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "TEST CHIP!!!\n");358 } else {359 version = VERSION_NORMAL_CHIP_92D_SINGLEPHY;360 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Normal CHIP!!!\n");361 }362 return version;363}364 365static void _rtl92d_readpowervalue_fromprom(struct txpower_info *pwrinfo,366 u8 *efuse, bool autoloadfail)367{368 u32 rfpath, eeaddr, group, offset, offset1, offset2;369 u8 i, val8;370 371 memset(pwrinfo, 0, sizeof(struct txpower_info));372 if (autoloadfail) {373 for (group = 0; group < CHANNEL_GROUP_MAX; group++) {374 for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) {375 if (group < CHANNEL_GROUP_MAX_2G) {376 pwrinfo->cck_index[rfpath][group] =377 EEPROM_DEFAULT_TXPOWERLEVEL_2G;378 pwrinfo->ht40_1sindex[rfpath][group] =379 EEPROM_DEFAULT_TXPOWERLEVEL_2G;380 } else {381 pwrinfo->ht40_1sindex[rfpath][group] =382 EEPROM_DEFAULT_TXPOWERLEVEL_5G;383 }384 pwrinfo->ht40_2sindexdiff[rfpath][group] =385 EEPROM_DEFAULT_HT40_2SDIFF;386 pwrinfo->ht20indexdiff[rfpath][group] =387 EEPROM_DEFAULT_HT20_DIFF;388 pwrinfo->ofdmindexdiff[rfpath][group] =389 EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF;390 pwrinfo->ht40maxoffset[rfpath][group] =391 EEPROM_DEFAULT_HT40_PWRMAXOFFSET;392 pwrinfo->ht20maxoffset[rfpath][group] =393 EEPROM_DEFAULT_HT20_PWRMAXOFFSET;394 }395 }396 for (i = 0; i < 3; i++) {397 pwrinfo->tssi_a[i] = EEPROM_DEFAULT_TSSI;398 pwrinfo->tssi_b[i] = EEPROM_DEFAULT_TSSI;399 }400 return;401 }402 403 /* Maybe autoload OK,buf the tx power index value is not filled.404 * If we find it, we set it to default value.405 */406 for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) {407 for (group = 0; group < CHANNEL_GROUP_MAX_2G; group++) {408 eeaddr = EEPROM_CCK_TX_PWR_INX_2G + (rfpath * 3) + group;409 410 pwrinfo->cck_index[rfpath][group] =411 efuse[eeaddr] == 0xFF ?412 (eeaddr > 0x7B ?413 EEPROM_DEFAULT_TXPOWERLEVEL_5G :414 EEPROM_DEFAULT_TXPOWERLEVEL_2G) :415 efuse[eeaddr];416 }417 }418 for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) {419 for (group = 0; group < CHANNEL_GROUP_MAX; group++) {420 offset1 = group / 3;421 offset2 = group % 3;422 eeaddr = EEPROM_HT40_1S_TX_PWR_INX_2G + (rfpath * 3);423 eeaddr += offset2 + offset1 * 21;424 425 pwrinfo->ht40_1sindex[rfpath][group] =426 efuse[eeaddr] == 0xFF ?427 (eeaddr > 0x7B ?428 EEPROM_DEFAULT_TXPOWERLEVEL_5G :429 EEPROM_DEFAULT_TXPOWERLEVEL_2G) :430 efuse[eeaddr];431 }432 }433 434 /* These just for 92D efuse offset. */435 for (group = 0; group < CHANNEL_GROUP_MAX; group++) {436 for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) {437 offset1 = group / 3;438 offset2 = group % 3;439 offset = offset2 + offset1 * 21;440 441 val8 = efuse[EEPROM_HT40_2S_TX_PWR_INX_DIFF_2G + offset];442 if (val8 != 0xFF)443 pwrinfo->ht40_2sindexdiff[rfpath][group] =444 (val8 >> (rfpath * 4)) & 0xF;445 else446 pwrinfo->ht40_2sindexdiff[rfpath][group] =447 EEPROM_DEFAULT_HT40_2SDIFF;448 449 val8 = efuse[EEPROM_HT20_TX_PWR_INX_DIFF_2G + offset];450 if (val8 != 0xFF)451 pwrinfo->ht20indexdiff[rfpath][group] =452 (val8 >> (rfpath * 4)) & 0xF;453 else454 pwrinfo->ht20indexdiff[rfpath][group] =455 EEPROM_DEFAULT_HT20_DIFF;456 457 val8 = efuse[EEPROM_OFDM_TX_PWR_INX_DIFF_2G + offset];458 if (val8 != 0xFF)459 pwrinfo->ofdmindexdiff[rfpath][group] =460 (val8 >> (rfpath * 4)) & 0xF;461 else462 pwrinfo->ofdmindexdiff[rfpath][group] =463 EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF;464 465 val8 = efuse[EEPROM_HT40_MAX_PWR_OFFSET_2G + offset];466 if (val8 != 0xFF)467 pwrinfo->ht40maxoffset[rfpath][group] =468 (val8 >> (rfpath * 4)) & 0xF;469 else470 pwrinfo->ht40maxoffset[rfpath][group] =471 EEPROM_DEFAULT_HT40_PWRMAXOFFSET;472 473 val8 = efuse[EEPROM_HT20_MAX_PWR_OFFSET_2G + offset];474 if (val8 != 0xFF)475 pwrinfo->ht20maxoffset[rfpath][group] =476 (val8 >> (rfpath * 4)) & 0xF;477 else478 pwrinfo->ht20maxoffset[rfpath][group] =479 EEPROM_DEFAULT_HT20_PWRMAXOFFSET;480 }481 }482 483 if (efuse[EEPROM_TSSI_A_5G] != 0xFF) {484 /* 5GL */485 pwrinfo->tssi_a[0] = efuse[EEPROM_TSSI_A_5G] & 0x3F;486 pwrinfo->tssi_b[0] = efuse[EEPROM_TSSI_B_5G] & 0x3F;487 /* 5GM */488 pwrinfo->tssi_a[1] = efuse[EEPROM_TSSI_AB_5G] & 0x3F;489 pwrinfo->tssi_b[1] = (efuse[EEPROM_TSSI_AB_5G] & 0xC0) >> 6 |490 (efuse[EEPROM_TSSI_AB_5G + 1] & 0x0F) << 2;491 /* 5GH */492 pwrinfo->tssi_a[2] = (efuse[EEPROM_TSSI_AB_5G + 1] & 0xF0) >> 4 |493 (efuse[EEPROM_TSSI_AB_5G + 2] & 0x03) << 4;494 pwrinfo->tssi_b[2] = (efuse[EEPROM_TSSI_AB_5G + 2] & 0xFC) >> 2;495 } else {496 for (i = 0; i < 3; i++) {497 pwrinfo->tssi_a[i] = EEPROM_DEFAULT_TSSI;498 pwrinfo->tssi_b[i] = EEPROM_DEFAULT_TSSI;499 }500 }501}502 503static void _rtl92d_read_txpower_info(struct ieee80211_hw *hw,504 bool autoload_fail, u8 *hwinfo)505{506 struct rtl_priv *rtlpriv = rtl_priv(hw);507 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));508 struct txpower_info pwrinfo;509 u8 tempval[2], i, pwr, diff;510 u32 ch, rfpath, group;511 512 _rtl92d_readpowervalue_fromprom(&pwrinfo, hwinfo, autoload_fail);513 if (!autoload_fail) {514 /* bit0~2 */515 rtlefuse->eeprom_regulatory = (hwinfo[EEPROM_RF_OPT1] & 0x7);516 rtlefuse->eeprom_thermalmeter =517 hwinfo[EEPROM_THERMAL_METER] & 0x1f;518 rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_K];519 tempval[0] = hwinfo[EEPROM_IQK_DELTA] & 0x03;520 tempval[1] = (hwinfo[EEPROM_LCK_DELTA] & 0x0C) >> 2;521 rtlefuse->txpwr_fromeprom = true;522 if (IS_92D_D_CUT(rtlpriv->rtlhal.version) ||523 IS_92D_E_CUT(rtlpriv->rtlhal.version)) {524 rtlefuse->internal_pa_5g[0] =525 !((hwinfo[EEPROM_TSSI_A_5G] & BIT(6)) >> 6);526 rtlefuse->internal_pa_5g[1] =527 !((hwinfo[EEPROM_TSSI_B_5G] & BIT(6)) >> 6);528 rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG,529 "Is D cut,Internal PA0 %d Internal PA1 %d\n",530 rtlefuse->internal_pa_5g[0],531 rtlefuse->internal_pa_5g[1]);532 }533 rtlefuse->eeprom_c9 = hwinfo[EEPROM_RF_OPT6];534 rtlefuse->eeprom_cc = hwinfo[EEPROM_RF_OPT7];535 } else {536 rtlefuse->eeprom_regulatory = 0;537 rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;538 rtlefuse->crystalcap = EEPROM_DEFAULT_CRYSTALCAP;539 tempval[0] = 3;540 tempval[1] = tempval[0];541 }542 543 /* Use default value to fill parameters if544 * efuse is not filled on some place.545 */546 547 /* ThermalMeter from EEPROM */548 if (rtlefuse->eeprom_thermalmeter < 0x06 ||549 rtlefuse->eeprom_thermalmeter > 0x1c)550 rtlefuse->eeprom_thermalmeter = 0x12;551 rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;552 553 /* check XTAL_K */554 if (rtlefuse->crystalcap == 0xFF)555 rtlefuse->crystalcap = 0;556 if (rtlefuse->eeprom_regulatory > 3)557 rtlefuse->eeprom_regulatory = 0;558 559 for (i = 0; i < 2; i++) {560 switch (tempval[i]) {561 case 0:562 tempval[i] = 5;563 break;564 case 1:565 tempval[i] = 4;566 break;567 case 2:568 tempval[i] = 3;569 break;570 case 3:571 default:572 tempval[i] = 0;573 break;574 }575 }576 577 rtlefuse->delta_iqk = tempval[0];578 if (tempval[1] > 0)579 rtlefuse->delta_lck = tempval[1] - 1;580 if (rtlefuse->eeprom_c9 == 0xFF)581 rtlefuse->eeprom_c9 = 0x00;582 rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD,583 "EEPROMRegulatory = 0x%x\n", rtlefuse->eeprom_regulatory);584 rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD,585 "ThermalMeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);586 rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD,587 "CrystalCap = 0x%x\n", rtlefuse->crystalcap);588 rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD,589 "Delta_IQK = 0x%x Delta_LCK = 0x%x\n",590 rtlefuse->delta_iqk, rtlefuse->delta_lck);591 592 for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) {593 for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {594 group = rtl92d_get_chnlgroup_fromarray((u8)ch);595 if (ch < CHANNEL_MAX_NUMBER_2G)596 rtlefuse->txpwrlevel_cck[rfpath][ch] =597 pwrinfo.cck_index[rfpath][group];598 rtlefuse->txpwrlevel_ht40_1s[rfpath][ch] =599 pwrinfo.ht40_1sindex[rfpath][group];600 rtlefuse->txpwr_ht20diff[rfpath][ch] =601 pwrinfo.ht20indexdiff[rfpath][group];602 rtlefuse->txpwr_legacyhtdiff[rfpath][ch] =603 pwrinfo.ofdmindexdiff[rfpath][group];604 rtlefuse->pwrgroup_ht20[rfpath][ch] =605 pwrinfo.ht20maxoffset[rfpath][group];606 rtlefuse->pwrgroup_ht40[rfpath][ch] =607 pwrinfo.ht40maxoffset[rfpath][group];608 pwr = pwrinfo.ht40_1sindex[rfpath][group];609 diff = pwrinfo.ht40_2sindexdiff[rfpath][group];610 rtlefuse->txpwrlevel_ht40_2s[rfpath][ch] =611 (pwr > diff) ? (pwr - diff) : 0;612 }613 }614}615 616static void _rtl92d_read_macphymode_from_prom(struct ieee80211_hw *hw,617 u8 *content)618{619 struct rtl_priv *rtlpriv = rtl_priv(hw);620 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));621 bool is_single_mac = true;622 623 if (rtlhal->interface == INTF_PCI)624 is_single_mac = !!(content[EEPROM_MAC_FUNCTION] & BIT(3));625 else if (rtlhal->interface == INTF_USB)626 is_single_mac = !(content[EEPROM_ENDPOINT_SETTING] & BIT(0));627 628 if (is_single_mac) {629 rtlhal->macphymode = SINGLEMAC_SINGLEPHY;630 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,631 "MacPhyMode SINGLEMAC_SINGLEPHY\n");632 } else {633 rtlhal->macphymode = DUALMAC_DUALPHY;634 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,635 "MacPhyMode DUALMAC_DUALPHY\n");636 }637}638 639static void _rtl92d_read_macphymode_and_bandtype(struct ieee80211_hw *hw,640 u8 *content)641{642 _rtl92d_read_macphymode_from_prom(hw, content);643 rtl92d_phy_config_macphymode(hw);644 rtl92d_phy_config_macphymode_info(hw);645}646 647static void _rtl92d_efuse_update_chip_version(struct ieee80211_hw *hw)648{649 struct rtl_priv *rtlpriv = rtl_priv(hw);650 enum version_8192d chipver = rtlpriv->rtlhal.version;651 u8 cutvalue[2];652 u16 chipvalue;653 654 read_efuse_byte(hw, EEPROME_CHIP_VERSION_H, &cutvalue[1]);655 read_efuse_byte(hw, EEPROME_CHIP_VERSION_L, &cutvalue[0]);656 chipvalue = (cutvalue[1] << 8) | cutvalue[0];657 switch (chipvalue) {658 case 0xAA55:659 chipver |= CHIP_92D_C_CUT;660 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "C-CUT!!!\n");661 break;662 case 0x9966:663 chipver |= CHIP_92D_D_CUT;664 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "D-CUT!!!\n");665 break;666 case 0xCC33:667 case 0x33CC:668 chipver |= CHIP_92D_E_CUT;669 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "E-CUT!!!\n");670 break;671 default:672 chipver |= CHIP_92D_D_CUT;673 pr_err("Unknown CUT!\n");674 break;675 }676 rtlpriv->rtlhal.version = chipver;677}678 679static void _rtl92d_read_adapter_info(struct ieee80211_hw *hw)680{681 static const int params_pci[] = {682 RTL8190_EEPROM_ID, EEPROM_VID, EEPROM_DID,683 EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR_MAC0_92D,684 EEPROM_CHANNEL_PLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID,685 COUNTRY_CODE_WORLD_WIDE_13686 };687 static const int params_usb[] = {688 RTL8190_EEPROM_ID, EEPROM_VID_USB, EEPROM_PID_USB,689 EEPROM_VID_USB, EEPROM_PID_USB, EEPROM_MAC_ADDR_MAC0_92DU,690 EEPROM_CHANNEL_PLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID,691 COUNTRY_CODE_WORLD_WIDE_13692 };693 struct rtl_priv *rtlpriv = rtl_priv(hw);694 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));695 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));696 const int *params = params_pci;697 u8 *hwinfo;698 699 if (rtlhal->interface == INTF_USB)700 params = params_usb;701 702 hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL);703 if (!hwinfo)704 return;705 706 if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params))707 goto exit;708 709 _rtl92d_efuse_update_chip_version(hw);710 _rtl92d_read_macphymode_and_bandtype(hw, hwinfo);711 712 /* Read Permanent MAC address for 2nd interface */713 if (rtlhal->interfaceindex != 0)714 ether_addr_copy(rtlefuse->dev_addr,715 &hwinfo[EEPROM_MAC_ADDR_MAC1_92D]);716 717 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR,718 rtlefuse->dev_addr);719 rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr);720 _rtl92d_read_txpower_info(hw, rtlefuse->autoload_failflag, hwinfo);721 722 /* Read Channel Plan */723 switch (rtlhal->bandset) {724 case BAND_ON_2_4G:725 rtlefuse->channel_plan = COUNTRY_CODE_TELEC;726 break;727 case BAND_ON_5G:728 rtlefuse->channel_plan = COUNTRY_CODE_FCC;729 break;730 case BAND_ON_BOTH:731 rtlefuse->channel_plan = COUNTRY_CODE_FCC;732 break;733 default:734 rtlefuse->channel_plan = COUNTRY_CODE_FCC;735 break;736 }737 rtlefuse->txpwr_fromeprom = true;738exit:739 kfree(hwinfo);740}741 742void rtl92d_read_eeprom_info(struct ieee80211_hw *hw)743{744 struct rtl_priv *rtlpriv = rtl_priv(hw);745 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));746 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));747 u8 tmp_u1b;748 749 rtlhal->version = _rtl92d_read_chip_version(hw);750 tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);751 rtlefuse->autoload_status = tmp_u1b;752 if (tmp_u1b & BIT(4)) {753 rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");754 rtlefuse->epromtype = EEPROM_93C46;755 } else {756 rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");757 rtlefuse->epromtype = EEPROM_BOOT_EFUSE;758 }759 if (tmp_u1b & BIT(5)) {760 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");761 762 rtlefuse->autoload_failflag = false;763 _rtl92d_read_adapter_info(hw);764 } else {765 pr_err("Autoload ERR!!\n");766 }767}768EXPORT_SYMBOL_GPL(rtl92d_read_eeprom_info);769 770static void rtl92d_update_hal_rate_table(struct ieee80211_hw *hw,771 struct ieee80211_sta *sta)772{773 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));774 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));775 struct rtl_priv *rtlpriv = rtl_priv(hw);776 struct rtl_phy *rtlphy = &rtlpriv->phy;777 enum wireless_mode wirelessmode;778 u8 mimo_ps = IEEE80211_SMPS_OFF;779 u8 curtxbw_40mhz = mac->bw_40;780 u8 nmode = mac->ht_enable;781 u8 curshortgi_40mhz;782 u8 curshortgi_20mhz;783 u32 tmp_ratr_value;784 u8 ratr_index = 0;785 u16 shortgi_rate;786 u32 ratr_value;787 788 curshortgi_40mhz = !!(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40);789 curshortgi_20mhz = !!(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20);790 wirelessmode = mac->mode;791 792 if (rtlhal->current_bandtype == BAND_ON_5G)793 ratr_value = sta->deflink.supp_rates[1] << 4;794 else795 ratr_value = sta->deflink.supp_rates[0];796 ratr_value |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 |797 sta->deflink.ht_cap.mcs.rx_mask[0] << 12);798 switch (wirelessmode) {799 case WIRELESS_MODE_A:800 ratr_value &= 0x00000FF0;801 break;802 case WIRELESS_MODE_B:803 if (ratr_value & 0x0000000c)804 ratr_value &= 0x0000000d;805 else806 ratr_value &= 0x0000000f;807 break;808 case WIRELESS_MODE_G:809 ratr_value &= 0x00000FF5;810 break;811 case WIRELESS_MODE_N_24G:812 case WIRELESS_MODE_N_5G:813 nmode = 1;814 if (mimo_ps == IEEE80211_SMPS_STATIC) {815 ratr_value &= 0x0007F005;816 } else {817 u32 ratr_mask;818 819 if (get_rf_type(rtlphy) == RF_1T2R ||820 get_rf_type(rtlphy) == RF_1T1R) {821 ratr_mask = 0x000ff005;822 } else {823 ratr_mask = 0x0f0ff005;824 }825 826 ratr_value &= ratr_mask;827 }828 break;829 default:830 if (rtlphy->rf_type == RF_1T2R)831 ratr_value &= 0x000ff0ff;832 else833 ratr_value &= 0x0f0ff0ff;834 835 break;836 }837 ratr_value &= 0x0FFFFFFF;838 if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) ||839 (!curtxbw_40mhz && curshortgi_20mhz))) {840 ratr_value |= 0x10000000;841 tmp_ratr_value = (ratr_value >> 12);842 for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {843 if ((1 << shortgi_rate) & tmp_ratr_value)844 break;845 }846 shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |847 (shortgi_rate << 4) | (shortgi_rate);848 }849 rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);850 rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",851 rtl_read_dword(rtlpriv, REG_ARFR0));852}853 854static void rtl92d_update_hal_rate_mask(struct ieee80211_hw *hw,855 struct ieee80211_sta *sta,856 u8 rssi_level, bool update_bw)857{858 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));859 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));860 struct rtl92d_rate_mask_h2c rate_mask = {};861 struct rtl_priv *rtlpriv = rtl_priv(hw);862 struct rtl_phy *rtlphy = &rtlpriv->phy;863 struct rtl_sta_info *sta_entry = NULL;864 enum wireless_mode wirelessmode;865 bool shortgi = false;866 u8 curshortgi_40mhz;867 u8 curshortgi_20mhz;868 u8 curtxbw_40mhz;869 u32 ratr_bitmap;870 u8 ratr_index;871 u8 macid = 0;872 u8 mimo_ps;873 874 curtxbw_40mhz = sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40;875 curshortgi_40mhz = !!(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40);876 curshortgi_20mhz = !!(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20);877 878 sta_entry = (struct rtl_sta_info *)sta->drv_priv;879 mimo_ps = sta_entry->mimo_ps;880 wirelessmode = sta_entry->wireless_mode;881 882 if (mac->opmode == NL80211_IFTYPE_STATION)883 curtxbw_40mhz = mac->bw_40;884 else if (mac->opmode == NL80211_IFTYPE_AP ||885 mac->opmode == NL80211_IFTYPE_ADHOC)886 macid = sta->aid + 1;887 888 if (rtlhal->current_bandtype == BAND_ON_5G)889 ratr_bitmap = sta->deflink.supp_rates[1] << 4;890 else891 ratr_bitmap = sta->deflink.supp_rates[0];892 ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 |893 sta->deflink.ht_cap.mcs.rx_mask[0] << 12);894 895 switch (wirelessmode) {896 case WIRELESS_MODE_B:897 ratr_index = RATR_INX_WIRELESS_B;898 if (ratr_bitmap & 0x0000000c)899 ratr_bitmap &= 0x0000000d;900 else901 ratr_bitmap &= 0x0000000f;902 break;903 case WIRELESS_MODE_G:904 ratr_index = RATR_INX_WIRELESS_GB;905 906 if (rssi_level == 1)907 ratr_bitmap &= 0x00000f00;908 else if (rssi_level == 2)909 ratr_bitmap &= 0x00000ff0;910 else911 ratr_bitmap &= 0x00000ff5;912 break;913 case WIRELESS_MODE_A:914 ratr_index = RATR_INX_WIRELESS_G;915 ratr_bitmap &= 0x00000ff0;916 break;917 case WIRELESS_MODE_N_24G:918 case WIRELESS_MODE_N_5G:919 if (wirelessmode == WIRELESS_MODE_N_24G)920 ratr_index = RATR_INX_WIRELESS_NGB;921 else922 ratr_index = RATR_INX_WIRELESS_NG;923 924 if (mimo_ps == IEEE80211_SMPS_STATIC) {925 if (rssi_level == 1)926 ratr_bitmap &= 0x00070000;927 else if (rssi_level == 2)928 ratr_bitmap &= 0x0007f000;929 else930 ratr_bitmap &= 0x0007f005;931 } else {932 if (rtlphy->rf_type == RF_1T2R ||933 rtlphy->rf_type == RF_1T1R) {934 if (curtxbw_40mhz) {935 if (rssi_level == 1)936 ratr_bitmap &= 0x000f0000;937 else if (rssi_level == 2)938 ratr_bitmap &= 0x000ff000;939 else940 ratr_bitmap &= 0x000ff015;941 } else {942 if (rssi_level == 1)943 ratr_bitmap &= 0x000f0000;944 else if (rssi_level == 2)945 ratr_bitmap &= 0x000ff000;946 else947 ratr_bitmap &= 0x000ff005;948 }949 } else {950 if (curtxbw_40mhz) {951 if (rssi_level == 1)952 ratr_bitmap &= 0x0f0f0000;953 else if (rssi_level == 2)954 ratr_bitmap &= 0x0f0ff000;955 else956 ratr_bitmap &= 0x0f0ff015;957 } else {958 if (rssi_level == 1)959 ratr_bitmap &= 0x0f0f0000;960 else if (rssi_level == 2)961 ratr_bitmap &= 0x0f0ff000;962 else963 ratr_bitmap &= 0x0f0ff005;964 }965 }966 }967 968 if ((curtxbw_40mhz && curshortgi_40mhz) ||969 (!curtxbw_40mhz && curshortgi_20mhz)) {970 if (macid == 0)971 shortgi = true;972 else if (macid == 1)973 shortgi = false;974 }975 break;976 default:977 ratr_index = RATR_INX_WIRELESS_NGB;978 979 if (rtlphy->rf_type == RF_1T2R)980 ratr_bitmap &= 0x000ff0ff;981 else982 ratr_bitmap &= 0x0f0ff0ff;983 break;984 }985 986 le32p_replace_bits(&rate_mask.rate_mask_and_raid, ratr_bitmap, RATE_MASK_MASK);987 le32p_replace_bits(&rate_mask.rate_mask_and_raid, ratr_index, RAID_MASK);988 u8p_replace_bits(&rate_mask.macid_and_short_gi, macid, MACID_MASK);989 u8p_replace_bits(&rate_mask.macid_and_short_gi, shortgi, SHORT_GI_MASK);990 u8p_replace_bits(&rate_mask.macid_and_short_gi, 1, BIT(7));991 992 rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG,993 "Rate_index:%x, ratr_val:%x, %5phC\n",994 ratr_index, ratr_bitmap, &rate_mask);995 996 if (rtlhal->interface == INTF_PCI) {997 rtl92d_fill_h2c_cmd(hw, H2C_RA_MASK, sizeof(rate_mask),998 (u8 *)&rate_mask);999 } else {1000 /* rtl92d_fill_h2c_cmd() does USB I/O and will result in a1001 * "scheduled while atomic" if called directly1002 */1003 memcpy(rtlpriv->rate_mask, &rate_mask,1004 sizeof(rtlpriv->rate_mask));1005 schedule_work(&rtlpriv->works.fill_h2c_cmd);1006 }1007 1008 if (macid != 0)1009 sta_entry->ratr_index = ratr_index;1010}1011 1012void rtl92d_update_hal_rate_tbl(struct ieee80211_hw *hw,1013 struct ieee80211_sta *sta,1014 u8 rssi_level, bool update_bw)1015{1016 struct rtl_priv *rtlpriv = rtl_priv(hw);1017 1018 if (rtlpriv->dm.useramask)1019 rtl92d_update_hal_rate_mask(hw, sta, rssi_level, update_bw);1020 else1021 rtl92d_update_hal_rate_table(hw, sta);1022}1023EXPORT_SYMBOL_GPL(rtl92d_update_hal_rate_tbl);1024 1025void rtl92d_update_channel_access_setting(struct ieee80211_hw *hw)1026{1027 struct rtl_priv *rtlpriv = rtl_priv(hw);1028 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));1029 u16 sifs_timer;1030 1031 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,1032 &mac->slot_time);1033 if (!mac->ht_enable)1034 sifs_timer = 0x0a0a;1035 else1036 sifs_timer = 0x1010;1037 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);1038}1039EXPORT_SYMBOL_GPL(rtl92d_update_channel_access_setting);1040 1041bool rtl92d_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)1042{1043 struct rtl_priv *rtlpriv = rtl_priv(hw);1044 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));1045 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));1046 enum rf_pwrstate e_rfpowerstate_toset;1047 u8 u1tmp;1048 bool actuallyset = false;1049 unsigned long flag;1050 1051 if (rtlpriv->rtlhal.interface == INTF_PCI &&1052 rtlpci->being_init_adapter)1053 return false;1054 if (ppsc->swrf_processing)1055 return false;1056 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);1057 if (ppsc->rfchange_inprogress) {1058 spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);1059 return false;1060 }1061 1062 ppsc->rfchange_inprogress = true;1063 spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);1064 1065 rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG,1066 rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG) & ~(BIT(3)));1067 u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL);1068 e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF;1069 if (ppsc->hwradiooff && e_rfpowerstate_toset == ERFON) {1070 rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,1071 "GPIOChangeRF - HW Radio ON, RF ON\n");1072 e_rfpowerstate_toset = ERFON;1073 ppsc->hwradiooff = false;1074 actuallyset = true;1075 } else if (!ppsc->hwradiooff && e_rfpowerstate_toset == ERFOFF) {1076 rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,1077 "GPIOChangeRF - HW Radio OFF, RF OFF\n");1078 e_rfpowerstate_toset = ERFOFF;1079 ppsc->hwradiooff = true;1080 actuallyset = true;1081 }1082 if (actuallyset) {1083 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);1084 ppsc->rfchange_inprogress = false;1085 spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);1086 } else {1087 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)1088 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);1089 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);1090 ppsc->rfchange_inprogress = false;1091 spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);1092 }1093 *valid = 1;1094 return !ppsc->hwradiooff;1095}1096EXPORT_SYMBOL_GPL(rtl92d_gpio_radio_on_off_checking);1097 1098void rtl92d_set_key(struct ieee80211_hw *hw, u32 key_index,1099 u8 *p_macaddr, bool is_group, u8 enc_algo,1100 bool is_wepkey, bool clear_all)1101{1102 static const u8 cam_const_addr[4][6] = {1103 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},1104 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},1105 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},1106 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}1107 };1108 static const u8 cam_const_broad[] = {1109 0xff, 0xff, 0xff, 0xff, 0xff, 0xff1110 };1111 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));1112 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));1113 struct rtl_priv *rtlpriv = rtl_priv(hw);1114 const u8 *macaddr = p_macaddr;1115 bool is_pairwise = false;1116 u32 entry_id;1117 1118 if (clear_all) {1119 u8 idx;1120 u8 cam_offset = 0;1121 u8 clear_number = 5;1122 1123 rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");1124 for (idx = 0; idx < clear_number; idx++) {1125 rtl_cam_mark_invalid(hw, cam_offset + idx);1126 rtl_cam_empty_entry(hw, cam_offset + idx);1127 1128 if (idx < 5) {1129 memset(rtlpriv->sec.key_buf[idx], 0,1130 MAX_KEY_LEN);1131 rtlpriv->sec.key_len[idx] = 0;1132 }1133 }1134 1135 return;1136 }1137 1138 switch (enc_algo) {1139 case WEP40_ENCRYPTION:1140 enc_algo = CAM_WEP40;1141 break;1142 case WEP104_ENCRYPTION:1143 enc_algo = CAM_WEP104;1144 break;1145 case TKIP_ENCRYPTION:1146 enc_algo = CAM_TKIP;1147 break;1148 case AESCCMP_ENCRYPTION:1149 enc_algo = CAM_AES;1150 break;1151 default:1152 pr_err("switch case %#x not processed\n",1153 enc_algo);1154 enc_algo = CAM_TKIP;1155 break;1156 }1157 if (is_wepkey || rtlpriv->sec.use_defaultkey) {1158 macaddr = cam_const_addr[key_index];1159 entry_id = key_index;1160 } else {1161 if (is_group) {1162 macaddr = cam_const_broad;1163 entry_id = key_index;1164 } else {1165 if (mac->opmode == NL80211_IFTYPE_AP) {1166 entry_id = rtl_cam_get_free_entry(hw, p_macaddr);1167 if (entry_id >= TOTAL_CAM_ENTRY) {1168 pr_err("Can not find free hw security cam entry\n");1169 return;1170 }1171 } else {1172 entry_id = CAM_PAIRWISE_KEY_POSITION;1173 }1174 key_index = PAIRWISE_KEYIDX;1175 is_pairwise = true;1176 }1177 }1178 if (rtlpriv->sec.key_len[key_index] == 0) {1179 rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,1180 "delete one entry, entry_id is %d\n",1181 entry_id);1182 if (mac->opmode == NL80211_IFTYPE_AP)1183 rtl_cam_del_entry(hw, p_macaddr);1184 rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);1185 } else {1186 rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD,1187 "The insert KEY length is %d\n",1188 rtlpriv->sec.key_len[PAIRWISE_KEYIDX]);1189 rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD,1190 "The insert KEY is %x %x\n",1191 rtlpriv->sec.key_buf[0][0],1192 rtlpriv->sec.key_buf[0][1]);1193 rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,1194 "add one entry\n");1195 if (is_pairwise) {1196 RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,1197 "Pairwise Key content",1198 rtlpriv->sec.pairwise_key,1199 rtlpriv->sec.key_len[PAIRWISE_KEYIDX]);1200 rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,1201 "set Pairwise key\n");1202 rtl_cam_add_one_entry(hw, macaddr, key_index,1203 entry_id, enc_algo,1204 CAM_CONFIG_NO_USEDK,1205 rtlpriv->sec.key_buf[key_index]);1206 } else {1207 rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,1208 "set group key\n");1209 if (mac->opmode == NL80211_IFTYPE_ADHOC) {1210 rtl_cam_add_one_entry(hw,1211 rtlefuse->dev_addr,1212 PAIRWISE_KEYIDX,1213 CAM_PAIRWISE_KEY_POSITION,1214 enc_algo, CAM_CONFIG_NO_USEDK,1215 rtlpriv->sec.key_buf[entry_id]);1216 }1217 rtl_cam_add_one_entry(hw, macaddr, key_index,1218 entry_id, enc_algo,1219 CAM_CONFIG_NO_USEDK,1220 rtlpriv->sec.key_buf1221 [entry_id]);1222 }1223 }1224}1225EXPORT_SYMBOL_GPL(rtl92d_set_key);1226