blob: 1010da97d88e29e130879663f585e8ef4e70ba28 [file] [log] [blame]
Amar Singhal0928b192017-12-01 10:50:54 -08001/*
2 * Copyright (c) 2017 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/**
23 * DOC: wlan_hdd_sysfs.c
24 *
25 * WLAN Host Device Driver implementation
26 *
27 */
28
29#include <linux/module.h>
30#include <linux/kobject.h>
31#include <linux/fs.h>
32#include <linux/string.h>
33#include "wlan_hdd_includes.h"
34#include "wlan_hdd_sysfs.h"
35#include "qwlan_version.h"
36#include "cds_api.h"
37
38#define MAX_PSOC_ID_SIZE 10
39
40#ifdef MULTI_IF_NAME
41#define DRIVER_NAME MULTI_IF_NAME
42#else
43#define DRIVER_NAME "wlan"
44#endif
45
46static struct kobject *wlan_kobject;
47static struct kobject *driver_kobject;
48static struct kobject *fw_kobject;
49static struct kobject *psoc_kobject;
50
51static ssize_t __show_driver_version(struct kobject *kobj,
52 struct kobj_attribute *attr,
53 char *buf)
54{
55 return scnprintf(buf, PAGE_SIZE, QWLAN_VERSIONSTR);
56}
57
58static ssize_t show_driver_version(struct kobject *kobj,
59 struct kobj_attribute *attr,
60 char *buf)
61{
62 ssize_t ret_val;
63
64 cds_ssr_protect(__func__);
65 ret_val = __show_driver_version(kobj, attr, buf);
66 cds_ssr_unprotect(__func__);
67
68 return ret_val;
69}
70
71static ssize_t __show_fw_version(struct kobject *kobj,
72 struct kobj_attribute *attr,
73 char *buf)
74{
75 const char *hw_version;
76 uint32_t major_spid = 0, minor_spid = 0, siid = 0, crmid = 0;
77 uint32_t sub_id = 0;
78 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
79 int ret;
80
81 ret = wlan_hdd_validate_context(hdd_ctx);
82 if (ret) {
83 hdd_err("hdd ctx is invalid");
84 return ret;
85 }
86
87 hdd_debug("Rcvd req for FW version");
88 hdd_get_fw_version(hdd_ctx, &major_spid, &minor_spid, &siid,
89 &crmid);
90 sub_id = (hdd_ctx->target_fw_vers_ext & 0xf0000000) >> 28;
91 hw_version = hdd_ctx->target_hw_name;
92
93 return scnprintf(buf, PAGE_SIZE,
94 "FW:%d.%d.%d.%d.%d HW:%s", major_spid,
95 minor_spid, siid, crmid, sub_id,
96 hw_version);
97}
98
99static ssize_t show_fw_version(struct kobject *kobj,
100 struct kobj_attribute *attr,
101 char *buf)
102{
103 ssize_t ret_val;
104
105 cds_ssr_protect(__func__);
106 ret_val = __show_fw_version(kobj, attr, buf);
107 cds_ssr_unprotect(__func__);
108
109 return ret_val;
110}
111
112static struct kobj_attribute dr_ver_attribute =
113 __ATTR(driver_version, 0440, show_driver_version, NULL);
114static struct kobj_attribute fw_ver_attribute =
115 __ATTR(version, 0440, show_fw_version, NULL);
116
117void hdd_sysfs_create_version_interface(struct wlan_objmgr_psoc *psoc)
118{
119 int error = 0;
120 uint32_t psoc_id;
121 char buf[MAX_PSOC_ID_SIZE];
122
Amar Singhal6c0c0d92017-12-14 15:14:49 -0800123 wlan_kobject = kobject_create_and_add("wifi", kernel_kobj);
Amar Singhal0928b192017-12-01 10:50:54 -0800124 if (!wlan_kobject) {
125 hdd_err("could not allocate wlan kobject");
126 return;
127 }
128
129 driver_kobject = kobject_create_and_add(DRIVER_NAME, wlan_kobject);
130 if (!driver_kobject) {
131 hdd_err("could not allocate driver kobject");
132 goto free_wlan_kobj;
133 }
134
135 error = sysfs_create_file(driver_kobject, &dr_ver_attribute.attr);
136 if (error) {
137 hdd_err("could not create driver sysfs file");
138 goto free_drv_kobj;
139 }
140
141 fw_kobject = kobject_create_and_add("fw", driver_kobject);
142 if (!fw_kobject) {
143 hdd_err("could not allocate fw kobject");
144 goto free_fw_kobj;
145 }
146
147 psoc_id = wlan_psoc_get_nif_phy_version(psoc);
148 scnprintf(buf, PAGE_SIZE, "%d", psoc_id);
149
150 psoc_kobject = kobject_create_and_add(buf, fw_kobject);
151 if (!psoc_kobject) {
152 hdd_err("could not allocate psoc kobject");
153 goto free_fw_kobj;
154 }
155
156 error = sysfs_create_file(psoc_kobject, &fw_ver_attribute.attr);
157 if (error) {
158 hdd_err("could not create fw sysfs file");
159 goto free_psoc_kobj;
160 }
161
162 return;
163
164free_psoc_kobj:
165 kobject_put(psoc_kobject);
166 psoc_kobject = NULL;
167
168free_fw_kobj:
169 kobject_put(fw_kobject);
170 fw_kobject = NULL;
171
172free_drv_kobj:
173 kobject_put(driver_kobject);
174 driver_kobject = NULL;
175
176free_wlan_kobj:
177 kobject_put(wlan_kobject);
178 wlan_kobject = NULL;
179}
180
181void hdd_sysfs_destroy_version_interface(void)
182{
183 if (psoc_kobject) {
184 kobject_put(psoc_kobject);
185 psoc_kobject = NULL;
186 kobject_put(fw_kobject);
187 fw_kobject = NULL;
188 kobject_put(driver_kobject);
189 driver_kobject = NULL;
190 kobject_put(wlan_kobject);
191 wlan_kobject = NULL;
192 }
193}