iwl-agn-debugfs.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871
  1. /******************************************************************************
  2. *
  3. * GPL LICENSE SUMMARY
  4. *
  5. * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of version 2 of the GNU General Public License as
  9. * published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
  19. * USA
  20. *
  21. * The full GNU General Public License is included in this distribution
  22. * in the file called LICENSE.GPL.
  23. *
  24. * Contact Information:
  25. * Intel Linux Wireless <ilw@linux.intel.com>
  26. * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  27. *****************************************************************************/
  28. #include "iwl-agn-debugfs.h"
  29. static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
  30. {
  31. int p = 0;
  32. p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n",
  33. le32_to_cpu(priv->_agn.statistics.flag));
  34. if (le32_to_cpu(priv->_agn.statistics.flag) &
  35. UCODE_STATISTICS_CLEAR_MSK)
  36. p += scnprintf(buf + p, bufsz - p,
  37. "\tStatistics have been cleared\n");
  38. p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
  39. (le32_to_cpu(priv->_agn.statistics.flag) &
  40. UCODE_STATISTICS_FREQUENCY_MSK)
  41. ? "2.4 GHz" : "5.2 GHz");
  42. p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
  43. (le32_to_cpu(priv->_agn.statistics.flag) &
  44. UCODE_STATISTICS_NARROW_BAND_MSK)
  45. ? "enabled" : "disabled");
  46. return p;
  47. }
  48. ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
  49. size_t count, loff_t *ppos)
  50. {
  51. struct iwl_priv *priv = file->private_data;
  52. int pos = 0;
  53. char *buf;
  54. int bufsz = sizeof(struct statistics_rx_phy) * 40 +
  55. sizeof(struct statistics_rx_non_phy) * 40 +
  56. sizeof(struct statistics_rx_ht_phy) * 40 + 400;
  57. ssize_t ret;
  58. struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
  59. struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
  60. struct statistics_rx_non_phy *general, *accum_general;
  61. struct statistics_rx_non_phy *delta_general, *max_general;
  62. struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
  63. if (!iwl_is_alive(priv))
  64. return -EAGAIN;
  65. buf = kzalloc(bufsz, GFP_KERNEL);
  66. if (!buf) {
  67. IWL_ERR(priv, "Can not allocate Buffer\n");
  68. return -ENOMEM;
  69. }
  70. /*
  71. * the statistic information display here is based on
  72. * the last statistics notification from uCode
  73. * might not reflect the current uCode activity
  74. */
  75. ofdm = &priv->_agn.statistics.rx.ofdm;
  76. cck = &priv->_agn.statistics.rx.cck;
  77. general = &priv->_agn.statistics.rx.general;
  78. ht = &priv->_agn.statistics.rx.ofdm_ht;
  79. accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm;
  80. accum_cck = &priv->_agn.accum_statistics.rx.cck;
  81. accum_general = &priv->_agn.accum_statistics.rx.general;
  82. accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht;
  83. delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm;
  84. delta_cck = &priv->_agn.delta_statistics.rx.cck;
  85. delta_general = &priv->_agn.delta_statistics.rx.general;
  86. delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht;
  87. max_ofdm = &priv->_agn.max_delta.rx.ofdm;
  88. max_cck = &priv->_agn.max_delta.rx.cck;
  89. max_general = &priv->_agn.max_delta.rx.general;
  90. max_ht = &priv->_agn.max_delta.rx.ofdm_ht;
  91. pos += iwl_statistics_flag(priv, buf, bufsz);
  92. pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
  93. "acumulative delta max\n",
  94. "Statistics_Rx - OFDM:");
  95. pos += scnprintf(buf + pos, bufsz - pos,
  96. " %-30s %10u %10u %10u %10u\n",
  97. "ina_cnt:", le32_to_cpu(ofdm->ina_cnt),
  98. accum_ofdm->ina_cnt,
  99. delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
  100. pos += scnprintf(buf + pos, bufsz - pos,
  101. " %-30s %10u %10u %10u %10u\n",
  102. "fina_cnt:",
  103. le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
  104. delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
  105. pos += scnprintf(buf + pos, bufsz - pos,
  106. " %-30s %10u %10u %10u %10u\n",
  107. "plcp_err:",
  108. le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
  109. delta_ofdm->plcp_err, max_ofdm->plcp_err);
  110. pos += scnprintf(buf + pos, bufsz - pos,
  111. " %-30s %10u %10u %10u %10u\n", "crc32_err:",
  112. le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
  113. delta_ofdm->crc32_err, max_ofdm->crc32_err);
  114. pos += scnprintf(buf + pos, bufsz - pos,
  115. " %-30s %10u %10u %10u %10u\n", "overrun_err:",
  116. le32_to_cpu(ofdm->overrun_err),
  117. accum_ofdm->overrun_err, delta_ofdm->overrun_err,
  118. max_ofdm->overrun_err);
  119. pos += scnprintf(buf + pos, bufsz - pos,
  120. " %-30s %10u %10u %10u %10u\n",
  121. "early_overrun_err:",
  122. le32_to_cpu(ofdm->early_overrun_err),
  123. accum_ofdm->early_overrun_err,
  124. delta_ofdm->early_overrun_err,
  125. max_ofdm->early_overrun_err);
  126. pos += scnprintf(buf + pos, bufsz - pos,
  127. " %-30s %10u %10u %10u %10u\n",
  128. "crc32_good:", le32_to_cpu(ofdm->crc32_good),
  129. accum_ofdm->crc32_good, delta_ofdm->crc32_good,
  130. max_ofdm->crc32_good);
  131. pos += scnprintf(buf + pos, bufsz - pos,
  132. " %-30s %10u %10u %10u %10u\n", "false_alarm_cnt:",
  133. le32_to_cpu(ofdm->false_alarm_cnt),
  134. accum_ofdm->false_alarm_cnt,
  135. delta_ofdm->false_alarm_cnt,
  136. max_ofdm->false_alarm_cnt);
  137. pos += scnprintf(buf + pos, bufsz - pos,
  138. " %-30s %10u %10u %10u %10u\n",
  139. "fina_sync_err_cnt:",
  140. le32_to_cpu(ofdm->fina_sync_err_cnt),
  141. accum_ofdm->fina_sync_err_cnt,
  142. delta_ofdm->fina_sync_err_cnt,
  143. max_ofdm->fina_sync_err_cnt);
  144. pos += scnprintf(buf + pos, bufsz - pos,
  145. " %-30s %10u %10u %10u %10u\n", "sfd_timeout:",
  146. le32_to_cpu(ofdm->sfd_timeout),
  147. accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout,
  148. max_ofdm->sfd_timeout);
  149. pos += scnprintf(buf + pos, bufsz - pos,
  150. " %-30s %10u %10u %10u %10u\n", "fina_timeout:",
  151. le32_to_cpu(ofdm->fina_timeout),
  152. accum_ofdm->fina_timeout, delta_ofdm->fina_timeout,
  153. max_ofdm->fina_timeout);
  154. pos += scnprintf(buf + pos, bufsz - pos,
  155. " %-30s %10u %10u %10u %10u\n",
  156. "unresponded_rts:",
  157. le32_to_cpu(ofdm->unresponded_rts),
  158. accum_ofdm->unresponded_rts,
  159. delta_ofdm->unresponded_rts,
  160. max_ofdm->unresponded_rts);
  161. pos += scnprintf(buf + pos, bufsz - pos,
  162. " %-30s %10u %10u %10u %10u\n",
  163. "rxe_frame_lmt_ovrun:",
  164. le32_to_cpu(ofdm->rxe_frame_limit_overrun),
  165. accum_ofdm->rxe_frame_limit_overrun,
  166. delta_ofdm->rxe_frame_limit_overrun,
  167. max_ofdm->rxe_frame_limit_overrun);
  168. pos += scnprintf(buf + pos, bufsz - pos,
  169. " %-30s %10u %10u %10u %10u\n", "sent_ack_cnt:",
  170. le32_to_cpu(ofdm->sent_ack_cnt),
  171. accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt,
  172. max_ofdm->sent_ack_cnt);
  173. pos += scnprintf(buf + pos, bufsz - pos,
  174. " %-30s %10u %10u %10u %10u\n", "sent_cts_cnt:",
  175. le32_to_cpu(ofdm->sent_cts_cnt),
  176. accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt,
  177. max_ofdm->sent_cts_cnt);
  178. pos += scnprintf(buf + pos, bufsz - pos,
  179. " %-30s %10u %10u %10u %10u\n",
  180. "sent_ba_rsp_cnt:",
  181. le32_to_cpu(ofdm->sent_ba_rsp_cnt),
  182. accum_ofdm->sent_ba_rsp_cnt,
  183. delta_ofdm->sent_ba_rsp_cnt,
  184. max_ofdm->sent_ba_rsp_cnt);
  185. pos += scnprintf(buf + pos, bufsz - pos,
  186. " %-30s %10u %10u %10u %10u\n", "dsp_self_kill:",
  187. le32_to_cpu(ofdm->dsp_self_kill),
  188. accum_ofdm->dsp_self_kill,
  189. delta_ofdm->dsp_self_kill,
  190. max_ofdm->dsp_self_kill);
  191. pos += scnprintf(buf + pos, bufsz - pos,
  192. " %-30s %10u %10u %10u %10u\n",
  193. "mh_format_err:",
  194. le32_to_cpu(ofdm->mh_format_err),
  195. accum_ofdm->mh_format_err,
  196. delta_ofdm->mh_format_err,
  197. max_ofdm->mh_format_err);
  198. pos += scnprintf(buf + pos, bufsz - pos,
  199. " %-30s %10u %10u %10u %10u\n",
  200. "re_acq_main_rssi_sum:",
  201. le32_to_cpu(ofdm->re_acq_main_rssi_sum),
  202. accum_ofdm->re_acq_main_rssi_sum,
  203. delta_ofdm->re_acq_main_rssi_sum,
  204. max_ofdm->re_acq_main_rssi_sum);
  205. pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
  206. "acumulative delta max\n",
  207. "Statistics_Rx - CCK:");
  208. pos += scnprintf(buf + pos, bufsz - pos,
  209. " %-30s %10u %10u %10u %10u\n",
  210. "ina_cnt:",
  211. le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
  212. delta_cck->ina_cnt, max_cck->ina_cnt);
  213. pos += scnprintf(buf + pos, bufsz - pos,
  214. " %-30s %10u %10u %10u %10u\n",
  215. "fina_cnt:",
  216. le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
  217. delta_cck->fina_cnt, max_cck->fina_cnt);
  218. pos += scnprintf(buf + pos, bufsz - pos,
  219. " %-30s %10u %10u %10u %10u\n",
  220. "plcp_err:",
  221. le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
  222. delta_cck->plcp_err, max_cck->plcp_err);
  223. pos += scnprintf(buf + pos, bufsz - pos,
  224. " %-30s %10u %10u %10u %10u\n",
  225. "crc32_err:",
  226. le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
  227. delta_cck->crc32_err, max_cck->crc32_err);
  228. pos += scnprintf(buf + pos, bufsz - pos,
  229. " %-30s %10u %10u %10u %10u\n",
  230. "overrun_err:",
  231. le32_to_cpu(cck->overrun_err),
  232. accum_cck->overrun_err, delta_cck->overrun_err,
  233. max_cck->overrun_err);
  234. pos += scnprintf(buf + pos, bufsz - pos,
  235. " %-30s %10u %10u %10u %10u\n",
  236. "early_overrun_err:",
  237. le32_to_cpu(cck->early_overrun_err),
  238. accum_cck->early_overrun_err,
  239. delta_cck->early_overrun_err,
  240. max_cck->early_overrun_err);
  241. pos += scnprintf(buf + pos, bufsz - pos,
  242. " %-30s %10u %10u %10u %10u\n",
  243. "crc32_good:",
  244. le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
  245. delta_cck->crc32_good, max_cck->crc32_good);
  246. pos += scnprintf(buf + pos, bufsz - pos,
  247. " %-30s %10u %10u %10u %10u\n",
  248. "false_alarm_cnt:",
  249. le32_to_cpu(cck->false_alarm_cnt),
  250. accum_cck->false_alarm_cnt,
  251. delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
  252. pos += scnprintf(buf + pos, bufsz - pos,
  253. " %-30s %10u %10u %10u %10u\n",
  254. "fina_sync_err_cnt:",
  255. le32_to_cpu(cck->fina_sync_err_cnt),
  256. accum_cck->fina_sync_err_cnt,
  257. delta_cck->fina_sync_err_cnt,
  258. max_cck->fina_sync_err_cnt);
  259. pos += scnprintf(buf + pos, bufsz - pos,
  260. " %-30s %10u %10u %10u %10u\n",
  261. "sfd_timeout:",
  262. le32_to_cpu(cck->sfd_timeout),
  263. accum_cck->sfd_timeout, delta_cck->sfd_timeout,
  264. max_cck->sfd_timeout);
  265. pos += scnprintf(buf + pos, bufsz - pos,
  266. " %-30s %10u %10u %10u %10u\n", "fina_timeout:",
  267. le32_to_cpu(cck->fina_timeout),
  268. accum_cck->fina_timeout, delta_cck->fina_timeout,
  269. max_cck->fina_timeout);
  270. pos += scnprintf(buf + pos, bufsz - pos,
  271. " %-30s %10u %10u %10u %10u\n",
  272. "unresponded_rts:",
  273. le32_to_cpu(cck->unresponded_rts),
  274. accum_cck->unresponded_rts, delta_cck->unresponded_rts,
  275. max_cck->unresponded_rts);
  276. pos += scnprintf(buf + pos, bufsz - pos,
  277. " %-30s %10u %10u %10u %10u\n",
  278. "rxe_frame_lmt_ovrun:",
  279. le32_to_cpu(cck->rxe_frame_limit_overrun),
  280. accum_cck->rxe_frame_limit_overrun,
  281. delta_cck->rxe_frame_limit_overrun,
  282. max_cck->rxe_frame_limit_overrun);
  283. pos += scnprintf(buf + pos, bufsz - pos,
  284. " %-30s %10u %10u %10u %10u\n", "sent_ack_cnt:",
  285. le32_to_cpu(cck->sent_ack_cnt),
  286. accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt,
  287. max_cck->sent_ack_cnt);
  288. pos += scnprintf(buf + pos, bufsz - pos,
  289. " %-30s %10u %10u %10u %10u\n", "sent_cts_cnt:",
  290. le32_to_cpu(cck->sent_cts_cnt),
  291. accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt,
  292. max_cck->sent_cts_cnt);
  293. pos += scnprintf(buf + pos, bufsz - pos,
  294. " %-30s %10u %10u %10u %10u\n", "sent_ba_rsp_cnt:",
  295. le32_to_cpu(cck->sent_ba_rsp_cnt),
  296. accum_cck->sent_ba_rsp_cnt,
  297. delta_cck->sent_ba_rsp_cnt,
  298. max_cck->sent_ba_rsp_cnt);
  299. pos += scnprintf(buf + pos, bufsz - pos,
  300. " %-30s %10u %10u %10u %10u\n", "dsp_self_kill:",
  301. le32_to_cpu(cck->dsp_self_kill),
  302. accum_cck->dsp_self_kill, delta_cck->dsp_self_kill,
  303. max_cck->dsp_self_kill);
  304. pos += scnprintf(buf + pos, bufsz - pos,
  305. " %-30s %10u %10u %10u %10u\n", "mh_format_err:",
  306. le32_to_cpu(cck->mh_format_err),
  307. accum_cck->mh_format_err, delta_cck->mh_format_err,
  308. max_cck->mh_format_err);
  309. pos += scnprintf(buf + pos, bufsz - pos,
  310. " %-30s %10u %10u %10u %10u\n",
  311. "re_acq_main_rssi_sum:",
  312. le32_to_cpu(cck->re_acq_main_rssi_sum),
  313. accum_cck->re_acq_main_rssi_sum,
  314. delta_cck->re_acq_main_rssi_sum,
  315. max_cck->re_acq_main_rssi_sum);
  316. pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
  317. "acumulative delta max\n",
  318. "Statistics_Rx - GENERAL:");
  319. pos += scnprintf(buf + pos, bufsz - pos,
  320. " %-30s %10u %10u %10u %10u\n", "bogus_cts:",
  321. le32_to_cpu(general->bogus_cts),
  322. accum_general->bogus_cts, delta_general->bogus_cts,
  323. max_general->bogus_cts);
  324. pos += scnprintf(buf + pos, bufsz - pos,
  325. " %-30s %10u %10u %10u %10u\n", "bogus_ack:",
  326. le32_to_cpu(general->bogus_ack),
  327. accum_general->bogus_ack, delta_general->bogus_ack,
  328. max_general->bogus_ack);
  329. pos += scnprintf(buf + pos, bufsz - pos,
  330. " %-30s %10u %10u %10u %10u\n",
  331. "non_bssid_frames:",
  332. le32_to_cpu(general->non_bssid_frames),
  333. accum_general->non_bssid_frames,
  334. delta_general->non_bssid_frames,
  335. max_general->non_bssid_frames);
  336. pos += scnprintf(buf + pos, bufsz - pos,
  337. " %-30s %10u %10u %10u %10u\n",
  338. "filtered_frames:",
  339. le32_to_cpu(general->filtered_frames),
  340. accum_general->filtered_frames,
  341. delta_general->filtered_frames,
  342. max_general->filtered_frames);
  343. pos += scnprintf(buf + pos, bufsz - pos,
  344. " %-30s %10u %10u %10u %10u\n",
  345. "non_channel_beacons:",
  346. le32_to_cpu(general->non_channel_beacons),
  347. accum_general->non_channel_beacons,
  348. delta_general->non_channel_beacons,
  349. max_general->non_channel_beacons);
  350. pos += scnprintf(buf + pos, bufsz - pos,
  351. " %-30s %10u %10u %10u %10u\n",
  352. "channel_beacons:",
  353. le32_to_cpu(general->channel_beacons),
  354. accum_general->channel_beacons,
  355. delta_general->channel_beacons,
  356. max_general->channel_beacons);
  357. pos += scnprintf(buf + pos, bufsz - pos,
  358. " %-30s %10u %10u %10u %10u\n",
  359. "num_missed_bcon:",
  360. le32_to_cpu(general->num_missed_bcon),
  361. accum_general->num_missed_bcon,
  362. delta_general->num_missed_bcon,
  363. max_general->num_missed_bcon);
  364. pos += scnprintf(buf + pos, bufsz - pos,
  365. " %-30s %10u %10u %10u %10u\n",
  366. "adc_rx_saturation_time:",
  367. le32_to_cpu(general->adc_rx_saturation_time),
  368. accum_general->adc_rx_saturation_time,
  369. delta_general->adc_rx_saturation_time,
  370. max_general->adc_rx_saturation_time);
  371. pos += scnprintf(buf + pos, bufsz - pos,
  372. " %-30s %10u %10u %10u %10u\n",
  373. "ina_detect_search_tm:",
  374. le32_to_cpu(general->ina_detection_search_time),
  375. accum_general->ina_detection_search_time,
  376. delta_general->ina_detection_search_time,
  377. max_general->ina_detection_search_time);
  378. pos += scnprintf(buf + pos, bufsz - pos,
  379. " %-30s %10u %10u %10u %10u\n",
  380. "beacon_silence_rssi_a:",
  381. le32_to_cpu(general->beacon_silence_rssi_a),
  382. accum_general->beacon_silence_rssi_a,
  383. delta_general->beacon_silence_rssi_a,
  384. max_general->beacon_silence_rssi_a);
  385. pos += scnprintf(buf + pos, bufsz - pos,
  386. " %-30s %10u %10u %10u %10u\n",
  387. "beacon_silence_rssi_b:",
  388. le32_to_cpu(general->beacon_silence_rssi_b),
  389. accum_general->beacon_silence_rssi_b,
  390. delta_general->beacon_silence_rssi_b,
  391. max_general->beacon_silence_rssi_b);
  392. pos += scnprintf(buf + pos, bufsz - pos,
  393. " %-30s %10u %10u %10u %10u\n",
  394. "beacon_silence_rssi_c:",
  395. le32_to_cpu(general->beacon_silence_rssi_c),
  396. accum_general->beacon_silence_rssi_c,
  397. delta_general->beacon_silence_rssi_c,
  398. max_general->beacon_silence_rssi_c);
  399. pos += scnprintf(buf + pos, bufsz - pos,
  400. " %-30s %10u %10u %10u %10u\n",
  401. "interference_data_flag:",
  402. le32_to_cpu(general->interference_data_flag),
  403. accum_general->interference_data_flag,
  404. delta_general->interference_data_flag,
  405. max_general->interference_data_flag);
  406. pos += scnprintf(buf + pos, bufsz - pos,
  407. " %-30s %10u %10u %10u %10u\n",
  408. "channel_load:",
  409. le32_to_cpu(general->channel_load),
  410. accum_general->channel_load,
  411. delta_general->channel_load,
  412. max_general->channel_load);
  413. pos += scnprintf(buf + pos, bufsz - pos,
  414. " %-30s %10u %10u %10u %10u\n",
  415. "dsp_false_alarms:",
  416. le32_to_cpu(general->dsp_false_alarms),
  417. accum_general->dsp_false_alarms,
  418. delta_general->dsp_false_alarms,
  419. max_general->dsp_false_alarms);
  420. pos += scnprintf(buf + pos, bufsz - pos,
  421. " %-30s %10u %10u %10u %10u\n",
  422. "beacon_rssi_a:",
  423. le32_to_cpu(general->beacon_rssi_a),
  424. accum_general->beacon_rssi_a,
  425. delta_general->beacon_rssi_a,
  426. max_general->beacon_rssi_a);
  427. pos += scnprintf(buf + pos, bufsz - pos,
  428. " %-30s %10u %10u %10u %10u\n",
  429. "beacon_rssi_b:",
  430. le32_to_cpu(general->beacon_rssi_b),
  431. accum_general->beacon_rssi_b,
  432. delta_general->beacon_rssi_b,
  433. max_general->beacon_rssi_b);
  434. pos += scnprintf(buf + pos, bufsz - pos,
  435. " %-30s %10u %10u %10u %10u\n",
  436. "beacon_rssi_c:",
  437. le32_to_cpu(general->beacon_rssi_c),
  438. accum_general->beacon_rssi_c,
  439. delta_general->beacon_rssi_c,
  440. max_general->beacon_rssi_c);
  441. pos += scnprintf(buf + pos, bufsz - pos,
  442. " %-30s %10u %10u %10u %10u\n",
  443. "beacon_energy_a:",
  444. le32_to_cpu(general->beacon_energy_a),
  445. accum_general->beacon_energy_a,
  446. delta_general->beacon_energy_a,
  447. max_general->beacon_energy_a);
  448. pos += scnprintf(buf + pos, bufsz - pos,
  449. " %-30s %10u %10u %10u %10u\n",
  450. "beacon_energy_b:",
  451. le32_to_cpu(general->beacon_energy_b),
  452. accum_general->beacon_energy_b,
  453. delta_general->beacon_energy_b,
  454. max_general->beacon_energy_b);
  455. pos += scnprintf(buf + pos, bufsz - pos,
  456. " %-30s %10u %10u %10u %10u\n",
  457. "beacon_energy_c:",
  458. le32_to_cpu(general->beacon_energy_c),
  459. accum_general->beacon_energy_c,
  460. delta_general->beacon_energy_c,
  461. max_general->beacon_energy_c);
  462. pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n");
  463. pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
  464. "acumulative delta max\n",
  465. "Statistics_Rx - OFDM_HT:");
  466. pos += scnprintf(buf + pos, bufsz - pos,
  467. " %-30s %10u %10u %10u %10u\n",
  468. "plcp_err:",
  469. le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
  470. delta_ht->plcp_err, max_ht->plcp_err);
  471. pos += scnprintf(buf + pos, bufsz - pos,
  472. " %-30s %10u %10u %10u %10u\n",
  473. "overrun_err:",
  474. le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
  475. delta_ht->overrun_err, max_ht->overrun_err);
  476. pos += scnprintf(buf + pos, bufsz - pos,
  477. " %-30s %10u %10u %10u %10u\n",
  478. "early_overrun_err:",
  479. le32_to_cpu(ht->early_overrun_err),
  480. accum_ht->early_overrun_err,
  481. delta_ht->early_overrun_err,
  482. max_ht->early_overrun_err);
  483. pos += scnprintf(buf + pos, bufsz - pos,
  484. " %-30s %10u %10u %10u %10u\n",
  485. "crc32_good:",
  486. le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
  487. delta_ht->crc32_good, max_ht->crc32_good);
  488. pos += scnprintf(buf + pos, bufsz - pos,
  489. " %-30s %10u %10u %10u %10u\n",
  490. "crc32_err:",
  491. le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
  492. delta_ht->crc32_err, max_ht->crc32_err);
  493. pos += scnprintf(buf + pos, bufsz - pos,
  494. " %-30s %10u %10u %10u %10u\n",
  495. "mh_format_err:",
  496. le32_to_cpu(ht->mh_format_err),
  497. accum_ht->mh_format_err,
  498. delta_ht->mh_format_err, max_ht->mh_format_err);
  499. pos += scnprintf(buf + pos, bufsz - pos,
  500. " %-30s %10u %10u %10u %10u\n",
  501. "agg_crc32_good:",
  502. le32_to_cpu(ht->agg_crc32_good),
  503. accum_ht->agg_crc32_good,
  504. delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
  505. pos += scnprintf(buf + pos, bufsz - pos,
  506. " %-30s %10u %10u %10u %10u\n",
  507. "agg_mpdu_cnt:",
  508. le32_to_cpu(ht->agg_mpdu_cnt),
  509. accum_ht->agg_mpdu_cnt,
  510. delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
  511. pos += scnprintf(buf + pos, bufsz - pos,
  512. " %-30s %10u %10u %10u %10u\n",
  513. "agg_cnt:",
  514. le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
  515. delta_ht->agg_cnt, max_ht->agg_cnt);
  516. pos += scnprintf(buf + pos, bufsz - pos,
  517. " %-30s %10u %10u %10u %10u\n",
  518. "unsupport_mcs:",
  519. le32_to_cpu(ht->unsupport_mcs),
  520. accum_ht->unsupport_mcs,
  521. delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
  522. ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
  523. kfree(buf);
  524. return ret;
  525. }
  526. ssize_t iwl_ucode_tx_stats_read(struct file *file,
  527. char __user *user_buf,
  528. size_t count, loff_t *ppos)
  529. {
  530. struct iwl_priv *priv = file->private_data;
  531. int pos = 0;
  532. char *buf;
  533. int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
  534. ssize_t ret;
  535. struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
  536. if (!iwl_is_alive(priv))
  537. return -EAGAIN;
  538. buf = kzalloc(bufsz, GFP_KERNEL);
  539. if (!buf) {
  540. IWL_ERR(priv, "Can not allocate Buffer\n");
  541. return -ENOMEM;
  542. }
  543. /* the statistic information display here is based on
  544. * the last statistics notification from uCode
  545. * might not reflect the current uCode activity
  546. */
  547. tx = &priv->_agn.statistics.tx;
  548. accum_tx = &priv->_agn.accum_statistics.tx;
  549. delta_tx = &priv->_agn.delta_statistics.tx;
  550. max_tx = &priv->_agn.max_delta.tx;
  551. pos += iwl_statistics_flag(priv, buf, bufsz);
  552. pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
  553. "acumulative delta max\n",
  554. "Statistics_Tx:");
  555. pos += scnprintf(buf + pos, bufsz - pos,
  556. " %-30s %10u %10u %10u %10u\n",
  557. "preamble:",
  558. le32_to_cpu(tx->preamble_cnt),
  559. accum_tx->preamble_cnt,
  560. delta_tx->preamble_cnt, max_tx->preamble_cnt);
  561. pos += scnprintf(buf + pos, bufsz - pos,
  562. " %-30s %10u %10u %10u %10u\n",
  563. "rx_detected_cnt:",
  564. le32_to_cpu(tx->rx_detected_cnt),
  565. accum_tx->rx_detected_cnt,
  566. delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
  567. pos += scnprintf(buf + pos, bufsz - pos,
  568. " %-30s %10u %10u %10u %10u\n",
  569. "bt_prio_defer_cnt:",
  570. le32_to_cpu(tx->bt_prio_defer_cnt),
  571. accum_tx->bt_prio_defer_cnt,
  572. delta_tx->bt_prio_defer_cnt,
  573. max_tx->bt_prio_defer_cnt);
  574. pos += scnprintf(buf + pos, bufsz - pos,
  575. " %-30s %10u %10u %10u %10u\n",
  576. "bt_prio_kill_cnt:",
  577. le32_to_cpu(tx->bt_prio_kill_cnt),
  578. accum_tx->bt_prio_kill_cnt,
  579. delta_tx->bt_prio_kill_cnt,
  580. max_tx->bt_prio_kill_cnt);
  581. pos += scnprintf(buf + pos, bufsz - pos,
  582. " %-30s %10u %10u %10u %10u\n",
  583. "few_bytes_cnt:",
  584. le32_to_cpu(tx->few_bytes_cnt),
  585. accum_tx->few_bytes_cnt,
  586. delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
  587. pos += scnprintf(buf + pos, bufsz - pos,
  588. " %-30s %10u %10u %10u %10u\n",
  589. "cts_timeout:",
  590. le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
  591. delta_tx->cts_timeout, max_tx->cts_timeout);
  592. pos += scnprintf(buf + pos, bufsz - pos,
  593. " %-30s %10u %10u %10u %10u\n",
  594. "ack_timeout:",
  595. le32_to_cpu(tx->ack_timeout),
  596. accum_tx->ack_timeout,
  597. delta_tx->ack_timeout, max_tx->ack_timeout);
  598. pos += scnprintf(buf + pos, bufsz - pos,
  599. " %-30s %10u %10u %10u %10u\n",
  600. "expected_ack_cnt:",
  601. le32_to_cpu(tx->expected_ack_cnt),
  602. accum_tx->expected_ack_cnt,
  603. delta_tx->expected_ack_cnt,
  604. max_tx->expected_ack_cnt);
  605. pos += scnprintf(buf + pos, bufsz - pos,
  606. " %-30s %10u %10u %10u %10u\n",
  607. "actual_ack_cnt:",
  608. le32_to_cpu(tx->actual_ack_cnt),
  609. accum_tx->actual_ack_cnt,
  610. delta_tx->actual_ack_cnt,
  611. max_tx->actual_ack_cnt);
  612. pos += scnprintf(buf + pos, bufsz - pos,
  613. " %-30s %10u %10u %10u %10u\n",
  614. "dump_msdu_cnt:",
  615. le32_to_cpu(tx->dump_msdu_cnt),
  616. accum_tx->dump_msdu_cnt,
  617. delta_tx->dump_msdu_cnt,
  618. max_tx->dump_msdu_cnt);
  619. pos += scnprintf(buf + pos, bufsz - pos,
  620. " %-30s %10u %10u %10u %10u\n",
  621. "abort_nxt_frame_mismatch:",
  622. le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
  623. accum_tx->burst_abort_next_frame_mismatch_cnt,
  624. delta_tx->burst_abort_next_frame_mismatch_cnt,
  625. max_tx->burst_abort_next_frame_mismatch_cnt);
  626. pos += scnprintf(buf + pos, bufsz - pos,
  627. " %-30s %10u %10u %10u %10u\n",
  628. "abort_missing_nxt_frame:",
  629. le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
  630. accum_tx->burst_abort_missing_next_frame_cnt,
  631. delta_tx->burst_abort_missing_next_frame_cnt,
  632. max_tx->burst_abort_missing_next_frame_cnt);
  633. pos += scnprintf(buf + pos, bufsz - pos,
  634. " %-30s %10u %10u %10u %10u\n",
  635. "cts_timeout_collision:",
  636. le32_to_cpu(tx->cts_timeout_collision),
  637. accum_tx->cts_timeout_collision,
  638. delta_tx->cts_timeout_collision,
  639. max_tx->cts_timeout_collision);
  640. pos += scnprintf(buf + pos, bufsz - pos,
  641. " %-30s %10u %10u %10u %10u\n",
  642. "ack_ba_timeout_collision:",
  643. le32_to_cpu(tx->ack_or_ba_timeout_collision),
  644. accum_tx->ack_or_ba_timeout_collision,
  645. delta_tx->ack_or_ba_timeout_collision,
  646. max_tx->ack_or_ba_timeout_collision);
  647. pos += scnprintf(buf + pos, bufsz - pos,
  648. " %-30s %10u %10u %10u %10u\n",
  649. "agg ba_timeout:",
  650. le32_to_cpu(tx->agg.ba_timeout),
  651. accum_tx->agg.ba_timeout,
  652. delta_tx->agg.ba_timeout,
  653. max_tx->agg.ba_timeout);
  654. pos += scnprintf(buf + pos, bufsz - pos,
  655. " %-30s %10u %10u %10u %10u\n",
  656. "agg ba_resched_frames:",
  657. le32_to_cpu(tx->agg.ba_reschedule_frames),
  658. accum_tx->agg.ba_reschedule_frames,
  659. delta_tx->agg.ba_reschedule_frames,
  660. max_tx->agg.ba_reschedule_frames);
  661. pos += scnprintf(buf + pos, bufsz - pos,
  662. " %-30s %10u %10u %10u %10u\n",
  663. "agg scd_query_agg_frame:",
  664. le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
  665. accum_tx->agg.scd_query_agg_frame_cnt,
  666. delta_tx->agg.scd_query_agg_frame_cnt,
  667. max_tx->agg.scd_query_agg_frame_cnt);
  668. pos += scnprintf(buf + pos, bufsz - pos,
  669. " %-30s %10u %10u %10u %10u\n",
  670. "agg scd_query_no_agg:",
  671. le32_to_cpu(tx->agg.scd_query_no_agg),
  672. accum_tx->agg.scd_query_no_agg,
  673. delta_tx->agg.scd_query_no_agg,
  674. max_tx->agg.scd_query_no_agg);
  675. pos += scnprintf(buf + pos, bufsz - pos,
  676. " %-30s %10u %10u %10u %10u\n",
  677. "agg scd_query_agg:",
  678. le32_to_cpu(tx->agg.scd_query_agg),
  679. accum_tx->agg.scd_query_agg,
  680. delta_tx->agg.scd_query_agg,
  681. max_tx->agg.scd_query_agg);
  682. pos += scnprintf(buf + pos, bufsz - pos,
  683. " %-30s %10u %10u %10u %10u\n",
  684. "agg scd_query_mismatch:",
  685. le32_to_cpu(tx->agg.scd_query_mismatch),
  686. accum_tx->agg.scd_query_mismatch,
  687. delta_tx->agg.scd_query_mismatch,
  688. max_tx->agg.scd_query_mismatch);
  689. pos += scnprintf(buf + pos, bufsz - pos,
  690. " %-30s %10u %10u %10u %10u\n",
  691. "agg frame_not_ready:",
  692. le32_to_cpu(tx->agg.frame_not_ready),
  693. accum_tx->agg.frame_not_ready,
  694. delta_tx->agg.frame_not_ready,
  695. max_tx->agg.frame_not_ready);
  696. pos += scnprintf(buf + pos, bufsz - pos,
  697. " %-30s %10u %10u %10u %10u\n",
  698. "agg underrun:",
  699. le32_to_cpu(tx->agg.underrun),
  700. accum_tx->agg.underrun,
  701. delta_tx->agg.underrun, max_tx->agg.underrun);
  702. pos += scnprintf(buf + pos, bufsz - pos,
  703. " %-30s %10u %10u %10u %10u\n",
  704. "agg bt_prio_kill:",
  705. le32_to_cpu(tx->agg.bt_prio_kill),
  706. accum_tx->agg.bt_prio_kill,
  707. delta_tx->agg.bt_prio_kill,
  708. max_tx->agg.bt_prio_kill);
  709. pos += scnprintf(buf + pos, bufsz - pos,
  710. " %-30s %10u %10u %10u %10u\n",
  711. "agg rx_ba_rsp_cnt:",
  712. le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
  713. accum_tx->agg.rx_ba_rsp_cnt,
  714. delta_tx->agg.rx_ba_rsp_cnt,
  715. max_tx->agg.rx_ba_rsp_cnt);
  716. if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) {
  717. pos += scnprintf(buf + pos, bufsz - pos,
  718. "tx power: (1/2 dB step)\n");
  719. if ((priv->cfg->valid_tx_ant & ANT_A) && tx->tx_power.ant_a)
  720. pos += scnprintf(buf + pos, bufsz - pos,
  721. "\tantenna A: 0x%X\n",
  722. tx->tx_power.ant_a);
  723. if ((priv->cfg->valid_tx_ant & ANT_B) && tx->tx_power.ant_b)
  724. pos += scnprintf(buf + pos, bufsz - pos,
  725. "\tantenna B: 0x%X\n",
  726. tx->tx_power.ant_b);
  727. if ((priv->cfg->valid_tx_ant & ANT_C) && tx->tx_power.ant_c)
  728. pos += scnprintf(buf + pos, bufsz - pos,
  729. "\tantenna C: 0x%X\n",
  730. tx->tx_power.ant_c);
  731. }
  732. ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
  733. kfree(buf);
  734. return ret;
  735. }
  736. ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
  737. size_t count, loff_t *ppos)
  738. {
  739. struct iwl_priv *priv = file->private_data;
  740. int pos = 0;
  741. char *buf;
  742. int bufsz = sizeof(struct statistics_general) * 10 + 300;
  743. ssize_t ret;
  744. struct statistics_general *general, *accum_general;
  745. struct statistics_general *delta_general, *max_general;
  746. struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
  747. struct statistics_div *div, *accum_div, *delta_div, *max_div;
  748. if (!iwl_is_alive(priv))
  749. return -EAGAIN;
  750. buf = kzalloc(bufsz, GFP_KERNEL);
  751. if (!buf) {
  752. IWL_ERR(priv, "Can not allocate Buffer\n");
  753. return -ENOMEM;
  754. }
  755. /* the statistic information display here is based on
  756. * the last statistics notification from uCode
  757. * might not reflect the current uCode activity
  758. */
  759. general = &priv->_agn.statistics.general;
  760. dbg = &priv->_agn.statistics.general.dbg;
  761. div = &priv->_agn.statistics.general.div;
  762. accum_general = &priv->_agn.accum_statistics.general;
  763. delta_general = &priv->_agn.delta_statistics.general;
  764. max_general = &priv->_agn.max_delta.general;
  765. accum_dbg = &priv->_agn.accum_statistics.general.dbg;
  766. delta_dbg = &priv->_agn.delta_statistics.general.dbg;
  767. max_dbg = &priv->_agn.max_delta.general.dbg;
  768. accum_div = &priv->_agn.accum_statistics.general.div;
  769. delta_div = &priv->_agn.delta_statistics.general.div;
  770. max_div = &priv->_agn.max_delta.general.div;
  771. pos += iwl_statistics_flag(priv, buf, bufsz);
  772. pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
  773. "acumulative delta max\n",
  774. "Statistics_General:");
  775. pos += scnprintf(buf + pos, bufsz - pos, " %-30s %10u\n",
  776. "temperature:",
  777. le32_to_cpu(general->temperature));
  778. pos += scnprintf(buf + pos, bufsz - pos, " %-30s %10u\n",
  779. "temperature_m:",
  780. le32_to_cpu(general->temperature_m));
  781. pos += scnprintf(buf + pos, bufsz - pos,
  782. " %-30s %10u %10u %10u %10u\n",
  783. "burst_check:",
  784. le32_to_cpu(dbg->burst_check),
  785. accum_dbg->burst_check,
  786. delta_dbg->burst_check, max_dbg->burst_check);
  787. pos += scnprintf(buf + pos, bufsz - pos,
  788. " %-30s %10u %10u %10u %10u\n",
  789. "burst_count:",
  790. le32_to_cpu(dbg->burst_count),
  791. accum_dbg->burst_count,
  792. delta_dbg->burst_count, max_dbg->burst_count);
  793. pos += scnprintf(buf + pos, bufsz - pos,
  794. " %-30s %10u %10u %10u %10u\n",
  795. "sleep_time:",
  796. le32_to_cpu(general->sleep_time),
  797. accum_general->sleep_time,
  798. delta_general->sleep_time, max_general->sleep_time);
  799. pos += scnprintf(buf + pos, bufsz - pos,
  800. " %-30s %10u %10u %10u %10u\n",
  801. "slots_out:",
  802. le32_to_cpu(general->slots_out),
  803. accum_general->slots_out,
  804. delta_general->slots_out, max_general->slots_out);
  805. pos += scnprintf(buf + pos, bufsz - pos,
  806. " %-30s %10u %10u %10u %10u\n",
  807. "slots_idle:",
  808. le32_to_cpu(general->slots_idle),
  809. accum_general->slots_idle,
  810. delta_general->slots_idle, max_general->slots_idle);
  811. pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n",
  812. le32_to_cpu(general->ttl_timestamp));
  813. pos += scnprintf(buf + pos, bufsz - pos,
  814. " %-30s %10u %10u %10u %10u\n",
  815. "tx_on_a:",
  816. le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
  817. delta_div->tx_on_a, max_div->tx_on_a);
  818. pos += scnprintf(buf + pos, bufsz - pos,
  819. " %-30s %10u %10u %10u %10u\n",
  820. "tx_on_b:",
  821. le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
  822. delta_div->tx_on_b, max_div->tx_on_b);
  823. pos += scnprintf(buf + pos, bufsz - pos,
  824. " %-30s %10u %10u %10u %10u\n",
  825. "exec_time:",
  826. le32_to_cpu(div->exec_time), accum_div->exec_time,
  827. delta_div->exec_time, max_div->exec_time);
  828. pos += scnprintf(buf + pos, bufsz - pos,
  829. " %-30s %10u %10u %10u %10u\n",
  830. "probe_time:",
  831. le32_to_cpu(div->probe_time), accum_div->probe_time,
  832. delta_div->probe_time, max_div->probe_time);
  833. pos += scnprintf(buf + pos, bufsz - pos,
  834. " %-30s %10u %10u %10u %10u\n",
  835. "rx_enable_counter:",
  836. le32_to_cpu(general->rx_enable_counter),
  837. accum_general->rx_enable_counter,
  838. delta_general->rx_enable_counter,
  839. max_general->rx_enable_counter);
  840. pos += scnprintf(buf + pos, bufsz - pos,
  841. " %-30s %10u %10u %10u %10u\n",
  842. "num_of_sos_states:",
  843. le32_to_cpu(general->num_of_sos_states),
  844. accum_general->num_of_sos_states,
  845. delta_general->num_of_sos_states,
  846. max_general->num_of_sos_states);
  847. ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
  848. kfree(buf);
  849. return ret;
  850. }