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