1 /*
2  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /**
18  * DOC: wlan_hdd_coap.c
19  *
20  * The implementation of CoAP offload configuration
21  *
22  */
23 
24 #include "wlan_hdd_main.h"
25 #include "wlan_hdd_coap.h"
26 #include "osif_sync.h"
27 #include "wlan_hdd_object_manager.h"
28 #include "wlan_cfg80211_coap.h"
29 
30 /**
31  * __wlan_hdd_cfg80211_coap_offload() - configure CoAP offloading
32  * @wiphy: pointer to wireless wiphy structure.
33  * @wdev: pointer to wireless_dev structure.
34  * @data: pointer to netlink TLV buffer
35  * @data_len: the length of @data in bytes
36  *
37  * Return: An error code or 0 on success.
38  */
39 static int
__wlan_hdd_cfg80211_coap_offload(struct wiphy * wiphy,struct wireless_dev * wdev,const void * data,int data_len)40 __wlan_hdd_cfg80211_coap_offload(struct wiphy *wiphy,
41 				 struct wireless_dev *wdev,
42 				 const void *data, int data_len)
43 {
44 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev);
45 	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
46 	int errno;
47 	struct wlan_objmgr_vdev *vdev;
48 
49 	hdd_enter_dev(wdev->netdev);
50 
51 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
52 		hdd_err("Command not allowed in FTM mode");
53 		return -EPERM;
54 	}
55 
56 	errno = wlan_hdd_validate_context(hdd_ctx);
57 	if (errno != 0)
58 		return errno;
59 
60 	if (adapter->device_mode != QDF_STA_MODE)
61 		return -ENOTSUPP;
62 
63 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_COAP_ID);
64 	if (!vdev)
65 		return -EINVAL;
66 
67 	errno = wlan_cfg80211_coap_offload(wiphy, vdev, data, data_len);
68 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_COAP_ID);
69 	return errno;
70 }
71 
wlan_hdd_cfg80211_coap_offload(struct wiphy * wiphy,struct wireless_dev * wdev,const void * data,int data_len)72 int wlan_hdd_cfg80211_coap_offload(struct wiphy *wiphy,
73 				   struct wireless_dev *wdev,
74 				   const void *data, int data_len)
75 {
76 	int errno;
77 	struct osif_vdev_sync *vdev_sync;
78 
79 	errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
80 	if (errno)
81 		return errno;
82 
83 	errno = __wlan_hdd_cfg80211_coap_offload(wiphy, wdev, data, data_len);
84 	osif_vdev_sync_op_stop(vdev_sync);
85 	return errno;
86 }
87