• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Debug code for XRadio drivers
3  *
4  * Copyright (c) 2013
5  * Xradio Technology Co., Ltd. <www.xradiotech.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11 
12 /*Linux version 3.4.0 compilation*/
13 /*#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))*/
14 #include<linux/module.h>
15 /*#endif*/
16 #include <linux/debugfs.h>
17 #include <linux/seq_file.h>
18 #include <linux/rtc.h>
19 #include <linux/time.h>
20 
21 #include "xradio.h"
22 #include "hwio.h"
23 #include "bh.h"
24 #include "debug.h"
25 #ifdef SUPPORT_FW_DBG_INF
26 #include "fw_dbg_inf.h"
27 #endif
28 
29 /*for host debuglevel*/
30 #define XRADIO_DBG_DEFAULT (XRADIO_DBG_ALWY|XRADIO_DBG_ERROR|XRADIO_DBG_WARN)
31 
32 u8 dbg_common  = XRADIO_DBG_DEFAULT;
33 u8 dbg_sbus    = XRADIO_DBG_DEFAULT;
34 u8 dbg_bh      = XRADIO_DBG_DEFAULT;
35 u8 dbg_txrx    = XRADIO_DBG_DEFAULT;
36 u8 dbg_wsm     = XRADIO_DBG_DEFAULT;
37 u8 dbg_sta     = XRADIO_DBG_DEFAULT;
38 u8 dbg_scan    = XRADIO_DBG_DEFAULT;
39 u8 dbg_ap      = XRADIO_DBG_DEFAULT;
40 u8 dbg_pm      = XRADIO_DBG_DEFAULT;
41 u8 dbg_itp     = XRADIO_DBG_DEFAULT;
42 u8 dbg_etf     = XRADIO_DBG_DEFAULT;
43 u8 dbg_logfile = XRADIO_DBG_ERROR;
44 
45 #ifdef ERROR_HANG_DRIVER
46 u8 error_hang_driver;
47 #endif
48 
49 
50 #if (DBG_XRADIO_HIF)
51 u16 hif_test_rw; /*0: nothing to do; 1: write only; 2: write and read*/
52 u16 hif_test_data_mode; /* hif test data mode, such as 0x55, 0xff etc*/
53 u16 hif_test_data_len; /* hif test data len, every data len pre round*/
54 u16 hif_test_data_round;
55 u16 hif_test_oper_delta; /* hif test operation delta time, give more time to analyze data tranx*/
56 #endif
57 
58 #ifdef CONFIG_XRADIO_DEBUGFS
59 /* join_status */
60 static const char *const xradio_debug_join_status[] = {
61 	"passive",
62 	"monitor",
63 	"station",
64 	"access point",
65 };
66 
67 /* WSM_JOIN_PREAMBLE_... */
68 static const char *const xradio_debug_preamble[] = {
69 	"long",
70 	"short",
71 	"long on 1 and 2 Mbps",
72 };
73 
74 static const char *const xradio_debug_fw_types[] = {
75 	"ETF",
76 	"WFM",
77 	"WSM",
78 	"HI test",
79 	"Platform test",
80 };
81 
82 static const char *const xradio_debug_link_id[] = {
83 	"OFF",
84 	"REQ",
85 	"SOFT",
86 	"HARD",
87 };
88 
xradio_debug_mode(int mode)89 static const char *xradio_debug_mode(int mode)
90 {
91 	switch (mode) {
92 	case NL80211_IFTYPE_UNSPECIFIED:
93 		return "unspecified";
94 	case NL80211_IFTYPE_MONITOR:
95 		return "monitor";
96 	case NL80211_IFTYPE_STATION:
97 		return "station";
98 	case NL80211_IFTYPE_ADHOC:
99 		return "ad-hok";
100 	case NL80211_IFTYPE_MESH_POINT:
101 		return "mesh point";
102 	case NL80211_IFTYPE_AP:
103 		return "access point";
104 	case NL80211_IFTYPE_P2P_CLIENT:
105 		return "p2p client";
106 	case NL80211_IFTYPE_P2P_GO:
107 		return "p2p go";
108 	default:
109 		return "unsupported";
110 	}
111 }
112 
xradio_queue_status_show(struct seq_file * seq,struct xradio_queue * q)113 static void xradio_queue_status_show(struct seq_file *seq,
114 				     struct xradio_queue *q)
115 {
116 	int i, if_id;
117 	seq_printf(seq, "Queue       %d:\n", q->queue_id);
118 	seq_printf(seq, "  capacity: %zu\n", q->capacity);
119 	seq_printf(seq, "  queued:   %zu\n", q->num_queued);
120 	seq_printf(seq, "  pending:  %zu\n", q->num_pending);
121 	seq_printf(seq, "  sent:     %zu\n", q->num_sent);
122 	seq_printf(seq, "  locked:   %s\n", q->tx_locked_cnt ? "yes" : "no");
123 	seq_printf(seq, "  overfull: %s\n", q->overfull ? "yes" : "no");
124 	seq_puts(seq, "  link map: 0-> ");
125 	for (if_id = 0; if_id < XRWL_MAX_VIFS; if_id++) {
126 		for (i = 0; i < q->stats->map_capacity; ++i)
127 			seq_printf(seq, "%.2d ", q->link_map_cache[if_id][i]);
128 		seq_printf(seq, "<-%zu\n", q->stats->map_capacity);
129 	}
130 }
131 
xradio_debug_print_map(struct seq_file * seq,struct xradio_vif * priv,const char * label,u32 map)132 static void xradio_debug_print_map(struct seq_file *seq,
133 				   struct xradio_vif *priv,
134 				   const char *label, u32 map)
135 {
136 	int i;
137 	seq_printf(seq, "%s0-> ", label);
138 	for (i = 0; i < priv->hw_priv->tx_queue_stats.map_capacity; ++i)
139 		seq_printf(seq, "%s ", (map & BIT(i)) ? "**" : "..");
140 	seq_printf(seq, "<-%zu\n",
141 		   priv->hw_priv->tx_queue_stats.map_capacity - 1);
142 }
143 
xradio_version_show(struct seq_file * seq,void * v)144 static int xradio_version_show(struct seq_file *seq, void *v)
145 {
146 	struct xradio_common *hw_priv = seq->private;
147 	seq_printf(seq, "Driver Label:%s  %s\n", DRV_VERSION, DRV_BUILDTIME);
148 	seq_printf(seq, "Firmware Label:%s\n", &hw_priv->wsm_caps.fw_label[0]);
149 	return 0;
150 }
151 
xradio_version_open(struct inode * inode,struct file * file)152 static int xradio_version_open(struct inode *inode, struct file *file)
153 {
154 	return single_open(file, &xradio_version_show, inode->i_private);
155 }
156 
157 static const struct file_operations fops_version = {
158 	.open = xradio_version_open,
159 	.read = seq_read,
160 	.llseek = seq_lseek,
161 	.release = single_release,
162 	.owner = THIS_MODULE,
163 };
164 
165 #if (DGB_XRADIO_QC)
xradio_hwinfo_show(struct seq_file * seq,void * v)166 static int xradio_hwinfo_show(struct seq_file *seq, void *v)
167 {
168 	struct xradio_common *hw_priv = seq->private;
169 	u32 hw_arry[8] = { 0 };
170 
171 	wsm_read_mib(hw_priv, WSM_MIB_ID_HW_INFO, (void *)&hw_arry,
172 		     sizeof(hw_arry), 4);
173 
174 	/*
175 	get_random_bytes((u8 *)&hw_arry[0], 8*sizeof(u32));
176 	hw_arry[0] = 0x0B140D4;
177 	hw_arry[1] &= ~0xF803FFFF;
178 	hw_arry[2] &= ~0xC0001FFF;
179 	hw_arry[5] &= ~0xFFFFF000;
180 	hw_arry[7] &= ~0xFFFC07C0;
181 	*/
182 
183 	seq_printf(seq, "0x%08x, 0x%08x, 0x%08x, 0x%08x, "
184 			"0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
185 			hw_arry[0], hw_arry[1], hw_arry[2], hw_arry[3],
186 			hw_arry[4], hw_arry[5], hw_arry[6], hw_arry[7]);
187 	return 0;
188 }
189 
xradio_hwinfo_open(struct inode * inode,struct file * file)190 static int xradio_hwinfo_open(struct inode *inode, struct file *file)
191 {
192 	return single_open(file, &xradio_hwinfo_show, inode->i_private);
193 }
194 
195 static const struct file_operations fops_hwinfo = {
196 	.open = xradio_hwinfo_open,
197 	.read = seq_read,
198 	.llseek = seq_lseek,
199 	.release = single_release,
200 	.owner = THIS_MODULE,
201 };
202 
203 
xradio_temperature_show(struct seq_file * seq,void * v)204 static int xradio_temperature_show(struct seq_file *seq, void *v)
205 {
206 	struct xradio_common *hw_priv = seq->private;
207 	s32 s32tempQ4;
208 
209 	wsm_read_mib(hw_priv, WSM_MIB_ID_GET_TEMPERATURE, (void *)&s32tempQ4,
210 		     sizeof(s32tempQ4), 4);
211 	seq_printf(seq, "%d\n", (s32tempQ4 >> 4));
212 	return 0;
213 }
214 
xradio_temperature_open(struct inode * inode,struct file * file)215 static int xradio_temperature_open(struct inode *inode, struct file *file)
216 {
217 	return single_open(file, &xradio_temperature_show, inode->i_private);
218 }
219 
220 static const struct file_operations fops_temperature = {
221 	.open = xradio_temperature_open,
222 	.read = seq_read,
223 	.llseek = seq_lseek,
224 	.release = single_release,
225 	.owner = THIS_MODULE,
226 };
227 #endif
228 
xradio_status_show_common(struct seq_file * seq,void * v)229 static int xradio_status_show_common(struct seq_file *seq, void *v)
230 {
231 	int i;
232 	struct list_head *item;
233 	struct xradio_common *hw_priv = seq->private;
234 	struct xradio_debug_common *d = hw_priv->debug;
235 	int ba_cnt, ba_acc, ba_cnt_rx, ba_acc_rx, ba_avg = 0, ba_avg_rx = 0;
236 	bool ba_ena;
237 
238 	spin_lock_bh(&hw_priv->ba_lock);
239 	ba_cnt = hw_priv->debug->ba_cnt;
240 	ba_acc = hw_priv->debug->ba_acc;
241 	ba_cnt_rx = hw_priv->debug->ba_cnt_rx;
242 	ba_acc_rx = hw_priv->debug->ba_acc_rx;
243 	ba_ena = hw_priv->ba_ena;
244 	if (ba_cnt)
245 		ba_avg = ba_acc / ba_cnt;
246 	if (ba_cnt_rx)
247 		ba_avg_rx = ba_acc_rx / ba_cnt_rx;
248 	spin_unlock_bh(&hw_priv->ba_lock);
249 
250 	seq_puts(seq,   "XRADIO Wireless LAN driver status\n");
251 	seq_printf(seq, "Hardware:   %d.%d\n",
252 		hw_priv->wsm_caps.hardwareId,
253 		hw_priv->wsm_caps.hardwareSubId);
254 	seq_printf(seq, "Firmware:   %s %d.%d\n",
255 		xradio_debug_fw_types[hw_priv->wsm_caps.firmwareType],
256 		hw_priv->wsm_caps.firmwareVersion,
257 		hw_priv->wsm_caps.firmwareBuildNumber);
258 	seq_printf(seq, "FW API:     %d\n",
259 		hw_priv->wsm_caps.firmwareApiVer);
260 	seq_printf(seq, "FW caps:    0x%.4X\n",
261 		hw_priv->wsm_caps.firmwareCap);
262 	if (hw_priv->channel) {
263 		seq_printf(seq, "Channel:    %d%s\n",
264 			hw_priv->channel->hw_value,
265 			hw_priv->channel_switch_in_progress ?
266 			" (switching)" : "");
267 
268 		seq_printf(seq, "  flags:    0x%08x\n",
269 			hw_priv->channel->flags);
270 	}
271 	seq_printf(seq, "HT:         %s\n",
272 		xradio_is_ht(&hw_priv->ht_info) ? "on" : "off");
273 	if (xradio_is_ht(&hw_priv->ht_info)) {
274 
275 #ifdef SUPPORT_HT40
276 
277 		seq_printf(seq, "2040BSS:    %s\n",
278 			xradio_is_2040BSS(&hw_priv->ht_info) ? "yes" : "no");
279 
280 		if (xradio_is_2040BSS(&hw_priv->ht_info)) {
281 			switch (hw_priv->ht_info.channel_type) {
282 			case NL80211_CHAN_HT40MINUS:
283 				seq_printf(seq, "Second Chan:Below\n");
284 				break;
285 			case NL80211_CHAN_HT40PLUS:
286 				seq_printf(seq, "Second Chan:Above\n");
287 				break;
288 			default:
289 				break;
290 			}
291 		}
292 
293 		seq_printf(seq, "ShortGI:    %s\n",
294 			xradio_ht_ShortGI(&hw_priv->ht_info) ? "yes" : "no");
295 
296 #endif
297 
298 		seq_printf(seq, "Greenfield: %s\n",
299 			xradio_ht_greenfield(&hw_priv->ht_info) ? "yes" : "no");
300 		seq_printf(seq, "AMPDU dens: %d\n",
301 			xradio_ht_ampdu_density(&hw_priv->ht_info));
302 	}
303 	spin_lock_bh(&hw_priv->tx_policy_cache.lock);
304 	i = 0;
305 	list_for_each(item, &hw_priv->tx_policy_cache.used)
306 		++i;
307 	spin_unlock_bh(&hw_priv->tx_policy_cache.lock);
308 	seq_printf(seq, "RC in use:  %d\n", i);
309 	seq_printf(seq, "BA stat:    %d, %d (%d)\n",
310 		ba_cnt, ba_acc, ba_avg);
311 	seq_printf(seq, "BA RX stat:    %d, %d (%d)\n",
312 		ba_cnt_rx, ba_acc_rx, ba_avg_rx);
313 	seq_printf(seq, "Block ACK:  %s\n", ba_ena ? "on" : "off");
314 
315 	seq_puts(seq, "\n");
316 	for (i = 0; i < 4; ++i) {
317 		xradio_queue_status_show(seq, &hw_priv->tx_queue[i]);
318 		seq_puts(seq, "\n");
319 	}
320 	seq_printf(seq, "TX burst:   %d\n",
321 		d->tx_burst);
322 	seq_printf(seq, "RX burst:   %d\n",
323 		d->rx_burst);
324 	seq_printf(seq, "TX miss:    %d\n",
325 		d->tx_cache_miss);
326 	seq_printf(seq, "Long retr:  %d\n",
327 		hw_priv->long_frame_max_tx_count);
328 	seq_printf(seq, "Short retr: %d\n",
329 		hw_priv->short_frame_max_tx_count);
330 
331 	seq_printf(seq, "BH status: %s, errcode=%d\n",
332 		   atomic_read(&hw_priv->bh_term) ? "terminated" : "alive",
333 		   hw_priv->bh_error);
334 	seq_printf(seq, "Pending RX: %d\n",
335 		atomic_read(&hw_priv->bh_rx));
336 	seq_printf(seq, "Pending TX: %d\n",
337 		atomic_read(&hw_priv->bh_tx));
338 
339 	seq_printf(seq, "TX bufs:    %d x %d bytes\n",
340 		hw_priv->wsm_caps.numInpChBufs,
341 		hw_priv->wsm_caps.sizeInpChBuf);
342 	seq_printf(seq, "Used bufs:  %d\n",
343 		hw_priv->hw_bufs_used);
344 #ifdef BH_PROC_THREAD
345 	seq_printf(seq, "tx_queued:  %d\n",
346 		atomic_read(&hw_priv->proc.tx_queued));
347 	seq_printf(seq, "rx_queued:  %d\n",
348 		atomic_read(&hw_priv->proc.rx_queued));
349 #endif
350 	seq_printf(seq, "Powersavemode:%s\n",
351 		hw_priv->powersave_enabled ? "enable" : "disable");
352 	seq_printf(seq, "Device:     %s\n",
353 		hw_priv->device_can_sleep ? "alseep" : "awake");
354 
355 	spin_lock(&hw_priv->wsm_cmd.lock);
356 	seq_printf(seq, "WSM status: %s\n",
357 		hw_priv->wsm_cmd.done ? "idle" : "active");
358 	seq_printf(seq, "WSM cmd:    0x%.4X (%zu bytes)\n",
359 		hw_priv->wsm_cmd.cmd, hw_priv->wsm_cmd.len);
360 	seq_printf(seq, "WSM retval: %d\n",
361 		hw_priv->wsm_cmd.ret);
362 	spin_unlock(&hw_priv->wsm_cmd.lock);
363 
364 	seq_printf(seq, "Datapath:   %s\n",
365 		atomic_read(&hw_priv->tx_lock) ? "locked" : "unlocked");
366 	if (atomic_read(&hw_priv->tx_lock))
367 		seq_printf(seq, "TXlock cnt: %d\n",
368 			atomic_read(&hw_priv->tx_lock));
369 
370 	seq_printf(seq, "Scan:       %s\n",
371 		atomic_read(&hw_priv->scan.in_progress) ? "active" : "idle");
372 	seq_printf(seq, "Led state:  0x%.2X\n",
373 		hw_priv->softled_state);
374 
375 	return 0;
376 }
377 
xradio_status_open_common(struct inode * inode,struct file * file)378 static int xradio_status_open_common(struct inode *inode, struct file *file)
379 {
380 	return single_open(file, &xradio_status_show_common,
381 		inode->i_private);
382 }
383 
384 static const struct file_operations fops_status_common = {
385 	.open = xradio_status_open_common,
386 	.read = seq_read,
387 	.llseek = seq_lseek,
388 	.release = single_release,
389 	.owner = THIS_MODULE,
390 };
391 
xradio_counters_show(struct seq_file * seq,void * v)392 static int xradio_counters_show(struct seq_file *seq, void *v)
393 {
394 	int ret;
395 	struct xradio_common *hw_priv = seq->private;
396 	struct wsm_counters_table counters;
397 
398 	ret = wsm_get_counters_table(hw_priv, &counters);
399 	if (ret)
400 		return ret;
401 
402 #define CAT_STR(x, y) x ## y
403 #define PUT_COUNTER(tab, name) \
404 	seq_printf(seq, "%s:" tab "%d\n", #name, \
405 		__le32_to_cpu(counters.CAT_STR(count, name)))
406 
407 	PUT_COUNTER("\t\t\t\t", PlcpErrors);
408 	PUT_COUNTER("\t\t\t\t", FcsErrors);
409 	PUT_COUNTER("\t\t\t\t", TxPackets);
410 	PUT_COUNTER("\t\t\t\t", RxPackets);
411 	PUT_COUNTER("\t\t\t",   RxPacketErrors);
412 	PUT_COUNTER("\t\t\t\t", RtsSuccess);
413 	PUT_COUNTER("\t\t\t", RtsFailures);
414 	PUT_COUNTER("\t\t",   RxFramesSuccess);
415 	PUT_COUNTER("\t",     RxDecryptionFailures);
416 	PUT_COUNTER("\t\t\t", RxMicFailures);
417 	PUT_COUNTER("\t\t",   RxNoKeyFailures);
418 	PUT_COUNTER("\t\t",   TxMulticastFrames);
419 	PUT_COUNTER("\t\t",   TxFramesSuccess);
420 	PUT_COUNTER("\t\t",   TxFrameFailures);
421 	PUT_COUNTER("\t\t",   TxFramesRetried);
422 	PUT_COUNTER("\t",     TxFramesMultiRetried);
423 	PUT_COUNTER("\t\t",   RxFrameDuplicates);
424 	PUT_COUNTER("\t\t\t", AckFailures);
425 	PUT_COUNTER("\t\t",   RxMulticastFrames);
426 	PUT_COUNTER("\t\t",   RxCMACICVErrors);
427 	PUT_COUNTER("\t\t\t", RxCMACReplays);
428 	PUT_COUNTER("\t\t",   RxMgmtCCMPReplays);
429 	PUT_COUNTER("\t\t\t", RxBIPMICErrors);
430 
431 	PUT_COUNTER("\t\t\t", AllBeacons);
432 	PUT_COUNTER("\t\t\t", ScanBeacons);
433 	PUT_COUNTER("\t\t\t", ScanProbeRsps);
434 	PUT_COUNTER("\t\t\t", OutChanBeacons);
435 	PUT_COUNTER("\t\t",   OutChanProbeRsps);
436 	PUT_COUNTER("\t\t\t", BssBeacons);
437 	PUT_COUNTER("\t\t\t", HostBeacons);
438 	PUT_COUNTER("\t\t\t", MissBeacons);
439 	PUT_COUNTER("\t\t\t", DTIMBeacons);
440 
441 
442 #undef PUT_COUNTER
443 #undef CAT_STR
444 
445 	return 0;
446 }
447 
xradio_counters_open(struct inode * inode,struct file * file)448 static int xradio_counters_open(struct inode *inode, struct file *file)
449 {
450 	return single_open(file, &xradio_counters_show,
451 		inode->i_private);
452 }
453 
454 static const struct file_operations fops_counters = {
455 	.open = xradio_counters_open,
456 	.read = seq_read,
457 	.llseek = seq_lseek,
458 	.release = single_release,
459 	.owner = THIS_MODULE,
460 };
461 
xradio_backoff_show(struct seq_file * seq,void * v)462 static int xradio_backoff_show(struct seq_file *seq, void *v)
463 {
464 	int ret;
465 	struct xradio_common *hw_priv = seq->private;
466 	struct wsm_backoff_counter counters;
467 
468 	ret = wsm_get_backoff_dbg(hw_priv, &counters);
469 	if (ret)
470 		return ret;
471 
472 #define CAT_STR(x, y) x ## y
473 #define PUT_COUNTER(tab, name) \
474 	seq_printf(seq, tab"%s:\t%d\n", #name, \
475 		(__le32_to_cpu(counters.CAT_STR(count, name))&0xffff))
476 
477 	PUT_COUNTER("backoff_max ", 0);
478 	PUT_COUNTER("[0, 7]       ", 1);
479 	PUT_COUNTER("[~, 15]      ", 2);
480 	PUT_COUNTER("[~, 31]      ", 3);
481 	PUT_COUNTER("[~, 63]      ", 4);
482 	PUT_COUNTER("[~, 127]     ", 5);
483 	PUT_COUNTER("[~, 255]     ", 6);
484 	PUT_COUNTER("[~, 511]     ", 7);
485 	PUT_COUNTER("[~, 1023]    ", 8);
486 
487 
488 #undef PUT_COUNTER
489 #undef CAT_STR
490 
491 	return 0;
492 }
493 
xradio_backoff_open(struct inode * inode,struct file * file)494 static int xradio_backoff_open(struct inode *inode, struct file *file)
495 {
496 	return single_open(file, &xradio_backoff_show,
497 		inode->i_private);
498 }
499 
500 static const struct file_operations fops_backoff = {
501 	.open = xradio_backoff_open,
502 	.read = seq_read,
503 	.llseek = seq_lseek,
504 	.release = single_release,
505 	.owner = THIS_MODULE,
506 };
507 
508 #ifdef SUPPORT_HT40
509 
xradio_ratemap_show(struct seq_file * seq,void * v)510 static int xradio_ratemap_show(struct seq_file *seq, void *v)
511 {
512 	/* int ret; */
513 	/* struct xradio_common *hw_priv = seq->private; */
514 
515 #define PUT_TXRATE_COUNT(idx, bdsss, aofdm) do { \
516 	seq_printf(seq, "MCS%d:"  "[%8d][%8d] [%8d][%8d] %4s:" \
517 		"[%8d] %3s:[%8d]\n", idx, \
518 		__le32_to_cpu(TxedHtofdmRateMap[0][idx]), \
519 		__le32_to_cpu(TxedHtofdmRateMap[1][idx]), \
520 		__le32_to_cpu(TxedHtofdmRateMap[2][idx]), \
521 		__le32_to_cpu(TxedHtofdmRateMap[3][idx]), \
522 		#bdsss, __le32_to_cpu(TxedLegacyRateMap[0][idx]), \
523 		#aofdm, __le32_to_cpu(TxedLegacyRateMap[1][idx]));\
524 		TxedHtofdmRateMap[0][idx] = 0;\
525 		TxedHtofdmRateMap[1][idx] = 0;\
526 		TxedHtofdmRateMap[2][idx] = 0;\
527 		TxedHtofdmRateMap[3][idx] = 0;\
528 		TxedLegacyRateMap[0][idx] = 0;\
529 		TxedLegacyRateMap[1][idx] = 0;\
530 } while (0)
531 
532 	seq_printf(seq, "\nTxRateMap:\n");
533 	seq_printf(seq, "     " "[20SGI TX][20LGI TX] " \
534 				"[40SGI TX][40LGI TX] " \
535 				"     [DSSS  TX] " \
536 				"    [OFDM  TX]\n");
537 
538 	PUT_TXRATE_COUNT(7, 11MS, 54M);
539 	PUT_TXRATE_COUNT(6, 11ML, 48M);
540 	PUT_TXRATE_COUNT(5, 5M5S, 36M);
541 	PUT_TXRATE_COUNT(4, 5M5L, 24M);
542 	PUT_TXRATE_COUNT(3,  2MS, 18M);
543 	PUT_TXRATE_COUNT(2,  2ML, 12M);
544 	PUT_TXRATE_COUNT(1, ----,  9M);
545 	PUT_TXRATE_COUNT(0,  1ML,  6M);
546 
547 #undef PUT_TXRATE_COUNT
548 
549 #define PUT_RXRATE_COUNT(idx, bdsss, aofdm) do { \
550 	seq_printf(seq, "MCS%d:"  "[%8d][%8d] [%8d][%8d] %4s:" \
551 		"[%8d] %3s:[%8d]\n", idx, \
552 		__le32_to_cpu(RxedHtofdmRateMap[0][idx]), \
553 		__le32_to_cpu(RxedHtofdmRateMap[1][idx]), \
554 		__le32_to_cpu(RxedHtofdmRateMap[2][idx]), \
555 		__le32_to_cpu(RxedHtofdmRateMap[3][idx]), \
556 		#bdsss, __le32_to_cpu(RxedLegacyRateMap[0][idx]), \
557 		#aofdm, __le32_to_cpu(RxedLegacyRateMap[1][idx]));\
558 		RxedHtofdmRateMap[0][idx] = 0;\
559 		RxedHtofdmRateMap[1][idx] = 0;\
560 		RxedHtofdmRateMap[2][idx] = 0;\
561 		RxedHtofdmRateMap[3][idx] = 0;\
562 		RxedLegacyRateMap[0][idx] = 0;\
563 		RxedLegacyRateMap[1][idx] = 0;\
564 } while (0)
565 
566 	seq_printf(seq, "\nRxRateMap:\n");
567 	seq_printf(seq, "     " "[20SGI RX][20LGI RX] " \
568 				"[40SGI RX][40LGI RX] " \
569 				"     [DSSS  RX] " \
570 				"    [OFDM  RX]\n");
571 
572 	PUT_RXRATE_COUNT(7, 11MS, 54M);
573 	PUT_RXRATE_COUNT(6, 11ML, 48M);
574 	PUT_RXRATE_COUNT(5, 5M5S, 36M);
575 	PUT_RXRATE_COUNT(4, 5M5L, 24M);
576 	PUT_RXRATE_COUNT(3,  2MS, 18M);
577 	PUT_RXRATE_COUNT(2,  2ML, 12M);
578 	PUT_RXRATE_COUNT(1, ----,  9M);
579 	PUT_RXRATE_COUNT(0,  1ML,  6M);
580 
581 #undef PUT_RXRATE_COUNT
582 
583 	return 0;
584 }
585 
586 #else
587 
xradio_ratemap_show(struct seq_file * seq,void * v)588 static int xradio_ratemap_show(struct seq_file *seq, void *v)
589 {
590 	/* int ret; */
591 	/* struct xradio_common *hw_priv = seq->private; */
592 
593 	seq_printf(seq, "\nRateMap for Tx & RX:\n");
594 #define PUT_RATE_COUNT(name, idx) do { \
595 	seq_printf(seq, "%s\t"  "%d,  %d\n", #name, \
596 		__le32_to_cpu(TxedRateIdx_Map[idx]), \
597 		__le32_to_cpu(RxedRateIdx_Map[idx])); \
598 	TxedRateIdx_Map[idx] = 0; \
599 	RxedRateIdx_Map[idx] = 0; \
600 } while (0)
601 
602 	PUT_RATE_COUNT("65   Mbps:", 21);
603 	PUT_RATE_COUNT("58.5 Mbps:", 20);
604 	PUT_RATE_COUNT("52   Mbps:", 19);
605 	PUT_RATE_COUNT("39   Mbps:", 18);
606 	PUT_RATE_COUNT("26   Mbps:", 17);
607 	PUT_RATE_COUNT("19.5 Mbps:", 16);
608 	PUT_RATE_COUNT("13   Mbps:", 15);
609 	PUT_RATE_COUNT("6.5  Mbps:", 14);
610 
611 	PUT_RATE_COUNT("54   Mbps:", 13);
612 	PUT_RATE_COUNT("48   Mbps:", 12);
613 	PUT_RATE_COUNT("36   Mbps:", 11);
614 	PUT_RATE_COUNT("24   Mbps:", 10);
615 	PUT_RATE_COUNT("18   Mbps:",  9);
616 	PUT_RATE_COUNT("12   Mbps:",  8);
617 	PUT_RATE_COUNT("9    Mbps:", 7);
618 	PUT_RATE_COUNT("6    Mbps:",  6);
619 
620 	PUT_RATE_COUNT("11   Mbps:", 3);
621 	PUT_RATE_COUNT("5.5  Mbps:", 2);
622 	PUT_RATE_COUNT("2    Mbps:", 1);
623 	PUT_RATE_COUNT("1    Mbps:", 0);
624 
625 #undef PUT_RATE_COUNT
626 
627 	return 0;
628 }
629 
630 #endif
631 
xradio_ratemap_open(struct inode * inode,struct file * file)632 static int xradio_ratemap_open(struct inode *inode, struct file *file)
633 {
634 	return single_open(file, &xradio_ratemap_show,
635 		inode->i_private);
636 }
637 
638 static const struct file_operations fops_ratemap = {
639 	.open = xradio_ratemap_open,
640 	.read = seq_read,
641 	.llseek = seq_lseek,
642 	.release = single_release,
643 	.owner = THIS_MODULE,
644 };
645 
xradio_ampducounters_show(struct seq_file * seq,void * v)646 static int xradio_ampducounters_show(struct seq_file *seq, void *v)
647 {
648 	int ret;
649 	struct xradio_common *hw_priv = seq->private;
650 	struct wsm_ampducounters_table counters;
651 
652 	ret = wsm_get_ampducounters_table(hw_priv, &counters);
653 	if (ret)
654 		return ret;
655 
656 #define CAT_STR(x, y) x ## y
657 #define PUT_COUNTER(tab, name) \
658 	seq_printf(seq, "%s:" tab "%d\n", #name, \
659 		__le32_to_cpu(counters.CAT_STR(count, name)))
660 
661 	PUT_COUNTER("\t\t\t",	TxAMPDUs);
662 	PUT_COUNTER("\t\t",	TxMPDUsInAMPDUs);
663 	PUT_COUNTER("\t\t",	TxOctetsInAMPDUs_l32);
664 	PUT_COUNTER("\t\t",	TxOctetsInAMPDUs_h32);
665 	PUT_COUNTER("\t\t\t",	RxAMPDUs);
666 	PUT_COUNTER("\t\t",	RxMPDUsInAMPDUs);
667 	PUT_COUNTER("\t\t",	RxOctetsInAMPDUs_l32);
668 	PUT_COUNTER("\t\t",	RxOctetsInAMPDUs_h32);
669 	PUT_COUNTER("\t",	RxDelimeterCRCErrorCount);
670 	PUT_COUNTER("\t\t",	ImplictBARFailures);
671 	PUT_COUNTER("\t\t",	ExplictBARFailures);
672 
673 
674 
675 #undef PUT_COUNTER
676 #undef CAT_STR
677 
678 	return 0;
679 }
680 
xradio_ampducounters_open(struct inode * inode,struct file * file)681 static int xradio_ampducounters_open(struct inode *inode, struct file *file)
682 {
683 	return single_open(file, &xradio_ampducounters_show,
684 		inode->i_private);
685 }
686 
687 static const struct file_operations fops_ampducounters = {
688 	.open = xradio_ampducounters_open,
689 	.read = seq_read,
690 	.llseek = seq_lseek,
691 	.release = single_release,
692 	.owner = THIS_MODULE,
693 };
694 
xradio_txpipe_show(struct seq_file * seq,void * v)695 static int xradio_txpipe_show(struct seq_file *seq, void *v)
696 {
697 	int ret;
698 	struct xradio_common *hw_priv = seq->private;
699 	struct wsm_txpipe_counter counters;
700 
701 	ret = wsm_get_txpipe_table(hw_priv, &counters);
702 	if (ret)
703 		return ret;
704 
705 #define CAT_STR(x, y) x ## y
706 #define PUT_COUNTER(tab, name) \
707 	seq_printf(seq, tab":\t%d\n", \
708 		__le32_to_cpu(counters.CAT_STR(count, name)))
709 
710 	PUT_COUNTER("tx-aggr       ", 1);
711 	PUT_COUNTER("retx-aggr     ", 2);
712 	PUT_COUNTER("retry_type1   ", 3);
713 	PUT_COUNTER("retry_type2   ", 4);
714 	PUT_COUNTER("retry_type3   ", 5);
715 	PUT_COUNTER("rx-aggr-event ", 6);
716 	PUT_COUNTER("rx-aggr-end   ", 7);
717 	PUT_COUNTER("rx-ba         ", 8);
718 	PUT_COUNTER("tx_ampdu_len  ", 9);
719 	PUT_COUNTER("fail_by_rts   ", a);
720 
721 
722 #undef PUT_COUNTER
723 #undef CAT_STR
724 
725 	return 0;
726 }
727 
xradio_txpipe_open(struct inode * inode,struct file * file)728 static int xradio_txpipe_open(struct inode *inode, struct file *file)
729 {
730 	return single_open(file, &xradio_txpipe_show,
731 		inode->i_private);
732 }
733 
734 static const struct file_operations fops_txpipe = {
735 	.open = xradio_txpipe_open,
736 	.read = seq_read,
737 	.llseek = seq_lseek,
738 	.release = single_release,
739 	.owner = THIS_MODULE,
740 };
741 
742 #if (SUPPORT_EPTA)
743 
744 u32 epta_stat_dbg_ctrl = 0x484;
745 char *med_state_str[4] = {
746 	"bt inactive",
747 	"with bt and wlan not waiting",
748 	"with wlan",
749 	"with bt and wlan waiting"
750 };
751 char *req_type_str[11] = {
752 	"rx_recovery", "rx_mcast", "rx_bcn", "tx_bcn", "tx_cts", "tx_high", "tx_uapsd", "fastps",
753 	"scan", "pspoll", "tx_low"
754 };
755 
xradio_epta_stat_show(struct seq_file * seq,void * v)756 static int xradio_epta_stat_show(struct seq_file *seq, void *v)
757 {
758 	int ret, i;
759 	struct xradio_epta_stat epta_stat;
760 	struct xradio_common *hw_priv = seq->private;
761 
762 //	memset(&epta_stat, 0, sizeof(epta_stat));
763 	ret = wsm_get_epta_statistics(hw_priv, &epta_stat);
764 #if 0
765 	seq_printf(seq, "\n================\n");
766 	for (i = 0; i < sizeof(epta_stat); i++) {
767 		if (i % 4 == 0)
768 			seq_printf(seq, "%d:\t ", i);
769 		seq_printf(seq, "%2x ", *((u8 *)&epta_stat+i));
770 		if ((i+1) % 4 == 0)
771 			seq_printf(seq, "\n");
772 	}
773 	seq_printf(seq, "\n================\n");
774 #endif
775 	if (ret)
776 		return ret;
777 
778 	seq_printf(seq, "\n[epta statistics]\n");
779 	seq_printf(seq, "medium state: %s\n", med_state_str[epta_stat.medium_state]);
780 	if (epta_stat.medium_state == 0)
781 		return 0;
782 	if (epta_stat.wlan_req_ongoing) {
783 		//req got into epta from lmc_epta but not granted or aborted yet
784 	}
785 	if (epta_stat.medium_state == 2) {
786 		seq_printf(seq, "current req :[type:%s][prio_sw:%u][prio_hw:%u][req dur:%u]\n", req_type_str[epta_stat.wlan_req_type],
787 				epta_stat.wlan_req_priority & 0xf, (epta_stat.wlan_req_priority >> 4) & 0xf,  __le32_to_cpu(epta_stat.wlan_req_request_dur));
788 	//	seq_printf(seq, "current req granted time: \t %u\n", __le32_to_cpu(epta_stat.grant_or_wait_time));
789 	} else if (epta_stat.medium_state == 3) {
790 		seq_printf(seq, "current req :[type:%s][prio_sw:%u][prio_hw:%u][req dur:%u]\n", req_type_str[epta_stat.wlan_req_type],
791 				epta_stat.wlan_req_priority & 0xf, (epta_stat.wlan_req_priority >> 4) & 0xf, __le32_to_cpu(epta_stat.wlan_req_request_dur));
792 	//	seq_printf(seq, "wlan is waiting for bt: \t\t %u\n", __le32_to_cpu(epta_stat.grant_or_wait_time));
793 	} else {
794 		seq_printf(seq, "current req :\n");
795 	}
796 
797 	seq_printf(seq, "=========================wlan req info========================\n");
798 
799 	seq_printf(seq, "                   %10s ", "all");
800 	for (i = 0; i < 11; i++)
801 		if (epta_stat_dbg_ctrl & (1<<i))
802 			seq_printf(seq, "%10s ", req_type_str[i]);
803 	seq_printf(seq, "\n");
804 	seq_printf(seq, "req win cnt:       %10u %10u %10u %10u\n", __le32_to_cpu(epta_stat.wl_req_info[0].cnt_win), __le32_to_cpu(epta_stat.wl_req_info[1].cnt_win),
805 			__le32_to_cpu(epta_stat.wl_req_info[2].cnt_win), __le32_to_cpu(epta_stat.wl_req_info[3].cnt_win));
806 	seq_printf(seq, "req lose cnt:      %10u %10u %10u %10u\n", __le32_to_cpu(epta_stat.wl_req_info[0].cnt_lose), __le32_to_cpu(epta_stat.wl_req_info[1].cnt_lose),
807 			__le32_to_cpu(epta_stat.wl_req_info[2].cnt_lose), __le32_to_cpu(epta_stat.wl_req_info[3].cnt_lose));
808 
809 	seq_printf(seq, "grant med ret cnt: %10u %10u %10u %10u\n", __le16_to_cpu(epta_stat.wl_req_info[0].cnt_grant_med_ret), __le16_to_cpu(epta_stat.wl_req_info[1].cnt_grant_med_ret),
810 			__le16_to_cpu(epta_stat.wl_req_info[2].cnt_grant_med_ret), __le16_to_cpu(epta_stat.wl_req_info[3].cnt_grant_med_ret));
811 	seq_printf(seq, "grant timeout cnt: %10u %10u %10u %10u\n", __le16_to_cpu(epta_stat.wl_req_info[0].cnt_grant_timeout), __le16_to_cpu(epta_stat.wl_req_info[1].cnt_grant_timeout),
812 			__le16_to_cpu(epta_stat.wl_req_info[2].cnt_grant_timeout), __le16_to_cpu(epta_stat.wl_req_info[3].cnt_grant_timeout));
813 	seq_printf(seq, "abort misss rx cnt:%10u %10u %10u %10u\n", __le16_to_cpu(epta_stat.wl_req_info[0].cnt_abort_miss_rx), __le16_to_cpu(epta_stat.wl_req_info[1].cnt_abort_miss_rx),
814 			__le16_to_cpu(epta_stat.wl_req_info[2].cnt_abort_miss_rx), __le16_to_cpu(epta_stat.wl_req_info[3].cnt_abort_miss_rx));
815 	seq_printf(seq, "abort expired cnt: %10u %10u %10u %10u\n", __le16_to_cpu(epta_stat.wl_req_info[0].cnt_abort_expired), __le16_to_cpu(epta_stat.wl_req_info[1].cnt_abort_expired),
816 			__le16_to_cpu(epta_stat.wl_req_info[2].cnt_abort_expired), __le16_to_cpu(epta_stat.wl_req_info[3].cnt_abort_expired));
817 
818 	seq_printf(seq, "granted time:      %10u %10u %10u %10u\n", __le32_to_cpu(epta_stat.wl_req_info[0].granted_time), __le32_to_cpu(epta_stat.wl_req_info[1].granted_time),
819 			__le32_to_cpu(epta_stat.wl_req_info[2].granted_time), __le32_to_cpu(epta_stat.wl_req_info[3].granted_time));
820 	seq_printf(seq, "granted used time: %10u %10u %10u %10u\n", __le32_to_cpu(epta_stat.wl_req_info[0].gr_used_time), __le32_to_cpu(epta_stat.wl_req_info[1].gr_used_time),
821 			__le32_to_cpu(epta_stat.wl_req_info[2].gr_used_time), __le32_to_cpu(epta_stat.wl_req_info[3].gr_used_time));
822 
823 	seq_printf(seq, "\n");
824 	seq_printf(seq, "%25s %17s %18s\n", "[req ext cnt] grant_uapsd", "abort_rx_bcn", "abort_pspoll");
825 	seq_printf(seq, "%25u %17u %18u\n", __le16_to_cpu(epta_stat.cnt_ex_grant_uapsd),
826 			__le16_to_cpu(epta_stat.cnt_ex_abort_rx_bcn), __le16_to_cpu(epta_stat.cnt_ex_abort_pspoll));
827 
828 	seq_printf(seq, "%25s %17s %18s\n", "[bt abort cnt]      total", "abort_tx", "abort_tx_fix");
829 	seq_printf(seq, "%25u %17u %18u\n", __le16_to_cpu(epta_stat.cnt_bt_abort),
830 			__le16_to_cpu(epta_stat.cnt_bt_abort_tx), __le16_to_cpu(epta_stat.cnt_bt_abort_tx_fix));
831 
832 	seq_printf(seq, "========================bt tx req type========================\n");
833 	seq_printf(seq, "%4s %13s %13s %14s %14s\n", "poll", "dm1", "br", "edr", "sco");
834 	seq_printf(seq, "%4u %13u %13u %14u %14u\n", __le16_to_cpu(epta_stat.cnt_bt_tx_poll_pkt_req),
835 			__le16_to_cpu(epta_stat.cnt_bt_tx_dm1_pkt_req), __le16_to_cpu(epta_stat.cnt_bt_tx_br_pkt_req),
836 			__le16_to_cpu(epta_stat.cnt_bt_tx_edr_pkt_req), __le16_to_cpu(epta_stat.cnt_bt_tx_sco_pkt_req));
837 
838 	seq_printf(seq, "=======================wlan/bt nrt info=======================\n");
839 	seq_printf(seq, "%13s %14s %7s %10s %14s\n", "wl_quota_used", " bt_quota_used", "bt_req", "gr_bt_req", "gr_bt_max_gap");
840 	seq_printf(seq, "%13u %14u %7u %10u %14u\n", __le32_to_cpu(epta_stat.nrt_wlan_quota_used), __le32_to_cpu(epta_stat.nrt_bt_quota_used),
841 			__le32_to_cpu(epta_stat.nrt_bt_requests), __le32_to_cpu(epta_stat.nrt_bt_granted_requestd), __le32_to_cpu(epta_stat.nrt_bt_granted_req_max_gap));
842 	seq_printf(seq, "\n");
843 
844 	for (i = 0; i < epta_stat.num_active_rt_bt_links; i++) {
845 		struct xradio_epta_bt_link_info *bt_link_info = &epta_stat.bt_link_info[i];
846 		seq_printf(seq, "=======================rt bt link idx %u=======================\n", i);
847 		seq_printf(seq, "%6s: %-3u %12s: %-2u %13s: %-3u %9s: %-1u\n", "linkid", bt_link_info->link_id, "type  ", bt_link_info->traffic_type,
848 				"master", bt_link_info->master_or_slave, "prio_sw    ", bt_link_info->traffic_priority);
849 		seq_printf(seq, "%6s: %7u %8s: %7u %8s: %-3u %9s: %-1u\n", "rt_si ", __le32_to_cpu(bt_link_info->rt_si), "rt_sw ", __le32_to_cpu(bt_link_info->rt_sw),
850 				"req   ", __le32_to_cpu(bt_link_info->requests), "prio_hw_rt ", ((__le32_to_cpu(bt_link_info->time_diff_req_start)) >> 4) & 0xf);
851 		seq_printf(seq, "%6s: %7u %8s: %7u %8s: %-3u %9s: %-1u\n", "msg_si", __le32_to_cpu(bt_link_info->msg_si), "msg_sw", __le32_to_cpu(bt_link_info->msg_sw),
852 				"gr_req", __le32_to_cpu(bt_link_info->granted_requests), "prio_hw_nrt",  (__le32_to_cpu(bt_link_info->time_diff_req_start)) & 0xf);
853 
854 		seq_printf(seq, "%6s: %-3u %14s: %-3u\n", "caton ",  __le32_to_cpu(bt_link_info->bt_caton_num), "tx_retry", __le32_to_cpu(bt_link_info->bt_tx_retry_num));
855 
856 		/*if (bt_link_info->curr_req_ongoing)
857 			seq_printf(seq, "time_from_cur_req_start : %7d\n", __le32_to_cpu(bt_link_info->time_diff_req_start));
858 		else
859 			seq_printf(seq, "time_to_next_req_start  : %7d\n", __le32_to_cpu(bt_link_info->time_diff_req_start)); //unuse */
860 	}
861 
862 	return 0;
863 }
864 
xradio_epta_stat_open(struct inode * inode,struct file * file)865 static int xradio_epta_stat_open(struct inode *inode, struct file *file)
866 {
867 	return single_open(file, &xradio_epta_stat_show,
868 		inode->i_private);
869 }
870 
871 static const struct file_operations fops_epta_stat = {
872 	.open = xradio_epta_stat_open,
873 	.read = seq_read,
874 	.llseek = seq_lseek,
875 	.release = single_release,
876 	.owner = THIS_MODULE,
877 };
878 
xradio_epta_stat_dbg_write(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)879 static ssize_t xradio_epta_stat_dbg_write(struct file *file,
880 	const char __user *user_buf, size_t count, loff_t *ppos)
881 {
882 	struct xradio_common *hw_priv = file->private_data;
883 	char buf[12] = {0};
884 	char *endptr = NULL;
885 	u32 dbg_val = 0;
886 
887 	count = (count > 11 ? 11 : count);
888 
889 	if (!count)
890 		return -EINVAL;
891 	if (copy_from_user(buf, user_buf, count))
892 		return -EFAULT;
893 	dbg_val = simple_strtoul(buf, &endptr, 16);
894 	if (count_ones(dbg_val) > 3 || dbg_val > 0x7ff) {
895 		SYS_WARN(1);
896 		return count;
897 	}
898 	epta_stat_dbg_ctrl = dbg_val;
899 	xradio_dbg(XRADIO_DBG_ALWY, "epta_stat_dbg_ctrl = 0x%x\n", epta_stat_dbg_ctrl);
900 	SYS_WARN(wsm_set_epta_stat_dbg_ctrl(hw_priv, epta_stat_dbg_ctrl));
901 
902 	return count;
903 }
904 
xradio_epta_stat_dbg_read(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)905 static ssize_t xradio_epta_stat_dbg_read(struct file *file,
906 	char __user *user_buf, size_t count, loff_t *ppos)
907 {
908 	/* struct xradio_common *hw_priv = file->private_data; */
909 	char buf[50];
910 	size_t size = 0;
911 
912 	sprintf(buf, "epta_stat_dbg_ctrl = 0x%x\n", epta_stat_dbg_ctrl);
913 	size = strlen(buf);
914 
915 	return simple_read_from_buffer(user_buf, count, ppos, buf, size);
916 }
917 #endif
918 
919 static int count_idx;
920 
921 #ifdef SUPPORT_HT40
922 
xradio_dbgstats_show(struct seq_file * seq,void * v)923 static int xradio_dbgstats_show(struct seq_file *seq, void *v)
924 {
925 	int ret;
926 	int avg_ampdu_len = 0;
927 	int FrameFail_ratio = 0;
928 	int FailByRts_ratio = 0;
929 	int FrameRetry_ratio = 0;
930 	int AMPDURetry_ratio = 0;
931 	int Retry1_ratio = 0;
932 	int Retry2_ratio = 0;
933 	int Retry3_ratio = 0;
934 	struct xradio_common *hw_priv = seq->private;
935 	struct wsm_counters_table counters;
936 	struct wsm_ampducounters_table ampdu_counters;
937 	struct wsm_txpipe_counter txpipe;
938 
939 	ret = wsm_get_counters_table(hw_priv, &counters);
940 	if (ret)
941 		return ret;
942 
943 	ret = wsm_get_txpipe_table(hw_priv, &txpipe);
944 	if (ret)
945 		return ret;
946 
947 	ret = wsm_get_ampducounters_table(hw_priv, &ampdu_counters);
948 	if (ret)
949 		return ret;
950 
951 #define CAT_STR(x, y) x ## y
952 
953 #define PUT_COUNTER(tab, name) \
954 	seq_printf(seq, tab "%d\n", \
955 		__le32_to_cpu(counters.CAT_STR(count, name)))
956 
957 #define PUT_AMPDU_COUNTER(tab, name) \
958 	seq_printf(seq, tab "%d\n", \
959 		__le32_to_cpu(ampdu_counters.CAT_STR(count, name)))
960 
961 #define PUT_TXPIPE(tab, name) \
962 	seq_printf(seq, tab "%d\n", \
963 		__le32_to_cpu(txpipe.CAT_STR(count, name)))
964 
965 	if (ampdu_counters.countTxAMPDUs) {
966 		avg_ampdu_len = (int)((ampdu_counters.countTxMPDUsInAMPDUs + \
967 				      (ampdu_counters.countTxAMPDUs>>1)) \
968 				      /ampdu_counters.countTxAMPDUs);
969 		AMPDURetry_ratio = (int)(ampdu_counters.countImplictBARFailures * \
970 					 100/ampdu_counters.countTxAMPDUs);
971 	}
972 	if (counters.countAckFailures) {
973 		Retry1_ratio = (int)(txpipe.count3*100/counters.countAckFailures);
974 		Retry2_ratio = (int)(txpipe.count4*100/counters.countAckFailures);
975 		Retry3_ratio = (int)(txpipe.count5*100/counters.countAckFailures);
976 	}
977 	if (ampdu_counters.countTxMPDUsInAMPDUs) {
978 		FrameFail_ratio = (int)(counters.countTxFrameFailures * \
979 				       1000/ampdu_counters.countTxMPDUsInAMPDUs);
980 		FrameRetry_ratio = (int)(counters.countAckFailures * \
981 				       100/ampdu_counters.countTxMPDUsInAMPDUs);
982 	}
983 
984 	if (counters.countTxFrameFailures)
985 		FailByRts_ratio = (int)(txpipe.counta * \
986 					100/counters.countTxFrameFailures);
987 
988 	seq_printf(seq, "===========================================\n");
989 	seq_printf(seq, "                   %02d\n", count_idx);
990 	seq_printf(seq, "===========================================\n");
991 	count_idx++;
992 	count_idx = count_idx % 100;
993 	PUT_COUNTER("RtsSuccess:        ", RtsSuccess);
994 	PUT_COUNTER("RtsFailures:       ", RtsFailures);
995 	seq_printf(seq, "Avg_AMPDU_Len:     %d\n", __le32_to_cpu(avg_ampdu_len));
996 	PUT_AMPDU_COUNTER("TxAMPDUs:          ", TxAMPDUs);
997 	PUT_AMPDU_COUNTER("TxMPDUsInAMPDUs:   ", TxMPDUsInAMPDUs);
998 	/* PUT_COUNTER      ("TxFrameRetries:    ", AckFailures); */
999 	/* PUT_COUNTER      ("TxFrameFailures:   ", TxFrameFailures); */
1000 	PUT_TXPIPE("Failure_By_Rts:    ", a);
1001 	/* PUT_AMPDU_COUNTER("BA-RX-Fails    ", ImplictBARFailures);
1002 	PUT_AMPDU_COUNTER("TxAMPDUs       ", TxAMPDUs);
1003 	PUT_TXPIPE       ("ReTx-AMPDUs    ", 2);
1004 	PUT_TXPIPE       ("Retry_type1    ", 3);
1005 	PUT_TXPIPE       ("Retry_type2    ", 4);
1006 	PUT_TXPIPE       ("Retry_type3    ", 5); */
1007 	seq_printf(seq, "==============\n");
1008 	seq_printf(seq, "FrameFail_ratio:   %d%%%%\n",
1009 		   __le32_to_cpu(FrameFail_ratio));
1010 	seq_printf(seq, "FailByRts_ratio:   %d%%\n",
1011 		   __le32_to_cpu(FailByRts_ratio));
1012 	seq_printf(seq, "FrameRetry_ratio:  %d%%\n",
1013 		   __le32_to_cpu(FrameRetry_ratio));
1014 	seq_printf(seq, "AMPDURetry_ratio:  %d%%\n",
1015 		   __le32_to_cpu(AMPDURetry_ratio));
1016 	seq_printf(seq, "Retry1_ratio:      %d%%\n",
1017 		   __le32_to_cpu(Retry1_ratio));
1018 	seq_printf(seq, "Retry2_ratio:      %d%%\n",
1019 		   __le32_to_cpu(Retry2_ratio));
1020 	seq_printf(seq, "Retry3_ratio:      %d%%\n",
1021 		   __le32_to_cpu(Retry3_ratio));
1022 
1023 	seq_printf(seq, "==============\n");
1024 
1025 
1026 
1027 #define PUT_TXRATE_COUNT(idx, bdsss, aofdm) do { \
1028 		seq_printf(seq, "MCS%d:"  "[%8d][%8d] [%8d][%8d] %4s:" \
1029 			"[%8d] %3s:[%8d]\n", idx, \
1030 			__le32_to_cpu(TxedHtofdmRateMap[0][idx]), \
1031 			__le32_to_cpu(TxedHtofdmRateMap[1][idx]), \
1032 			__le32_to_cpu(TxedHtofdmRateMap[2][idx]), \
1033 			__le32_to_cpu(TxedHtofdmRateMap[3][idx]), \
1034 		#bdsss, __le32_to_cpu(TxedLegacyRateMap[0][idx]), \
1035 		#aofdm, __le32_to_cpu(TxedLegacyRateMap[1][idx]));\
1036 			TxedHtofdmRateMap[0][idx] = 0;\
1037 			TxedHtofdmRateMap[1][idx] = 0;\
1038 			TxedHtofdmRateMap[2][idx] = 0;\
1039 			TxedHtofdmRateMap[3][idx] = 0;\
1040 			TxedLegacyRateMap[0][idx] = 0;\
1041 			TxedLegacyRateMap[1][idx] = 0;\
1042 	} while (0)
1043 
1044 		seq_printf(seq, "\nTxRateMap:\n");
1045 		seq_printf(seq, "     " "[20SGI TX][20LGI TX] " \
1046 					"[40SGI TX][40LGI TX] " \
1047 					"     [DSSS  TX] " \
1048 					"    [OFDM  TX]\n");
1049 
1050 		PUT_TXRATE_COUNT(7, 11MS, 54M);
1051 		PUT_TXRATE_COUNT(6, 11ML, 48M);
1052 		PUT_TXRATE_COUNT(5, 5M5S, 36M);
1053 		PUT_TXRATE_COUNT(4, 5M5L, 24M);
1054 		PUT_TXRATE_COUNT(3,  2MS, 18M);
1055 		PUT_TXRATE_COUNT(2,  2ML, 12M);
1056 		PUT_TXRATE_COUNT(1, ----,  9M);
1057 		PUT_TXRATE_COUNT(0,  1ML,  6M);
1058 
1059 #undef PUT_TXRATE_COUNT
1060 
1061 #define PUT_RXRATE_COUNT(idx, bdsss, aofdm) do { \
1062 		seq_printf(seq, "MCS%d:"  "[%8d][%8d] [%8d][%8d] %4s:" \
1063 			"[%8d] %3s:[%8d]\n", idx, \
1064 			__le32_to_cpu(RxedHtofdmRateMap[0][idx]), \
1065 			__le32_to_cpu(RxedHtofdmRateMap[1][idx]), \
1066 			__le32_to_cpu(RxedHtofdmRateMap[2][idx]), \
1067 			__le32_to_cpu(RxedHtofdmRateMap[3][idx]), \
1068 		#bdsss, __le32_to_cpu(RxedLegacyRateMap[0][idx]), \
1069 		#aofdm, __le32_to_cpu(RxedLegacyRateMap[1][idx]));\
1070 			RxedHtofdmRateMap[0][idx] = 0;\
1071 			RxedHtofdmRateMap[1][idx] = 0;\
1072 			RxedHtofdmRateMap[2][idx] = 0;\
1073 			RxedHtofdmRateMap[3][idx] = 0;\
1074 			RxedLegacyRateMap[0][idx] = 0;\
1075 			RxedLegacyRateMap[1][idx] = 0;\
1076 	} while (0)
1077 
1078 		seq_printf(seq, "\nRxRateMap:\n");
1079 		seq_printf(seq, "     " "[20SGI RX][20LGI RX] " \
1080 					"[40SGI RX][40LGI RX] " \
1081 					"     [DSSS  RX] " \
1082 					"    [OFDM  RX]\n");
1083 
1084 		PUT_RXRATE_COUNT(7, 11MS, 54M);
1085 		PUT_RXRATE_COUNT(6, 11ML, 48M);
1086 		PUT_RXRATE_COUNT(5, 5M5S, 36M);
1087 		PUT_RXRATE_COUNT(4, 5M5L, 24M);
1088 		PUT_RXRATE_COUNT(3,  2MS, 18M);
1089 		PUT_RXRATE_COUNT(2,  2ML, 12M);
1090 		PUT_RXRATE_COUNT(1, ----,  9M);
1091 		PUT_RXRATE_COUNT(0,  1ML,  6M);
1092 
1093 #undef PUT_RXRATE_COUNT
1094 
1095 #undef PUT_COUNTER
1096 #undef PUT_AMPDU_COUNTER
1097 #undef PUT_TXPIPE
1098 #undef CAT_STR
1099 
1100 	return 0;
1101 }
1102 
1103 #else
1104 
xradio_dbgstats_show(struct seq_file * seq,void * v)1105 static int xradio_dbgstats_show(struct seq_file *seq, void *v)
1106 {
1107 	int ret;
1108 	int avg_ampdu_len = 0;
1109 	int FrameFail_ratio = 0;
1110 	int FailByRts_ratio = 0;
1111 	int FrameRetry_ratio = 0;
1112 	int AMPDURetry_ratio = 0;
1113 	int Retry1_ratio = 0;
1114 	int Retry2_ratio = 0;
1115 	int Retry3_ratio = 0;
1116 	struct xradio_common *hw_priv = seq->private;
1117 	struct wsm_counters_table counters;
1118 	struct wsm_ampducounters_table ampdu_counters;
1119 	struct wsm_txpipe_counter txpipe;
1120 
1121 	ret = wsm_get_counters_table(hw_priv, &counters);
1122 	if (ret)
1123 		return ret;
1124 
1125 	ret = wsm_get_txpipe_table(hw_priv, &txpipe);
1126 	if (ret)
1127 		return ret;
1128 
1129 	ret = wsm_get_ampducounters_table(hw_priv, &ampdu_counters);
1130 	if (ret)
1131 		return ret;
1132 
1133 #define CAT_STR(x, y) x ## y
1134 
1135 #define PUT_COUNTER(tab, name) \
1136 	seq_printf(seq, tab "%d\n", \
1137 		__le32_to_cpu(counters.CAT_STR(count, name)))
1138 
1139 #define PUT_AMPDU_COUNTER(tab, name) \
1140 	seq_printf(seq, tab "%d\n", \
1141 		__le32_to_cpu(ampdu_counters.CAT_STR(count, name)))
1142 
1143 #define PUT_TXPIPE(tab, name) \
1144 	seq_printf(seq, tab "%d\n", \
1145 		__le32_to_cpu(txpipe.CAT_STR(count, name)))
1146 
1147 #define PUT_RATE_COUNT(name, idx) do { \
1148 	seq_printf(seq, "%s\t%d\n", #name, \
1149 		__le32_to_cpu(TxedRateIdx_Map[idx])); \
1150 	TxedRateIdx_Map[idx] = 0; \
1151 	} while (0)
1152 
1153 	if (ampdu_counters.countTxAMPDUs) {
1154 		avg_ampdu_len = (int)((ampdu_counters.countTxMPDUsInAMPDUs + \
1155 				      (ampdu_counters.countTxAMPDUs>>1)) \
1156 				      /ampdu_counters.countTxAMPDUs);
1157 		AMPDURetry_ratio = (int)(ampdu_counters.countImplictBARFailures * \
1158 					 100/ampdu_counters.countTxAMPDUs);
1159 	}
1160 	if (counters.countAckFailures) {
1161 		Retry1_ratio = (int)(txpipe.count3*100/counters.countAckFailures);
1162 		Retry2_ratio = (int)(txpipe.count4*100/counters.countAckFailures);
1163 		Retry3_ratio = (int)(txpipe.count5*100/counters.countAckFailures);
1164 	}
1165 	if (ampdu_counters.countTxMPDUsInAMPDUs) {
1166 		FrameFail_ratio = (int)(counters.countTxFrameFailures * \
1167 				       1000/ampdu_counters.countTxMPDUsInAMPDUs);
1168 		FrameRetry_ratio = (int)(counters.countAckFailures * \
1169 				       100/ampdu_counters.countTxMPDUsInAMPDUs);
1170 	}
1171 
1172 	if (counters.countTxFrameFailures)
1173 		FailByRts_ratio = (int)(txpipe.counta * \
1174 					100/counters.countTxFrameFailures);
1175 
1176 	seq_printf(seq, "===========================================\n");
1177 	seq_printf(seq, "                   %02d\n", count_idx);
1178 	seq_printf(seq, "===========================================\n");
1179 	count_idx++;
1180 	count_idx = count_idx%100;
1181 	PUT_COUNTER      ("RtsSuccess:        ", RtsSuccess);
1182 	PUT_COUNTER      ("RtsFailures:       ", RtsFailures);
1183 	seq_printf(seq, "Avg_AMPDU_Len:     %d\n", __le32_to_cpu(avg_ampdu_len));
1184 	PUT_AMPDU_COUNTER("TxAMPDUs:          ", TxAMPDUs);
1185 	PUT_AMPDU_COUNTER("TxMPDUsInAMPDUs:   ", TxMPDUsInAMPDUs);
1186 	/* PUT_COUNTER      ("TxFrameRetries:    ", AckFailures); */
1187 	/* PUT_COUNTER      ("TxFrameFailures:   ", TxFrameFailures); */
1188 	PUT_TXPIPE       ("Failure_By_Rts:    ", a);
1189 	/* PUT_AMPDU_COUNTER("BA-RX-Fails    ", ImplictBARFailures);
1190 	PUT_AMPDU_COUNTER("TxAMPDUs       ", TxAMPDUs);
1191 	PUT_TXPIPE       ("ReTx-AMPDUs    ", 2);
1192 	PUT_TXPIPE       ("Retry_type1    ", 3);
1193 	PUT_TXPIPE       ("Retry_type2    ", 4);
1194 	PUT_TXPIPE       ("Retry_type3    ", 5); */
1195 	seq_printf(seq, "==============\n");
1196 	seq_printf(seq, "FrameFail_ratio:   %d%%%%\n",
1197 		   __le32_to_cpu(FrameFail_ratio));
1198 	seq_printf(seq, "FailByRts_ratio:   %d%%\n",
1199 		   __le32_to_cpu(FailByRts_ratio));
1200 	seq_printf(seq, "FrameRetry_ratio:  %d%%\n",
1201 		   __le32_to_cpu(FrameRetry_ratio));
1202 	seq_printf(seq, "AMPDURetry_ratio:  %d%%\n",
1203 		   __le32_to_cpu(AMPDURetry_ratio));
1204 	seq_printf(seq, "Retry1_ratio:      %d%%\n",
1205 		   __le32_to_cpu(Retry1_ratio));
1206 	seq_printf(seq, "Retry2_ratio:      %d%%\n",
1207 		   __le32_to_cpu(Retry2_ratio));
1208 	seq_printf(seq, "Retry3_ratio:      %d%%\n",
1209 		   __le32_to_cpu(Retry3_ratio));
1210 
1211 	seq_printf(seq, "==============\n");
1212 	PUT_RATE_COUNT("65   Mbps:", 21);
1213 	PUT_RATE_COUNT("58.5 Mbps:", 20);
1214 	PUT_RATE_COUNT("52   Mbps:", 19);
1215 	PUT_RATE_COUNT("39   Mbps:", 18);
1216 	PUT_RATE_COUNT("26   Mbps:", 17);
1217 	PUT_RATE_COUNT("19.5 Mbps:", 16);
1218 	PUT_RATE_COUNT("13   Mbps:", 15);
1219 	PUT_RATE_COUNT("6.5  Mbps:", 14);
1220 
1221 #undef PUT_COUNTER
1222 #undef PUT_AMPDU_COUNTER
1223 #undef PUT_TXPIPE
1224 #undef PUT_RATE_COUNT
1225 #undef CAT_STR
1226 
1227 	return 0;
1228 }
1229 
1230 #endif
1231 
xradio_dbgstats_open(struct inode * inode,struct file * file)1232 static int xradio_dbgstats_open(struct inode *inode, struct file *file)
1233 {
1234 	return single_open(file, &xradio_dbgstats_show, inode->i_private);
1235 }
1236 
1237 static const struct file_operations fops_dbgstats = {
1238 	.open = xradio_dbgstats_open,
1239 	.read = seq_read,
1240 	.llseek = seq_lseek,
1241 	.release = single_release,
1242 	.owner = THIS_MODULE,
1243 };
1244 
xradio_generic_open(struct inode * inode,struct file * file)1245 static int xradio_generic_open(struct inode *inode, struct file *file)
1246 {
1247 	file->private_data = inode->i_private;
1248 	return 0;
1249 }
1250 
xradio_11n_read(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)1251 static ssize_t xradio_11n_read(struct file *file,
1252 	char __user *user_buf, size_t count, loff_t *ppos)
1253 {
1254 	struct xradio_common *hw_priv = file->private_data;
1255 	struct ieee80211_supported_band *band =
1256 		hw_priv->hw->wiphy->bands[NL80211_BAND_2GHZ];
1257 	return simple_read_from_buffer(user_buf, count, ppos,
1258 		    band->ht_cap.ht_supported ? "1\n" : "0\n", 2);
1259 }
1260 
xradio_11n_write(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)1261 static ssize_t xradio_11n_write(struct file *file,
1262 	const char __user *user_buf, size_t count, loff_t *ppos)
1263 {
1264 	struct xradio_common *hw_priv = file->private_data;
1265 	struct ieee80211_supported_band *band[2] = {
1266 		hw_priv->hw->wiphy->bands[NL80211_BAND_2GHZ],
1267 		hw_priv->hw->wiphy->bands[NL80211_BAND_5GHZ],
1268 	};
1269 	char buf[1];
1270 	int ena = 0;
1271 
1272 	if (!count)
1273 		return -EINVAL;
1274 	if (copy_from_user(buf, user_buf, 1))
1275 		return -EFAULT;
1276 	if (buf[0] == 1)
1277 		ena = 1;
1278 
1279 	band[0]->ht_cap.ht_supported = ena;
1280 #ifdef CONFIG_XRADIO_5GHZ_SUPPORT
1281 	band[1]->ht_cap.ht_supported = ena;
1282 #endif /* CONFIG_XRADIO_5GHZ_SUPPORT */
1283 
1284 	return count;
1285 }
1286 
1287 static const struct file_operations fops_11n = {
1288 	.open = xradio_generic_open,
1289 	.read = xradio_11n_read,
1290 	.write = xradio_11n_write,
1291 	.llseek = default_llseek,
1292 };
1293 
1294 
1295 static u32 fwdbg_ctrl;
1296 
xradio_fwdbg_write(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)1297 static ssize_t xradio_fwdbg_write(struct file *file,
1298 	const char __user *user_buf, size_t count, loff_t *ppos)
1299 {
1300 	struct xradio_common *hw_priv = file->private_data;
1301 	char buf[12] = {0};
1302 	char *endptr = NULL;
1303 
1304 	count = (count > 11 ? 11 : count);
1305 
1306 	if (!count)
1307 		return -EINVAL;
1308 	if (copy_from_user(buf, user_buf, count))
1309 		return -EFAULT;
1310 	fwdbg_ctrl = simple_strtoul(buf, &endptr, 16);
1311 	xradio_dbg(XRADIO_DBG_ALWY, "fwdbg_ctrl = %d\n", fwdbg_ctrl);
1312 	SYS_WARN(wsm_set_fw_debug_control(hw_priv, fwdbg_ctrl, 0));
1313 
1314 	return count;
1315 }
1316 
xradio_fwdbg_read(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)1317 static ssize_t xradio_fwdbg_read(struct file *file,
1318 	char __user *user_buf, size_t count, loff_t *ppos)
1319 {
1320 	/* struct xradio_common *hw_priv = file->private_data; */
1321 	char buf[50];
1322 	size_t size = 0;
1323 
1324 	sprintf(buf, "fwdbg_ctrl = %u\n", fwdbg_ctrl);
1325 	size = strlen(buf);
1326 
1327 	return simple_read_from_buffer(user_buf, count, ppos, buf, size);
1328 }
1329 static const struct file_operations fops_fwdbg = {
1330 	.open = xradio_generic_open,
1331 	.write = xradio_fwdbg_write,
1332 	.read = xradio_fwdbg_read,
1333 	.llseek = default_llseek,
1334 };
1335 
1336 /* read/write fw registers */
xradio_fwreg_rw(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)1337 static ssize_t xradio_fwreg_rw(struct file *file,
1338 	const char __user *user_buf, size_t count, loff_t *ppos)
1339 {
1340 	struct xradio_common *hw_priv = file->private_data;
1341 	char  buf[256] = {0};
1342 	u16   buf_size = (count > 255 ? 255 : count);
1343 	char *startptr = &buf[0];
1344 	char *endptr   = NULL;
1345 	u16   flag     = 0;
1346 	int   i, end   = 16;
1347 
1348 	if (!count)
1349 		return -EINVAL;
1350 	if (copy_from_user(buf, user_buf, buf_size))
1351 		return -EFAULT;
1352 
1353 	flag  = simple_strtoul(startptr, &endptr, 16);
1354 	startptr = endptr+1;
1355 	if (flag & WSM_REG_RW_F) {  /* write */
1356 		WSM_REG_W reg_w;
1357 		reg_w.flag = flag;
1358 		reg_w.data_size = 0;
1359 		if (flag & WSM_REG_BK_F)
1360 			end = 2;
1361 
1362 		for (i = 0; (i < end) && ((buf + buf_size - 12) > endptr); i++) {
1363 			reg_w.arg[i].reg_addr = simple_strtoul(startptr, &endptr, 16);
1364 			startptr = endptr + 1;
1365 			reg_w.arg[i].reg_val  = simple_strtoul(startptr, &endptr, 16);
1366 			startptr = endptr + 1;
1367 		}
1368 		if (i)
1369 			reg_w.data_size = 4 + i * 8;
1370 		xradio_dbg(XRADIO_DBG_ALWY, "W:flag=0x%x, size=%d\n",
1371 			   reg_w.flag, reg_w.data_size);
1372 		wsm_write_mib(hw_priv, WSM_MIB_ID_RW_FW_REG,
1373 			      (void *)&reg_w, reg_w.data_size, 0);
1374 
1375 	} else {  /* read */
1376 		WSM_REG_R reg_r;
1377 		reg_r.flag = flag;
1378 		reg_r.data_size = 0;
1379 		if (flag & WSM_REG_BK_F)
1380 			end = 2;
1381 
1382 		for (i = 0; (i < end) && ((buf + buf_size - 6) > endptr); i++) {
1383 			reg_r.arg[i] = simple_strtoul(startptr, &endptr, 16);
1384 			startptr = endptr + 1;
1385 		}
1386 		if (i)
1387 			reg_r.data_size = 4 + i * 4;
1388 
1389 		wsm_read_mib(hw_priv, WSM_MIB_ID_RW_FW_REG, (void *)&reg_r,
1390 			     sizeof(WSM_REG_R), reg_r.data_size);
1391 
1392 		xradio_dbg(XRADIO_DBG_ALWY, "R:flag=0x%x, size=%d\n",
1393 			   reg_r.flag, reg_r.data_size);
1394 
1395 		end = (reg_r.data_size >> 2) - 1;
1396 		if (!end || !(reg_r.flag & WSM_REG_RET_F))
1397 			return count;
1398 
1399 		for (i = 0; i < end; i++) {
1400 			xradio_dbg(XRADIO_DBG_ALWY, "0x%08x ", reg_r.arg[i]);
1401 			if ((i & 3) == 3)
1402 				xradio_dbg(XRADIO_DBG_ALWY, "\n");
1403 		}
1404 		xradio_dbg(XRADIO_DBG_ALWY, "\n");
1405 	}
1406 	return count;
1407 }
1408 
1409 static const struct file_operations fops_rw_fwreg = {
1410 	.open = xradio_generic_open,
1411 	.write = xradio_fwreg_rw,
1412 	.llseek = default_llseek,
1413 };
1414 
1415 /* This ops only used in bh error occured already.
1416  * It can be dangerous to use it in normal status. */
xradio_fwreg_rw_direct(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)1417 static ssize_t xradio_fwreg_rw_direct(struct file *file,
1418 	const char __user *user_buf, size_t count, loff_t *ppos)
1419 {
1420 	/* for H64 HIF test */
1421 	struct xradio_common *hw_priv = file->private_data;
1422 	char buf[256] = { 0 };
1423 	u16 buf_size = (count > 255 ? 255 : count);
1424 	char *startptr = &buf[0];
1425 	char *endptr = NULL;
1426 	u16 flag = 0;
1427 	int i, end = 16;
1428 
1429 	if (!count)
1430 		return -EINVAL;
1431 	if (copy_from_user(buf, user_buf, buf_size))
1432 		return -EFAULT;
1433 
1434 	flag = simple_strtoul(startptr, &endptr, 16);
1435 	startptr = endptr + 1;
1436 	if (flag & WSM_REG_RW_F) {  /* write */
1437 		int ret = 0;
1438 		u32 val32 = 0;
1439 		WSM_REG_W reg_w;
1440 		reg_w.flag = flag;
1441 		reg_w.data_size = 0;
1442 		if (flag & WSM_REG_BK_F)
1443 			end = 2;
1444 
1445 		for (i = 0; (i < end) && ((buf + buf_size - 12) > endptr); i++) {
1446 			reg_w.arg[i].reg_addr = simple_strtoul(startptr, &endptr, 16);
1447 			startptr = endptr + 1;
1448 			reg_w.arg[i].reg_val  = simple_strtoul(startptr, &endptr, 16);
1449 			startptr = endptr + 1;
1450 		}
1451 
1452 		if (!(reg_w.arg[0].reg_addr & 0xffff0000)) { /* means write register */
1453 			ret = xradio_reg_write_32(hw_priv,
1454 				reg_w.arg[0].reg_addr, reg_w.arg[0].reg_val);
1455 			if (ret < 0) {
1456 				xradio_dbg(XRADIO_DBG_ERROR, "%s:test HIF R/W [register]-- " \
1457 					   "write CONFIG err, ret is %d! \n",
1458 					   __func__, ret);
1459 			} else {
1460 				xradio_dbg(XRADIO_DBG_ALWY, "%s:test HIF R/W [register]]-- " \
1461 					   "write  register @0x%x, val is 0x%x\n",
1462 					   __func__, reg_w.arg[0].reg_addr,
1463 					   reg_w.arg[0].reg_val);
1464 			}
1465 		} else { /* means write memory */
1466 			/* change to direct mode */
1467 			ret = xradio_reg_read_32(hw_priv, HIF_CONFIG_REG_ID, &val32);
1468 			if (ret < 0) {
1469 				xradio_dbg(XRADIO_DBG_ERROR, "%s:test HIF R/W -- " \
1470 					   "reading CONFIG err, ret is %d! \n", __func__, ret);
1471 			}
1472 			ret = xradio_reg_write_32(hw_priv, HIF_CONFIG_REG_ID,
1473 						  val32 | HIF_CONFIG_ACCESS_MODE_BIT);
1474 			if (ret < 0) {
1475 				xradio_dbg(XRADIO_DBG_ERROR, "%s:test HIF R/W -- " \
1476 					   "setting direct mode err, ret is %d! \n",
1477 					   __func__, ret);
1478 			}
1479 
1480 			ret = xradio_ahb_write_32(hw_priv, reg_w.arg[0].reg_addr,
1481 						  reg_w.arg[0].reg_val);
1482 			if (ret < 0) {
1483 				xradio_dbg(XRADIO_DBG_ERROR,
1484 					   "%s:AHB write test, val of addr %x is %x! \n",
1485 					   __func__, reg_w.arg[0].reg_addr, reg_w.arg[0].reg_val);
1486 			}
1487 
1488 			/* return to queue mode */
1489 			ret = xradio_reg_write_32(hw_priv, HIF_CONFIG_REG_ID,
1490 						  val32 & ~HIF_CONFIG_ACCESS_MODE_BIT);
1491 			if (ret < 0) {
1492 				xradio_dbg(XRADIO_DBG_ERROR, "%s:test HIF R/W -- " \
1493 					   "setting queue mode err, ret is %d! \n", __func__, ret);
1494 			}
1495 		}
1496 	} else {  /* read */
1497 		WSM_REG_R reg_r;
1498 		u32 val32 = 0;
1499 		u32 mem_val = 0;
1500 		int ret = 0;
1501 		reg_r.flag = flag;
1502 		reg_r.data_size = 0;
1503 		if (flag & WSM_REG_BK_F)
1504 			end = 2;
1505 
1506 		for (i = 0; (i < end) && ((buf + buf_size - 6) > endptr); i++) {
1507 			reg_r.arg[i] = simple_strtoul(startptr, &endptr, 16);
1508 			startptr = endptr + 1;
1509 		}
1510 		/* if (i) reg_r.data_size = 4+i*4; */
1511 		if (!(reg_r.arg[0] & 0xffff0000)) { /* means read register */
1512 			ret = xradio_reg_read_32(hw_priv, (u16)reg_r.arg[0], &val32);
1513 			if (ret < 0) {
1514 				xradio_dbg(XRADIO_DBG_ERROR, "%s:test HIF R/W [register]-- " \
1515 					   "reading CONFIG err, ret is %d! \n",
1516 					   __func__, ret);
1517 			}
1518 			xradio_dbg(XRADIO_DBG_ALWY, "%s:test HIF R/W [register]]-- " \
1519 				   "reading  register @0x%x, val is 0x%x\n",
1520 				   __func__, reg_r.arg[0], val32);
1521 		} else { /* means read memory */
1522 
1523 			/* change to direct mode */
1524 			ret = xradio_reg_read_32(hw_priv, HIF_CONFIG_REG_ID, &val32);
1525 			if (ret < 0) {
1526 				xradio_dbg(XRADIO_DBG_ERROR, "%s:test HIF R/W -- " \
1527 					   "reading CONFIG err, ret is %d! \n",
1528 					   __func__, ret);
1529 			}
1530 			ret = xradio_reg_write_32(hw_priv, HIF_CONFIG_REG_ID,
1531 						   val32 | HIF_CONFIG_ACCESS_MODE_BIT);
1532 			if (ret < 0) {
1533 				xradio_dbg(XRADIO_DBG_ERROR, "%s:test HIF R/W -- " \
1534 					   "setting direct mode err, ret is %d! \n",
1535 					    __func__, ret);
1536 			}
1537 
1538 			if (reg_r.arg[0] & 0x08000000) {
1539 				ret = xradio_ahb_read_32(hw_priv, reg_r.arg[0], &mem_val);
1540 				if (ret < 0) {
1541 					xradio_dbg(XRADIO_DBG_ERROR, "%s:AHB read test err, " \
1542 						   "val of addr %08x is %08x \n",
1543 						   __func__, reg_r.arg[0], mem_val);
1544 				}
1545 				xradio_dbg(XRADIO_DBG_ALWY, "[%08x] = 0x%08x\n",
1546 					   reg_r.arg[0], mem_val);
1547 			} else if (reg_r.arg[0] & 0x09000000) {
1548 				ret = xradio_apb_read_32(hw_priv, reg_r.arg[0], &mem_val);
1549 				if (ret < 0) {
1550 					xradio_dbg(XRADIO_DBG_ERROR, "%s:APB read test err, " \
1551 						   "val of addr %08x is %08x \n",
1552 						   __func__, reg_r.arg[0], mem_val);
1553 				}
1554 				xradio_dbg(XRADIO_DBG_ALWY, "[%08x] = 0x%08x\n",
1555 					   reg_r.arg[0], mem_val);
1556 			}
1557 
1558 			/* return to queue mode */
1559 			ret = xradio_reg_write_32(hw_priv, HIF_CONFIG_REG_ID,
1560 						  val32 & ~HIF_CONFIG_ACCESS_MODE_BIT);
1561 			if (ret < 0) {
1562 				xradio_dbg(XRADIO_DBG_ERROR, "%s:test HIF R/W -- " \
1563 					   "setting queue mode err, ret is %d! \n",
1564 					   __func__, ret);
1565 			}
1566 		}
1567 	}
1568 	return count;
1569 }
1570 static const struct file_operations fops_rw_fwreg_direct = {
1571 	.open = xradio_generic_open,
1572 	.write = xradio_fwreg_rw_direct,
1573 	.llseek = default_llseek,
1574 };
1575 /* setting ampdu_len */
1576 u16 ampdu_len[2] = {16, 16};
xradio_ampdu_len_write(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)1577 static ssize_t xradio_ampdu_len_write(struct file *file,
1578 	const char __user *user_buf, size_t count, loff_t *ppos)
1579 {
1580 	struct xradio_common *hw_priv = file->private_data;
1581 	char buf[12] = { 0 };
1582 	char *endptr = NULL;
1583 	u8 if_id = 0;
1584 
1585 	count = (count > 11 ? 11 : count);
1586 
1587 	if (!count)
1588 		return -EINVAL;
1589 	if (copy_from_user(buf, user_buf, count))
1590 		return -EFAULT;
1591 	if_id = simple_strtoul(buf, &endptr, 10);
1592 	ampdu_len[if_id] = simple_strtoul(endptr + 1, NULL, 10);
1593 
1594 	xradio_dbg(XRADIO_DBG_ALWY, "vif=%d, ampdu_len = %d\n",
1595 		   if_id, ampdu_len[if_id]);
1596 	wsm_write_mib(hw_priv, WSM_MIB_ID_SET_AMPDU_NUM,
1597 		      &ampdu_len[if_id], sizeof(u16), if_id);
1598 
1599 	return count;
1600 }
1601 
xradio_ampdu_len_read(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)1602 static ssize_t xradio_ampdu_len_read(struct file *file,
1603 	char __user *user_buf, size_t count, loff_t *ppos)
1604 {
1605 	/* struct xradio_common *hw_priv = file->private_data; */
1606 	char buf[100];
1607 	size_t size = 0;
1608 
1609 	sprintf(buf, "ampdu_len(0)=%d, (1)=%d\n", ampdu_len[0], ampdu_len[1]);
1610 	size = strlen(buf);
1611 
1612 	return simple_read_from_buffer(user_buf, count, ppos, buf, size);
1613 }
1614 
1615 static const struct file_operations fops_ampdu_len = {
1616 	.open = xradio_generic_open,
1617 	.write = xradio_ampdu_len_write,
1618 	.read = xradio_ampdu_len_read,
1619 	.llseek = default_llseek,
1620 };
1621 
1622 
1623 /* setting rts threshold. */
1624 u32 rts_threshold[2] = {3000, 3000};
xradio_rts_threshold_get(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)1625 static ssize_t xradio_rts_threshold_get(struct file *file,
1626 	char __user *user_buf, size_t count, loff_t *ppos)
1627 {
1628 	/* struct xradio_common *hw_priv = file->private_data; */
1629 	char buf[100];
1630 	size_t size = 0;
1631 
1632 	sprintf(buf, "rts_threshold(0)=%d, (1)=%d\n",
1633 		rts_threshold[0], rts_threshold[1]);
1634 	size = strlen(buf);
1635 
1636 	return simple_read_from_buffer(user_buf, count, ppos, buf, size);
1637 }
1638 
xradio_rts_threshold_set(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)1639 static ssize_t xradio_rts_threshold_set(struct file *file,
1640 	const char __user *user_buf, size_t count, loff_t *ppos)
1641 {
1642 	struct xradio_common *hw_priv = file->private_data;
1643 	char buf[12] = { 0 };
1644 	char *endptr = NULL;
1645 	u8 if_id = 0;
1646 
1647 	count = (count > 11 ? 11 : count);
1648 	if (!count)
1649 		return -EINVAL;
1650 	if (copy_from_user(buf, user_buf, count))
1651 		return -EFAULT;
1652 	if_id = simple_strtoul(buf, &endptr, 10);
1653 	rts_threshold[if_id] = simple_strtoul(endptr + 1, NULL, 10);
1654 
1655 	xradio_dbg(XRADIO_DBG_ALWY, "vif=%d, rts_threshold = %d\n",
1656 		   if_id, rts_threshold[if_id]);
1657 	wsm_write_mib(hw_priv, WSM_MIB_ID_DOT11_RTS_THRESHOLD,
1658 		      &rts_threshold[if_id], sizeof(u32), if_id);
1659 
1660 	return count;
1661 }
1662 
1663 static const struct file_operations fops_rts_threshold = {
1664 	.open = xradio_generic_open,
1665 	.write = xradio_rts_threshold_set,
1666 	.read = xradio_rts_threshold_get,
1667 	.llseek = default_llseek,
1668 };
1669 
1670 /* disable low power mode. */
1671 u8 low_pwr_disable;
xradio_low_pwr_get(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)1672 static ssize_t xradio_low_pwr_get(struct file *file,
1673 	char __user *user_buf, size_t count, loff_t *ppos)
1674 {
1675 	/* struct xradio_common *hw_priv = file->private_data; */
1676 	char buf[100];
1677 	size_t size = 0;
1678 
1679 	sprintf(buf, "low_pwr_disable=%d\n", low_pwr_disable);
1680 	size = strlen(buf);
1681 
1682 	return simple_read_from_buffer(user_buf, count, ppos, buf, size);
1683 }
1684 
xradio_low_pwr_set(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)1685 static ssize_t xradio_low_pwr_set(struct file *file,
1686 	const char __user *user_buf, size_t count, loff_t *ppos)
1687 {
1688 	struct xradio_common *hw_priv = file->private_data;
1689 	char buf[12] = { 0 };
1690 	char *endptr = NULL;
1691 	int if_id = 0;
1692 	u32 val = wsm_power_mode_quiescent;
1693 
1694 	count = (count > 11 ? 11 : count);
1695 	if (!count)
1696 		return -EINVAL;
1697 	if (copy_from_user(buf, user_buf, count))
1698 		return -EFAULT;
1699 	low_pwr_disable = simple_strtoul(buf, &endptr, 16);
1700 	xradio_dbg(XRADIO_DBG_ALWY, "low_pwr_disable=%d\n", low_pwr_disable);
1701 
1702 	if (low_pwr_disable)
1703 		val = wsm_power_mode_active;
1704 
1705 	val |= BIT(4);   /* disableMoreFlagUsage */
1706 
1707 	for (if_id = 0; if_id < xrwl_get_nr_hw_ifaces(hw_priv); if_id++)
1708 		wsm_write_mib(hw_priv, WSM_MIB_ID_OPERATIONAL_POWER_MODE, &val,
1709 				sizeof(val), if_id);
1710 
1711 	return count;
1712 }
1713 
1714 static const struct file_operations fops_low_pwr = {
1715 	.open = xradio_generic_open,
1716 	.write = xradio_low_pwr_set,
1717 	.read = xradio_low_pwr_get,
1718 	.llseek = default_llseek,
1719 };
1720 
1721 /* disable ps mode(80211 protol). */
xradio_ps_get(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)1722 static ssize_t xradio_ps_get(struct file *file,
1723 	char __user *user_buf, size_t count, loff_t *ppos)
1724 {
1725 	/* struct xradio_common *hw_priv = file->private_data; */
1726 	char buf[100];
1727 	size_t size = 0;
1728 
1729 	sprintf(buf, "ps_disable=%d, idleperiod=%d, changeperiod=%d\n",
1730 		ps_disable, ps_idleperiod, ps_changeperiod);
1731 	size = strlen(buf);
1732 
1733 	return simple_read_from_buffer(user_buf, count, ppos, buf, size);
1734 }
1735 
xradio_ps_set(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)1736 static ssize_t xradio_ps_set(struct file *file,
1737 	const char __user *user_buf, size_t count, loff_t *ppos)
1738 {
1739 	struct xradio_common *hw_priv = file->private_data;
1740 	char buf[20] = { 0 };
1741 	char *start = &buf[0];
1742 	char *endptr = NULL;
1743 	struct wsm_set_pm ps = {
1744 		.pmMode = WSM_PSM_FAST_PS,
1745 		.fastPsmIdlePeriod = 0xC8  /* defaut 100ms */
1746 	};
1747 
1748 	count = (count > 19 ? 19 : count);
1749 	if (!count)
1750 		return -EINVAL;
1751 	if (copy_from_user(buf, user_buf, count))
1752 		return -EFAULT;
1753 
1754 	ps_disable = simple_strtoul(start, &endptr, 10);
1755 	start = endptr + 1;
1756 	if (start < buf + count)
1757 		ps_idleperiod = simple_strtoul(start, &endptr, 10) & 0xff;
1758 	start = endptr + 1;
1759 	if (start < buf + count)
1760 		ps_changeperiod = simple_strtoul(start, &endptr, 10) & 0xff;
1761 
1762 	xradio_dbg(XRADIO_DBG_ALWY,
1763 		   "ps_disable=%d, idleperiod=%d, changeperiod=%d\n",
1764 		   ps_disable, ps_idleperiod, ps_changeperiod);
1765 
1766 	/* set pm for debug */
1767 	if (ps_disable)
1768 		ps.pmMode = WSM_PSM_ACTIVE;
1769 	if (ps_idleperiod)
1770 		ps.fastPsmIdlePeriod = ps_idleperiod << 1;
1771 	if (ps_changeperiod)
1772 		ps.apPsmChangePeriod = ps_changeperiod << 1;
1773 
1774 	wsm_set_pm(hw_priv, &ps, 0);
1775 	if (hw_priv->vif_list[1])
1776 		wsm_set_pm(hw_priv, &ps, 1);
1777 
1778 	return count;
1779 }
1780 
1781 static const struct file_operations fops_ps_ctrl = {
1782 	.open = xradio_generic_open,
1783 	.write = xradio_ps_set,
1784 	.read = xradio_ps_get,
1785 	.llseek = default_llseek,
1786 };
1787 
1788 /* for retry debug. */
1789 u8 retry_dbg;
1790 u8 tx_short;   /* save orgin value. */
1791 u8 tx_long;    /* save orgin value. */
1792 
xradio_retry_get(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)1793 static ssize_t xradio_retry_get(struct file *file,
1794 	char __user *user_buf, size_t count, loff_t *ppos)
1795 {
1796 	struct xradio_common *hw_priv = file->private_data;
1797 	char buf[100];
1798 	size_t size = 0;
1799 
1800 	sprintf(buf, "retry_dbg=%d, short=%d, long=%d\n", retry_dbg,
1801 		hw_priv->short_frame_max_tx_count,
1802 		hw_priv->long_frame_max_tx_count);
1803 	size = strlen(buf);
1804 
1805 	return simple_read_from_buffer(user_buf, count, ppos, buf, size);
1806 }
1807 
xradio_retry_set(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)1808 static ssize_t xradio_retry_set(struct file *file,
1809 	const char __user *user_buf, size_t count, loff_t *ppos)
1810 {
1811 	struct xradio_common *hw_priv = file->private_data;
1812 	char buf[20] = { 0 };
1813 	char *start = &buf[0];
1814 	char *endptr = NULL;
1815 
1816 	count = (count > 19 ? 19 : count);
1817 	if (!count)
1818 		return -EINVAL;
1819 	if (copy_from_user(buf, user_buf, count))
1820 		return -EFAULT;
1821 	retry_dbg = (simple_strtoul(start, &endptr, 10) & 0x1);
1822 	if (retry_dbg) { /* change retry.*/
1823 		if (!tx_short)
1824 			tx_short = hw_priv->short_frame_max_tx_count;
1825 		if (!tx_long)
1826 			tx_long = hw_priv->long_frame_max_tx_count;
1827 		start = endptr + 1;
1828 		if (start < buf + count) {
1829 			hw_priv->short_frame_max_tx_count =
1830 			    simple_strtoul(start, &endptr, 10) & 0xf;
1831 			start = endptr + 1;
1832 			if (start < buf + count)
1833 				hw_priv->long_frame_max_tx_count =
1834 				    simple_strtoul(start, &endptr, 10) & 0xf;
1835 		}
1836 		xradio_dbg(XRADIO_DBG_ALWY, "retry_dbg on, s=%d, l=%d\n",
1837 			  hw_priv->short_frame_max_tx_count,
1838 			  hw_priv->long_frame_max_tx_count);
1839 	} else {  /* restore retry. */
1840 		if (tx_short) {
1841 			hw_priv->short_frame_max_tx_count = tx_short;
1842 			tx_short = 0;
1843 		}
1844 		if (tx_long) {
1845 			hw_priv->long_frame_max_tx_count = tx_long;
1846 			tx_long = 0;
1847 		}
1848 		xradio_dbg(XRADIO_DBG_ALWY, "retry_dbg off, s=%d, l=%d\n",
1849 			  hw_priv->short_frame_max_tx_count,
1850 			  hw_priv->long_frame_max_tx_count);
1851 	}
1852 	retry_dbg |= 0x2;
1853 	return count;
1854 }
1855 
1856 static const struct file_operations fops_retry_ctrl = {
1857 	.open = xradio_generic_open,
1858 	.write = xradio_retry_set,
1859 	.read = xradio_retry_get,
1860 	.llseek = default_llseek,
1861 };
1862 
1863 /* for rates debug. */
1864 
1865 #ifdef SUPPORT_HT40
1866 
1867 u8  rates_dbg_en;
1868 u16 rates_debug[6] = {0x0};
1869 u8  Ratecnt_dbg;
1870 
xradio_rates_get(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)1871 static ssize_t xradio_rates_get(struct file *file,
1872 	char __user *user_buf, size_t count, loff_t *ppos)
1873 {
1874 	/* struct xradio_common *hw_priv = file->private_data; */
1875 	char buf[200];
1876 	size_t size = 0;
1877 	sprintf(buf, "rates_dbg_en=%d, [0]=0x%04x, [1]=0x%04x, [2]=0x%04x " \
1878 		"[3]=0x%04x, [4]=0x%04x, [5]=0x%04x\n", (rates_dbg_en & 0x1),
1879 		rates_debug[0], rates_debug[1], rates_debug[2],
1880 		rates_debug[3], rates_debug[4], rates_debug[5]);
1881 	size = strlen(buf);
1882 
1883 	return simple_read_from_buffer(user_buf, count, ppos, buf, size);
1884 }
1885 
xradio_rates_set(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)1886 static ssize_t xradio_rates_set(struct file *file,
1887 	const char __user *user_buf, size_t count, loff_t *ppos)
1888 {
1889 	/* struct xradio_common *hw_priv = file->private_data; */
1890 	char buf[50] = {0};
1891 	char *start  = &buf[0];
1892 	char *endptr = NULL;
1893 	int i = 0;
1894 	count = (count > 49 ? 49 : count);
1895 
1896 	if (!count)
1897 		return -EINVAL;
1898 	if (copy_from_user(buf, user_buf, count))
1899 		return -EFAULT;
1900 
1901 	rates_dbg_en &= ~0x1;
1902 	if (simple_strtoul(start, &endptr, 10)) {
1903 		for (i = 0; i < 6; i++) {
1904 			start = endptr+1;
1905 			if (start < buf+count)
1906 				rates_debug[i] = simple_strtoul(start, &endptr, 16);
1907 			else
1908 				break;
1909 		}
1910 
1911 		Ratecnt_dbg  = i;
1912 		rates_dbg_en = 0x1;
1913 
1914 		if (Ratecnt_dbg)
1915 			xradio_dbg(XRADIO_DBG_ERROR, "rates_dbg on, entry_cnt=%d!\n", Ratecnt_dbg);
1916 		else
1917 			xradio_dbg(XRADIO_DBG_ERROR, "rates_dbg fail, invaid params!\n");
1918 
1919 	} else {
1920 		xradio_dbg(XRADIO_DBG_ERROR, "rates_dbg off\n");
1921 	}
1922 	return count;
1923 }
1924 
1925 #else
1926 
1927 u8 rates_dbg_en;
1928 u32 rates_debug[3];
1929 u8  maxRate_dbg;
1930 
xradio_rates_get(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)1931 static ssize_t xradio_rates_get(struct file *file,
1932 	char __user *user_buf, size_t count, loff_t *ppos)
1933 {
1934 	/* struct xradio_common *hw_priv = file->private_data; */
1935 	char buf[100];
1936 	size_t size = 0;
1937 	sprintf(buf, "rates_dbg_en=%d, [0]=0x%08x, [1]=0x%08x, [2]=0x%08x\n",
1938 		(rates_dbg_en & 0x1), rates_debug[2],
1939 		 rates_debug[1], rates_debug[0]);
1940 	size = strlen(buf);
1941 
1942 	return simple_read_from_buffer(user_buf, count, ppos, buf, size);
1943 }
1944 
xradio_rates_set(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)1945 static ssize_t xradio_rates_set(struct file *file,
1946 	const char __user *user_buf, size_t count, loff_t *ppos)
1947 {
1948 	/* struct xradio_common *hw_priv = file->private_data; */
1949 	char buf[50] = { 0 };
1950 	char *start = &buf[0];
1951 	char *endptr = NULL;
1952 	int i = 0;
1953 	count = (count > 49 ? 49 : count);
1954 
1955 	if (!count)
1956 		return -EINVAL;
1957 	if (copy_from_user(buf, user_buf, count))
1958 		return -EFAULT;
1959 
1960 	rates_dbg_en &= ~0x1;
1961 	if (simple_strtoul(start, &endptr, 10)) {
1962 		start = endptr + 1;
1963 		if (start < buf + count)
1964 			rates_debug[2] = simple_strtoul(start, &endptr, 16);
1965 
1966 		start = endptr + 1;
1967 		if (start < buf + count)
1968 			rates_debug[1] = simple_strtoul(start, &endptr, 16);
1969 
1970 		start = endptr + 1;
1971 		if (start < buf + count)
1972 			rates_debug[0] = simple_strtoul(start, &endptr, 16);
1973 
1974 		for (i = 21; i >= 0; i--) {
1975 			if ((rates_debug[i >> 3] >> ((i & 0x7) << 2)) & 0xf) {
1976 				maxRate_dbg = i;
1977 				rates_dbg_en |= 0x1;
1978 				break;
1979 			}
1980 		}
1981 		if (rates_dbg_en & 0x1) {
1982 			xradio_dbg(XRADIO_DBG_ALWY,
1983 				   "rates_dbg on, maxrate=%d!\n", maxRate_dbg);
1984 		} else {
1985 			xradio_dbg(XRADIO_DBG_ALWY, "rates_dbg fail, invaid params!\n");
1986 		}
1987 	} else {
1988 		xradio_dbg(XRADIO_DBG_ALWY, "rates_dbg off\n");
1989 	}
1990 	return count;
1991 }
1992 
1993 #endif
1994 
1995 static const struct file_operations fops_rates_ctrl = {
1996 	.open = xradio_generic_open,
1997 	.write = xradio_rates_set,
1998 	.read = xradio_rates_get,
1999 	.llseek = default_llseek,
2000 };
2001 
2002 
2003 /* for backoff setting. */
2004 struct wsm_backoff_ctrl backoff_ctrl;
2005 
xradio_backoff_ctrl_get(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)2006 static ssize_t xradio_backoff_ctrl_get(struct file *file,
2007 	char __user *user_buf, size_t count, loff_t *ppos)
2008 {
2009 	/* struct xradio_common *hw_priv = file->private_data; */
2010 	char buf[100];
2011 	size_t size = 0;
2012 	sprintf(buf, "backoff_ctrl_en=%d, min=%d, max=%d\n",
2013 		backoff_ctrl.enable,
2014 		backoff_ctrl.min,
2015 		backoff_ctrl.max);
2016 	size = strlen(buf);
2017 
2018 	return simple_read_from_buffer(user_buf, count, ppos, buf, size);
2019 }
2020 
xradio_backoff_ctrl_set(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)2021 static ssize_t xradio_backoff_ctrl_set(struct file *file,
2022 	const char __user *user_buf, size_t count, loff_t *ppos)
2023 {
2024 	struct xradio_common *hw_priv = file->private_data;
2025 	char buf[20] = { 0 };
2026 	char *start = &buf[0];
2027 	char *endptr = NULL;
2028 	count = (count > 19 ? 19 : count);
2029 
2030 	if (!count)
2031 		return -EINVAL;
2032 	if (copy_from_user(buf, user_buf, count))
2033 		return -EFAULT;
2034 	backoff_ctrl.enable = simple_strtoul(start, &endptr, 10);
2035 	if (backoff_ctrl.enable) {
2036 		start = endptr + 1;
2037 		if (start < buf + count)
2038 			backoff_ctrl.min = simple_strtoul(start, &endptr, 10);
2039 		start = endptr + 1;
2040 		if (start < buf + count)
2041 			backoff_ctrl.max = simple_strtoul(start, &endptr, 10);
2042 
2043 		xradio_dbg(XRADIO_DBG_ALWY, "backoff_ctrl on\n");
2044 	} else {
2045 		xradio_dbg(XRADIO_DBG_ALWY, "backoff_ctrl off\n");
2046 	}
2047 	wsm_set_backoff_ctrl(hw_priv, &backoff_ctrl);
2048 	return count;
2049 }
2050 
2051 static const struct file_operations fops_backoff_ctrl = {
2052 	.open = xradio_generic_open,
2053 	.write = xradio_backoff_ctrl_set,
2054 	.read = xradio_backoff_ctrl_get,
2055 	.llseek = default_llseek,
2056 };
2057 
2058 /* for TALA(Tx-Ampdu-Len-Adaption) setting. */
2059 struct wsm_tala_para tala_para;
xradio_tala_get(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)2060 static ssize_t xradio_tala_get(struct file *file,
2061 	char __user *user_buf, size_t count, loff_t *ppos)
2062 {
2063 	/* struct xradio_common *hw_priv = file->private_data; */
2064 	char buf[100];
2065 	size_t size = 0;
2066 	sprintf(buf, "tala_para=0x%08x, tala_thresh=0x%08x\n",
2067 		tala_para.para, tala_para.thresh);
2068 	size = strlen(buf);
2069 
2070 	return simple_read_from_buffer(user_buf, count, ppos, buf, size);
2071 }
2072 
xradio_tala_set(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)2073 static ssize_t xradio_tala_set(struct file *file,
2074 	const char __user *user_buf, size_t count, loff_t *ppos)
2075 {
2076 	struct xradio_common *hw_priv = file->private_data;
2077 	char buf[30] = { 0 };
2078 	char *start = &buf[0];
2079 	char *endptr = NULL;
2080 	count = (count > 29 ? 29 : count);
2081 
2082 	if (!count)
2083 		return -EINVAL;
2084 	if (copy_from_user(buf, user_buf, count))
2085 		return -EFAULT;
2086 
2087 	if (start < buf + count)
2088 		tala_para.para = simple_strtoul(start, &endptr, 16);
2089 	start = endptr + 1;
2090 	if (start < buf + count)
2091 		tala_para.thresh = simple_strtoul(start, &endptr, 16);
2092 
2093 	wsm_set_tala(hw_priv, &tala_para);
2094 	return count;
2095 }
2096 
2097 static const struct file_operations fops_tala_ctrl = {
2098 	.open = xradio_generic_open,
2099 	.write = xradio_tala_set,
2100 	.read = xradio_tala_get,
2101 	.llseek = default_llseek,
2102 };
2103 
2104 /* Tx power debug */
2105 char buf_show[1024] = { 0 };
2106 
2107 typedef struct _PWR_INFO_TBL {
2108 	u8 Index;
2109 	u8 u8Complete;
2110 	s16 s16TargetPwr;
2111 	s16 s16AdjustedPower;
2112 	s16 s16SmthErrTerm;
2113 	u32 u32Count;
2114 	u16 u16PpaVal;
2115 	u16 u16DigVal;
2116 } PWR_CTRL_TBL;
2117 struct _TX_PWR_SHOW {
2118 	u8 InfoID;
2119 	u8 Status;
2120 	u16 reserved;
2121 	PWR_CTRL_TBL table[16];
2122 } pwr_ctrl;
xradio_tx_pwr_show(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)2123 static ssize_t xradio_tx_pwr_show(struct file *file,
2124 	char __user *user_buf, size_t count, loff_t *ppos)
2125 {
2126 	struct xradio_common *hw_priv = file->private_data;
2127 
2128 	int pos = 0, i = 0;
2129 	pwr_ctrl.InfoID = 0x1;
2130 	wsm_read_mib(hw_priv, WSM_MIB_ID_TX_POWER_INFO,
2131 		     (void *)&pwr_ctrl, sizeof(pwr_ctrl), 4);
2132 
2133 	if (pwr_ctrl.Status) {
2134 		pos += sprintf(&buf_show[pos],
2135 			       "read TX_POWER_INFO error=%x\n",
2136 				pwr_ctrl.Status);
2137 	} else {
2138 		for (i = 0; i < 16; i++) {
2139 			pos += sprintf(&buf_show[pos], "M%d:%d, ALG=%d, DIG=%d\n", i,
2140 				       pwr_ctrl.table[i].s16AdjustedPower,
2141 				       pwr_ctrl.table[i].u16PpaVal,
2142 				       pwr_ctrl.table[i].u16DigVal);
2143 		}
2144 	}
2145 	return simple_read_from_buffer(user_buf, count, ppos, buf_show, pos);
2146 }
2147 
xradio_tx_pwr_set(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)2148 static ssize_t xradio_tx_pwr_set(struct file *file,
2149 	const char __user *user_buf, size_t count, loff_t *ppos)
2150 {
2151 	/* struct xradio_common *hw_priv = file->private_data; */
2152 	return count;
2153 }
2154 
2155 static const struct file_operations fops_tx_pwr_ctrl = {
2156 	.open = xradio_generic_open,
2157 	.write = xradio_tx_pwr_set,
2158 	.read = xradio_tx_pwr_show,
2159 	.llseek = default_llseek,
2160 };
2161 
2162 /* TPA debug */
2163 #define CASE_NUM   9
2164 #define MAX_POINTS 4
2165 #define PWR_LEVEL_NUM 40
2166 #define MODULN_NUM 11
2167 typedef struct tag_pwr_modulation {
2168 	u8      def_pwr_idx;  /* default power index of modulation.*/
2169 	u8      max_pwr_idx;  /* max power index of modulation.*/
2170 	u8      mid_pwr_idx;  /* power index of middle point.*/
2171 	u8      cur_point;    /* current sample point.*/
2172 
2173 	u8      max_point;   /* the point has max q value.*/
2174 	u8      max_stable;  /* counter of stable max of the same point.*/
2175 	u8      exception;   /* the counter of exception case.*/
2176 	u8      listen_def;  /* whether to listen to default point.*/
2177 
2178 	u16     mod_smp_cnt;   /* total sample of the modulation.*/
2179 	u16     update_cnt;    /* counter of power update.*/
2180 	u32     update_time;   /* last time of power update.*/
2181 	u16     smp_points[MAX_POINTS*2];
2182 
2183 	u8      reserved;
2184 	u8      last_rate;
2185 	u16     last_max_Q;
2186 } PWR_MODULN;
2187 
2188 typedef struct tag_tpa_debug {
2189 	u32     update_total[MODULN_NUM];
2190 	u32     power_sum[MODULN_NUM];
2191 
2192 	u16     smp_case[CASE_NUM]; /* counter of every case.*/
2193 	u16     reserved0;
2194 	u16     smp_move_cnt[MAX_POINTS];    /* counter of movement of update power.*/
2195 	u16     max_point_cnt[MAX_POINTS];   /* counter of max point.*/
2196 
2197 	u16     smp_thresh_q_cnt;
2198 	u16     smp_timeout;
2199 	u16     smp_listdef_cnt;
2200 	u16     smp_excep_cnt;
2201 	u16     smp_stable_cnt;
2202 
2203 	u8      reserved2;
2204 	u8      smp_last_moduln;
2205 	u16     point_last_smp[MAX_POINTS*2];  /* Q value of point last update.*/
2206 } TPA_DEBUG_INFO;
2207 
2208 typedef struct tag_tpa_control {
2209 	u8      tpa_enable;
2210 	u8      tpa_initialized;
2211 	u8      point_interval;
2212 	u8      point_step;
2213 
2214 	u16     thresh_q;
2215 	u16     thresh_time;
2216 	u16     thresh_update;
2217 	u8      thresh_def_lstn;
2218 	u8      thresh_stable;
2219 	u8      pwr_level[PWR_LEVEL_NUM];
2220 } TPA_CONTROL;
2221 
2222 struct _TPA_INFO {
2223 	u8  InfoID;
2224 	u8  Status;
2225 	u8  node;
2226 	u8  reserved;
2227 	union {
2228 		TPA_DEBUG_INFO debug;
2229 		TPA_CONTROL    ctrl;
2230 		PWR_MODULN moduln[MODULN_NUM];
2231 	} u;
2232 } tpa_info;
xradio_tpa_ctrl_get(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)2233 static ssize_t xradio_tpa_ctrl_get(struct file *file,
2234 	char __user *user_buf, size_t count, loff_t *ppos)
2235 {
2236 	struct xradio_common *hw_priv = file->private_data;
2237 	int pos = 0, i = 0;
2238 	memset(&tpa_info, 0, sizeof(tpa_info));
2239 	tpa_info.InfoID = 0x03;
2240 	tpa_info.node   = 0;
2241 	wsm_read_mib(hw_priv, WSM_MIB_ID_TPA_DEBUG_INFO,
2242 		     (void *)&tpa_info, sizeof(tpa_info), 4);
2243 
2244 	if (tpa_info.Status && tpa_info.InfoID != 0x43) {
2245 		pos += sprintf(&buf_show[pos],
2246 			       "read TPA_DEBUG_INFO error=%x\n",
2247 			       tpa_info.Status);
2248 	} else {
2249 		u8  *pwr = &tpa_info.u.ctrl.pwr_level[0];
2250 
2251 		pos += sprintf(&buf_show[pos],
2252 			       "en=%d, init=%d, intvl=%d, step=%d\n",
2253 			       tpa_info.u.ctrl.tpa_enable,
2254 			       tpa_info.u.ctrl.tpa_initialized,
2255 			       tpa_info.u.ctrl.point_interval,
2256 			       tpa_info.u.ctrl.point_step);
2257 		pos += sprintf(&buf_show[pos], "th_q=%d, th_tm=%d, th_updt=%d, " \
2258 			       "th_def_lstn=%d, th_stbl=%d\n",
2259 			       tpa_info.u.ctrl.thresh_q,
2260 			       tpa_info.u.ctrl.thresh_time,
2261 			       tpa_info.u.ctrl.thresh_update,
2262 			       tpa_info.u.ctrl.thresh_def_lstn,
2263 			       tpa_info.u.ctrl.thresh_stable);
2264 	  for (i = 0; i < 4; i++) {
2265 			pos += sprintf(&buf_show[pos],
2266 				       "pwr lvl=%d.%d, %d.%d, %d.%d, %d.%d\n",
2267 				       pwr[0]>>3, ((pwr[0]%8)*100)>>3,
2268 				       pwr[1]>>3, ((pwr[1]%8)*100)>>3,
2269 				       pwr[2]>>3, ((pwr[2]%8)*100)>>3,
2270 				       pwr[3]>>3, ((pwr[3]%8)*100)>>3);
2271 			pwr += 4;
2272 		}
2273 	}
2274 	return simple_read_from_buffer(user_buf, count, ppos, buf_show, pos);
2275 }
2276 
2277 struct TPA_CONTROL_SET {
2278 	u8      tpa_enable;
2279 	u8      reserved;
2280 	u8      point_interval;
2281 	u8      point_step;
2282 
2283 	u16     thresh_q;
2284 	u16     thresh_time;
2285 	u16     thresh_update;
2286 	u8      thresh_def_lstn;
2287 	u8      thresh_stable;
2288 } tpa_ctrl_set;
xradio_tpa_ctrl_set(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)2289 static ssize_t xradio_tpa_ctrl_set(struct file *file,
2290 	const char __user *user_buf, size_t count, loff_t *ppos)
2291 {
2292 	struct xradio_common *hw_priv = file->private_data;
2293 	char buffer[256] = { 0 };
2294 	char *buf = &buffer[0];
2295 	u16 buf_size = (count > 255 ? 255 : count);
2296 	char *startptr = &buffer[0];
2297 	char *endptr = NULL;
2298 
2299 	if (!count)
2300 		return -EINVAL;
2301 	if (copy_from_user(buf, user_buf, buf_size))
2302 		return -EFAULT;
2303 
2304 
2305 	if ((buf + buf_size) > endptr) {
2306 		tpa_ctrl_set.tpa_enable = simple_strtoul(startptr, &endptr, 10);
2307 		startptr = endptr + 1;
2308 	}
2309 	if ((buf + buf_size) > endptr) {
2310 		tpa_ctrl_set.point_interval = simple_strtoul(startptr, &endptr, 10);
2311 		startptr = endptr + 1;
2312 	}
2313 	if ((buf + buf_size) > endptr) {
2314 		tpa_ctrl_set.point_step = simple_strtoul(startptr, &endptr, 10);
2315 		startptr = endptr + 1;
2316 	}
2317 
2318 	if ((buf + buf_size) > endptr) {
2319 		tpa_ctrl_set.thresh_q = simple_strtoul(startptr, &endptr, 10);
2320 		startptr = endptr + 1;
2321 	}
2322 	if ((buf + buf_size) > endptr) {
2323 		tpa_ctrl_set.thresh_time = simple_strtoul(startptr, &endptr, 10);
2324 		startptr = endptr + 1;
2325 	}
2326 	if ((buf + buf_size) > endptr) {
2327 		tpa_ctrl_set.thresh_update = simple_strtoul(startptr, &endptr, 10);
2328 		startptr = endptr + 1;
2329 	}
2330 	if ((buf + buf_size) > endptr) {
2331 		tpa_ctrl_set.thresh_def_lstn = simple_strtoul(startptr, &endptr, 10);
2332 		startptr = endptr + 1;
2333 	}
2334 	if ((buf + buf_size) > endptr) {
2335 		tpa_ctrl_set.thresh_stable = simple_strtoul(startptr, &endptr, 10);
2336 		startptr = endptr + 1;
2337 	}
2338 	wsm_write_mib(hw_priv, WSM_MIB_ID_SET_TPA_PARAM,
2339 		      (void *)&tpa_ctrl_set, sizeof(tpa_ctrl_set), 0);
2340 
2341 	return count;
2342 }
2343 
2344 static const struct file_operations fops_tpa_ctrl = {
2345 	.open = xradio_generic_open,
2346 	.write = xradio_tpa_ctrl_set,
2347 	.read = xradio_tpa_ctrl_get,
2348 	.llseek = default_llseek,
2349 };
2350 
2351 u8 tpa_node_dbg;
xradio_tpa_debug(struct seq_file * seq,void * v)2352 static int xradio_tpa_debug(struct seq_file *seq, void *v)
2353 {
2354 	int ret, i;
2355 	struct xradio_common *hw_priv = seq->private;
2356 
2357 #define PUT_TPA_MODULN(tab, name) \
2358 	seq_printf(seq, tab":\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", \
2359 		   __le32_to_cpu(tpa_info.u.moduln[0].name), \
2360 		   __le32_to_cpu(tpa_info.u.moduln[1].name), \
2361 		   __le32_to_cpu(tpa_info.u.moduln[2].name), \
2362 		   __le32_to_cpu(tpa_info.u.moduln[3].name), \
2363 		   __le32_to_cpu(tpa_info.u.moduln[4].name), \
2364 		   __le32_to_cpu(tpa_info.u.moduln[5].name), \
2365 		   __le32_to_cpu(tpa_info.u.moduln[6].name), \
2366 		   __le32_to_cpu(tpa_info.u.moduln[7].name), \
2367 		   __le32_to_cpu(tpa_info.u.moduln[8].name), \
2368 		   __le32_to_cpu(tpa_info.u.moduln[9].name), \
2369 		   __le32_to_cpu(tpa_info.u.moduln[10].name))
2370 
2371 	tpa_info.InfoID = 0x01;
2372 	tpa_info.node = tpa_node_dbg;
2373 	ret = wsm_read_mib(hw_priv, WSM_MIB_ID_TPA_DEBUG_INFO,
2374 			   (void *)&tpa_info, sizeof(tpa_info), 4);
2375 
2376 	if (tpa_info.Status && tpa_info.InfoID != 0x41) {
2377 		seq_printf(seq, "read TPA_DEBUG_INFO error=%x\n", tpa_info.Status);
2378 	} else {
2379 		seq_printf(seq, "\t\tm0\tm1\tm2\tm3\tm4\tm5\tm6\tm7\tm8\tm9\tm10\t\n");
2380 
2381 		PUT_TPA_MODULN("max_idx", max_pwr_idx);
2382 		PUT_TPA_MODULN("def_idx", def_pwr_idx);
2383 		PUT_TPA_MODULN("mid_idx", mid_pwr_idx);
2384 		PUT_TPA_MODULN("cur_pt ", cur_point);
2385 		PUT_TPA_MODULN("max_pt ", max_point);
2386 		PUT_TPA_MODULN("stable ", max_stable);
2387 		PUT_TPA_MODULN("exceptn", exception);
2388 		PUT_TPA_MODULN("listen ", listen_def);
2389 		PUT_TPA_MODULN("smp_cnt", mod_smp_cnt);
2390 		PUT_TPA_MODULN("update ", update_cnt);
2391 
2392 		PUT_TPA_MODULN("pt[0]  ", smp_points[0]);
2393 		PUT_TPA_MODULN("pt[0]  ", smp_points[1]);
2394 		PUT_TPA_MODULN("pt[1]  ", smp_points[2]);
2395 		PUT_TPA_MODULN("pt[1]  ", smp_points[3]);
2396 		PUT_TPA_MODULN("pt[2]  ", smp_points[4]);
2397 		PUT_TPA_MODULN("pt[2]  ", smp_points[5]);
2398 		PUT_TPA_MODULN("pt[3]  ", smp_points[6]);
2399 		PUT_TPA_MODULN("pt[3]  ", smp_points[7]);
2400 
2401 		PUT_TPA_MODULN("rate   ", last_rate);
2402 		PUT_TPA_MODULN("Max Q  ", last_max_Q);
2403 	}
2404 #undef PUT_TPA_MODULN
2405 
2406 #define SMP_CASE(i)    __le32_to_cpu(tpa_info.u.debug.smp_case[i])
2407 #define PWR_LVL_S(n)  (tpa_info.u.debug.power_sum[n]>>3)
2408 
2409 
2410 	tpa_info.InfoID = 0x02;
2411 	tpa_info.node = tpa_node_dbg;
2412 	ret = wsm_read_mib(hw_priv, WSM_MIB_ID_TPA_DEBUG_INFO,
2413 			   (void *)&tpa_info, sizeof(tpa_info), 4);
2414 
2415 	if (tpa_info.Status && tpa_info.InfoID != 0x42) {
2416 		seq_printf(seq, "read TPA_DEBUG_INFO error=%x\n", tpa_info.Status);
2417 	} else {
2418 		for (i = 0; i < MODULN_NUM; i++) {
2419 			if (tpa_info.u.debug.update_total[i])
2420 				tpa_info.u.debug.power_sum[i] /=
2421 				    tpa_info.u.debug.update_total[i];
2422 			else
2423 				tpa_info.u.debug.power_sum[i] = 0;
2424 		}
2425 		seq_printf(seq, "\nupdate_total:\t%d\t%d\t%d\t%d\t" \
2426 			   "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", \
2427 			   __le32_to_cpu(tpa_info.u.debug.update_total[0]), \
2428 			   __le32_to_cpu(tpa_info.u.debug.update_total[1]), \
2429 			   __le32_to_cpu(tpa_info.u.debug.update_total[2]), \
2430 			   __le32_to_cpu(tpa_info.u.debug.update_total[3]), \
2431 			   __le32_to_cpu(tpa_info.u.debug.update_total[4]), \
2432 			   __le32_to_cpu(tpa_info.u.debug.update_total[5]), \
2433 			   __le32_to_cpu(tpa_info.u.debug.update_total[6]), \
2434 			   __le32_to_cpu(tpa_info.u.debug.update_total[7]), \
2435 			   __le32_to_cpu(tpa_info.u.debug.update_total[8]), \
2436 			   __le32_to_cpu(tpa_info.u.debug.update_total[9]), \
2437 			   __le32_to_cpu(tpa_info.u.debug.update_total[10]));
2438 
2439 		seq_printf(seq, "pwr_avrg:\t%d\t%d\t%d\t%d\t%d\t%d\t"
2440 				"%d\t%d\t%d\t%d\t%d\n", \
2441 			   PWR_LVL_S(0), \
2442 			   PWR_LVL_S(1), \
2443 			   PWR_LVL_S(2), \
2444 			   PWR_LVL_S(3), \
2445 			   PWR_LVL_S(4), \
2446 			   PWR_LVL_S(5), \
2447 			   PWR_LVL_S(6), \
2448 			   PWR_LVL_S(7), \
2449 			   PWR_LVL_S(8), \
2450 			   PWR_LVL_S(9), \
2451 			   PWR_LVL_S(10));
2452 
2453 		seq_printf(seq, "SMP_CASE: %d, %d, %d, %d(E), " \
2454 			   "%d, %d, %d(E), %d(E), %d\n",
2455 			   SMP_CASE(0), SMP_CASE(1), SMP_CASE(2), SMP_CASE(3),
2456 			   SMP_CASE(4), SMP_CASE(5), SMP_CASE(6), SMP_CASE(7),
2457 			   SMP_CASE(8));
2458 		seq_printf(seq, "MAX: M=%d, L=%d, R=%d, D=%d\n",
2459 			   tpa_info.u.debug.max_point_cnt[0],
2460 			   tpa_info.u.debug.max_point_cnt[1],
2461 			   tpa_info.u.debug.max_point_cnt[2],
2462 			   tpa_info.u.debug.max_point_cnt[3]);
2463 		seq_printf(seq, "MOVE: M=%d, L=%d, R=%d, D=%d\n",
2464 			   tpa_info.u.debug.smp_move_cnt[0],
2465 			   tpa_info.u.debug.smp_move_cnt[1],
2466 			   tpa_info.u.debug.smp_move_cnt[2],
2467 			   tpa_info.u.debug.smp_move_cnt[3]);
2468 		seq_printf(seq, "listen=%d, timeout=%d, thresh_q=%d, " \
2469 			   "excep=%d, stable=%d\n",
2470 			   tpa_info.u.debug.smp_listdef_cnt,
2471 			   tpa_info.u.debug.smp_timeout,
2472 			   tpa_info.u.debug.smp_thresh_q_cnt,
2473 			   tpa_info.u.debug.smp_excep_cnt,
2474 			   tpa_info.u.debug.smp_stable_cnt);
2475 
2476 		seq_printf(seq, "lsat Moduln=%d, M=%d, %d; " \
2477 			   "L=%d, %d; R=%d, %d; D=%d, %d\n",
2478 			   tpa_info.u.debug.smp_last_moduln,
2479 			   tpa_info.u.debug.point_last_smp[0],
2480 			   tpa_info.u.debug.point_last_smp[1],
2481 			   tpa_info.u.debug.point_last_smp[2],
2482 			   tpa_info.u.debug.point_last_smp[3],
2483 			   tpa_info.u.debug.point_last_smp[4],
2484 			   tpa_info.u.debug.point_last_smp[5],
2485 			   tpa_info.u.debug.point_last_smp[6],
2486 			   tpa_info.u.debug.point_last_smp[7]);
2487 	}
2488 
2489 #undef PWR_LVL_S
2490 #undef SMP_CASE
2491 
2492 	return 0;
2493 }
2494 
xradio_tpa_debug_open(struct inode * inode,struct file * file)2495 static int xradio_tpa_debug_open(struct inode *inode, struct file *file)
2496 {
2497 	return single_open(file, &xradio_tpa_debug,
2498 		inode->i_private);
2499 }
2500 
2501 static const struct file_operations fops_tpa_debug = {
2502 	.open = xradio_tpa_debug_open,
2503 	.read = seq_read,
2504 	.llseek = seq_lseek,
2505 	.release = single_release,
2506 	.owner = THIS_MODULE,
2507 };
2508 
2509 /* policy_info */
2510 u32 tx_retrylimit;
2511 u32 tx_lower_limit;
2512 u32 tx_over_limit;
2513 int retry_mis;
2514 u32 policy_upload;
2515 u32 policy_num;
2516 
xradio_policy_info(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)2517 static ssize_t xradio_policy_info(struct file *file,
2518 	char __user *user_buf, size_t count, loff_t *ppos)
2519 {
2520 	/* struct xradio_common *hw_priv = file->private_data; */
2521 	char buf[256];
2522 	size_t size = 0;
2523 	sprintf(buf, "tx_retrylimit=%d, tx_lower_limit=%d, " \
2524 		"tx_over_limit=%d, retry_mis=%d\n" \
2525 		"policy_upload=%d, policy_num=%d\n",
2526 		tx_retrylimit, tx_lower_limit, tx_over_limit, retry_mis,
2527 		policy_upload, policy_num);
2528 	size = strlen(buf);
2529 
2530 	/* clear counters */
2531 	tx_retrylimit  = 0;
2532 	tx_lower_limit = 0;
2533 	tx_over_limit  = 0;
2534 	retry_mis      = 0;
2535 	policy_upload  = 0;
2536 	policy_num     = 0;
2537 
2538 	return simple_read_from_buffer(user_buf, count, ppos, buf, size);
2539 }
2540 
2541 static const struct file_operations fops_policy_info = {
2542 	.open   = xradio_generic_open,
2543 	.read   = xradio_policy_info,
2544 	.llseek = default_llseek,
2545 };
2546 
2547 /* info of interruption */
2548 u32 irq_count;
2549 u32 int_miss_cnt;
2550 u32 fix_miss_cnt;
2551 u32 next_rx_cnt;
2552 u32 rx_total_cnt;
2553 u32 tx_total_cnt;
2554 u32 tx_buf_limit;
2555 u32 tx_limit;
2556 u32 tx_rx_idle;
2557 u32 bh_idle;
2558 u32 queue_lock_cnt;
2559 u32 overfull_lock_cnt;
2560 u32 policy_lock_cnt;
2561 
xradio_bh_statistic(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)2562 static ssize_t xradio_bh_statistic(struct file *file,
2563 	char __user *user_buf, size_t count, loff_t *ppos)
2564 {
2565 	struct xradio_common *hw_priv = file->private_data;
2566 	char buf[512];
2567 	size_t size = 0;
2568 	sprintf(buf, "irq_count=%u, rx_total=%u, rx_miss=%u, "
2569 		"rx_fix=%u, rx_next=%u, rx_burst=%d, irq/rx=%u%%\n"
2570 		"tx_total=%u, tx_burst=%d, tx_limit=%u, tx_buf_limit=%u, "
2571 		"limit/tx=%u%%, buf_limit/limit=%u%%, tx_rx_idle=%u, bh_idle=%u\n"
2572 		"queue_lock_cnt=%u, overfull_lock_cnt=%u, policy_lock_cnt=%u\n",
2573 		irq_count, rx_total_cnt, int_miss_cnt, fix_miss_cnt,
2574 		next_rx_cnt, hw_priv->debug->rx_burst,
2575 		(rx_total_cnt ? irq_count*100/rx_total_cnt : 0),
2576 		tx_total_cnt, hw_priv->debug->tx_burst, tx_limit, tx_buf_limit,
2577 		(tx_total_cnt ? tx_limit*100/tx_total_cnt : 0),
2578 		(tx_limit ? tx_buf_limit*100/tx_limit : 0),
2579 		tx_rx_idle, bh_idle, queue_lock_cnt, overfull_lock_cnt,
2580 		policy_lock_cnt);
2581 	size = strlen(buf);
2582 
2583 	/*clear counters*/
2584 	irq_count    = 0;
2585 	int_miss_cnt = 0;
2586 	fix_miss_cnt = 0;
2587 	next_rx_cnt  = 0;
2588 	rx_total_cnt = 0;
2589 	tx_total_cnt = 0;
2590 	tx_buf_limit = 0;
2591 	tx_limit     = 0;
2592 	tx_rx_idle   = 0;
2593 	bh_idle      = 0;
2594 	queue_lock_cnt = 0;
2595 	overfull_lock_cnt = 0;
2596 	policy_lock_cnt = 0;
2597 	hw_priv->debug->rx_burst = 0;
2598 	hw_priv->debug->tx_burst = 0;
2599 
2600 	return simple_read_from_buffer(user_buf, count, ppos, buf, size);
2601 }
2602 
2603 static const struct file_operations fops_bh_stat = {
2604 	.open = xradio_generic_open,
2605 	.read = xradio_bh_statistic,
2606 	.llseek = default_llseek,
2607 };
2608 
2609 /* time info of bh tx and rx */
2610 #if PERF_INFO_TEST
perf_info_reset(struct perf_info * info)2611 static inline void perf_info_reset(struct perf_info *info)
2612 {
2613 	memset(info, 0, sizeof(struct perf_info));
2614 	info->min_time = (u32)-1;
2615 }
2616 struct perf_info data_tx;
2617 struct perf_info data_rx;
2618 struct perf_info bh_others;
2619 struct perf_info bh_wait;
2620 struct perf_info sdio_reg;
2621 struct perf_info prepare_tx;
2622 struct perf_info sdio_write;
2623 struct perf_info dev_wake;
2624 struct perf_info prepare_rx;
2625 struct perf_info sdio_read;
2626 struct perf_info handle_rx;
2627 
2628 #ifdef BH_PROC_THREAD
2629 struct perf_info get_item;
2630 struct perf_info wake_proc;
2631 struct perf_info proc_rx;
2632 struct perf_info proc_tx;
2633 struct perf_info proc_wait;
2634 #endif
2635 struct perf_info ind_rx;
2636 struct perf_info mac_rx;
2637 struct perf_info mac_tx;
2638 
2639 #if TEST_GETTIME
2640 struct perf_info get_time;
2641 #endif
2642 
2643 struct timespec64 last_showtime;
xradio_show_intv(struct timespec64 * showtime)2644 static inline u32 xradio_show_intv(struct timespec64 *showtime)
2645 {
2646 	u32 time_int;
2647 	struct timespec64 time_now;
2648 	xr_do_gettimeofday(&time_now);
2649 	time_int = (time_now.tv_sec - showtime->tv_sec) * 100000 + \
2650 			    (time_now.tv_usec - showtime->tv_usec) / 10;
2651 	xr_do_gettimeofday(showtime);
2652 	return time_int; /*10us*/
2653 }
2654 /*mac(26) + IV(8) + LLC(8) + IP(20) + TCP(20) or UDP(8)*/
2655 #define TX_OVERHEAD (sizeof(struct wsm_tx)+26+8+20+20)
2656 #define RX_OVERHEAD (12+26+8+20+20)
xradio_perf_info(struct seq_file * seq,void * v)2657 static int xradio_perf_info(struct seq_file *seq, void *v)
2658 {
2659 	/* struct xradio_common *hw_priv = seq->private; */
2660 	u32 time_int = xradio_show_intv(&last_showtime);
2661 	u32 txrx_time = data_tx.totaltime + data_rx.totaltime;
2662 	u32 real_tx = (data_tx.totalsize<<3)/107*10;
2663 	u32 real_rx = (data_rx.totalsize<<3)/106*10;
2664 	if (bh_others.totaltime > bh_wait.totaltime)
2665 		txrx_time += (bh_others.totaltime - bh_wait.totaltime);
2666 	else
2667 		txrx_time += sdio_reg.totaltime;
2668 
2669 
2670 #define PUT_PERF_INFO(tab, name) \
2671 	seq_printf(seq, "%s" tab "%d\t%d\t%d\t%d\t%d\t%d\t%d.%d\t%d.%02d%%\n", #name, \
2672 	name.count, name.totaltime, (name.totalsize>>3), name.min_time, name.max_time, \
2673 	name.count ? (name.totaltime/name.count) : 0, \
2674 	name.totaltime ? ((name.totalsize<<3)/name.totaltime) : 0, \
2675 	name.totaltime ? (((name.totalsize<<3)%name.totaltime)*10/name.totaltime) : 0, \
2676 	time_int ? (name.totaltime*10/time_int) : 0, \
2677 	time_int ? (((name.totaltime*10)%time_int)*100/time_int) : 0)
2678 
2679 	seq_printf(seq, "\nTime_int=%d, Tx=%d.%02dMbps, Rx=%d.%02dMbps, "
2680 		"RealTx=%d.%02dMbps, RealRx=%d.%02dMbps\n", time_int*10,
2681 		txrx_time ? ((data_tx.totalsize<<3)/txrx_time) : 0,
2682 		txrx_time ? ((data_tx.totalsize<<3)%txrx_time)*100/txrx_time : 0,
2683 		txrx_time ? ((data_rx.totalsize<<3)/txrx_time) : 0,
2684 		txrx_time ? ((data_rx.totalsize<<3)%txrx_time)*100/txrx_time : 0,
2685 		time_int ? (real_tx/time_int) : 0,
2686 		time_int ? (real_tx%time_int)*100/time_int : 0,
2687 		time_int ? (real_rx/time_int) : 0,
2688 		time_int ? (real_rx%time_int)*100/time_int : 0);
2689 	seq_printf(seq, "Items\t\tcnt\ttime\tsize(8)\tmin\tmax\tavg\tperf(M)\tduty\n");
2690 	PUT_PERF_INFO("\t\t", data_tx);
2691 	PUT_PERF_INFO("\t\t", data_rx);
2692 	PUT_PERF_INFO("\t\t", bh_wait);
2693 	PUT_PERF_INFO("\t",   sdio_reg);
2694 	PUT_PERF_INFO("\t",   prepare_tx);
2695 	PUT_PERF_INFO("\t",   sdio_write);
2696 	PUT_PERF_INFO("\t",   dev_wake);
2697 	PUT_PERF_INFO("\t",   prepare_rx);
2698 	PUT_PERF_INFO("\t",   sdio_read);
2699 	PUT_PERF_INFO("\t",   handle_rx);
2700 #ifdef BH_PROC_THREAD
2701 	PUT_PERF_INFO("\t",   get_item);
2702 	PUT_PERF_INFO("\t",   wake_proc);
2703 	PUT_PERF_INFO("\t\t", proc_rx);
2704 	PUT_PERF_INFO("\t\t", proc_tx);
2705 	PUT_PERF_INFO("\t",   proc_wait);
2706 #endif
2707 	PUT_PERF_INFO("\t\t", ind_rx);
2708 	PUT_PERF_INFO("\t\t", mac_rx);
2709 	PUT_PERF_INFO("\t\t", mac_tx);
2710 	PUT_PERF_INFO("\t",   bh_others);
2711 
2712 #if TEST_GETTIME
2713 	PUT_PERF_INFO("\t", get_time);
2714 #endif
2715 
2716 	seq_printf(seq, "reg_cnt1=%d, reg_cnt2=%d, reg_cnt3=%d, reg_cnt4=%d, "
2717 		"reg_fail1=%d, reg_fail2=%d\n",
2718 		sdio_reg_cnt1, sdio_reg_cnt2, sdio_reg_cnt3, sdio_reg_cnt4,
2719 		sdio_reg_cnt5, sdio_reg_cnt6);
2720 	seq_printf(seq, "limit_cnt1=%d, limit_cnt2=%d, "
2721 		"limit_cnt3=%d, limit_cnt4=%d, limit_cnt5=%d, limit_cnt6=%d\n",
2722 		tx_limit_cnt1, tx_limit_cnt2, tx_limit_cnt3,
2723 		tx_limit_cnt4, tx_limit_cnt5, tx_limit_cnt6);
2724 
2725 #if BH_PROC_DPA
2726 	seq_printf(seq, "proc_dpa_cnt=%d, proc_up_cnt=%d, proc_down_cnt=%d, prio=%d\n",
2727 			proc_dpa_cnt, proc_up_cnt, proc_down_cnt, hw_priv->proc.proc_prio);
2728 	proc_dpa_cnt = 0;
2729 	proc_up_cnt  = 0;
2730 	proc_down_cnt = 0;
2731 #endif
2732 
2733 	sdio_reg_cnt1 = 0;
2734 	sdio_reg_cnt2 = 0;
2735 	sdio_reg_cnt3 = 0;
2736 	sdio_reg_cnt4 = 0;
2737 	sdio_reg_cnt5 = 0;
2738 	sdio_reg_cnt6 = 0;
2739 
2740 	tx_limit_cnt1 = 0;
2741 	tx_limit_cnt2 = 0;
2742 	tx_limit_cnt3 = 0;
2743 	tx_limit_cnt4 = 0;
2744 	tx_limit_cnt5 = 0;
2745 	tx_limit_cnt6 = 0;
2746 
2747 
2748 #undef PUT_PERF_INFO
2749 
2750 	perf_info_reset(&data_tx);
2751 	perf_info_reset(&data_rx);
2752 	perf_info_reset(&bh_wait);
2753 	perf_info_reset(&sdio_reg);
2754 	perf_info_reset(&prepare_tx);
2755 	perf_info_reset(&sdio_write);
2756 	perf_info_reset(&dev_wake);
2757 	perf_info_reset(&prepare_rx);
2758 	perf_info_reset(&sdio_read);
2759 	perf_info_reset(&handle_rx);
2760 #ifdef BH_PROC_THREAD
2761 	perf_info_reset(&get_item);
2762 	perf_info_reset(&wake_proc);
2763 	perf_info_reset(&proc_rx);
2764 	perf_info_reset(&proc_tx);
2765 	perf_info_reset(&proc_wait);
2766 #endif
2767 	perf_info_reset(&ind_rx);
2768 	perf_info_reset(&mac_rx);
2769 	perf_info_reset(&mac_tx);
2770 	perf_info_reset(&bh_others);
2771 
2772 #if TEST_GETTIME
2773 	if (get_time.count > 10000)
2774 		perf_info_reset(&get_time);
2775 #endif
2776 
2777 	return 0;
2778 }
2779 
xradio_perf_info_open(struct inode * inode,struct file * file)2780 static int xradio_perf_info_open(struct inode *inode, struct file *file)
2781 {
2782 	return single_open(file, &xradio_perf_info, inode->i_private);
2783 }
2784 
2785 static const struct file_operations fops_perf_info = {
2786 	.open = xradio_perf_info_open,
2787 	.read = seq_read,
2788 	.llseek = seq_lseek,
2789 	.release = single_release,
2790 	.owner = THIS_MODULE,
2791 };
2792 #endif /* #if PERF_INFO_TEST */
2793 
2794 
2795 u32 dbg_txconfirm[32];
xradio_txconfirm_show(struct seq_file * seq,void * v)2796 static int xradio_txconfirm_show(struct seq_file *seq, void *v)
2797 {
2798 	int i;
2799 
2800 	for (i = 0; i < 8; i++) {
2801 		seq_printf(seq, "Txcfm%d:%d\t", i+1, dbg_txconfirm[i]);
2802 		seq_printf(seq, "Txcfm%d:%d\t", i+1+8, dbg_txconfirm[i+8]);
2803 		seq_printf(seq, "Txcfm%d:%d\t", i+1+16, dbg_txconfirm[i+16]);
2804 		seq_printf(seq, "Txcfm%d:%d\t\n", i+1+24, dbg_txconfirm[i+24]);
2805 		dbg_txconfirm[i]    = 0;
2806 		dbg_txconfirm[i+8]  = 0;
2807 		dbg_txconfirm[i+16] = 0;
2808 		dbg_txconfirm[i+24] = 0;
2809 	}
2810 	return 0;
2811 }
2812 
xradio_txconfirm_open(struct inode * inode,struct file * file)2813 static int xradio_txconfirm_open(struct inode *inode, struct file *file)
2814 {
2815 	return single_open(file, &xradio_txconfirm_show,
2816 		inode->i_private);
2817 }
2818 
2819 static const struct file_operations fops_txconfirm = {
2820 	.open = xradio_txconfirm_open,
2821 	.read = seq_read,
2822 	.llseek = seq_lseek,
2823 	.release = single_release,
2824 	.owner = THIS_MODULE,
2825 };
2826 
2827 u32 dbg_tx_delay_min = 0xffffffff;
2828 u32 dbg_tx_delay_max;
2829 u32 dbg_tx_media_delay[16];
xradio_debug_tx_delay(u32 media_delay,u32 queue_delay)2830 void xradio_debug_tx_delay(u32 media_delay, u32 queue_delay)
2831 {
2832 	if (media_delay < dbg_tx_delay_min)
2833 		dbg_tx_delay_min = media_delay;
2834 	if (media_delay > dbg_tx_delay_max)
2835 		dbg_tx_delay_max = media_delay;
2836 	if (media_delay <= 500)
2837 		dbg_tx_media_delay[0]++;
2838 	else if (media_delay <= 1000)
2839 		dbg_tx_media_delay[1]++;
2840 	else if (media_delay <= 10000)
2841 		dbg_tx_media_delay[2]++;
2842 	else if (media_delay <= 20000)
2843 		dbg_tx_media_delay[3]++;
2844 	else if (media_delay <= 30000)
2845 		dbg_tx_media_delay[4]++;
2846 	else if (media_delay <= 40000)
2847 		dbg_tx_media_delay[5]++;
2848 	else if (media_delay <= 50000)
2849 		dbg_tx_media_delay[6]++;
2850 	else if (media_delay <= 100000)
2851 		dbg_tx_media_delay[7]++;
2852 	else if (media_delay <= 150000)
2853 		dbg_tx_media_delay[8]++;
2854 	else if (media_delay <= 200000)
2855 		dbg_tx_media_delay[9]++;
2856 	else if (media_delay <= 300000)
2857 		dbg_tx_media_delay[10]++;
2858 	else if (media_delay <= 500000)
2859 		dbg_tx_media_delay[11]++;
2860 	else if (media_delay <= 1000000)
2861 		dbg_tx_media_delay[12]++;
2862 	else if (media_delay <= 3000000)
2863 		dbg_tx_media_delay[13]++;
2864 	else if (media_delay <= 15000000)
2865 		dbg_tx_media_delay[14]++;
2866 	else
2867 		xradio_dbg(XRADIO_DBG_WARN, "media_delay=%d, queue_delay=%d\n",
2868 		   media_delay, queue_delay);
2869 	if (media_delay >= 30000)
2870 		xradio_dbg(XRADIO_DBG_NIY, "media_delay=%d, queue_delay=%d\n",
2871 		   media_delay, queue_delay);
2872 }
xradio_tx_delay_show(struct seq_file * seq,void * v)2873 static int xradio_tx_delay_show(struct seq_file *seq, void *v)
2874 {
2875 	seq_printf(seq, "MinDelay %dus, MaxDelay=%dus\n", dbg_tx_delay_min, dbg_tx_delay_max);
2876 	seq_printf(seq, "Delay (0~0.5ms]   :%d\n", dbg_tx_media_delay[0]);
2877 	seq_printf(seq, "Delay (0.5~1ms]   :%d\n", dbg_tx_media_delay[1]);
2878 	seq_printf(seq, "Delay (1~10ms]    :%d\n", dbg_tx_media_delay[2]);
2879 	seq_printf(seq, "Delay (10~20ms]   :%d\n", dbg_tx_media_delay[3]);
2880 	seq_printf(seq, "Delay (20~30ms]   :%d\n", dbg_tx_media_delay[4]);
2881 	seq_printf(seq, "Delay (30~40ms]   :%d\n", dbg_tx_media_delay[5]);
2882 	seq_printf(seq, "Delay (40~50ms]   :%d\n", dbg_tx_media_delay[6]);
2883 	seq_printf(seq, "Delay (50~100ms]  :%d\n", dbg_tx_media_delay[7]);
2884 	seq_printf(seq, "Delay (100~150ms] :%d\n", dbg_tx_media_delay[8]);
2885 	seq_printf(seq, "Delay (150~200ms] :%d\n", dbg_tx_media_delay[9]);
2886 	seq_printf(seq, "Delay (200~300ms] :%d\n", dbg_tx_media_delay[10]);
2887 	seq_printf(seq, "Delay (300~500ms] :%d\n", dbg_tx_media_delay[11]);
2888 	seq_printf(seq, "Delay (500~1000ms]:%d\n", dbg_tx_media_delay[12]);
2889 	seq_printf(seq, "Delay (1~3s]      :%d\n", dbg_tx_media_delay[13]);
2890 	seq_printf(seq, "Delay (3~15s]     :%d\n", dbg_tx_media_delay[14]);
2891 
2892 	dbg_tx_delay_min = 0xffffffff;
2893 	dbg_tx_delay_max = 0;
2894 	memset(dbg_tx_media_delay, 0, sizeof(dbg_tx_media_delay));
2895 	return 0;
2896 }
2897 
xradio_tx_delay_open(struct inode * inode,struct file * file)2898 static int xradio_tx_delay_open(struct inode *inode, struct file *file)
2899 {
2900 	return single_open(file, &xradio_tx_delay_show,
2901 		inode->i_private);
2902 }
2903 
2904 static const struct file_operations fops_txdelay = {
2905 	.open = xradio_tx_delay_open,
2906 	.read = seq_read,
2907 	.llseek = seq_lseek,
2908 	.release = single_release,
2909 	.owner = THIS_MODULE,
2910 };
2911 
2912 /*for disable low power mode.*/
2913 extern u16 txparse_flags;
2914 extern u16 rxparse_flags;
xradio_parse_flags_get(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)2915 static ssize_t xradio_parse_flags_get(struct file *file,
2916 	char __user *user_buf, size_t count, loff_t *ppos)
2917 {
2918 	/*struct xradio_common *hw_priv = file->private_data;*/
2919 	char buf[100];
2920 	size_t size = 0;
2921 
2922 	sprintf(buf, "txparse=0x%04x, rxparse=0x%04x\n",
2923 		txparse_flags, rxparse_flags);
2924 	size = strlen(buf);
2925 
2926 	return simple_read_from_buffer(user_buf, count, ppos, buf, size);
2927 }
2928 
xradio_parse_flags_set(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)2929 static ssize_t xradio_parse_flags_set(struct file *file,
2930 				      const char __user *user_buf,
2931 				      size_t count, loff_t *ppos)
2932 {
2933 	/*struct xradio_common *hw_priv = file->private_data;*/
2934 	char buf[30] = { 0 };
2935 	char *start = &buf[0];
2936 	char *endptr = NULL;
2937 
2938 	count = (count > 29 ? 29 : count);
2939 
2940 	if (!count)
2941 		return -EINVAL;
2942 	if (copy_from_user(buf, user_buf, count))
2943 		return -EFAULT;
2944 
2945 	txparse_flags = simple_strtoul(buf, &endptr, 16);
2946 	start = endptr + 1;
2947 	if (start < buf + count)
2948 		rxparse_flags = simple_strtoul(start, &endptr, 16);
2949 
2950 	txparse_flags &= 0x7fff;
2951 	rxparse_flags &= 0x7fff;
2952 
2953 	xradio_dbg(XRADIO_DBG_ALWY, "txparse=0x%04x, rxparse=0x%04x\n",
2954 		   txparse_flags, rxparse_flags);
2955 	return count;
2956 }
2957 
2958 static const struct file_operations fops_parse_flags = {
2959 	.open = xradio_generic_open,
2960 	.write = xradio_parse_flags_set,
2961 	.read = xradio_parse_flags_get,
2962 	.llseek = default_llseek,
2963 };
2964 
2965 #if (DGB_XRADIO_HWT)
2966 u8 hwt_testing;
2967 /*HIF TX test*/
2968 u8 hwt_tx_en;
2969 u8 hwt_tx_cfm;	/*confirm interval*/
2970 u16 hwt_tx_len;
2971 u16 hwt_tx_num;
2972 struct timespec64 hwt_start_time = { 0 };
2973 struct timespec64 hwt_end_time = { 0 };
2974 
2975 int wsm_hwt_cmd(struct xradio_common *hw_priv, void *arg,
2976 		size_t arg_size);
2977 
xradio_hwt_hif_tx(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)2978 static ssize_t xradio_hwt_hif_tx(struct file *file,
2979 	const char __user *user_buf, size_t count, loff_t *ppos)
2980 {
2981 	struct xradio_common *hw_priv = file->private_data;
2982 	char buf[100] = { 0 };
2983 	char *start = &buf[0];
2984 	char *endptr = NULL;
2985 
2986 	if (hwt_testing) {
2987 		xradio_dbg(XRADIO_DBG_ALWY, "cmd refuse, hwt is testing!\n");
2988 		return count;
2989 	}
2990 
2991 	count = (count > 99 ? 99 : count);
2992 	if (!count)
2993 		return -EINVAL;
2994 	if (copy_from_user(buf, user_buf, count))
2995 		return -EFAULT;
2996 
2997 	if (simple_strtoul(start, &endptr, 10)) {
2998 		start = endptr + 1;
2999 		if (start < buf + count)
3000 			hwt_tx_len = simple_strtoul(start, &endptr, 10);
3001 		start = endptr + 1;
3002 		if (start < buf + count)
3003 			hwt_tx_num = simple_strtoul(start, &endptr, 10);
3004 		start = endptr + 1;
3005 		if (start < buf + count)
3006 			hwt_tx_cfm = simple_strtoul(start, &endptr, 10);
3007 		hwt_tx_en = 1;
3008 		hwt_testing = 1;
3009 	} else {
3010 		hwt_tx_en = 0;
3011 	}
3012 	xradio_dbg(XRADIO_DBG_ALWY,
3013 		   "hwt_tx_en=%d, hwt_tx_len=%d, hwt_tx_num=%d, hwt_tx_cfm=%d\n",
3014 		   hwt_tx_en, hwt_tx_len, hwt_tx_num, hwt_tx_cfm);
3015 
3016 	if (!hw_priv->bh_error &&
3017 		  atomic_add_return(1, &hw_priv->bh_tx) == 1)
3018 		wake_up(&hw_priv->bh_wq);
3019 	return count;
3020 }
3021 
3022 static const struct file_operations fops_hwt_hif_tx = {
3023 	.open = xradio_generic_open,
3024 	.write = xradio_hwt_hif_tx,
3025 	.llseek = default_llseek,
3026 };
3027 
3028 /*HIF RX test*/
3029 u8 hwt_rx_en;
3030 u16 hwt_rx_len;
3031 u16 hwt_rx_num;
xradio_hwt_hif_rx(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)3032 static ssize_t xradio_hwt_hif_rx(struct file *file,
3033 	const char __user *user_buf, size_t count, loff_t *ppos)
3034 {
3035 	struct xradio_common *hw_priv = file->private_data;
3036 	char buf[100] = { 0 };
3037 	char *start = &buf[0];
3038 	char *endptr = NULL;
3039 
3040 	if (hwt_testing) {
3041 		xradio_dbg(XRADIO_DBG_ALWY, "cmd refuse, hwt is testing!\n");
3042 		return count;
3043 	}
3044 
3045 	count = (count > 99 ? 99 : count);
3046 	if (!count)
3047 		return -EINVAL;
3048 	if (copy_from_user(buf, user_buf, count))
3049 		return -EFAULT;
3050 
3051 	if (simple_strtoul(start, &endptr, 10)) {
3052 		start = endptr + 1;
3053 		if (start < buf + count)
3054 			hwt_rx_len = simple_strtoul(start, &endptr, 10);
3055 		start = endptr + 1;
3056 		if (start < buf + count)
3057 			hwt_rx_num = simple_strtoul(start, &endptr, 10);
3058 
3059 		hwt_rx_en = 1;
3060 	} else {
3061 		hwt_rx_en = 0;
3062 	}
3063 	xradio_dbg(XRADIO_DBG_ALWY,
3064 		   "hwt_rx_en=%d, hwt_rx_len=%d, hwt_rx_num=%d\n", hwt_rx_en,
3065 		   hwt_rx_len, hwt_rx_num);
3066 
3067 	/*check the parameters.*/
3068 	if (hwt_rx_len < 100 || hwt_rx_len > 1500)
3069 		hwt_rx_len = 1500;
3070 	if (hwt_rx_en && hwt_rx_num) {
3071 		HWT_PARAMETERS hwt_hdr = {
3072 			.TestID = 0x0002,
3073 			.Params = hwt_rx_num,
3074 			.Data = hwt_rx_len
3075 		};
3076 		hwt_testing = 1;
3077 		wsm_hwt_cmd(hw_priv, (void *)&hwt_hdr.TestID, sizeof(hwt_hdr)-4);
3078 		xr_do_gettimeofday(&hwt_start_time);
3079 	}
3080 
3081 	return count;
3082 }
3083 
3084 static const struct file_operations fops_hwt_hif_rx = {
3085 	.open = xradio_generic_open,
3086 	.write = xradio_hwt_hif_rx,
3087 	.llseek = default_llseek,
3088 };
3089 
3090 /*ENC test*/
3091 u8 hwt_enc_type;
3092 u8 hwt_key_len;
3093 u16 hwt_enc_len;
3094 u16 hwt_enc_cnt;
xradio_hwt_enc(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)3095 static ssize_t xradio_hwt_enc(struct file *file,
3096 	const char __user *user_buf, size_t count, loff_t *ppos)
3097 {
3098 	struct xradio_common *hw_priv = file->private_data;
3099 	char buf[100] = { 0 };
3100 	char *start = &buf[0];
3101 	char *endptr = NULL;
3102 
3103 	if (hwt_testing) {
3104 		xradio_dbg(XRADIO_DBG_ALWY, "cmd refuse, hwt is testing!\n");
3105 		return count;
3106 	}
3107 
3108 	count = (count > 99 ? 99 : count);
3109 	if (!count)
3110 		return -EINVAL;
3111 	if (copy_from_user(buf, user_buf, count))
3112 		return -EFAULT;
3113 
3114 	hwt_enc_type = simple_strtoul(start, &endptr, 10);
3115 	start = endptr + 1;
3116 	if (start < buf + count)
3117 		hwt_key_len = simple_strtoul(start, &endptr, 10);
3118 	start = endptr + 1;
3119 	if (start < buf + count)
3120 		hwt_enc_len = simple_strtoul(start, &endptr, 10);
3121 	start = endptr + 1;
3122 	if (start < buf + count)
3123 		hwt_enc_cnt = simple_strtoul(start, &endptr, 10);
3124 
3125 	xradio_dbg(XRADIO_DBG_ALWY,
3126 		   "enc_type=%d, key_len=%d, enc_len=%d, enc_cnt=%d\n",
3127 		   hwt_enc_type, hwt_key_len, hwt_enc_len, hwt_enc_cnt);
3128 
3129 	/*check the parameters.*/
3130 	if (hwt_enc_type < 10 && hwt_key_len <= 16 &&
3131 		hwt_enc_len <= 1500 && hwt_enc_cnt > 0) {
3132 		HWT_PARAMETERS hwt_hdr = {
3133 			.TestID  = 0x0003,
3134 			.Params  = (hwt_key_len<<8) | hwt_enc_type,
3135 			.Datalen = hwt_enc_len,
3136 			.Data    = hwt_enc_cnt
3137 		};
3138 		hwt_testing = 1;
3139 		wsm_hwt_cmd(hw_priv, (void *)&hwt_hdr.TestID, sizeof(hwt_hdr)-4);
3140 	}
3141 
3142 	return count;
3143 }
3144 
3145 static const struct file_operations fops_hwt_enc = {
3146 	.open = xradio_generic_open,
3147 	.write = xradio_hwt_enc,
3148 	.llseek = default_llseek,
3149 };
3150 
3151 /*MIC test*/
3152 u16 hwt_mic_len;
3153 u16 hwt_mic_cnt;
xradio_hwt_mic(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)3154 static ssize_t xradio_hwt_mic(struct file *file,
3155 	const char __user *user_buf, size_t count, loff_t *ppos)
3156 {
3157 	struct xradio_common *hw_priv = file->private_data;
3158 	char buf[100] = { 0 };
3159 	char *start = &buf[0];
3160 	char *endptr = NULL;
3161 
3162 	if (hwt_testing) {
3163 		xradio_dbg(XRADIO_DBG_ALWY, "cmd refuse, hwt is testing!\n");
3164 		return count;
3165 	}
3166 
3167 	count = (count > 99 ? 99 : count);
3168 	if (!count)
3169 		return -EINVAL;
3170 	if (copy_from_user(buf, user_buf, count))
3171 		return -EFAULT;
3172 
3173 	hwt_mic_len = simple_strtoul(start, &endptr, 10);
3174 	start = endptr + 1;
3175 	if (start < buf + count)
3176 		hwt_mic_cnt = simple_strtoul(start, &endptr, 10);
3177 
3178 	xradio_dbg(XRADIO_DBG_ALWY, "mic_len=%d, mic_cnt=%d\n",
3179 		   hwt_mic_len, hwt_mic_cnt);
3180 
3181 	/*check the parameters.*/
3182 	if (hwt_mic_len <= 1500 && hwt_mic_cnt > 0) {
3183 		HWT_PARAMETERS hwt_hdr = {
3184 			.TestID = 0x0004,
3185 			.Params = 0,
3186 			.Datalen = hwt_mic_len,
3187 			.Data = hwt_mic_cnt
3188 		};
3189 		hwt_testing = 1;
3190 		wsm_hwt_cmd(hw_priv, (void *)&hwt_hdr.TestID, sizeof(hwt_hdr)-4);
3191 	}
3192 
3193 	return count;
3194 }
3195 
3196 static const struct file_operations fops_hwt_mic = {
3197 	.open = xradio_generic_open,
3198 	.write = xradio_hwt_mic,
3199 	.llseek = default_llseek,
3200 };
3201 
xradio_hwt_hif_rx_burn(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)3202 static ssize_t xradio_hwt_hif_rx_burn(struct file *file,
3203 	const char __user *user_buf, size_t count, loff_t *ppos)
3204 {
3205 	struct xradio_common *hw_priv = file->private_data;
3206 	char buf[100] = { 0 };
3207 	char *start = &buf[0];
3208 	char *endptr = NULL;
3209 
3210 	u16 hw_inf_cmd = 0;
3211 
3212 	HWT_PARAMETERS hwt_hdr = {
3213 		.TestID = 0x0005,
3214 		.Params = hw_inf_cmd,
3215 		.Data = 10000
3216 	};
3217 
3218 
3219 	count = (count > 99 ? 99 : count);
3220 	if (!count)
3221 		return -EINVAL;
3222 	if (copy_from_user(buf, user_buf, count))
3223 		return -EFAULT;
3224 
3225 
3226 	hw_inf_cmd = simple_strtoul(start, &endptr, 10);
3227 
3228 	xradio_dbg(XRADIO_DBG_ALWY, "hw_inf_cmd=%d\n", hw_inf_cmd);
3229 
3230 	hwt_hdr.Params = hw_inf_cmd;
3231 
3232 	wsm_hwt_cmd(hw_priv, (void *)&hwt_hdr.TestID, sizeof(hwt_hdr)-4);
3233 
3234 	return count;
3235 }
3236 
3237 static const struct file_operations fops_hwt_hif_rx_burn = {
3238 	.open = xradio_generic_open,
3239 	.write = xradio_hwt_hif_rx_burn,
3240 	.llseek = default_llseek,
3241 };
3242 
3243 #endif /*DGB_XRADIO_HWT*/
3244 
3245 static u32 measure_type;
3246 
xradio_measure_type_write(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)3247 static ssize_t xradio_measure_type_write(struct file *file,
3248 	const char __user *user_buf, size_t count, loff_t *ppos)
3249 {
3250 	struct xradio_common *hw_priv = file->private_data;
3251 	char buf[12] = { 0 };
3252 	char *endptr = NULL;
3253 	count = (count > 11 ? 11 : count);
3254 	if (!count)
3255 		return -EINVAL;
3256 	if (copy_from_user(buf, user_buf, count))
3257 		return -EFAULT;
3258 	measure_type = simple_strtoul(buf, &endptr, 16);
3259 
3260 	xradio_dbg(XRADIO_DBG_ALWY, "measure_type = %08x\n", measure_type);
3261 	SYS_WARN(wsm_11k_measure_requset(hw_priv, (measure_type & 0xff),
3262 					 ((measure_type & 0xff00) >> 8),
3263 					 ((measure_type & 0xffff0000) >> 16)));
3264 	return count;
3265 }
3266 
xradio_measure_type_read(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)3267 static ssize_t xradio_measure_type_read(struct file *file,
3268 	char __user *user_buf, size_t count, loff_t *ppos)
3269 {
3270 	/*struct xradio_common *hw_priv = file->private_data;*/
3271 	char buf[20];
3272 	size_t size = 0;
3273 
3274 	sprintf(buf, "measure_type = %u\n", measure_type);
3275 	size = strlen(buf);
3276 
3277 	return simple_read_from_buffer(user_buf, count, ppos, buf, size);
3278 }
3279 
3280 static const struct file_operations fops_11k = {
3281 	.open = xradio_generic_open,
3282 	.write = xradio_measure_type_write,
3283 	.read = xradio_measure_type_read,
3284 	.llseek = default_llseek,
3285 };
3286 
xradio_wsm_dumps(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)3287 static ssize_t xradio_wsm_dumps(struct file *file,
3288 	const char __user *user_buf, size_t count, loff_t *ppos)
3289 {
3290 	struct xradio_common *hw_priv = file->private_data;
3291 	char buf[1];
3292 
3293 	if (!count)
3294 		return -EINVAL;
3295 	if (copy_from_user(buf, user_buf, 1))
3296 		return -EFAULT;
3297 
3298 	if (buf[0] == '1')
3299 		hw_priv->wsm_enable_wsm_dumps = 1;
3300 	else
3301 		hw_priv->wsm_enable_wsm_dumps = 0;
3302 
3303 	return count;
3304 }
3305 
3306 static const struct file_operations fops_wsm_dumps = {
3307 	.open = xradio_generic_open,
3308 	.write = xradio_wsm_dumps,
3309 	.llseek = default_llseek,
3310 };
3311 
xradio_short_dump_read(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)3312 static ssize_t xradio_short_dump_read(struct file *file,
3313 	char __user *user_buf, size_t count, loff_t *ppos)
3314 {
3315 	struct xradio_common *hw_priv = file->private_data;
3316 	char buf[20];
3317 	size_t size = 0;
3318 
3319 	sprintf(buf, "Size: %u\n", hw_priv->wsm_dump_max_size);
3320 	size = strlen(buf);
3321 
3322 	return simple_read_from_buffer(user_buf, count, ppos, buf, size);
3323 }
3324 
xradio_short_dump_write(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)3325 static ssize_t xradio_short_dump_write(struct file *file,
3326 	const char __user *user_buf, size_t count, loff_t *ppos)
3327 {
3328 	struct xradio_common *priv = file->private_data;
3329 	char buf[20];
3330 	unsigned long dump_size = 0;
3331 
3332 	if (!count || count > 20)
3333 		return -EINVAL;
3334 	if (copy_from_user(buf, user_buf, count))
3335 		return -EFAULT;
3336 
3337 	if (kstrtoul(buf, 10, &dump_size))
3338 		return -EINVAL;
3339 	xradio_dbg(XRADIO_DBG_ALWY, "%s get %lu\n", __func__, dump_size);
3340 
3341 	priv->wsm_dump_max_size = dump_size;
3342 
3343 	return count;
3344 }
3345 
3346 static const struct file_operations fops_short_dump = {
3347 	.open = xradio_generic_open,
3348 	.write = xradio_short_dump_write,
3349 	.read = xradio_short_dump_read,
3350 	.llseek = default_llseek,
3351 };
3352 
3353 #ifdef SUPPORT_HT40
3354 
xradio_status_show_priv(struct seq_file * seq,void * v)3355 static int xradio_status_show_priv(struct seq_file *seq, void *v)
3356 {
3357 	int i;
3358 	struct xradio_vif *priv = seq->private;
3359 	struct xradio_debug_priv *d = priv->debug;
3360 
3361 	seq_printf(seq, "Mode:       %s%s\n",
3362 		xradio_debug_mode(priv->mode),
3363 		priv->listening ? " (listening)" : "");
3364 	seq_printf(seq, "Assoc:      %s\n",
3365 		xradio_debug_join_status[priv->join_status]);
3366 	if (priv->rx_filter.promiscuous)
3367 		seq_puts(seq, "Filter:     promisc\n");
3368 	else if (priv->rx_filter.fcs)
3369 		seq_puts(seq, "Filter:     fcs\n");
3370 	if (priv->rx_filter.bssid)
3371 		seq_puts(seq, "Filter:     bssid\n");
3372 	if (priv->bf_control.bcn_count)
3373 		seq_puts(seq, "Filter:     beacons\n");
3374 
3375 	if (priv->enable_beacon ||
3376 	    priv->mode == NL80211_IFTYPE_AP ||
3377 	    priv->mode == NL80211_IFTYPE_ADHOC ||
3378 	    priv->mode == NL80211_IFTYPE_MESH_POINT ||
3379 	    priv->mode == NL80211_IFTYPE_P2P_GO)
3380 		seq_printf(seq, "Beaconing:  %s\n",
3381 			   priv->enable_beacon ? "enabled" : "disabled");
3382 	if (priv->ssid_length ||
3383 	    priv->mode == NL80211_IFTYPE_AP ||
3384 	    priv->mode == NL80211_IFTYPE_ADHOC ||
3385 	    priv->mode == NL80211_IFTYPE_MESH_POINT ||
3386 	    priv->mode == NL80211_IFTYPE_P2P_GO)
3387 		seq_printf(seq, "SSID:       %.*s\n",
3388 			   (int)priv->ssid_length, priv->ssid);
3389 
3390 	for (i = 0; i < 4; ++i) {
3391 		seq_printf(seq, "EDCA(%d):    %d, %d, %d, %d, %d\n", i,
3392 			   priv->edca.params[i].cwMin,
3393 			   priv->edca.params[i].cwMax,
3394 			   priv->edca.params[i].aifns,
3395 			   priv->edca.params[i].txOpLimit,
3396 			   priv->edca.params[i].maxReceiveLifetime);
3397 	}
3398 	if (priv->join_status == XRADIO_JOIN_STATUS_STA) {
3399 		static const char *pmMode = "unknown";
3400 		switch (priv->powersave_mode.pmMode) {
3401 		case WSM_PSM_ACTIVE:
3402 			pmMode = "off";
3403 			break;
3404 		case WSM_PSM_PS:
3405 			pmMode = "on";
3406 			break;
3407 		case WSM_PSM_FAST_PS:
3408 			pmMode = "dynamic";
3409 			break;
3410 		}
3411 		seq_printf(seq, "Preamble:   %s\n",
3412 			xradio_debug_preamble[
3413 			priv->association_mode.PhyModeCfg.PreambleCfg]);
3414 		seq_printf(seq, "AMPDU spcn: %d\n",
3415 			priv->association_mode.mpduStartSpacing);
3416 		seq_printf(seq, "Basic rate: 0x%.8X\n",
3417 			le32_to_cpu(priv->association_mode.basicRateSet));
3418 		seq_printf(seq, "Bss lost:   %d beacons\n",
3419 			priv->bss_params.beaconLostCount);
3420 		seq_printf(seq, "AID:        %d\n",
3421 			priv->bss_params.aid);
3422 		seq_printf(seq, "Rates:      0x%.8X\n",
3423 			priv->bss_params.operationalRateSet);
3424 		seq_printf(seq, "Powersave:  %s\n", pmMode);
3425 	}
3426 	seq_printf(seq, "RSSI thold: %d\n",
3427 		priv->cqm_rssi_thold);
3428 	seq_printf(seq, "RSSI hyst:  %d\n",
3429 		priv->cqm_rssi_hyst);
3430 	seq_printf(seq, "TXFL thold: %d\n",
3431 		priv->cqm_tx_failure_thold);
3432 	seq_printf(seq, "Linkloss:   %d\n",
3433 		priv->cqm_link_loss_count);
3434 	seq_printf(seq, "Bcnloss:    %d\n",
3435 		priv->cqm_beacon_loss_count);
3436 
3437 	xradio_debug_print_map(seq, priv, "Link map:   ",
3438 		priv->link_id_map);
3439 	xradio_debug_print_map(seq, priv, "Asleep map: ",
3440 		priv->sta_asleep_mask);
3441 	xradio_debug_print_map(seq, priv, "PSPOLL map: ",
3442 		priv->pspoll_mask);
3443 
3444 	seq_puts(seq, "\n");
3445 
3446 	for (i = 0; i < MAX_STA_IN_AP_MODE; ++i) {
3447 		if (priv->link_id_db[i].status) {
3448 			seq_printf(seq, "Link %d:     %s, %pM\n",
3449 				i + 1, xradio_debug_link_id[
3450 				priv->link_id_db[i].status],
3451 				priv->link_id_db[i].mac);
3452 		}
3453 	}
3454 
3455 	seq_puts(seq, "\n");
3456 
3457 	seq_printf(seq, "Powermgmt:  %s\n",
3458 		priv->powersave_enabled ? "on" : "off");
3459 
3460 	seq_printf(seq, "TXed:       %d\n",
3461 		d->tx);
3462 	seq_printf(seq, "AGG TXed:   %d\n",
3463 		d->tx_agg);
3464 	seq_printf(seq, "MULTI TXed: %d (%d)\n",
3465 		d->tx_multi, d->tx_multi_frames);
3466 	seq_printf(seq, "RXed:       %d\n",
3467 		d->rx);
3468 	seq_printf(seq, "AGG RXed:   %d\n",
3469 		d->rx_agg);
3470 	seq_printf(seq, "TX align:   %d\n",
3471 		d->tx_align);
3472 	seq_printf(seq, "TX TTL:     %d\n",
3473 		d->tx_ttl);
3474 	return 0;
3475 }
3476 
3477 #else
3478 
xradio_status_show_priv(struct seq_file * seq,void * v)3479 static int xradio_status_show_priv(struct seq_file *seq, void *v)
3480 {
3481 	int i;
3482 	struct xradio_vif *priv = seq->private;
3483 	struct xradio_debug_priv *d = priv->debug;
3484 
3485 	seq_printf(seq, "Mode:       %s%s\n",
3486 		xradio_debug_mode(priv->mode),
3487 		priv->listening ? " (listening)" : "");
3488 	seq_printf(seq, "Assoc:      %s\n",
3489 		xradio_debug_join_status[priv->join_status]);
3490 	if (priv->rx_filter.promiscuous)
3491 		seq_puts(seq, "Filter:     promisc\n");
3492 	else if (priv->rx_filter.fcs)
3493 		seq_puts(seq, "Filter:     fcs\n");
3494 	if (priv->rx_filter.bssid)
3495 		seq_puts(seq, "Filter:     bssid\n");
3496 	if (priv->bf_control.bcn_count)
3497 		seq_puts(seq, "Filter:     beacons\n");
3498 
3499 	if (priv->enable_beacon ||
3500 	    priv->mode == NL80211_IFTYPE_AP ||
3501 	    priv->mode == NL80211_IFTYPE_ADHOC ||
3502 	    priv->mode == NL80211_IFTYPE_MESH_POINT ||
3503 	    priv->mode == NL80211_IFTYPE_P2P_GO)
3504 		seq_printf(seq, "Beaconing:  %s\n",
3505 			   priv->enable_beacon ? "enabled" : "disabled");
3506 	if (priv->ssid_length ||
3507 	    priv->mode == NL80211_IFTYPE_AP ||
3508 	    priv->mode == NL80211_IFTYPE_ADHOC ||
3509 	    priv->mode == NL80211_IFTYPE_MESH_POINT ||
3510 	    priv->mode == NL80211_IFTYPE_P2P_GO)
3511 		seq_printf(seq, "SSID:       %.*s\n",
3512 			   (int)priv->ssid_length, priv->ssid);
3513 
3514 	for (i = 0; i < 4; ++i) {
3515 		seq_printf(seq, "EDCA(%d):    %d, %d, %d, %d, %d\n", i,
3516 			   priv->edca.params[i].cwMin,
3517 			   priv->edca.params[i].cwMax,
3518 			   priv->edca.params[i].aifns,
3519 			   priv->edca.params[i].txOpLimit,
3520 			   priv->edca.params[i].maxReceiveLifetime);
3521 	}
3522 	if (priv->join_status == XRADIO_JOIN_STATUS_STA) {
3523 		static const char *pmMode = "unknown";
3524 		switch (priv->powersave_mode.pmMode) {
3525 		case WSM_PSM_ACTIVE:
3526 			pmMode = "off";
3527 			break;
3528 		case WSM_PSM_PS:
3529 			pmMode = "on";
3530 			break;
3531 		case WSM_PSM_FAST_PS:
3532 			pmMode = "dynamic";
3533 			break;
3534 		}
3535 		seq_printf(seq, "Preamble:   %s\n",
3536 			xradio_debug_preamble[
3537 			priv->association_mode.preambleType]);
3538 		seq_printf(seq, "AMPDU spcn: %d\n",
3539 			   priv->association_mode.mpduStartSpacing);
3540 		seq_printf(seq, "Basic rate: 0x%.8X\n",
3541 			   le32_to_cpu(priv->association_mode.basicRateSet));
3542 		seq_printf(seq, "Bss lost:   %d beacons\n",
3543 			   priv->bss_params.beaconLostCount);
3544 		seq_printf(seq, "AID:        %d\n", priv->bss_params.aid);
3545 		seq_printf(seq, "Rates:      0x%.8X\n",
3546 			   priv->bss_params.operationalRateSet);
3547 		seq_printf(seq, "Powersave:  %s\n", pmMode);
3548 	}
3549 	seq_printf(seq, "RSSI thold: %d\n", priv->cqm_rssi_thold);
3550 	seq_printf(seq, "RSSI hyst:  %d\n", priv->cqm_rssi_hyst);
3551 	seq_printf(seq, "TXFL thold: %d\n", priv->cqm_tx_failure_thold);
3552 	seq_printf(seq, "Linkloss:   %d\n", priv->cqm_link_loss_count);
3553 	seq_printf(seq, "Bcnloss:    %d\n", priv->cqm_beacon_loss_count);
3554 
3555 	xradio_debug_print_map(seq, priv, "Link map:   ", priv->link_id_map);
3556 	xradio_debug_print_map(seq, priv, "Asleep map: ",
3557 			       priv->sta_asleep_mask);
3558 	xradio_debug_print_map(seq, priv, "PSPOLL map: ", priv->pspoll_mask);
3559 
3560 	seq_puts(seq, "\n");
3561 
3562 	for (i = 0; i < MAX_STA_IN_AP_MODE; ++i) {
3563 		if (priv->link_id_db[i].status) {
3564 			seq_printf(seq, "Link %d:     %s, %pM\n",
3565 				i + 1, xradio_debug_link_id[
3566 				priv->link_id_db[i].status],
3567 				priv->link_id_db[i].mac);
3568 		}
3569 	}
3570 
3571 	seq_puts(seq, "\n");
3572 
3573 	seq_printf(seq, "Powermgmt:  %s\n",
3574 		priv->powersave_enabled ? "on" : "off");
3575 
3576 	seq_printf(seq, "TXed:       %d\n", d->tx);
3577 	seq_printf(seq, "AGG TXed:   %d\n", d->tx_agg);
3578 	seq_printf(seq, "MULTI TXed: %d (%d)\n",
3579 		   d->tx_multi, d->tx_multi_frames);
3580 	seq_printf(seq, "RXed:       %d\n", d->rx);
3581 	seq_printf(seq, "AGG RXed:   %d\n", d->rx_agg);
3582 	seq_printf(seq, "TX align:   %d\n", d->tx_align);
3583 	seq_printf(seq, "TX TTL:     %d\n", d->tx_ttl);
3584 	return 0;
3585 }
3586 
3587 #endif
3588 
xradio_status_open_priv(struct inode * inode,struct file * file)3589 static int xradio_status_open_priv(struct inode *inode,
3590 			struct file *file)
3591 {
3592 	return single_open(file, &xradio_status_show_priv, inode->i_private);
3593 }
3594 
3595 static const struct file_operations fops_status_priv = {
3596 	.open = xradio_status_open_priv,
3597 	.read = seq_read,
3598 	.llseek = seq_lseek,
3599 	.release = single_release,
3600 	.owner = THIS_MODULE,
3601 };
3602 
3603 #if defined(CONFIG_XRADIO_USE_EXTENSIONS)
3604 
xradio_hang_write(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)3605 static ssize_t xradio_hang_write(struct file *file,
3606 	const char __user *user_buf, size_t count, loff_t *ppos)
3607 {
3608 	struct xradio_vif *priv = file->private_data;
3609 	struct xradio_common *hw_priv = xrwl_vifpriv_to_hwpriv(priv);
3610 	char buf[1];
3611 
3612 	if (!count)
3613 		return -EINVAL;
3614 	if (copy_from_user(buf, user_buf, 1))
3615 		return -EFAULT;
3616 
3617 	if (priv->vif) {
3618 #ifdef CONFIG_PM
3619 		xradio_pm_stay_awake(&hw_priv->pm_state, 3 * HZ);
3620 #endif
3621 
3622 		wsm_send_deauth_to_self(hw_priv, priv);
3623 
3624 		/* ieee80211_driver_hang_notify(priv->vif, GFP_KERNEL); */
3625 	} else
3626 		return -ENODEV;
3627 
3628 	return count;
3629 }
3630 
3631 static const struct file_operations fops_hang = {
3632 	.open = xradio_generic_open,
3633 	.write = xradio_hang_write,
3634 	.llseek = default_llseek,
3635 };
3636 #endif
3637 
3638 #ifdef AP_HT_COMPAT_FIX
3639 extern u8 ap_compat_bssid[ETH_ALEN];
xradio_ht_compat_show(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)3640 static ssize_t xradio_ht_compat_show(struct file *file,
3641 	char __user *user_buf, size_t count, loff_t *ppos)
3642 {
3643 	struct xradio_vif *priv = file->private_data;
3644 	char buf[100];
3645 	size_t size = 0;
3646 	sprintf(buf, "ht_compat_det=0x%x, BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n",
3647 		priv->ht_compat_det,
3648 		ap_compat_bssid[0], ap_compat_bssid[1],
3649 		ap_compat_bssid[2], ap_compat_bssid[3],
3650 		ap_compat_bssid[4], ap_compat_bssid[5]);
3651 	size = strlen(buf);
3652 
3653 	return simple_read_from_buffer(user_buf, count, ppos, buf, size);
3654 }
3655 
xradio_ht_compat_disalbe(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)3656 static ssize_t xradio_ht_compat_disalbe(struct file *file,
3657 	const char __user *user_buf, size_t count, loff_t *ppos)
3658 {
3659 	struct xradio_vif *priv = file->private_data;
3660 	char buf[2];
3661 	char *endptr = NULL;
3662 
3663 	if (!count)
3664 		return -EINVAL;
3665 	if (copy_from_user(buf, user_buf, 2))
3666 		return -EFAULT;
3667 
3668 	if (simple_strtoul(buf, &endptr, 10))
3669 		priv->ht_compat_det |= 0x10;
3670 	else
3671 		priv->ht_compat_det &= ~0x10;
3672 	return count;
3673 }
3674 
3675 static const struct file_operations fops_ht_compat_dis = {
3676 	.open = xradio_generic_open,
3677 	.read = xradio_ht_compat_show,
3678 	.write = xradio_ht_compat_disalbe,
3679 	.llseek = default_llseek,
3680 };
3681 #endif
3682 
3683 #define VIF_DEBUGFS_NAME_S 10
xradio_debug_init_priv(struct xradio_common * hw_priv,struct xradio_vif * priv)3684 int xradio_debug_init_priv(struct xradio_common *hw_priv,
3685 			   struct xradio_vif *priv)
3686 {
3687 	int ret = -ENOMEM;
3688 	struct xradio_debug_priv *d;
3689 	char name[VIF_DEBUGFS_NAME_S];
3690 	xradio_dbg(XRADIO_DBG_TRC, "%s\n", __func__);
3691 
3692 	if (SYS_WARN(!hw_priv))
3693 		return ret;
3694 
3695 	if (SYS_WARN(!hw_priv->debug))
3696 		return ret;
3697 
3698 	d = xr_kzalloc(sizeof(struct xradio_debug_priv), false);
3699 	priv->debug = d;
3700 	if (SYS_WARN(!d))
3701 		return ret;
3702 
3703 	memset(name, 0, VIF_DEBUGFS_NAME_S);
3704 	ret = snprintf(name, VIF_DEBUGFS_NAME_S, "vif_%d", priv->if_id);
3705 	if (SYS_WARN(ret < 0))
3706 		goto err;
3707 
3708 	d->debugfs_phy = debugfs_create_dir(name,
3709 					    hw_priv->debug->debugfs_phy);
3710 	if (SYS_WARN(!d->debugfs_phy))
3711 		goto err;
3712 
3713 #if defined(CONFIG_XRADIO_USE_EXTENSIONS)
3714 	if (SYS_WARN(!debugfs_create_file("hang", S_IWUSR, d->debugfs_phy,
3715 			priv, &fops_hang)))
3716 		goto err;
3717 #endif
3718 
3719 #if defined(AP_HT_COMPAT_FIX)
3720 	if (SYS_WARN(!debugfs_create_file("htcompat_disable",
3721 			 S_IWUSR, d->debugfs_phy, priv, &fops_ht_compat_dis)))
3722 		goto err;
3723 #endif
3724 
3725 	if (!debugfs_create_file("status", S_IRUSR, d->debugfs_phy,
3726 			priv, &fops_status_priv))
3727 		goto err;
3728 
3729 	return 0;
3730 err:
3731 	priv->debug = NULL;
3732 	debugfs_remove_recursive(d->debugfs_phy);
3733 	kfree(d);
3734 	return ret;
3735 
3736 }
3737 
xradio_debug_release_priv(struct xradio_vif * priv)3738 void xradio_debug_release_priv(struct xradio_vif *priv)
3739 {
3740 	struct xradio_debug_priv *d = priv->debug;
3741 	xradio_dbg(XRADIO_DBG_TRC, "%s\n", __func__);
3742 	if (d) {
3743 		priv->debug = NULL;
3744 		debugfs_remove_recursive(d->debugfs_phy);
3745 		kfree(d);
3746 	}
3747 }
3748 
xradio_print_fw_version(struct xradio_common * hw_priv,u8 * buf,size_t len)3749 int xradio_print_fw_version(struct xradio_common *hw_priv,
3750 				u8 *buf, size_t len)
3751 {
3752 	return snprintf(buf, len, "%s %d.%d",
3753 			xradio_debug_fw_types[hw_priv->wsm_caps.firmwareType],
3754 			hw_priv->wsm_caps.firmwareVersion,
3755 			hw_priv->wsm_caps.firmwareBuildNumber);
3756 }
3757 #if (SUPPORT_EPTA)
3758 static const struct file_operations fops_epta_stat_dbg_ctrl = {
3759 	.open = xradio_generic_open,
3760 	.write = xradio_epta_stat_dbg_write,
3761 	.read = xradio_epta_stat_dbg_read,
3762 	.llseek = default_llseek,
3763 };
3764 #endif
3765 
3766 #if (DBG_XRADIO_HIF)
3767 
xradio_hif_test_write(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)3768 static ssize_t xradio_hif_test_write(struct file *file,
3769 	const char __user *user_buf, size_t count, loff_t *ppos)
3770 {
3771 	char buf[50] = {0};
3772 	char *start = &buf[0];
3773 	char *endptr = NULL;
3774 
3775 	count = (count > 50 ? 50 : count);
3776 
3777 	printk(KERN_ERR"set value\n");
3778 	if (!count)
3779 		return -EINVAL;
3780 	if (copy_from_user(buf, user_buf, count))
3781 		return -EFAULT;
3782 	hif_test_rw = simple_strtoul(start, &endptr, 16);
3783 	start = endptr + 1;
3784 
3785 	if (start < buf + count)
3786 		hif_test_data_mode = simple_strtoul(start, &endptr, 16);
3787 
3788 	start = endptr + 1;
3789 	if (start < buf + count)
3790 		hif_test_data_len = simple_strtoul(start, &endptr, 16);
3791 
3792 	start = endptr + 1;
3793 	if (start < buf + count)
3794 		hif_test_data_round = simple_strtoul(start, &endptr, 16);
3795 
3796 	start = endptr + 1;
3797 	if (start < buf + count)
3798 		hif_test_oper_delta = simple_strtoul(start, &endptr, 16);
3799 
3800 	xradio_dbg(XRADIO_DBG_ALWY, "[HIF test] configuration %s, val is 0x%x, "
3801 		"round is %u, data size is %u per round delay %u ms per round\n",
3802 		hif_test_rw ? (hif_test_rw > 1 ? "R & W" : "W") : "Not Test",
3803 		hif_test_data_round,
3804 		hif_test_data_mode,
3805 		hif_test_data_len*4,
3806 		hif_test_oper_delta);
3807 	return count;
3808 }
3809 
xradio_hif_test_read(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)3810 static ssize_t xradio_hif_test_read(struct file *file,
3811 	char __user *user_buf, size_t count, loff_t *ppos)
3812 {
3813 	/* struct xradio_common *hw_priv = file->private_data;
3814 	char buf[50];
3815 	size_t size = 0;
3816 
3817 	sprintf(buf, "fwdbg_ctrl = %u\n", fwdbg_ctrl);
3818 	size = strlen(buf);
3819 
3820 	return simple_read_from_buffer(user_buf, count, ppos, buf, size);
3821 	 */
3822 	return 0;
3823 }
3824 static const struct file_operations fops_hif_test = {
3825 	.open = xradio_generic_open,
3826 	.write = xradio_hif_test_write,
3827 	.read = xradio_hif_test_read,
3828 	.llseek = default_llseek,
3829 };
3830 
3831 #endif
3832 
3833 #ifdef ERROR_HANG_DRIVER
xradio_hang_driver_for_debug(struct xradio_common * hw_priv,int error)3834 void xradio_hang_driver_for_debug(struct xradio_common *hw_priv, int error)
3835 {
3836 	int cnt = 0;
3837 	if (!error_hang_driver || !error)
3838 		return ; /*do nothing.*/
3839 
3840 	if (!hw_priv->debug) { /*have not setup debugfs yet, just do it.*/
3841 		xradio_debug_init_common(hw_priv);
3842 	}
3843 	while (error_hang_driver) {
3844 		msleep(5000);
3845 		cnt++;
3846 		xradio_dbg(XRADIO_DBG_ALWY, "err=%d, hang driver for %ds.\n",
3847 			error, cnt*5);
3848 	}
3849 	xradio_debug_release_common(hw_priv);
3850 	xradio_dbg(XRADIO_DBG_ALWY, "%s exit.\n", __func__);
3851 }
3852 #endif
3853 
3854 /*for host debuglevel*/
3855 struct dentry *debugfs_host;
3856 #if (DGB_XRADIO_QC)
3857 struct dentry *debugfs_hwinfo;
3858 #endif
xradio_host_dbg_init(void)3859 int xradio_host_dbg_init(void)
3860 {
3861 	int line = 0;
3862 	xradio_dbg(XRADIO_DBG_TRC, "%s\n", __func__);
3863 
3864 	if (!debugfs_initialized()) {
3865 		xradio_dbg(XRADIO_DBG_ERROR, "debugfs isnot initialized\n");
3866 		return 0;
3867 	}
3868 #define ERR_LINE  do { line = __LINE__; goto err; } while (0)
3869 
3870 	debugfs_host = debugfs_create_dir("xradio_host_dbg", NULL);
3871 	if (!debugfs_host)
3872 		ERR_LINE;
3873 
3874 	debugfs_create_x8("dbg_common", S_IRUSR | S_IWUSR,
3875 				   debugfs_host, &dbg_common);
3876 
3877 	debugfs_create_x8("dbg_sbus", S_IRUSR | S_IWUSR,
3878 				   debugfs_host, &dbg_sbus);
3879 
3880 	debugfs_create_x8("dbg_ap", S_IRUSR | S_IWUSR,
3881 				   debugfs_host, &dbg_ap);
3882 
3883 	debugfs_create_x8("dbg_sta", S_IRUSR | S_IWUSR,
3884 				   debugfs_host, &dbg_sta);
3885 
3886 	debugfs_create_x8("dbg_scan", S_IRUSR | S_IWUSR,
3887 				   debugfs_host, &dbg_scan);
3888 
3889 	debugfs_create_x8("dbg_bh", S_IRUSR | S_IWUSR,
3890 				   debugfs_host, &dbg_bh);
3891 
3892 	debugfs_create_x8("dbg_txrx", S_IRUSR | S_IWUSR,
3893 				   debugfs_host, &dbg_txrx);
3894 
3895 	debugfs_create_x8("dbg_wsm", S_IRUSR | S_IWUSR,
3896 				   debugfs_host, &dbg_wsm);
3897 
3898 	debugfs_create_x8("dbg_pm", S_IRUSR | S_IWUSR,
3899 				   debugfs_host, &dbg_pm);
3900 
3901 #ifdef CONFIG_XRADIO_ITP
3902 	debugfs_create_x8("dbg_itp", S_IRUSR | S_IWUSR,
3903 				   debugfs_host, &dbg_itp);
3904 #endif
3905 
3906 #ifdef CONFIG_XRADIO_ETF
3907 	debugfs_create_x8("dbg_etf", S_IRUSR | S_IWUSR,
3908 				   debugfs_host, &dbg_etf);
3909 #endif
3910 
3911 	debugfs_create_x8("dbg_logfile", S_IRUSR | S_IWUSR,
3912 				   debugfs_host, &dbg_logfile);
3913 
3914 	debugfs_create_x8("dbg_tpa_node", S_IRUSR | S_IWUSR,
3915 				   debugfs_host, &tpa_node_dbg);
3916 
3917 	debugfs_create_u32("set_sdio_clk", S_IRUSR | S_IWUSR,
3918 				   debugfs_host, &dbg_sdio_clk);
3919 
3920 	debugfs_create_u32("tx_burst_limit", S_IRUSR | S_IWUSR,
3921 				   debugfs_host, &tx_burst_limit);
3922 
3923 #ifdef ERROR_HANG_DRIVER
3924 	debugfs_create_u8("error_hang_driver", S_IRUSR | S_IWUSR,
3925 				   debugfs_host, &error_hang_driver);
3926 #endif
3927 
3928 	return 0;
3929 
3930 #undef ERR_LINE
3931 err:
3932 	xradio_dbg(XRADIO_DBG_ERROR, "xradio_host_dbg_init failed=%d\n", line);
3933 	if (debugfs_host)
3934 		debugfs_remove_recursive(debugfs_host);
3935 #if (DGB_XRADIO_QC)
3936 	debugfs_hwinfo = NULL;
3937 #endif
3938 	debugfs_host = NULL;
3939 	return 0;
3940 }
3941 
xradio_host_dbg_deinit(void)3942 void xradio_host_dbg_deinit(void)
3943 {
3944 	xradio_dbg(XRADIO_DBG_TRC, "%s\n", __func__);
3945 	if (debugfs_host)
3946 		debugfs_remove_recursive(debugfs_host);
3947 #if (DGB_XRADIO_QC)
3948 	debugfs_hwinfo = NULL;
3949 #endif
3950 	debugfs_host = NULL;
3951 }
3952 
xradio_debug_init_common(struct xradio_common * hw_priv)3953 int xradio_debug_init_common(struct xradio_common *hw_priv)
3954 {
3955 	int ret = -ENOMEM;
3956 	int line = 0;
3957 	struct xradio_debug_common *d = NULL;
3958 	xradio_dbg(XRADIO_DBG_TRC, "%s\n", __func__);
3959 
3960 	/*init some debug variables here.*/
3961 	retry_dbg    = 0;
3962 	tpa_node_dbg = 0;
3963 
3964 #define ERR_LINE  do { line = __LINE__; goto err; } while (0)
3965 
3966 	d = xr_kzalloc(sizeof(struct xradio_debug_common), false);
3967 	hw_priv->debug = d;
3968 	if (!d) {
3969 		xradio_dbg(XRADIO_DBG_ERROR, "%s, xr_kzalloc failed!\n", __func__);
3970 		return ret;
3971 	}
3972 
3973 #ifdef ERROR_HANG_DRIVER
3974 	d->debugfs_phy = debugfs_create_dir("xradio", NULL);
3975 #else
3976 	d->debugfs_phy = debugfs_create_dir("xradio",
3977 			    hw_priv->hw->wiphy->debugfsdir);
3978 #endif
3979 
3980 	if (!d->debugfs_phy)
3981 		ERR_LINE;
3982 
3983 	if (!debugfs_create_file("version", S_IRUSR, d->debugfs_phy,
3984 			hw_priv, &fops_version))
3985 		ERR_LINE;
3986 
3987 	if (!debugfs_create_file("status", S_IRUSR, d->debugfs_phy,
3988 			hw_priv, &fops_status_common))
3989 		ERR_LINE;
3990 
3991 	if (!debugfs_create_file("counters", S_IRUSR, d->debugfs_phy,
3992 			hw_priv, &fops_counters))
3993 		ERR_LINE;
3994 
3995 	if (!debugfs_create_file("backoff", S_IRUSR, d->debugfs_phy,
3996 			hw_priv, &fops_backoff))
3997 		ERR_LINE;
3998 
3999 	if (!debugfs_create_file("txpipe", S_IRUSR, d->debugfs_phy,
4000 			hw_priv, &fops_txpipe))
4001 		ERR_LINE;
4002 
4003 	if (!debugfs_create_file("ampdu", S_IRUSR, d->debugfs_phy,
4004 			hw_priv, &fops_ampducounters))
4005 		ERR_LINE;
4006 
4007 	if (!debugfs_create_file("ratemap", S_IRUSR, d->debugfs_phy,
4008 			hw_priv, &fops_ratemap))
4009 		ERR_LINE;
4010 
4011 	if (!debugfs_create_file("dbgstats", S_IRUSR, d->debugfs_phy,
4012 			hw_priv, &fops_dbgstats))
4013 		ERR_LINE;
4014 
4015 	if (!debugfs_create_file("11n", S_IRUSR | S_IWUSR,
4016 			d->debugfs_phy, hw_priv, &fops_11n))
4017 		ERR_LINE;
4018 
4019 	if (!debugfs_create_file("wsm_dumps", S_IWUSR, d->debugfs_phy,
4020 			hw_priv, &fops_wsm_dumps))
4021 		ERR_LINE;
4022 
4023 	if (!debugfs_create_file("set_fwdbg", S_IRUSR | S_IWUSR, d->debugfs_phy,
4024 			hw_priv, &fops_fwdbg))
4025 		ERR_LINE;
4026 
4027 	if (!debugfs_create_file("rw_fwreg", S_IWUSR, d->debugfs_phy, hw_priv,
4028 		  &fops_rw_fwreg))
4029 		ERR_LINE;
4030 
4031 	if (!debugfs_create_file("rw_fwreg_direct", S_IWUSR, d->debugfs_phy,
4032 		  hw_priv, &fops_rw_fwreg_direct))
4033 		ERR_LINE;
4034 
4035 	if (!debugfs_create_file("set_ampdu_len", S_IRUSR | S_IWUSR,
4036 		  d->debugfs_phy, hw_priv, &fops_ampdu_len))
4037 		ERR_LINE;
4038 
4039 	if (!debugfs_create_file("set_rts_threshold", S_IRUSR | S_IWUSR,
4040 		  d->debugfs_phy, hw_priv, &fops_rts_threshold))
4041 		ERR_LINE;
4042 
4043 	if (!debugfs_create_file("low_pwr_disable", S_IRUSR | S_IWUSR,
4044 		  d->debugfs_phy, hw_priv, &fops_low_pwr))
4045 		ERR_LINE;
4046 
4047 	if (!debugfs_create_file("ps_disable", S_IRUSR | S_IWUSR, d->debugfs_phy,
4048 		  hw_priv, &fops_ps_ctrl))
4049 		ERR_LINE;
4050 
4051 	if (!debugfs_create_file("retry_ctrl", S_IRUSR | S_IWUSR, d->debugfs_phy,
4052 		  hw_priv, &fops_retry_ctrl))
4053 		ERR_LINE;
4054 
4055 	if (!debugfs_create_file("rates_ctrl", S_IRUSR | S_IWUSR, d->debugfs_phy,
4056 		  hw_priv, &fops_rates_ctrl))
4057 		ERR_LINE;
4058 
4059 	if (!debugfs_create_file("backoff_ctrl", S_IRUSR | S_IWUSR, d->debugfs_phy,
4060 		  hw_priv, &fops_backoff_ctrl))
4061 		ERR_LINE;
4062 
4063 	if (!debugfs_create_file("tala_ctrl", S_IRUSR | S_IWUSR, d->debugfs_phy,
4064 		  hw_priv, &fops_tala_ctrl))
4065 		ERR_LINE;
4066 
4067 	if (!debugfs_create_file("tx_pwr_ctrl", S_IRUSR | S_IWUSR, d->debugfs_phy,
4068 		  hw_priv, &fops_tx_pwr_ctrl))
4069 		ERR_LINE;
4070 
4071 	if (!debugfs_create_file("tpa_ctrl", S_IRUSR | S_IWUSR, d->debugfs_phy,
4072 		  hw_priv, &fops_tpa_ctrl))
4073 		ERR_LINE;
4074 
4075 	if (!debugfs_create_file("tpa_debug", S_IRUSR, d->debugfs_phy,
4076 		  hw_priv, &fops_tpa_debug))
4077 		ERR_LINE;
4078 
4079 	if (!debugfs_create_file("policy_info", S_IRUSR, d->debugfs_phy,
4080 		  hw_priv, &fops_policy_info))
4081 		ERR_LINE;
4082 
4083 	if (!debugfs_create_file("bh_stat", S_IRUSR, d->debugfs_phy,
4084 		  hw_priv, &fops_bh_stat))
4085 		ERR_LINE;
4086 
4087 #if PERF_INFO_TEST
4088 	if (!debugfs_create_file("perf_info", S_IRUSR, d->debugfs_phy,
4089 		  hw_priv, &fops_perf_info))
4090 		ERR_LINE;
4091 #endif
4092 
4093 	if (!debugfs_create_file("txconfirm", S_IRUSR, d->debugfs_phy,
4094 		  hw_priv, &fops_txconfirm))
4095 		ERR_LINE;
4096 
4097 	if (!debugfs_create_file("tx_delay", S_IRUSR, d->debugfs_phy,
4098 		  hw_priv, &fops_txdelay))
4099 		ERR_LINE;
4100 
4101 	if (!debugfs_create_file("parse_flags", S_IRUSR | S_IWUSR,
4102 		  d->debugfs_phy, hw_priv, &fops_parse_flags))
4103 		ERR_LINE;
4104 
4105 	if (!debugfs_create_file("set_measure_type", S_IRUSR | S_IWUSR,
4106 		 d->debugfs_phy, hw_priv, &fops_11k))
4107 		ERR_LINE;
4108 
4109 	if (!debugfs_create_file("wsm_dump_size", S_IRUSR | S_IWUSR,
4110 		d->debugfs_phy, hw_priv, &fops_short_dump))
4111 		ERR_LINE;
4112 
4113 #if (SUPPORT_EPTA)
4114 	if (!debugfs_create_file("epta_stat", S_IRUSR, d->debugfs_phy,
4115 			hw_priv, &fops_epta_stat))
4116 		ERR_LINE;
4117 
4118 	if (!debugfs_create_file("epta_stat_ctrl", S_IRUSR | S_IWUSR, d->debugfs_phy,
4119 			hw_priv, &fops_epta_stat_dbg_ctrl))
4120 		ERR_LINE;
4121 #endif
4122 
4123 #if (DGB_XRADIO_HWT)
4124 	/*hardware test*/
4125 	if (!debugfs_create_file("hwt_hif_tx", S_IWUSR, d->debugfs_phy,
4126 		  hw_priv, &fops_hwt_hif_tx))
4127 		ERR_LINE;
4128 
4129 	if (!debugfs_create_file("hwt_hif_rx", S_IWUSR, d->debugfs_phy,
4130 		  hw_priv, &fops_hwt_hif_rx))
4131 		ERR_LINE;
4132 
4133 	if (!debugfs_create_file("hwt_enc", S_IWUSR, d->debugfs_phy,
4134 		  hw_priv, &fops_hwt_enc))
4135 		ERR_LINE;
4136 
4137 	if (!debugfs_create_file("hwt_mic", S_IWUSR, d->debugfs_phy,
4138 		  hw_priv, &fops_hwt_mic))
4139 		ERR_LINE;
4140 
4141 	if (!debugfs_create_file("hwt_hif_rx_burn", S_IWUSR, d->debugfs_phy,
4142 		hw_priv, &fops_hwt_hif_rx_burn))
4143 	ERR_LINE;
4144 
4145 #endif /*DGB_XRADIO_HWT*/
4146 
4147 #if (DGB_XRADIO_QC)
4148 	/*for QC apk read.*/
4149 	if (debugfs_host && !debugfs_hwinfo) {
4150 		debugfs_hwinfo = debugfs_create_file("hwinfo", S_IRUSR | S_IWUSR,
4151 				debugfs_host, hw_priv, &fops_hwinfo);
4152 		if (!debugfs_hwinfo)
4153 			ERR_LINE;
4154 	}
4155 
4156 	if (!debugfs_create_file("temperature", S_IRUSR, d->debugfs_phy,
4157 		hw_priv, &fops_temperature))
4158 	ERR_LINE;
4159 #endif
4160 	ret = xradio_itp_init(hw_priv);
4161 	if (ret)
4162 		ERR_LINE;
4163 
4164 #ifdef SUPPORT_FW_DBG_INF
4165 	xradio_fw_dbg_init(hw_priv);
4166 #endif
4167 
4168 	return 0;
4169 
4170 #undef ERR_LINE
4171 
4172 err:
4173 	xradio_dbg(XRADIO_DBG_ERROR,
4174 		   "xradio_debug_init_common failed=%d\n", line);
4175 	hw_priv->debug = NULL;
4176 	debugfs_remove_recursive(d->debugfs_phy);
4177 	kfree(d);
4178 	return ret;
4179 }
4180 
xradio_debug_release_common(struct xradio_common * hw_priv)4181 void xradio_debug_release_common(struct xradio_common *hw_priv)
4182 {
4183 	struct xradio_debug_common *d = hw_priv->debug;
4184 	xradio_dbg(XRADIO_DBG_TRC, "%s\n", __func__);
4185 
4186 #if (DGB_XRADIO_QC)
4187 	if (debugfs_hwinfo) {
4188 		debugfs_remove(debugfs_hwinfo);
4189 		debugfs_hwinfo = NULL;
4190 	}
4191 #endif
4192 	if (d) {
4193 #ifdef SUPPORT_FW_DBG_INF
4194 		xradio_fw_dbg_deinit();
4195 #endif
4196 		xradio_itp_release(hw_priv);
4197 		hw_priv->debug = NULL;
4198 
4199 #ifdef ERROR_HANG_DRIVER
4200 		debugfs_remove_recursive(d->debugfs_phy);
4201 #else
4202 		/* removed by mac80211, don't remove it again,
4203 		 * fixed wifi on/off.*/
4204 		/*
4205 		 debugfs_remove_recursive(d->debugfs_phy);
4206 		 */
4207 #endif
4208 		kfree(d);
4209 	}
4210 }
4211 
4212 #define FRAME_TYPE(xx) ieee80211_is_ ## xx(fctl)
4213 #define FT_MSG_PUT(f, ...) do { \
4214 	if (flags&f)	\
4215 		frame_msg += sprintf(frame_msg, __VA_ARGS__); \
4216 	} while (0)
4217 
4218 #define PT_MSG_PUT(f, ...) do { \
4219 	if (flags&f)	\
4220 		proto_msg += sprintf(proto_msg, __VA_ARGS__); \
4221 	} while (0)
4222 
4223 #define FRAME_PARSE(f, name) do { \
4224 	if (FRAME_TYPE(name)) { \
4225 		FT_MSG_PUT(f, "%s", #name); goto outprint; } \
4226 	} while (0)
4227 
4228 #define IS_FRAME_PRINT (frame_msg != (char *)&framebuf[0])
4229 #define IS_PROTO_PRINT (proto_msg != (char *)&protobuf[0])
4230 
4231 
4232 char framebuf[512] = { 0 };
4233 char protobuf[512] = { 0 };
4234 
4235 char *p2p_frame_type[] = {
4236 	"GO Negotiation Request",
4237 	"GO Negotiation Response",
4238 	"GO Negotiation Confirmation",
4239 	"P2P Invitation Request",
4240 	"P2P Invitation Response",
4241 	"Device Discoverability Request",
4242 	"Device Discoverability Response",
4243 	"Provision Discovery Request",
4244 	"Provision Discovery Response",
4245 	"Reserved"
4246 };
4247 
xradio_parse_frame(u8 * mac_data,u8 iv_len,u16 flags,u8 if_id)4248 void xradio_parse_frame(u8 *mac_data, u8 iv_len, u16 flags, u8 if_id)
4249 {
4250 	char *frame_msg = &framebuf[0];
4251 	char *proto_msg = &protobuf[0];
4252 	struct ieee80211_hdr *frame = (struct ieee80211_hdr *)mac_data;
4253 	u16 fctl = frame->frame_control;
4254 
4255 	memset(frame_msg, 0, sizeof(framebuf));
4256 	memset(proto_msg, 0, sizeof(protobuf));
4257 
4258 	if (ieee80211_is_data(fctl)) {
4259 		u8 machdrlen = ieee80211_hdrlen(fctl);
4260 		u8 *llc_data = mac_data + machdrlen + iv_len;
4261 
4262 		if (ieee80211_is_qos_nullfunc(fctl) ||
4263 		    ieee80211_is_data_qos(fctl))
4264 			FT_MSG_PUT(PF_DATA, "QoS");
4265 		if (ieee80211_is_nullfunc(fctl)) {
4266 			FT_MSG_PUT(PF_DATA, "NULL(ps=%d)", !!(fctl&IEEE80211_FCTL_PM));
4267 			goto outprint;
4268 		}
4269 		FT_MSG_PUT(PF_DATA, "data(TDFD=%d%d, R=%d, P=%d)",
4270 			   !!(fctl & IEEE80211_FCTL_TODS),
4271 			   !!(fctl & IEEE80211_FCTL_FROMDS),
4272 			   !!(fctl & IEEE80211_FCTL_RETRY),
4273 			   !!(fctl & IEEE80211_FCTL_PROTECTED));
4274 
4275 		if (is_SNAP(llc_data)) {
4276 			if (is_ip(llc_data)) {
4277 				u8 *ip_hdr = llc_data + LLC_LEN;
4278 				u8 *ipaddr_s = ip_hdr + IP_S_ADD_OFF;
4279 				u8 *ipaddr_d = ip_hdr + IP_D_ADD_OFF;
4280 				u8 *proto_hdr = ip_hdr + ((ip_hdr[0] & 0xf) << 2);	/*ihl:words*/
4281 
4282 				if (is_tcp(llc_data)) {
4283 					PT_MSG_PUT(PF_TCP,
4284 						   "TCP%s%s, src=%d, dest=%d, seq=0x%08x, ack=0x%08x",
4285 					    (proto_hdr[13]&0x01) ? "(S)" : "",
4286 					    (proto_hdr[13]&0x02) ? "(F)" : "",
4287 					    (proto_hdr[0]<<8)  | proto_hdr[1],
4288 					    (proto_hdr[2]<<8)  | proto_hdr[3],
4289 					    (proto_hdr[4]<<24) | (proto_hdr[5]<<16) |
4290 					    (proto_hdr[6]<<8)  | proto_hdr[7],
4291 					    (proto_hdr[8]<<24) | (proto_hdr[9]<<16) |
4292 					    (proto_hdr[10]<<8) | proto_hdr[11]);
4293 
4294 				} else if (is_udp(llc_data)) {
4295 					if (is_dhcp(llc_data)) {
4296 						u8 Options_len = BOOTP_OPS_LEN;
4297 						u32 dhcp_magic  = cpu_to_be32(DHCP_MAGIC);
4298 						u8 *dhcphdr = proto_hdr + UDP_LEN+UDP_BOOTP_LEN;
4299 						while (Options_len) {
4300 							if (*(u32 *)dhcphdr == dhcp_magic)
4301 								break;
4302 							dhcphdr++;
4303 							Options_len--;
4304 						}
4305 						PT_MSG_PUT(PF_DHCP, "DHCP, Opt=%d, MsgType=%d",
4306 							   *(dhcphdr+4), *(dhcphdr+6));
4307 					} else {
4308 						PT_MSG_PUT(PF_UDP, "UDP, source=%d, dest=%d",
4309 							  (proto_hdr[0]<<8) | proto_hdr[1],
4310 							  (proto_hdr[2]<<8) | proto_hdr[3]);
4311 					}
4312 				} else if (is_icmp(llc_data)) {
4313 					PT_MSG_PUT(PF_ICMP, "ICMP%s%s, Seq=%d",
4314 						   (8 == proto_hdr[0]) ? "(ping)"  : "",
4315 						   (0 == proto_hdr[0]) ? "(reply)" : "",
4316 							(proto_hdr[6]<<8) | proto_hdr[7]);
4317 				} else if (is_igmp(llc_data)) {
4318 					PT_MSG_PUT(PF_UNKNWN, "IGMP, type=0x%x", proto_hdr[0]);
4319 				} else {
4320 					PT_MSG_PUT(PF_UNKNWN, "unknown IP type=%d",
4321 						   *(ip_hdr + IP_PROTO_OFF));
4322 				}
4323 				if (IS_PROTO_PRINT) {
4324 					PT_MSG_PUT(PF_IPADDR, "-%d.%d.%d.%d(s)", \
4325 						   ipaddr_s[0], ipaddr_s[1],
4326 						   ipaddr_s[2], ipaddr_s[3]);
4327 					PT_MSG_PUT(PF_IPADDR, "-%d.%d.%d.%d(d)", \
4328 						   ipaddr_d[0], ipaddr_d[1],
4329 						   ipaddr_d[2], ipaddr_d[3]);
4330 				}
4331 
4332 			} else if (is_8021x(llc_data)) {
4333 				PT_MSG_PUT(PF_8021X, "8021X");
4334 			} else {	/*other protol, no detail.*/
4335 				switch (cpu_to_be16(*(u16 *)(llc_data+LLC_TYPE_OFF))) {
4336 				case ETH_P_IPV6:	/*0x08dd*/
4337 					PT_MSG_PUT(PF_UNKNWN, "IPv6");
4338 					break;
4339 				case ETH_P_ARP:	/*0x0806*/
4340 					PT_MSG_PUT(PF_UNKNWN, "ARP");
4341 					break;
4342 				case ETH_P_RARP:	/*0x8035*/
4343 					PT_MSG_PUT(PF_UNKNWN, "RARP");
4344 					break;
4345 				case ETH_P_DNA_RC:	/*0x6002*/
4346 					PT_MSG_PUT(PF_UNKNWN, "DNA Remote Console");
4347 					break;
4348 				case ETH_P_DNA_RT:	/*0x6003*/
4349 					PT_MSG_PUT(PF_UNKNWN, "DNA Routing");
4350 					break;
4351 				case ETH_P_8021Q:	/*0x8100*/
4352 					PT_MSG_PUT(PF_UNKNWN, "802.1Q VLAN");
4353 					break;
4354 				case ETH_P_LINK_CTL:	/*0x886c*/
4355 					PT_MSG_PUT(PF_UNKNWN, "wlan link local tunnel(HPNA)");
4356 					break;
4357 				case ETH_P_PPP_DISC:	/*0x8863*/
4358 					PT_MSG_PUT(PF_UNKNWN, "PPPoE discovery");
4359 					break;
4360 				case ETH_P_PPP_SES:	/*0x8864*/
4361 					PT_MSG_PUT(PF_UNKNWN, "PPPoE session");
4362 					break;
4363 				case ETH_P_MPLS_UC:	/*0x8847*/
4364 					PT_MSG_PUT(PF_UNKNWN, "MPLS Unicast");
4365 					break;
4366 				case ETH_P_MPLS_MC:	/*0x8848*/
4367 					PT_MSG_PUT(PF_UNKNWN, "MPLS Multicast");
4368 					break;
4369 				default:
4370 					PT_MSG_PUT(PF_UNKNWN, "unknown Ethernet type=0x%04x",
4371 						   cpu_to_be16(*(u16 *)(llc_data+LLC_TYPE_OFF)));
4372 					break;
4373 				}
4374 			}
4375 		} else if (is_STP(llc_data)) {
4376 			/*spanning tree proto.*/
4377 			PT_MSG_PUT(PF_UNKNWN, "spanning tree");
4378 		} else {
4379 			PT_MSG_PUT(PF_UNKNWN, "unknown LLC type=0x%08x, 0x%08x",
4380 				   *(u32 *)(llc_data), *((u32 *)(llc_data)+1));
4381 		}
4382 
4383 	} else if (ieee80211_is_mgmt(fctl) && (PF_MGMT & flags)) {
4384 
4385 		FRAME_PARSE(PF_MGMT, auth);
4386 		FRAME_PARSE(PF_MGMT, deauth);
4387 		FRAME_PARSE(PF_MGMT, assoc_req);
4388 		FRAME_PARSE(PF_MGMT, assoc_resp);
4389 		FRAME_PARSE(PF_MGMT, reassoc_req);
4390 		FRAME_PARSE(PF_MGMT, reassoc_resp);
4391 		FRAME_PARSE(PF_MGMT, disassoc);
4392 		FRAME_PARSE(PF_MGMT, atim);
4393 
4394 		/*for more information about action frames.*/
4395 		if (FRAME_TYPE(action)) {
4396 			u8 *encrypt_frame = NULL;
4397 			struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)frame;
4398 			if (frame->frame_control & __cpu_to_le32(IEEE80211_FCTL_PROTECTED) && (flags & PF_RX)) {
4399 				encrypt_frame = (u8 *)frame + IEEE80211_CCMP_256_HDR_LEN;
4400 				mgmt = (struct ieee80211_mgmt *)encrypt_frame;
4401 			}
4402 			FT_MSG_PUT(PF_MGMT, "%s", "action");
4403 
4404 			if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) {
4405 				u8 *action = (u8 *) &mgmt->u.action.category;
4406 				u32 oui = *(u32 *) &action[2];
4407 				u8 oui_subtype = action[6] > 8 ? 9 : action[6];
4408 				if (action[1] == 0x09 && oui == 0x099A6F50)
4409 					FT_MSG_PUT(PF_MGMT, "(%s)", p2p_frame_type[oui_subtype]);
4410 			} else if (mgmt->u.action.category == WLAN_CATEGORY_BACK &&
4411 				mgmt->u.action.u.addba_req.action_code ==
4412 				WLAN_ACTION_ADDBA_REQ) {
4413 				FT_MSG_PUT(PF_MGMT, "(ADDBA_REQ-%d)",
4414 					   mgmt->u.action.u.addba_req.start_seq_num);
4415 			} else if (mgmt->u.action.category == WLAN_CATEGORY_BACK &&
4416 				mgmt->u.action.u.addba_req.action_code ==
4417 				WLAN_ACTION_ADDBA_RESP) {
4418 				FT_MSG_PUT(PF_MGMT, "(ADDBA_RESP-%d)",
4419 					   mgmt->u.action.u.addba_resp.status);
4420 			} else if (mgmt->u.action.category == WLAN_CATEGORY_SA_QUERY &&
4421 				mgmt->u.action.u.sa_query.action ==
4422 				WLAN_ACTION_SA_QUERY_REQUEST) {
4423 				FT_MSG_PUT(PF_MGMT, "(SA_Query_Req)");
4424 			} else if (mgmt->u.action.category == WLAN_CATEGORY_SA_QUERY &&
4425 				mgmt->u.action.u.sa_query.action ==
4426 				WLAN_ACTION_SA_QUERY_RESPONSE) {
4427 				FT_MSG_PUT(PF_MGMT, "(SA_Query_Resp)");
4428 			} else {
4429 				FT_MSG_PUT(PF_MGMT, "(%d)", mgmt->u.action.category);
4430 			}
4431 			goto outprint;
4432 		}
4433 		/*too much scan results, don't print if no need.*/
4434 		FRAME_PARSE(PF_SCAN, probe_req);
4435 		FRAME_PARSE(PF_SCAN, probe_resp);
4436 		FRAME_PARSE(PF_SCAN, beacon);
4437 		/*must be last.*/
4438 		FT_MSG_PUT(PF_UNKNWN, "unknown mgmt");
4439 
4440 	} else if (ieee80211_is_ctl(fctl) && (PF_CTRL & flags)) {
4441 
4442 		flags &= (~PF_MAC_SN);	/*no seq ctrl in ctrl frames.*/
4443 		FRAME_PARSE(PF_CTRL, back);
4444 		FRAME_PARSE(PF_CTRL, back_req);
4445 		FRAME_PARSE(PF_CTRL, ack);
4446 		FRAME_PARSE(PF_CTRL, rts);
4447 		FRAME_PARSE(PF_CTRL, cts);
4448 		FRAME_PARSE(PF_CTRL, pspoll);
4449 		/*must be last.*/
4450 		FT_MSG_PUT(PF_UNKNWN, "unknown ctrl");
4451 	} else {
4452 		FT_MSG_PUT(PF_UNKNWN, "unknown mac frame, fctl=0x%04x\n", fctl);
4453 	}
4454 
4455 outprint:
4456 
4457 	FT_MSG_PUT(PF_MAC_SN, "-SN=%d(%d)",
4458 		   (frame->seq_ctrl>>4), (frame->seq_ctrl&0xf));
4459 
4460 	/*output all msg.*/
4461 	if (IS_FRAME_PRINT || IS_PROTO_PRINT) {
4462 		u8 *related = NULL;
4463 		u8 *own = NULL;
4464 		char *r_type = NULL;
4465 		char *o_type = NULL;
4466 		u8 machdrlen = ieee80211_hdrlen(fctl);
4467 		u8 *sa = ieee80211_get_SA(frame);
4468 		u8 *da = ieee80211_get_DA(frame);
4469 
4470 		if (flags & PF_RX) {
4471 			related = frame->addr2;
4472 			own = frame->addr1;
4473 			r_type = "TA";
4474 			o_type = "RA";
4475 		} else {
4476 			related = frame->addr1;
4477 			own = frame->addr2;
4478 			r_type = "RA";
4479 			o_type = "TA";
4480 		}
4481 
4482 		if (machdrlen >= 16) {	/*if ACK or BA, don't print.*/
4483 			FT_MSG_PUT(PF_MACADDR, "-%02x:%02x:%02x:%02x:%02x:%02x(%s)",
4484 				   related[0], related[1], related[2],
4485 				   related[3], related[4], related[5],
4486 				   r_type);
4487 			FT_MSG_PUT(PF_OWNMAC, "-%02x:%02x:%02x:%02x:%02x:%02x(%s)",
4488 				   own[0], own[1], own[2], own[3], own[4], own[5],
4489 				   o_type);
4490 			FT_MSG_PUT(PF_SA_DA, "-%02x:%02x:%02x:%02x:%02x:%02x(DA)",
4491 				   da[0], da[1], da[2], da[3], da[4], da[5]);
4492 			FT_MSG_PUT(PF_SA_DA, "-%02x:%02x:%02x:%02x:%02x:%02x(SA)",
4493 				   sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
4494 		}
4495 
4496 		xradio_dbg(XRADIO_DBG_ALWY, "if%d-%s%s--%s\n", if_id,
4497 			   (PF_RX & flags) ? "RX-" : "TX-", framebuf, protobuf);
4498 	}
4499 }
4500 
4501 #undef FT_MSG_PUT
4502 #undef PT_MSG_PUT
4503 #undef FRAME_PARSE
4504 #undef FRAME_TYPE
4505 
4506 #if DGB_LOG_FILE
4507 u8 log_buffer[DGB_LOG_BUF_LEN];
4508 u16 log_pos;
4509 struct file *fp_log;
4510 atomic_t file_ref = { 0 };
4511 
4512 #define T_LABEL_LEN  32
4513 char last_time_label[T_LABEL_LEN] = { 0 };
4514 
xradio_logfile(char * buffer,int buf_len,u8 b_time)4515 int xradio_logfile(char *buffer, int buf_len, u8 b_time)
4516 {
4517 	int ret = -1;
4518 	int size = buf_len;
4519 	mm_segment_t old_fs = get_fs();
4520 
4521 	if (!buffer)
4522 		return ret;
4523 
4524 	if (buf_len < 0)
4525 		size = strlen(buffer);
4526 	if (!size)
4527 		return ret;
4528 
4529 	if (atomic_add_return(1, &file_ref) == 1) {
4530 		fp_log = filp_open(DGB_LOG_PATH0, O_CREAT | O_WRONLY, 0666);
4531 		if (IS_ERR(fp_log)) {
4532 			printk(KERN_ERR "[XRADIO] ERR, can't open %s(%d).\n",
4533 			       DGB_LOG_PATH0, (int)fp_log);
4534 			goto exit;
4535 		}
4536 	}
4537 	/*printk(KERN_ERR "[XRADIO] file_ref=%d\n", atomic_read(&file_ref));*/
4538 
4539 	if (fp_log->f_op->write == NULL) {
4540 		printk(KERN_ERR "[XRADIO] ERR, %s:File is not allow to write!\n",
4541 		       __func__);
4542 		goto exit;
4543 	} else {
4544 		set_fs(KERNEL_DS);
4545 		if (fp_log->f_op->llseek != NULL) {
4546 			vfs_llseek(fp_log, 0, SEEK_END);
4547 		} else {
4548 			fp_log->f_pos = 0;
4549 		}
4550 		set_fs(old_fs);
4551 		if (b_time) {
4552 			struct timespec64 time_now = { 0 };
4553 			struct rtc_time tm;
4554 			char time_label[T_LABEL_LEN] = { 0 };
4555 			xr_do_gettimeofday(&time_now);
4556 			time_now.tv_sec -= sys_tz.tz_minuteswest * 60;
4557 			rtc_time_to_tm(time_now.tv_sec, &tm);
4558 			sprintf(time_label, "\n%d-%02d-%02d_%02d-%02d-%02d\n",
4559 				tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
4560 				tm.tm_hour, tm.tm_min, tm.tm_sec);
4561 			if (memcmp(last_time_label, time_label, T_LABEL_LEN)) {
4562 				memcpy(last_time_label, time_label, T_LABEL_LEN);
4563 				ret = kernel_write(fp_log, time_label, strlen(time_label),
4564 						&fp_log->f_pos);
4565 			}
4566 		}
4567 		ret = kernel_write(fp_log, buffer, size, &fp_log->f_pos);
4568 	}
4569 
4570 exit:
4571 	if (atomic_read(&file_ref) == 1) {
4572 		if (!IS_ERR(fp_log)) {
4573 			filp_close(fp_log, NULL);
4574 			fp_log = (struct file *)-ENOENT;
4575 		}
4576 	}
4577 	atomic_sub(1, &file_ref);
4578 	return ret;
4579 }
4580 #endif
4581 
4582 #if (DGB_XRADIO_HWT)
4583 /***************************for HWT********************************/
4584 struct sk_buff *hwt_skb;
4585 int sent_num;
get_hwt_hif_tx(struct xradio_common * hw_priv,u8 ** data,size_t * tx_len,int * burst,int * vif_selected)4586 int get_hwt_hif_tx(struct xradio_common *hw_priv, u8 **data,
4587 		   size_t *tx_len, int *burst, int *vif_selected)
4588 {
4589 
4590 	HWT_PARAMETERS *hwt_tx_hdr = NULL;
4591 	if (!hwt_tx_en || !hwt_tx_len || !hwt_tx_num ||
4592 		  sent_num >= hwt_tx_num) {
4593 		if (hwt_skb) {
4594 			dev_kfree_skb(hwt_skb);
4595 			hwt_skb = NULL;
4596 		}
4597 		return 0;
4598 	}
4599 
4600 	if (!hwt_skb) {
4601 		hwt_skb = xr_alloc_skb(1504);
4602 		if (!hwt_skb) {
4603 			xradio_dbg(XRADIO_DBG_ERROR, "%s:skb is NULL!\n", __func__);
4604 			return 0;
4605 		}
4606 		if ((unsigned long)hwt_skb->data & 3) {
4607 			u8 align = 4 - ((unsigned long)hwt_skb->data & 3);
4608 			skb_reserve(hwt_skb, align);
4609 		}
4610 		skb_put(hwt_skb, 1500);
4611 	}
4612 	/*fill the header info*/
4613 	if (hwt_tx_len < sizeof(HWT_PARAMETERS))
4614 		hwt_tx_len = sizeof(HWT_PARAMETERS);
4615 	if (hwt_tx_len > 1500)
4616 		hwt_tx_len = 1500;
4617 	hwt_tx_hdr = (HWT_PARAMETERS *)hwt_skb->data;
4618 	hwt_tx_hdr->MsgID = 0x0004;
4619 	hwt_tx_hdr->Msglen = hwt_tx_len;
4620 	hwt_tx_hdr->TestID = 0x0001;
4621 	hwt_tx_hdr->Data = 0x1234;
4622 
4623 	/*send the packet*/
4624 	*data = hwt_skb->data;
4625 	*tx_len = hwt_tx_hdr->Msglen;
4626 	*vif_selected = 0;
4627 	*burst = 2;		/*burst > 1 for continuous tx.*/
4628 	sent_num++;
4629 
4630 	/*first packet.*/
4631 	if (sent_num == 1) {
4632 		xr_do_gettimeofday(&hwt_start_time);
4633 	}
4634 	/*set confirm*/
4635 	hwt_tx_hdr->Params = 0;
4636 	if (sent_num >= hwt_tx_num) {
4637 		hwt_tx_hdr->Params = 0x101;	/*last packet*/
4638 		hwt_tx_en = 0;	/*disable hwt_tx_en*/
4639 		xradio_dbg(XRADIO_DBG_ALWY, "%s:sent last packet!\n", __func__);
4640 	} else if (hwt_tx_cfm) {
4641 		hwt_tx_hdr->Params = !(sent_num % hwt_tx_cfm);
4642 	}
4643 
4644 	return 1;
4645 }
4646 #endif
4647 
4648 #endif /* CONFIG_XRADIO_DEBUGFS */
4649