Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/net/wireless/realtek/rtw89/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 10 kB image not shown  

Quelle  rtw8922a_rfk.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2023  Realtek Corporation
 */


#include "chan.h"
#include "debug.h"
#include "mac.h"
#include "phy.h"
#include "reg.h"
#include "rtw8922a.h"
#include "rtw8922a_rfk.h"

static void rtw8922a_tssi_cont_en(struct rtw89_dev *rtwdev, bool en,
      enum rtw89_rf_path path)
{
 static const u32 tssi_trk_man[2] = {R_TSSI_PWR_P0, R_TSSI_PWR_P1};

 if (en)
  rtw89_phy_write32_mask(rtwdev, tssi_trk_man[path], B_TSSI_CONT_EN, 0);
 else
  rtw89_phy_write32_mask(rtwdev, tssi_trk_man[path], B_TSSI_CONT_EN, 1);
}

void rtw8922a_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx)
{
 if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF) {
  if (phy_idx == RTW89_PHY_0)
   rtw8922a_tssi_cont_en(rtwdev, en, RF_PATH_A);
  else
   rtw8922a_tssi_cont_en(rtwdev, en, RF_PATH_B);
 } else {
  rtw8922a_tssi_cont_en(rtwdev, en, RF_PATH_A);
  rtw8922a_tssi_cont_en(rtwdev, en, RF_PATH_B);
 }
}

static
void rtw8922a_ctl_band_ch_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
        const struct rtw89_chan *chan)
{
 const u32 rf_addr[2] = {RR_CFGCH, RR_CFGCH_V1};
 struct rtw89_hal *hal = &rtwdev->hal;
 u32 rf_reg[RF_PATH_NUM_8922A][2];
 u8 synpath;
 u32 rf18;
 u8 kpath;
 u8 path;
 u8 i;

 rf_reg[RF_PATH_A][0] = rtw89_read_rf(rtwdev, RF_PATH_A, rf_addr[0], RFREG_MASK);
 rf_reg[RF_PATH_A][1] = rtw89_read_rf(rtwdev, RF_PATH_A, rf_addr[1], RFREG_MASK);
 rf_reg[RF_PATH_B][0] = rtw89_read_rf(rtwdev, RF_PATH_B, rf_addr[0], RFREG_MASK);
 rf_reg[RF_PATH_B][1] = rtw89_read_rf(rtwdev, RF_PATH_B, rf_addr[1], RFREG_MASK);

 kpath = rtw89_phy_get_kpath(rtwdev, phy);
 synpath = rtw89_phy_get_syn_sel(rtwdev, phy);

 rf18 = rtw89_read_rf(rtwdev, synpath, RR_CFGCH, RFREG_MASK);
 if (rf18 == INV_RF_DATA) {
  rtw89_warn(rtwdev, "[RFK] Invalid RF18 value\n");
  return;
 }

 for (path = 0; path < RF_PATH_NUM_8922A; path++) {
  if (!(kpath & BIT(path)))
   continue;

  for (i = 0; i < 2; i++) {
   if (rf_reg[path][i] == INV_RF_DATA) {
    rtw89_warn(rtwdev,
        "[RFK] Invalid RF_0x18 for Path-%d\n", path);
    return;
   }

   rf_reg[path][i] &= ~(RR_CFGCH_BAND1 | RR_CFGCH_BW_V2 |
          RR_CFGCH_BAND0 | RR_CFGCH_CH);
   rf_reg[path][i] |= rtw89_chip_chan_to_rf18_val(rtwdev, chan);

   rtw89_write_rf(rtwdev, path, rf_addr[i],
           RFREG_MASK, rf_reg[path][i]);
   fsleep(100);
  }
 }

 if (hal->cv != CHIP_CAV)
  return;

 if (chan->band_type == RTW89_BAND_2G) {
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x80000);
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x00003);
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD1, RFREG_MASK, 0x0c990);
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0xebe38);
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x00000);
 } else {
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x80000);
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x00003);
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD1, RFREG_MASK, 0x0c190);
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0xebe38);
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x00000);
 }
}

void rtw8922a_set_channel_rf(struct rtw89_dev *rtwdev,
        const struct rtw89_chan *chan,
        enum rtw89_phy_idx phy_idx)
{
 rtw8922a_ctl_band_ch_bw(rtwdev, phy_idx, chan);
}

