blob: 335e796ec3470a9ba5147b6d4c14a3adaa4f1c58 [file] [log] [blame]
Mohammed Javid478b3c02018-12-17 14:39:54 +05301/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
Amir Levy9659e592016-10-27 18:08:27 +03002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#ifdef CONFIG_DEBUG_FS
14
15#include <linux/debugfs.h>
16#include <linux/kernel.h>
17#include <linux/stringify.h>
18#include "ipa_i.h"
19#include "../ipa_rm_i.h"
Amir Levy479cfdd2017-10-26 12:23:14 +030020#include "ipahal/ipahal_nat.h"
Amir Levy9659e592016-10-27 18:08:27 +030021
Amir Levy479cfdd2017-10-26 12:23:14 +030022#define IPA_MAX_ENTRY_STRING_LEN 500
Amir Levy9659e592016-10-27 18:08:27 +030023#define IPA_MAX_MSG_LEN 4096
24#define IPA_DBG_MAX_RULE_IN_TBL 128
25#define IPA_DBG_ACTIVE_CLIENT_BUF_SIZE ((IPA3_ACTIVE_CLIENTS_LOG_LINE_LEN \
26 * IPA3_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES) + IPA_MAX_MSG_LEN)
27
28#define IPA_DUMP_STATUS_FIELD(f) \
29 pr_err(#f "=0x%x\n", status->f)
30
Amir Levy479cfdd2017-10-26 12:23:14 +030031#define IPA_READ_ONLY_MODE 0444
32#define IPA_READ_WRITE_MODE 0664
33#define IPA_WRITE_ONLY_MODE 0220
34
35struct ipa3_debugfs_file {
36 const char *name;
37 umode_t mode;
38 void *data;
39 const struct file_operations fops;
40};
41
Amir Levy9659e592016-10-27 18:08:27 +030042
43const char *ipa3_event_name[] = {
44 __stringify(WLAN_CLIENT_CONNECT),
45 __stringify(WLAN_CLIENT_DISCONNECT),
46 __stringify(WLAN_CLIENT_POWER_SAVE_MODE),
47 __stringify(WLAN_CLIENT_NORMAL_MODE),
48 __stringify(SW_ROUTING_ENABLE),
49 __stringify(SW_ROUTING_DISABLE),
50 __stringify(WLAN_AP_CONNECT),
51 __stringify(WLAN_AP_DISCONNECT),
52 __stringify(WLAN_STA_CONNECT),
53 __stringify(WLAN_STA_DISCONNECT),
54 __stringify(WLAN_CLIENT_CONNECT_EX),
55 __stringify(WLAN_SWITCH_TO_SCC),
56 __stringify(WLAN_SWITCH_TO_MCC),
57 __stringify(WLAN_WDI_ENABLE),
58 __stringify(WLAN_WDI_DISABLE),
59 __stringify(WAN_UPSTREAM_ROUTE_ADD),
60 __stringify(WAN_UPSTREAM_ROUTE_DEL),
61 __stringify(WAN_EMBMS_CONNECT),
62 __stringify(WAN_XLAT_CONNECT),
63 __stringify(ECM_CONNECT),
64 __stringify(ECM_DISCONNECT),
65 __stringify(IPA_TETHERING_STATS_UPDATE_STATS),
66 __stringify(IPA_TETHERING_STATS_UPDATE_NETWORK_STATS),
Skylar Chang09e0e252017-03-20 14:51:29 -070067 __stringify(IPA_QUOTA_REACH),
68 __stringify(IPA_SSR_BEFORE_SHUTDOWN),
69 __stringify(IPA_SSR_AFTER_POWERUP),
Shihuan Liuc3174f52017-05-04 15:59:13 -070070 __stringify(ADD_VLAN_IFACE),
71 __stringify(DEL_VLAN_IFACE),
72 __stringify(ADD_L2TP_VLAN_MAPPING),
Mohammed Javidd0c2a1e2017-10-30 15:34:22 +053073 __stringify(DEL_L2TP_VLAN_MAPPING),
74 __stringify(IPA_PER_CLIENT_STATS_CONNECT_EVENT),
75 __stringify(IPA_PER_CLIENT_STATS_DISCONNECT_EVENT),
Amir Levy4f8b4832018-06-05 15:48:03 +030076 __stringify(ADD_BRIDGE_VLAN_MAPPING),
77 __stringify(DEL_BRIDGE_VLAN_MAPPING),
Mohammed Javid1102e802018-06-25 18:58:20 +053078 __stringify(WLAN_FWR_SSR_BEFORE_SHUTDOWN),
Mohammed Javida0f23d92018-09-11 10:50:28 +053079 __stringify(IPA_GSB_CONNECT),
80 __stringify(IPA_GSB_DISCONNECT),
Amir Levy9659e592016-10-27 18:08:27 +030081};
82
83const char *ipa3_hdr_l2_type_name[] = {
84 __stringify(IPA_HDR_L2_NONE),
85 __stringify(IPA_HDR_L2_ETHERNET_II),
86 __stringify(IPA_HDR_L2_802_3),
87};
88
89const char *ipa3_hdr_proc_type_name[] = {
90 __stringify(IPA_HDR_PROC_NONE),
91 __stringify(IPA_HDR_PROC_ETHII_TO_ETHII),
92 __stringify(IPA_HDR_PROC_ETHII_TO_802_3),
93 __stringify(IPA_HDR_PROC_802_3_TO_ETHII),
94 __stringify(IPA_HDR_PROC_802_3_TO_802_3),
Skylar Chang7fa22712017-04-03 18:29:21 -070095 __stringify(IPA_HDR_PROC_L2TP_HEADER_ADD),
96 __stringify(IPA_HDR_PROC_L2TP_HEADER_REMOVE),
Amir Levy9659e592016-10-27 18:08:27 +030097};
98
99static struct dentry *dent;
Amir Levy9659e592016-10-27 18:08:27 +0300100static char dbg_buff[IPA_MAX_MSG_LEN];
101static char *active_clients_buf;
102
103static s8 ep_reg_idx;
Skylar Chang48c83622017-04-25 16:24:49 -0700104static void *ipa_ipc_low_buff;
Amir Levy9659e592016-10-27 18:08:27 +0300105
106
107static ssize_t ipa3_read_gen_reg(struct file *file, char __user *ubuf,
108 size_t count, loff_t *ppos)
109{
110 int nbytes;
111 struct ipahal_reg_shared_mem_size smem_sz;
112
113 memset(&smem_sz, 0, sizeof(smem_sz));
114
115 IPA_ACTIVE_CLIENTS_INC_SIMPLE();
116
117 ipahal_read_reg_fields(IPA_SHARED_MEM_SIZE, &smem_sz);
118 nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
119 "IPA_VERSION=0x%x\n"
120 "IPA_COMP_HW_VERSION=0x%x\n"
121 "IPA_ROUTE=0x%x\n"
122 "IPA_SHARED_MEM_RESTRICTED=0x%x\n"
123 "IPA_SHARED_MEM_SIZE=0x%x\n",
124 ipahal_read_reg(IPA_VERSION),
125 ipahal_read_reg(IPA_COMP_HW_VERSION),
126 ipahal_read_reg(IPA_ROUTE),
127 smem_sz.shared_mem_baddr,
128 smem_sz.shared_mem_sz);
129
130 IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
131
132 return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes);
133}
134
135static ssize_t ipa3_write_ep_holb(struct file *file,
136 const char __user *buf, size_t count, loff_t *ppos)
137{
138 struct ipa_ep_cfg_holb holb;
139 u32 en;
140 u32 tmr_val;
141 u32 ep_idx;
142 unsigned long missing;
143 char *sptr, *token;
144
145 if (sizeof(dbg_buff) < count + 1)
146 return -EFAULT;
147
148 missing = copy_from_user(dbg_buff, buf, count);
149 if (missing)
150 return -EFAULT;
151
152 dbg_buff[count] = '\0';
153
154 sptr = dbg_buff;
155
156 token = strsep(&sptr, " ");
157 if (!token)
158 return -EINVAL;
159 if (kstrtou32(token, 0, &ep_idx))
160 return -EINVAL;
161
162 token = strsep(&sptr, " ");
163 if (!token)
164 return -EINVAL;
165 if (kstrtou32(token, 0, &en))
166 return -EINVAL;
167
168 token = strsep(&sptr, " ");
169 if (!token)
170 return -EINVAL;
171 if (kstrtou32(token, 0, &tmr_val))
172 return -EINVAL;
173
174 holb.en = en;
175 holb.tmr_val = tmr_val;
176
177 ipa3_cfg_ep_holb(ep_idx, &holb);
178
179 return count;
180}
181
182static ssize_t ipa3_write_ep_reg(struct file *file, const char __user *buf,
183 size_t count, loff_t *ppos)
184{
185 unsigned long missing;
186 s8 option = 0;
187
188 if (sizeof(dbg_buff) < count + 1)
189 return -EFAULT;
190
191 missing = copy_from_user(dbg_buff, buf, count);
192 if (missing)
193 return -EFAULT;
194
195 dbg_buff[count] = '\0';
196 if (kstrtos8(dbg_buff, 0, &option))
197 return -EFAULT;
198
199 if (option >= ipa3_ctx->ipa_num_pipes) {
200 IPAERR("bad pipe specified %u\n", option);
201 return count;
202 }
203
204 ep_reg_idx = option;
205
206 return count;
207}
208
209/**
210 * _ipa_read_ep_reg_v3_0() - Reads and prints endpoint configuration registers
211 *
212 * Returns the number of characters printed
213 */
214int _ipa_read_ep_reg_v3_0(char *buf, int max_len, int pipe)
215{
216 return scnprintf(
217 dbg_buff, IPA_MAX_MSG_LEN,
218 "IPA_ENDP_INIT_NAT_%u=0x%x\n"
219 "IPA_ENDP_INIT_HDR_%u=0x%x\n"
220 "IPA_ENDP_INIT_HDR_EXT_%u=0x%x\n"
221 "IPA_ENDP_INIT_MODE_%u=0x%x\n"
222 "IPA_ENDP_INIT_AGGR_%u=0x%x\n"
223 "IPA_ENDP_INIT_ROUTE_%u=0x%x\n"
224 "IPA_ENDP_INIT_CTRL_%u=0x%x\n"
225 "IPA_ENDP_INIT_HOL_EN_%u=0x%x\n"
226 "IPA_ENDP_INIT_HOL_TIMER_%u=0x%x\n"
227 "IPA_ENDP_INIT_DEAGGR_%u=0x%x\n"
228 "IPA_ENDP_INIT_CFG_%u=0x%x\n",
229 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_NAT_n, pipe),
230 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_HDR_n, pipe),
231 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_HDR_EXT_n, pipe),
232 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_MODE_n, pipe),
233 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_AGGR_n, pipe),
234 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_ROUTE_n, pipe),
235 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_CTRL_n, pipe),
236 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_HOL_BLOCK_EN_n, pipe),
237 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_HOL_BLOCK_TIMER_n, pipe),
238 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_DEAGGR_n, pipe),
239 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_CFG_n, pipe));
240}
241
Michael Adisumarta891a4ff2017-05-16 16:40:06 -0700242/**
243 * _ipa_read_ep_reg_v4_0() - Reads and prints endpoint configuration registers
244 *
245 * Returns the number of characters printed
246 * Removed IPA_ENDP_INIT_ROUTE_n from v3
247 */
248int _ipa_read_ep_reg_v4_0(char *buf, int max_len, int pipe)
249{
250 return scnprintf(
251 dbg_buff, IPA_MAX_MSG_LEN,
252 "IPA_ENDP_INIT_NAT_%u=0x%x\n"
Amir Levydc65f4c2017-07-06 09:49:50 +0300253 "IPA_ENDP_INIT_CONN_TRACK_n%u=0x%x\n"
Michael Adisumarta891a4ff2017-05-16 16:40:06 -0700254 "IPA_ENDP_INIT_HDR_%u=0x%x\n"
255 "IPA_ENDP_INIT_HDR_EXT_%u=0x%x\n"
256 "IPA_ENDP_INIT_MODE_%u=0x%x\n"
257 "IPA_ENDP_INIT_AGGR_%u=0x%x\n"
258 "IPA_ENDP_INIT_CTRL_%u=0x%x\n"
259 "IPA_ENDP_INIT_HOL_EN_%u=0x%x\n"
260 "IPA_ENDP_INIT_HOL_TIMER_%u=0x%x\n"
261 "IPA_ENDP_INIT_DEAGGR_%u=0x%x\n"
262 "IPA_ENDP_INIT_CFG_%u=0x%x\n",
263 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_NAT_n, pipe),
Amir Levydc65f4c2017-07-06 09:49:50 +0300264 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_CONN_TRACK_n, pipe),
Michael Adisumarta891a4ff2017-05-16 16:40:06 -0700265 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_HDR_n, pipe),
266 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_HDR_EXT_n, pipe),
267 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_MODE_n, pipe),
268 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_AGGR_n, pipe),
269 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_CTRL_n, pipe),
270 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_HOL_BLOCK_EN_n, pipe),
271 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_HOL_BLOCK_TIMER_n, pipe),
272 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_DEAGGR_n, pipe),
273 pipe, ipahal_read_reg_n(IPA_ENDP_INIT_CFG_n, pipe));
274}
275
Amir Levy9659e592016-10-27 18:08:27 +0300276static ssize_t ipa3_read_ep_reg(struct file *file, char __user *ubuf,
277 size_t count, loff_t *ppos)
278{
279 int nbytes;
280 int i;
281 int start_idx;
282 int end_idx;
283 int size = 0;
284 int ret;
285 loff_t pos;
286
287 /* negative ep_reg_idx means all registers */
288 if (ep_reg_idx < 0) {
289 start_idx = 0;
290 end_idx = ipa3_ctx->ipa_num_pipes;
291 } else {
292 start_idx = ep_reg_idx;
293 end_idx = start_idx + 1;
294 }
295 pos = *ppos;
296 IPA_ACTIVE_CLIENTS_INC_SIMPLE();
297 for (i = start_idx; i < end_idx; i++) {
298
299 nbytes = ipa3_ctx->ctrl->ipa3_read_ep_reg(dbg_buff,
300 IPA_MAX_MSG_LEN, i);
301
302 *ppos = pos;
303 ret = simple_read_from_buffer(ubuf, count, ppos, dbg_buff,
304 nbytes);
305 if (ret < 0) {
306 IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
307 return ret;
308 }
309
310 size += ret;
311 ubuf += nbytes;
312 count -= nbytes;
313 }
314 IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
315
316 *ppos = pos + size;
317 return size;
318}
319
320static ssize_t ipa3_write_keep_awake(struct file *file, const char __user *buf,
321 size_t count, loff_t *ppos)
322{
323 unsigned long missing;
324 s8 option = 0;
325
326 if (sizeof(dbg_buff) < count + 1)
327 return -EFAULT;
328
329 missing = copy_from_user(dbg_buff, buf, count);
330 if (missing)
331 return -EFAULT;
332
333 dbg_buff[count] = '\0';
334 if (kstrtos8(dbg_buff, 0, &option))
335 return -EFAULT;
336
337 if (option == 1)
338 IPA_ACTIVE_CLIENTS_INC_SIMPLE();
339 else if (option == 0)
340 IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
341 else
342 return -EFAULT;
343
344 return count;
345}
346
347static ssize_t ipa3_read_keep_awake(struct file *file, char __user *ubuf,
348 size_t count, loff_t *ppos)
349{
350 int nbytes;
351
Skylar Chang242952b2017-07-20 15:04:05 -0700352 mutex_lock(&ipa3_ctx->ipa3_active_clients.mutex);
353 if (atomic_read(&ipa3_ctx->ipa3_active_clients.cnt))
Amir Levy9659e592016-10-27 18:08:27 +0300354 nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
355 "IPA APPS power state is ON\n");
356 else
357 nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
358 "IPA APPS power state is OFF\n");
Skylar Chang242952b2017-07-20 15:04:05 -0700359 mutex_unlock(&ipa3_ctx->ipa3_active_clients.mutex);
Amir Levy9659e592016-10-27 18:08:27 +0300360
361 return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes);
362}
363
364static ssize_t ipa3_read_hdr(struct file *file, char __user *ubuf, size_t count,
365 loff_t *ppos)
366{
367 int nbytes = 0;
368 int i = 0;
369 struct ipa3_hdr_entry *entry;
370
371 mutex_lock(&ipa3_ctx->lock);
372
373 if (ipa3_ctx->hdr_tbl_lcl)
374 pr_err("Table resides on local memory\n");
375 else
376 pr_err("Table resides on system (ddr) memory\n");
377
378 list_for_each_entry(entry, &ipa3_ctx->hdr_tbl.head_hdr_entry_list,
379 link) {
Mohammed Javid7f81eda2018-04-10 15:33:48 +0530380 if (entry->cookie != IPA_HDR_COOKIE)
381 continue;
Amir Levy9659e592016-10-27 18:08:27 +0300382 nbytes = scnprintf(
383 dbg_buff,
384 IPA_MAX_MSG_LEN,
385 "name:%s len=%d ref=%d partial=%d type=%s ",
386 entry->name,
387 entry->hdr_len,
388 entry->ref_cnt,
389 entry->is_partial,
390 ipa3_hdr_l2_type_name[entry->type]);
391
392 if (entry->is_hdr_proc_ctx) {
393 nbytes += scnprintf(
394 dbg_buff + nbytes,
395 IPA_MAX_MSG_LEN - nbytes,
396 "phys_base=0x%pa ",
397 &entry->phys_base);
398 } else {
399 nbytes += scnprintf(
400 dbg_buff + nbytes,
401 IPA_MAX_MSG_LEN - nbytes,
402 "ofst=%u ",
403 entry->offset_entry->offset >> 2);
404 }
405 for (i = 0; i < entry->hdr_len; i++) {
406 scnprintf(dbg_buff + nbytes + i * 2,
407 IPA_MAX_MSG_LEN - nbytes - i * 2,
408 "%02x", entry->hdr[i]);
409 }
410 scnprintf(dbg_buff + nbytes + entry->hdr_len * 2,
411 IPA_MAX_MSG_LEN - nbytes - entry->hdr_len * 2,
412 "\n");
413 pr_err("%s", dbg_buff);
414 }
415 mutex_unlock(&ipa3_ctx->lock);
416
417 return 0;
418}
419
420static int ipa3_attrib_dump(struct ipa_rule_attrib *attrib,
421 enum ipa_ip_type ip)
422{
423 uint32_t addr[4];
424 uint32_t mask[4];
425 int i;
426
427 if (attrib->attrib_mask & IPA_FLT_TOS_MASKED)
428 pr_err("tos_value:%d ", attrib->tos_value);
429
430 if (attrib->attrib_mask & IPA_FLT_TOS_MASKED)
431 pr_err("tos_mask:%d ", attrib->tos_mask);
432
433 if (attrib->attrib_mask & IPA_FLT_PROTOCOL)
434 pr_err("protocol:%d ", attrib->u.v4.protocol);
435
436 if (attrib->attrib_mask & IPA_FLT_SRC_ADDR) {
437 if (ip == IPA_IP_v4) {
438 addr[0] = htonl(attrib->u.v4.src_addr);
439 mask[0] = htonl(attrib->u.v4.src_addr_mask);
440 pr_err(
441 "src_addr:%pI4 src_addr_mask:%pI4 ",
442 addr + 0, mask + 0);
443 } else if (ip == IPA_IP_v6) {
444 for (i = 0; i < 4; i++) {
445 addr[i] = htonl(attrib->u.v6.src_addr[i]);
446 mask[i] = htonl(attrib->u.v6.src_addr_mask[i]);
447 }
448 pr_err(
449 "src_addr:%pI6 src_addr_mask:%pI6 ",
450 addr + 0, mask + 0);
451 } else {
452 WARN_ON(1);
453 }
454 }
455 if (attrib->attrib_mask & IPA_FLT_DST_ADDR) {
456 if (ip == IPA_IP_v4) {
457 addr[0] = htonl(attrib->u.v4.dst_addr);
458 mask[0] = htonl(attrib->u.v4.dst_addr_mask);
459 pr_err(
460 "dst_addr:%pI4 dst_addr_mask:%pI4 ",
461 addr + 0, mask + 0);
462 } else if (ip == IPA_IP_v6) {
463 for (i = 0; i < 4; i++) {
464 addr[i] = htonl(attrib->u.v6.dst_addr[i]);
465 mask[i] = htonl(attrib->u.v6.dst_addr_mask[i]);
466 }
467 pr_err(
468 "dst_addr:%pI6 dst_addr_mask:%pI6 ",
469 addr + 0, mask + 0);
470 } else {
471 WARN_ON(1);
472 }
473 }
474 if (attrib->attrib_mask & IPA_FLT_SRC_PORT_RANGE) {
475 pr_err("src_port_range:%u %u ",
476 attrib->src_port_lo,
477 attrib->src_port_hi);
478 }
479 if (attrib->attrib_mask & IPA_FLT_DST_PORT_RANGE) {
480 pr_err("dst_port_range:%u %u ",
481 attrib->dst_port_lo,
482 attrib->dst_port_hi);
483 }
484 if (attrib->attrib_mask & IPA_FLT_TYPE)
485 pr_err("type:%d ", attrib->type);
486
487 if (attrib->attrib_mask & IPA_FLT_CODE)
488 pr_err("code:%d ", attrib->code);
489
490 if (attrib->attrib_mask & IPA_FLT_SPI)
491 pr_err("spi:%x ", attrib->spi);
492
493 if (attrib->attrib_mask & IPA_FLT_SRC_PORT)
494 pr_err("src_port:%u ", attrib->src_port);
495
496 if (attrib->attrib_mask & IPA_FLT_DST_PORT)
497 pr_err("dst_port:%u ", attrib->dst_port);
498
499 if (attrib->attrib_mask & IPA_FLT_TC)
500 pr_err("tc:%d ", attrib->u.v6.tc);
501
502 if (attrib->attrib_mask & IPA_FLT_FLOW_LABEL)
503 pr_err("flow_label:%x ", attrib->u.v6.flow_label);
504
505 if (attrib->attrib_mask & IPA_FLT_NEXT_HDR)
506 pr_err("next_hdr:%d ", attrib->u.v6.next_hdr);
507
508 if (attrib->attrib_mask & IPA_FLT_META_DATA) {
509 pr_err(
510 "metadata:%x metadata_mask:%x ",
511 attrib->meta_data, attrib->meta_data_mask);
512 }
513
514 if (attrib->attrib_mask & IPA_FLT_FRAGMENT)
515 pr_err("frg ");
516
517 if ((attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_ETHER_II) ||
518 (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_802_3)) {
519 pr_err("src_mac_addr:%pM ", attrib->src_mac_addr);
520 }
521
522 if ((attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_ETHER_II) ||
Shihuan Liu65a4a412017-05-22 18:30:28 -0700523 (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_802_3) ||
524 (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_L2TP)) {
Amir Levy9659e592016-10-27 18:08:27 +0300525 pr_err("dst_mac_addr:%pM ", attrib->dst_mac_addr);
526 }
527
528 if (attrib->attrib_mask & IPA_FLT_MAC_ETHER_TYPE)
529 pr_err("ether_type:%x ", attrib->ether_type);
530
Shihuan Liu83889ee2017-08-04 11:00:00 -0700531 if (attrib->attrib_mask & IPA_FLT_TCP_SYN)
532 pr_err("tcp syn ");
533
534 if (attrib->attrib_mask & IPA_FLT_TCP_SYN_L2TP)
535 pr_err("tcp syn l2tp ");
536
Shihuan Liuf4433442017-09-28 17:46:41 -0700537 if (attrib->attrib_mask & IPA_FLT_L2TP_INNER_IP_TYPE)
538 pr_err("l2tp inner ip type: %d ", attrib->type);
539
540 if (attrib->attrib_mask & IPA_FLT_L2TP_INNER_IPV4_DST_ADDR) {
541 addr[0] = htonl(attrib->u.v4.dst_addr);
542 mask[0] = htonl(attrib->u.v4.dst_addr_mask);
543 pr_err("dst_addr:%pI4 dst_addr_mask:%pI4 ", addr, mask);
544 }
545
Amir Levy9659e592016-10-27 18:08:27 +0300546 pr_err("\n");
547 return 0;
548}
549
550static int ipa3_attrib_dump_eq(struct ipa_ipfltri_rule_eq *attrib)
551{
552 uint8_t addr[16];
553 uint8_t mask[16];
554 int i;
555 int j;
556
557 if (attrib->tos_eq_present)
558 pr_err("tos_value:%d ", attrib->tos_eq);
559
560 if (attrib->protocol_eq_present)
561 pr_err("protocol:%d ", attrib->protocol_eq);
562
563 if (attrib->tc_eq_present)
564 pr_err("tc:%d ", attrib->tc_eq);
565
Mohammed Javid7f81eda2018-04-10 15:33:48 +0530566 if (attrib->num_offset_meq_128 > IPA_IPFLTR_NUM_MEQ_128_EQNS) {
567 IPAERR_RL("num_offset_meq_128 Max %d passed value %d\n",
568 IPA_IPFLTR_NUM_MEQ_128_EQNS, attrib->num_offset_meq_128);
569 return -EPERM;
570 }
571
Amir Levy9659e592016-10-27 18:08:27 +0300572 for (i = 0; i < attrib->num_offset_meq_128; i++) {
573 for (j = 0; j < 16; j++) {
574 addr[j] = attrib->offset_meq_128[i].value[j];
575 mask[j] = attrib->offset_meq_128[i].mask[j];
576 }
577 pr_err(
578 "(ofst_meq128: ofst:%d mask:%pI6 val:%pI6) ",
579 attrib->offset_meq_128[i].offset,
580 mask, addr);
581 }
582
Mohammed Javid7f81eda2018-04-10 15:33:48 +0530583 if (attrib->num_offset_meq_32 > IPA_IPFLTR_NUM_MEQ_32_EQNS) {
584 IPAERR_RL("num_offset_meq_32 Max %d passed value %d\n",
585 IPA_IPFLTR_NUM_MEQ_32_EQNS, attrib->num_offset_meq_32);
586 return -EPERM;
587 }
588
Amir Levy9659e592016-10-27 18:08:27 +0300589 for (i = 0; i < attrib->num_offset_meq_32; i++)
590 pr_err(
591 "(ofst_meq32: ofst:%u mask:0x%x val:0x%x) ",
592 attrib->offset_meq_32[i].offset,
593 attrib->offset_meq_32[i].mask,
594 attrib->offset_meq_32[i].value);
595
Mohammed Javid7f81eda2018-04-10 15:33:48 +0530596 if (attrib->num_ihl_offset_meq_32 > IPA_IPFLTR_NUM_IHL_MEQ_32_EQNS) {
597 IPAERR_RL("num_ihl_offset_meq_32 Max %d passed value %d\n",
598 IPA_IPFLTR_NUM_IHL_MEQ_32_EQNS, attrib->num_ihl_offset_meq_32);
599 return -EPERM;
600 }
601
Amir Levy9659e592016-10-27 18:08:27 +0300602 for (i = 0; i < attrib->num_ihl_offset_meq_32; i++)
603 pr_err(
604 "(ihl_ofst_meq32: ofts:%d mask:0x%x val:0x%x) ",
605 attrib->ihl_offset_meq_32[i].offset,
606 attrib->ihl_offset_meq_32[i].mask,
607 attrib->ihl_offset_meq_32[i].value);
608
609 if (attrib->metadata_meq32_present)
610 pr_err(
611 "(metadata: ofst:%u mask:0x%x val:0x%x) ",
612 attrib->metadata_meq32.offset,
613 attrib->metadata_meq32.mask,
614 attrib->metadata_meq32.value);
615
Mohammed Javid7f81eda2018-04-10 15:33:48 +0530616 if (attrib->num_ihl_offset_range_16 >
617 IPA_IPFLTR_NUM_IHL_RANGE_16_EQNS) {
618 IPAERR_RL("num_ihl_offset_range_16 Max %d passed value %d\n",
619 IPA_IPFLTR_NUM_IHL_RANGE_16_EQNS,
620 attrib->num_ihl_offset_range_16);
621 return -EPERM;
622 }
623
Amir Levy9659e592016-10-27 18:08:27 +0300624 for (i = 0; i < attrib->num_ihl_offset_range_16; i++)
625 pr_err(
626 "(ihl_ofst_range16: ofst:%u lo:%u hi:%u) ",
627 attrib->ihl_offset_range_16[i].offset,
628 attrib->ihl_offset_range_16[i].range_low,
629 attrib->ihl_offset_range_16[i].range_high);
630
631 if (attrib->ihl_offset_eq_32_present)
632 pr_err(
633 "(ihl_ofst_eq32:%d val:0x%x) ",
634 attrib->ihl_offset_eq_32.offset,
635 attrib->ihl_offset_eq_32.value);
636
637 if (attrib->ihl_offset_eq_16_present)
638 pr_err(
639 "(ihl_ofst_eq16:%d val:0x%x) ",
640 attrib->ihl_offset_eq_16.offset,
641 attrib->ihl_offset_eq_16.value);
642
643 if (attrib->fl_eq_present)
644 pr_err("flow_label:%d ", attrib->fl_eq);
645
646 if (attrib->ipv4_frag_eq_present)
647 pr_err("frag ");
648
649 pr_err("\n");
650 return 0;
651}
652
653static int ipa3_open_dbg(struct inode *inode, struct file *file)
654{
655 file->private_data = inode->i_private;
656 return 0;
657}
658
659static ssize_t ipa3_read_rt(struct file *file, char __user *ubuf, size_t count,
660 loff_t *ppos)
661{
662 int i = 0;
663 struct ipa3_rt_tbl *tbl;
664 struct ipa3_rt_entry *entry;
665 struct ipa3_rt_tbl_set *set;
666 enum ipa_ip_type ip = (enum ipa_ip_type)file->private_data;
667 u32 ofst;
668 u32 ofst_words;
669
670 set = &ipa3_ctx->rt_tbl_set[ip];
671
672 mutex_lock(&ipa3_ctx->lock);
673
674 if (ip == IPA_IP_v6) {
675 if (ipa3_ctx->ip6_rt_tbl_hash_lcl)
676 pr_err("Hashable table resides on local memory\n");
677 else
678 pr_err("Hashable table resides on system (ddr) memory\n");
679 if (ipa3_ctx->ip6_rt_tbl_nhash_lcl)
680 pr_err("Non-Hashable table resides on local memory\n");
681 else
682 pr_err("Non-Hashable table resides on system (ddr) memory\n");
683 } else if (ip == IPA_IP_v4) {
684 if (ipa3_ctx->ip4_rt_tbl_hash_lcl)
685 pr_err("Hashable table resides on local memory\n");
686 else
687 pr_err("Hashable table resides on system (ddr) memory\n");
688 if (ipa3_ctx->ip4_rt_tbl_nhash_lcl)
689 pr_err("Non-Hashable table resides on local memory\n");
690 else
691 pr_err("Non-Hashable table resides on system (ddr) memory\n");
692 }
693
694 list_for_each_entry(tbl, &set->head_rt_tbl_list, link) {
695 i = 0;
696 list_for_each_entry(entry, &tbl->head_rt_rule_list, link) {
697 if (entry->proc_ctx) {
698 ofst = entry->proc_ctx->offset_entry->offset;
699 ofst_words =
700 (ofst +
701 ipa3_ctx->hdr_proc_ctx_tbl.start_offset)
702 >> 5;
703
704 pr_err("tbl_idx:%d tbl_name:%s tbl_ref:%u ",
705 entry->tbl->idx, entry->tbl->name,
706 entry->tbl->ref_cnt);
707 pr_err("rule_idx:%d dst:%d ep:%d S:%u ",
708 i, entry->rule.dst,
709 ipa3_get_ep_mapping(entry->rule.dst),
710 !ipa3_ctx->hdr_proc_ctx_tbl_lcl);
711 pr_err("proc_ctx[32B]:%u attrib_mask:%08x ",
712 ofst_words,
713 entry->rule.attrib.attrib_mask);
714 pr_err("rule_id:%u max_prio:%u prio:%u ",
715 entry->rule_id, entry->rule.max_prio,
716 entry->prio);
717 pr_err("hashable:%u retain_hdr:%u ",
718 entry->rule.hashable,
719 entry->rule.retain_hdr);
720 } else {
721 if (entry->hdr)
722 ofst = entry->hdr->offset_entry->offset;
723 else
724 ofst = 0;
725
726 pr_err("tbl_idx:%d tbl_name:%s tbl_ref:%u ",
727 entry->tbl->idx, entry->tbl->name,
728 entry->tbl->ref_cnt);
729 pr_err("rule_idx:%d dst:%d ep:%d S:%u ",
730 i, entry->rule.dst,
731 ipa3_get_ep_mapping(entry->rule.dst),
732 !ipa3_ctx->hdr_tbl_lcl);
733 pr_err("hdr_ofst[words]:%u attrib_mask:%08x ",
734 ofst >> 2,
735 entry->rule.attrib.attrib_mask);
736 pr_err("rule_id:%u max_prio:%u prio:%u ",
737 entry->rule_id, entry->rule.max_prio,
738 entry->prio);
739 pr_err("hashable:%u retain_hdr:%u ",
740 entry->rule.hashable,
741 entry->rule.retain_hdr);
742 }
743
744 ipa3_attrib_dump(&entry->rule.attrib, ip);
745 i++;
746 }
747 }
748 mutex_unlock(&ipa3_ctx->lock);
749
750 return 0;
751}
752
753static ssize_t ipa3_read_rt_hw(struct file *file, char __user *ubuf,
754 size_t count, loff_t *ppos)
755{
756 enum ipa_ip_type ip = (enum ipa_ip_type)file->private_data;
757 int tbls_num;
758 int rules_num;
759 int tbl;
760 int rl;
761 int res = 0;
762 struct ipahal_rt_rule_entry *rules = NULL;
763
764 switch (ip) {
765 case IPA_IP_v4:
766 tbls_num = IPA_MEM_PART(v4_rt_num_index);
767 break;
768 case IPA_IP_v6:
769 tbls_num = IPA_MEM_PART(v6_rt_num_index);
770 break;
771 default:
772 IPAERR("ip type error %d\n", ip);
773 return -EINVAL;
774 };
775
776 IPADBG("Tring to parse %d H/W routing tables - IP=%d\n", tbls_num, ip);
777
778 rules = kzalloc(sizeof(*rules) * IPA_DBG_MAX_RULE_IN_TBL, GFP_KERNEL);
779 if (!rules) {
780 IPAERR("failed to allocate mem for tbl rules\n");
781 return -ENOMEM;
782 }
783
784 IPA_ACTIVE_CLIENTS_INC_SIMPLE();
785 mutex_lock(&ipa3_ctx->lock);
786
787 for (tbl = 0 ; tbl < tbls_num ; tbl++) {
788 pr_err("=== Routing Table %d = Hashable Rules ===\n", tbl);
789 rules_num = IPA_DBG_MAX_RULE_IN_TBL;
790 res = ipa3_rt_read_tbl_from_hw(tbl, ip, true, rules,
791 &rules_num);
792 if (res) {
793 pr_err("ERROR - Check the logs\n");
794 IPAERR("failed reading tbl from hw\n");
795 goto bail;
796 }
797 if (!rules_num)
798 pr_err("-->No rules. Empty tbl or modem system table\n");
799
800 for (rl = 0 ; rl < rules_num ; rl++) {
801 pr_err("rule_idx:%d dst ep:%d L:%u ",
802 rl, rules[rl].dst_pipe_idx, rules[rl].hdr_lcl);
803
804 if (rules[rl].hdr_type == IPAHAL_RT_RULE_HDR_PROC_CTX)
805 pr_err("proc_ctx:%u attrib_mask:%08x ",
806 rules[rl].hdr_ofst,
807 rules[rl].eq_attrib.rule_eq_bitmap);
808 else
809 pr_err("hdr_ofst:%u attrib_mask:%08x ",
810 rules[rl].hdr_ofst,
811 rules[rl].eq_attrib.rule_eq_bitmap);
812
813 pr_err("rule_id:%u prio:%u retain_hdr:%u ",
814 rules[rl].id, rules[rl].priority,
815 rules[rl].retain_hdr);
Mohammed Javid7f81eda2018-04-10 15:33:48 +0530816 res = ipa3_attrib_dump_eq(&rules[rl].eq_attrib);
817 if (res) {
818 IPAERR_RL("failed read attrib eq\n");
819 goto bail;
820 }
Amir Levy9659e592016-10-27 18:08:27 +0300821 }
822
823 pr_err("=== Routing Table %d = Non-Hashable Rules ===\n", tbl);
824 rules_num = IPA_DBG_MAX_RULE_IN_TBL;
825 res = ipa3_rt_read_tbl_from_hw(tbl, ip, false, rules,
826 &rules_num);
827 if (res) {
828 pr_err("ERROR - Check the logs\n");
829 IPAERR("failed reading tbl from hw\n");
830 goto bail;
831 }
832 if (!rules_num)
833 pr_err("-->No rules. Empty tbl or modem system table\n");
834
835 for (rl = 0 ; rl < rules_num ; rl++) {
836 pr_err("rule_idx:%d dst ep:%d L:%u ",
837 rl, rules[rl].dst_pipe_idx, rules[rl].hdr_lcl);
838
839 if (rules[rl].hdr_type == IPAHAL_RT_RULE_HDR_PROC_CTX)
840 pr_err("proc_ctx:%u attrib_mask:%08x ",
841 rules[rl].hdr_ofst,
842 rules[rl].eq_attrib.rule_eq_bitmap);
843 else
844 pr_err("hdr_ofst:%u attrib_mask:%08x ",
845 rules[rl].hdr_ofst,
846 rules[rl].eq_attrib.rule_eq_bitmap);
847
848 pr_err("rule_id:%u prio:%u retain_hdr:%u\n",
849 rules[rl].id, rules[rl].priority,
850 rules[rl].retain_hdr);
Mohammed Javid7f81eda2018-04-10 15:33:48 +0530851 res = ipa3_attrib_dump_eq(&rules[rl].eq_attrib);
852 if (res) {
853 IPAERR_RL("failed read attrib eq\n");
854 goto bail;
855 }
Amir Levy9659e592016-10-27 18:08:27 +0300856 }
857 pr_err("\n");
858 }
859
860bail:
861 mutex_unlock(&ipa3_ctx->lock);
862 IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
863 kfree(rules);
864 return res;
865}
866
867static ssize_t ipa3_read_proc_ctx(struct file *file, char __user *ubuf,
868 size_t count, loff_t *ppos)
869{
870 int nbytes = 0;
871 struct ipa3_hdr_proc_ctx_tbl *tbl;
872 struct ipa3_hdr_proc_ctx_entry *entry;
873 u32 ofst_words;
874
875 tbl = &ipa3_ctx->hdr_proc_ctx_tbl;
876
877 mutex_lock(&ipa3_ctx->lock);
878
879 if (ipa3_ctx->hdr_proc_ctx_tbl_lcl)
880 pr_info("Table resides on local memory\n");
881 else
882 pr_info("Table resides on system(ddr) memory\n");
883
884 list_for_each_entry(entry, &tbl->head_proc_ctx_entry_list, link) {
885 ofst_words = (entry->offset_entry->offset +
886 ipa3_ctx->hdr_proc_ctx_tbl.start_offset)
887 >> 5;
888 if (entry->hdr->is_hdr_proc_ctx) {
889 nbytes += scnprintf(dbg_buff + nbytes,
890 IPA_MAX_MSG_LEN - nbytes,
891 "id:%u hdr_proc_type:%s proc_ctx[32B]:%u ",
892 entry->id,
893 ipa3_hdr_proc_type_name[entry->type],
894 ofst_words);
895 nbytes += scnprintf(dbg_buff + nbytes,
896 IPA_MAX_MSG_LEN - nbytes,
897 "hdr_phys_base:0x%pa\n",
898 &entry->hdr->phys_base);
899 } else {
900 nbytes += scnprintf(dbg_buff + nbytes,
901 IPA_MAX_MSG_LEN - nbytes,
902 "id:%u hdr_proc_type:%s proc_ctx[32B]:%u ",
903 entry->id,
904 ipa3_hdr_proc_type_name[entry->type],
905 ofst_words);
906 nbytes += scnprintf(dbg_buff + nbytes,
907 IPA_MAX_MSG_LEN - nbytes,
908 "hdr[words]:%u\n",
909 entry->hdr->offset_entry->offset >> 2);
910 }
911 }
912 mutex_unlock(&ipa3_ctx->lock);
913
914 return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes);
915}
916
917static ssize_t ipa3_read_flt(struct file *file, char __user *ubuf, size_t count,
918 loff_t *ppos)
919{
920 int i;
921 int j;
922 struct ipa3_flt_tbl *tbl;
923 struct ipa3_flt_entry *entry;
924 enum ipa_ip_type ip = (enum ipa_ip_type)file->private_data;
925 struct ipa3_rt_tbl *rt_tbl;
926 u32 rt_tbl_idx;
927 u32 bitmap;
928 bool eq;
Mohammed Javid7f81eda2018-04-10 15:33:48 +0530929 int res = 0;
Amir Levy9659e592016-10-27 18:08:27 +0300930
931 mutex_lock(&ipa3_ctx->lock);
932
933 for (j = 0; j < ipa3_ctx->ipa_num_pipes; j++) {
934 if (!ipa_is_ep_support_flt(j))
935 continue;
936 tbl = &ipa3_ctx->flt_tbl[j][ip];
937 i = 0;
938 list_for_each_entry(entry, &tbl->head_flt_rule_list, link) {
Mohammed Javid7f81eda2018-04-10 15:33:48 +0530939 if (entry->cookie != IPA_FLT_COOKIE)
940 continue;
Amir Levy9659e592016-10-27 18:08:27 +0300941 if (entry->rule.eq_attrib_type) {
942 rt_tbl_idx = entry->rule.rt_tbl_idx;
943 bitmap = entry->rule.eq_attrib.rule_eq_bitmap;
944 eq = true;
945 } else {
946 rt_tbl = ipa3_id_find(entry->rule.rt_tbl_hdl);
Mohammed Javidb7c859b2017-09-07 11:05:56 +0530947 if (rt_tbl == NULL ||
948 rt_tbl->cookie != IPA_RT_TBL_COOKIE)
949 rt_tbl_idx = ~0;
Amir Levy9659e592016-10-27 18:08:27 +0300950 else
Mohammed Javidb7c859b2017-09-07 11:05:56 +0530951 rt_tbl_idx = rt_tbl->idx;
Amir Levy9659e592016-10-27 18:08:27 +0300952 bitmap = entry->rule.attrib.attrib_mask;
953 eq = false;
954 }
955 pr_err("ep_idx:%d rule_idx:%d act:%d rt_tbl_idx:%d ",
956 j, i, entry->rule.action, rt_tbl_idx);
957 pr_err("attrib_mask:%08x retain_hdr:%d eq:%d ",
958 bitmap, entry->rule.retain_hdr, eq);
959 pr_err("hashable:%u rule_id:%u max_prio:%u prio:%u ",
960 entry->rule.hashable, entry->rule_id,
961 entry->rule.max_prio, entry->prio);
Amir Levy05fccd02017-06-13 16:25:45 +0300962 if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0)
963 pr_err("pdn index %d, set metadata %d ",
964 entry->rule.pdn_idx,
965 entry->rule.set_metadata);
Mohammed Javid7f81eda2018-04-10 15:33:48 +0530966 if (eq) {
967 res = ipa3_attrib_dump_eq(
968 &entry->rule.eq_attrib);
969 if (res) {
970 IPAERR_RL("failed read attrib eq\n");
971 goto bail;
972 }
973 } else
Amir Levy9659e592016-10-27 18:08:27 +0300974 ipa3_attrib_dump(
975 &entry->rule.attrib, ip);
976 i++;
977 }
978 }
Mohammed Javid7f81eda2018-04-10 15:33:48 +0530979bail:
Amir Levy9659e592016-10-27 18:08:27 +0300980 mutex_unlock(&ipa3_ctx->lock);
981
Mohammed Javid7f81eda2018-04-10 15:33:48 +0530982 return res;
Amir Levy9659e592016-10-27 18:08:27 +0300983}
984
985static ssize_t ipa3_read_flt_hw(struct file *file, char __user *ubuf,
986 size_t count, loff_t *ppos)
987{
988 int pipe;
989 int rl;
990 int rules_num;
991 struct ipahal_flt_rule_entry *rules;
992 enum ipa_ip_type ip = (enum ipa_ip_type)file->private_data;
993 u32 rt_tbl_idx;
994 u32 bitmap;
995 int res = 0;
996
997 IPADBG("Tring to parse %d H/W filtering tables - IP=%d\n",
998 ipa3_ctx->ep_flt_num, ip);
999
1000 rules = kzalloc(sizeof(*rules) * IPA_DBG_MAX_RULE_IN_TBL, GFP_KERNEL);
1001 if (!rules) {
1002 IPAERR("failed to allocate mem for tbl rules\n");
1003 return -ENOMEM;
1004 }
1005
1006 IPA_ACTIVE_CLIENTS_INC_SIMPLE();
1007 mutex_lock(&ipa3_ctx->lock);
1008 for (pipe = 0; pipe < ipa3_ctx->ipa_num_pipes; pipe++) {
1009 if (!ipa_is_ep_support_flt(pipe))
1010 continue;
1011 pr_err("=== Filtering Table ep:%d = Hashable Rules ===\n",
1012 pipe);
1013 rules_num = IPA_DBG_MAX_RULE_IN_TBL;
1014 res = ipa3_flt_read_tbl_from_hw(pipe, ip, true, rules,
1015 &rules_num);
1016 if (res) {
1017 pr_err("ERROR - Check the logs\n");
1018 IPAERR("failed reading tbl from hw\n");
1019 goto bail;
1020 }
1021 if (!rules_num)
1022 pr_err("-->No rules. Empty tbl or modem sys table\n");
1023
1024 for (rl = 0; rl < rules_num; rl++) {
1025 rt_tbl_idx = rules[rl].rule.rt_tbl_idx;
1026 bitmap = rules[rl].rule.eq_attrib.rule_eq_bitmap;
1027 pr_err("ep_idx:%d rule_idx:%d act:%d rt_tbl_idx:%d ",
1028 pipe, rl, rules[rl].rule.action, rt_tbl_idx);
1029 pr_err("attrib_mask:%08x retain_hdr:%d ",
1030 bitmap, rules[rl].rule.retain_hdr);
1031 pr_err("rule_id:%u prio:%u ",
1032 rules[rl].id, rules[rl].priority);
Amir Levy05fccd02017-06-13 16:25:45 +03001033 if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0)
1034 pr_err("pdn: %u, set_metadata: %u ",
1035 rules[rl].rule.pdn_idx,
1036 rules[rl].rule.set_metadata);
Mohammed Javid7f81eda2018-04-10 15:33:48 +05301037 res = ipa3_attrib_dump_eq(&rules[rl].rule.eq_attrib);
1038 if (res) {
1039 IPAERR_RL("failed read attrib eq\n");
1040 goto bail;
1041 }
Amir Levy9659e592016-10-27 18:08:27 +03001042 }
1043
1044 pr_err("=== Filtering Table ep:%d = Non-Hashable Rules ===\n",
1045 pipe);
1046 rules_num = IPA_DBG_MAX_RULE_IN_TBL;
1047 res = ipa3_flt_read_tbl_from_hw(pipe, ip, false, rules,
1048 &rules_num);
1049 if (res) {
1050 pr_err("ERROR - Check the logs\n");
1051 IPAERR("failed reading tbl from hw\n");
1052 goto bail;
1053 }
1054 if (!rules_num)
1055 pr_err("-->No rules. Empty tbl or modem sys table\n");
1056 for (rl = 0; rl < rules_num; rl++) {
1057 rt_tbl_idx = rules[rl].rule.rt_tbl_idx;
1058 bitmap = rules[rl].rule.eq_attrib.rule_eq_bitmap;
1059 pr_err("ep_idx:%d rule_idx:%d act:%d rt_tbl_idx:%d ",
1060 pipe, rl, rules[rl].rule.action, rt_tbl_idx);
1061 pr_err("attrib_mask:%08x retain_hdr:%d ",
1062 bitmap, rules[rl].rule.retain_hdr);
1063 pr_err("rule_id:%u prio:%u ",
1064 rules[rl].id, rules[rl].priority);
Amir Levy05fccd02017-06-13 16:25:45 +03001065 if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0)
1066 pr_err("pdn: %u, set_metadata: %u ",
1067 rules[rl].rule.pdn_idx,
1068 rules[rl].rule.set_metadata);
Mohammed Javid7f81eda2018-04-10 15:33:48 +05301069 res = ipa3_attrib_dump_eq(&rules[rl].rule.eq_attrib);
1070 if (res) {
1071 IPAERR_RL("failed read attrib eq\n");
1072 goto bail;
1073 }
Amir Levy9659e592016-10-27 18:08:27 +03001074 }
1075 pr_err("\n");
1076 }
1077
1078bail:
1079 mutex_unlock(&ipa3_ctx->lock);
1080 kfree(rules);
1081 IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
1082 return res;
1083}
1084
1085static ssize_t ipa3_read_stats(struct file *file, char __user *ubuf,
1086 size_t count, loff_t *ppos)
1087{
1088 int nbytes;
1089 int i;
1090 int cnt = 0;
1091 uint connect = 0;
1092
1093 for (i = 0; i < ipa3_ctx->ipa_num_pipes; i++)
1094 connect |= (ipa3_ctx->ep[i].valid << i);
1095
1096 nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
1097 "sw_tx=%u\n"
1098 "hw_tx=%u\n"
1099 "tx_non_linear=%u\n"
1100 "tx_compl=%u\n"
1101 "wan_rx=%u\n"
1102 "stat_compl=%u\n"
1103 "lan_aggr_close=%u\n"
1104 "wan_aggr_close=%u\n"
1105 "act_clnt=%u\n"
1106 "con_clnt_bmap=0x%x\n"
1107 "wan_rx_empty=%u\n"
1108 "wan_repl_rx_empty=%u\n"
1109 "lan_rx_empty=%u\n"
1110 "lan_repl_rx_empty=%u\n"
1111 "flow_enable=%u\n"
1112 "flow_disable=%u\n",
1113 ipa3_ctx->stats.tx_sw_pkts,
1114 ipa3_ctx->stats.tx_hw_pkts,
1115 ipa3_ctx->stats.tx_non_linear,
1116 ipa3_ctx->stats.tx_pkts_compl,
1117 ipa3_ctx->stats.rx_pkts,
1118 ipa3_ctx->stats.stat_compl,
1119 ipa3_ctx->stats.aggr_close,
1120 ipa3_ctx->stats.wan_aggr_close,
Skylar Chang242952b2017-07-20 15:04:05 -07001121 atomic_read(&ipa3_ctx->ipa3_active_clients.cnt),
Amir Levy9659e592016-10-27 18:08:27 +03001122 connect,
1123 ipa3_ctx->stats.wan_rx_empty,
1124 ipa3_ctx->stats.wan_repl_rx_empty,
1125 ipa3_ctx->stats.lan_rx_empty,
1126 ipa3_ctx->stats.lan_repl_rx_empty,
1127 ipa3_ctx->stats.flow_enable,
1128 ipa3_ctx->stats.flow_disable);
1129 cnt += nbytes;
1130
1131 for (i = 0; i < IPAHAL_PKT_STATUS_EXCEPTION_MAX; i++) {
1132 nbytes = scnprintf(dbg_buff + cnt,
1133 IPA_MAX_MSG_LEN - cnt,
1134 "lan_rx_excp[%u:%20s]=%u\n", i,
1135 ipahal_pkt_status_exception_str(i),
1136 ipa3_ctx->stats.rx_excp_pkts[i]);
1137 cnt += nbytes;
1138 }
1139
1140 return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
1141}
1142
1143static ssize_t ipa3_read_wstats(struct file *file, char __user *ubuf,
1144 size_t count, loff_t *ppos)
1145{
1146
1147#define HEAD_FRMT_STR "%25s\n"
1148#define FRMT_STR "%25s %10u\n"
1149#define FRMT_STR1 "%25s %10u\n\n"
1150
1151 int cnt = 0;
1152 int nbytes;
1153 int ipa_ep_idx;
1154 enum ipa_client_type client = IPA_CLIENT_WLAN1_PROD;
1155 struct ipa3_ep_context *ep;
1156
1157 do {
1158 nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
1159 HEAD_FRMT_STR, "Client IPA_CLIENT_WLAN1_PROD Stats:");
1160 cnt += nbytes;
1161
1162 ipa_ep_idx = ipa3_get_ep_mapping(client);
1163 if (ipa_ep_idx == -1) {
1164 nbytes = scnprintf(dbg_buff + cnt,
1165 IPA_MAX_MSG_LEN - cnt, HEAD_FRMT_STR, "Not up");
1166 cnt += nbytes;
1167 break;
1168 }
1169
1170 ep = &ipa3_ctx->ep[ipa_ep_idx];
1171 if (ep->valid != 1) {
1172 nbytes = scnprintf(dbg_buff + cnt,
1173 IPA_MAX_MSG_LEN - cnt, HEAD_FRMT_STR, "Not up");
1174 cnt += nbytes;
1175 break;
1176 }
1177
1178 nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
1179 FRMT_STR, "Avail Fifo Desc:",
1180 atomic_read(&ep->avail_fifo_desc));
1181 cnt += nbytes;
1182
1183 nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
1184 FRMT_STR, "Rx Pkts Rcvd:", ep->wstats.rx_pkts_rcvd);
1185 cnt += nbytes;
1186
1187 nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
1188 FRMT_STR, "Rx Pkts Status Rcvd:",
1189 ep->wstats.rx_pkts_status_rcvd);
1190 cnt += nbytes;
1191
1192 nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
1193 FRMT_STR, "Rx DH Rcvd:", ep->wstats.rx_hd_rcvd);
1194 cnt += nbytes;
1195
1196 nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
1197 FRMT_STR, "Rx DH Processed:",
1198 ep->wstats.rx_hd_processed);
1199 cnt += nbytes;
1200
1201 nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
1202 FRMT_STR, "Rx DH Sent Back:", ep->wstats.rx_hd_reply);
1203 cnt += nbytes;
1204
1205 nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
1206 FRMT_STR, "Rx Pkt Leak:", ep->wstats.rx_pkt_leak);
1207 cnt += nbytes;
1208
1209 nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
1210 FRMT_STR1, "Rx DP Fail:", ep->wstats.rx_dp_fail);
1211 cnt += nbytes;
1212
1213 } while (0);
1214
1215 client = IPA_CLIENT_WLAN1_CONS;
1216 nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt, HEAD_FRMT_STR,
1217 "Client IPA_CLIENT_WLAN1_CONS Stats:");
1218 cnt += nbytes;
1219 while (1) {
1220 ipa_ep_idx = ipa3_get_ep_mapping(client);
1221 if (ipa_ep_idx == -1) {
1222 nbytes = scnprintf(dbg_buff + cnt,
1223 IPA_MAX_MSG_LEN - cnt, HEAD_FRMT_STR, "Not up");
1224 cnt += nbytes;
1225 goto nxt_clnt_cons;
1226 }
1227
1228 ep = &ipa3_ctx->ep[ipa_ep_idx];
1229 if (ep->valid != 1) {
1230 nbytes = scnprintf(dbg_buff + cnt,
1231 IPA_MAX_MSG_LEN - cnt, HEAD_FRMT_STR, "Not up");
1232 cnt += nbytes;
1233 goto nxt_clnt_cons;
1234 }
1235
1236 nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
1237 FRMT_STR, "Tx Pkts Received:", ep->wstats.tx_pkts_rcvd);
1238 cnt += nbytes;
1239
1240 nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
1241 FRMT_STR, "Tx Pkts Sent:", ep->wstats.tx_pkts_sent);
1242 cnt += nbytes;
1243
1244 nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
1245 FRMT_STR1, "Tx Pkts Dropped:",
1246 ep->wstats.tx_pkts_dropped);
1247 cnt += nbytes;
1248
1249nxt_clnt_cons:
1250 switch (client) {
1251 case IPA_CLIENT_WLAN1_CONS:
1252 client = IPA_CLIENT_WLAN2_CONS;
1253 nbytes = scnprintf(dbg_buff + cnt,
1254 IPA_MAX_MSG_LEN - cnt, HEAD_FRMT_STR,
1255 "Client IPA_CLIENT_WLAN2_CONS Stats:");
1256 cnt += nbytes;
1257 continue;
1258 case IPA_CLIENT_WLAN2_CONS:
1259 client = IPA_CLIENT_WLAN3_CONS;
1260 nbytes = scnprintf(dbg_buff + cnt,
1261 IPA_MAX_MSG_LEN - cnt, HEAD_FRMT_STR,
1262 "Client IPA_CLIENT_WLAN3_CONS Stats:");
1263 cnt += nbytes;
1264 continue;
1265 case IPA_CLIENT_WLAN3_CONS:
1266 client = IPA_CLIENT_WLAN4_CONS;
1267 nbytes = scnprintf(dbg_buff + cnt,
1268 IPA_MAX_MSG_LEN - cnt, HEAD_FRMT_STR,
1269 "Client IPA_CLIENT_WLAN4_CONS Stats:");
1270 cnt += nbytes;
1271 continue;
1272 case IPA_CLIENT_WLAN4_CONS:
1273 default:
1274 break;
1275 }
1276 break;
1277 }
1278
1279 nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
1280 "\n"HEAD_FRMT_STR, "All Wlan Consumer pipes stats:");
1281 cnt += nbytes;
1282
1283 nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt, FRMT_STR,
1284 "Tx Comm Buff Allocated:",
1285 ipa3_ctx->wc_memb.wlan_comm_total_cnt);
1286 cnt += nbytes;
1287
1288 nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt, FRMT_STR,
1289 "Tx Comm Buff Avail:", ipa3_ctx->wc_memb.wlan_comm_free_cnt);
1290 cnt += nbytes;
1291
1292 nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt, FRMT_STR1,
1293 "Total Tx Pkts Freed:", ipa3_ctx->wc_memb.total_tx_pkts_freed);
1294 cnt += nbytes;
1295
1296 return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
1297}
1298
1299static ssize_t ipa3_read_ntn(struct file *file, char __user *ubuf,
1300 size_t count, loff_t *ppos)
1301{
1302#define TX_STATS(y) \
1303 ipa3_ctx->uc_ntn_ctx.ntn_uc_stats_mmio->tx_ch_stats[0].y
1304#define RX_STATS(y) \
1305 ipa3_ctx->uc_ntn_ctx.ntn_uc_stats_mmio->rx_ch_stats[0].y
1306
1307 struct Ipa3HwStatsNTNInfoData_t stats;
1308 int nbytes;
1309 int cnt = 0;
1310
1311 if (!ipa3_get_ntn_stats(&stats)) {
1312 nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
1313 "TX num_pkts_processed=%u\n"
Amir Levy9659e592016-10-27 18:08:27 +03001314 "TX ringFull=%u\n"
1315 "TX ringEmpty=%u\n"
1316 "TX ringUsageHigh=%u\n"
1317 "TX ringUsageLow=%u\n"
1318 "TX RingUtilCount=%u\n"
1319 "TX bamFifoFull=%u\n"
1320 "TX bamFifoEmpty=%u\n"
1321 "TX bamFifoUsageHigh=%u\n"
1322 "TX bamFifoUsageLow=%u\n"
1323 "TX bamUtilCount=%u\n"
1324 "TX num_db=%u\n"
Sunil Paidimarri495fbff2017-07-12 14:25:10 -07001325 "TX num_qmb_int_handled=%u\n"
1326 "TX ipa_pipe_number=%u\n",
Amir Levy9659e592016-10-27 18:08:27 +03001327 TX_STATS(num_pkts_processed),
Sunil Paidimarri495fbff2017-07-12 14:25:10 -07001328 TX_STATS(ring_stats.ringFull),
1329 TX_STATS(ring_stats.ringEmpty),
1330 TX_STATS(ring_stats.ringUsageHigh),
1331 TX_STATS(ring_stats.ringUsageLow),
1332 TX_STATS(ring_stats.RingUtilCount),
1333 TX_STATS(gsi_stats.bamFifoFull),
1334 TX_STATS(gsi_stats.bamFifoEmpty),
1335 TX_STATS(gsi_stats.bamFifoUsageHigh),
1336 TX_STATS(gsi_stats.bamFifoUsageLow),
1337 TX_STATS(gsi_stats.bamUtilCount),
Amir Levy9659e592016-10-27 18:08:27 +03001338 TX_STATS(num_db),
Sunil Paidimarri495fbff2017-07-12 14:25:10 -07001339 TX_STATS(num_qmb_int_handled),
1340 TX_STATS(ipa_pipe_number));
Amir Levy9659e592016-10-27 18:08:27 +03001341 cnt += nbytes;
1342 nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
Amir Levy9659e592016-10-27 18:08:27 +03001343 "RX num_pkts_processed=%u\n"
Amir Levy9659e592016-10-27 18:08:27 +03001344 "RX ringFull=%u\n"
1345 "RX ringEmpty=%u\n"
1346 "RX ringUsageHigh=%u\n"
1347 "RX ringUsageLow=%u\n"
1348 "RX RingUtilCount=%u\n"
1349 "RX bamFifoFull=%u\n"
1350 "RX bamFifoEmpty=%u\n"
1351 "RX bamFifoUsageHigh=%u\n"
1352 "RX bamFifoUsageLow=%u\n"
1353 "RX bamUtilCount=%u\n"
Sunil Paidimarri495fbff2017-07-12 14:25:10 -07001354 "RX num_db=%u\n"
1355 "RX num_qmb_int_handled=%u\n"
1356 "RX ipa_pipe_number=%u\n",
Amir Levy9659e592016-10-27 18:08:27 +03001357 RX_STATS(num_pkts_processed),
Sunil Paidimarri495fbff2017-07-12 14:25:10 -07001358 RX_STATS(ring_stats.ringFull),
1359 RX_STATS(ring_stats.ringEmpty),
1360 RX_STATS(ring_stats.ringUsageHigh),
1361 RX_STATS(ring_stats.ringUsageLow),
1362 RX_STATS(ring_stats.RingUtilCount),
1363 RX_STATS(gsi_stats.bamFifoFull),
1364 RX_STATS(gsi_stats.bamFifoEmpty),
1365 RX_STATS(gsi_stats.bamFifoUsageHigh),
1366 RX_STATS(gsi_stats.bamFifoUsageLow),
1367 RX_STATS(gsi_stats.bamUtilCount),
1368 RX_STATS(num_db),
1369 RX_STATS(num_qmb_int_handled),
1370 RX_STATS(ipa_pipe_number));
Amir Levy9659e592016-10-27 18:08:27 +03001371 cnt += nbytes;
1372 } else {
1373 nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
1374 "Fail to read NTN stats\n");
1375 cnt += nbytes;
1376 }
1377
1378 return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
1379}
1380
1381static ssize_t ipa3_read_wdi(struct file *file, char __user *ubuf,
1382 size_t count, loff_t *ppos)
1383{
1384 struct IpaHwStatsWDIInfoData_t stats;
1385 int nbytes;
1386 int cnt = 0;
1387
1388 if (!ipa3_get_wdi_stats(&stats)) {
1389 nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
1390 "TX num_pkts_processed=%u\n"
1391 "TX copy_engine_doorbell_value=%u\n"
1392 "TX num_db_fired=%u\n"
1393 "TX ringFull=%u\n"
1394 "TX ringEmpty=%u\n"
1395 "TX ringUsageHigh=%u\n"
1396 "TX ringUsageLow=%u\n"
1397 "TX RingUtilCount=%u\n"
1398 "TX bamFifoFull=%u\n"
1399 "TX bamFifoEmpty=%u\n"
1400 "TX bamFifoUsageHigh=%u\n"
1401 "TX bamFifoUsageLow=%u\n"
1402 "TX bamUtilCount=%u\n"
1403 "TX num_db=%u\n"
1404 "TX num_unexpected_db=%u\n"
1405 "TX num_bam_int_handled=%u\n"
1406 "TX num_bam_int_in_non_running_state=%u\n"
1407 "TX num_qmb_int_handled=%u\n"
1408 "TX num_bam_int_handled_while_wait_for_bam=%u\n",
1409 stats.tx_ch_stats.num_pkts_processed,
1410 stats.tx_ch_stats.copy_engine_doorbell_value,
1411 stats.tx_ch_stats.num_db_fired,
1412 stats.tx_ch_stats.tx_comp_ring_stats.ringFull,
1413 stats.tx_ch_stats.tx_comp_ring_stats.ringEmpty,
1414 stats.tx_ch_stats.tx_comp_ring_stats.ringUsageHigh,
1415 stats.tx_ch_stats.tx_comp_ring_stats.ringUsageLow,
1416 stats.tx_ch_stats.tx_comp_ring_stats.RingUtilCount,
1417 stats.tx_ch_stats.bam_stats.bamFifoFull,
1418 stats.tx_ch_stats.bam_stats.bamFifoEmpty,
1419 stats.tx_ch_stats.bam_stats.bamFifoUsageHigh,
1420 stats.tx_ch_stats.bam_stats.bamFifoUsageLow,
1421 stats.tx_ch_stats.bam_stats.bamUtilCount,
1422 stats.tx_ch_stats.num_db,
1423 stats.tx_ch_stats.num_unexpected_db,
1424 stats.tx_ch_stats.num_bam_int_handled,
1425 stats.tx_ch_stats.num_bam_int_in_non_running_state,
1426 stats.tx_ch_stats.num_qmb_int_handled,
1427 stats.tx_ch_stats.
1428 num_bam_int_handled_while_wait_for_bam);
1429 cnt += nbytes;
1430 nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
1431 "RX max_outstanding_pkts=%u\n"
1432 "RX num_pkts_processed=%u\n"
1433 "RX rx_ring_rp_value=%u\n"
1434 "RX ringFull=%u\n"
1435 "RX ringEmpty=%u\n"
1436 "RX ringUsageHigh=%u\n"
1437 "RX ringUsageLow=%u\n"
1438 "RX RingUtilCount=%u\n"
1439 "RX bamFifoFull=%u\n"
1440 "RX bamFifoEmpty=%u\n"
1441 "RX bamFifoUsageHigh=%u\n"
1442 "RX bamFifoUsageLow=%u\n"
1443 "RX bamUtilCount=%u\n"
1444 "RX num_bam_int_handled=%u\n"
1445 "RX num_db=%u\n"
1446 "RX num_unexpected_db=%u\n"
1447 "RX num_pkts_in_dis_uninit_state=%u\n"
Utkarsh Saxena971a03c2017-01-22 22:04:13 +05301448 "RX num_ic_inj_vdev_change=%u\n"
1449 "RX num_ic_inj_fw_desc_change=%u\n"
1450 "RX num_qmb_int_handled=%u\n"
Amir Levy9659e592016-10-27 18:08:27 +03001451 "RX reserved1=%u\n"
1452 "RX reserved2=%u\n",
1453 stats.rx_ch_stats.max_outstanding_pkts,
1454 stats.rx_ch_stats.num_pkts_processed,
1455 stats.rx_ch_stats.rx_ring_rp_value,
1456 stats.rx_ch_stats.rx_ind_ring_stats.ringFull,
1457 stats.rx_ch_stats.rx_ind_ring_stats.ringEmpty,
1458 stats.rx_ch_stats.rx_ind_ring_stats.ringUsageHigh,
1459 stats.rx_ch_stats.rx_ind_ring_stats.ringUsageLow,
1460 stats.rx_ch_stats.rx_ind_ring_stats.RingUtilCount,
1461 stats.rx_ch_stats.bam_stats.bamFifoFull,
1462 stats.rx_ch_stats.bam_stats.bamFifoEmpty,
1463 stats.rx_ch_stats.bam_stats.bamFifoUsageHigh,
1464 stats.rx_ch_stats.bam_stats.bamFifoUsageLow,
1465 stats.rx_ch_stats.bam_stats.bamUtilCount,
1466 stats.rx_ch_stats.num_bam_int_handled,
1467 stats.rx_ch_stats.num_db,
1468 stats.rx_ch_stats.num_unexpected_db,
1469 stats.rx_ch_stats.num_pkts_in_dis_uninit_state,
1470 stats.rx_ch_stats.num_ic_inj_vdev_change,
1471 stats.rx_ch_stats.num_ic_inj_fw_desc_change,
Utkarsh Saxena971a03c2017-01-22 22:04:13 +05301472 stats.rx_ch_stats.num_qmb_int_handled,
Amir Levy9659e592016-10-27 18:08:27 +03001473 stats.rx_ch_stats.reserved1,
1474 stats.rx_ch_stats.reserved2);
1475 cnt += nbytes;
1476 } else {
1477 nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
1478 "Fail to read WDI stats\n");
1479 cnt += nbytes;
1480 }
1481
1482 return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
1483}
1484
1485static ssize_t ipa3_write_dbg_cnt(struct file *file, const char __user *buf,
1486 size_t count, loff_t *ppos)
1487{
1488 unsigned long missing;
1489 u32 option = 0;
1490 struct ipahal_reg_debug_cnt_ctrl dbg_cnt_ctrl;
1491
Michael Adisumarta891a4ff2017-05-16 16:40:06 -07001492 if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) {
1493 IPAERR("IPA_DEBUG_CNT_CTRL is not supported in IPA 4.0\n");
1494 return -EPERM;
1495 }
1496
Amir Levy9659e592016-10-27 18:08:27 +03001497 if (sizeof(dbg_buff) < count + 1)
1498 return -EFAULT;
1499
1500 missing = copy_from_user(dbg_buff, buf, count);
1501 if (missing)
1502 return -EFAULT;
1503
1504 dbg_buff[count] = '\0';
1505 if (kstrtou32(dbg_buff, 0, &option))
1506 return -EFAULT;
1507
1508 memset(&dbg_cnt_ctrl, 0, sizeof(dbg_cnt_ctrl));
1509 dbg_cnt_ctrl.type = DBG_CNT_TYPE_GENERAL;
1510 dbg_cnt_ctrl.product = true;
1511 dbg_cnt_ctrl.src_pipe = 0xff;
1512 dbg_cnt_ctrl.rule_idx_pipe_rule = false;
1513 dbg_cnt_ctrl.rule_idx = 0;
1514 if (option == 1)
1515 dbg_cnt_ctrl.en = true;
1516 else
1517 dbg_cnt_ctrl.en = false;
1518
1519 IPA_ACTIVE_CLIENTS_INC_SIMPLE();
1520 ipahal_write_reg_n_fields(IPA_DEBUG_CNT_CTRL_n, 0, &dbg_cnt_ctrl);
1521 IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
1522
1523 return count;
1524}
1525
1526static ssize_t ipa3_read_dbg_cnt(struct file *file, char __user *ubuf,
1527 size_t count, loff_t *ppos)
1528{
1529 int nbytes;
1530 u32 regval;
1531
Michael Adisumarta891a4ff2017-05-16 16:40:06 -07001532 if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) {
1533 IPAERR("IPA_DEBUG_CNT_REG is not supported in IPA 4.0\n");
1534 return -EPERM;
1535 }
1536
Amir Levy9659e592016-10-27 18:08:27 +03001537 IPA_ACTIVE_CLIENTS_INC_SIMPLE();
1538 regval =
1539 ipahal_read_reg_n(IPA_DEBUG_CNT_REG_n, 0);
1540 nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
1541 "IPA_DEBUG_CNT_REG_0=0x%x\n", regval);
1542 IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
1543
1544 return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes);
1545}
1546
1547static ssize_t ipa3_read_msg(struct file *file, char __user *ubuf,
1548 size_t count, loff_t *ppos)
1549{
1550 int nbytes;
1551 int cnt = 0;
1552 int i;
1553
1554 for (i = 0; i < IPA_EVENT_MAX_NUM; i++) {
1555 nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
1556 "msg[%u:%27s] W:%u R:%u\n", i,
1557 ipa3_event_name[i],
1558 ipa3_ctx->stats.msg_w[i],
1559 ipa3_ctx->stats.msg_r[i]);
1560 cnt += nbytes;
1561 }
1562
1563 return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
1564}
1565
Mohammed Javid478b3c02018-12-17 14:39:54 +05301566static void ipa3_read_table(
Amir Levy479cfdd2017-10-26 12:23:14 +03001567 char *table_addr, u32 table_size,
Amir Levy479cfdd2017-10-26 12:23:14 +03001568 u32 *total_num_entries,
1569 u32 *rule_id,
1570 enum ipahal_nat_type nat_type)
1571{
1572 int result;
1573 char *entry;
1574 size_t entry_size;
1575 bool entry_zeroed;
Ghanim Fodic9908732018-03-26 13:30:34 +03001576 bool entry_valid;
Mohammed Javid478b3c02018-12-17 14:39:54 +05301577 u32 i, num_entries = 0, id = *rule_id;
1578 char *buff;
1579 size_t buff_size = 2 * IPA_MAX_ENTRY_STRING_LEN;
Amir Levy479cfdd2017-10-26 12:23:14 +03001580
1581 IPADBG("\n");
Mohammed Javid478b3c02018-12-17 14:39:54 +05301582 if (table_addr == NULL) {
1583 pr_err("NULL NAT table\n");
1584 return;
1585 }
Amir Levy479cfdd2017-10-26 12:23:14 +03001586
1587 result = ipahal_nat_entry_size(nat_type, &entry_size);
1588 if (result) {
1589 IPAERR("Failed to retrieve size of %s entry\n",
1590 ipahal_nat_type_str(nat_type));
Mohammed Javid478b3c02018-12-17 14:39:54 +05301591 return;
1592 }
1593
1594 buff = kzalloc(buff_size, GFP_KERNEL);
1595 if (!buff) {
1596 IPAERR("Out of memory\n");
1597 return;
Amir Levy479cfdd2017-10-26 12:23:14 +03001598 }
1599
1600 for (i = 0, entry = table_addr;
1601 i < table_size;
1602 ++i, ++id, entry += entry_size) {
1603 result = ipahal_nat_is_entry_zeroed(nat_type, entry,
1604 &entry_zeroed);
1605 if (result) {
1606 IPAERR(
Ghanim Fodic9908732018-03-26 13:30:34 +03001607 "Failed to determine whether the %s entry is definitely zero\n"
1608 , ipahal_nat_type_str(nat_type));
Amir Levy479cfdd2017-10-26 12:23:14 +03001609 goto bail;
1610 }
1611 if (entry_zeroed)
1612 continue;
1613
Ghanim Fodic9908732018-03-26 13:30:34 +03001614 result = ipahal_nat_is_entry_valid(nat_type, entry,
1615 &entry_valid);
1616 if (result) {
1617 IPAERR(
1618 "Failed to determine whether the %s entry is valid\n"
1619 , ipahal_nat_type_str(nat_type));
1620 goto bail;
1621 }
1622
1623 if (entry_valid) {
1624 ++num_entries;
Mohammed Javid478b3c02018-12-17 14:39:54 +05301625 pr_err("\tEntry_Index=%d\n", id);
1626 } else
1627 pr_err("\tEntry_Index=%d - Invalid Entry\n", id);
Amir Levy479cfdd2017-10-26 12:23:14 +03001628
Mohammed Javid478b3c02018-12-17 14:39:54 +05301629 ipahal_nat_stringify_entry(nat_type, entry,
1630 buff, buff_size);
1631 pr_err("%s\n", buff);
1632 memset(buff, 0, buff_size);
Amir Levy479cfdd2017-10-26 12:23:14 +03001633 }
1634
1635 if (num_entries)
Mohammed Javid478b3c02018-12-17 14:39:54 +05301636 pr_err("\n");
Amir Levy479cfdd2017-10-26 12:23:14 +03001637 else
Mohammed Javid478b3c02018-12-17 14:39:54 +05301638 pr_err("\tEmpty\n\n");
Amir Levy479cfdd2017-10-26 12:23:14 +03001639 IPADBG("return\n");
1640bail:
Mohammed Javid478b3c02018-12-17 14:39:54 +05301641 kfree(buff);
Amir Levy479cfdd2017-10-26 12:23:14 +03001642 *rule_id = id;
1643 *total_num_entries += num_entries;
Amir Levy479cfdd2017-10-26 12:23:14 +03001644}
1645
Mohammed Javid478b3c02018-12-17 14:39:54 +05301646static void ipa3_start_read_memory_device(
Amir Levy479cfdd2017-10-26 12:23:14 +03001647 struct ipa3_nat_ipv6ct_common_mem *dev,
Amir Levy479cfdd2017-10-26 12:23:14 +03001648 enum ipahal_nat_type nat_type,
1649 u32 *num_entries)
1650{
Mohammed Javid478b3c02018-12-17 14:39:54 +05301651 u32 rule_id = 0;
Amir Levy479cfdd2017-10-26 12:23:14 +03001652
1653 IPADBG("\n");
1654
Mohammed Javid478b3c02018-12-17 14:39:54 +05301655 pr_err("%s_Table_Size=%d\n",
Amir Levy479cfdd2017-10-26 12:23:14 +03001656 dev->name, dev->table_entries + 1);
1657
Mohammed Javid478b3c02018-12-17 14:39:54 +05301658 pr_err("%s_Expansion_Table_Size=%d\n",
Amir Levy479cfdd2017-10-26 12:23:14 +03001659 dev->name, dev->expn_table_entries);
1660
1661 if (!dev->is_sys_mem)
Mohammed Javid478b3c02018-12-17 14:39:54 +05301662 pr_err("Not supported for local(shared) memory\n");
Amir Levy479cfdd2017-10-26 12:23:14 +03001663
Mohammed Javid478b3c02018-12-17 14:39:54 +05301664 pr_err("\n%s Base Table:\n", dev->name);
1665 ipa3_read_table(dev->base_table_addr, dev->table_entries + 1,
1666 num_entries, &rule_id, nat_type);
Amir Levy479cfdd2017-10-26 12:23:14 +03001667
Mohammed Javid478b3c02018-12-17 14:39:54 +05301668 pr_err("%s Expansion Table:\n", dev->name);
1669 ipa3_read_table(
Amir Levy479cfdd2017-10-26 12:23:14 +03001670 dev->expansion_table_addr, dev->expn_table_entries,
Amir Levy479cfdd2017-10-26 12:23:14 +03001671 num_entries,
1672 &rule_id,
1673 nat_type);
1674
1675 IPADBG("return\n");
Amir Levy479cfdd2017-10-26 12:23:14 +03001676}
1677
Mohammed Javid478b3c02018-12-17 14:39:54 +05301678static void ipa3_finish_read_memory_device(
Amir Levy479cfdd2017-10-26 12:23:14 +03001679 struct ipa3_nat_ipv6ct_common_mem *dev,
Amir Levy479cfdd2017-10-26 12:23:14 +03001680 u32 num_entries)
1681{
Amir Levy479cfdd2017-10-26 12:23:14 +03001682 IPADBG("\n");
Mohammed Javid478b3c02018-12-17 14:39:54 +05301683 pr_err("Overall number %s entries: %d\n\n", dev->name, num_entries);
Amir Levy479cfdd2017-10-26 12:23:14 +03001684 IPADBG("return\n");
Amir Levy479cfdd2017-10-26 12:23:14 +03001685}
1686
Mohammed Javid478b3c02018-12-17 14:39:54 +05301687static void ipa3_read_pdn_table(void)
Amir Levy479cfdd2017-10-26 12:23:14 +03001688{
1689 int i, result;
1690 char *pdn_entry;
1691 size_t pdn_entry_size;
1692 bool entry_zeroed;
Ghanim Fodic9908732018-03-26 13:30:34 +03001693 bool entry_valid;
Mohammed Javid478b3c02018-12-17 14:39:54 +05301694 char *buff;
1695 size_t buff_size = 128;
Amir Levy479cfdd2017-10-26 12:23:14 +03001696
1697 IPADBG("\n");
1698
1699 result = ipahal_nat_entry_size(IPAHAL_NAT_IPV4_PDN, &pdn_entry_size);
1700 if (result) {
1701 IPAERR("Failed to retrieve size of PDN entry");
Mohammed Javid478b3c02018-12-17 14:39:54 +05301702 return;
1703 }
1704
1705 buff = kzalloc(buff_size, GFP_KERNEL);
1706 if (!buff) {
1707 IPAERR("Out of memory\n");
1708 return;
Amir Levy479cfdd2017-10-26 12:23:14 +03001709 }
1710
1711 for (i = 0, pdn_entry = ipa3_ctx->nat_mem.pdn_mem.base;
1712 i < IPA_MAX_PDN_NUM;
1713 ++i, pdn_entry += pdn_entry_size) {
1714 result = ipahal_nat_is_entry_zeroed(IPAHAL_NAT_IPV4_PDN,
1715 pdn_entry, &entry_zeroed);
1716 if (result) {
1717 IPAERR(
Ghanim Fodic9908732018-03-26 13:30:34 +03001718 "Failed to determine whether the PDN entry is definitely zero\n");
Amir Levy479cfdd2017-10-26 12:23:14 +03001719 goto bail;
1720 }
1721 if (entry_zeroed)
1722 continue;
1723
Ghanim Fodic9908732018-03-26 13:30:34 +03001724 result = ipahal_nat_is_entry_valid(IPAHAL_NAT_IPV4_PDN,
1725 pdn_entry, &entry_valid);
1726 if (result) {
1727 IPAERR(
1728 "Failed to determine whether the PDN entry is valid\n");
1729 goto bail;
1730 }
1731 if (entry_valid)
Mohammed Javid478b3c02018-12-17 14:39:54 +05301732 pr_err("PDN %d: ", i);
Ghanim Fodic9908732018-03-26 13:30:34 +03001733 else
Mohammed Javid478b3c02018-12-17 14:39:54 +05301734 pr_err("PDN %d - Invalid: ", i);
Amir Levy479cfdd2017-10-26 12:23:14 +03001735
Mohammed Javid478b3c02018-12-17 14:39:54 +05301736 ipahal_nat_stringify_entry(IPAHAL_NAT_IPV4_PDN,
1737 pdn_entry, buff, buff_size);
1738 pr_err("%s\n", buff);
1739 memset(buff, 0, buff_size);
Amir Levy479cfdd2017-10-26 12:23:14 +03001740 }
Mohammed Javid478b3c02018-12-17 14:39:54 +05301741 pr_err("\n");
Amir Levy479cfdd2017-10-26 12:23:14 +03001742bail:
Mohammed Javid478b3c02018-12-17 14:39:54 +05301743 kfree(buff);
1744 IPADBG("return\n");
Amir Levy479cfdd2017-10-26 12:23:14 +03001745}
1746
Amir Levy9659e592016-10-27 18:08:27 +03001747static ssize_t ipa3_read_nat4(struct file *file,
1748 char __user *ubuf, size_t count,
Amir Levy479cfdd2017-10-26 12:23:14 +03001749 loff_t *ppos)
1750{
Mohammed Javid478b3c02018-12-17 14:39:54 +05301751 u32 rule_id = 0, num_entries = 0, index_num_entries = 0;
Amir Levy9659e592016-10-27 18:08:27 +03001752
Mohammed Javid478b3c02018-12-17 14:39:54 +05301753 pr_err("IPA3 NAT stats\n");
Amir Levy479cfdd2017-10-26 12:23:14 +03001754 if (!ipa3_ctx->nat_mem.dev.is_dev_init) {
Mohammed Javid478b3c02018-12-17 14:39:54 +05301755 pr_err("NAT hasn't been initialized or not supported\n");
Amir Levy479cfdd2017-10-26 12:23:14 +03001756 goto ret;
Amir Levy9659e592016-10-27 18:08:27 +03001757 }
1758
Amir Levy479cfdd2017-10-26 12:23:14 +03001759 mutex_lock(&ipa3_ctx->nat_mem.dev.lock);
1760
1761 if (!ipa3_ctx->nat_mem.dev.is_hw_init) {
Mohammed Javid478b3c02018-12-17 14:39:54 +05301762 pr_err("NAT H/W hasn't been initialized\n");
Amir Levy479cfdd2017-10-26 12:23:14 +03001763 goto bail;
1764 }
1765
Amir Levy479cfdd2017-10-26 12:23:14 +03001766 if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) {
Mohammed Javid478b3c02018-12-17 14:39:54 +05301767 ipa3_read_pdn_table();
Amir Levy479cfdd2017-10-26 12:23:14 +03001768 } else {
Mohammed Javid478b3c02018-12-17 14:39:54 +05301769 pr_err("NAT Table IP Address=%pI4h\n\n",
Amir Levy479cfdd2017-10-26 12:23:14 +03001770 &ipa3_ctx->nat_mem.public_ip_addr);
1771 }
1772
Mohammed Javid478b3c02018-12-17 14:39:54 +05301773 ipa3_start_read_memory_device(&ipa3_ctx->nat_mem.dev,
1774 IPAHAL_NAT_IPV4, &num_entries);
Amir Levy479cfdd2017-10-26 12:23:14 +03001775
Amir Levy9659e592016-10-27 18:08:27 +03001776 /* Print Index tables */
Mohammed Javid478b3c02018-12-17 14:39:54 +05301777 pr_err("ipaNatTable Index Table:\n");
1778 ipa3_read_table(
Amir Levy479cfdd2017-10-26 12:23:14 +03001779 ipa3_ctx->nat_mem.index_table_addr,
1780 ipa3_ctx->nat_mem.dev.table_entries + 1,
Amir Levy479cfdd2017-10-26 12:23:14 +03001781 &index_num_entries,
1782 &rule_id,
1783 IPAHAL_NAT_IPV4_INDEX);
Amir Levy9659e592016-10-27 18:08:27 +03001784
Mohammed Javid478b3c02018-12-17 14:39:54 +05301785 pr_err("ipaNatTable Expansion Index Table:\n");
1786 ipa3_read_table(
Amir Levy479cfdd2017-10-26 12:23:14 +03001787 ipa3_ctx->nat_mem.index_table_expansion_addr,
1788 ipa3_ctx->nat_mem.dev.expn_table_entries,
Amir Levy479cfdd2017-10-26 12:23:14 +03001789 &index_num_entries,
1790 &rule_id,
1791 IPAHAL_NAT_IPV4_INDEX);
Amir Levy9659e592016-10-27 18:08:27 +03001792
Amir Levy479cfdd2017-10-26 12:23:14 +03001793 if (num_entries != index_num_entries)
1794 IPAERR(
1795 "The NAT table number of entries %d is different from index table number of entries %d\n",
1796 num_entries, index_num_entries);
Amir Levy9659e592016-10-27 18:08:27 +03001797
Mohammed Javid478b3c02018-12-17 14:39:54 +05301798 ipa3_finish_read_memory_device(&ipa3_ctx->nat_mem.dev, num_entries);
Amir Levy9659e592016-10-27 18:08:27 +03001799
Amir Levy479cfdd2017-10-26 12:23:14 +03001800 IPADBG("return\n");
1801bail:
1802 mutex_unlock(&ipa3_ctx->nat_mem.dev.lock);
1803ret:
Mohammed Javid478b3c02018-12-17 14:39:54 +05301804 return 0;
Amir Levy479cfdd2017-10-26 12:23:14 +03001805}
Amir Levy9659e592016-10-27 18:08:27 +03001806
Amir Levy479cfdd2017-10-26 12:23:14 +03001807static ssize_t ipa3_read_ipv6ct(struct file *file,
1808 char __user *ubuf, size_t count,
1809 loff_t *ppos) {
Mohammed Javid478b3c02018-12-17 14:39:54 +05301810 u32 num_entries = 0;
Amir Levy9659e592016-10-27 18:08:27 +03001811
Mohammed Javid478b3c02018-12-17 14:39:54 +05301812 pr_err("\n");
Amir Levy479cfdd2017-10-26 12:23:14 +03001813
1814 if (!ipa3_ctx->ipv6ct_mem.dev.is_dev_init) {
Mohammed Javid478b3c02018-12-17 14:39:54 +05301815 pr_err("IPv6 Conntrack not initialized or not supported\n");
1816 return 0;
Amir Levy9659e592016-10-27 18:08:27 +03001817 }
Amir Levy9659e592016-10-27 18:08:27 +03001818
Amir Levy479cfdd2017-10-26 12:23:14 +03001819 mutex_lock(&ipa3_ctx->ipv6ct_mem.dev.lock);
1820
1821 if (!ipa3_ctx->ipv6ct_mem.dev.is_hw_init) {
Mohammed Javid478b3c02018-12-17 14:39:54 +05301822 pr_err("IPv6 connection tracking H/W hasn't been initialized\n");
Amir Levy479cfdd2017-10-26 12:23:14 +03001823 goto bail;
1824 }
1825
Mohammed Javid478b3c02018-12-17 14:39:54 +05301826 ipa3_start_read_memory_device(&ipa3_ctx->ipv6ct_mem.dev,
1827 IPAHAL_NAT_IPV6CT, &num_entries);
1828 ipa3_finish_read_memory_device(&ipa3_ctx->ipv6ct_mem.dev,
1829 num_entries);
Amir Levy479cfdd2017-10-26 12:23:14 +03001830
1831 IPADBG("return\n");
1832bail:
1833 mutex_unlock(&ipa3_ctx->ipv6ct_mem.dev.lock);
Mohammed Javid478b3c02018-12-17 14:39:54 +05301834 return 0;
Amir Levy9659e592016-10-27 18:08:27 +03001835}
1836
1837static ssize_t ipa3_rm_read_stats(struct file *file, char __user *ubuf,
1838 size_t count, loff_t *ppos)
1839{
Amir Levy479cfdd2017-10-26 12:23:14 +03001840 int result, cnt = 0;
Amir Levy9659e592016-10-27 18:08:27 +03001841
Michael Adisumarta3e350812017-09-18 14:54:36 -07001842 /* deprecate if IPA PM is used */
Amir Levy479cfdd2017-10-26 12:23:14 +03001843 if (ipa3_ctx->use_ipa_pm) {
1844 cnt += scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
1845 "IPA RM is disabled\n");
1846 goto ret;
1847 }
Michael Adisumarta3e350812017-09-18 14:54:36 -07001848
Amir Levy9659e592016-10-27 18:08:27 +03001849 result = ipa_rm_stat(dbg_buff, IPA_MAX_MSG_LEN);
1850 if (result < 0) {
Amir Levy479cfdd2017-10-26 12:23:14 +03001851 cnt += scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
Amir Levy9659e592016-10-27 18:08:27 +03001852 "Error in printing RM stat %d\n", result);
Amir Levy479cfdd2017-10-26 12:23:14 +03001853 goto ret;
1854 }
1855 cnt += result;
1856ret:
Amir Levy9659e592016-10-27 18:08:27 +03001857 return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
1858}
1859
Michael Adisumarta3e350812017-09-18 14:54:36 -07001860static ssize_t ipa3_pm_read_stats(struct file *file, char __user *ubuf,
1861 size_t count, loff_t *ppos)
1862{
Amir Levy479cfdd2017-10-26 12:23:14 +03001863 int result, cnt = 0;
Michael Adisumarta3e350812017-09-18 14:54:36 -07001864
Amir Levy479cfdd2017-10-26 12:23:14 +03001865 if (!ipa3_ctx->use_ipa_pm) {
1866 cnt += scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
1867 "IPA PM is disabled\n");
1868 goto ret;
1869 }
Michael Adisumarta3e350812017-09-18 14:54:36 -07001870
1871 result = ipa_pm_stat(dbg_buff, IPA_MAX_MSG_LEN);
1872 if (result < 0) {
Amir Levy479cfdd2017-10-26 12:23:14 +03001873 cnt += scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
Michael Adisumarta3e350812017-09-18 14:54:36 -07001874 "Error in printing PM stat %d\n", result);
Amir Levy479cfdd2017-10-26 12:23:14 +03001875 goto ret;
1876 }
1877 cnt += result;
1878ret:
Michael Adisumarta3e350812017-09-18 14:54:36 -07001879 return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
1880}
1881
1882static ssize_t ipa3_pm_ex_read_stats(struct file *file, char __user *ubuf,
1883 size_t count, loff_t *ppos)
1884{
Amir Levy479cfdd2017-10-26 12:23:14 +03001885 int result, cnt = 0;
Michael Adisumarta3e350812017-09-18 14:54:36 -07001886
Amir Levy479cfdd2017-10-26 12:23:14 +03001887 if (!ipa3_ctx->use_ipa_pm) {
1888 cnt += scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
1889 "IPA PM is disabled\n");
1890 goto ret;
1891 }
Michael Adisumarta3e350812017-09-18 14:54:36 -07001892
1893 result = ipa_pm_exceptions_stat(dbg_buff, IPA_MAX_MSG_LEN);
1894 if (result < 0) {
Amir Levy479cfdd2017-10-26 12:23:14 +03001895 cnt += scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
Michael Adisumarta3e350812017-09-18 14:54:36 -07001896 "Error in printing PM stat %d\n", result);
Amir Levy479cfdd2017-10-26 12:23:14 +03001897 goto ret;
1898 }
1899 cnt += result;
1900ret:
Michael Adisumarta3e350812017-09-18 14:54:36 -07001901 return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
1902}
1903
Michael Adisumartaedba22d2018-04-19 12:28:33 -07001904static ssize_t ipa3_read_ipahal_regs(struct file *file, char __user *ubuf,
1905 size_t count, loff_t *ppos)
1906{
1907 IPA_ACTIVE_CLIENTS_INC_SIMPLE();
Michael Adisumartac50b8002018-06-13 15:21:07 -07001908 ipahal_print_all_regs(true);
Michael Adisumartaedba22d2018-04-19 12:28:33 -07001909 IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
1910
1911 return 0;
1912}
1913
Amir Levy9659e592016-10-27 18:08:27 +03001914static void ipa_dump_status(struct ipahal_pkt_status *status)
1915{
1916 IPA_DUMP_STATUS_FIELD(status_opcode);
1917 IPA_DUMP_STATUS_FIELD(exception);
1918 IPA_DUMP_STATUS_FIELD(status_mask);
1919 IPA_DUMP_STATUS_FIELD(pkt_len);
1920 IPA_DUMP_STATUS_FIELD(endp_src_idx);
1921 IPA_DUMP_STATUS_FIELD(endp_dest_idx);
1922 IPA_DUMP_STATUS_FIELD(metadata);
1923 IPA_DUMP_STATUS_FIELD(flt_local);
1924 IPA_DUMP_STATUS_FIELD(flt_hash);
1925 IPA_DUMP_STATUS_FIELD(flt_global);
1926 IPA_DUMP_STATUS_FIELD(flt_ret_hdr);
1927 IPA_DUMP_STATUS_FIELD(flt_miss);
1928 IPA_DUMP_STATUS_FIELD(flt_rule_id);
1929 IPA_DUMP_STATUS_FIELD(rt_local);
1930 IPA_DUMP_STATUS_FIELD(rt_hash);
1931 IPA_DUMP_STATUS_FIELD(ucp);
1932 IPA_DUMP_STATUS_FIELD(rt_tbl_idx);
1933 IPA_DUMP_STATUS_FIELD(rt_miss);
1934 IPA_DUMP_STATUS_FIELD(rt_rule_id);
1935 IPA_DUMP_STATUS_FIELD(nat_hit);
1936 IPA_DUMP_STATUS_FIELD(nat_entry_idx);
1937 IPA_DUMP_STATUS_FIELD(nat_type);
1938 pr_err("tag = 0x%llx\n", (u64)status->tag_info & 0xFFFFFFFFFFFF);
1939 IPA_DUMP_STATUS_FIELD(seq_num);
1940 IPA_DUMP_STATUS_FIELD(time_of_day_ctr);
1941 IPA_DUMP_STATUS_FIELD(hdr_local);
1942 IPA_DUMP_STATUS_FIELD(hdr_offset);
1943 IPA_DUMP_STATUS_FIELD(frag_hit);
1944 IPA_DUMP_STATUS_FIELD(frag_rule);
1945}
1946
1947static ssize_t ipa_status_stats_read(struct file *file, char __user *ubuf,
1948 size_t count, loff_t *ppos)
1949{
1950 struct ipa3_status_stats *stats;
1951 int i, j;
1952
1953 stats = kzalloc(sizeof(*stats), GFP_KERNEL);
1954 if (!stats)
1955 return -EFAULT;
1956
1957 for (i = 0; i < ipa3_ctx->ipa_num_pipes; i++) {
1958 if (!ipa3_ctx->ep[i].sys || !ipa3_ctx->ep[i].sys->status_stat)
1959 continue;
1960
1961 memcpy(stats, ipa3_ctx->ep[i].sys->status_stat, sizeof(*stats));
1962 pr_err("Statuses for pipe %d\n", i);
1963 for (j = 0; j < IPA_MAX_STATUS_STAT_NUM; j++) {
1964 pr_err("curr=%d\n", stats->curr);
1965 ipa_dump_status(&stats->status[stats->curr]);
1966 pr_err("\n\n\n");
1967 stats->curr = (stats->curr + 1) %
1968 IPA_MAX_STATUS_STAT_NUM;
1969 }
1970 }
1971
1972 kfree(stats);
1973 return 0;
1974}
1975
1976static ssize_t ipa3_print_active_clients_log(struct file *file,
1977 char __user *ubuf, size_t count, loff_t *ppos)
1978{
1979 int cnt;
1980 int table_size;
1981
1982 if (active_clients_buf == NULL) {
1983 IPAERR("Active Clients buffer is not allocated");
1984 return 0;
1985 }
1986 memset(active_clients_buf, 0, IPA_DBG_ACTIVE_CLIENT_BUF_SIZE);
Skylar Chang242952b2017-07-20 15:04:05 -07001987 mutex_lock(&ipa3_ctx->ipa3_active_clients.mutex);
Amir Levy9659e592016-10-27 18:08:27 +03001988 cnt = ipa3_active_clients_log_print_buffer(active_clients_buf,
1989 IPA_DBG_ACTIVE_CLIENT_BUF_SIZE - IPA_MAX_MSG_LEN);
1990 table_size = ipa3_active_clients_log_print_table(active_clients_buf
1991 + cnt, IPA_MAX_MSG_LEN);
Skylar Chang242952b2017-07-20 15:04:05 -07001992 mutex_unlock(&ipa3_ctx->ipa3_active_clients.mutex);
Amir Levy9659e592016-10-27 18:08:27 +03001993
1994 return simple_read_from_buffer(ubuf, count, ppos,
1995 active_clients_buf, cnt + table_size);
1996}
1997
1998static ssize_t ipa3_clear_active_clients_log(struct file *file,
1999 const char __user *ubuf, size_t count, loff_t *ppos)
2000{
2001 unsigned long missing;
2002 s8 option = 0;
2003
2004 if (sizeof(dbg_buff) < count + 1)
2005 return -EFAULT;
2006
2007 missing = copy_from_user(dbg_buff, ubuf, count);
2008 if (missing)
2009 return -EFAULT;
2010
2011 dbg_buff[count] = '\0';
2012 if (kstrtos8(dbg_buff, 0, &option))
2013 return -EFAULT;
2014
2015 ipa3_active_clients_log_clear();
2016
2017 return count;
2018}
2019
2020static ssize_t ipa3_enable_ipc_low(struct file *file,
2021 const char __user *ubuf, size_t count, loff_t *ppos)
2022{
2023 unsigned long missing;
2024 s8 option = 0;
2025
2026 if (sizeof(dbg_buff) < count + 1)
2027 return -EFAULT;
2028
2029 missing = copy_from_user(dbg_buff, ubuf, count);
2030 if (missing)
2031 return -EFAULT;
2032
2033 dbg_buff[count] = '\0';
2034 if (kstrtos8(dbg_buff, 0, &option))
2035 return -EFAULT;
2036
Skylar Chang48c83622017-04-25 16:24:49 -07002037 mutex_lock(&ipa3_ctx->lock);
Amir Levy9659e592016-10-27 18:08:27 +03002038 if (option) {
Skylar Chang48c83622017-04-25 16:24:49 -07002039 if (!ipa_ipc_low_buff) {
2040 ipa_ipc_low_buff =
Amir Levy9659e592016-10-27 18:08:27 +03002041 ipc_log_context_create(IPA_IPC_LOG_PAGES,
2042 "ipa_low", 0);
2043 }
Skylar Chang48c83622017-04-25 16:24:49 -07002044 if (ipa_ipc_low_buff == NULL)
Mohammed Javid0af3c662018-06-29 15:06:00 +05302045 IPADBG("failed to get logbuf_low\n");
Skylar Chang48c83622017-04-25 16:24:49 -07002046 ipa3_ctx->logbuf_low = ipa_ipc_low_buff;
Amir Levy9659e592016-10-27 18:08:27 +03002047 } else {
Amir Levy9659e592016-10-27 18:08:27 +03002048 ipa3_ctx->logbuf_low = NULL;
2049 }
Skylar Chang48c83622017-04-25 16:24:49 -07002050 mutex_unlock(&ipa3_ctx->lock);
Amir Levy9659e592016-10-27 18:08:27 +03002051
2052 return count;
2053}
2054
Amir Levy479cfdd2017-10-26 12:23:14 +03002055static const struct ipa3_debugfs_file debugfs_files[] = {
2056 {
2057 "gen_reg", IPA_READ_ONLY_MODE, NULL, {
2058 .read = ipa3_read_gen_reg
2059 }
2060 }, {
2061 "active_clients", IPA_READ_WRITE_MODE, NULL, {
2062 .read = ipa3_print_active_clients_log,
2063 .write = ipa3_clear_active_clients_log
2064 }
2065 }, {
2066 "ep_reg", IPA_READ_WRITE_MODE, NULL, {
2067 .read = ipa3_read_ep_reg,
2068 .write = ipa3_write_ep_reg,
2069 }
2070 }, {
2071 "keep_awake", IPA_READ_WRITE_MODE, NULL, {
2072 .read = ipa3_read_keep_awake,
2073 .write = ipa3_write_keep_awake,
2074 }
2075 }, {
2076 "holb", IPA_WRITE_ONLY_MODE, NULL, {
2077 .write = ipa3_write_ep_holb,
2078 }
2079 }, {
2080 "hdr", IPA_READ_ONLY_MODE, NULL, {
2081 .read = ipa3_read_hdr,
2082 }
2083 }, {
2084 "proc_ctx", IPA_READ_ONLY_MODE, NULL, {
2085 .read = ipa3_read_proc_ctx,
2086 }
2087 }, {
2088 "ip4_rt", IPA_READ_ONLY_MODE, (void *)IPA_IP_v4, {
2089 .read = ipa3_read_rt,
2090 .open = ipa3_open_dbg,
2091 }
2092 }, {
2093 "ip4_rt_hw", IPA_READ_ONLY_MODE, (void *)IPA_IP_v4, {
2094 .read = ipa3_read_rt_hw,
2095 .open = ipa3_open_dbg,
2096 }
2097 }, {
2098 "ip6_rt", IPA_READ_ONLY_MODE, (void *)IPA_IP_v6, {
2099 .read = ipa3_read_rt,
2100 .open = ipa3_open_dbg,
2101 }
2102 }, {
2103 "ip6_rt_hw", IPA_READ_ONLY_MODE, (void *)IPA_IP_v6, {
2104 .read = ipa3_read_rt_hw,
2105 .open = ipa3_open_dbg,
2106 }
2107 }, {
2108 "ip4_flt", IPA_READ_ONLY_MODE, (void *)IPA_IP_v4, {
2109 .read = ipa3_read_flt,
2110 .open = ipa3_open_dbg,
2111 }
2112 }, {
2113 "ip4_flt_hw", IPA_READ_ONLY_MODE, (void *)IPA_IP_v4, {
2114 .read = ipa3_read_flt_hw,
2115 .open = ipa3_open_dbg,
2116 }
2117 }, {
2118 "ip6_flt", IPA_READ_ONLY_MODE, (void *)IPA_IP_v6, {
2119 .read = ipa3_read_flt,
2120 .open = ipa3_open_dbg,
2121 }
2122 }, {
2123 "ip6_flt_hw", IPA_READ_ONLY_MODE, (void *)IPA_IP_v6, {
2124 .read = ipa3_read_flt_hw,
2125 .open = ipa3_open_dbg,
2126 }
2127 }, {
2128 "stats", IPA_READ_ONLY_MODE, NULL, {
2129 .read = ipa3_read_stats,
2130 }
2131 }, {
2132 "wstats", IPA_READ_ONLY_MODE, NULL, {
2133 .read = ipa3_read_wstats,
2134 }
2135 }, {
2136 "wdi", IPA_READ_ONLY_MODE, NULL, {
2137 .read = ipa3_read_wdi,
2138 }
2139 }, {
2140 "ntn", IPA_READ_ONLY_MODE, NULL, {
2141 .read = ipa3_read_ntn,
2142 }
2143 }, {
2144 "dbg_cnt", IPA_READ_WRITE_MODE, NULL, {
2145 .read = ipa3_read_dbg_cnt,
2146 .write = ipa3_write_dbg_cnt,
2147 }
2148 }, {
2149 "msg", IPA_READ_ONLY_MODE, NULL, {
2150 .read = ipa3_read_msg,
2151 }
2152 }, {
2153 "ip4_nat", IPA_READ_ONLY_MODE, NULL, {
2154 .read = ipa3_read_nat4,
2155 }
2156 }, {
2157 "ipv6ct", IPA_READ_ONLY_MODE, NULL, {
2158 .read = ipa3_read_ipv6ct,
2159 }
2160 }, {
2161 "rm_stats", IPA_READ_ONLY_MODE, NULL, {
2162 .read = ipa3_rm_read_stats,
2163 }
2164 }, {
2165 "pm_stats", IPA_READ_ONLY_MODE, NULL, {
2166 .read = ipa3_pm_read_stats,
2167 }
2168 }, {
2169 "pm_ex_stats", IPA_READ_ONLY_MODE, NULL, {
2170 .read = ipa3_pm_ex_read_stats,
2171 }
2172 }, {
2173 "status_stats", IPA_READ_ONLY_MODE, NULL, {
2174 .read = ipa_status_stats_read,
2175 }
2176 }, {
2177 "enable_low_prio_print", IPA_WRITE_ONLY_MODE, NULL, {
2178 .write = ipa3_enable_ipc_low,
2179 }
Michael Adisumartaedba22d2018-04-19 12:28:33 -07002180 }, {
2181 "ipa_dump_regs", IPA_READ_ONLY_MODE, NULL, {
2182 .read = ipa3_read_ipahal_regs,
2183 }
Amir Levy479cfdd2017-10-26 12:23:14 +03002184 }
Amir Levy9659e592016-10-27 18:08:27 +03002185};
2186
2187void ipa3_debugfs_init(void)
2188{
Amir Levy479cfdd2017-10-26 12:23:14 +03002189 const size_t debugfs_files_num =
2190 sizeof(debugfs_files) / sizeof(struct ipa3_debugfs_file);
2191 size_t i;
Amir Levy9659e592016-10-27 18:08:27 +03002192 struct dentry *file;
2193
2194 dent = debugfs_create_dir("ipa", 0);
2195 if (IS_ERR(dent)) {
2196 IPAERR("fail to create folder in debug_fs.\n");
2197 return;
2198 }
2199
Amir Levy479cfdd2017-10-26 12:23:14 +03002200 file = debugfs_create_u32("hw_type", IPA_READ_ONLY_MODE,
2201 dent, &ipa3_ctx->ipa_hw_type);
Amir Levy9659e592016-10-27 18:08:27 +03002202 if (!file) {
2203 IPAERR("could not create hw_type file\n");
2204 goto fail;
2205 }
2206
2207
Amir Levy479cfdd2017-10-26 12:23:14 +03002208 for (i = 0; i < debugfs_files_num; ++i) {
2209 const struct ipa3_debugfs_file *curr = &debugfs_files[i];
Amir Levy9659e592016-10-27 18:08:27 +03002210
Amir Levy479cfdd2017-10-26 12:23:14 +03002211 file = debugfs_create_file(curr->name, curr->mode, dent,
2212 curr->data, &curr->fops);
2213 if (!file || IS_ERR(file)) {
2214 IPAERR("fail to create file for debug_fs %s\n",
2215 curr->name);
2216 goto fail;
2217 }
Amir Levy9659e592016-10-27 18:08:27 +03002218 }
2219
2220 active_clients_buf = NULL;
2221 active_clients_buf = kzalloc(IPA_DBG_ACTIVE_CLIENT_BUF_SIZE,
2222 GFP_KERNEL);
2223 if (active_clients_buf == NULL)
2224 IPAERR("fail to allocate active clients memory buffer");
2225
Amir Levy479cfdd2017-10-26 12:23:14 +03002226 file = debugfs_create_u32("enable_clock_scaling", IPA_READ_WRITE_MODE,
Amir Levy9659e592016-10-27 18:08:27 +03002227 dent, &ipa3_ctx->enable_clock_scaling);
2228 if (!file) {
2229 IPAERR("could not create enable_clock_scaling file\n");
2230 goto fail;
2231 }
2232
2233 file = debugfs_create_u32("clock_scaling_bw_threshold_nominal_mbps",
Amir Levy479cfdd2017-10-26 12:23:14 +03002234 IPA_READ_WRITE_MODE, dent,
Amir Levy9659e592016-10-27 18:08:27 +03002235 &ipa3_ctx->ctrl->clock_scaling_bw_threshold_nominal);
2236 if (!file) {
2237 IPAERR("could not create bw_threshold_nominal_mbps\n");
2238 goto fail;
2239 }
2240
2241 file = debugfs_create_u32("clock_scaling_bw_threshold_turbo_mbps",
Amir Levy479cfdd2017-10-26 12:23:14 +03002242 IPA_READ_WRITE_MODE, dent,
2243 &ipa3_ctx->ctrl->clock_scaling_bw_threshold_turbo);
Amir Levy9659e592016-10-27 18:08:27 +03002244 if (!file) {
2245 IPAERR("could not create bw_threshold_turbo_mbps\n");
2246 goto fail;
2247 }
2248
Mohammed Javidcd9016e2018-05-15 13:27:26 +05302249 file = debugfs_create_u32("clk_rate", IPA_READ_ONLY_MODE,
2250 dent, &ipa3_ctx->curr_ipa_clk_rate);
2251 if (!file) {
2252 IPAERR("could not create clk_rate file\n");
2253 goto fail;
2254 }
2255
Skylar Chang6f6e3072017-07-28 10:03:47 -07002256 ipa_debugfs_init_stats(dent);
2257
Amir Levy9659e592016-10-27 18:08:27 +03002258 return;
2259
2260fail:
2261 debugfs_remove_recursive(dent);
2262}
2263
2264void ipa3_debugfs_remove(void)
2265{
2266 if (IS_ERR(dent)) {
2267 IPAERR("ipa3_debugfs_remove: folder was not created.\n");
2268 return;
2269 }
2270 if (active_clients_buf != NULL) {
2271 kfree(active_clients_buf);
2272 active_clients_buf = NULL;
2273 }
2274 debugfs_remove_recursive(dent);
2275}
2276
2277struct dentry *ipa_debugfs_get_root(void)
2278{
2279 return dent;
2280}
2281EXPORT_SYMBOL(ipa_debugfs_get_root);
2282
2283#else /* !CONFIG_DEBUG_FS */
2284void ipa3_debugfs_init(void) {}
2285void ipa3_debugfs_remove(void) {}
2286#endif