ipa_debugfs.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182
  1. /* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  2. *
  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. #ifdef CONFIG_DEBUG_FS
  13. #include <linux/debugfs.h>
  14. #include <linux/stringify.h>
  15. #include "ipa_i.h"
  16. #include "ipa_rm_i.h"
  17. #define IPA_MAX_MSG_LEN 4096
  18. #define IPA_DBG_CNTR_ON 127265
  19. #define IPA_DBG_CNTR_OFF 127264
  20. const char *ipa_client_name[] = {
  21. __stringify(IPA_CLIENT_HSIC1_PROD),
  22. __stringify(IPA_CLIENT_HSIC2_PROD),
  23. __stringify(IPA_CLIENT_HSIC3_PROD),
  24. __stringify(IPA_CLIENT_HSIC4_PROD),
  25. __stringify(IPA_CLIENT_HSIC5_PROD),
  26. __stringify(IPA_CLIENT_USB_PROD),
  27. __stringify(IPA_CLIENT_A5_WLAN_AMPDU_PROD),
  28. __stringify(IPA_CLIENT_A2_EMBEDDED_PROD),
  29. __stringify(IPA_CLIENT_A2_TETHERED_PROD),
  30. __stringify(IPA_CLIENT_A5_LAN_WAN_PROD),
  31. __stringify(IPA_CLIENT_A5_CMD_PROD),
  32. __stringify(IPA_CLIENT_Q6_LAN_PROD),
  33. __stringify(IPA_CLIENT_HSIC1_CONS),
  34. __stringify(IPA_CLIENT_HSIC2_CONS),
  35. __stringify(IPA_CLIENT_HSIC3_CONS),
  36. __stringify(IPA_CLIENT_HSIC4_CONS),
  37. __stringify(IPA_CLIENT_HSIC5_CONS),
  38. __stringify(IPA_CLIENT_USB_CONS),
  39. __stringify(IPA_CLIENT_A2_EMBEDDED_CONS),
  40. __stringify(IPA_CLIENT_A2_TETHERED_CONS),
  41. __stringify(IPA_CLIENT_A5_LAN_WAN_CONS),
  42. __stringify(IPA_CLIENT_Q6_LAN_CONS),
  43. __stringify(IPA_CLIENT_MAX),
  44. };
  45. const char *ipa_ic_name[] = {
  46. __stringify_1(IPA_IP_CMD_INVALID),
  47. __stringify_1(IPA_DECIPH_INIT),
  48. __stringify_1(IPA_PPP_FRM_INIT),
  49. __stringify_1(IPA_IP_V4_FILTER_INIT),
  50. __stringify_1(IPA_IP_V6_FILTER_INIT),
  51. __stringify_1(IPA_IP_V4_NAT_INIT),
  52. __stringify_1(IPA_IP_V6_NAT_INIT),
  53. __stringify_1(IPA_IP_V4_ROUTING_INIT),
  54. __stringify_1(IPA_IP_V6_ROUTING_INIT),
  55. __stringify_1(IPA_HDR_INIT_LOCAL),
  56. __stringify_1(IPA_HDR_INIT_SYSTEM),
  57. __stringify_1(IPA_DECIPH_SETUP),
  58. __stringify_1(IPA_INSERT_NAT_RULE),
  59. __stringify_1(IPA_DELETE_NAT_RULE),
  60. __stringify_1(IPA_NAT_DMA),
  61. __stringify_1(IPA_IP_PACKET_TAG),
  62. __stringify_1(IPA_IP_PACKET_INIT),
  63. };
  64. const char *ipa_excp_name[] = {
  65. __stringify_1(IPA_A5_MUX_HDR_EXCP_RSVD0),
  66. __stringify_1(IPA_A5_MUX_HDR_EXCP_RSVD1),
  67. __stringify_1(IPA_A5_MUX_HDR_EXCP_FLAG_IHL),
  68. __stringify_1(IPA_A5_MUX_HDR_EXCP_FLAG_REPLICATED),
  69. __stringify_1(IPA_A5_MUX_HDR_EXCP_FLAG_TAG),
  70. __stringify_1(IPA_A5_MUX_HDR_EXCP_FLAG_SW_FLT),
  71. __stringify_1(IPA_A5_MUX_HDR_EXCP_FLAG_NAT),
  72. __stringify_1(IPA_A5_MUX_HDR_EXCP_FLAG_IP),
  73. };
  74. const char *ipa_event_name[] = {
  75. __stringify(WLAN_CLIENT_CONNECT),
  76. __stringify(WLAN_CLIENT_DISCONNECT),
  77. __stringify(WLAN_CLIENT_POWER_SAVE_MODE),
  78. __stringify(WLAN_CLIENT_NORMAL_MODE),
  79. __stringify(SW_ROUTING_ENABLE),
  80. __stringify(SW_ROUTING_DISABLE),
  81. __stringify(WLAN_AP_CONNECT),
  82. __stringify(WLAN_AP_DISCONNECT),
  83. __stringify(WLAN_STA_CONNECT),
  84. __stringify(WLAN_STA_DISCONNECT),
  85. };
  86. static struct dentry *dent;
  87. static struct dentry *dfile_gen_reg;
  88. static struct dentry *dfile_ep_reg;
  89. static struct dentry *dfile_ep_holb;
  90. static struct dentry *dfile_hdr;
  91. static struct dentry *dfile_ip4_rt;
  92. static struct dentry *dfile_ip6_rt;
  93. static struct dentry *dfile_ip4_flt;
  94. static struct dentry *dfile_ip6_flt;
  95. static struct dentry *dfile_stats;
  96. static struct dentry *dfile_dbg_cnt;
  97. static struct dentry *dfile_msg;
  98. static struct dentry *dfile_ip4_nat;
  99. static struct dentry *dfile_rm_stats;
  100. static char dbg_buff[IPA_MAX_MSG_LEN];
  101. static s8 ep_reg_idx;
  102. static ssize_t ipa_read_gen_reg(struct file *file, char __user *ubuf,
  103. size_t count, loff_t *ppos)
  104. {
  105. int nbytes;
  106. ipa_inc_client_enable_clks();
  107. if (ipa_ctx->ipa_hw_type == IPA_HW_v1_0)
  108. nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
  109. "IPA_VERSION=0x%x\n"
  110. "IPA_COMP_HW_VERSION=0x%x\n"
  111. "IPA_ROUTE=0x%x\n"
  112. "IPA_FILTER=0x%x\n"
  113. "IPA_SHARED_MEM_SIZE=0x%x\n"
  114. "IPA_HEAD_OF_LINE_BLOCK_EN=0x%x\n",
  115. ipa_read_reg(ipa_ctx->mmio, IPA_VERSION_OFST),
  116. ipa_read_reg(ipa_ctx->mmio, IPA_COMP_HW_VERSION_OFST),
  117. ipa_read_reg(ipa_ctx->mmio, IPA_ROUTE_OFST_v1),
  118. ipa_read_reg(ipa_ctx->mmio, IPA_FILTER_OFST_v1),
  119. ipa_read_reg(ipa_ctx->mmio,
  120. IPA_SHARED_MEM_SIZE_OFST_v1),
  121. ipa_read_reg(ipa_ctx->mmio,
  122. IPA_HEAD_OF_LINE_BLOCK_EN_OFST)
  123. );
  124. else
  125. nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
  126. "IPA_VERSION=0x%x\n"
  127. "IPA_COMP_HW_VERSION=0x%x\n"
  128. "IPA_ROUTE=0x%x\n"
  129. "IPA_FILTER=0x%x\n"
  130. "IPA_SHARED_MEM_SIZE=0x%x\n",
  131. ipa_read_reg(ipa_ctx->mmio, IPA_VERSION_OFST),
  132. ipa_read_reg(ipa_ctx->mmio, IPA_COMP_HW_VERSION_OFST),
  133. ipa_read_reg(ipa_ctx->mmio, IPA_ROUTE_OFST_v2),
  134. ipa_read_reg(ipa_ctx->mmio, IPA_FILTER_OFST_v2),
  135. ipa_read_reg(ipa_ctx->mmio, IPA_SHARED_MEM_SIZE_OFST_v2)
  136. );
  137. ipa_dec_client_disable_clks();
  138. return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes);
  139. }
  140. static ssize_t ipa_write_ep_holb(struct file *file,
  141. const char __user *buf, size_t count, loff_t *ppos)
  142. {
  143. struct ipa_ep_cfg_holb holb;
  144. u32 en;
  145. u32 tmr_val;
  146. u32 ep_idx;
  147. unsigned long missing;
  148. char *sptr, *token;
  149. if (sizeof(dbg_buff) < count + 1)
  150. return -EFAULT;
  151. missing = copy_from_user(dbg_buff, buf, count);
  152. if (missing)
  153. return -EFAULT;
  154. dbg_buff[count] = '\0';
  155. sptr = dbg_buff;
  156. token = strsep(&sptr, " ");
  157. if (!token)
  158. return -EINVAL;
  159. if (kstrtou32(token, 0, &ep_idx))
  160. return -EINVAL;
  161. token = strsep(&sptr, " ");
  162. if (!token)
  163. return -EINVAL;
  164. if (kstrtou32(token, 0, &en))
  165. return -EINVAL;
  166. token = strsep(&sptr, " ");
  167. if (!token)
  168. return -EINVAL;
  169. if (kstrtou32(token, 0, &tmr_val))
  170. return -EINVAL;
  171. holb.en = en;
  172. holb.tmr_val = tmr_val;
  173. ipa_cfg_ep_holb(ep_idx, &holb);
  174. return count;
  175. }
  176. static ssize_t ipa_write_ep_reg(struct file *file, const char __user *buf,
  177. size_t count, loff_t *ppos)
  178. {
  179. unsigned long missing;
  180. s8 option = 0;
  181. if (sizeof(dbg_buff) < count + 1)
  182. return -EFAULT;
  183. missing = copy_from_user(dbg_buff, buf, count);
  184. if (missing)
  185. return -EFAULT;
  186. dbg_buff[count] = '\0';
  187. if (kstrtos8(dbg_buff, 0, &option))
  188. return -EFAULT;
  189. if (option >= IPA_NUM_PIPES) {
  190. IPAERR("bad pipe specified %u\n", option);
  191. return count;
  192. }
  193. ep_reg_idx = option;
  194. return count;
  195. }
  196. static ssize_t ipa_read_ep_reg(struct file *file, char __user *ubuf,
  197. size_t count, loff_t *ppos)
  198. {
  199. int nbytes;
  200. int i;
  201. int start_idx;
  202. int end_idx;
  203. int size = 0;
  204. int ret;
  205. loff_t pos;
  206. /* negative ep_reg_idx means all registers */
  207. if (ep_reg_idx < 0) {
  208. start_idx = 0;
  209. end_idx = IPA_NUM_PIPES;
  210. } else {
  211. start_idx = ep_reg_idx;
  212. end_idx = start_idx + 1;
  213. }
  214. pos = *ppos;
  215. ipa_inc_client_enable_clks();
  216. for (i = start_idx; i < end_idx; i++) {
  217. if (ipa_ctx->ipa_hw_type == IPA_HW_v1_0) {
  218. nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
  219. "IPA_ENDP_INIT_NAT_%u=0x%x\n"
  220. "IPA_ENDP_INIT_HDR_%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. i, ipa_read_reg(ipa_ctx->mmio,
  225. IPA_ENDP_INIT_NAT_n_OFST_v1(i)),
  226. i, ipa_read_reg(ipa_ctx->mmio,
  227. IPA_ENDP_INIT_HDR_n_OFST_v1(i)),
  228. i, ipa_read_reg(ipa_ctx->mmio,
  229. IPA_ENDP_INIT_MODE_n_OFST_v1(i)),
  230. i, ipa_read_reg(ipa_ctx->mmio,
  231. IPA_ENDP_INIT_AGGR_n_OFST_v1(i)),
  232. i, ipa_read_reg(ipa_ctx->mmio,
  233. IPA_ENDP_INIT_ROUTE_n_OFST_v1(i)));
  234. } else {
  235. nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
  236. "IPA_ENDP_INIT_NAT_%u=0x%x\n"
  237. "IPA_ENDP_INIT_HDR_%u=0x%x\n"
  238. "IPA_ENDP_INIT_MODE_%u=0x%x\n"
  239. "IPA_ENDP_INIT_AGGR_%u=0x%x\n"
  240. "IPA_ENDP_INIT_ROUTE_%u=0x%x\n"
  241. "IPA_ENDP_INIT_CTRL_%u=0x%x\n"
  242. "IPA_ENDP_INIT_HOL_EN_%u=0x%x\n"
  243. "IPA_ENDP_INIT_HOL_TIMER_%u=0x%x\n",
  244. i, ipa_read_reg(ipa_ctx->mmio,
  245. IPA_ENDP_INIT_NAT_n_OFST_v2(i)),
  246. i, ipa_read_reg(ipa_ctx->mmio,
  247. IPA_ENDP_INIT_HDR_n_OFST_v2(i)),
  248. i, ipa_read_reg(ipa_ctx->mmio,
  249. IPA_ENDP_INIT_MODE_n_OFST_v2(i)),
  250. i, ipa_read_reg(ipa_ctx->mmio,
  251. IPA_ENDP_INIT_AGGR_n_OFST_v2(i)),
  252. i, ipa_read_reg(ipa_ctx->mmio,
  253. IPA_ENDP_INIT_ROUTE_n_OFST_v2(i)),
  254. i, ipa_read_reg(ipa_ctx->mmio,
  255. IPA_ENDP_INIT_CTRL_n_OFST(i)),
  256. i, ipa_read_reg(ipa_ctx->mmio,
  257. IPA_ENDP_INIT_HOL_BLOCK_EN_n_OFST(i)),
  258. i, ipa_read_reg(ipa_ctx->mmio,
  259. IPA_ENDP_INIT_HOL_BLOCK_TIMER_n_OFST(i))
  260. );
  261. }
  262. *ppos = pos;
  263. ret = simple_read_from_buffer(ubuf, count, ppos, dbg_buff,
  264. nbytes);
  265. if (ret < 0) {
  266. ipa_dec_client_disable_clks();
  267. return ret;
  268. }
  269. size += ret;
  270. ubuf += nbytes;
  271. count -= nbytes;
  272. }
  273. ipa_dec_client_disable_clks();
  274. *ppos = pos + size;
  275. return size;
  276. }
  277. static ssize_t ipa_read_hdr(struct file *file, char __user *ubuf, size_t count,
  278. loff_t *ppos)
  279. {
  280. int nbytes = 0;
  281. int cnt = 0;
  282. int i = 0;
  283. struct ipa_hdr_entry *entry;
  284. mutex_lock(&ipa_ctx->lock);
  285. list_for_each_entry(entry, &ipa_ctx->hdr_tbl.head_hdr_entry_list,
  286. link) {
  287. nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
  288. "name:%s len=%d ref=%d partial=%d lcl=%d ofst=%u ",
  289. entry->name,
  290. entry->hdr_len, entry->ref_cnt,
  291. entry->is_partial,
  292. ipa_ctx->hdr_tbl_lcl,
  293. entry->offset_entry->offset >> 2);
  294. for (i = 0; i < entry->hdr_len; i++) {
  295. scnprintf(dbg_buff + cnt + nbytes + i * 2,
  296. IPA_MAX_MSG_LEN - cnt - nbytes - i * 2,
  297. "%02x", entry->hdr[i]);
  298. }
  299. scnprintf(dbg_buff + cnt + nbytes + entry->hdr_len * 2,
  300. IPA_MAX_MSG_LEN - cnt - nbytes - entry->hdr_len * 2,
  301. "\n");
  302. cnt += nbytes + entry->hdr_len * 2 + 1;
  303. }
  304. mutex_unlock(&ipa_ctx->lock);
  305. return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
  306. }
  307. static int ipa_attrib_dump(char *buff, size_t sz,
  308. struct ipa_rule_attrib *attrib, enum ipa_ip_type ip)
  309. {
  310. int nbytes = 0;
  311. int cnt = 0;
  312. uint32_t addr[4];
  313. uint32_t mask[4];
  314. int i;
  315. if (attrib->attrib_mask & IPA_FLT_TOS_MASKED) {
  316. nbytes = scnprintf(buff + cnt, sz - cnt, "tos_value:%d ",
  317. attrib->tos_value);
  318. cnt += nbytes;
  319. }
  320. if (attrib->attrib_mask & IPA_FLT_TOS_MASKED) {
  321. nbytes = scnprintf(buff + cnt, sz - cnt, "tos_mask:%d ",
  322. attrib->tos_mask);
  323. cnt += nbytes;
  324. }
  325. if (attrib->attrib_mask & IPA_FLT_PROTOCOL) {
  326. nbytes = scnprintf(buff + cnt, sz - cnt, "protocol:%d ",
  327. attrib->u.v4.protocol);
  328. cnt += nbytes;
  329. }
  330. if (attrib->attrib_mask & IPA_FLT_SRC_ADDR) {
  331. if (ip == IPA_IP_v4) {
  332. addr[0] = htonl(attrib->u.v4.src_addr);
  333. mask[0] = htonl(attrib->u.v4.src_addr_mask);
  334. nbytes = scnprintf(buff + cnt, sz - cnt,
  335. "src_addr:%pI4 src_addr_mask:%pI4 ",
  336. addr + 0, mask + 0);
  337. cnt += nbytes;
  338. } else if (ip == IPA_IP_v6) {
  339. for (i = 0; i < 4; i++) {
  340. addr[i] = htonl(attrib->u.v6.src_addr[i]);
  341. mask[i] = htonl(attrib->u.v6.src_addr_mask[i]);
  342. }
  343. nbytes =
  344. scnprintf(buff + cnt, sz - cnt,
  345. "src_addr:%pI6 src_addr_mask:%pI6 ",
  346. addr + 0, mask + 0);
  347. cnt += nbytes;
  348. } else {
  349. WARN_ON(1);
  350. }
  351. }
  352. if (attrib->attrib_mask & IPA_FLT_DST_ADDR) {
  353. if (ip == IPA_IP_v4) {
  354. addr[0] = htonl(attrib->u.v4.dst_addr);
  355. mask[0] = htonl(attrib->u.v4.dst_addr_mask);
  356. nbytes =
  357. scnprintf(buff + cnt, sz - cnt,
  358. "dst_addr:%pI4 dst_addr_mask:%pI4 ",
  359. addr + 0, mask + 0);
  360. cnt += nbytes;
  361. } else if (ip == IPA_IP_v6) {
  362. for (i = 0; i < 4; i++) {
  363. addr[i] = htonl(attrib->u.v6.dst_addr[i]);
  364. mask[i] = htonl(attrib->u.v6.dst_addr_mask[i]);
  365. }
  366. nbytes =
  367. scnprintf(buff + cnt, sz - cnt,
  368. "dst_addr:%pI6 dst_addr_mask:%pI6 ",
  369. addr + 0, mask + 0);
  370. cnt += nbytes;
  371. } else {
  372. WARN_ON(1);
  373. }
  374. }
  375. if (attrib->attrib_mask & IPA_FLT_SRC_PORT_RANGE) {
  376. nbytes =
  377. scnprintf(buff + cnt, sz - cnt, "src_port_range:%u %u ",
  378. attrib->src_port_lo,
  379. attrib->src_port_hi);
  380. cnt += nbytes;
  381. }
  382. if (attrib->attrib_mask & IPA_FLT_DST_PORT_RANGE) {
  383. nbytes =
  384. scnprintf(buff + cnt, sz - cnt, "dst_port_range:%u %u ",
  385. attrib->dst_port_lo,
  386. attrib->dst_port_hi);
  387. cnt += nbytes;
  388. }
  389. if (attrib->attrib_mask & IPA_FLT_TYPE) {
  390. nbytes = scnprintf(buff + cnt, sz - cnt, "type:%d ",
  391. attrib->type);
  392. cnt += nbytes;
  393. }
  394. if (attrib->attrib_mask & IPA_FLT_CODE) {
  395. nbytes = scnprintf(buff + cnt, sz - cnt, "code:%d ",
  396. attrib->code);
  397. cnt += nbytes;
  398. }
  399. if (attrib->attrib_mask & IPA_FLT_SPI) {
  400. nbytes = scnprintf(buff + cnt, sz - cnt, "spi:%x ",
  401. attrib->spi);
  402. cnt += nbytes;
  403. }
  404. if (attrib->attrib_mask & IPA_FLT_SRC_PORT) {
  405. nbytes = scnprintf(buff + cnt, sz - cnt, "src_port:%u ",
  406. attrib->src_port);
  407. cnt += nbytes;
  408. }
  409. if (attrib->attrib_mask & IPA_FLT_DST_PORT) {
  410. nbytes = scnprintf(buff + cnt, sz - cnt, "dst_port:%u ",
  411. attrib->dst_port);
  412. cnt += nbytes;
  413. }
  414. if (attrib->attrib_mask & IPA_FLT_TC) {
  415. nbytes = scnprintf(buff + cnt, sz - cnt, "tc:%d ",
  416. attrib->u.v6.tc);
  417. cnt += nbytes;
  418. }
  419. if (attrib->attrib_mask & IPA_FLT_FLOW_LABEL) {
  420. nbytes = scnprintf(buff + cnt, sz - cnt, "flow_label:%x ",
  421. attrib->u.v6.flow_label);
  422. cnt += nbytes;
  423. }
  424. if (attrib->attrib_mask & IPA_FLT_NEXT_HDR) {
  425. nbytes = scnprintf(buff + cnt, sz - cnt, "next_hdr:%d ",
  426. attrib->u.v6.next_hdr);
  427. cnt += nbytes;
  428. }
  429. if (attrib->attrib_mask & IPA_FLT_META_DATA) {
  430. nbytes =
  431. scnprintf(buff + cnt, sz - cnt,
  432. "metadata:%x metadata_mask:%x",
  433. attrib->meta_data, attrib->meta_data_mask);
  434. cnt += nbytes;
  435. }
  436. if (attrib->attrib_mask & IPA_FLT_FRAGMENT) {
  437. nbytes = scnprintf(buff + cnt, sz - cnt, "frg ");
  438. cnt += nbytes;
  439. }
  440. nbytes = scnprintf(buff + cnt, sz - cnt, "\n");
  441. cnt += nbytes;
  442. return cnt;
  443. }
  444. static int ipa_open_dbg(struct inode *inode, struct file *file)
  445. {
  446. file->private_data = inode->i_private;
  447. return 0;
  448. }
  449. static ssize_t ipa_read_rt(struct file *file, char __user *ubuf, size_t count,
  450. loff_t *ppos)
  451. {
  452. int nbytes = 0;
  453. int cnt = 0;
  454. int i = 0;
  455. struct ipa_rt_tbl *tbl;
  456. struct ipa_rt_entry *entry;
  457. struct ipa_rt_tbl_set *set;
  458. enum ipa_ip_type ip = (enum ipa_ip_type)file->private_data;
  459. u32 hdr_ofst;
  460. set = &ipa_ctx->rt_tbl_set[ip];
  461. mutex_lock(&ipa_ctx->lock);
  462. if (ip == IPA_IP_v6) {
  463. if (ipa_ctx->ip6_rt_tbl_lcl) {
  464. nbytes = scnprintf(dbg_buff + cnt,
  465. IPA_MAX_MSG_LEN - cnt,
  466. "Table Resides on local memory\n");
  467. cnt += nbytes;
  468. } else {
  469. nbytes = scnprintf(dbg_buff + cnt,
  470. IPA_MAX_MSG_LEN - cnt,
  471. "Table Resides on system(ddr) memory\n");
  472. cnt += nbytes;
  473. }
  474. } else if (ip == IPA_IP_v4) {
  475. if (ipa_ctx->ip4_rt_tbl_lcl) {
  476. nbytes = scnprintf(dbg_buff + cnt,
  477. IPA_MAX_MSG_LEN - cnt,
  478. "Table Resides on local memory\n");
  479. cnt += nbytes;
  480. } else {
  481. nbytes = scnprintf(dbg_buff + cnt,
  482. IPA_MAX_MSG_LEN - cnt,
  483. "Table Resides on system(ddr) memory\n");
  484. cnt += nbytes;
  485. }
  486. }
  487. list_for_each_entry(tbl, &set->head_rt_tbl_list, link) {
  488. i = 0;
  489. list_for_each_entry(entry, &tbl->head_rt_rule_list, link) {
  490. if (entry->hdr)
  491. hdr_ofst = entry->hdr->offset_entry->offset;
  492. else
  493. hdr_ofst = 0;
  494. nbytes = scnprintf(dbg_buff + cnt,
  495. IPA_MAX_MSG_LEN - cnt,
  496. "tbl_idx:%d tbl_name:%s tbl_ref:%u rule_idx:%d dst:%d name:%s ep:%d S:%u hdr_ofst[words]:%u attrib_mask:%08x ",
  497. entry->tbl->idx, entry->tbl->name,
  498. entry->tbl->ref_cnt, i, entry->rule.dst,
  499. ipa_client_name[entry->rule.dst],
  500. ipa_get_ep_mapping(ipa_ctx->mode,
  501. entry->rule.dst),
  502. !ipa_ctx->hdr_tbl_lcl,
  503. hdr_ofst >> 2,
  504. entry->rule.attrib.attrib_mask);
  505. cnt += nbytes;
  506. cnt += ipa_attrib_dump(dbg_buff + cnt,
  507. IPA_MAX_MSG_LEN - cnt,
  508. &entry->rule.attrib,
  509. ip);
  510. i++;
  511. }
  512. }
  513. mutex_unlock(&ipa_ctx->lock);
  514. return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
  515. }
  516. static ssize_t ipa_read_flt(struct file *file, char __user *ubuf, size_t count,
  517. loff_t *ppos)
  518. {
  519. int nbytes = 0;
  520. int cnt = 0;
  521. int i;
  522. int j;
  523. int k;
  524. struct ipa_flt_tbl *tbl;
  525. struct ipa_flt_entry *entry;
  526. enum ipa_ip_type ip = (enum ipa_ip_type)file->private_data;
  527. struct ipa_rt_tbl *rt_tbl;
  528. u32 rt_tbl_idx;
  529. tbl = &ipa_ctx->glob_flt_tbl[ip];
  530. mutex_lock(&ipa_ctx->lock);
  531. i = 0;
  532. list_for_each_entry(entry, &tbl->head_flt_rule_list, link) {
  533. rt_tbl = (struct ipa_rt_tbl *)entry->rule.rt_tbl_hdl;
  534. if (rt_tbl == NULL)
  535. rt_tbl_idx = ~0;
  536. else
  537. rt_tbl_idx = rt_tbl->idx;
  538. nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
  539. "ep_idx:global rule_idx:%d act:%d rt_tbl_idx:%d attrib_mask:%08x ",
  540. i, entry->rule.action, rt_tbl_idx,
  541. entry->rule.attrib.attrib_mask);
  542. cnt += nbytes;
  543. cnt += ipa_attrib_dump(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
  544. &entry->rule.attrib, ip);
  545. i++;
  546. }
  547. for (j = 0; j < IPA_NUM_PIPES; j++) {
  548. tbl = &ipa_ctx->flt_tbl[j][ip];
  549. i = 0;
  550. list_for_each_entry(entry, &tbl->head_flt_rule_list, link) {
  551. rt_tbl = (struct ipa_rt_tbl *)entry->rule.rt_tbl_hdl;
  552. if (rt_tbl == NULL)
  553. rt_tbl_idx = ~0;
  554. else
  555. rt_tbl_idx = rt_tbl->idx;
  556. k = ipa_get_client_mapping(ipa_ctx->mode, j);
  557. nbytes = scnprintf(dbg_buff + cnt,
  558. IPA_MAX_MSG_LEN - cnt,
  559. "ep_idx:%d name:%s rule_idx:%d act:%d rt_tbl_idx:%d attrib_mask:%08x ",
  560. j, ipa_client_name[k], i,
  561. entry->rule.action, rt_tbl_idx,
  562. entry->rule.attrib.attrib_mask);
  563. cnt += nbytes;
  564. cnt +=
  565. ipa_attrib_dump(dbg_buff + cnt,
  566. IPA_MAX_MSG_LEN - cnt,
  567. &entry->rule.attrib,
  568. ip);
  569. i++;
  570. }
  571. }
  572. mutex_unlock(&ipa_ctx->lock);
  573. return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
  574. }
  575. static ssize_t ipa_read_stats(struct file *file, char __user *ubuf,
  576. size_t count, loff_t *ppos)
  577. {
  578. int nbytes;
  579. int i;
  580. int cnt = 0;
  581. uint connect = 0;
  582. for (i = 0; i < IPA_NUM_PIPES; i++)
  583. connect |= (ipa_ctx->ep[i].valid << i);
  584. nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
  585. "sw_tx=%u\n"
  586. "hw_tx=%u\n"
  587. "rx=%u\n"
  588. "rx_repl_repost=%u\n"
  589. "x_intr_repost=%u\n"
  590. "x_intr_repost_tx=%u\n"
  591. "rx_q_len=%u\n"
  592. "act_clnt=%u\n"
  593. "con_clnt_bmap=0x%x\n"
  594. "a2_power_on_reqs_in=%u\n"
  595. "a2_power_on_reqs_out=%u\n"
  596. "a2_power_off_reqs_in=%u\n"
  597. "a2_power_off_reqs_out=%u\n"
  598. "a2_power_modem_acks=%u\n"
  599. "a2_power_apps_acks=%u\n",
  600. ipa_ctx->stats.tx_sw_pkts,
  601. ipa_ctx->stats.tx_hw_pkts,
  602. ipa_ctx->stats.rx_pkts,
  603. ipa_ctx->stats.rx_repl_repost,
  604. ipa_ctx->stats.x_intr_repost,
  605. ipa_ctx->stats.x_intr_repost_tx,
  606. ipa_ctx->stats.rx_q_len,
  607. ipa_ctx->ipa_active_clients,
  608. connect,
  609. ipa_ctx->stats.a2_power_on_reqs_in,
  610. ipa_ctx->stats.a2_power_on_reqs_out,
  611. ipa_ctx->stats.a2_power_off_reqs_in,
  612. ipa_ctx->stats.a2_power_off_reqs_out,
  613. ipa_ctx->stats.a2_power_modem_acks,
  614. ipa_ctx->stats.a2_power_apps_acks);
  615. cnt += nbytes;
  616. for (i = 0; i < MAX_NUM_EXCP; i++) {
  617. nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
  618. "rx_excp[%u:%35s]=%u\n", i, ipa_excp_name[i],
  619. ipa_ctx->stats.rx_excp_pkts[i]);
  620. cnt += nbytes;
  621. }
  622. for (i = 0; i < IPA_BRIDGE_TYPE_MAX; i++) {
  623. nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
  624. "brg_pkt[%u:%s][dl]=%u\n"
  625. "brg_pkt[%u:%s][ul]=%u\n",
  626. i, (i == 0) ? "teth" : "embd",
  627. ipa_ctx->stats.bridged_pkts[i][0],
  628. i, (i == 0) ? "teth" : "embd",
  629. ipa_ctx->stats.bridged_pkts[i][1]);
  630. cnt += nbytes;
  631. }
  632. for (i = 0; i < MAX_NUM_IMM_CMD; i++) {
  633. nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
  634. "IC[%2u:%22s]=%u\n", i, ipa_ic_name[i],
  635. ipa_ctx->stats.imm_cmds[i]);
  636. cnt += nbytes;
  637. }
  638. return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
  639. }
  640. static ssize_t ipa_write_dbg_cnt(struct file *file, const char __user *buf,
  641. size_t count, loff_t *ppos)
  642. {
  643. unsigned long missing;
  644. u32 option = 0;
  645. if (sizeof(dbg_buff) < count + 1)
  646. return -EFAULT;
  647. missing = copy_from_user(dbg_buff, buf, count);
  648. if (missing)
  649. return -EFAULT;
  650. dbg_buff[count] = '\0';
  651. if (kstrtou32(dbg_buff, 0, &option))
  652. return -EFAULT;
  653. ipa_inc_client_enable_clks();
  654. if (option == 1)
  655. ipa_write_reg(ipa_ctx->mmio, IPA_DEBUG_CNT_CTRL_n_OFST(0),
  656. IPA_DBG_CNTR_ON);
  657. else
  658. ipa_write_reg(ipa_ctx->mmio, IPA_DEBUG_CNT_CTRL_n_OFST(0),
  659. IPA_DBG_CNTR_OFF);
  660. ipa_dec_client_disable_clks();
  661. return count;
  662. }
  663. static ssize_t ipa_read_dbg_cnt(struct file *file, char __user *ubuf,
  664. size_t count, loff_t *ppos)
  665. {
  666. int nbytes;
  667. ipa_inc_client_enable_clks();
  668. nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
  669. "IPA_DEBUG_CNT_REG_0=0x%x\n",
  670. ipa_read_reg(ipa_ctx->mmio,
  671. IPA_DEBUG_CNT_REG_n_OFST(0)));
  672. ipa_dec_client_disable_clks();
  673. return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes);
  674. }
  675. static ssize_t ipa_read_msg(struct file *file, char __user *ubuf,
  676. size_t count, loff_t *ppos)
  677. {
  678. int nbytes;
  679. int cnt = 0;
  680. int i;
  681. for (i = 0; i < IPA_EVENT_MAX; i++) {
  682. nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
  683. "msg[%u:%27s] W:%u R:%u\n", i,
  684. ipa_event_name[i],
  685. ipa_ctx->stats.msg_w[i],
  686. ipa_ctx->stats.msg_r[i]);
  687. cnt += nbytes;
  688. }
  689. return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
  690. }
  691. static ssize_t ipa_read_nat4(struct file *file,
  692. char __user *ubuf, size_t count,
  693. loff_t *ppos) {
  694. #define ENTRY_U32_FIELDS 8
  695. #define NAT_ENTRY_ENABLE 0x8000
  696. #define NAT_ENTRY_RST_FIN_BIT 0x4000
  697. #define BASE_TABLE 0
  698. #define EXPANSION_TABLE 1
  699. u32 *base_tbl, *indx_tbl;
  700. u32 tbl_size, *tmp;
  701. u32 value, i, j, rule_id;
  702. u16 enable, tbl_entry, flag;
  703. int nbytes, cnt;
  704. cnt = 0;
  705. value = ipa_ctx->nat_mem.public_ip_addr;
  706. nbytes = scnprintf(dbg_buff + cnt,
  707. IPA_MAX_MSG_LEN,
  708. "Table IP Address:%d.%d.%d.%d\n",
  709. ((value & 0xFF000000) >> 24),
  710. ((value & 0x00FF0000) >> 16),
  711. ((value & 0x0000FF00) >> 8),
  712. ((value & 0x000000FF)));
  713. cnt += nbytes;
  714. nbytes = scnprintf(dbg_buff + cnt,
  715. IPA_MAX_MSG_LEN,
  716. "Table Size:%d\n",
  717. ipa_ctx->nat_mem.size_base_tables);
  718. cnt += nbytes;
  719. nbytes = scnprintf(dbg_buff + cnt,
  720. IPA_MAX_MSG_LEN,
  721. "Expansion Table Size:%d\n",
  722. ipa_ctx->nat_mem.size_expansion_tables);
  723. cnt += nbytes;
  724. if (!ipa_ctx->nat_mem.is_sys_mem) {
  725. nbytes = scnprintf(dbg_buff + cnt,
  726. IPA_MAX_MSG_LEN,
  727. "Not supported for local(shared) memory\n");
  728. cnt += nbytes;
  729. return simple_read_from_buffer(ubuf, count,
  730. ppos, dbg_buff, cnt);
  731. }
  732. /* Print Base tables */
  733. rule_id = 0;
  734. for (j = 0; j < 2; j++) {
  735. if (j == BASE_TABLE) {
  736. tbl_size = ipa_ctx->nat_mem.size_base_tables;
  737. base_tbl = (u32 *)ipa_ctx->nat_mem.ipv4_rules_addr;
  738. nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN,
  739. "\nBase Table:\n");
  740. cnt += nbytes;
  741. } else {
  742. tbl_size = ipa_ctx->nat_mem.size_expansion_tables;
  743. base_tbl =
  744. (u32 *)ipa_ctx->nat_mem.ipv4_expansion_rules_addr;
  745. nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN,
  746. "\nExpansion Base Table:\n");
  747. cnt += nbytes;
  748. }
  749. if (base_tbl != NULL) {
  750. for (i = 0; i <= tbl_size; i++, rule_id++) {
  751. tmp = base_tbl;
  752. value = tmp[4];
  753. enable = ((value & 0xFFFF0000) >> 16);
  754. if (enable & NAT_ENTRY_ENABLE) {
  755. nbytes = scnprintf(dbg_buff + cnt,
  756. IPA_MAX_MSG_LEN,
  757. "Rule:%d ",
  758. rule_id);
  759. cnt += nbytes;
  760. value = *tmp;
  761. nbytes = scnprintf(dbg_buff + cnt,
  762. IPA_MAX_MSG_LEN,
  763. "Private_IP:%d.%d.%d.%d ",
  764. ((value & 0xFF000000) >> 24),
  765. ((value & 0x00FF0000) >> 16),
  766. ((value & 0x0000FF00) >> 8),
  767. ((value & 0x000000FF)));
  768. cnt += nbytes;
  769. tmp++;
  770. value = *tmp;
  771. nbytes = scnprintf(dbg_buff + cnt,
  772. IPA_MAX_MSG_LEN,
  773. "Target_IP:%d.%d.%d.%d ",
  774. ((value & 0xFF000000) >> 24),
  775. ((value & 0x00FF0000) >> 16),
  776. ((value & 0x0000FF00) >> 8),
  777. ((value & 0x000000FF)));
  778. cnt += nbytes;
  779. tmp++;
  780. value = *tmp;
  781. nbytes = scnprintf(dbg_buff + cnt,
  782. IPA_MAX_MSG_LEN,
  783. "Next_Index:%d Public_Port:%d ",
  784. (value & 0x0000FFFF),
  785. ((value & 0xFFFF0000) >> 16));
  786. cnt += nbytes;
  787. tmp++;
  788. value = *tmp;
  789. nbytes = scnprintf(dbg_buff + cnt,
  790. IPA_MAX_MSG_LEN,
  791. "Private_Port:%d Target_Port:%d ",
  792. (value & 0x0000FFFF),
  793. ((value & 0xFFFF0000) >> 16));
  794. cnt += nbytes;
  795. tmp++;
  796. value = *tmp;
  797. nbytes = scnprintf(dbg_buff + cnt,
  798. IPA_MAX_MSG_LEN,
  799. "IP-CKSM-delta:0x%x ",
  800. (value & 0x0000FFFF));
  801. cnt += nbytes;
  802. flag = ((value & 0xFFFF0000) >> 16);
  803. if (flag & NAT_ENTRY_RST_FIN_BIT) {
  804. nbytes =
  805. scnprintf(dbg_buff + cnt,
  806. IPA_MAX_MSG_LEN,
  807. "IP_CKSM_delta:0x%x Flags:%s ",
  808. (value & 0x0000FFFF),
  809. "Direct_To_A5");
  810. cnt += nbytes;
  811. } else {
  812. nbytes =
  813. scnprintf(dbg_buff + cnt,
  814. IPA_MAX_MSG_LEN,
  815. "IP_CKSM_delta:0x%x Flags:%s ",
  816. (value & 0x0000FFFF),
  817. "Fwd_to_route");
  818. cnt += nbytes;
  819. }
  820. tmp++;
  821. value = *tmp;
  822. nbytes = scnprintf(dbg_buff + cnt,
  823. IPA_MAX_MSG_LEN,
  824. "Time_stamp:0x%x Proto:%d ",
  825. (value & 0x00FFFFFF),
  826. ((value & 0xFF000000) >> 27));
  827. cnt += nbytes;
  828. tmp++;
  829. value = *tmp;
  830. nbytes = scnprintf(dbg_buff + cnt,
  831. IPA_MAX_MSG_LEN,
  832. "Prev_Index:%d Indx_tbl_entry:%d ",
  833. (value & 0x0000FFFF),
  834. ((value & 0xFFFF0000) >> 16));
  835. cnt += nbytes;
  836. tmp++;
  837. value = *tmp;
  838. nbytes = scnprintf(dbg_buff + cnt,
  839. IPA_MAX_MSG_LEN,
  840. "TCP_UDP_cksum_delta:0x%x\n",
  841. ((value & 0xFFFF0000) >> 16));
  842. cnt += nbytes;
  843. }
  844. base_tbl += ENTRY_U32_FIELDS;
  845. }
  846. }
  847. }
  848. /* Print Index tables */
  849. rule_id = 0;
  850. for (j = 0; j < 2; j++) {
  851. if (j == BASE_TABLE) {
  852. tbl_size = ipa_ctx->nat_mem.size_base_tables;
  853. indx_tbl = (u32 *)ipa_ctx->nat_mem.index_table_addr;
  854. nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN,
  855. "\nIndex Table:\n");
  856. cnt += nbytes;
  857. } else {
  858. tbl_size = ipa_ctx->nat_mem.size_expansion_tables;
  859. indx_tbl =
  860. (u32 *)ipa_ctx->nat_mem.index_table_expansion_addr;
  861. nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN,
  862. "\nExpansion Index Table:\n");
  863. cnt += nbytes;
  864. }
  865. if (indx_tbl != NULL) {
  866. for (i = 0; i <= tbl_size; i++, rule_id++) {
  867. tmp = indx_tbl;
  868. value = *tmp;
  869. tbl_entry = (value & 0x0000FFFF);
  870. if (tbl_entry) {
  871. nbytes = scnprintf(dbg_buff + cnt,
  872. IPA_MAX_MSG_LEN,
  873. "Rule:%d ",
  874. rule_id);
  875. cnt += nbytes;
  876. value = *tmp;
  877. nbytes = scnprintf(dbg_buff + cnt,
  878. IPA_MAX_MSG_LEN,
  879. "Table_Entry:%d Next_Index:%d\n",
  880. tbl_entry,
  881. ((value & 0xFFFF0000) >> 16));
  882. cnt += nbytes;
  883. }
  884. indx_tbl++;
  885. }
  886. }
  887. }
  888. return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
  889. }
  890. static ssize_t ipa_rm_read_stats(struct file *file, char __user *ubuf,
  891. size_t count, loff_t *ppos)
  892. {
  893. int result, nbytes, cnt = 0;
  894. result = ipa_rm_stat(dbg_buff, IPA_MAX_MSG_LEN);
  895. if (result < 0) {
  896. nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
  897. "Error in printing RM stat %d\n", result);
  898. cnt += nbytes;
  899. } else
  900. cnt += result;
  901. return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
  902. }
  903. const struct file_operations ipa_gen_reg_ops = {
  904. .read = ipa_read_gen_reg,
  905. };
  906. const struct file_operations ipa_ep_reg_ops = {
  907. .read = ipa_read_ep_reg,
  908. .write = ipa_write_ep_reg,
  909. };
  910. const struct file_operations ipa_ep_holb_ops = {
  911. .write = ipa_write_ep_holb,
  912. };
  913. const struct file_operations ipa_hdr_ops = {
  914. .read = ipa_read_hdr,
  915. };
  916. const struct file_operations ipa_rt_ops = {
  917. .read = ipa_read_rt,
  918. .open = ipa_open_dbg,
  919. };
  920. const struct file_operations ipa_flt_ops = {
  921. .read = ipa_read_flt,
  922. .open = ipa_open_dbg,
  923. };
  924. const struct file_operations ipa_stats_ops = {
  925. .read = ipa_read_stats,
  926. };
  927. const struct file_operations ipa_msg_ops = {
  928. .read = ipa_read_msg,
  929. };
  930. const struct file_operations ipa_dbg_cnt_ops = {
  931. .read = ipa_read_dbg_cnt,
  932. .write = ipa_write_dbg_cnt,
  933. };
  934. const struct file_operations ipa_nat4_ops = {
  935. .read = ipa_read_nat4,
  936. };
  937. const struct file_operations ipa_rm_stats = {
  938. .read = ipa_rm_read_stats,
  939. };
  940. void ipa_debugfs_init(void)
  941. {
  942. const mode_t read_only_mode = S_IRUSR | S_IRGRP | S_IROTH;
  943. const mode_t read_write_mode = S_IRUSR | S_IRGRP | S_IROTH |
  944. S_IWUSR | S_IWGRP | S_IWOTH;
  945. const mode_t write_only_mode = S_IWUSR | S_IWGRP | S_IWOTH;
  946. dent = debugfs_create_dir("ipa", 0);
  947. if (IS_ERR(dent)) {
  948. IPAERR("fail to create folder in debug_fs.\n");
  949. return;
  950. }
  951. dfile_gen_reg = debugfs_create_file("gen_reg", read_only_mode, dent, 0,
  952. &ipa_gen_reg_ops);
  953. if (!dfile_gen_reg || IS_ERR(dfile_gen_reg)) {
  954. IPAERR("fail to create file for debug_fs gen_reg\n");
  955. goto fail;
  956. }
  957. dfile_ep_reg = debugfs_create_file("ep_reg", read_write_mode, dent, 0,
  958. &ipa_ep_reg_ops);
  959. if (!dfile_ep_reg || IS_ERR(dfile_ep_reg)) {
  960. IPAERR("fail to create file for debug_fs ep_reg\n");
  961. goto fail;
  962. }
  963. dfile_ep_holb = debugfs_create_file("holb", write_only_mode, dent,
  964. 0, &ipa_ep_holb_ops);
  965. if (!dfile_ep_holb || IS_ERR(dfile_ep_holb)) {
  966. IPAERR("fail to create file for debug_fs dfile_ep_hol_en\n");
  967. goto fail;
  968. }
  969. dfile_hdr = debugfs_create_file("hdr", read_only_mode, dent, 0,
  970. &ipa_hdr_ops);
  971. if (!dfile_hdr || IS_ERR(dfile_hdr)) {
  972. IPAERR("fail to create file for debug_fs hdr\n");
  973. goto fail;
  974. }
  975. dfile_ip4_rt = debugfs_create_file("ip4_rt", read_only_mode, dent,
  976. (void *)IPA_IP_v4, &ipa_rt_ops);
  977. if (!dfile_ip4_rt || IS_ERR(dfile_ip4_rt)) {
  978. IPAERR("fail to create file for debug_fs ip4 rt\n");
  979. goto fail;
  980. }
  981. dfile_ip6_rt = debugfs_create_file("ip6_rt", read_only_mode, dent,
  982. (void *)IPA_IP_v6, &ipa_rt_ops);
  983. if (!dfile_ip6_rt || IS_ERR(dfile_ip6_rt)) {
  984. IPAERR("fail to create file for debug_fs ip6:w" " rt\n");
  985. goto fail;
  986. }
  987. dfile_ip4_flt = debugfs_create_file("ip4_flt", read_only_mode, dent,
  988. (void *)IPA_IP_v4, &ipa_flt_ops);
  989. if (!dfile_ip4_flt || IS_ERR(dfile_ip4_flt)) {
  990. IPAERR("fail to create file for debug_fs ip4 flt\n");
  991. goto fail;
  992. }
  993. dfile_ip6_flt = debugfs_create_file("ip6_flt", read_only_mode, dent,
  994. (void *)IPA_IP_v6, &ipa_flt_ops);
  995. if (!dfile_ip6_flt || IS_ERR(dfile_ip6_flt)) {
  996. IPAERR("fail to create file for debug_fs ip6 flt\n");
  997. goto fail;
  998. }
  999. dfile_stats = debugfs_create_file("stats", read_only_mode, dent, 0,
  1000. &ipa_stats_ops);
  1001. if (!dfile_stats || IS_ERR(dfile_stats)) {
  1002. IPAERR("fail to create file for debug_fs stats\n");
  1003. goto fail;
  1004. }
  1005. dfile_dbg_cnt = debugfs_create_file("dbg_cnt", read_write_mode, dent, 0,
  1006. &ipa_dbg_cnt_ops);
  1007. if (!dfile_dbg_cnt || IS_ERR(dfile_dbg_cnt)) {
  1008. IPAERR("fail to create file for debug_fs dbg_cnt\n");
  1009. goto fail;
  1010. }
  1011. dfile_msg = debugfs_create_file("msg", read_only_mode, dent, 0,
  1012. &ipa_msg_ops);
  1013. if (!dfile_msg || IS_ERR(dfile_msg)) {
  1014. IPAERR("fail to create file for debug_fs msg\n");
  1015. goto fail;
  1016. }
  1017. dfile_ip4_nat = debugfs_create_file("ip4_nat", read_only_mode, dent,
  1018. 0, &ipa_nat4_ops);
  1019. if (!dfile_ip4_nat || IS_ERR(dfile_ip4_nat)) {
  1020. IPAERR("fail to create file for debug_fs ip4 nat\n");
  1021. goto fail;
  1022. }
  1023. dfile_rm_stats = debugfs_create_file("rm_stats", read_only_mode,
  1024. dent, 0,
  1025. &ipa_rm_stats);
  1026. if (!dfile_rm_stats || IS_ERR(dfile_rm_stats)) {
  1027. IPAERR("fail to create file for debug_fs rm_stats\n");
  1028. goto fail;
  1029. }
  1030. return;
  1031. fail:
  1032. debugfs_remove_recursive(dent);
  1033. }
  1034. void ipa_debugfs_remove(void)
  1035. {
  1036. if (IS_ERR(dent)) {
  1037. IPAERR("ipa_debugfs_remove: folder was not created.\n");
  1038. return;
  1039. }
  1040. debugfs_remove_recursive(dent);
  1041. }
  1042. #else /* !CONFIG_DEBUG_FS */
  1043. void ipa_debugfs_init(void) {}
  1044. void ipa_debugfs_remove(void) {}
  1045. #endif