enum _rf_syn_pow {
 RF_SYN_ON_OFF,
 RF_SYN_OFF_ON,
 RF_SYN_ALLON,
 RF_SYN_ALLOFF,
};

static void rtw8922a_set_syn01_cav(struct rtw89_dev *rtwdev, enum _rf_syn_pow syn)
{
 if (syn == RF_SYN_ALLON) {
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3);
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x2);
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3);

  rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x3);
  rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x2);
  rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x3);
 } else if (syn == RF_SYN_ON_OFF) {
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3);
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x2);
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3);

  rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x0);
 } else if (syn == RF_SYN_OFF_ON) {
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x0);

  rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x3);
  rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x2);
  rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x3);
 } else if (syn == RF_SYN_ALLOFF) {
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x0);
  rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x0);
 }
}

static void rtw8922a_set_syn01_cbv(struct rtw89_dev *rtwdev, enum _rf_syn_pow syn)
{
 if (syn == RF_SYN_ALLON) {
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0xf);
  rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0xf);
 } else if (syn == RF_SYN_ON_OFF) {
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0xf);
  rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0x0);
 } else if (syn == RF_SYN_OFF_ON) {
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0x0);
  rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0xf);
 } else if (syn == RF_SYN_ALLOFF) {
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0x0);
  rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0x0);
 }
}

static void rtw8922a_set_syn01(struct rtw89_dev *rtwdev, enum _rf_syn_pow syn)
{
 struct rtw89_hal *hal = &rtwdev->hal;

 rtw89_debug(rtwdev, RTW89_DBG_RFK, "SYN config=%d\n", syn);

 if (hal->cv == CHIP_CAV)
  rtw8922a_set_syn01_cav(rtwdev, syn);
 else
  rtw8922a_set_syn01_cbv(rtwdev, syn);
}

static void rtw8922a_chlk_ktbl_sel(struct rtw89_dev *rtwdev, u8 kpath, u8 idx)
{
 u32 tmp;

 if (idx > 2) {
  rtw89_warn(rtwdev, "[DBCC][ERROR]indx is out of limit!! index(%d)", idx);
  return;
 }

 if (kpath & RF_A) {
  rtw89_phy_write32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_EN, 0x1);
  rtw89_phy_write32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_IQC_V1, idx);
  rtw89_phy_write32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_MDPD_V1, idx);
  rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RR_TXG_SEL, 0x4 | idx);

  tmp = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL, BIT(0));
  rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, tmp);
  tmp = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL, BIT(1));
  rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G5, tmp);
 }

 if (kpath & RF_B) {
  rtw89_phy_write32_mask(rtwdev, R_COEF_SEL_C1, B_COEF_SEL_EN, 0x1);
  rtw89_phy_write32_mask(rtwdev, R_COEF_SEL_C1, B_COEF_SEL_IQC_V1, idx);
  rtw89_phy_write32_mask(rtwdev, R_COEF_SEL_C1, B_COEF_SEL_MDPD_V1, idx);
  rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RR_TXG_SEL, 0x4 | idx);

  tmp = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL_C1, BIT(0));
  rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT_C1, B_CFIR_LUT_G3, tmp);
  tmp = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL_C1, BIT(1));
  rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT_C1, B_CFIR_LUT_G5, tmp);
 }
}

static u8 rtw8922a_chlk_reload_sel_tbl(struct rtw89_dev *rtwdev,
           const struct rtw89_chan *chan, u8 path)
{
 struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
 struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V1] = {};
 u8 tbl_sel;

 for (tbl_sel = 0; tbl_sel < ARRAY_SIZE(desc); tbl_sel++) {
  struct rtw89_rfk_chan_desc *p = &desc[tbl_sel];

  p->ch = rfk_mcc->data[path].ch[tbl_sel];

  p->has_band = true;
  p->band = rfk_mcc->data[path].band[tbl_sel];

  p->has_bw = true;
  p->bw = rfk_mcc->data[path].bw[tbl_sel];
 }

 tbl_sel = rtw89_rfk_chan_lookup(rtwdev, desc, ARRAY_SIZE(desc), chan);

 rfk_mcc->data[path].ch[tbl_sel] = chan->channel;
 rfk_mcc->data[path].band[tbl_sel] = chan->band_type;
 rfk_mcc->data[path].bw[tbl_sel] = chan->band_width;
 rfk_mcc->data[path].table_idx = tbl_sel;

 return tbl_sel;
}

