dp_hist.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * Copyright (c) 2020 The Linux Foundation. All rights reserved.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for
  5. * any purpose with or without fee is hereby granted, provided that the
  6. * above copyright notice and this permission notice appear in all
  7. * copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  10. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  11. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  12. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  13. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  14. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  15. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  16. * PERFORMANCE OF THIS SOFTWARE.
  17. */
  18. #include <qdf_util.h>
  19. #include <qdf_mem.h>
  20. #include <cdp_txrx_hist_struct.h>
  21. #include "dp_hist.h"
  22. /*
  23. * dp_hist_sw_enq_dbucket: Sofware enqueue delay bucket in ms
  24. * @index_0 = 0_1 ms
  25. * @index_1 = 1_2 ms
  26. * @index_2 = 2_3 ms
  27. * @index_3 = 3_4 ms
  28. * @index_4 = 4_5 ms
  29. * @index_5 = 5_6 ms
  30. * @index_6 = 6_7 ms
  31. * @index_7 = 7_8 ms
  32. * @index_8 = 8_9 ms
  33. * @index_8 = 9+ ms
  34. */
  35. static uint16_t dp_hist_sw_enq_dbucket[CDP_HIST_BUCKET_MAX] = {
  36. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  37. /*
  38. * cdp_hist_fw2hw_dbucket: HW enqueue to Completion Delay
  39. * @index_0 = 0_10 ms
  40. * @index_1 = 10_20 ms
  41. * @index_2 = 20_30ms
  42. * @index_3 = 30_40 ms
  43. * @index_4 = 40_50 ms
  44. * @index_5 = 50_60 ms
  45. * @index_6 = 60_70 ms
  46. * @index_7 = 70_80 ms
  47. * @index_8 = 80_90 ms
  48. * @index_9 = 90+ ms
  49. */
  50. static uint16_t dp_hist_fw2hw_dbucket[CDP_HIST_BUCKET_MAX] = {
  51. 0, 10, 20, 30, 40, 50, 60, 70, 80, 90};
  52. /*
  53. * dp_hist_reap2stack_bucket: Reap to stack bucket
  54. * @index_0 = 0_5 ms
  55. * @index_1 = 5_10 ms
  56. * @index_2 = 10_15 ms
  57. * @index_3 = 15_20 ms
  58. * @index_4 = 20_25 ms
  59. * @index_5 = 25_30 ms
  60. * @index_6 = 30_35 ms
  61. * @index_7 = 35_40 ms
  62. * @index_8 = 40_45 ms
  63. * @index_9 = 45+ ms
  64. */
  65. static uint16_t dp_hist_reap2stack_bucket[CDP_HIST_BUCKET_MAX] = {
  66. 0, 5, 10, 15, 20, 25, 30, 35, 40, 45};
  67. /*
  68. * dp_hist_find_bucket_idx: Find the bucket index
  69. * @bucket_array: Bucket array
  70. * @value: Frequency value
  71. *
  72. * Return: The bucket index
  73. */
  74. static int dp_hist_find_bucket_idx(int16_t *bucket_array, int value)
  75. {
  76. uint8_t idx = CDP_HIST_BUCKET_0;
  77. for (; idx < (CDP_HIST_BUCKET_MAX - 1); idx++) {
  78. if (value < bucket_array[idx + 1])
  79. break;
  80. }
  81. return idx;
  82. }
  83. /*
  84. * dp_hist_fill_buckets: Fill the histogram frequency buckets
  85. * @hist_bucket: Histogram bukcets
  86. * @value: Frequency value
  87. *
  88. * Return: void
  89. */
  90. static void dp_hist_fill_buckets(struct cdp_hist_bucket *hist_bucket, int value)
  91. {
  92. enum cdp_hist_types hist_type;
  93. int idx = CDP_HIST_BUCKET_MAX;
  94. if (qdf_unlikely(!hist_bucket))
  95. return;
  96. hist_type = hist_bucket->hist_type;
  97. /* Identify the bucket the bucket and update. */
  98. switch (hist_type) {
  99. case CDP_HIST_TYPE_SW_ENQEUE_DELAY:
  100. idx = dp_hist_find_bucket_idx(&dp_hist_sw_enq_dbucket[0],
  101. value);
  102. break;
  103. case CDP_HIST_TYPE_HW_COMP_DELAY:
  104. idx = dp_hist_find_bucket_idx(&dp_hist_fw2hw_dbucket[0],
  105. value);
  106. break;
  107. case CDP_HIST_TYPE_REAP_STACK:
  108. idx = dp_hist_find_bucket_idx(
  109. &dp_hist_reap2stack_bucket[0], value);
  110. break;
  111. default:
  112. break;
  113. }
  114. if (idx == CDP_HIST_BUCKET_MAX)
  115. return;
  116. hist_bucket->freq[idx]++;
  117. }
  118. /*
  119. * dp_hist_update_stats: Update histogram stats
  120. * @hist_stats: Hist stats object
  121. * @value: Delay value
  122. *
  123. * Return: void
  124. */
  125. void dp_hist_update_stats(struct cdp_hist_stats *hist_stats, int value)
  126. {
  127. if (qdf_unlikely(!hist_stats))
  128. return;
  129. /*
  130. * Fill the histogram buckets according to the delay
  131. */
  132. dp_hist_fill_buckets(&hist_stats->hist, value);
  133. /*
  134. * Compute the min, max and average. Average computed is weighted
  135. * average
  136. */
  137. if (value < hist_stats->min)
  138. hist_stats->min = value;
  139. if (value > hist_stats->max)
  140. hist_stats->max = value;
  141. if (qdf_unlikely(!hist_stats->avg))
  142. hist_stats->avg = value;
  143. else
  144. hist_stats->avg = hist_stats->avg +
  145. ((value - hist_stats->avg) >> HIST_AVG_WEIGHT_DENOM);
  146. }
  147. /*
  148. * dp_copy_hist_stats(): Copy the histogram stats
  149. * @src_hist_stats: Source histogram stats
  150. * @dst_hist_stats: Destination histogram stats
  151. *
  152. * Return: void
  153. */
  154. void dp_copy_hist_stats(struct cdp_hist_stats *src_hist_stats,
  155. struct cdp_hist_stats *dst_hist_stats)
  156. {
  157. uint8_t index;
  158. for (index = 0; index < CDP_HIST_BUCKET_MAX; index++)
  159. dst_hist_stats->hist.freq[index] =
  160. src_hist_stats->hist.freq[index];
  161. dst_hist_stats->min = src_hist_stats->min;
  162. dst_hist_stats->max = src_hist_stats->max;
  163. dst_hist_stats->avg = src_hist_stats->avg;
  164. }
  165. /*
  166. * dp_accumulate_hist_stats(): Accumulate the hist src to dst
  167. * @src_hist_stats: Source histogram stats
  168. * @dst_hist_stats: Destination histogram stats
  169. *
  170. * Return: void
  171. */
  172. void dp_accumulate_hist_stats(struct cdp_hist_stats *src_hist_stats,
  173. struct cdp_hist_stats *dst_hist_stats)
  174. {
  175. uint8_t index;
  176. for (index = 0; index < CDP_HIST_BUCKET_MAX; index++)
  177. dst_hist_stats->hist.freq[index] +=
  178. src_hist_stats->hist.freq[index];
  179. dst_hist_stats->min = QDF_MIN(src_hist_stats->min, dst_hist_stats->min);
  180. dst_hist_stats->max = QDF_MAX(src_hist_stats->max, dst_hist_stats->max);
  181. dst_hist_stats->avg = (src_hist_stats->avg + dst_hist_stats->avg) >> 1;
  182. }
  183. /*
  184. * dp_hist_init(): Initialize the histogram object
  185. * @hist_stats: Hist stats object
  186. * @hist_type: Histogram type
  187. */
  188. void dp_hist_init(struct cdp_hist_stats *hist_stats,
  189. enum cdp_hist_types hist_type)
  190. {
  191. qdf_mem_zero(hist_stats, sizeof(*hist_stats));
  192. hist_stats->hist.hist_type = hist_type;
  193. }