Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
0002 /* Copyright(c) 2018-2019  Realtek Corporation.
0003  */
0004 
0005 #include "main.h"
0006 #include "reg.h"
0007 #include "bf.h"
0008 #include "debug.h"
0009 
0010 void rtw_bf_disassoc(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
0011              struct ieee80211_bss_conf *bss_conf)
0012 {
0013     struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
0014     struct rtw_bfee *bfee = &rtwvif->bfee;
0015     struct rtw_bf_info *bfinfo = &rtwdev->bf_info;
0016 
0017     if (bfee->role == RTW_BFEE_NONE)
0018         return;
0019 
0020     if (bfee->role == RTW_BFEE_MU)
0021         bfinfo->bfer_mu_cnt--;
0022     else if (bfee->role == RTW_BFEE_SU)
0023         bfinfo->bfer_su_cnt--;
0024 
0025     rtw_chip_config_bfee(rtwdev, rtwvif, bfee, false);
0026 
0027     bfee->role = RTW_BFEE_NONE;
0028 }
0029 
0030 void rtw_bf_assoc(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
0031           struct ieee80211_bss_conf *bss_conf)
0032 {
0033     struct ieee80211_hw *hw = rtwdev->hw;
0034     struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
0035     struct rtw_bfee *bfee = &rtwvif->bfee;
0036     struct rtw_bf_info *bfinfo = &rtwdev->bf_info;
0037     struct rtw_chip_info *chip = rtwdev->chip;
0038     struct ieee80211_sta *sta;
0039     struct ieee80211_sta_vht_cap *vht_cap;
0040     struct ieee80211_sta_vht_cap *ic_vht_cap;
0041     const u8 *bssid = bss_conf->bssid;
0042     u32 sound_dim;
0043     u8 i;
0044 
0045     if (!(chip->band & RTW_BAND_5G))
0046         return;
0047 
0048     rcu_read_lock();
0049 
0050     sta = ieee80211_find_sta(vif, bssid);
0051     if (!sta) {
0052         rtw_warn(rtwdev, "failed to find station entry for bss %pM\n",
0053              bssid);
0054         goto out_unlock;
0055     }
0056 
0057     ic_vht_cap = &hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap;
0058     vht_cap = &sta->deflink.vht_cap;
0059 
0060     if ((ic_vht_cap->cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE) &&
0061         (vht_cap->cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
0062         if (bfinfo->bfer_mu_cnt >= chip->bfer_mu_max_num) {
0063             rtw_dbg(rtwdev, RTW_DBG_BF, "mu bfer number over limit\n");
0064             goto out_unlock;
0065         }
0066 
0067         ether_addr_copy(bfee->mac_addr, bssid);
0068         bfee->role = RTW_BFEE_MU;
0069         bfee->p_aid = (bssid[5] << 1) | (bssid[4] >> 7);
0070         bfee->aid = vif->cfg.aid;
0071         bfinfo->bfer_mu_cnt++;
0072 
0073         rtw_chip_config_bfee(rtwdev, rtwvif, bfee, true);
0074     } else if ((ic_vht_cap->cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE) &&
0075            (vht_cap->cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) {
0076         if (bfinfo->bfer_su_cnt >= chip->bfer_su_max_num) {
0077             rtw_dbg(rtwdev, RTW_DBG_BF, "su bfer number over limit\n");
0078             goto out_unlock;
0079         }
0080 
0081         sound_dim = vht_cap->cap &
0082                 IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
0083         sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
0084 
0085         ether_addr_copy(bfee->mac_addr, bssid);
0086         bfee->role = RTW_BFEE_SU;
0087         bfee->sound_dim = (u8)sound_dim;
0088         bfee->g_id = 0;
0089         bfee->p_aid = (bssid[5] << 1) | (bssid[4] >> 7);
0090         bfinfo->bfer_su_cnt++;
0091         for (i = 0; i < chip->bfer_su_max_num; i++) {
0092             if (!test_bit(i, bfinfo->bfer_su_reg_maping)) {
0093                 set_bit(i, bfinfo->bfer_su_reg_maping);
0094                 bfee->su_reg_index = i;
0095                 break;
0096             }
0097         }
0098 
0099         rtw_chip_config_bfee(rtwdev, rtwvif, bfee, true);
0100     }
0101 
0102 out_unlock:
0103     rcu_read_unlock();
0104 }
0105 
0106 void rtw_bf_init_bfer_entry_mu(struct rtw_dev *rtwdev,
0107                    struct mu_bfer_init_para *param)
0108 {
0109     u16 mu_bf_ctl = 0;
0110     u8 *addr = param->bfer_address;
0111     int i;
0112 
0113     for (i = 0; i < ETH_ALEN; i++)
0114         rtw_write8(rtwdev, REG_ASSOCIATED_BFMER0_INFO + i, addr[i]);
0115     rtw_write16(rtwdev, REG_ASSOCIATED_BFMER0_INFO + 6, param->paid);
0116     rtw_write16(rtwdev, REG_TX_CSI_RPT_PARAM_BW20, param->csi_para);
0117 
0118     mu_bf_ctl = rtw_read16(rtwdev, REG_WMAC_MU_BF_CTL) & 0xC000;
0119     mu_bf_ctl |= param->my_aid | (param->csi_length_sel << 12);
0120     rtw_write16(rtwdev, REG_WMAC_MU_BF_CTL, mu_bf_ctl);
0121 }
0122 
0123 void rtw_bf_cfg_sounding(struct rtw_dev *rtwdev, struct rtw_vif *vif,
0124              enum rtw_trx_desc_rate rate)
0125 {
0126     u32 psf_ctl = 0;
0127     u8 csi_rsc = 0x1;
0128 
0129     psf_ctl = rtw_read32(rtwdev, REG_BBPSF_CTRL) |
0130           BIT_WMAC_USE_NDPARATE |
0131           (csi_rsc << 13);
0132 
0133     rtw_write8_mask(rtwdev, REG_SND_PTCL_CTRL, BIT_MASK_BEAMFORM,
0134             RTW_SND_CTRL_SOUNDING);
0135     rtw_write8(rtwdev, REG_SND_PTCL_CTRL + 3, 0x26);
0136     rtw_write8_clr(rtwdev, REG_RXFLTMAP1, BIT_RXFLTMAP1_BF_REPORT_POLL);
0137     rtw_write8_clr(rtwdev, REG_RXFLTMAP4, BIT_RXFLTMAP4_BF_REPORT_POLL);
0138 
0139     if (vif->net_type == RTW_NET_AP_MODE)
0140         rtw_write32(rtwdev, REG_BBPSF_CTRL, psf_ctl | BIT(12));
0141     else
0142         rtw_write32(rtwdev, REG_BBPSF_CTRL, psf_ctl & ~BIT(12));
0143 }
0144 
0145 void rtw_bf_cfg_mu_bfee(struct rtw_dev *rtwdev, struct cfg_mumimo_para *param)
0146 {
0147     u8 mu_tbl_sel;
0148     u8 mu_valid;
0149 
0150     mu_valid = rtw_read8(rtwdev, REG_MU_TX_CTL) &
0151            ~BIT_MASK_R_MU_TABLE_VALID;
0152 
0153     rtw_write8(rtwdev, REG_MU_TX_CTL,
0154            (mu_valid | BIT(0) | BIT(1)) & ~(BIT(7)));
0155 
0156     mu_tbl_sel = rtw_read8(rtwdev, REG_MU_TX_CTL + 1) & 0xF8;
0157 
0158     rtw_write8(rtwdev, REG_MU_TX_CTL + 1, mu_tbl_sel);
0159     rtw_write32(rtwdev, REG_MU_STA_GID_VLD, param->given_gid_tab[0]);
0160     rtw_write32(rtwdev, REG_MU_STA_USER_POS_INFO, param->given_user_pos[0]);
0161     rtw_write32(rtwdev, REG_MU_STA_USER_POS_INFO + 4,
0162             param->given_user_pos[1]);
0163 
0164     rtw_write8(rtwdev, REG_MU_TX_CTL + 1, mu_tbl_sel | 1);
0165     rtw_write32(rtwdev, REG_MU_STA_GID_VLD, param->given_gid_tab[1]);
0166     rtw_write32(rtwdev, REG_MU_STA_USER_POS_INFO, param->given_user_pos[2]);
0167     rtw_write32(rtwdev, REG_MU_STA_USER_POS_INFO + 4,
0168             param->given_user_pos[3]);
0169 }
0170 
0171 void rtw_bf_del_bfer_entry_mu(struct rtw_dev *rtwdev)
0172 {
0173     rtw_write32(rtwdev, REG_ASSOCIATED_BFMER0_INFO, 0);
0174     rtw_write32(rtwdev, REG_ASSOCIATED_BFMER0_INFO + 4, 0);
0175     rtw_write16(rtwdev, REG_WMAC_MU_BF_CTL, 0);
0176     rtw_write8(rtwdev, REG_MU_TX_CTL, 0);
0177 }
0178 
0179 void rtw_bf_del_sounding(struct rtw_dev *rtwdev)
0180 {
0181     rtw_write8_mask(rtwdev, REG_SND_PTCL_CTRL, BIT_MASK_BEAMFORM, 0);
0182 }
0183 
0184 void rtw_bf_enable_bfee_su(struct rtw_dev *rtwdev, struct rtw_vif *vif,
0185                struct rtw_bfee *bfee)
0186 {
0187     u8 nc_index = hweight8(rtwdev->hal.antenna_rx) - 1;
0188     u8 nr_index = bfee->sound_dim;
0189     u8 grouping = 0, codebookinfo = 1, coefficientsize = 3;
0190     u32 addr_bfer_info, addr_csi_rpt, csi_param;
0191     u8 i;
0192 
0193     rtw_dbg(rtwdev, RTW_DBG_BF, "config as an su bfee\n");
0194 
0195     switch (bfee->su_reg_index) {
0196     case 1:
0197         addr_bfer_info = REG_ASSOCIATED_BFMER1_INFO;
0198         addr_csi_rpt = REG_TX_CSI_RPT_PARAM_BW20 + 2;
0199         break;
0200     case 0:
0201     default:
0202         addr_bfer_info = REG_ASSOCIATED_BFMER0_INFO;
0203         addr_csi_rpt = REG_TX_CSI_RPT_PARAM_BW20;
0204         break;
0205     }
0206 
0207     /* Sounding protocol control */
0208     rtw_write8_mask(rtwdev, REG_SND_PTCL_CTRL, BIT_MASK_BEAMFORM,
0209             RTW_SND_CTRL_SOUNDING);
0210 
0211     /* MAC address/Partial AID of Beamformer */
0212     for (i = 0; i < ETH_ALEN; i++)
0213         rtw_write8(rtwdev, addr_bfer_info + i, bfee->mac_addr[i]);
0214 
0215     csi_param = (u16)((coefficientsize << 10) |
0216               (codebookinfo << 8) |
0217               (grouping << 6) |
0218               (nr_index << 3) |
0219               nc_index);
0220     rtw_write16(rtwdev, addr_csi_rpt, csi_param);
0221 
0222     /* ndp rx standby timer */
0223     rtw_write8(rtwdev, REG_SND_PTCL_CTRL + 3, RTW_NDP_RX_STANDBY_TIME);
0224 }
0225 EXPORT_SYMBOL(rtw_bf_enable_bfee_su);
0226 
0227 /* nc index: 1 2T2R 0 1T1R
0228  * nr index: 1 use Nsts 0 use reg setting
0229  * codebookinfo: 1 802.11ac 3 802.11n
0230  */
0231 void rtw_bf_enable_bfee_mu(struct rtw_dev *rtwdev, struct rtw_vif *vif,
0232                struct rtw_bfee *bfee)
0233 {
0234     struct rtw_bf_info *bf_info = &rtwdev->bf_info;
0235     struct mu_bfer_init_para param;
0236     u8 nc_index = hweight8(rtwdev->hal.antenna_rx) - 1;
0237     u8 nr_index = 1;
0238     u8 grouping = 0, codebookinfo = 1, coefficientsize = 0;
0239     u32 csi_param;
0240 
0241     rtw_dbg(rtwdev, RTW_DBG_BF, "config as an mu bfee\n");
0242 
0243     csi_param = (u16)((coefficientsize << 10) |
0244               (codebookinfo << 8) |
0245               (grouping << 6) |
0246               (nr_index << 3) |
0247               nc_index);
0248 
0249     rtw_dbg(rtwdev, RTW_DBG_BF, "nc=%d nr=%d group=%d codebookinfo=%d coefficientsize=%d\n",
0250         nc_index, nr_index, grouping, codebookinfo,
0251         coefficientsize);
0252 
0253     param.paid = bfee->p_aid;
0254     param.csi_para = csi_param;
0255     param.my_aid = bfee->aid & 0xfff;
0256     param.csi_length_sel = HAL_CSI_SEG_4K;
0257     ether_addr_copy(param.bfer_address, bfee->mac_addr);
0258 
0259     rtw_bf_init_bfer_entry_mu(rtwdev, &param);
0260 
0261     bf_info->cur_csi_rpt_rate = DESC_RATE6M;
0262     rtw_bf_cfg_sounding(rtwdev, vif, DESC_RATE6M);
0263 
0264     /* accept action_no_ack */
0265     rtw_write16_set(rtwdev, REG_RXFLTMAP0, BIT_RXFLTMAP0_ACTIONNOACK);
0266 
0267     /* accept NDPA and BF report poll */
0268     rtw_write16_set(rtwdev, REG_RXFLTMAP1, BIT_RXFLTMAP1_BF);
0269 }
0270 EXPORT_SYMBOL(rtw_bf_enable_bfee_mu);
0271 
0272 void rtw_bf_remove_bfee_su(struct rtw_dev *rtwdev,
0273                struct rtw_bfee *bfee)
0274 {
0275     struct rtw_bf_info *bfinfo = &rtwdev->bf_info;
0276 
0277     rtw_dbg(rtwdev, RTW_DBG_BF, "remove as a su bfee\n");
0278     rtw_write8_mask(rtwdev, REG_SND_PTCL_CTRL, BIT_MASK_BEAMFORM,
0279             RTW_SND_CTRL_REMOVE);
0280 
0281     switch (bfee->su_reg_index) {
0282     case 0:
0283         rtw_write32(rtwdev, REG_ASSOCIATED_BFMER0_INFO, 0);
0284         rtw_write16(rtwdev, REG_ASSOCIATED_BFMER0_INFO + 4, 0);
0285         rtw_write16(rtwdev, REG_TX_CSI_RPT_PARAM_BW20, 0);
0286         break;
0287     case 1:
0288         rtw_write32(rtwdev, REG_ASSOCIATED_BFMER1_INFO, 0);
0289         rtw_write16(rtwdev, REG_ASSOCIATED_BFMER1_INFO + 4, 0);
0290         rtw_write16(rtwdev, REG_TX_CSI_RPT_PARAM_BW20 + 2, 0);
0291         break;
0292     }
0293 
0294     clear_bit(bfee->su_reg_index, bfinfo->bfer_su_reg_maping);
0295     bfee->su_reg_index = 0xFF;
0296 }
0297 EXPORT_SYMBOL(rtw_bf_remove_bfee_su);
0298 
0299 void rtw_bf_remove_bfee_mu(struct rtw_dev *rtwdev,
0300                struct rtw_bfee *bfee)
0301 {
0302     struct rtw_bf_info *bfinfo = &rtwdev->bf_info;
0303 
0304     rtw_write8_mask(rtwdev, REG_SND_PTCL_CTRL, BIT_MASK_BEAMFORM,
0305             RTW_SND_CTRL_REMOVE);
0306 
0307     rtw_bf_del_bfer_entry_mu(rtwdev);
0308 
0309     if (bfinfo->bfer_su_cnt == 0 && bfinfo->bfer_mu_cnt == 0)
0310         rtw_bf_del_sounding(rtwdev);
0311 }
0312 EXPORT_SYMBOL(rtw_bf_remove_bfee_mu);
0313 
0314 void rtw_bf_set_gid_table(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
0315               struct ieee80211_bss_conf *conf)
0316 {
0317     struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
0318     struct rtw_bfee *bfee = &rtwvif->bfee;
0319     struct cfg_mumimo_para param;
0320 
0321     if (bfee->role != RTW_BFEE_MU) {
0322         rtw_dbg(rtwdev, RTW_DBG_BF, "this vif is not mu bfee\n");
0323         return;
0324     }
0325 
0326     param.grouping_bitmap = 0;
0327     param.mu_tx_en = 0;
0328     memset(param.sounding_sts, 0, 6);
0329     memcpy(param.given_gid_tab, conf->mu_group.membership, 8);
0330     memcpy(param.given_user_pos, conf->mu_group.position, 16);
0331     rtw_dbg(rtwdev, RTW_DBG_BF, "STA0: gid_valid=0x%x, user_position_l=0x%x, user_position_h=0x%x\n",
0332         param.given_gid_tab[0], param.given_user_pos[0],
0333         param.given_user_pos[1]);
0334 
0335     rtw_dbg(rtwdev, RTW_DBG_BF, "STA1: gid_valid=0x%x, user_position_l=0x%x, user_position_h=0x%x\n",
0336         param.given_gid_tab[1], param.given_user_pos[2],
0337         param.given_user_pos[3]);
0338 
0339     rtw_bf_cfg_mu_bfee(rtwdev, &param);
0340 }
0341 EXPORT_SYMBOL(rtw_bf_set_gid_table);
0342 
0343 void rtw_bf_phy_init(struct rtw_dev *rtwdev)
0344 {
0345     u8 tmp8;
0346     u32 tmp32;
0347     u8 retry_limit = 0xA;
0348     u8 ndpa_rate = 0x10;
0349     u8 ack_policy = 3;
0350 
0351     tmp32 = rtw_read32(rtwdev, REG_MU_TX_CTL);
0352     /* Enable P1 aggr new packet according to P0 transfer time */
0353     tmp32 |= BIT_MU_P1_WAIT_STATE_EN;
0354     /* MU Retry Limit */
0355     tmp32 &= ~BIT_MASK_R_MU_RL;
0356     tmp32 |= (retry_limit << BIT_SHIFT_R_MU_RL) & BIT_MASK_R_MU_RL;
0357     /* Disable Tx MU-MIMO until sounding done */
0358     tmp32 &= ~BIT_EN_MU_MIMO;
0359     /* Clear validity of MU STAs */
0360     tmp32 &= ~BIT_MASK_R_MU_TABLE_VALID;
0361     rtw_write32(rtwdev, REG_MU_TX_CTL, tmp32);
0362 
0363     /* MU-MIMO Option as default value */
0364     tmp8 = ack_policy << BIT_SHIFT_WMAC_TXMU_ACKPOLICY;
0365     tmp8 |= BIT_WMAC_TXMU_ACKPOLICY_EN;
0366     rtw_write8(rtwdev, REG_WMAC_MU_BF_OPTION, tmp8);
0367 
0368     /* MU-MIMO Control as default value */
0369     rtw_write16(rtwdev, REG_WMAC_MU_BF_CTL, 0);
0370     /* Set MU NDPA rate & BW source */
0371     rtw_write32_set(rtwdev, REG_TXBF_CTRL, BIT_USE_NDPA_PARAMETER);
0372     /* Set NDPA Rate */
0373     rtw_write8(rtwdev, REG_NDPA_OPT_CTRL, ndpa_rate);
0374 
0375     rtw_write32_mask(rtwdev, REG_BBPSF_CTRL, BIT_MASK_CSI_RATE,
0376              DESC_RATE6M);
0377 }
0378 EXPORT_SYMBOL(rtw_bf_phy_init);
0379 
0380 void rtw_bf_cfg_csi_rate(struct rtw_dev *rtwdev, u8 rssi, u8 cur_rate,
0381              u8 fixrate_en, u8 *new_rate)
0382 {
0383     u32 csi_cfg;
0384     u16 cur_rrsr;
0385 
0386     csi_cfg = rtw_read32(rtwdev, REG_BBPSF_CTRL) & ~BIT_MASK_CSI_RATE;
0387     cur_rrsr = rtw_read16(rtwdev, REG_RRSR);
0388 
0389     if (rssi >= 40) {
0390         if (cur_rate != DESC_RATE54M) {
0391             cur_rrsr |= BIT(DESC_RATE54M);
0392             csi_cfg |= (DESC_RATE54M & BIT_MASK_CSI_RATE_VAL) <<
0393                    BIT_SHIFT_CSI_RATE;
0394             rtw_write16(rtwdev, REG_RRSR, cur_rrsr);
0395             rtw_write32(rtwdev, REG_BBPSF_CTRL, csi_cfg);
0396         }
0397         *new_rate = DESC_RATE54M;
0398     } else {
0399         if (cur_rate != DESC_RATE24M) {
0400             cur_rrsr &= ~BIT(DESC_RATE54M);
0401             csi_cfg |= (DESC_RATE54M & BIT_MASK_CSI_RATE_VAL) <<
0402                    BIT_SHIFT_CSI_RATE;
0403             rtw_write16(rtwdev, REG_RRSR, cur_rrsr);
0404             rtw_write32(rtwdev, REG_BBPSF_CTRL, csi_cfg);
0405         }
0406         *new_rate = DESC_RATE24M;
0407     }
0408 }
0409 EXPORT_SYMBOL(rtw_bf_cfg_csi_rate);