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 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
|
/*
* Huawei HiNIC PCI Express Linux driver
* Copyright(c) 2017 Huawei Technologies Co., Ltd
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
*/
#ifndef HINIC_CMDQ_H
#define HINIC_CMDQ_H
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/pci.h>
#include "hinic_hw_if.h"
#include "hinic_hw_wq.h"
#define HINIC_CMDQ_CTXT_CURR_WQE_PAGE_PFN_SHIFT 0
#define HINIC_CMDQ_CTXT_EQ_ID_SHIFT 56
#define HINIC_CMDQ_CTXT_CEQ_ARM_SHIFT 61
#define HINIC_CMDQ_CTXT_CEQ_EN_SHIFT 62
#define HINIC_CMDQ_CTXT_WRAPPED_SHIFT 63
#define HINIC_CMDQ_CTXT_CURR_WQE_PAGE_PFN_MASK 0xFFFFFFFFFFFFF
#define HINIC_CMDQ_CTXT_EQ_ID_MASK 0x1F
#define HINIC_CMDQ_CTXT_CEQ_ARM_MASK 0x1
#define HINIC_CMDQ_CTXT_CEQ_EN_MASK 0x1
#define HINIC_CMDQ_CTXT_WRAPPED_MASK 0x1
#define HINIC_CMDQ_CTXT_PAGE_INFO_SET(val, member) \
(((u64)(val) & HINIC_CMDQ_CTXT_##member##_MASK) \
<< HINIC_CMDQ_CTXT_##member##_SHIFT)
#define HINIC_CMDQ_CTXT_PAGE_INFO_CLEAR(val, member) \
((val) & (~((u64)HINIC_CMDQ_CTXT_##member##_MASK \
<< HINIC_CMDQ_CTXT_##member##_SHIFT)))
#define HINIC_CMDQ_CTXT_WQ_BLOCK_PFN_SHIFT 0
#define HINIC_CMDQ_CTXT_CI_SHIFT 52
#define HINIC_CMDQ_CTXT_WQ_BLOCK_PFN_MASK 0xFFFFFFFFFFFFF
#define HINIC_CMDQ_CTXT_CI_MASK 0xFFF
#define HINIC_CMDQ_CTXT_BLOCK_INFO_SET(val, member) \
(((u64)(val) & HINIC_CMDQ_CTXT_##member##_MASK) \
<< HINIC_CMDQ_CTXT_##member##_SHIFT)
#define HINIC_CMDQ_CTXT_BLOCK_INFO_CLEAR(val, member) \
((val) & (~((u64)HINIC_CMDQ_CTXT_##member##_MASK \
<< HINIC_CMDQ_CTXT_##member##_SHIFT)))
#define HINIC_SAVED_DATA_ARM_SHIFT 31
#define HINIC_SAVED_DATA_ARM_MASK 0x1
#define HINIC_SAVED_DATA_SET(val, member) \
(((u32)(val) & HINIC_SAVED_DATA_##member##_MASK) \
<< HINIC_SAVED_DATA_##member##_SHIFT)
#define HINIC_SAVED_DATA_GET(val, member) \
(((val) >> HINIC_SAVED_DATA_##member##_SHIFT) \
& HINIC_SAVED_DATA_##member##_MASK)
#define HINIC_SAVED_DATA_CLEAR(val, member) \
((val) & (~(HINIC_SAVED_DATA_##member##_MASK \
<< HINIC_SAVED_DATA_##member##_SHIFT)))
#define HINIC_CMDQ_DB_INFO_HI_PROD_IDX_SHIFT 0
#define HINIC_CMDQ_DB_INFO_PATH_SHIFT 23
#define HINIC_CMDQ_DB_INFO_CMDQ_TYPE_SHIFT 24
#define HINIC_CMDQ_DB_INFO_DB_TYPE_SHIFT 27
#define HINIC_CMDQ_DB_INFO_HI_PROD_IDX_MASK 0xFF
#define HINIC_CMDQ_DB_INFO_PATH_MASK 0x1
#define HINIC_CMDQ_DB_INFO_CMDQ_TYPE_MASK 0x7
#define HINIC_CMDQ_DB_INFO_DB_TYPE_MASK 0x1F
#define HINIC_CMDQ_DB_INFO_SET(val, member) \
(((u32)(val) & HINIC_CMDQ_DB_INFO_##member##_MASK) \
<< HINIC_CMDQ_DB_INFO_##member##_SHIFT)
#define HINIC_CMDQ_BUF_SIZE 2048
#define HINIC_CMDQ_BUF_HW_RSVD 8
#define HINIC_CMDQ_MAX_DATA_SIZE (HINIC_CMDQ_BUF_SIZE - \
HINIC_CMDQ_BUF_HW_RSVD)
enum hinic_cmdq_type {
HINIC_CMDQ_SYNC,
HINIC_MAX_CMDQ_TYPES,
};
enum hinic_set_arm_qtype {
HINIC_SET_ARM_CMDQ,
};
enum hinic_cmd_ack_type {
HINIC_CMD_ACK_TYPE_CMDQ,
};
struct hinic_cmdq_buf {
void *buf;
dma_addr_t dma_addr;
size_t size;
};
struct hinic_cmdq_arm_bit {
u32 q_type;
u32 q_id;
};
struct hinic_cmdq_ctxt_info {
u64 curr_wqe_page_pfn;
u64 wq_block_pfn;
};
struct hinic_cmdq_ctxt {
u8 status;
u8 version;
u8 rsvd0[6];
u16 func_idx;
u8 cmdq_type;
u8 rsvd1[1];
u8 rsvd2[4];
struct hinic_cmdq_ctxt_info ctxt_info;
};
struct hinic_cmdq {
struct hinic_wq *wq;
enum hinic_cmdq_type cmdq_type;
int wrapped;
/* Lock for keeping the doorbell order */
spinlock_t cmdq_lock;
struct completion **done;
int **errcode;
/* doorbell area */
void __iomem *db_base;
};
struct hinic_cmdqs {
struct hinic_hwif *hwif;
struct dma_pool *cmdq_buf_pool;
struct hinic_wq *saved_wqs;
struct hinic_cmdq_pages cmdq_pages;
struct hinic_cmdq cmdq[HINIC_MAX_CMDQ_TYPES];
};
int hinic_alloc_cmdq_buf(struct hinic_cmdqs *cmdqs,
struct hinic_cmdq_buf *cmdq_buf);
void hinic_free_cmdq_buf(struct hinic_cmdqs *cmdqs,
struct hinic_cmdq_buf *cmdq_buf);
int hinic_cmdq_direct_resp(struct hinic_cmdqs *cmdqs,
enum hinic_mod_type mod, u8 cmd,
struct hinic_cmdq_buf *buf_in, u64 *out_param);
int hinic_set_arm_bit(struct hinic_cmdqs *cmdqs,
enum hinic_set_arm_qtype q_type, u32 q_id);
int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif,
void __iomem **db_area);
void hinic_free_cmdqs(struct hinic_cmdqs *cmdqs);
#endif
|