722 lines · c
1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause2/* Copyright 2024 Fiona Klute3 *4 * Based on code originally in rtw8723d.[ch],5 * Copyright(c) 2018-2019 Realtek Corporation6 */7 8#include "main.h"9#include "debug.h"10#include "phy.h"11#include "reg.h"12#include "tx.h"13#include "rtw8723x.h"14 15static const struct rtw_hw_reg rtw8723x_txagc[] = {16 [DESC_RATE1M] = { .addr = 0xe08, .mask = 0x0000ff00 },17 [DESC_RATE2M] = { .addr = 0x86c, .mask = 0x0000ff00 },18 [DESC_RATE5_5M] = { .addr = 0x86c, .mask = 0x00ff0000 },19 [DESC_RATE11M] = { .addr = 0x86c, .mask = 0xff000000 },20 [DESC_RATE6M] = { .addr = 0xe00, .mask = 0x000000ff },21 [DESC_RATE9M] = { .addr = 0xe00, .mask = 0x0000ff00 },22 [DESC_RATE12M] = { .addr = 0xe00, .mask = 0x00ff0000 },23 [DESC_RATE18M] = { .addr = 0xe00, .mask = 0xff000000 },24 [DESC_RATE24M] = { .addr = 0xe04, .mask = 0x000000ff },25 [DESC_RATE36M] = { .addr = 0xe04, .mask = 0x0000ff00 },26 [DESC_RATE48M] = { .addr = 0xe04, .mask = 0x00ff0000 },27 [DESC_RATE54M] = { .addr = 0xe04, .mask = 0xff000000 },28 [DESC_RATEMCS0] = { .addr = 0xe10, .mask = 0x000000ff },29 [DESC_RATEMCS1] = { .addr = 0xe10, .mask = 0x0000ff00 },30 [DESC_RATEMCS2] = { .addr = 0xe10, .mask = 0x00ff0000 },31 [DESC_RATEMCS3] = { .addr = 0xe10, .mask = 0xff000000 },32 [DESC_RATEMCS4] = { .addr = 0xe14, .mask = 0x000000ff },33 [DESC_RATEMCS5] = { .addr = 0xe14, .mask = 0x0000ff00 },34 [DESC_RATEMCS6] = { .addr = 0xe14, .mask = 0x00ff0000 },35 [DESC_RATEMCS7] = { .addr = 0xe14, .mask = 0xff000000 },36};37 38static void __rtw8723x_lck(struct rtw_dev *rtwdev)39{40 u32 lc_cal;41 u8 val_ctx, rf_val;42 int ret;43 44 val_ctx = rtw_read8(rtwdev, REG_CTX);45 if ((val_ctx & BIT_MASK_CTX_TYPE) != 0)46 rtw_write8(rtwdev, REG_CTX, val_ctx & ~BIT_MASK_CTX_TYPE);47 else48 rtw_write8(rtwdev, REG_TXPAUSE, 0xFF);49 lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK);50 51 rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal | BIT_LCK);52 53 ret = read_poll_timeout(rtw_read_rf, rf_val, rf_val != 0x1,54 10000, 1000000, false,55 rtwdev, RF_PATH_A, RF_CFGCH, BIT_LCK);56 if (ret)57 rtw_warn(rtwdev, "failed to poll LCK status bit\n");58 59 rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal);60 if ((val_ctx & BIT_MASK_CTX_TYPE) != 0)61 rtw_write8(rtwdev, REG_CTX, val_ctx);62 else63 rtw_write8(rtwdev, REG_TXPAUSE, 0x00);64}65 66#define DBG_EFUSE_VAL(rtwdev, map, name) \67 rtw_dbg(rtwdev, RTW_DBG_EFUSE, # name "=0x%02x\n", \68 (map)->name)69#define DBG_EFUSE_2BYTE(rtwdev, map, name) \70 rtw_dbg(rtwdev, RTW_DBG_EFUSE, # name "=0x%02x%02x\n", \71 (map)->name[0], (map)->name[1])72 73static void rtw8723xe_efuse_debug(struct rtw_dev *rtwdev,74 struct rtw8723x_efuse *map)75{76 rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->e.mac_addr);77 DBG_EFUSE_2BYTE(rtwdev, map, e.vendor_id);78 DBG_EFUSE_2BYTE(rtwdev, map, e.device_id);79 DBG_EFUSE_2BYTE(rtwdev, map, e.sub_vendor_id);80 DBG_EFUSE_2BYTE(rtwdev, map, e.sub_device_id);81}82 83static void rtw8723xu_efuse_debug(struct rtw_dev *rtwdev,84 struct rtw8723x_efuse *map)85{86 DBG_EFUSE_2BYTE(rtwdev, map, u.vendor_id);87 DBG_EFUSE_2BYTE(rtwdev, map, u.product_id);88 DBG_EFUSE_VAL(rtwdev, map, u.usb_option);89 rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->u.mac_addr);90}91 92static void rtw8723xs_efuse_debug(struct rtw_dev *rtwdev,93 struct rtw8723x_efuse *map)94{95 rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->s.mac_addr);96}97 98static void __rtw8723x_debug_txpwr_limit(struct rtw_dev *rtwdev,99 struct rtw_txpwr_idx *table,100 int tx_path_count)101{102 if (!rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE))103 return;104 105 rtw_dbg(rtwdev, RTW_DBG_EFUSE,106 "Power index table (2.4G):\n");107 /* CCK base */108 rtw_dbg(rtwdev, RTW_DBG_EFUSE, "CCK base\n");109 rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF G0 G1 G2 G3 G4 G5\n");110 for (int i = 0; i < tx_path_count; i++)111 rtw_dbg(rtwdev, RTW_DBG_EFUSE,112 "[%c]: %3u %3u %3u %3u %3u %3u\n",113 'A' + i,114 table[i].pwr_idx_2g.cck_base[0],115 table[i].pwr_idx_2g.cck_base[1],116 table[i].pwr_idx_2g.cck_base[2],117 table[i].pwr_idx_2g.cck_base[3],118 table[i].pwr_idx_2g.cck_base[4],119 table[i].pwr_idx_2g.cck_base[5]);120 /* CCK diff */121 rtw_dbg(rtwdev, RTW_DBG_EFUSE, "CCK diff\n");122 rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n");123 for (int i = 0; i < tx_path_count; i++)124 rtw_dbg(rtwdev, RTW_DBG_EFUSE,125 "[%c]: %2d %2d %2d %2d\n",126 'A' + i, 0 /* no diff for 1S */,127 table[i].pwr_idx_2g.ht_2s_diff.cck,128 table[i].pwr_idx_2g.ht_3s_diff.cck,129 table[i].pwr_idx_2g.ht_4s_diff.cck);130 /* BW40-1S base */131 rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW40-1S base\n");132 rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF G0 G1 G2 G3 G4\n");133 for (int i = 0; i < tx_path_count; i++)134 rtw_dbg(rtwdev, RTW_DBG_EFUSE,135 "[%c]: %3u %3u %3u %3u %3u\n",136 'A' + i,137 table[i].pwr_idx_2g.bw40_base[0],138 table[i].pwr_idx_2g.bw40_base[1],139 table[i].pwr_idx_2g.bw40_base[2],140 table[i].pwr_idx_2g.bw40_base[3],141 table[i].pwr_idx_2g.bw40_base[4]);142 /* OFDM diff */143 rtw_dbg(rtwdev, RTW_DBG_EFUSE, "OFDM diff\n");144 rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n");145 for (int i = 0; i < tx_path_count; i++)146 rtw_dbg(rtwdev, RTW_DBG_EFUSE,147 "[%c]: %2d %2d %2d %2d\n",148 'A' + i,149 table[i].pwr_idx_2g.ht_1s_diff.ofdm,150 table[i].pwr_idx_2g.ht_2s_diff.ofdm,151 table[i].pwr_idx_2g.ht_3s_diff.ofdm,152 table[i].pwr_idx_2g.ht_4s_diff.ofdm);153 /* BW20 diff */154 rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW20 diff\n");155 rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n");156 for (int i = 0; i < tx_path_count; i++)157 rtw_dbg(rtwdev, RTW_DBG_EFUSE,158 "[%c]: %2d %2d %2d %2d\n",159 'A' + i,160 table[i].pwr_idx_2g.ht_1s_diff.bw20,161 table[i].pwr_idx_2g.ht_2s_diff.bw20,162 table[i].pwr_idx_2g.ht_3s_diff.bw20,163 table[i].pwr_idx_2g.ht_4s_diff.bw20);164 /* BW40 diff */165 rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW40 diff\n");166 rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n");167 for (int i = 0; i < tx_path_count; i++)168 rtw_dbg(rtwdev, RTW_DBG_EFUSE,169 "[%c]: %2d %2d %2d %2d\n",170 'A' + i, 0 /* no diff for 1S */,171 table[i].pwr_idx_2g.ht_2s_diff.bw40,172 table[i].pwr_idx_2g.ht_3s_diff.bw40,173 table[i].pwr_idx_2g.ht_4s_diff.bw40);174}175 176static void efuse_debug_dump(struct rtw_dev *rtwdev,177 struct rtw8723x_efuse *map)178{179 if (!rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE))180 return;181 182 rtw_dbg(rtwdev, RTW_DBG_EFUSE, "EFUSE raw logical map:\n");183 print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1,184 (u8 *)map, sizeof(struct rtw8723x_efuse), false);185 rtw_dbg(rtwdev, RTW_DBG_EFUSE, "Parsed rtw8723x EFUSE data:\n");186 DBG_EFUSE_VAL(rtwdev, map, rtl_id);187 DBG_EFUSE_VAL(rtwdev, map, afe);188 rtw8723x_debug_txpwr_limit(rtwdev, map->txpwr_idx_table, 4);189 DBG_EFUSE_VAL(rtwdev, map, channel_plan);190 DBG_EFUSE_VAL(rtwdev, map, xtal_k);191 DBG_EFUSE_VAL(rtwdev, map, thermal_meter);192 DBG_EFUSE_VAL(rtwdev, map, iqk_lck);193 DBG_EFUSE_VAL(rtwdev, map, pa_type);194 DBG_EFUSE_2BYTE(rtwdev, map, lna_type_2g);195 DBG_EFUSE_2BYTE(rtwdev, map, lna_type_5g);196 DBG_EFUSE_VAL(rtwdev, map, rf_board_option);197 DBG_EFUSE_VAL(rtwdev, map, rf_feature_option);198 DBG_EFUSE_VAL(rtwdev, map, rf_bt_setting);199 DBG_EFUSE_VAL(rtwdev, map, eeprom_version);200 DBG_EFUSE_VAL(rtwdev, map, eeprom_customer_id);201 DBG_EFUSE_VAL(rtwdev, map, tx_bb_swing_setting_2g);202 DBG_EFUSE_VAL(rtwdev, map, tx_pwr_calibrate_rate);203 DBG_EFUSE_VAL(rtwdev, map, rf_antenna_option);204 DBG_EFUSE_VAL(rtwdev, map, rfe_option);205 DBG_EFUSE_2BYTE(rtwdev, map, country_code);206 207 switch (rtw_hci_type(rtwdev)) {208 case RTW_HCI_TYPE_PCIE:209 rtw8723xe_efuse_debug(rtwdev, map);210 break;211 case RTW_HCI_TYPE_USB:212 rtw8723xu_efuse_debug(rtwdev, map);213 break;214 case RTW_HCI_TYPE_SDIO:215 rtw8723xs_efuse_debug(rtwdev, map);216 break;217 default:218 /* unsupported now */219 break;220 }221}222 223static void rtw8723xe_efuse_parsing(struct rtw_efuse *efuse,224 struct rtw8723x_efuse *map)225{226 ether_addr_copy(efuse->addr, map->e.mac_addr);227}228 229static void rtw8723xu_efuse_parsing(struct rtw_efuse *efuse,230 struct rtw8723x_efuse *map)231{232 ether_addr_copy(efuse->addr, map->u.mac_addr);233}234 235static void rtw8723xs_efuse_parsing(struct rtw_efuse *efuse,236 struct rtw8723x_efuse *map)237{238 ether_addr_copy(efuse->addr, map->s.mac_addr);239}240 241static int __rtw8723x_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)242{243 struct rtw_efuse *efuse = &rtwdev->efuse;244 struct rtw8723x_efuse *map;245 int i;246 247 map = (struct rtw8723x_efuse *)log_map;248 efuse_debug_dump(rtwdev, map);249 250 efuse->rfe_option = 0;251 efuse->rf_board_option = map->rf_board_option;252 efuse->crystal_cap = map->xtal_k;253 efuse->pa_type_2g = map->pa_type;254 efuse->lna_type_2g = map->lna_type_2g[0];255 efuse->channel_plan = map->channel_plan;256 efuse->country_code[0] = map->country_code[0];257 efuse->country_code[1] = map->country_code[1];258 efuse->bt_setting = map->rf_bt_setting;259 efuse->regd = map->rf_board_option & 0x7;260 efuse->thermal_meter[0] = map->thermal_meter;261 efuse->thermal_meter_k = map->thermal_meter;262 efuse->afe = map->afe;263 264 for (i = 0; i < 4; i++)265 efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i];266 267 switch (rtw_hci_type(rtwdev)) {268 case RTW_HCI_TYPE_PCIE:269 rtw8723xe_efuse_parsing(efuse, map);270 break;271 case RTW_HCI_TYPE_USB:272 rtw8723xu_efuse_parsing(efuse, map);273 break;274 case RTW_HCI_TYPE_SDIO:275 rtw8723xs_efuse_parsing(efuse, map);276 break;277 default:278 /* unsupported now */279 return -EOPNOTSUPP;280 }281 282 return 0;283}284 285#define BIT_CFENDFORM BIT(9)286#define BIT_WMAC_TCR_ERR0 BIT(12)287#define BIT_WMAC_TCR_ERR1 BIT(13)288#define BIT_TCR_CFG (BIT_CFENDFORM | BIT_WMAC_TCR_ERR0 | \289 BIT_WMAC_TCR_ERR1)290#define WLAN_RX_FILTER0 0xFFFF291#define WLAN_RX_FILTER1 0x400292#define WLAN_RX_FILTER2 0xFFFF293#define WLAN_RCR_CFG 0x700060CE294 295static int __rtw8723x_mac_init(struct rtw_dev *rtwdev)296{297 rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN);298 rtw_write32(rtwdev, REG_TCR, BIT_TCR_CFG);299 300 rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0);301 rtw_write16(rtwdev, REG_RXFLTMAP1, WLAN_RX_FILTER1);302 rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2);303 rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG);304 305 rtw_write32(rtwdev, REG_INT_MIG, 0);306 rtw_write32(rtwdev, REG_MCUTST_1, 0x0);307 308 rtw_write8(rtwdev, REG_MISC_CTRL, BIT_DIS_SECOND_CCA);309 rtw_write8(rtwdev, REG_2ND_CCA_CTRL, 0);310 311 return 0;312}313 314static void __rtw8723x_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)315{316 u8 ldo_pwr;317 318 ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3);319 if (enable) {320 ldo_pwr &= ~BIT_MASK_LDO25_VOLTAGE;321 ldo_pwr |= (BIT_LDO25_VOLTAGE_V25 << 4) | BIT_LDO25_EN;322 } else {323 ldo_pwr &= ~BIT_LDO25_EN;324 }325 rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr);326}327 328static void329rtw8723x_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)330{331 struct rtw_hal *hal = &rtwdev->hal;332 const struct rtw_hw_reg *txagc;333 u8 rate, pwr_index;334 int j;335 336 for (j = 0; j < rtw_rate_size[rs]; j++) {337 rate = rtw_rate_section[rs][j];338 pwr_index = hal->tx_pwr_tbl[path][rate];339 340 if (rate >= ARRAY_SIZE(rtw8723x_txagc)) {341 rtw_warn(rtwdev, "rate 0x%x isn't supported\n", rate);342 continue;343 }344 txagc = &rtw8723x_txagc[rate];345 if (!txagc->addr) {346 rtw_warn(rtwdev, "rate 0x%x isn't defined\n", rate);347 continue;348 }349 350 rtw_write32_mask(rtwdev, txagc->addr, txagc->mask, pwr_index);351 }352}353 354static void __rtw8723x_set_tx_power_index(struct rtw_dev *rtwdev)355{356 struct rtw_hal *hal = &rtwdev->hal;357 int rs, path;358 359 for (path = 0; path < hal->rf_path_num; path++) {360 for (rs = 0; rs <= RTW_RATE_SECTION_HT_1S; rs++)361 rtw8723x_set_tx_power_index_by_rate(rtwdev, path, rs);362 }363}364 365static void __rtw8723x_efuse_grant(struct rtw_dev *rtwdev, bool on)366{367 if (on) {368 rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);369 370 rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_ELDR);371 rtw_write16_set(rtwdev, REG_SYS_CLKR, BIT_LOADER_CLK_EN | BIT_ANA8M);372 } else {373 rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);374 }375}376 377static void __rtw8723x_false_alarm_statistics(struct rtw_dev *rtwdev)378{379 struct rtw_dm_info *dm_info = &rtwdev->dm_info;380 u32 cck_fa_cnt;381 u32 ofdm_fa_cnt;382 u32 crc32_cnt;383 u32 val32;384 385 /* hold counter */386 rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 1);387 rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 1);388 rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KEEP, 1);389 rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KEEP, 1);390 391 cck_fa_cnt = rtw_read32_mask(rtwdev, REG_CCK_FA_LSB_11N, MASKBYTE0);392 cck_fa_cnt += rtw_read32_mask(rtwdev, REG_CCK_FA_MSB_11N, MASKBYTE3) << 8;393 394 val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE1_11N);395 ofdm_fa_cnt = u32_get_bits(val32, BIT_MASK_OFDM_FF_CNT);396 ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_SF_CNT);397 val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE2_11N);398 dm_info->ofdm_cca_cnt = u32_get_bits(val32, BIT_MASK_OFDM_CCA_CNT);399 ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_PF_CNT);400 val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE3_11N);401 ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_RI_CNT);402 ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_CRC_CNT);403 val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE4_11N);404 ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_MNS_CNT);405 406 dm_info->cck_fa_cnt = cck_fa_cnt;407 dm_info->ofdm_fa_cnt = ofdm_fa_cnt;408 dm_info->total_fa_cnt = cck_fa_cnt + ofdm_fa_cnt;409 410 dm_info->cck_err_cnt = rtw_read32(rtwdev, REG_IGI_C_11N);411 dm_info->cck_ok_cnt = rtw_read32(rtwdev, REG_IGI_D_11N);412 crc32_cnt = rtw_read32(rtwdev, REG_OFDM_CRC32_CNT_11N);413 dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_ERR);414 dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_OK);415 crc32_cnt = rtw_read32(rtwdev, REG_HT_CRC32_CNT_11N);416 dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_ERR);417 dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_OK);418 dm_info->vht_err_cnt = 0;419 dm_info->vht_ok_cnt = 0;420 421 val32 = rtw_read32(rtwdev, REG_CCK_CCA_CNT_11N);422 dm_info->cck_cca_cnt = (u32_get_bits(val32, BIT_MASK_CCK_FA_MSB) << 8) |423 u32_get_bits(val32, BIT_MASK_CCK_FA_LSB);424 dm_info->total_cca_cnt = dm_info->cck_cca_cnt + dm_info->ofdm_cca_cnt;425 426 /* reset counter */427 rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 1);428 rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 0);429 rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 1);430 rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 0);431 rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 0);432 rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 0);433 rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 0);434 rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 2);435 rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 0);436 rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 2);437 rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 1);438 rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 0);439}440 441/* IQK (IQ calibration) */442 443static444void __rtw8723x_iqk_backup_regs(struct rtw_dev *rtwdev,445 struct rtw8723x_iqk_backup_regs *backup)446{447 int i;448 449 for (i = 0; i < RTW8723X_IQK_ADDA_REG_NUM; i++)450 backup->adda[i] = rtw_read32(rtwdev,451 rtw8723x_common.iqk_adda_regs[i]);452 453 for (i = 0; i < RTW8723X_IQK_MAC8_REG_NUM; i++)454 backup->mac8[i] = rtw_read8(rtwdev,455 rtw8723x_common.iqk_mac8_regs[i]);456 for (i = 0; i < RTW8723X_IQK_MAC32_REG_NUM; i++)457 backup->mac32[i] = rtw_read32(rtwdev,458 rtw8723x_common.iqk_mac32_regs[i]);459 460 for (i = 0; i < RTW8723X_IQK_BB_REG_NUM; i++)461 backup->bb[i] = rtw_read32(rtwdev,462 rtw8723x_common.iqk_bb_regs[i]);463 464 backup->igia = rtw_read32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0);465 backup->igib = rtw_read32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0);466 467 backup->bb_sel_btg = rtw_read32(rtwdev, REG_BB_SEL_BTG);468}469 470static471void __rtw8723x_iqk_restore_regs(struct rtw_dev *rtwdev,472 const struct rtw8723x_iqk_backup_regs *backup)473{474 int i;475 476 for (i = 0; i < RTW8723X_IQK_ADDA_REG_NUM; i++)477 rtw_write32(rtwdev, rtw8723x_common.iqk_adda_regs[i],478 backup->adda[i]);479 480 for (i = 0; i < RTW8723X_IQK_MAC8_REG_NUM; i++)481 rtw_write8(rtwdev, rtw8723x_common.iqk_mac8_regs[i],482 backup->mac8[i]);483 for (i = 0; i < RTW8723X_IQK_MAC32_REG_NUM; i++)484 rtw_write32(rtwdev, rtw8723x_common.iqk_mac32_regs[i],485 backup->mac32[i]);486 487 for (i = 0; i < RTW8723X_IQK_BB_REG_NUM; i++)488 rtw_write32(rtwdev, rtw8723x_common.iqk_bb_regs[i],489 backup->bb[i]);490 491 rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50);492 rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, backup->igia);493 494 rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, 0x50);495 rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, backup->igib);496 497 rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x01008c00);498 rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x01008c00);499}500 501static502bool __rtw8723x_iqk_similarity_cmp(struct rtw_dev *rtwdev,503 s32 result[][IQK_NR],504 u8 c1, u8 c2)505{506 u32 i, j, diff;507 u32 bitmap = 0;508 u8 candidate[PATH_NR] = {IQK_ROUND_INVALID, IQK_ROUND_INVALID};509 bool ret = true;510 511 s32 tmp1, tmp2;512 513 for (i = 0; i < IQK_NR; i++) {514 tmp1 = iqkxy_to_s32(result[c1][i]);515 tmp2 = iqkxy_to_s32(result[c2][i]);516 517 diff = abs(tmp1 - tmp2);518 519 if (diff <= MAX_TOLERANCE)520 continue;521 522 if ((i == IQK_S1_RX_X || i == IQK_S0_RX_X) && !bitmap) {523 if (result[c1][i] + result[c1][i + 1] == 0)524 candidate[i / IQK_SX_NR] = c2;525 else if (result[c2][i] + result[c2][i + 1] == 0)526 candidate[i / IQK_SX_NR] = c1;527 else528 bitmap |= BIT(i);529 } else {530 bitmap |= BIT(i);531 }532 }533 534 if (bitmap != 0)535 goto check_sim;536 537 for (i = 0; i < PATH_NR; i++) {538 if (candidate[i] == IQK_ROUND_INVALID)539 continue;540 541 for (j = i * IQK_SX_NR; j < i * IQK_SX_NR + 2; j++)542 result[IQK_ROUND_HYBRID][j] = result[candidate[i]][j];543 ret = false;544 }545 546 return ret;547 548check_sim:549 for (i = 0; i < IQK_NR; i++) {550 j = i & ~1; /* 2 bits are a pair for IQ[X, Y] */551 if (bitmap & GENMASK(j + 1, j))552 continue;553 554 result[IQK_ROUND_HYBRID][i] = result[c1][i];555 }556 557 return false;558}559 560static u8 __rtw8723x_pwrtrack_get_limit_ofdm(struct rtw_dev *rtwdev)561{562 struct rtw_dm_info *dm_info = &rtwdev->dm_info;563 u8 tx_rate = dm_info->tx_rate;564 u8 limit_ofdm = 30;565 566 switch (tx_rate) {567 case DESC_RATE1M...DESC_RATE5_5M:568 case DESC_RATE11M:569 break;570 case DESC_RATE6M...DESC_RATE48M:571 limit_ofdm = 36;572 break;573 case DESC_RATE54M:574 limit_ofdm = 34;575 break;576 case DESC_RATEMCS0...DESC_RATEMCS2:577 limit_ofdm = 38;578 break;579 case DESC_RATEMCS3...DESC_RATEMCS4:580 limit_ofdm = 36;581 break;582 case DESC_RATEMCS5...DESC_RATEMCS7:583 limit_ofdm = 34;584 break;585 default:586 rtw_warn(rtwdev, "pwrtrack unhandled tx_rate 0x%x\n", tx_rate);587 break;588 }589 590 return limit_ofdm;591}592 593static594void __rtw8723x_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path,595 u8 delta)596{597 struct rtw_dm_info *dm_info = &rtwdev->dm_info;598 const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl;599 const s8 *pwrtrk_xtal;600 s8 xtal_cap;601 602 if (dm_info->thermal_avg[therm_path] >603 rtwdev->efuse.thermal_meter[therm_path])604 pwrtrk_xtal = tbl->pwrtrk_xtal_p;605 else606 pwrtrk_xtal = tbl->pwrtrk_xtal_n;607 608 xtal_cap = rtwdev->efuse.crystal_cap & 0x3F;609 xtal_cap = clamp_t(s8, xtal_cap + pwrtrk_xtal[delta], 0, 0x3F);610 rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL,611 xtal_cap | (xtal_cap << 6));612}613 614static615void __rtw8723x_fill_txdesc_checksum(struct rtw_dev *rtwdev,616 struct rtw_tx_pkt_info *pkt_info,617 u8 *txdesc)618{619 size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */620 __le16 chksum = 0;621 __le16 *data = (__le16 *)(txdesc);622 struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc;623 624 le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM);625 626 while (words--)627 chksum ^= *data++;628 629 chksum = ~chksum;630 631 le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum),632 RTW_TX_DESC_W7_TXDESC_CHECKSUM);633}634 635static void __rtw8723x_coex_cfg_init(struct rtw_dev *rtwdev)636{637 /* enable TBTT nterrupt */638 rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);639 640 /* BT report packet sample rate */641 /* 0x790[5:0]=0x5 */642 rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5);643 644 /* enable BT counter statistics */645 rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1);646 647 /* enable PTA (3-wire function form BT side) */648 rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN);649 rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS);650 651 /* enable PTA (tx/rx signal form WiFi side) */652 rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN);653}654 655const struct rtw8723x_common rtw8723x_common = {656 .iqk_adda_regs = {657 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84,658 0xe88, 0xe8c, 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec659 },660 .iqk_mac8_regs = {0x522, 0x550, 0x551},661 .iqk_mac32_regs = {0x40},662 .iqk_bb_regs = {663 0xc04, 0xc08, 0x874, 0xb68, 0xb6c, 0x870, 0x860, 0x864, 0xa04664 },665 666 .ltecoex_addr = {667 .ctrl = REG_LTECOEX_CTRL,668 .wdata = REG_LTECOEX_WRITE_DATA,669 .rdata = REG_LTECOEX_READ_DATA,670 },671 .rf_sipi_addr = {672 [RF_PATH_A] = { .hssi_1 = 0x820, .lssi_read = 0x8a0,673 .hssi_2 = 0x824, .lssi_read_pi = 0x8b8},674 [RF_PATH_B] = { .hssi_1 = 0x828, .lssi_read = 0x8a4,675 .hssi_2 = 0x82c, .lssi_read_pi = 0x8bc},676 },677 .dig = {678 [0] = { .addr = 0xc50, .mask = 0x7f },679 [1] = { .addr = 0xc50, .mask = 0x7f },680 },681 .dig_cck = {682 [0] = { .addr = 0xa0c, .mask = 0x3f00 },683 },684 .prioq_addrs = {685 .prio[RTW_DMA_MAPPING_EXTRA] = {686 .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3,687 },688 .prio[RTW_DMA_MAPPING_LOW] = {689 .rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1,690 },691 .prio[RTW_DMA_MAPPING_NORMAL] = {692 .rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1,693 },694 .prio[RTW_DMA_MAPPING_HIGH] = {695 .rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2,696 },697 .wsize = false,698 },699 700 .lck = __rtw8723x_lck,701 .read_efuse = __rtw8723x_read_efuse,702 .mac_init = __rtw8723x_mac_init,703 .cfg_ldo25 = __rtw8723x_cfg_ldo25,704 .set_tx_power_index = __rtw8723x_set_tx_power_index,705 .efuse_grant = __rtw8723x_efuse_grant,706 .false_alarm_statistics = __rtw8723x_false_alarm_statistics,707 .iqk_backup_regs = __rtw8723x_iqk_backup_regs,708 .iqk_restore_regs = __rtw8723x_iqk_restore_regs,709 .iqk_similarity_cmp = __rtw8723x_iqk_similarity_cmp,710 .pwrtrack_get_limit_ofdm = __rtw8723x_pwrtrack_get_limit_ofdm,711 .pwrtrack_set_xtal = __rtw8723x_pwrtrack_set_xtal,712 .coex_cfg_init = __rtw8723x_coex_cfg_init,713 .fill_txdesc_checksum = __rtw8723x_fill_txdesc_checksum,714 .debug_txpwr_limit = __rtw8723x_debug_txpwr_limit,715};716EXPORT_SYMBOL(rtw8723x_common);717 718MODULE_AUTHOR("Realtek Corporation");719MODULE_AUTHOR("Fiona Klute <fiona.klute@gmx.de>");720MODULE_DESCRIPTION("Common functions for Realtek 802.11n wireless 8723x drivers");721MODULE_LICENSE("Dual BSD/GPL");722