1 /*
2 * Copyright (c) 2020 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 /**
19 * DOC: wlan_hdd_sysfs_dcm.c
20 *
21 * implementation for creating sysfs file dcm
22 */
23
24 #include <wlan_hdd_includes.h>
25 #include "osif_vdev_sync.h"
26 #include <wlan_hdd_sysfs.h>
27 #include "wlan_hdd_sysfs_dcm.h"
28 #include <wma_api.h>
29
30 static ssize_t
__wlan_hdd_sysfs_dcm_store(struct net_device * net_dev,char const * buf,size_t count)31 __wlan_hdd_sysfs_dcm_store(struct net_device *net_dev, char const *buf,
32 size_t count)
33 {
34 struct hdd_adapter *adapter = netdev_priv(net_dev);
35 struct hdd_context *hdd_ctx;
36 char buf_local[MAX_SYSFS_USER_COMMAND_SIZE_LENGTH + 1];
37 char *sptr, *token;
38 int value, ret;
39
40 if (hdd_validate_adapter(adapter))
41 return -EINVAL;
42
43 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
44 ret = wlan_hdd_validate_context(hdd_ctx);
45 if (ret != 0)
46 return ret;
47
48 if (!wlan_hdd_validate_modules_state(hdd_ctx))
49 return -EINVAL;
50
51 ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local),
52 buf, count);
53 if (ret) {
54 hdd_err_rl("invalid input");
55 return ret;
56 }
57
58 sptr = buf_local;
59 token = strsep(&sptr, " ");
60 if (!token)
61 return -EINVAL;
62 if (kstrtou32(token, 0, &value))
63 return -EINVAL;
64
65 hdd_debug("dcm %d", value);
66
67 ret = wma_cli_set_command(adapter->deflink->vdev_id,
68 wmi_vdev_param_he_dcm_enable,
69 value, VDEV_CMD);
70 if (ret) {
71 hdd_err_rl("Failed to set dcm, errno %d", ret);
72 return ret;
73 }
74
75 return count;
76 }
77
wlan_hdd_sysfs_dcm_store(struct device * dev,struct device_attribute * attr,char const * buf,size_t count)78 static ssize_t wlan_hdd_sysfs_dcm_store(struct device *dev,
79 struct device_attribute *attr,
80 char const *buf, size_t count)
81 {
82 struct net_device *net_dev = container_of(dev, struct net_device, dev);
83 struct osif_vdev_sync *vdev_sync;
84 ssize_t err_size;
85
86 err_size = osif_vdev_sync_op_start(net_dev, &vdev_sync);
87 if (err_size)
88 return err_size;
89
90 err_size = __wlan_hdd_sysfs_dcm_store(net_dev, buf, count);
91
92 osif_vdev_sync_op_stop(vdev_sync);
93
94 return err_size;
95 }
96
97 static ssize_t
__wlan_hdd_sysfs_dcm_show(struct net_device * net_dev,char * buf)98 __wlan_hdd_sysfs_dcm_show(struct net_device *net_dev, char *buf)
99 {
100 struct hdd_adapter *adapter = netdev_priv(net_dev);
101 struct hdd_context *hdd_ctx;
102 int ret, value;
103
104 if (hdd_validate_adapter(adapter))
105 return -EINVAL;
106
107 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
108 ret = wlan_hdd_validate_context(hdd_ctx);
109 if (ret != 0)
110 return ret;
111
112 if (!wlan_hdd_validate_modules_state(hdd_ctx))
113 return -EINVAL;
114
115 value = wma_cli_get_command(adapter->deflink->vdev_id,
116 wmi_vdev_param_he_dcm_enable,
117 VDEV_CMD);
118
119 hdd_debug("dcm %d", value);
120
121 ret = scnprintf(buf, PAGE_SIZE, "%d", value);
122
123 return ret;
124 }
125
wlan_hdd_sysfs_dcm_show(struct device * dev,struct device_attribute * attr,char * buf)126 static ssize_t wlan_hdd_sysfs_dcm_show(struct device *dev,
127 struct device_attribute *attr,
128 char *buf)
129 {
130 struct net_device *net_dev = container_of(dev, struct net_device, dev);
131 struct osif_vdev_sync *vdev_sync;
132 ssize_t err_size;
133
134 err_size = osif_vdev_sync_op_start(net_dev, &vdev_sync);
135 if (err_size)
136 return err_size;
137
138 err_size = __wlan_hdd_sysfs_dcm_show(net_dev, buf);
139
140 osif_vdev_sync_op_stop(vdev_sync);
141
142 return err_size;
143 }
144
145 static DEVICE_ATTR(dcm, 0664, wlan_hdd_sysfs_dcm_show,
146 wlan_hdd_sysfs_dcm_store);
147
hdd_sysfs_dcm_create(struct hdd_adapter * adapter)148 int hdd_sysfs_dcm_create(struct hdd_adapter *adapter)
149 {
150 int error;
151
152 error = device_create_file(&adapter->dev->dev, &dev_attr_dcm);
153 if (error)
154 hdd_err("could not create dcm sysfs file");
155
156 return error;
157 }
158
hdd_sysfs_dcm_destroy(struct hdd_adapter * adapter)159 void hdd_sysfs_dcm_destroy(struct hdd_adapter *adapter)
160 {
161 device_remove_file(&adapter->dev->dev, &dev_attr_dcm);
162 }
163