瀏覽代碼

qcacmn: Unpack AFC structures

During initial AFC development it was assumed that AFC object would travel
till an application endpoint outside the driver, presumably till an
application of a different machine anything in the internet and therefore,
a packed and well formatted structure was propped for the AFC object.
However, when the AFC object leaves the driver, it is converted to an
object that has NL80211 TLVs to represent it. Therefore, the packed
AFC-request object is no longer a necessity. Moreover, since an unpacked
structure (or structures) is speed/time optimized, modify the packed
structures into unpacked structures.

Change-Id: I08db1911a355b6eebffa0e13def547c98ddf38d3
CRs-Fixed: 3431997
Vignesh U 2 年之前
父節點
當前提交
5dc7fe9a25

+ 33 - 69
umac/cmn_services/regulatory/inc/wlan_reg_afc.h

@@ -26,51 +26,28 @@
  * byte order
  */
 
-/**
- * struct wlan_afc_host_req_fixed_params - Structure to send the list of AFC
- *                                          requests to AFC app to query the
- *                                          AFC server.
- *
- * @req_id:        Unique request ID from FW to be used as AFC request ID
- *                 to server.
- * @version_minor: Lower 16 bits for the AFC request version.
- * @version_major: Higher 16 bits for the AFC request version.
- * @req_length:    Length of entire AFC request message.
- * @min_des_power: Minimum desired power(in dbm) for queried spectrum.
- */
-struct wlan_afc_host_req_fixed_params {
-	uint64_t req_id;
-	uint16_t version_minor;
-	uint16_t version_major;
-	uint16_t req_length;
-	int16_t  min_des_power;
-} qdf_packed;
-
 /**
  * struct wlan_afc_freq_range_obj - Structure for frequency range query.
- *
  * @lowfreq:  Lower limit(in MHz) for frequency range query.
  * @highfreq: Higher limit(in MHz) for frequency range query.
  */
 struct wlan_afc_freq_range_obj {
 	uint16_t lowfreq;
 	uint16_t highfreq;
-} qdf_packed;
+};
 
 /**
  * struct wlan_afc_frange_list - Structure to send freq range list to AFC app.
- *
  * @num_ranges: Number of queried frequency ranges.
  * @range_objs: List of queried frequency ranges.
  */
 struct wlan_afc_frange_list {
 	uint32_t num_ranges;
-	struct wlan_afc_freq_range_obj range_objs[0];
-} qdf_packed;
+	struct wlan_afc_freq_range_obj *range_objs;
+};
 
 /**
  * struct wlan_afc_opclass_obj - Structure for opclass/channel query.
- *
  * @opclass_num_cfis: Number of channels to be required for given opclass.
  * @opclass:          Operating class to be queried.
  * @cfis:             List of Channels to be queried for given Global opclass.
@@ -78,45 +55,43 @@ struct wlan_afc_frange_list {
 struct wlan_afc_opclass_obj {
 	uint8_t opclass_num_cfis;
 	uint8_t opclass;
-	uint8_t cfis[0];
-} qdf_packed;
+	uint8_t *cfis;
+};
 
 /**
- * struct wlan_afc_num_opclasses - Structure for opclass list
- *
- * @num_opclasses: Number of opclass to be queried.
- */
-struct wlan_afc_num_opclasses {
-	uint8_t num_opclasses;
-} qdf_packed;
+ * struct wlan_afc_opclass_obj_list - Structure to send opclass object list
+ * to AFC app.
+ * @num_opclass_objs: Number of opclass objects.
+ * @opclass_objs: Pointer to list of opclass objects.
+ */
+struct wlan_afc_opclass_obj_list {
+	uint8_t num_opclass_objs;
+	struct wlan_afc_opclass_obj *opclass_objs;
+};
 
 /**
- * struct wlan_afc_host_partial_request - Structure to send AFC request info
- *
- * @fixed_params: AFC request fixed params (req_id, length, min_des_power)
- *
- * The following is the layout of the AFC host request
- * It is not a C structure as some of the structures are not of fixed size.
- *
- * struct wlan_afc_host_partial_request {
- *      <fixed-size>    struct wlan_afc_host_req_fixed_params fixed_parms;
- *      <variable-size> struct wlan_afc_freq_list freq_lst;
- *      <fixed-size>    struct wlan_afc_num_opclasses opclss_list_size;
- *      <variable-size> struct wlan_afc_opclass_obj obj[0];
- *      <variable-size> struct wlan_afc_opclass_obj obj[1];
- *      ....
- *      <variable-size> struct wlan_afc_opclass_obj obj[opclass_list_size-1];
- *      <fixed-size>    struct wlan_afc_location afc_location;
- * };
+ * struct wlan_afc_host_request - Structure to send AFC request info.
+ * @req_id:        Unique request ID from FW to be used as AFC request ID
+ *                 to server.
+ * @version_minor: Lower 16 bits for the AFC request version.
+ * @version_major: Higher 16 bits for the AFC request version.
+ * @min_des_power: Minimum desired power(in dbm) for queried spectrum.
+ * @freq_lst: Pointer to the list of frequency ranges.
+ * @opclass_obj_lst: Pointer to opclass objects list.
+ * @afc_location: Pointer to the AFC location structure,
  */
