Skip to content

Commit a230aa2

Browse files
P Praneeshgregkh
authored andcommitted
wifi: ath12k: Fix legacy rate mapping for monitor mode capture
[ Upstream commit 616217a ] The current implementation incorrectly reports legacy CCK and OFDM rates in monitor mode radiotap headers. The rate field displays wrong values, for example showing 11 Mbps when the actual rate is 1 Mbps. This occurs because the HAL layer uses a unified enum for both CCK and OFDM rates without distinguishing between long/short preamble variants and proper rate mapping to hardware rate indices. The root cause is threefold: 1. The hal_rx_legacy_rate enum conflates CCK and OFDM rates into a single enumeration, making it impossible to differentiate between 802.11b CCK rates (with long/short preamble variants) and 802.11a/g OFDM rates. 2. The L-SIG-B parsing function maps hardware rate values to the wrong enum values. For CCK rates, it incorrectly combines long and short preamble cases (e.g., cases 2 and 5 both map to 2 Mbps), losing preamble information critical for proper rate identification. 3. The mac layer's rate-to-index conversion function does not properly handle the precedence between long preamble, short preamble, and OFDM rates when matching hardware rate values. Split the hal_rx_legacy_rate enum into two separate enumerations: hal_rx_legacy_rate for CCK rates with explicit long preamble (LP) and short preamble (SP) variants, and hal_rx_legacy_rates_ofdm for OFDM rates. This separation allows proper identification of rate types and preamble modes. Introduce a new mapping ath12k_wifi7_hal_mon_map_legacy_rate_to_hw_rate() that converts HAL CCK rate enums to hardware rate indices defined in ath12k_hw_rate_cck. This ensures the rate field in ppdu_info contains the correct hardware rate index that matches the mac layer's expectations. Update the L-SIG-B parsing to map each hardware rate value (1-7) to its corresponding CCK rate enum with proper preamble designation: - Cases 1-4: Long preamble (1, 2, 5.5, 11 Mbps) - Cases 5-7: Short preamble (2, 5.5, 11 Mbps) Update the L-SIG-A parsing to use the new OFDM-specific enum values, maintaining the existing rate mapping for 802.11a/g OFDM rates. Refactor the mac layer's ath12k_mac_hw_rate_to_idx() function to implement proper matching precedence: 1. First match OFDM rates using the IEEE80211_RATE_MANDATORY_A flag 2. Then match CCK short preamble rates 3. Finally match CCK long preamble rates as fallback Add helper macros ATH12K_MAC_RATE_A_M and ATH12K_MAC_RATE_B to improve readability of the rate table initialization and ensure the mandatory flag is set for OFDM rates. This fix ensures monitor mode captures display accurate rate information in the radiotap header, correctly distinguishing between 1 Mbps and 11 Mbps, and properly identifying preamble types for CCK rates. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01181-QCAHKSWPL_SILICONZ-1 Fixes: d889913 ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") Signed-off-by: P Praneesh <praneesh.p@oss.qualcomm.com> Signed-off-by: Thiraviyam Mariyappan <thiraviyam.mariyappan@oss.qualcomm.com> Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com> Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com> Link: https://patch.msgid.link/20260209054924.2713072-1-thiraviyam.mariyappan@oss.qualcomm.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent d2602a0 commit a230aa2

3 files changed

Lines changed: 108 additions & 50 deletions

File tree

drivers/net/wireless/ath/ath12k/hal.h

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -268,21 +268,28 @@ enum hal_rx_reception_type {
268268
};
269269

