Search Linux Wireless

RE: [PATCH 18/20] wifi: rtw88: Add rtw8821a.{c,h}

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Bitterblue Smith <rtl8821cerfe2@xxxxxxxxx> wrote:
> These contain all the logic for the RTL8821AU and RTL8812AU chips.
> 
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@xxxxxxxxx>
> ---
>  drivers/net/wireless/realtek/rtw88/rtw8821a.c | 4139 +++++++++++++++++
>  drivers/net/wireless/realtek/rtw88/rtw8821a.h |  385 ++
>  2 files changed, 4524 insertions(+)
>  create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a.c
>  create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a.h
> 
> diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a.c
> b/drivers/net/wireless/realtek/rtw88/rtw8821a.c
> new file mode 100644
> index 000000000000..e72599db74ed
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.c
> @@ -0,0 +1,4139 @@
> +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
> +/* Copyright(c) 2018-2019  Realtek Corporation

Year 2024

[...]

> +static void rtw8812a_config_1t(struct rtw_dev *rtwdev)
> +{
> +       /* BB OFDM RX Path_A */
> +       rtw_write32_mask(rtwdev, REG_RXPSEL, 0xff, 0x11);
> +
> +       /* BB OFDM TX Path_A */
> +       rtw_write32_mask(rtwdev, REG_TXPSEL, MASKLWORD, 0x1111);
> +
> +       /* BB CCK R/Rx Path_A */
> +       rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0c000000, 0x0);
> +
> +       /* MCS support */
> +       rtw_write32_mask(rtwdev, 0x8bc, 0xc0000060, 0x4);

#define REG_RX_MCS_LIMIT 0x8bc

The setting value is weird to me though. 

> +
> +       /* RF Path_B HSSI OFF */
> +       rtw_write32_mask(rtwdev, 0xe00, 0xf, 0x4);

#define REG_HSSI_WRITE_B 	0xe00

> +
> +       /* RF Path_B Power Down */
> +       rtw_write32_mask(rtwdev, REG_LSSI_WRITE_B, MASKDWORD, 0);
> +
> +       /* ADDA Path_B OFF */
> +       rtw_write32_mask(rtwdev, REG_AFE_PWR1_B, MASKDWORD, 0);
> +       rtw_write32_mask(rtwdev, REG_AFE_PWR2_B, MASKDWORD, 0);
> +}

[...]


> +
> +static u8 rtw8821a_get_swing_index(struct rtw_dev *rtwdev)
> +{
> +       u32 swing, table_value;
> +       u8 i = 0;

no need '= 0'

> +
> +       swing = rtw8821a_get_bb_swing(rtwdev, rtwdev->hal.current_band_type,
> +                                     RF_PATH_A);
> +
> +       for (i = 0; i < ARRAY_SIZE(rtw8821a_txscale_tbl); i++) {
> +               table_value = rtw8821a_txscale_tbl[i];
> +               if (swing == table_value)
> +                       break;

return i;

> +       }
> +
> +       return i;

return ARRAY_SIZE(rtw8821a_txscale_tbl)?  (but I don't like it so much)

or

return 24;

Move checking statement from callers to here. 

> +}
> +
> +static void rtw8821a_pwrtrack_init(struct rtw_dev *rtwdev)
> +{
> +       struct rtw_dm_info *dm_info = &rtwdev->dm_info;
> +       u8 ofdm_swing_idx;
> +       u8 path;
> +
> +       ofdm_swing_idx = rtw8821a_get_swing_index(rtwdev);
> +
> +       if (ofdm_swing_idx >= ARRAY_SIZE(rtw8821a_txscale_tbl))
> +               dm_info->default_ofdm_index = 24;
> +       else
> +               dm_info->default_ofdm_index = ofdm_swing_idx;

If rtw8821a_get_swing_index(rtwdev) returns 24 for the case we can't find a 
match from rtw8821a_txscale_tbl[], here can be simply

    dm_info->default_ofdm_index = rtw8821a_get_swing_index(rtwdev);


> +
> +       if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A)
> +               dm_info->default_cck_index = 0;
> +       else
> +               dm_info->default_cck_index = 24;
> +
> +       for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) {
> +               ewma_thermal_init(&dm_info->avg_thermal[path]);
> +               dm_info->delta_power_index[path] = 0;
> +               dm_info->delta_power_index_last[path] = 0;
> +       }
> +
> +       dm_info->pwr_trk_triggered = false;
> +       dm_info->pwr_trk_init_trigger = true;
> +       dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k;
> +}
> +

[...]

> +static int rtw8821a_power_on(struct rtw_dev *rtwdev)
> +{

Will the coming RTL8814AU share this flow? If so, we can move this power on
to main.c/mac.c as rtw_power_on_v1() or something else. 

If we decide moving power on flow into chip specific files, the duplicate code
will become more and more. Please think about this. 


> +       struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
> +       const struct rtw_chip_info *chip = rtwdev->chip;
> +       struct rtw_efuse *efuse = &rtwdev->efuse;
> +       struct rtw_hal *hal = &rtwdev->hal;
> +       int ret;
> +
> +       if (test_bit(RTW_FLAG_POWERON, rtwdev->flags))
> +               return 0;
> +
> +       /* Override rtw_chip_efuse_info_setup() */
> +       if (chip->id == RTW_CHIP_TYPE_8821A)
> +               efuse->btcoex = rtw_read32_mask(rtwdev, REG_WL_BT_PWR_CTRL,
> +                                               BIT_BT_FUNC_EN);
> +
> +       /* Override rtw_chip_efuse_info_setup() */
> +       if (chip->id == RTW_CHIP_TYPE_8812A)
> +               rtw8812a_read_amplifier_type(rtwdev);
> +
> +       ret = rtw_hci_setup(rtwdev);
> +       if (ret) {
> +               rtw_err(rtwdev, "failed to setup hci\n");
> +               goto err;
> +       }
> +
> +       /* Revise for U2/U3 switch we can not update RF-A/B reset.
> +        * Reset after MAC power on to prevent RF R/W error.
> +        * Is it a right method?
> +        */
> +       if (chip->id == RTW_CHIP_TYPE_8812A) {
> +               rtw_write8(rtwdev, REG_RF_CTRL, 5);
> +               rtw_write8(rtwdev, REG_RF_CTRL, 7);
> +               rtw_write8(rtwdev, REG_RF_B_CTRL, 5);
> +               rtw_write8(rtwdev, REG_RF_B_CTRL, 7);
> +       }
> +
> +       /* If HW didn't go through a complete de-initial procedure,
> +        * it probably occurs some problem for double initial
> +        * procedure.
> +        */
> +       rtw8812au_hw_reset(rtwdev);
> +
> +       ret = rtw8812au_init_power_on(rtwdev);
> +       if (ret) {
> +               rtw_err(rtwdev, "failed to power on\n");
> +               goto err;
> +       }
> +
> +       ret = rtw_set_trx_fifo_info(rtwdev);
> +       if (ret) {
> +               rtw_err(rtwdev, "failed to set trx fifo info\n");
> +               goto err;
> +       }
> +
> +       ret = rtw8821a_llt_init(rtwdev, rtwdev->fifo.rsvd_boundary);
> +       if (ret) {
> +               rtw_err(rtwdev, "failed to init llt\n");
> +               goto err;
> +       }
> +
> +       rtw_write32_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN);
> +
> +       ret = rtw_wait_firmware_completion(rtwdev);
> +       if (ret) {
> +               rtw_err(rtwdev, "failed to wait firmware completion\n");
> +               goto err_off;
> +       }
> +
> +       ret = rtw_download_firmware(rtwdev, &rtwdev->fw);
> +       if (ret) {
> +               rtw_err(rtwdev, "failed to download firmware\n");
> +               goto err_off;
> +       }
> +
> +       rtw_write8(rtwdev, REG_HMETFR, 0xf);
> +
> +       rtw_load_table(rtwdev, chip->mac_tbl);
> +
> +       rtw8821au_init_queue_reserved_page(rtwdev);
> +       rtw8821au_init_tx_buffer_boundary(rtwdev);
> +       rtw8821au_init_queue_priority(rtwdev);
> +

