Commit 8704d0be authored by Zong-Zhe Yang's avatar Zong-Zhe Yang Committed by Kalle Valo
Browse files

rtw88: support SAR via kernel common API



Register cfg80211_sar_capa with type NL80211_SAR_TYPE_POWER and four
frequency ranges for configurations in unit of 0.25 dBm. And handle
callback set_sar_specs.

Originally, TX power has three main parameters, i.e. power base,
power by rate, and power limit. The formula can be simply considered
as TX power = power base + min(power by rate, power limit). With the
support of SAR which can be treated as another power limit, there is
one more parameter for TX power. And the formula will evolve into
TX power = power base + min(power by rate, power limit, power sar).

Besides, debugfs tx_pwr_tbl is also refined to show SAR information.
The following is an example for the difference.
Before supporting SAR,
-----------------------------------
...
path rate       pwr       base      (byr  lmt ) rem
   A  CCK_1M     66(0x42)   78  -12 (  12  -12)    0
   A  CCK_2M     66(0x42)   78  -12 (   8  -12)    0
...
-----------------------------------
After supporting SAR and making some configurations,
-----------------------------------
...
path rate       pwr       base      (byr  lmt  sar ) rem
   A  CCK_1M     62(0x3e)   78  -16 (  12  -12  -16)    0
   A  CCK_2M     62(0x3e)   78  -16 (   8  -12  -16)    0
...
-----------------------------------

Signed-off-by: default avatarZong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20211220093656.65312-1-pkshih@realtek.com
parent 10d162b2
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ rtw88_core-y += main.o \
	   ps.o \
	   sec.o \
	   bf.o \
	   sar.o \
	   regd.o

rtw88_core-$(CONFIG_PM) += wow.o
+7 −5
Original line number Diff line number Diff line
@@ -634,8 +634,8 @@ static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v)
	seq_printf(m, "channel: %u\n", ch);
	seq_printf(m, "bandwidth: %u\n", bw);
	seq_printf(m, "regulatory: %s\n", rtw_get_regd_string(regd));
	seq_printf(m, "%-4s %-10s %-3s%6s %-4s %4s (%-4s %-4s) %-4s\n",
		   "path", "rate", "pwr", "", "base", "", "byr", "lmt", "rem");
	seq_printf(m, "%-4s %-10s %-9s %-9s (%-4s %-4s %-4s) %-4s\n",
		   "path", "rate", "pwr", "base", "byr", "lmt", "sar", "rem");

	mutex_lock(&hal->tx_power_mutex);
	for (path = RF_PATH_A; path <= RF_PATH_B; path++) {
@@ -657,13 +657,15 @@ static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v)

			seq_printf(m, "%4c ", path + 'A');
			rtw_print_rate(m, rate);
			seq_printf(m, " %3u(0x%02x) %4u %4d (%4d %4d) %4d\n",
			seq_printf(m, " %3u(0x%02x) %4u %4d (%4d %4d %4d) %4d\n",
				   hal->tx_pwr_tbl[path][rate],
				   hal->tx_pwr_tbl[path][rate],
				   pwr_param.pwr_base,
				   min_t(s8, pwr_param.pwr_offset,
					 pwr_param.pwr_limit),
				   min3(pwr_param.pwr_offset,
					pwr_param.pwr_limit,
					pwr_param.pwr_sar),
				   pwr_param.pwr_offset, pwr_param.pwr_limit,
				   pwr_param.pwr_sar,
				   pwr_param.pwr_remnant);
		}
	}
+12 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include "bf.h"
#include "debug.h"
#include "wow.h"
#include "sar.h"

