Browse Source

qcacld-3.0: Fix HE PPET parsing/packing for OTA frames

HE PPET is an optional field within HE Capability IE, however
current frame parser code was treating it as optiona IE and
inserting EID, length for it causing in-correct PPET values.
Fix frame parser code by treating PPET as just another data
field instead of IE.

Change-Id: I1903d99daf5eb00e47f42485886532551e061982
CRs-Fixed: 2172820
Naveen Rawat 7 years ago
parent
commit
819158d0fb

+ 4 - 5
core/hdd/src/wlan_hdd_he.c

@@ -54,7 +54,6 @@ void hdd_update_tgt_he_cap(struct hdd_context *hdd_ctx,
 			   struct wma_tgt_cfg *cfg)
 {
 	uint8_t chan_width;
-	uint32_t ppet_size = sizeof(tDot11fIEppe_threshold);
 	QDF_STATUS status;
 	tDot11fIEhe_cap *he_cap = &cfg->he_cap;
 
@@ -203,14 +202,14 @@ void hdd_update_tgt_he_cap(struct hdd_context *hdd_ctx,
 
 	/* PPET can not be configured by user - Set per band values from FW */
 	status = sme_cfg_set_str(hdd_ctx->hHal, WNI_CFG_HE_PPET_2G,
-				 (void *)&cfg->ppet_2g, ppet_size);
+				 cfg->ppet_2g, HE_MAX_PPET_SIZE);
 	if (status == QDF_STATUS_E_FAILURE)
-		hdd_alert("could not set HE PPET");
+		hdd_alert("could not set 2G HE PPET");
 
 	status = sme_cfg_set_str(hdd_ctx->hHal, WNI_CFG_HE_PPET_5G,
-				 (void *)&cfg->ppet_5g, ppet_size);
+				 cfg->ppet_5g, HE_MAX_PPET_SIZE);
 	if (status == QDF_STATUS_E_FAILURE)
