Browse Source

qcacld-3.0: Update HE capabilities in wiphy structure

Update the mac, phy, mcs, nss caps of bands
2.4ghz, and 5ghz for HE capabilities in the
wiphy structure to inform userspace about
the driver capability.

Change-Id: I9fb1233e5396bf3ea411c057af9cbcd5b358271c
CRs-Fixed: 2486266
gaurank kathpalia 5 years ago
parent
commit
ccfca4a11e

+ 10 - 0
components/mlme/dispatcher/inc/wlan_mlme_api.h

@@ -822,6 +822,16 @@ QDF_STATUS wlan_mlme_cfg_get_he_ul_mumimo(struct wlan_objmgr_psoc *psoc,
 QDF_STATUS wlan_mlme_cfg_set_he_ul_mumimo(struct wlan_objmgr_psoc *psoc,
 					  uint32_t value);
 
+/**
+ * mlme_cfg_get_he_caps() - Get the HE capability info
+ * @psoc: pointer to psoc object
+ * @he_cap: Caps that needs to be filled.
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS mlme_cfg_get_he_caps(struct wlan_objmgr_psoc *psoc,
+				tDot11fIEhe_cap *he_cap);
+
 /**
  * wlan_mlme_cfg_get_enable_ul_mimo() - Get the HE Ul mimo
  * @psoc: pointer to psoc object

+ 14 - 0
components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h

@@ -3149,6 +3149,20 @@ ucfg_mlme_update_tgt_he_cap(struct wlan_objmgr_psoc *psoc,
 	return mlme_update_tgt_he_caps_in_cfg(psoc, cfg);
 }
 
+/**
+ * ucfg_mlme_cfg_get_he_caps() - Get the HE capability info
+ * @psoc: pointer to psoc object
+ * @he_cap: Caps that needs to be filled.
+ *
+ * Return: QDF Status
+ */
+static inline
+QDF_STATUS ucfg_mlme_cfg_get_he_caps(struct wlan_objmgr_psoc *psoc,
+				     tDot11fIEhe_cap *he_cap)
+{
+	return mlme_cfg_get_he_caps(psoc, he_cap);
+}
+
 /**
  * ucfg_mlme_cfg_get_he_ul_mumimo() - Get the HE Ul Mumio
  * @psoc: pointer to psoc object

+ 14 - 0
components/mlme/dispatcher/src/wlan_mlme_api.c

@@ -471,6 +471,20 @@ QDF_STATUS wlan_mlme_cfg_get_he_ul_mumimo(struct wlan_objmgr_psoc *psoc,
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS mlme_cfg_get_he_caps(struct wlan_objmgr_psoc *psoc,
+				tDot11fIEhe_cap *he_cap)
+{
+	struct wlan_mlme_psoc_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_obj(psoc);
+	if (!mlme_obj)
+		return QDF_STATUS_E_FAILURE;
+
+	*he_cap = mlme_obj->cfg.he_caps.he_cap_orig;
+
+	return QDF_STATUS_SUCCESS;
+}
+
 QDF_STATUS wlan_mlme_cfg_set_he_ul_mumimo(struct wlan_objmgr_psoc *psoc,
 					  uint32_t value)
 {

+ 7 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -1665,6 +1665,8 @@ struct hdd_fw_ver_info {
  * struct hdd_context - hdd shared driver and psoc/device context
  * @psoc: object manager psoc context
  * @pdev: object manager pdev context
+ * @iftype_data_2g: Interface data for 2g band
+ * @iftype_data_5g: Interface data for 5g band
  * @bus_bw_work: work for periodically computing DDR bus bandwidth requirements
  * @g_event_flags: a bitmap of hdd_driver_flags
  * @psoc_idle_timeout_work: delayed work for psoc idle shutdown
@@ -1697,6 +1699,11 @@ struct hdd_context {
 	struct ieee80211_channel *channels_2ghz;
 	struct ieee80211_channel *channels_5ghz;
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
+	struct ieee80211_sband_iftype_data *iftype_data_2g;
+	struct ieee80211_sband_iftype_data *iftype_data_5g;
+#endif
+
 	/* Completion  variable to indicate Mc Thread Suspended */
 	struct completion mc_sus_event_var;
 

+ 64 - 9
core/hdd/src/wlan_hdd_cfg80211.c

@@ -13294,6 +13294,53 @@ wlan_hdd_populate_srd_chan_info(struct hdd_context *hdd_ctx, uint32_t index)
 
 #endif
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
+static QDF_STATUS
+wlan_hdd_iftype_data_alloc(struct hdd_context *hdd_ctx)
+{
+	hdd_ctx->iftype_data_2g =
+			qdf_mem_malloc(sizeof(*hdd_ctx->iftype_data_2g));
+
+	if (!hdd_ctx->iftype_data_2g) {
+		hdd_err("mem alloc failed for 2g iftype data");
+		return QDF_STATUS_E_NOMEM;
+	}
+	hdd_ctx->iftype_data_5g =
+			qdf_mem_malloc(sizeof(*hdd_ctx->iftype_data_5g));
+
+	if (!hdd_ctx->iftype_data_5g) {
+		hdd_err("mem alloc failed for 5g iftype data");
+		qdf_mem_free(hdd_ctx->iftype_data_2g);
+		hdd_ctx->iftype_data_2g = NULL;
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static inline QDF_STATUS
+wlan_hdd_iftype_data_alloc(struct hdd_context *hdd_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
+static void
+wlan_hdd_iftype_data_mem_free(struct hdd_context *hdd_ctx)
+{
+	qdf_mem_free(hdd_ctx->iftype_data_5g);
+	qdf_mem_free(hdd_ctx->iftype_data_2g);
+	hdd_ctx->iftype_data_5g = NULL;
+	hdd_ctx->iftype_data_2g = NULL;
+}
+#else
+static inline void
+wlan_hdd_iftype_data_mem_free(struct hdd_context *hdd_ctx)
+{
+}
+#endif
+
 /*
  * FUNCTION: wlan_hdd_cfg80211_init
  * This function is called by hdd_wlan_startup()
@@ -13377,14 +13424,17 @@ int wlan_hdd_cfg80211_init(struct device *dev,
 	}
 	hdd_ctx->channels_5ghz = qdf_mem_malloc(band_5_ghz_chanenls_size);
 	if (!hdd_ctx->channels_5ghz)
-		goto mem_fail;
+		goto mem_fail_5g;
+
+	if (QDF_IS_STATUS_ERROR(wlan_hdd_iftype_data_alloc(hdd_ctx)))
+		goto mem_fail_iftype_data;
 
 	/*Initialise the supported cipher suite details */
 	if (ucfg_fwol_get_gcmp_enable(hdd_ctx->psoc)) {
 		cipher_suites = qdf_mem_malloc(sizeof(hdd_cipher_suites) +
 					       sizeof(hdd_gcmp_cipher_suits));
 		if (!cipher_suites)
-			return -ENOMEM;
+			goto mem_fail_cipher_suites;
 		wiphy->n_cipher_suites = QDF_ARRAY_SIZE(hdd_cipher_suites) +
 			 QDF_ARRAY_SIZE(hdd_gcmp_cipher_suits);
 		qdf_mem_copy(cipher_suites, &hdd_cipher_suites,
@@ -13395,7 +13445,7 @@ int wlan_hdd_cfg80211_init(struct device *dev,
 	} else {
 		cipher_suites = qdf_mem_malloc(sizeof(hdd_cipher_suites));
 		if (!cipher_suites)
-			return -ENOMEM;
+			goto mem_fail_cipher_suites;
 		wiphy->n_cipher_suites = QDF_ARRAY_SIZE(hdd_cipher_suites);
 		qdf_mem_copy(cipher_suites, &hdd_cipher_suites,
 			     sizeof(hdd_cipher_suites));
@@ -13436,12 +13486,16 @@ int wlan_hdd_cfg80211_init(struct device *dev,
 	hdd_exit();
 	return 0;
 
-mem_fail:
+mem_fail_cipher_suites:
+	wlan_hdd_iftype_data_mem_free(hdd_ctx);
+mem_fail_iftype_data:
+	qdf_mem_free(hdd_ctx->channels_5ghz);
+	hdd_ctx->channels_5ghz = NULL;
+mem_fail_5g:
 	hdd_err("Not enough memory to allocate channels");
-	if (hdd_ctx->channels_2ghz) {
-		qdf_mem_free(hdd_ctx->channels_2ghz);
-		hdd_ctx->channels_2ghz = NULL;
-	}
+	qdf_mem_free(hdd_ctx->channels_2ghz);
+	hdd_ctx->channels_2ghz = NULL;
+
 	return -ENOMEM;
 }
 
@@ -13466,8 +13520,9 @@ void wlan_hdd_cfg80211_deinit(struct wiphy *wiphy)
 		   (wiphy->bands[i]->channels))
 			wiphy->bands[i]->channels = NULL;
 	}
-	qdf_mem_free(hdd_ctx->channels_2ghz);
+	wlan_hdd_iftype_data_mem_free(hdd_ctx);
 	qdf_mem_free(hdd_ctx->channels_5ghz);
+	qdf_mem_free(hdd_ctx->channels_2ghz);
 	hdd_ctx->channels_2ghz = NULL;
 	hdd_ctx->channels_5ghz = NULL;
 

+ 38 - 0
core/hdd/src/wlan_hdd_main.c

@@ -1993,6 +1993,43 @@ static void hdd_extract_fw_version_info(struct hdd_context *hdd_ctx)
 			HDD_FW_VER_REL_ID(hdd_ctx->target_fw_vers_ext);
 }
 
+#if defined(WLAN_FEATURE_11AX) && \
+	   (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
+static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx)
+{
+	tDot11fIEhe_cap he_cap_cfg;
+	struct ieee80211_supported_band *band_2g =
+			hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ];
+	struct ieee80211_supported_band *band_5g =
+			hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ];
+	QDF_STATUS status;
+
+	status = ucfg_mlme_cfg_get_he_caps(hdd_ctx->psoc, &he_cap_cfg);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		return;
+
+	if (band_2g) {
+		hdd_ctx->iftype_data_2g->types_mask =
+			(BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP));
+		hdd_ctx->iftype_data_2g->he_cap.has_he = he_cap_cfg.present;
+		band_2g->n_iftype_data = 1;
+		band_2g->iftype_data = hdd_ctx->iftype_data_2g;
+	}
+	if (band_5g) {
+		hdd_ctx->iftype_data_5g->types_mask =
+			(BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP));
+		hdd_ctx->iftype_data_5g->he_cap.has_he = he_cap_cfg.present;
+		band_5g->n_iftype_data = 1;
+		band_5g->iftype_data = hdd_ctx->iftype_data_5g;
+	}
+}
+#else
+static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx)
+{
+}
+#endif
+
 int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg)
 {
 	int ret;
@@ -2161,6 +2198,7 @@ int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg)
 	if (cfg->services.en_11ax) {
 		hdd_info("11AX: 11ax is enabled - update HDD config");
 		hdd_update_tgt_he_cap(hdd_ctx, cfg);
+		hdd_update_wiphy_he_cap(hdd_ctx);
 	}
 	hdd_update_tgt_twt_cap(hdd_ctx, cfg);