ipa_nat_statemach.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /*
  2. * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are
  6. * met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above
  10. * copyright notice, this list of conditions and the following
  11. * disclaimer in the documentation and/or other materials provided
  12. * with the distribution.
  13. * * Neither the name of The Linux Foundation nor the names of its
  14. * contributors may be used to endorse or promote products derived
  15. * from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
  18. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  19. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
  21. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  22. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  23. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  24. * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  25. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  26. * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  27. * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. */
  29. #if !defined(_IPA_NAT_STATEMACH_H_)
  30. # define _IPA_NAT_STATEMACH_H_
  31. typedef uintptr_t arb_t;
  32. #define MAKE_AS_STR_CASE(v) case v: return #v
  33. /******************************************************************************/
  34. /**
  35. * The following enum represents the states that a nati object can be
  36. * in.
  37. */
  38. typedef enum {
  39. NATI_STATE_NULL = 0,
  40. NATI_STATE_DDR_ONLY = 1, /* NAT in DDR only (traditional) */
  41. NATI_STATE_SRAM_ONLY = 2, /* NAT in SRAM only (new) */
  42. NATI_STATE_HYBRID = 3, /* NAT simultaneously in both SRAM/DDR */
  43. NATI_STATE_HYBRID_DDR = 4, /* NAT transitioned from SRAM to DDR */
  44. NATI_STATE_LAST
  45. } ipa_nati_state;
  46. /* KEEP THE FOLLOWING IN SYNC WITH ABOVE. */
  47. static inline const char* ipa_nati_state_as_str(
  48. ipa_nati_state s )
  49. {
  50. switch ( s )
  51. {
  52. MAKE_AS_STR_CASE(NATI_STATE_NULL);
  53. MAKE_AS_STR_CASE(NATI_STATE_DDR_ONLY);
  54. MAKE_AS_STR_CASE(NATI_STATE_SRAM_ONLY);
  55. MAKE_AS_STR_CASE(NATI_STATE_HYBRID);
  56. MAKE_AS_STR_CASE(NATI_STATE_HYBRID_DDR);
  57. MAKE_AS_STR_CASE(NATI_STATE_LAST);
  58. default:
  59. break;
  60. }
  61. return "???";
  62. }
  63. # undef strcasesame
  64. # define strcasesame(a, b) (!strcasecmp(a, b))
  65. static inline ipa_nati_state mem_type_str_to_ipa_nati_state(
  66. const char* str )
  67. {
  68. if ( str ) {
  69. if (strcasesame(str, "HYBRID" ))
  70. return NATI_STATE_HYBRID;
  71. if (strcasesame(str, "SRAM" ))
  72. return NATI_STATE_SRAM_ONLY;
  73. }
  74. return NATI_STATE_DDR_ONLY;
  75. }
  76. /******************************************************************************/
  77. /**
  78. * The following enum represents the API triggers that may or may not
  79. * cause a nati object to transition through its various allowable
  80. * states defined in ipa_nati_state above.
  81. */
  82. typedef enum {
  83. NATI_TRIG_NULL = 0,
  84. NATI_TRIG_ADD_TABLE = 1,
  85. NATI_TRIG_DEL_TABLE = 2,
  86. NATI_TRIG_CLR_TABLE = 3,
  87. NATI_TRIG_WLK_TABLE = 4,
  88. NATI_TRIG_TBL_STATS = 5,
  89. NATI_TRIG_ADD_RULE = 6,
  90. NATI_TRIG_DEL_RULE = 7,
  91. NATI_TRIG_TBL_SWITCH = 8,
  92. NATI_TRIG_GOTO_DDR = 9,
  93. NATI_TRIG_GOTO_SRAM = 10,
  94. NATI_TRIG_GET_TSTAMP = 11,
  95. NATI_TRIG_LAST
  96. } ipa_nati_trigger;
  97. /******************************************************************************/
  98. /**
  99. * The following structure used to keep switch stats.
  100. */
  101. typedef struct
  102. {
  103. uint32_t pass;
  104. uint32_t fail;
  105. } nati_switch_stats;
  106. /******************************************************************************/
  107. /**
  108. * The following structure used to direct map usage.
  109. *
  110. * Maps are needed to map rule handles..orig to new and new to orig.
  111. * See comments in ipa_nat_statemach.c on this topic...
  112. */
  113. typedef struct
  114. {
  115. uint32_t orig2new_map;
  116. uint32_t new2orig_map;
  117. } nati_map_pair;
  118. /******************************************************************************/
  119. /**
  120. * The following is a nati object that will maintain state relative to
  121. * various API calls.
  122. */
  123. typedef struct
  124. {
  125. ipa_nati_state prev_state;
  126. ipa_nati_state curr_state;
  127. bool hold_state;
  128. ipa_nati_state state_to_hold;
  129. uint32_t ddr_tbl_hdl;
  130. uint32_t sram_tbl_hdl;
  131. uint32_t tot_slots_in_sram;
  132. uint32_t back_to_sram_thresh;
  133. /*
  134. * tot_rules_in_table[0] for ddr, and
  135. * tot_rules_in_table[1] for sram
  136. */
  137. uint32_t tot_rules_in_table[2];
  138. /*
  139. * map_pairs[0] for ddr, and
  140. * map_pairs[1] for sram
  141. */
  142. nati_map_pair map_pairs[2];
  143. /*
  144. * sw_stats[0] for ddr, and
  145. * sw_stats[1] for sram
  146. */
  147. nati_switch_stats sw_stats[2];
  148. } ipa_nati_obj;
  149. /*
  150. * For use with the arrays above..in ipa_nati_obj...
  151. */
  152. #undef DDR_SUB
  153. #undef SRAM_SUB
  154. #define DDR_SUB 0
  155. #define SRAM_SUB 1
  156. #undef BACK2_UNSTARTED_STATE
  157. #define BACK2_UNSTARTED_STATE() \
  158. nati_obj.prev_state = nati_obj.curr_state = NATI_STATE_NULL;
  159. #undef IN_UNSTARTED_STATE
  160. #define IN_UNSTARTED_STATE() \
  161. ( nati_obj.prev_state == NATI_STATE_NULL )
  162. #undef IN_HYBRID_STATE
  163. #define IN_HYBRID_STATE() \
  164. ( nati_obj.curr_state == NATI_STATE_HYBRID || \
  165. nati_obj.curr_state == NATI_STATE_HYBRID_DDR )
  166. #undef COMPATIBLE_NMI_4SWITCH
  167. #define COMPATIBLE_NMI_4SWITCH(n) \
  168. ( (n) == IPA_NAT_MEM_IN_SRAM && nati_obj.curr_state == NATI_STATE_HYBRID_DDR ) || \
  169. ( (n) == IPA_NAT_MEM_IN_DDR && nati_obj.curr_state == NATI_STATE_HYBRID ) || \
  170. ( (n) == IPA_NAT_MEM_IN_DDR && nati_obj.curr_state == NATI_STATE_DDR_ONLY ) || \
  171. ( (n) == IPA_NAT_MEM_IN_SRAM && nati_obj.curr_state == NATI_STATE_SRAM_ONLY )
  172. #undef GEN_HOLD_STATE
  173. #define GEN_HOLD_STATE() \
  174. ( ! IN_HYBRID_STATE() ) ? nati_obj.curr_state : \
  175. (nati_obj.curr_state == NATI_STATE_HYBRID) ? NATI_STATE_SRAM_ONLY : \
  176. NATI_STATE_DDR_ONLY
  177. #undef SRAM_CURRENTLY_ACTIVE
  178. #define SRAM_CURRENTLY_ACTIVE() \
  179. ( nati_obj.curr_state == NATI_STATE_SRAM_ONLY || \
  180. nati_obj.curr_state == NATI_STATE_HYBRID )
  181. #define SRAM_TO_BE_ACCESSED(t) \
  182. ( SRAM_CURRENTLY_ACTIVE() || \
  183. (t) == NATI_TRIG_GOTO_SRAM || \
  184. (t) == NATI_TRIG_TBL_SWITCH )
  185. /*
  186. * NOTE: The exclusion of timestamp retrieval and table creation
  187. * below.
  188. *
  189. * Why?
  190. *
  191. * In re timestamp:
  192. *
  193. * Because timestamp retrieval institutes too many repetitive
  194. * accesses, hence would lead to too many successive votes. Instead,
  195. * it will be handled differently and in the app layer above.
  196. *
  197. * In re table creation:
  198. *
  199. * Because it can't be known, apriori, whether or not sram is
  200. * really available for use. Instead, we'll move table creation
  201. * voting to a place where we know sram is available.
  202. */
  203. #undef VOTE_REQUIRED
  204. #define VOTE_REQUIRED(t) \
  205. ( SRAM_TO_BE_ACCESSED(t) && \
  206. (t) != NATI_TRIG_GET_TSTAMP && \
  207. (t) != NATI_TRIG_ADD_TABLE )
  208. /******************************************************************************/
  209. /**
  210. * A helper macro for changing a nati object's state...
  211. */
  212. # undef SET_NATIOBJ_STATE
  213. # define SET_NATIOBJ_STATE(x, s) { \
  214. (x)->prev_state = (x)->curr_state; \
  215. (x)->curr_state = s; \
  216. }
  217. /******************************************************************************/
  218. /**
  219. * A function signature for a state/trigger callback function...
  220. */
  221. typedef int (*nati_statemach_cb)(
  222. ipa_nati_obj* nati_obj_ptr,
  223. ipa_nati_trigger trigger,
  224. arb_t* arb_data_ptr );
  225. /******************************************************************************/
  226. /**
  227. * A structure for relating state to trigger callbacks.
  228. */
  229. typedef struct
  230. {
  231. ipa_nati_state state;
  232. ipa_nati_trigger trigger;
  233. nati_statemach_cb sm_cb;
  234. const char* state_as_str;
  235. const char* trigger_as_str;
  236. const char* sm_cb_as_str;
  237. } nati_statemach_tuple;
  238. #undef SM_ROW
  239. #define SM_ROW(s, t, f) \
  240. { s, t, f, #s, #t, #f }
  241. /******************************************************************************/
  242. /**
  243. * FUNCTION: ipa_nati_statemach
  244. *
  245. * PARAMS:
  246. *
  247. * @nati_obj_ptr (IN) A pointer to an initialized nati object
  248. *
  249. * @trigger (IN) The trigger to run through the state machine
  250. *
  251. * @arb_data_ptr (IN) Anything you like. Will be passed, untouched,
  252. * to the state/trigger callback function.
  253. *
  254. * DESCRIPTION:
  255. *
  256. * This function allows a nati object and a trigger to be run
  257. * through the state machine.
  258. *
  259. * RETURNS:
  260. *
  261. * zero on success, otherwise non-zero
  262. */
  263. int ipa_nati_statemach(
  264. ipa_nati_obj* nati_obj_ptr,
  265. ipa_nati_trigger trigger,
  266. arb_t* arb_data_ptr );
  267. #endif /* #if !defined(_IPA_NAT_STATEMACH_H_) */