1 /*
2 * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 /**
20 * DOC: wlan_hdd_sysfs_monitor_mode_channel.c
21 *
22 * Implementation for creating sysfs file monitor_mode_channel
23 */
24
25 #include <wlan_hdd_includes.h>
26 #include "osif_vdev_sync.h"
27 #include <wlan_hdd_sysfs.h>
28 #include <wlan_hdd_sysfs_monitor_mode_channel.h>
29
30 static ssize_t
__hdd_sysfs_monitor_mode_channel_store(struct net_device * net_dev,char const * buf,size_t count)31 __hdd_sysfs_monitor_mode_channel_store(struct net_device *net_dev,
32 char const *buf, size_t count)
33 {
34 struct hdd_adapter *adapter = netdev_priv(net_dev);
35 char buf_local[MAX_SYSFS_USER_COMMAND_SIZE_LENGTH + 1];
36 struct hdd_context *hdd_ctx;
37 char *sptr, *token;
38 uint32_t val1, val2;
39 int ret;
40
41 if (hdd_validate_adapter(adapter))
42 return -EINVAL;
43
44 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
45 ret = wlan_hdd_validate_context(hdd_ctx);
46 if (ret != 0)
47 return ret;
48
49 if (!wlan_hdd_validate_modules_state(hdd_ctx))
50 return -EINVAL;
51
52 ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local),
53 buf, count);
54
55 if (ret) {
56 hdd_err_rl("invalid input");
57 return ret;
58 }
59
60 sptr = buf_local;
61 hdd_debug("set_mon_chan: count %zu buf_local:(%s) net_devname %s",
62 count, buf_local, net_dev->name);
63
64 /* Get val1 */
65 token = strsep(&sptr, " ");
66 if (!token)
67 return -EINVAL;
68 if (kstrtou32(token, 0, &val1))
69 return -EINVAL;
70
71 /* Get val2 */
72 token = strsep(&sptr, " ");
73 if (!token)
74 return -EINVAL;
75 if (kstrtou32(token, 0, &val2))
76 return -EINVAL;
77
78 if (val1 > 256)
79 ret = wlan_hdd_set_mon_chan(adapter, val1, val2);
80 else
81 ret = wlan_hdd_set_mon_chan(adapter,
82 wlan_reg_legacy_chan_to_freq(
83 hdd_ctx->pdev, val1),
84 val2);
85
86 return count;
87 }
88
89 static ssize_t
hdd_sysfs_monitor_mode_channel_store(struct device * dev,struct device_attribute * attr,char const * buf,size_t count)90 hdd_sysfs_monitor_mode_channel_store(struct device *dev,
91 struct device_attribute *attr,
92 char const *buf, size_t count)
93 {
94 struct net_device *net_dev = container_of(dev, struct net_device, dev);
95 struct osif_vdev_sync *vdev_sync;
96 ssize_t errno_size;
97
98 errno_size = osif_vdev_sync_op_start(net_dev, &vdev_sync);
99 if (errno_size)
100 return errno_size;
101
102 errno_size = __hdd_sysfs_monitor_mode_channel_store(net_dev,
103 buf, count);
104
105 osif_vdev_sync_op_stop(vdev_sync);
106
107 return errno_size;
108 }
109
110 static DEVICE_ATTR(monitor_mode_channel, 0220,
111 NULL, hdd_sysfs_monitor_mode_channel_store);
112
hdd_sysfs_monitor_mode_channel_create(struct hdd_adapter * adapter)113 int hdd_sysfs_monitor_mode_channel_create(struct hdd_adapter *adapter)
114 {
115 int error;
116
117 error = device_create_file(&adapter->dev->dev,
118 &dev_attr_monitor_mode_channel);
119 if (error)
120 hdd_err("could not create monitor_mode_channel sysfs file");
121
122 return error;
123 }
124
hdd_sysfs_monitor_mode_channel_destroy(struct hdd_adapter * adapter)125 void hdd_sysfs_monitor_mode_channel_destroy(struct hdd_adapter *adapter)
126 {
127 device_remove_file(&adapter->dev->dev, &dev_attr_monitor_mode_channel);
128 }
129