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[] = {
next prev parent reply other threads:[~2026-03-21 19:24 UTC|newest]
Thread overview: 20+ 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-12 10:37 ` [PATCH 02/10] carl9170: mac80211: advertise RX STBC capability Masi Osmani
2026-03-21 18:47 ` Christian Lamparter
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-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-12 10:38 ` [PATCH 07/10] carl9170: main: add exponential restart backoff Masi Osmani
2026-03-21 20:42 ` Christian Lamparter
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-12 10:38 ` [PATCH 09/10] carl9170: fw: enable DFS radar detection Masi Osmani
2026-03-21 20:11 ` Christian Lamparter
2026-03-12 10:38 ` [PATCH 10/10] carl9170: phy: add periodic runtime IQ calibration Masi Osmani
2026-03-21 21:25 ` Christian Lamparter
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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox