Browse Source

qcacld-3.0: Add API to set/get phymode for easymesh

Add API to set/get phymode for easymesh

Change-Id: I6d03de8ae61fa1b752213edcfd053e219fba3de9
CRs-Fixed: 3038234
Bing Sun 3 years ago
parent
commit
09c0fa4748

+ 19 - 12
core/hdd/src/wlan_hdd_cfg80211.c

@@ -7375,19 +7375,11 @@ static int wlan_hdd_cfg80211_wifi_set_rx_blocksize(struct hdd_adapter *adapter,
 	return ret_val;
 }
 
-/**
- * hdd_config_phy_mode() - set PHY mode
- * @adapter: hdd adapter
- * @attr: nla attr sent from userspace
- *
- * Return: 0 on success; error number otherwise
- */
-static int hdd_config_phy_mode(struct hdd_adapter *adapter,
-			       const struct nlattr *attr)
+int hdd_set_phy_mode(struct hdd_adapter *adapter,
+		     enum qca_wlan_vendor_phy_mode vendor_phy_mode)
 {
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
-	enum qca_wlan_vendor_phy_mode vendor_phy_mode;
 	eCsrPhyMode phymode;
 	uint8_t supported_band;
 	uint32_t bonding_mode;
@@ -7398,8 +7390,6 @@ static int hdd_config_phy_mode(struct hdd_adapter *adapter,
 		return -EINVAL;
 	}
 
-	vendor_phy_mode = nla_get_u32(attr);
-
 	ret = hdd_vendor_mode_to_phymode(vendor_phy_mode, &phymode);
 	if (ret < 0)
 		return ret;
@@ -7417,6 +7407,23 @@ static int hdd_config_phy_mode(struct hdd_adapter *adapter,
 				  bonding_mode);
 }
 
+/**
+ * hdd_config_phy_mode() - set PHY mode
+ * @adapter: hdd adapter
+ * @attr: nla attr sent from userspace
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int hdd_config_phy_mode(struct hdd_adapter *adapter,
+			       const struct nlattr *attr)
+{
+	enum qca_wlan_vendor_phy_mode vendor_phy_mode;
+
+	vendor_phy_mode = nla_get_u32(attr);
+
+	return hdd_set_phy_mode(adapter, vendor_phy_mode);
+}
+
 /**
  * hdd_set_roam_reason_vsie_status() - enable/disable inclusion of
  * roam reason vsie in Reassoc

+ 10 - 0
core/hdd/src/wlan_hdd_cfg80211.h

@@ -777,6 +777,16 @@ static inline void hdd_send_update_owe_info_event(struct hdd_adapter *adapter,
 }
 #endif
 
+/**
+ * hdd_set_phy_mode() - set phy mode
+ * @adapter: Handle to hdd_adapter
+ * @vendor_phy_mode: phy mode to set
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int hdd_set_phy_mode(struct hdd_adapter *adapter,
+		     enum qca_wlan_vendor_phy_mode vendor_phy_mode);
+
 /**
  * hdd_is_legacy_connection() - Is adapter connection is legacy
  * @adapter: Handle to hdd_adapter

+ 272 - 0
core/hdd/src/wlan_hdd_son.c

@@ -597,6 +597,276 @@ static qdf_freq_t hdd_son_get_candidate_freq(struct wlan_objmgr_vdev *vdev)
 	return freq;
 }
 
+/**
+ * hdd_son_phy_mode_to_vendor_phy_mode() - translate son phy mode to
+ *                                         vendor_phy_mode
+ * @mode: son phy mode
+ *
+ * Return: qca_wlan_vendor_phy_mode
+ */
+static enum qca_wlan_vendor_phy_mode hdd_son_phy_mode_to_vendor_phy_mode(
+						enum ieee80211_phymode mode)
+{
+	enum qca_wlan_vendor_phy_mode vendor_mode;
+
+	switch (mode) {
+	case IEEE80211_MODE_AUTO:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_AUTO;
+		break;
+	case IEEE80211_MODE_11A:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11A;
+		break;
+	case IEEE80211_MODE_11B:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11B;
+		break;
+	case IEEE80211_MODE_11G:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11G;
+		break;
+	case IEEE80211_MODE_11NA_HT20:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11NA_HT20;
+		break;
+	case IEEE80211_MODE_11NG_HT20:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11NG_HT20;
+		break;
+	case IEEE80211_MODE_11NA_HT40PLUS:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40PLUS;
+		break;
+	case IEEE80211_MODE_11NA_HT40MINUS:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40MINUS;
+		break;
+	case IEEE80211_MODE_11NG_HT40PLUS:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40PLUS;
+		break;
+	case IEEE80211_MODE_11NG_HT40MINUS:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40MINUS;
+		break;
+	case IEEE80211_MODE_11NG_HT40:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40;
+		break;
+	case IEEE80211_MODE_11NA_HT40:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40;
+		break;
+	case IEEE80211_MODE_11AC_VHT20:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT20;
+		break;
+	case IEEE80211_MODE_11AC_VHT40PLUS:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40PLUS;
+		break;
+	case IEEE80211_MODE_11AC_VHT40MINUS:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40MINUS;
+		break;
+	case IEEE80211_MODE_11AC_VHT40:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40;
+		break;
+	case IEEE80211_MODE_11AC_VHT80:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80;
+		break;
+	case IEEE80211_MODE_11AC_VHT160:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT160;
+		break;
+	case IEEE80211_MODE_11AC_VHT80_80:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80P80;
+		break;
+	case IEEE80211_MODE_11AXA_HE20:
+	case IEEE80211_MODE_11AXG_HE20:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AX_HE20;
+		break;
+	case IEEE80211_MODE_11AXA_HE40PLUS:
+	case IEEE80211_MODE_11AXG_HE40PLUS:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40PLUS;
+		break;
+	case IEEE80211_MODE_11AXA_HE40MINUS:
+	case IEEE80211_MODE_11AXG_HE40MINUS:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40MINUS;
+		break;
+	case IEEE80211_MODE_11AXA_HE40:
+	case IEEE80211_MODE_11AXG_HE40:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40;
+		break;
+	case IEEE80211_MODE_11AXA_HE80:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AX_HE80;
+		break;
+	case IEEE80211_MODE_11AXA_HE160:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AX_HE160;
+		break;
+	case IEEE80211_MODE_11AXA_HE80_80:
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AX_HE80P80;
+		break;
+	default:
+		hdd_err("Invalid config phy mode %d, set it as auto", mode);
+		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_AUTO;
+		break;
+	}
+
+	return vendor_mode;
+}
+
+/**
+ * hdd_son_set_phymode() - set son phy mode
+ * @vdev: vdev
+ * @mode: son phy mode to set
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int hdd_son_set_phymode(struct wlan_objmgr_vdev *vdev,
+			       enum ieee80211_phymode mode)
+{
+	struct hdd_adapter *adapter;
+	enum qca_wlan_vendor_phy_mode vendor_phy_mode;
+
+	if (!vdev) {
+		hdd_err("null vdev");
+		return -EINVAL;
+	}
+	adapter = wlan_hdd_get_adapter_from_objmgr(vdev);
+	if (!adapter) {
+		hdd_err("null adapter");
+		return -EINVAL;
+	}
+
+	vendor_phy_mode = hdd_son_phy_mode_to_vendor_phy_mode(mode);
+
+	return hdd_set_phy_mode(adapter, vendor_phy_mode);
+}
+
+/**
+ * hdd_phymode_chwidth_freq_to_son_phymode() - get son phymode from csr phymode
+ *                                             chan width and freq
+ * @phymode: csr phymode
+ * @chwidth: chan width
+ * @freq: chan frequence
+ *
+ * Return: ieee80211_phymode
+ */
+static enum ieee80211_phymode hdd_phymode_chwidth_freq_to_son_phymode(
+					eCsrPhyMode phymode,
+					enum eSirMacHTChannelWidth chwidth,
+					qdf_freq_t freq)
+{
+	uint32_t band_2g = WLAN_REG_IS_24GHZ_CH_FREQ(freq);
+	enum ieee80211_phymode son_phymode;
+
+	switch (phymode) {
+	case eCSR_DOT11_MODE_abg:
+	case eCSR_DOT11_MODE_AUTO:
+		son_phymode = IEEE80211_MODE_AUTO;
+		break;
+	case eCSR_DOT11_MODE_11a:
+		son_phymode = IEEE80211_MODE_11A;
+		break;
+	case eCSR_DOT11_MODE_11b:
+	case eCSR_DOT11_MODE_11b_ONLY:
+		son_phymode = IEEE80211_MODE_11B;
+		break;
+	case eCSR_DOT11_MODE_11g:
+	case eCSR_DOT11_MODE_11g_ONLY:
+		son_phymode = IEEE80211_MODE_11G;
+		break;
+	case eCSR_DOT11_MODE_11n:
+	case eCSR_DOT11_MODE_11n_ONLY:
+		if (chwidth == eHT_CHANNEL_WIDTH_40MHZ) {
+			if (band_2g)
+				son_phymode = IEEE80211_MODE_11NG_HT40;
+			else
+				son_phymode = IEEE80211_MODE_11NA_HT40;
+		} else {
+			if (band_2g)
+				son_phymode = IEEE80211_MODE_11NG_HT20;
+			else
+				son_phymode = IEEE80211_MODE_11NA_HT20;
+		}
+		break;
+	case eCSR_DOT11_MODE_11ac:
+	case eCSR_DOT11_MODE_11ac_ONLY:
+		if (chwidth == eHT_CHANNEL_WIDTH_160MHZ)
+			son_phymode = IEEE80211_MODE_11AC_VHT160;
+		else if (chwidth == eHT_CHANNEL_WIDTH_80P80MHZ)
+			son_phymode = IEEE80211_MODE_11AC_VHT80_80;
+		else if (chwidth == eHT_CHANNEL_WIDTH_80MHZ)
+			son_phymode = IEEE80211_MODE_11AC_VHT80;
+		else if (chwidth == eHT_CHANNEL_WIDTH_40MHZ)
+			son_phymode = IEEE80211_MODE_11AC_VHT40;
+		else
+			son_phymode = IEEE80211_MODE_11AC_VHT20;
+		break;
+	case eCSR_DOT11_MODE_11ax:
+	case eCSR_DOT11_MODE_11ax_ONLY:
+		if (chwidth == eHT_CHANNEL_WIDTH_160MHZ) {
+			son_phymode = IEEE80211_MODE_11AXA_HE160;
+		} else if (chwidth == eHT_CHANNEL_WIDTH_80P80MHZ) {
+			son_phymode = IEEE80211_MODE_11AXA_HE80_80;
+		} else if (chwidth == eHT_CHANNEL_WIDTH_80MHZ) {
+			son_phymode = IEEE80211_MODE_11AXA_HE80;
+		} else if (chwidth == eHT_CHANNEL_WIDTH_40MHZ) {
+			if (band_2g)
+				son_phymode = IEEE80211_MODE_11AXG_HE40;
+			else
+				son_phymode = IEEE80211_MODE_11AXA_HE40;
+		} else {
+			if (band_2g)
+				son_phymode = IEEE80211_MODE_11AXG_HE20;
+			else
+				son_phymode = IEEE80211_MODE_11AXA_HE20;
+		}
+		break;
+	default:
+		son_phymode = IEEE80211_MODE_AUTO;
+		break;
+	}
+
+	return son_phymode;
+}
+
+/**
+ * hdd_son_get_phymode() - get son phy mode
+ * @vdev: vdev
+ *
+ * Return: enum ieee80211_phymode
+ */
+static enum ieee80211_phymode hdd_son_get_phymode(struct wlan_objmgr_vdev *vdev)
+{
+	enum eSirMacHTChannelWidth chwidth;
+	eCsrPhyMode phymode;
+	struct hdd_adapter *adapter;
+	qdf_freq_t freq;
+	struct wlan_objmgr_pdev *pdev;
+	struct hdd_context *hdd_ctx;
+
+	if (!vdev) {
+		hdd_err("null vdev");
+		return IEEE80211_MODE_AUTO;
+	}
+	adapter = wlan_hdd_get_adapter_from_objmgr(vdev);
+	if (!adapter) {
+		hdd_err("null adapter");
+		return IEEE80211_MODE_AUTO;
+	}
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev) {
+		hdd_err("null pdev");
+		return IEEE80211_MODE_AUTO;
+	}
+
+	freq = ucfg_son_get_operation_chan_freq_vdev_id(pdev, adapter->vdev_id);
+
+	chwidth = wma_cli_get_command(adapter->vdev_id, WMI_VDEV_PARAM_CHWIDTH,
+				      VDEV_CMD);
+
+	if (chwidth < 0) {
+		hdd_err("Failed to get chwidth");
+		return IEEE80211_MODE_AUTO;
+	}
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (!hdd_ctx) {
+		hdd_err("null hdd ctx");
+		return IEEE80211_MODE_AUTO;
+	}
+	phymode = sme_get_phy_mode(hdd_ctx->mac_handle);
+
+	return hdd_phymode_chwidth_freq_to_son_phymode(phymode, chwidth, freq);
+}
+
 void hdd_son_register_callbacks(struct hdd_context *hdd_ctx)
 {
 	struct son_callbacks cb_obj = {0};
@@ -610,6 +880,8 @@ void hdd_son_register_callbacks(struct hdd_context *hdd_ctx)
 	cb_obj.os_if_set_country_code = hdd_son_set_country;
 	cb_obj.os_if_set_candidate_freq = hdd_son_set_candidate_freq;
 	cb_obj.os_if_get_candidate_freq = hdd_son_get_candidate_freq;
+	cb_obj.os_if_set_phymode = hdd_son_set_phymode;
+	cb_obj.os_if_get_phymode = hdd_son_get_phymode;
 
 	os_if_son_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj);
 }

