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