All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christian Lamparter <chunkeey@gmail.com>
To: Masi Osmani <mas-i@hotmail.de>
Cc: linux-wireless@vger.kernel.org, ath9k-devel@qca.qualcomm.com
Subject: Re: [PATCH 06/10] carl9170: phy: populate per-channel TX power from EEPROM
Date: Sat, 21 Mar 2026 20:24:07 +0100	[thread overview]
Message-ID: <ec4490af-1156-41b0-9df1-770fe8be6f91@gmail.com> (raw)
In-Reply-To: <AM7PPF5613FA0B6E8EAEDB73BAB87748A8C9444A@AM7PPF5613FA0B6.EURP251.PROD.OUTLOOK.COM>

On 3/12/26 11:38 AM, Masi Osmani wrote:
> Replace the hardcoded max_power = 18 dBm (marked XXX) in the
> channel definitions with actual per-channel values derived from
> the EEPROM calibration target power tables.
> 
> The new carl9170_get_max_tgt_power() function interpolates the
> maximum target power for a given frequency from the EEPROM's
> legacy OFDM and CCK target power tables, using the same frequency
> encoding and interpolation helpers already used by the power
> calibration code.  carl9170_update_channel_maxpower() iterates
> all registered channels and updates their max_power fields.


Why the need for interpolation here? Don't you just need to look
for the max(ctpl[idx].power, previous_value) within the band?

I'm not aware of any high-powered AR9170 devices. Were/are there any?

Cheers,
Christian

