hinic_hw_eqs.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /*
  2. * Huawei HiNIC PCI Express Linux driver
  3. * Copyright(c) 2017 Huawei Technologies Co., Ltd
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms and conditions of the GNU General Public License,
  7. * version 2, as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  12. * for more details.
  13. *
  14. */
  15. #ifndef HINIC_HW_EQS_H
  16. #define HINIC_HW_EQS_H
  17. #include <linux/types.h>
  18. #include <linux/workqueue.h>
  19. #include <linux/pci.h>
  20. #include <linux/sizes.h>
  21. #include <linux/bitops.h>
  22. #include <linux/interrupt.h>
  23. #include "hinic_hw_if.h"
  24. #define HINIC_AEQ_CTRL_0_INT_IDX_SHIFT 0
  25. #define HINIC_AEQ_CTRL_0_DMA_ATTR_SHIFT 12
  26. #define HINIC_AEQ_CTRL_0_PCI_INTF_IDX_SHIFT 20
  27. #define HINIC_AEQ_CTRL_0_INT_MODE_SHIFT 31
  28. #define HINIC_AEQ_CTRL_0_INT_IDX_MASK 0x3FF
  29. #define HINIC_AEQ_CTRL_0_DMA_ATTR_MASK 0x3F
  30. #define HINIC_AEQ_CTRL_0_PCI_INTF_IDX_MASK 0x3
  31. #define HINIC_AEQ_CTRL_0_INT_MODE_MASK 0x1
  32. #define HINIC_AEQ_CTRL_0_SET(val, member) \
  33. (((u32)(val) & HINIC_AEQ_CTRL_0_##member##_MASK) << \
  34. HINIC_AEQ_CTRL_0_##member##_SHIFT)
  35. #define HINIC_AEQ_CTRL_0_CLEAR(val, member) \
  36. ((val) & (~(HINIC_AEQ_CTRL_0_##member##_MASK \
  37. << HINIC_AEQ_CTRL_0_##member##_SHIFT)))
  38. #define HINIC_AEQ_CTRL_1_LEN_SHIFT 0
  39. #define HINIC_AEQ_CTRL_1_ELEM_SIZE_SHIFT 24
  40. #define HINIC_AEQ_CTRL_1_PAGE_SIZE_SHIFT 28
  41. #define HINIC_AEQ_CTRL_1_LEN_MASK 0x1FFFFF
  42. #define HINIC_AEQ_CTRL_1_ELEM_SIZE_MASK 0x3
  43. #define HINIC_AEQ_CTRL_1_PAGE_SIZE_MASK 0xF
  44. #define HINIC_AEQ_CTRL_1_SET(val, member) \
  45. (((u32)(val) & HINIC_AEQ_CTRL_1_##member##_MASK) << \
  46. HINIC_AEQ_CTRL_1_##member##_SHIFT)
  47. #define HINIC_AEQ_CTRL_1_CLEAR(val, member) \
  48. ((val) & (~(HINIC_AEQ_CTRL_1_##member##_MASK \
  49. << HINIC_AEQ_CTRL_1_##member##_SHIFT)))
  50. #define HINIC_CEQ_CTRL_0_INTR_IDX_SHIFT 0
  51. #define HINIC_CEQ_CTRL_0_DMA_ATTR_SHIFT 12
  52. #define HINIC_CEQ_CTRL_0_KICK_THRESH_SHIFT 20
  53. #define HINIC_CEQ_CTRL_0_PCI_INTF_IDX_SHIFT 24
  54. #define HINIC_CEQ_CTRL_0_INTR_MODE_SHIFT 31
  55. #define HINIC_CEQ_CTRL_0_INTR_IDX_MASK 0x3FF
  56. #define HINIC_CEQ_CTRL_0_DMA_ATTR_MASK 0x3F
  57. #define HINIC_CEQ_CTRL_0_KICK_THRESH_MASK 0xF
  58. #define HINIC_CEQ_CTRL_0_PCI_INTF_IDX_MASK 0x3
  59. #define HINIC_CEQ_CTRL_0_INTR_MODE_MASK 0x1
  60. #define HINIC_CEQ_CTRL_0_SET(val, member) \
  61. (((u32)(val) & HINIC_CEQ_CTRL_0_##member##_MASK) << \
  62. HINIC_CEQ_CTRL_0_##member##_SHIFT)
  63. #define HINIC_CEQ_CTRL_0_CLEAR(val, member) \
  64. ((val) & (~(HINIC_CEQ_CTRL_0_##member##_MASK \
  65. << HINIC_CEQ_CTRL_0_##member##_SHIFT)))
  66. #define HINIC_CEQ_CTRL_1_LEN_SHIFT 0
  67. #define HINIC_CEQ_CTRL_1_PAGE_SIZE_SHIFT 28
  68. #define HINIC_CEQ_CTRL_1_LEN_MASK 0x1FFFFF
  69. #define HINIC_CEQ_CTRL_1_PAGE_SIZE_MASK 0xF
  70. #define HINIC_CEQ_CTRL_1_SET(val, member) \
  71. (((u32)(val) & HINIC_CEQ_CTRL_1_##member##_MASK) << \
  72. HINIC_CEQ_CTRL_1_##member##_SHIFT)
  73. #define HINIC_CEQ_CTRL_1_CLEAR(val, member) \
  74. ((val) & (~(HINIC_CEQ_CTRL_1_##member##_MASK \
  75. << HINIC_CEQ_CTRL_1_##member##_SHIFT)))
  76. #define HINIC_EQ_ELEM_DESC_TYPE_SHIFT 0
  77. #define HINIC_EQ_ELEM_DESC_SRC_SHIFT 7
  78. #define HINIC_EQ_ELEM_DESC_SIZE_SHIFT 8
  79. #define HINIC_EQ_ELEM_DESC_WRAPPED_SHIFT 31
  80. #define HINIC_EQ_ELEM_DESC_TYPE_MASK 0x7F
  81. #define HINIC_EQ_ELEM_DESC_SRC_MASK 0x1
  82. #define HINIC_EQ_ELEM_DESC_SIZE_MASK 0xFF
  83. #define HINIC_EQ_ELEM_DESC_WRAPPED_MASK 0x1
  84. #define HINIC_EQ_ELEM_DESC_SET(val, member) \
  85. (((u32)(val) & HINIC_EQ_ELEM_DESC_##member##_MASK) << \
  86. HINIC_EQ_ELEM_DESC_##member##_SHIFT)
  87. #define HINIC_EQ_ELEM_DESC_GET(val, member) \
  88. (((val) >> HINIC_EQ_ELEM_DESC_##member##_SHIFT) & \
  89. HINIC_EQ_ELEM_DESC_##member##_MASK)
  90. #define HINIC_EQ_CI_IDX_SHIFT 0
  91. #define HINIC_EQ_CI_WRAPPED_SHIFT 20
  92. #define HINIC_EQ_CI_XOR_CHKSUM_SHIFT 24
  93. #define HINIC_EQ_CI_INT_ARMED_SHIFT 31
  94. #define HINIC_EQ_CI_IDX_MASK 0xFFFFF
  95. #define HINIC_EQ_CI_WRAPPED_MASK 0x1
  96. #define HINIC_EQ_CI_XOR_CHKSUM_MASK 0xF
  97. #define HINIC_EQ_CI_INT_ARMED_MASK 0x1
  98. #define HINIC_EQ_CI_SET(val, member) \
  99. (((u32)(val) & HINIC_EQ_CI_##member##_MASK) << \
  100. HINIC_EQ_CI_##member##_SHIFT)
  101. #define HINIC_EQ_CI_CLEAR(val, member) \
  102. ((val) & (~(HINIC_EQ_CI_##member##_MASK \
  103. << HINIC_EQ_CI_##member##_SHIFT)))
  104. #define HINIC_MAX_AEQS 4
  105. #define HINIC_MAX_CEQS 32
  106. #define HINIC_AEQE_SIZE 64
  107. #define HINIC_CEQE_SIZE 4
  108. #define HINIC_AEQE_DESC_SIZE 4
  109. #define HINIC_AEQE_DATA_SIZE \
  110. (HINIC_AEQE_SIZE - HINIC_AEQE_DESC_SIZE)
  111. #define HINIC_DEFAULT_AEQ_LEN 64
  112. #define HINIC_DEFAULT_CEQ_LEN 1024
  113. #define HINIC_EQ_PAGE_SIZE SZ_4K
  114. #define HINIC_CEQ_ID_CMDQ 0
  115. enum hinic_eq_type {
  116. HINIC_AEQ,
  117. HINIC_CEQ,
  118. };
  119. enum hinic_aeq_type {
  120. HINIC_MSG_FROM_MGMT_CPU = 2,
  121. HINIC_MAX_AEQ_EVENTS,
  122. };
  123. enum hinic_ceq_type {
  124. HINIC_CEQ_CMDQ = 3,
  125. HINIC_MAX_CEQ_EVENTS,
  126. };
  127. enum hinic_eqe_state {
  128. HINIC_EQE_ENABLED = BIT(0),
  129. HINIC_EQE_RUNNING = BIT(1),
  130. };
  131. struct hinic_aeq_elem {
  132. u8 data[HINIC_AEQE_DATA_SIZE];
  133. u32 desc;
  134. };
  135. struct hinic_eq_work {
  136. struct work_struct work;
  137. void *data;
  138. };
  139. struct hinic_eq {
  140. struct hinic_hwif *hwif;
  141. enum hinic_eq_type type;
  142. int q_id;
  143. u32 q_len;
  144. u32 page_size;
  145. u32 cons_idx;
  146. int wrapped;
  147. size_t elem_size;
  148. int num_pages;
  149. int num_elem_in_pg;
  150. struct msix_entry msix_entry;
  151. dma_addr_t *dma_addr;
  152. void **virt_addr;
  153. struct hinic_eq_work aeq_work;
  154. struct tasklet_struct ceq_tasklet;
  155. };
  156. struct hinic_hw_event_cb {
  157. void (*hwe_handler)(void *handle, void *data, u8 size);
  158. void *handle;
  159. unsigned long hwe_state;
  160. };
  161. struct hinic_aeqs {
  162. struct hinic_hwif *hwif;
  163. struct hinic_eq aeq[HINIC_MAX_AEQS];
  164. int num_aeqs;
  165. struct hinic_hw_event_cb hwe_cb[HINIC_MAX_AEQ_EVENTS];
  166. struct workqueue_struct *workq;
  167. };
  168. struct hinic_ceq_cb {
  169. void (*handler)(void *handle, u32 ceqe_data);
  170. void *handle;
  171. enum hinic_eqe_state ceqe_state;
  172. };
  173. struct hinic_ceqs {
  174. struct hinic_hwif *hwif;
  175. struct hinic_eq ceq[HINIC_MAX_CEQS];
  176. int num_ceqs;
  177. struct hinic_ceq_cb ceq_cb[HINIC_MAX_CEQ_EVENTS];
  178. };
  179. void hinic_aeq_register_hw_cb(struct hinic_aeqs *aeqs,
  180. enum hinic_aeq_type event, void *handle,
  181. void (*hwe_handler)(void *handle, void *data,
  182. u8 size));
  183. void hinic_aeq_unregister_hw_cb(struct hinic_aeqs *aeqs,
  184. enum hinic_aeq_type event);
  185. void hinic_ceq_register_cb(struct hinic_ceqs *ceqs,
  186. enum hinic_ceq_type event, void *handle,
  187. void (*ceq_cb)(void *handle, u32 ceqe_data));
  188. void hinic_ceq_unregister_cb(struct hinic_ceqs *ceqs,
  189. enum hinic_ceq_type event);
  190. int hinic_aeqs_init(struct hinic_aeqs *aeqs, struct hinic_hwif *hwif,
  191. int num_aeqs, u32 q_len, u32 page_size,
  192. struct msix_entry *msix_entries);
  193. void hinic_aeqs_free(struct hinic_aeqs *aeqs);
  194. int hinic_ceqs_init(struct hinic_ceqs *ceqs, struct hinic_hwif *hwif,
  195. int num_ceqs, u32 q_len, u32 page_size,
  196. struct msix_entry *msix_entries);
  197. void hinic_ceqs_free(struct hinic_ceqs *ceqs);
  198. #endif