Browse Source

qcacld-3.0: Add support to set primary STA interface

Add support to primary STA iface when there are more
than one STA iface concurrently active via the
SET_WIFI_CONFIGURATION vendor command.

Below attribute associated with this vendor command to
give indication to host to set primary interface:
QCA_WLAN_VENDOR_ATTR_CONFIG_CONCURRENT_STA_PRIMARY.
Set indicates that the specified iface is the primary
STA iface.

This configuration helps the firmware/chip to support
certain features (e.g., roaming) on this primary interface,
if the same cannot be supported on concurrent STA ifaces
simultaneously.
This configuration is only applicable for the STA iface and
gives the priority for it only over other concurrent STA
ifaces. 1-Enable, 0-Disable.

Change-Id: I2bc7d8880c78c0c05e824f58aadacd84369d1880
CRs-Fixed: 2915728
abhinav kumar 4 years ago
parent
commit
0ad5179cd6

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

@@ -1053,6 +1053,20 @@ QDF_STATUS wlan_mlme_get_fils_enabled_info(struct wlan_objmgr_psoc *psoc,
 QDF_STATUS wlan_mlme_set_fils_enabled_info(struct wlan_objmgr_psoc *psoc,
 					   bool value);
 
+/**
+ * wlan_mlme_set_primary_interface() - Set the primary iface id for driver
+ * @psoc: pointer to psoc object
+ * @value: value that needs to be set from the caller
+ *
+ * When a vdev is set as primary then based on the dual sta policy
+ * "qca_wlan_concurrent_sta_policy_config" mcc preference and roaming has
+ * to be enabled on the primary vdev
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wlan_mlme_set_primary_interface(struct wlan_objmgr_psoc *psoc,
+					   uint8_t value);
+
 /**
  * wlan_mlme_get_tl_delayed_trgr_frm_int() - Get delay interval(in ms)
  * of UAPSD auto trigger

+ 3 - 0
components/mlme/dispatcher/inc/wlan_mlme_public_struct.h

@@ -1280,9 +1280,12 @@ struct wlan_mlme_ratemask {
  * struct dual_sta_policy - Concurrent STA policy configuration
  * @concurrent_sta_policy: Possible values are defined in enum
  * qca_wlan_concurrent_sta_policy_config
+ * @primary_vdev_id: specified iface is the primary STA iface, say 0 means
+ * vdev 0 is acting as primary interface
  */
 struct dual_sta_policy {
 	uint8_t concurrent_sta_policy;
+	uint8_t primary_vdev_id;
 };
 
 /* struct wlan_mlme_generic - Generic CFG config items

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

@@ -1961,6 +1961,26 @@ QDF_STATUS ucfg_mlme_set_fils_enabled_info(struct wlan_objmgr_psoc *psoc,
 	return wlan_mlme_set_fils_enabled_info(psoc, value);
 }
 
+/**
+ * ucfg_mlme_set_primary_interface() - Set primary STA iface id
+ *
+ * @psoc: pointer to psoc object
+ * @value: value that needs to be set from the caller
+ *
+ * When a vdev is set as primary then based on the dual sta policy
+ * "qca_wlan_concurrent_sta_policy_config" mcc preference and roaming has
+ * to be enabled on the primary vdev
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_FAILURE
+ */
+static inline
+QDF_STATUS ucfg_mlme_set_primary_interface(struct wlan_objmgr_psoc *psoc,
+					   uint8_t value)
+{
+	return wlan_mlme_set_primary_interface(psoc, value);
+}
+
+
 /**
  * ucfg_mlme_set_enable_bcast_probe_rsp() - Set enable bcast probe resp info
  * @psoc: pointer to psoc object

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

@@ -2411,6 +2411,18 @@ QDF_STATUS wlan_mlme_set_fils_enabled_info(struct wlan_objmgr_psoc *psoc,
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS wlan_mlme_set_primary_interface(struct wlan_objmgr_psoc *psoc,
+					   uint8_t value)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc);
+
+	if (!mlme_obj)
+		return QDF_STATUS_E_FAILURE;
+
+	mlme_obj->cfg.gen.dual_sta_policy.primary_vdev_id = value;
+	return QDF_STATUS_SUCCESS;
+}
+
 QDF_STATUS wlan_mlme_set_enable_bcast_probe_rsp(struct wlan_objmgr_psoc *psoc,
 						bool value)
 {

+ 31 - 1
core/hdd/src/wlan_hdd_cfg80211.c

@@ -7001,7 +7001,8 @@ const struct nla_policy wlan_hdd_wifi_config_policy[
 	[QCA_WLAN_VENDOR_ATTR_CONFIG_ANI_LEVEL] = {.type = NLA_S32 },
 	[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS] = {.type = NLA_U8 },
 	[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS] = {.type = NLA_U8 },
-
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_CONCURRENT_STA_PRIMARY] = {
+							.type = NLA_U8 },
 };
 
 static const struct nla_policy
@@ -8623,6 +8624,33 @@ static int hdd_config_disable_fils(struct hdd_adapter *adapter,
 	return qdf_status_to_os_return(status);
 }
 
+static int hdd_set_primary_interface(struct hdd_adapter *adapter,
+				     const struct nlattr *attr)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	bool is_set_primary_iface;
+	QDF_STATUS status;
+	uint8_t primary_vdev_id;
+
+	/* ignore unless in STA mode */
+	if (adapter->device_mode != QDF_STA_MODE)
+		return 0;
+
+	is_set_primary_iface = nla_get_u8(attr);
+
+	primary_vdev_id = is_set_primary_iface ? adapter->vdev_id : WLAN_UMAC_VDEV_ID_MAX;
+	hdd_debug("Primary interface: %d", primary_vdev_id);
+
+	status = ucfg_mlme_set_primary_interface(hdd_ctx->psoc,
+						 primary_vdev_id);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("could not set primary interface, %d", status);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int hdd_config_rsn_ie(struct hdd_adapter *adapter,
 			     const struct nlattr *attr)
 {
@@ -8976,6 +9004,8 @@ static const struct independent_setters independent_setters[] = {
 	 hdd_config_power},
 	{QCA_WLAN_VENDOR_ATTR_CONFIG_UDP_QOS_UPGRADE,
 	 hdd_config_udp_qos_upgrade_threshold},
+	{QCA_WLAN_VENDOR_ATTR_CONFIG_CONCURRENT_STA_PRIMARY,
+	 hdd_set_primary_interface},
 };
 
 #ifdef WLAN_FEATURE_ELNA