[9610] wlbt: SCSC Driver version 10.9.1.0
[GitHub/MotorolaMobilityLLC/kernel-slsi.git] / drivers / net / wireless / scsc / procfs.c
1 /*****************************************************************************
2 *
3 * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved
4 *
5 ****************************************************************************/
6
7 #include "dev.h"
8 #include "procfs.h"
9 #include "debug.h"
10 #include "mlme.h"
11 #include "mgt.h"
12 #include "mib.h"
13 #include "cac.h"
14 #include "hip.h"
15 #include "netif.h"
16 #include "ioctl.h"
17 #include "nl80211_vendor.h"
18
19 #include "mib.h"
20
21 int slsi_procfs_open_file_generic(struct inode *inode, struct file *file)
22 {
23 file->private_data = SLSI_PDE_DATA(inode);
24 return 0;
25 }
26
27 #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG
28 static int slsi_printf_mutex_stats(char *buf, const size_t bufsz, const char *printf_padding, struct slsi_mutex *mutex_p)
29 {
30 int pos = 0;
31 const char *filename;
32 bool is_locked;
33
34 if (mutex_p->valid) {
35 is_locked = SLSI_MUTEX_IS_LOCKED(*mutex_p);
36 pos += scnprintf(buf, bufsz, "INFO: lock:%d\n", is_locked);
37 if (is_locked) {
38 filename = strrchr(mutex_p->file_name_before, '/');
39 if (filename)
40 filename++;
41 else
42 filename = mutex_p->file_name_before;
43 pos += scnprintf(buf + pos, bufsz - pos, "\t%sTryingToAcquire:%s:%d\n", printf_padding,
44 filename, mutex_p->line_no_before);
45 filename = strrchr(mutex_p->file_name_after, '/');
46 if (filename)
47 filename++;
48 else
49 filename = mutex_p->file_name_after;
50 pos += scnprintf(buf + pos, bufsz - pos, "\t%sAcquired:%s:%d:%s\n", printf_padding,
51 filename, mutex_p->line_no_after, mutex_p->function);
52 pos += scnprintf(buf + pos, bufsz - pos, "\t%sProcessName:%s\n", printf_padding, mutex_p->owner->comm);
53 }
54 } else {
55 pos += scnprintf(buf, bufsz, "NoInit\n");
56 }
57 return pos;
58 }
59
60 static ssize_t slsi_procfs_mutex_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
61 {
62 char buf[76 + (200 * CONFIG_SCSC_WLAN_MAX_INTERFACES)];
63 int pos = 0;
64 int i;
65 const size_t bufsz = sizeof(buf);
66 struct slsi_dev *sdev = (struct slsi_dev *)file->private_data;
67 struct net_device *dev;
68 struct netdev_vif *ndev_vif;
69
70 SLSI_UNUSED_PARAMETER(file);
71
72 pos += scnprintf(buf, bufsz, "sdev\n");
73 pos += scnprintf(buf + pos, bufsz - pos, "\tnetdev_add_remove_mutex ");
74 pos += slsi_printf_mutex_stats(buf + pos, bufsz - pos, "\t", &sdev->netdev_add_remove_mutex);
75 pos += scnprintf(buf + pos, bufsz - pos, "\tstart_stop_mutex ");
76 pos += slsi_printf_mutex_stats(buf + pos, bufsz - pos, "\t", &sdev->start_stop_mutex);
77 pos += scnprintf(buf + pos, bufsz - pos, "\tdevice_config_mutex ");
78 pos += slsi_printf_mutex_stats(buf + pos, bufsz - pos, "\t", &sdev->device_config_mutex);
79 pos += scnprintf(buf + pos, bufsz - pos, "\tsig_wait.mutex ");
80 pos += slsi_printf_mutex_stats(buf + pos, bufsz - pos, "\t", &sdev->sig_wait.mutex);
81 #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING
82 pos += scnprintf(buf + pos, bufsz - pos, "\tlogger_mutex ");
83 pos += slsi_printf_mutex_stats(buf + pos, bufsz - pos, "\t", &sdev->logger_mutex);
84 #endif
85
86 for (i = 1; i < CONFIG_SCSC_WLAN_MAX_INTERFACES + 1; i++) {
87 pos += scnprintf(buf + pos, bufsz - pos, "netdevvif %d\n", i);
88 dev = slsi_get_netdev_locked(sdev, i);
89 if (!dev)
90 continue;
91 ndev_vif = netdev_priv(dev);
92 if (ndev_vif->is_available) {
93 pos += scnprintf(buf + pos, bufsz - pos, "\tvif_mutex ");
94 pos += slsi_printf_mutex_stats(buf + pos, bufsz - pos, "\t\t", &ndev_vif->vif_mutex);
95 pos += scnprintf(buf + pos, bufsz - pos, "\tsig_wait.mutex ");
96 pos += slsi_printf_mutex_stats(buf + pos, bufsz - pos, "\t\t", &ndev_vif->sig_wait.mutex);
97 pos += scnprintf(buf + pos, bufsz - pos, "\tscan_mutex ");
98 pos += slsi_printf_mutex_stats(buf + pos, bufsz - pos, "\t\t", &ndev_vif->scan_mutex);
99 } else {
100 pos += scnprintf(buf + pos, bufsz - pos, "\tvif UNAVAILABLE\n");
101 }
102 }
103 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
104 }
105 #endif
106
107 static ssize_t slsi_procfs_throughput_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
108 {
109 char buf[5 * 25];
110 int pos = 0;
111 const size_t bufsz = sizeof(buf);
112 struct slsi_dev *sdev = (struct slsi_dev *)file->private_data;
113 struct net_device *dev;
114 struct netdev_vif *ndev_vif;
115 struct slsi_mib_data mibrsp = { 0, NULL };
116 struct slsi_mib_value *values = NULL;
117 struct slsi_mib_get_entry get_values[] = {{ SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 3, 0 } },
118 { SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 4, 0 } },
119 { SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 5, 0 } },
120 { SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 25, 0 } },
121 { SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 30, 0 } } };
122
123 SLSI_UNUSED_PARAMETER(file);
124
125 dev = slsi_get_netdev(sdev, 1);
126 ndev_vif = netdev_priv(dev);
127
128 if (ndev_vif->activated) {
129 mibrsp.dataLength = 15 * ARRAY_SIZE(get_values);
130 mibrsp.data = kmalloc(mibrsp.dataLength, GFP_KERNEL);
131 if (!mibrsp.data)
132 SLSI_ERR(sdev, "Cannot kmalloc %d bytes\n", mibrsp.dataLength);
133 values = slsi_read_mibs(sdev, dev, get_values, ARRAY_SIZE(get_values), &mibrsp);
134 if (!values) {
135 kfree(mibrsp.data);
136 return -EINVAL;
137 }
138 if (values[0].type != SLSI_MIB_TYPE_UINT)
139 SLSI_ERR(sdev, "invalid type. iter:%d", 0); /*bad_fcs_count*/
140 if (values[1].type != SLSI_MIB_TYPE_UINT)
141 SLSI_ERR(sdev, "invalid type. iter:%d", 1); /*missed_ba_count*/
142 if (values[2].type != SLSI_MIB_TYPE_UINT)
143 SLSI_ERR(sdev, "invalid type. iter:%d", 2); /*missed_ack_count*/
144 if (values[3].type != SLSI_MIB_TYPE_UINT)
145 SLSI_ERR(sdev, "invalid type. iter:%d", 3); /*mac_bad_sig_count*/
146 if (values[4].type != SLSI_MIB_TYPE_UINT)
147 SLSI_ERR(sdev, "invalid type. iter:%d", 4); /*rx_error_count*/
148
149 pos += scnprintf(buf, bufsz, "RX FCS: %d\n", values[0].u.uintValue);
150 pos += scnprintf(buf + pos, bufsz - pos, "RX bad SIG: %d\n", values[3].u.uintValue);
151 pos += scnprintf(buf + pos, bufsz - pos, "RX dot11 error: %d\n", values[4].u.uintValue);
152 pos += scnprintf(buf + pos, bufsz - pos, "TX MPDU no ACK: %d\n", values[2].u.uintValue);
153 pos += scnprintf(buf + pos, bufsz - pos, "TX A-MPDU no ACK: %d\n", values[1].u.uintValue);
154
155 kfree(values);
156 kfree(mibrsp.data);
157 } else {
158 pos += scnprintf(buf, bufsz, "RX FCS: %d\n", 0);
159 pos += scnprintf(buf + pos, bufsz - pos, "RX bad SIG: %d\n", 0);
160 pos += scnprintf(buf + pos, bufsz - pos, "RX dot11 error: %d\n", 0);
161 pos += scnprintf(buf + pos, bufsz - pos, "TX MPDU no ACK: %d\n", 0);
162 pos += scnprintf(buf + pos, bufsz - pos, "TX A-MPDU no ACK: %d\n", 0);
163 }
164
165 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
166 }
167
168 static ssize_t slsi_procfs_sta_bss_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
169 {
170 char buf[100];
171 int pos;
172 const size_t bufsz = sizeof(buf);
173 struct slsi_dev *sdev = (struct slsi_dev *)file->private_data;
174 struct net_device *dev;
175 struct netdev_vif *ndev_vif;
176 struct cfg80211_bss *sta_bss;
177 int channel = 0, center_freq = 0;
178 u8 no_mac[] = {0, 0, 0, 0, 0, 0};
179 u8 *mac_ptr;
180 u8 ssid[33];
181 s32 signal = 0;
182
183 SLSI_UNUSED_PARAMETER(file);
184
185 mac_ptr = no_mac;
186 ssid[0] = 0;
187
188 dev = slsi_get_netdev(sdev, 1);
189 if (!dev)
190 goto exit;
191
192 ndev_vif = netdev_priv(dev);
193
194 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
195 sta_bss = ndev_vif->sta.sta_bss;
196 if (sta_bss && ndev_vif->vif_type == FAPI_VIFTYPE_STATION &&
197 ndev_vif->sta.vif_status == SLSI_VIF_STATUS_CONNECTED) {
198 const u8 *ssid_ie = cfg80211_find_ie(WLAN_EID_SSID, sta_bss->ies->data, sta_bss->ies->len);
199
200 if (ssid_ie) {
201 memcpy(ssid, &ssid_ie[2], ssid_ie[1]);
202 ssid[ssid_ie[1]] = 0;
203 }
204
205 if (sta_bss->channel) {
206 channel = sta_bss->channel->hw_value;
207 center_freq = sta_bss->channel->center_freq;
208 }
209 mac_ptr = sta_bss->bssid;
210 signal = sta_bss->signal;
211 }
212 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
213
214 exit:
215 pos = scnprintf(buf, bufsz, "%pM,%s,%d,%d,%d", mac_ptr, ssid, channel, center_freq, signal);
216 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
217 }
218
219 static ssize_t slsi_procfs_big_data_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
220 {
221 char buf[100];
222 int pos;
223 const size_t bufsz = sizeof(buf);
224 struct slsi_dev *sdev = (struct slsi_dev *)file->private_data;
225 struct net_device *dev;
226 struct netdev_vif *ndev_vif;
227
228 SLSI_UNUSED_PARAMETER(file);
229 dev = slsi_get_netdev(sdev, 1);
230 if (!dev)
231 goto exit;
232
233 ndev_vif = netdev_priv(dev);
234
235 exit:
236 pos = slsi_get_sta_info(dev, buf, bufsz);
237 if (pos >= 0)
238 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
239 return 0;
240 }
241
242 static int slsi_procfs_status_show(struct seq_file *m, void *v)
243 {
244 struct slsi_dev *sdev = (struct slsi_dev *)m->private;
245 const char *state;
246 u32 conf_hip4_ver = 0;
247 int i;
248
249 SLSI_UNUSED_PARAMETER(v);
250
251 switch (sdev->device_state) {
252 case SLSI_DEVICE_STATE_ATTACHING:
253 state = "Attaching";
254 break;
255 case SLSI_DEVICE_STATE_STOPPED:
256 state = "Stopped";
257 break;
258 case SLSI_DEVICE_STATE_STARTING:
259 state = "Starting";
260 break;
261 case SLSI_DEVICE_STATE_STARTED:
262 state = "Started";
263 break;
264 case SLSI_DEVICE_STATE_STOPPING:
265 state = "Stopping";
266 break;
267 default:
268 state = "UNKNOWN";
269 break;
270 }
271
272 seq_printf(m, "Driver FAPI Version: MA SAP : %d.%d.%d\n", FAPI_MAJOR_VERSION(FAPI_DATA_SAP_VERSION),
273 FAPI_MINOR_VERSION(FAPI_DATA_SAP_VERSION), FAPI_DATA_SAP_ENG_VERSION);
274 seq_printf(m, "Driver FAPI Version: MLME SAP : %d.%d.%d\n", FAPI_MAJOR_VERSION(FAPI_CONTROL_SAP_VERSION),
275 FAPI_MINOR_VERSION(FAPI_CONTROL_SAP_VERSION), FAPI_CONTROL_SAP_ENG_VERSION);
276 seq_printf(m, "Driver FAPI Version: DEBUG SAP : %d.%d.%d\n", FAPI_MAJOR_VERSION(FAPI_DEBUG_SAP_VERSION),
277 FAPI_MINOR_VERSION(FAPI_DEBUG_SAP_VERSION), FAPI_DEBUG_SAP_ENG_VERSION);
278 seq_printf(m, "Driver FAPI Version: TEST SAP : %d.%d.%d\n", FAPI_MAJOR_VERSION(FAPI_TEST_SAP_VERSION),
279 FAPI_MINOR_VERSION(FAPI_TEST_SAP_VERSION), FAPI_TEST_SAP_ENG_VERSION);
280
281 if (atomic_read(&sdev->hip.hip_state) == SLSI_HIP_STATE_STARTED) {
282 conf_hip4_ver = scsc_wifi_get_hip_config_version(&sdev->hip4_inst.hip_control->init);
283 seq_printf(m, "HIP4 Version : %d\n", conf_hip4_ver);
284 if (conf_hip4_ver == 4) {
285 seq_printf(m, "Chip FAPI Version (v4): MA SAP : %d.%d\n",
286 FAPI_MAJOR_VERSION(scsc_wifi_get_hip_config_version_4_u16(&sdev->hip4_inst.hip_control->config_v4, sap_ma_ver)),
287 FAPI_MINOR_VERSION(scsc_wifi_get_hip_config_version_4_u16(&sdev->hip4_inst.hip_control->config_v4, sap_ma_ver)));
288 seq_printf(m, "Chip FAPI Version (v4): MLME SAP : %d.%d\n",
289 FAPI_MAJOR_VERSION(scsc_wifi_get_hip_config_version_4_u16(&sdev->hip4_inst.hip_control->config_v4, sap_mlme_ver)),
290 FAPI_MINOR_VERSION(scsc_wifi_get_hip_config_version_4_u16(&sdev->hip4_inst.hip_control->config_v4, sap_mlme_ver)));
291 seq_printf(m, "Chip FAPI Version (v4): DEBUG SAP : %d.%d\n",
292 FAPI_MAJOR_VERSION(scsc_wifi_get_hip_config_version_4_u16(&sdev->hip4_inst.hip_control->config_v4, sap_debug_ver)),
293 FAPI_MINOR_VERSION(scsc_wifi_get_hip_config_version_4_u16(&sdev->hip4_inst.hip_control->config_v4, sap_debug_ver)));
294 seq_printf(m, "Chip FAPI Version (v4): TEST SAP : %d.%d\n",
295 FAPI_MAJOR_VERSION(scsc_wifi_get_hip_config_version_4_u16(&sdev->hip4_inst.hip_control->config_v4, sap_test_ver)),
296 FAPI_MINOR_VERSION(scsc_wifi_get_hip_config_version_4_u16(&sdev->hip4_inst.hip_control->config_v4, sap_test_ver)));
297 } else if (conf_hip4_ver == 5) {
298 seq_printf(m, "Chip FAPI Version (v5): MA SAP : %d.%d\n",
299 FAPI_MAJOR_VERSION(scsc_wifi_get_hip_config_version_5_u16(&sdev->hip4_inst.hip_control->config_v5, sap_ma_ver)),
300 FAPI_MINOR_VERSION(scsc_wifi_get_hip_config_version_5_u16(&sdev->hip4_inst.hip_control->config_v5, sap_ma_ver)));
301 seq_printf(m, "Chip FAPI Version (v5): MLME SAP : %d.%d\n",
302 FAPI_MAJOR_VERSION(scsc_wifi_get_hip_config_version_5_u16(&sdev->hip4_inst.hip_control->config_v5, sap_mlme_ver)),
303 FAPI_MINOR_VERSION(scsc_wifi_get_hip_config_version_5_u16(&sdev->hip4_inst.hip_control->config_v5, sap_mlme_ver)));
304 seq_printf(m, "Chip FAPI Version (v5): DEBUG SAP : %d.%d\n",
305 FAPI_MAJOR_VERSION(scsc_wifi_get_hip_config_version_5_u16(&sdev->hip4_inst.hip_control->config_v5, sap_debug_ver)),
306 FAPI_MINOR_VERSION(scsc_wifi_get_hip_config_version_5_u16(&sdev->hip4_inst.hip_control->config_v5, sap_debug_ver)));
307 seq_printf(m, "Chip FAPI Version (v5): TEST SAP : %d.%d\n",
308 FAPI_MAJOR_VERSION(scsc_wifi_get_hip_config_version_5_u16(&sdev->hip4_inst.hip_control->config_v5, sap_test_ver)),
309 FAPI_MINOR_VERSION(scsc_wifi_get_hip_config_version_5_u16(&sdev->hip4_inst.hip_control->config_v5, sap_test_ver)));
310 }
311 }
312
313 #ifdef CONFIG_SCSC_WLAN_DEBUG
314 seq_puts(m, "Driver Debug : Enabled\n");
315 #else
316 seq_puts(m, "Driver Debug : Disabled\n");
317 #endif
318 seq_printf(m, "Driver State : %s\n", state);
319
320 seq_printf(m, "HW Version [MIB] : 0x%.4X (%u)\n", sdev->chip_info_mib.chip_version, sdev->chip_info_mib.chip_version);
321 seq_printf(m, "Platform Build [MIB] : 0x%.4X (%u)\n", sdev->plat_info_mib.plat_build, sdev->plat_info_mib.plat_build);
322 for (i = 0; i < SLSI_WLAN_MAX_MIB_FILE; i++) {
323 seq_printf(m, "Hash [MIB%2d] : 0x%.4X (%u)\n", i, sdev->mib[i].mib_hash, sdev->mib[i].mib_hash);
324 seq_printf(m, "Platform: [MIB%2d] : %s\n", i, sdev->mib[i].platform);
325 }
326 seq_printf(m, "Hash [local_MIB] : 0x%.4X (%u)\n", sdev->local_mib.mib_hash, sdev->local_mib.mib_hash);
327 seq_printf(m, "Platform: [local_MIB] : %s\n", sdev->local_mib.platform);
328
329 return 0;
330 }
331
332 static int slsi_procfs_build_show(struct seq_file *m, void *v)
333 {
334 SLSI_UNUSED_PARAMETER(v);
335 seq_printf(m, "FAPI_DATA_SAP_VERSION : %d.%d.%d\n",
336 FAPI_MAJOR_VERSION(FAPI_DATA_SAP_VERSION),
337 FAPI_MINOR_VERSION(FAPI_DATA_SAP_VERSION),
338 FAPI_DATA_SAP_ENG_VERSION);
339 seq_printf(m, "FAPI_CONTROL_SAP_VERSION : %d.%d.%d\n",
340 FAPI_MAJOR_VERSION(FAPI_CONTROL_SAP_VERSION),
341 FAPI_MINOR_VERSION(FAPI_CONTROL_SAP_VERSION),
342 FAPI_CONTROL_SAP_ENG_VERSION);
343 seq_printf(m, "FAPI_DEBUG_SAP_VERSION : %d.%d.%d\n",
344 FAPI_MAJOR_VERSION(FAPI_DEBUG_SAP_VERSION),
345 FAPI_MINOR_VERSION(FAPI_DEBUG_SAP_VERSION),
346 FAPI_DEBUG_SAP_ENG_VERSION);
347 seq_printf(m, "FAPI_TEST_SAP_VERSION : %d.%d.%d\n",
348 FAPI_MAJOR_VERSION(FAPI_TEST_SAP_VERSION),
349 FAPI_MINOR_VERSION(FAPI_TEST_SAP_VERSION),
350 FAPI_TEST_SAP_ENG_VERSION);
351 seq_printf(m, "CONFIG_SCSC_WLAN_MAX_INTERFACES : %d\n", CONFIG_SCSC_WLAN_MAX_INTERFACES);
352 #ifdef CONFIG_SCSC_WLAN_RX_NAPI
353 seq_puts(m, "CONFIG_SCSC_WLAN_RX_NAPI : y\n");
354 #else
355 seq_puts(m, "CONFIG_SCSC_WLAN_RX_NAPI : n\n");
356 #endif
357 #ifdef CONFIG_SCSC_WLAN_RX_NAPI_GRO
358 seq_puts(m, "CONFIG_SCSC_WLAN_RX_NAPI_GRO : y\n");
359 #else
360 seq_puts(m, "CONFIG_SCSC_WLAN_RX_NAPI_GRO : n\n");
361 #endif
362 #ifdef CONFIG_SCSC_WLAN_ANDROID
363 seq_puts(m, "CONFIG_SCSC_WLAN_ANDROID : y\n");
364 #else
365 seq_puts(m, "CONFIG_SCSC_WLAN_ANDROID : n\n");
366 #endif
367 #ifdef CONFIG_SCSC_WLAN_GSCAN_ENABLE
368 seq_puts(m, "CONFIG_SCSC_WLAN_GSCAN_ENABLE : y\n");
369 #else
370 seq_puts(m, "CONFIG_SCSC_WLAN_GSCAN_ENABLE : n\n");
371 #endif
372 #ifdef CONFIG_SCSC_WLAN_KEY_MGMT_OFFLOAD
373 seq_puts(m, "CONFIG_SCSC_WLAN_KEY_MGMT_OFFLOAD : y\n");
374 #else
375 seq_puts(m, "CONFIG_SCSC_WLAN_KEY_MGMT_OFFLOAD : n\n");
376 #endif
377 #ifdef CONFIG_SCSC_WLAN_PRIORITISE_IMP_FRAMES
378 seq_puts(m, "CONFIG_SCSC_WLAN_PRIORITISE_IMP_FRAMES : y\n");
379 #else
380 seq_puts(m, "CONFIG_SCSC_WLAN_PRIORITISE_IMP_FRAMES : n\n");
381 #endif
382 seq_puts(m, "-------------------------------------------------\n");
383 #ifdef CONFIG_SCSC_WLAN_DEBUG
384 seq_puts(m, "CONFIG_SCSC_WLAN_DEBUG : y\n");
385 #else
386 seq_puts(m, "CONFIG_SCSC_WLAN_DEBUG : n\n");
387 #endif
388 #ifdef CONFIG_SCSC_WLAN_SKB_TRACKING
389 seq_puts(m, "CONFIG_SCSC_WLAN_SKB_TRACKING : y\n");
390 #else
391 seq_puts(m, "CONFIG_SCSC_WLAN_SKB_TRACKING : n\n");
392 #endif
393 #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG
394 seq_puts(m, "CONFIG_SCSC_WLAN_MUTEX_DEBUG : y\n");
395 #else
396 seq_puts(m, "CONFIG_SCSC_WLAN_MUTEX_DEBUG : n\n");
397 #endif
398 #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING
399 seq_puts(m, "CONFIG_SCSC_WLAN_ENHANCED_LOGGING : y\n");
400 #else
401 seq_puts(m, "CONFIG_SCSC_WLAN_ENHANCED_LOGGING : n\n");
402 #endif
403 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
404 seq_puts(m, "CONFIG_SCSC_WLAN_WIFI_SHARING : y\n");
405 #else
406 seq_puts(m, "CONFIG_SCSC_WLAN_WIFI_SHARING : n\n");
407 #endif
408 #ifdef CONFIG_SCSC_WLAN_SINGLE_ANTENNA
409 seq_puts(m, "CONFIG_SCSC_WLAN_SINGLE_ANTENNA : y\n");
410 #else
411 seq_puts(m, "CONFIG_SCSC_WLAN_SINGLE_ANTENNA : n\n");
412 #endif
413 #ifdef CONFIG_SCSC_AP_INTERFACE_NAME
414 seq_printf(m, "CONFIG_SCSC_AP_INTERFACE_NAME : %s\n", CONFIG_SCSC_AP_INTERFACE_NAME);
415 #endif
416 #ifdef CONFIG_SCSC_WIFI_NAN_ENABLE
417 seq_puts(m, "CONFIG_SCSC_WIFI_NAN_ENABLE : y\n");
418 #else
419 seq_puts(m, "CONFIG_SCSC_WIFI_NAN_ENABLE : n\n");
420 #endif
421 #ifdef CONFIG_SCSC_WLAN_SET_PREFERRED_ANTENNA
422 seq_puts(m, "CONFIG_SCSC_WLAN_SET_PREFERRED_ANTENNA : y\n");
423 #else
424 seq_puts(m, "CONFIG_SCSC_WLAN_SET_PREFERRED_ANTENNA : n\n");
425 #endif
426 #ifdef CONFIG_SLSI_WLAN_STA_FWD_BEACON
427 seq_puts(m, "CONFIG_SLSI_WLAN_STA_FWD_BEACON : y\n");
428 #else
429 seq_puts(m, "CONFIG_SLSI_WLAN_STA_FWD_BEACON : n\n");
430 #endif
431 #ifdef CONFIG_SCSC_WLAN_STA_ENHANCED_ARP_DETECT
432 seq_puts(m, "CONFIG_SCSC_WLAN_STA_ENHANCED_ARP_DETECT : y\n");
433 #else
434 seq_puts(m, "CONFIG_SCSC_WLAN_STA_ENHANCED_ARP_DETECT : n\n");
435 #endif
436
437 return 0;
438 }
439
440 static const char *slsi_procfs_vif_type_to_str(u16 type)
441 {
442 switch (type) {
443 case FAPI_VIFTYPE_STATION:
444 return "STATION";
445 case FAPI_VIFTYPE_AP:
446 return "AP";
447 case FAPI_VIFTYPE_UNSYNCHRONISED:
448 return "UNSYNCH";
449 default:
450 return "?";
451 }
452 }
453
454 static int slsi_procfs_vifs_show(struct seq_file *m, void *v)
455 {
456 struct slsi_dev *sdev = (struct slsi_dev *)m->private;
457 u16 vif;
458 u16 peer_index;
459
460 SLSI_UNUSED_PARAMETER(v);
461
462 SLSI_MUTEX_LOCK(sdev->netdev_add_remove_mutex);
463 for (vif = 1; vif <= CONFIG_SCSC_WLAN_MAX_INTERFACES; vif++) {
464 struct net_device *dev = slsi_get_netdev_locked(sdev, vif);
465 struct netdev_vif *ndev_vif;
466
467 if (!dev)
468 continue;
469
470 ndev_vif = netdev_priv(dev);
471 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
472
473 if (!ndev_vif->activated) {
474 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
475 continue;
476 }
477 seq_printf(m, "vif:%d %pM %s\n", vif, dev->dev_addr, slsi_procfs_vif_type_to_str(ndev_vif->vif_type));
478 for (peer_index = 0; peer_index < SLSI_ADHOC_PEER_CONNECTIONS_MAX; peer_index++) {
479 struct slsi_peer *peer = ndev_vif->peer_sta_record[peer_index];
480
481 if (peer && peer->valid)
482 seq_printf(m, "vif:%d %pM peer[%d] %pM\n", vif, dev->dev_addr, peer_index, peer->address);
483 }
484 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
485 }
486 SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex);
487
488 return 0;
489 }
490
491 static ssize_t slsi_procfs_read_int(struct file *file, char __user *user_buf, size_t count, loff_t *ppos, int value, const char *extra)
492 {
493 char buf[128];
494 int pos = 0;
495 const size_t bufsz = sizeof(buf);
496
497 SLSI_UNUSED_PARAMETER(file);
498
499 pos += scnprintf(buf + pos, bufsz - pos, "%d\n", value);
500 if (extra)
501 pos += scnprintf(buf + pos, bufsz - pos, "%s", extra);
502 SLSI_INFO((struct slsi_dev *)file->private_data, "%s", buf);
503 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
504 }
505
506 static ssize_t slsi_procfs_uapsd_write(struct file *file,
507 const char __user *user_buf,
508 size_t count, loff_t *ppos)
509 {
510 struct slsi_dev *sdev = file->private_data;
511 struct net_device *dev = NULL;
512 struct netdev_vif *ndev_vif = NULL;
513 int qos_info = 0;
514 int offset = 0;
515 char *read_string;
516
517 dev = slsi_get_netdev(sdev, SLSI_NET_INDEX_WLAN);
518
519 if (!dev) {
520 SLSI_ERR(sdev, "Dev not found\n");
521 return -EINVAL;
522 }
523
524 ndev_vif = netdev_priv(dev);
525
526 if (!count)
527 return -EINVAL;
528
529 read_string = kmalloc(count + 1, GFP_KERNEL);
530 memset(read_string, 0, (count + 1));
531
532 simple_write_to_buffer(read_string, count, ppos, user_buf, count);
533 read_string[count] = '\0';
534
535 offset = slsi_str_to_int(read_string, &qos_info);
536 if (!offset) {
537 SLSI_ERR(sdev, "qos info : failed to read a numeric value");
538 kfree(read_string);
539 return -EINVAL;
540 }
541
542 /*Store the qos info and use it to set MIB during connection*/
543 sdev->device_config.qos_info = qos_info;
544 SLSI_DBG1(sdev, SLSI_MLME, "set qos_info:%d\n", sdev->device_config.qos_info);
545
546
547 kfree(read_string);
548 return count;
549 }
550
551 static ssize_t slsi_procfs_ap_cert_disable_ht_vht_write(struct file *file, const char __user *user_buf,
552 size_t count, loff_t *ppos)
553 {
554 struct slsi_dev *sdev = file->private_data;
555 int offset = 0;
556 int width = 0;
557 char *read_string;
558
559 if (!count)
560 return -EINVAL;
561
562 read_string = kmalloc(count + 1, GFP_KERNEL);
563 memset(read_string, 0, (count + 1));
564
565 simple_write_to_buffer(read_string, count, ppos, user_buf, count);
566 read_string[count] = '\0';
567
568 offset = slsi_str_to_int(read_string, &width);
569 if (!offset) {
570 SLSI_ERR(sdev, "Failed to read a numeric value");
571 kfree(read_string);
572 return -EINVAL;
573 }
574
575 /* Disable default upgrade of corresponding width during AP start */
576 if (width == 80)
577 sdev->allow_switch_80_mhz = false;
578 else if (width == 40)
579 sdev->allow_switch_40_mhz = false;
580
581 kfree(read_string);
582 return count;
583 }
584
585 static ssize_t slsi_procfs_p2p_certif_write(struct file *file,
586 const char __user *user_buf,
587 size_t count, loff_t *ppos)
588 {
589 struct slsi_dev *sdev = file->private_data;
590 char *read_string;
591 int cert_info = 0;
592 int offset = 0;
593
594 read_string = kmalloc(count + 1, GFP_KERNEL);
595 memset(read_string, 0, (count + 1));
596
597 simple_write_to_buffer(read_string, count, ppos, user_buf, count);
598 read_string[count] = '\0';
599
600 offset = slsi_str_to_int(read_string, &cert_info);
601 if (!offset) {
602 SLSI_ERR(sdev, "qos info : failed to read a numeric value");
603 kfree(read_string);
604 return -EINVAL;
605 }
606 sdev->p2p_certif = cert_info;
607 kfree(read_string);
608 return count;
609 }
610
611 static ssize_t slsi_procfs_p2p_certif_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
612 {
613 struct slsi_dev *sdev = file->private_data;
614 char buf[128];
615 int pos = 0;
616 const size_t bufsz = sizeof(buf);
617
618 SLSI_UNUSED_PARAMETER(file);
619
620 pos += scnprintf(buf + pos, bufsz - pos, "%d\n", sdev->p2p_certif);
621
622 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
623 }
624
625 static int slsi_procfs_mac_addr_show(struct seq_file *m, void *v)
626 {
627 struct slsi_dev *sdev = (struct slsi_dev *)m->private;
628
629 SLSI_UNUSED_PARAMETER(v);
630
631 seq_printf(m, "%pM", sdev->hw_addr);
632 return 0;
633 }
634
635 static ssize_t slsi_procfs_create_tspec_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
636 {
637 struct slsi_dev *sdev = file->private_data;
638 static const char *extra_info = "";
639
640 return slsi_procfs_read_int(file, user_buf, count, ppos, sdev->current_tspec_id, extra_info);
641 }
642
643 static ssize_t slsi_procfs_create_tspec_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos)
644 {
645 struct slsi_dev *sfdev = (struct slsi_dev *)file->private_data;
646 char *read_string = kmalloc(count + 1, GFP_KERNEL);
647
648 if (!read_string) {
649 SLSI_ERR(sfdev, "Malloc for read_string failed\n");
650 return -ENOMEM;
651 }
652
653 if (!count) {
654 kfree(read_string);
655 return 0;
656 }
657
658 simple_write_to_buffer(read_string, count, ppos, user_buf, count);
659 read_string[count] = '\0';
660
661 sfdev->current_tspec_id = cac_ctrl_create_tspec(sfdev, read_string);
662 if (sfdev->current_tspec_id < 0) {
663 SLSI_ERR(sfdev, "create tspec: No parameters or not valid parameters\n");
664 kfree(read_string);
665 return -EINVAL;
666 }
667 kfree(read_string);
668
669 return count;
670 }
671
672 static ssize_t slsi_procfs_confg_tspec_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
673 {
674 static const char *extra_info = "Not implemented yet";
675 int value = 10;
676
677 return slsi_procfs_read_int(file, user_buf, count, ppos, value, extra_info);
678 }
679
680 static ssize_t slsi_procfs_confg_tspec_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos)
681 {
682 struct slsi_dev *sfdev = (struct slsi_dev *)file->private_data;
683 char *read_string = kmalloc(count + 1, GFP_KERNEL);
684
685 if (!read_string) {
686 SLSI_ERR(sfdev, "Malloc for read_string failed\n");
687 return -ENOMEM;
688 }
689
690 if (!count) {
691 kfree(read_string);
692 return 0;
693 }
694
695 simple_write_to_buffer(read_string, count, ppos, user_buf, count);
696 read_string[count] = '\0';
697
698 /* to do: call to config_tspec() to configure a tspec field */
699 if (cac_ctrl_config_tspec(sfdev, read_string) < 0) {
700 SLSI_ERR(sfdev, "config tspec error\n");
701 kfree(read_string);
702 return -EINVAL;
703 }
704
705 kfree(read_string);
706
707 return count;
708 }
709
710 static ssize_t slsi_procfs_send_addts_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
711 {
712 struct slsi_dev *sdev = file->private_data;
713 static const char *extra_info = "";
714
715 return slsi_procfs_read_int(file, user_buf, count, ppos, sdev->tspec_error_code, extra_info);
716 }
717
718 static ssize_t slsi_procfs_send_addts_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos)
719 {
720 struct slsi_dev *sfdev = (struct slsi_dev *)file->private_data;
721 char *read_string = kmalloc(count + 1, GFP_KERNEL);
722
723 if (!read_string) {
724 SLSI_ERR(sfdev, "Malloc for read_string failed\n");
725 return -ENOMEM;
726 }
727
728 sfdev->tspec_error_code = -1;
729 if (!count) {
730 kfree(read_string);
731 return 0;
732 }
733
734 simple_write_to_buffer(read_string, count, ppos, user_buf, count);
735 read_string[count] = '\0';
736
737 /* to do: call to config_tspec() to configure a tspec field */
738 if (cac_ctrl_send_addts(sfdev, read_string) < 0) {
739 SLSI_ERR(sfdev, "send addts error\n");
740 kfree(read_string);
741 return -EINVAL;
742 }
743 kfree(read_string);
744 return count;
745 }
746
747 static ssize_t slsi_procfs_send_delts_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
748 {
749 struct slsi_dev *sdev = file->private_data;
750 static const char *extra_info = "";
751
752 return slsi_procfs_read_int(file, user_buf, count, ppos, sdev->tspec_error_code, extra_info);
753 }
754
755 static ssize_t slsi_procfs_send_delts_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos)
756 {
757 struct slsi_dev *sfdev = (struct slsi_dev *)file->private_data;
758 char *read_string = kmalloc(count + 1, GFP_KERNEL);
759
760 if (!read_string) {
761 SLSI_ERR(sfdev, "Malloc for read_string failed\n");
762 return -ENOMEM;
763 }
764
765 sfdev->tspec_error_code = -1;
766
767 if (!count) {
768 kfree(read_string);
769 return 0;
770 }
771
772 simple_write_to_buffer(read_string, count, ppos, user_buf, count);
773 read_string[count] = '\0';
774
775 /* to do: call to config_tspec() to configure a tspec field */
776 if (cac_ctrl_send_delts(sfdev, read_string) < 0) {
777 SLSI_ERR(sfdev, "send delts error\n");
778 kfree(read_string);
779 return -EINVAL;
780 }
781 kfree(read_string);
782 return count;
783 }
784
785 static ssize_t slsi_procfs_del_tspec_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
786 {
787 static const char *extra_info = "Not implemented yet";
788 int value = 10;
789
790 return slsi_procfs_read_int(file, user_buf, count, ppos, value, extra_info);
791 }
792
793 static ssize_t slsi_procfs_del_tspec_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos)
794 {
795 struct slsi_dev *sfdev = (struct slsi_dev *)file->private_data;
796 char *read_string = kmalloc(count + 1, GFP_KERNEL);
797
798 if (!read_string) {
799 SLSI_ERR(sfdev, "Malloc for read_string failed\n");
800 return -ENOMEM;
801 }
802
803 if (!count) {
804 kfree(read_string);
805 return 0;
806 }
807
808 simple_write_to_buffer(read_string, count, ppos, user_buf, count);
809 read_string[count] = '\0';
810
811 /* to do: call to config_tspec() to configure a tspec field */
812 if (cac_ctrl_delete_tspec(sfdev, read_string) < 0) {
813 SLSI_ERR(sfdev, "config tspec error\n");
814 kfree(read_string);
815 return -EINVAL;
816 }
817 kfree(read_string);
818 return count;
819 }
820
821 static ssize_t slsi_procfs_tput_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
822 {
823 struct slsi_dev *sdev = (struct slsi_dev *)file->private_data;
824 struct net_device *dev;
825 struct netdev_vif *ndev_vif;
826 int i;
827 char buf[256];
828 int pos = 0;
829 const size_t bufsz = sizeof(buf);
830
831 SLSI_MUTEX_LOCK(sdev->netdev_add_remove_mutex);
832 for (i = 1; i <= CONFIG_SCSC_WLAN_MAX_INTERFACES; i++) {
833 dev = sdev->netdev[i];
834 if (dev) {
835 ndev_vif = netdev_priv(dev);
836 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t", dev->name);
837 if (ndev_vif->throughput_tx_bps < 1000)
838 pos += scnprintf(buf + pos, bufsz - pos, "TX:%u bps\t", ndev_vif->throughput_tx_bps);
839 else if ((ndev_vif->throughput_tx_bps >= 1000) && (ndev_vif->throughput_tx_bps < (1000 * 1000)))
840 pos += scnprintf(buf + pos, bufsz - pos, "TX:%u Kbps\t", (ndev_vif->throughput_tx_bps / 1000));
841 else
842 pos += scnprintf(buf + pos, bufsz - pos, "TX:%u Mbps\t", (ndev_vif->throughput_tx_bps / (1000 * 1000)));
843
844 if (ndev_vif->throughput_rx_bps < 1000)
845 pos += scnprintf(buf + pos, bufsz - pos, "RX:%u bps\n", ndev_vif->throughput_rx_bps);
846 else if ((ndev_vif->throughput_rx_bps >= 1000) && (ndev_vif->throughput_rx_bps < (1000 * 1000)))
847 pos += scnprintf(buf + pos, bufsz - pos, "RX:%u Kbps\n", (ndev_vif->throughput_rx_bps / 1000));
848 else
849 pos += scnprintf(buf + pos, bufsz - pos, "RX:%u Mbps\n", (ndev_vif->throughput_rx_bps / (1000 * 1000)));
850 }
851 }
852 SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex);
853 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
854 }
855
856 static ssize_t slsi_procfs_tput_write(struct file *file, const char __user *user_buf, size_t len, loff_t *ppos)
857 {
858 struct slsi_dev *sdev = (struct slsi_dev *)file->private_data;
859 char read_buf[2];
860
861 if (!sdev) {
862 SLSI_ERR(sdev, "invalid sdev\n");
863 return -ENOMEM;
864 }
865
866 if (!len || (len > sizeof(read_buf))) {
867 SLSI_ERR(sdev, "invalid len\n");
868 return -EINVAL;
869 }
870
871 simple_write_to_buffer(read_buf, len, ppos, user_buf, len);
872
873 switch (read_buf[0]) {
874 case '1':
875 if (!slsi_traffic_mon_is_running(sdev)) {
876 SLSI_DBG1(sdev, SLSI_HIP, "start Traffic monitor\n");
877 slsi_traffic_mon_client_register(sdev, sdev, 0, 0, 0, NULL);
878 }
879 break;
880 case '0':
881 SLSI_DBG1(sdev, SLSI_HIP, "stop Traffic monitor\n");
882 slsi_traffic_mon_client_unregister(sdev, sdev);
883 break;
884 default:
885 SLSI_DBG1(sdev, SLSI_HIP, "invalid value %c\n", read_buf[0]);
886 return -EINVAL;
887 }
888 return len;
889 }
890
891 static atomic_t fd_opened_count;
892
893 void slsi_procfs_inc_node(void)
894 {
895 atomic_inc(&fd_opened_count);
896 }
897
898 void slsi_procfs_dec_node(void)
899 {
900 if (0 == atomic_read(&fd_opened_count)) {
901 WARN_ON(1);
902 return;
903 }
904 atomic_dec(&fd_opened_count);
905 }
906
907 static ssize_t slsi_procfs_fd_opened_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
908 {
909 char buf[128];
910 int pos = 0;
911 const size_t bufsz = sizeof(buf);
912
913 SLSI_UNUSED_PARAMETER(file);
914
915 pos += scnprintf(buf + pos, bufsz - pos, "%d\n", atomic_read(&fd_opened_count));
916
917 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
918 }
919
920 static int slsi_procfs_fcq_show(struct seq_file *m, void *v)
921 {
922 struct slsi_dev *sdev = (struct slsi_dev *)m->private;
923 int ac;
924 s32 vif, i;
925
926 SLSI_UNUSED_PARAMETER(v);
927
928 SLSI_MUTEX_LOCK(sdev->netdev_add_remove_mutex);
929 for (vif = 1; vif <= CONFIG_SCSC_WLAN_MAX_INTERFACES; vif++) {
930 struct net_device *dev = slsi_get_netdev_locked(sdev, vif);
931 struct netdev_vif *ndev_vif;
932
933 if (!dev)
934 continue;
935
936 ndev_vif = netdev_priv(dev);
937 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
938
939 /* Unicast */
940 for (i = 0; i < SLSI_ADHOC_PEER_CONNECTIONS_MAX; i++) {
941 struct slsi_peer *peer = ndev_vif->peer_sta_record[i];
942 int smod = 0, scod = 0, qmod = 0, qcod = 0;
943 struct scsc_wifi_fcq_q_stat queue_stat;
944 u32 peer_ps_state_transitions = 0;
945 enum scsc_wifi_fcq_8021x_state cp_state;
946
947 if (!peer || !peer->valid)
948 continue;
949
950 if (scsc_wifi_fcq_stat_queueset(&peer->data_qs, &queue_stat, &smod, &scod, &cp_state, &peer_ps_state_transitions) != 0)
951 continue;
952
953 seq_printf(m, "|%-12s|%-6d|%-6s|\n%d). peer:%pM, qs:%2d, smod:%u, scod:%u, netq stops :%u, netq resumes :%u, PS transitions :%u Controlled port :%s\n",
954 netdev_name(dev),
955 vif,
956 "UCAST",
957 i + 1,
958 peer->address,
959 peer->queueset,
960 smod,
961 scod,
962 queue_stat.netq_stops,
963 queue_stat.netq_resumes,
964 peer_ps_state_transitions,
965 cp_state == SCSC_WIFI_FCQ_8021x_STATE_BLOCKED ? "Blocked" : "Opened");
966
967 seq_printf(m, " |%-12s|%-17s|%4s|%8s|%8s|%8s|%8s|%10s|%8s|\n",
968 "netdev",
969 "peer",
970 "AC index", "qcod", "qmod",
971 "nq_state", "nq_stop", "nq_resume",
972 "tq_state");
973
974 for (ac = 0; ac < SLSI_NETIF_Q_PER_PEER; ac++) {
975 if (scsc_wifi_fcq_stat_queue(&peer->data_qs.ac_q[ac].head,
976 &queue_stat,
977 &qmod, &qcod) == 0)
978 seq_printf(m, " |%-12s|%pM|%4d|%8u|%8u|%8u|%8u\n",
979 netdev_name(dev),
980 peer->address,
981 ac,
982 qcod,
983 qmod,
984 queue_stat.netq_stops,
985 queue_stat.netq_resumes);
986 else
987 break;
988 }
989 }
990
991 /* Groupcast */
992 if (ndev_vif->vif_type == FAPI_VIFTYPE_AP) {
993 int smod = 0, scod = 0, qmod = 0, qcod = 0;
994 struct scsc_wifi_fcq_q_stat queue_stat;
995 u32 peer_ps_state_transitions = 0;
996 enum scsc_wifi_fcq_8021x_state cp_state;
997
998 if (scsc_wifi_fcq_stat_queueset(&ndev_vif->ap.group_data_qs, &queue_stat, &smod, &scod, &cp_state, &peer_ps_state_transitions) != 0)
999 continue;
1000
1001 seq_printf(m, "|%-12s|%-6d|%-6s|\n%d). smod:%u, scod:%u, netq stops :%u, netq resumes :%u, PS transitions :%u Controlled port :%s\n",
1002 netdev_name(dev),
1003 vif,
1004 "MCAST",
1005 i + 1,
1006 smod,
1007 scod,
1008 queue_stat.netq_stops,
1009 queue_stat.netq_resumes,
1010 peer_ps_state_transitions,
1011 cp_state == SCSC_WIFI_FCQ_8021x_STATE_BLOCKED ? "Blocked" : "Opened");
1012
1013 seq_printf(m, " |%-12s|%4s|%8s|%8s|%8s|%8s|%10s|%8s|\n",
1014 "netdev",
1015 "AC index", "qcod", "qmod",
1016 "nq_state", "nq_stop", "nq_resume",
1017 "tq_state");
1018
1019 for (ac = 0; ac < SLSI_NETIF_Q_PER_PEER; ac++) {
1020 if (scsc_wifi_fcq_stat_queue(&ndev_vif->ap.group_data_qs.ac_q[ac].head,
1021 &queue_stat,
1022 &qmod, &qcod) == 0)
1023 seq_printf(m, " |%-12s|%4d|%8u|%8u|%8u|%8u\n",
1024 netdev_name(dev),
1025 ac,
1026 qcod,
1027 qmod,
1028 queue_stat.netq_stops,
1029 queue_stat.netq_resumes);
1030 else
1031 break;
1032 }
1033 }
1034 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1035 }
1036
1037 SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex);
1038
1039 return 0;
1040 }
1041
1042 static int slsi_procfs_tcp_ack_suppression_show(struct seq_file *m, void *v)
1043 {
1044 struct slsi_dev *sdev = (struct slsi_dev *)m->private;
1045 struct net_device *dev;
1046 struct netdev_vif *ndev_vif;
1047 int i;
1048
1049 SLSI_MUTEX_LOCK(sdev->netdev_add_remove_mutex);
1050 for (i = 1; i <= CONFIG_SCSC_WLAN_MAX_INTERFACES; i++) {
1051 dev = sdev->netdev[i];
1052 if (dev) {
1053 ndev_vif = netdev_priv(dev);
1054
1055 seq_printf(m, "%s: tack_acks=%u\n", dev->name, ndev_vif->tcp_ack_stats.tack_acks);
1056 seq_printf(m, "%s: tack_suppressed=%u\n", dev->name, ndev_vif->tcp_ack_stats.tack_suppressed);
1057 seq_printf(m, "%s: tack_sent=%u\n", dev->name, ndev_vif->tcp_ack_stats.tack_sent);
1058 seq_printf(m, "%s: tack_max=%u\n", dev->name, ndev_vif->tcp_ack_stats.tack_max);
1059 seq_printf(m, "%s: tack_timeout=%u\n", dev->name, ndev_vif->tcp_ack_stats.tack_timeout);
1060 seq_printf(m, "%s: tack_aged=%u\n", dev->name, ndev_vif->tcp_ack_stats.tack_ktime);
1061 seq_printf(m, "%s: tack_dacks=%u\n", dev->name, ndev_vif->tcp_ack_stats.tack_dacks);
1062 seq_printf(m, "%s: tack_sacks=%u\n", dev->name, ndev_vif->tcp_ack_stats.tack_sacks);
1063 seq_printf(m, "%s: tack_delay_acks=%u\n", dev->name, ndev_vif->tcp_ack_stats.tack_delay_acks);
1064 seq_printf(m, "%s: tack_low_window=%u\n", dev->name, ndev_vif->tcp_ack_stats.tack_low_window);
1065 seq_printf(m, "%s: tack_ece=%u\n", dev->name, ndev_vif->tcp_ack_stats.tack_ece);
1066 seq_printf(m, "%s: tack_nocache=%u\n", dev->name, ndev_vif->tcp_ack_stats.tack_nocache);
1067 seq_printf(m, "%s: tack_norecord=%u\n", dev->name, ndev_vif->tcp_ack_stats.tack_norecord);
1068 seq_printf(m, "%s: tack_lastrecord=%u\n", dev->name, ndev_vif->tcp_ack_stats.tack_lastrecord);
1069 seq_printf(m, "%s: tack_searchrecord=%u\n", dev->name, ndev_vif->tcp_ack_stats.tack_searchrecord);
1070 seq_printf(m, "%s: tack_hasdata=%u\n", dev->name, ndev_vif->tcp_ack_stats.tack_hasdata);
1071 seq_printf(m, "%s: tack_psh=%u\n", dev->name, ndev_vif->tcp_ack_stats.tack_psh);
1072 seq_printf(m, "%s: tack_dropped=%u\n", dev->name, ndev_vif->tcp_ack_stats.tack_dropped);
1073
1074 /* reset stats after it is read */
1075 memset(&ndev_vif->tcp_ack_stats, 0, sizeof(struct slsi_tcp_ack_stats));
1076 }
1077 }
1078 SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex);
1079 return 0;
1080 }
1081
1082 static ssize_t slsi_procfs_nan_mac_addr_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
1083 {
1084 char buf[20];
1085 char nan_mac[ETH_ALEN];
1086 int pos = 0;
1087 #ifdef CONFIG_SCSC_WIFI_NAN_ENABLE
1088 struct slsi_dev *sdev = (struct slsi_dev *)file->private_data;
1089
1090 slsi_nan_get_mac(sdev, nan_mac);
1091 #else
1092
1093 SLSI_UNUSED_PARAMETER(file);
1094 memset(nan_mac, 0, ETH_ALEN);
1095 #endif
1096 pos = scnprintf(buf, sizeof(buf), "%pM", nan_mac);
1097 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1098 }
1099
1100 #ifdef CONFIG_SCSC_WIFI_NAN_ENABLE
1101 static ssize_t slsi_procfs_nan_info_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
1102 {
1103 char buf[300];
1104 int pos = 0;
1105 const size_t bufsz = sizeof(buf);
1106 struct slsi_dev *sdev = (struct slsi_dev *)file->private_data;
1107 struct net_device *dev = slsi_nan_get_netdev(sdev);
1108 struct netdev_vif *ndev_vif = netdev_priv(dev);
1109 struct slsi_vif_nan *nan_data;
1110
1111 SLSI_UNUSED_PARAMETER(file);
1112
1113 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1114 nan_data = &ndev_vif->nan;
1115 memset(buf, 0, sizeof(buf));
1116
1117 pos += scnprintf(buf, bufsz, "NANMACADDRESS,");
1118 pos += scnprintf(buf + pos, bufsz - pos, "%pM", nan_data->local_nmi);
1119 pos += scnprintf(buf + pos, bufsz, ",CLUSTERID,");
1120 pos += scnprintf(buf + pos, bufsz - pos, "%pM", nan_data->cluster_id);
1121 pos += scnprintf(buf + pos, bufsz, ",OPERATINGCHANNEL,");
1122 if (nan_data->operating_channel[0])
1123 pos += scnprintf(buf + pos, bufsz - pos, "%d ", nan_data->operating_channel[0]);
1124 if (nan_data->operating_channel[1])
1125 pos += scnprintf(buf + pos, bufsz - pos, "%d", nan_data->operating_channel[1]);
1126 pos += scnprintf(buf + pos, bufsz, ",ROLE,");
1127 pos += scnprintf(buf + pos, bufsz - pos, "%d", nan_data->role);
1128 pos += scnprintf(buf + pos, bufsz, ",STATE,");
1129 pos += scnprintf(buf + pos, bufsz - pos, "%d", nan_data->state);
1130 pos += scnprintf(buf + pos, bufsz, ",MASTERPREFVAL,");
1131 pos += scnprintf(buf + pos, bufsz - pos, "%d", nan_data->master_pref_value);
1132 pos += scnprintf(buf + pos, bufsz, ",AMT,");
1133 pos += scnprintf(buf + pos, bufsz - pos, "%d", nan_data->amt);
1134 pos += scnprintf(buf + pos, bufsz, ",HOPCOUNT,");
1135 pos += scnprintf(buf + pos, bufsz - pos, "%d", nan_data->hopcount);
1136 pos += scnprintf(buf + pos, bufsz, ",NMIRANDOMINTERVAL,");
1137 pos += scnprintf(buf + pos, bufsz - pos, "%d", nan_data->random_mac_interval_sec);
1138
1139 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1140 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1141 }
1142
1143 static ssize_t slsi_procfs_nan_exclude_ipv6_addr_tlv_write(struct file *file, const char __user *user_buf, size_t len,
1144 loff_t *ppos)
1145 {
1146 struct slsi_dev *sdev = (struct slsi_dev *)file->private_data;
1147 struct net_device *dev = slsi_nan_get_netdev(sdev);
1148 struct netdev_vif *ndev_vif = netdev_priv(dev);
1149 char read_string[3];
1150 int val, ret;
1151
1152 simple_write_to_buffer(read_string, sizeof(read_string), ppos, user_buf, sizeof(read_string) - 1);
1153 read_string[sizeof(read_string) - 1] = '\0';
1154
1155 if (strtoint(read_string, &val)) {
1156 SLSI_ERR(sdev, "invalid input %s\n", read_string);
1157 ret = -EINVAL;
1158 } else {
1159 ndev_vif->nan.disable_cluster_merge = val ? 1 : 0;
1160 ret = sizeof(read_string) - 1;
1161 }
1162
1163 kfree(read_string);
1164 return ret;
1165 }
1166
1167 #endif
1168
1169 SLSI_PROCFS_SEQ_FILE_OPS(vifs);
1170 SLSI_PROCFS_SEQ_FILE_OPS(mac_addr);
1171 SLSI_PROCFS_WRITE_FILE_OPS(uapsd);
1172 SLSI_PROCFS_WRITE_FILE_OPS(ap_cert_disable_ht_vht);
1173 SLSI_PROCFS_RW_FILE_OPS(p2p_certif);
1174 SLSI_PROCFS_RW_FILE_OPS(create_tspec);
1175 SLSI_PROCFS_RW_FILE_OPS(confg_tspec);
1176 SLSI_PROCFS_RW_FILE_OPS(send_addts);
1177 SLSI_PROCFS_RW_FILE_OPS(send_delts);
1178 SLSI_PROCFS_RW_FILE_OPS(del_tspec);
1179 SLSI_PROCFS_RW_FILE_OPS(tput);
1180 SLSI_PROCFS_READ_FILE_OPS(fd_opened);
1181 SLSI_PROCFS_SEQ_FILE_OPS(build);
1182 SLSI_PROCFS_SEQ_FILE_OPS(status);
1183 SLSI_PROCFS_SEQ_FILE_OPS(fcq);
1184 #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG
1185 SLSI_PROCFS_READ_FILE_OPS(mutex_stats);
1186 #endif
1187 SLSI_PROCFS_READ_FILE_OPS(sta_bss);
1188 SLSI_PROCFS_READ_FILE_OPS(big_data);
1189 SLSI_PROCFS_READ_FILE_OPS(throughput_stats);
1190 SLSI_PROCFS_SEQ_FILE_OPS(tcp_ack_suppression);
1191 SLSI_PROCFS_READ_FILE_OPS(nan_mac_addr);
1192 #ifdef CONFIG_SCSC_WIFI_NAN_ENABLE
1193 SLSI_PROCFS_READ_FILE_OPS(nan_info);
1194 SLSI_PROCFS_WRITE_FILE_OPS(nan_exclude_ipv6_addr_tlv);
1195 #endif
1196
1197 int slsi_create_proc_dir(struct slsi_dev *sdev)
1198 {
1199 char dir[16];
1200 struct proc_dir_entry *parent;
1201
1202 (void)snprintf(dir, sizeof(dir), "driver/unifi%d", sdev->procfs_instance);
1203 parent = proc_mkdir(dir, NULL);
1204 if (parent) {
1205 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0))
1206 parent->data = sdev;
1207 #endif
1208 sdev->procfs_dir = parent;
1209
1210 SLSI_PROCFS_SEQ_ADD_FILE(sdev, build, parent, S_IRUSR | S_IRGRP | S_IROTH);
1211 SLSI_PROCFS_SEQ_ADD_FILE(sdev, status, parent, S_IRUSR | S_IRGRP | S_IROTH);
1212 SLSI_PROCFS_SEQ_ADD_FILE(sdev, fcq, parent, S_IRUSR | S_IRGRP | S_IROTH);
1213 SLSI_PROCFS_SEQ_ADD_FILE(sdev, vifs, parent, S_IRUSR | S_IRGRP);
1214 SLSI_PROCFS_SEQ_ADD_FILE(sdev, mac_addr, parent, S_IRUSR | S_IRGRP | S_IROTH); /*Add S_IROTH permission so that android settings can access it*/
1215 SLSI_PROCFS_ADD_FILE(sdev, uapsd, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1216 SLSI_PROCFS_ADD_FILE(sdev, ap_cert_disable_ht_vht, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1217 SLSI_PROCFS_ADD_FILE(sdev, p2p_certif, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1218 SLSI_PROCFS_ADD_FILE(sdev, create_tspec, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1219 SLSI_PROCFS_ADD_FILE(sdev, confg_tspec, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1220 SLSI_PROCFS_ADD_FILE(sdev, send_addts, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1221 SLSI_PROCFS_ADD_FILE(sdev, send_delts, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1222 SLSI_PROCFS_ADD_FILE(sdev, del_tspec, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1223 SLSI_PROCFS_ADD_FILE(sdev, tput, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1224 SLSI_PROCFS_ADD_FILE(sdev, fd_opened, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1225 #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG
1226 SLSI_PROCFS_ADD_FILE(sdev, mutex_stats, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1227 #endif
1228 SLSI_PROCFS_ADD_FILE(sdev, sta_bss, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1229 SLSI_PROCFS_ADD_FILE(sdev, big_data, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1230 SLSI_PROCFS_ADD_FILE(sdev, throughput_stats, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1231 SLSI_PROCFS_SEQ_ADD_FILE(sdev, tcp_ack_suppression, sdev->procfs_dir, S_IRUSR | S_IRGRP);
1232 SLSI_PROCFS_ADD_FILE(sdev, nan_mac_addr, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1233 #ifdef CONFIG_SCSC_WIFI_NAN_ENABLE
1234 SLSI_PROCFS_ADD_FILE(sdev, nan_info, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1235 SLSI_PROCFS_ADD_FILE(sdev, nan_exclude_ipv6_addr_tlv, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1236 #endif
1237 return 0;
1238 }
1239
1240 err:
1241 SLSI_DBG1(sdev, SLSI_HIP, "Failure in creation of proc directories\n");
1242 return -EINVAL;
1243 }
1244
1245 void slsi_remove_proc_dir(struct slsi_dev *sdev)
1246 {
1247 if (sdev->procfs_dir) {
1248 char dir[32];
1249
1250 SLSI_PROCFS_REMOVE_FILE(build, sdev->procfs_dir);
1251 SLSI_PROCFS_REMOVE_FILE(release, sdev->procfs_dir);
1252 SLSI_PROCFS_REMOVE_FILE(version, sdev->procfs_dir);
1253 SLSI_PROCFS_REMOVE_FILE(status, sdev->procfs_dir);
1254 SLSI_PROCFS_REMOVE_FILE(vifs, sdev->procfs_dir);
1255 SLSI_PROCFS_REMOVE_FILE(mac_addr, sdev->procfs_dir);
1256 SLSI_PROCFS_REMOVE_FILE(fcq, sdev->procfs_dir);
1257 SLSI_PROCFS_REMOVE_FILE(uapsd, sdev->procfs_dir);
1258 SLSI_PROCFS_REMOVE_FILE(ap_cert_disable_ht_vht, sdev->procfs_dir);
1259 SLSI_PROCFS_REMOVE_FILE(p2p_certif, sdev->procfs_dir);
1260 SLSI_PROCFS_REMOVE_FILE(create_tspec, sdev->procfs_dir);
1261 SLSI_PROCFS_REMOVE_FILE(confg_tspec, sdev->procfs_dir);
1262 SLSI_PROCFS_REMOVE_FILE(send_addts, sdev->procfs_dir);
1263 SLSI_PROCFS_REMOVE_FILE(send_delts, sdev->procfs_dir);
1264 SLSI_PROCFS_REMOVE_FILE(del_tspec, sdev->procfs_dir);
1265 SLSI_PROCFS_REMOVE_FILE(tput, sdev->procfs_dir);
1266 SLSI_PROCFS_REMOVE_FILE(fd_opened, sdev->procfs_dir);
1267 #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG
1268 SLSI_PROCFS_REMOVE_FILE(mutex_stats, sdev->procfs_dir);
1269 #endif
1270 SLSI_PROCFS_REMOVE_FILE(sta_bss, sdev->procfs_dir);
1271 SLSI_PROCFS_REMOVE_FILE(big_data, sdev->procfs_dir);
1272 SLSI_PROCFS_REMOVE_FILE(throughput_stats, sdev->procfs_dir);
1273 SLSI_PROCFS_REMOVE_FILE(tcp_ack_suppression, sdev->procfs_dir);
1274 SLSI_PROCFS_REMOVE_FILE(nan_mac_addr, sdev->procfs_dir);
1275 #ifdef CONFIG_SCSC_WIFI_NAN_ENABLE
1276 SLSI_PROCFS_REMOVE_FILE(nan_info, sdev->procfs_dir);
1277 SLSI_PROCFS_REMOVE_FILE(nan_exclude_ipv6_addr_tlv, sdev->procfs_dir);
1278 #endif
1279
1280 (void)snprintf(dir, sizeof(dir), "driver/unifi%d", sdev->procfs_instance);
1281 remove_proc_entry(dir, NULL);
1282 sdev->procfs_dir = NULL;
1283 }
1284 }