// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 /*
- * Copyright (C) 2012-2014, 2018-2021 Intel Corporation
+ * Copyright (C) 2012-2014, 2018-2022 Intel Corporation
  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
  * Copyright (C) 2016-2017 Intel Deutschland GmbH
  */
        return res;
 }
 
+static void iwl_mvm_parse_ppe(struct iwl_mvm *mvm,
+                             struct iwl_he_pkt_ext_v2 *pkt_ext, u8 nss,
+                             u8 ru_index_bitmap, u8 *ppe, u8 ppe_pos_bit)
+{
+       int i;
+
+       /*
+       * FW currently supports only nss == MAX_HE_SUPP_NSS
+       *
+       * If nss > MAX: we can ignore values we don't support
+       * If nss < MAX: we can set zeros in other streams
+       */
+       if (nss > MAX_HE_SUPP_NSS) {
+               IWL_INFO(mvm, "Got NSS = %d - trimming to %d\n", nss,
+                        MAX_HE_SUPP_NSS);
+               nss = MAX_HE_SUPP_NSS;
+       }
+
+       for (i = 0; i < nss; i++) {
+               u8 ru_index_tmp = ru_index_bitmap << 1;
+               u8 low_th = IWL_HE_PKT_EXT_NONE, high_th = IWL_HE_PKT_EXT_NONE;
+               u8 bw;
+
+               for (bw = 0;
+                    bw < ARRAY_SIZE(pkt_ext->pkt_ext_qam_th[i]);
+                    bw++) {
+                       ru_index_tmp >>= 1;
+
+                       if (!(ru_index_tmp & 1))
+                               continue;
+
+                       high_th = iwl_mvm_he_get_ppe_val(ppe, ppe_pos_bit);
+                       ppe_pos_bit += IEEE80211_PPE_THRES_INFO_PPET_SIZE;
+                       low_th = iwl_mvm_he_get_ppe_val(ppe, ppe_pos_bit);
+                       ppe_pos_bit += IEEE80211_PPE_THRES_INFO_PPET_SIZE;
+
+                       pkt_ext->pkt_ext_qam_th[i][bw][0] = low_th;
+                       pkt_ext->pkt_ext_qam_th[i][bw][1] = high_th;
+               }
+       }
+}
+
+static void iwl_mvm_set_pkt_ext_from_he_ppe(struct iwl_mvm *mvm,
+                                           struct ieee80211_sta *sta,
+                                           struct iwl_he_pkt_ext_v2 *pkt_ext)
+{
+       u8 nss = (sta->he_cap.ppe_thres[0] & IEEE80211_PPE_THRES_NSS_MASK) + 1;
+       u8 *ppe = &sta->he_cap.ppe_thres[0];
+       u8 ru_index_bitmap =
+               u8_get_bits(*ppe,
+                           IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK);
+       /* Starting after PPE header */
+       u8 ppe_pos_bit = IEEE80211_HE_PPE_THRES_INFO_HEADER_SIZE;
+
+       iwl_mvm_parse_ppe(mvm, pkt_ext, nss, ru_index_bitmap, ppe, ppe_pos_bit);
+}
+
+static void iwl_mvm_set_pkt_ext_from_nominal_padding(struct iwl_he_pkt_ext_v2 *pkt_ext,
+                                                    u8 nominal_padding,
+                                                    u32 *flags)
+{
+       int low_th = -1;
+       int high_th = -1;
+       int i;
+
+       switch (nominal_padding) {
+       case IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_0US:
+               low_th = IWL_HE_PKT_EXT_NONE;
+               high_th = IWL_HE_PKT_EXT_NONE;
+               break;
+       case IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_8US:
+               low_th = IWL_HE_PKT_EXT_BPSK;
+               high_th = IWL_HE_PKT_EXT_NONE;
+               break;
+       case IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US:
+               low_th = IWL_HE_PKT_EXT_NONE;
+               high_th = IWL_HE_PKT_EXT_BPSK;
+               break;
+       }
+
+       /* Set the PPE thresholds accordingly */
+       if (low_th >= 0 && high_th >= 0) {
+               for (i = 0; i < MAX_HE_SUPP_NSS; i++) {
+                       u8 bw;
+
+                       for (bw = 0;
+                            bw < ARRAY_SIZE(pkt_ext->pkt_ext_qam_th[i]);
+                            bw++) {
+                               pkt_ext->pkt_ext_qam_th[i][bw][0] = low_th;
+                               pkt_ext->pkt_ext_qam_th[i][bw][1] = high_th;
+                       }
+               }
+
+               *flags |= STA_CTXT_HE_PACKET_EXT;
+       }
+}
+
 static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm,
                               struct ieee80211_vif *vif, u8 sta_id)
 {
         * Initialize the PPE thresholds to "None" (7), as described in Table
         * 9-262ac of 80211.ax/D3.0.
         */
-       memset(&sta_ctxt_cmd.pkt_ext, 7, sizeof(sta_ctxt_cmd.pkt_ext));
+       memset(&sta_ctxt_cmd.pkt_ext, IWL_HE_PKT_EXT_NONE,
+              sizeof(sta_ctxt_cmd.pkt_ext));
 
        /* If PPE Thresholds exist, parse them into a FW-familiar format. */
        if (sta->he_cap.he_cap_elem.phy_cap_info[6] &
-           IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) {
-               u8 nss = (sta->he_cap.ppe_thres[0] &
-                         IEEE80211_PPE_THRES_NSS_MASK) + 1;
-               u8 ru_index_bitmap =
-                       (sta->he_cap.ppe_thres[0] &
-                        IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK) >>
-                       IEEE80211_PPE_THRES_RU_INDEX_BITMASK_POS;
-               u8 *ppe = &sta->he_cap.ppe_thres[0];
-               u8 ppe_pos_bit = 7; /* Starting after PPE header */
-
-               /*
-                * FW currently supports only nss == MAX_HE_SUPP_NSS
-                *
-                * If nss > MAX: we can ignore values we don't support
-                * If nss < MAX: we can set zeros in other streams
-                */
-               if (nss > MAX_HE_SUPP_NSS) {
-                       IWL_INFO(mvm, "Got NSS = %d - trimming to %d\n", nss,
-                                MAX_HE_SUPP_NSS);
-                       nss = MAX_HE_SUPP_NSS;
-               }
-
-               for (i = 0; i < nss; i++) {
-                       u8 ru_index_tmp = ru_index_bitmap << 1;
-                       u8 bw;
-
-                       for (bw = 0;
-                            bw < ARRAY_SIZE(sta_ctxt_cmd.pkt_ext.pkt_ext_qam_th[i]);
-                            bw++) {
-                               ru_index_tmp >>= 1;
-                               if (!(ru_index_tmp & 1))
-                                       continue;
-
-                               sta_ctxt_cmd.pkt_ext.pkt_ext_qam_th[i][bw][1] =
-                                       iwl_mvm_he_get_ppe_val(ppe,
-                                                              ppe_pos_bit);
-                               ppe_pos_bit +=
-                                       IEEE80211_PPE_THRES_INFO_PPET_SIZE;
-                               sta_ctxt_cmd.pkt_ext.pkt_ext_qam_th[i][bw][0] =
-                                       iwl_mvm_he_get_ppe_val(ppe,
-                                                              ppe_pos_bit);
-                               ppe_pos_bit +=
-                                       IEEE80211_PPE_THRES_INFO_PPET_SIZE;
-                       }
-               }
-
+               IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) {
+               iwl_mvm_set_pkt_ext_from_he_ppe(mvm, sta,
+                                               &sta_ctxt_cmd.pkt_ext);
                flags |= STA_CTXT_HE_PACKET_EXT;
-       } else if (u8_get_bits(sta->he_cap.he_cap_elem.phy_cap_info[9],
-                              IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK)
-                  != IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_RESERVED) {
-               int low_th = -1;
-               int high_th = -1;
-
-               /* Take the PPE thresholds from the nominal padding info */
-               switch (u8_get_bits(sta->he_cap.he_cap_elem.phy_cap_info[9],
-                                   IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK)) {
-               case IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_0US:
-                       low_th = IWL_HE_PKT_EXT_NONE;
-                       high_th = IWL_HE_PKT_EXT_NONE;
-                       break;
-               case IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_8US:
-                       low_th = IWL_HE_PKT_EXT_BPSK;
-                       high_th = IWL_HE_PKT_EXT_NONE;
-                       break;
-               case IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US:
-                       low_th = IWL_HE_PKT_EXT_NONE;
-                       high_th = IWL_HE_PKT_EXT_BPSK;
-                       break;
-               }
-
-               /* Set the PPE thresholds accordingly */
-               if (low_th >= 0 && high_th >= 0) {
-                       struct iwl_he_pkt_ext_v2 *pkt_ext =
-                               &sta_ctxt_cmd.pkt_ext;
-
-                       for (i = 0; i < MAX_HE_SUPP_NSS; i++) {
-                               u8 bw;
-
-                               for (bw = 0;
-                                    bw < ARRAY_SIZE(pkt_ext->pkt_ext_qam_th[i]);
-                                    bw++) {
-                                       pkt_ext->pkt_ext_qam_th[i][bw][0] =
-                                               low_th;
-                                       pkt_ext->pkt_ext_qam_th[i][bw][1] =
-                                               high_th;
-                               }
-                       }
-
-                       flags |= STA_CTXT_HE_PACKET_EXT;
-               }
+       /* PPE Thresholds doesn't exist - set the API PPE values
+       * according to Common Nominal Packet Padding fiels. */
+       } else {
+               u8 nominal_padding =
+                       u8_get_bits(sta->he_cap.he_cap_elem.phy_cap_info[9],
+                                   IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK);
+               if (nominal_padding != IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_RESERVED)
+                       iwl_mvm_set_pkt_ext_from_nominal_padding(&sta_ctxt_cmd.pkt_ext,
+                                                                nominal_padding,
+                                                                &flags);
        }
 
        if (sta->he_cap.he_cap_elem.mac_cap_info[2] &