GNU Linux-libre 4.19.286-gnu1
[releases.git] / drivers / net / ethernet / huawei / hinic / hinic_hw_cmdq.h
1 /*
2  * Huawei HiNIC PCI Express Linux driver
3  * Copyright(c) 2017 Huawei Technologies Co., Ltd
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * for more details.
13  *
14  */
15
16 #ifndef HINIC_CMDQ_H
17 #define HINIC_CMDQ_H
18
19 #include <linux/types.h>
20 #include <linux/spinlock.h>
21 #include <linux/completion.h>
22 #include <linux/pci.h>
23
24 #include "hinic_hw_if.h"
25 #include "hinic_hw_wq.h"
26
27 #define HINIC_CMDQ_CTXT_CURR_WQE_PAGE_PFN_SHIFT         0
28 #define HINIC_CMDQ_CTXT_EQ_ID_SHIFT                     56
29 #define HINIC_CMDQ_CTXT_CEQ_ARM_SHIFT                   61
30 #define HINIC_CMDQ_CTXT_CEQ_EN_SHIFT                    62
31 #define HINIC_CMDQ_CTXT_WRAPPED_SHIFT                   63
32
33 #define HINIC_CMDQ_CTXT_CURR_WQE_PAGE_PFN_MASK          0xFFFFFFFFFFFFF
34 #define HINIC_CMDQ_CTXT_EQ_ID_MASK                      0x1F
35 #define HINIC_CMDQ_CTXT_CEQ_ARM_MASK                    0x1
36 #define HINIC_CMDQ_CTXT_CEQ_EN_MASK                     0x1
37 #define HINIC_CMDQ_CTXT_WRAPPED_MASK                    0x1
38
39 #define HINIC_CMDQ_CTXT_PAGE_INFO_SET(val, member)      \
40                         (((u64)(val) & HINIC_CMDQ_CTXT_##member##_MASK) \
41                          << HINIC_CMDQ_CTXT_##member##_SHIFT)
42
43 #define HINIC_CMDQ_CTXT_PAGE_INFO_CLEAR(val, member)    \
44                         ((val) & (~((u64)HINIC_CMDQ_CTXT_##member##_MASK \
45                          << HINIC_CMDQ_CTXT_##member##_SHIFT)))
46
47 #define HINIC_CMDQ_CTXT_WQ_BLOCK_PFN_SHIFT              0
48 #define HINIC_CMDQ_CTXT_CI_SHIFT                        52
49
50 #define HINIC_CMDQ_CTXT_WQ_BLOCK_PFN_MASK               0xFFFFFFFFFFFFF
51 #define HINIC_CMDQ_CTXT_CI_MASK                         0xFFF
52
53 #define HINIC_CMDQ_CTXT_BLOCK_INFO_SET(val, member)     \
54                         (((u64)(val) & HINIC_CMDQ_CTXT_##member##_MASK) \
55                          << HINIC_CMDQ_CTXT_##member##_SHIFT)
56
57 #define HINIC_CMDQ_CTXT_BLOCK_INFO_CLEAR(val, member)   \
58                         ((val) & (~((u64)HINIC_CMDQ_CTXT_##member##_MASK \
59                          << HINIC_CMDQ_CTXT_##member##_SHIFT)))
60
61 #define HINIC_SAVED_DATA_ARM_SHIFT                      31
62
63 #define HINIC_SAVED_DATA_ARM_MASK                       0x1
64
65 #define HINIC_SAVED_DATA_SET(val, member)               \
66                         (((u32)(val) & HINIC_SAVED_DATA_##member##_MASK) \
67                          << HINIC_SAVED_DATA_##member##_SHIFT)
68
69 #define HINIC_SAVED_DATA_GET(val, member)               \
70                         (((val) >> HINIC_SAVED_DATA_##member##_SHIFT) \
71                          & HINIC_SAVED_DATA_##member##_MASK)
72
73 #define HINIC_SAVED_DATA_CLEAR(val, member)             \
74                         ((val) & (~(HINIC_SAVED_DATA_##member##_MASK \
75                          << HINIC_SAVED_DATA_##member##_SHIFT)))
76
77 #define HINIC_CMDQ_DB_INFO_HI_PROD_IDX_SHIFT            0
78 #define HINIC_CMDQ_DB_INFO_PATH_SHIFT                   23
79 #define HINIC_CMDQ_DB_INFO_CMDQ_TYPE_SHIFT              24
80 #define HINIC_CMDQ_DB_INFO_DB_TYPE_SHIFT                27
81
82 #define HINIC_CMDQ_DB_INFO_HI_PROD_IDX_MASK             0xFF
83 #define HINIC_CMDQ_DB_INFO_PATH_MASK                    0x1
84 #define HINIC_CMDQ_DB_INFO_CMDQ_TYPE_MASK               0x7
85 #define HINIC_CMDQ_DB_INFO_DB_TYPE_MASK                 0x1F
86
87 #define HINIC_CMDQ_DB_INFO_SET(val, member)             \
88                         (((u32)(val) & HINIC_CMDQ_DB_INFO_##member##_MASK) \
89                          << HINIC_CMDQ_DB_INFO_##member##_SHIFT)
90
91 #define HINIC_CMDQ_BUF_SIZE             2048
92
93 #define HINIC_CMDQ_BUF_HW_RSVD          8
94 #define HINIC_CMDQ_MAX_DATA_SIZE        (HINIC_CMDQ_BUF_SIZE - \
95                                          HINIC_CMDQ_BUF_HW_RSVD)
96
97 enum hinic_cmdq_type {
98         HINIC_CMDQ_SYNC,
99
100         HINIC_MAX_CMDQ_TYPES,
101 };
102
103 enum hinic_set_arm_qtype {
104         HINIC_SET_ARM_CMDQ,
105 };
106
107 enum hinic_cmd_ack_type {
108         HINIC_CMD_ACK_TYPE_CMDQ,
109 };
110
111 struct hinic_cmdq_buf {
112         void            *buf;
113         dma_addr_t      dma_addr;
114         size_t          size;
115 };
116
117 struct hinic_cmdq_arm_bit {
118         u32     q_type;
119         u32     q_id;
120 };
121
122 struct hinic_cmdq_ctxt_info {
123         u64     curr_wqe_page_pfn;
124         u64     wq_block_pfn;
125 };
126
127 struct hinic_cmdq_ctxt {
128         u8      status;
129         u8      version;
130         u8      rsvd0[6];
131
132         u16     func_idx;
133         u8      cmdq_type;
134         u8      rsvd1[1];
135
136         u8      rsvd2[4];
137
138         struct hinic_cmdq_ctxt_info ctxt_info;
139 };
140
141 struct hinic_cmdq {
142         struct hinic_wq         *wq;
143
144         enum hinic_cmdq_type    cmdq_type;
145         int                     wrapped;
146
147         /* Lock for keeping the doorbell order */
148         spinlock_t              cmdq_lock;
149
150         struct completion       **done;
151         int                     **errcode;
152
153         /* doorbell area */
154         void __iomem            *db_base;
155 };
156
157 struct hinic_cmdqs {
158         struct hinic_hwif       *hwif;
159
160         struct dma_pool         *cmdq_buf_pool;
161
162         struct hinic_wq         *saved_wqs;
163
164         struct hinic_cmdq_pages cmdq_pages;
165
166         struct hinic_cmdq       cmdq[HINIC_MAX_CMDQ_TYPES];
167 };
168
169 int hinic_alloc_cmdq_buf(struct hinic_cmdqs *cmdqs,
170                          struct hinic_cmdq_buf *cmdq_buf);
171
172 void hinic_free_cmdq_buf(struct hinic_cmdqs *cmdqs,
173                          struct hinic_cmdq_buf *cmdq_buf);
174
175 int hinic_cmdq_direct_resp(struct hinic_cmdqs *cmdqs,
176                            enum hinic_mod_type mod, u8 cmd,
177                            struct hinic_cmdq_buf *buf_in, u64 *out_param);
178
179 int hinic_set_arm_bit(struct hinic_cmdqs *cmdqs,
180                       enum hinic_set_arm_qtype q_type, u32 q_id);
181
182 int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif,
183                      void __iomem **db_area);
184
185 void hinic_free_cmdqs(struct hinic_cmdqs *cmdqs);
186
187 #endif