270270
enum hal_rx_legacy_rate {
271-
HAL_RX_LEGACY_RATE_1_MBPS,
272-
HAL_RX_LEGACY_RATE_2_MBPS,
273-
HAL_RX_LEGACY_RATE_5_5_MBPS,
274-
HAL_RX_LEGACY_RATE_6_MBPS,
275-
HAL_RX_LEGACY_RATE_9_MBPS,
276-
HAL_RX_LEGACY_RATE_11_MBPS,
277-
HAL_RX_LEGACY_RATE_12_MBPS,
278-
HAL_RX_LEGACY_RATE_18_MBPS,
279-
HAL_RX_LEGACY_RATE_24_MBPS,
280-
HAL_RX_LEGACY_RATE_36_MBPS,
281-
HAL_RX_LEGACY_RATE_48_MBPS,
282-
HAL_RX_LEGACY_RATE_54_MBPS,
271+
HAL_RX_LEGACY_RATE_LP_1_MBPS,
272+
HAL_RX_LEGACY_RATE_LP_2_MBPS,
273+
HAL_RX_LEGACY_RATE_LP_5_5_MBPS,
274+
HAL_RX_LEGACY_RATE_LP_11_MBPS,
275+
HAL_RX_LEGACY_RATE_SP_2_MBPS,
276+
HAL_RX_LEGACY_RATE_SP_5_5_MBPS,
277+
HAL_RX_LEGACY_RATE_SP_11_MBPS,
283278
HAL_RX_LEGACY_RATE_INVALID,
284279
};
285280

281+
enum hal_rx_legacy_rates_ofdm {
282+
HAL_RX_LEGACY_RATE_OFDM_48_MBPS,
283+
HAL_RX_LEGACY_RATE_OFDM_24_MBPS,
284+
HAL_RX_LEGACY_RATE_OFDM_12_MBPS,
285+
HAL_RX_LEGACY_RATE_OFDM_6_MBPS,
286+
HAL_RX_LEGACY_RATE_OFDM_54_MBPS,
287+
HAL_RX_LEGACY_RATE_OFDM_36_MBPS,
288+
HAL_RX_LEGACY_RATE_OFDM_18_MBPS,
289+
HAL_RX_LEGACY_RATE_OFDM_9_MBPS,
290+
HAL_RX_LEGACY_RATE_OFDM_INVALID,
291+
};
292+
286293
enum hal_ring_type {
287294
HAL_REO_DST,
288295
HAL_REO_EXCEPTION,

drivers/net/wireless/ath/ath12k/mac.c

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -164,30 +164,31 @@ static const struct ieee80211_channel ath12k_6ghz_channels[] = {
164164
CHAN6G(233, 7115, 0),
165165
};
166166

167+
#define ATH12K_MAC_RATE_A_M(bps, code) \
168+
{ .bitrate = (bps), .hw_value = (code),\
169+
.flags = IEEE80211_RATE_MANDATORY_A }
170+
171+
#define ATH12K_MAC_RATE_B(bps, code, code_short) \
172+
{ .bitrate = (bps), .hw_value = (code), .hw_value_short = (code_short),\
173+
.flags = IEEE80211_RATE_SHORT_PREAMBLE }
174+
167175
static struct ieee80211_rate ath12k_legacy_rates[] = {
168176
{ .bitrate = 10,
169177
.hw_value = ATH12K_HW_RATE_CCK_LP_1M },
170-
{ .bitrate = 20,
171-
.hw_value = ATH12K_HW_RATE_CCK_LP_2M,
172-
.hw_value_short = ATH12K_HW_RATE_CCK_SP_2M,
173-
.flags = IEEE80211_RATE_SHORT_PREAMBLE },
174-
{ .bitrate = 55,
175-
.hw_value = ATH12K_HW_RATE_CCK_LP_5_5M,
176-
.hw_value_short = ATH12K_HW_RATE_CCK_SP_5_5M,
177-
.flags = IEEE80211_RATE_SHORT_PREAMBLE },
178-
{ .bitrate = 110,
179-
.hw_value = ATH12K_HW_RATE_CCK_LP_11M,
180-
.hw_value_short = ATH12K_HW_RATE_CCK_SP_11M,
181-
.flags = IEEE80211_RATE_SHORT_PREAMBLE },
182-
183-
{ .bitrate = 60, .hw_value = ATH12K_HW_RATE_OFDM_6M },
184-
{ .bitrate = 90, .hw_value = ATH12K_HW_RATE_OFDM_9M },
185-
{ .bitrate = 120, .hw_value = ATH12K_HW_RATE_OFDM_12M },
186-
{ .bitrate = 180, .hw_value = ATH12K_HW_RATE_OFDM_18M },
187-
{ .bitrate = 240, .hw_value = ATH12K_HW_RATE_OFDM_24M },
188-
{ .bitrate = 360, .hw_value = ATH12K_HW_RATE_OFDM_36M },
189-
{ .bitrate = 480, .hw_value = ATH12K_HW_RATE_OFDM_48M },
190-
{ .bitrate = 540, .hw_value = ATH12K_HW_RATE_OFDM_54M },
178+
ATH12K_MAC_RATE_B(20, ATH12K_HW_RATE_CCK_LP_2M,
179+
ATH12K_HW_RATE_CCK_SP_2M),
180+
ATH12K_MAC_RATE_B(55, ATH12K_HW_RATE_CCK_LP_5_5M,
181+
ATH12K_HW_RATE_CCK_SP_5_5M),
182+
ATH12K_MAC_RATE_B(110, ATH12K_HW_RATE_CCK_LP_11M,
183+
ATH12K_HW_RATE_CCK_SP_11M),
184+
ATH12K_MAC_RATE_A_M(60, ATH12K_HW_RATE_OFDM_6M),
185+
ATH12K_MAC_RATE_A_M(90, ATH12K_HW_RATE_OFDM_9M),
186+
ATH12K_MAC_RATE_A_M(120, ATH12K_HW_RATE_OFDM_12M),
187+
ATH12K_MAC_RATE_A_M(180, ATH12K_HW_RATE_OFDM_18M),
188+
ATH12K_MAC_RATE_A_M(240, ATH12K_HW_RATE_OFDM_24M),
189+
ATH12K_MAC_RATE_A_M(360, ATH12K_HW_RATE_OFDM_36M),
190+
ATH12K_MAC_RATE_A_M(480, ATH12K_HW_RATE_OFDM_48M),
191+
ATH12K_MAC_RATE_A_M(540, ATH12K_HW_RATE_OFDM_54M),
191192
};
192193

193194
static const int
@@ -732,11 +733,17 @@ u8 ath12k_mac_hw_rate_to_idx(const struct ieee80211_supported_band *sband,
732733
if (ath12k_mac_bitrate_is_cck(rate->bitrate) != cck)
733734
continue;
734735

735-
if (rate->hw_value == hw_rate)
736+
/* To handle 802.11a PPDU type */
737+
if ((!cck) && (rate->hw_value == hw_rate) &&
738+
(rate->flags & IEEE80211_RATE_MANDATORY_A))
736739
return i;
740+
/* To handle 802.11b short PPDU type */
737741
else if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE &&
738742
rate->hw_value_short == hw_rate)
739743
return i;
744+
/* To handle 802.11b long PPDU type */
745+
else if (rate->hw_value == hw_rate)
746+
return i;
740747
}
741748

