Selaa lähdekoodia

qcacld-3.0: Change TWT nudge to asynchronous command

Change TWT nudge command to be asynchronous. Handle wake
time tsf field in the nudge command response.

Change-Id: I22c75a42bf60f52f52d7d7fe19f408ebb55f360a
CRs-Fixed: 2847173
Rajasekaran Kalidoss 4 vuotta sitten
vanhempi
sitoutus
8ad0440a66

+ 18 - 6
components/mlme/core/src/wlan_mlme_twt_api.c

@@ -202,10 +202,14 @@ bool mlme_is_twt_setup_done(struct wlan_objmgr_psoc *psoc,
 	}
 
 	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
-		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id) {
+		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id ||
+		    dialog_id == WLAN_ALL_SESSIONS_DIALOG_ID) {
 			is_setup_done =
 				peer_priv->twt_ctx.session_info[i].setup_done;
-			break;
+
+			if (dialog_id != WLAN_ALL_SESSIONS_DIALOG_ID ||
+			    is_setup_done)
+				break;
 		}
 	}
 
@@ -295,7 +299,8 @@ void mlme_set_twt_session_state(struct wlan_objmgr_psoc *psoc,
 
 	mlme_debug("set_state:%d for dialog_id:%d", state, dialog_id);
 	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
-		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id) {
+		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id ||
+		    dialog_id == WLAN_ALL_SESSIONS_DIALOG_ID) {
 			peer_priv->twt_ctx.session_info[i].state = state;
 			break;
 		}
@@ -508,14 +513,21 @@ bool mlme_twt_is_command_in_progress(struct wlan_objmgr_psoc *psoc,
 
 	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
 		active_cmd = peer_priv->twt_ctx.session_info[i].active_cmd;
-		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id) {
+		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id ||
+		    dialog_id == WLAN_ALL_SESSIONS_DIALOG_ID) {
 			if (cmd == WLAN_TWT_ANY) {
 				is_command_in_progress =
 					(active_cmd != WLAN_TWT_NONE);
-				break;
+
+				if (dialog_id != WLAN_ALL_SESSIONS_DIALOG_ID ||
+				    is_command_in_progress)
+					break;
 			} else {
 				is_command_in_progress = (active_cmd == cmd);
-				break;
+
+				if (dialog_id != WLAN_ALL_SESSIONS_DIALOG_ID ||
+				    is_command_in_progress)
+					break;
 			}
 		}
 	}

+ 101 - 123
core/hdd/src/wlan_hdd_twt.c

@@ -38,7 +38,6 @@
 #include <wlan_mlme_twt_ucfg_api.h>
 
 #define TWT_DISABLE_COMPLETE_TIMEOUT 4000
-#define TWT_NUDGE_COMPLETE_TIMEOUT 4000
 
 #define TWT_FLOW_TYPE_ANNOUNCED 0
 #define TWT_FLOW_TYPE_UNANNOUNCED 1
@@ -50,18 +49,6 @@
 #define TWT_MAX_NEXT_TWT_SIZE                   3
 #define TWT_ALL_SESSIONS_DIALOG_ID              255
 
-/**
- * struct twt_nudge_dialog_comp_ev_priv - private struct for twt nudge dialog
- * @nudge_dialog_comp_ev_buf: buffer from TWT nudge dialog complete_event
- *
- * This TWT nudge dialog private structure is registered with os_if to
- * retrieve the TWT nudge dialog response event buffer.
- */
-struct twt_nudge_dialog_comp_ev_priv {
-	struct wmi_twt_nudge_dialog_complete_event_param
-						nudge_dialog_comp_ev_buf;
-};
-
 static const struct nla_policy
 qca_wlan_vendor_twt_add_dialog_policy[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1] = {
 	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP] = {.type = NLA_U8 },
