Просмотр исходного кода

qcacmn: Extract AFC event in WMI layer

Extract the parameters of the WMI_AFC_EVENTID in WMI.

Change-Id: I086f095beb0961dfd7d3813c68e2caedf65a596d
CRs-Fixed: 3023089
Hariharan Basuthkar 4 лет назад
Родитель
Сommit
21ee351e31

+ 3 - 0
wmi/inc/wmi_unified_param.h

@@ -4571,6 +4571,9 @@ typedef enum {
 	wmi_pdev_csa_switch_count_status_event_id,
 	wmi_reg_chan_list_cc_event_id,
 	wmi_reg_chan_list_cc_ext_event_id,
+#ifdef CONFIG_AFC_SUPPORT
+	wmi_afc_event_id,
+#endif
 	wmi_offchan_data_tx_completion_event,
 	wmi_dfs_cac_complete_id,
 	wmi_dfs_radar_detection_event_id,

+ 7 - 0
wmi/inc/wmi_unified_priv.h

@@ -2101,6 +2101,13 @@ QDF_STATUS (*extract_reg_chan_list_ext_update_event)(wmi_unified_t wmi_handle,
 						     struct cur_regulatory_info
 						     *reg_info,
 						     uint32_t len);
+#ifdef CONFIG_AFC_SUPPORT
+QDF_STATUS
+(*extract_afc_event)(wmi_unified_t wmi_handle,
+		     uint8_t *evt_buf,
+		     struct afc_regulatory_info *reg_info,
+		     uint32_t len);
+#endif
 #endif
 
 QDF_STATUS (*extract_reg_11d_new_country_event)(wmi_unified_t wmi_handle,

+ 16 - 0
wmi/inc/wmi_unified_reg_api.h

@@ -54,6 +54,22 @@ QDF_STATUS wmi_extract_reg_chan_list_ext_update_event(wmi_unified_t wmi_handle,
 					uint8_t *evt_buf,
 					struct cur_regulatory_info *reg_info,
 					uint32_t len);
+
+#ifdef CONFIG_AFC_SUPPORT
+/**
+ * wmi_extract_afc_event() - function to read the contents of the AFC event
+ * @wmi_handle: wmi handle
+ * @evt_buf: event buffer
+ * @afc_info: AFC regulatory info
+ * @len: length of buffer
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS wmi_extract_afc_event(wmi_unified_t wmi_handle,
+				 uint8_t *evt_buf,
+				 struct afc_regulatory_info *afc_info,
+				 uint32_t len);
+#endif
 #endif
 
 /*

+ 17 - 0
wmi/src/wmi_unified_reg_api.c

@@ -58,6 +58,23 @@ QDF_STATUS wmi_extract_reg_chan_list_ext_update_event(
 }
 
 qdf_export_symbol(wmi_extract_reg_chan_list_ext_update_event);
+
+#ifdef CONFIG_AFC_SUPPORT
+QDF_STATUS wmi_extract_afc_event(wmi_unified_t wmi_handle,
+				 uint8_t *evt_buf,
+				 struct afc_regulatory_info *afc_info,
+				 uint32_t len)
+{
+	if (wmi_handle &&
+	    wmi_handle->ops->extract_afc_event)
+		return wmi_handle->ops->extract_afc_event(wmi_handle, evt_buf,
+							  afc_info, len);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+qdf_export_symbol(wmi_extract_afc_event);
+#endif
 #endif
 
 /*

+ 267 - 0
wmi/src/wmi_unified_tlv.c

@@ -12861,6 +12861,267 @@ static QDF_STATUS extract_reg_chan_list_ext_update_event_tlv(
 
 	return QDF_STATUS_SUCCESS;
 }
+
+#ifdef CONFIG_AFC_SUPPORT
+/**
+ * copy_afc_chan_eirp_info() - Copy the channel EIRP object from
+ * chan_eirp_power_info_hdr to the internal buffer chan_eirp_info. Since the
+ * cfi and eirp is continuously filled in chan_eirp_power_info_hdr, there is
+ * an index pointer required to store the current index of
+ * chan_eirp_power_info_hdr, to fill into the chan_eirp_info object.
+ * @chan_eirp_info: pointer to chan_eirp_info
+ * @num_chans: Number of channels
+ * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr
+ * @index: Pointer to index
+ *
+ * Return: void
+ */
+static void
+copy_afc_chan_eirp_info(struct chan_eirp_obj *chan_eirp_info,
+			uint8_t num_chans,
+			wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr,
+			uint8_t *index)
+{
+	uint8_t chan_idx;
+
+	for (chan_idx = 0; chan_idx < num_chans; chan_idx++, (*index)++) {
+		chan_eirp_info[chan_idx].cfi =
+				chan_eirp_power_info_hdr[*index].channel_cfi;
+		chan_eirp_info[chan_idx].eirp_power =
+				chan_eirp_power_info_hdr[*index].eirp_pwr;
+	}
+}
+
+/**
+ * copy_afc_chan_obj_info() - Copy the channel object from channel_info_hdr to
+ * to the internal buffer afc_chan_info.
+ * @afc_chan_info: pointer to afc_chan_info
+ * @num_chan_objs: Number of channel objects
+ * @channel_info_hdr: Pointer to channel_info_hdr
+ * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr
+ *
+ * Return: void
+ */
+static void
+copy_afc_chan_obj_info(struct afc_chan_obj *afc_chan_info,
+		       uint8_t num_chan_objs,
+		       wmi_6g_afc_channel_info *channel_info_hdr,
+		       wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr)
+{
+	uint8_t count;
+	uint8_t src_pwr_index = 0;
+
+	for (count = 0; count < num_chan_objs; count++) {
+		afc_chan_info[count].global_opclass =
+			channel_info_hdr[count].global_operating_class;
+		afc_chan_info[count].num_chans =
+					channel_info_hdr[count].num_channels;
+
+		if (afc_chan_info[count].num_chans > 0) {
+			struct chan_eirp_obj *chan_eirp_info;
+
+			chan_eirp_info =
+				qdf_mem_malloc(afc_chan_info[count].num_chans *
+					       sizeof(*chan_eirp_info));
+
+			if (!chan_eirp_info)
+				return;
+
+			copy_afc_chan_eirp_info(chan_eirp_info,
+						afc_chan_info[count].num_chans,
+						chan_eirp_power_info_hdr,
+						&src_pwr_index);
+			afc_chan_info[count].chan_eirp_info = chan_eirp_info;
+		} else {
+			wmi_err("Number of channels is zero in object idx %d",
+				count);
+		}
+	}
+}
+
+static void copy_afc_freq_obj_info(struct afc_freq_obj *afc_freq_info,
+				   uint8_t num_freq_objs,
+				   wmi_6g_afc_frequency_info *freq_info_hdr)
+{
+	uint8_t count;
+
+	for (count = 0; count < num_freq_objs; count++) {
+		afc_freq_info[count].low_freq =
+		WMI_REG_RULE_START_FREQ_GET(freq_info_hdr[count].freq_info);
+		afc_freq_info[count].high_freq =
+		WMI_REG_RULE_END_FREQ_GET(freq_info_hdr[count].freq_info);
+		afc_freq_info[count].max_psd =
+					freq_info_hdr[count].psd_power_info;
+	}
+}
+
+/**
+ * copy_afc_event_fixed_hdr_power_info() - Copy the fixed header portion of
+ * the power event info from the WMI AFC event buffer to the internal buffer
+ * power_info.
+ * @power_info: pointer to power_info
+ * @afc_power_event_hdr: pointer to afc_power_event_hdr
+ *
+ * Return: void
+ */
+static void
+copy_afc_event_fixed_hdr_power_info(
+		struct reg_fw_afc_power_event *power_info,
+		wmi_afc_power_event_param *afc_power_event_hdr)
+{
+	power_info->fw_status_code = afc_power_event_hdr->fw_status_code;
+	power_info->resp_id = afc_power_event_hdr->resp_id;
+	power_info->serv_resp_code = afc_power_event_hdr->afc_serv_resp_code;
+	power_info->afc_wfa_version =
+	WMI_AFC_WFA_MINOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version);
+	power_info->afc_wfa_version |=
+	WMI_AFC_WFA_MAJOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version);
+
+	power_info->avail_exp_time_d =
+	WMI_AVAIL_EXPIRY_TIME_DAY_GET(afc_power_event_hdr->avail_exp_time_d);
+	power_info->avail_exp_time_d |=
+	WMI_AVAIL_EXPIRY_TIME_MONTH_GET(afc_power_event_hdr->avail_exp_time_d);
+	power_info->avail_exp_time_d |=
+	WMI_AVAIL_EXPIRY_TIME_YEAR_GET(afc_power_event_hdr->avail_exp_time_d);
+
+	power_info->avail_exp_time_t =
+	WMI_AVAIL_EXPIRY_TIME_SEC_GET(afc_power_event_hdr->avail_exp_time_t);
+	power_info->avail_exp_time_t |=
+	WMI_AVAIL_EXPIRY_TIME_MINUTE_GET(afc_power_event_hdr->avail_exp_time_t);
+	power_info->avail_exp_time_t |=
+	WMI_AVAIL_EXPIRY_TIME_HOUR_GET(afc_power_event_hdr->avail_exp_time_t);
+}
+
+/**
+ * copy_power_event() - Copy the power event parameters from the AFC event
+ * buffer to the power_info within the afc_info.
+ * @afc_info: pointer to afc_info
+ * @param_buf: pointer to param_buf
+ *
+ * Return: void
+ */
+static void copy_power_event(struct afc_regulatory_info *afc_info,
+			     WMI_AFC_EVENTID_param_tlvs *param_buf)
+{
+	struct reg_fw_afc_power_event *power_info;
+	wmi_afc_power_event_param *afc_power_event_hdr;
+	struct afc_freq_obj *afc_freq_info;
+
+	power_info = qdf_mem_malloc(sizeof(*power_info));
+
+	if (!power_info)
+		return;
+
+	afc_power_event_hdr = param_buf->afc_power_event_param;
+	copy_afc_event_fixed_hdr_power_info(power_info, afc_power_event_hdr);
+	afc_info->power_info = power_info;
+
+	power_info->num_freq_objs = param_buf->num_freq_info_array;
+	if (power_info->num_freq_objs > 0) {
+		wmi_6g_afc_frequency_info *freq_info_hdr;
+
+		freq_info_hdr = param_buf->freq_info_array;
+		afc_freq_info = qdf_mem_malloc(power_info->num_freq_objs *
+					       sizeof(*afc_freq_info));
+
+		if (!afc_freq_info)
+			return;
+
+		copy_afc_freq_obj_info(afc_freq_info, power_info->num_freq_objs,
+				       freq_info_hdr);
+		power_info->afc_freq_info = afc_freq_info;
+	} else {
+		wmi_err("Number of frequency objects is zero");
+	}
+
+	power_info->num_chan_objs = param_buf->num_channel_info_array;
+	if (power_info->num_chan_objs > 0) {
+		struct afc_chan_obj *afc_chan_info;
+		wmi_6g_afc_channel_info *channel_info_hdr;
+
+		channel_info_hdr = param_buf->channel_info_array;
+		afc_chan_info = qdf_mem_malloc(power_info->num_chan_objs *
+					       sizeof(*afc_chan_info));
+
+		copy_afc_chan_obj_info(afc_chan_info,
+				       power_info->num_chan_objs,
+				       channel_info_hdr,
+				       param_buf->chan_eirp_power_info_array);
+		power_info->afc_chan_info = afc_chan_info;
+	} else {
+		wmi_err("Number of channel objects is zero");
+	}
+}
+
+static void copy_expiry_event(struct afc_regulatory_info *afc_info,
+			      WMI_AFC_EVENTID_param_tlvs *param_buf)
+{
+	struct reg_afc_expiry_event *expiry_info;
+
+	expiry_info = qdf_mem_malloc(sizeof(*expiry_info));
+
+	if (!expiry_info)
+		return;
+
+	expiry_info->request_id =
+				param_buf->expiry_event_param->request_id;
+	expiry_info->event_subtype =
+				param_buf->expiry_event_param->event_subtype;
+	afc_info->expiry_info = expiry_info;
+}
+
+/**
+ * copy_afc_event_common_info() - Copy the phy_id and event_type parameters
+ * in the AFC event. 'Common' indicates that these parameters are common for
+ * WMI_AFC_EVENT_POWER_INFO and WMI_AFC_EVENT_TIMER_EXPIRY.
+ * @wmi_handle: wmi handle
+ * @afc_info: pointer to afc_info
+ * @event_fixed_hdr: pointer to event_fixed_hdr
+ *
+ * Return: void
+ */
+static void
+copy_afc_event_common_info(wmi_unified_t wmi_handle,
+			   struct afc_regulatory_info *afc_info,
+			   wmi_afc_event_fixed_param *event_fixed_hdr)
+{
+	afc_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host(
+				wmi_handle, event_fixed_hdr->phy_id);
+	afc_info->event_type = event_fixed_hdr->event_type;
+}
+
+static QDF_STATUS extract_afc_event_tlv(wmi_unified_t wmi_handle,
+					uint8_t *evt_buf,
+					struct afc_regulatory_info *afc_info,
+					uint32_t len)
+{
+	WMI_AFC_EVENTID_param_tlvs *param_buf;
+	wmi_afc_event_fixed_param *event_fixed_hdr;
+
+	param_buf = (WMI_AFC_EVENTID_param_tlvs *)evt_buf;
+	if (!param_buf) {
+		wmi_err("Invalid AFC event buf");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	event_fixed_hdr = param_buf->fixed_param;
+	copy_afc_event_common_info(wmi_handle, afc_info, event_fixed_hdr);
+
+	switch (afc_info->event_type) {
+	case WMI_AFC_EVENT_POWER_INFO:
+		copy_power_event(afc_info, param_buf);
+		break;
+	case WMI_AFC_EVENT_TIMER_EXPIRY:
+		copy_expiry_event(afc_info, param_buf);
+		return QDF_STATUS_SUCCESS;
+	default:
+		wmi_err("Invalid event type");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
 #endif
 
 static QDF_STATUS extract_reg_chan_list_update_event_tlv(
@@ -15871,6 +16132,9 @@ struct wmi_ops tlv_ops =  {
 #ifdef CONFIG_BAND_6GHZ
 	.extract_reg_chan_list_ext_update_event =
 		extract_reg_chan_list_ext_update_event_tlv,
+#ifdef CONFIG_AFC_SUPPORT
+	.extract_afc_event = extract_afc_event_tlv,
+#endif
 #endif
 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION
 	.extract_num_rf_characterization_entries =
@@ -16242,6 +16506,9 @@ static void populate_tlv_events_id(uint32_t *event_ids)
 	event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID;
 	event_ids[wmi_reg_chan_list_cc_ext_event_id] =
 					WMI_REG_CHAN_LIST_CC_EXT_EVENTID;
+#ifdef CONFIG_AFC_SUPPORT
+	event_ids[wmi_afc_event_id] = WMI_AFC_EVENTID,
+#endif
 	event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID;
 	event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID;
 	event_ids[wmi_peer_sta_ps_statechg_event_id] =