瀏覽代碼

qcacld-3.0: Send BW ind and wide band channel switch element in rsp

As per spec if Wide Bandwidth Channel Switch (id 163) and Bandwidth
Indication (id 164) sub element present in channel load request,
Host should send same sub element ids with same values as in request
in channel load response.

Change-Id: If419c1e2ac694ee5d2da301e404085bb3fc68674
CRs-Fixed: 3629125
Abhinav Kumar 1 年之前
父節點
當前提交
fd4debd695

+ 6 - 9
components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_ucfg_api.h

@@ -398,14 +398,12 @@ void wlan_cp_stats_update_chan_info(struct wlan_objmgr_psoc *psoc,
  * wlan_cp_stats_get_rx_clear_count() - API to get rx clear count for a channel
  * @psoc: pointer to psoc
  * @vdev_id: vdev id
- * @channel: channel for which rx clear count require
- * @chan_load: buffer to store rx clear count for a channel
+ * @req_freq: freq for which rx clear count require
  *
- * Return: None
+ * Return: channel load
  */
-void wlan_cp_stats_get_rx_clear_count(struct wlan_objmgr_psoc *psoc,
-				      uint8_t vdev_id, uint8_t channel,
-				      uint8_t *chan_load);
+uint8_t wlan_cp_stats_get_rx_clear_count(struct wlan_objmgr_psoc *psoc,
+					 uint8_t vdev_id, qdf_freq_t req_freq);
 
 /**
  * ucfg_mc_cp_stats_clear_channel_status() - API to clear chan stats
@@ -520,9 +518,8 @@ void wlan_cp_stats_update_chan_info(struct wlan_objmgr_psoc *psoc,
 }
 
 static inline
-void wlan_cp_stats_get_rx_clear_count(struct wlan_objmgr_psoc *psoc,
-				      uint8_t vdev_id, uint8_t channel,
-				      uint8_t *chan_load)
+uint8_t wlan_cp_stats_get_rx_clear_count(struct wlan_objmgr_psoc *psoc,
+					 uint8_t vdev_id, qdf_freq_t req_freq)
 {
 }
 

+ 15 - 13
components/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c

@@ -1049,23 +1049,23 @@ void ucfg_mc_cp_stats_register_lost_link_info_cb(
 }
 
 #ifdef QCA_SUPPORT_CP_STATS
-void wlan_cp_stats_get_rx_clear_count(struct wlan_objmgr_psoc *psoc,
-				      uint8_t vdev_id, uint8_t channel,
-				      uint8_t *chan_load)
+uint8_t wlan_cp_stats_get_rx_clear_count(struct wlan_objmgr_psoc *psoc,
+					 uint8_t vdev_id, qdf_freq_t req_freq)
 {
 	struct wlan_objmgr_pdev *pdev;
 	struct wlan_objmgr_vdev *vdev;
 	struct pdev_cp_stats *pdev_cp_stats_priv;
 	struct per_channel_stats *channel_stats;
 	struct channel_status *channel_status_list;
-	uint8_t total_channel;
+	uint8_t total_channel, chan_load = 0;
 	uint8_t i;
 	uint32_t rx_clear_count = 0, cycle_count = 0;
+	bool found = false;
 
 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
 						    WLAN_CP_STATS_ID);
 	if (!vdev)
-		return;
+		return 0;
 
 	pdev = wlan_vdev_get_pdev(vdev);
 	if (!pdev) {
@@ -1083,16 +1083,17 @@ void wlan_cp_stats_get_rx_clear_count(struct wlan_objmgr_psoc *psoc,
 	channel_status_list = channel_stats->channel_status_list;
 	total_channel = channel_stats->total_channel;
 
-	for (i = 0; i < total_channel && i < NUM_CHANNELS; i++) {
-		if (channel_status_list[i].channel_id == channel) {
+	for (i = 0; i < total_channel; i++) {
+		if (channel_status_list[i].channel_freq == req_freq) {
 			rx_clear_count = channel_status_list[i].rx_clear_count;
 			cycle_count = channel_status_list[i].cycle_count;
+			found = true;
 			break;
 		}
 	}
 
-	if (i == total_channel) {
-		cp_stats_debug("no channel found for chan:%d", channel);
+	if (!found) {
+		cp_stats_debug("no channel found for freq:%d", req_freq);
 		goto release_ref;
 	}
 
@@ -1101,14 +1102,15 @@ void wlan_cp_stats_get_rx_clear_count(struct wlan_objmgr_psoc *psoc,
 		goto release_ref;
 	}
 
-	*chan_load = ((rx_clear_count * 255) / cycle_count);
+	chan_load = ((rx_clear_count * 255) / cycle_count);
 
-	cp_stats_debug("t_chan:%d, chan:%d, rcc:%u, cc:%u, chan_load:%d",
-		       total_channel, channel, rx_clear_count, cycle_count,
-		       *chan_load);
+	cp_stats_debug("t_chan:%d, freq:%d, rcc:%u, cc:%u, chan_load:%d",
+		       total_channel, req_freq, rx_clear_count, cycle_count,
+		       chan_load);
 
 release_ref:
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+	return chan_load;
 }
 #endif
 

+ 34 - 0
core/mac/inc/sir_mac_prot_def.h

@@ -1347,6 +1347,36 @@ typedef struct sSirMacBeaconReport {
 
 } tSirMacBeaconReport, *tpSirMacBeaconReport;
 
+/**
+ * struct sir_mac_bw_ind_element - Contains info for Bandwidth Indication IE
+ * present in channel load request received from AP
+ * @is_wide_bw_chan_switch: to check Bandwidth Indication optional IE present
+ * @channel_width: channel width
+ * @center_chan_freq0: center freq segment 0 for 320 MHz request
+ * @center_chan_freq1: center freq segment 1 for 320 MHz request
+ */
+struct sir_mac_bw_ind_element {
+	bool is_bw_ind_element;
+	uint8_t channel_width;
+	uint8_t center_freq_seg0;
+	uint8_t center_freq_seg1;
+};
+
+/**
+ * struct sir_mac_wide_bw_chan_switch - Contains info for Wide Bandwidth Channel
+ * Switch IE present in channel load request received from AP
+ * @is_wide_bw_chan_switch: to check Bandwidth Indication optional IE present
+ * @channel_width: channel width
+ * @center_chan_freq0: center freq segment 0 for till 160 MHz request
+ * @center_chan_freq1: center freq segment 1 for till 160 MHz request
+ */
+struct sir_mac_wide_bw_chan_switch {
+	uint8_t is_wide_bw_chan_switch;
+	uint8_t channel_width;
+	uint8_t center_chan_freq0;
+	uint8_t center_chan_freq1;
+};
+
 /**
  * struct chan_load_report - channel load Report Structure
  * @op_class: Regulatory Class
@@ -1354,6 +1384,8 @@ typedef struct sSirMacBeaconReport {
  * @rrm_scan_tsf: RRM scan start time for this report
  * @meas_duration: Scan duration for the current channel
  * @chan_load: channel utilization measurement
+ * @bw_ind: Contains info for Bandwidth Indication IE
+ * @wide_bw: Contains info for Wide Bandwidth Channel IE
  */
 struct chan_load_report {
 	uint8_t op_class;
@@ -1361,6 +1393,8 @@ struct chan_load_report {
 	qdf_time_t rrm_scan_tsf;
 	uint8_t meas_duration;
 	uint8_t chan_load;
+	struct sir_mac_bw_ind_element bw_ind;
+	struct sir_mac_wide_bw_chan_switch wide_bw;
 };
 
 /**

+ 8 - 2
core/mac/src/pe/include/rrm_global.h

@@ -66,11 +66,11 @@ struct rrm_reporting {
 /**
  * struct bw_ind_element - Contains info for Bandwidth Indication IE
  * present in channel load request received from AP
- * @s_bw_ind_element: to check Bandwidth Indication optional IE present
+ * @is_bw_ind_element: to check Bandwidth Indication optional IE present
  * @channel_width: channel width
  * @ccfi0: center channel frequency index segment 0
  * @ccfi1: center channel frequency index segment 1
- * @center_chan_freq: center freq segment  for 320 MHz request
+ * @center_freq: center freq segment  for 320 MHz request
  */
 struct bw_ind_element {
 	bool is_bw_ind_element;
@@ -105,6 +105,7 @@ struct wide_bw_chan_switch {
  * @msg_source: message source of type enum tRrmMsgReqSource
  * @op_class: regulatory class
  * @channel: channel number
+ * @req_freq: freq as per channel load req
  * @randomization_intv: Random interval in ms
  * @meas_duration: measurement duration in ms
  * @bw_ind: Info for bandwidth indication IE
@@ -119,6 +120,7 @@ struct ch_load_ind {
 	tRrmMsgReqSource msg_source;
 	uint8_t op_class;
 	uint8_t channel;
+	qdf_freq_t req_freq;
 	uint16_t randomization_intv;
 	uint16_t meas_duration;
 	struct bw_ind_element bw_ind;
@@ -138,6 +140,8 @@ struct ch_load_ind {
  * @chan_load: channel utilization measurement
  * @rrm_scan_tsf: time at which driver triggers rrm scan for channel load
  * @is_report_success: need to send failure report or not
+ * @bw_ind: Info for bandwidth indication IE
+ * @wide_bw: Info for wide bandwidth channel switch IE
  */
 struct chan_load_xmit_ind {
 	uint16_t messageType;
@@ -151,6 +155,8 @@ struct chan_load_xmit_ind {
 	uint8_t chan_load;
 	qdf_time_t rrm_scan_tsf;
 	bool is_report_success;
+	struct bw_ind_element bw_ind;
+	struct wide_bw_chan_switch wide_bw;
 };
 
 typedef struct sSirBeaconReportReqInd {

+ 5 - 1
core/mac/src/pe/rrm/rrm_api.c

@@ -2182,6 +2182,7 @@ rrm_process_channel_load_req(struct mac_context *mac,
 	load_ind->randomization_intv = SYS_TU_TO_MS(randomization_intv);
 	load_ind->measurement_idx = curr_req->measurement_idx;
 	load_ind->channel = channel;
+	load_ind->req_freq = chan_freq;
 	load_ind->op_class = op_class;
 	load_ind->meas_duration = meas_duration;
 	curr_req->token = chan_load_req->measurement_token;
@@ -2332,7 +2333,10 @@ rrm_process_chan_load_report_xmit(struct mac_context *mac_ctx,
 	channel_load_report->rrm_scan_tsf = chan_load_ind->rrm_scan_tsf;
 	channel_load_report->meas_duration = chan_load_ind->duration;
 	channel_load_report->chan_load = chan_load_ind->chan_load;
-
+	qdf_mem_copy(&channel_load_report->bw_ind, &chan_load_ind->bw_ind,
+		     sizeof(channel_load_report->bw_ind));
+	qdf_mem_copy(&channel_load_report->wide_bw, &chan_load_ind->wide_bw,
+		     sizeof(channel_load_report->wide_bw));
 	pe_err("send chan load report for bssId:"QDF_MAC_ADDR_FMT" reg_class:%d, channel:%d, measStartTime:%llu, measDuration:%d, chan_load:%d",
 	       QDF_MAC_ADDR_REF(sessionBssId.bytes),
 	       channel_load_report->op_class,

+ 14 - 0
core/mac/src/sys/legacy/src/utils/src/parser_api.c

@@ -7092,6 +7092,20 @@ populate_dot11f_chan_load_report(struct mac_context *mac,
 	dot11f->report.channel_load_report.chan_load =
 				channel_load_report->chan_load;
 
+	if (channel_load_report->wide_bw.is_wide_bw_chan_switch) {
+		dot11f->report.channel_load_report.wide_bw_chan_switch.present = 1;
+		dot11f->report.channel_load_report.wide_bw_chan_switch.new_chan_width = channel_load_report->wide_bw.channel_width;
+		dot11f->report.channel_load_report.wide_bw_chan_switch.new_center_chan_freq0 = channel_load_report->wide_bw.center_chan_freq0;
+		dot11f->report.channel_load_report.wide_bw_chan_switch.new_center_chan_freq1 = channel_load_report->wide_bw.center_chan_freq1;
+	}
+
+	if (channel_load_report->bw_ind.is_bw_ind_element) {
+		dot11f->report.channel_load_report.bw_indication.present = 1;
+		dot11f->report.channel_load_report.bw_indication.channel_width = channel_load_report->bw_ind.channel_width;
+		dot11f->report.channel_load_report.bw_indication.ccfs0 = channel_load_report->bw_ind.center_freq_seg0;
+		dot11f->report.channel_load_report.bw_indication.ccfs1 = channel_load_report->bw_ind.center_freq_seg1;
+	}
+
 	pe_debug("regClass %d chan %d meas_time %d meas_dur %d, chan_load %d",
 		 dot11f->report.channel_load_report.op_class,
 		 dot11f->report.channel_load_report.channel,

+ 4 - 0
core/sme/inc/sme_rrm_internal.h

@@ -74,12 +74,16 @@ enum rrm_measurement_type {
 /**
  * enum channel_load_req_info: channel load request info
  * @channel: channel for which the host receives the channel load req from AP
+ * @req_chan_width: channel width for which the host receives the channel load
+ * req from AP
  * @rrm_scan_tsf: to store jiffies for RRM scan to process chan load req
  * @bw_ind: Contains info for Bandwidth Indication IE
  * @wide_bw: Contains info for Wide Bandwidth Channel IE
  */
 struct channel_load_req_info {
 	uint8_t channel;
+	qdf_freq_t req_freq;
+	enum phy_ch_width req_chan_width;
 	qdf_time_t rrm_scan_tsf;
 	struct bw_ind_element bw_ind;
 	struct wide_bw_chan_switch wide_bw;

+ 79 - 4
core/sme/src/rrm/sme_rrm.c

@@ -737,6 +737,10 @@ sme_rrm_send_chan_load_report_xmit_ind(struct mac_context *mac,
 	struct chan_load_xmit_ind *chan_load_resp;
 	uint16_t length;
 	tpRrmSMEContext rrm_ctx = &mac->rrm.rrmSmeContext[measurement_index];
+	const struct bonded_channel_freq *range;
+	uint8_t chan_load = 0, temp_chan_load;
+	qdf_freq_t start_freq, end_freq, op_freq;
+	enum phy_ch_width req_chan_width;
 
 	length = sizeof(struct chan_load_xmit_ind);
 	chan_load_resp = qdf_mem_malloc(length);
@@ -752,9 +756,77 @@ sme_rrm_send_chan_load_report_xmit_ind(struct mac_context *mac,
 	chan_load_resp->op_class = rrm_ctx->regClass;
 	chan_load_resp->channel = rrm_ctx->chan_load_req_info.channel;
 	chan_load_resp->rrm_scan_tsf = rrm_ctx->chan_load_req_info.rrm_scan_tsf;
-	wlan_cp_stats_get_rx_clear_count(mac->psoc, vdev_id,
-					 rrm_ctx->chan_load_req_info.channel,
-					 &chan_load_resp->chan_load);
+
+	op_freq = rrm_ctx->chan_load_req_info.req_freq;
+	req_chan_width = rrm_ctx->chan_load_req_info.req_chan_width;
+	if (req_chan_width == CH_WIDTH_INVALID) {
+		sme_debug("Invalid scanned_ch_width");
+		return;
+	}
+
+	if (req_chan_width == CH_WIDTH_20MHZ) {
+		start_freq = op_freq;
+		end_freq = op_freq;
+		sme_debug("cw %d: start_freq %d, end_freq %d", req_chan_width,
+			  start_freq, end_freq);
+	} else if (req_chan_width == CH_WIDTH_320MHZ) {
+		if (!rrm_ctx->chan_load_req_info.bw_ind.is_bw_ind_element) {
+			sme_debug("is_bw_ind_element is false");
+			return;
+		}
+
+		qdf_mem_copy(&chan_load_resp->bw_ind,
+			     &rrm_ctx->chan_load_req_info.bw_ind,
+			     sizeof(chan_load_resp->bw_ind));
+		range = wlan_reg_get_bonded_chan_entry(op_freq,
+			  rrm_ctx->chan_load_req_info.bw_ind.channel_width,
+			  rrm_ctx->chan_load_req_info.bw_ind.center_freq);
+		if (!range) {
+			sme_debug("vdev %d : range is null for freq %d",
+				  vdev_id, op_freq);
+			return;
+		}
+
+		start_freq = range->start_freq;
+		end_freq = range->end_freq;
+		sme_debug("cw %d: start_freq %d, end_freq %d", req_chan_width,
+			  start_freq, end_freq);
+	} else {
+		if (rrm_ctx->chan_load_req_info.wide_bw.is_wide_bw_chan_switch) {
+			qdf_mem_copy(&chan_load_resp->wide_bw,
+				     &rrm_ctx->chan_load_req_info.wide_bw,
+				     sizeof(chan_load_resp->wide_bw));
+			req_chan_width =
+			    rrm_ctx->chan_load_req_info.wide_bw.channel_width;
+			sme_debug("Fill wide_bw_chan_switch IE for cw:%d",
+				  req_chan_width);
+		}
+
+		range =
+		   wlan_reg_get_bonded_chan_entry(op_freq, req_chan_width, 0);
+		if (!range) {
+			sme_debug("range is NULL for freq %d, ch_width %d",
+				  op_freq, req_chan_width);
+			return;
+		}
+		start_freq = range->start_freq;
+		end_freq = range->end_freq;
+		sme_debug("cw %d: start_freq %d, end_freq %d",
+			  req_chan_width, start_freq, end_freq);
+	}
+
+	for (; start_freq <= end_freq;) {
+		temp_chan_load =
+			wlan_cp_stats_get_rx_clear_count(mac->psoc,
+							 vdev_id,
+							 start_freq);
+		if (chan_load < temp_chan_load)
+			chan_load = temp_chan_load;
+
+		start_freq += BW_20_MHZ;
+	}
+
+	chan_load_resp->chan_load = chan_load;
 
 	sme_debug("SME Sending CHAN_LOAD_REPORT_RESP_XMIT_IND to PE");
 	umac_send_mb_message_to_mac(chan_load_resp);
@@ -1204,6 +1276,7 @@ sme_rrm_fill_freq_list_for_channel_load(struct mac_context *mac_ctx,
 		}
 	}
 
+	sme_rrm_ctx->chan_load_req_info.req_chan_width = chan_width;
 	return mlme_update_freq_in_scan_start_req(vdev, req, chan_width,
 						  scan_freq, cen320_freq);
 }
@@ -1334,6 +1407,7 @@ static QDF_STATUS sme_rrm_process_chan_load_req_ind(struct mac_context *mac,
 		     SIR_ESE_MAX_MEAS_IE_REQS);
 	sme_rrm_ctx->measurement_type = RRM_CHANNEL_LOAD;
 	sme_rrm_ctx->chan_load_req_info.channel = chan_load->channel;
+	sme_rrm_ctx->chan_load_req_info.req_freq = chan_load->req_freq;
 
 	qdf_mem_copy(&sme_rrm_ctx->chan_load_req_info.bw_ind,
 			&chan_load->bw_ind,
@@ -1342,13 +1416,14 @@ static QDF_STATUS sme_rrm_process_chan_load_req_ind(struct mac_context *mac,
 			&chan_load->wide_bw,
 			sizeof(sme_rrm_ctx->chan_load_req_info.wide_bw));
 
-	sme_debug("idx:%d, token: %d randnIntvl: %d meas_duration %d, rrm_ctx dur %d reg_class: %d, type: %d, channel: %d, [bw_ind cw:%d, ccfs0:%d], [wide_bw cw:%d]",
+	sme_debug("idx:%d, token: %d randnIntvl: %d meas_duration %d, rrm_ctx dur %d reg_class: %d, type: %d, channel: %d, freq:%d, [bw_ind cw:%d, ccfs0:%d], [wide_bw cw:%d]",
 		  chan_load->measurement_idx, sme_rrm_ctx->token,
 		  sme_rrm_ctx->randnIntvl,
 		  chan_load->meas_duration,
 		  sme_rrm_ctx->duration[0], sme_rrm_ctx->regClass,
 		  sme_rrm_ctx->measurement_type,
 		  sme_rrm_ctx->chan_load_req_info.channel,
+		  sme_rrm_ctx->chan_load_req_info.req_freq,
 		  sme_rrm_ctx->chan_load_req_info.bw_ind.channel_width,
 		  sme_rrm_ctx->chan_load_req_info.bw_ind.center_freq,
 		  sme_rrm_ctx->chan_load_req_info.wide_bw.channel_width);