Procházet zdrojové kódy

qcacld-3.0: Fix legacy STA did not follow AP bandwidth

Currently if reference AP upgrades its channel bandwidth, STA
does not follow it.
Make legacy STA follow channel bandwidth of ap through
lim_handle_sta_csa_param.

Change-Id: Ic4473189a0df5edf9475d6683df1387ac4a4375a
CRs-Fixed: 3326762
Bing Sun před 2 roky
rodič
revize
9dd94bfc5f
1 změnil soubory, kde provedl 83 přidání a 6 odebrání
  1. 83 6
      core/mac/src/pe/lim/lim_utils.c

+ 83 - 6
core/mac/src/pe/lim/lim_utils.c

@@ -4850,18 +4850,95 @@ void lim_pmf_sa_query_timer_handler(void *pMacGlobal, uint32_t param)
 	}
 }
 
+/**
+ * lim_get_update_bw_allow() whether bw can be sent to target directly
+ * @session: pe session
+ * @new_bw: bandwdith to set
+ * @update_allow: return true if bw and puncture can be updated directly
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+lim_get_update_bw_allow(struct pe_session *session,
+			enum phy_ch_width new_bw,
+			bool *update_allow)
+{
+	enum phy_ch_width ch_width;
+	struct wlan_objmgr_psoc *psoc;
+	enum wlan_phymode phy_mode;
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+
+	*update_allow = false;
+
+	if (!session || !update_allow) {
+		pe_err("invalid input");
+		return status;
+	}
+	psoc = wlan_vdev_get_psoc(session->vdev);
+	if (!psoc) {
+		pe_err("psoc object invalid");
+		return status;
+	}
+	status = mlme_get_peer_phymode(psoc, session->bssId, &phy_mode);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pe_err("failed to get phy_mode %d mac: " QDF_MAC_ADDR_FMT,
+		       status, QDF_MAC_ADDR_REF(session->bssId));
+		return status;
+	}
+	ch_width = wlan_mlme_get_ch_width_from_phymode(phy_mode);
+	if (new_bw <= ch_width)
+		*update_allow = true;
+
+	return status;
+}
+
 bool lim_check_vht_op_mode_change(struct mac_context *mac,
 				  struct pe_session *pe_session,
 				  uint8_t chanWidth, uint8_t *peerMac)
 {
-	tUpdateVHTOpMode tempParam;
+	QDF_STATUS status;
+	bool update_allow = false;
+	struct ch_params ch_params;
+	struct csa_offload_params *csa_param;
 
-	tempParam.opMode = chanWidth;
-	tempParam.smesessionId = pe_session->smeSessionId;
-	qdf_mem_copy(tempParam.peer_mac, peerMac, sizeof(tSirMacAddr));
+	status = lim_get_update_bw_allow(pe_session, chanWidth, &update_allow);
+	if (QDF_IS_STATUS_ERROR(status))
+		return false;
+
+	if (update_allow) {
+		tUpdateVHTOpMode tempParam;
+
+		tempParam.opMode = chanWidth;
+		tempParam.smesessionId = pe_session->smeSessionId;
+		qdf_mem_copy(tempParam.peer_mac, peerMac, sizeof(tSirMacAddr));
+
+		lim_send_mode_update(mac, &tempParam, pe_session);
+		lim_update_tdls_2g_bw(pe_session);
+
+		return true;
+	}
+
+	qdf_mem_zero(&ch_params, sizeof(ch_params));
+	ch_params.ch_width = chanWidth;
+	wlan_reg_set_channel_params_for_pwrmode(mac->pdev,
+						pe_session->curr_op_freq,
+						0, &ch_params,
+						REG_CURRENT_PWR_MODE);
+	csa_param = qdf_mem_malloc(sizeof(*csa_param));
+	if (!csa_param) {
+		pe_err("csa_param allocation fails");
+		return false;
+	}
 
-	lim_send_mode_update(mac, &tempParam, pe_session);
-	lim_update_tdls_2g_bw(pe_session);
+	csa_param->channel = wlan_reg_freq_to_chan(mac->pdev,
+						   pe_session->curr_op_freq);
+	csa_param->csa_chan_freq = pe_session->curr_op_freq;
+	csa_param->new_ch_width = ch_params.ch_width;
+	csa_param->new_ch_freq_seg1 = ch_params.center_freq_seg0;
+	csa_param->new_ch_freq_seg2 = ch_params.center_freq_seg1;
+	qdf_copy_macaddr(&csa_param->bssid,
+			 (struct qdf_mac_addr *)pe_session->bssId);
+	lim_handle_sta_csa_param(mac, csa_param);
 
 	return true;
 }