ccci_statistics.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. #include <linux/module.h>
  2. #include <linux/device.h>
  3. #include <linux/fs.h>
  4. #include <linux/cdev.h>
  5. #include <linux/interrupt.h>
  6. #include <linux/spinlock.h>
  7. #include <linux/uaccess.h>
  8. #include <linux/mm.h>
  9. #include <linux/kfifo.h>
  10. #include <linux/firmware.h>
  11. #include <linux/syscalls.h>
  12. #include <linux/uaccess.h>
  13. #include <linux/platform_device.h>
  14. #include <linux/proc_fs.h>
  15. #include <ccci.h>
  16. #define CCCI_LOG_MAX_LEN 16
  17. struct ccci_log_t {
  18. struct timeval tv;
  19. struct ccci_msg_t msg;
  20. int droped;
  21. };
  22. struct logic_ch_record_t {
  23. struct ccci_log_t log[CCCI_LOG_MAX_LEN];
  24. unsigned long msg_num;
  25. unsigned long drop_num;
  26. int log_idx;
  27. int dir;
  28. char *name;
  29. };
  30. struct ch_history_t {
  31. struct logic_ch_record_t all_ch[CCCI_MAX_CH_NUM];
  32. int md_id;
  33. };
  34. static struct ch_history_t *history_ctlb[MAX_MD_NUM];
  35. void add_logic_layer_record(int md_id, struct ccci_msg_t *data, int drop)
  36. {
  37. struct logic_ch_record_t *ctlb;
  38. unsigned int ch = data->channel;
  39. struct ccci_log_t *record;
  40. if (ch >= CCCI_MAX_CH_NUM)
  41. return;
  42. ctlb = &(history_ctlb[md_id]->all_ch[ch]);
  43. if (ctlb == NULL)
  44. return;
  45. record = &(ctlb->log[ctlb->log_idx]);
  46. ctlb->log_idx++;
  47. ctlb->log_idx &= (CCCI_LOG_MAX_LEN - 1);
  48. do_gettimeofday(&(record->tv));
  49. record->msg = *data;
  50. record->droped = drop;
  51. if (drop)
  52. ctlb->drop_num++;
  53. else
  54. ctlb->msg_num++;
  55. }
  56. static int s_to_date(long seconds, long usec, int *us, int *sec, int *min,
  57. int *hour, int *day, int *month, int *year)
  58. {
  59. #define DAY_PER_LEAP_YEAR 366
  60. #define DAY_PER_NON_LEAP_YEAR 365
  61. unsigned int i = 0;
  62. unsigned long mins, hours, days, month_t, year_t;
  63. unsigned char m[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  64. if (!sec || !min || !hour || !day || !month || !year) {
  65. CCCI_MSG("<ctl>%s invalid param!\n", __func__);
  66. return -1;
  67. }
  68. *us = usec;
  69. *sec = seconds % 60;
  70. mins = seconds / 60;
  71. *min = mins % 60;
  72. hours = mins / 60;
  73. *hour = hours % 24;
  74. days = hours / 24;
  75. year_t = 1970;
  76. while (1) {
  77. if (!(year_t % 4) && (year_t % 100)) {
  78. if (days >= DAY_PER_LEAP_YEAR) {
  79. days -= DAY_PER_LEAP_YEAR;
  80. year_t++;
  81. } else
  82. break;
  83. } else {
  84. if (days >= DAY_PER_NON_LEAP_YEAR) {
  85. days -= DAY_PER_NON_LEAP_YEAR;
  86. year_t++;
  87. } else
  88. break;
  89. }
  90. }
  91. if (!(year_t % 4) && year_t % 100)
  92. m[1] = 29;
  93. month_t = 1;
  94. for (i = 0; i < 12; i++) {
  95. if (days > m[i]) {
  96. days -= m[i];
  97. month_t++;
  98. } else
  99. break;
  100. }
  101. *day = days;
  102. *year = year_t;
  103. *month = month_t;
  104. return 0;
  105. }
  106. static int ccci_record_dump(struct ccci_log_t *log)
  107. {
  108. int ms, sec, min, hour, day, month, year;
  109. long tv_sec, tv_usec;
  110. tv_sec = (long)log->tv.tv_sec;
  111. tv_usec = (long)log->tv.tv_usec;
  112. if ((tv_sec == 0) && (tv_usec == 0))
  113. return -1;
  114. s_to_date(tv_sec, tv_usec, &ms, &sec, &min, &hour, &day, &month, &year);
  115. if (!log->droped) {
  116. CCCI_DBG_COM_MSG
  117. ("%08X %08X %02d %08X %d-%02d-%02d %02d:%02d:%02d.%06d\n",
  118. log->msg.data0, log->msg.data1, log->msg.channel,
  119. log->msg.reserved, year, month, day, hour, min, sec, ms);
  120. } else {
  121. CCCI_DBG_COM_MSG
  122. ("%08X %08X %02d %08X %d-%02d-%02d %02d:%02d:%02d.%06d -\n",
  123. log->msg.data0, log->msg.data1, log->msg.channel,
  124. log->msg.reserved, year, month, day, hour, min, sec, ms);
  125. }
  126. return 0;
  127. }
  128. void logic_layer_ch_record_dump(int md_id, int ch)
  129. {
  130. struct ch_history_t *ctlb = history_ctlb[md_id];
  131. int i, j;
  132. struct logic_ch_record_t *record;
  133. if ((ctlb != NULL) && (ch < CCCI_MAX_CH_NUM)) {
  134. record = &(ctlb->all_ch[ch]);
  135. CCCI_DBG_COM_MSG("\n");
  136. if (record->dir == CCCI_LOG_TX)
  137. CCCI_DBG_COM_MSG
  138. ("ch%02d tx:%ld\t tx_drop:%ld name: %s\t\n", ch,
  139. record->msg_num, record->drop_num, record->name);
  140. else
  141. CCCI_DBG_COM_MSG
  142. ("ch%02d rx:%ld\t rx_drop:%ld name: %s\t\n", ch,
  143. record->msg_num, record->drop_num, record->name);
  144. /* dump last ten message */
  145. j = record->log_idx - 1;
  146. j &= (CCCI_LOG_MAX_LEN - 1);
  147. for (i = 0; i < 10; i++) {
  148. if (ccci_record_dump(&(record->log[j])) < 0)
  149. break;
  150. j--;
  151. j &= (CCCI_LOG_MAX_LEN - 1);
  152. }
  153. }
  154. }
  155. void dump_logical_layer_tx_rx_histroy(int md_id)
  156. {
  157. int i = 0;
  158. struct ch_history_t *ctlb = history_ctlb[md_id];
  159. if (ctlb != NULL)
  160. for (i = 0; i < CCCI_MAX_CH_NUM; i++)
  161. logic_layer_ch_record_dump(md_id, i);
  162. }
  163. int statistics_init_ch_dir(int md_id, int ch, int dir, char *name)
  164. {
  165. struct ch_history_t *ctlb = history_ctlb[md_id];
  166. struct logic_ch_record_t *record;
  167. int ret = 0;
  168. if ((ctlb != NULL) && (ch < CCCI_MAX_CH_NUM)) {
  169. record = &(ctlb->all_ch[ch]);
  170. record->dir = dir;
  171. record->name = name;
  172. } else
  173. ret = -1;
  174. return ret;
  175. }
  176. int statistics_init(int md_id)
  177. {
  178. history_ctlb[md_id] = kmalloc(sizeof(struct ch_history_t), GFP_KERNEL);
  179. if (history_ctlb[md_id] != NULL)
  180. memset(history_ctlb[md_id], 0, sizeof(struct ch_history_t));
  181. return 0;
  182. }
  183. void statistics_exit(int md_id)
  184. {
  185. kfree(history_ctlb[md_id]);
  186. history_ctlb[md_id] = NULL;
  187. }