Browse Source

qcacld-3.0: Enable ML support for virtual interface

For virtual interface, add support to create the interface
as ML capable.
Currently implementation will create a single link ML interface.
This ML capability will only be enabled for STA/SAP type mode.

Change-Id: I11263460ee8404c8ea319cd139d92b080035b416
CRs-Fixed: 3315353
Vinod Kumar Pirla 2 years ago
parent
commit
370fadfee0

+ 28 - 4
core/hdd/inc/wlan_hdd_mlo.h

@@ -33,18 +33,22 @@
  * @associate_with_ml_adapter: Vdev points to the same netdev adapter
  * @is_ml_adapter: is a ml adapter with associated netdev
  * @is_add_virtual_iface: is netdev create request from add virtual interface
+ * @is_single_link: Is the adapter single link ML
  */
 struct hdd_adapter_create_param {
 	uint32_t only_wdev_register:1,
 		 associate_with_ml_adapter:1,
 		 is_ml_adapter:1,
 		 is_add_virtual_iface:1,
-		 unused:28;
+		 is_single_link:1,
+		 unused:27;
 };
 
 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
 #define hdd_adapter_is_link_adapter(x) ((x)->mlo_adapter_info.is_link_adapter)
 #define hdd_adapter_is_ml_adapter(x)   ((x)->mlo_adapter_info.is_ml_adapter)
+#define hdd_adapter_is_sl_ml_adapter(x) \
+			   ((x)->mlo_adapter_info.is_single_link_ml)
 #define hdd_adapter_is_associated_with_ml_adapter(x) \
 			   ((x)->mlo_adapter_info.associate_with_ml_adapter)
 #define hdd_adapter_get_mlo_adapter_from_link(x) \
