Browse Source

qcacld-3.0: Add TWT notify support to componentization

Add TWT notify support to componentization.

Change-Id: I44afb4a0d045916e9ca0f29924330de3a5d95859
CRs-Fixed: 3085549
Srinivas Girigowda 3 years ago
parent
commit
96132d1c52

+ 43 - 1
components/target_if/twt/src/target_if_ext_twt_evt.c

@@ -158,7 +158,49 @@ static int
 target_if_twt_notify_event_handler(ol_scn_t scn, uint8_t *event,
 				   uint32_t len)
 {
-	return 0;
+	QDF_STATUS qdf_status;
+	struct wmi_unified *wmi_handle;
+	struct wlan_objmgr_psoc *psoc;
+	struct twt_notify_event_param *data;
+	struct wlan_lmac_if_twt_rx_ops *twt_rx_ops;
+
+	TARGET_IF_ENTER();
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("psoc is null");
+		return -EINVAL;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("wmi_handle is null");
+		return -EINVAL;
+	}
+
+	twt_rx_ops = wlan_twt_get_rx_ops(psoc);
+	if (!twt_rx_ops || !twt_rx_ops->twt_notify_comp_cb) {
+		target_if_err("No valid twt notify rx ops");
+		return -EINVAL;
+	}
+
+	data = qdf_mem_malloc(sizeof(*data));
+	if (!data)
+		return -ENOMEM;
+
+	qdf_status = wmi_extract_twt_notify_event(wmi_handle, event, data);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		target_if_err("extract twt notify event failed (status=%d)",
+			      qdf_status);
+		goto done;
+	}
+
+	qdf_status = twt_rx_ops->twt_notify_comp_cb(psoc, data);
+
+done:
+	qdf_mem_free(data);
+	return qdf_status_to_os_return(qdf_status);
+
 }
 
 static int

+ 48 - 1
components/umac/twt/core/src/wlan_twt_main.c

@@ -173,7 +173,30 @@ wlan_twt_init_context(struct wlan_objmgr_psoc *psoc,
 static bool
 wlan_is_twt_notify_in_progress(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id)
 {
-	return false;
+	struct wlan_objmgr_vdev *vdev;
+	struct twt_vdev_priv_obj *twt_vdev_priv;
+	bool is_twt_notify_in_progress;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_TWT_ID);
+	if (!vdev) {
+		twt_err("vdev object not found");
+		return false;
+	}
+
+	twt_vdev_priv = wlan_objmgr_vdev_get_comp_private_obj(vdev,
+							WLAN_UMAC_COMP_TWT);
+	if (!twt_vdev_priv) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_TWT_ID);
+		twt_err("twt vdev private object is NULL");
+		return false;
+	}
+
+	is_twt_notify_in_progress = twt_vdev_priv->twt_wait_for_notify;
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_TWT_ID);
+
+	twt_debug("is_twt_notify_in_progress: %d", is_twt_notify_in_progress);
+	return is_twt_notify_in_progress;
 }
 
 /**
@@ -188,6 +211,27 @@ static QDF_STATUS
 wlan_twt_set_wait_for_notify(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id,
 			     bool is_set)
 {
+	struct wlan_objmgr_vdev *vdev;
+	struct twt_vdev_priv_obj *twt_vdev_priv;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_TWT_ID);
+	if (!vdev) {
+		twt_err("vdev object not found");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	twt_vdev_priv = wlan_objmgr_vdev_get_comp_private_obj(vdev,
+							WLAN_UMAC_COMP_TWT);
+	if (!twt_vdev_priv) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_TWT_ID);
+		twt_err("twt vdev private object is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	twt_vdev_priv->twt_wait_for_notify = is_set;
+	twt_debug("twt_wait_for_notify: %d", is_set);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_TWT_ID);
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -1336,5 +1380,8 @@ QDF_STATUS
 wlan_twt_notify_event_handler(struct wlan_objmgr_psoc *psoc,
 			      struct twt_notify_event_param *event)
 {
+	wlan_twt_set_wait_for_notify(psoc, event->vdev_id, false);
+	mlme_twt_osif_notify_complete_ind(psoc, event);
+
 	return QDF_STATUS_SUCCESS;
 }

+ 1 - 1
components/umac/twt/dispatcher/src/wlan_twt_tgt_if_ext_rx_api.c

@@ -65,7 +65,7 @@ static QDF_STATUS
 tgt_twt_notify_complete_resp_handler(struct wlan_objmgr_psoc *psoc,
 			    struct twt_notify_event_param *event)
 {
-	return QDF_STATUS_SUCCESS;
+	return wlan_twt_notify_event_handler(psoc, event);
 }
 
 static QDF_STATUS

+ 60 - 0
os_if/twt/src/osif_twt_ext_rsp.c

@@ -383,6 +383,18 @@ osif_twt_setup_pack_resp_nlmsg(struct sk_buff *reply_skb,
  * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes
  * on failure
  */
+static QDF_STATUS
+osif_twt_notify_pack_nlmsg(struct sk_buff *reply_skb)
+{
+	if (nla_put_u8(reply_skb, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
+		       QCA_WLAN_TWT_SETUP_READY_NOTIFY)) {
+		osif_err("Failed to put TWT notify operation");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
 static QDF_STATUS
 osif_twt_teardown_pack_resp_nlmsg(struct sk_buff *reply_skb,
 			     struct twt_del_dialog_complete_event_param *event)
@@ -624,6 +636,54 @@ QDF_STATUS
 osif_twt_notify_complete_cb(struct wlan_objmgr_psoc *psoc,
 			    struct twt_notify_event_param *event)
 {
+	struct wireless_dev *wdev;
+	struct sk_buff *twt_vendor_event;
+	size_t data_len;
+	QDF_STATUS status;
+	struct vdev_osif_priv *osif_priv;
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, event->vdev_id,
+						    WLAN_TWT_ID);
+	if (!vdev) {
+		osif_err("vdev is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	osif_priv = wlan_vdev_get_ospriv(vdev);
+	if (!osif_priv) {
+		osif_err("osif_priv is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wdev = osif_priv->wdev;
+	if (!wdev) {
+		osif_err("wireless dev is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	data_len = NLA_HDRLEN;
+	data_len += nla_total_size(sizeof(u8));
+
+	twt_vendor_event = wlan_cfg80211_vendor_event_alloc(
+				wdev->wiphy, wdev, data_len,
+				QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT_INDEX,
+				GFP_KERNEL);
+	if (!twt_vendor_event) {
+		osif_err("Notify skb alloc failed");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	osif_debug("twt Notify vdev_id %d", event->vdev_id);
+
+	status = osif_twt_notify_pack_nlmsg(twt_vendor_event);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		osif_err("Failed to pack nl notify event");
+		wlan_cfg80211_vendor_free_skb(twt_vendor_event);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wlan_cfg80211_vendor_event(twt_vendor_event, GFP_KERNEL);
 	return QDF_STATUS_SUCCESS;
 }