linux/drivers/infiniband/hw/hns/hns_roce_hem.h
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2016 Hisilicon Limited.
   3 * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
   4 *
   5 * This software is available to you under a choice of one of two
   6 * licenses.  You may choose to be licensed under the terms of the GNU
   7 * General Public License (GPL) Version 2, available from the file
   8 * COPYING in the main directory of this source tree, or the
   9 * OpenIB.org BSD license below:
  10 *
  11 *     Redistribution and use in source and binary forms, with or
  12 *     without modification, are permitted provided that the following
  13 *     conditions are met:
  14 *
  15 *      - Redistributions of source code must retain the above
  16 *        copyright notice, this list of conditions and the following
  17 *        disclaimer.
  18 *
  19 *      - Redistributions in binary form must reproduce the above
  20 *        copyright notice, this list of conditions and the following
  21 *        disclaimer in the documentation and/or other materials
  22 *        provided with the distribution.
  23 *
  24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  31 * SOFTWARE.
  32 */
  33
  34#ifndef _HNS_ROCE_HEM_H
  35#define _HNS_ROCE_HEM_H
  36
  37#define HW_SYNC_TIMEOUT_MSECS           500
  38#define HW_SYNC_SLEEP_TIME_INTERVAL     20
  39#define BT_CMD_SYNC_SHIFT               31
  40
  41enum {
  42        /* MAP HEM(Hardware Entry Memory) */
  43        HEM_TYPE_QPC = 0,
  44        HEM_TYPE_MTPT,
  45        HEM_TYPE_CQC,
  46        HEM_TYPE_SRQC,
  47
  48         /* UNMAP HEM */
  49        HEM_TYPE_MTT,
  50        HEM_TYPE_IRRL,
  51};
  52
  53#define HNS_ROCE_HEM_CHUNK_LEN  \
  54         ((256 - sizeof(struct list_head) - 2 * sizeof(int)) /   \
  55         (sizeof(struct scatterlist)))
  56
  57enum {
  58         HNS_ROCE_HEM_PAGE_SHIFT = 12,
  59         HNS_ROCE_HEM_PAGE_SIZE  = 1 << HNS_ROCE_HEM_PAGE_SHIFT,
  60};
  61
  62struct hns_roce_hem_chunk {
  63        struct list_head         list;
  64        int                      npages;
  65        int                      nsg;
  66        struct scatterlist       mem[HNS_ROCE_HEM_CHUNK_LEN];
  67};
  68
  69struct hns_roce_hem {
  70        struct list_head         chunk_list;
  71        int                      refcount;
  72};
  73
  74struct hns_roce_hem_iter {
  75        struct hns_roce_hem              *hem;
  76        struct hns_roce_hem_chunk        *chunk;
  77        int                              page_idx;
  78};
  79
  80void hns_roce_free_hem(struct hns_roce_dev *hr_dev, struct hns_roce_hem *hem);
  81int hns_roce_table_get(struct hns_roce_dev *hr_dev,
  82                       struct hns_roce_hem_table *table, unsigned long obj);
  83void hns_roce_table_put(struct hns_roce_dev *hr_dev,
  84                        struct hns_roce_hem_table *table, unsigned long obj);
  85void *hns_roce_table_find(struct hns_roce_hem_table *table, unsigned long obj,
  86                          dma_addr_t *dma_handle);
  87int hns_roce_table_get_range(struct hns_roce_dev *hr_dev,
  88                             struct hns_roce_hem_table *table,
  89                             unsigned long start, unsigned long end);
  90void hns_roce_table_put_range(struct hns_roce_dev *hr_dev,
  91                              struct hns_roce_hem_table *table,
  92                              unsigned long start, unsigned long end);
  93int hns_roce_init_hem_table(struct hns_roce_dev *hr_dev,
  94                            struct hns_roce_hem_table *table, u32 type,
  95                            unsigned long obj_size, unsigned long nobj,
  96                            int use_lowmem);
  97void hns_roce_cleanup_hem_table(struct hns_roce_dev *hr_dev,
  98                                struct hns_roce_hem_table *table);
  99void hns_roce_cleanup_hem(struct hns_roce_dev *hr_dev);
 100
 101static inline void hns_roce_hem_first(struct hns_roce_hem *hem,
 102                                      struct hns_roce_hem_iter *iter)
 103{
 104        iter->hem = hem;
 105        iter->chunk = list_empty(&hem->chunk_list) ? NULL :
 106                                 list_entry(hem->chunk_list.next,
 107                                            struct hns_roce_hem_chunk, list);
 108         iter->page_idx = 0;
 109}
 110
 111static inline int hns_roce_hem_last(struct hns_roce_hem_iter *iter)
 112{
 113        return !iter->chunk;
 114}
 115
 116static inline void hns_roce_hem_next(struct hns_roce_hem_iter *iter)
 117{
 118        if (++iter->page_idx >= iter->chunk->nsg) {
 119                if (iter->chunk->list.next == &iter->hem->chunk_list) {
 120                        iter->chunk = NULL;
 121                        return;
 122                }
 123
 124                iter->chunk = list_entry(iter->chunk->list.next,
 125                                         struct hns_roce_hem_chunk, list);
 126                iter->page_idx = 0;
 127        }
 128}
 129
 130static inline dma_addr_t hns_roce_hem_addr(struct hns_roce_hem_iter *iter)
 131{
 132        return sg_dma_address(&iter->chunk->mem[iter->page_idx]);
 133}
 134
 135#endif /*_HNS_ROCE_HEM_H*/
 136