@@ -1619,39 +1606,119 @@ static int hdd_twt_terminate_session(struct hdd_adapter *adapter,
 }
 
 /**
+ * hdd_twt_nudge_pack_resp_nlmsg() - pack the skb with
+ * firmware response for twt nudge command
+ * @reply_skb: skb to store the response
+ * @params: Pointer to nudge dialog complete event buffer
+ *
+ * Return: QDF_STATUS_SUCCESS on Success, QDF_STATUS_E_FAILURE
+ * on failure
+ */
+static QDF_STATUS
+hdd_twt_nudge_pack_resp_nlmsg(struct sk_buff *reply_skb,
+		      struct wmi_twt_nudge_dialog_complete_event_param *params)
+{
+	struct nlattr *config_attr;
+	int vendor_status;
+	uint64_t tsf_val;
+
+	if (nla_put_u8(reply_skb, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
+		       QCA_WLAN_TWT_NUDGE)) {
+		hdd_err("Failed to put TWT operation");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	config_attr = nla_nest_start(reply_skb,
+				     QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS);
+	if (!config_attr) {
+		hdd_err("nla_nest_start error");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (nla_put_u8(reply_skb, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID,
+		       params->dialog_id)) {
+		hdd_debug("Failed to put dialog_id");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	tsf_val = params->next_twt_tsf_us_hi;
+	tsf_val = (tsf_val << 32) | params->next_twt_tsf_us_lo;
+	if (hdd_wlan_nla_put_u64(reply_skb,
+				 QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME_TSF,
+				 tsf_val)) {
+		hdd_err("get_params failed to put TSF Value");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	vendor_status =
+		     wmi_twt_nudge_status_to_vendor_twt_status(params->status);
+	if (nla_put_u8(reply_skb, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS,
+		       vendor_status)) {
+		hdd_err("Failed to put QCA_WLAN_TWT_NUDGE status");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	nla_nest_end(reply_skb, config_attr);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
  * hdd_twt_nudge_dialog_comp_cb() - callback function
  * to get twt nudge command complete event
- * @context: private context
+ * @psoc: Pointer to global psoc
  * @params: Pointer to nudge dialog complete event buffer
  *
  * Return: None
  */
-static void
-hdd_twt_nudge_dialog_comp_cb(void *context,
-		       struct wmi_twt_nudge_dialog_complete_event_param *params)
+static void hdd_twt_nudge_dialog_comp_cb(
+		struct wlan_objmgr_psoc *psoc,
+		struct wmi_twt_nudge_dialog_complete_event_param *params)
 {
-	struct osif_request *request;
-	struct twt_nudge_dialog_comp_ev_priv *priv;
 
-	hdd_enter();
+	struct hdd_adapter *adapter =
+		wlan_hdd_get_adapter_from_vdev(psoc, params->vdev_id);
+	struct wireless_dev *wdev;
+	struct hdd_context *hdd_ctx;
+	struct sk_buff *twt_vendor_event;
+	size_t data_len;
+	QDF_STATUS status;
 
-	request = osif_request_get(context);
-	if (!request) {
-		hdd_err("Obsolete request");
+	hdd_enter();
+	if (hdd_validate_adapter(adapter))
 		return;
-	}
 
-	priv = osif_request_priv(request);
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 
-	priv->nudge_dialog_comp_ev_buf = *params;
-	osif_request_complete(request);
-	osif_request_put(request);
+	wdev = adapter->dev->ieee80211_ptr;
 
-	hdd_debug("TWT: nudge dialog_id:%d, status:%d vdev_id %d peer mac_addr "
+	hdd_debug("Nudge dialog_id:%d, status:%d vdev_id %d peer mac_addr "
 		  QDF_MAC_ADDR_FMT, params->dialog_id,
 		  params->status, params->vdev_id,
 		  QDF_MAC_ADDR_REF(params->peer_macaddr));
 
+	data_len = hdd_get_twt_event_len() + nla_total_size(sizeof(u8)) +
+		   nla_total_size(sizeof(u64));
+	data_len += NLA_HDRLEN;
+
+	twt_vendor_event = wlan_cfg80211_vendor_event_alloc(
+				hdd_ctx->wiphy, wdev,
+				data_len,
+				QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT_INDEX,
+				GFP_KERNEL);
+	if (!twt_vendor_event) {
+		hdd_err("Nudge dialog alloc skb failed");
+		return;
+	}
+
+	status = hdd_twt_nudge_pack_resp_nlmsg(twt_vendor_event, params);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to pack nl nudge dialog response %d", status);
+		wlan_cfg80211_vendor_free_skb(twt_vendor_event);
+	}
+
+	wlan_cfg80211_vendor_event(twt_vendor_event, GFP_KERNEL);
+
 	hdd_exit();
 }
 
@@ -1702,38 +1769,6 @@ hdd_twt_pause_pack_resp_nlmsg(struct sk_buff *reply_skb,
 	return QDF_STATUS_SUCCESS;
 }
 
-/**
- * hdd_twt_nudge_pack_resp_nlmsg() - pack the skb with
- * firmware response for twt nudge command
- * @reply_skb: skb to store the response
- * @params: Pointer to nudge dialog complete event buffer
- *
- * Return: QDF_STATUS_SUCCESS on Success, QDF_STATUS_E_FAILURE
- * on failure
- */
-static QDF_STATUS
-hdd_twt_nudge_pack_resp_nlmsg(struct sk_buff *reply_skb,
-		      struct wmi_twt_nudge_dialog_complete_event_param *params)
-{
-	int vendor_status;
-
-	if (nla_put_u8(reply_skb, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID,
-		       params->dialog_id)) {
-		hdd_debug("TWT: Failed to put dialog_id");
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	vendor_status =
-		     wmi_twt_nudge_status_to_vendor_twt_status(params->status);
-	if (nla_put_u8(reply_skb, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS,
-		       vendor_status)) {
-		hdd_err("TWT: Failed to put QCA_WLAN_TWT_NUDGE status");
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	return QDF_STATUS_SUCCESS;
-}
-
 /*
  * hdd_twt_pause_dialog_comp_cb() - callback function
  * to get twt pause command complete event
@@ -1908,72 +1943,13 @@ static
 int hdd_send_twt_nudge_dialog_cmd(struct hdd_context *hdd_ctx,
 			struct wmi_twt_nudge_dialog_cmd_param *twt_params)
 {
-	struct wmi_twt_nudge_dialog_complete_event_param *comp_ev_params;
-	struct twt_nudge_dialog_comp_ev_priv *priv;
-	static const struct osif_request_params osif_req_params = {
-		.priv_size = sizeof(*priv),
-		.timeout_ms = TWT_NUDGE_COMPLETE_TIMEOUT,
-		.dealloc = NULL,
-	};
-	struct osif_request *request;
-	struct sk_buff *reply_skb = NULL;
 	QDF_STATUS status;
-	void *cookie;
-	int skb_len;
-	int ret;
-
-	request = osif_request_alloc(&osif_req_params);
-	if (!request) {
-		hdd_err("twt osif request allocation failure");
-		ret = -ENOMEM;
-		goto err;
-	}
-
-	cookie = osif_request_cookie(request);
 
-	status = sme_nudge_dialog_cmd(hdd_ctx->mac_handle,
-				      hdd_twt_nudge_dialog_comp_cb,
-				      twt_params, cookie);
-	if (QDF_IS_STATUS_ERROR(status)) {
+	status = sme_nudge_dialog_cmd(hdd_ctx->mac_handle, twt_params);
+	if (QDF_IS_STATUS_ERROR(status))
 		hdd_err("Failed to send nudge dialog command");
-		ret = qdf_status_to_os_return(status);
-		goto err;
-	}
 
-	ret = osif_request_wait_for_response(request);
-	if (ret) {
-		hdd_err("twt: nudge dialog req timedout");
-		ret = -ETIMEDOUT;
-		goto err;
-	}
-
-	priv = osif_request_priv(request);
-	comp_ev_params = &priv->nudge_dialog_comp_ev_buf;
-
-	skb_len = hdd_get_twt_event_len();
-	reply_skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
-							     skb_len);
-	if (!reply_skb) {
-		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
-		ret = -ENOMEM;
-		goto err;
-	}
-
-	status = hdd_twt_nudge_pack_resp_nlmsg(reply_skb, comp_ev_params);
-	if (QDF_IS_STATUS_ERROR(status)) {
-		hdd_err("Failed to pack nl nudge dialog response");
-		ret = qdf_status_to_os_return(status);
-		goto err;
-	}
-
-	ret = wlan_cfg80211_vendor_cmd_reply(reply_skb);
-
-err:
-	if (request)
-		osif_request_put(request);
-	if (ret && reply_skb)
-		kfree_skb(reply_skb);
-	return ret;
+	return qdf_status_to_os_return(status);
 }
 
 /**
@@ -2928,6 +2904,8 @@ void wlan_hdd_twt_init(struct hdd_context *hdd_ctx)
 	twt_cb.twt_pause_dialog_cb = hdd_twt_pause_dialog_comp_cb;
 	twt_cb.twt_resume_dialog_cb = hdd_twt_resume_dialog_comp_cb;
 	twt_cb.twt_notify_cb = hdd_twt_notify_cb;
+	twt_cb.twt_nudge_dialog_cb = hdd_twt_nudge_dialog_comp_cb;
+
 	status = sme_register_twt_callbacks(hdd_ctx->mac_handle, &twt_cb);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		hdd_err("Register twt enable complete failed");

+ 1 - 5
core/sme/inc/sme_api.h

@@ -3735,18 +3735,14 @@ sme_pause_dialog_cmd(mac_handle_t mac_handle,
  * sme_nudge_dialog_cmd() - Register callback and send TWT nudge dialog
  * command to firmware
  * @mac_handle: MAC handle
- * @twt_nudge_dialog_cb: Function callback to handle nudge_dialog event
  * @twt_params: TWT nudge dialog parameters
- * @context: os_if_request cookie
  *
  * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes
  * on failure
  */
 QDF_STATUS
 sme_nudge_dialog_cmd(mac_handle_t mac_handle,
-		     twt_nudge_dialog_cb nudge_dialog_cb,
-		     struct wmi_twt_nudge_dialog_cmd_param *twt_params,
-		     void *context);
+		     struct wmi_twt_nudge_dialog_cmd_param *twt_params);
 
 /**
  * sme_resume_dialog_cmd() - Register callback and send TWT resume dialog

+ 5 - 4
core/sme/inc/sme_internal.h

@@ -189,12 +189,11 @@ void (*twt_pause_dialog_cb)(struct wlan_objmgr_psoc *psoc,
 
 /**
  * typedef twt_nudge_dialog_cb - TWT nudge dialog callback signature.
- * @context: Opaque context that the client can use to associate the
- *           callback with the request.
+ * @psoc: Pointer to global psoc
  * @params: TWT nudge dialog complete event parameters.
  */
 typedef
-void (*twt_nudge_dialog_cb)(void *context,
+void (*twt_nudge_dialog_cb)(struct wlan_objmgr_psoc *psoc,
 		      struct wmi_twt_nudge_dialog_complete_event_param *params);
 
 /**
@@ -223,6 +222,7 @@ void (*twt_notify_cb)(struct wlan_objmgr_psoc *psoc,
  * @twt_pause_dialog_cb: TWT pause dialog completion callback
  * @twt_resume_dialog_cb: TWT resume dialog completion callback
  * @twt_notify_cb: TWT notify event callback
+ * @twt_nudge_dialog_cb: TWT nudge dialog completion callback
  */
 struct twt_callbacks {
 	void (*twt_enable_cb)(hdd_handle_t hdd_handle,
@@ -238,6 +238,8 @@ struct twt_callbacks {
 				     struct wmi_twt_resume_dialog_complete_event_param *params);
 	void (*twt_notify_cb)(struct wlan_objmgr_psoc *psoc,
 			      struct wmi_twt_notify_event_param *params);
+	void (*twt_nudge_dialog_cb)(struct wlan_objmgr_psoc *psoc,
+		    struct wmi_twt_nudge_dialog_complete_event_param *params);
 };
 #endif
 
@@ -454,7 +456,6 @@ struct sme_context {
 	twt_nudge_dialog_cb twt_nudge_dialog_cb;
 	twt_resume_dialog_cb twt_resume_dialog_cb;
 	twt_notify_cb twt_notify_cb;
-	void *twt_nudge_dialog_context;
 #endif
 #ifdef FEATURE_WLAN_APF
 	apf_get_offload_cb apf_get_offload_cb;

+ 4 - 17
core/sme/src/common/sme_api.c

@@ -2226,7 +2226,6 @@ sme_process_twt_nudge_dialog_event(struct mac_context *mac,
 			struct wmi_twt_nudge_dialog_complete_event_param *param)
 {
 	twt_nudge_dialog_cb callback;
-	void *context;
 	bool is_evt_allowed;
 
 	is_evt_allowed = mlme_twt_is_command_in_progress(
@@ -2239,11 +2238,8 @@ sme_process_twt_nudge_dialog_event(struct mac_context *mac,
 	}
 
 	callback = mac->sme.twt_nudge_dialog_cb;
-	context = mac->sme.twt_nudge_dialog_context;
-	mac->sme.twt_nudge_dialog_cb = NULL;
 	if (callback)
-		callback(context, param);
-
+		callback(mac->psoc, param);
 	/* Reset the active TWT command to none */
 	mlme_set_twt_command_in_progress(
 			mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
@@ -14004,6 +14000,7 @@ QDF_STATUS sme_clear_twt_complete_cb(mac_handle_t mac_handle)
 		mac->sme.twt_pause_dialog_cb = NULL;
 		mac->sme.twt_resume_dialog_cb = NULL;
 		mac->sme.twt_notify_cb = NULL;
+		mac->sme.twt_nudge_dialog_cb = NULL;
 		sme_release_global_lock(&mac->sme);
 
 		sme_debug("TWT: callbacks Initialized");
@@ -14027,6 +14024,7 @@ QDF_STATUS sme_register_twt_callbacks(mac_handle_t mac_handle,
 		mac->sme.twt_resume_dialog_cb = twt_cb->twt_resume_dialog_cb;
 		mac->sme.twt_disable_cb = twt_cb->twt_disable_cb;
 		mac->sme.twt_notify_cb = twt_cb->twt_notify_cb;
+		mac->sme.twt_nudge_dialog_cb = twt_cb->twt_nudge_dialog_cb;
 		sme_release_global_lock(&mac->sme);
 		sme_debug("TWT: callbacks registered");
 	}
@@ -14244,9 +14242,7 @@ sme_pause_dialog_cmd(mac_handle_t mac_handle,
 
 QDF_STATUS
 sme_nudge_dialog_cmd(mac_handle_t mac_handle,
-		     twt_nudge_dialog_cb nudge_dialog_cb,
-		     struct wmi_twt_nudge_dialog_cmd_param *twt_params,
-		     void *context)
+		     struct wmi_twt_nudge_dialog_cmd_param *twt_params)
 {
 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
 	struct wmi_twt_nudge_dialog_cmd_param *cmd_params;
@@ -14285,16 +14281,7 @@ sme_nudge_dialog_cmd(mac_handle_t mac_handle,
 		return status;
 	}
 
-	if (mac->sme.twt_nudge_dialog_cb) {
-		sme_release_global_lock(&mac->sme);
-		qdf_mem_free(cmd_params);
-		sme_err_rl("TWT: Command in progress - STATUS E_BUSY");
-		return QDF_STATUS_E_BUSY;
-	}
-
 	/* Serialize the req through MC thread */
-	mac->sme.twt_nudge_dialog_cb = nudge_dialog_cb;
-	mac->sme.twt_nudge_dialog_context = context;
 	twt_msg.bodyptr = cmd_params;
 	twt_msg.type = WMA_TWT_NUDGE_DIALOG_REQUEST;
 	sme_release_global_lock(&mac->sme);