742749
return 0;

drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,42 @@ ath12k_wifi7_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *r
405405
}
406406
}
407407

408+
static __always_inline u8
409+
ath12k_wifi7_hal_mon_map_legacy_rate_to_hw_rate(u8 rate)
410+
{
411+
u8 ath12k_rate;
412+
413+
/* Map hal_rx_legacy_rate to ath12k_hw_rate_cck */
414+
switch (rate) {
415+
case HAL_RX_LEGACY_RATE_LP_1_MBPS:
416+
ath12k_rate = ATH12K_HW_RATE_CCK_LP_1M;
417+
break;
418+
case HAL_RX_LEGACY_RATE_LP_2_MBPS:
419+
ath12k_rate = ATH12K_HW_RATE_CCK_LP_2M;
420+
break;
421+
case HAL_RX_LEGACY_RATE_LP_5_5_MBPS:
422+
ath12k_rate = ATH12K_HW_RATE_CCK_LP_5_5M;
423+
break;
424+
case HAL_RX_LEGACY_RATE_LP_11_MBPS:
425+
ath12k_rate = ATH12K_HW_RATE_CCK_LP_11M;
426+
break;
427+
case HAL_RX_LEGACY_RATE_SP_2_MBPS:
428+
ath12k_rate = ATH12K_HW_RATE_CCK_SP_2M;
429+
break;
430+
case HAL_RX_LEGACY_RATE_SP_5_5_MBPS:
431+
ath12k_rate = ATH12K_HW_RATE_CCK_SP_5_5M;
432+
break;
433+
case HAL_RX_LEGACY_RATE_SP_11_MBPS:
434+
ath12k_rate = ATH12K_HW_RATE_CCK_SP_11M;
435+
break;
436+
default:
437+
ath12k_rate = rate;
438+
break;
439+
}
440+
441+
return ath12k_rate;
442+
}
443+
408444
static void
409445
ath12k_wifi7_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb,
410446
struct hal_rx_mon_ppdu_info *ppdu_info)
@@ -415,25 +451,32 @@ ath12k_wifi7_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb,
415451
rate = u32_get_bits(info0, HAL_RX_LSIG_B_INFO_INFO0_RATE);
416452
switch (rate) {
417453
case 1:
418-
rate = HAL_RX_LEGACY_RATE_1_MBPS;
454+
rate = HAL_RX_LEGACY_RATE_LP_1_MBPS;
419455
break;
420456
case 2:
421-
case 5:
422-
rate = HAL_RX_LEGACY_RATE_2_MBPS;
457+
rate = HAL_RX_LEGACY_RATE_LP_2_MBPS;
423458
break;
424459
case 3:
425-
case 6:
426-
rate = HAL_RX_LEGACY_RATE_5_5_MBPS;
460+
rate = HAL_RX_LEGACY_RATE_LP_5_5_MBPS;
427461
break;
428462
case 4:
463+
rate = HAL_RX_LEGACY_RATE_LP_11_MBPS;
464+
break;
465+
case 5:
466+
rate = HAL_RX_LEGACY_RATE_SP_2_MBPS;
467+
break;
468+
case 6:
469+
rate = HAL_RX_LEGACY_RATE_SP_5_5_MBPS;
470+
break;
429471
case 7:
430-
rate = HAL_RX_LEGACY_RATE_11_MBPS;
472+
rate = HAL_RX_LEGACY_RATE_SP_11_MBPS;
431473
break;
432474
default:
433475
rate = HAL_RX_LEGACY_RATE_INVALID;
476+
break;
434477
}
435478