static void rtw_ops_tx(struct ieee80211_hw *hw,
		       struct ieee80211_tx_control *control,
@@ -836,6 +837,16 @@ static void rtw_ops_cancel_hw_scan(struct ieee80211_hw *hw,
	mutex_unlock(&rtwdev->mutex);
}

static int rtw_ops_set_sar_specs(struct ieee80211_hw *hw,
				 const struct cfg80211_sar_specs *sar)
{
	struct rtw_dev *rtwdev = hw->priv;

	rtw_set_sar_specs(rtwdev, sar);

	return 0;
}

const struct ieee80211_ops rtw_ops = {
	.tx			= rtw_ops_tx,
	.wake_tx_queue		= rtw_ops_wake_tx_queue,
@@ -865,6 +876,7 @@ const struct ieee80211_ops rtw_ops = {
	.reconfig_complete	= rtw_reconfig_complete,
	.hw_scan		= rtw_ops_hw_scan,
	.cancel_hw_scan		= rtw_ops_cancel_hw_scan,
	.set_sar_specs          = rtw_ops_set_sar_specs,
#ifdef CONFIG_PM
	.suspend		= rtw_ops_suspend,
	.resume			= rtw_ops_resume,
+22 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "tx.h"
#include "debug.h"
#include "bf.h"
#include "sar.h"

bool rtw_disable_lps_deep_mode;
EXPORT_SYMBOL(rtw_disable_lps_deep_mode);
@@ -751,6 +752,25 @@ void rtw_set_channel(struct rtw_dev *rtwdev)
	hal->current_primary_channel_index = primary_chan_idx;
	hal->current_band_type = center_chan > 14 ? RTW_BAND_5G : RTW_BAND_2G;

	switch (center_chan) {
	case 1 ... 14:
		hal->sar_band = RTW_SAR_BAND_0;
		break;
	case 36 ... 64:
		hal->sar_band = RTW_SAR_BAND_1;
		break;
	case 100 ... 144:
		hal->sar_band = RTW_SAR_BAND_3;
		break;
	case 149 ... 177:
		hal->sar_band = RTW_SAR_BAND_4;
		break;
	default:
		WARN(1, "unknown ch(%u) to SAR band\n", center_chan);
		hal->sar_band = RTW_SAR_BAND_0;
		break;
	}

	for (i = RTW_CHANNEL_WIDTH_20; i <= RTW_MAX_CHANNEL_WIDTH; i++)
		hal->cch_by_bw[i] = ch_param.cch_by_bw[i];

@@ -2037,6 +2057,8 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
	rtw_set_supported_band(hw, rtwdev->chip);
	SET_IEEE80211_PERM_ADDR(hw, rtwdev->efuse.addr);

	hw->wiphy->sar_capa = &rtw_sar_capa;

	ret = rtw_regd_init(rtwdev);
	if (ret) {
		rtw_err(rtwdev, "failed to init regd\n");
+30 −0
Original line number Diff line number Diff line
@@ -1813,6 +1813,33 @@ struct rtw_fw_state {
	u32 feature;
};

enum rtw_sar_sources {
	RTW_SAR_SOURCE_NONE,
	RTW_SAR_SOURCE_COMMON,
};

enum rtw_sar_bands {
	RTW_SAR_BAND_0,
	RTW_SAR_BAND_1,
	/* RTW_SAR_BAND_2, not used now */
	RTW_SAR_BAND_3,
	RTW_SAR_BAND_4,

	RTW_SAR_BAND_NR,
};

/* the union is reserved for other knids of SAR sources
 * which might not re-use same format with array common.
 */
union rtw_sar_cfg {
	s8 common[RTW_SAR_BAND_NR];
};

struct rtw_sar {
	enum rtw_sar_sources src;
	union rtw_sar_cfg cfg[RTW_RF_PATH_MAX][RTW_RATE_SECTION_MAX];
};

struct rtw_hal {
	u32 rcr;

@@ -1861,6 +1888,9 @@ struct rtw_hal {
			  [RTW_MAX_CHANNEL_NUM_5G];
	s8 tx_pwr_tbl[RTW_RF_PATH_MAX]
		     [DESC_RATE_MAX];

	enum rtw_sar_bands sar_band;
	struct rtw_sar sar;
};

struct rtw_path_div {
Loading