exp_rcv.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
  2. /*
  3. * Copyright(c) 2017 Intel Corporation.
  4. */
  5. #ifndef _HFI1_EXP_RCV_H
  6. #define _HFI1_EXP_RCV_H
  7. #include "hfi.h"
  8. #define EXP_TID_SET_EMPTY(set) (set.count == 0 && list_empty(&set.list))
  9. #define EXP_TID_TIDLEN_MASK 0x7FFULL
  10. #define EXP_TID_TIDLEN_SHIFT 0
  11. #define EXP_TID_TIDCTRL_MASK 0x3ULL
  12. #define EXP_TID_TIDCTRL_SHIFT 20
  13. #define EXP_TID_TIDIDX_MASK 0x3FFULL
  14. #define EXP_TID_TIDIDX_SHIFT 22
  15. #define EXP_TID_GET(tid, field) \
  16. (((tid) >> EXP_TID_TID##field##_SHIFT) & EXP_TID_TID##field##_MASK)
  17. #define EXP_TID_SET(field, value) \
  18. (((value) & EXP_TID_TID##field##_MASK) << \
  19. EXP_TID_TID##field##_SHIFT)
  20. #define EXP_TID_CLEAR(tid, field) ({ \
  21. (tid) &= ~(EXP_TID_TID##field##_MASK << \
  22. EXP_TID_TID##field##_SHIFT); \
  23. })
  24. #define EXP_TID_RESET(tid, field, value) do { \
  25. EXP_TID_CLEAR(tid, field); \
  26. (tid) |= EXP_TID_SET(field, (value)); \
  27. } while (0)
  28. /*
  29. * Define fields in the KDETH header so we can update the header
  30. * template.
  31. */
  32. #define KDETH_OFFSET_SHIFT 0
  33. #define KDETH_OFFSET_MASK 0x7fff
  34. #define KDETH_OM_SHIFT 15
  35. #define KDETH_OM_MASK 0x1
  36. #define KDETH_TID_SHIFT 16
  37. #define KDETH_TID_MASK 0x3ff
  38. #define KDETH_TIDCTRL_SHIFT 26
  39. #define KDETH_TIDCTRL_MASK 0x3
  40. #define KDETH_INTR_SHIFT 28
  41. #define KDETH_INTR_MASK 0x1
  42. #define KDETH_SH_SHIFT 29
  43. #define KDETH_SH_MASK 0x1
  44. #define KDETH_KVER_SHIFT 30
  45. #define KDETH_KVER_MASK 0x3
  46. #define KDETH_JKEY_SHIFT 0x0
  47. #define KDETH_JKEY_MASK 0xff
  48. #define KDETH_HCRC_UPPER_SHIFT 16
  49. #define KDETH_HCRC_UPPER_MASK 0xff
  50. #define KDETH_HCRC_LOWER_SHIFT 24
  51. #define KDETH_HCRC_LOWER_MASK 0xff
  52. #define KDETH_GET(val, field) \
  53. (((le32_to_cpu((val))) >> KDETH_##field##_SHIFT) & KDETH_##field##_MASK)
  54. #define KDETH_SET(dw, field, val) do { \
  55. u32 dwval = le32_to_cpu(dw); \
  56. dwval &= ~(KDETH_##field##_MASK << KDETH_##field##_SHIFT); \
  57. dwval |= (((val) & KDETH_##field##_MASK) << \
  58. KDETH_##field##_SHIFT); \
  59. dw = cpu_to_le32(dwval); \
  60. } while (0)
  61. #define KDETH_RESET(dw, field, val) ({ dw = 0; KDETH_SET(dw, field, val); })
  62. /* KDETH OM multipliers and switch over point */
  63. #define KDETH_OM_SMALL 4
  64. #define KDETH_OM_SMALL_SHIFT 2
  65. #define KDETH_OM_LARGE 64
  66. #define KDETH_OM_LARGE_SHIFT 6
  67. #define KDETH_OM_MAX_SIZE (1 << ((KDETH_OM_LARGE / KDETH_OM_SMALL) + 1))
  68. struct tid_group {
  69. struct list_head list;
  70. u32 base;
  71. u8 size;
  72. u8 used;
  73. u8 map;
  74. };
  75. /*
  76. * Write an "empty" RcvArray entry.
  77. * This function exists so the TID registaration code can use it
  78. * to write to unused/unneeded entries and still take advantage
  79. * of the WC performance improvements. The HFI will ignore this
  80. * write to the RcvArray entry.
  81. */
  82. static inline void rcv_array_wc_fill(struct hfi1_devdata *dd, u32 index)
  83. {
  84. /*
  85. * Doing the WC fill writes only makes sense if the device is
  86. * present and the RcvArray has been mapped as WC memory.
  87. */
  88. if ((dd->flags & HFI1_PRESENT) && dd->rcvarray_wc) {
  89. writeq(0, dd->rcvarray_wc + (index * 8));
  90. if ((index & 3) == 3)
  91. flush_wc();
  92. }
  93. }
  94. static inline void tid_group_add_tail(struct tid_group *grp,
  95. struct exp_tid_set *set)
  96. {
  97. list_add_tail(&grp->list, &set->list);
  98. set->count++;
  99. }
  100. static inline void tid_group_remove(struct tid_group *grp,
  101. struct exp_tid_set *set)
  102. {
  103. list_del_init(&grp->list);
  104. set->count--;
  105. }
  106. static inline void tid_group_move(struct tid_group *group,
  107. struct exp_tid_set *s1,
  108. struct exp_tid_set *s2)
  109. {
  110. tid_group_remove(group, s1);
  111. tid_group_add_tail(group, s2);
  112. }
  113. static inline struct tid_group *tid_group_pop(struct exp_tid_set *set)
  114. {
  115. struct tid_group *grp =
  116. list_first_entry(&set->list, struct tid_group, list);
  117. list_del_init(&grp->list);
  118. set->count--;
  119. return grp;
  120. }
  121. static inline u32 rcventry2tidinfo(u32 rcventry)
  122. {
  123. u32 pair = rcventry & ~0x1;
  124. return EXP_TID_SET(IDX, pair >> 1) |
  125. EXP_TID_SET(CTRL, 1 << (rcventry - pair));
  126. }
  127. /**
  128. * hfi1_tid_group_to_idx - convert an index to a group
  129. * @rcd - the receive context
  130. * @grp - the group pointer
  131. */
  132. static inline u16
  133. hfi1_tid_group_to_idx(struct hfi1_ctxtdata *rcd, struct tid_group *grp)
  134. {
  135. return grp - &rcd->groups[0];
  136. }
  137. /**
  138. * hfi1_idx_to_tid_group - convert a group to an index
  139. * @rcd - the receive context
  140. * @idx - the index
  141. */
  142. static inline struct tid_group *
  143. hfi1_idx_to_tid_group(struct hfi1_ctxtdata *rcd, u16 idx)
  144. {
  145. return &rcd->groups[idx];
  146. }
  147. int hfi1_alloc_ctxt_rcv_groups(struct hfi1_ctxtdata *rcd);
  148. void hfi1_free_ctxt_rcv_groups(struct hfi1_ctxtdata *rcd);
  149. void hfi1_exp_tid_group_init(struct hfi1_ctxtdata *rcd);
  150. #endif /* _HFI1_EXP_RCV_H */