436-
ppdu_info->rate = rate;
479+
ppdu_info->rate = ath12k_wifi7_hal_mon_map_legacy_rate_to_hw_rate(rate);
437480
ppdu_info->cck_flag = 1;
438481
}
439482

@@ -447,31 +490,32 @@ ath12k_wifi7_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga,
447490
rate = u32_get_bits(info0, HAL_RX_LSIG_A_INFO_INFO0_RATE);
448491
switch (rate) {
449492
case 8:
450-
rate = HAL_RX_LEGACY_RATE_48_MBPS;
493+
rate = HAL_RX_LEGACY_RATE_OFDM_48_MBPS;
451494
break;
452495
case 9:
453-
rate = HAL_RX_LEGACY_RATE_24_MBPS;
496+
rate = HAL_RX_LEGACY_RATE_OFDM_24_MBPS;
454497
break;
455498
case 10:
456-
rate = HAL_RX_LEGACY_RATE_12_MBPS;
499+
rate = HAL_RX_LEGACY_RATE_OFDM_12_MBPS;
457500
break;
458501
case 11:
459-
rate = HAL_RX_LEGACY_RATE_6_MBPS;
502+
rate = HAL_RX_LEGACY_RATE_OFDM_6_MBPS;
460503
break;
461504
case 12:
462-
rate = HAL_RX_LEGACY_RATE_54_MBPS;
505+
rate = HAL_RX_LEGACY_RATE_OFDM_54_MBPS;
463506
break;
464507
case 13:
465-
rate = HAL_RX_LEGACY_RATE_36_MBPS;
508+
rate = HAL_RX_LEGACY_RATE_OFDM_36_MBPS;
466509
break;
467510
case 14:
468-
rate = HAL_RX_LEGACY_RATE_18_MBPS;
511+
rate = HAL_RX_LEGACY_RATE_OFDM_18_MBPS;
469512
break;
470513
case 15:
471-
rate = HAL_RX_LEGACY_RATE_9_MBPS;
514+
rate = HAL_RX_LEGACY_RATE_OFDM_9_MBPS;
472515
break;
473516
default:
474-
rate = HAL_RX_LEGACY_RATE_INVALID;
517+
rate = HAL_RX_LEGACY_RATE_OFDM_INVALID;
518+
break;
475519
}
476520

477521
ppdu_info->rate = rate;

0 commit comments

Comments
 (0)