Seemingly above flow looks common. Can it share with other chips?

[...]

> +}
> +
> +static u32 rtw8821a_phy_read_rf(struct rtw_dev *rtwdev,
> +                               enum rtw_rf_path rf_path, u32 addr, u32 mask)
> +{

read/write RF functions are also common for chips. Can it share with coming RTL8814A?
Move this to phy.c as v1?

> +       static const u32 pi_addr[2] = { 0xc00, 0xe00 };
> +       static const u32 read_addr[2][2] = {
> +               { REG_SI_READ_A, REG_SI_READ_B },
> +               { REG_PI_READ_A, REG_PI_READ_B }
> +       };

[...]

> +
> +static void rtw8821a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
> +                                     struct rtw_rx_pkt_stat *pkt_stat)
> +{
> +       struct rtw_dm_info *dm_info = &rtwdev->dm_info;
> +       struct rtw8821a_phy_status_rpt *phy_sts;
> +       u8 lna_idx, vga_idx, cck_agc_rpt;
> +       s8 rx_pwr_db, power_a, power_b;
> +       const s8 min_rx_power = -120;
> +       u8 rssi, val, i;
> +
> +       phy_sts = (struct rtw8821a_phy_status_rpt *)phy_status;
> +
> +       if (pkt_stat->rate <= DESC_RATE11M) {
> +               cck_agc_rpt = phy_sts->cfosho[0];
> +               lna_idx = (cck_agc_rpt & 0xE0) >> 5;
> +               vga_idx = cck_agc_rpt & 0x1F;

If we remove "#ifdef __LITTLE_ENDIAN" from rtw8821a_phy_status_rpt and define
bit mask there, additionally define these bit masks and then use u8_get_bits().

By the way, shouldn't the field of 'cfosho[2]' be 'u8' instead of 's8'?

> +
> +               if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A)
> +                       rx_pwr_db = rtw8821a_cck_rx_pwr(rtwdev, lna_idx, vga_idx);
> +               else
> +                       rx_pwr_db = rtw8812a_cck_rx_pwr(rtwdev, lna_idx, vga_idx);
> +
> +               pkt_stat->rx_power[RF_PATH_A] = rx_pwr_db;
> +               pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
> +               dm_info->rssi[RF_PATH_A] = pkt_stat->rssi;
> +               pkt_stat->bw = RTW_CHANNEL_WIDTH_20;
> +               pkt_stat->signal_power = rx_pwr_db;
> +
> +               if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A &&
> +                   !rtwdev->hal.cck_high_power) {
> +                       if (pkt_stat->rssi >= 80)
> +                               pkt_stat->rssi = ((pkt_stat->rssi - 80) << 1) +
> +                                                ((pkt_stat->rssi - 80) >> 1) + 80;
> +                       else if (pkt_stat->rssi <= 78 && pkt_stat->rssi >= 20)
> +                               pkt_stat->rssi += 3;
> +               }
> +       } else { /* OFDM rate */
> +               for (i = RF_PATH_A; i < rtwdev->hal.rf_path_num; i++) {
> +                       val = phy_sts->gain_trsw[i];
> +                       pkt_stat->rx_power[i] = (val & 0x7F) - 110;
> +                       rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[i], 1);
> +                       dm_info->rssi[i] = rssi;
> +               }
> +
> +               pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power,
> +                                                        rtwdev->hal.rf_path_num);
> +
> +               power_a = pkt_stat->rx_power[RF_PATH_A];
> +               power_b = pkt_stat->rx_power[RF_PATH_B];
> +               if (rtwdev->hal.rf_path_num == 1)
> +                       power_b = power_a;
> +
> +               pkt_stat->signal_power = max3(power_a, power_b, min_rx_power);
> +       }
> +}
> +
> +static void rtw8821a_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
> +                                  struct rtw_rx_pkt_stat *pkt_stat,
> +                                  struct ieee80211_rx_status *rx_status)
> +{
> +       u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
> +       struct ieee80211_hdr *hdr;
> +       u8 *phy_status = NULL;
> +
> +       memset(pkt_stat, 0, sizeof(*pkt_stat));
> +
> +       pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
> +       pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
> +       pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
> +       pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
> +                             GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
> +       pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
> +       pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
> +       pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
> +       pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
> +       pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
> +       pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
> +       pkt_stat->ppdu_cnt = 0;
> +       pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
> +       pkt_stat->bw = GET_RX_DESC_BW(rx_desc);

More and more chips use these macros. Please add a patch using struct to 
access these fields. More, query_rx_desc() are very similar across chips,
please move them to mac.c or phy.c as a common function.

> +
> +       /* drv_info_sz is in unit of 8-bytes */
> +       pkt_stat->drv_info_sz *= 8;
> +
> +       /* c2h cmd pkt's rx/phy status is not interested */
> +       if (pkt_stat->is_c2h)
> +               return;
> +
> +       hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
> +                                      pkt_stat->drv_info_sz);
> +       if (pkt_stat->phy_status) {
> +               phy_status = rx_desc + desc_sz + pkt_stat->shift;
> +               rtw8821a_query_phy_status(rtwdev, phy_status, pkt_stat);
> +       }
> +
> +       rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
> +}
> +

[...]

> +
> +static void rtw8821a_false_alarm_statistics(struct rtw_dev *rtwdev)
> +{
> +       struct rtw_dm_info *dm_info = &rtwdev->dm_info;
> +       u32 cck_fa_cnt, ofdm_fa_cnt;
> +       u32 crc32_cnt, cca32_cnt;
> +       u32 cck_enable;
> +
> +       cck_enable = rtw_read32(rtwdev, REG_RXPSEL) & BIT(28);
> +       cck_fa_cnt = rtw_read16(rtwdev, REG_FA_CCK);
> +       ofdm_fa_cnt = rtw_read16(rtwdev, REG_FA_OFDM);
> +
> +       dm_info->cck_fa_cnt = cck_fa_cnt;
> +       dm_info->ofdm_fa_cnt = ofdm_fa_cnt;
> +       dm_info->total_fa_cnt = ofdm_fa_cnt;
> +       if (cck_enable)
> +               dm_info->total_fa_cnt += cck_fa_cnt;
> +
> +       crc32_cnt = rtw_read32(rtwdev, REG_CRC_CCK);
> +       dm_info->cck_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt);
> +       dm_info->cck_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt);

use u32_get_bits() instead.