-struct wlan_afc_host_partial_request {
-	struct wlan_afc_host_req_fixed_params fixed_params;
-	/* Other structures to follow. See the layout in the comment above */
-} qdf_packed;
+struct wlan_afc_host_request {
+	uint64_t req_id;
+	uint16_t version_minor;
+	uint16_t version_major;
+	int16_t  min_des_power;
+	struct wlan_afc_frange_list *freq_lst;
+	struct wlan_afc_opclass_obj_list *opclass_obj_lst;
+	struct wlan_afc_location *afc_location;
+};
 
 /**
  * enum reg_afc_dev_deploy_type - Deployment type of AP
- *
  * @AFC_DEPLOYMENT_UNKNOWN: Unknown
  * @AFC_DEPLOYMENT_INDOOR: Located Indoor
  * @AFC_DEPLOYMENT_OUTDOOR: Located Outdoor
@@ -129,7 +104,6 @@ enum reg_afc_dev_deploy_type {
 
 /**
  * enum afc_object_type - AFC Request object types
- *
  * @AFC_OBJ_LOCATION: Location object
  */
 enum afc_object_type {
@@ -138,20 +112,14 @@ enum afc_object_type {
 
 /**
  * struct wlan_afc_location - Structure for afc location info.
- *
- * @afc_elem_type: AFC element type of enum afc_object_type
- * @afc_elem_len: AFC element length
  * @deployment_type: Deployment type of enum reg_afc_dev_deploy_type
  */
 struct wlan_afc_location {
-	uint32_t afc_elem_type;
-	uint32_t afc_elem_len;
 	uint32_t deployment_type;
-} qdf_packed;
+};
 
 /**
  * struct wlan_afc_host_resp - Structure for AFC Host response to FW
- *
  * @header:       Header for compatibility.
  *                Valid value: 0
  * @status:       Flag to indicate validity of data. To be updated by TZ
@@ -208,7 +176,6 @@ struct wlan_afc_host_resp {
  * struct wlan_afc_resp_opclass_info - Structure to populate operating class
  *                                     and channel information from AFC
  *                                     response.
- *
  * @opclass:        Operating class
  * @num_channels:   Number of channels received in AFC response
  */
@@ -219,7 +186,6 @@ struct wlan_afc_resp_opclass_info {
 
 /**
  * struct wlan_afc_resp_eirp_info - Structure to update EIRP values for channels
- *
  * @channel_cfi:  Channel center frequency index
  * @max_eirp_pwr: Maximum permissible EIRP(in dBm) for the Channel
  */
@@ -231,7 +197,6 @@ struct wlan_afc_resp_eirp_info {
 /**
  * struct wlan_afc_resp_freq_psd_info - Structure to update PSD values for
  *                                      queried frequency ranges
- *
  * @freq_info: Frequency range in MHz:- bits 15:0  = u16 start_freq,
  *                                      bits 31:16 = u16 end_freq
  * @max_psd:   Maximum PSD in dbm/MHz
@@ -243,7 +208,6 @@ struct wlan_afc_resp_freq_psd_info {
 
 /**
  * struct wlan_afc_bin_resp_data - Structure to populate AFC binary response
- *
  * @local_err_code:     Internal error code between AFC app and FW
  *                      0 - Success
  *                      1 - General failure

+ 343 - 286
umac/regulatory/core/src/reg_services_common.c

@@ -7086,116 +7086,16 @@ static void reg_cp_freq_ranges(struct wlan_objmgr_pdev *pdev,
 }
 
 /**
- * reg_get_frange_list_len() - Calculate the length of the list of the
- * frequency ranges
- * @num_freq_ranges: Number of frequency ranges
- *
- * Return: Length of the frequency range list
- */
-static uint16_t reg_get_frange_list_len(uint8_t num_freq_ranges)
-{
-	uint16_t frange_lst_len;
-
-	if (!num_freq_ranges)
-		reg_err("AFC:There is no freq ranges");
-
-	frange_lst_len =
-		sizeof(struct wlan_afc_frange_list) +
-		sizeof(struct wlan_afc_freq_range_obj) * num_freq_ranges;
-
-	return frange_lst_len;
-}
-
-/**
- * reg_get_opclasses_array_len() - Calculate the length of the array of
- * opclasses objects
- * @pdev: Pointer to pdev
- * @num_opclasses: The number of opclasses
- * @chansize_lst: The array of sizes of channel lists
- *
- * Return: Length of the array of opclass object
- */
-static uint16_t reg_get_opclasses_array_len(struct wlan_objmgr_pdev *pdev,
-					    uint8_t num_opclasses,
-					    uint8_t *chansize_lst)
-{
-	uint16_t opclasses_arr_len = 0;
-	uint16_t i;
-
-	for (i = 0; i < num_opclasses; i++) {
-		opclasses_arr_len +=
-			sizeof(struct wlan_afc_opclass_obj) +
-			sizeof(uint8_t) * chansize_lst[i];
-	}
-
-	return opclasses_arr_len;
-}
-
-/**
- * reg_get_afc_req_length() - Calculate the length of the AFC partial request
- * @pdev: Pointer to pdev
- * @num_opclasses: The number of opclasses
- * @num_freq_ranges: The number of frequency ranges
- * @chansize_lst: The array of sizes of channel lists
- *
- * Return: Length of the partial AFC request
- */
-static uint16_t reg_get_afc_req_length(struct wlan_objmgr_pdev *pdev,
-				       uint8_t num_opclasses,
-				       uint8_t num_freq_ranges,
-				       uint8_t *chansize_lst)
-{
-	uint16_t afc_req_len;
-	uint16_t frange_lst_len;
-	uint16_t fixed_param_len;
-	uint16_t num_opclasses_len;
-	uint16_t opclasses_arr_len;
-	uint16_t afc_location_len;
-
-	fixed_param_len = sizeof(struct wlan_afc_host_req_fixed_params);
-	frange_lst_len = reg_get_frange_list_len(num_freq_ranges);
-	num_opclasses_len = sizeof(struct wlan_afc_num_opclasses);
-	opclasses_arr_len = reg_get_opclasses_array_len(pdev,
-							num_opclasses,
-							chansize_lst);
-	afc_location_len = sizeof(struct wlan_afc_location);
-
-	afc_req_len =
-		fixed_param_len +
-		frange_lst_len +
-		num_opclasses_len +
-		opclasses_arr_len +
-		afc_location_len;
-
-	return afc_req_len;
-}
-
-/**
- * reg_fill_afc_fixed_params() - Fill the AFC fixed params
- * @p_fixed_params: Pointer to afc fixed params object
- * @afc_req_len: Length of the partial AFC request
- *
- * Return: Void
- */
-static inline void
-reg_fill_afc_fixed_params(struct wlan_afc_host_req_fixed_params *p_fixed_params,
-			  uint16_t afc_req_len)
-{
-	p_fixed_params->req_length = afc_req_len;
-	p_fixed_params->req_id = DEFAULT_REQ_ID;
-	p_fixed_params->min_des_power = DEFAULT_MIN_POWER;
-}
-
-/**
- * reg_fill_afc_freq_ranges() - Fill the AFC fixed params
+ * reg_fill_afc_freq_ranges() - Allocate memory for and fill the AFC frequency
+ * range lists.
  * @pdev: Pointer to pdev
  * @pdev_priv_obj: Pointer to pdev private object
  * @p_frange_lst: Pointer to frequency range list
  * @num_freq_ranges: Number of frequency ranges
  *
- * Return: Void
+ * Return: QDF_STATUS
  */
-static inline void
+static inline QDF_STATUS
 reg_fill_afc_freq_ranges(struct wlan_objmgr_pdev *pdev,
 			 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
 			 struct wlan_afc_frange_list *p_frange_lst,
@@ -7204,10 +7104,18 @@ reg_fill_afc_freq_ranges(struct wlan_objmgr_pdev *pdev,
 	struct wlan_afc_freq_range_obj *p_range_obj;
 
 	p_frange_lst->num_ranges = num_freq_ranges;
+	if (!num_freq_ranges)
+		return QDF_STATUS_E_INVAL;
 
-	p_range_obj = &p_frange_lst->range_objs[0];
+	p_range_obj = qdf_mem_malloc(num_freq_ranges * sizeof(*p_range_obj));
+	if (!p_range_obj)
+		return QDF_STATUS_E_NOMEM;
 
 	reg_cp_freq_ranges(pdev, pdev_priv_obj, num_freq_ranges, p_range_obj);
+
+	p_frange_lst->range_objs = p_range_obj;
+
+	return QDF_STATUS_SUCCESS;
 }
 
 /**
@@ -7218,31 +7126,57 @@ reg_fill_afc_freq_ranges(struct wlan_objmgr_pdev *pdev,
  * @num_chans: Number of channels in the opclass
  * @p_chan_lst: Pointer to channel list
  *
- * Return: Pointer to the next AFC opclass object
+ * Return: QDF_STATUS
  */
-static struct wlan_afc_opclass_obj *
+static QDF_STATUS
 reg_fill_afc_opclass_obj(struct wlan_afc_opclass_obj *p_obj_opclass_obj,
 			 uint8_t opclass,
 			 uint8_t num_chans,
 			 uint8_t *p_chan_lst)
 {
-	uint16_t len_obj;
-	uint8_t *out_p;
 	uint8_t *src, *dst;
 	uint8_t copy_len;
 
 	p_obj_opclass_obj->opclass_num_cfis = num_chans;
 	p_obj_opclass_obj->opclass = opclass;
+	/* Zero CFIs(opclass_num_cfis / num_chans) is a valid case */
+	if (!num_chans)
+		return QDF_STATUS_SUCCESS;
+
 	src = p_chan_lst;
-	dst = p_obj_opclass_obj->cfis;
 	copy_len = num_chans * sizeof(uint8_t);
+	dst = qdf_mem_malloc(copy_len);
+	if (!dst)
+		return QDF_STATUS_E_NOMEM;
 
 	qdf_mem_copy(dst, src, copy_len);
+	p_obj_opclass_obj->cfis = dst;
 
-	len_obj = sizeof(struct wlan_afc_opclass_obj) + copy_len;
-	out_p = (uint8_t *)p_obj_opclass_obj + len_obj;
+	return QDF_STATUS_SUCCESS;
+}
 
-	return (struct wlan_afc_opclass_obj *)out_p;
+/**
+ * reg_free_afc_opclass_objs() - Free the  memory allocated for AFC opclass
+ * object. Each opclass object also contains a cfi array. Free the memory
+ * allocated for the cfi array.
+ * @opclass_objs: Pointer to opclass objects array.
+ * @num_opclass_objs: Number of opclass objects.
+ *
+ * Return: void
+ */
+static void
+reg_free_afc_opclass_objs(struct wlan_afc_opclass_obj *opclass_objs,
+			  uint8_t num_opclass_objs)
+{
+	uint8_t i;
+
+	for (i = 0; i < num_opclass_objs; i++) {
+		struct wlan_afc_opclass_obj *opclass_obj;
+
+		opclass_obj = &opclass_objs[i];
+		qdf_mem_free(opclass_obj->cfis);
+	}
+	qdf_mem_free(opclass_objs);
 }
 
 /**
@@ -7254,9 +7188,9 @@ reg_fill_afc_opclass_obj(struct wlan_afc_opclass_obj *p_obj_opclass_obj,
  * @channel_lists: The array of channel lists
  * @p_opclass_obj_arr: Pointer to the first opclass object
  *
- * Return: Pointer to the end of last opclass object
+ * Return: QDF_STATUS
  */
-static inline struct wlan_afc_opclass_obj *
+static QDF_STATUS
 reg_fill_afc_opclasses_arr(struct wlan_objmgr_pdev *pdev,
 			   uint8_t num_opclasses,
 			   uint8_t *opclass_lst,
@@ -7265,68 +7199,60 @@ reg_fill_afc_opclasses_arr(struct wlan_objmgr_pdev *pdev,
 			   struct wlan_afc_opclass_obj *p_opclass_obj_arr)
 {
 	uint16_t i;
-	struct wlan_afc_opclass_obj *p_opclass_obj;
-
-	p_opclass_obj = p_opclass_obj_arr;
+	QDF_STATUS status;
 
 	for (i = 0; i < num_opclasses; i++) {
-		p_opclass_obj = reg_fill_afc_opclass_obj(p_opclass_obj,
-							 opclass_lst[i],
-							 chansize_lst[i],
-							 channel_lists[i]);
+		struct wlan_afc_opclass_obj *p_opclass_obj;
+
+		p_opclass_obj = &p_opclass_obj_arr[i];
+		status = reg_fill_afc_opclass_obj(p_opclass_obj,
+						  opclass_lst[i],
+						  chansize_lst[i],
+						  channel_lists[i]);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			reg_free_afc_opclass_objs(p_opclass_obj_arr,
+						  num_opclasses);
+			return status;
+		}
 	}
-	return p_opclass_obj;
+	return QDF_STATUS_SUCCESS;
 }
 
 /**
- * reg_next_opcls_ptr() - Get the pointer to the next opclass object
- * @p_cur_opcls_obj: Pointer to the current operating class object
- * @num_cfis: number of center frequency indices
+ * reg_print_afc_req_info_header_params() - Print the fixed param portion of the
+ * AFC request information.
+ * @afc_req: Pointer to AFC request
  *
- * Return: Pointer to next opclss object
+ * Return: Void
  */
-static struct wlan_afc_opclass_obj *
-reg_next_opcls_ptr(struct wlan_afc_opclass_obj *p_cur_opcls_obj,
-		   uint8_t num_cfis)
+static void
+reg_print_afc_req_info_header_params(struct wlan_afc_host_request *afc_req)
 {
-	uint8_t cur_obj_sz;
-	uint8_t fixed_opcls_sz;
-	struct wlan_afc_opclass_obj *p_next_opcls_obj;
-	uint8_t *p_tmp_next;
-
-	fixed_opcls_sz = sizeof(struct wlan_afc_opclass_obj);
-	cur_obj_sz = fixed_opcls_sz + num_cfis * sizeof(uint8_t);
-	p_tmp_next = (uint8_t *)p_cur_opcls_obj + cur_obj_sz;
-	p_next_opcls_obj = (struct wlan_afc_opclass_obj *)p_tmp_next;
-
-	return p_next_opcls_obj;
+	reg_debug("req_id=%llu", afc_req->req_id);
+	reg_debug("version_minor=%u", afc_req->version_minor);
+	reg_debug("version_major=%u", afc_req->version_major);
+	reg_debug("min_des_power=%hd", afc_req->min_des_power);
 }
 
-void reg_print_partial_afc_req_info(struct wlan_objmgr_pdev *pdev,
-				    struct wlan_afc_host_partial_request *afc_req)
+/**
+ * reg_print_afc_req_info_frange_list() - Print the list of frequency ranges
+ * portion of the AFC request information.
+ * @afc_req: Pointer to AFC request
+ *
+ * Return: Void
+ */
+static void
+reg_print_afc_req_info_frange_list(struct wlan_afc_host_request *afc_req)
 {
-	struct wlan_afc_host_req_fixed_params *p_fixed_params;
 	struct wlan_afc_frange_list *p_frange_lst;
-	struct wlan_afc_num_opclasses *p_num_opclasses;
 	uint8_t i;
-	uint8_t j;
-	uint16_t frange_lst_len;
-	uint8_t num_opclasses;
-	struct wlan_afc_opclass_obj *p_obj_opclass_arr;
-	struct wlan_afc_opclass_obj *p_opclass_obj;
-	uint8_t num_freq_ranges;
-	uint8_t *p_temp;
-	struct wlan_afc_location *p_afc_location;
-	uint8_t *deployment_type_str;
 
-	p_fixed_params = &afc_req->fixed_params;
-	reg_debug("req_length=%hu", p_fixed_params->req_length);
-	reg_debug("req_id=%llu", p_fixed_params->req_id);
-	reg_debug("min_des_power=%hd", p_fixed_params->min_des_power);
+	p_frange_lst = afc_req->freq_lst;
+	if (!p_frange_lst) {
+		reg_debug("p_frange_lst is NULL");
+		return;
+	}
 
-	p_temp = (uint8_t *)p_fixed_params;
-	p_temp += sizeof(*p_fixed_params);
-	p_frange_lst = (struct wlan_afc_frange_list *)p_temp;
 	reg_debug("num_ranges=%hhu", p_frange_lst->num_ranges);
 	for (i = 0; i < p_frange_lst->num_ranges; i++) {
 		struct wlan_afc_freq_range_obj *p_range_obj;
@@ -7335,21 +7261,37 @@ void reg_print_partial_afc_req_info(struct wlan_objmgr_pdev *pdev,
 		reg_debug("lowfreq=%hu", p_range_obj->lowfreq);
 		reg_debug("highfreq=%hu", p_range_obj->highfreq);
 	}
+}
 
-	num_freq_ranges = p_frange_lst->num_ranges;
-	frange_lst_len = reg_get_frange_list_len(num_freq_ranges);
-	p_temp += frange_lst_len;
-	p_num_opclasses = (struct wlan_afc_num_opclasses *)p_temp;
-	num_opclasses = p_num_opclasses->num_opclasses;
-	reg_debug("num_opclasses=%hhu", num_opclasses);
+/**
+ * reg_print_afc_req_info_opclass_list() - Print the list of opclasses
+ * and the corresponding CFIs supported in those opclasses.
+ * @afc_req: Pointer to AFC request
+ *
+ * Return: Void
+ */
+static void
+reg_print_afc_req_info_opclass_list(struct wlan_afc_host_request *afc_req)
+{
+	uint8_t i;
+	uint8_t num_opclasses;
+	struct wlan_afc_opclass_obj_list *p_opclass_obj_lst;
+	struct wlan_afc_opclass_obj *p_opclass_obj;
+
+	p_opclass_obj_lst = afc_req->opclass_obj_lst;
+	if (!p_opclass_obj_lst) {
+		reg_debug("p_opclass_obj_lst is NULL");
+		return;
+	}
 
-	p_temp += sizeof(*p_num_opclasses);
-	p_obj_opclass_arr = (struct wlan_afc_opclass_obj *)p_temp;
-	p_opclass_obj = p_obj_opclass_arr;
+	num_opclasses = p_opclass_obj_lst->num_opclass_objs;
+	reg_debug("num_opclasses=%hhu", num_opclasses);
+	p_opclass_obj = p_opclass_obj_lst->opclass_objs;
 	for (i = 0; i < num_opclasses; i++) {
-		uint8_t opclass = p_opclass_obj->opclass;
-		uint8_t num_cfis = p_opclass_obj->opclass_num_cfis;
-		uint8_t *cfis = p_opclass_obj->cfis;
+		uint8_t opclass = p_opclass_obj[i].opclass;
+		uint8_t num_cfis = p_opclass_obj[i].opclass_num_cfis;
+		uint8_t *cfis = p_opclass_obj[i].cfis;
+		uint8_t j;
 
 		reg_debug("opclass[%hhu]=%hhu", i, opclass);
 		reg_debug("num_cfis[%hhu]=%hhu", i, num_cfis);
@@ -7357,11 +7299,28 @@ void reg_print_partial_afc_req_info(struct wlan_objmgr_pdev *pdev,
 		for (j = 0; j < num_cfis; j++)
 			reg_debug("%hhu,", cfis[j]);
 		reg_debug("]");
+	}
+}
 
-		p_opclass_obj = reg_next_opcls_ptr(p_opclass_obj, num_cfis);
+/**
+ * reg_print_afc_req_info_location() - Print the location information in the afc
+ * request.
+ * @afc_req: Pointer to AFC request
+ *
+ * Return: Void
+ */
+static void
+reg_print_afc_req_info_location(struct wlan_afc_host_request *afc_req)
+{
+	struct wlan_afc_location *p_afc_location;
+	uint8_t *deployment_type_str;
+
+	p_afc_location = afc_req->afc_location;
+	if (!p_afc_location) {
+		reg_debug("p_afc_location is NULL");
+		return;
 	}
 
-	p_afc_location = (struct wlan_afc_location *)p_opclass_obj;
 	switch (p_afc_location->deployment_type) {
 	case AFC_DEPLOYMENT_INDOOR:
 		deployment_type_str = "Indoor";
@@ -7375,171 +7334,269 @@ void reg_print_partial_afc_req_info(struct wlan_objmgr_pdev *pdev,
 	reg_debug("AFC location=%s", deployment_type_str);
 }
 
+void reg_print_afc_req_info(struct wlan_objmgr_pdev *pdev,
+			    struct wlan_afc_host_request *afc_req)
+{
+	if (!afc_req) {
+		reg_debug("afc_req is NULL");
+		return;
+	}
+
+	reg_print_afc_req_info_header_params(afc_req);
+	reg_print_afc_req_info_frange_list(afc_req);
+	reg_print_afc_req_info_opclass_list(afc_req);
+	reg_print_afc_req_info_location(afc_req);
+}
+
+/**
+ * reg_free_afc_freq_list() - Free the  memory allocated for AFC frequency list
+ * pointer and range object.
+ * @freq_lst: Pointer to AFC frequency list structure.
+ *
+ * Return: void
+ */
+static void reg_free_afc_freq_list(struct wlan_afc_frange_list *freq_lst)
+{
+	if (freq_lst) {
+		qdf_mem_free(freq_lst->range_objs);
+		qdf_mem_free(freq_lst);
+	}
+}
+
 /**
- * reg_get_frange_filled_buf() - Allocate and fill the frange buffer and return
+ * reg_free_afc_opclass_list() - Free the  memory allocated for AFC opclass list
+ * pointer and opclass objects.
+ * @opclass_obj_lst: Pointer to AFC opclass object list structure.
+ *
+ * Return: void
+ */
+static void
+reg_free_afc_opclass_list(struct wlan_afc_opclass_obj_list *opclass_obj_lst)
+{
+	uint8_t num_opclass_objs;
+
+	if (!opclass_obj_lst)
+		return;
+
+	num_opclass_objs = opclass_obj_lst->num_opclass_objs;
+	if (opclass_obj_lst->opclass_objs)
+		reg_free_afc_opclass_objs(opclass_obj_lst->opclass_objs,
+					  num_opclass_objs);
+	qdf_mem_free(opclass_obj_lst);
+}
+
+/**
+ * reg_fill_freq_lst() - Allocate and fill the frange buffer and return
  * the buffer. Also return the number of frequence ranges
  * @pdev: Pointer to pdev
  * @pdev_priv_obj: Pointer to pdev private object
- * @num_freq_ranges: Pointer to number of frequency ranges (output param)
  *
  * Return: Pointer to the frange buffer
  */
 static struct wlan_afc_frange_list *
-reg_get_frange_filled_buf(struct wlan_objmgr_pdev *pdev,
-			  struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
-			  uint8_t *num_freq_ranges)
+reg_fill_freq_lst(struct wlan_objmgr_pdev *pdev,
+		  struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
 {
-	uint16_t frange_lst_len;
+	uint8_t num_freq_ranges;
 	struct wlan_afc_frange_list *p_frange_lst_local;
+	QDF_STATUS status;
 
-	*num_freq_ranges =  reg_get_num_sp_freq_ranges(pdev, pdev_priv_obj);
-	frange_lst_len = reg_get_frange_list_len(*num_freq_ranges);
-
-	p_frange_lst_local = qdf_mem_malloc(frange_lst_len);
+	num_freq_ranges =  reg_get_num_sp_freq_ranges(pdev, pdev_priv_obj);
+	p_frange_lst_local = qdf_mem_malloc(sizeof(*p_frange_lst_local));
 	if (!p_frange_lst_local)
 		return NULL;
 
-	reg_fill_afc_freq_ranges(pdev,
-				 pdev_priv_obj,
-				 p_frange_lst_local,
-				 *num_freq_ranges);
+	status = reg_fill_afc_freq_ranges(pdev,
+					  pdev_priv_obj,
+					  p_frange_lst_local,
+					  num_freq_ranges);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		reg_free_afc_freq_list(p_frange_lst_local);
+		return NULL;
+	}
+
 	return p_frange_lst_local;
 }
 
-QDF_STATUS
-reg_get_partial_afc_req_info(struct wlan_objmgr_pdev *pdev,
-			     struct wlan_afc_host_partial_request **afc_req)
+void reg_free_afc_req(struct wlan_objmgr_pdev *pdev,
+		      struct wlan_afc_host_request *afc_req)
 {
-	/* allocate the memory for the partial request */
-	struct wlan_afc_host_partial_request *temp_afc_req;
-	struct wlan_afc_host_req_fixed_params *p_fixed_params;
-	struct wlan_afc_frange_list *p_frange_lst_local;
-	struct wlan_afc_frange_list *p_frange_lst_afc;
-	struct wlan_afc_num_opclasses *p_num_opclasses;
-	uint16_t afc_req_len;
-	uint16_t frange_lst_len;
-	uint8_t num_freq_ranges;
-	uint8_t num_opclasses;
-	struct wlan_afc_opclass_obj *p_obj_opclass_arr;
-	struct wlan_afc_location *p_afc_location;
+	if (!afc_req)
+		return;
 
+	reg_free_afc_freq_list(afc_req->freq_lst);
+	reg_free_afc_opclass_list(afc_req->opclass_obj_lst);
+	qdf_mem_free(afc_req->afc_location);
+	qdf_mem_free(afc_req);
+}
+
+/**
+ * reg_fill_afc_opclass_obj_lst() - Allocate and fill the opclass object list
+ * pointer and return the pointer.
+ * @pdev: Pointer to pdev
+ * @p_afc_req: Pointer to AFC request.
+ *
+ * Return: Pointer to the opclass object list.
+ */
+static struct wlan_afc_opclass_obj_list *
+reg_fill_afc_opclass_obj_lst(struct wlan_objmgr_pdev *pdev,
+			     struct wlan_afc_host_request *p_afc_req)
+{
+	uint8_t num_opclasses;
 	uint8_t *opclass_lst;
 	uint8_t *chansize_lst;
 	uint8_t **channel_lists;
+	struct wlan_afc_opclass_obj_list *opclass_obj_lst;
+	struct wlan_afc_opclass_obj *l_opclass_objs;
 	QDF_STATUS status;
-	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
-
-	if (!afc_req) {
-		reg_err("afc_req is NULL");
-		status = QDF_STATUS_E_INVAL;
-		return status;
-	}
-
-	temp_afc_req = NULL;
-	pdev_priv_obj = reg_get_pdev_obj(pdev);
-	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
-		reg_err("pdev reg component is NULL");
-		status = QDF_STATUS_E_INVAL;
-		goto handle_invalid_priv_object;
-	}
-
-	p_frange_lst_local = reg_get_frange_filled_buf(pdev,
-						       pdev_priv_obj,
-						       &num_freq_ranges);
-	if (!p_frange_lst_local) {
-		reg_err("Frange lst not allocated");
-		status = QDF_STATUS_E_NOMEM;
-		goto handle_invalid_priv_object;
-	}
 
 	status = reg_dmn_get_6g_opclasses_and_channels(pdev,
-						       p_frange_lst_local,
+						       p_afc_req->freq_lst,
 						       &num_opclasses,
 						       &opclass_lst,
 						       &chansize_lst,
 						       &channel_lists);
 	if (status != QDF_STATUS_SUCCESS) {
 		reg_err("Opclasses and chans not allocated");
-		status = QDF_STATUS_E_NOMEM;
-		goto free_frange_lst_local;
+		return NULL;
 	}
 
-	afc_req_len = reg_get_afc_req_length(pdev,
-					     num_opclasses,
-					     num_freq_ranges,
-					     chansize_lst);
-
-	temp_afc_req = qdf_mem_malloc(afc_req_len);
-	if (!temp_afc_req) {
-		reg_err("AFC request not allocated");
-		status = QDF_STATUS_E_NOMEM;
-		goto free_opcls_chan_mem;
+	opclass_obj_lst =  qdf_mem_malloc(sizeof(*opclass_obj_lst));
+	if (!opclass_obj_lst) {
+		reg_dmn_free_6g_opclasses_and_channels(pdev, num_opclasses,
+						       opclass_lst,
+						       chansize_lst,
+						       channel_lists);
+		return NULL;
 	}
 
-	p_fixed_params = &temp_afc_req->fixed_params;
-	reg_fill_afc_fixed_params(p_fixed_params, afc_req_len);
-
-	/* frange list is already filled just copy it */
-	frange_lst_len = reg_get_frange_list_len(num_freq_ranges);
-	p_frange_lst_afc = (struct wlan_afc_frange_list *)&p_fixed_params[1];
-	qdf_mem_copy(p_frange_lst_afc, p_frange_lst_local, frange_lst_len);
+	if (!num_opclasses)
+		return NULL;
 
-	p_num_opclasses = (struct wlan_afc_num_opclasses *)
-	    ((char *)(p_frange_lst_afc) + frange_lst_len);
-	p_num_opclasses->num_opclasses = num_opclasses;
+	opclass_obj_lst->num_opclass_objs = num_opclasses;
+	l_opclass_objs = qdf_mem_malloc(num_opclasses *
+					sizeof(struct wlan_afc_opclass_obj));
+	if (!l_opclass_objs) {
+		reg_dmn_free_6g_opclasses_and_channels(pdev, num_opclasses,
+						       opclass_lst,
+						       chansize_lst,
+						       channel_lists);
+		reg_free_afc_opclass_list(opclass_obj_lst);
+		return NULL;
+	}
 
-	p_obj_opclass_arr = (struct wlan_afc_opclass_obj *)&p_num_opclasses[1];
-	p_obj_opclass_arr = reg_fill_afc_opclasses_arr(pdev,
-						       num_opclasses,
+	status = reg_fill_afc_opclasses_arr(pdev, num_opclasses, opclass_lst,
+					    chansize_lst, channel_lists,
+					    l_opclass_objs);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		reg_dmn_free_6g_opclasses_and_channels(pdev, num_opclasses,
 						       opclass_lst,
 						       chansize_lst,
-						       channel_lists,
-						       p_obj_opclass_arr);
+						       channel_lists);
+		reg_free_afc_opclass_list(opclass_obj_lst);
+		return NULL;
+	}
 
-	p_afc_location = (struct wlan_afc_location *)p_obj_opclass_arr;
-	p_afc_location->deployment_type =
-				pdev_priv_obj->reg_afc_dev_deployment_type;
-	p_afc_location->afc_elem_type = AFC_OBJ_LOCATION;
-	p_afc_location->afc_elem_len =
-				sizeof(*p_afc_location) -
-				sizeof(p_afc_location->afc_elem_type) -
-				sizeof(p_afc_location->afc_elem_len);
-free_opcls_chan_mem:
-	reg_dmn_free_6g_opclasses_and_channels(pdev,
-					       num_opclasses,
+	opclass_obj_lst->opclass_objs = l_opclass_objs;
+	reg_dmn_free_6g_opclasses_and_channels(pdev, num_opclasses,
 					       opclass_lst,
 					       chansize_lst,
 					       channel_lists);
+	return opclass_obj_lst;
+}
 
-free_frange_lst_local:
-	qdf_mem_free(p_frange_lst_local);
+/**
+ * reg_fill_afc_location_obj() - Allocate and fill the AFC location object
+ * pointer and return the pointer.
+ * @pdev_priv_obj: Pointer to pdev private object
+ * @afc_req: Pointer to AFC request.
+ *
+ * Return: Pointer to the AFC location object.
+ */
+static struct wlan_afc_location *
+reg_fill_afc_location_obj(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
+			  struct wlan_afc_host_request *afc_req)
+{
+	struct wlan_afc_location *p_afc_location;
 
-handle_invalid_priv_object:
-	*afc_req = temp_afc_req;
+	p_afc_location = qdf_mem_malloc(sizeof(*p_afc_location));
+	if (!p_afc_location)
+		return NULL;
 
-	return status;
+	p_afc_location->deployment_type =
+				pdev_priv_obj->reg_afc_dev_deployment_type;
+	return p_afc_location;
+}
+
+QDF_STATUS
+reg_get_afc_req_info(struct wlan_objmgr_pdev *pdev,
+		     struct wlan_afc_host_request **afc_req)
+{
+	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
+	struct wlan_afc_host_request *p_afc_req;
+
+	pdev_priv_obj = reg_get_pdev_obj(pdev);
+	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
+		reg_err("pdev reg component is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!afc_req) {
+		reg_err("afc_req is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*afc_req = qdf_mem_malloc(sizeof(struct wlan_afc_host_request));
+	if (!*afc_req)
+		return QDF_STATUS_E_NOMEM;
+
+	p_afc_req = *afc_req;
+	p_afc_req->req_id = DEFAULT_REQ_ID;
+	p_afc_req->min_des_power = DEFAULT_MIN_POWER;
+
+	p_afc_req->freq_lst = reg_fill_freq_lst(pdev, pdev_priv_obj);
+	if (!p_afc_req->freq_lst) {
+		reg_err("Frange lst not allocated");
+		reg_free_afc_req(pdev, p_afc_req);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	p_afc_req->opclass_obj_lst = reg_fill_afc_opclass_obj_lst(pdev,
+								  p_afc_req);
+	if (!p_afc_req->opclass_obj_lst) {
+		reg_err("opclass object lst not allocated");
+		reg_free_afc_req(pdev, p_afc_req);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	p_afc_req->afc_location = reg_fill_afc_location_obj(pdev_priv_obj,
+							    p_afc_req);
+	if (!p_afc_req->afc_location) {
+		reg_err("AFC location not allocated");
+		reg_free_afc_req(pdev, p_afc_req);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	return QDF_STATUS_SUCCESS;
 }
 
-void reg_dmn_set_afc_req_id(struct wlan_afc_host_partial_request *afc_req,
+void reg_dmn_set_afc_req_id(struct wlan_afc_host_request *afc_req,
 			    uint64_t req_id)
 {
-	struct wlan_afc_host_req_fixed_params *p_fixed_params;
 
-	p_fixed_params = &afc_req->fixed_params;
-	p_fixed_params->req_id = req_id;
+	afc_req->req_id = req_id;
 }
 
 /**
- * reg_send_afc_partial_request() - Send AFC partial request to registered
- * recipient
+ * reg_send_afc_request() - Send AFC request to registered recipient
  * @pdev: Pointer to pdev
- * @afc_req: Pointer to afc partial request
+ * @afc_req: Pointer to afc request
  *
  * Return: void
  */
 static
-void reg_send_afc_partial_request(struct wlan_objmgr_pdev *pdev,
-				  struct wlan_afc_host_partial_request *afc_req)
+void reg_send_afc_request(struct wlan_objmgr_pdev *pdev,
+			  struct wlan_afc_host_request *afc_req)
 {
 	afc_req_rx_evt_handler cbf;
 	void *arg;
@@ -7562,10 +7619,10 @@ void reg_send_afc_partial_request(struct wlan_objmgr_pdev *pdev,
 
 QDF_STATUS reg_afc_start(struct wlan_objmgr_pdev *pdev, uint64_t req_id)
 {
-	struct wlan_afc_host_partial_request *afc_req;
+	struct wlan_afc_host_request *afc_req;
 	QDF_STATUS status;
 
-	status = reg_get_partial_afc_req_info(pdev, &afc_req);
+	status = reg_get_afc_req_info(pdev, &afc_req);
 	if (status != QDF_STATUS_SUCCESS) {
 		reg_err("Creating AFC Request failed");
 		return QDF_STATUS_E_FAILURE;
@@ -7576,11 +7633,11 @@ QDF_STATUS reg_afc_start(struct wlan_objmgr_pdev *pdev, uint64_t req_id)
 
 	reg_dmn_set_afc_req_id(afc_req, req_id);
 
-	reg_print_partial_afc_req_info(pdev, afc_req);
+	reg_print_afc_req_info(pdev, afc_req);
 
-	reg_send_afc_partial_request(pdev, afc_req);
+	reg_send_afc_request(pdev, afc_req);
 
-	qdf_mem_free(afc_req);
+	reg_free_afc_req(pdev, afc_req);
 
 	return QDF_STATUS_SUCCESS;
 }

+ 20 - 10
umac/regulatory/core/src/reg_services_common.h

@@ -1720,7 +1720,18 @@ reg_get_cur_6g_ap_pwr_type(struct wlan_objmgr_pdev *pdev,
 QDF_STATUS reg_afc_start(struct wlan_objmgr_pdev *pdev, uint64_t req_id);
 
 /**
- * reg_get_partial_afc_req_info() - Get the AFC partial request information
+ * reg_free_afc_req() - Free the  memory allocated for AFC request structure and
+ * its members.
+ * @pdev: Pointer to pdev.
+ * @afc_req: Pointer to AFC request structure.
+ *
+ * Return: void
+ */
+void reg_free_afc_req(struct wlan_objmgr_pdev *pdev,
+		      struct wlan_afc_host_request *afc_req);
+
+/**
+ * reg_get_afc_req_info() - Get the AFC request information.
  * @pdev: Pointer to pdev
  * @afc_req: Address of AFC request pointer
  *
@@ -1729,20 +1740,19 @@ QDF_STATUS reg_afc_start(struct wlan_objmgr_pdev *pdev, uint64_t req_id);
  * Return: QDF_STATUS
  */
 QDF_STATUS
-reg_get_partial_afc_req_info(struct wlan_objmgr_pdev *pdev,
-			     struct wlan_afc_host_partial_request **afc_req);
+reg_get_afc_req_info(struct wlan_objmgr_pdev *pdev,
+		     struct wlan_afc_host_request **afc_req);
 
 /**
- * reg_print_partial_afc_req_info() - Print the AFC partial request
- *                                    information
+ * reg_print_afc_req_info() - Print the AFC request information.
  * @pdev: Pointer to pdev
  * @afc_req: Pointer to AFC request
  *
  * Return: Void
  */
 void
-reg_print_partial_afc_req_info(struct wlan_objmgr_pdev *pdev,
-			       struct wlan_afc_host_partial_request *afc_req);
+reg_print_afc_req_info(struct wlan_objmgr_pdev *pdev,
+		       struct wlan_afc_host_request *afc_req);
 
 /**
  * reg_register_afc_req_rx_callback() - add AFC request received callback
@@ -2516,14 +2526,14 @@ bool reg_is_afc_expiry_event_received(struct wlan_objmgr_pdev *pdev);
 bool reg_is_noaction_on_afc_pwr_evt(struct wlan_objmgr_pdev *pdev);
 
 /**
- * reg_dmn_set_afc_req_id() - Set the request ID in the AFC partial request
+ * reg_dmn_set_afc_req_id() - Set the request ID in the AFC request
  *                            object
- * @afc_req: pointer to AFC partial request
+ * @afc_req: pointer to AFC request
  * @req_id: AFC request ID
  *
  * Return: Void
  */
-void reg_dmn_set_afc_req_id(struct wlan_afc_host_partial_request *afc_req,
+void reg_dmn_set_afc_req_id(struct wlan_afc_host_request *afc_req,
 			    uint64_t req_id);
 #endif
 

+ 2 - 2
umac/regulatory/dispatcher/inc/reg_services_public_struct.h

@@ -2312,13 +2312,13 @@ struct reg_afc_resp_rx_ind_info {
  * typedef afc_req_rx_evt_handler() - Function prototype of AFC request
  *                                    received event handler
  * @pdev: Pointer to pdev
- * @afc_par_req: Pointer to AFC partial request
+ * @afc_req: Pointer to AFC request
  * @arg: Pointer to void (opaque) argument object
  *
  * Return: void
  */
 typedef void (*afc_req_rx_evt_handler)(struct wlan_objmgr_pdev *pdev,
-				       struct wlan_afc_host_partial_request *afc_par_req,
+				       struct wlan_afc_host_request *afc_req,
 				       void *arg);
 
 /**

+ 16 - 5
umac/regulatory/dispatcher/inc/wlan_reg_ucfg_api.h

@@ -340,7 +340,7 @@ QDF_STATUS ucfg_reg_unregister_afc_req_rx_callback(struct wlan_objmgr_pdev *pdev
 						   afc_req_rx_evt_handler cbf);
 
 /**
- * ucfg_reg_get_partial_afc_req_info() - Get the the frequency ranges and
+ * ucfg_reg_get_afc_req_info() - Get the the frequency ranges and
  * opclass + channel ranges. This is partial because in the AFC request there
  * are a few more parameters: Longitude, Latitude a few other information
  * @pdev: Pointer to PDEV object.
@@ -349,10 +349,21 @@ QDF_STATUS ucfg_reg_unregister_afc_req_rx_callback(struct wlan_objmgr_pdev *pdev
  *
  * Return: QDF_STATUS_E_INVAL if unable to set and QDF_STATUS_SUCCESS is set.
  */
-QDF_STATUS ucfg_reg_get_partial_afc_req_info(
-		struct wlan_objmgr_pdev *pdev,
-		struct wlan_afc_host_partial_request **afc_req,
-		uint64_t req_id);
+QDF_STATUS ucfg_reg_get_afc_req_info(struct wlan_objmgr_pdev *pdev,
+				     struct wlan_afc_host_request **afc_req,
+				     uint64_t req_id);
+
+/**
+ * ucfg_reg_free_afc_req() - Free the  memory allocated for AFC request
+ * structure and its members.
+ * @pdev: Pointer to pdev.
+ * @afc_req: Pointer to AFC request structure.
+ *
+ * Return: void
+ */
+void
+ucfg_reg_free_afc_req(struct wlan_objmgr_pdev *pdev,
+		      struct wlan_afc_host_request *afc_req);
 
 /**
  * ucfg_reg_register_afc_power_event_callback() - add AFC power event received

+ 11 - 8
umac/regulatory/dispatcher/src/wlan_reg_ucfg_api.c

@@ -229,23 +229,26 @@ ucfg_reg_unregister_afc_power_event_callback(struct wlan_objmgr_pdev *pdev,
 	return reg_unregister_afc_power_event_callback(pdev, cbf);
 }
 
-QDF_STATUS ucfg_reg_get_partial_afc_req_info(
-		struct wlan_objmgr_pdev *pdev,
-		struct wlan_afc_host_partial_request **afc_req,
-		uint64_t req_id)
+QDF_STATUS ucfg_reg_get_afc_req_info(struct wlan_objmgr_pdev *pdev,
+				     struct wlan_afc_host_request **afc_req,
+				     uint64_t req_id)
 {
 	QDF_STATUS status;
 
-	status = reg_get_partial_afc_req_info(pdev, afc_req);
-
-	if (!afc_req)
-		return QDF_STATUS_E_NOMEM;
+	status = reg_get_afc_req_info(pdev, afc_req);
 
 	if (status == QDF_STATUS_SUCCESS)
 		reg_dmn_set_afc_req_id(*afc_req, req_id);
 
 	return status;
 }
+
+void
+ucfg_reg_free_afc_req(struct wlan_objmgr_pdev *pdev,
+		      struct wlan_afc_host_request *afc_req)
+{
+	reg_free_afc_req(pdev, afc_req);
+}
 #endif
 
 enum country_src ucfg_reg_get_cc_and_src(struct wlan_objmgr_psoc *psoc,