1 /*
2  * Copyright (c) 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_sysfs_dfsnol.c
19  *
20  * Implementation for creating sysfs file dfsnol
21  */
22 
23 #include <wlan_hdd_includes.h>
24 #include "osif_vdev_sync.h"
25 #include "wlan_dfs_utils_api.h"
26 #include <wlan_hdd_sysfs.h>
27 #include <wlan_hdd_sysfs_dfsnol.h>
28 
29 static ssize_t
__hdd_sysfs_dfsnol_show(struct net_device * net_dev,char * buf)30 __hdd_sysfs_dfsnol_show(struct net_device *net_dev, char *buf)
31 {
32 	struct hdd_adapter *adapter = netdev_priv(net_dev);
33 	struct hdd_context *hdd_ctx;
34 	struct wlan_objmgr_pdev *pdev;
35 	int ret;
36 
37 	if (hdd_validate_adapter(adapter))
38 		return -EINVAL;
39 
40 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
41 	ret = wlan_hdd_validate_context(hdd_ctx);
42 	if (ret)
43 		return ret;
44 
45 	if (!wlan_hdd_validate_modules_state(hdd_ctx))
46 		return -EINVAL;
47 
48 	pdev = hdd_ctx->pdev;
49 	if (!pdev) {
50 		hdd_err("null pdev");
51 		return -EINVAL;
52 	}
53 
54 	utils_dfs_print_nol_channels(pdev);
55 	return scnprintf(buf, PAGE_SIZE, "DFS NOL Info written to dmesg log\n");
56 }
57 
58 static ssize_t
hdd_sysfs_dfsnol_show(struct device * dev,struct device_attribute * attr,char * buf)59 hdd_sysfs_dfsnol_show(struct device *dev,
60 		      struct device_attribute *attr, char *buf)
61 {
62 	struct net_device *net_dev = container_of(dev, struct net_device, dev);
63 	struct osif_vdev_sync *vdev_sync;
64 	ssize_t errno_size;
65 
66 	errno_size = osif_vdev_sync_op_start(net_dev, &vdev_sync);
67 	if (errno_size)
68 		return errno_size;
69 
70 	errno_size = __hdd_sysfs_dfsnol_show(net_dev, buf);
71 
72 	osif_vdev_sync_op_stop(vdev_sync);
73 
74 	return errno_size;
75 }
76 
77 static ssize_t
__hdd_sysfs_dfsnol_store(struct net_device * net_dev,char const * buf,size_t count)78 __hdd_sysfs_dfsnol_store(struct net_device *net_dev,
79 			 char const *buf, size_t count)
80 {
81 	struct hdd_adapter *adapter = netdev_priv(net_dev);
82 	struct hdd_context *hdd_ctx;
83 	struct sap_context *sap_ctx;
84 	char buf_local[MAX_SYSFS_USER_COMMAND_SIZE_LENGTH + 1];
85 	char *sptr, *token;
86 	eSapDfsNolType set_value;
87 	int ret;
88 	QDF_STATUS status;
89 
90 	if (hdd_validate_adapter(adapter))
91 		return -EINVAL;
92 
93 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
94 	ret = wlan_hdd_validate_context(hdd_ctx);
95 	if (ret)
96 		return ret;
97 
98 	if (!wlan_hdd_validate_modules_state(hdd_ctx))
99 		return -EINVAL;
100 
101 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink);
102 	if (!sap_ctx) {
103 		hdd_err_rl("Null SAP Context");
104 		return -EINVAL;
105 	}
106 
107 	ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local),
108 					      buf, count);
109 	if (ret) {
110 		hdd_err_rl("invalid input");
111 		return ret;
112 	}
113 
114 	sptr = buf_local;
115 	hdd_nofl_debug("set_dfsnol: count %zu buf_local:(%s) net_devname %s",
116 		       count, buf_local, net_dev->name);
117 
118 	/* Get set_value */
119 	token = strsep(&sptr, " ");
120 	if (!token)
121 		return -EINVAL;
122 	if (kstrtou32(token, 0, &set_value))
123 		return -EINVAL;
124 
125 	status = wlansap_set_dfs_nol(sap_ctx, set_value);
126 	if (QDF_IS_STATUS_ERROR(status)) {
127 		hdd_err_rl("Unable to set_dfsnol val %d", set_value);
128 		return -EINVAL;
129 	}
130 
131 	return count;
132 }
133 
134 static ssize_t
hdd_sysfs_dfsnol_store(struct device * dev,struct device_attribute * attr,char const * buf,size_t count)135 hdd_sysfs_dfsnol_store(struct device *dev, struct device_attribute *attr,
136 		       char const *buf, size_t count)
137 {
138 	struct net_device *net_dev = container_of(dev, struct net_device, dev);
139 	struct osif_vdev_sync *vdev_sync;
140 	ssize_t errno_size;
141 
142 	errno_size = osif_vdev_sync_op_start(net_dev, &vdev_sync);
143 	if (errno_size)
144 		return errno_size;
145 
146 	errno_size = __hdd_sysfs_dfsnol_store(net_dev, buf, count);
147 
148 	osif_vdev_sync_op_stop(vdev_sync);
149 
150 	return errno_size;
151 }
152 
153 static DEVICE_ATTR(dfsnol, 0660, hdd_sysfs_dfsnol_show,
154 		   hdd_sysfs_dfsnol_store);
155 
hdd_sysfs_dfsnol_create(struct hdd_adapter * adapter)156 int hdd_sysfs_dfsnol_create(struct hdd_adapter *adapter)
157 {
158 	int error;
159 
160 	error = device_create_file(&adapter->dev->dev, &dev_attr_dfsnol);
161 	if (error)
162 		hdd_err_rl("could not create dfsnol sysfs file");
163 
164 	return error;
165 }
166 
hdd_sysfs_dfsnol_destroy(struct hdd_adapter * adapter)167 void hdd_sysfs_dfsnol_destroy(struct hdd_adapter *adapter)
168 {
169 	device_remove_file(&adapter->dev->dev, &dev_attr_dfsnol);
170 }
171