wlanfw_health_mon.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
  2. *
  3. * Permission to use, copy, modify, and/or distribute this software for any
  4. * purpose with or without fee is hereby granted, provided that the above
  5. * copyright notice and this permission notice appear in all copies.
  6. *
  7. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  8. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  10. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  11. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  12. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  13. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  14. */
  15. #ifndef __WLANFW_HEALTH_MON_H__
  16. #define __WLANFW_HEALTH_MON_H__
  17. #include <a_types.h> /* A_UINT32 */
  18. /* WLAN Health monitor data structure shared by host and FW */
  19. /*
  20. * Version 1 of the upload metric structs (i.e. wlanfw_health_mon_metric_upload_t)
  21. * provides a fixed allocation of 8 bytes of scratch space after each metric,
  22. * to optionally hold metric-specific data, e.g. from intermediate calculations when computing the score_pct.
  23. */
  24. #define WLANFW_HEALTH_MON_EXTRA_WORDS32 2
  25. /* word0:
  26. * Extract bitfields from the A_UINT32 "word" containing them.
  27. * The target produces the data in little-endian order.
  28. * If the host uses big-endian order, it needs to account for the endianness
  29. * difference when reading the data.
  30. * Definition of bitfields within 32-bit word:
  31. * bits 7:0 = module ID (M7...M0)
  32. * bits 14:8 = module local ID (m6...m0)
  33. * bits 31:15 = instance ID (I16...I0)
  34. * bits
  35. * |31 15|14 8|7 0|
  36. * +-------------------------------+-----------------+-------------------+
  37. * | instance ID | metric local ID | module ID |
  38. * |I16 ... I0|m6 ... m0|M7 ... M0|
  39. *
  40. * Layout in memory:
  41. * bits
  42. * |7 |6 0|
  43. * +---+--------------------------+
  44. * byte 0 |M7 M6 M5 M4 M3 M2 M1 M0|
  45. * +---+--------------------------+
  46. * byte 1 |I0 |m6 m5 m4 m3 m2 m1 m0|
  47. * +---+--------------------------+
  48. * byte 2 |I8 I7 I6 I5 I4 I3 I2 I1|
  49. * +------------------------------+
  50. * byte 3 |I16 I15 I14 I13 I12 I11 I10 I9|
  51. */
  52. #ifdef LITTLE_ENDIAN
  53. /* The little-endian version of the macro to extract the module id and metric id */
  54. #define WLANFW_HEALTH_MON_MODULE_ID_GET(word32) \
  55. (((word32) & 0x000000ff) >> 0)
  56. #define WLANFW_HEALTH_MON_METRIC_LOCAL_ID_GET(word32) \
  57. (((word32) & 0x00007f00) >> 8)
  58. #define WLANFW_HEALTH_MON_INSTANCE_ID_GET(word32) \
  59. (((word32) & 0xffff8000) >> 15)
  60. #else
  61. /*
  62. * When read into a big-endian 32-bit word:
  63. * bits
  64. * |31 24|23|22 16|15 8|7 0|
  65. * +--------------+--+--------------+------------------+-----------------+
  66. * |M7 M0|I0|m6 m0|I8 I1|I16 I9|
  67. *
  68. */
  69. /*
  70. * big-endian macro def to extract module ID = M7:M0 = byte3
  71. */
  72. #define WLANFW_HEALTH_MON_MODULE_ID_GET(word32) \
  73. (((word32) >> 24) && 0xff)
  74. /*
  75. * big-endian macro def to extract metric local ID = m6:m0 = byte2 & 0x7f
  76. */
  77. #define WLANFW_HEALTH_MON_METRIC_LOCAL_ID_GET(word32) \
  78. (((word32) >> 16) && 0x7f)
  79. /*
  80. * big-endian macro def to extract instance ID = I16:I0 =
  81. * (I16:I9 << 9) | (I8:I1 << 1) | I0
  82. * (byte0 << 9) | (byte1 << 1) | (byte2 >> 7)
  83. */
  84. #define WLANFW_HEALTH_MON_INSTANCE_ID_GET(word32) \
  85. (((((word32) >> 0) & 0xff) << 9) | /* I16:I9 */ \
  86. ((((word32) >> 8) & 0xff) << 1) | /* I8:I1 */ \
  87. ((((word32) >> 23) & 0x01) << 0)) /* I0 */
  88. #endif
  89. /* word1:
  90. * Extract bitfields from the A_UINT32 "word" containing them.
  91. * The target produces the data in little-endian order.
  92. * If the host uses big-endian order, it needs to account for the endianness
  93. * difference when reading the data.
  94. * Definition of bitfields within 32-bit word:
  95. * bits 7:0 = score_pct (S7...S0)
  96. * bits 15:8 = alarm_threshold (A7...A0)
  97. * bit 16 = old_alarm_state (P)
  98. * bits 20:17 = num_extra_bytes (N3..N0)
  99. * bit 21 = valid_data_flag (V)
  100. * bits 31:22 = reserved (R9...R0)
  101. * bits
  102. * |31 22|21|20 17|16|15 8|7 0|
  103. * +------------------+--+---------+--+-----------------+----------------+
  104. * | reserved |V |num bytes|P | alarm threshold | score_pct |
  105. * |R9 R0|V |N3 N0|P |A7 A0|S7 S0|
  106. *
  107. * Layout in memory:
  108. * bits
  109. * |7 6| 5 |4 2|1 0|
  110. * +-------+---+---------------+---+
  111. * byte 0 |S7 S6 S5 S4 S3 S2 S1 S0 |
  112. * +-------------------------------+
  113. * byte 1 |A7 A6 A5 A4 A3 A2 A1 A0 |
  114. * +-------+---+---------------+---+
  115. * byte 2 |R1 R0 | V |N3 N2 N1 N0 | P |
  116. * +-------------------------------+
  117. * byte 3 |R9 R8 R7 R6 R5 R4 R3 R2 |
  118. * +-------------------------------+
  119. */
  120. #ifdef LITTLE_ENDIAN
  121. #define WLANFW_HEALTH_MON_SCORE_PCT_GET(word32) \
  122. (((word32) & 0x000000ff) >> 0)
  123. #define WLANFW_HEALTH_MON_SCORE_ALARM_THRESHOLD_GET(word32) \
  124. (((word32) & 0x0000ff00) >> 8)
  125. #define WLANFW_HEALTH_MON_SCORE_OLD_ALARM_STATE_GET(word32) \
  126. (((word32) & 0x00010000) >> 16)
  127. #define WLANFW_HEALTH_MON_SCORE_NUM_EXTRA_BYTES_GET(word32) \
  128. (((word32) & 0x001e0000) >> 17)
  129. #define WLANFW_HEALTH_MON_SCORE_VALID_DATA_FLAG_GET(word32) \
  130. (((word32) & 0x00200000) >> 21)
  131. #else
  132. /*
  133. * When read into a big-endian 32-bit word:
  134. * bits
  135. * |31 24|23 16|15 14|13|12 9|8 |7 0|
  136. * +----------------+--------------+-------------------+-----------------+
  137. * |S7 S0|A7 A0|R1 R0|V |N3 N0|P |R9 R2|
  138. */
  139. /*
  140. * big-endian macro def to extract score_pct = S7:S0 = byte3
  141. */
  142. #define WLANFW_HEALTH_MON_SCORE_PCT_GET(word32) \
  143. (((word32) >> 24) && 0xff)
  144. /*
  145. * big-endian macro def to extract alarm_threshold = A7:A0 = byte2
  146. */
  147. #define WLANFW_HEALTH_MON_SCORE_ALARM_THRESHOLD_GET(word32) \
  148. (((word32) >> 16) && 0xff)
  149. /*
  150. * big-endian macro def to extract old_alarm_state = P = byte1 & 0x1
  151. */
  152. #define WLANFW_HEALTH_MON_SCORE_OLD_ALARM_STATE_GET(word32) \
  153. (((word32) >> 8) && 0x01)
  154. /*
  155. * big-endian macro def to extract num_extra_bytes = N3:N0 = (byte1>>1) & 0xf
  156. */
  157. #define WLANFW_HEALTH_MON_SCORE_NUM_EXTRA_BYTES_GET(word32) \
  158. (((word32) >> 9) && 0x0f)
  159. /*
  160. * big-endian macro def to extract valid_data_flag = V = (byte1 >> 5) & 0x1
  161. */
  162. #define WLANFW_HEALTH_MON_SCORE_VALID_DATA_FLAG_GET(word32) \
  163. (((word32) >> 13) && 0x01)
  164. #endif
  165. typedef struct _wlanfw_health_mon_metric_upload {
  166. union {
  167. A_UINT32 metric_id; /* Metric ID
  168. * Unique ID assigned to every metric registered
  169. */
  170. struct {
  171. A_UINT32 module_id:8, /* module_id:
  172. * Unique ID assigned to the FW module that owns the metric.
  173. * Refer to WLAN_MODULE_ID enum.
  174. */
  175. metric_local_id:7, /* metric_local_id:
  176. * Unique ID (within the module) assigned to this type of metric by the module that owns the metric.
  177. */
  178. instance_id:17; /* instance_id:
  179. * The ID of the owner of this particular instance of the metric.
  180. * E.g. for a per-pdev metric, this is the pdev_id, for a per-vdev metric this is the vdev_id, etc.
  181. */
  182. };
  183. };
  184. union {
  185. A_UINT32 word1;
  186. struct {
  187. A_UINT32 score_pct:8, /* range: 0 (bad) - 100 (perfect) */
  188. alarm_threshold:8, /* alarm_threshold:
  189. * If the metric's score falls below this threshold, the characteristic measured by the metric is a concern.
  190. * If the score is above this threshold the characteristic in question is behaving normally.
  191. * Any metrics that are purely for measurement (i.e. not for fault detection) should have alarm_threshold = 0.
  192. */
  193. old_alarm_state:1, /* old_alarm_state:
  194. * This flag indicates whether a score_pct below the alarm_threshold is new (old_alarm_state = 0) or ongoing (old_alarm_state = 1).
  195. */
  196. num_extra_bytes:4, /* num_extra_words32:
  197. * How many valid extra 4-byte words of metric-specific context follow this struct.
  198. */
  199. valid_data_flag:1, /* valid_data_flag:
  200. * Indication of whether this metric is in-use and containing valid data, or unallocated and invalid.
  201. * Since the target may upload all metric objects, both those that are in use and those that are available but unused, the host must check this flag to see whether the metric object contains valid data.
  202. */
  203. reserved:10;
  204. };
  205. };
  206. /* Extra scratch space for metric specific context data, e.g. the raw data used to compute the score_pct. */
  207. A_UINT32 extra_data[WLANFW_HEALTH_MON_EXTRA_WORDS32];
  208. } wlanfw_health_mon_metric_upload_t;
  209. typedef enum {
  210. WLANFW_HEALTH_MON_UPLOAD_FMT_INVALID = 0,
  211. /* V1: metrics use the wlanfw_health_mon_metric_upload_t format */
  212. WLANFW_HEALTH_MON_UPLOAD_FMT_V1 = 1,
  213. } wlanfw_health_mon_upload_fmt;
  214. typedef struct _wlanfw_health_mon_upload_ring {
  215. wlanfw_health_mon_upload_fmt version_number; /* version_number:
  216. * Specifies the format of the uploaded records.
  217. * 0 - unused
  218. * 1 - the upload records use the wlanfw_health_mon_metric_upload_t format.
  219. * (WLANFW_HEALTH_MON_UPLOAD_FMT_V1)
  220. * All other values are reserved.
  221. */
  222. /* specifies how large each element within the upload ring is */
  223. A_UINT32 ring_element_bytes;
  224. /* specifies how many spaces the ring contains */
  225. A_UINT32 num_ring_elements;
  226. /* specifies which ring element was last written by the target */
  227. A_UINT32 write_index;
  228. } wlanfw_health_mon_upload_ring_t;
  229. typedef struct _wlanfw_health_mon_upload_ring_elem_t {
  230. A_UINT32 timestamp;
  231. /* how much of the head portion of the ring element contains valid data */
  232. A_UINT32 num_valid_bytes;
  233. } wlanfw_health_mon_upload_ring_elem_t;
  234. #endif /* __WLANFW_HEALTH_MON_H__*/