summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h
blob: 23f8d39eab68d46cd269a821a243f68ec0ccf010 (plain)
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