rmnet_module.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. */
  12. #ifndef __RMNET_MODULE_H__
  13. #define __RMNET_MODULE_H__
  14. #include <linux/rcupdate.h>
  15. enum {
  16. RMNET_MODULE_HOOK_OFFLOAD_INGRESS,
  17. RMNET_MODULE_HOOK_OFFLOAD_CHAIN_END,
  18. RMNET_MODULE_HOOK_SHS_SKB_ENTRY,
  19. RMNET_MODULE_HOOK_SHS_SKB_LL_ENTRY,
  20. RMNET_MODULE_HOOK_SHS_SWITCH,
  21. RMNET_MODULE_HOOK_PERF_TETHER_INGRESS,
  22. RMNET_MODULE_HOOK_PERF_TETHER_EGRESS,
  23. RMNET_MODULE_HOOK_PERF_TETHER_CMD,
  24. RMNET_MODULE_HOOK_PERF_INGRESS,
  25. RMNET_MODULE_HOOK_PERF_EGRESS,
  26. RMNET_MODULE_HOOK_PERF_SET_THRESH,
  27. RMNET_MODULE_HOOK_APS_PRE_QUEUE,
  28. RMNET_MODULE_HOOK_APS_POST_QUEUE,
  29. RMNET_MODULE_HOOK_WLAN_FLOW_MATCH,
  30. RMNET_MODULE_HOOK_APS_DATA_INACTIVE,
  31. RMNET_MODULE_HOOK_APS_DATA_ACTIVE,
  32. RMNET_MODULE_HOOK_APS_DATA_REPORT,
  33. RMNET_MODULE_HOOK_PERF_INGRESS_RX_HANDLER,
  34. RMNET_MODULE_HOOK_WLAN_INGRESS_RX_HANDLER,
  35. __RMNET_MODULE_NUM_HOOKS,
  36. };
  37. struct rmnet_module_hook_register_info {
  38. int hooknum;
  39. void *func;
  40. };
  41. void
  42. rmnet_module_hook_register(const struct rmnet_module_hook_register_info *info,
  43. int hook_count);
  44. bool rmnet_module_hook_is_set(int hook);
  45. void
  46. rmnet_module_hook_unregister_no_sync(const struct rmnet_module_hook_register_info *info,
  47. int hook_count);
  48. static inline void
  49. rmnet_module_hook_unregister(const struct rmnet_module_hook_register_info *info,
  50. int hook_count)
  51. {
  52. rmnet_module_hook_unregister_no_sync(info, hook_count);
  53. synchronize_rcu();
  54. }
  55. /* Dummy macro. Can use kernel version later */
  56. #define __CAT(a, b) a ## b
  57. #define CAT(a, b) __CAT(a, b)
  58. #define RMNET_HOOK_PARAMS(args...) args
  59. #define RMNET_MODULE_HOOK_NUM(__hook) CAT(RMNET_MODULE_HOOK_, __hook)
  60. #define RMNET_MODULE_HOOK_PROTOCOL(proto...) proto
  61. #define RMNET_MODULE_HOOK_ARGS(args...) args
  62. #define RMNET_MODULE_HOOK_RETURN_TYPE(type) type
  63. /* A ...lovely... framework for checking if the argument passed in to a function
  64. * macro is a pair of parentheses.
  65. * If so, resolve to 1. Otherwise, 0.
  66. *
  67. * The idea here is that you pass the argument along with a "test" macro to
  68. * a "checker" macro. If the argument IS a pair of parentheses, this will cause
  69. * the tester macro to expand into multiple arguments.
  70. *
  71. * The key is that "checker" macro just returns the second argument it receives.
  72. * So have the "tester" macro expand to a set of arguments that makes 1 the
  73. * second argument, or 0 if it doesn't expand.
  74. */
  75. #define __RMNET_HOOK_SECOND_ARG(_, arg, ...) arg
  76. #define RMNET_HOOK_PARENTHESES_CHECKER(args...) \
  77. __RMNET_HOOK_SECOND_ARG(args, 0, )
  78. #define __RMNET_HOOK_PARENTHESES_TEST(arg) arg, 1,
  79. #define __RMNET_HOOK_IS_PARENTHESES_TEST(...) __RMNET_HOOK_PARENTHESES_TEST(XXX)
  80. #define RMNET_HOOK_IS_PARENTHESES(arg) \
  81. RMNET_HOOK_PARENTHESES_CHECKER(__RMNET_HOOK_IS_PARENTHESES_TEST arg)
  82. /* So what's the point of the above stuff, you ask?
  83. *
  84. * CPP can't actually do type checking ;). But what we CAN do is something
  85. * like this to determine if the type passed in is void. If so, this will
  86. * expand to (), causing the RMNET_HOOK_IS_PARENTHESES check to resolve to 1,
  87. * but if not, then the check resolves to 0.
  88. */
  89. #define __RMNET_HOOK_CHECK_TYPE_IS_void(arg) arg
  90. #define RMNET_HOOK_TYPE_IS_VOID(type) \
  91. RMNET_HOOK_IS_PARENTHESES( __RMNET_HOOK_CHECK_TYPE_IS_ ## type (()) )
  92. /* And now, we have some logic macros. The main macro will resolve
  93. * to one of the branches depending on the bool value passed in.
  94. */
  95. #define __IF_0(t_path, e_path...) e_path
  96. #define __IF_1(t_path, e_path...) t_path
  97. #define IF(arg) CAT(__IF_, arg)
  98. #define __NOT_1 0
  99. #define __NOT_0 1
  100. #define NOT(arg) CAT(__NOT_, arg)
  101. /* And now we combine this all, for a purely function macro way of splitting
  102. * return type handling...
  103. *
  104. * ...all to circumvent that you can't actually add #if conditionals in macro
  105. * expansions. It would have been much simpler that way. ;)
  106. */
  107. #define RMNET_HOOK_IF_NON_VOID_TYPE(type) \
  108. IF(NOT(RMNET_HOOK_TYPE_IS_VOID(type)))
  109. #define __RMNET_HOOK_PROTO(proto, ret_type)\
  110. RMNET_HOOK_IF_NON_VOID_TYPE(ret_type) \
  111. (RMNET_HOOK_PARAMS(ret_type *__ret_code, proto), \
  112. RMNET_HOOK_PARAMS(proto))
  113. #define __RMNET_HOOK_DECLARE(call, proto, ret_type) \
  114. int rmnet_module_hook_##call( \
  115. __RMNET_HOOK_PROTO(RMNET_HOOK_PARAMS(proto), ret_type));
  116. #undef RMNET_MODULE_HOOK
  117. #define RMNET_MODULE_HOOK(call, hook_num, proto, args, ret_type) \
  118. __RMNET_HOOK_DECLARE(call, RMNET_HOOK_PARAMS(proto), ret_type)
  119. #include "rmnet_hook.h"
  120. #endif