> 
> This is called during EEPROM parsing, so mac80211 and userspace
> see correct per-channel power limits from the start.  The CHAN
> macro default of 18 dBm remains as a safe fallback for channels
> where EEPROM data is missing.
> 
> Signed-off-by: Masi Osmani <mas-i@hotmail.de>
> ---
>   drivers/net/wireless/ath/carl9170/carl9170.h |  1 +
>   drivers/net/wireless/ath/carl9170/main.c     |  4 +-
>   drivers/net/wireless/ath/carl9170/phy.c      | 88 ++++++++++++++++++++
>   3 files changed, 92 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
> index eaac859..a2ffa62 100644
> --- a/drivers/net/wireless/ath/carl9170/carl9170.h
> +++ b/drivers/net/wireless/ath/carl9170/carl9170.h
> @@ -602,6 +602,7 @@ int carl9170_led_set_state(struct ar9170 *ar, const u32 led_state);
>   int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
>   			 enum nl80211_channel_type bw);
>   int carl9170_get_noisefloor(struct ar9170 *ar);
> +void carl9170_update_channel_maxpower(struct ar9170 *ar);
>   
>   /* FW */
>   int carl9170_parse_firmware(struct ar9170 *ar);
> diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
> index d75688c..dcedcb1 100644
> --- a/drivers/net/wireless/ath/carl9170/main.c
> +++ b/drivers/net/wireless/ath/carl9170/main.c
> @@ -89,7 +89,7 @@ struct ieee80211_rate __carl9170_ratetable[] = {
>   #define CHAN(_freq, _idx) {		\
>   	.center_freq	= (_freq),	\
>   	.hw_value	= (_idx),	\
> -	.max_power	= 18, /* XXX */	\
> +	.max_power	= 18,		\
>   }
>   
>   static struct ieee80211_channel carl9170_2ghz_chantable[] = {
> @@ -1930,6 +1930,8 @@ static int carl9170_parse_eeprom(struct ar9170 *ar)
>   	if (!bands)
>   		return -EINVAL;
>   
> +	carl9170_update_channel_maxpower(ar);
> +
>   	ar->survey = devm_kcalloc(&ar->udev->dev, chans,
>   				  sizeof(struct survey_info), GFP_KERNEL);
>   	if (!ar->survey)
> diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c
> index 34d9fd7..290c336 100644
> --- a/drivers/net/wireless/ath/carl9170/phy.c
> +++ b/drivers/net/wireless/ath/carl9170/phy.c
> @@ -1524,6 +1524,94 @@ static void carl9170_set_power_cal(struct ar9170 *ar, u32 freq,
>   	carl9170_calc_ctl(ar, freq, bw);
>   }
>   
> +static u8 carl9170_get_max_tgt_power(struct ar9170 *ar, u32 freq)
> +{
> +	struct ar9170_calibration_target_power_legacy *ctpl;
> +	int ntargets, idx, n, i;
> +	u8 f, max_power = 0;
> +	u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS];
> +
> +	if (freq < 3000)
> +		f = freq - 2300;
> +	else
> +		f = (freq - 4800) / 5;
> +
> +	/* check legacy target powers (OFDM for 2G, 5G leg) */
> +	for (i = 0; i < 2; i++) {
> +		switch (i) {
> +		case 0:
> +			if (freq >= 3000) {
> +				ctpl = &ar->eeprom.cal_tgt_pwr_5G[0];
> +				ntargets = AR5416_NUM_5G_TARGET_PWRS;
> +			} else {
> +				ctpl = &ar->eeprom.cal_tgt_pwr_2G_ofdm[0];
> +				ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
> +			}
> +			break;
> +		case 1:
> +			if (freq < 3000) {
> +				ctpl = &ar->eeprom.cal_tgt_pwr_2G_cck[0];
> +				ntargets = AR5416_NUM_2G_CCK_TARGET_PWRS;
> +			} else {
> +				continue;
> +			}
> +			break;
> +		default:
> +			continue;
> +		}
> +
> +		for (n = 0; n < ntargets; n++) {
> +			if (ctpl[n].freq == 0xff)
> +				break;
> +			pwr_freqs[n] = ctpl[n].freq;
> +		}
> +		ntargets = n;
> +		if (ntargets < 2)
> +			continue;
> +
> +		idx = carl9170_find_freq_idx(ntargets, pwr_freqs, f);
> +		for (n = 0; n < 4; n++) {
> +			u8 pwr;
> +
> +			pwr = carl9170_interpolate_u8(f,
> +						     ctpl[idx + 0].freq,
> +						     ctpl[idx + 0].power[n],
> +						     ctpl[idx + 1].freq,
> +						     ctpl[idx + 1].power[n]);
> +			max_power = max(max_power, pwr);
> +		}
> +	}
> +
> +	/* target power is in half-dBm, max_power is in dBm */
> +	return max_power / 2;
> +}
> +
> +void carl9170_update_channel_maxpower(struct ar9170 *ar)
> +{
> +	struct ieee80211_supported_band *band;
> +	int i;
> +
> +	band = ar->hw->wiphy->bands[NL80211_BAND_2GHZ];
> +	if (band) {
> +		for (i = 0; i < band->n_channels; i++) {
> +			u8 pwr = carl9170_get_max_tgt_power(ar,
> +				band->channels[i].center_freq);
> +			if (pwr)
> +				band->channels[i].max_power = pwr;
> +		}
> +	}
> +
> +	band = ar->hw->wiphy->bands[NL80211_BAND_5GHZ];
> +	if (band) {
> +		for (i = 0; i < band->n_channels; i++) {
> +			u8 pwr = carl9170_get_max_tgt_power(ar,
> +				band->channels[i].center_freq);
> +			if (pwr)
> +				band->channels[i].max_power = pwr;
> +		}
> +	}
> +}
> +
>   int carl9170_get_noisefloor(struct ar9170 *ar)
>   {
>   	static const u32 phy_regs[] = {


  reply	other threads:[~2026-03-21 19:24 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <cover.1773277728.git.mas-i@hotmail.de>
2026-03-12 10:37 ` [PATCH 01/10] carl9170: mac80211: enable Short Guard Interval for 20 MHz Masi Osmani
2026-03-21 18:41   ` Christian Lamparter
2026-03-31 19:06     ` Masi Osmani
2026-03-31 19:19     ` [PATCH v2 01/10] carl9170: mac80211: enable Short Guard Interval for 20 MHz (experimental) Masi Osmani
2026-07-17 15:06   ` (subset) [PATCH 01/10] carl9170: mac80211: enable Short Guard Interval for 20 MHz Jeff Johnson
2026-03-12 10:37 ` [PATCH 02/10] carl9170: mac80211: advertise RX STBC capability Masi Osmani
2026-03-21 18:47   ` Christian Lamparter
2026-03-31 19:06     ` Masi Osmani
2026-03-12 10:37 ` [PATCH 03/10] carl9170: mac80211: document spatial multiplexing power save handler Masi Osmani
2026-03-21 18:57   ` Christian Lamparter
2026-03-12 10:37 ` [PATCH 04/10] carl9170: rx: wire up dropped frame counter Masi Osmani
2026-03-21 19:03   ` Christian Lamparter
2026-03-31 19:06     ` Masi Osmani
2026-03-31 19:20     ` [PATCH v2 04/10] carl9170: rx: remove stale TODO comment in carl9170_rx_mac_status Masi Osmani
2026-03-12 10:38 ` [PATCH 05/10] carl9170: rx: track PHY errors via debugfs Masi Osmani
2026-03-21 20:29   ` Christian Lamparter
2026-03-12 10:38 ` [PATCH 06/10] carl9170: phy: populate per-channel TX power from EEPROM Masi Osmani
2026-03-21 19:24   ` Christian Lamparter [this message]
2026-03-31 19:06     ` Masi Osmani
2026-03-12 10:38 ` [PATCH 07/10] carl9170: main: add exponential restart backoff Masi Osmani
2026-03-21 20:42   ` Christian Lamparter
2026-03-31 18:58     ` Masi Osmani
2026-03-31 19:20     ` [PATCH v2 " Masi Osmani
2026-03-12 10:38 ` [PATCH 08/10] carl9170: phy: enable antenna diversity for 2-chain devices Masi Osmani
2026-03-21 19:53   ` Christian Lamparter
2026-03-31 18:58     ` Masi Osmani
2026-03-12 10:38 ` [PATCH 09/10] carl9170: fw: enable DFS radar detection Masi Osmani
2026-03-21 20:11   ` Christian Lamparter
2026-03-31 19:06     ` Masi Osmani
2026-04-29  4:46   ` John Scott
2026-03-12 10:38 ` [PATCH 10/10] carl9170: phy: add periodic runtime IQ calibration Masi Osmani
2026-03-21 21:25   ` Christian Lamparter
2026-03-31 19:06     ` Masi Osmani

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ec4490af-1156-41b0-9df1-770fe8be6f91@gmail.com \
    --to=chunkeey@gmail.com \
    --cc=ath9k-devel@qca.qualcomm.com \
    --cc=linux-wireless@vger.kernel.org \
    --cc=mas-i@hotmail.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.