return 0;
}
+static void ath12k_mac_parse_tx_pwr_env(struct ath12k *ar,
+ struct ath12k_link_vif *arvif)
+{
+ struct ieee80211_bss_conf *bss_conf = ath12k_mac_get_link_bss_conf(arvif);
+ struct ath12k_reg_tpc_power_info *tpc_info = &arvif->reg_tpc_info;
+ struct ieee80211_parsed_tpe_eirp *local_non_psd, *reg_non_psd;
+ struct ieee80211_parsed_tpe_psd *local_psd, *reg_psd;
+ struct ieee80211_parsed_tpe *tpe = &bss_conf->tpe;
+ enum wmi_reg_6g_client_type client_type;
+ struct ath12k_reg_info *reg_info;
+ struct ath12k_base *ab = ar->ab;
+ bool psd_valid, non_psd_valid;
+ int i;
+
+ reg_info = ab->reg_info[ar->pdev_idx];
+ client_type = reg_info->client_type;
+
+ local_psd = &tpe->psd_local[client_type];
+ reg_psd = &tpe->psd_reg_client[client_type];
+ local_non_psd = &tpe->max_local[client_type];
+ reg_non_psd = &tpe->max_reg_client[client_type];
+
+ psd_valid = local_psd->valid | reg_psd->valid;
+ non_psd_valid = local_non_psd->valid | reg_non_psd->valid;
+
+ if (!psd_valid && !non_psd_valid) {
+ ath12k_warn(ab,
+ "no transmit power envelope match client power type %d\n",
+ client_type);
+ return;
+ };
+
+ if (psd_valid) {
+ tpc_info->is_psd_power = true;
+
+ tpc_info->num_pwr_levels = max(local_psd->count,
+ reg_psd->count);
+ if (tpc_info->num_pwr_levels > ATH12K_NUM_PWR_LEVELS)
+ tpc_info->num_pwr_levels = ATH12K_NUM_PWR_LEVELS;
+
+ for (i = 0; i < tpc_info->num_pwr_levels; i++) {
+ tpc_info->tpe[i] = min(local_psd->power[i],
+ reg_psd->power[i]) / 2;
+ ath12k_dbg(ab, ATH12K_DBG_MAC,
+ "TPE PSD power[%d] : %d\n",
+ i, tpc_info->tpe[i]);
+ }
+ } else {
+ tpc_info->is_psd_power = false;
+ tpc_info->eirp_power = 0;
+
+ tpc_info->num_pwr_levels = max(local_non_psd->count,
+ reg_non_psd->count);
+ if (tpc_info->num_pwr_levels > ATH12K_NUM_PWR_LEVELS)
+ tpc_info->num_pwr_levels = ATH12K_NUM_PWR_LEVELS;
+
+ for (i = 0; i < tpc_info->num_pwr_levels; i++) {
+ tpc_info->tpe[i] = min(local_non_psd->power[i],
+ reg_non_psd->power[i]) / 2;
+ ath12k_dbg(ab, ATH12K_DBG_MAC,
+ "non PSD power[%d] : %d\n",
+ i, tpc_info->tpe[i]);
+ }
+ }
+}
+
static int
ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
"mac chanctx assign ptr %p vdev_id %i\n",
ctx, arvif->vdev_id);
+ if (ath12k_wmi_supports_6ghz_cc_ext(ar) &&
+ ctx->def.chan->band == NL80211_BAND_6GHZ &&
+ ahvif->vdev_type == WMI_VDEV_TYPE_STA)
+ ath12k_mac_parse_tx_pwr_env(ar, arvif);
+
arvif->punct_bitmap = ctx->def.punctured;
/* for some targets bss peer must be created before vdev_start */
struct ieee80211_chanctx_conf *chanctx_conf;
};
+/**
+ * struct ath12k_chan_power_info - TPE containing power info per channel chunk
+ * @chan_cfreq: channel center freq (MHz)
+ * e.g.
+ * channel 37/20 MHz, it is 6135
+ * channel 37/40 MHz, it is 6125
+ * channel 37/80 MHz, it is 6145
+ * channel 37/160 MHz, it is 6185
+ * @tx_power: transmit power (dBm)
+ */
+struct ath12k_chan_power_info {
+ u16 chan_cfreq;
+ s8 tx_power;
+};
+
+/* ath12k only deals with 320 MHz, so 16 subchannels */
+#define ATH12K_NUM_PWR_LEVELS 16
+
+/**
+ * struct ath12k_reg_tpc_power_info - regulatory TPC power info
+ * @is_psd_power: is PSD power or not
+ * @eirp_power: Maximum EIRP power (dBm), valid only if power is PSD
+ * @ap_power_type: type of power (SP/LPI/VLP)
+ * @num_pwr_levels: number of power levels
+ * @reg_max: Array of maximum TX power (dBm) per PSD value
+ * @ap_constraint_power: AP constraint power (dBm)
+ * @tpe: TPE values processed from TPE IE
+ * @chan_power_info: power info to send to firmware
+ */
+struct ath12k_reg_tpc_power_info {
+ bool is_psd_power;
+ u8 eirp_power;
+ enum wmi_reg_6g_ap_type ap_power_type;
+ u8 num_pwr_levels;
+ u8 reg_max[ATH12K_NUM_PWR_LEVELS];
+ u8 ap_constraint_power;
+ s8 tpe[ATH12K_NUM_PWR_LEVELS];
+ struct ath12k_chan_power_info chan_power_info[ATH12K_NUM_PWR_LEVELS];
+};
+
extern const struct htt_rx_ring_tlv_filter ath12k_mac_mon_status_filter_default;
#define ATH12K_SCAN_11D_INTERVAL 600000