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
|
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Huawei HiNIC PCI Express Linux driver
* Copyright(c) 2017 Huawei Technologies Co., Ltd
*/
#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
|