static void rtw8922a_chlk_reload(struct rtw89_dev *rtwdev)
{
 const struct rtw89_chan *chan0, *chan1;
 u8 s0_tbl, s1_tbl;

 switch (rtwdev->mlo_dbcc_mode) {
 default:
 case MLO_2_PLUS_0_1RF:
  chan0 = rtw89_mgnt_chan_get(rtwdev, 0);
  chan1 = chan0;
  break;
 case MLO_0_PLUS_2_1RF:
  chan1 = rtw89_mgnt_chan_get(rtwdev, 1);
  chan0 = chan1;
  break;
 case MLO_1_PLUS_1_1RF:
  chan0 = rtw89_mgnt_chan_get(rtwdev, 0);
  chan1 = rtw89_mgnt_chan_get(rtwdev, 1);
  break;
 }

 s0_tbl = rtw8922a_chlk_reload_sel_tbl(rtwdev, chan0, 0);
 s1_tbl = rtw8922a_chlk_reload_sel_tbl(rtwdev, chan1, 1);

 rtw8922a_chlk_ktbl_sel(rtwdev, RF_A, s0_tbl);
 rtw8922a_chlk_ktbl_sel(rtwdev, RF_B, s1_tbl);
}

static void rtw8922a_rfk_mlo_ctrl(struct rtw89_dev *rtwdev)
{
 enum _rf_syn_pow syn_pow;

 if (!rtwdev->dbcc_en)
  goto set_rfk_reload;

 switch (rtwdev->mlo_dbcc_mode) {
 case MLO_0_PLUS_2_1RF:
  syn_pow = RF_SYN_OFF_ON;
  break;
 case MLO_0_PLUS_2_2RF:
 case MLO_1_PLUS_1_2RF:
 case MLO_2_PLUS_0_1RF:
 case MLO_2_PLUS_0_2RF:
 case MLO_2_PLUS_2_2RF:
 case MLO_DBCC_NOT_SUPPORT:
 default:
  syn_pow = RF_SYN_ON_OFF;
  break;
 case MLO_1_PLUS_1_1RF:
 case DBCC_LEGACY:
  syn_pow = RF_SYN_ALLON;
  break;
 }

 rtw8922a_set_syn01(rtwdev, syn_pow);

set_rfk_reload:
 rtw8922a_chlk_reload(rtwdev);
}

static void rtw8922a_rfk_pll_init(struct rtw89_dev *rtwdev)
{
 int ret;
 u8 tmp;

 ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_PLL_1, &tmp);
 if (ret)
  return;
 ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL_1, tmp | 0xf8, 0xFF);
 if (ret)
  return;

 ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_APBT, &tmp);
 if (ret)
  return;
 ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_APBT, tmp & ~0x60, 0xFF);
 if (ret)
  return;

 ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_XTAL_PLL, &tmp);
 if (ret)
  return;
 ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_PLL, tmp | 0x38, 0xFF);
 if (ret)
  return;
}

void rtw8922a_rfk_hw_init(struct rtw89_dev *rtwdev)
{
 if (rtwdev->dbcc_en)
  rtw8922a_rfk_mlo_ctrl(rtwdev);

 rtw8922a_rfk_pll_init(rtwdev);
}

void rtw8922a_pre_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
{
 bool mlo_1_1;

 if (!rtwdev->dbcc_en)
  return;

 mlo_1_1 = rtw89_is_mlo_1_1(rtwdev);
 if (mlo_1_1)
  rtw8922a_set_syn01(rtwdev, RF_SYN_ALLON);
 else if (phy_idx == RTW89_PHY_0)
  rtw8922a_set_syn01(rtwdev, RF_SYN_ON_OFF);
 else
  rtw8922a_set_syn01(rtwdev, RF_SYN_OFF_ON);

 fsleep(1000);
}

void rtw8922a_post_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
{
 rtw8922a_rfk_mlo_ctrl(rtwdev);
}

Messung V0.5
C=100 H=96 G=97

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.