@@ -52,6 +56,7 @@ struct hdd_adapter_create_param {
 #else
 #define hdd_adapter_is_link_adapter(x) (0)
 #define hdd_adapter_is_ml_adapter(x)   (0)
+#define hdd_adapter_is_sl_ml_adapter(x) (0)
 #define hdd_adapter_is_associated_with_ml_adapter(x) (0)
 #define hdd_adapter_get_mlo_adapter_from_link(x) (NULL)
 #endif
@@ -64,7 +69,8 @@ struct hdd_adapter_create_param {
  * @is_link_adapter: Whether this a link adapter without netdev
  * @associate_with_ml_adapter: adapter which shares the vdev object with the ml
  * adapter
- * num_of_vdev_links: Num of vdevs/links part of the association
+ * @num_of_vdev_links: Num of vdevs/links part of the association
+ * @is_single_link_ml: Is the adapter a single link ML adapter
  * @ml_adapter: ML adapter backpointer
  * @link_adapter: backpointers to link adapters part of association
  */
@@ -73,7 +79,8 @@ struct hdd_mlo_adapter_info {
 		 is_link_adapter:1,
 		 associate_with_ml_adapter:1,
 		 num_of_vdev_links:2,
-		 unused:27;
+		 is_single_link_ml:1,
+		 unused:26;
 	struct hdd_adapter *ml_adapter;
 	struct hdd_adapter *link_adapter[WLAN_MAX_MLD];
 };
@@ -120,6 +127,15 @@ void hdd_wlan_register_mlo_interfaces(struct hdd_context *hdd_ctx);
  */
 void hdd_adapter_set_ml_adapter(struct hdd_adapter *adapter);
 
+/**
+ * hdd_adapter_set_sl_ml_adapter() - Set adapter as sl ml adapter
+ * @adapter: HDD adapter
+ *
+ * This function sets adapter as single link ML adapter
+ * Return: None
+ */
+void hdd_adapter_set_sl_ml_adapter(struct hdd_adapter *adapter);
+
 /**
  * hdd_get_ml_adater() - get an ml adapter
  * @adapter: HDD adapter
@@ -133,7 +149,10 @@ struct hdd_adapter *hdd_get_ml_adater(struct hdd_context *hdd_ctx);
  * hdd_get_assoc_link_adapter() - get assoc link adapter
  * @ml_adapter: ML adapter
  *
- * This function returns assoc link adapter
+ * This function returns assoc link adapter.
+ * For single link ML adapter, function returns
+ * same adapter pointer.
+ *
  * Return: adapter or NULL
  */
 struct hdd_adapter *hdd_get_assoc_link_adapter(struct hdd_adapter *ml_adapter);
@@ -162,6 +181,11 @@ hdd_adapter_set_ml_adapter(struct hdd_adapter *adapter)
 {
 }
 
+static inline void
+hdd_adapter_set_sl_ml_adapter(struct hdd_adapter *adapter)
+{
+}
+
 static inline
 struct hdd_adapter *hdd_get_ml_adater(struct hdd_context *hdd_ctx)
 {

+ 8 - 4
core/hdd/src/wlan_hdd_cm_connect.c

@@ -1242,18 +1242,22 @@ struct hdd_adapter *hdd_get_assoc_link_adapter(struct hdd_adapter *ml_adapter)
 {
 	int i;
 	bool eht_capab;
+	struct hdd_adapter *link_adapter;
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ml_adapter);
 
 	ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab);
-	if (!eht_capab)
+	if (!eht_capab || hdd_adapter_is_sl_ml_adapter(ml_adapter))
 		return ml_adapter;
 
 	for (i = 0; i < WLAN_MAX_MLD; i++) {
-		if (hdd_adapter_is_associated_with_ml_adapter(
-		    ml_adapter->mlo_adapter_info.link_adapter[i])) {
-			return ml_adapter->mlo_adapter_info.link_adapter[i];
+		link_adapter = ml_adapter->mlo_adapter_info.link_adapter[i];
+		if (link_adapter) {
+			if (hdd_adapter_is_associated_with_ml_adapter(
+								link_adapter))
+				return link_adapter;
 		}
 	}
+
 	return NULL;
 }
 #endif

+ 27 - 17
core/hdd/src/wlan_hdd_main.c

@@ -5114,6 +5114,12 @@ int hdd_dynamic_mac_address_set(struct hdd_context *hdd_ctx,
 		update_self_peer =
 			hdd_adapter_is_associated_with_ml_adapter(adapter);
 		update_mld_addr = true;
+	} else if (hdd_adapter_is_sl_ml_adapter(adapter)) {
+		update_mld_addr = true;
+		if (adapter->device_mode == QDF_SAP_MODE)
+			update_self_peer = false;
+		else
+			update_self_peer = true;
 	} else {
 		update_self_peer = true;
 		update_mld_addr = false;
@@ -5229,7 +5235,6 @@ static int __hdd_set_mac_address(struct net_device *dev, void *addr)
 	int ret;
 	struct qdf_mac_addr mac_addr;
 	bool net_if_running = netif_running(dev);
-	bool eht_capab;
 
 	hdd_enter_dev(dev);
 
@@ -6319,8 +6324,7 @@ static void
 hdd_populate_vdev_create_params(struct hdd_adapter *adapter,
 				struct wlan_vdev_create_params *vdev_params)
 {
-	int i;
-	struct hdd_mlo_adapter_info *mlo_adapter_info, *link_mlo_adapter_info;
+	struct hdd_mlo_adapter_info *mlo_adapter_info;
 	struct hdd_adapter *link_adapter;
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 	bool eht_capab;
@@ -6329,19 +6333,12 @@ hdd_populate_vdev_create_params(struct hdd_adapter *adapter,
 	mlo_adapter_info = &adapter->mlo_adapter_info;
 
 	ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab);
-	if (mlo_adapter_info->is_ml_adapter &&
-	    adapter->device_mode == QDF_STA_MODE && eht_capab) {
-		for (i = 0; i < WLAN_MAX_MLD; i++) {
-			link_adapter = mlo_adapter_info->link_adapter[i];
-			if (!link_adapter)
-				continue;
-			link_mlo_adapter_info = &link_adapter->mlo_adapter_info;
-			if (link_mlo_adapter_info->associate_with_ml_adapter) {
-				qdf_mem_copy(vdev_params->macaddr,
-					     link_adapter->mac_addr.bytes,
-					     QDF_MAC_ADDR_SIZE);
-				break;
-			}
+	if (mlo_adapter_info->is_ml_adapter && eht_capab) {
+		link_adapter = hdd_get_assoc_link_adapter(adapter);
+		if (link_adapter) {
+			qdf_mem_copy(vdev_params->macaddr,
+				     link_adapter->mac_addr.bytes,
+				     QDF_MAC_ADDR_SIZE);
 		}
 	} else {
 		qdf_mem_copy(vdev_params->macaddr, adapter->mac_addr.bytes,
@@ -7650,11 +7647,15 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx,
 	if (params->is_ml_adapter) {
 		hdd_adapter_set_ml_adapter(adapter);
 		ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab);
-		if (eht_capab)
+		if (eht_capab) {
 			qdf_mem_copy(adapter->mld_addr.bytes,
 				     adapter->mac_addr.bytes,
 				     QDF_MAC_ADDR_SIZE);
+			if (params->is_single_link)
+				hdd_adapter_set_sl_ml_adapter(adapter);
+		}
 	}
+
 	status = hdd_adapter_feature_update_work_init(adapter);
 	if (QDF_IS_STATUS_ERROR(status))
 		goto err_cleanup_adapter;
@@ -9170,6 +9171,15 @@ struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
 							  dbgid);
 			return adapter;
 		}
+
+		if (hdd_adapter_is_sl_ml_adapter(adapter) &&
+		    !qdf_mem_cmp(adapter->mld_addr.bytes,
+				 mac_addr, sizeof(tSirMacAddr))) {
+			hdd_adapter_dev_put_debug(adapter, dbgid);
+			if (next_adapter)
+				hdd_adapter_dev_put_debug(next_adapter, dbgid);
+			return adapter;
+		}
 		hdd_adapter_dev_put_debug(adapter, dbgid);
 	}
 

+ 11 - 0
core/hdd/src/wlan_hdd_mlo.c

@@ -209,6 +209,12 @@ hdd_adapter_set_ml_adapter(struct hdd_adapter *adapter)
 	adapter->mlo_adapter_info.is_ml_adapter = true;
 }
 
+void
+hdd_adapter_set_sl_ml_adapter(struct hdd_adapter *adapter)
+{
+	adapter->mlo_adapter_info.is_single_link_ml = true;
+}
+
 struct hdd_adapter *hdd_get_ml_adater(struct hdd_context *hdd_ctx)
 {
 	struct hdd_adapter *adapter, *next_adapter = NULL;
@@ -241,6 +247,11 @@ int hdd_update_vdev_mac_address(struct hdd_context *hdd_ctx,
 
 	ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab);
 	if (hdd_adapter_is_ml_adapter(adapter) && eht_capab) {
+		if (hdd_adapter_is_sl_ml_adapter(adapter)) {
+			ret = hdd_dynamic_mac_address_set(hdd_ctx, adapter,
+							  mac_addr);
+			return ret;
+		}
 		mlo_adapter_info = &adapter->mlo_adapter_info;
 
 		for (i = 0; i < WLAN_MAX_MLD; i++) {

+ 26 - 0
core/hdd/src/wlan_hdd_p2p.c

@@ -698,6 +698,26 @@ int hdd_set_p2p_ps(struct net_device *dev, void *msgData)
 	return wlan_hdd_set_power_save(adapter, &noa);
 }
 
+#ifdef WLAN_FEATURE_11BE_MLO
+static inline void
+wlan_hdd_set_ml_capab_add_iface(struct hdd_adapter_create_param *create_params,
+				enum QDF_OPMODE mode)
+{
+	if (mode != QDF_SAP_MODE)
+		return;
+
+	create_params->is_single_link = true;
+	create_params->is_ml_adapter = true;
+}
+#else
+static inline void
+wlan_hdd_set_ml_capab_add_iface(struct hdd_adapter_create_param *create_params,
+				enum QDF_OPMODE mode)
+{
+}
+
+#endif
+
 /**
  * __wlan_hdd_add_virtual_intf() - Add virtual interface
  * @wiphy: wiphy pointer
@@ -724,6 +744,7 @@ struct wireless_dev *__wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
 	QDF_STATUS status;
 	struct wlan_objmgr_vdev *vdev;
 	int ret;
+	bool eht_capab;
 	struct hdd_adapter_create_param create_params = {0};
 
 	hdd_enter();
@@ -769,6 +790,11 @@ struct wireless_dev *__wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
 	}
 
 	create_params.is_add_virtual_iface = 1;
+
+	ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab);
+	if (eht_capab)
+		wlan_hdd_set_ml_capab_add_iface(&create_params, mode);
+
 	adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
 	if (adapter && !wlan_hdd_validate_vdev_id(adapter->vdev_id)) {
 		vdev = hdd_objmgr_get_vdev_by_user(adapter, WLAN_OSIF_P2P_ID);

+ 16 - 8
core/sme/src/common/sme_api.c

@@ -16217,12 +16217,14 @@ QDF_STATUS sme_send_set_mac_addr(struct qdf_mac_addr mac_addr,
 			return qdf_ret_status;
 	}
 
-	if (vdev_opmode == QDF_STA_MODE &&
-	    sme_is_11be_capable() && update_mld_addr) {
+	if (sme_is_11be_capable() && update_mld_addr) {
 		/* Set new MAC addr as MLD address incase of MLO */
 		mld_addr = mac_addr;
-		qdf_mem_copy(&vdev_mac_addr, wlan_vdev_mlme_get_linkaddr(vdev),
-			     sizeof(struct qdf_mac_addr));
+		if (vdev_opmode == QDF_STA_MODE) {
+			qdf_mem_copy(&vdev_mac_addr,
+				     wlan_vdev_mlme_get_linkaddr(vdev),
+				     sizeof(struct qdf_mac_addr));
+		}
 	}
 
 	qdf_ret_status = wlan_vdev_mlme_send_set_mac_addr(vdev_mac_addr,
@@ -16275,7 +16277,7 @@ QDF_STATUS sme_update_vdev_mac_addr(struct wlan_objmgr_psoc *psoc,
 	if (req_status)
 		goto p2p_self_peer_create;
 
-	if ((vdev_opmode == QDF_STA_MODE) && update_sta_self_peer) {
+	if (vdev_opmode == QDF_STA_MODE && update_sta_self_peer) {
 		if (sme_is_11be_capable() && update_mld_addr)
 			old_mac_addr_bytes = wlan_vdev_mlme_get_mldaddr(vdev);
 		else
@@ -16302,9 +16304,8 @@ QDF_STATUS sme_update_vdev_mac_addr(struct wlan_objmgr_psoc *psoc,
 	}
 
 	/* Update VDEV MAC address */
-	if (vdev_opmode == QDF_STA_MODE &&
-	    sme_is_11be_capable() && update_mld_addr) {
-		if (update_sta_self_peer) {
+	if (sme_is_11be_capable() && update_mld_addr) {
+		if (update_sta_self_peer || vdev_opmode == QDF_SAP_MODE) {
 			qdf_ret_status = wlan_mlo_mgr_update_mld_addr(
 					    (struct qdf_mac_addr *)
 					       wlan_vdev_mlme_get_mldaddr(vdev),
@@ -16313,6 +16314,13 @@ QDF_STATUS sme_update_vdev_mac_addr(struct wlan_objmgr_psoc *psoc,
 				return qdf_ret_status;
 		}
 		wlan_vdev_mlme_set_mldaddr(vdev, mac_addr.bytes);
+		/* Currently the design is to use same MAC for
+		 * MLD and Link for SAP so update link and MAC addr.
+		 */
+		if (vdev_opmode == QDF_SAP_MODE) {
+			wlan_vdev_mlme_set_macaddr(vdev, mac_addr.bytes);
+			wlan_vdev_mlme_set_linkaddr(vdev, mac_addr.bytes);
+		}
 	} else {
 		wlan_vdev_mlme_set_macaddr(vdev, mac_addr.bytes);
 		wlan_vdev_mlme_set_linkaddr(vdev, mac_addr.bytes);