> +
> +       crc32_cnt = rtw_read32(rtwdev, REG_CRC_OFDM);
> +       dm_info->ofdm_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt);
> +       dm_info->ofdm_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt);
> +
> +       crc32_cnt = rtw_read32(rtwdev, REG_CRC_HT);
> +       dm_info->ht_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt);
> +       dm_info->ht_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt);
> +
> +       crc32_cnt = rtw_read32(rtwdev, REG_CRC_VHT);
> +       dm_info->vht_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt);
> +       dm_info->vht_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt);
> +
> +       cca32_cnt = rtw_read32(rtwdev, REG_CCA_OFDM);
> +       dm_info->ofdm_cca_cnt = FIELD_GET(GENMASK(31, 16), cca32_cnt);
> +       dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt;
> +       if (cck_enable) {
> +               cca32_cnt = rtw_read32(rtwdev, REG_CCA_CCK);
> +               dm_info->cck_cca_cnt = FIELD_GET(GENMASK(15, 0), cca32_cnt);
> +               dm_info->total_cca_cnt += dm_info->cck_cca_cnt;
> +       }
> +
> +       rtw_write32_set(rtwdev, REG_FAS, BIT(17));
> +       rtw_write32_clr(rtwdev, REG_FAS, BIT(17));
> +       rtw_write32_clr(rtwdev, REG_RXDESC, BIT(15));
> +       rtw_write32_set(rtwdev, REG_RXDESC, BIT(15));
> +       rtw_write32_set(rtwdev, REG_CNTRST, BIT(0));
> +       rtw_write32_clr(rtwdev, REG_CNTRST, BIT(0));
> +}
> +

[...]

