1/*
2 * Copyright 2008-2012 Freescale Semiconductor Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *     * Redistributions of source code must retain the above copyright
7 *       notice, this list of conditions and the following disclaimer.
8 *     * Redistributions in binary form must reproduce the above copyright
9 *       notice, this list of conditions and the following disclaimer in the
10 *       documentation and/or other materials provided with the distribution.
11 *     * Neither the name of Freescale Semiconductor nor the
12 *       names of its contributors may be used to endorse or promote products
13 *       derived from this software without specific prior written permission.
14 *
15 *
16 * ALTERNATIVELY, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL") as published by the Free Software
18 * Foundation, either version 2 of that License or (at your option) any
19 * later version.
20 *
21 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#ifndef __FSL_FMAN_KG_H
34#define __FSL_FMAN_KG_H
35
36#include "common/general.h"
37
38#define FM_KG_NUM_OF_GENERIC_REGS	8 /**< Num of generic KeyGen regs */
39#define FMAN_MAX_NUM_OF_HW_PORTS	64
40/**< Total num of masks allowed on KG extractions */
41#define FM_KG_EXTRACT_MASKS_NUM		4
42#define FM_KG_NUM_CLS_PLAN_ENTR		8 /**< Num of class. plan regs */
43#define FM_KG_CLS_PLAN_GRPS_NUM		32 /**< Max num of class. groups */
44
45struct fman_kg_regs {
46	uint32_t fmkg_gcr;
47	uint32_t res004;
48	uint32_t res008;
49	uint32_t fmkg_eer;
50	uint32_t fmkg_eeer;
51	uint32_t res014;
52	uint32_t res018;
53	uint32_t fmkg_seer;
54	uint32_t fmkg_seeer;
55	uint32_t fmkg_gsr;
56	uint32_t fmkg_tpc;
57	uint32_t fmkg_serc;
58	uint32_t res030[4];
59	uint32_t fmkg_fdor;
60	uint32_t fmkg_gdv0r;
61	uint32_t fmkg_gdv1r;
62	uint32_t res04c[6];
63	uint32_t fmkg_feer;
64	uint32_t res068[38];
65	uint32_t fmkg_indirect[63];
66	uint32_t fmkg_ar;
67};
68
69struct fman_kg_scheme_regs {
70	uint32_t kgse_mode; /**< MODE */
71	uint32_t kgse_ekfc; /**< Extract Known Fields Command */
72	uint32_t kgse_ekdv; /**< Extract Known Default Value */
73	uint32_t kgse_bmch; /**< Bit Mask Command High */
74	uint32_t kgse_bmcl; /**< Bit Mask Command Low */
75	uint32_t kgse_fqb; /**< Frame Queue Base */
76	uint32_t kgse_hc; /**< Hash Command */
77	uint32_t kgse_ppc; /**< Policer Profile Command */
78	uint32_t kgse_gec[FM_KG_NUM_OF_GENERIC_REGS];
79				/**< Generic Extract Command */
80	uint32_t kgse_spc; /**< KeyGen Scheme Entry Statistic Packet Counter */
81	uint32_t kgse_dv0; /**< KeyGen Scheme Entry Default Value 0 */
82	uint32_t kgse_dv1; /**< KeyGen Scheme Entry Default Value 1 */
83	uint32_t kgse_ccbs; /**< KeyGen Scheme Entry Coarse Classification Bit*/
84	uint32_t kgse_mv; /**< KeyGen Scheme Entry Match vector */
85	uint32_t kgse_om; /**< KeyGen Scheme Entry Operation Mode bits */
86	uint32_t kgse_vsp; /**< KeyGen Scheme Entry Virtual Storage Profile */
87};
88
89struct fman_kg_pe_regs{
90	uint32_t fmkg_pe_sp;
91	uint32_t fmkg_pe_cpp;
92};
93
94struct fman_kg_cp_regs {
95	uint32_t kgcpe[FM_KG_NUM_CLS_PLAN_ENTR];
96};
97
98
99#define FM_KG_KGAR_GO				0x80000000
100#define FM_KG_KGAR_READ				0x40000000
101#define FM_KG_KGAR_WRITE			0x00000000
102#define FM_KG_KGAR_SEL_SCHEME_ENTRY		0x00000000
103#define FM_KG_KGAR_SCM_WSEL_UPDATE_CNT		0x00008000
104
105#define KG_SCH_PP_SHIFT_HIGH			0x80000000
106#define KG_SCH_PP_NO_GEN			0x10000000
107#define KG_SCH_PP_SHIFT_LOW			0x0000F000
108#define KG_SCH_MODE_NIA_PLCR			0x40000000
109#define KG_SCH_GEN_EXTRACT_TYPE			0x00008000
110#define KG_SCH_BITMASK_MASK			0x000000FF
111#define KG_SCH_GEN_VALID			0x80000000
112#define KG_SCH_GEN_MASK				0x00FF0000
113#define FM_PCD_KG_KGAR_ERR			0x20000000
114#define FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY	0x01000000
115#define FM_PCD_KG_KGAR_SEL_PORT_ENTRY		0x02000000
116#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP		0x00008000
117#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP	0x00004000
118#define FM_PCD_KG_KGAR_WSEL_MASK		0x0000FF00
119#define KG_SCH_HASH_CONFIG_NO_FQID		0x80000000
120#define KG_SCH_HASH_CONFIG_SYM			0x40000000
121
122#define FM_EX_KG_DOUBLE_ECC			0x80000000
123#define FM_EX_KG_KEYSIZE_OVERFLOW		0x40000000
124
125/* ECC capture register */
126#define KG_FMKG_SERC_CAP			0x80000000
127#define KG_FMKG_SERC_CET			0x40000000
128#define KG_FMKG_SERC_CNT_MSK			0x00FF0000
129#define KG_FMKG_SERC_CNT_SHIFT			16
130#define KG_FMKG_SERC_ADDR_MSK			0x000003FF
131
132/* Masks */
133#define FM_KG_KGGCR_EN				0x80000000
134#define KG_SCH_GEN_VALID			0x80000000
135#define KG_SCH_GEN_EXTRACT_TYPE			0x00008000
136#define KG_ERR_TYPE_DOUBLE			0x40000000
137#define KG_ERR_ADDR_MASK			0x00000FFF
138#define KG_SCH_MODE_EN				0x80000000
139
140/* shifts */
141#define FM_KG_KGAR_NUM_SHIFT			16
142#define FM_KG_PE_CPP_MASK_SHIFT			16
143#define FM_KG_KGAR_WSEL_SHIFT			8
144
145#define FM_KG_SCH_GEN_HT_INVALID		0
146
147#define FM_KG_MASK_SEL_GEN_BASE			0x20
148
149#define KG_GET_MASK_SEL_SHIFT(shift, i)	\
150switch (i)				\
151{					\
152	case 0: (shift) = 26; break;	\
153	case 1: (shift) = 20; break;	\
154	case 2: (shift) = 10; break;	\
155	case 3: (shift) = 4; break;	\
156	default: (shift) = 0;		\
157}
158
159#define KG_GET_MASK_OFFSET_SHIFT(shift, i)	\
160switch (i)				\
161{					\
162	case 0: (shift) = 16; break;	\
163	case 1: (shift) = 0; break;	\
164	case 2: (shift) = 28; break;	\
165	case 3: (shift) = 24; break;	\
166	default: (shift) = 0;		\
167}
168
169#define KG_GET_MASK_SHIFT(shift, i)	\
170switch (i)				\
171{					\
172	case 0: shift = 24; break;	\
173	case 1: shift = 16; break;	\
174	case 2: shift = 8;  break;	\
175	case 3: shift = 0;  break;	\
176	default: shift = 0;		\
177}
178
179/* Port entry CPP register */
180#define FMAN_KG_PE_CPP_MASK_SHIFT	16
181
182/* Scheme registers */
183#define FMAN_KG_SCH_MODE_EN		0x80000000
184#define FMAN_KG_SCH_MODE_NIA_PLCR	0x40000000
185#define FMAN_KG_SCH_MODE_CCOBASE_SHIFT	24
186
187#define FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT	30
188#define FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT	28
189#define FMAN_KG_SCH_DEF_ETYPE_SHIFT	26
190#define FMAN_KG_SCH_DEF_PPP_SID_SHIFT	24
191#define FMAN_KG_SCH_DEF_PPP_PID_SHIFT	22
192#define FMAN_KG_SCH_DEF_MPLS_SHIFT	20
193#define FMAN_KG_SCH_DEF_IP_ADDR_SHIFT	18
194#define FMAN_KG_SCH_DEF_PTYPE_SHIFT	16
195#define FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT	14
196#define FMAN_KG_SCH_DEF_IPv6_FL_SHIFT	12
197#define FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT	10
198#define FMAN_KG_SCH_DEF_L4_PORT_SHIFT	8
199#define FMAN_KG_SCH_DEF_TCP_FLG_SHIFT	6
200
201#define FMAN_KG_SCH_GEN_VALID		0x80000000
202#define FMAN_KG_SCH_GEN_SIZE_MAX	16
203#define FMAN_KG_SCH_GEN_OR		0x00008000
204
205#define FMAN_KG_SCH_GEN_DEF_SHIFT	29
206#define FMAN_KG_SCH_GEN_SIZE_SHIFT	24
207#define FMAN_KG_SCH_GEN_MASK_SHIFT	16
208#define FMAN_KG_SCH_GEN_HT_SHIFT	8
209
210#define FMAN_KG_SCH_HASH_HSHIFT_SHIFT	24
211#define FMAN_KG_SCH_HASH_HSHIFT_MAX	0x28
212#define FMAN_KG_SCH_HASH_SYM		0x40000000
213#define FMAN_KG_SCH_HASH_NO_FQID_GEN	0x80000000
214
215#define FMAN_KG_SCH_PP_SH_SHIFT		27
216#define FMAN_KG_SCH_PP_SL_SHIFT		12
217#define FMAN_KG_SCH_PP_SH_MASK		0x80000000
218#define FMAN_KG_SCH_PP_SL_MASK		0x0000F000
219#define FMAN_KG_SCH_PP_SHIFT_MAX	0x17
220#define FMAN_KG_SCH_PP_MASK_SHIFT	16
221#define FMAN_KG_SCH_PP_NO_GEN		0x10000000
222
223enum fman_kg_gen_extract_src {
224	E_FMAN_KG_GEN_EXTRACT_ETH,
225	E_FMAN_KG_GEN_EXTRACT_ETYPE,
226	E_FMAN_KG_GEN_EXTRACT_SNAP,
227	E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1,
228	E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N,
229	E_FMAN_KG_GEN_EXTRACT_PPPoE,
230	E_FMAN_KG_GEN_EXTRACT_MPLS_1,
231	E_FMAN_KG_GEN_EXTRACT_MPLS_2,
232	E_FMAN_KG_GEN_EXTRACT_MPLS_3,
233	E_FMAN_KG_GEN_EXTRACT_MPLS_N,
234	E_FMAN_KG_GEN_EXTRACT_IPv4_1,
235	E_FMAN_KG_GEN_EXTRACT_IPv6_1,
236	E_FMAN_KG_GEN_EXTRACT_IPv4_2,
237	E_FMAN_KG_GEN_EXTRACT_IPv6_2,
238	E_FMAN_KG_GEN_EXTRACT_MINENCAP,
239	E_FMAN_KG_GEN_EXTRACT_IP_PID,
240	E_FMAN_KG_GEN_EXTRACT_GRE,
241	E_FMAN_KG_GEN_EXTRACT_TCP,
242	E_FMAN_KG_GEN_EXTRACT_UDP,
243	E_FMAN_KG_GEN_EXTRACT_SCTP,
244	E_FMAN_KG_GEN_EXTRACT_DCCP,
245	E_FMAN_KG_GEN_EXTRACT_IPSEC_AH,
246	E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP,
247	E_FMAN_KG_GEN_EXTRACT_SHIM_1,
248	E_FMAN_KG_GEN_EXTRACT_SHIM_2,
249	E_FMAN_KG_GEN_EXTRACT_FROM_DFLT,
250	E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START,
251	E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT,
252	E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE,
253	E_FMAN_KG_GEN_EXTRACT_FROM_FQID
254};
255
256struct fman_kg_ex_ecc_attr
257{
258	bool		valid;
259	bool		double_ecc;
260	uint16_t	addr;
261	uint8_t		single_ecc_count;
262};
263
264enum fman_kg_def_select
265{
266	E_FMAN_KG_DEF_GLOBAL_0,
267	E_FMAN_KG_DEF_GLOBAL_1,
268	E_FMAN_KG_DEF_SCHEME_0,
269	E_FMAN_KG_DEF_SCHEME_1
270};
271
272struct fman_kg_extract_def
273{
274	enum fman_kg_def_select	mac_addr;
275	enum fman_kg_def_select	vlan_tci;
276	enum fman_kg_def_select	etype;
277	enum fman_kg_def_select	ppp_sid;
278	enum fman_kg_def_select	ppp_pid;
279	enum fman_kg_def_select	mpls;
280	enum fman_kg_def_select	ip_addr;
281	enum fman_kg_def_select	ptype;
282	enum fman_kg_def_select	ip_tos_tc;
283	enum fman_kg_def_select	ipv6_fl;
284	enum fman_kg_def_select	ipsec_spi;
285	enum fman_kg_def_select	l4_port;
286	enum fman_kg_def_select	tcp_flg;
287};
288
289enum fman_kg_gen_extract_type
290{
291	E_FMAN_KG_HASH_EXTRACT,
292	E_FMAN_KG_OR_EXTRACT
293};
294
295struct fman_kg_gen_extract_params
296{
297	/* Hash or Or-ed extract */
298	enum fman_kg_gen_extract_type	type;
299	enum fman_kg_gen_extract_src	src;
300	bool				no_validation;
301	/* Extraction offset from the header location specified above */
302	uint8_t				offset;
303	/* Size of extraction for FMAN_KG_HASH_EXTRACT,
304	 * hash result shift for FMAN_KG_OR_EXTRACT */
305	uint8_t				extract;
306	uint8_t				mask;
307	/* Default value to use when header specified
308	 * by fman_kg_gen_extract_src doesn't present */
309	enum fman_kg_def_select		def_val;
310};
311
312struct fman_kg_extract_mask
313{
314	/**< Indication if mask is on known field extraction or
315	 * on general extraction; TRUE for known field */
316	bool		is_known;
317	/**< One of FMAN_KG_EXTRACT_xxx defines for known fields mask and
318	 * generic register index for generic extracts mask */
319	uint32_t	field_or_gen_idx;
320	/**< Byte offset from start of the extracted data specified
321	 * by field_or_gen_idx */
322	uint8_t		offset;
323	/**< Byte mask (selected bits will be used) */
324	uint8_t		mask;
325};
326
327struct fman_kg_extract_params
328{
329	/* Or-ed mask of FMAN_KG_EXTRACT_xxx defines */
330	uint32_t				known_fields;
331	struct fman_kg_extract_def		known_fields_def;
332	/* Number of entries in gen_extract */
333	uint8_t					gen_extract_num;
334	struct fman_kg_gen_extract_params	gen_extract[FM_KG_NUM_OF_GENERIC_REGS];
335	/* Number of entries in masks */
336	uint8_t					masks_num;
337	struct fman_kg_extract_mask		masks[FM_KG_EXTRACT_MASKS_NUM];
338	uint32_t				def_scheme_0;
339	uint32_t				def_scheme_1;
340};
341
342struct fman_kg_hash_params
343{
344	bool		use_hash;
345	uint8_t		shift_r;
346	uint32_t	mask; /**< 24-bit mask */
347	bool		sym; /**< Symmetric hash for src and dest pairs */
348};
349
350struct fman_kg_pp_params
351{
352	uint8_t		base;
353	uint8_t		shift;
354	uint8_t		mask;
355	bool		bypass_pp_gen;
356};
357
358struct fman_kg_cc_params
359{
360	uint8_t		base_offset;
361	uint32_t	qlcv_bits_sel;
362};
363
364enum fman_pcd_engine
365{
366	E_FMAN_PCD_INVALID = 0,	/**< Invalid PCD engine indicated*/
367	E_FMAN_PCD_DONE,	/**< No PCD Engine indicated */
368	E_FMAN_PCD_KG,		/**< Keygen indicated */
369	E_FMAN_PCD_CC,		/**< Coarse classification indicated */
370	E_FMAN_PCD_PLCR,	/**< Policer indicated */
371	E_FMAN_PCD_PRS		/**< Parser indicated */
372};
373
374struct fman_kg_cls_plan_params
375{
376	uint8_t entries_mask;
377	uint32_t mask_vector[FM_KG_NUM_CLS_PLAN_ENTR];
378};
379
380struct fman_kg_scheme_params
381{
382	uint32_t			match_vector;
383	struct fman_kg_extract_params	extract_params;
384	struct fman_kg_hash_params	hash_params;
385	uint32_t			base_fqid;
386	/* What we do w/features supported per FM version ?? */
387	bool				bypass_fqid_gen;
388	struct fman_kg_pp_params	policer_params;
389	struct fman_kg_cc_params	cc_params;
390	bool				update_counter;
391	/**< counter_value: Set scheme counter to the specified value;
392	 * relevant only when update_counter = TRUE. */
393	uint32_t			counter_value;
394	enum fman_pcd_engine		next_engine;
395	/**< Next engine action code */
396	uint32_t			next_engine_action;
397};
398
399
400
401int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar);
402void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add);
403void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp);
404void fman_kg_get_event(struct fman_kg_regs *regs,
405			uint32_t *event,
406			uint32_t *scheme_idx);
407void fman_kg_init(struct fman_kg_regs *regs,
408			uint32_t exceptions,
409			uint32_t dflt_nia);
410void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs);
411void fman_kg_enable(struct fman_kg_regs *regs);
412void fman_kg_disable(struct fman_kg_regs *regs);
413int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs,
414					uint8_t hwport_id,
415					uint32_t bind_cls_plans);
416int fman_kg_build_bind_cls_plans(uint8_t grp_base,
417					uint8_t grp_mask,
418					uint32_t *bind_cls_plans);
419int fman_kg_write_bind_schemes(struct fman_kg_regs *regs,
420				uint8_t hwport_id,
421				uint32_t schemes);
422int fman_kg_write_cls_plan(struct fman_kg_regs *regs,
423				uint8_t grp_id,
424				uint8_t entries_mask,
425				uint8_t hwport_id,
426				struct fman_kg_cp_regs *cls_plan_regs);
427int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params,
428				struct fman_kg_cp_regs *cls_plan_regs);
429uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs);
430int fman_kg_set_scheme_counter(struct fman_kg_regs *regs,
431				uint8_t scheme_id,
432				uint8_t hwport_id,
433				uint32_t counter);
434int fman_kg_get_scheme_counter(struct fman_kg_regs *regs,
435				uint8_t scheme_id,
436				uint8_t hwport_id,
437				uint32_t *counter);
438int fman_kg_delete_scheme(struct fman_kg_regs *regs,
439				uint8_t scheme_id,
440				uint8_t hwport_id);
441int fman_kg_write_scheme(struct fman_kg_regs *regs,
442				uint8_t scheme_id,
443				uint8_t hwport_id,
444				struct fman_kg_scheme_regs *scheme_regs,
445				bool update_counter);
446int fman_kg_build_scheme(struct fman_kg_scheme_params *params,
447				struct fman_kg_scheme_regs *scheme_regs);
448void fman_kg_get_capture(struct fman_kg_regs *regs,
449				struct fman_kg_ex_ecc_attr *ecc_attr,
450				bool clear);
451void fman_kg_get_exception(struct fman_kg_regs *regs,
452				uint32_t *events,
453				uint32_t *scheme_ids,
454				bool clear);
455void fman_kg_set_exception(struct fman_kg_regs *regs,
456				uint32_t exception,
457				bool enable);
458void fman_kg_set_dflt_val(struct fman_kg_regs *regs,
459				uint8_t def_id,
460				uint32_t val);
461void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset);
462
463
464
465/**************************************************************************//**
466  @Description       NIA Description
467*//***************************************************************************/
468#define KG_NIA_ORDER_RESTOR	0x00800000
469#define KG_NIA_ENG_FM_CTL	0x00000000
470#define KG_NIA_ENG_PRS		0x00440000
471#define KG_NIA_ENG_KG		0x00480000
472#define KG_NIA_ENG_PLCR		0x004C0000
473#define KG_NIA_ENG_BMI		0x00500000
474#define KG_NIA_ENG_QMI_ENQ	0x00540000
475#define KG_NIA_ENG_QMI_DEQ	0x00580000
476#define KG_NIA_ENG_MASK		0x007C0000
477
478#define KG_NIA_AC_MASK		0x0003FFFF
479
480#define KG_NIA_INVALID		0xFFFFFFFF
481
482static __inline__ uint32_t fm_kg_build_nia(enum fman_pcd_engine next_engine,
483					uint32_t next_engine_action)
484{
485	uint32_t nia;
486
487	if (next_engine_action & ~KG_NIA_AC_MASK)
488		return KG_NIA_INVALID;
489
490	switch (next_engine) {
491	case E_FMAN_PCD_DONE:
492		nia = KG_NIA_ENG_BMI | next_engine_action;
493		break;
494
495	case E_FMAN_PCD_KG:
496		nia = KG_NIA_ENG_KG | next_engine_action;
497		break;
498
499	case E_FMAN_PCD_CC:
500		nia = KG_NIA_ENG_FM_CTL | next_engine_action;
501		break;
502
503	case E_FMAN_PCD_PLCR:
504		nia = KG_NIA_ENG_PLCR | next_engine_action;
505		break;
506
507	default:
508		nia = KG_NIA_INVALID;
509	}
510
511	return nia;
512}
513
514#endif /* __FSL_FMAN_KG_H */
515