Просмотр исходного кода

qcacld-3.0: Add async event for Spatial Reuse

Add async event for Spatial Reuse and also send Spatial Reuse
enable / disable event to upper layer due to same MAC concurrency.

Change-Id: Idcb5b99e39f1810e63ae7ac1e8d2eab6028a163f
CRs-Fixed: 3307801
Rachit Kankane 2 лет назад
Родитель
Сommit
14e356b81e

+ 66 - 0
components/spatial_reuse/dispatcher/inc/spatial_reuse_api.h

@@ -25,6 +25,43 @@
 #include <qdf_trace.h>
 #include <wlan_objmgr_vdev_obj.h>
 
+/**
+ * enum sr_osif_operation - Spatial Reuse operation
+ * @SR_OPERATION_SUSPEND: Spatial Reuse suspend indication
+ * @SR_OPERATION_RESUME: Spatial Reuse resume indication
+ * @SR_OPERATION_UPDATE_PARAMS: Spatial Reuse parameters are updated
+ */
+enum sr_osif_operation {
+	SR_OPERATION_SUSPEND = 0,
+	SR_OPERATION_RESUME = 1,
+	SR_OPERATION_UPDATE_PARAMS = 2,
+};
+
+/**
+ * enum sr_osif_reason_code - Spatial Reuse reason codes
+ * @SR_REASON_CODE_ROAMING: Spatial Reuse reason code is Roaming will be
+ *			     set when SR is suspended / resumed due to roaming
+ * @SR_REASON_CODE_CONCURRENCY: Spatial Reuse reason code is concurrency
+ *				 will be set when SR is suspended / resumed
+ *				 due to concurrency
+ */
+enum sr_osif_reason_code {
+	SR_REASON_CODE_ROAMING = 0,
+	SR_REASON_CODE_CONCURRENCY = 1,
+};
+
+/**
+ * sr_osif_event_cb() - CB to deliver SR events
+ * @vdev: objmgr manager vdev
+ * @sr_osif_oper: SR Operation like suspend / resume
+ * @sr_osif_rc: Event reason code
+ *
+ * Return: void
+ */
+typedef void (*sr_osif_event_cb)(struct wlan_objmgr_vdev *vdev,
+				 enum sr_osif_operation sr_osif_oper,
+				 enum sr_osif_reason_code sr_osif_rc);
+
 #ifdef WLAN_FEATURE_SR
 /**
  * wlan_spatial_reuse_config_set() - Set spatial reuse config
@@ -47,6 +84,28 @@ QDF_STATUS wlan_spatial_reuse_config_set(struct wlan_objmgr_vdev *vdev,
  * Return: QDF_STATUS
  */
 QDF_STATUS wlan_spatial_reuse_pdev_init(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * wlan_sr_register_callback() - registers SR osif events
+ * @psoc: pointer to psoc
+ * @cb: Callback to be registered
+ *
+ * Return: void
+ */
+void wlan_sr_register_callback(struct wlan_objmgr_psoc *psoc,
+			       sr_osif_event_cb cb);
+
+/**
+ * wlan_spatial_reuse_osif_event() - Send SR asynchronous events
+ * @vdev: objmgr manager vdev
+ * @sr_osif_oper: SR Operation like suspend / resume
+ * @sr_osif_rc: Event reason code
+ *
+ * Return: void
+ */
+void wlan_spatial_reuse_osif_event(struct wlan_objmgr_vdev *vdev,
+				   enum sr_osif_operation sr_osif_oper,
+				   enum sr_osif_reason_code sr_osif_rc);
 #else
 static inline
 QDF_STATUS wlan_spatial_reuse_config_set(struct wlan_objmgr_vdev *vdev,
@@ -61,6 +120,13 @@ QDF_STATUS wlan_spatial_reuse_pdev_init(struct wlan_objmgr_pdev *pdev)
 {
 	return QDF_STATUS_SUCCESS;
 }
+
+static inline
+void wlan_spatial_reuse_osif_event(struct wlan_objmgr_vdev *vdev,
+				   enum sr_osif_operation sr_osif_oper,
+				   enum sr_osif_reason_code sr_osif_rc)
+{
+}
 #endif
 
 /**

+ 19 - 1
components/spatial_reuse/dispatcher/inc/spatial_reuse_ucfg_api.h

@@ -20,9 +20,21 @@
 #ifndef _SPATIAL_REUSE_UCFG_API_H_
 #define _SPATIAL_REUSE_UCFG_API_H_
 
-#ifdef WLAN_FEATURE_SR
 #include <qdf_trace.h>
 #include <wlan_objmgr_vdev_obj.h>
+#include <spatial_reuse_api.h>
+
+#ifdef WLAN_FEATURE_SR
+/**
+ * ucfg_spatial_reuse_register_cb() - Registers CB for SR
+ * @psoc: pointer to psoc
+ * @cb: SR osif event callback
+ *
+ * Return: void
+ */
+void ucfg_spatial_reuse_register_cb(struct wlan_objmgr_psoc *psoc,
+				    sr_osif_event_cb cb);
+
 /**
  * ucfg_spatial_reuse_get_sr_config() - Spatial reuse config get
  *
@@ -120,5 +132,11 @@ QDF_STATUS ucfg_spatial_reuse_setup_req(struct wlan_objmgr_vdev *vdev,
 					struct wlan_objmgr_pdev *pdev,
 					bool is_sr_enable,
 					int32_t pd_threshold);
+#else
+static inline
+void ucfg_spatial_reuse_register_cb(struct wlan_objmgr_psoc *psoc,
+				    sr_osif_event_cb cb)
+{
+}
 #endif
 #endif

+ 20 - 0
components/spatial_reuse/dispatcher/src/spatial_reuse_api.c

@@ -20,6 +20,10 @@
 #include <spatial_reuse_api.h>
 #include <target_if_spatial_reuse.h>
 
+struct sr_cb {
+	sr_osif_event_cb send_osif_event;
+} sr_cb;
+
 QDF_STATUS wlan_spatial_reuse_config_set(struct wlan_objmgr_vdev *vdev,
 					 uint8_t sr_ctrl,
 					 uint8_t non_srg_max_pd_offset)
@@ -114,3 +118,19 @@ QDF_STATUS wlan_spatial_reuse_pdev_init(struct wlan_objmgr_pdev *pdev)
 	return wmi_unified_pdev_param_send(wmi_handle, &pparam,
 					   WILDCARD_PDEV_ID);
 }
+
+void wlan_sr_register_callback(struct wlan_objmgr_psoc *psoc,
+			       sr_osif_event_cb cb)
+{
+	if (!psoc)
+		return;
+	sr_cb.send_osif_event = cb;
+}
+
+void wlan_spatial_reuse_osif_event(struct wlan_objmgr_vdev *vdev,
+				   enum sr_osif_operation sr_osif_oper,
+				   enum sr_osif_reason_code sr_osif_rc)
+{
+	if (sr_cb.send_osif_event)
+		sr_cb.send_osif_event(vdev, sr_osif_oper, sr_osif_rc);
+}

+ 6 - 0
components/spatial_reuse/dispatcher/src/spatial_reuse_ucfg_api.c

@@ -21,6 +21,12 @@
 #include <spatial_reuse_ucfg_api.h>
 #include <spatial_reuse_api.h>
 
+void ucfg_spatial_reuse_register_cb(struct wlan_objmgr_psoc *psoc,
+				    sr_osif_event_cb cb)
+{
+	wlan_sr_register_callback(psoc, cb);
+}
+
 void ucfg_spatial_reuse_get_sr_config(struct wlan_objmgr_vdev *vdev,
 				      uint8_t *sr_ctrl,
 				      uint8_t *non_srg_max_pd_offset,

+ 17 - 0
core/hdd/inc/wlan_hdd_he.h

@@ -134,6 +134,15 @@ int wlan_hdd_cfg80211_get_he_cap(struct wiphy *wiphy,
 int wlan_hdd_cfg80211_sr_operations(struct wiphy *wiphy,
 				    struct wireless_dev *wdev,
 				    const void *data, int data_len);
+
+/**
+ * hdd_sr_register_callbacks() - register hdd callback for sr
+ * @hdd_ctx: hdd context
+ *
+ * Return: void
+ */
+void hdd_sr_register_callbacks(struct hdd_context *hdd_ctx);
+
 #else
 static inline
 int wlan_hdd_cfg80211_sr_operations(struct wiphy *wiphy,
@@ -142,6 +151,10 @@ int wlan_hdd_cfg80211_sr_operations(struct wiphy *wiphy,
 {
 	return 0;
 }
+
+static inline void hdd_sr_register_callbacks(struct hdd_context *hdd_ctx)
+{
+}
 #endif
 
 #define FEATURE_11AX_VENDOR_COMMANDS                                    \
@@ -180,6 +193,10 @@ static inline int hdd_update_he_cap_in_cfg(struct hdd_context *hdd_ctx)
 	return 0;
 }
 
+static inline void hdd_sr_register_callbacks(struct hdd_context *hdd_ctx)
+{
+}
+
 /* dummy definition */
 #define FEATURE_11AX_VENDOR_COMMANDS
 

+ 6 - 0
core/hdd/src/wlan_hdd_cfg80211.c

@@ -1839,6 +1839,12 @@ static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
 		.subcmd = QCA_NL80211_VENDOR_SUBCMD_DRIVER_READY,
 	},
 	FEATURE_WIFI_POS_11AZ_AUTH_EVENTS
+#ifdef WLAN_FEATURE_SR
+	[QCA_NL80211_VENDOR_SUBCMD_SR_INDEX] = {
+		.vendor_id = QCA_NL80211_VENDOR_ID,
+		.subcmd = QCA_NL80211_VENDOR_SUBCMD_SR,
+	},
+#endif
 };
 
 /**

+ 158 - 0
core/hdd/src/wlan_hdd_he.c

@@ -247,6 +247,164 @@ int wlan_hdd_cfg80211_get_he_cap(struct wiphy *wiphy,
 }
 
 #ifdef WLAN_FEATURE_SR
+static QDF_STATUS
+hdd_sr_event_convert_reason_code(enum sr_osif_reason_code sr_osif_rc,
+				 enum qca_wlan_sr_reason_code *sr_nl_rc)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	switch (sr_osif_rc) {
+	case SR_REASON_CODE_ROAMING:
+		*sr_nl_rc = QCA_WLAN_SR_REASON_CODE_ROAMING;
+		break;
+	case SR_REASON_CODE_CONCURRENCY:
+		*sr_nl_rc = QCA_WLAN_SR_REASON_CODE_CONCURRENCY;
+		break;
+	default:
+		status = QDF_STATUS_E_INVAL;
+	}
+
+	return status;
+}
+
+static QDF_STATUS
+hdd_sr_event_convert_operation(enum sr_osif_operation sr_osif_oper,
+			       enum qca_wlan_sr_operation *sr_nl_oper)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	switch (sr_osif_oper) {
+	case SR_OPERATION_SUSPEND:
+		*sr_nl_oper = QCA_WLAN_SR_OPERATION_SR_SUSPEND;
+		break;
+	case SR_OPERATION_RESUME:
+		*sr_nl_oper = QCA_WLAN_SR_OPERATION_SR_RESUME;
+		break;
+	case SR_OPERATION_UPDATE_PARAMS:
+		*sr_nl_oper = QCA_WLAN_SR_OPERATION_UPDATE_PARAMS;
+		break;
+	default:
+		status = QDF_STATUS_E_INVAL;
+	}
+
+	return status;
+}
+
+static QDF_STATUS hdd_sr_pack_conc_event(struct sk_buff *skb,
+					 enum qca_wlan_sr_operation sr_nl_oper,
+					 enum qca_wlan_sr_reason_code sr_nl_rc)
+{
+	struct nlattr *attr;
+	QDF_STATUS status = QDF_STATUS_E_FAULT;
+
+	if (sr_nl_rc != QCA_WLAN_SR_REASON_CODE_CONCURRENCY ||
+	    (sr_nl_oper != QCA_WLAN_SR_OPERATION_SR_SUSPEND &&
+	     sr_nl_oper != QCA_WLAN_SR_OPERATION_SR_RESUME)) {
+		hdd_err("SR concurrency operation is invalid");
+		status = QDF_STATUS_E_INVAL;
+		goto sr_events_end;
+	}
+
+	if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_SR_OPERATION, sr_nl_oper)) {
+		hdd_err("failed to put attr SR Operation");
+		goto sr_events_end;
+	}
+
+	attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_SR_PARAMS);
+	if (!attr) {
+		hdd_err("nesting failed");
+		goto sr_events_end;
+	}
+
+	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_SR_PARAMS_REASON_CODE,
+			sr_nl_rc)) {
+		hdd_err("failed to put attr SR Reascon Code");
+		goto sr_events_end;
+	}
+	status = QDF_STATUS_SUCCESS;
+	nla_nest_end(skb, attr);
+
+sr_events_end:
+	return status;
+}
+
+static void hdd_sr_osif_events(struct wlan_objmgr_vdev *vdev,
+			       enum sr_osif_operation sr_osif_oper,
+			       enum sr_osif_reason_code sr_osif_rc)
+{
+	struct hdd_adapter *adapter;
+	struct wireless_dev *wdev;
+	struct wiphy *wiphy;
+	struct sk_buff *skb;
+	uint32_t idx = QCA_NL80211_VENDOR_SUBCMD_SR_INDEX;
+	uint32_t len = NLMSG_HDRLEN;
+	QDF_STATUS status;
+	enum qca_wlan_sr_operation sr_nl_oper;
+	enum qca_wlan_sr_reason_code sr_nl_rc;
+
+	if (!vdev) {
+		hdd_err("Null VDEV");
+		return;
+	}
+
+	adapter = wlan_hdd_get_adapter_from_objmgr(vdev);
+	if (!adapter) {
+		hdd_err("Null adapter");
+		return;
+	}
+
+	status = hdd_sr_event_convert_operation(sr_osif_oper, &sr_nl_oper);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Invalid SR Operation: %d", sr_osif_oper);
+		return;
+	}
+	status = hdd_sr_event_convert_reason_code(sr_osif_rc, &sr_nl_rc);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Invalid SR Reason Code: %d", sr_osif_rc);
+		return;
+	}
+
+	hdd_debug("SR Operation: %u SR Reason Code: %u",
+		  sr_nl_oper, sr_nl_rc);
+	switch (sr_nl_oper) {
+	case QCA_WLAN_SR_OPERATION_SR_SUSPEND:
+	case QCA_WLAN_SR_OPERATION_SR_RESUME:
+		if (sr_nl_rc == QCA_WLAN_SR_REASON_CODE_CONCURRENCY) {
+			wiphy = adapter->hdd_ctx->wiphy;
+			wdev = &adapter->wdev;
+			len += nla_total_size(sizeof(uint8_t)) +
+			       nla_total_size(sizeof(uint32_t));
+			skb = wlan_cfg80211_vendor_event_alloc(wiphy, wdev,
+							       len, idx,
+							       GFP_KERNEL);
+			if (!skb) {
+				hdd_err("cfg80211_vendor_event_alloc failed");
+				return;
+			}
+			status = hdd_sr_pack_conc_event(skb, sr_nl_oper,
+							sr_nl_rc);
+			if (QDF_IS_STATUS_ERROR(status)) {
+				kfree_skb(skb);
+				return;
+			}
+
+			wlan_cfg80211_vendor_event(skb, GFP_KERNEL);
+			hdd_debug("SR cfg80211 event is sent");
+		} else {
+			hdd_debug("SR Reason code not supported");
+		}
+		break;
+	default:
+		hdd_debug("SR Operation not supported");
+		break;
+	}
+}
+
+void hdd_sr_register_callbacks(struct hdd_context *hdd_ctx)
+{
+	ucfg_spatial_reuse_register_cb(hdd_ctx->psoc, hdd_sr_osif_events);
+}
+
 static int hdd_get_srp_stats_len(void)
 {
 	struct cdp_pdev_obss_pd_stats_tlv stats;

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

@@ -4289,6 +4289,8 @@ int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit)
 
 		hdd_son_register_callbacks(hdd_ctx);
 
+		hdd_sr_register_callbacks(hdd_ctx);
+
 		wlan_hdd_register_btc_chain_mode_handler(hdd_ctx->psoc);
 
 		status = cds_pre_enable();

+ 1 - 4
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -9527,8 +9527,6 @@ void lim_process_set_he_bss_color(struct mac_context *mac_ctx, uint32_t *msg_buf
 	struct sir_set_he_bss_color *bss_color;
 	struct pe_session *session_entry = NULL;
 	tUpdateBeaconParams beacon_params;
-	/* PD threshold -128 to disable SR */
-	uint8_t non_srg_pd_threshold_disabled = 0x80;
 
 	if (!msg_buf) {
 		pe_err("Buffer is Pointing to NULL");
@@ -9566,8 +9564,7 @@ void lim_process_set_he_bss_color(struct mac_context *mac_ctx, uint32_t *msg_buf
 
 	if (wlan_vdev_mlme_get_he_spr_enabled(session_entry->vdev))
 		/* Disable spatial reuse during BSS color change */
-		wlan_spatial_reuse_config_set(session_entry->vdev, 0,
-					      non_srg_pd_threshold_disabled);
+		wlan_spatial_reuse_config_set(session_entry->vdev, 0, 0);
 
 	if (sch_set_fixed_beacon_fields(mac_ctx, session_entry) !=
 			QDF_STATUS_SUCCESS) {

+ 7 - 1
core/mac/src/pe/lim/lim_send_sme_rsp_messages.c

@@ -2344,11 +2344,17 @@ lim_update_spatial_reuse(struct pe_session *session)
 							       false);
 			wlan_spatial_reuse_config_set(session->vdev, sr_ctrl,
 						      non_srg_pd_max_offset);
+			wlan_spatial_reuse_osif_event(session->vdev,
+						      SR_OPERATION_RESUME,
+						      SR_REASON_CODE_CONCURRENCY);
 		} else {
 			wlan_vdev_mlme_set_sr_disable_due_conc(session->vdev,
 							       true);
 			wlan_spatial_reuse_config_set(session->vdev, sr_ctrl,
-						      0x80);
+						 NON_SR_PD_THRESHOLD_DISABLED);
+			wlan_spatial_reuse_osif_event(session->vdev,
+						      SR_OPERATION_SUSPEND,
+						      SR_REASON_CODE_CONCURRENCY);
 		}
 	}
 }