> +
> +static void rtw8821a_iqk_restore_afe(struct rtw_dev *rtwdev, u32 *afe_backup,
> +                                    const u32 *backup_afe_reg, u32 afe_num)
> +{
> +       u32 i;
> +
> +       /* [31] = 0 --> Page C */
> +       rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
> +
> +       /* Reload AFE Parameters */
> +       for (i = 0; i < afe_num; i++)
> +               rtw_write32(rtwdev, backup_afe_reg[i], afe_backup[i]);
> +
> +       /* [31] = 1 --> Page C1 */
> +       rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
> +
> +       rtw_write32(rtwdev, 0xc80, 0x0);
> +       rtw_write32(rtwdev, 0xc84, 0x0);
> +       rtw_write32(rtwdev, 0xc88, 0x0);
> +       rtw_write32(rtwdev, 0xc8c, 0x3c000000);
> +       rtw_write32(rtwdev, REG_LSSI_WRITE_A, 0x00000080);
> +       rtw_write32(rtwdev, 0xc94, 0x00000000);
> +       rtw_write32(rtwdev, 0xcc4, 0x20040000);
> +       rtw_write32(rtwdev, 0xcc8, 0x20000000);
> +       rtw_write32(rtwdev, REG_RFECTL_A, 0x0);

I think we can reuse existing definitions:

rtw8723x.h:#define REG_OFDM_0_XA_TX_IQ_IMBALANCE        0x0c80
rtw8703b.h:#define REG_OFDM0_A_TX_AFE 0x0c84
rtw8723x.h:#define REG_OFDM_0_XB_TX_IQ_IMBALANCE        0x0c88

#define REG_TSSI_TRK_SW 0xc8c

rtw8821a.h:#define REG_TXAGCIDX                         0xc94

#define REG_IQK_DPD_CFG 0xcc4
#define REG_CFG_PMPD 0xcc8

[...]

> +
> +static void rtw8821a_iqk_tx_fill(struct rtw_dev *rtwdev,
> +                                unsigned int tx_x, unsigned int tx_y)
> +{
> +       /* [31] = 1 --> Page C1 */
> +       rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
> +
> +       rtw_write32(rtwdev, REG_LSSI_WRITE_A, 0x00000080);
> +       rtw_write32(rtwdev, 0xcc4, 0x20040000);
> +       rtw_write32(rtwdev, 0xcc8, 0x20000000);
> +       rtw_write32_mask(rtwdev, 0xccc, 0x000007ff, tx_y);
> +       rtw_write32_mask(rtwdev, 0xcd4, 0x000007ff, tx_x);

#define REG_IQC_Y 0xccc
#define REG_IQC_X 0xcd4

> +}
> +
> +static void rtw8821a_iqk_tx_vdf_true(struct rtw_dev *rtwdev, u32 cal,
> +                                    bool *tx0iqkok,
> +                                    int tx_x0[CAL_NUM_8821A],
> +                                    int tx_y0[CAL_NUM_8821A])
> +{
> +       u32 cal_retry, delay_count, iqk_ready, tx_fail;
> +       int tx_dt[3], vdf_y[3], vdf_x[3];
> +       int k;
> +
> +       for (k = 0; k <= 2; k++) {

'< 3' would be more intuitive, because 'k' is index of array.

> +               switch (k) {
> +               case 0:
> +                       /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
> +                       rtw_write32(rtwdev, 0xc80, 0x18008c38);
> +                       /* RX_Tone_idx[9:0], RxK_Mask[29] */
> +                       rtw_write32(rtwdev, 0xc84, 0x38008c38);
> +                       rtw_write32_mask(rtwdev, 0xce8, BIT(31), 0x0);
> +                       break;
> +               case 1:
> +                       rtw_write32_mask(rtwdev, 0xc80, BIT(28), 0x0);
> +                       rtw_write32_mask(rtwdev, 0xc84, BIT(28), 0x0);
> +                       rtw_write32_mask(rtwdev, 0xce8, BIT(31), 0x0);
> +                       break;
> +               case 2:
> +                       rtw_dbg(rtwdev, RTW_DBG_RFK,
> +                               "vdf_y[1] = %x vdf_y[0] = %x\n",
> +                               vdf_y[1] >> 21 & 0x00007ff,
> +                               vdf_y[0] >> 21 & 0x00007ff);
> +
> +                       rtw_dbg(rtwdev, RTW_DBG_RFK,
> +                               "vdf_x[1] = %x vdf_x[0] = %x\n",
> +                               vdf_x[1] >> 21 & 0x00007ff,
> +                               vdf_x[0] >> 21 & 0x00007ff);
> +
> +                       tx_dt[cal] = (vdf_y[1] >> 20) - (vdf_y[0] >> 20);
> +                       tx_dt[cal] = (16 * tx_dt[cal]) * 10000 / 15708;
> +                       tx_dt[cal] = (tx_dt[cal] >> 1) + (tx_dt[cal] & BIT(0));
> +
> +                       /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
> +                       rtw_write32(rtwdev, 0xc80, 0x18008c20);
> +                       /* RX_Tone_idx[9:0], RxK_Mask[29] */
> +                       rtw_write32(rtwdev, 0xc84, 0x38008c20);
> +                       rtw_write32_mask(rtwdev, 0xce8, BIT(31), 0x1);
> +                       rtw_write32_mask(rtwdev, 0xce8, 0x3fff0000,
> +                                        tx_dt[cal] & 0x00003fff);
> +                       break;
> +               }
> +
> +               rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);
> +               cal_retry = 0;
> +               while (1) {

Can we replace 'while()' by 'for (cal_retry = 0; cal_retry < 10; cal_retry++)'?

> +                       /* one shot */
> +                       rtw_write32(rtwdev, 0x980, 0xfa000000);
> +                       rtw_write32(rtwdev, 0x980, 0xf8000000);
> +
> +                       mdelay(10);
> +
> +                       rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
> +
> +                       delay_count = 0;
> +                       while (1) {

Similarly. 'for (delay_count = 0; delay_count < 20; delay_count++)'.

> +                               iqk_ready = rtw_read32_mask(rtwdev, 0xd00, BIT(10));
> +
> +                               /* Originally: if (~iqk_ready || delay_count > 20)
> +                                * that looks like a typo so make it more explicit
> +                                */
> +                               iqk_ready = true;
> +
> +                               if (iqk_ready || delay_count > 20)
> +                                       break;
> +
> +                               mdelay(1);
> +                               delay_count++;
> +                       }
> +
> +                       if (delay_count < 20) {
> +                               /* ============TXIQK Check============== */
> +                               tx_fail = rtw_read32_mask(rtwdev, 0xd00, BIT(12));
> +
> +                               /* Originally: if (~tx_fail) {
> +                                * It looks like a typo, so make it more explicit.
> +                                */
> +                               tx_fail = false;
> +
> +                               if (!tx_fail) {
> +                                       rtw_write32(rtwdev, REG_RFECTL_A,
> +                                                   0x02000000);
> +                                       vdf_x[k] = rtw_read32_mask(rtwdev, 0xd00,
> +                                                                  0x07ff0000);
> +                                       vdf_x[k] <<= 21;
> +
> +                                       rtw_write32(rtwdev, REG_RFECTL_A,
> +                                                   0x04000000);
> +                                       vdf_y[k] = rtw_read32_mask(rtwdev, 0xd00,
> +                                                                  0x07ff0000);
> +                                       vdf_y[k] <<= 21;
> +
> +                                       *tx0iqkok = true;
> +                                       break;
> +                               }
> +
> +                               rtw_write32_mask(rtwdev, 0xccc, 0x000007ff, 0x0);
> +                               rtw_write32_mask(rtwdev, 0xcd4, 0x000007ff, 0x200);
> +
> +                               *tx0iqkok = false;
> +                               cal_retry++;
> +                               if (cal_retry == 10)
> +                                       break;
> +                       } else { /* If 20ms No Result, then cal_retry++ */
> +                               *tx0iqkok = false;
> +                               cal_retry++;
> +                               if (cal_retry == 10)
> +                                       break;
> +                       }
> +               }
> +       }
> +
> +       if (k == 3) {
> +               tx_x0[cal] = vdf_x[k - 1];
> +               tx_y0[cal] = vdf_y[k - 1];
> +       }
> +}
> +
> +static void rtw8821a_iqk_tx_vdf_false(struct rtw_dev *rtwdev, u32 cal,
> +                                     bool *tx0iqkok,
> +                                     int tx_x0[CAL_NUM_8821A],
> +                                     int tx_y0[CAL_NUM_8821A])
> +{
> +       u32 cal_retry, delay_count, iqk_ready, tx_fail;
> +
> +       /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
> +       rtw_write32(rtwdev, 0xc80, 0x18008c10);
> +       /* RX_Tone_idx[9:0], RxK_Mask[29] */
> +       rtw_write32(rtwdev, 0xc84, 0x38008c10);
> +       rtw_write32(rtwdev, 0xcb8, 0x00100000);
> +
> +       cal_retry = 0;
> +       while (1) {

Ditto. 'for (cal_retry = 0; cal_retry < 10; cal_retry++)'

> +               /* one shot */
> +               rtw_write32(rtwdev, 0x980, 0xfa000000);
> +               rtw_write32(rtwdev, 0x980, 0xf8000000);
> +
> +               mdelay(10);
> +               rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
> +
> +               delay_count = 0;
> +               while (1) {

'for (delay_count = 0; delay_count < 20; delay_count++)'.

> +                       iqk_ready = rtw_read32_mask(rtwdev, 0xd00, BIT(10));
> +
> +                       /* Originally: if (~iqk_ready || delay_count > 20)
> +                        * that looks like a typo so make it more explicit
> +                        */
> +                       iqk_ready = true;
> +
> +                       if (iqk_ready || delay_count > 20)
> +                               break;
> +
> +                       mdelay(1);
> +                       delay_count++;
> +               }
> +
> +               if (delay_count < 20) {
> +                       /* ============TXIQK Check============== */
> +                       tx_fail = rtw_read32_mask(rtwdev, 0xd00, BIT(12));
> +
> +                       /* Originally: if (~tx_fail) {
> +                        * It looks like a typo, so make it more explicit.
> +                        */
> +                       tx_fail = false;
> +
> +                       if (!tx_fail) {
> +                               rtw_write32(rtwdev, REG_RFECTL_A, 0x02000000);
> +                               tx_x0[cal] = rtw_read32_mask(rtwdev, 0xd00,
> +                                                            0x07ff0000);
> +                               tx_x0[cal] <<= 21;
> +
> +                               rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000);
> +                               tx_y0[cal] = rtw_read32_mask(rtwdev, 0xd00,
> +                                                            0x07ff0000);
> +                               tx_y0[cal] <<= 21;
> +
> +                               *tx0iqkok = true;
> +                               break;
> +                       }
> +
> +                       rtw_write32_mask(rtwdev, 0xccc, 0x000007ff, 0x0);
> +                       rtw_write32_mask(rtwdev, 0xcd4, 0x000007ff, 0x200);
> +
> +                       *tx0iqkok = false;
> +                       cal_retry++;
> +                       if (cal_retry == 10)
> +                               break;
> +               } else { /* If 20ms No Result, then cal_retry++ */
> +                       *tx0iqkok = false;
> +                       cal_retry++;
> +                       if (cal_retry == 10)
> +                               break;
> +               }
> +       }
> +}
> +
> +static void rtw8821a_iqk_rx(struct rtw_dev *rtwdev, u32 cal, bool *rx0iqkok,
> +                           int rx_x0[CAL_NUM_8821A],
> +                           int rx_y0[CAL_NUM_8821A])
> +{
> +       u32 cal_retry, delay_count, iqk_ready, rx_fail;
> +
> +       rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);
> +
> +       cal_retry = 0;
> +       while (1) {

'for (cal_retry = 0; cal_retry < 10; cal_retry++)'

> +               /* one shot */
> +               rtw_write32(rtwdev, 0x980, 0xfa000000);
> +               rtw_write32(rtwdev, 0x980, 0xf8000000);
> +
> +               mdelay(10);
> +
> +               rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
> +
> +               delay_count = 0;
> +               while (1) {

'for (delay_count = 0; delay_count < 20; delay_count++)'.

> +                       iqk_ready = rtw_read32_mask(rtwdev, 0xd00, BIT(10));
> +
> +                       /* Originally: if (~iqk_ready || delay_count > 20)
> +                        * that looks like a typo so make it more explicit
> +                        */
> +                       iqk_ready = true;
> +
> +                       if (iqk_ready || delay_count > 20)
> +                               break;
> +
> +                       mdelay(1);
> +                       delay_count++;
> +               }
> +
> +               if (delay_count < 20) {
> +                       /* ============RXIQK Check============== */
> +                       rx_fail = rtw_read32_mask(rtwdev, 0xd00, BIT(11));
> +                       if (!rx_fail) {
> +                               rtw_write32(rtwdev, REG_RFECTL_A, 0x06000000);
> +                               rx_x0[cal] = rtw_read32_mask(rtwdev, 0xd00,
> +                                                            0x07ff0000);
> +                               rx_x0[cal] <<= 21;
> +
> +                               rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000);
> +                               rx_y0[cal] = rtw_read32_mask(rtwdev, 0xd00,
> +                                                            0x07ff0000);
> +                               rx_y0[cal] <<= 21;
> +
> +                               *rx0iqkok = true;
> +                               break;
> +                       }
> +
> +                       rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,
> +                                        0x000003ff, 0x200 >> 1);
> +                       rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,
> +                                        0x03ff0000, 0x0 >> 1);
> +
> +                       *rx0iqkok = false;
> +                       cal_retry++;
> +                       if (cal_retry == 10)
> +                               break;
> +               } else { /* If 20ms No Result, then cal_retry++ */
> +                       *rx0iqkok = false;
> +                       cal_retry++;
> +                       if (cal_retry == 10)
> +                               break;
> +               }
> +       }
> +}
> +
> +static bool rtw8821a_iqk_finish(int average, int threshold,
> +                               int *x_temp, int *y_temp, int *x, int *y,
> +                               bool break_inner, bool break_outer)
> +{
> +       bool finish = false;
> +       int i, ii, dx, dy;
> +
> +       for (i = 0; i < average; i++) {
> +               for (ii = i + 1; ii < average; ii++) {
> +                       dx = abs_diff(x_temp[i] >> 21, x_temp[ii] >> 21);
> +                       dy = abs_diff(y_temp[i] >> 21, y_temp[ii] >> 21);
> +
> +                       if (dx < threshold && dy < threshold) {
> +                               *x = ((x_temp[i] >> 21) + (x_temp[ii] >> 21));
> +                               *y = ((y_temp[i] >> 21) + (y_temp[ii] >> 21));
> +
> +                               *x /= 2;
> +                               *y /= 2;
> +
> +                               finish = true;
> +
> +                               if (break_inner)
> +                                       break;
> +                       }
> +               }
> +
> +               if (finish && break_outer)
> +                       break;
> +       }
> +
> +       return finish;
> +}
> +
> +static void rtw8821a_iqk(struct rtw_dev *rtwdev)
> +{
> +       int tx_average = 0, rx_average = 0, rx_iqk_loop = 0;
> +       const struct rtw_efuse *efuse = &rtwdev->efuse;
> +       int tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0;
> +       const struct rtw_hal *hal = &rtwdev->hal;
> +       bool tx0iqkok = false, rx0iqkok = false;
> +       int rx_x_temp = 0, rx_y_temp = 0;
> +       int rx_x0[2][CAL_NUM_8821A];
> +       int rx_y0[2][CAL_NUM_8821A];
> +       int tx_x0[CAL_NUM_8821A];
> +       int tx_y0[CAL_NUM_8821A];
> +       bool rx_finish1 = false;
> +       bool rx_finish2 = false;
> +       bool vdf_enable;
> +       u32 cal = 0;
> +       int i;
> +
> +       rtw_dbg(rtwdev, RTW_DBG_RFK,
> +               "band_width = %d, ext_pa = %d, ext_pa_5g = %d\n",
> +               hal->current_band_width, efuse->ext_pa_2g, efuse->ext_pa_5g);
> +
> +       vdf_enable = hal->current_band_width == RTW_CHANNEL_WIDTH_80;
> +
> +       while (cal < CAL_NUM_8821A) {

for (cal = 0; cal < CAL_NUM_8821A; cal++)

[...]


> +static void rtw8812a_iqk_rx_fill(struct rtw_dev *rtwdev, enum rtw_rf_path path,
> +                                unsigned int rx_x, unsigned int rx_y)
> +{
> +       switch (path) {
> +       case RF_PATH_A: {

no need brace for 'case:'.

> +               /* [31] = 0 --> Page C */
> +               rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
> +               if (rx_x >> 1 >= 0x112 || (rx_y >> 1 >= 0x12 && rx_y >> 1 <= 0x3ee)) {
> +                       rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, 0x000003ff, 0x100);
> +                       rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, 0x03ff0000, 0);
> +               } else {
> +                       rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, 0x000003ff, rx_x >> 1);
> +                       rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, 0x03ff0000, rx_y >> 1);
> +               }
> +               rtw_dbg(rtwdev, RTW_DBG_RFK,
> +                       "rx_x = %x;;rx_y = %x ====>fill to IQC\n",
> +                       rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff);
> +               rtw_dbg(rtwdev, RTW_DBG_RFK, "0xc10 = %x ====>fill to IQC\n",
> +                       rtw_read32(rtwdev, REG_RX_IQC_AB_A));
> +       } break;
> +       case RF_PATH_B: {

ditto.

> +               /* [31] = 0 --> Page C */
> +               rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
> +               if (rx_x >> 1 >= 0x112 || (rx_y >> 1 >= 0x12 && rx_y >> 1 <= 0x3ee)) {
> +                       rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, 0x000003ff, 0x100);
> +                       rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, 0x03ff0000, 0);
> +               } else {
> +                       rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, 0x000003ff, rx_x >> 1);
> +                       rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, 0x03ff0000, rx_y >> 1);
> +               }
> +               rtw_dbg(rtwdev, RTW_DBG_RFK,
> +                       "rx_x = %x;;rx_y = %x ====>fill to IQC\n",
> +                       rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff);
> +               rtw_dbg(rtwdev, RTW_DBG_RFK, "0xe10 = %x====>fill to IQC\n",
> +                       rtw_read32(rtwdev, REG_RX_IQC_AB_B));
> +       } break;
> +       default:
> +               break;
> +       };

