The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/rtw88/sar.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
    2 /* Copyright(c) 2018-2021  Realtek Corporation
    3  */
    4 
    5 #include "sar.h"
    6 #include "phy.h"
    7 #include "debug.h"
    8 
    9 s8 rtw_query_sar(struct rtw_dev *rtwdev, const struct rtw_sar_arg *arg)
   10 {
   11         const struct rtw_hal *hal = &rtwdev->hal;
   12         const struct rtw_sar *sar = &hal->sar;
   13 
   14         switch (sar->src) {
   15         default:
   16                 rtw_warn(rtwdev, "unknown SAR source: %d\n", sar->src);
   17                 fallthrough;
   18         case RTW_SAR_SOURCE_NONE:
   19                 return (s8)rtwdev->chip->max_power_index;
   20         case RTW_SAR_SOURCE_COMMON:
   21                 return sar->cfg[arg->path][arg->rs].common[arg->sar_band];
   22         }
   23 }
   24 
   25 static int rtw_apply_sar(struct rtw_dev *rtwdev, const struct rtw_sar *new)
   26 {
   27         struct rtw_hal *hal = &rtwdev->hal;
   28         struct rtw_sar *sar = &hal->sar;
   29 
   30         if (sar->src != RTW_SAR_SOURCE_NONE && new->src != sar->src) {
   31                 rtw_warn(rtwdev, "SAR source: %d is in use\n", sar->src);
   32                 return -EBUSY;
   33         }
   34 
   35         *sar = *new;
   36         rtw_phy_set_tx_power_level(rtwdev, hal->current_channel);
   37 
   38         return 0;
   39 }
   40 
   41 static s8 rtw_sar_to_phy(struct rtw_dev *rtwdev, u8 fct, s32 sar,
   42                          const struct rtw_sar_arg *arg)
   43 {
   44         struct rtw_hal *hal = &rtwdev->hal;
   45         u8 txgi = rtwdev->chip->txgi_factor;
   46         u8 max = rtwdev->chip->max_power_index;
   47         s32 tmp;
   48         s8 base;
   49 
   50         tmp = fct > txgi ? sar >> (fct - txgi) : sar << (txgi - fct);
   51         base = arg->sar_band == RTW_SAR_BAND_0 ?
   52                hal->tx_pwr_by_rate_base_2g[arg->path][arg->rs] :
   53                hal->tx_pwr_by_rate_base_5g[arg->path][arg->rs];
   54 
   55         return (s8)clamp_t(s32, tmp, -max - 1, max) - base;
   56 }
   57 
   58 static const struct cfg80211_sar_freq_ranges rtw_common_sar_freq_ranges[] = {
   59         [RTW_SAR_BAND_0] = { .start_freq = 2412, .end_freq = 2484, },
   60         [RTW_SAR_BAND_1] = { .start_freq = 5180, .end_freq = 5320, },
   61         [RTW_SAR_BAND_3] = { .start_freq = 5500, .end_freq = 5720, },
   62         [RTW_SAR_BAND_4] = { .start_freq = 5745, .end_freq = 5825, },
   63 };
   64 
   65 rtw88_static_assert(ARRAY_SIZE(rtw_common_sar_freq_ranges) == RTW_SAR_BAND_NR);
   66 
   67 const struct cfg80211_sar_capa rtw_sar_capa = {
   68         .type = NL80211_SAR_TYPE_POWER,
   69         .num_freq_ranges = RTW_SAR_BAND_NR,
   70         .freq_ranges = rtw_common_sar_freq_ranges,
   71 };
   72 
   73 int rtw_set_sar_specs(struct rtw_dev *rtwdev,
   74                       const struct cfg80211_sar_specs *sar)
   75 {
   76         struct rtw_sar_arg arg = {0};
   77         struct rtw_sar new = {0};
   78         u32 idx, i, j, k;
   79         s32 power;
   80         s8 val;
   81 
   82         if (sar->type != NL80211_SAR_TYPE_POWER)
   83                 return -EINVAL;
   84 
   85         memset(&new, rtwdev->chip->max_power_index, sizeof(new));
   86         new.src = RTW_SAR_SOURCE_COMMON;
   87 
   88         for (i = 0; i < sar->num_sub_specs; i++) {
   89                 idx = sar->sub_specs[i].freq_range_index;
   90                 if (idx >= RTW_SAR_BAND_NR)
   91                         return -EINVAL;
   92 
   93                 power = sar->sub_specs[i].power;
   94                 rtw_dbg(rtwdev, RTW_DBG_REGD, "On freq %u to %u, set SAR %d in 1/%lu dBm\n",
   95                         rtw_common_sar_freq_ranges[idx].start_freq,
   96                         rtw_common_sar_freq_ranges[idx].end_freq,
   97                         power, BIT(RTW_COMMON_SAR_FCT));
   98 
   99                 for (j = 0; j < RTW_RF_PATH_MAX; j++) {
  100                         for (k = 0; k < RTW_RATE_SECTION_MAX; k++) {
  101                                 arg = (struct rtw_sar_arg){
  102                                         .sar_band = idx,
  103                                         .path = j,
  104                                         .rs = k,
  105                                 };
  106                                 val = rtw_sar_to_phy(rtwdev, RTW_COMMON_SAR_FCT,
  107                                                      power, &arg);
  108                                 new.cfg[j][k].common[idx] = val;
  109                         }
  110                 }
  111         }
  112 
  113         return rtw_apply_sar(rtwdev, &new);
  114 }

Cache object: 7a89a748dc3470fd8b3373d748797302


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.