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