no need semicolon 

> +}
> +
> +static void rtw8812a_iqk_tx_fill(struct rtw_dev *rtwdev, enum rtw_rf_path path,
> +                                unsigned int tx_x, unsigned int tx_y)
> +{
> +       switch (path) {
> +       case RF_PATH_A: {

no need brace

> +               /* [31] = 1 --> Page C1 */
> +               rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
> +               rtw_write32_mask(rtwdev, 0xc90, BIT(7), 0x1);
> +               rtw_write32_mask(rtwdev, 0xcc4, BIT(18), 0x1);
> +               rtw_write32_mask(rtwdev, 0xcc4, BIT(29), 0x1);
> +               rtw_write32_mask(rtwdev, 0xcc8, BIT(29), 0x1);
> +               rtw_write32_mask(rtwdev, 0xccc, 0x000007ff, tx_y);
> +               rtw_write32_mask(rtwdev, 0xcd4, 0x000007ff, tx_x);
> +               rtw_dbg(rtwdev, RTW_DBG_RFK,
> +                       "tx_x = %x;;tx_y = %x =====> fill to IQC\n",
> +                       tx_x & 0x000007ff, tx_y & 0x000007ff);
> +               rtw_dbg(rtwdev, RTW_DBG_RFK,
> +                       "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n",
> +                       rtw_read32_mask(rtwdev, 0xcd4, 0x000007ff),
> +                       rtw_read32_mask(rtwdev, 0xccc, 0x000007ff));
> +       } break;
> +       case RF_PATH_B: {

ditto. 

> +               /* [31] = 1 --> Page C1 */
> +               rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
> +               rtw_write32_mask(rtwdev, 0xe90, BIT(7), 0x1);
> +               rtw_write32_mask(rtwdev, 0xec4, BIT(18), 0x1);
> +               rtw_write32_mask(rtwdev, 0xec4, BIT(29), 0x1);
> +               rtw_write32_mask(rtwdev, 0xec8, BIT(29), 0x1);
> +               rtw_write32_mask(rtwdev, 0xecc, 0x000007ff, tx_y);
> +               rtw_write32_mask(rtwdev, 0xed4, 0x000007ff, tx_x);
> +               rtw_dbg(rtwdev, RTW_DBG_RFK,
> +                       "tx_x = %x;;tx_y = %x =====> fill to IQC\n",
> +                       tx_x & 0x000007ff, tx_y & 0x000007ff);
> +               rtw_dbg(rtwdev, RTW_DBG_RFK,
> +                       "0xed4 = %x;;0xecc = %x ====>fill to IQC\n",
> +                       rtw_read32_mask(rtwdev, 0xed4, 0x000007ff),
> +                       rtw_read32_mask(rtwdev, 0xecc, 0x000007ff));
> +       } break;
> +       default:
> +               break;
> +       };

no need semicolon

> +}
> +
> +static void rtw8812a_iqk(struct rtw_dev *rtwdev)
> +{
> +       int tx_x0_temp[10], tx_y0_temp[10], tx_x1_temp[10], tx_y1_temp[10];
> +       int rx_x0_temp[10], rx_y0_temp[10], rx_x1_temp[10], rx_y1_temp[10];
> +       bool iqk0_ready = false, tx0_finish = false, rx0_finish = false;
> +       bool iqk1_ready = false, tx1_finish = false, rx1_finish = false;
> +       u8 tx0_avg = 0, tx1_avg = 0, rx0_avg = 0, rx1_avg = 0;
> +       struct rtw_efuse *efuse = &rtwdev->efuse;
> +       bool tx0_fail = true, rx0_fail = true;
> +       bool tx1_fail = true, rx1_fail = true;
> +       int tx_x0, tx_y0, tx_x1, tx_y1;
> +       int rx_x0, rx_y0, rx_x1, rx_y1;
> +       u8 cal0_retry, cal1_retry;
> +       u8 delay_count;
> +
> +       /* [31] = 0 --> Page C */
> +       rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
> +
> +       /* ========path-A AFE all on======== */
> +       /* Port 0 DAC/ADC on */
> +       rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x77777777);
> +       rtw_write32(rtwdev, REG_AFE_PWR2_A, 0x77777777);
> +
> +       /* Port 1 DAC/ADC on */
> +       rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x77777777);
> +       rtw_write32(rtwdev, REG_AFE_PWR2_B, 0x77777777);
> +
> +       rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_A, 0x19791979);
> +       rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_B, 0x19791979);
> +
> +       /* hardware 3-wire off */
> +       rtw_write32_mask(rtwdev, 0xc00, 0xf, 0x4);
> +       rtw_write32_mask(rtwdev, 0xe00, 0xf, 0x4);
> +
> +       /* DAC/ADC sampling rate (160 MHz) */
> +       rtw_write32_mask(rtwdev, 0xc5c, BIT(26) | BIT(25) | BIT(24), 0x7);
> +       rtw_write32_mask(rtwdev, 0xe5c, BIT(26) | BIT(25) | BIT(24), 0x7);
> +
> +       /* [31] = 0 --> Page C */
> +       rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
> +       /* ====== path A TX IQK RF setting ====== */
> +       rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80002);
> +       rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000);
> +       rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3fffd);
> +       rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe83f);
> +       rtw_write_rf(rtwdev, RF_PATH_A, 0x65, RFREG_MASK, 0x931d5);
> +       rtw_write_rf(rtwdev, RF_PATH_A, 0x8f, RFREG_MASK, 0x8a001);
> +
> +       /* ====== path B TX IQK RF setting ====== */
> +       rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x80002);
> +       rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000);
> +       rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3fffd);
> +       rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe83f);
> +       rtw_write_rf(rtwdev, RF_PATH_B, 0x65, RFREG_MASK, 0x931d5);
> +       rtw_write_rf(rtwdev, RF_PATH_B, 0x8f, RFREG_MASK, 0x8a001);
> +
> +       rtw_write32(rtwdev, 0x90c, 0x00008000);
> +       rtw_write32_mask(rtwdev, 0xc94, BIT(0), 0x1);
> +       rtw_write32_mask(rtwdev, 0xe94, BIT(0), 0x1);
> +       rtw_write32(rtwdev, 0x978, 0x29002000); /* TX (X,Y) */
> +       rtw_write32(rtwdev, 0x97c, 0xa9002000); /* RX (X,Y) */
> +       rtw_write32(rtwdev, 0x984, 0x00462910); /* [0]:AGC_en, [15]:idac_K_Mask */
> +       /* [31] = 1 --> Page C1 */
> +       rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
> +
> +       if (efuse->ext_pa_5g) {
> +               if (efuse->rfe_option == 1) {
> +                       rtw_write32(rtwdev, 0xc88, 0x821403e3);
> +                       rtw_write32(rtwdev, 0xe88, 0x821403e3);
> +               } else {
> +                       rtw_write32(rtwdev, 0xc88, 0x821403f7);
> +                       rtw_write32(rtwdev, 0xe88, 0x821403f7);
> +               }
> +       } else {
> +               rtw_write32(rtwdev, 0xc88, 0x821403f1);
> +               rtw_write32(rtwdev, 0xe88, 0x821403f1);
> +       }
> +
> +       if (rtwdev->hal.current_band_type == RTW_BAND_5G) {
> +               rtw_write32(rtwdev, 0xc8c, 0x68163e96);
> +               rtw_write32(rtwdev, 0xe8c, 0x68163e96);
> +       } else {
> +               rtw_write32(rtwdev, 0xc8c, 0x28163e96);
> +               rtw_write32(rtwdev, 0xe8c, 0x28163e96);
> +
> +               if (efuse->rfe_option == 3) {
> +                       if (efuse->ext_pa_2g)
> +                               rtw_write32(rtwdev, 0xc88, 0x821403e3);
> +                       else
> +                               rtw_write32(rtwdev, 0xc88, 0x821403f7);
> +               }
> +       }
> +
> +       /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
> +       rtw_write32(rtwdev, 0xc80, 0x18008c10);
> +       /* RX_Tone_idx[9:0], RxK_Mask[29] */
> +       rtw_write32(rtwdev, 0xc84, 0x38008c10);
> +       rtw_write32(rtwdev, 0xce8, 0x00000000);
> +       /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
> +       rtw_write32(rtwdev, 0xe80, 0x18008c10);
> +       /* RX_Tone_idx[9:0], RxK_Mask[29] */
> +       rtw_write32(rtwdev, 0xe84, 0x38008c10);
> +       rtw_write32(rtwdev, 0xee8, 0x00000000);
> +
> +       cal0_retry = 0;
> +       cal1_retry = 0;
> +       while (1) {
> +               /* one shot */
> +               rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);
> +               rtw_write32(rtwdev, REG_RFECTL_B, 0x00100000);
> +               rtw_write32(rtwdev, 0x980, 0xfa000000);
> +               rtw_write32(rtwdev, 0x980, 0xf8000000);
> +
> +               mdelay(10);
> +
> +               rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
> +               rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000);
> +
> +               delay_count = 0;
> +               while (1) {

prefer 'for' 

> +                       if (!tx0_finish)
> +                               iqk0_ready = rtw_read32_mask(rtwdev, 0xd00, BIT(10));
> +                       if (!tx1_finish)
> +                               iqk1_ready = rtw_read32_mask(rtwdev, 0xd40, BIT(10));
> +                       if ((iqk0_ready && iqk1_ready) || delay_count > 20)
> +                               break;
> +
> +                       mdelay(1);
> +                       delay_count++;
> +               }
> +
> +               rtw_dbg(rtwdev, RTW_DBG_RFK, "TX delay_count = %d\n",
> +                       delay_count);
> +
> +               if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
> +                       /* ============TXIQK Check============== */
> +                       tx0_fail = rtw_read32_mask(rtwdev, 0xd00, BIT(12));
> +                       tx1_fail = rtw_read32_mask(rtwdev, 0xd40, BIT(12));

