1 | /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later */ |
2 | /* |
3 | * Copyright 2008 - 2015 Freescale Semiconductor Inc. |
4 | * Copyright 2020 NXP |
5 | */ |
6 | |
7 | #ifndef __FM_H |
8 | #define __FM_H |
9 | |
10 | #include <linux/io.h> |
11 | #include <linux/interrupt.h> |
12 | #include <linux/of_irq.h> |
13 | |
14 | /* FM Frame descriptor macros */ |
15 | /* Frame queue Context Override */ |
16 | #define FM_FD_CMD_FCO 0x80000000 |
17 | #define FM_FD_CMD_RPD 0x40000000 /* Read Prepended Data */ |
18 | #define FM_FD_CMD_UPD 0x20000000 /* Update Prepended Data */ |
19 | #define FM_FD_CMD_DTC 0x10000000 /* Do L4 Checksum */ |
20 | |
21 | /* TX-Port: Unsupported Format */ |
22 | #define FM_FD_ERR_UNSUPPORTED_FORMAT 0x04000000 |
23 | /* TX Port: Length Error */ |
24 | #define FM_FD_ERR_LENGTH 0x02000000 |
25 | #define FM_FD_ERR_DMA 0x01000000 /* DMA Data error */ |
26 | |
27 | /* IPR frame (not error) */ |
28 | #define FM_FD_IPR 0x00000001 |
29 | /* IPR non-consistent-sp */ |
30 | #define FM_FD_ERR_IPR_NCSP (0x00100000 | FM_FD_IPR) |
31 | /* IPR error */ |
32 | #define FM_FD_ERR_IPR (0x00200000 | FM_FD_IPR) |
33 | /* IPR timeout */ |
34 | #define FM_FD_ERR_IPR_TO (0x00300000 | FM_FD_IPR) |
35 | /* TX Port: Length Error */ |
36 | #define FM_FD_ERR_IPRE (FM_FD_ERR_IPR & ~FM_FD_IPR) |
37 | |
38 | /* Rx FIFO overflow, FCS error, code error, running disparity error |
39 | * (SGMII and TBI modes), FIFO parity error. PHY Sequence error, |
40 | * PHY error control character detected. |
41 | */ |
42 | #define FM_FD_ERR_PHYSICAL 0x00080000 |
43 | /* Frame too long OR Frame size exceeds max_length_frame */ |
44 | #define FM_FD_ERR_SIZE 0x00040000 |
45 | /* classification discard */ |
46 | #define FM_FD_ERR_CLS_DISCARD 0x00020000 |
47 | /* Extract Out of Frame */ |
48 | #define 0x00008000 |
49 | /* No Scheme Selected */ |
50 | #define FM_FD_ERR_NO_SCHEME 0x00004000 |
51 | /* Keysize Overflow */ |
52 | #define FM_FD_ERR_KEYSIZE_OVERFLOW 0x00002000 |
53 | /* Frame color is red */ |
54 | #define FM_FD_ERR_COLOR_RED 0x00000800 |
55 | /* Frame color is yellow */ |
56 | #define FM_FD_ERR_COLOR_YELLOW 0x00000400 |
57 | /* Parser Time out Exceed */ |
58 | #define FM_FD_ERR_PRS_TIMEOUT 0x00000080 |
59 | /* Invalid Soft Parser instruction */ |
60 | #define FM_FD_ERR_PRS_ILL_INSTRUCT 0x00000040 |
61 | /* Header error was identified during parsing */ |
62 | #define FM_FD_ERR_PRS_HDR_ERR 0x00000020 |
63 | /* Frame parsed beyind 256 first bytes */ |
64 | #define FM_FD_ERR_BLOCK_LIMIT_EXCEEDED 0x00000008 |
65 | |
66 | /* non Frame-Manager error */ |
67 | #define FM_FD_RX_STATUS_ERR_NON_FM 0x00400000 |
68 | |
69 | /* FMan driver defines */ |
70 | #define FMAN_BMI_FIFO_UNITS 0x100 |
71 | #define OFFSET_UNITS 16 |
72 | |
73 | /* BMan defines */ |
74 | #define BM_MAX_NUM_OF_POOLS 64 /* Buffers pools */ |
75 | #define FMAN_PORT_MAX_EXT_POOLS_NUM 8 /* External BM pools per Rx port */ |
76 | |
77 | struct fman; /* FMan data */ |
78 | |
79 | /* Enum for defining port types */ |
80 | enum fman_port_type { |
81 | FMAN_PORT_TYPE_TX = 0, /* TX Port */ |
82 | FMAN_PORT_TYPE_RX, /* RX Port */ |
83 | }; |
84 | |
85 | struct fman_rev_info { |
86 | u8 major; /* Major revision */ |
87 | u8 minor; /* Minor revision */ |
88 | }; |
89 | |
90 | enum fman_exceptions { |
91 | FMAN_EX_DMA_BUS_ERROR = 0, /* DMA bus error. */ |
92 | FMAN_EX_DMA_READ_ECC, /* Read Buffer ECC error */ |
93 | FMAN_EX_DMA_SYSTEM_WRITE_ECC, /* Write Buffer ECC err on sys side */ |
94 | FMAN_EX_DMA_FM_WRITE_ECC, /* Write Buffer ECC error on FM side */ |
95 | FMAN_EX_DMA_SINGLE_PORT_ECC, /* Single Port ECC error on FM side */ |
96 | FMAN_EX_FPM_STALL_ON_TASKS, /* Stall of tasks on FPM */ |
97 | FMAN_EX_FPM_SINGLE_ECC, /* Single ECC on FPM. */ |
98 | FMAN_EX_FPM_DOUBLE_ECC, /* Double ECC error on FPM ram access */ |
99 | FMAN_EX_QMI_SINGLE_ECC, /* Single ECC on QMI. */ |
100 | FMAN_EX_QMI_DOUBLE_ECC, /* Double bit ECC occurred on QMI */ |
101 | FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/* DeQ from unknown port id */ |
102 | FMAN_EX_BMI_LIST_RAM_ECC, /* Linked List RAM ECC error */ |
103 | FMAN_EX_BMI_STORAGE_PROFILE_ECC,/* storage profile */ |
104 | FMAN_EX_BMI_STATISTICS_RAM_ECC,/* Statistics RAM ECC Err Enable */ |
105 | FMAN_EX_BMI_DISPATCH_RAM_ECC, /* Dispatch RAM ECC Error Enable */ |
106 | FMAN_EX_IRAM_ECC, /* Double bit ECC occurred on IRAM */ |
107 | FMAN_EX_MURAM_ECC /* Double bit ECC occurred on MURAM */ |
108 | }; |
109 | |
110 | /* Parse results memory layout */ |
111 | struct fman_prs_result { |
112 | u8 lpid; /* Logical port id */ |
113 | u8 shimr; /* Shim header result */ |
114 | __be16 l2r; /* Layer 2 result */ |
115 | __be16 l3r; /* Layer 3 result */ |
116 | u8 l4r; /* Layer 4 result */ |
117 | u8 cplan; /* Classification plan id */ |
118 | __be16 nxthdr; /* Next Header */ |
119 | __be16 cksum; /* Running-sum */ |
120 | /* Flags&fragment-offset field of the last IP-header */ |
121 | __be16 flags_frag_off; |
122 | /* Routing type field of a IPV6 routing extension header */ |
123 | u8 route_type; |
124 | /* Routing Extension Header Present; last bit is IP valid */ |
125 | u8 rhp_ip_valid; |
126 | u8 shim_off[2]; /* Shim offset */ |
127 | u8 ip_pid_off; /* IP PID (last IP-proto) offset */ |
128 | u8 eth_off; /* ETH offset */ |
129 | u8 llc_snap_off; /* LLC_SNAP offset */ |
130 | u8 vlan_off[2]; /* VLAN offset */ |
131 | u8 etype_off; /* ETYPE offset */ |
132 | u8 pppoe_off; /* PPP offset */ |
133 | u8 mpls_off[2]; /* MPLS offset */ |
134 | u8 ip_off[2]; /* IP offset */ |
135 | u8 gre_off; /* GRE offset */ |
136 | u8 l4_off; /* Layer 4 offset */ |
137 | u8 nxthdr_off; /* Parser end point */ |
138 | }; |
139 | |
140 | /* A structure for defining buffer prefix area content. */ |
141 | struct fman_buffer_prefix_content { |
142 | /* Number of bytes to be left at the beginning of the external |
143 | * buffer; Note that the private-area will start from the base |
144 | * of the buffer address. |
145 | */ |
146 | u16 priv_data_size; |
147 | /* true to pass the parse result to/from the FM; |
148 | * User may use FM_PORT_GetBufferPrsResult() in |
149 | * order to get the parser-result from a buffer. |
150 | */ |
151 | bool pass_prs_result; |
152 | /* true to pass the timeStamp to/from the FM User */ |
153 | bool pass_time_stamp; |
154 | /* true to pass the KG hash result to/from the FM User may |
155 | * use FM_PORT_GetBufferHashResult() in order to get the |
156 | * parser-result from a buffer. |
157 | */ |
158 | bool pass_hash_result; |
159 | /* Add all other Internal-Context information: AD, |
160 | * hash-result, key, etc. |
161 | */ |
162 | u16 data_align; |
163 | }; |
164 | |
165 | /* A structure of information about each of the external |
166 | * buffer pools used by a port or storage-profile. |
167 | */ |
168 | struct fman_ext_pool_params { |
169 | u8 id; /* External buffer pool id */ |
170 | u16 size; /* External buffer pool buffer size */ |
171 | }; |
172 | |
173 | /* A structure for informing the driver about the external |
174 | * buffer pools allocated in the BM and used by a port or a |
175 | * storage-profile. |
176 | */ |
177 | struct fman_ext_pools { |
178 | u8 num_of_pools_used; /* Number of pools use by this port */ |
179 | struct fman_ext_pool_params ext_buf_pool[FMAN_PORT_MAX_EXT_POOLS_NUM]; |
180 | /* Parameters for each port */ |
181 | }; |
182 | |
183 | /* A structure for defining BM pool depletion criteria */ |
184 | struct fman_buf_pool_depletion { |
185 | /* select mode in which pause frames will be sent after a |
186 | * number of pools (all together!) are depleted |
187 | */ |
188 | bool pools_grp_mode_enable; |
189 | /* the number of depleted pools that will invoke pause |
190 | * frames transmission. |
191 | */ |
192 | u8 num_of_pools; |
193 | /* For each pool, true if it should be considered for |
194 | * depletion (Note - this pool must be used by this port!). |
195 | */ |
196 | bool pools_to_consider[BM_MAX_NUM_OF_POOLS]; |
197 | /* select mode in which pause frames will be sent |
198 | * after a single-pool is depleted; |
199 | */ |
200 | bool single_pool_mode_enable; |
201 | /* For each pool, true if it should be considered |
202 | * for depletion (Note - this pool must be used by this port!) |
203 | */ |
204 | bool pools_to_consider_for_single_mode[BM_MAX_NUM_OF_POOLS]; |
205 | }; |
206 | |
207 | /* Enum for inter-module interrupts registration */ |
208 | enum fman_event_modules { |
209 | FMAN_MOD_MAC = 0, /* MAC event */ |
210 | FMAN_MOD_FMAN_CTRL, /* FMAN Controller */ |
211 | FMAN_MOD_DUMMY_LAST |
212 | }; |
213 | |
214 | /* Enum for interrupts types */ |
215 | enum fman_intr_type { |
216 | FMAN_INTR_TYPE_ERR, |
217 | FMAN_INTR_TYPE_NORMAL |
218 | }; |
219 | |
220 | /* Enum for inter-module interrupts registration */ |
221 | enum fman_inter_module_event { |
222 | FMAN_EV_ERR_MAC0 = 0, /* MAC 0 error event */ |
223 | FMAN_EV_ERR_MAC1, /* MAC 1 error event */ |
224 | FMAN_EV_ERR_MAC2, /* MAC 2 error event */ |
225 | FMAN_EV_ERR_MAC3, /* MAC 3 error event */ |
226 | FMAN_EV_ERR_MAC4, /* MAC 4 error event */ |
227 | FMAN_EV_ERR_MAC5, /* MAC 5 error event */ |
228 | FMAN_EV_ERR_MAC6, /* MAC 6 error event */ |
229 | FMAN_EV_ERR_MAC7, /* MAC 7 error event */ |
230 | FMAN_EV_ERR_MAC8, /* MAC 8 error event */ |
231 | FMAN_EV_ERR_MAC9, /* MAC 9 error event */ |
232 | FMAN_EV_MAC0, /* MAC 0 event (Magic packet detection) */ |
233 | FMAN_EV_MAC1, /* MAC 1 event (Magic packet detection) */ |
234 | FMAN_EV_MAC2, /* MAC 2 (Magic packet detection) */ |
235 | FMAN_EV_MAC3, /* MAC 3 (Magic packet detection) */ |
236 | FMAN_EV_MAC4, /* MAC 4 (Magic packet detection) */ |
237 | FMAN_EV_MAC5, /* MAC 5 (Magic packet detection) */ |
238 | FMAN_EV_MAC6, /* MAC 6 (Magic packet detection) */ |
239 | FMAN_EV_MAC7, /* MAC 7 (Magic packet detection) */ |
240 | FMAN_EV_MAC8, /* MAC 8 event (Magic packet detection) */ |
241 | FMAN_EV_MAC9, /* MAC 9 event (Magic packet detection) */ |
242 | FMAN_EV_FMAN_CTRL_0, /* Fman controller event 0 */ |
243 | FMAN_EV_FMAN_CTRL_1, /* Fman controller event 1 */ |
244 | FMAN_EV_FMAN_CTRL_2, /* Fman controller event 2 */ |
245 | FMAN_EV_FMAN_CTRL_3, /* Fman controller event 3 */ |
246 | FMAN_EV_CNT |
247 | }; |
248 | |
249 | struct fman_intr_src { |
250 | void (*isr_cb)(void *src_arg); |
251 | void *src_handle; |
252 | }; |
253 | |
254 | /** fman_exceptions_cb |
255 | * fman - Pointer to FMan |
256 | * exception - The exception. |
257 | * |
258 | * Exceptions user callback routine, will be called upon an exception |
259 | * passing the exception identification. |
260 | * |
261 | * Return: irq status |
262 | */ |
263 | typedef irqreturn_t (fman_exceptions_cb)(struct fman *fman, |
264 | enum fman_exceptions exception); |
265 | /** fman_bus_error_cb |
266 | * fman - Pointer to FMan |
267 | * port_id - Port id |
268 | * addr - Address that caused the error |
269 | * tnum - Owner of error |
270 | * liodn - Logical IO device number |
271 | * |
272 | * Bus error user callback routine, will be called upon bus error, |
273 | * passing parameters describing the errors and the owner. |
274 | * |
275 | * Return: IRQ status |
276 | */ |
277 | typedef irqreturn_t (fman_bus_error_cb)(struct fman *fman, u8 port_id, |
278 | u64 addr, u8 tnum, u16 liodn); |
279 | |
280 | /* Structure that holds information received from device tree */ |
281 | struct fman_dts_params { |
282 | void __iomem *base_addr; /* FMan virtual address */ |
283 | struct resource *res; /* FMan memory resource */ |
284 | u8 id; /* FMan ID */ |
285 | |
286 | int err_irq; /* FMan Error IRQ */ |
287 | |
288 | u16 clk_freq; /* FMan clock freq (In Mhz) */ |
289 | |
290 | u32 qman_channel_base; /* QMan channels base */ |
291 | u32 num_of_qman_channels; /* Number of QMan channels */ |
292 | |
293 | struct resource muram_res; /* MURAM resource */ |
294 | }; |
295 | |
296 | struct fman { |
297 | struct device *dev; |
298 | void __iomem *base_addr; |
299 | struct fman_intr_src intr_mng[FMAN_EV_CNT]; |
300 | |
301 | struct fman_fpm_regs __iomem *fpm_regs; |
302 | struct fman_bmi_regs __iomem *bmi_regs; |
303 | struct fman_qmi_regs __iomem *qmi_regs; |
304 | struct fman_dma_regs __iomem *dma_regs; |
305 | struct fman_hwp_regs __iomem *hwp_regs; |
306 | struct fman_kg_regs __iomem *kg_regs; |
307 | fman_exceptions_cb *exception_cb; |
308 | fman_bus_error_cb *bus_error_cb; |
309 | /* Spinlock for FMan use */ |
310 | spinlock_t spinlock; |
311 | struct fman_state_struct *state; |
312 | |
313 | struct fman_cfg *cfg; |
314 | struct muram_info *muram; |
315 | struct fman_keygen *keygen; |
316 | /* cam section in muram */ |
317 | unsigned long cam_offset; |
318 | size_t cam_size; |
319 | /* Fifo in MURAM */ |
320 | unsigned long fifo_offset; |
321 | size_t fifo_size; |
322 | |
323 | u32 liodn_base[64]; |
324 | u32 liodn_offset[64]; |
325 | |
326 | struct fman_dts_params dts_params; |
327 | }; |
328 | |
329 | /* Structure for port-FM communication during fman_port_init. */ |
330 | struct fman_port_init_params { |
331 | u8 port_id; /* port Id */ |
332 | enum fman_port_type port_type; /* Port type */ |
333 | u16 port_speed; /* Port speed */ |
334 | u16 liodn_offset; /* Port's requested resource */ |
335 | u8 num_of_tasks; /* Port's requested resource */ |
336 | u8 ; /* Port's requested resource */ |
337 | u8 num_of_open_dmas; /* Port's requested resource */ |
338 | u8 ; /* Port's requested resource */ |
339 | u32 size_of_fifo; /* Port's requested resource */ |
340 | u32 ; /* Port's requested resource */ |
341 | u8 deq_pipeline_depth; /* Port's requested resource */ |
342 | u16 max_frame_length; /* Port's max frame length. */ |
343 | u16 liodn_base; |
344 | /* LIODN base for this port, to be used together with LIODN offset. */ |
345 | }; |
346 | |
347 | void fman_get_revision(struct fman *fman, struct fman_rev_info *rev_info); |
348 | |
349 | void fman_register_intr(struct fman *fman, enum fman_event_modules mod, |
350 | u8 mod_id, enum fman_intr_type intr_type, |
351 | void (*f_isr)(void *h_src_arg), void *h_src_arg); |
352 | |
353 | void fman_unregister_intr(struct fman *fman, enum fman_event_modules mod, |
354 | u8 mod_id, enum fman_intr_type intr_type); |
355 | |
356 | int fman_set_port_params(struct fman *fman, |
357 | struct fman_port_init_params *port_params); |
358 | |
359 | int fman_reset_mac(struct fman *fman, u8 mac_id); |
360 | |
361 | u16 fman_get_clock_freq(struct fman *fman); |
362 | |
363 | u32 fman_get_bmi_max_fifo_size(struct fman *fman); |
364 | |
365 | int fman_set_mac_max_frame(struct fman *fman, u8 mac_id, u16 mfl); |
366 | |
367 | u32 fman_get_qman_channel_id(struct fman *fman, u32 port_id); |
368 | |
369 | struct resource *fman_get_mem_region(struct fman *fman); |
370 | |
371 | u16 fman_get_max_frm(void); |
372 | |
373 | int (void); |
374 | |
375 | #ifdef CONFIG_DPAA_ERRATUM_A050385 |
376 | bool fman_has_errata_a050385(void); |
377 | #endif |
378 | |
379 | struct fman *fman_bind(struct device *dev); |
380 | |
381 | #endif /* __FM_H */ |
382 | |