Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rtw88: add set_bitrate_mask support

Support setting bit rate from upper layer.
After configuring the original rate control result in the driver, the
result is then masked by the bit rate mask received from the ops
set_bitrate_mask. Lastly, the masked result will be sent to firmware.

Signed-off-by: Tzu-En Huang <tehuang@realtek.com>
Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>
Reviewed-by: Chris Chiu <chiu@endlessm.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

authored by

Tzu-En Huang and committed by
Kalle Valo
f39e9bd4 0bd95573

+118 -16
+53
drivers/net/wireless/realtek/rtw88/mac80211.c
··· 475 475 for (i = 0; i < ARRAY_SIZE(sta->txq); i++) 476 476 rtw_txq_cleanup(rtwdev, sta->txq[i]); 477 477 478 + kfree(si->mask); 479 + 478 480 rtwdev->sta_cnt--; 479 481 480 482 rtw_info(rtwdev, "sta %pM with macid %d left\n", ··· 686 684 mutex_unlock(&rtwdev->mutex); 687 685 } 688 686 687 + struct rtw_iter_bitrate_mask_data { 688 + struct rtw_dev *rtwdev; 689 + struct ieee80211_vif *vif; 690 + const struct cfg80211_bitrate_mask *mask; 691 + }; 692 + 693 + static void rtw_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta) 694 + { 695 + struct rtw_iter_bitrate_mask_data *br_data = data; 696 + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; 697 + 698 + if (si->vif != br_data->vif) 699 + return; 700 + 701 + /* free previous mask setting */ 702 + kfree(si->mask); 703 + si->mask = kmemdup(br_data->mask, sizeof(struct cfg80211_bitrate_mask), 704 + GFP_ATOMIC); 705 + if (!si->mask) { 706 + si->use_cfg_mask = false; 707 + return; 708 + } 709 + 710 + si->use_cfg_mask = true; 711 + rtw_update_sta_info(br_data->rtwdev, si); 712 + } 713 + 714 + static void rtw_ra_mask_info_update(struct rtw_dev *rtwdev, 715 + struct ieee80211_vif *vif, 716 + const struct cfg80211_bitrate_mask *mask) 717 + { 718 + struct rtw_iter_bitrate_mask_data br_data; 719 + 720 + br_data.rtwdev = rtwdev; 721 + br_data.vif = vif; 722 + br_data.mask = mask; 723 + rtw_iterate_stas_atomic(rtwdev, rtw_ra_mask_info_update_iter, &br_data); 724 + } 725 + 726 + static int rtw_ops_set_bitrate_mask(struct ieee80211_hw *hw, 727 + struct ieee80211_vif *vif, 728 + const struct cfg80211_bitrate_mask *mask) 729 + { 730 + struct rtw_dev *rtwdev = hw->priv; 731 + 732 + rtw_ra_mask_info_update(rtwdev, vif, mask); 733 + 734 + return 0; 735 + } 736 + 689 737 const struct ieee80211_ops rtw_ops = { 690 738 .tx = rtw_ops_tx, 691 739 .wake_tx_queue = rtw_ops_wake_tx_queue, ··· 757 705 .set_rts_threshold = rtw_ops_set_rts_threshold, 758 706 .sta_statistics = rtw_ops_sta_statistics, 759 707 .flush = rtw_ops_flush, 708 + .set_bitrate_mask = rtw_ops_set_bitrate_mask, 760 709 }; 761 710 EXPORT_SYMBOL(rtw_ops);
+62 -16
drivers/net/wireless/realtek/rtw88/main.c
··· 612 612 #define RA_MASK_OFDM_IN_HT_2G 0x00010 613 613 #define RA_MASK_OFDM_IN_HT_5G 0x00030 614 614 615 + static u64 rtw_update_rate_mask(struct rtw_dev *rtwdev, 616 + struct rtw_sta_info *si, 617 + u64 ra_mask, bool is_vht_enable, 618 + u8 wireless_set) 619 + { 620 + struct rtw_hal *hal = &rtwdev->hal; 621 + const struct cfg80211_bitrate_mask *mask = si->mask; 622 + u64 cfg_mask = GENMASK(63, 0); 623 + u8 rssi_level, band; 624 + 625 + if (wireless_set != WIRELESS_CCK) { 626 + rssi_level = si->rssi_level; 627 + if (rssi_level == 0) 628 + ra_mask &= 0xffffffffffffffffULL; 629 + else if (rssi_level == 1) 630 + ra_mask &= 0xfffffffffffffff0ULL; 631 + else if (rssi_level == 2) 632 + ra_mask &= 0xffffffffffffefe0ULL; 633 + else if (rssi_level == 3) 634 + ra_mask &= 0xffffffffffffcfc0ULL; 635 + else if (rssi_level == 4) 636 + ra_mask &= 0xffffffffffff8f80ULL; 637 + else if (rssi_level >= 5) 638 + ra_mask &= 0xffffffffffff0f00ULL; 639 + } 640 + 641 + if (!si->use_cfg_mask) 642 + return ra_mask; 643 + 644 + band = hal->current_band_type; 645 + if (band == RTW_BAND_2G) { 646 + band = NL80211_BAND_2GHZ; 647 + cfg_mask = mask->control[band].legacy; 648 + } else if (band == RTW_BAND_5G) { 649 + band = NL80211_BAND_5GHZ; 650 + cfg_mask = u64_encode_bits(mask->control[band].legacy, 651 + RA_MASK_OFDM_RATES); 652 + } 653 + 654 + if (!is_vht_enable) { 655 + if (ra_mask & RA_MASK_HT_RATES_1SS) 656 + cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[0], 657 + RA_MASK_HT_RATES_1SS); 658 + if (ra_mask & RA_MASK_HT_RATES_2SS) 659 + cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[1], 660 + RA_MASK_HT_RATES_2SS); 661 + } else { 662 + if (ra_mask & RA_MASK_VHT_RATES_1SS) 663 + cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[0], 664 + RA_MASK_VHT_RATES_1SS); 665 + if (ra_mask & RA_MASK_VHT_RATES_2SS) 666 + cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[1], 667 + RA_MASK_VHT_RATES_2SS); 668 + } 669 + 670 + ra_mask &= cfg_mask; 671 + 672 + return ra_mask; 673 + } 674 + 615 675 void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) 616 676 { 617 677 struct ieee80211_sta *sta = si->sta; 618 678 struct rtw_efuse *efuse = &rtwdev->efuse; 619 679 struct rtw_hal *hal = &rtwdev->hal; 620 - u8 rssi_level; 621 680 u8 wireless_set; 622 681 u8 bw_mode; 623 682 u8 rate_id; ··· 769 710 770 711 rate_id = get_rate_id(wireless_set, bw_mode, tx_num); 771 712 772 - if (wireless_set != WIRELESS_CCK) { 773 - rssi_level = si->rssi_level; 774 - if (rssi_level == 0) 775 - ra_mask &= 0xffffffffffffffffULL; 776 - else if (rssi_level == 1) 777 - ra_mask &= 0xfffffffffffffff0ULL; 778 - else if (rssi_level == 2) 779 - ra_mask &= 0xffffffffffffefe0ULL; 780 - else if (rssi_level == 3) 781 - ra_mask &= 0xffffffffffffcfc0ULL; 782 - else if (rssi_level == 4) 783 - ra_mask &= 0xffffffffffff8f80ULL; 784 - else if (rssi_level >= 5) 785 - ra_mask &= 0xffffffffffff0f00ULL; 786 - } 713 + ra_mask = rtw_update_rate_mask(rtwdev, si, ra_mask, is_vht_enable, 714 + wireless_set); 787 715 788 716 si->bw_mode = bw_mode; 789 717 si->stbc_en = stbc_en;
+3
drivers/net/wireless/realtek/rtw88/main.h
··· 646 646 DECLARE_BITMAP(tid_ba, IEEE80211_NUM_TIDS); 647 647 648 648 struct rtw_ra_report ra_report; 649 + 650 + bool use_cfg_mask; 651 + struct cfg80211_bitrate_mask *mask; 649 652 }; 650 653 651 654 enum rtw_bfee_role {