1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * FUJITSU Extended Socket Network Device driver |
4 | * Copyright (c) 2015 FUJITSU LIMITED |
5 | */ |
6 | |
7 | #ifndef FJES_HW_H_ |
8 | #define FJES_HW_H_ |
9 | |
10 | #include <linux/netdevice.h> |
11 | #include <linux/if_vlan.h> |
12 | #include <linux/vmalloc.h> |
13 | |
14 | #include "fjes_regs.h" |
15 | |
16 | struct fjes_hw; |
17 | |
18 | #define EP_BUFFER_SUPPORT_VLAN_MAX 4 |
19 | #define EP_BUFFER_INFO_SIZE 4096 |
20 | |
21 | #define FJES_DEBUG_PAGE_SIZE 4096 |
22 | #define FJES_DEBUG_BUFFER_SIZE (16 * FJES_DEBUG_PAGE_SIZE) |
23 | |
24 | #define FJES_DEVICE_RESET_TIMEOUT ((17 + 1) * 3 * 8) /* sec */ |
25 | #define FJES_COMMAND_REQ_TIMEOUT ((5 + 1) * 3 * 8) /* sec */ |
26 | #define FJES_COMMAND_REQ_BUFF_TIMEOUT (60 * 3) /* sec */ |
27 | #define FJES_COMMAND_EPSTOP_WAIT_TIMEOUT (1) /* sec */ |
28 | |
29 | #define FJES_CMD_REQ_ERR_INFO_PARAM (0x0001) |
30 | #define FJES_CMD_REQ_ERR_INFO_STATUS (0x0002) |
31 | |
32 | #define FJES_CMD_REQ_RES_CODE_NORMAL (0) |
33 | #define FJES_CMD_REQ_RES_CODE_BUSY (1) |
34 | |
35 | #define FJES_ZONING_STATUS_DISABLE (0x00) |
36 | #define FJES_ZONING_STATUS_ENABLE (0x01) |
37 | #define FJES_ZONING_STATUS_INVALID (0xFF) |
38 | |
39 | #define FJES_ZONING_ZONE_TYPE_NONE (0xFF) |
40 | |
41 | #define FJES_TX_DELAY_SEND_NONE (0) |
42 | #define FJES_TX_DELAY_SEND_PENDING (1) |
43 | |
44 | #define FJES_RX_STOP_REQ_NONE (0x0) |
45 | #define FJES_RX_STOP_REQ_DONE (0x1) |
46 | #define FJES_RX_STOP_REQ_REQUEST (0x2) |
47 | #define FJES_RX_POLL_WORK (0x4) |
48 | #define FJES_RX_MTU_CHANGING_DONE (0x8) |
49 | |
50 | #define EP_BUFFER_SIZE \ |
51 | (((sizeof(union ep_buffer_info) + (128 * (64 * 1024))) \ |
52 | / EP_BUFFER_INFO_SIZE) * EP_BUFFER_INFO_SIZE) |
53 | |
54 | #define EP_RING_NUM(buffer_size, frame_size) \ |
55 | (u32)((buffer_size) / (frame_size)) |
56 | #define EP_RING_INDEX(_num, _max) (((_num) + (_max)) % (_max)) |
57 | #define EP_RING_INDEX_INC(_num, _max) \ |
58 | ((_num) = EP_RING_INDEX((_num) + 1, (_max))) |
59 | #define EP_RING_FULL(_head, _tail, _max) \ |
60 | (0 == EP_RING_INDEX(((_tail) - (_head)), (_max))) |
61 | #define EP_RING_EMPTY(_head, _tail, _max) \ |
62 | (1 == EP_RING_INDEX(((_tail) - (_head)), (_max))) |
63 | |
64 | #define FJES_MTU_TO_BUFFER_SIZE(mtu) \ |
65 | (ETH_HLEN + VLAN_HLEN + (mtu) + ETH_FCS_LEN) |
66 | #define FJES_MTU_TO_FRAME_SIZE(mtu) \ |
67 | (sizeof(struct esmem_frame) + FJES_MTU_TO_BUFFER_SIZE(mtu)) |
68 | #define FJES_MTU_DEFINE(size) \ |
69 | ((size) - sizeof(struct esmem_frame) - \ |
70 | (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN)) |
71 | |
72 | #define FJES_DEV_COMMAND_INFO_REQ_LEN (4) |
73 | #define FJES_DEV_COMMAND_INFO_RES_LEN(epnum) (8 + 2 * (epnum)) |
74 | #define FJES_DEV_COMMAND_SHARE_BUFFER_REQ_LEN(txb, rxb) \ |
75 | (24 + (8 * ((txb) / EP_BUFFER_INFO_SIZE + (rxb) / EP_BUFFER_INFO_SIZE))) |
76 | #define FJES_DEV_COMMAND_SHARE_BUFFER_RES_LEN (8) |
77 | #define FJES_DEV_COMMAND_UNSHARE_BUFFER_REQ_LEN (8) |
78 | #define FJES_DEV_COMMAND_UNSHARE_BUFFER_RES_LEN (8) |
79 | |
80 | #define FJES_DEV_REQ_BUF_SIZE(maxep) \ |
81 | FJES_DEV_COMMAND_SHARE_BUFFER_REQ_LEN(EP_BUFFER_SIZE, EP_BUFFER_SIZE) |
82 | #define FJES_DEV_RES_BUF_SIZE(maxep) \ |
83 | FJES_DEV_COMMAND_INFO_RES_LEN(maxep) |
84 | |
85 | #define FJES_DEV_COMMAND_START_DBG_REQ_LEN(byte) \ |
86 | (16 + (8 * (byte) / FJES_DEBUG_PAGE_SIZE)) |
87 | #define FJES_DEV_COMMAND_START_DBG_RES_LEN (8) |
88 | #define FJES_DEV_COMMAND_STOP_DBG_REQ_LEN (4) |
89 | #define FJES_DEV_COMMAND_STOP_DBG_RES_LEN (8) |
90 | |
91 | /* Frame & MTU */ |
92 | struct esmem_frame { |
93 | __le32 frame_size; |
94 | u8 frame_data[]; |
95 | }; |
96 | |
97 | /* EP partner status */ |
98 | enum ep_partner_status { |
99 | EP_PARTNER_UNSHARE, |
100 | EP_PARTNER_SHARED, |
101 | EP_PARTNER_WAITING, |
102 | EP_PARTNER_COMPLETE, |
103 | EP_PARTNER_STATUS_MAX, |
104 | }; |
105 | |
106 | /* shared status region */ |
107 | struct fjes_device_shared_info { |
108 | int epnum; |
109 | u8 ep_status[]; |
110 | }; |
111 | |
112 | /* structures for command control request data*/ |
113 | union fjes_device_command_req { |
114 | struct { |
115 | __le32 length; |
116 | } info; |
117 | struct { |
118 | __le32 length; |
119 | __le32 epid; |
120 | __le64 buffer[]; |
121 | } share_buffer; |
122 | struct { |
123 | __le32 length; |
124 | __le32 epid; |
125 | } unshare_buffer; |
126 | struct { |
127 | __le32 length; |
128 | __le32 mode; |
129 | __le64 buffer_len; |
130 | __le64 buffer[]; |
131 | } start_trace; |
132 | struct { |
133 | __le32 length; |
134 | } stop_trace; |
135 | }; |
136 | |
137 | /* structures for command control response data */ |
138 | union fjes_device_command_res { |
139 | struct { |
140 | __le32 length; |
141 | __le32 code; |
142 | struct { |
143 | u8 es_status; |
144 | u8 zone; |
145 | } info[]; |
146 | } info; |
147 | struct { |
148 | __le32 length; |
149 | __le32 code; |
150 | } share_buffer; |
151 | struct { |
152 | __le32 length; |
153 | __le32 code; |
154 | } unshare_buffer; |
155 | struct { |
156 | __le32 length; |
157 | __le32 code; |
158 | } start_trace; |
159 | struct { |
160 | __le32 length; |
161 | __le32 code; |
162 | } stop_trace; |
163 | }; |
164 | |
165 | /* request command type */ |
166 | enum fjes_dev_command_request_type { |
167 | FJES_CMD_REQ_INFO = 0x0001, |
168 | FJES_CMD_REQ_SHARE_BUFFER = 0x0002, |
169 | FJES_CMD_REQ_UNSHARE_BUFFER = 0x0004, |
170 | FJES_CMD_REQ_START_DEBUG = 0x0100, |
171 | FJES_CMD_REQ_STOP_DEBUG = 0x0200, |
172 | }; |
173 | |
174 | /* parameter for command control */ |
175 | struct fjes_device_command_param { |
176 | u32 req_len; |
177 | phys_addr_t req_start; |
178 | u32 res_len; |
179 | phys_addr_t res_start; |
180 | phys_addr_t share_start; |
181 | }; |
182 | |
183 | /* error code for command control */ |
184 | enum fjes_dev_command_response_e { |
185 | FJES_CMD_STATUS_UNKNOWN, |
186 | FJES_CMD_STATUS_NORMAL, |
187 | FJES_CMD_STATUS_TIMEOUT, |
188 | FJES_CMD_STATUS_ERROR_PARAM, |
189 | FJES_CMD_STATUS_ERROR_STATUS, |
190 | }; |
191 | |
192 | /* EP buffer information */ |
193 | union ep_buffer_info { |
194 | u8 raw[EP_BUFFER_INFO_SIZE]; |
195 | |
196 | struct _ep_buffer_info_common_t { |
197 | u32 version; |
198 | } common; |
199 | |
200 | struct _ep_buffer_info_v1_t { |
201 | u32 version; |
202 | u32 info_size; |
203 | |
204 | u32 buffer_size; |
205 | u16 count_max; |
206 | |
207 | u16 _rsv_1; |
208 | |
209 | u32 frame_max; |
210 | u8 mac_addr[ETH_ALEN]; |
211 | |
212 | u16 _rsv_2; |
213 | u32 _rsv_3; |
214 | |
215 | u16 tx_status; |
216 | u16 rx_status; |
217 | |
218 | u32 head; |
219 | u32 tail; |
220 | |
221 | u16 vlan_id[EP_BUFFER_SUPPORT_VLAN_MAX]; |
222 | |
223 | } v1i; |
224 | |
225 | }; |
226 | |
227 | /* statistics of EP */ |
228 | struct fjes_drv_ep_stats { |
229 | u64 com_regist_buf_exec; |
230 | u64 com_unregist_buf_exec; |
231 | u64 send_intr_rx; |
232 | u64 send_intr_unshare; |
233 | u64 send_intr_zoneupdate; |
234 | u64 recv_intr_rx; |
235 | u64 recv_intr_unshare; |
236 | u64 recv_intr_stop; |
237 | u64 recv_intr_zoneupdate; |
238 | u64 tx_buffer_full; |
239 | u64 tx_dropped_not_shared; |
240 | u64 tx_dropped_ver_mismatch; |
241 | u64 tx_dropped_buf_size_mismatch; |
242 | u64 tx_dropped_vlanid_mismatch; |
243 | }; |
244 | |
245 | /* buffer pair for Extended Partition */ |
246 | struct ep_share_mem_info { |
247 | struct epbuf_handler { |
248 | void *buffer; |
249 | size_t size; |
250 | union ep_buffer_info *info; |
251 | u8 *ring; |
252 | } tx, rx; |
253 | |
254 | struct rtnl_link_stats64 net_stats; |
255 | struct fjes_drv_ep_stats ep_stats; |
256 | |
257 | u16 tx_status_work; |
258 | |
259 | u8 es_status; |
260 | u8 zone; |
261 | }; |
262 | |
263 | struct es_device_trace { |
264 | u32 record_num; |
265 | u32 current_record; |
266 | u32 status_flag; |
267 | u32 _rsv; |
268 | |
269 | struct { |
270 | u16 epid; |
271 | u16 dir_offset; |
272 | u32 data; |
273 | u64 tsc; |
274 | } record[]; |
275 | }; |
276 | |
277 | struct fjes_hw_info { |
278 | struct fjes_device_shared_info *share; |
279 | union fjes_device_command_req *req_buf; |
280 | u64 req_buf_size; |
281 | union fjes_device_command_res *res_buf; |
282 | u64 res_buf_size; |
283 | |
284 | int *my_epid; |
285 | int *max_epid; |
286 | |
287 | struct es_device_trace *trace; |
288 | u64 trace_size; |
289 | |
290 | struct mutex lock; /* buffer lock*/ |
291 | |
292 | unsigned long buffer_share_bit; |
293 | unsigned long buffer_unshare_reserve_bit; |
294 | }; |
295 | |
296 | struct fjes_hw { |
297 | void *back; |
298 | |
299 | unsigned long txrx_stop_req_bit; |
300 | unsigned long epstop_req_bit; |
301 | struct work_struct update_zone_task; |
302 | struct work_struct epstop_task; |
303 | |
304 | int my_epid; |
305 | int max_epid; |
306 | |
307 | struct ep_share_mem_info *ep_shm_info; |
308 | |
309 | struct fjes_hw_resource { |
310 | u64 start; |
311 | u64 size; |
312 | int irq; |
313 | } hw_res; |
314 | |
315 | u8 *base; |
316 | |
317 | struct fjes_hw_info hw_info; |
318 | |
319 | spinlock_t rx_status_lock; /* spinlock for rx_status */ |
320 | |
321 | u32 debug_mode; |
322 | }; |
323 | |
324 | int fjes_hw_init(struct fjes_hw *); |
325 | void fjes_hw_exit(struct fjes_hw *); |
326 | int fjes_hw_reset(struct fjes_hw *); |
327 | int fjes_hw_request_info(struct fjes_hw *); |
328 | int fjes_hw_register_buff_addr(struct fjes_hw *, int, |
329 | struct ep_share_mem_info *); |
330 | int fjes_hw_unregister_buff_addr(struct fjes_hw *, int); |
331 | void fjes_hw_init_command_registers(struct fjes_hw *, |
332 | struct fjes_device_command_param *); |
333 | void fjes_hw_setup_epbuf(struct epbuf_handler *, const u8 *, u32); |
334 | int fjes_hw_raise_interrupt(struct fjes_hw *, int, enum REG_ICTL_MASK); |
335 | void fjes_hw_set_irqmask(struct fjes_hw *, enum REG_ICTL_MASK, bool); |
336 | u32 fjes_hw_capture_interrupt_status(struct fjes_hw *); |
337 | void fjes_hw_raise_epstop(struct fjes_hw *); |
338 | int fjes_hw_wait_epstop(struct fjes_hw *); |
339 | enum ep_partner_status |
340 | fjes_hw_get_partner_ep_status(struct fjes_hw *, int); |
341 | |
342 | bool fjes_hw_epid_is_same_zone(struct fjes_hw *, int); |
343 | int fjes_hw_epid_is_shared(struct fjes_device_shared_info *, int); |
344 | bool fjes_hw_check_epbuf_version(struct epbuf_handler *, u32); |
345 | bool fjes_hw_check_mtu(struct epbuf_handler *, u32); |
346 | bool fjes_hw_check_vlan_id(struct epbuf_handler *, u16); |
347 | bool fjes_hw_set_vlan_id(struct epbuf_handler *, u16); |
348 | void fjes_hw_del_vlan_id(struct epbuf_handler *, u16); |
349 | bool fjes_hw_epbuf_rx_is_empty(struct epbuf_handler *); |
350 | void *fjes_hw_epbuf_rx_curpkt_get_addr(struct epbuf_handler *, size_t *); |
351 | void fjes_hw_epbuf_rx_curpkt_drop(struct epbuf_handler *); |
352 | int fjes_hw_epbuf_tx_pkt_send(struct epbuf_handler *, void *, size_t); |
353 | |
354 | int fjes_hw_start_debug(struct fjes_hw *); |
355 | int fjes_hw_stop_debug(struct fjes_hw *); |
356 | #endif /* FJES_HW_H_ */ |
357 | |