-		hdd_alert("could not set HE PPET");
+		hdd_alert("could not set 5G HE PPET");
 }
 
 void wlan_hdd_check_11ax_support(struct hdd_beacon_data *beacon,

+ 9 - 0
core/mac/inc/sir_api.h

@@ -7429,6 +7429,15 @@ struct wow_enable_params {
 #define HE_PPET_SIZE 3
 #define HE_BYTE_SIZE 8
 
+struct ppet_hdr {
+	uint8_t nss:3;
+	uint8_t ru_idx_mask:4;
+	uint8_t remaining:1;
+};
+
+/* MAX PPET size = 7 bits + (max_nss X max_ru_number X 6) = 25 bytes */
+#define HE_MAX_PPET_SIZE WNI_CFG_HE_PPET_LEN
+
 #define HE_MAX_PHY_CAP_SIZE 3
 
 #define HE_CH_WIDTH_GET_BIT(ch_wd, bit)      (((ch_wd) >> (bit)) & 1)

+ 1 - 1
core/mac/inc/wni_cfg.h

@@ -413,7 +413,7 @@ enum {
 #define WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN    255
 #define WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN    255
 #define WNI_CFG_WPS_UUID_LEN    16
-#define WNI_CFG_HE_PPET_LEN 27
+#define WNI_CFG_HE_PPET_LEN     25
 
 /*
  * Integer parameter min/max/default values

+ 6 - 10
core/mac/src/cfg/cfgUtil/dot11f.frms

@@ -2808,8 +2808,6 @@ IE MeasurementRequest (EID_MEAS_REQUEST)  // 7.3.2.21
     };
 }
 
-const SUB_EID_PPET = 1;
-
 IE he_cap (EID_EXTN_ID_ELEMENT) OUI (0x23)
 {
     {
@@ -2906,15 +2904,13 @@ IE he_cap (EID_EXTN_ID_ELEMENT) OUI (0x23)
     tx_he_mcs_map_160[2][0..1] COUNTIS chan_width_2;
     rx_he_mcs_map_80_80[2][0..1] COUNTIS chan_width_3;
     tx_he_mcs_map_80_80[2][0..1] COUNTIS chan_width_3;
-    OPTIE IE ppe_threshold (SUB_EID_PPET)
+    OPTIONAL UNION ppet (DISCRIMINATOR ppet_present)
     {
-      {
-        nss_count:3;
-        ru_idx_mask:4;
-        ppet_b1:1;
-      }
-      ppet[1..24];
-    }
+        ppe_threshold (ppet_present IS 1)
+        {
+            ppe_th[1..25];
+        }
+    };
 }
 
 IE he_op (EID_EXTN_ID_ELEMENT) OUI (0x24)

+ 93 - 131
core/mac/src/include/dot11f.h

@@ -35,7 +35,7 @@
  *
  *
  * This file was automatically generated by 'framesc'
- * Tue Jan 16 10:54:27 2018 from the following file(s):
+ * Thu Jan 25 09:35:43 2018 from the following file(s):
  *
  * dot11f.frms
  *
@@ -2705,49 +2705,6 @@ uint32_t dot11f_get_packed_ie_R1KH_ID(
 }; /* End extern "C". */
 #endif /* C++ */
 
-/* EID 1 (0x01) */
-typedef struct sDot11fIEppe_threshold {
-	uint8_t             present;
-	uint8_t            nss_count:3;
-	uint8_t          ru_idx_mask:4;
-	uint8_t              ppet_b1:1;
-	uint8_t             num_ppet;
-	uint8_t             ppet[24];
-} tDot11fIEppe_threshold;
-
-#define DOT11F_EID_PPE_THRESHOLD (1)
-
-/* N.B. These #defines do *not* include the EID & length */
-#define DOT11F_IE_PPE_THRESHOLD_MIN_LEN (2)
-
-#define DOT11F_IE_PPE_THRESHOLD_MAX_LEN (25)
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* C++ */
-uint32_t dot11f_unpack_ie_ppe_threshold(
-	tpAniSirGlobal,
-	uint8_t *,
-	uint8_t,
-	tDot11fIEppe_threshold*,
-	bool);
-
-uint32_t dot11f_pack_ie_ppe_threshold(
-	tpAniSirGlobal,
-	tDot11fIEppe_threshold *,
-	uint8_t *,
-	uint32_t,
-	uint32_t*);
-
-uint32_t dot11f_get_packed_ie_ppe_threshold(
-	tpAniSirGlobal,
-	tDot11fIEppe_threshold *,
-	uint32_t*);
-
-#ifdef __cplusplus
-}; /* End extern "C". */
-#endif /* C++ */
-
 /* EID 51 (0x33) */
 typedef struct sDot11fIEAPChannelReport {
 	uint8_t             present;
@@ -8716,92 +8673,97 @@ uint32_t dot11f_get_packed_ie_fragment_ie(
 
 /* EID 255 (0xff) Extended EID 35 (0x23) */
 typedef struct sDot11fIEhe_cap {
-	uint8_t                       present;
-	uint32_t                         htc_he:1;
-	uint32_t                    twt_request:1;
-	uint32_t                  twt_responder:1;
-	uint32_t                  fragmentation:2;
-	uint32_t              max_num_frag_msdu:3;
-	uint32_t                  min_frag_size:2;
-	uint32_t            trigger_frm_mac_pad:2;
-	uint32_t                 multi_tid_aggr:3;
-	uint32_t             he_link_adaptation:2;
-	uint32_t                        all_ack:1;
-	uint32_t                ul_mu_rsp_sched:1;
-	uint32_t                          a_bsr:1;
-	uint32_t                  broadcast_twt:1;
-	uint32_t                ba_32bit_bitmap:1;
-	uint32_t                     mu_cascade:1;
-	uint32_t           ack_enabled_multitid:1;
-	uint32_t                       dl_mu_ba:1;
-	uint32_t                     omi_a_ctrl:1;
-	uint32_t                       ofdma_ra:1;
-	uint32_t                  max_ampdu_len:2;
-	uint32_t                     amsdu_frag:1;
-	uint32_t                 flex_twt_sched:1;
-	uint32_t                  rx_ctrl_frame:1;
-	uint8_t                bsrp_ampdu_aggr:1;
-	uint8_t                            qtp:1;
-	uint8_t                          a_bqr:1;
-	uint8_t                   sr_responder:1;
-	uint8_t              ndp_feedback_supp:1;
-	uint8_t                       ops_supp:1;
-	uint8_t                 amsdu_in_ampdu:1;
-	uint8_t                      reserved1:1;
-	uint32_t                      dual_band:1;
-	uint32_t                   chan_width_0:1;
-	uint32_t                   chan_width_1:1;
-	uint32_t                   chan_width_2:1;
-	uint32_t                   chan_width_3:1;
-	uint32_t                   chan_width_4:1;
-	uint32_t                   chan_width_5:1;
-	uint32_t                   chan_width_6:1;
-	uint32_t            rx_pream_puncturing:4;
-	uint32_t                   device_class:1;
-	uint32_t                    ldpc_coding:1;
-	uint32_t          he_1x_ltf_800_gi_ppdu:1;
-	uint32_t           midamble_rx_max_nsts:2;
-	uint32_t          he_4x_ltf_3200_gi_ndp:1;
-	uint32_t                  stbc_lt_80mhz:2;
-	uint32_t                        doppler:2;
-	uint32_t                          ul_mu:2;
-	uint32_t                     dcm_enc_tx:3;
-	uint32_t                     dcm_enc_rx:3;
-	uint32_t                       ul_he_mu:1;
-	uint32_t                  su_beamformer:1;
-	uint32_t                  su_beamformee:1;
-	uint32_t                  mu_beamformer:1;
-	uint32_t                 bfee_sts_lt_80:3;
-	uint32_t                 bfee_sts_gt_80:3;
-	uint32_t             num_sounding_lt_80:3;
-	uint32_t             num_sounding_gt_80:3;
-	uint32_t             su_feedback_tone16:1;
-	uint32_t             mu_feedback_tone16:1;
-	uint32_t                    codebook_su:1;
-	uint32_t                    codebook_mu:1;
-	uint32_t           beamforming_feedback:3;
-	uint32_t                  he_er_su_ppdu:1;
-	uint32_t             dl_mu_mimo_part_bw:1;
-	uint32_t                   ppet_present:1;
-	uint32_t                            srp:1;
-	uint32_t                    power_boost:1;
-	uint32_t               he_ltf_800_gi_4x:1;
-	uint32_t                         max_nc:3;
-	uint32_t                  stbc_gt_80mhz:2;
-	uint8_t            er_he_ltf_800_gi_4x:1;
-	uint8_t         he_ppdu_20_in_40Mhz_2G:1;
-	uint8_t     he_ppdu_20_in_160_80p80Mhz:1;
-	uint8_t     he_ppdu_80_in_160_80p80Mhz:1;
-	uint8_t                er_1x_he_ltf_gi:1;
-	uint8_t          midamble_rx_1x_he_ltf:1;
-	uint8_t                      reserved2:2;
-	uint16_t                      rx_he_mcs_map_lt_80;
-	uint16_t                      tx_he_mcs_map_lt_80;
-	uint8_t                       rx_he_mcs_map_160[1][2];
-	uint8_t                       tx_he_mcs_map_160[1][2];
-	uint8_t                       rx_he_mcs_map_80_80[1][2];
-	uint8_t                       tx_he_mcs_map_80_80[1][2];
-	tDot11fIEppe_threshold        ppe_threshold;
+	uint8_t             present;
+	uint32_t               htc_he:1;
+	uint32_t          twt_request:1;
+	uint32_t        twt_responder:1;
+	uint32_t        fragmentation:2;
+	uint32_t    max_num_frag_msdu:3;
+	uint32_t        min_frag_size:2;
+	uint32_t  trigger_frm_mac_pad:2;
+	uint32_t       multi_tid_aggr:3;
+	uint32_t   he_link_adaptation:2;
+	uint32_t              all_ack:1;
+	uint32_t      ul_mu_rsp_sched:1;
+	uint32_t                a_bsr:1;
+	uint32_t        broadcast_twt:1;
+	uint32_t      ba_32bit_bitmap:1;
+	uint32_t           mu_cascade:1;
+	uint32_t ack_enabled_multitid:1;
+	uint32_t             dl_mu_ba:1;
+	uint32_t           omi_a_ctrl:1;
+	uint32_t             ofdma_ra:1;
+	uint32_t        max_ampdu_len:2;
+	uint32_t           amsdu_frag:1;
+	uint32_t       flex_twt_sched:1;
+	uint32_t        rx_ctrl_frame:1;
+	uint8_t      bsrp_ampdu_aggr:1;
+	uint8_t                  qtp:1;
+	uint8_t                a_bqr:1;
+	uint8_t         sr_responder:1;
+	uint8_t    ndp_feedback_supp:1;
+	uint8_t             ops_supp:1;
+	uint8_t       amsdu_in_ampdu:1;
+	uint8_t            reserved1:1;
+	uint32_t            dual_band:1;
+	uint32_t         chan_width_0:1;
+	uint32_t         chan_width_1:1;
+	uint32_t         chan_width_2:1;
+	uint32_t         chan_width_3:1;
+	uint32_t         chan_width_4:1;
+	uint32_t         chan_width_5:1;
+	uint32_t         chan_width_6:1;
+	uint32_t  rx_pream_puncturing:4;
+	uint32_t         device_class:1;
+	uint32_t          ldpc_coding:1;
+	uint32_t he_1x_ltf_800_gi_ppdu:1;
+	uint32_t midamble_rx_max_nsts:2;
+	uint32_t he_4x_ltf_3200_gi_ndp:1;
+	uint32_t        stbc_lt_80mhz:2;
+	uint32_t              doppler:2;
+	uint32_t                ul_mu:2;
+	uint32_t           dcm_enc_tx:3;
+	uint32_t           dcm_enc_rx:3;
+	uint32_t             ul_he_mu:1;
+	uint32_t        su_beamformer:1;
+	uint32_t        su_beamformee:1;
+	uint32_t        mu_beamformer:1;
+	uint32_t       bfee_sts_lt_80:3;
+	uint32_t       bfee_sts_gt_80:3;
+	uint32_t   num_sounding_lt_80:3;
+	uint32_t   num_sounding_gt_80:3;
+	uint32_t   su_feedback_tone16:1;
+	uint32_t   mu_feedback_tone16:1;
+	uint32_t          codebook_su:1;
+	uint32_t          codebook_mu:1;
+	uint32_t beamforming_feedback:3;
+	uint32_t        he_er_su_ppdu:1;
+	uint32_t   dl_mu_mimo_part_bw:1;
+	uint32_t         ppet_present:1;
+	uint32_t                  srp:1;
+	uint32_t          power_boost:1;
+	uint32_t     he_ltf_800_gi_4x:1;
+	uint32_t               max_nc:3;
+	uint32_t        stbc_gt_80mhz:2;
+	uint8_t  er_he_ltf_800_gi_4x:1;
+	uint8_t he_ppdu_20_in_40Mhz_2G:1;
+	uint8_t he_ppdu_20_in_160_80p80Mhz:1;
+	uint8_t he_ppdu_80_in_160_80p80Mhz:1;
+	uint8_t      er_1x_he_ltf_gi:1;
+	uint8_t midamble_rx_1x_he_ltf:1;
+	uint8_t            reserved2:2;
+	uint16_t            rx_he_mcs_map_lt_80;
+	uint16_t            tx_he_mcs_map_lt_80;
+	uint8_t             rx_he_mcs_map_160[1][2];
+	uint8_t             tx_he_mcs_map_160[1][2];
+	uint8_t             rx_he_mcs_map_80_80[1][2];
+	uint8_t             tx_he_mcs_map_80_80[1][2];
+	union {
+		struct {
+			uint8_t num_ppe_th;
+			uint8_t ppe_th[25];
+		} ppe_threshold; /* ppet_present = 1 */
+	} ppet;
 } tDot11fIEhe_cap;
 
 #define DOT11F_EID_HE_CAP (255)
@@ -8809,7 +8771,7 @@ typedef struct sDot11fIEhe_cap {
 /* N.B. These #defines do *not* include the EID & length */
 #define DOT11F_IE_HE_CAP_MIN_LEN (18)
 
-#define DOT11F_IE_HE_CAP_MAX_LEN (53)
+#define DOT11F_IE_HE_CAP_MAX_LEN (51)
 
 #ifdef __cplusplus
 extern "C" {

+ 16 - 0
core/mac/src/include/parser_api.h

@@ -1223,4 +1223,20 @@ uint32_t sir_unpack_beacon_ie(tpAniSirGlobal mac_ctx, uint8_t *buf,
 				       uint32_t buf_len,
 				       tDot11fBeaconIEs *frame, bool append_ie);
 
+/**
+ * lim_truncate_ppet: truncates ppet of trailling zeros
+ * @ppet: ppet to truncate
+ * max_len: max length of ppet
+ *
+ * Return: new length after truncation
+ */
+static inline uint32_t lim_truncate_ppet(uint8_t *ppet, uint32_t max_len)
+{
+	while (max_len) {
+		if (ppet[max_len - 1])
+			break;
+		max_len--;
+	}
+	return max_len;
+}
 #endif /* __PARSE_H__ */

+ 5 - 14
core/mac/src/pe/lim/lim_utils.c

@@ -7391,6 +7391,7 @@ void lim_copy_join_req_he_cap(tpPESession session,
 void lim_log_he_cap(tpAniSirGlobal mac, tDot11fIEhe_cap *he_cap)
 {
 	uint8_t chan_width;
+	struct ppet_hdr *hdr;
 
 	if (!he_cap->present)
 		return;
@@ -7530,22 +7531,12 @@ void lim_log_he_cap(tpAniSirGlobal mac, tDot11fIEhe_cap *he_cap)
 	pe_debug("\tTx MCS map for <= 80+80 Mhz: 0x%04x",
 		*((uint16_t *)he_cap->tx_he_mcs_map_80_80));
 
-	pe_debug("\t ppe_th:  present: %d, nss_count: %d, ru_idx_msk: %d",
-		he_cap->ppe_threshold.present,
-		he_cap->ppe_threshold.nss_count,
-		he_cap->ppe_threshold.ru_idx_mask);
+	hdr = (struct ppet_hdr *)&he_cap->ppet;
+	pe_debug("\t ppe_th:: nss_count: %d, ru_idx_msk: %d",
+		hdr->nss, hdr->ru_idx_mask);
 
 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
-		&he_cap->ppe_threshold, sizeof(tDot11fIEppe_threshold));
-
-	/* HE PPET */
-	if (!he_cap->ppet_present)
-		return;
-
-	if (!he_cap->ppe_threshold.present) {
-		pe_debug(FL("PPET is not present. Invalid IE"));
-		return;
-	}
+		&he_cap->ppet, HE_MAX_PPET_SIZE);
 }
 
 void lim_log_he_op(tpAniSirGlobal mac, tDot11fIEhe_op *he_ops)

File diff suppressed because it is too large
+ 218 - 257
core/mac/src/sys/legacy/src/utils/src/dot11f.c


+ 15 - 5
core/mac/src/sys/legacy/src/utils/src/parser_api.c

@@ -2842,6 +2842,8 @@ sir_convert_assoc_req_frame2_struct(tpAniSirGlobal pMac,
 		qdf_mem_copy(&pAssocReq->he_cap, &ar->he_cap,
 			     sizeof(tDot11fIEhe_cap));
 		pe_debug("Received Assoc Req with HE Capability IE");
+		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+				   &pAssocReq->he_cap, sizeof(tDot11fIEhe_cap));
 	}
 	qdf_mem_free(ar);
 	return eSIR_SUCCESS;
@@ -6111,6 +6113,7 @@ tSirRetStatus populate_dot11f_timing_advert_frame(tpAniSirGlobal mac_ctx,
 QDF_STATUS populate_dot11f_he_caps(tpAniSirGlobal mac_ctx, tpPESession session,
 				   tDot11fIEhe_cap *he_cap)
 {
+	uint8_t *ppet;
 	uint32_t value = 0;
 	tSirRetStatus status;
 
@@ -6294,9 +6297,13 @@ QDF_STATUS populate_dot11f_he_caps(tpAniSirGlobal mac_ctx, tpPESession session,
 			value = WNI_CFG_HE_PPET_LEN;
 			/* if session less then take 5g cap */
 			CFG_GET_STR(status, mac_ctx, WNI_CFG_HE_PPET_5G,
-				(void *)&he_cap->ppe_threshold, value, value);
+				    he_cap->ppet.ppe_threshold.ppe_th,
+				    value, value);
+			ppet = he_cap->ppet.ppe_threshold.ppe_th;
+			he_cap->ppet.ppe_threshold.num_ppe_th =
+						lim_truncate_ppet(ppet, value);
 		} else {
-			he_cap->ppe_threshold.present = false;
+			he_cap->ppet.ppe_threshold.num_ppe_th = 0;
 		}
 
 		return QDF_STATUS_SUCCESS;
@@ -6308,14 +6315,17 @@ QDF_STATUS populate_dot11f_he_caps(tpAniSirGlobal mac_ctx, tpPESession session,
 		/* if session is present, populate PPET based on band */
 		if (IS_5G_CH(session->currentOperChannel))
 			CFG_GET_STR(status, mac_ctx, WNI_CFG_HE_PPET_5G,
-				    (void *)&he_cap->ppe_threshold,
+				    he_cap->ppet.ppe_threshold.ppe_th,
 				    value, value);
 		else
 			CFG_GET_STR(status, mac_ctx, WNI_CFG_HE_PPET_2G,
-				    (void *)&he_cap->ppe_threshold,
+				    he_cap->ppet.ppe_threshold.ppe_th,
 				    value, value);
+		ppet = he_cap->ppet.ppe_threshold.ppe_th;
+		he_cap->ppet.ppe_threshold.num_ppe_th =
+						lim_truncate_ppet(ppet, value);
 	} else {
-		he_cap->ppe_threshold.present = false;
+		he_cap->ppet.ppe_threshold.num_ppe_th = 0;
 	}
 
 	lim_log_he_cap(mac_ctx, he_cap);

+ 5 - 2
core/sme/src/csr/csr_api_roam.c

@@ -2497,9 +2497,12 @@ static void csr_update_session_he_cap(tpAniSirGlobal mac_ctx,
 		value = WNI_CFG_HE_PPET_LEN;
 		/* till now operating channel is not decided yet, use 5g cap */
 		sme_cfg_get_str(mac_ctx, WNI_CFG_HE_PPET_5G,
-			(void *)&he_cap->ppe_threshold, &value);
+				he_cap->ppet.ppe_threshold.ppe_th, &value);
+		he_cap->ppet.ppe_threshold.num_ppe_th =
+			lim_truncate_ppet(he_cap->ppet.ppe_threshold.ppe_th,
+					  value);
 	} else {
-		he_cap->ppe_threshold.present = false;
+		he_cap->ppet.ppe_threshold.num_ppe_th = 0;
 	}
 	sme_cfg_get_int(mac_ctx, WNI_CFG_HE_STA_OBSSPD, &value);
 	session->he_sta_obsspd = value;

+ 2 - 2
core/wma/inc/wma_tgt_cfg.h

@@ -191,8 +191,8 @@ struct wma_tgt_cfg {
 	uint16_t wmi_max_len;
 #ifdef WLAN_FEATURE_11AX
 	tDot11fIEhe_cap he_cap;
-	tDot11fIEppe_threshold ppet_2g;
-	tDot11fIEppe_threshold ppet_5g;
+	uint8_t ppet_2g[HE_MAX_PPET_SIZE];
+	uint8_t ppet_5g[HE_MAX_PPET_SIZE];
 #endif
 	bool dfs_cac_offload;
 	bool tx_bfee_8ss_enabled;

+ 36 - 65
core/wma/src/wma_he.c

@@ -71,7 +71,7 @@ static void wma_he_ppet_merge(uint8_t *host_ppet, int *byte_idx_p, int *used_p,
 }
 
 /**
- * wma_he_find_ppet() - Helper function for PPET conversion
+ * wma_he_populate_ppet() - Helper function for PPET conversion
  * @ppet: pointer to fw array
  * @nss: Number of NSS
  * @ru: Number of RU
@@ -84,8 +84,8 @@ static void wma_he_ppet_merge(uint8_t *host_ppet, int *byte_idx_p, int *used_p,
  *
  * Return: None
  */
-static void wma_he_find_ppet(uint32_t *ppet, int nss, int ru,
-			     uint8_t *host_ppet, int req_byte)
+static void wma_he_populate_ppet(uint32_t *ppet, int nss, int ru,
+				 uint8_t *host_ppet, int req_byte)
 {
 	int byte_idx = 0, used, i, j;
 	uint8_t ppet16, ppet8;
@@ -119,23 +119,25 @@ static void wma_he_find_ppet(uint32_t *ppet, int nss, int ru,
  *
  * Return: None
  */
-static void wma_convert_he_ppet(tDot11fIEppe_threshold *he_ppet,
+static void wma_convert_he_ppet(uint8_t *he_ppet,
 				struct wmi_host_ppe_threshold *ppet)
 {
 	int bits, req_byte;
-	uint8_t *host_ppet, ru_count, mask;
+	struct ppet_hdr *hdr;
+	uint8_t ru_count, mask;
+	struct ppe_threshold *ppet_1;
 
+	ppet_1 = NULL;
 	if (!ppet) {
 		WMA_LOGE(FL("PPET is NULL"));
-		he_ppet->present = false;
+		qdf_mem_zero(he_ppet, HE_MAX_PPET_SIZE);
 		return;
 	}
 
-	he_ppet->present = true;
-	he_ppet->nss_count = ppet->numss_m1;
-	he_ppet->ru_idx_mask = ppet->ru_bit_mask;
-
-	mask = he_ppet->ru_idx_mask;
+	hdr = (struct ppet_hdr *)he_ppet;
+	hdr->nss = ppet->numss_m1;
+	hdr->ru_idx_mask = ppet->ru_bit_mask;
+	mask = hdr->ru_idx_mask;
 	for (ru_count = 0; mask; mask >>= 1)
 		if (mask & 0x01)
 			ru_count++;
@@ -144,33 +146,12 @@ static void wma_convert_he_ppet(tDot11fIEppe_threshold *he_ppet,
 	 * there will be two PPET for each NSS/RU pair
 	 * PPET8 and PPET16, hence HE_PPET_SIZE * 2 bits for PPET
 	 */
-	bits = HE_PPET_NSS_RU_LEN + ((he_ppet->nss_count + 1) * ru_count) *
+	bits = HE_PPET_NSS_RU_LEN + ((hdr->nss + 1) * ru_count) *
 				     (HE_PPET_SIZE * 2);
 
 	req_byte = (bits / HE_BYTE_SIZE) + 1;
-
-	host_ppet = qdf_mem_malloc(sizeof(*host_ppet) * req_byte);
-	if (!host_ppet) {
-		WMA_LOGE(FL("mem alloc failed for host_ppet"));
-		he_ppet->present = false;
-		return;
-	}
-
-	wma_he_find_ppet(ppet->ppet16_ppet8_ru3_ru0, he_ppet->nss_count + 1,
-			 ru_count, host_ppet, req_byte);
-
-	he_ppet->ppet_b1 = (host_ppet[0] << HE_PPET_NSS_RU_LEN);
-
-	/*
-	 * req_byte calculates total bytes, num_ppet stores only the bytes
-	 * going into ppet data member in he_ppet. -1 to exclude the byte
-	 * storing nss/ru and first PPET16.
-	 */
-	he_ppet->num_ppet = req_byte - 1;
-	if (he_ppet->num_ppet > 0)
-		qdf_mem_copy(he_ppet->ppet, &host_ppet[1], he_ppet->num_ppet);
-
-	qdf_mem_free(host_ppet);
+	wma_he_populate_ppet(ppet->ppet16_ppet8_ru3_ru0, hdr->nss + 1,
+			 ru_count, he_ppet, req_byte);
 }
 
 /**
@@ -526,6 +507,7 @@ static void wma_derive_ext_he_cap(t_wma_handle *wma_handle,
 void wma_print_he_cap(tDot11fIEhe_cap *he_cap)
 {
 	uint8_t chan_width;
+	struct ppet_hdr *hdr;
 
 	if (!he_cap->present) {
 		WMA_LOGI(FL("HE Capabilities not present"));
@@ -644,12 +626,14 @@ void wma_print_he_cap(tDot11fIEhe_cap *he_cap)
 	WMA_LOGD("\tTx MCS MAP for BW = 80 + 80 MHz: 0x%x",
 		*((uint16_t *)he_cap->tx_he_mcs_map_80_80));
 
+	hdr = (struct ppet_hdr *)&he_cap->ppet.ppe_threshold.ppe_th[0];
 	/* HE PPET */
-	WMA_LOGD("\tNSS: %d", he_cap->ppe_threshold.nss_count + 1);
-	WMA_LOGD("\tRU Index mask: 0x%04x", he_cap->ppe_threshold.ru_idx_mask);
-	WMA_LOGD("\tnum_ppet: %d", he_cap->ppe_threshold.num_ppet);
+	WMA_LOGD("\tNSS: %d", hdr->nss + 1);
+	WMA_LOGD("\tRU Index mask: 0x%04x", hdr->ru_idx_mask);
+	WMA_LOGD("\tnum_ppet: %d", he_cap->ppet.ppe_threshold.num_ppe_th);
 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
-		he_cap->ppe_threshold.ppet, he_cap->ppe_threshold.num_ppet);
+		he_cap->ppet.ppe_threshold.ppe_th,
+		he_cap->ppet.ppe_threshold.num_ppe_th);
 }
 
 void wma_print_he_ppet(void *he_ppet)
@@ -877,7 +861,7 @@ void wma_update_target_ext_he_cap(tp_wma_handle wma_handle,
 				WMA_LOGD(FL("2g phy: nss: %d, ru_idx_msk: %d"),
 					mac_cap->he_ppet2G.numss_m1,
 					mac_cap->he_ppet2G.ru_mask);
-				wma_convert_he_ppet(&tgt_cfg->ppet_2g,
+				wma_convert_he_ppet(tgt_cfg->ppet_2g,
 					(struct wmi_host_ppe_threshold *)
 					&mac_cap->he_ppet2G);
 			}
@@ -898,7 +882,7 @@ void wma_update_target_ext_he_cap(tp_wma_handle wma_handle,
 				WMA_LOGD(FL("5g phy: nss: %d, ru_idx_msk: %d"),
 					mac_cap->he_ppet2G.numss_m1,
 					mac_cap->he_ppet2G.ru_mask);
-				wma_convert_he_ppet(&tgt_cfg->ppet_5g,
+				wma_convert_he_ppet(tgt_cfg->ppet_5g,
 					(struct wmi_host_ppe_threshold *)
 					&mac_cap->he_ppet5G);
 			}
@@ -938,7 +922,7 @@ void wma_print_he_op(tDot11fIEhe_op *he_ops)
 /**
  * wma_parse_he_ppet() - Convert PPET stored in dot11f structure into FW
  *                       structure.
- * @dot11f_ppet: pointer to dot11f format PPET
+ * @rcvd_ppet: pointer to dot11f format PPET
  * @peer_ppet: pointer peer_ppet to be sent in peer assoc
  *
  * This function converts the sequence of PPET stored in the host in OTA type
@@ -947,19 +931,22 @@ void wma_print_he_op(tDot11fIEhe_op *he_ops)
  *
  * Return: None
  */
-static void wma_parse_he_ppet(tDot11fIEppe_threshold *dot11f_ppet,
+static void wma_parse_he_ppet(int8_t *rcvd_ppet,
 			      struct wmi_host_ppe_threshold *peer_ppet)
 {
+	struct ppet_hdr *hdr;
 	uint8_t num_ppet, mask, mask1, mask2;
 	uint32_t ppet1, ppet2, ppet;
 	uint8_t bits, pad, pad_bits, req_byte;
 	uint8_t byte_idx, start, i, j, parsed;
 	uint32_t *ppet_r = peer_ppet->ppet16_ppet8_ru3_ru0;
-	uint8_t *rcvd_ppet;
 	uint8_t nss, ru;
 
-	nss = dot11f_ppet->nss_count + 1;
-	mask = dot11f_ppet->ru_idx_mask;
+	hdr = (struct ppet_hdr *)rcvd_ppet;
+	nss = hdr->nss + 1;
+	mask = hdr->ru_idx_mask;
+	peer_ppet->numss_m1 = nss - 1;
+	peer_ppet->ru_bit_mask = mask;
 
 	for (ru = 0; mask; mask >>= 1) {
 		if (mask & 0x1)
@@ -967,21 +954,7 @@ static void wma_parse_he_ppet(tDot11fIEppe_threshold *dot11f_ppet,
 	}
 
 	WMA_LOGD(FL("Rcvd nss=%d ru_idx_mask: %0x ru_count=%d"),
-		 nss, mask, ru);
-
-	/* rcvd_ppet will store the ppet array and first byte of the ppet */
-	rcvd_ppet = qdf_mem_malloc(sizeof(*rcvd_ppet) *
-				  (dot11f_ppet->num_ppet + 1));
-	if (!rcvd_ppet) {
-		WMA_LOGE(FL("mem alloc failed"));
-		return;
-	}
-
-	rcvd_ppet[0] = (dot11f_ppet->ppet_b1 << 7);
-	qdf_mem_copy(&rcvd_ppet[1], dot11f_ppet->ppet, dot11f_ppet->num_ppet);
-
-	peer_ppet->numss_m1 = nss - 1;
-	peer_ppet->ru_bit_mask = dot11f_ppet->ru_idx_mask;
+		 nss, hdr->ru_idx_mask, ru);
 
 	/* each nss-ru pair have 2 PPET (PPET8/PPET16) */
 	bits = HE_PPET_NSS_RU_LEN + (nss + ru) * (HE_PPET_SIZE * 2);
@@ -1006,7 +979,7 @@ static void wma_parse_he_ppet(tDot11fIEppe_threshold *dot11f_ppet,
 	 */
 
 	/* first bit of first PPET is in the last bit of first byte */
-	parsed = 7;
+	parsed = HE_PPET_NSS_RU_LEN;
 
 	/*
 	 * refer wmi_ppe_threshold defn to understand how ppet is stored.
@@ -1038,8 +1011,6 @@ static void wma_parse_he_ppet(tDot11fIEppe_threshold *dot11f_ppet,
 				 ppet_r[i]);
 		}
 	}
-
-	qdf_mem_free(rcvd_ppet);
 }
 
 void wma_populate_peer_he_cap(struct peer_assoc_params *peer,
@@ -1195,7 +1166,7 @@ void wma_populate_peer_he_cap(struct peer_assoc_params *peer,
 	WMI_HEOPS_BSSCOLORDISABLE_SET(he_ops, he_op->bss_col_disabled);
 	peer->peer_he_ops = he_ops;
 
-	wma_parse_he_ppet(&he_cap->ppe_threshold, &peer->peer_ppet);
+	wma_parse_he_ppet(he_cap->ppet.ppe_threshold.ppe_th, &peer->peer_ppet);
 
 	wma_print_he_cap(he_cap);
 	WMA_LOGD(FL("Peer HE Capabilities:"));

Some files were not shown because too many files changed in this diff