+ 7 - 0
core/wma/src/wma_features.c

@@ -69,6 +69,7 @@
 #include "target_if_nan.h"
 #endif
 #include "wlan_scan_api.h"
+#include "spatial_reuse_api.h"
 #include "wlan_cm_api.h"
 #include <wlan_crypto_global_api.h>
 #include "cdp_txrx_host_stats.h"
@@ -683,6 +684,9 @@ static void wma_sr_handle_conc(tp_wma_handle wma,
 			return;
 
 		wma_sr_send_pd_threshold(wma, conc_vdev_id, val);
+		wlan_spatial_reuse_osif_event(conc_vdev,
+					      SR_OPERATION_SUSPEND,
+					      SR_REASON_CODE_CONCURRENCY);
 	} else if (wlan_vdev_mlme_is_sr_disable_due_conc(conc_vdev)) {
 		wlan_vdev_mlme_set_sr_disable_due_conc(conc_vdev, false);
 		if (!wlan_vdev_mlme_get_he_spr_enabled(conc_vdev))
@@ -694,6 +698,9 @@ static void wma_sr_handle_conc(tp_wma_handle wma,
 		    (sr_ctrl & SRG_INFO_PRESENT)) {
 			wlan_mlme_update_sr_data(conc_vdev, &val, 0, true);
 			wma_sr_send_pd_threshold(wma, conc_vdev_id, val);
+			wlan_spatial_reuse_osif_event(conc_vdev,
+						      SR_OPERATION_RESUME,
+						      SR_REASON_CODE_CONCURRENCY);
 		} else {
 			wma_debug("SR Disabled in SR Control");
 		}