• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2 /* QLogic qed NIC Driver
3  * Copyright (c) 2015-2017  QLogic Corporation
4  * Copyright (c) 2019-2020 Marvell International Ltd.
5  */
6 
7 #include <linux/types.h>
8 #include <linux/crc8.h>
9 #include <linux/delay.h>
10 #include <linux/kernel.h>
11 #include <linux/slab.h>
12 #include <linux/string.h>
13 #include "qed_hsi.h"
14 #include "qed_hw.h"
15 #include "qed_init_ops.h"
16 #include "qed_reg_addr.h"
17 
18 #define CDU_VALIDATION_DEFAULT_CFG	61
19 
20 static u16 con_region_offsets[3][NUM_OF_CONNECTION_TYPES_E4] = {
21 	{400, 336, 352, 368, 304, 384, 416, 352},	/* region 3 offsets */
22 	{528, 496, 416, 512, 448, 512, 544, 480},	/* region 4 offsets */
23 	{608, 544, 496, 576, 576, 592, 624, 560}	/* region 5 offsets */
24 };
25 
26 static u16 task_region_offsets[1][NUM_OF_CONNECTION_TYPES_E4] = {
27 	{240, 240, 112, 0, 0, 0, 0, 96}	/* region 1 offsets */
28 };
29 
30 /* General constants */
31 #define QM_PQ_MEM_4KB(pq_size)	(pq_size ? DIV_ROUND_UP((pq_size + 1) *	\
32 							QM_PQ_ELEMENT_SIZE, \
33 							0x1000) : 0)
34 #define QM_PQ_SIZE_256B(pq_size)	(pq_size ? DIV_ROUND_UP(pq_size, \
35 								0x100) - 1 : 0)
36 #define QM_INVALID_PQ_ID		0xffff
37 
38 /* Max link speed (in Mbps) */
39 #define QM_MAX_LINK_SPEED               100000
40 
41 /* Feature enable */
42 #define QM_BYPASS_EN	1
43 #define QM_BYTE_CRD_EN	1
44 
45 /* Other PQ constants */
46 #define QM_OTHER_PQS_PER_PF	4
47 
48 /* WFQ constants */
49 
50 /* Upper bound in MB, 10 * burst size of 1ms in 50Gbps */
51 #define QM_WFQ_UPPER_BOUND	62500000
52 
53 /* Bit  of VOQ in WFQ VP PQ map */
54 #define QM_WFQ_VP_PQ_VOQ_SHIFT	0
55 
56 /* Bit  of PF in WFQ VP PQ map */
57 #define QM_WFQ_VP_PQ_PF_E4_SHIFT	5
58 
59 /* 0x9000 = 4*9*1024 */
60 #define QM_WFQ_INC_VAL(weight)	((weight) * 0x9000)
61 
62 /* Max WFQ increment value is 0.7 * upper bound */
63 #define QM_WFQ_MAX_INC_VAL	((QM_WFQ_UPPER_BOUND * 7) / 10)
64 
65 /* RL constants */
66 
67 /* Period in us */
68 #define QM_RL_PERIOD	5
69 
70 /* Period in 25MHz cycles */
71 #define QM_RL_PERIOD_CLK_25M	(25 * QM_RL_PERIOD)
72 
73 /* RL increment value - rate is specified in mbps */
74 #define QM_RL_INC_VAL(rate) ({ \
75 	typeof(rate) __rate = (rate); \
76 	max_t(u32, \
77 	      (u32)(((__rate ? __rate : 1000000) * QM_RL_PERIOD * 101) / \
78 		    (8 * 100)), \
79 	      1); })
80 
81 /* PF RL Upper bound is set to 10 * burst size of 1ms in 50Gbps */
82 #define QM_PF_RL_UPPER_BOUND	62500000
83 
84 /* Max PF RL increment value is 0.7 * upper bound */
85 #define QM_PF_RL_MAX_INC_VAL	((QM_PF_RL_UPPER_BOUND * 7) / 10)
86 
87 /* Vport RL Upper bound, link speed is in Mpbs */
88 #define QM_VP_RL_UPPER_BOUND(speed)	((u32)max_t(u32, \
89 						    QM_RL_INC_VAL(speed), \
90 						    9700 + 1000))
91 
92 /* Max Vport RL increment value is the Vport RL upper bound */
93 #define QM_VP_RL_MAX_INC_VAL(speed)	QM_VP_RL_UPPER_BOUND(speed)
94 
95 /* Vport RL credit threshold in case of QM bypass */
96 #define QM_VP_RL_BYPASS_THRESH_SPEED	(QM_VP_RL_UPPER_BOUND(10000) - 1)
97 
98 /* AFullOprtnstcCrdMask constants */
99 #define QM_OPPOR_LINE_VOQ_DEF	1
100 #define QM_OPPOR_FW_STOP_DEF	0
101 #define QM_OPPOR_PQ_EMPTY_DEF	1
102 
103 /* Command Queue constants */
104 
105 /* Pure LB CmdQ lines (+spare) */
106 #define PBF_CMDQ_PURE_LB_LINES	150
107 
108 #define PBF_CMDQ_LINES_RT_OFFSET(ext_voq) \
109 	(PBF_REG_YCMD_QS_NUM_LINES_VOQ0_RT_OFFSET + \
110 	 (ext_voq) * (PBF_REG_YCMD_QS_NUM_LINES_VOQ1_RT_OFFSET - \
111 		PBF_REG_YCMD_QS_NUM_LINES_VOQ0_RT_OFFSET))
112 
113 #define PBF_BTB_GUARANTEED_RT_OFFSET(ext_voq) \
114 	(PBF_REG_BTB_GUARANTEED_VOQ0_RT_OFFSET + \
115 	 (ext_voq) * (PBF_REG_BTB_GUARANTEED_VOQ1_RT_OFFSET - \
116 		PBF_REG_BTB_GUARANTEED_VOQ0_RT_OFFSET))
117 
118 /* Returns the VOQ line credit for the specified number of PBF command lines.
119  * PBF lines are specified in 256b units.
120  */
121 #define QM_VOQ_LINE_CRD(pbf_cmd_lines) \
122 	((((pbf_cmd_lines) - 4) * 2) | QM_LINE_CRD_REG_SIGN_BIT)
123 
124 /* BTB: blocks constants (block size = 256B) */
125 
126 /* 256B blocks in 9700B packet */
127 #define BTB_JUMBO_PKT_BLOCKS	38
128 
129 /* Headroom per-port */
130 #define BTB_HEADROOM_BLOCKS	BTB_JUMBO_PKT_BLOCKS
131 #define BTB_PURE_LB_FACTOR	10
132 
133 /* Factored (hence really 0.7) */
134 #define BTB_PURE_LB_RATIO	7
135 
136 /* QM stop command constants */
137 #define QM_STOP_PQ_MASK_WIDTH		32
138 #define QM_STOP_CMD_ADDR		2
139 #define QM_STOP_CMD_STRUCT_SIZE		2
140 #define QM_STOP_CMD_PAUSE_MASK_OFFSET	0
141 #define QM_STOP_CMD_PAUSE_MASK_SHIFT	0
142 #define QM_STOP_CMD_PAUSE_MASK_MASK	-1
143 #define QM_STOP_CMD_GROUP_ID_OFFSET	1
144 #define QM_STOP_CMD_GROUP_ID_SHIFT	16
145 #define QM_STOP_CMD_GROUP_ID_MASK	15
146 #define QM_STOP_CMD_PQ_TYPE_OFFSET	1
147 #define QM_STOP_CMD_PQ_TYPE_SHIFT	24
148 #define QM_STOP_CMD_PQ_TYPE_MASK	1
149 #define QM_STOP_CMD_MAX_POLL_COUNT	100
150 #define QM_STOP_CMD_POLL_PERIOD_US	500
151 
152 /* QM command macros */
153 #define QM_CMD_STRUCT_SIZE(cmd)	cmd ## _STRUCT_SIZE
154 #define QM_CMD_SET_FIELD(var, cmd, field, value) \
155 	SET_FIELD(var[cmd ## _ ## field ## _OFFSET], \
156 		  cmd ## _ ## field, \
157 		  value)
158 
159 #define QM_INIT_TX_PQ_MAP(p_hwfn, map, chip, pq_id, vp_pq_id, rl_valid,	      \
160 			  rl_id, ext_voq, wrr)				      \
161 	do {								      \
162 		u32 __reg = 0;						      \
163 									      \
164 		BUILD_BUG_ON(sizeof((map).reg) != sizeof(__reg));	      \
165 									      \
166 		SET_FIELD(__reg, QM_RF_PQ_MAP_##chip##_PQ_VALID, 1);	      \
167 		SET_FIELD(__reg, QM_RF_PQ_MAP_##chip##_RL_VALID,	      \
168 			  !!(rl_valid));				      \
169 		SET_FIELD(__reg, QM_RF_PQ_MAP_##chip##_VP_PQ_ID, (vp_pq_id)); \
170 		SET_FIELD(__reg, QM_RF_PQ_MAP_##chip##_RL_ID, (rl_id));	      \
171 		SET_FIELD(__reg, QM_RF_PQ_MAP_##chip##_VOQ, (ext_voq));	      \
172 		SET_FIELD(__reg, QM_RF_PQ_MAP_##chip##_WRR_WEIGHT_GROUP,      \
173 			  (wrr));					      \
174 									      \
175 		STORE_RT_REG((p_hwfn), QM_REG_TXPQMAP_RT_OFFSET + (pq_id),    \
176 			     __reg);					      \
177 		(map).reg = cpu_to_le32(__reg);				      \
178 	} while (0)
179 
180 #define WRITE_PQ_INFO_TO_RAM	1
181 #define PQ_INFO_ELEMENT(vp, pf, tc, port, rl_valid, rl) \
182 	(((vp) << 0) | ((pf) << 12) | ((tc) << 16) | ((port) << 20) | \
183 	((rl_valid ? 1 : 0) << 22) | (((rl) & 255) << 24) | \
184 	(((rl) >> 8) << 9))
185 
186 #define PQ_INFO_RAM_GRC_ADDRESS(pq_id) \
187 	XSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM + \
188 	XSTORM_PQ_INFO_OFFSET(pq_id)
189 
190 /******************** INTERNAL IMPLEMENTATION *********************/
191 
192 /* Returns the external VOQ number */
qed_get_ext_voq(struct qed_hwfn * p_hwfn,u8 port_id,u8 tc,u8 max_phys_tcs_per_port)193 static u8 qed_get_ext_voq(struct qed_hwfn *p_hwfn,
194 			  u8 port_id, u8 tc, u8 max_phys_tcs_per_port)
195 {
196 	if (tc == PURE_LB_TC)
197 		return NUM_OF_PHYS_TCS * MAX_NUM_PORTS_BB + port_id;
198 	else
199 		return port_id * max_phys_tcs_per_port + tc;
200 }
201 
202 /* Prepare PF RL enable/disable runtime init values */
qed_enable_pf_rl(struct qed_hwfn * p_hwfn,bool pf_rl_en)203 static void qed_enable_pf_rl(struct qed_hwfn *p_hwfn, bool pf_rl_en)
204 {
205 	STORE_RT_REG(p_hwfn, QM_REG_RLPFENABLE_RT_OFFSET, pf_rl_en ? 1 : 0);
206 	if (pf_rl_en) {
207 		u8 num_ext_voqs = MAX_NUM_VOQS_E4;
208 		u64 voq_bit_mask = ((u64)1 << num_ext_voqs) - 1;
209 
210 		/* Enable RLs for all VOQs */
211 		STORE_RT_REG(p_hwfn,
212 			     QM_REG_RLPFVOQENABLE_RT_OFFSET,
213 			     (u32)voq_bit_mask);
214 
215 		/* Write RL period */
216 		STORE_RT_REG(p_hwfn,
217 			     QM_REG_RLPFPERIOD_RT_OFFSET, QM_RL_PERIOD_CLK_25M);
218 		STORE_RT_REG(p_hwfn,
219 			     QM_REG_RLPFPERIODTIMER_RT_OFFSET,
220 			     QM_RL_PERIOD_CLK_25M);
221 
222 		/* Set credit threshold for QM bypass flow */
223 		if (QM_BYPASS_EN)
224 			STORE_RT_REG(p_hwfn,
225 				     QM_REG_AFULLQMBYPTHRPFRL_RT_OFFSET,
226 				     QM_PF_RL_UPPER_BOUND);
227 	}
228 }
229 
230 /* Prepare PF WFQ enable/disable runtime init values */
qed_enable_pf_wfq(struct qed_hwfn * p_hwfn,bool pf_wfq_en)231 static void qed_enable_pf_wfq(struct qed_hwfn *p_hwfn, bool pf_wfq_en)
232 {
233 	STORE_RT_REG(p_hwfn, QM_REG_WFQPFENABLE_RT_OFFSET, pf_wfq_en ? 1 : 0);
234 
235 	/* Set credit threshold for QM bypass flow */
236 	if (pf_wfq_en && QM_BYPASS_EN)
237 		STORE_RT_REG(p_hwfn,
238 			     QM_REG_AFULLQMBYPTHRPFWFQ_RT_OFFSET,
239 			     QM_WFQ_UPPER_BOUND);
240 }
241 
242 /* Prepare global RL enable/disable runtime init values */
qed_enable_global_rl(struct qed_hwfn * p_hwfn,bool global_rl_en)243 static void qed_enable_global_rl(struct qed_hwfn *p_hwfn, bool global_rl_en)
244 {
245 	STORE_RT_REG(p_hwfn, QM_REG_RLGLBLENABLE_RT_OFFSET,
246 		     global_rl_en ? 1 : 0);
247 	if (global_rl_en) {
248 		/* Write RL period (use timer 0 only) */
249 		STORE_RT_REG(p_hwfn,
250 			     QM_REG_RLGLBLPERIOD_0_RT_OFFSET,
251 			     QM_RL_PERIOD_CLK_25M);
252 		STORE_RT_REG(p_hwfn,
253 			     QM_REG_RLGLBLPERIODTIMER_0_RT_OFFSET,
254 			     QM_RL_PERIOD_CLK_25M);
255 
256 		/* Set credit threshold for QM bypass flow */
257 		if (QM_BYPASS_EN)
258 			STORE_RT_REG(p_hwfn,
259 				     QM_REG_AFULLQMBYPTHRGLBLRL_RT_OFFSET,
260 				     QM_VP_RL_BYPASS_THRESH_SPEED);
261 	}
262 }
263 
264 /* Prepare VPORT WFQ enable/disable runtime init values */
qed_enable_vport_wfq(struct qed_hwfn * p_hwfn,bool vport_wfq_en)265 static void qed_enable_vport_wfq(struct qed_hwfn *p_hwfn, bool vport_wfq_en)
266 {
267 	STORE_RT_REG(p_hwfn, QM_REG_WFQVPENABLE_RT_OFFSET,
268 		     vport_wfq_en ? 1 : 0);
269 
270 	/* Set credit threshold for QM bypass flow */
271 	if (vport_wfq_en && QM_BYPASS_EN)
272 		STORE_RT_REG(p_hwfn,
273 			     QM_REG_AFULLQMBYPTHRVPWFQ_RT_OFFSET,
274 			     QM_WFQ_UPPER_BOUND);
275 }
276 
277 /* Prepare runtime init values to allocate PBF command queue lines for
278  * the specified VOQ.
279  */
qed_cmdq_lines_voq_rt_init(struct qed_hwfn * p_hwfn,u8 ext_voq,u16 cmdq_lines)280 static void qed_cmdq_lines_voq_rt_init(struct qed_hwfn *p_hwfn,
281 				       u8 ext_voq, u16 cmdq_lines)
282 {
283 	u32 qm_line_crd = QM_VOQ_LINE_CRD(cmdq_lines);
284 
285 	OVERWRITE_RT_REG(p_hwfn, PBF_CMDQ_LINES_RT_OFFSET(ext_voq),
286 			 (u32)cmdq_lines);
287 	STORE_RT_REG(p_hwfn, QM_REG_VOQCRDLINE_RT_OFFSET + ext_voq,
288 		     qm_line_crd);
289 	STORE_RT_REG(p_hwfn, QM_REG_VOQINITCRDLINE_RT_OFFSET + ext_voq,
290 		     qm_line_crd);
291 }
292 
293 /* Prepare runtime init values to allocate PBF command queue lines. */
qed_cmdq_lines_rt_init(struct qed_hwfn * p_hwfn,u8 max_ports_per_engine,u8 max_phys_tcs_per_port,struct init_qm_port_params port_params[MAX_NUM_PORTS])294 static void qed_cmdq_lines_rt_init(
295 	struct qed_hwfn *p_hwfn,
296 	u8 max_ports_per_engine,
297 	u8 max_phys_tcs_per_port,
298 	struct init_qm_port_params port_params[MAX_NUM_PORTS])
299 {
300 	u8 tc, ext_voq, port_id, num_tcs_in_port;
301 	u8 num_ext_voqs = MAX_NUM_VOQS_E4;
302 
303 	/* Clear PBF lines of all VOQs */
304 	for (ext_voq = 0; ext_voq < num_ext_voqs; ext_voq++)
305 		STORE_RT_REG(p_hwfn, PBF_CMDQ_LINES_RT_OFFSET(ext_voq), 0);
306 
307 	for (port_id = 0; port_id < max_ports_per_engine; port_id++) {
308 		u16 phys_lines, phys_lines_per_tc;
309 
310 		if (!port_params[port_id].active)
311 			continue;
312 
313 		/* Find number of command queue lines to divide between the
314 		 * active physical TCs.
315 		 */
316 		phys_lines = port_params[port_id].num_pbf_cmd_lines;
317 		phys_lines -= PBF_CMDQ_PURE_LB_LINES;
318 
319 		/* Find #lines per active physical TC */
320 		num_tcs_in_port = 0;
321 		for (tc = 0; tc < max_phys_tcs_per_port; tc++)
322 			if (((port_params[port_id].active_phys_tcs >>
323 			      tc) & 0x1) == 1)
324 				num_tcs_in_port++;
325 		phys_lines_per_tc = phys_lines / num_tcs_in_port;
326 
327 		/* Init registers per active TC */
328 		for (tc = 0; tc < max_phys_tcs_per_port; tc++) {
329 			ext_voq = qed_get_ext_voq(p_hwfn,
330 						  port_id,
331 						  tc, max_phys_tcs_per_port);
332 			if (((port_params[port_id].active_phys_tcs >>
333 			      tc) & 0x1) == 1)
334 				qed_cmdq_lines_voq_rt_init(p_hwfn,
335 							   ext_voq,
336 							   phys_lines_per_tc);
337 		}
338 
339 		/* Init registers for pure LB TC */
340 		ext_voq = qed_get_ext_voq(p_hwfn,
341 					  port_id,
342 					  PURE_LB_TC, max_phys_tcs_per_port);
343 		qed_cmdq_lines_voq_rt_init(p_hwfn, ext_voq,
344 					   PBF_CMDQ_PURE_LB_LINES);
345 	}
346 }
347 
348 /* Prepare runtime init values to allocate guaranteed BTB blocks for the
349  * specified port. The guaranteed BTB space is divided between the TCs as
350  * follows (shared space Is currently not used):
351  * 1. Parameters:
352  *    B - BTB blocks for this port
353  *    C - Number of physical TCs for this port
354  * 2. Calculation:
355  *    a. 38 blocks (9700B jumbo frame) are allocated for global per port
356  *	 headroom.
357  *    b. B = B - 38 (remainder after global headroom allocation).
358  *    c. MAX(38,B/(C+0.7)) blocks are allocated for the pure LB VOQ.
359  *    d. B = B - MAX(38, B/(C+0.7)) (remainder after pure LB allocation).
360  *    e. B/C blocks are allocated for each physical TC.
361  * Assumptions:
362  * - MTU is up to 9700 bytes (38 blocks)
363  * - All TCs are considered symmetrical (same rate and packet size)
364  * - No optimization for lossy TC (all are considered lossless). Shared space
365  *   is not enabled and allocated for each TC.
366  */
qed_btb_blocks_rt_init(struct qed_hwfn * p_hwfn,u8 max_ports_per_engine,u8 max_phys_tcs_per_port,struct init_qm_port_params port_params[MAX_NUM_PORTS])367 static void qed_btb_blocks_rt_init(
368 	struct qed_hwfn *p_hwfn,
369 	u8 max_ports_per_engine,
370 	u8 max_phys_tcs_per_port,
371 	struct init_qm_port_params port_params[MAX_NUM_PORTS])
372 {
373 	u32 usable_blocks, pure_lb_blocks, phys_blocks;
374 	u8 tc, ext_voq, port_id, num_tcs_in_port;
375 
376 	for (port_id = 0; port_id < max_ports_per_engine; port_id++) {
377 		if (!port_params[port_id].active)
378 			continue;
379 
380 		/* Subtract headroom blocks */
381 		usable_blocks = port_params[port_id].num_btb_blocks -
382 				BTB_HEADROOM_BLOCKS;
383 
384 		/* Find blocks per physical TC. Use factor to avoid floating
385 		 * arithmethic.
386 		 */
387 		num_tcs_in_port = 0;
388 		for (tc = 0; tc < NUM_OF_PHYS_TCS; tc++)
389 			if (((port_params[port_id].active_phys_tcs >>
390 			      tc) & 0x1) == 1)
391 				num_tcs_in_port++;
392 
393 		pure_lb_blocks = (usable_blocks * BTB_PURE_LB_FACTOR) /
394 				 (num_tcs_in_port * BTB_PURE_LB_FACTOR +
395 				  BTB_PURE_LB_RATIO);
396 		pure_lb_blocks = max_t(u32, BTB_JUMBO_PKT_BLOCKS,
397 				       pure_lb_blocks / BTB_PURE_LB_FACTOR);
398 		phys_blocks = (usable_blocks - pure_lb_blocks) /
399 			      num_tcs_in_port;
400 
401 		/* Init physical TCs */
402 		for (tc = 0; tc < NUM_OF_PHYS_TCS; tc++) {
403 			if (((port_params[port_id].active_phys_tcs >>
404 			      tc) & 0x1) == 1) {
405 				ext_voq =
406 					qed_get_ext_voq(p_hwfn,
407 							port_id,
408 							tc,
409 							max_phys_tcs_per_port);
410 				STORE_RT_REG(p_hwfn,
411 					     PBF_BTB_GUARANTEED_RT_OFFSET
412 					     (ext_voq), phys_blocks);
413 			}
414 		}
415 
416 		/* Init pure LB TC */
417 		ext_voq = qed_get_ext_voq(p_hwfn,
418 					  port_id,
419 					  PURE_LB_TC, max_phys_tcs_per_port);
420 		STORE_RT_REG(p_hwfn, PBF_BTB_GUARANTEED_RT_OFFSET(ext_voq),
421 			     pure_lb_blocks);
422 	}
423 }
424 
425 /* Prepare runtime init values for the specified RL.
426  * Set max link speed (100Gbps) per rate limiter.
427  * Return -1 on error.
428  */
qed_global_rl_rt_init(struct qed_hwfn * p_hwfn)429 static int qed_global_rl_rt_init(struct qed_hwfn *p_hwfn)
430 {
431 	u32 upper_bound = QM_VP_RL_UPPER_BOUND(QM_MAX_LINK_SPEED) |
432 			  (u32)QM_RL_CRD_REG_SIGN_BIT;
433 	u32 inc_val;
434 	u16 rl_id;
435 
436 	/* Go over all global RLs */
437 	for (rl_id = 0; rl_id < MAX_QM_GLOBAL_RLS; rl_id++) {
438 		inc_val = QM_RL_INC_VAL(QM_MAX_LINK_SPEED);
439 
440 		STORE_RT_REG(p_hwfn,
441 			     QM_REG_RLGLBLCRD_RT_OFFSET + rl_id,
442 			     (u32)QM_RL_CRD_REG_SIGN_BIT);
443 		STORE_RT_REG(p_hwfn,
444 			     QM_REG_RLGLBLUPPERBOUND_RT_OFFSET + rl_id,
445 			     upper_bound);
446 		STORE_RT_REG(p_hwfn,
447 			     QM_REG_RLGLBLINCVAL_RT_OFFSET + rl_id, inc_val);
448 	}
449 
450 	return 0;
451 }
452 
453 /* Prepare Tx PQ mapping runtime init values for the specified PF */
qed_tx_pq_map_rt_init(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,struct qed_qm_pf_rt_init_params * p_params,u32 base_mem_addr_4kb)454 static void qed_tx_pq_map_rt_init(struct qed_hwfn *p_hwfn,
455 				  struct qed_ptt *p_ptt,
456 				  struct qed_qm_pf_rt_init_params *p_params,
457 				  u32 base_mem_addr_4kb)
458 {
459 	u32 tx_pq_vf_mask[MAX_QM_TX_QUEUES / QM_PF_QUEUE_GROUP_SIZE] = { 0 };
460 	struct init_qm_vport_params *vport_params = p_params->vport_params;
461 	u32 num_tx_pq_vf_masks = MAX_QM_TX_QUEUES / QM_PF_QUEUE_GROUP_SIZE;
462 	u16 num_pqs, first_pq_group, last_pq_group, i, j, pq_id, pq_group;
463 	struct init_qm_pq_params *pq_params = p_params->pq_params;
464 	u32 pq_mem_4kb, vport_pq_mem_4kb, mem_addr_4kb;
465 
466 	num_pqs = p_params->num_pf_pqs + p_params->num_vf_pqs;
467 
468 	first_pq_group = p_params->start_pq / QM_PF_QUEUE_GROUP_SIZE;
469 	last_pq_group = (p_params->start_pq + num_pqs - 1) /
470 			QM_PF_QUEUE_GROUP_SIZE;
471 
472 	pq_mem_4kb = QM_PQ_MEM_4KB(p_params->num_pf_cids);
473 	vport_pq_mem_4kb = QM_PQ_MEM_4KB(p_params->num_vf_cids);
474 	mem_addr_4kb = base_mem_addr_4kb;
475 
476 	/* Set mapping from PQ group to PF */
477 	for (pq_group = first_pq_group; pq_group <= last_pq_group; pq_group++)
478 		STORE_RT_REG(p_hwfn, QM_REG_PQTX2PF_0_RT_OFFSET + pq_group,
479 			     (u32)(p_params->pf_id));
480 
481 	/* Set PQ sizes */
482 	STORE_RT_REG(p_hwfn, QM_REG_MAXPQSIZE_0_RT_OFFSET,
483 		     QM_PQ_SIZE_256B(p_params->num_pf_cids));
484 	STORE_RT_REG(p_hwfn, QM_REG_MAXPQSIZE_1_RT_OFFSET,
485 		     QM_PQ_SIZE_256B(p_params->num_vf_cids));
486 
487 	/* Go over all Tx PQs */
488 	for (i = 0, pq_id = p_params->start_pq; i < num_pqs; i++, pq_id++) {
489 		u16 *p_first_tx_pq_id, vport_id_in_pf;
490 		struct qm_rf_pq_map_e4 tx_pq_map;
491 		u8 tc_id = pq_params[i].tc_id;
492 		bool is_vf_pq;
493 		u8 ext_voq;
494 
495 		ext_voq = qed_get_ext_voq(p_hwfn,
496 					  pq_params[i].port_id,
497 					  tc_id,
498 					  p_params->max_phys_tcs_per_port);
499 		is_vf_pq = (i >= p_params->num_pf_pqs);
500 
501 		/* Update first Tx PQ of VPORT/TC */
502 		vport_id_in_pf = pq_params[i].vport_id - p_params->start_vport;
503 		p_first_tx_pq_id =
504 		    &vport_params[vport_id_in_pf].first_tx_pq_id[tc_id];
505 		if (*p_first_tx_pq_id == QM_INVALID_PQ_ID) {
506 			u32 map_val =
507 				(ext_voq << QM_WFQ_VP_PQ_VOQ_SHIFT) |
508 				(p_params->pf_id << QM_WFQ_VP_PQ_PF_E4_SHIFT);
509 
510 			/* Create new VP PQ */
511 			*p_first_tx_pq_id = pq_id;
512 
513 			/* Map VP PQ to VOQ and PF */
514 			STORE_RT_REG(p_hwfn,
515 				     QM_REG_WFQVPMAP_RT_OFFSET +
516 				     *p_first_tx_pq_id,
517 				     map_val);
518 		}
519 
520 		/* Prepare PQ map entry */
521 		QM_INIT_TX_PQ_MAP(p_hwfn,
522 				  tx_pq_map,
523 				  E4,
524 				  pq_id,
525 				  *p_first_tx_pq_id,
526 				  pq_params[i].rl_valid,
527 				  pq_params[i].rl_id,
528 				  ext_voq, pq_params[i].wrr_group);
529 
530 		/* Set PQ base address */
531 		STORE_RT_REG(p_hwfn,
532 			     QM_REG_BASEADDRTXPQ_RT_OFFSET + pq_id,
533 			     mem_addr_4kb);
534 
535 		/* Clear PQ pointer table entry (64 bit) */
536 		if (p_params->is_pf_loading)
537 			for (j = 0; j < 2; j++)
538 				STORE_RT_REG(p_hwfn,
539 					     QM_REG_PTRTBLTX_RT_OFFSET +
540 					     (pq_id * 2) + j, 0);
541 
542 		/* Write PQ info to RAM */
543 		if (WRITE_PQ_INFO_TO_RAM != 0) {
544 			u32 pq_info = 0;
545 
546 			pq_info = PQ_INFO_ELEMENT(*p_first_tx_pq_id,
547 						  p_params->pf_id,
548 						  tc_id,
549 						  pq_params[i].port_id,
550 						  pq_params[i].rl_valid,
551 						  pq_params[i].rl_id);
552 			qed_wr(p_hwfn, p_ptt, PQ_INFO_RAM_GRC_ADDRESS(pq_id),
553 			       pq_info);
554 		}
555 
556 		/* If VF PQ, add indication to PQ VF mask */
557 		if (is_vf_pq) {
558 			tx_pq_vf_mask[pq_id /
559 				      QM_PF_QUEUE_GROUP_SIZE] |=
560 			    BIT((pq_id % QM_PF_QUEUE_GROUP_SIZE));
561 			mem_addr_4kb += vport_pq_mem_4kb;
562 		} else {
563 			mem_addr_4kb += pq_mem_4kb;
564 		}
565 	}
566 
567 	/* Store Tx PQ VF mask to size select register */
568 	for (i = 0; i < num_tx_pq_vf_masks; i++)
569 		if (tx_pq_vf_mask[i])
570 			STORE_RT_REG(p_hwfn,
571 				     QM_REG_MAXPQSIZETXSEL_0_RT_OFFSET + i,
572 				     tx_pq_vf_mask[i]);
573 }
574 
575 /* Prepare Other PQ mapping runtime init values for the specified PF */
qed_other_pq_map_rt_init(struct qed_hwfn * p_hwfn,u8 pf_id,bool is_pf_loading,u32 num_pf_cids,u32 num_tids,u32 base_mem_addr_4kb)576 static void qed_other_pq_map_rt_init(struct qed_hwfn *p_hwfn,
577 				     u8 pf_id,
578 				     bool is_pf_loading,
579 				     u32 num_pf_cids,
580 				     u32 num_tids, u32 base_mem_addr_4kb)
581 {
582 	u32 pq_size, pq_mem_4kb, mem_addr_4kb;
583 	u16 i, j, pq_id, pq_group;
584 
585 	/* A single other PQ group is used in each PF, where PQ group i is used
586 	 * in PF i.
587 	 */
588 	pq_group = pf_id;
589 	pq_size = num_pf_cids + num_tids;
590 	pq_mem_4kb = QM_PQ_MEM_4KB(pq_size);
591 	mem_addr_4kb = base_mem_addr_4kb;
592 
593 	/* Map PQ group to PF */
594 	STORE_RT_REG(p_hwfn, QM_REG_PQOTHER2PF_0_RT_OFFSET + pq_group,
595 		     (u32)(pf_id));
596 
597 	/* Set PQ sizes */
598 	STORE_RT_REG(p_hwfn, QM_REG_MAXPQSIZE_2_RT_OFFSET,
599 		     QM_PQ_SIZE_256B(pq_size));
600 
601 	for (i = 0, pq_id = pf_id * QM_PF_QUEUE_GROUP_SIZE;
602 	     i < QM_OTHER_PQS_PER_PF; i++, pq_id++) {
603 		/* Set PQ base address */
604 		STORE_RT_REG(p_hwfn,
605 			     QM_REG_BASEADDROTHERPQ_RT_OFFSET + pq_id,
606 			     mem_addr_4kb);
607 
608 		/* Clear PQ pointer table entry */
609 		if (is_pf_loading)
610 			for (j = 0; j < 2; j++)
611 				STORE_RT_REG(p_hwfn,
612 					     QM_REG_PTRTBLOTHER_RT_OFFSET +
613 					     (pq_id * 2) + j, 0);
614 
615 		mem_addr_4kb += pq_mem_4kb;
616 	}
617 }
618 
619 /* Prepare PF WFQ runtime init values for the specified PF.
620  * Return -1 on error.
621  */
qed_pf_wfq_rt_init(struct qed_hwfn * p_hwfn,struct qed_qm_pf_rt_init_params * p_params)622 static int qed_pf_wfq_rt_init(struct qed_hwfn *p_hwfn,
623 
624 			      struct qed_qm_pf_rt_init_params *p_params)
625 {
626 	u16 num_tx_pqs = p_params->num_pf_pqs + p_params->num_vf_pqs;
627 	struct init_qm_pq_params *pq_params = p_params->pq_params;
628 	u32 inc_val, crd_reg_offset;
629 	u8 ext_voq;
630 	u16 i;
631 
632 	inc_val = QM_WFQ_INC_VAL(p_params->pf_wfq);
633 	if (!inc_val || inc_val > QM_WFQ_MAX_INC_VAL) {
634 		DP_NOTICE(p_hwfn, "Invalid PF WFQ weight configuration\n");
635 		return -1;
636 	}
637 
638 	for (i = 0; i < num_tx_pqs; i++) {
639 		ext_voq = qed_get_ext_voq(p_hwfn,
640 					  pq_params[i].port_id,
641 					  pq_params[i].tc_id,
642 					  p_params->max_phys_tcs_per_port);
643 		crd_reg_offset =
644 			(p_params->pf_id < MAX_NUM_PFS_BB ?
645 			 QM_REG_WFQPFCRD_RT_OFFSET :
646 			 QM_REG_WFQPFCRD_MSB_RT_OFFSET) +
647 			ext_voq * MAX_NUM_PFS_BB +
648 			(p_params->pf_id % MAX_NUM_PFS_BB);
649 		OVERWRITE_RT_REG(p_hwfn,
650 				 crd_reg_offset, (u32)QM_WFQ_CRD_REG_SIGN_BIT);
651 	}
652 
653 	STORE_RT_REG(p_hwfn,
654 		     QM_REG_WFQPFUPPERBOUND_RT_OFFSET + p_params->pf_id,
655 		     QM_WFQ_UPPER_BOUND | (u32)QM_WFQ_CRD_REG_SIGN_BIT);
656 	STORE_RT_REG(p_hwfn, QM_REG_WFQPFWEIGHT_RT_OFFSET + p_params->pf_id,
657 		     inc_val);
658 
659 	return 0;
660 }
661 
662 /* Prepare PF RL runtime init values for the specified PF.
663  * Return -1 on error.
664  */
qed_pf_rl_rt_init(struct qed_hwfn * p_hwfn,u8 pf_id,u32 pf_rl)665 static int qed_pf_rl_rt_init(struct qed_hwfn *p_hwfn, u8 pf_id, u32 pf_rl)
666 {
667 	u32 inc_val = QM_RL_INC_VAL(pf_rl);
668 
669 	if (inc_val > QM_PF_RL_MAX_INC_VAL) {
670 		DP_NOTICE(p_hwfn, "Invalid PF rate limit configuration\n");
671 		return -1;
672 	}
673 
674 	STORE_RT_REG(p_hwfn,
675 		     QM_REG_RLPFCRD_RT_OFFSET + pf_id,
676 		     (u32)QM_RL_CRD_REG_SIGN_BIT);
677 	STORE_RT_REG(p_hwfn,
678 		     QM_REG_RLPFUPPERBOUND_RT_OFFSET + pf_id,
679 		     QM_PF_RL_UPPER_BOUND | (u32)QM_RL_CRD_REG_SIGN_BIT);
680 	STORE_RT_REG(p_hwfn, QM_REG_RLPFINCVAL_RT_OFFSET + pf_id, inc_val);
681 
682 	return 0;
683 }
684 
685 /* Prepare VPORT WFQ runtime init values for the specified VPORTs.
686  * Return -1 on error.
687  */
qed_vp_wfq_rt_init(struct qed_hwfn * p_hwfn,u16 num_vports,struct init_qm_vport_params * vport_params)688 static int qed_vp_wfq_rt_init(struct qed_hwfn *p_hwfn,
689 			      u16 num_vports,
690 			      struct init_qm_vport_params *vport_params)
691 {
692 	u16 vport_pq_id, i;
693 	u32 inc_val;
694 	u8 tc;
695 
696 	/* Go over all PF VPORTs */
697 	for (i = 0; i < num_vports; i++) {
698 		if (!vport_params[i].wfq)
699 			continue;
700 
701 		inc_val = QM_WFQ_INC_VAL(vport_params[i].wfq);
702 		if (inc_val > QM_WFQ_MAX_INC_VAL) {
703 			DP_NOTICE(p_hwfn,
704 				  "Invalid VPORT WFQ weight configuration\n");
705 			return -1;
706 		}
707 
708 		/* Each VPORT can have several VPORT PQ IDs for various TCs */
709 		for (tc = 0; tc < NUM_OF_TCS; tc++) {
710 			vport_pq_id = vport_params[i].first_tx_pq_id[tc];
711 			if (vport_pq_id != QM_INVALID_PQ_ID) {
712 				STORE_RT_REG(p_hwfn,
713 					     QM_REG_WFQVPCRD_RT_OFFSET +
714 					     vport_pq_id,
715 					     (u32)QM_WFQ_CRD_REG_SIGN_BIT);
716 				STORE_RT_REG(p_hwfn,
717 					     QM_REG_WFQVPWEIGHT_RT_OFFSET +
718 					     vport_pq_id, inc_val);
719 			}
720 		}
721 	}
722 
723 	return 0;
724 }
725 
qed_poll_on_qm_cmd_ready(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt)726 static bool qed_poll_on_qm_cmd_ready(struct qed_hwfn *p_hwfn,
727 				     struct qed_ptt *p_ptt)
728 {
729 	u32 reg_val, i;
730 
731 	for (i = 0, reg_val = 0; i < QM_STOP_CMD_MAX_POLL_COUNT && !reg_val;
732 	     i++) {
733 		udelay(QM_STOP_CMD_POLL_PERIOD_US);
734 		reg_val = qed_rd(p_hwfn, p_ptt, QM_REG_SDMCMDREADY);
735 	}
736 
737 	/* Check if timeout while waiting for SDM command ready */
738 	if (i == QM_STOP_CMD_MAX_POLL_COUNT) {
739 		DP_VERBOSE(p_hwfn, NETIF_MSG_HW,
740 			   "Timeout when waiting for QM SDM command ready signal\n");
741 		return false;
742 	}
743 
744 	return true;
745 }
746 
qed_send_qm_cmd(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u32 cmd_addr,u32 cmd_data_lsb,u32 cmd_data_msb)747 static bool qed_send_qm_cmd(struct qed_hwfn *p_hwfn,
748 			    struct qed_ptt *p_ptt,
749 			    u32 cmd_addr, u32 cmd_data_lsb, u32 cmd_data_msb)
750 {
751 	if (!qed_poll_on_qm_cmd_ready(p_hwfn, p_ptt))
752 		return false;
753 
754 	qed_wr(p_hwfn, p_ptt, QM_REG_SDMCMDADDR, cmd_addr);
755 	qed_wr(p_hwfn, p_ptt, QM_REG_SDMCMDDATALSB, cmd_data_lsb);
756 	qed_wr(p_hwfn, p_ptt, QM_REG_SDMCMDDATAMSB, cmd_data_msb);
757 	qed_wr(p_hwfn, p_ptt, QM_REG_SDMCMDGO, 1);
758 	qed_wr(p_hwfn, p_ptt, QM_REG_SDMCMDGO, 0);
759 
760 	return qed_poll_on_qm_cmd_ready(p_hwfn, p_ptt);
761 }
762 
763 /******************** INTERFACE IMPLEMENTATION *********************/
764 
qed_qm_pf_mem_size(u32 num_pf_cids,u32 num_vf_cids,u32 num_tids,u16 num_pf_pqs,u16 num_vf_pqs)765 u32 qed_qm_pf_mem_size(u32 num_pf_cids,
766 		       u32 num_vf_cids,
767 		       u32 num_tids, u16 num_pf_pqs, u16 num_vf_pqs)
768 {
769 	return QM_PQ_MEM_4KB(num_pf_cids) * num_pf_pqs +
770 	       QM_PQ_MEM_4KB(num_vf_cids) * num_vf_pqs +
771 	       QM_PQ_MEM_4KB(num_pf_cids + num_tids) * QM_OTHER_PQS_PER_PF;
772 }
773 
qed_qm_common_rt_init(struct qed_hwfn * p_hwfn,struct qed_qm_common_rt_init_params * p_params)774 int qed_qm_common_rt_init(struct qed_hwfn *p_hwfn,
775 			  struct qed_qm_common_rt_init_params *p_params)
776 {
777 	u32 mask = 0;
778 
779 	/* Init AFullOprtnstcCrdMask */
780 	SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_LINEVOQ,
781 		  QM_OPPOR_LINE_VOQ_DEF);
782 	SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_BYTEVOQ, QM_BYTE_CRD_EN);
783 	SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_PFWFQ, p_params->pf_wfq_en);
784 	SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_VPWFQ, p_params->vport_wfq_en);
785 	SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_PFRL, p_params->pf_rl_en);
786 	SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_VPQCNRL,
787 		  p_params->global_rl_en);
788 	SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_FWPAUSE, QM_OPPOR_FW_STOP_DEF);
789 	SET_FIELD(mask,
790 		  QM_RF_OPPORTUNISTIC_MASK_QUEUEEMPTY, QM_OPPOR_PQ_EMPTY_DEF);
791 	STORE_RT_REG(p_hwfn, QM_REG_AFULLOPRTNSTCCRDMASK_RT_OFFSET, mask);
792 
793 	/* Enable/disable PF RL */
794 	qed_enable_pf_rl(p_hwfn, p_params->pf_rl_en);
795 
796 	/* Enable/disable PF WFQ */
797 	qed_enable_pf_wfq(p_hwfn, p_params->pf_wfq_en);
798 
799 	/* Enable/disable global RL */
800 	qed_enable_global_rl(p_hwfn, p_params->global_rl_en);
801 
802 	/* Enable/disable VPORT WFQ */
803 	qed_enable_vport_wfq(p_hwfn, p_params->vport_wfq_en);
804 
805 	/* Init PBF CMDQ line credit */
806 	qed_cmdq_lines_rt_init(p_hwfn,
807 			       p_params->max_ports_per_engine,
808 			       p_params->max_phys_tcs_per_port,
809 			       p_params->port_params);
810 
811 	/* Init BTB blocks in PBF */
812 	qed_btb_blocks_rt_init(p_hwfn,
813 			       p_params->max_ports_per_engine,
814 			       p_params->max_phys_tcs_per_port,
815 			       p_params->port_params);
816 
817 	qed_global_rl_rt_init(p_hwfn);
818 
819 	return 0;
820 }
821 
qed_qm_pf_rt_init(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,struct qed_qm_pf_rt_init_params * p_params)822 int qed_qm_pf_rt_init(struct qed_hwfn *p_hwfn,
823 		      struct qed_ptt *p_ptt,
824 		      struct qed_qm_pf_rt_init_params *p_params)
825 {
826 	struct init_qm_vport_params *vport_params = p_params->vport_params;
827 	u32 other_mem_size_4kb = QM_PQ_MEM_4KB(p_params->num_pf_cids +
828 					       p_params->num_tids) *
829 				 QM_OTHER_PQS_PER_PF;
830 	u16 i;
831 	u8 tc;
832 
833 
834 	/* Clear first Tx PQ ID array for each VPORT */
835 	for (i = 0; i < p_params->num_vports; i++)
836 		for (tc = 0; tc < NUM_OF_TCS; tc++)
837 			vport_params[i].first_tx_pq_id[tc] = QM_INVALID_PQ_ID;
838 
839 	/* Map Other PQs (if any) */
840 	qed_other_pq_map_rt_init(p_hwfn,
841 				 p_params->pf_id,
842 				 p_params->is_pf_loading, p_params->num_pf_cids,
843 				 p_params->num_tids, 0);
844 
845 	/* Map Tx PQs */
846 	qed_tx_pq_map_rt_init(p_hwfn, p_ptt, p_params, other_mem_size_4kb);
847 
848 	/* Init PF WFQ */
849 	if (p_params->pf_wfq)
850 		if (qed_pf_wfq_rt_init(p_hwfn, p_params))
851 			return -1;
852 
853 	/* Init PF RL */
854 	if (qed_pf_rl_rt_init(p_hwfn, p_params->pf_id, p_params->pf_rl))
855 		return -1;
856 
857 	/* Init VPORT WFQ */
858 	if (qed_vp_wfq_rt_init(p_hwfn, p_params->num_vports, vport_params))
859 		return -1;
860 
861 	return 0;
862 }
863 
qed_init_pf_wfq(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u8 pf_id,u16 pf_wfq)864 int qed_init_pf_wfq(struct qed_hwfn *p_hwfn,
865 		    struct qed_ptt *p_ptt, u8 pf_id, u16 pf_wfq)
866 {
867 	u32 inc_val = QM_WFQ_INC_VAL(pf_wfq);
868 
869 	if (!inc_val || inc_val > QM_WFQ_MAX_INC_VAL) {
870 		DP_NOTICE(p_hwfn, "Invalid PF WFQ weight configuration\n");
871 		return -1;
872 	}
873 
874 	qed_wr(p_hwfn, p_ptt, QM_REG_WFQPFWEIGHT + pf_id * 4, inc_val);
875 
876 	return 0;
877 }
878 
qed_init_pf_rl(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u8 pf_id,u32 pf_rl)879 int qed_init_pf_rl(struct qed_hwfn *p_hwfn,
880 		   struct qed_ptt *p_ptt, u8 pf_id, u32 pf_rl)
881 {
882 	u32 inc_val = QM_RL_INC_VAL(pf_rl);
883 
884 	if (inc_val > QM_PF_RL_MAX_INC_VAL) {
885 		DP_NOTICE(p_hwfn, "Invalid PF rate limit configuration\n");
886 		return -1;
887 	}
888 
889 	qed_wr(p_hwfn,
890 	       p_ptt, QM_REG_RLPFCRD + pf_id * 4, (u32)QM_RL_CRD_REG_SIGN_BIT);
891 	qed_wr(p_hwfn, p_ptt, QM_REG_RLPFINCVAL + pf_id * 4, inc_val);
892 
893 	return 0;
894 }
895 
qed_init_vport_wfq(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u16 first_tx_pq_id[NUM_OF_TCS],u16 wfq)896 int qed_init_vport_wfq(struct qed_hwfn *p_hwfn,
897 		       struct qed_ptt *p_ptt,
898 		       u16 first_tx_pq_id[NUM_OF_TCS], u16 wfq)
899 {
900 	u16 vport_pq_id;
901 	u32 inc_val;
902 	u8 tc;
903 
904 	inc_val = QM_WFQ_INC_VAL(wfq);
905 	if (!inc_val || inc_val > QM_WFQ_MAX_INC_VAL) {
906 		DP_NOTICE(p_hwfn, "Invalid VPORT WFQ configuration.\n");
907 		return -1;
908 	}
909 
910 	/* A VPORT can have several VPORT PQ IDs for various TCs */
911 	for (tc = 0; tc < NUM_OF_TCS; tc++) {
912 		vport_pq_id = first_tx_pq_id[tc];
913 		if (vport_pq_id != QM_INVALID_PQ_ID)
914 			qed_wr(p_hwfn,
915 			       p_ptt,
916 			       QM_REG_WFQVPWEIGHT + vport_pq_id * 4, inc_val);
917 	}
918 
919 	return 0;
920 }
921 
qed_init_global_rl(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u16 rl_id,u32 rate_limit)922 int qed_init_global_rl(struct qed_hwfn *p_hwfn,
923 		       struct qed_ptt *p_ptt, u16 rl_id, u32 rate_limit)
924 {
925 	u32 inc_val;
926 
927 	inc_val = QM_RL_INC_VAL(rate_limit);
928 	if (inc_val > QM_VP_RL_MAX_INC_VAL(rate_limit)) {
929 		DP_NOTICE(p_hwfn, "Invalid rate limit configuration.\n");
930 		return -1;
931 	}
932 
933 	qed_wr(p_hwfn, p_ptt,
934 	       QM_REG_RLGLBLCRD + rl_id * 4, (u32)QM_RL_CRD_REG_SIGN_BIT);
935 	qed_wr(p_hwfn, p_ptt, QM_REG_RLGLBLINCVAL + rl_id * 4, inc_val);
936 
937 	return 0;
938 }
939 
qed_send_qm_stop_cmd(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,bool is_release_cmd,bool is_tx_pq,u16 start_pq,u16 num_pqs)940 bool qed_send_qm_stop_cmd(struct qed_hwfn *p_hwfn,
941 			  struct qed_ptt *p_ptt,
942 			  bool is_release_cmd,
943 			  bool is_tx_pq, u16 start_pq, u16 num_pqs)
944 {
945 	u32 cmd_arr[QM_CMD_STRUCT_SIZE(QM_STOP_CMD)] = { 0 };
946 	u32 pq_mask = 0, last_pq, pq_id;
947 
948 	last_pq = start_pq + num_pqs - 1;
949 
950 	/* Set command's PQ type */
951 	QM_CMD_SET_FIELD(cmd_arr, QM_STOP_CMD, PQ_TYPE, is_tx_pq ? 0 : 1);
952 
953 	/* Go over requested PQs */
954 	for (pq_id = start_pq; pq_id <= last_pq; pq_id++) {
955 		/* Set PQ bit in mask (stop command only) */
956 		if (!is_release_cmd)
957 			pq_mask |= BIT((pq_id % QM_STOP_PQ_MASK_WIDTH));
958 
959 		/* If last PQ or end of PQ mask, write command */
960 		if ((pq_id == last_pq) ||
961 		    (pq_id % QM_STOP_PQ_MASK_WIDTH ==
962 		     (QM_STOP_PQ_MASK_WIDTH - 1))) {
963 			QM_CMD_SET_FIELD(cmd_arr,
964 					 QM_STOP_CMD, PAUSE_MASK, pq_mask);
965 			QM_CMD_SET_FIELD(cmd_arr,
966 					 QM_STOP_CMD,
967 					 GROUP_ID,
968 					 pq_id / QM_STOP_PQ_MASK_WIDTH);
969 			if (!qed_send_qm_cmd(p_hwfn, p_ptt, QM_STOP_CMD_ADDR,
970 					     cmd_arr[0], cmd_arr[1]))
971 				return false;
972 			pq_mask = 0;
973 		}
974 	}
975 
976 	return true;
977 }
978 
979 #define SET_TUNNEL_TYPE_ENABLE_BIT(var, offset, enable) \
980 	do { \
981 		typeof(var) *__p_var = &(var); \
982 		typeof(offset) __offset = offset; \
983 		*__p_var = (*__p_var & ~BIT(__offset)) | \
984 			   ((enable) ? BIT(__offset) : 0); \
985 	} while (0)
986 
987 #define PRS_ETH_TUNN_OUTPUT_FORMAT     0xF4DAB910
988 #define PRS_ETH_OUTPUT_FORMAT          0xFFFF4910
989 
990 #define ARR_REG_WR(dev, ptt, addr, arr,	arr_size) \
991 	do { \
992 		u32 i; \
993 		\
994 		for (i = 0; i < (arr_size); i++) \
995 			qed_wr(dev, ptt, \
996 			       ((addr) + (4 * i)), \
997 			       ((u32 *)&(arr))[i]); \
998 	} while (0)
999 
1000 /**
1001  * qed_dmae_to_grc() - Internal function for writing from host to
1002  * wide-bus registers (split registers are not supported yet).
1003  *
1004  * @p_hwfn: HW device data.
1005  * @p_ptt: PTT window used for writing the registers.
1006  * @p_data: Pointer to source data.
1007  * @addr: Destination register address.
1008  * @len_in_dwords: Data length in dwords (u32).
1009  *
1010  * Return: Length of the written data in dwords (u32) or -1 on invalid
1011  *         input.
1012  */
qed_dmae_to_grc(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,__le32 * p_data,u32 addr,u32 len_in_dwords)1013 static int qed_dmae_to_grc(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
1014 			   __le32 *p_data, u32 addr, u32 len_in_dwords)
1015 {
1016 	struct qed_dmae_params params = {};
1017 	u32 *data_cpu;
1018 	int rc;
1019 
1020 	if (!p_data)
1021 		return -1;
1022 
1023 	/* Set DMAE params */
1024 	SET_FIELD(params.flags, QED_DMAE_PARAMS_COMPLETION_DST, 1);
1025 
1026 	/* Execute DMAE command */
1027 	rc = qed_dmae_host2grc(p_hwfn, p_ptt,
1028 			       (u64)(uintptr_t)(p_data),
1029 			       addr, len_in_dwords, &params);
1030 
1031 	/* If not read using DMAE, read using GRC */
1032 	if (rc) {
1033 		DP_VERBOSE(p_hwfn,
1034 			   QED_MSG_DEBUG,
1035 			   "Failed writing to chip using DMAE, using GRC instead\n");
1036 
1037 		/* Swap to CPU byteorder and write to registers using GRC */
1038 		data_cpu = (__force u32 *)p_data;
1039 		le32_to_cpu_array(data_cpu, len_in_dwords);
1040 
1041 		ARR_REG_WR(p_hwfn, p_ptt, addr, data_cpu, len_in_dwords);
1042 		cpu_to_le32_array(data_cpu, len_in_dwords);
1043 	}
1044 
1045 	return len_in_dwords;
1046 }
1047 
qed_set_vxlan_dest_port(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u16 dest_port)1048 void qed_set_vxlan_dest_port(struct qed_hwfn *p_hwfn,
1049 			     struct qed_ptt *p_ptt, u16 dest_port)
1050 {
1051 	/* Update PRS register */
1052 	qed_wr(p_hwfn, p_ptt, PRS_REG_VXLAN_PORT, dest_port);
1053 
1054 	/* Update NIG register */
1055 	qed_wr(p_hwfn, p_ptt, NIG_REG_VXLAN_CTRL, dest_port);
1056 
1057 	/* Update PBF register */
1058 	qed_wr(p_hwfn, p_ptt, PBF_REG_VXLAN_PORT, dest_port);
1059 }
1060 
qed_set_vxlan_enable(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,bool vxlan_enable)1061 void qed_set_vxlan_enable(struct qed_hwfn *p_hwfn,
1062 			  struct qed_ptt *p_ptt, bool vxlan_enable)
1063 {
1064 	u32 reg_val;
1065 	u8 shift;
1066 
1067 	/* Update PRS register */
1068 	reg_val = qed_rd(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN);
1069 	shift = PRS_REG_ENCAPSULATION_TYPE_EN_VXLAN_ENABLE_SHIFT;
1070 	SET_TUNNEL_TYPE_ENABLE_BIT(reg_val, shift, vxlan_enable);
1071 	qed_wr(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN, reg_val);
1072 	if (reg_val) {
1073 		reg_val =
1074 		    qed_rd(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0_BB_K2);
1075 
1076 		/* Update output  only if tunnel blocks not included. */
1077 		if (reg_val == (u32)PRS_ETH_OUTPUT_FORMAT)
1078 			qed_wr(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0_BB_K2,
1079 			       (u32)PRS_ETH_TUNN_OUTPUT_FORMAT);
1080 	}
1081 
1082 	/* Update NIG register */
1083 	reg_val = qed_rd(p_hwfn, p_ptt, NIG_REG_ENC_TYPE_ENABLE);
1084 	shift = NIG_REG_ENC_TYPE_ENABLE_VXLAN_ENABLE_SHIFT;
1085 	SET_TUNNEL_TYPE_ENABLE_BIT(reg_val, shift, vxlan_enable);
1086 	qed_wr(p_hwfn, p_ptt, NIG_REG_ENC_TYPE_ENABLE, reg_val);
1087 
1088 	/* Update DORQ register */
1089 	qed_wr(p_hwfn,
1090 	       p_ptt, DORQ_REG_L2_EDPM_TUNNEL_VXLAN_EN, vxlan_enable ? 1 : 0);
1091 }
1092 
qed_set_gre_enable(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,bool eth_gre_enable,bool ip_gre_enable)1093 void qed_set_gre_enable(struct qed_hwfn *p_hwfn,
1094 			struct qed_ptt *p_ptt,
1095 			bool eth_gre_enable, bool ip_gre_enable)
1096 {
1097 	u32 reg_val;
1098 	u8 shift;
1099 
1100 	/* Update PRS register */
1101 	reg_val = qed_rd(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN);
1102 	shift = PRS_REG_ENCAPSULATION_TYPE_EN_ETH_OVER_GRE_ENABLE_SHIFT;
1103 	SET_TUNNEL_TYPE_ENABLE_BIT(reg_val, shift, eth_gre_enable);
1104 	shift = PRS_REG_ENCAPSULATION_TYPE_EN_IP_OVER_GRE_ENABLE_SHIFT;
1105 	SET_TUNNEL_TYPE_ENABLE_BIT(reg_val, shift, ip_gre_enable);
1106 	qed_wr(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN, reg_val);
1107 	if (reg_val) {
1108 		reg_val =
1109 		    qed_rd(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0_BB_K2);
1110 
1111 		/* Update output  only if tunnel blocks not included. */
1112 		if (reg_val == (u32)PRS_ETH_OUTPUT_FORMAT)
1113 			qed_wr(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0_BB_K2,
1114 			       (u32)PRS_ETH_TUNN_OUTPUT_FORMAT);
1115 	}
1116 
1117 	/* Update NIG register */
1118 	reg_val = qed_rd(p_hwfn, p_ptt, NIG_REG_ENC_TYPE_ENABLE);
1119 	shift = NIG_REG_ENC_TYPE_ENABLE_ETH_OVER_GRE_ENABLE_SHIFT;
1120 	SET_TUNNEL_TYPE_ENABLE_BIT(reg_val, shift, eth_gre_enable);
1121 	shift = NIG_REG_ENC_TYPE_ENABLE_IP_OVER_GRE_ENABLE_SHIFT;
1122 	SET_TUNNEL_TYPE_ENABLE_BIT(reg_val, shift, ip_gre_enable);
1123 	qed_wr(p_hwfn, p_ptt, NIG_REG_ENC_TYPE_ENABLE, reg_val);
1124 
1125 	/* Update DORQ registers */
1126 	qed_wr(p_hwfn,
1127 	       p_ptt,
1128 	       DORQ_REG_L2_EDPM_TUNNEL_GRE_ETH_EN, eth_gre_enable ? 1 : 0);
1129 	qed_wr(p_hwfn,
1130 	       p_ptt, DORQ_REG_L2_EDPM_TUNNEL_GRE_IP_EN, ip_gre_enable ? 1 : 0);
1131 }
1132 
qed_set_geneve_dest_port(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u16 dest_port)1133 void qed_set_geneve_dest_port(struct qed_hwfn *p_hwfn,
1134 			      struct qed_ptt *p_ptt, u16 dest_port)
1135 {
1136 	/* Update PRS register */
1137 	qed_wr(p_hwfn, p_ptt, PRS_REG_NGE_PORT, dest_port);
1138 
1139 	/* Update NIG register */
1140 	qed_wr(p_hwfn, p_ptt, NIG_REG_NGE_PORT, dest_port);
1141 
1142 	/* Update PBF register */
1143 	qed_wr(p_hwfn, p_ptt, PBF_REG_NGE_PORT, dest_port);
1144 }
1145 
qed_set_geneve_enable(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,bool eth_geneve_enable,bool ip_geneve_enable)1146 void qed_set_geneve_enable(struct qed_hwfn *p_hwfn,
1147 			   struct qed_ptt *p_ptt,
1148 			   bool eth_geneve_enable, bool ip_geneve_enable)
1149 {
1150 	u32 reg_val;
1151 	u8 shift;
1152 
1153 	/* Update PRS register */
1154 	reg_val = qed_rd(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN);
1155 	shift = PRS_REG_ENCAPSULATION_TYPE_EN_ETH_OVER_GENEVE_ENABLE_SHIFT;
1156 	SET_TUNNEL_TYPE_ENABLE_BIT(reg_val, shift, eth_geneve_enable);
1157 	shift = PRS_REG_ENCAPSULATION_TYPE_EN_IP_OVER_GENEVE_ENABLE_SHIFT;
1158 	SET_TUNNEL_TYPE_ENABLE_BIT(reg_val, shift, ip_geneve_enable);
1159 	qed_wr(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN, reg_val);
1160 	if (reg_val) {
1161 		reg_val =
1162 		    qed_rd(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0_BB_K2);
1163 
1164 		/* Update output  only if tunnel blocks not included. */
1165 		if (reg_val == (u32)PRS_ETH_OUTPUT_FORMAT)
1166 			qed_wr(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0_BB_K2,
1167 			       (u32)PRS_ETH_TUNN_OUTPUT_FORMAT);
1168 	}
1169 
1170 	/* Update NIG register */
1171 	qed_wr(p_hwfn, p_ptt, NIG_REG_NGE_ETH_ENABLE,
1172 	       eth_geneve_enable ? 1 : 0);
1173 	qed_wr(p_hwfn, p_ptt, NIG_REG_NGE_IP_ENABLE, ip_geneve_enable ? 1 : 0);
1174 
1175 	/* EDPM with geneve tunnel not supported in BB */
1176 	if (QED_IS_BB_B0(p_hwfn->cdev))
1177 		return;
1178 
1179 	/* Update DORQ registers */
1180 	qed_wr(p_hwfn,
1181 	       p_ptt,
1182 	       DORQ_REG_L2_EDPM_TUNNEL_NGE_ETH_EN_K2_E5,
1183 	       eth_geneve_enable ? 1 : 0);
1184 	qed_wr(p_hwfn,
1185 	       p_ptt,
1186 	       DORQ_REG_L2_EDPM_TUNNEL_NGE_IP_EN_K2_E5,
1187 	       ip_geneve_enable ? 1 : 0);
1188 }
1189 
1190 #define PRS_ETH_VXLAN_NO_L2_ENABLE_OFFSET      3
1191 #define PRS_ETH_VXLAN_NO_L2_OUTPUT_FORMAT   -925189872
1192 
qed_set_vxlan_no_l2_enable(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,bool enable)1193 void qed_set_vxlan_no_l2_enable(struct qed_hwfn *p_hwfn,
1194 				struct qed_ptt *p_ptt, bool enable)
1195 {
1196 	u32 reg_val, cfg_mask;
1197 
1198 	/* read PRS config register */
1199 	reg_val = qed_rd(p_hwfn, p_ptt, PRS_REG_MSG_INFO);
1200 
1201 	/* set VXLAN_NO_L2_ENABLE mask */
1202 	cfg_mask = BIT(PRS_ETH_VXLAN_NO_L2_ENABLE_OFFSET);
1203 
1204 	if (enable) {
1205 		/* set VXLAN_NO_L2_ENABLE flag */
1206 		reg_val |= cfg_mask;
1207 
1208 		/* update PRS FIC  register */
1209 		qed_wr(p_hwfn,
1210 		       p_ptt,
1211 		       PRS_REG_OUTPUT_FORMAT_4_0_BB_K2,
1212 		       (u32)PRS_ETH_VXLAN_NO_L2_OUTPUT_FORMAT);
1213 	} else {
1214 		/* clear VXLAN_NO_L2_ENABLE flag */
1215 		reg_val &= ~cfg_mask;
1216 	}
1217 
1218 	/* write PRS config register */
1219 	qed_wr(p_hwfn, p_ptt, PRS_REG_MSG_INFO, reg_val);
1220 }
1221 
1222 #define T_ETH_PACKET_ACTION_GFT_EVENTID  23
1223 #define PARSER_ETH_CONN_GFT_ACTION_CM_HDR  272
1224 #define T_ETH_PACKET_MATCH_RFS_EVENTID 25
1225 #define PARSER_ETH_CONN_CM_HDR 0
1226 #define CAM_LINE_SIZE sizeof(u32)
1227 #define RAM_LINE_SIZE sizeof(u64)
1228 #define REG_SIZE sizeof(u32)
1229 
qed_gft_disable(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u16 pf_id)1230 void qed_gft_disable(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u16 pf_id)
1231 {
1232 	struct regpair ram_line = { };
1233 
1234 	/* Disable gft search for PF */
1235 	qed_wr(p_hwfn, p_ptt, PRS_REG_SEARCH_GFT, 0);
1236 
1237 	/* Clean ram & cam for next gft session */
1238 
1239 	/* Zero camline */
1240 	qed_wr(p_hwfn, p_ptt, PRS_REG_GFT_CAM + CAM_LINE_SIZE * pf_id, 0);
1241 
1242 	/* Zero ramline */
1243 	qed_dmae_to_grc(p_hwfn, p_ptt, &ram_line.lo,
1244 			PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE * pf_id,
1245 			sizeof(ram_line) / REG_SIZE);
1246 }
1247 
qed_gft_config(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u16 pf_id,bool tcp,bool udp,bool ipv4,bool ipv6,enum gft_profile_type profile_type)1248 void qed_gft_config(struct qed_hwfn *p_hwfn,
1249 		    struct qed_ptt *p_ptt,
1250 		    u16 pf_id,
1251 		    bool tcp,
1252 		    bool udp,
1253 		    bool ipv4, bool ipv6, enum gft_profile_type profile_type)
1254 {
1255 	struct regpair ram_line;
1256 	u32 search_non_ip_as_gft;
1257 	u32 reg_val, cam_line;
1258 	u32 lo = 0, hi = 0;
1259 
1260 	if (!ipv6 && !ipv4)
1261 		DP_NOTICE(p_hwfn,
1262 			  "gft_config: must accept at least on of - ipv4 or ipv6'\n");
1263 	if (!tcp && !udp)
1264 		DP_NOTICE(p_hwfn,
1265 			  "gft_config: must accept at least on of - udp or tcp\n");
1266 	if (profile_type >= MAX_GFT_PROFILE_TYPE)
1267 		DP_NOTICE(p_hwfn, "gft_config: unsupported gft_profile_type\n");
1268 
1269 	/* Set RFS event ID to be awakened i Tstorm By Prs */
1270 	reg_val = T_ETH_PACKET_MATCH_RFS_EVENTID <<
1271 		  PRS_REG_CM_HDR_GFT_EVENT_ID_SHIFT;
1272 	reg_val |= PARSER_ETH_CONN_CM_HDR << PRS_REG_CM_HDR_GFT_CM_HDR_SHIFT;
1273 	qed_wr(p_hwfn, p_ptt, PRS_REG_CM_HDR_GFT, reg_val);
1274 
1275 	/* Do not load context only cid in PRS on match. */
1276 	qed_wr(p_hwfn, p_ptt, PRS_REG_LOAD_L2_FILTER, 0);
1277 
1278 	/* Do not use tenant ID exist bit for gft search */
1279 	qed_wr(p_hwfn, p_ptt, PRS_REG_SEARCH_TENANT_ID, 0);
1280 
1281 	/* Set Cam */
1282 	cam_line = 0;
1283 	SET_FIELD(cam_line, GFT_CAM_LINE_MAPPED_VALID, 1);
1284 
1285 	/* Filters are per PF!! */
1286 	SET_FIELD(cam_line,
1287 		  GFT_CAM_LINE_MAPPED_PF_ID_MASK,
1288 		  GFT_CAM_LINE_MAPPED_PF_ID_MASK_MASK);
1289 	SET_FIELD(cam_line, GFT_CAM_LINE_MAPPED_PF_ID, pf_id);
1290 
1291 	if (!(tcp && udp)) {
1292 		SET_FIELD(cam_line,
1293 			  GFT_CAM_LINE_MAPPED_UPPER_PROTOCOL_TYPE_MASK,
1294 			  GFT_CAM_LINE_MAPPED_UPPER_PROTOCOL_TYPE_MASK_MASK);
1295 		if (tcp)
1296 			SET_FIELD(cam_line,
1297 				  GFT_CAM_LINE_MAPPED_UPPER_PROTOCOL_TYPE,
1298 				  GFT_PROFILE_TCP_PROTOCOL);
1299 		else
1300 			SET_FIELD(cam_line,
1301 				  GFT_CAM_LINE_MAPPED_UPPER_PROTOCOL_TYPE,
1302 				  GFT_PROFILE_UDP_PROTOCOL);
1303 	}
1304 
1305 	if (!(ipv4 && ipv6)) {
1306 		SET_FIELD(cam_line, GFT_CAM_LINE_MAPPED_IP_VERSION_MASK, 1);
1307 		if (ipv4)
1308 			SET_FIELD(cam_line,
1309 				  GFT_CAM_LINE_MAPPED_IP_VERSION,
1310 				  GFT_PROFILE_IPV4);
1311 		else
1312 			SET_FIELD(cam_line,
1313 				  GFT_CAM_LINE_MAPPED_IP_VERSION,
1314 				  GFT_PROFILE_IPV6);
1315 	}
1316 
1317 	/* Write characteristics to cam */
1318 	qed_wr(p_hwfn, p_ptt, PRS_REG_GFT_CAM + CAM_LINE_SIZE * pf_id,
1319 	       cam_line);
1320 	cam_line =
1321 	    qed_rd(p_hwfn, p_ptt, PRS_REG_GFT_CAM + CAM_LINE_SIZE * pf_id);
1322 
1323 	/* Write line to RAM - compare to filter 4 tuple */
1324 
1325 	/* Search no IP as GFT */
1326 	search_non_ip_as_gft = 0;
1327 
1328 	/* Tunnel type */
1329 	SET_FIELD(lo, GFT_RAM_LINE_TUNNEL_DST_PORT, 1);
1330 	SET_FIELD(lo, GFT_RAM_LINE_TUNNEL_OVER_IP_PROTOCOL, 1);
1331 
1332 	if (profile_type == GFT_PROFILE_TYPE_4_TUPLE) {
1333 		SET_FIELD(hi, GFT_RAM_LINE_DST_IP, 1);
1334 		SET_FIELD(hi, GFT_RAM_LINE_SRC_IP, 1);
1335 		SET_FIELD(hi, GFT_RAM_LINE_OVER_IP_PROTOCOL, 1);
1336 		SET_FIELD(lo, GFT_RAM_LINE_ETHERTYPE, 1);
1337 		SET_FIELD(lo, GFT_RAM_LINE_SRC_PORT, 1);
1338 		SET_FIELD(lo, GFT_RAM_LINE_DST_PORT, 1);
1339 	} else if (profile_type == GFT_PROFILE_TYPE_L4_DST_PORT) {
1340 		SET_FIELD(hi, GFT_RAM_LINE_OVER_IP_PROTOCOL, 1);
1341 		SET_FIELD(lo, GFT_RAM_LINE_ETHERTYPE, 1);
1342 		SET_FIELD(lo, GFT_RAM_LINE_DST_PORT, 1);
1343 	} else if (profile_type == GFT_PROFILE_TYPE_IP_DST_ADDR) {
1344 		SET_FIELD(hi, GFT_RAM_LINE_DST_IP, 1);
1345 		SET_FIELD(lo, GFT_RAM_LINE_ETHERTYPE, 1);
1346 	} else if (profile_type == GFT_PROFILE_TYPE_IP_SRC_ADDR) {
1347 		SET_FIELD(hi, GFT_RAM_LINE_SRC_IP, 1);
1348 		SET_FIELD(lo, GFT_RAM_LINE_ETHERTYPE, 1);
1349 	} else if (profile_type == GFT_PROFILE_TYPE_TUNNEL_TYPE) {
1350 		SET_FIELD(lo, GFT_RAM_LINE_TUNNEL_ETHERTYPE, 1);
1351 
1352 		/* Allow tunneled traffic without inner IP */
1353 		search_non_ip_as_gft = 1;
1354 	}
1355 
1356 	ram_line.lo = cpu_to_le32(lo);
1357 	ram_line.hi = cpu_to_le32(hi);
1358 
1359 	qed_wr(p_hwfn,
1360 	       p_ptt, PRS_REG_SEARCH_NON_IP_AS_GFT, search_non_ip_as_gft);
1361 	qed_dmae_to_grc(p_hwfn, p_ptt, &ram_line.lo,
1362 			PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE * pf_id,
1363 			sizeof(ram_line) / REG_SIZE);
1364 
1365 	/* Set default profile so that no filter match will happen */
1366 	ram_line.lo = cpu_to_le32(0xffffffff);
1367 	ram_line.hi = cpu_to_le32(0x3ff);
1368 	qed_dmae_to_grc(p_hwfn, p_ptt, &ram_line.lo,
1369 			PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE *
1370 			PRS_GFT_CAM_LINES_NO_MATCH,
1371 			sizeof(ram_line) / REG_SIZE);
1372 
1373 	/* Enable gft search */
1374 	qed_wr(p_hwfn, p_ptt, PRS_REG_SEARCH_GFT, 1);
1375 }
1376 
1377 DECLARE_CRC8_TABLE(cdu_crc8_table);
1378 
1379 /* Calculate and return CDU validation byte per connection type/region/cid */
qed_calc_cdu_validation_byte(u8 conn_type,u8 region,u32 cid)1380 static u8 qed_calc_cdu_validation_byte(u8 conn_type, u8 region, u32 cid)
1381 {
1382 	const u8 validation_cfg = CDU_VALIDATION_DEFAULT_CFG;
1383 	u8 crc, validation_byte = 0;
1384 	static u8 crc8_table_valid; /* automatically initialized to 0 */
1385 	u32 validation_string = 0;
1386 	__be32 data_to_crc;
1387 
1388 	if (!crc8_table_valid) {
1389 		crc8_populate_msb(cdu_crc8_table, 0x07);
1390 		crc8_table_valid = 1;
1391 	}
1392 
1393 	/* The CRC is calculated on the String-to-compress:
1394 	 * [31:8]  = {CID[31:20],CID[11:0]}
1395 	 * [7:4]   = Region
1396 	 * [3:0]   = Type
1397 	 */
1398 	if ((validation_cfg >> CDU_CONTEXT_VALIDATION_CFG_USE_CID) & 1)
1399 		validation_string |= (cid & 0xFFF00000) | ((cid & 0xFFF) << 8);
1400 
1401 	if ((validation_cfg >> CDU_CONTEXT_VALIDATION_CFG_USE_REGION) & 1)
1402 		validation_string |= ((region & 0xF) << 4);
1403 
1404 	if ((validation_cfg >> CDU_CONTEXT_VALIDATION_CFG_USE_TYPE) & 1)
1405 		validation_string |= (conn_type & 0xF);
1406 
1407 	/* Convert to big-endian and calculate CRC8 */
1408 	data_to_crc = cpu_to_be32(validation_string);
1409 	crc = crc8(cdu_crc8_table, (u8 *)&data_to_crc, sizeof(data_to_crc),
1410 		   CRC8_INIT_VALUE);
1411 
1412 	/* The validation byte [7:0] is composed:
1413 	 * for type A validation
1414 	 * [7]          = active configuration bit
1415 	 * [6:0]        = crc[6:0]
1416 	 *
1417 	 * for type B validation
1418 	 * [7]          = active configuration bit
1419 	 * [6:3]        = connection_type[3:0]
1420 	 * [2:0]        = crc[2:0]
1421 	 */
1422 	validation_byte |=
1423 	    ((validation_cfg >>
1424 	      CDU_CONTEXT_VALIDATION_CFG_USE_ACTIVE) & 1) << 7;
1425 
1426 	if ((validation_cfg >>
1427 	     CDU_CONTEXT_VALIDATION_CFG_VALIDATION_TYPE_SHIFT) & 1)
1428 		validation_byte |= ((conn_type & 0xF) << 3) | (crc & 0x7);
1429 	else
1430 		validation_byte |= crc & 0x7F;
1431 
1432 	return validation_byte;
1433 }
1434 
1435 /* Calcualte and set validation bytes for session context */
qed_calc_session_ctx_validation(void * p_ctx_mem,u16 ctx_size,u8 ctx_type,u32 cid)1436 void qed_calc_session_ctx_validation(void *p_ctx_mem,
1437 				     u16 ctx_size, u8 ctx_type, u32 cid)
1438 {
1439 	u8 *x_val_ptr, *t_val_ptr, *u_val_ptr, *p_ctx;
1440 
1441 	p_ctx = (u8 * const)p_ctx_mem;
1442 	x_val_ptr = &p_ctx[con_region_offsets[0][ctx_type]];
1443 	t_val_ptr = &p_ctx[con_region_offsets[1][ctx_type]];
1444 	u_val_ptr = &p_ctx[con_region_offsets[2][ctx_type]];
1445 
1446 	memset(p_ctx, 0, ctx_size);
1447 
1448 	*x_val_ptr = qed_calc_cdu_validation_byte(ctx_type, 3, cid);
1449 	*t_val_ptr = qed_calc_cdu_validation_byte(ctx_type, 4, cid);
1450 	*u_val_ptr = qed_calc_cdu_validation_byte(ctx_type, 5, cid);
1451 }
1452 
1453 /* Calcualte and set validation bytes for task context */
qed_calc_task_ctx_validation(void * p_ctx_mem,u16 ctx_size,u8 ctx_type,u32 tid)1454 void qed_calc_task_ctx_validation(void *p_ctx_mem,
1455 				  u16 ctx_size, u8 ctx_type, u32 tid)
1456 {
1457 	u8 *p_ctx, *region1_val_ptr;
1458 
1459 	p_ctx = (u8 * const)p_ctx_mem;
1460 	region1_val_ptr = &p_ctx[task_region_offsets[0][ctx_type]];
1461 
1462 	memset(p_ctx, 0, ctx_size);
1463 
1464 	*region1_val_ptr = qed_calc_cdu_validation_byte(ctx_type, 1, tid);
1465 }
1466 
1467 /* Memset session context to 0 while preserving validation bytes */
qed_memset_session_ctx(void * p_ctx_mem,u32 ctx_size,u8 ctx_type)1468 void qed_memset_session_ctx(void *p_ctx_mem, u32 ctx_size, u8 ctx_type)
1469 {
1470 	u8 *x_val_ptr, *t_val_ptr, *u_val_ptr, *p_ctx;
1471 	u8 x_val, t_val, u_val;
1472 
1473 	p_ctx = (u8 * const)p_ctx_mem;
1474 	x_val_ptr = &p_ctx[con_region_offsets[0][ctx_type]];
1475 	t_val_ptr = &p_ctx[con_region_offsets[1][ctx_type]];
1476 	u_val_ptr = &p_ctx[con_region_offsets[2][ctx_type]];
1477 
1478 	x_val = *x_val_ptr;
1479 	t_val = *t_val_ptr;
1480 	u_val = *u_val_ptr;
1481 
1482 	memset(p_ctx, 0, ctx_size);
1483 
1484 	*x_val_ptr = x_val;
1485 	*t_val_ptr = t_val;
1486 	*u_val_ptr = u_val;
1487 }
1488 
1489 /* Memset task context to 0 while preserving validation bytes */
qed_memset_task_ctx(void * p_ctx_mem,u32 ctx_size,u8 ctx_type)1490 void qed_memset_task_ctx(void *p_ctx_mem, u32 ctx_size, u8 ctx_type)
1491 {
1492 	u8 *p_ctx, *region1_val_ptr;
1493 	u8 region1_val;
1494 
1495 	p_ctx = (u8 * const)p_ctx_mem;
1496 	region1_val_ptr = &p_ctx[task_region_offsets[0][ctx_type]];
1497 
1498 	region1_val = *region1_val_ptr;
1499 
1500 	memset(p_ctx, 0, ctx_size);
1501 
1502 	*region1_val_ptr = region1_val;
1503 }
1504 
1505 /* Enable and configure context validation */
qed_enable_context_validation(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt)1506 void qed_enable_context_validation(struct qed_hwfn *p_hwfn,
1507 				   struct qed_ptt *p_ptt)
1508 {
1509 	u32 ctx_validation;
1510 
1511 	/* Enable validation for connection region 3: CCFC_CTX_VALID0[31:24] */
1512 	ctx_validation = CDU_VALIDATION_DEFAULT_CFG << 24;
1513 	qed_wr(p_hwfn, p_ptt, CDU_REG_CCFC_CTX_VALID0, ctx_validation);
1514 
1515 	/* Enable validation for connection region 5: CCFC_CTX_VALID1[15:8] */
1516 	ctx_validation = CDU_VALIDATION_DEFAULT_CFG << 8;
1517 	qed_wr(p_hwfn, p_ptt, CDU_REG_CCFC_CTX_VALID1, ctx_validation);
1518 
1519 	/* Enable validation for connection region 1: TCFC_CTX_VALID0[15:8] */
1520 	ctx_validation = CDU_VALIDATION_DEFAULT_CFG << 8;
1521 	qed_wr(p_hwfn, p_ptt, CDU_REG_TCFC_CTX_VALID0, ctx_validation);
1522 }
1523 
qed_get_rdma_assert_ram_addr(struct qed_hwfn * p_hwfn,u8 storm_id)1524 static u32 qed_get_rdma_assert_ram_addr(struct qed_hwfn *p_hwfn, u8 storm_id)
1525 {
1526 	switch (storm_id) {
1527 	case 0:
1528 		return TSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1529 		    TSTORM_RDMA_ASSERT_LEVEL_OFFSET(p_hwfn->rel_pf_id);
1530 	case 1:
1531 		return MSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1532 		    MSTORM_RDMA_ASSERT_LEVEL_OFFSET(p_hwfn->rel_pf_id);
1533 	case 2:
1534 		return USEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1535 		    USTORM_RDMA_ASSERT_LEVEL_OFFSET(p_hwfn->rel_pf_id);
1536 	case 3:
1537 		return XSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1538 		    XSTORM_RDMA_ASSERT_LEVEL_OFFSET(p_hwfn->rel_pf_id);
1539 	case 4:
1540 		return YSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1541 		    YSTORM_RDMA_ASSERT_LEVEL_OFFSET(p_hwfn->rel_pf_id);
1542 	case 5:
1543 		return PSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1544 		    PSTORM_RDMA_ASSERT_LEVEL_OFFSET(p_hwfn->rel_pf_id);
1545 
1546 	default:
1547 		return 0;
1548 	}
1549 }
1550 
qed_set_rdma_error_level(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u8 assert_level[NUM_STORMS])1551 void qed_set_rdma_error_level(struct qed_hwfn *p_hwfn,
1552 			      struct qed_ptt *p_ptt,
1553 			      u8 assert_level[NUM_STORMS])
1554 {
1555 	u8 storm_id;
1556 
1557 	for (storm_id = 0; storm_id < NUM_STORMS; storm_id++) {
1558 		u32 ram_addr = qed_get_rdma_assert_ram_addr(p_hwfn, storm_id);
1559 
1560 		qed_wr(p_hwfn, p_ptt, ram_addr, assert_level[storm_id]);
1561 	}
1562 }
1563 
1564 #define PHYS_ADDR_DWORDS        DIV_ROUND_UP(sizeof(dma_addr_t), 4)
1565 #define OVERLAY_HDR_SIZE_DWORDS (sizeof(struct fw_overlay_buf_hdr) / 4)
1566 
qed_get_overlay_addr_ram_addr(struct qed_hwfn * p_hwfn,u8 storm_id)1567 static u32 qed_get_overlay_addr_ram_addr(struct qed_hwfn *p_hwfn, u8 storm_id)
1568 {
1569 	switch (storm_id) {
1570 	case 0:
1571 		return TSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1572 		    TSTORM_OVERLAY_BUF_ADDR_OFFSET;
1573 	case 1:
1574 		return MSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1575 		    MSTORM_OVERLAY_BUF_ADDR_OFFSET;
1576 	case 2:
1577 		return USEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1578 		    USTORM_OVERLAY_BUF_ADDR_OFFSET;
1579 	case 3:
1580 		return XSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1581 		    XSTORM_OVERLAY_BUF_ADDR_OFFSET;
1582 	case 4:
1583 		return YSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1584 		    YSTORM_OVERLAY_BUF_ADDR_OFFSET;
1585 	case 5:
1586 		return PSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1587 		    PSTORM_OVERLAY_BUF_ADDR_OFFSET;
1588 
1589 	default:
1590 		return 0;
1591 	}
1592 }
1593 
qed_fw_overlay_mem_alloc(struct qed_hwfn * p_hwfn,const u32 * const fw_overlay_in_buf,u32 buf_size_in_bytes)1594 struct phys_mem_desc *qed_fw_overlay_mem_alloc(struct qed_hwfn *p_hwfn,
1595 					       const u32 * const
1596 					       fw_overlay_in_buf,
1597 					       u32 buf_size_in_bytes)
1598 {
1599 	u32 buf_size = buf_size_in_bytes / sizeof(u32), buf_offset = 0;
1600 	struct phys_mem_desc *allocated_mem;
1601 
1602 	if (!buf_size)
1603 		return NULL;
1604 
1605 	allocated_mem = kcalloc(NUM_STORMS, sizeof(struct phys_mem_desc),
1606 				GFP_KERNEL);
1607 	if (!allocated_mem)
1608 		return NULL;
1609 
1610 	memset(allocated_mem, 0, NUM_STORMS * sizeof(struct phys_mem_desc));
1611 
1612 	/* For each Storm, set physical address in RAM */
1613 	while (buf_offset < buf_size) {
1614 		struct phys_mem_desc *storm_mem_desc;
1615 		struct fw_overlay_buf_hdr *hdr;
1616 		u32 storm_buf_size;
1617 		u8 storm_id;
1618 
1619 		hdr =
1620 		    (struct fw_overlay_buf_hdr *)&fw_overlay_in_buf[buf_offset];
1621 		storm_buf_size = GET_FIELD(hdr->data,
1622 					   FW_OVERLAY_BUF_HDR_BUF_SIZE);
1623 		storm_id = GET_FIELD(hdr->data, FW_OVERLAY_BUF_HDR_STORM_ID);
1624 		storm_mem_desc = allocated_mem + storm_id;
1625 		storm_mem_desc->size = storm_buf_size * sizeof(u32);
1626 
1627 		/* Allocate physical memory for Storm's overlays buffer */
1628 		storm_mem_desc->virt_addr =
1629 		    dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
1630 				       storm_mem_desc->size,
1631 				       &storm_mem_desc->phys_addr, GFP_KERNEL);
1632 		if (!storm_mem_desc->virt_addr)
1633 			break;
1634 
1635 		/* Skip overlays buffer header */
1636 		buf_offset += OVERLAY_HDR_SIZE_DWORDS;
1637 
1638 		/* Copy Storm's overlays buffer to allocated memory */
1639 		memcpy(storm_mem_desc->virt_addr,
1640 		       &fw_overlay_in_buf[buf_offset], storm_mem_desc->size);
1641 
1642 		/* Advance to next Storm */
1643 		buf_offset += storm_buf_size;
1644 	}
1645 
1646 	/* If memory allocation has failed, free all allocated memory */
1647 	if (buf_offset < buf_size) {
1648 		qed_fw_overlay_mem_free(p_hwfn, allocated_mem);
1649 		return NULL;
1650 	}
1651 
1652 	return allocated_mem;
1653 }
1654 
qed_fw_overlay_init_ram(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,struct phys_mem_desc * fw_overlay_mem)1655 void qed_fw_overlay_init_ram(struct qed_hwfn *p_hwfn,
1656 			     struct qed_ptt *p_ptt,
1657 			     struct phys_mem_desc *fw_overlay_mem)
1658 {
1659 	u8 storm_id;
1660 
1661 	for (storm_id = 0; storm_id < NUM_STORMS; storm_id++) {
1662 		struct phys_mem_desc *storm_mem_desc =
1663 		    (struct phys_mem_desc *)fw_overlay_mem + storm_id;
1664 		u32 ram_addr, i;
1665 
1666 		/* Skip Storms with no FW overlays */
1667 		if (!storm_mem_desc->virt_addr)
1668 			continue;
1669 
1670 		/* Calculate overlay RAM GRC address of current PF */
1671 		ram_addr = qed_get_overlay_addr_ram_addr(p_hwfn, storm_id) +
1672 			   sizeof(dma_addr_t) * p_hwfn->rel_pf_id;
1673 
1674 		/* Write Storm's overlay physical address to RAM */
1675 		for (i = 0; i < PHYS_ADDR_DWORDS; i++, ram_addr += sizeof(u32))
1676 			qed_wr(p_hwfn, p_ptt, ram_addr,
1677 			       ((u32 *)&storm_mem_desc->phys_addr)[i]);
1678 	}
1679 }
1680 
qed_fw_overlay_mem_free(struct qed_hwfn * p_hwfn,struct phys_mem_desc * fw_overlay_mem)1681 void qed_fw_overlay_mem_free(struct qed_hwfn *p_hwfn,
1682 			     struct phys_mem_desc *fw_overlay_mem)
1683 {
1684 	u8 storm_id;
1685 
1686 	if (!fw_overlay_mem)
1687 		return;
1688 
1689 	for (storm_id = 0; storm_id < NUM_STORMS; storm_id++) {
1690 		struct phys_mem_desc *storm_mem_desc =
1691 		    (struct phys_mem_desc *)fw_overlay_mem + storm_id;
1692 
1693 		/* Free Storm's physical memory */
1694 		if (storm_mem_desc->virt_addr)
1695 			dma_free_coherent(&p_hwfn->cdev->pdev->dev,
1696 					  storm_mem_desc->size,
1697 					  storm_mem_desc->virt_addr,
1698 					  storm_mem_desc->phys_addr);
1699 	}
1700 
1701 	/* Free allocated virtual memory */
1702 	kfree(fw_overlay_mem);
1703 }
1704