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