Can you collect undefined register addresses? I can try to lookup them in one go. 

[...]

> +
> +#define MACBB_REG_NUM_8812A 9
> +#define AFE_REG_NUM_8812A 12
> +#define RF_REG_NUM_8812A 3
> +
> +static void rtw8812a_do_iqk(struct rtw_dev *rtwdev)
> +{
> +       static const u32 backup_macbb_reg[MACBB_REG_NUM_8812A] = {
> +               0x520, 0x550, 0x808, 0xa04, 0x90c, 0xc00, 0xe00, 0x838, 0x82c
> +       };
> +       static const u32 backup_afe_reg[AFE_REG_NUM_8812A] = {
> +               0xc5c, 0xc60, 0xc64, 0xc68, 0xcb0, 0xcb4,
> +               0xe5c, 0xe60, 0xe64, 0xe68, 0xeb0, 0xeb4
> +       };
> +       static const u32 backup_rf_reg[RF_REG_NUM_8812A] = {
> +               0x65, 0x8f, 0x0
> +       };
> +       u32 macbb_backup[MACBB_REG_NUM_8812A] = {0};
> +       u32 afe_backup[AFE_REG_NUM_8812A] = {0};
> +       u32 rfa_backup[RF_REG_NUM_8812A] = {0};
> +       u32 rfb_backup[RF_REG_NUM_8812A] = {0};

'= {}'


[...]

> +
> +static void rtw8821a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev)
> +{}

