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_fw_mode_config.c
21 *
22 * Implementation for creating sysfs file fw_mode_config
23 */
24
25 #include <wlan_hdd_includes.h>
26 #include "osif_psoc_sync.h"
27 #include <wlan_hdd_sysfs.h>
28 #include <wlan_hdd_sysfs_fw_mode_config.h>
29 #include "wlan_policy_mgr_ucfg.h"
30
31 static ssize_t
__wlan_hdd_store_fw_mode_config_sysfs(struct hdd_context * hdd_ctx,struct kobj_attribute * attr,const char * buf,size_t count)32 __wlan_hdd_store_fw_mode_config_sysfs(struct hdd_context *hdd_ctx,
33 struct kobj_attribute *attr,
34 const char *buf,
35 size_t count)
36 {
37 uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN;
38 char buf_local[MAX_SYSFS_USER_COMMAND_SIZE_LENGTH + 1];
39 char *sptr, *token;
40 uint32_t val1, val2;
41 QDF_STATUS status;
42 int ret;
43
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 hdd_debug("set_fw_mode_cfg: count %zu buf_local:(%s)",
59 count, buf_local);
60
61 sptr = buf_local;
62 /* Get val1 */
63 token = strsep(&sptr, " ");
64 if (!token)
65 return -EINVAL;
66 if (kstrtou32(token, 0, &val1))
67 return -EINVAL;
68
69 /* Get val2 */
70 token = strsep(&sptr, " ");
71 if (!token)
72 return -EINVAL;
73 if (kstrtou32(token, 0, &val2))
74 return -EINVAL;
75
76 hdd_debug("Sysfs to set dual fw mode config");
77 status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
78 &dual_mac_feature);
79 if (status != QDF_STATUS_SUCCESS)
80 hdd_err_rl("can't get dual mac feature val, use def");
81 if (dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) {
82 hdd_err_rl("Dual mac feature is disabled from INI");
83 return -EPERM;
84 }
85 hdd_debug("%d %d", val1, val2);
86 policy_mgr_set_dual_mac_fw_mode_config(hdd_ctx->psoc,
87 val1, val2);
88
89 return count;
90 }
91
92 static ssize_t
wlan_hdd_store_fw_mode_config_sysfs(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)93 wlan_hdd_store_fw_mode_config_sysfs(struct kobject *kobj,
94 struct kobj_attribute *attr,
95 const char *buf,
96 size_t count)
97 {
98 struct osif_psoc_sync *psoc_sync;
99 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
100 ssize_t errno_size;
101 int ret;
102
103 ret = wlan_hdd_validate_context(hdd_ctx);
104 if (ret != 0)
105 return ret;
106
107 errno_size = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy),
108 &psoc_sync);
109 if (errno_size)
110 return errno_size;
111
112 errno_size = __wlan_hdd_store_fw_mode_config_sysfs(hdd_ctx, attr,
113 buf, count);
114
115 osif_psoc_sync_op_stop(psoc_sync);
116
117 return errno_size;
118 }
119
120 static struct kobj_attribute set_fw_mode_cfg_attribute =
121 __ATTR(fw_mode_config, 0220, NULL,
122 wlan_hdd_store_fw_mode_config_sysfs);
123
hdd_sysfs_fw_mode_config_create(struct kobject * driver_kobject)124 int hdd_sysfs_fw_mode_config_create(struct kobject *driver_kobject)
125 {
126 int error;
127
128 if (!driver_kobject) {
129 hdd_err("could not get driver kobject!");
130 return -EINVAL;
131 }
132
133 error = sysfs_create_file(driver_kobject,
134 &set_fw_mode_cfg_attribute.attr);
135 if (error)
136 hdd_err("could not create fw_mode_config sysfs file");
137
138 return error;
139 }
140
141 void
hdd_sysfs_fw_mode_config_destroy(struct kobject * driver_kobject)142 hdd_sysfs_fw_mode_config_destroy(struct kobject *driver_kobject)
143 {
144 if (!driver_kobject) {
145 hdd_err("could not get driver kobject!");
146 return;
147 }
148 sysfs_remove_file(driver_kobject, &set_fw_mode_cfg_attribute.attr);
149 }
150