+ 24 - 0
os_if/son/inc/os_if_son.h

@@ -43,6 +43,8 @@
  * @os_if_set_country_code: set country code
  * @os_if_set_candidate_freq: set freq to switch after radar detection
  * @os_if_get_candidate_freq: get freq to switch after radar detection
+ * @os_if_set_phymode: set phy mode
+ * @os_if_get_phymode: get phy mode
  */
 struct son_callbacks {
 	uint32_t (*os_if_is_acs_in_progress)(struct wlan_objmgr_vdev *vdev);
@@ -62,6 +64,10 @@ struct son_callbacks {
 	int (*os_if_set_candidate_freq)(struct wlan_objmgr_vdev *vdev,
 					qdf_freq_t freq);
 	qdf_freq_t (*os_if_get_candidate_freq)(struct wlan_objmgr_vdev *vdev);
+	int (*os_if_set_phymode)(struct wlan_objmgr_vdev *vdev,
+				 enum ieee80211_phymode mode);
+	enum ieee80211_phymode (*os_if_get_phymode)(
+					struct wlan_objmgr_vdev *vdev);
 };
 
 /**
@@ -256,4 +262,22 @@ int os_if_son_set_candidate_freq(struct wlan_objmgr_vdev *vdev,
  * Return: candidate freq to switch after radar detection
  */
 qdf_freq_t os_if_son_get_candidate_freq(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * os_if_son_get_phymode() - get phy mode
+ * @vdev: vdev
+ *
+ * Return: enum ieee80211_phymode
+ */
+enum ieee80211_phymode os_if_son_get_phymode(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * os_if_son_set_phymode() - set phy mode
+ * @vdev: vdev
+ * @mode: son phy mode to set
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int os_if_son_set_phymode(struct wlan_objmgr_vdev *vdev,
+			  enum ieee80211_phymode mode);
 #endif

+ 35 - 0
os_if/son/src/os_if_son.c

@@ -623,3 +623,38 @@ qdf_freq_t os_if_son_get_candidate_freq(struct wlan_objmgr_vdev *vdev)
 	return freq;
 }
 qdf_export_symbol(os_if_son_get_candidate_freq);
+
+int os_if_son_set_phymode(struct wlan_objmgr_vdev *vdev,
+			  enum ieee80211_phymode mode)
+{
+	int ret;
+
+	if (!vdev) {
+		osif_err("null vdev");
+		return 0;
+	}
+
+	ret = g_son_os_if_cb.os_if_set_phymode(vdev, mode);
+	osif_debug("vdev %d phymode %d ret %d",
+		   wlan_vdev_get_id(vdev), mode, ret);
+
+	return ret;
+}
+qdf_export_symbol(os_if_son_set_phymode);
+
+enum ieee80211_phymode os_if_son_get_phymode(struct wlan_objmgr_vdev *vdev)
+{
+	enum ieee80211_phymode phymode;
+
+	if (!vdev) {
+		osif_err("null vdev");
+		return 0;
+	}
+
+	phymode = g_son_os_if_cb.os_if_get_phymode(vdev);
+	osif_debug("vdev %d phymode %d",
+		   wlan_vdev_get_id(vdev), phymode);
+
+	return phymode;
+}
+qdf_export_symbol(os_if_son_get_phymode);