Below looks regular. 

static void rtw8821a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev)
{
}

As well as rtw8821a_coex_cfg_gnt_debug() and rtw8821a_coex_cfg_wl_rx_gain()

[...]

> +static struct rtw_hw_reg rtw8821a_dig[] = {

const ?

> +       [0] = { .addr = 0xc50, .mask = 0x7f },
> +       [1] = { .addr = 0xe50, .mask = 0x7f },
> +};
> +
> +static struct rtw_page_table page_table_8821a[] = {

const ?

> +       /* hq_num, nq_num, lq_num, exq_num, gapq_num */
> +       {0, 0, 0, 0, 0},        /* SDIO */
> +       {0, 0, 0, 0, 0},        /* PCI */
> +       {8, 0, 0, 0, 1},        /* 2 bulk out endpoints */
> +       {8, 0, 8, 0, 1},        /* 3 bulk out endpoints */
> +       {8, 0, 8, 4, 1},        /* 4 bulk out endpoints */
> +};
> +
> +static struct rtw_page_table page_table_8812a[] = {

const ?

> +       /* hq_num, nq_num, lq_num, exq_num, gapq_num */
> +       {0, 0, 0, 0, 0},        /* SDIO */
> +       {0, 0, 0, 0, 0},        /* PCI */
> +       {16, 0, 0, 0, 1},       /* 2 bulk out endpoints */
> +       {16, 0, 16, 0, 1},      /* 3 bulk out endpoints */
> +       {16, 0, 16, 0, 1},      /* 4 bulk out endpoints */
> +};
> +
> +static struct rtw_rqpn rqpn_table_8821a[] = {

const ?

> +       {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
> +        RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
> +        RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
> +
> +       {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
> +        RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
> +        RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
> +
> +       {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH,
> +        RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
> +        RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
> +
> +       {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL,
> +        RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
> +        RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
> +
> +       {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
> +        RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
> +        RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
> +};
> +
> +static struct rtw_prioq_addrs prioq_addrs_8821a = {

const?

> +       .prio[RTW_DMA_MAPPING_EXTRA] = {
> +               .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3,
> +       },
> +       .prio[RTW_DMA_MAPPING_LOW] = {
> +               .rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1,
> +       },
> +       .prio[RTW_DMA_MAPPING_NORMAL] = {
> +               .rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1,
> +       },
> +       .prio[RTW_DMA_MAPPING_HIGH] = {
> +               .rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2,
> +       },
> +       .wsize = false,
> +};
> +
> +static struct rtw_chip_ops rtw8821a_ops = {
> +       .power_on               = rtw8821a_power_on,
> +       .power_off              = rtw8821a_power_off,
> +       .phy_set_param          = NULL,
> +       .read_efuse             = rtw8821a_read_efuse,
> +       .query_rx_desc          = rtw8821a_query_rx_desc,
> +       .set_channel            = rtw8821a_set_channel,
> +       .mac_init               = NULL,
> +       .read_rf                = rtw8821a_phy_read_rf,
> +       .write_rf               = rtw_phy_write_rf_reg_sipi,
> +       .set_antenna            = NULL,
> +       .set_tx_power_index     = rtw8821a_set_tx_power_index,
> +       .cfg_ldo25              = rtw8821a_cfg_ldo25,
> +       .efuse_grant            = rtw8821a_efuse_grant,
> +       .false_alarm_statistics = rtw8821a_false_alarm_statistics,
> +       .phy_calibration        = rtw8821a_phy_calibration,
> +       .cck_pd_set             = rtw8821a_phy_cck_pd_set,
> +       .pwr_track              = rtw8821a_pwr_track,
> +       .config_bfee            = NULL,
> +       .set_gid_table          = NULL,
> +       .cfg_csi_rate           = NULL,
> +       .fill_txdesc_checksum   = rtw8821a_fill_txdesc_checksum,
> +       .coex_set_init          = rtw8821a_coex_cfg_init,
> +       .coex_set_ant_switch    = rtw8821a_coex_cfg_ant_switch,
> +       .coex_set_gnt_fix       = rtw8821a_coex_cfg_gnt_fix,
> +       .coex_set_gnt_debug     = rtw8821a_coex_cfg_gnt_debug,
> +       .coex_set_rfe_type      = rtw8821a_coex_cfg_rfe_type,
> +       .coex_set_wl_tx_power   = rtw8821a_coex_cfg_wl_tx_power,
> +       .coex_set_wl_rx_gain    = rtw8821a_coex_cfg_wl_rx_gain,
> +};
> +

[...]

> +
> +const struct rtw_chip_info rtw8812a_hw_spec = {

Is it possible moving 8812a to individual file?
Since you have rtw8812au.c and rtw8821au.c. 

> +       .ops = &rtw8821a_ops,
> +       .id = RTW_CHIP_TYPE_8812A,
> +       .fw_name = "rtw88/rtw8812a_fw.bin",
> +       .wlan_cpu = RTW_WCPU_11N,
> +       .tx_pkt_desc_sz = 40,
> +       .tx_buf_desc_sz = 16,
> +       .rx_pkt_desc_sz = 24,
> +       .rx_buf_desc_sz = 8,
> +       .phy_efuse_size = 512,
> +       .log_efuse_size = 512,
> +       .ptct_efuse_size = 96 + 1, /* TODO or just 18? */
> +       .txff_size = 131072,
> +       .rxff_size = 16128,
> +       .rsvd_drv_pg_num = 9,
> +       .txgi_factor = 1,
> +       .is_pwr_by_rate_dec = true,
> +       .max_power_index = 0x3f,
> +       .csi_buf_pg_num = 0,
> +       .band = RTW_BAND_2G | RTW_BAND_5G,
> +       .page_size = 512,
> +       .dig_min = 0x20,
> +       .ht_supported = true,
> +       .vht_supported = true,
> +       .lps_deep_mode_supported = 0,
> +       .sys_func_en = 0xFD,
> +       .pwr_on_seq = card_enable_flow_8812a,
> +       .pwr_off_seq = card_disable_flow_8812a,
> +       .page_table = page_table_8812a,
> +       .rqpn_table = rqpn_table_8821a,
> +       .prioq_addrs = &prioq_addrs_8821a,
> +       .intf_table = &phy_para_table_8821a,
> +       .dig = rtw8821a_dig,
> +       .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B},
> +       .ltecoex_addr = NULL,
> +       .mac_tbl = &rtw8812a_mac_tbl,
> +       .agc_tbl = &rtw8812a_agc_tbl,
> +       .bb_tbl = &rtw8812a_bb_tbl,
> +       .rf_tbl = {&rtw8812a_rf_a_tbl, &rtw8812a_rf_b_tbl},
> +       .rfe_defs = rtw8812a_rfe_defs,
> +       .rfe_defs_size = ARRAY_SIZE(rtw8812a_rfe_defs),
> +       .rx_ldpc = false,
> +       .hw_feature_report = false,
> +       .c2h_ra_report_size = 4,
> +       .old_datarate_fb_limit = true,
> +       .usb_tx_agg_desc_num = 1,
> +       .iqk_threshold = 8,
> +       .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
> +       .max_scan_ie_len = IEEE80211_MAX_DATA_LEN,
> +
> +       .coex_para_ver = 0, /* no coex code in 8812au driver */
> +       .bt_desired_ver = 0,
> +       .scbd_support = false,
> +       .new_scbd10_def = false,
> +       .ble_hid_profile_support = false,
> +       .wl_mimo_ps_support = false,
> +       .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF,
> +       .bt_rssi_type = COEX_BTRSSI_RATIO,
> +       .ant_isolation = 15,
> +       .rssi_tolerance = 2,
> +       .wl_rssi_step = wl_rssi_step_8821a,
> +       .bt_rssi_step = bt_rssi_step_8821a,
> +       .table_sant_num = 0,
> +       .table_sant = NULL,
> +       .table_nsant_num = 0,
> +       .table_nsant = NULL,
> +       .tdma_sant_num = 0,
> +       .tdma_sant = NULL,
> +       .tdma_nsant_num = 0,
> +       .tdma_nsant = NULL,
> +       .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8821a),
> +       .wl_rf_para_tx = rf_para_tx_8821a,
> +       .wl_rf_para_rx = rf_para_rx_8821a,
> +       .bt_afh_span_bw20 = 0x20,
> +       .bt_afh_span_bw40 = 0x30,
> +       .afh_5g_num = 0,
> +       .afh_5g = NULL,
> +
> +       .coex_info_hw_regs_num = 0,
> +       .coex_info_hw_regs = NULL,
> +};
> +EXPORT_SYMBOL(rtw8812a_hw_spec);
> +
> +MODULE_FIRMWARE("rtw88/rtw8821a_fw.bin");
> +MODULE_FIRMWARE("rtw88/rtw8812a_fw.bin");
> +
> +MODULE_AUTHOR("Realtek Corporation");
> +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a/8812a driver");
> +MODULE_LICENSE("Dual BSD/GPL");
> diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a.h
> b/drivers/net/wireless/realtek/rtw88/rtw8821a.h
> new file mode 100644
> index 000000000000..7f1c2d2eb6d2
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.h
> @@ -0,0 +1,385 @@
> +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
> +/* Copyright(c) 2018-2019  Realtek Corporation

Year 2024

> + */
> +
> +#ifndef __RTW8821A_H__
> +#define __RTW8821A_H__
> +
> +#include <asm/byteorder.h>
> +
> +struct rtw8821au_efuse {
> +       u8 res4[48];                    /* 0xd0 */
> +       u8 vid[2];                      /* 0x100 */
> +       u8 pid[2];
> +       u8 res8[3];
> +       u8 mac_addr[ETH_ALEN];          /* 0x107 */
> +       u8 res9[243];
> +};

__packed

> +
> +struct rtw8812au_efuse {
> +       u8 vid[2];                      /* 0xd0 */
> +       u8 pid[2];                      /* 0xd2 */
> +       u8 res0[3];
> +       u8 mac_addr[ETH_ALEN];          /* 0xd7 */
> +       u8 res1[291];
> +};

__packed

[...]

> +#define WLAN_SIFS_CFG  (WLAN_SIFS_CCK_CONT_TX | \
> +                       (WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \
> +                       (WLAN_SIFS_CCK_TRX << BIT_SHIFT_SIFS_CCK_TRX) | \
> +                       (WLAN_SIFS_OFDM_TRX << BIT_SHIFT_SIFS_OFDM_TRX))

BIT_SHIFT_SIFS_OFDM_CTX is defined in reg.h, so this header file should
include reg.h. Because every header file should be included independently. 

> +
> +#define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\
> +                       (WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP))
> +
> +#define WLAN_NAV_CFG           (WLAN_RDG_NAV | (WLAN_TXOP_NAV << 16))
> +#define WLAN_RX_TSF_CFG                (WLAN_CCK_RX_TSF | (WLAN_OFDM_RX_TSF) << 8)
> +#define WLAN_PRE_TXCNT_TIME_TH                 0x1E4
> +
> +struct rtw8821a_phy_status_rpt {
> +       /* DWORD 0 */
> +       u8 gain_trsw[2]; /* path-A and path-B { TRSW, gain[6:0] } */
> +       u8 chl_num_lsb; /* channel number[7:0] */
> +#ifdef __LITTLE_ENDIAN
> +       u8 chl_num_msb:2; /* channel number[9:8] */
> +       u8 sub_chnl:4; /* sub-channel location[3:0] */
> +       u8 r_rfmod:2; /* RF mode[1:0] */
> +#else
> +       u8 r_rfmod:2;
> +       u8 sub_chnl:4;
> +       u8 chl_num_msb:2;
> +#endif

Not prefer "#ifdef __LITTLE_ENDIAN" style, because we have never verified
big endian part. Prefer to define mask and access them via u8_get_bits() and
its friends.


> +
> +       /* DWORD 1 */
> +       u8 pwdb_all; /* CCK signal quality / OFDM pwdb all */
> +       s8 cfosho[2]; /* CCK AGC report and CCK_BB_Power */
> +                     /* OFDM path-A and path-B short CFO */
> +#ifdef __LITTLE_ENDIAN
> +       u8 resvd_0:6;
> +       u8 bt_rf_ch_msb:2; /* 8812A: 2'b0 8814A: bt rf channel keep[7:6] */

Will you share this struct with 8814A? If not please remove comments related to 8814A.

> +#else
> +       u8 bt_rf_ch_msb:2;
> +       u8 resvd_0:6;
> +#endif

[...]


> +
> +#define REG_SYS_CTRL                           0x000
> +#define BIT_FEN_EN                             BIT(26)
> +#define REG_APS_FSMCO                          0x04
> +#define  APS_FSMCO_MAC_ENABLE                  BIT(8)
> +#define  APS_FSMCO_MAC_OFF                     BIT(9)
> +#define  APS_FSMCO_HW_POWERDOWN                        BIT(15)
> +#define REG_ACLK_MON                           0x3e
> +#define REG_RF_B_CTRL                          0x76
> +#define REG_HIMR0                              0xb0
> +#define REG_HISR0                              0xb4
> +#define REG_HIMR1                              0xb8
> +#define REG_HISR1                              0xbc

[...]

Can't we move all of these registers (including what I delete) into reg.h?







[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux