11f4d4ed6SAlexander Lobakin // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2fe56b9e6SYuval Mintz /* QLogic qed NIC Driver
3e8f1cb50SMintz, Yuval  * Copyright (c) 2015-2017  QLogic Corporation
4b90cb538SOmkar Kulkarni  * Copyright (c) 2019-2021 Marvell International Ltd.
5fe56b9e6SYuval Mintz  */
6fe56b9e6SYuval Mintz 
7fe56b9e6SYuval Mintz #include <linux/types.h>
8da090917STomer Tayar #include <linux/crc8.h>
9fe56b9e6SYuval Mintz #include <linux/delay.h>
10fe56b9e6SYuval Mintz #include <linux/kernel.h>
11fe56b9e6SYuval Mintz #include <linux/slab.h>
12fe56b9e6SYuval Mintz #include <linux/string.h>
13fe56b9e6SYuval Mintz #include "qed_hsi.h"
14fe56b9e6SYuval Mintz #include "qed_hw.h"
15fe56b9e6SYuval Mintz #include "qed_init_ops.h"
16ee824f4bSOmkar Kulkarni #include "qed_iro_hsi.h"
17fe56b9e6SYuval Mintz #include "qed_reg_addr.h"
18fe56b9e6SYuval Mintz 
19b90cb538SOmkar Kulkarni #define CDU_VALIDATION_DEFAULT_CFG CDU_CONTEXT_VALIDATION_DEFAULT_CFG
20da090917STomer Tayar 
21fb09a1edSShai Malin static u16 con_region_offsets[3][NUM_OF_CONNECTION_TYPES] = {
226aebde8dSMichal Kalderon 	{400, 336, 352, 368, 304, 384, 416, 352},	/* region 3 offsets */
236aebde8dSMichal Kalderon 	{528, 496, 416, 512, 448, 512, 544, 480},	/* region 4 offsets */
246aebde8dSMichal Kalderon 	{608, 544, 496, 576, 576, 592, 624, 560}	/* region 5 offsets */
25da090917STomer Tayar };
26da090917STomer Tayar 
27fb09a1edSShai Malin static u16 task_region_offsets[1][NUM_OF_CONNECTION_TYPES] = {
28da090917STomer Tayar 	{240, 240, 112, 0, 0, 0, 0, 96}	/* region 1 offsets */
29da090917STomer Tayar };
30da090917STomer Tayar 
317b6859fbSMintz, Yuval /* General constants */
32fe56b9e6SYuval Mintz #define QM_PQ_MEM_4KB(pq_size)	(pq_size ? DIV_ROUND_UP((pq_size + 1) *	\
33fe56b9e6SYuval Mintz 							QM_PQ_ELEMENT_SIZE, \
34fe56b9e6SYuval Mintz 							0x1000) : 0)
35fe56b9e6SYuval Mintz #define QM_PQ_SIZE_256B(pq_size)	(pq_size ? DIV_ROUND_UP(pq_size, \
36fe56b9e6SYuval Mintz 								0x100) - 1 : 0)
37fe56b9e6SYuval Mintz #define QM_INVALID_PQ_ID		0xffff
38a2e7699eSTomer Tayar 
3992fae6fbSMichal Kalderon /* Max link speed (in Mbps) */
4092fae6fbSMichal Kalderon #define QM_MAX_LINK_SPEED               100000
4192fae6fbSMichal Kalderon 
427b6859fbSMintz, Yuval /* Feature enable */
43fe56b9e6SYuval Mintz #define QM_BYPASS_EN	1
44fe56b9e6SYuval Mintz #define QM_BYTE_CRD_EN	1
45a2e7699eSTomer Tayar 
46b90cb538SOmkar Kulkarni /* Initial VOQ byte credit */
47b90cb538SOmkar Kulkarni #define QM_INITIAL_VOQ_BYTE_CRD         98304
487b6859fbSMintz, Yuval /* Other PQ constants */
49fe56b9e6SYuval Mintz #define QM_OTHER_PQS_PER_PF	4
50a2e7699eSTomer Tayar 
51b90cb538SOmkar Kulkarni /* VOQ constants */
52b90cb538SOmkar Kulkarni #define MAX_NUM_VOQS	(MAX_NUM_PORTS_K2 * NUM_TCS_4PORT_K2)
53b90cb538SOmkar Kulkarni #define VOQS_BIT_MASK	(BIT(MAX_NUM_VOQS) - 1)
54b90cb538SOmkar Kulkarni 
55fe56b9e6SYuval Mintz /* WFQ constants */
56a2e7699eSTomer Tayar 
57b90cb538SOmkar Kulkarni /* PF WFQ increment value, 0x9000 = 4*9*1024 */
58b90cb538SOmkar Kulkarni #define QM_PF_WFQ_INC_VAL(weight)       ((weight) * 0x9000)
59a2e7699eSTomer Tayar 
60b90cb538SOmkar Kulkarni /* PF WFQ Upper bound, in MB, 10 * burst size of 1ms in 50Gbps */
61b90cb538SOmkar Kulkarni #define QM_PF_WFQ_UPPER_BOUND           62500000
62a2e7699eSTomer Tayar 
63b90cb538SOmkar Kulkarni /* PF WFQ max increment value, 0.7 * upper bound */
64b90cb538SOmkar Kulkarni #define QM_PF_WFQ_MAX_INC_VAL           ((QM_PF_WFQ_UPPER_BOUND * 7) / 10)
65a2e7699eSTomer Tayar 
66b90cb538SOmkar Kulkarni /* Number of VOQs in E5 PF WFQ credit register (QmWfqCrd) */
67b90cb538SOmkar Kulkarni #define QM_PF_WFQ_CRD_E5_NUM_VOQS       16
68a2e7699eSTomer Tayar 
69b90cb538SOmkar Kulkarni /* VP WFQ increment value */
70b90cb538SOmkar Kulkarni #define QM_VP_WFQ_INC_VAL(weight)       ((weight) * QM_VP_WFQ_MIN_INC_VAL)
71b90cb538SOmkar Kulkarni 
72b90cb538SOmkar Kulkarni /* VP WFQ min increment value */
73b90cb538SOmkar Kulkarni #define QM_VP_WFQ_MIN_INC_VAL           10800
74b90cb538SOmkar Kulkarni 
75b90cb538SOmkar Kulkarni /* VP WFQ max increment value, 2^30 */
76b90cb538SOmkar Kulkarni #define QM_VP_WFQ_MAX_INC_VAL           0x40000000
77b90cb538SOmkar Kulkarni 
78b90cb538SOmkar Kulkarni /* VP WFQ bypass threshold */
79b90cb538SOmkar Kulkarni #define QM_VP_WFQ_BYPASS_THRESH         (QM_VP_WFQ_MIN_INC_VAL - 100)
80b90cb538SOmkar Kulkarni 
81b90cb538SOmkar Kulkarni /* VP RL credit task cost */
82b90cb538SOmkar Kulkarni #define QM_VP_RL_CRD_TASK_COST          9700
83b90cb538SOmkar Kulkarni 
84b90cb538SOmkar Kulkarni /* Bit of VOQ in VP WFQ PQ map */
85b90cb538SOmkar Kulkarni #define QM_VP_WFQ_PQ_VOQ_SHIFT          0
86b90cb538SOmkar Kulkarni 
87b90cb538SOmkar Kulkarni /* Bit of PF in VP WFQ PQ map */
88b90cb538SOmkar Kulkarni #define QM_VP_WFQ_PQ_PF_SHIFT   5
89351a4dedSYuval Mintz 
90fe56b9e6SYuval Mintz /* RL constants */
91a2e7699eSTomer Tayar 
92a2e7699eSTomer Tayar /* Period in us */
93a2e7699eSTomer Tayar #define QM_RL_PERIOD	5
94a2e7699eSTomer Tayar 
95a2e7699eSTomer Tayar /* Period in 25MHz cycles */
96fe56b9e6SYuval Mintz #define QM_RL_PERIOD_CLK_25M	(25 * QM_RL_PERIOD)
97a2e7699eSTomer Tayar 
98a2e7699eSTomer Tayar /* RL increment value - rate is specified in mbps */
99da090917STomer Tayar #define QM_RL_INC_VAL(rate)                     ({	\
100da090917STomer Tayar 						typeof(rate) __rate = (rate); \
101da090917STomer Tayar 						max_t(u32,		\
102b90cb538SOmkar Kulkarni 						(u32)(((__rate ? __rate : \
103b90cb538SOmkar Kulkarni 						100000) *		\
104b90cb538SOmkar Kulkarni 						QM_RL_PERIOD *		\
105b90cb538SOmkar Kulkarni 						101) / (8 * 100)), 1); })
106a2e7699eSTomer Tayar 
107a2e7699eSTomer Tayar /* PF RL Upper bound is set to 10 * burst size of 1ms in 50Gbps */
108da090917STomer Tayar #define QM_PF_RL_UPPER_BOUND	62500000
109a2e7699eSTomer Tayar 
110a2e7699eSTomer Tayar /* Max PF RL increment value is 0.7 * upper bound */
111da090917STomer Tayar #define QM_PF_RL_MAX_INC_VAL	((QM_PF_RL_UPPER_BOUND * 7) / 10)
112da090917STomer Tayar 
113b90cb538SOmkar Kulkarni /* QCN RL Upper bound, speed is in Mpbs */
114b90cb538SOmkar Kulkarni #define QM_GLOBAL_RL_UPPER_BOUND(speed)         ((u32)max_t( \
115b90cb538SOmkar Kulkarni 		u32,					    \
116b90cb538SOmkar Kulkarni 		(u32)(((speed) *			    \
117b90cb538SOmkar Kulkarni 		       QM_RL_PERIOD * 101) / (8 * 100)),    \
118b90cb538SOmkar Kulkarni 		QM_VP_RL_CRD_TASK_COST			    \
119b90cb538SOmkar Kulkarni 		+ 1000))
120a2e7699eSTomer Tayar 
121fe56b9e6SYuval Mintz /* AFullOprtnstcCrdMask constants */
122fe56b9e6SYuval Mintz #define QM_OPPOR_LINE_VOQ_DEF	1
123fe56b9e6SYuval Mintz #define QM_OPPOR_FW_STOP_DEF	0
124fe56b9e6SYuval Mintz #define QM_OPPOR_PQ_EMPTY_DEF	1
125a2e7699eSTomer Tayar 
126fe56b9e6SYuval Mintz /* Command Queue constants */
127a2e7699eSTomer Tayar 
128a2e7699eSTomer Tayar /* Pure LB CmdQ lines (+spare) */
129fe56b9e6SYuval Mintz #define PBF_CMDQ_PURE_LB_LINES	150
130a2e7699eSTomer Tayar 
131a2e7699eSTomer Tayar #define PBF_CMDQ_LINES_RT_OFFSET(ext_voq) \
132a2e7699eSTomer Tayar 	(PBF_REG_YCMD_QS_NUM_LINES_VOQ0_RT_OFFSET + \
133a2e7699eSTomer Tayar 	 (ext_voq) * (PBF_REG_YCMD_QS_NUM_LINES_VOQ1_RT_OFFSET - \
134fe56b9e6SYuval Mintz 		PBF_REG_YCMD_QS_NUM_LINES_VOQ0_RT_OFFSET))
135a2e7699eSTomer Tayar 
136a2e7699eSTomer Tayar #define PBF_BTB_GUARANTEED_RT_OFFSET(ext_voq) \
137a2e7699eSTomer Tayar 	(PBF_REG_BTB_GUARANTEED_VOQ0_RT_OFFSET + \
138a2e7699eSTomer Tayar 	 (ext_voq) * (PBF_REG_BTB_GUARANTEED_VOQ1_RT_OFFSET - \
139fe56b9e6SYuval Mintz 		PBF_REG_BTB_GUARANTEED_VOQ0_RT_OFFSET))
140a2e7699eSTomer Tayar 
14192fae6fbSMichal Kalderon /* Returns the VOQ line credit for the specified number of PBF command lines.
14292fae6fbSMichal Kalderon  * PBF lines are specified in 256b units.
14392fae6fbSMichal Kalderon  */
144a2e7699eSTomer Tayar #define QM_VOQ_LINE_CRD(pbf_cmd_lines) \
145a2e7699eSTomer Tayar 	((((pbf_cmd_lines) - 4) * 2) | QM_LINE_CRD_REG_SIGN_BIT)
146a2e7699eSTomer Tayar 
147fe56b9e6SYuval Mintz /* BTB: blocks constants (block size = 256B) */
148a2e7699eSTomer Tayar 
149a2e7699eSTomer Tayar /* 256B blocks in 9700B packet */
150fe56b9e6SYuval Mintz #define BTB_JUMBO_PKT_BLOCKS	38
151a2e7699eSTomer Tayar 
152a2e7699eSTomer Tayar /* Headroom per-port */
153fe56b9e6SYuval Mintz #define BTB_HEADROOM_BLOCKS	BTB_JUMBO_PKT_BLOCKS
154fe56b9e6SYuval Mintz #define BTB_PURE_LB_FACTOR	10
155a2e7699eSTomer Tayar 
156a2e7699eSTomer Tayar /* Factored (hence really 0.7) */
157fe56b9e6SYuval Mintz #define BTB_PURE_LB_RATIO	7
158a2e7699eSTomer Tayar 
159fe56b9e6SYuval Mintz /* QM stop command constants */
160fe56b9e6SYuval Mintz #define QM_STOP_PQ_MASK_WIDTH		32
1617b6859fbSMintz, Yuval #define QM_STOP_CMD_ADDR		2
162fe56b9e6SYuval Mintz #define QM_STOP_CMD_STRUCT_SIZE		2
163fe56b9e6SYuval Mintz #define QM_STOP_CMD_PAUSE_MASK_OFFSET	0
164fe56b9e6SYuval Mintz #define QM_STOP_CMD_PAUSE_MASK_SHIFT	0
165fe56b9e6SYuval Mintz #define QM_STOP_CMD_PAUSE_MASK_MASK	-1
166fe56b9e6SYuval Mintz #define QM_STOP_CMD_GROUP_ID_OFFSET	1
167fe56b9e6SYuval Mintz #define QM_STOP_CMD_GROUP_ID_SHIFT	16
168fe56b9e6SYuval Mintz #define QM_STOP_CMD_GROUP_ID_MASK	15
169fe56b9e6SYuval Mintz #define QM_STOP_CMD_PQ_TYPE_OFFSET	1
170fe56b9e6SYuval Mintz #define QM_STOP_CMD_PQ_TYPE_SHIFT	24
171fe56b9e6SYuval Mintz #define QM_STOP_CMD_PQ_TYPE_MASK	1
172fe56b9e6SYuval Mintz #define QM_STOP_CMD_MAX_POLL_COUNT	100
173fe56b9e6SYuval Mintz #define QM_STOP_CMD_POLL_PERIOD_US	500
1747b6859fbSMintz, Yuval 
175fe56b9e6SYuval Mintz /* QM command macros */
176a2e7699eSTomer Tayar #define QM_CMD_STRUCT_SIZE(cmd)	cmd ## _STRUCT_SIZE
177a2e7699eSTomer Tayar #define QM_CMD_SET_FIELD(var, cmd, field, value) \
178a2e7699eSTomer Tayar 	SET_FIELD(var[cmd ## _ ## field ## _OFFSET], \
179fe56b9e6SYuval Mintz 		  cmd ## _ ## field, \
180fe56b9e6SYuval Mintz 		  value)
181da090917STomer Tayar 
182fb09a1edSShai Malin #define QM_INIT_TX_PQ_MAP(p_hwfn, map, pq_id, vp_pq_id, rl_valid,	      \
1831451e467SAlexander Lobakin 			  rl_id, ext_voq, wrr)				      \
184da090917STomer Tayar 	do {								      \
1855ab90341SAlexander Lobakin 		u32 __reg = 0;						      \
1861451e467SAlexander Lobakin 									      \
1875ab90341SAlexander Lobakin 		BUILD_BUG_ON(sizeof((map).reg) != sizeof(__reg));	      \
188b90cb538SOmkar Kulkarni 		memset(&(map), 0, sizeof(map));				      \
189fb09a1edSShai Malin 		SET_FIELD(__reg, QM_RF_PQ_MAP_PQ_VALID, 1);	      \
190fb09a1edSShai Malin 		SET_FIELD(__reg, QM_RF_PQ_MAP_RL_VALID,	      \
1911451e467SAlexander Lobakin 			  !!(rl_valid));				      \
192fb09a1edSShai Malin 		SET_FIELD(__reg, QM_RF_PQ_MAP_VP_PQ_ID, (vp_pq_id)); \
193fb09a1edSShai Malin 		SET_FIELD(__reg, QM_RF_PQ_MAP_RL_ID, (rl_id));	      \
194fb09a1edSShai Malin 		SET_FIELD(__reg, QM_RF_PQ_MAP_VOQ, (ext_voq));	      \
195fb09a1edSShai Malin 		SET_FIELD(__reg, QM_RF_PQ_MAP_WRR_WEIGHT_GROUP,      \
1961451e467SAlexander Lobakin 			  (wrr));					      \
1971451e467SAlexander Lobakin 									      \
1981451e467SAlexander Lobakin 		STORE_RT_REG((p_hwfn), QM_REG_TXPQMAP_RT_OFFSET + (pq_id),    \
1995ab90341SAlexander Lobakin 			     __reg);					      \
2005ab90341SAlexander Lobakin 		(map).reg = cpu_to_le32(__reg);				      \
201da090917STomer Tayar 	} while (0)
202da090917STomer Tayar 
203da090917STomer Tayar #define WRITE_PQ_INFO_TO_RAM	1
204da090917STomer Tayar #define PQ_INFO_ELEMENT(vp, pf, tc, port, rl_valid, rl) \
205da090917STomer Tayar 	(((vp) << 0) | ((pf) << 12) | ((tc) << 16) | ((port) << 20) | \
20692fae6fbSMichal Kalderon 	((rl_valid ? 1 : 0) << 22) | (((rl) & 255) << 24) | \
20792fae6fbSMichal Kalderon 	(((rl) >> 8) << 9))
20892fae6fbSMichal Kalderon 
209da090917STomer Tayar #define PQ_INFO_RAM_GRC_ADDRESS(pq_id) \
210b90cb538SOmkar Kulkarni 	(XSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM + \
211b90cb538SOmkar Kulkarni 	XSTORM_PQ_INFO_OFFSET(pq_id))
212da090917STomer Tayar 
213*7e9979e3SPrabhakar Kushwaha static const char * const s_protocol_types[] = {
214*7e9979e3SPrabhakar Kushwaha 	"PROTOCOLID_ISCSI", "PROTOCOLID_FCOE", "PROTOCOLID_ROCE",
215*7e9979e3SPrabhakar Kushwaha 	"PROTOCOLID_CORE", "PROTOCOLID_ETH", "PROTOCOLID_IWARP",
216*7e9979e3SPrabhakar Kushwaha 	"PROTOCOLID_TOE", "PROTOCOLID_PREROCE", "PROTOCOLID_COMMON",
217*7e9979e3SPrabhakar Kushwaha 	"PROTOCOLID_TCP", "PROTOCOLID_RDMA", "PROTOCOLID_SCSI",
218*7e9979e3SPrabhakar Kushwaha };
219*7e9979e3SPrabhakar Kushwaha 
220*7e9979e3SPrabhakar Kushwaha static const char *s_ramrod_cmd_ids[][28] = {
221*7e9979e3SPrabhakar Kushwaha 	{
222*7e9979e3SPrabhakar Kushwaha 	"ISCSI_RAMROD_CMD_ID_UNUSED", "ISCSI_RAMROD_CMD_ID_INIT_FUNC",
223*7e9979e3SPrabhakar Kushwaha 	 "ISCSI_RAMROD_CMD_ID_DESTROY_FUNC",
224*7e9979e3SPrabhakar Kushwaha 	 "ISCSI_RAMROD_CMD_ID_OFFLOAD_CONN",
225*7e9979e3SPrabhakar Kushwaha 	 "ISCSI_RAMROD_CMD_ID_UPDATE_CONN",
226*7e9979e3SPrabhakar Kushwaha 	 "ISCSI_RAMROD_CMD_ID_TERMINATION_CONN",
227*7e9979e3SPrabhakar Kushwaha 	 "ISCSI_RAMROD_CMD_ID_CLEAR_SQ", "ISCSI_RAMROD_CMD_ID_MAC_UPDATE",
228*7e9979e3SPrabhakar Kushwaha 	 "ISCSI_RAMROD_CMD_ID_CONN_STATS", },
229*7e9979e3SPrabhakar Kushwaha 	{ "FCOE_RAMROD_CMD_ID_INIT_FUNC", "FCOE_RAMROD_CMD_ID_DESTROY_FUNC",
230*7e9979e3SPrabhakar Kushwaha 	 "FCOE_RAMROD_CMD_ID_STAT_FUNC",
231*7e9979e3SPrabhakar Kushwaha 	 "FCOE_RAMROD_CMD_ID_OFFLOAD_CONN",
232*7e9979e3SPrabhakar Kushwaha 	 "FCOE_RAMROD_CMD_ID_TERMINATE_CONN", },
233*7e9979e3SPrabhakar Kushwaha 	{ "RDMA_RAMROD_UNUSED", "RDMA_RAMROD_FUNC_INIT",
234*7e9979e3SPrabhakar Kushwaha 	 "RDMA_RAMROD_FUNC_CLOSE", "RDMA_RAMROD_REGISTER_MR",
235*7e9979e3SPrabhakar Kushwaha 	 "RDMA_RAMROD_DEREGISTER_MR", "RDMA_RAMROD_CREATE_CQ",
236*7e9979e3SPrabhakar Kushwaha 	 "RDMA_RAMROD_RESIZE_CQ", "RDMA_RAMROD_DESTROY_CQ",
237*7e9979e3SPrabhakar Kushwaha 	 "RDMA_RAMROD_CREATE_SRQ", "RDMA_RAMROD_MODIFY_SRQ",
238*7e9979e3SPrabhakar Kushwaha 	 "RDMA_RAMROD_DESTROY_SRQ", "RDMA_RAMROD_START_NS_TRACKING",
239*7e9979e3SPrabhakar Kushwaha 	 "RDMA_RAMROD_STOP_NS_TRACKING", "ROCE_RAMROD_CREATE_QP",
240*7e9979e3SPrabhakar Kushwaha 	 "ROCE_RAMROD_MODIFY_QP", "ROCE_RAMROD_QUERY_QP",
241*7e9979e3SPrabhakar Kushwaha 	 "ROCE_RAMROD_DESTROY_QP", "ROCE_RAMROD_CREATE_UD_QP",
242*7e9979e3SPrabhakar Kushwaha 	 "ROCE_RAMROD_DESTROY_UD_QP", "ROCE_RAMROD_FUNC_UPDATE",
243*7e9979e3SPrabhakar Kushwaha 	 "ROCE_RAMROD_SUSPEND_QP", "ROCE_RAMROD_QUERY_SUSPENDED_QP",
244*7e9979e3SPrabhakar Kushwaha 	 "ROCE_RAMROD_CREATE_SUSPENDED_QP", "ROCE_RAMROD_RESUME_QP",
245*7e9979e3SPrabhakar Kushwaha 	 "ROCE_RAMROD_SUSPEND_UD_QP", "ROCE_RAMROD_RESUME_UD_QP",
246*7e9979e3SPrabhakar Kushwaha 	 "ROCE_RAMROD_CREATE_SUSPENDED_UD_QP", "ROCE_RAMROD_FLUSH_DPT_QP", },
247*7e9979e3SPrabhakar Kushwaha 	{ "CORE_RAMROD_UNUSED", "CORE_RAMROD_RX_QUEUE_START",
248*7e9979e3SPrabhakar Kushwaha 	 "CORE_RAMROD_TX_QUEUE_START", "CORE_RAMROD_RX_QUEUE_STOP",
249*7e9979e3SPrabhakar Kushwaha 	 "CORE_RAMROD_TX_QUEUE_STOP",
250*7e9979e3SPrabhakar Kushwaha 	 "CORE_RAMROD_RX_QUEUE_FLUSH",
251*7e9979e3SPrabhakar Kushwaha 	 "CORE_RAMROD_TX_QUEUE_UPDATE", "CORE_RAMROD_QUEUE_STATS_QUERY", },
252*7e9979e3SPrabhakar Kushwaha 	{ "ETH_RAMROD_UNUSED", "ETH_RAMROD_VPORT_START",
253*7e9979e3SPrabhakar Kushwaha 	 "ETH_RAMROD_VPORT_UPDATE", "ETH_RAMROD_VPORT_STOP",
254*7e9979e3SPrabhakar Kushwaha 	 "ETH_RAMROD_RX_QUEUE_START", "ETH_RAMROD_RX_QUEUE_STOP",
255*7e9979e3SPrabhakar Kushwaha 	 "ETH_RAMROD_TX_QUEUE_START", "ETH_RAMROD_TX_QUEUE_STOP",
256*7e9979e3SPrabhakar Kushwaha 	 "ETH_RAMROD_FILTERS_UPDATE", "ETH_RAMROD_RX_QUEUE_UPDATE",
257*7e9979e3SPrabhakar Kushwaha 	 "ETH_RAMROD_RX_CREATE_OPENFLOW_ACTION",
258*7e9979e3SPrabhakar Kushwaha 	 "ETH_RAMROD_RX_ADD_OPENFLOW_FILTER",
259*7e9979e3SPrabhakar Kushwaha 	 "ETH_RAMROD_RX_DELETE_OPENFLOW_FILTER",
260*7e9979e3SPrabhakar Kushwaha 	 "ETH_RAMROD_RX_ADD_UDP_FILTER",
261*7e9979e3SPrabhakar Kushwaha 	 "ETH_RAMROD_RX_DELETE_UDP_FILTER",
262*7e9979e3SPrabhakar Kushwaha 	 "ETH_RAMROD_RX_CREATE_GFT_ACTION",
263*7e9979e3SPrabhakar Kushwaha 	 "ETH_RAMROD_RX_UPDATE_GFT_FILTER", "ETH_RAMROD_TX_QUEUE_UPDATE",
264*7e9979e3SPrabhakar Kushwaha 	 "ETH_RAMROD_RGFS_FILTER_ADD", "ETH_RAMROD_RGFS_FILTER_DEL",
265*7e9979e3SPrabhakar Kushwaha 	 "ETH_RAMROD_TGFS_FILTER_ADD", "ETH_RAMROD_TGFS_FILTER_DEL",
266*7e9979e3SPrabhakar Kushwaha 	 "ETH_RAMROD_GFS_COUNTERS_REPORT_REQUEST", },
267*7e9979e3SPrabhakar Kushwaha 	{ "RDMA_RAMROD_UNUSED", "RDMA_RAMROD_FUNC_INIT",
268*7e9979e3SPrabhakar Kushwaha 	 "RDMA_RAMROD_FUNC_CLOSE", "RDMA_RAMROD_REGISTER_MR",
269*7e9979e3SPrabhakar Kushwaha 	 "RDMA_RAMROD_DEREGISTER_MR", "RDMA_RAMROD_CREATE_CQ",
270*7e9979e3SPrabhakar Kushwaha 	 "RDMA_RAMROD_RESIZE_CQ", "RDMA_RAMROD_DESTROY_CQ",
271*7e9979e3SPrabhakar Kushwaha 	 "RDMA_RAMROD_CREATE_SRQ", "RDMA_RAMROD_MODIFY_SRQ",
272*7e9979e3SPrabhakar Kushwaha 	 "RDMA_RAMROD_DESTROY_SRQ", "RDMA_RAMROD_START_NS_TRACKING",
273*7e9979e3SPrabhakar Kushwaha 	 "RDMA_RAMROD_STOP_NS_TRACKING",
274*7e9979e3SPrabhakar Kushwaha 	 "IWARP_RAMROD_CMD_ID_TCP_OFFLOAD",
275*7e9979e3SPrabhakar Kushwaha 	 "IWARP_RAMROD_CMD_ID_MPA_OFFLOAD",
276*7e9979e3SPrabhakar Kushwaha 	 "IWARP_RAMROD_CMD_ID_MPA_OFFLOAD_SEND_RTR",
277*7e9979e3SPrabhakar Kushwaha 	 "IWARP_RAMROD_CMD_ID_CREATE_QP", "IWARP_RAMROD_CMD_ID_QUERY_QP",
278*7e9979e3SPrabhakar Kushwaha 	 "IWARP_RAMROD_CMD_ID_MODIFY_QP",
279*7e9979e3SPrabhakar Kushwaha 	 "IWARP_RAMROD_CMD_ID_DESTROY_QP",
280*7e9979e3SPrabhakar Kushwaha 	 "IWARP_RAMROD_CMD_ID_ABORT_TCP_OFFLOAD", },
281*7e9979e3SPrabhakar Kushwaha 	{ NULL }, /*TOE*/
282*7e9979e3SPrabhakar Kushwaha 	{ NULL }, /*PREROCE*/
283*7e9979e3SPrabhakar Kushwaha 	{ "COMMON_RAMROD_UNUSED", "COMMON_RAMROD_PF_START",
284*7e9979e3SPrabhakar Kushwaha 	     "COMMON_RAMROD_PF_STOP", "COMMON_RAMROD_VF_START",
285*7e9979e3SPrabhakar Kushwaha 	     "COMMON_RAMROD_VF_STOP", "COMMON_RAMROD_PF_UPDATE",
286*7e9979e3SPrabhakar Kushwaha 	     "COMMON_RAMROD_RL_UPDATE", "COMMON_RAMROD_EMPTY", }
287*7e9979e3SPrabhakar Kushwaha };
288*7e9979e3SPrabhakar Kushwaha 
289fe56b9e6SYuval Mintz /******************** INTERNAL IMPLEMENTATION *********************/
290a2e7699eSTomer Tayar 
291da090917STomer Tayar /* 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)292da090917STomer Tayar static u8 qed_get_ext_voq(struct qed_hwfn *p_hwfn,
293da090917STomer Tayar 			  u8 port_id, u8 tc, u8 max_phys_tcs_per_port)
294da090917STomer Tayar {
295da090917STomer Tayar 	if (tc == PURE_LB_TC)
296da090917STomer Tayar 		return NUM_OF_PHYS_TCS * MAX_NUM_PORTS_BB + port_id;
297da090917STomer Tayar 	else
298da090917STomer Tayar 		return port_id * max_phys_tcs_per_port + tc;
299da090917STomer Tayar }
300da090917STomer Tayar 
301fe56b9e6SYuval Mintz /* Prepare PF RL enable/disable runtime init values */
qed_enable_pf_rl(struct qed_hwfn * p_hwfn,bool pf_rl_en)302351a4dedSYuval Mintz static void qed_enable_pf_rl(struct qed_hwfn *p_hwfn, bool pf_rl_en)
303fe56b9e6SYuval Mintz {
304fe56b9e6SYuval Mintz 	STORE_RT_REG(p_hwfn, QM_REG_RLPFENABLE_RT_OFFSET, pf_rl_en ? 1 : 0);
305fe56b9e6SYuval Mintz 	if (pf_rl_en) {
306fb09a1edSShai Malin 		u8 num_ext_voqs = MAX_NUM_VOQS;
307da090917STomer Tayar 		u64 voq_bit_mask = ((u64)1 << num_ext_voqs) - 1;
308da090917STomer Tayar 
3097b6859fbSMintz, Yuval 		/* Enable RLs for all VOQs */
310da090917STomer Tayar 		STORE_RT_REG(p_hwfn,
311da090917STomer Tayar 			     QM_REG_RLPFVOQENABLE_RT_OFFSET,
312da090917STomer Tayar 			     (u32)voq_bit_mask);
313da090917STomer Tayar 
3147b6859fbSMintz, Yuval 		/* Write RL period */
315fe56b9e6SYuval Mintz 		STORE_RT_REG(p_hwfn,
316351a4dedSYuval Mintz 			     QM_REG_RLPFPERIOD_RT_OFFSET, QM_RL_PERIOD_CLK_25M);
317fe56b9e6SYuval Mintz 		STORE_RT_REG(p_hwfn,
318fe56b9e6SYuval Mintz 			     QM_REG_RLPFPERIODTIMER_RT_OFFSET,
319fe56b9e6SYuval Mintz 			     QM_RL_PERIOD_CLK_25M);
3207b6859fbSMintz, Yuval 
3217b6859fbSMintz, Yuval 		/* Set credit threshold for QM bypass flow */
322fe56b9e6SYuval Mintz 		if (QM_BYPASS_EN)
323fe56b9e6SYuval Mintz 			STORE_RT_REG(p_hwfn,
324fe56b9e6SYuval Mintz 				     QM_REG_AFULLQMBYPTHRPFRL_RT_OFFSET,
325da090917STomer Tayar 				     QM_PF_RL_UPPER_BOUND);
326fe56b9e6SYuval Mintz 	}
327fe56b9e6SYuval Mintz }
328fe56b9e6SYuval Mintz 
329fe56b9e6SYuval Mintz /* Prepare PF WFQ enable/disable runtime init values */
qed_enable_pf_wfq(struct qed_hwfn * p_hwfn,bool pf_wfq_en)330351a4dedSYuval Mintz static void qed_enable_pf_wfq(struct qed_hwfn *p_hwfn, bool pf_wfq_en)
331fe56b9e6SYuval Mintz {
332fe56b9e6SYuval Mintz 	STORE_RT_REG(p_hwfn, QM_REG_WFQPFENABLE_RT_OFFSET, pf_wfq_en ? 1 : 0);
3337b6859fbSMintz, Yuval 
3347b6859fbSMintz, Yuval 	/* Set credit threshold for QM bypass flow */
335fe56b9e6SYuval Mintz 	if (pf_wfq_en && QM_BYPASS_EN)
336fe56b9e6SYuval Mintz 		STORE_RT_REG(p_hwfn,
337fe56b9e6SYuval Mintz 			     QM_REG_AFULLQMBYPTHRPFWFQ_RT_OFFSET,
338b90cb538SOmkar Kulkarni 			     QM_PF_WFQ_UPPER_BOUND);
339fe56b9e6SYuval Mintz }
340fe56b9e6SYuval Mintz 
34192fae6fbSMichal Kalderon /* Prepare global RL enable/disable runtime init values */
qed_enable_global_rl(struct qed_hwfn * p_hwfn,bool global_rl_en)34292fae6fbSMichal Kalderon static void qed_enable_global_rl(struct qed_hwfn *p_hwfn, bool global_rl_en)
343fe56b9e6SYuval Mintz {
344fe56b9e6SYuval Mintz 	STORE_RT_REG(p_hwfn, QM_REG_RLGLBLENABLE_RT_OFFSET,
34592fae6fbSMichal Kalderon 		     global_rl_en ? 1 : 0);
34692fae6fbSMichal Kalderon 	if (global_rl_en) {
3477b6859fbSMintz, Yuval 		/* Write RL period (use timer 0 only) */
348fe56b9e6SYuval Mintz 		STORE_RT_REG(p_hwfn,
349fe56b9e6SYuval Mintz 			     QM_REG_RLGLBLPERIOD_0_RT_OFFSET,
350fe56b9e6SYuval Mintz 			     QM_RL_PERIOD_CLK_25M);
351fe56b9e6SYuval Mintz 		STORE_RT_REG(p_hwfn,
352fe56b9e6SYuval Mintz 			     QM_REG_RLGLBLPERIODTIMER_0_RT_OFFSET,
353fe56b9e6SYuval Mintz 			     QM_RL_PERIOD_CLK_25M);
3547b6859fbSMintz, Yuval 
3557b6859fbSMintz, Yuval 		/* Set credit threshold for QM bypass flow */
356fe56b9e6SYuval Mintz 		if (QM_BYPASS_EN)
357fe56b9e6SYuval Mintz 			STORE_RT_REG(p_hwfn,
358fe56b9e6SYuval Mintz 				     QM_REG_AFULLQMBYPTHRGLBLRL_RT_OFFSET,
359b90cb538SOmkar Kulkarni 				     QM_GLOBAL_RL_UPPER_BOUND(10000) - 1);
360fe56b9e6SYuval Mintz 	}
361fe56b9e6SYuval Mintz }
362fe56b9e6SYuval Mintz 
363fe56b9e6SYuval Mintz /* Prepare VPORT WFQ enable/disable runtime init values */
qed_enable_vport_wfq(struct qed_hwfn * p_hwfn,bool vport_wfq_en)364351a4dedSYuval Mintz static void qed_enable_vport_wfq(struct qed_hwfn *p_hwfn, bool vport_wfq_en)
365fe56b9e6SYuval Mintz {
366fe56b9e6SYuval Mintz 	STORE_RT_REG(p_hwfn, QM_REG_WFQVPENABLE_RT_OFFSET,
367fe56b9e6SYuval Mintz 		     vport_wfq_en ? 1 : 0);
3687b6859fbSMintz, Yuval 
3697b6859fbSMintz, Yuval 	/* Set credit threshold for QM bypass flow */
370fe56b9e6SYuval Mintz 	if (vport_wfq_en && QM_BYPASS_EN)
371fe56b9e6SYuval Mintz 		STORE_RT_REG(p_hwfn,
372fe56b9e6SYuval Mintz 			     QM_REG_AFULLQMBYPTHRVPWFQ_RT_OFFSET,
373b90cb538SOmkar Kulkarni 			     QM_VP_WFQ_BYPASS_THRESH);
374fe56b9e6SYuval Mintz }
375fe56b9e6SYuval Mintz 
376fe56b9e6SYuval Mintz /* Prepare runtime init values to allocate PBF command queue lines for
3777b6859fbSMintz, Yuval  * the specified VOQ.
378fe56b9e6SYuval Mintz  */
qed_cmdq_lines_voq_rt_init(struct qed_hwfn * p_hwfn,u8 ext_voq,u16 cmdq_lines)379fe56b9e6SYuval Mintz static void qed_cmdq_lines_voq_rt_init(struct qed_hwfn *p_hwfn,
380da090917STomer Tayar 				       u8 ext_voq, u16 cmdq_lines)
381fe56b9e6SYuval Mintz {
382da090917STomer Tayar 	u32 qm_line_crd = QM_VOQ_LINE_CRD(cmdq_lines);
383fe56b9e6SYuval Mintz 
384da090917STomer Tayar 	OVERWRITE_RT_REG(p_hwfn, PBF_CMDQ_LINES_RT_OFFSET(ext_voq),
385fe56b9e6SYuval Mintz 			 (u32)cmdq_lines);
386da090917STomer Tayar 	STORE_RT_REG(p_hwfn, QM_REG_VOQCRDLINE_RT_OFFSET + ext_voq,
387da090917STomer Tayar 		     qm_line_crd);
388da090917STomer Tayar 	STORE_RT_REG(p_hwfn, QM_REG_VOQINITCRDLINE_RT_OFFSET + ext_voq,
389fe56b9e6SYuval Mintz 		     qm_line_crd);
390fe56b9e6SYuval Mintz }
391fe56b9e6SYuval Mintz 
392fe56b9e6SYuval Mintz /* Prepare runtime init values to allocate PBF command queue lines. */
393b90cb538SOmkar Kulkarni static void
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])394b90cb538SOmkar Kulkarni qed_cmdq_lines_rt_init(struct qed_hwfn *p_hwfn,
395fe56b9e6SYuval Mintz 		       u8 max_ports_per_engine,
396fe56b9e6SYuval Mintz 		       u8 max_phys_tcs_per_port,
397fe56b9e6SYuval Mintz 		       struct init_qm_port_params port_params[MAX_NUM_PORTS])
398fe56b9e6SYuval Mintz {
399da090917STomer Tayar 	u8 tc, ext_voq, port_id, num_tcs_in_port;
400fb09a1edSShai Malin 	u8 num_ext_voqs = MAX_NUM_VOQS;
401fe56b9e6SYuval Mintz 
402da090917STomer Tayar 	/* Clear PBF lines of all VOQs */
403da090917STomer Tayar 	for (ext_voq = 0; ext_voq < num_ext_voqs; ext_voq++)
404da090917STomer Tayar 		STORE_RT_REG(p_hwfn, PBF_CMDQ_LINES_RT_OFFSET(ext_voq), 0);
405da090917STomer Tayar 
406fe56b9e6SYuval Mintz 	for (port_id = 0; port_id < max_ports_per_engine; port_id++) {
407fe56b9e6SYuval Mintz 		u16 phys_lines, phys_lines_per_tc;
408fe56b9e6SYuval Mintz 
409da090917STomer Tayar 		if (!port_params[port_id].active)
410da090917STomer Tayar 			continue;
411da090917STomer Tayar 
412da090917STomer Tayar 		/* Find number of command queue lines to divide between the
41392fae6fbSMichal Kalderon 		 * active physical TCs.
414da090917STomer Tayar 		 */
415da090917STomer Tayar 		phys_lines = port_params[port_id].num_pbf_cmd_lines;
416da090917STomer Tayar 		phys_lines -= PBF_CMDQ_PURE_LB_LINES;
417da090917STomer Tayar 
418da090917STomer Tayar 		/* Find #lines per active physical TC */
419351a4dedSYuval Mintz 		num_tcs_in_port = 0;
420da090917STomer Tayar 		for (tc = 0; tc < max_phys_tcs_per_port; tc++)
421351a4dedSYuval Mintz 			if (((port_params[port_id].active_phys_tcs >>
422351a4dedSYuval Mintz 			      tc) & 0x1) == 1)
423351a4dedSYuval Mintz 				num_tcs_in_port++;
424351a4dedSYuval Mintz 		phys_lines_per_tc = phys_lines / num_tcs_in_port;
425351a4dedSYuval Mintz 
426da090917STomer Tayar 		/* Init registers per active TC */
427da090917STomer Tayar 		for (tc = 0; tc < max_phys_tcs_per_port; tc++) {
428da090917STomer Tayar 			ext_voq = qed_get_ext_voq(p_hwfn,
429da090917STomer Tayar 						  port_id,
430da090917STomer Tayar 						  tc, max_phys_tcs_per_port);
431da090917STomer Tayar 			if (((port_params[port_id].active_phys_tcs >>
432da090917STomer Tayar 			      tc) & 0x1) == 1)
433da090917STomer Tayar 				qed_cmdq_lines_voq_rt_init(p_hwfn,
434da090917STomer Tayar 							   ext_voq,
435fe56b9e6SYuval Mintz 							   phys_lines_per_tc);
436fe56b9e6SYuval Mintz 		}
437351a4dedSYuval Mintz 
438da090917STomer Tayar 		/* Init registers for pure LB TC */
439da090917STomer Tayar 		ext_voq = qed_get_ext_voq(p_hwfn,
440da090917STomer Tayar 					  port_id,
441da090917STomer Tayar 					  PURE_LB_TC, max_phys_tcs_per_port);
44292fae6fbSMichal Kalderon 		qed_cmdq_lines_voq_rt_init(p_hwfn, ext_voq,
44392fae6fbSMichal Kalderon 					   PBF_CMDQ_PURE_LB_LINES);
444fe56b9e6SYuval Mintz 	}
445fe56b9e6SYuval Mintz }
446fe56b9e6SYuval Mintz 
44792fae6fbSMichal Kalderon /* Prepare runtime init values to allocate guaranteed BTB blocks for the
44892fae6fbSMichal Kalderon  * specified port. The guaranteed BTB space is divided between the TCs as
44992fae6fbSMichal Kalderon  * follows (shared space Is currently not used):
45092fae6fbSMichal Kalderon  * 1. Parameters:
45192fae6fbSMichal Kalderon  *    B - BTB blocks for this port
45292fae6fbSMichal Kalderon  *    C - Number of physical TCs for this port
45392fae6fbSMichal Kalderon  * 2. Calculation:
45492fae6fbSMichal Kalderon  *    a. 38 blocks (9700B jumbo frame) are allocated for global per port
45592fae6fbSMichal Kalderon  *	 headroom.
45692fae6fbSMichal Kalderon  *    b. B = B - 38 (remainder after global headroom allocation).
45792fae6fbSMichal Kalderon  *    c. MAX(38,B/(C+0.7)) blocks are allocated for the pure LB VOQ.
45892fae6fbSMichal Kalderon  *    d. B = B - MAX(38, B/(C+0.7)) (remainder after pure LB allocation).
45992fae6fbSMichal Kalderon  *    e. B/C blocks are allocated for each physical TC.
46092fae6fbSMichal Kalderon  * Assumptions:
46192fae6fbSMichal Kalderon  * - MTU is up to 9700 bytes (38 blocks)
46292fae6fbSMichal Kalderon  * - All TCs are considered symmetrical (same rate and packet size)
46392fae6fbSMichal Kalderon  * - No optimization for lossy TC (all are considered lossless). Shared space
46492fae6fbSMichal Kalderon  *   is not enabled and allocated for each TC.
46592fae6fbSMichal Kalderon  */
466b90cb538SOmkar Kulkarni static void
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])467b90cb538SOmkar Kulkarni qed_btb_blocks_rt_init(struct qed_hwfn *p_hwfn,
468fe56b9e6SYuval Mintz 		       u8 max_ports_per_engine,
469fe56b9e6SYuval Mintz 		       u8 max_phys_tcs_per_port,
470fe56b9e6SYuval Mintz 		       struct init_qm_port_params port_params[MAX_NUM_PORTS])
471fe56b9e6SYuval Mintz {
472fe56b9e6SYuval Mintz 	u32 usable_blocks, pure_lb_blocks, phys_blocks;
473da090917STomer Tayar 	u8 tc, ext_voq, port_id, num_tcs_in_port;
474fe56b9e6SYuval Mintz 
475fe56b9e6SYuval Mintz 	for (port_id = 0; port_id < max_ports_per_engine; port_id++) {
476fe56b9e6SYuval Mintz 		if (!port_params[port_id].active)
477fe56b9e6SYuval Mintz 			continue;
478fe56b9e6SYuval Mintz 
4797b6859fbSMintz, Yuval 		/* Subtract headroom blocks */
480fe56b9e6SYuval Mintz 		usable_blocks = port_params[port_id].num_btb_blocks -
481fe56b9e6SYuval Mintz 				BTB_HEADROOM_BLOCKS;
482fe56b9e6SYuval Mintz 
483da090917STomer Tayar 		/* Find blocks per physical TC. Use factor to avoid floating
484da090917STomer Tayar 		 * arithmethic.
485da090917STomer Tayar 		 */
486351a4dedSYuval Mintz 		num_tcs_in_port = 0;
487da090917STomer Tayar 		for (tc = 0; tc < NUM_OF_PHYS_TCS; tc++)
488351a4dedSYuval Mintz 			if (((port_params[port_id].active_phys_tcs >>
489351a4dedSYuval Mintz 			      tc) & 0x1) == 1)
490351a4dedSYuval Mintz 				num_tcs_in_port++;
491351a4dedSYuval Mintz 
492fe56b9e6SYuval Mintz 		pure_lb_blocks = (usable_blocks * BTB_PURE_LB_FACTOR) /
493351a4dedSYuval Mintz 				 (num_tcs_in_port * BTB_PURE_LB_FACTOR +
494fe56b9e6SYuval Mintz 				  BTB_PURE_LB_RATIO);
495fe56b9e6SYuval Mintz 		pure_lb_blocks = max_t(u32, BTB_JUMBO_PKT_BLOCKS,
496fe56b9e6SYuval Mintz 				       pure_lb_blocks / BTB_PURE_LB_FACTOR);
497351a4dedSYuval Mintz 		phys_blocks = (usable_blocks - pure_lb_blocks) /
498351a4dedSYuval Mintz 			      num_tcs_in_port;
499fe56b9e6SYuval Mintz 
5007b6859fbSMintz, Yuval 		/* Init physical TCs */
501351a4dedSYuval Mintz 		for (tc = 0; tc < NUM_OF_PHYS_TCS; tc++) {
502351a4dedSYuval Mintz 			if (((port_params[port_id].active_phys_tcs >>
503da090917STomer Tayar 			      tc) & 0x1) == 1) {
504da090917STomer Tayar 				ext_voq =
505da090917STomer Tayar 					qed_get_ext_voq(p_hwfn,
506da090917STomer Tayar 							port_id,
507da090917STomer Tayar 							tc,
508351a4dedSYuval Mintz 							max_phys_tcs_per_port);
509da090917STomer Tayar 				STORE_RT_REG(p_hwfn,
510da090917STomer Tayar 					     PBF_BTB_GUARANTEED_RT_OFFSET
511da090917STomer Tayar 					     (ext_voq), phys_blocks);
512da090917STomer Tayar 			}
513fe56b9e6SYuval Mintz 		}
514fe56b9e6SYuval Mintz 
5157b6859fbSMintz, Yuval 		/* Init pure LB TC */
516da090917STomer Tayar 		ext_voq = qed_get_ext_voq(p_hwfn,
517da090917STomer Tayar 					  port_id,
518da090917STomer Tayar 					  PURE_LB_TC, max_phys_tcs_per_port);
519da090917STomer Tayar 		STORE_RT_REG(p_hwfn, PBF_BTB_GUARANTEED_RT_OFFSET(ext_voq),
520fe56b9e6SYuval Mintz 			     pure_lb_blocks);
521fe56b9e6SYuval Mintz 	}
522fe56b9e6SYuval Mintz }
523fe56b9e6SYuval Mintz 
52492fae6fbSMichal Kalderon /* Prepare runtime init values for the specified RL.
52592fae6fbSMichal Kalderon  * Set max link speed (100Gbps) per rate limiter.
52692fae6fbSMichal Kalderon  * Return -1 on error.
52792fae6fbSMichal Kalderon  */
qed_global_rl_rt_init(struct qed_hwfn * p_hwfn)52892fae6fbSMichal Kalderon static int qed_global_rl_rt_init(struct qed_hwfn *p_hwfn)
52992fae6fbSMichal Kalderon {
530b90cb538SOmkar Kulkarni 	u32 upper_bound = QM_GLOBAL_RL_UPPER_BOUND(QM_MAX_LINK_SPEED) |
53192fae6fbSMichal Kalderon 			  (u32)QM_RL_CRD_REG_SIGN_BIT;
53292fae6fbSMichal Kalderon 	u32 inc_val;
53392fae6fbSMichal Kalderon 	u16 rl_id;
53492fae6fbSMichal Kalderon 
53592fae6fbSMichal Kalderon 	/* Go over all global RLs */
53692fae6fbSMichal Kalderon 	for (rl_id = 0; rl_id < MAX_QM_GLOBAL_RLS; rl_id++) {
53792fae6fbSMichal Kalderon 		inc_val = QM_RL_INC_VAL(QM_MAX_LINK_SPEED);
53892fae6fbSMichal Kalderon 
53992fae6fbSMichal Kalderon 		STORE_RT_REG(p_hwfn,
54092fae6fbSMichal Kalderon 			     QM_REG_RLGLBLCRD_RT_OFFSET + rl_id,
54192fae6fbSMichal Kalderon 			     (u32)QM_RL_CRD_REG_SIGN_BIT);
54292fae6fbSMichal Kalderon 		STORE_RT_REG(p_hwfn,
54392fae6fbSMichal Kalderon 			     QM_REG_RLGLBLUPPERBOUND_RT_OFFSET + rl_id,
54492fae6fbSMichal Kalderon 			     upper_bound);
54592fae6fbSMichal Kalderon 		STORE_RT_REG(p_hwfn,
54692fae6fbSMichal Kalderon 			     QM_REG_RLGLBLINCVAL_RT_OFFSET + rl_id, inc_val);
54792fae6fbSMichal Kalderon 	}
54892fae6fbSMichal Kalderon 
54992fae6fbSMichal Kalderon 	return 0;
55092fae6fbSMichal Kalderon }
55192fae6fbSMichal Kalderon 
552b90cb538SOmkar Kulkarni /* Returns the upper bound for the specified Vport RL parameters.
553b90cb538SOmkar Kulkarni  * link_speed is in Mbps.
554b90cb538SOmkar Kulkarni  * Returns 0 in case of error.
555b90cb538SOmkar Kulkarni  */
qed_get_vport_rl_upper_bound(enum init_qm_rl_type vport_rl_type,u32 link_speed)556b90cb538SOmkar Kulkarni static u32 qed_get_vport_rl_upper_bound(enum init_qm_rl_type vport_rl_type,
557b90cb538SOmkar Kulkarni 					u32 link_speed)
558b90cb538SOmkar Kulkarni {
559b90cb538SOmkar Kulkarni 	switch (vport_rl_type) {
560b90cb538SOmkar Kulkarni 	case QM_RL_TYPE_NORMAL:
561b90cb538SOmkar Kulkarni 		return QM_INITIAL_VOQ_BYTE_CRD;
562b90cb538SOmkar Kulkarni 	case QM_RL_TYPE_QCN:
563b90cb538SOmkar Kulkarni 		return QM_GLOBAL_RL_UPPER_BOUND(link_speed);
564b90cb538SOmkar Kulkarni 	default:
565b90cb538SOmkar Kulkarni 		return 0;
566b90cb538SOmkar Kulkarni 	}
567b90cb538SOmkar Kulkarni }
568b90cb538SOmkar Kulkarni 
569b90cb538SOmkar Kulkarni /* Prepare VPORT RL runtime init values.
570b90cb538SOmkar Kulkarni  * Return -1 on error.
571b90cb538SOmkar Kulkarni  */
qed_vport_rl_rt_init(struct qed_hwfn * p_hwfn,u16 start_rl,u16 num_rls,u32 link_speed,struct init_qm_rl_params * rl_params)572b90cb538SOmkar Kulkarni static int qed_vport_rl_rt_init(struct qed_hwfn *p_hwfn,
573b90cb538SOmkar Kulkarni 				u16 start_rl,
574b90cb538SOmkar Kulkarni 				u16 num_rls,
575b90cb538SOmkar Kulkarni 				u32 link_speed,
576b90cb538SOmkar Kulkarni 				struct init_qm_rl_params *rl_params)
577b90cb538SOmkar Kulkarni {
578b90cb538SOmkar Kulkarni 	u16 i, rl_id;
579b90cb538SOmkar Kulkarni 
580b90cb538SOmkar Kulkarni 	if (num_rls && start_rl + num_rls >= MAX_QM_GLOBAL_RLS) {
581b90cb538SOmkar Kulkarni 		DP_NOTICE(p_hwfn, "Invalid rate limiter configuration\n");
582b90cb538SOmkar Kulkarni 		return -1;
583b90cb538SOmkar Kulkarni 	}
584b90cb538SOmkar Kulkarni 
585b90cb538SOmkar Kulkarni 	/* Go over all PF VPORTs */
586b90cb538SOmkar Kulkarni 	for (i = 0, rl_id = start_rl; i < num_rls; i++, rl_id++) {
587b90cb538SOmkar Kulkarni 		u32 upper_bound, inc_val;
588b90cb538SOmkar Kulkarni 
589b90cb538SOmkar Kulkarni 		upper_bound =
590b90cb538SOmkar Kulkarni 		    qed_get_vport_rl_upper_bound((enum init_qm_rl_type)
591b90cb538SOmkar Kulkarni 						 rl_params[i].vport_rl_type,
592b90cb538SOmkar Kulkarni 						 link_speed);
593b90cb538SOmkar Kulkarni 
594b90cb538SOmkar Kulkarni 		inc_val =
595b90cb538SOmkar Kulkarni 		    QM_RL_INC_VAL(rl_params[i].vport_rl ?
596b90cb538SOmkar Kulkarni 				  rl_params[i].vport_rl : link_speed);
597b90cb538SOmkar Kulkarni 		if (inc_val > upper_bound) {
598b90cb538SOmkar Kulkarni 			DP_NOTICE(p_hwfn,
599b90cb538SOmkar Kulkarni 				  "Invalid RL rate - limit configuration\n");
600b90cb538SOmkar Kulkarni 			return -1;
601b90cb538SOmkar Kulkarni 		}
602b90cb538SOmkar Kulkarni 
603b90cb538SOmkar Kulkarni 		STORE_RT_REG(p_hwfn, QM_REG_RLGLBLCRD_RT_OFFSET + rl_id,
604b90cb538SOmkar Kulkarni 			     (u32)QM_RL_CRD_REG_SIGN_BIT);
605b90cb538SOmkar Kulkarni 		STORE_RT_REG(p_hwfn, QM_REG_RLGLBLUPPERBOUND_RT_OFFSET + rl_id,
606b90cb538SOmkar Kulkarni 			     upper_bound | (u32)QM_RL_CRD_REG_SIGN_BIT);
607b90cb538SOmkar Kulkarni 		STORE_RT_REG(p_hwfn, QM_REG_RLGLBLINCVAL_RT_OFFSET + rl_id,
608b90cb538SOmkar Kulkarni 			     inc_val);
609b90cb538SOmkar Kulkarni 	}
610b90cb538SOmkar Kulkarni 
611b90cb538SOmkar Kulkarni 	return 0;
612b90cb538SOmkar Kulkarni }
613b90cb538SOmkar Kulkarni 
614fe56b9e6SYuval Mintz /* 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)615b90cb538SOmkar Kulkarni static int qed_tx_pq_map_rt_init(struct qed_hwfn *p_hwfn,
616fe56b9e6SYuval Mintz 				 struct qed_ptt *p_ptt,
617fe56b9e6SYuval Mintz 				 struct qed_qm_pf_rt_init_params *p_params,
618fe56b9e6SYuval Mintz 				 u32 base_mem_addr_4kb)
619fe56b9e6SYuval Mintz {
620fe56b9e6SYuval Mintz 	u32 tx_pq_vf_mask[MAX_QM_TX_QUEUES / QM_PF_QUEUE_GROUP_SIZE] = { 0 };
621da090917STomer Tayar 	struct init_qm_vport_params *vport_params = p_params->vport_params;
622be086e7cSMintz, Yuval 	u32 num_tx_pq_vf_masks = MAX_QM_TX_QUEUES / QM_PF_QUEUE_GROUP_SIZE;
623da090917STomer Tayar 	u16 num_pqs, first_pq_group, last_pq_group, i, j, pq_id, pq_group;
624da090917STomer Tayar 	struct init_qm_pq_params *pq_params = p_params->pq_params;
625da090917STomer Tayar 	u32 pq_mem_4kb, vport_pq_mem_4kb, mem_addr_4kb;
626da090917STomer Tayar 
627da090917STomer Tayar 	num_pqs = p_params->num_pf_pqs + p_params->num_vf_pqs;
628da090917STomer Tayar 
629da090917STomer Tayar 	first_pq_group = p_params->start_pq / QM_PF_QUEUE_GROUP_SIZE;
630da090917STomer Tayar 	last_pq_group = (p_params->start_pq + num_pqs - 1) /
631da090917STomer Tayar 			QM_PF_QUEUE_GROUP_SIZE;
632da090917STomer Tayar 
633da090917STomer Tayar 	pq_mem_4kb = QM_PQ_MEM_4KB(p_params->num_pf_cids);
634da090917STomer Tayar 	vport_pq_mem_4kb = QM_PQ_MEM_4KB(p_params->num_vf_cids);
635da090917STomer Tayar 	mem_addr_4kb = base_mem_addr_4kb;
636fe56b9e6SYuval Mintz 
6377b6859fbSMintz, Yuval 	/* Set mapping from PQ group to PF */
638fe56b9e6SYuval Mintz 	for (pq_group = first_pq_group; pq_group <= last_pq_group; pq_group++)
639fe56b9e6SYuval Mintz 		STORE_RT_REG(p_hwfn, QM_REG_PQTX2PF_0_RT_OFFSET + pq_group,
640fe56b9e6SYuval Mintz 			     (u32)(p_params->pf_id));
641da090917STomer Tayar 
6427b6859fbSMintz, Yuval 	/* Set PQ sizes */
643fe56b9e6SYuval Mintz 	STORE_RT_REG(p_hwfn, QM_REG_MAXPQSIZE_0_RT_OFFSET,
644fe56b9e6SYuval Mintz 		     QM_PQ_SIZE_256B(p_params->num_pf_cids));
645fe56b9e6SYuval Mintz 	STORE_RT_REG(p_hwfn, QM_REG_MAXPQSIZE_1_RT_OFFSET,
646fe56b9e6SYuval Mintz 		     QM_PQ_SIZE_256B(p_params->num_vf_cids));
647fe56b9e6SYuval Mintz 
6487b6859fbSMintz, Yuval 	/* Go over all Tx PQs */
649fe56b9e6SYuval Mintz 	for (i = 0, pq_id = p_params->start_pq; i < num_pqs; i++, pq_id++) {
65092fae6fbSMichal Kalderon 		u16 *p_first_tx_pq_id, vport_id_in_pf;
651fb09a1edSShai Malin 		struct qm_rf_pq_map tx_pq_map;
65292fae6fbSMichal Kalderon 		u8 tc_id = pq_params[i].tc_id;
65392fae6fbSMichal Kalderon 		bool is_vf_pq;
65492fae6fbSMichal Kalderon 		u8 ext_voq;
655fe56b9e6SYuval Mintz 
656da090917STomer Tayar 		ext_voq = qed_get_ext_voq(p_hwfn,
65750bc60cbSMichal Kalderon 					  pq_params[i].port_id,
658da090917STomer Tayar 					  tc_id,
659da090917STomer Tayar 					  p_params->max_phys_tcs_per_port);
660da090917STomer Tayar 		is_vf_pq = (i >= p_params->num_pf_pqs);
661be086e7cSMintz, Yuval 
6627b6859fbSMintz, Yuval 		/* Update first Tx PQ of VPORT/TC */
663da090917STomer Tayar 		vport_id_in_pf = pq_params[i].vport_id - p_params->start_vport;
664da090917STomer Tayar 		p_first_tx_pq_id =
665da090917STomer Tayar 		    &vport_params[vport_id_in_pf].first_tx_pq_id[tc_id];
666da090917STomer Tayar 		if (*p_first_tx_pq_id == QM_INVALID_PQ_ID) {
667da090917STomer Tayar 			u32 map_val =
668b90cb538SOmkar Kulkarni 				(ext_voq << QM_VP_WFQ_PQ_VOQ_SHIFT) |
669b90cb538SOmkar Kulkarni 				(p_params->pf_id << QM_VP_WFQ_PQ_PF_SHIFT);
670fe56b9e6SYuval Mintz 
6717b6859fbSMintz, Yuval 			/* Create new VP PQ */
672da090917STomer Tayar 			*p_first_tx_pq_id = pq_id;
6737b6859fbSMintz, Yuval 
6747b6859fbSMintz, Yuval 			/* Map VP PQ to VOQ and PF */
675fe56b9e6SYuval Mintz 			STORE_RT_REG(p_hwfn,
676fe56b9e6SYuval Mintz 				     QM_REG_WFQVPMAP_RT_OFFSET +
677da090917STomer Tayar 				     *p_first_tx_pq_id,
678da090917STomer Tayar 				     map_val);
679fe56b9e6SYuval Mintz 		}
680be086e7cSMintz, Yuval 
681da090917STomer Tayar 		/* Prepare PQ map entry */
682da090917STomer Tayar 		QM_INIT_TX_PQ_MAP(p_hwfn,
683da090917STomer Tayar 				  tx_pq_map,
684da090917STomer Tayar 				  pq_id,
685da090917STomer Tayar 				  *p_first_tx_pq_id,
68692fae6fbSMichal Kalderon 				  pq_params[i].rl_valid,
68792fae6fbSMichal Kalderon 				  pq_params[i].rl_id,
688da090917STomer Tayar 				  ext_voq, pq_params[i].wrr_group);
689da090917STomer Tayar 
690da090917STomer Tayar 		/* Set PQ base address */
691fe56b9e6SYuval Mintz 		STORE_RT_REG(p_hwfn,
692fe56b9e6SYuval Mintz 			     QM_REG_BASEADDRTXPQ_RT_OFFSET + pq_id,
693fe56b9e6SYuval Mintz 			     mem_addr_4kb);
6947b6859fbSMintz, Yuval 
695da090917STomer Tayar 		/* Clear PQ pointer table entry (64 bit) */
696da090917STomer Tayar 		if (p_params->is_pf_loading)
697da090917STomer Tayar 			for (j = 0; j < 2; j++)
698da090917STomer Tayar 				STORE_RT_REG(p_hwfn,
699da090917STomer Tayar 					     QM_REG_PTRTBLTX_RT_OFFSET +
700da090917STomer Tayar 					     (pq_id * 2) + j, 0);
701da090917STomer Tayar 
702da090917STomer Tayar 		/* Write PQ info to RAM */
703da090917STomer Tayar 		if (WRITE_PQ_INFO_TO_RAM != 0) {
704da090917STomer Tayar 			u32 pq_info = 0;
705da090917STomer Tayar 
706da090917STomer Tayar 			pq_info = PQ_INFO_ELEMENT(*p_first_tx_pq_id,
707da090917STomer Tayar 						  p_params->pf_id,
708da090917STomer Tayar 						  tc_id,
70950bc60cbSMichal Kalderon 						  pq_params[i].port_id,
71092fae6fbSMichal Kalderon 						  pq_params[i].rl_valid,
71192fae6fbSMichal Kalderon 						  pq_params[i].rl_id);
712da090917STomer Tayar 			qed_wr(p_hwfn, p_ptt, PQ_INFO_RAM_GRC_ADDRESS(pq_id),
713da090917STomer Tayar 			       pq_info);
714da090917STomer Tayar 		}
715da090917STomer Tayar 
7167b6859fbSMintz, Yuval 		/* If VF PQ, add indication to PQ VF mask */
717fe56b9e6SYuval Mintz 		if (is_vf_pq) {
718be086e7cSMintz, Yuval 			tx_pq_vf_mask[pq_id /
719be086e7cSMintz, Yuval 				      QM_PF_QUEUE_GROUP_SIZE] |=
720be086e7cSMintz, Yuval 			    BIT((pq_id % QM_PF_QUEUE_GROUP_SIZE));
721fe56b9e6SYuval Mintz 			mem_addr_4kb += vport_pq_mem_4kb;
722fe56b9e6SYuval Mintz 		} else {
723fe56b9e6SYuval Mintz 			mem_addr_4kb += pq_mem_4kb;
724fe56b9e6SYuval Mintz 		}
725fe56b9e6SYuval Mintz 	}
726fe56b9e6SYuval Mintz 
7277b6859fbSMintz, Yuval 	/* Store Tx PQ VF mask to size select register */
7287b6859fbSMintz, Yuval 	for (i = 0; i < num_tx_pq_vf_masks; i++)
7297b6859fbSMintz, Yuval 		if (tx_pq_vf_mask[i])
7307b6859fbSMintz, Yuval 			STORE_RT_REG(p_hwfn,
7317b6859fbSMintz, Yuval 				     QM_REG_MAXPQSIZETXSEL_0_RT_OFFSET + i,
732fe56b9e6SYuval Mintz 				     tx_pq_vf_mask[i]);
733b90cb538SOmkar Kulkarni 
734b90cb538SOmkar Kulkarni 	return 0;
735fe56b9e6SYuval Mintz }
736fe56b9e6SYuval Mintz 
737fe56b9e6SYuval Mintz /* 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)738fe56b9e6SYuval Mintz static void qed_other_pq_map_rt_init(struct qed_hwfn *p_hwfn,
739fe56b9e6SYuval Mintz 				     u8 pf_id,
740da090917STomer Tayar 				     bool is_pf_loading,
741fe56b9e6SYuval Mintz 				     u32 num_pf_cids,
742351a4dedSYuval Mintz 				     u32 num_tids, u32 base_mem_addr_4kb)
743fe56b9e6SYuval Mintz {
7447b6859fbSMintz, Yuval 	u32 pq_size, pq_mem_4kb, mem_addr_4kb;
745da090917STomer Tayar 	u16 i, j, pq_id, pq_group;
746fe56b9e6SYuval Mintz 
747da090917STomer Tayar 	/* A single other PQ group is used in each PF, where PQ group i is used
748da090917STomer Tayar 	 * in PF i.
749fe56b9e6SYuval Mintz 	 */
7507b6859fbSMintz, Yuval 	pq_group = pf_id;
7517b6859fbSMintz, Yuval 	pq_size = num_pf_cids + num_tids;
7527b6859fbSMintz, Yuval 	pq_mem_4kb = QM_PQ_MEM_4KB(pq_size);
7537b6859fbSMintz, Yuval 	mem_addr_4kb = base_mem_addr_4kb;
754fe56b9e6SYuval Mintz 
7557b6859fbSMintz, Yuval 	/* Map PQ group to PF */
756fe56b9e6SYuval Mintz 	STORE_RT_REG(p_hwfn, QM_REG_PQOTHER2PF_0_RT_OFFSET + pq_group,
757fe56b9e6SYuval Mintz 		     (u32)(pf_id));
758da090917STomer Tayar 
7597b6859fbSMintz, Yuval 	/* Set PQ sizes */
760fe56b9e6SYuval Mintz 	STORE_RT_REG(p_hwfn, QM_REG_MAXPQSIZE_2_RT_OFFSET,
761fe56b9e6SYuval Mintz 		     QM_PQ_SIZE_256B(pq_size));
7627b6859fbSMintz, Yuval 
763fe56b9e6SYuval Mintz 	for (i = 0, pq_id = pf_id * QM_PF_QUEUE_GROUP_SIZE;
764fe56b9e6SYuval Mintz 	     i < QM_OTHER_PQS_PER_PF; i++, pq_id++) {
765da090917STomer Tayar 		/* Set PQ base address */
766fe56b9e6SYuval Mintz 		STORE_RT_REG(p_hwfn,
767fe56b9e6SYuval Mintz 			     QM_REG_BASEADDROTHERPQ_RT_OFFSET + pq_id,
768fe56b9e6SYuval Mintz 			     mem_addr_4kb);
769da090917STomer Tayar 
770da090917STomer Tayar 		/* Clear PQ pointer table entry */
771da090917STomer Tayar 		if (is_pf_loading)
772da090917STomer Tayar 			for (j = 0; j < 2; j++)
773da090917STomer Tayar 				STORE_RT_REG(p_hwfn,
774da090917STomer Tayar 					     QM_REG_PTRTBLOTHER_RT_OFFSET +
775da090917STomer Tayar 					     (pq_id * 2) + j, 0);
776da090917STomer Tayar 
777fe56b9e6SYuval Mintz 		mem_addr_4kb += pq_mem_4kb;
778fe56b9e6SYuval Mintz 	}
779fe56b9e6SYuval Mintz }
780fe56b9e6SYuval Mintz 
781fe56b9e6SYuval Mintz /* Prepare PF WFQ runtime init values for the specified PF.
782fe56b9e6SYuval Mintz  * Return -1 on error.
783fe56b9e6SYuval Mintz  */
qed_pf_wfq_rt_init(struct qed_hwfn * p_hwfn,struct qed_qm_pf_rt_init_params * p_params)784fe56b9e6SYuval Mintz static int qed_pf_wfq_rt_init(struct qed_hwfn *p_hwfn,
785fe56b9e6SYuval Mintz 			      struct qed_qm_pf_rt_init_params *p_params)
786fe56b9e6SYuval Mintz {
787fe56b9e6SYuval Mintz 	u16 num_tx_pqs = p_params->num_pf_pqs + p_params->num_vf_pqs;
788da090917STomer Tayar 	struct init_qm_pq_params *pq_params = p_params->pq_params;
789da090917STomer Tayar 	u32 inc_val, crd_reg_offset;
790da090917STomer Tayar 	u8 ext_voq;
791fe56b9e6SYuval Mintz 	u16 i;
792fe56b9e6SYuval Mintz 
793b90cb538SOmkar Kulkarni 	inc_val = QM_PF_WFQ_INC_VAL(p_params->pf_wfq);
794b90cb538SOmkar Kulkarni 	if (!inc_val || inc_val > QM_PF_WFQ_MAX_INC_VAL) {
7957b6859fbSMintz, Yuval 		DP_NOTICE(p_hwfn, "Invalid PF WFQ weight configuration\n");
796fe56b9e6SYuval Mintz 		return -1;
797fe56b9e6SYuval Mintz 	}
798fe56b9e6SYuval Mintz 
799fe56b9e6SYuval Mintz 	for (i = 0; i < num_tx_pqs; i++) {
800da090917STomer Tayar 		ext_voq = qed_get_ext_voq(p_hwfn,
80150bc60cbSMichal Kalderon 					  pq_params[i].port_id,
802da090917STomer Tayar 					  pq_params[i].tc_id,
803fe56b9e6SYuval Mintz 					  p_params->max_phys_tcs_per_port);
804da090917STomer Tayar 		crd_reg_offset =
805da090917STomer Tayar 			(p_params->pf_id < MAX_NUM_PFS_BB ?
806da090917STomer Tayar 			 QM_REG_WFQPFCRD_RT_OFFSET :
807da090917STomer Tayar 			 QM_REG_WFQPFCRD_MSB_RT_OFFSET) +
808da090917STomer Tayar 			ext_voq * MAX_NUM_PFS_BB +
809da090917STomer Tayar 			(p_params->pf_id % MAX_NUM_PFS_BB);
810fe56b9e6SYuval Mintz 		OVERWRITE_RT_REG(p_hwfn,
811da090917STomer Tayar 				 crd_reg_offset, (u32)QM_WFQ_CRD_REG_SIGN_BIT);
812fe56b9e6SYuval Mintz 	}
813fe56b9e6SYuval Mintz 
814351a4dedSYuval Mintz 	STORE_RT_REG(p_hwfn,
815351a4dedSYuval Mintz 		     QM_REG_WFQPFUPPERBOUND_RT_OFFSET + p_params->pf_id,
816b90cb538SOmkar Kulkarni 		     QM_PF_WFQ_UPPER_BOUND | (u32)QM_WFQ_CRD_REG_SIGN_BIT);
817be086e7cSMintz, Yuval 	STORE_RT_REG(p_hwfn, QM_REG_WFQPFWEIGHT_RT_OFFSET + p_params->pf_id,
818be086e7cSMintz, Yuval 		     inc_val);
819da090917STomer Tayar 
820fe56b9e6SYuval Mintz 	return 0;
821fe56b9e6SYuval Mintz }
822fe56b9e6SYuval Mintz 
823fe56b9e6SYuval Mintz /* Prepare PF RL runtime init values for the specified PF.
824fe56b9e6SYuval Mintz  * Return -1 on error.
825fe56b9e6SYuval Mintz  */
qed_pf_rl_rt_init(struct qed_hwfn * p_hwfn,u8 pf_id,u32 pf_rl)826351a4dedSYuval Mintz static int qed_pf_rl_rt_init(struct qed_hwfn *p_hwfn, u8 pf_id, u32 pf_rl)
827fe56b9e6SYuval Mintz {
828fe56b9e6SYuval Mintz 	u32 inc_val = QM_RL_INC_VAL(pf_rl);
829fe56b9e6SYuval Mintz 
830da090917STomer Tayar 	if (inc_val > QM_PF_RL_MAX_INC_VAL) {
8317b6859fbSMintz, Yuval 		DP_NOTICE(p_hwfn, "Invalid PF rate limit configuration\n");
832fe56b9e6SYuval Mintz 		return -1;
833fe56b9e6SYuval Mintz 	}
834da090917STomer Tayar 
835da090917STomer Tayar 	STORE_RT_REG(p_hwfn,
836da090917STomer Tayar 		     QM_REG_RLPFCRD_RT_OFFSET + pf_id,
837da090917STomer Tayar 		     (u32)QM_RL_CRD_REG_SIGN_BIT);
838da090917STomer Tayar 	STORE_RT_REG(p_hwfn,
839da090917STomer Tayar 		     QM_REG_RLPFUPPERBOUND_RT_OFFSET + pf_id,
840da090917STomer Tayar 		     QM_PF_RL_UPPER_BOUND | (u32)QM_RL_CRD_REG_SIGN_BIT);
841fe56b9e6SYuval Mintz 	STORE_RT_REG(p_hwfn, QM_REG_RLPFINCVAL_RT_OFFSET + pf_id, inc_val);
842da090917STomer Tayar 
843fe56b9e6SYuval Mintz 	return 0;
844fe56b9e6SYuval Mintz }
845fe56b9e6SYuval Mintz 
846fe56b9e6SYuval Mintz /* Prepare VPORT WFQ runtime init values for the specified VPORTs.
847fe56b9e6SYuval Mintz  * Return -1 on error.
848fe56b9e6SYuval Mintz  */
qed_vp_wfq_rt_init(struct qed_hwfn * p_hwfn,u16 num_vports,struct init_qm_vport_params * vport_params)849fe56b9e6SYuval Mintz static int qed_vp_wfq_rt_init(struct qed_hwfn *p_hwfn,
85092fae6fbSMichal Kalderon 			      u16 num_vports,
851fe56b9e6SYuval Mintz 			      struct init_qm_vport_params *vport_params)
852fe56b9e6SYuval Mintz {
853b90cb538SOmkar Kulkarni 	u16 vport_pq_id, wfq, i;
854fe56b9e6SYuval Mintz 	u32 inc_val;
85592fae6fbSMichal Kalderon 	u8 tc;
856fe56b9e6SYuval Mintz 
8577b6859fbSMintz, Yuval 	/* Go over all PF VPORTs */
858fc48b7a6SYuval Mintz 	for (i = 0; i < num_vports; i++) {
859b90cb538SOmkar Kulkarni 		/* Each VPORT can have several VPORT PQ IDs for various TCs */
860b90cb538SOmkar Kulkarni 		for (tc = 0; tc < NUM_OF_TCS; tc++) {
861b90cb538SOmkar Kulkarni 			/* Check if VPORT/TC is valid */
862b90cb538SOmkar Kulkarni 			vport_pq_id = vport_params[i].first_tx_pq_id[tc];
863b90cb538SOmkar Kulkarni 			if (vport_pq_id == QM_INVALID_PQ_ID)
864fe56b9e6SYuval Mintz 				continue;
865fe56b9e6SYuval Mintz 
866b90cb538SOmkar Kulkarni 			/* Find WFQ weight (per VPORT or per VPORT+TC) */
867b90cb538SOmkar Kulkarni 			wfq = vport_params[i].wfq;
868b90cb538SOmkar Kulkarni 			wfq = wfq ? wfq : vport_params[i].tc_wfq[tc];
869b90cb538SOmkar Kulkarni 			inc_val = QM_VP_WFQ_INC_VAL(wfq);
870b90cb538SOmkar Kulkarni 			if (inc_val > QM_VP_WFQ_MAX_INC_VAL) {
871fe56b9e6SYuval Mintz 				DP_NOTICE(p_hwfn,
8727b6859fbSMintz, Yuval 					  "Invalid VPORT WFQ weight configuration\n");
873fe56b9e6SYuval Mintz 				return -1;
874fe56b9e6SYuval Mintz 			}
875fe56b9e6SYuval Mintz 
876b90cb538SOmkar Kulkarni 			/* Config registers */
877b90cb538SOmkar Kulkarni 			STORE_RT_REG(p_hwfn, QM_REG_WFQVPCRD_RT_OFFSET +
878fe56b9e6SYuval Mintz 				     vport_pq_id,
879da090917STomer Tayar 				     (u32)QM_WFQ_CRD_REG_SIGN_BIT);
880b90cb538SOmkar Kulkarni 			STORE_RT_REG(p_hwfn, QM_REG_WFQVPUPPERBOUND_RT_OFFSET +
881b90cb538SOmkar Kulkarni 				     vport_pq_id,
882b90cb538SOmkar Kulkarni 				     inc_val | QM_WFQ_CRD_REG_SIGN_BIT);
883b90cb538SOmkar Kulkarni 			STORE_RT_REG(p_hwfn, QM_REG_WFQVPWEIGHT_RT_OFFSET +
884fc48b7a6SYuval Mintz 				     vport_pq_id, inc_val);
885fe56b9e6SYuval Mintz 		}
886fe56b9e6SYuval Mintz 	}
887fe56b9e6SYuval Mintz 
888fe56b9e6SYuval Mintz 	return 0;
889fe56b9e6SYuval Mintz }
890fe56b9e6SYuval Mintz 
qed_poll_on_qm_cmd_ready(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt)891fe56b9e6SYuval Mintz static bool qed_poll_on_qm_cmd_ready(struct qed_hwfn *p_hwfn,
892fe56b9e6SYuval Mintz 				     struct qed_ptt *p_ptt)
893fe56b9e6SYuval Mintz {
894fe56b9e6SYuval Mintz 	u32 reg_val, i;
895fe56b9e6SYuval Mintz 
896da090917STomer Tayar 	for (i = 0, reg_val = 0; i < QM_STOP_CMD_MAX_POLL_COUNT && !reg_val;
897fe56b9e6SYuval Mintz 	     i++) {
898fe56b9e6SYuval Mintz 		udelay(QM_STOP_CMD_POLL_PERIOD_US);
899fe56b9e6SYuval Mintz 		reg_val = qed_rd(p_hwfn, p_ptt, QM_REG_SDMCMDREADY);
900fe56b9e6SYuval Mintz 	}
901fe56b9e6SYuval Mintz 
9027b6859fbSMintz, Yuval 	/* Check if timeout while waiting for SDM command ready */
903fe56b9e6SYuval Mintz 	if (i == QM_STOP_CMD_MAX_POLL_COUNT) {
904fe56b9e6SYuval Mintz 		DP_VERBOSE(p_hwfn, NETIF_MSG_HW,
905fe56b9e6SYuval Mintz 			   "Timeout when waiting for QM SDM command ready signal\n");
906fe56b9e6SYuval Mintz 		return false;
907fe56b9e6SYuval Mintz 	}
908fe56b9e6SYuval Mintz 
909fe56b9e6SYuval Mintz 	return true;
910fe56b9e6SYuval Mintz }
911fe56b9e6SYuval Mintz 
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)912fe56b9e6SYuval Mintz static bool qed_send_qm_cmd(struct qed_hwfn *p_hwfn,
913fe56b9e6SYuval Mintz 			    struct qed_ptt *p_ptt,
914351a4dedSYuval Mintz 			    u32 cmd_addr, u32 cmd_data_lsb, u32 cmd_data_msb)
915fe56b9e6SYuval Mintz {
916fe56b9e6SYuval Mintz 	if (!qed_poll_on_qm_cmd_ready(p_hwfn, p_ptt))
917fe56b9e6SYuval Mintz 		return false;
918fe56b9e6SYuval Mintz 
919fe56b9e6SYuval Mintz 	qed_wr(p_hwfn, p_ptt, QM_REG_SDMCMDADDR, cmd_addr);
920fe56b9e6SYuval Mintz 	qed_wr(p_hwfn, p_ptt, QM_REG_SDMCMDDATALSB, cmd_data_lsb);
921fe56b9e6SYuval Mintz 	qed_wr(p_hwfn, p_ptt, QM_REG_SDMCMDDATAMSB, cmd_data_msb);
922fe56b9e6SYuval Mintz 	qed_wr(p_hwfn, p_ptt, QM_REG_SDMCMDGO, 1);
923fe56b9e6SYuval Mintz 	qed_wr(p_hwfn, p_ptt, QM_REG_SDMCMDGO, 0);
924fe56b9e6SYuval Mintz 
925fe56b9e6SYuval Mintz 	return qed_poll_on_qm_cmd_ready(p_hwfn, p_ptt);
926fe56b9e6SYuval Mintz }
927fe56b9e6SYuval Mintz 
928fe56b9e6SYuval Mintz /******************** INTERFACE IMPLEMENTATION *********************/
929da090917STomer Tayar 
qed_qm_pf_mem_size(u32 num_pf_cids,u32 num_vf_cids,u32 num_tids,u16 num_pf_pqs,u16 num_vf_pqs)930da090917STomer Tayar u32 qed_qm_pf_mem_size(u32 num_pf_cids,
931fe56b9e6SYuval Mintz 		       u32 num_vf_cids,
932351a4dedSYuval Mintz 		       u32 num_tids, u16 num_pf_pqs, u16 num_vf_pqs)
933fe56b9e6SYuval Mintz {
934fe56b9e6SYuval Mintz 	return QM_PQ_MEM_4KB(num_pf_cids) * num_pf_pqs +
935fe56b9e6SYuval Mintz 	       QM_PQ_MEM_4KB(num_vf_cids) * num_vf_pqs +
936fe56b9e6SYuval Mintz 	       QM_PQ_MEM_4KB(num_pf_cids + num_tids) * QM_OTHER_PQS_PER_PF;
937fe56b9e6SYuval Mintz }
938fe56b9e6SYuval Mintz 
qed_qm_common_rt_init(struct qed_hwfn * p_hwfn,struct qed_qm_common_rt_init_params * p_params)939da090917STomer Tayar int qed_qm_common_rt_init(struct qed_hwfn *p_hwfn,
940fe56b9e6SYuval Mintz 			  struct qed_qm_common_rt_init_params *p_params)
941fe56b9e6SYuval Mintz {
94292fae6fbSMichal Kalderon 	u32 mask = 0;
943fe56b9e6SYuval Mintz 
94492fae6fbSMichal Kalderon 	/* Init AFullOprtnstcCrdMask */
94592fae6fbSMichal Kalderon 	SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_LINEVOQ,
94692fae6fbSMichal Kalderon 		  QM_OPPOR_LINE_VOQ_DEF);
94792fae6fbSMichal Kalderon 	SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_BYTEVOQ, QM_BYTE_CRD_EN);
948b90cb538SOmkar Kulkarni 	SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_PFWFQ,
949b90cb538SOmkar Kulkarni 		  p_params->pf_wfq_en ? 1 : 0);
950b90cb538SOmkar Kulkarni 	SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_VPWFQ,
951b90cb538SOmkar Kulkarni 		  p_params->vport_wfq_en ? 1 : 0);
952b90cb538SOmkar Kulkarni 	SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_PFRL,
953b90cb538SOmkar Kulkarni 		  p_params->pf_rl_en ? 1 : 0);
95492fae6fbSMichal Kalderon 	SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_VPQCNRL,
955b90cb538SOmkar Kulkarni 		  p_params->global_rl_en ? 1 : 0);
95692fae6fbSMichal Kalderon 	SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_FWPAUSE, QM_OPPOR_FW_STOP_DEF);
95792fae6fbSMichal Kalderon 	SET_FIELD(mask,
95892fae6fbSMichal Kalderon 		  QM_RF_OPPORTUNISTIC_MASK_QUEUEEMPTY, QM_OPPOR_PQ_EMPTY_DEF);
959fe56b9e6SYuval Mintz 	STORE_RT_REG(p_hwfn, QM_REG_AFULLOPRTNSTCCRDMASK_RT_OFFSET, mask);
960da090917STomer Tayar 
961da090917STomer Tayar 	/* Enable/disable PF RL */
962fe56b9e6SYuval Mintz 	qed_enable_pf_rl(p_hwfn, p_params->pf_rl_en);
963da090917STomer Tayar 
964da090917STomer Tayar 	/* Enable/disable PF WFQ */
965fe56b9e6SYuval Mintz 	qed_enable_pf_wfq(p_hwfn, p_params->pf_wfq_en);
966da090917STomer Tayar 
96792fae6fbSMichal Kalderon 	/* Enable/disable global RL */
96892fae6fbSMichal Kalderon 	qed_enable_global_rl(p_hwfn, p_params->global_rl_en);
969da090917STomer Tayar 
970da090917STomer Tayar 	/* Enable/disable VPORT WFQ */
971fe56b9e6SYuval Mintz 	qed_enable_vport_wfq(p_hwfn, p_params->vport_wfq_en);
972da090917STomer Tayar 
973da090917STomer Tayar 	/* Init PBF CMDQ line credit */
974fe56b9e6SYuval Mintz 	qed_cmdq_lines_rt_init(p_hwfn,
975fe56b9e6SYuval Mintz 			       p_params->max_ports_per_engine,
976fe56b9e6SYuval Mintz 			       p_params->max_phys_tcs_per_port,
977fe56b9e6SYuval Mintz 			       p_params->port_params);
978da090917STomer Tayar 
979da090917STomer Tayar 	/* Init BTB blocks in PBF */
980fe56b9e6SYuval Mintz 	qed_btb_blocks_rt_init(p_hwfn,
981fe56b9e6SYuval Mintz 			       p_params->max_ports_per_engine,
982fe56b9e6SYuval Mintz 			       p_params->max_phys_tcs_per_port,
983fe56b9e6SYuval Mintz 			       p_params->port_params);
984da090917STomer Tayar 
98592fae6fbSMichal Kalderon 	qed_global_rl_rt_init(p_hwfn);
98692fae6fbSMichal Kalderon 
987fe56b9e6SYuval Mintz 	return 0;
988fe56b9e6SYuval Mintz }
989fe56b9e6SYuval Mintz 
qed_qm_pf_rt_init(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,struct qed_qm_pf_rt_init_params * p_params)990fe56b9e6SYuval Mintz int qed_qm_pf_rt_init(struct qed_hwfn *p_hwfn,
991fe56b9e6SYuval Mintz 		      struct qed_ptt *p_ptt,
992fe56b9e6SYuval Mintz 		      struct qed_qm_pf_rt_init_params *p_params)
993fe56b9e6SYuval Mintz {
994fe56b9e6SYuval Mintz 	struct init_qm_vport_params *vport_params = p_params->vport_params;
995fe56b9e6SYuval Mintz 	u32 other_mem_size_4kb = QM_PQ_MEM_4KB(p_params->num_pf_cids +
996fe56b9e6SYuval Mintz 					       p_params->num_tids) *
997fe56b9e6SYuval Mintz 				 QM_OTHER_PQS_PER_PF;
99892fae6fbSMichal Kalderon 	u16 i;
99992fae6fbSMichal Kalderon 	u8 tc;
100092fae6fbSMichal Kalderon 
10017b6859fbSMintz, Yuval 	/* Clear first Tx PQ ID array for each VPORT */
1002fe56b9e6SYuval Mintz 	for (i = 0; i < p_params->num_vports; i++)
1003fe56b9e6SYuval Mintz 		for (tc = 0; tc < NUM_OF_TCS; tc++)
1004fe56b9e6SYuval Mintz 			vport_params[i].first_tx_pq_id[tc] = QM_INVALID_PQ_ID;
1005fe56b9e6SYuval Mintz 
10067b6859fbSMintz, Yuval 	/* Map Other PQs (if any) */
1007da090917STomer Tayar 	qed_other_pq_map_rt_init(p_hwfn,
1008da090917STomer Tayar 				 p_params->pf_id,
1009da090917STomer Tayar 				 p_params->is_pf_loading, p_params->num_pf_cids,
1010da090917STomer Tayar 				 p_params->num_tids, 0);
1011fe56b9e6SYuval Mintz 
10127b6859fbSMintz, Yuval 	/* Map Tx PQs */
1013b90cb538SOmkar Kulkarni 	if (qed_tx_pq_map_rt_init(p_hwfn, p_ptt, p_params, other_mem_size_4kb))
1014b90cb538SOmkar Kulkarni 		return -1;
1015fe56b9e6SYuval Mintz 
1016da090917STomer Tayar 	/* Init PF WFQ */
1017fe56b9e6SYuval Mintz 	if (p_params->pf_wfq)
1018fe56b9e6SYuval Mintz 		if (qed_pf_wfq_rt_init(p_hwfn, p_params))
1019fe56b9e6SYuval Mintz 			return -1;
1020fe56b9e6SYuval Mintz 
1021da090917STomer Tayar 	/* Init PF RL */
1022fe56b9e6SYuval Mintz 	if (qed_pf_rl_rt_init(p_hwfn, p_params->pf_id, p_params->pf_rl))
1023fe56b9e6SYuval Mintz 		return -1;
1024fe56b9e6SYuval Mintz 
102592fae6fbSMichal Kalderon 	/* Init VPORT WFQ */
1026fc48b7a6SYuval Mintz 	if (qed_vp_wfq_rt_init(p_hwfn, p_params->num_vports, vport_params))
1027fe56b9e6SYuval Mintz 		return -1;
1028fe56b9e6SYuval Mintz 
1029b90cb538SOmkar Kulkarni 	/* Set VPORT RL */
1030b90cb538SOmkar Kulkarni 	if (qed_vport_rl_rt_init(p_hwfn, p_params->start_rl,
1031b90cb538SOmkar Kulkarni 				 p_params->num_rls, p_params->link_speed,
1032b90cb538SOmkar Kulkarni 				 p_params->rl_params))
1033b90cb538SOmkar Kulkarni 		return -1;
1034b90cb538SOmkar Kulkarni 
1035fe56b9e6SYuval Mintz 	return 0;
1036fe56b9e6SYuval Mintz }
1037fe56b9e6SYuval Mintz 
qed_init_pf_wfq(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u8 pf_id,u16 pf_wfq)1038a64b02d5SManish Chopra int qed_init_pf_wfq(struct qed_hwfn *p_hwfn,
1039351a4dedSYuval Mintz 		    struct qed_ptt *p_ptt, u8 pf_id, u16 pf_wfq)
1040a64b02d5SManish Chopra {
1041b90cb538SOmkar Kulkarni 	u32 inc_val = QM_PF_WFQ_INC_VAL(pf_wfq);
1042a64b02d5SManish Chopra 
1043b90cb538SOmkar Kulkarni 	if (!inc_val || inc_val > QM_PF_WFQ_MAX_INC_VAL) {
10447b6859fbSMintz, Yuval 		DP_NOTICE(p_hwfn, "Invalid PF WFQ weight configuration\n");
1045a64b02d5SManish Chopra 		return -1;
1046a64b02d5SManish Chopra 	}
1047a64b02d5SManish Chopra 
1048a64b02d5SManish Chopra 	qed_wr(p_hwfn, p_ptt, QM_REG_WFQPFWEIGHT + pf_id * 4, inc_val);
1049da090917STomer Tayar 
1050a64b02d5SManish Chopra 	return 0;
1051a64b02d5SManish Chopra }
1052a64b02d5SManish Chopra 
qed_init_pf_rl(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u8 pf_id,u32 pf_rl)1053fe56b9e6SYuval Mintz int qed_init_pf_rl(struct qed_hwfn *p_hwfn,
1054351a4dedSYuval Mintz 		   struct qed_ptt *p_ptt, u8 pf_id, u32 pf_rl)
1055fe56b9e6SYuval Mintz {
1056fe56b9e6SYuval Mintz 	u32 inc_val = QM_RL_INC_VAL(pf_rl);
1057fe56b9e6SYuval Mintz 
1058da090917STomer Tayar 	if (inc_val > QM_PF_RL_MAX_INC_VAL) {
10597b6859fbSMintz, Yuval 		DP_NOTICE(p_hwfn, "Invalid PF rate limit configuration\n");
1060fe56b9e6SYuval Mintz 		return -1;
1061fe56b9e6SYuval Mintz 	}
1062fe56b9e6SYuval Mintz 
1063da090917STomer Tayar 	qed_wr(p_hwfn,
1064da090917STomer Tayar 	       p_ptt, QM_REG_RLPFCRD + pf_id * 4, (u32)QM_RL_CRD_REG_SIGN_BIT);
1065fe56b9e6SYuval Mintz 	qed_wr(p_hwfn, p_ptt, QM_REG_RLPFINCVAL + pf_id * 4, inc_val);
1066fe56b9e6SYuval Mintz 
1067fe56b9e6SYuval Mintz 	return 0;
1068fe56b9e6SYuval Mintz }
1069fe56b9e6SYuval Mintz 
qed_init_vport_wfq(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u16 first_tx_pq_id[NUM_OF_TCS],u16 wfq)1070bcd197c8SManish Chopra int qed_init_vport_wfq(struct qed_hwfn *p_hwfn,
1071bcd197c8SManish Chopra 		       struct qed_ptt *p_ptt,
107292fae6fbSMichal Kalderon 		       u16 first_tx_pq_id[NUM_OF_TCS], u16 wfq)
1073bcd197c8SManish Chopra {
1074b90cb538SOmkar Kulkarni 	int result = 0;
10757b6859fbSMintz, Yuval 	u16 vport_pq_id;
1076bcd197c8SManish Chopra 	u8 tc;
1077bcd197c8SManish Chopra 
1078b90cb538SOmkar Kulkarni 	for (tc = 0; tc < NUM_OF_TCS && !result; tc++) {
1079b90cb538SOmkar Kulkarni 		vport_pq_id = first_tx_pq_id[tc];
1080b90cb538SOmkar Kulkarni 		if (vport_pq_id != QM_INVALID_PQ_ID)
1081b90cb538SOmkar Kulkarni 			result = qed_init_vport_tc_wfq(p_hwfn, p_ptt,
1082b90cb538SOmkar Kulkarni 						       vport_pq_id, wfq);
1083b90cb538SOmkar Kulkarni 	}
1084b90cb538SOmkar Kulkarni 
1085b90cb538SOmkar Kulkarni 	return result;
1086b90cb538SOmkar Kulkarni }
1087b90cb538SOmkar Kulkarni 
qed_init_vport_tc_wfq(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u16 first_tx_pq_id,u16 wfq)1088b90cb538SOmkar Kulkarni int qed_init_vport_tc_wfq(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
1089b90cb538SOmkar Kulkarni 			  u16 first_tx_pq_id, u16 wfq)
1090b90cb538SOmkar Kulkarni {
1091b90cb538SOmkar Kulkarni 	u32 inc_val;
1092b90cb538SOmkar Kulkarni 
1093b90cb538SOmkar Kulkarni 	if (first_tx_pq_id == QM_INVALID_PQ_ID)
1094b90cb538SOmkar Kulkarni 		return -1;
1095b90cb538SOmkar Kulkarni 
1096b90cb538SOmkar Kulkarni 	inc_val = QM_VP_WFQ_INC_VAL(wfq);
1097b90cb538SOmkar Kulkarni 	if (!inc_val || inc_val > QM_VP_WFQ_MAX_INC_VAL) {
109892fae6fbSMichal Kalderon 		DP_NOTICE(p_hwfn, "Invalid VPORT WFQ configuration.\n");
1099bcd197c8SManish Chopra 		return -1;
1100bcd197c8SManish Chopra 	}
1101bcd197c8SManish Chopra 
1102b90cb538SOmkar Kulkarni 	qed_wr(p_hwfn, p_ptt, QM_REG_WFQVPCRD + first_tx_pq_id * 4,
1103b90cb538SOmkar Kulkarni 	       (u32)QM_WFQ_CRD_REG_SIGN_BIT);
1104b90cb538SOmkar Kulkarni 	qed_wr(p_hwfn, p_ptt, QM_REG_WFQVPUPPERBOUND + first_tx_pq_id * 4,
1105b90cb538SOmkar Kulkarni 	       inc_val | QM_WFQ_CRD_REG_SIGN_BIT);
1106b90cb538SOmkar Kulkarni 	qed_wr(p_hwfn, p_ptt, QM_REG_WFQVPWEIGHT + first_tx_pq_id * 4,
1107b90cb538SOmkar Kulkarni 	       inc_val);
1108bcd197c8SManish Chopra 
1109bcd197c8SManish Chopra 	return 0;
1110bcd197c8SManish Chopra }
1111bcd197c8SManish Chopra 
qed_init_global_rl(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u16 rl_id,u32 rate_limit,enum init_qm_rl_type vport_rl_type)111292fae6fbSMichal Kalderon int qed_init_global_rl(struct qed_hwfn *p_hwfn,
1113fe40a830SPrabhakar Kushwaha 		       struct qed_ptt *p_ptt, u16 rl_id, u32 rate_limit,
1114fe40a830SPrabhakar Kushwaha 		       enum init_qm_rl_type vport_rl_type)
1115fe56b9e6SYuval Mintz {
1116b90cb538SOmkar Kulkarni 	u32 inc_val, upper_bound;
1117fe56b9e6SYuval Mintz 
1118b90cb538SOmkar Kulkarni 	upper_bound =
1119b90cb538SOmkar Kulkarni 	    (vport_rl_type ==
1120b90cb538SOmkar Kulkarni 	     QM_RL_TYPE_QCN) ? QM_GLOBAL_RL_UPPER_BOUND(QM_MAX_LINK_SPEED) :
1121b90cb538SOmkar Kulkarni 	    QM_INITIAL_VOQ_BYTE_CRD;
112292fae6fbSMichal Kalderon 	inc_val = QM_RL_INC_VAL(rate_limit);
1123b90cb538SOmkar Kulkarni 	if (inc_val > upper_bound) {
1124b90cb538SOmkar Kulkarni 		DP_NOTICE(p_hwfn, "Invalid VPORT rate limit configuration.\n");
1125be086e7cSMintz, Yuval 		return -1;
1126be086e7cSMintz, Yuval 	}
1127be086e7cSMintz, Yuval 
112892fae6fbSMichal Kalderon 	qed_wr(p_hwfn, p_ptt,
112992fae6fbSMichal Kalderon 	       QM_REG_RLGLBLCRD + rl_id * 4, (u32)QM_RL_CRD_REG_SIGN_BIT);
1130b90cb538SOmkar Kulkarni 	qed_wr(p_hwfn,
1131b90cb538SOmkar Kulkarni 	       p_ptt,
1132b90cb538SOmkar Kulkarni 	       QM_REG_RLGLBLUPPERBOUND + rl_id * 4,
1133b90cb538SOmkar Kulkarni 	       upper_bound | (u32)QM_RL_CRD_REG_SIGN_BIT);
113492fae6fbSMichal Kalderon 	qed_wr(p_hwfn, p_ptt, QM_REG_RLGLBLINCVAL + rl_id * 4, inc_val);
1135fe56b9e6SYuval Mintz 
1136fe56b9e6SYuval Mintz 	return 0;
1137fe56b9e6SYuval Mintz }
1138fe56b9e6SYuval Mintz 
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)1139fe56b9e6SYuval Mintz bool qed_send_qm_stop_cmd(struct qed_hwfn *p_hwfn,
1140fe56b9e6SYuval Mintz 			  struct qed_ptt *p_ptt,
1141fe56b9e6SYuval Mintz 			  bool is_release_cmd,
1142351a4dedSYuval Mintz 			  bool is_tx_pq, u16 start_pq, u16 num_pqs)
1143fe56b9e6SYuval Mintz {
1144fe56b9e6SYuval Mintz 	u32 cmd_arr[QM_CMD_STRUCT_SIZE(QM_STOP_CMD)] = { 0 };
1145da090917STomer Tayar 	u32 pq_mask = 0, last_pq, pq_id;
1146da090917STomer Tayar 
1147da090917STomer Tayar 	last_pq = start_pq + num_pqs - 1;
1148fe56b9e6SYuval Mintz 
11497b6859fbSMintz, Yuval 	/* Set command's PQ type */
1150fe56b9e6SYuval Mintz 	QM_CMD_SET_FIELD(cmd_arr, QM_STOP_CMD, PQ_TYPE, is_tx_pq ? 0 : 1);
1151fe56b9e6SYuval Mintz 
1152da090917STomer Tayar 	/* Go over requested PQs */
1153fe56b9e6SYuval Mintz 	for (pq_id = start_pq; pq_id <= last_pq; pq_id++) {
11547b6859fbSMintz, Yuval 		/* Set PQ bit in mask (stop command only) */
1155fe56b9e6SYuval Mintz 		if (!is_release_cmd)
1156da090917STomer Tayar 			pq_mask |= BIT((pq_id % QM_STOP_PQ_MASK_WIDTH));
1157fe56b9e6SYuval Mintz 
11587b6859fbSMintz, Yuval 		/* If last PQ or end of PQ mask, write command */
1159fe56b9e6SYuval Mintz 		if ((pq_id == last_pq) ||
1160fe56b9e6SYuval Mintz 		    (pq_id % QM_STOP_PQ_MASK_WIDTH ==
1161fe56b9e6SYuval Mintz 		     (QM_STOP_PQ_MASK_WIDTH - 1))) {
1162da090917STomer Tayar 			QM_CMD_SET_FIELD(cmd_arr,
1163da090917STomer Tayar 					 QM_STOP_CMD, PAUSE_MASK, pq_mask);
1164da090917STomer Tayar 			QM_CMD_SET_FIELD(cmd_arr,
1165da090917STomer Tayar 					 QM_STOP_CMD,
1166fe56b9e6SYuval Mintz 					 GROUP_ID,
1167fe56b9e6SYuval Mintz 					 pq_id / QM_STOP_PQ_MASK_WIDTH);
1168fe56b9e6SYuval Mintz 			if (!qed_send_qm_cmd(p_hwfn, p_ptt, QM_STOP_CMD_ADDR,
1169fe56b9e6SYuval Mintz 					     cmd_arr[0], cmd_arr[1]))
1170fe56b9e6SYuval Mintz 				return false;
1171fe56b9e6SYuval Mintz 			pq_mask = 0;
1172fe56b9e6SYuval Mintz 		}
1173fe56b9e6SYuval Mintz 	}
1174fe56b9e6SYuval Mintz 
1175fe56b9e6SYuval Mintz 	return true;
1176fe56b9e6SYuval Mintz }
1177464f6645SManish Chopra 
1178da090917STomer Tayar #define SET_TUNNEL_TYPE_ENABLE_BIT(var, offset, enable) \
1179da090917STomer Tayar 	do { \
1180da090917STomer Tayar 		typeof(var) *__p_var = &(var); \
1181da090917STomer Tayar 		typeof(offset) __offset = offset; \
1182da090917STomer Tayar 		*__p_var = (*__p_var & ~BIT(__offset)) | \
1183da090917STomer Tayar 			   ((enable) ? BIT(__offset) : 0); \
1184da090917STomer Tayar 	} while (0)
118563ddca30SMichal Kalderon 
118663ddca30SMichal Kalderon #define PRS_ETH_TUNN_OUTPUT_FORMAT     0xF4DAB910
118763ddca30SMichal Kalderon #define PRS_ETH_OUTPUT_FORMAT          0xFFFF4910
1188464f6645SManish Chopra 
1189804c5702SMichal Kalderon #define ARR_REG_WR(dev, ptt, addr, arr,	arr_size) \
1190804c5702SMichal Kalderon 	do { \
1191804c5702SMichal Kalderon 		u32 i; \
1192804c5702SMichal Kalderon 		\
1193804c5702SMichal Kalderon 		for (i = 0; i < (arr_size); i++) \
1194804c5702SMichal Kalderon 			qed_wr(dev, ptt, \
1195804c5702SMichal Kalderon 			       ((addr) + (4 * i)), \
1196804c5702SMichal Kalderon 			       ((u32 *)&(arr))[i]); \
1197804c5702SMichal Kalderon 	} while (0)
1198804c5702SMichal Kalderon 
1199804c5702SMichal Kalderon /**
120071e11a3fSAlexander Lobakin  * qed_dmae_to_grc() - Internal function for writing from host to
120171e11a3fSAlexander Lobakin  * wide-bus registers (split registers are not supported yet).
1202804c5702SMichal Kalderon  *
120371e11a3fSAlexander Lobakin  * @p_hwfn: HW device data.
120471e11a3fSAlexander Lobakin  * @p_ptt: PTT window used for writing the registers.
120571e11a3fSAlexander Lobakin  * @p_data: Pointer to source data.
120671e11a3fSAlexander Lobakin  * @addr: Destination register address.
120771e11a3fSAlexander Lobakin  * @len_in_dwords: Data length in dwords (u32).
120871e11a3fSAlexander Lobakin  *
120971e11a3fSAlexander Lobakin  * Return: Length of the written data in dwords (u32) or -1 on invalid
121071e11a3fSAlexander Lobakin  *         input.
1211804c5702SMichal Kalderon  */
qed_dmae_to_grc(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,__le32 * p_data,u32 addr,u32 len_in_dwords)12121451e467SAlexander Lobakin static int qed_dmae_to_grc(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
12135ab90341SAlexander Lobakin 			   __le32 *p_data, u32 addr, u32 len_in_dwords)
1214804c5702SMichal Kalderon {
1215b90cb538SOmkar Kulkarni 	struct qed_dmae_params params = { 0 };
12165ab90341SAlexander Lobakin 	u32 *data_cpu;
1217804c5702SMichal Kalderon 	int rc;
1218804c5702SMichal Kalderon 
1219804c5702SMichal Kalderon 	if (!p_data)
1220804c5702SMichal Kalderon 		return -1;
1221804c5702SMichal Kalderon 
1222804c5702SMichal Kalderon 	/* Set DMAE params */
1223804c5702SMichal Kalderon 	SET_FIELD(params.flags, QED_DMAE_PARAMS_COMPLETION_DST, 1);
1224804c5702SMichal Kalderon 
1225804c5702SMichal Kalderon 	/* Execute DMAE command */
1226804c5702SMichal Kalderon 	rc = qed_dmae_host2grc(p_hwfn, p_ptt,
1227804c5702SMichal Kalderon 			       (u64)(uintptr_t)(p_data),
1228804c5702SMichal Kalderon 			       addr, len_in_dwords, &params);
1229804c5702SMichal Kalderon 
1230804c5702SMichal Kalderon 	/* If not read using DMAE, read using GRC */
1231804c5702SMichal Kalderon 	if (rc) {
1232804c5702SMichal Kalderon 		DP_VERBOSE(p_hwfn,
1233804c5702SMichal Kalderon 			   QED_MSG_DEBUG,
1234804c5702SMichal Kalderon 			   "Failed writing to chip using DMAE, using GRC instead\n");
12355ab90341SAlexander Lobakin 
12365ab90341SAlexander Lobakin 		/* Swap to CPU byteorder and write to registers using GRC */
12375ab90341SAlexander Lobakin 		data_cpu = (__force u32 *)p_data;
12385ab90341SAlexander Lobakin 		le32_to_cpu_array(data_cpu, len_in_dwords);
12395ab90341SAlexander Lobakin 
12405ab90341SAlexander Lobakin 		ARR_REG_WR(p_hwfn, p_ptt, addr, data_cpu, len_in_dwords);
12415ab90341SAlexander Lobakin 		cpu_to_le32_array(data_cpu, len_in_dwords);
1242804c5702SMichal Kalderon 	}
1243804c5702SMichal Kalderon 
1244804c5702SMichal Kalderon 	return len_in_dwords;
1245804c5702SMichal Kalderon }
1246804c5702SMichal Kalderon 
qed_set_vxlan_dest_port(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u16 dest_port)1247464f6645SManish Chopra void qed_set_vxlan_dest_port(struct qed_hwfn *p_hwfn,
1248351a4dedSYuval Mintz 			     struct qed_ptt *p_ptt, u16 dest_port)
1249464f6645SManish Chopra {
1250da090917STomer Tayar 	/* Update PRS register */
1251464f6645SManish Chopra 	qed_wr(p_hwfn, p_ptt, PRS_REG_VXLAN_PORT, dest_port);
1252da090917STomer Tayar 
1253da090917STomer Tayar 	/* Update NIG register */
1254351a4dedSYuval Mintz 	qed_wr(p_hwfn, p_ptt, NIG_REG_VXLAN_CTRL, dest_port);
1255da090917STomer Tayar 
1256da090917STomer Tayar 	/* Update PBF register */
1257464f6645SManish Chopra 	qed_wr(p_hwfn, p_ptt, PBF_REG_VXLAN_PORT, dest_port);
1258464f6645SManish Chopra }
1259464f6645SManish Chopra 
qed_set_vxlan_enable(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,bool vxlan_enable)1260464f6645SManish Chopra void qed_set_vxlan_enable(struct qed_hwfn *p_hwfn,
1261351a4dedSYuval Mintz 			  struct qed_ptt *p_ptt, bool vxlan_enable)
1262464f6645SManish Chopra {
1263da090917STomer Tayar 	u32 reg_val;
1264464f6645SManish Chopra 	u8 shift;
1265464f6645SManish Chopra 
1266da090917STomer Tayar 	/* Update PRS register */
1267464f6645SManish Chopra 	reg_val = qed_rd(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN);
1268b90cb538SOmkar Kulkarni 	SET_FIELD(reg_val,
1269b90cb538SOmkar Kulkarni 		  PRS_REG_ENCAPSULATION_TYPE_EN_VXLAN_ENABLE, vxlan_enable);
1270464f6645SManish Chopra 	qed_wr(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN, reg_val);
127150bc60cbSMichal Kalderon 	if (reg_val) {
127250bc60cbSMichal Kalderon 		reg_val =
1273b90cb538SOmkar Kulkarni 		    qed_rd(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0);
127450bc60cbSMichal Kalderon 
127550bc60cbSMichal Kalderon 		/* Update output  only if tunnel blocks not included. */
127650bc60cbSMichal Kalderon 		if (reg_val == (u32)PRS_ETH_OUTPUT_FORMAT)
1277b90cb538SOmkar Kulkarni 			qed_wr(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0,
127850bc60cbSMichal Kalderon 			       (u32)PRS_ETH_TUNN_OUTPUT_FORMAT);
127950bc60cbSMichal Kalderon 	}
1280464f6645SManish Chopra 
1281da090917STomer Tayar 	/* Update NIG register */
1282464f6645SManish Chopra 	reg_val = qed_rd(p_hwfn, p_ptt, NIG_REG_ENC_TYPE_ENABLE);
1283464f6645SManish Chopra 	shift = NIG_REG_ENC_TYPE_ENABLE_VXLAN_ENABLE_SHIFT;
1284da090917STomer Tayar 	SET_TUNNEL_TYPE_ENABLE_BIT(reg_val, shift, vxlan_enable);
1285464f6645SManish Chopra 	qed_wr(p_hwfn, p_ptt, NIG_REG_ENC_TYPE_ENABLE, reg_val);
1286464f6645SManish Chopra 
1287da090917STomer Tayar 	/* Update DORQ register */
1288da090917STomer Tayar 	qed_wr(p_hwfn,
1289da090917STomer Tayar 	       p_ptt, DORQ_REG_L2_EDPM_TUNNEL_VXLAN_EN, vxlan_enable ? 1 : 0);
1290464f6645SManish Chopra }
1291464f6645SManish Chopra 
qed_set_gre_enable(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,bool eth_gre_enable,bool ip_gre_enable)1292da090917STomer Tayar void qed_set_gre_enable(struct qed_hwfn *p_hwfn,
1293da090917STomer Tayar 			struct qed_ptt *p_ptt,
1294464f6645SManish Chopra 			bool eth_gre_enable, bool ip_gre_enable)
1295464f6645SManish Chopra {
1296da090917STomer Tayar 	u32 reg_val;
1297464f6645SManish Chopra 	u8 shift;
1298464f6645SManish Chopra 
1299da090917STomer Tayar 	/* Update PRS register */
1300464f6645SManish Chopra 	reg_val = qed_rd(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN);
1301b90cb538SOmkar Kulkarni 	SET_FIELD(reg_val,
1302b90cb538SOmkar Kulkarni 		  PRS_REG_ENCAPSULATION_TYPE_EN_ETH_OVER_GRE_ENABLE,
1303b90cb538SOmkar Kulkarni 		  eth_gre_enable);
1304b90cb538SOmkar Kulkarni 	SET_FIELD(reg_val,
1305b90cb538SOmkar Kulkarni 		  PRS_REG_ENCAPSULATION_TYPE_EN_IP_OVER_GRE_ENABLE,
1306b90cb538SOmkar Kulkarni 		  ip_gre_enable);
1307464f6645SManish Chopra 	qed_wr(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN, reg_val);
130850bc60cbSMichal Kalderon 	if (reg_val) {
130950bc60cbSMichal Kalderon 		reg_val =
1310b90cb538SOmkar Kulkarni 		    qed_rd(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0);
131150bc60cbSMichal Kalderon 
131250bc60cbSMichal Kalderon 		/* Update output  only if tunnel blocks not included. */
131350bc60cbSMichal Kalderon 		if (reg_val == (u32)PRS_ETH_OUTPUT_FORMAT)
1314b90cb538SOmkar Kulkarni 			qed_wr(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0,
131550bc60cbSMichal Kalderon 			       (u32)PRS_ETH_TUNN_OUTPUT_FORMAT);
131650bc60cbSMichal Kalderon 	}
1317464f6645SManish Chopra 
1318da090917STomer Tayar 	/* Update NIG register */
1319464f6645SManish Chopra 	reg_val = qed_rd(p_hwfn, p_ptt, NIG_REG_ENC_TYPE_ENABLE);
1320464f6645SManish Chopra 	shift = NIG_REG_ENC_TYPE_ENABLE_ETH_OVER_GRE_ENABLE_SHIFT;
1321da090917STomer Tayar 	SET_TUNNEL_TYPE_ENABLE_BIT(reg_val, shift, eth_gre_enable);
1322464f6645SManish Chopra 	shift = NIG_REG_ENC_TYPE_ENABLE_IP_OVER_GRE_ENABLE_SHIFT;
1323da090917STomer Tayar 	SET_TUNNEL_TYPE_ENABLE_BIT(reg_val, shift, ip_gre_enable);
1324464f6645SManish Chopra 	qed_wr(p_hwfn, p_ptt, NIG_REG_ENC_TYPE_ENABLE, reg_val);
1325464f6645SManish Chopra 
1326da090917STomer Tayar 	/* Update DORQ registers */
1327da090917STomer Tayar 	qed_wr(p_hwfn,
1328da090917STomer Tayar 	       p_ptt,
1329da090917STomer Tayar 	       DORQ_REG_L2_EDPM_TUNNEL_GRE_ETH_EN, eth_gre_enable ? 1 : 0);
1330da090917STomer Tayar 	qed_wr(p_hwfn,
1331da090917STomer Tayar 	       p_ptt, DORQ_REG_L2_EDPM_TUNNEL_GRE_IP_EN, ip_gre_enable ? 1 : 0);
1332464f6645SManish Chopra }
1333464f6645SManish Chopra 
qed_set_geneve_dest_port(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u16 dest_port)1334464f6645SManish Chopra void qed_set_geneve_dest_port(struct qed_hwfn *p_hwfn,
1335351a4dedSYuval Mintz 			      struct qed_ptt *p_ptt, u16 dest_port)
1336464f6645SManish Chopra {
1337da090917STomer Tayar 	/* Update PRS register */
1338464f6645SManish Chopra 	qed_wr(p_hwfn, p_ptt, PRS_REG_NGE_PORT, dest_port);
1339da090917STomer Tayar 
1340da090917STomer Tayar 	/* Update NIG register */
1341464f6645SManish Chopra 	qed_wr(p_hwfn, p_ptt, NIG_REG_NGE_PORT, dest_port);
1342da090917STomer Tayar 
1343da090917STomer Tayar 	/* Update PBF register */
1344464f6645SManish Chopra 	qed_wr(p_hwfn, p_ptt, PBF_REG_NGE_PORT, dest_port);
1345464f6645SManish Chopra }
1346464f6645SManish Chopra 
qed_set_geneve_enable(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,bool eth_geneve_enable,bool ip_geneve_enable)1347464f6645SManish Chopra void qed_set_geneve_enable(struct qed_hwfn *p_hwfn,
1348464f6645SManish Chopra 			   struct qed_ptt *p_ptt,
1349351a4dedSYuval Mintz 			   bool eth_geneve_enable, bool ip_geneve_enable)
1350464f6645SManish Chopra {
1351da090917STomer Tayar 	u32 reg_val;
1352464f6645SManish Chopra 
1353da090917STomer Tayar 	/* Update PRS register */
1354464f6645SManish Chopra 	reg_val = qed_rd(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN);
1355b90cb538SOmkar Kulkarni 	SET_FIELD(reg_val,
1356b90cb538SOmkar Kulkarni 		  PRS_REG_ENCAPSULATION_TYPE_EN_ETH_OVER_GENEVE_ENABLE,
1357b90cb538SOmkar Kulkarni 		  eth_geneve_enable);
1358b90cb538SOmkar Kulkarni 	SET_FIELD(reg_val,
1359b90cb538SOmkar Kulkarni 		  PRS_REG_ENCAPSULATION_TYPE_EN_IP_OVER_GENEVE_ENABLE,
1360b90cb538SOmkar Kulkarni 		  ip_geneve_enable);
1361464f6645SManish Chopra 	qed_wr(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN, reg_val);
136250bc60cbSMichal Kalderon 	if (reg_val) {
136350bc60cbSMichal Kalderon 		reg_val =
1364b90cb538SOmkar Kulkarni 		    qed_rd(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0);
136550bc60cbSMichal Kalderon 
136650bc60cbSMichal Kalderon 		/* Update output  only if tunnel blocks not included. */
136750bc60cbSMichal Kalderon 		if (reg_val == (u32)PRS_ETH_OUTPUT_FORMAT)
1368b90cb538SOmkar Kulkarni 			qed_wr(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0,
136950bc60cbSMichal Kalderon 			       (u32)PRS_ETH_TUNN_OUTPUT_FORMAT);
137050bc60cbSMichal Kalderon 	}
1371464f6645SManish Chopra 
1372da090917STomer Tayar 	/* Update NIG register */
1373464f6645SManish Chopra 	qed_wr(p_hwfn, p_ptt, NIG_REG_NGE_ETH_ENABLE,
1374464f6645SManish Chopra 	       eth_geneve_enable ? 1 : 0);
1375464f6645SManish Chopra 	qed_wr(p_hwfn, p_ptt, NIG_REG_NGE_IP_ENABLE, ip_geneve_enable ? 1 : 0);
1376464f6645SManish Chopra 
1377da090917STomer Tayar 	/* EDPM with geneve tunnel not supported in BB */
1378464f6645SManish Chopra 	if (QED_IS_BB_B0(p_hwfn->cdev))
1379464f6645SManish Chopra 		return;
1380464f6645SManish Chopra 
1381da090917STomer Tayar 	/* Update DORQ registers */
1382da090917STomer Tayar 	qed_wr(p_hwfn,
1383da090917STomer Tayar 	       p_ptt,
1384b90cb538SOmkar Kulkarni 	       DORQ_REG_L2_EDPM_TUNNEL_NGE_ETH_EN_K2,
1385464f6645SManish Chopra 	       eth_geneve_enable ? 1 : 0);
1386da090917STomer Tayar 	qed_wr(p_hwfn,
1387da090917STomer Tayar 	       p_ptt,
1388b90cb538SOmkar Kulkarni 	       DORQ_REG_L2_EDPM_TUNNEL_NGE_IP_EN_K2,
1389464f6645SManish Chopra 	       ip_geneve_enable ? 1 : 0);
1390464f6645SManish Chopra }
1391d51e4af5SChopra, Manish 
139263ddca30SMichal Kalderon #define PRS_ETH_VXLAN_NO_L2_ENABLE_OFFSET      3
1393b90cb538SOmkar Kulkarni #define PRS_ETH_VXLAN_NO_L2_OUTPUT_FORMAT   0xC8DAB910
139450bc60cbSMichal Kalderon 
qed_set_vxlan_no_l2_enable(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,bool enable)139550bc60cbSMichal Kalderon void qed_set_vxlan_no_l2_enable(struct qed_hwfn *p_hwfn,
139650bc60cbSMichal Kalderon 				struct qed_ptt *p_ptt, bool enable)
139750bc60cbSMichal Kalderon {
139850bc60cbSMichal Kalderon 	u32 reg_val, cfg_mask;
139950bc60cbSMichal Kalderon 
140050bc60cbSMichal Kalderon 	/* read PRS config register */
140150bc60cbSMichal Kalderon 	reg_val = qed_rd(p_hwfn, p_ptt, PRS_REG_MSG_INFO);
140250bc60cbSMichal Kalderon 
140350bc60cbSMichal Kalderon 	/* set VXLAN_NO_L2_ENABLE mask */
140450bc60cbSMichal Kalderon 	cfg_mask = BIT(PRS_ETH_VXLAN_NO_L2_ENABLE_OFFSET);
140550bc60cbSMichal Kalderon 
140650bc60cbSMichal Kalderon 	if (enable) {
140750bc60cbSMichal Kalderon 		/* set VXLAN_NO_L2_ENABLE flag */
140850bc60cbSMichal Kalderon 		reg_val |= cfg_mask;
140950bc60cbSMichal Kalderon 
141050bc60cbSMichal Kalderon 		/* update PRS FIC  register */
141150bc60cbSMichal Kalderon 		qed_wr(p_hwfn,
141250bc60cbSMichal Kalderon 		       p_ptt,
1413b90cb538SOmkar Kulkarni 		       PRS_REG_OUTPUT_FORMAT_4_0,
141450bc60cbSMichal Kalderon 		       (u32)PRS_ETH_VXLAN_NO_L2_OUTPUT_FORMAT);
141550bc60cbSMichal Kalderon 	} else {
141650bc60cbSMichal Kalderon 		/* clear VXLAN_NO_L2_ENABLE flag */
141750bc60cbSMichal Kalderon 		reg_val &= ~cfg_mask;
141850bc60cbSMichal Kalderon 	}
141950bc60cbSMichal Kalderon 
142050bc60cbSMichal Kalderon 	/* write PRS config register */
142150bc60cbSMichal Kalderon 	qed_wr(p_hwfn, p_ptt, PRS_REG_MSG_INFO, reg_val);
142250bc60cbSMichal Kalderon }
142350bc60cbSMichal Kalderon 
14247b6859fbSMintz, Yuval #define T_ETH_PACKET_ACTION_GFT_EVENTID  23
14257b6859fbSMintz, Yuval #define PARSER_ETH_CONN_GFT_ACTION_CM_HDR  272
1426d51e4af5SChopra, Manish #define T_ETH_PACKET_MATCH_RFS_EVENTID 25
14277b6859fbSMintz, Yuval #define PARSER_ETH_CONN_CM_HDR 0
1428d51e4af5SChopra, Manish #define CAM_LINE_SIZE sizeof(u32)
1429d51e4af5SChopra, Manish #define RAM_LINE_SIZE sizeof(u64)
1430d51e4af5SChopra, Manish #define REG_SIZE sizeof(u32)
1431d51e4af5SChopra, Manish 
qed_gft_disable(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u16 pf_id)1432da090917STomer Tayar void qed_gft_disable(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u16 pf_id)
1433d51e4af5SChopra, Manish {
1434b90cb538SOmkar Kulkarni 	struct regpair ram_line = { 0 };
1435804c5702SMichal Kalderon 
1436da090917STomer Tayar 	/* Disable gft search for PF */
1437d51e4af5SChopra, Manish 	qed_wr(p_hwfn, p_ptt, PRS_REG_SEARCH_GFT, 0);
1438da090917STomer Tayar 
1439da090917STomer Tayar 	/* Clean ram & cam for next gft session */
1440da090917STomer Tayar 
1441da090917STomer Tayar 	/* Zero camline */
14427b6859fbSMintz, Yuval 	qed_wr(p_hwfn, p_ptt, PRS_REG_GFT_CAM + CAM_LINE_SIZE * pf_id, 0);
1443da090917STomer Tayar 
1444da090917STomer Tayar 	/* Zero ramline */
14455ab90341SAlexander Lobakin 	qed_dmae_to_grc(p_hwfn, p_ptt, &ram_line.lo,
1446804c5702SMichal Kalderon 			PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE * pf_id,
1447804c5702SMichal Kalderon 			sizeof(ram_line) / REG_SIZE);
1448d51e4af5SChopra, Manish }
1449d51e4af5SChopra, Manish 
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)1450da090917STomer Tayar void qed_gft_config(struct qed_hwfn *p_hwfn,
1451da090917STomer Tayar 		    struct qed_ptt *p_ptt,
1452da090917STomer Tayar 		    u16 pf_id,
1453da090917STomer Tayar 		    bool tcp,
1454da090917STomer Tayar 		    bool udp,
1455da090917STomer Tayar 		    bool ipv4, bool ipv6, enum gft_profile_type profile_type)
1456da090917STomer Tayar {
14575ab90341SAlexander Lobakin 	struct regpair ram_line;
14585ab90341SAlexander Lobakin 	u32 search_non_ip_as_gft;
14595ab90341SAlexander Lobakin 	u32 reg_val, cam_line;
14605ab90341SAlexander Lobakin 	u32 lo = 0, hi = 0;
1461d51e4af5SChopra, Manish 
1462d51e4af5SChopra, Manish 	if (!ipv6 && !ipv4)
1463d51e4af5SChopra, Manish 		DP_NOTICE(p_hwfn,
1464da090917STomer Tayar 			  "gft_config: must accept at least on of - ipv4 or ipv6'\n");
1465d51e4af5SChopra, Manish 	if (!tcp && !udp)
1466d51e4af5SChopra, Manish 		DP_NOTICE(p_hwfn,
1467da090917STomer Tayar 			  "gft_config: must accept at least on of - udp or tcp\n");
1468da090917STomer Tayar 	if (profile_type >= MAX_GFT_PROFILE_TYPE)
1469da090917STomer Tayar 		DP_NOTICE(p_hwfn, "gft_config: unsupported gft_profile_type\n");
1470d51e4af5SChopra, Manish 
1471da090917STomer Tayar 	/* Set RFS event ID to be awakened i Tstorm By Prs */
1472da090917STomer Tayar 	reg_val = T_ETH_PACKET_MATCH_RFS_EVENTID <<
1473d51e4af5SChopra, Manish 		  PRS_REG_CM_HDR_GFT_EVENT_ID_SHIFT;
1474da090917STomer Tayar 	reg_val |= PARSER_ETH_CONN_CM_HDR << PRS_REG_CM_HDR_GFT_CM_HDR_SHIFT;
1475da090917STomer Tayar 	qed_wr(p_hwfn, p_ptt, PRS_REG_CM_HDR_GFT, reg_val);
1476d51e4af5SChopra, Manish 
1477da090917STomer Tayar 	/* Do not load context only cid in PRS on match. */
1478d51e4af5SChopra, Manish 	qed_wr(p_hwfn, p_ptt, PRS_REG_LOAD_L2_FILTER, 0);
1479d51e4af5SChopra, Manish 
1480da090917STomer Tayar 	/* Do not use tenant ID exist bit for gft search */
1481da090917STomer Tayar 	qed_wr(p_hwfn, p_ptt, PRS_REG_SEARCH_TENANT_ID, 0);
1482d51e4af5SChopra, Manish 
1483da090917STomer Tayar 	/* Set Cam */
1484da090917STomer Tayar 	cam_line = 0;
1485da090917STomer Tayar 	SET_FIELD(cam_line, GFT_CAM_LINE_MAPPED_VALID, 1);
1486da090917STomer Tayar 
1487da090917STomer Tayar 	/* Filters are per PF!! */
1488da090917STomer Tayar 	SET_FIELD(cam_line,
14897b6859fbSMintz, Yuval 		  GFT_CAM_LINE_MAPPED_PF_ID_MASK,
14907b6859fbSMintz, Yuval 		  GFT_CAM_LINE_MAPPED_PF_ID_MASK_MASK);
1491da090917STomer Tayar 	SET_FIELD(cam_line, GFT_CAM_LINE_MAPPED_PF_ID, pf_id);
1492da090917STomer Tayar 
1493d51e4af5SChopra, Manish 	if (!(tcp && udp)) {
1494da090917STomer Tayar 		SET_FIELD(cam_line,
14957b6859fbSMintz, Yuval 			  GFT_CAM_LINE_MAPPED_UPPER_PROTOCOL_TYPE_MASK,
14967b6859fbSMintz, Yuval 			  GFT_CAM_LINE_MAPPED_UPPER_PROTOCOL_TYPE_MASK_MASK);
1497d51e4af5SChopra, Manish 		if (tcp)
1498da090917STomer Tayar 			SET_FIELD(cam_line,
1499d51e4af5SChopra, Manish 				  GFT_CAM_LINE_MAPPED_UPPER_PROTOCOL_TYPE,
1500d51e4af5SChopra, Manish 				  GFT_PROFILE_TCP_PROTOCOL);
1501d51e4af5SChopra, Manish 		else
1502da090917STomer Tayar 			SET_FIELD(cam_line,
1503d51e4af5SChopra, Manish 				  GFT_CAM_LINE_MAPPED_UPPER_PROTOCOL_TYPE,
1504d51e4af5SChopra, Manish 				  GFT_PROFILE_UDP_PROTOCOL);
1505d51e4af5SChopra, Manish 	}
1506d51e4af5SChopra, Manish 
1507d51e4af5SChopra, Manish 	if (!(ipv4 && ipv6)) {
1508da090917STomer Tayar 		SET_FIELD(cam_line, GFT_CAM_LINE_MAPPED_IP_VERSION_MASK, 1);
1509d51e4af5SChopra, Manish 		if (ipv4)
1510da090917STomer Tayar 			SET_FIELD(cam_line,
1511d51e4af5SChopra, Manish 				  GFT_CAM_LINE_MAPPED_IP_VERSION,
1512d51e4af5SChopra, Manish 				  GFT_PROFILE_IPV4);
1513d51e4af5SChopra, Manish 		else
1514da090917STomer Tayar 			SET_FIELD(cam_line,
1515d51e4af5SChopra, Manish 				  GFT_CAM_LINE_MAPPED_IP_VERSION,
1516d51e4af5SChopra, Manish 				  GFT_PROFILE_IPV6);
1517d51e4af5SChopra, Manish 	}
1518d51e4af5SChopra, Manish 
15197b6859fbSMintz, Yuval 	/* Write characteristics to cam */
1520d51e4af5SChopra, Manish 	qed_wr(p_hwfn, p_ptt, PRS_REG_GFT_CAM + CAM_LINE_SIZE * pf_id,
1521da090917STomer Tayar 	       cam_line);
1522da090917STomer Tayar 	cam_line =
1523da090917STomer Tayar 	    qed_rd(p_hwfn, p_ptt, PRS_REG_GFT_CAM + CAM_LINE_SIZE * pf_id);
1524d51e4af5SChopra, Manish 
15257b6859fbSMintz, Yuval 	/* Write line to RAM - compare to filter 4 tuple */
1526d51e4af5SChopra, Manish 
1527d52c89f1SMichal Kalderon 	/* Search no IP as GFT */
1528d52c89f1SMichal Kalderon 	search_non_ip_as_gft = 0;
1529d52c89f1SMichal Kalderon 
153050bc60cbSMichal Kalderon 	/* Tunnel type */
15315ab90341SAlexander Lobakin 	SET_FIELD(lo, GFT_RAM_LINE_TUNNEL_DST_PORT, 1);
15325ab90341SAlexander Lobakin 	SET_FIELD(lo, GFT_RAM_LINE_TUNNEL_OVER_IP_PROTOCOL, 1);
153350bc60cbSMichal Kalderon 
1534da090917STomer Tayar 	if (profile_type == GFT_PROFILE_TYPE_4_TUPLE) {
15355ab90341SAlexander Lobakin 		SET_FIELD(hi, GFT_RAM_LINE_DST_IP, 1);
15365ab90341SAlexander Lobakin 		SET_FIELD(hi, GFT_RAM_LINE_SRC_IP, 1);
15375ab90341SAlexander Lobakin 		SET_FIELD(hi, GFT_RAM_LINE_OVER_IP_PROTOCOL, 1);
15385ab90341SAlexander Lobakin 		SET_FIELD(lo, GFT_RAM_LINE_ETHERTYPE, 1);
15395ab90341SAlexander Lobakin 		SET_FIELD(lo, GFT_RAM_LINE_SRC_PORT, 1);
15405ab90341SAlexander Lobakin 		SET_FIELD(lo, GFT_RAM_LINE_DST_PORT, 1);
1541da090917STomer Tayar 	} else if (profile_type == GFT_PROFILE_TYPE_L4_DST_PORT) {
15425ab90341SAlexander Lobakin 		SET_FIELD(hi, GFT_RAM_LINE_OVER_IP_PROTOCOL, 1);
15435ab90341SAlexander Lobakin 		SET_FIELD(lo, GFT_RAM_LINE_ETHERTYPE, 1);
15445ab90341SAlexander Lobakin 		SET_FIELD(lo, GFT_RAM_LINE_DST_PORT, 1);
154550bc60cbSMichal Kalderon 	} else if (profile_type == GFT_PROFILE_TYPE_IP_DST_ADDR) {
15465ab90341SAlexander Lobakin 		SET_FIELD(hi, GFT_RAM_LINE_DST_IP, 1);
15475ab90341SAlexander Lobakin 		SET_FIELD(lo, GFT_RAM_LINE_ETHERTYPE, 1);
154850bc60cbSMichal Kalderon 	} else if (profile_type == GFT_PROFILE_TYPE_IP_SRC_ADDR) {
15495ab90341SAlexander Lobakin 		SET_FIELD(hi, GFT_RAM_LINE_SRC_IP, 1);
15505ab90341SAlexander Lobakin 		SET_FIELD(lo, GFT_RAM_LINE_ETHERTYPE, 1);
155150bc60cbSMichal Kalderon 	} else if (profile_type == GFT_PROFILE_TYPE_TUNNEL_TYPE) {
15525ab90341SAlexander Lobakin 		SET_FIELD(lo, GFT_RAM_LINE_TUNNEL_ETHERTYPE, 1);
1553d52c89f1SMichal Kalderon 
1554d52c89f1SMichal Kalderon 		/* Allow tunneled traffic without inner IP */
1555d52c89f1SMichal Kalderon 		search_non_ip_as_gft = 1;
1556da090917STomer Tayar 	}
1557da090917STomer Tayar 
15585ab90341SAlexander Lobakin 	ram_line.lo = cpu_to_le32(lo);
15595ab90341SAlexander Lobakin 	ram_line.hi = cpu_to_le32(hi);
15605ab90341SAlexander Lobakin 
1561da090917STomer Tayar 	qed_wr(p_hwfn,
1562d52c89f1SMichal Kalderon 	       p_ptt, PRS_REG_SEARCH_NON_IP_AS_GFT, search_non_ip_as_gft);
15635ab90341SAlexander Lobakin 	qed_dmae_to_grc(p_hwfn, p_ptt, &ram_line.lo,
15647b6859fbSMintz, Yuval 			PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE * pf_id,
1565804c5702SMichal Kalderon 			sizeof(ram_line) / REG_SIZE);
15667b6859fbSMintz, Yuval 
15677b6859fbSMintz, Yuval 	/* Set default profile so that no filter match will happen */
15685ab90341SAlexander Lobakin 	ram_line.lo = cpu_to_le32(0xffffffff);
15695ab90341SAlexander Lobakin 	ram_line.hi = cpu_to_le32(0x3ff);
15705ab90341SAlexander Lobakin 	qed_dmae_to_grc(p_hwfn, p_ptt, &ram_line.lo,
1571da090917STomer Tayar 			PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE *
1572804c5702SMichal Kalderon 			PRS_GFT_CAM_LINES_NO_MATCH,
1573804c5702SMichal Kalderon 			sizeof(ram_line) / REG_SIZE);
1574da090917STomer Tayar 
1575da090917STomer Tayar 	/* Enable gft search */
1576da090917STomer Tayar 	qed_wr(p_hwfn, p_ptt, PRS_REG_SEARCH_GFT, 1);
1577da090917STomer Tayar }
1578da090917STomer Tayar 
1579da090917STomer Tayar DECLARE_CRC8_TABLE(cdu_crc8_table);
1580da090917STomer Tayar 
1581da090917STomer Tayar /* Calculate and return CDU validation byte per connection type/region/cid */
qed_calc_cdu_validation_byte(u8 conn_type,u8 region,u32 cid)1582da090917STomer Tayar static u8 qed_calc_cdu_validation_byte(u8 conn_type, u8 region, u32 cid)
1583da090917STomer Tayar {
1584da090917STomer Tayar 	const u8 validation_cfg = CDU_VALIDATION_DEFAULT_CFG;
1585da090917STomer Tayar 	u8 crc, validation_byte = 0;
1586da090917STomer Tayar 	static u8 crc8_table_valid; /* automatically initialized to 0 */
1587da090917STomer Tayar 	u32 validation_string = 0;
15885ab90341SAlexander Lobakin 	__be32 data_to_crc;
1589da090917STomer Tayar 
1590da090917STomer Tayar 	if (!crc8_table_valid) {
1591da090917STomer Tayar 		crc8_populate_msb(cdu_crc8_table, 0x07);
1592da090917STomer Tayar 		crc8_table_valid = 1;
1593da090917STomer Tayar 	}
1594da090917STomer Tayar 
1595da090917STomer Tayar 	/* The CRC is calculated on the String-to-compress:
1596da090917STomer Tayar 	 * [31:8]  = {CID[31:20],CID[11:0]}
1597da090917STomer Tayar 	 * [7:4]   = Region
1598da090917STomer Tayar 	 * [3:0]   = Type
1599da090917STomer Tayar 	 */
1600da090917STomer Tayar 	if ((validation_cfg >> CDU_CONTEXT_VALIDATION_CFG_USE_CID) & 1)
1601da090917STomer Tayar 		validation_string |= (cid & 0xFFF00000) | ((cid & 0xFFF) << 8);
1602da090917STomer Tayar 
1603da090917STomer Tayar 	if ((validation_cfg >> CDU_CONTEXT_VALIDATION_CFG_USE_REGION) & 1)
1604da090917STomer Tayar 		validation_string |= ((region & 0xF) << 4);
1605da090917STomer Tayar 
1606da090917STomer Tayar 	if ((validation_cfg >> CDU_CONTEXT_VALIDATION_CFG_USE_TYPE) & 1)
1607da090917STomer Tayar 		validation_string |= (conn_type & 0xF);
1608da090917STomer Tayar 
1609da090917STomer Tayar 	/* Convert to big-endian and calculate CRC8 */
16105ab90341SAlexander Lobakin 	data_to_crc = cpu_to_be32(validation_string);
16115ab90341SAlexander Lobakin 	crc = crc8(cdu_crc8_table, (u8 *)&data_to_crc, sizeof(data_to_crc),
16125ab90341SAlexander Lobakin 		   CRC8_INIT_VALUE);
1613da090917STomer Tayar 
1614da090917STomer Tayar 	/* The validation byte [7:0] is composed:
1615da090917STomer Tayar 	 * for type A validation
1616da090917STomer Tayar 	 * [7]          = active configuration bit
1617da090917STomer Tayar 	 * [6:0]        = crc[6:0]
1618da090917STomer Tayar 	 *
1619da090917STomer Tayar 	 * for type B validation
1620da090917STomer Tayar 	 * [7]          = active configuration bit
1621da090917STomer Tayar 	 * [6:3]        = connection_type[3:0]
1622da090917STomer Tayar 	 * [2:0]        = crc[2:0]
1623da090917STomer Tayar 	 */
1624da090917STomer Tayar 	validation_byte |=
1625da090917STomer Tayar 	    ((validation_cfg >>
1626da090917STomer Tayar 	      CDU_CONTEXT_VALIDATION_CFG_USE_ACTIVE) & 1) << 7;
1627da090917STomer Tayar 
1628da090917STomer Tayar 	if ((validation_cfg >>
1629da090917STomer Tayar 	     CDU_CONTEXT_VALIDATION_CFG_VALIDATION_TYPE_SHIFT) & 1)
1630da090917STomer Tayar 		validation_byte |= ((conn_type & 0xF) << 3) | (crc & 0x7);
1631da090917STomer Tayar 	else
1632da090917STomer Tayar 		validation_byte |= crc & 0x7F;
1633da090917STomer Tayar 
1634da090917STomer Tayar 	return validation_byte;
1635da090917STomer Tayar }
1636da090917STomer Tayar 
1637da090917STomer Tayar /* 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)1638da090917STomer Tayar void qed_calc_session_ctx_validation(void *p_ctx_mem,
1639da090917STomer Tayar 				     u16 ctx_size, u8 ctx_type, u32 cid)
1640da090917STomer Tayar {
1641da090917STomer Tayar 	u8 *x_val_ptr, *t_val_ptr, *u_val_ptr, *p_ctx;
1642da090917STomer Tayar 
1643da090917STomer Tayar 	p_ctx = (u8 * const)p_ctx_mem;
1644da090917STomer Tayar 	x_val_ptr = &p_ctx[con_region_offsets[0][ctx_type]];
1645da090917STomer Tayar 	t_val_ptr = &p_ctx[con_region_offsets[1][ctx_type]];
1646da090917STomer Tayar 	u_val_ptr = &p_ctx[con_region_offsets[2][ctx_type]];
1647da090917STomer Tayar 
1648da090917STomer Tayar 	memset(p_ctx, 0, ctx_size);
1649da090917STomer Tayar 
1650da090917STomer Tayar 	*x_val_ptr = qed_calc_cdu_validation_byte(ctx_type, 3, cid);
1651da090917STomer Tayar 	*t_val_ptr = qed_calc_cdu_validation_byte(ctx_type, 4, cid);
1652da090917STomer Tayar 	*u_val_ptr = qed_calc_cdu_validation_byte(ctx_type, 5, cid);
1653da090917STomer Tayar }
1654da090917STomer Tayar 
1655da090917STomer Tayar /* 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)1656da090917STomer Tayar void qed_calc_task_ctx_validation(void *p_ctx_mem,
1657da090917STomer Tayar 				  u16 ctx_size, u8 ctx_type, u32 tid)
1658da090917STomer Tayar {
1659da090917STomer Tayar 	u8 *p_ctx, *region1_val_ptr;
1660da090917STomer Tayar 
1661da090917STomer Tayar 	p_ctx = (u8 * const)p_ctx_mem;
1662da090917STomer Tayar 	region1_val_ptr = &p_ctx[task_region_offsets[0][ctx_type]];
1663da090917STomer Tayar 
1664da090917STomer Tayar 	memset(p_ctx, 0, ctx_size);
1665da090917STomer Tayar 
1666da090917STomer Tayar 	*region1_val_ptr = qed_calc_cdu_validation_byte(ctx_type, 1, tid);
1667da090917STomer Tayar }
1668da090917STomer Tayar 
1669da090917STomer Tayar /* Memset session context to 0 while preserving validation bytes */
qed_memset_session_ctx(void * p_ctx_mem,u32 ctx_size,u8 ctx_type)1670da090917STomer Tayar void qed_memset_session_ctx(void *p_ctx_mem, u32 ctx_size, u8 ctx_type)
1671da090917STomer Tayar {
1672da090917STomer Tayar 	u8 *x_val_ptr, *t_val_ptr, *u_val_ptr, *p_ctx;
1673da090917STomer Tayar 	u8 x_val, t_val, u_val;
1674da090917STomer Tayar 
1675da090917STomer Tayar 	p_ctx = (u8 * const)p_ctx_mem;
1676da090917STomer Tayar 	x_val_ptr = &p_ctx[con_region_offsets[0][ctx_type]];
1677da090917STomer Tayar 	t_val_ptr = &p_ctx[con_region_offsets[1][ctx_type]];
1678da090917STomer Tayar 	u_val_ptr = &p_ctx[con_region_offsets[2][ctx_type]];
1679da090917STomer Tayar 
1680da090917STomer Tayar 	x_val = *x_val_ptr;
1681da090917STomer Tayar 	t_val = *t_val_ptr;
1682da090917STomer Tayar 	u_val = *u_val_ptr;
1683da090917STomer Tayar 
1684da090917STomer Tayar 	memset(p_ctx, 0, ctx_size);
1685da090917STomer Tayar 
1686da090917STomer Tayar 	*x_val_ptr = x_val;
1687da090917STomer Tayar 	*t_val_ptr = t_val;
1688da090917STomer Tayar 	*u_val_ptr = u_val;
1689da090917STomer Tayar }
1690da090917STomer Tayar 
1691da090917STomer Tayar /* Memset task context to 0 while preserving validation bytes */
qed_memset_task_ctx(void * p_ctx_mem,u32 ctx_size,u8 ctx_type)1692da090917STomer Tayar void qed_memset_task_ctx(void *p_ctx_mem, u32 ctx_size, u8 ctx_type)
1693da090917STomer Tayar {
1694da090917STomer Tayar 	u8 *p_ctx, *region1_val_ptr;
1695da090917STomer Tayar 	u8 region1_val;
1696da090917STomer Tayar 
1697da090917STomer Tayar 	p_ctx = (u8 * const)p_ctx_mem;
1698da090917STomer Tayar 	region1_val_ptr = &p_ctx[task_region_offsets[0][ctx_type]];
1699da090917STomer Tayar 
1700da090917STomer Tayar 	region1_val = *region1_val_ptr;
1701da090917STomer Tayar 
1702da090917STomer Tayar 	memset(p_ctx, 0, ctx_size);
1703da090917STomer Tayar 
1704da090917STomer Tayar 	*region1_val_ptr = region1_val;
1705da090917STomer Tayar }
1706da090917STomer Tayar 
1707da090917STomer Tayar /* Enable and configure context validation */
qed_enable_context_validation(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt)1708da090917STomer Tayar void qed_enable_context_validation(struct qed_hwfn *p_hwfn,
1709da090917STomer Tayar 				   struct qed_ptt *p_ptt)
1710da090917STomer Tayar {
1711da090917STomer Tayar 	u32 ctx_validation;
1712da090917STomer Tayar 
1713da090917STomer Tayar 	/* Enable validation for connection region 3: CCFC_CTX_VALID0[31:24] */
1714da090917STomer Tayar 	ctx_validation = CDU_VALIDATION_DEFAULT_CFG << 24;
1715da090917STomer Tayar 	qed_wr(p_hwfn, p_ptt, CDU_REG_CCFC_CTX_VALID0, ctx_validation);
1716da090917STomer Tayar 
1717da090917STomer Tayar 	/* Enable validation for connection region 5: CCFC_CTX_VALID1[15:8] */
1718da090917STomer Tayar 	ctx_validation = CDU_VALIDATION_DEFAULT_CFG << 8;
1719da090917STomer Tayar 	qed_wr(p_hwfn, p_ptt, CDU_REG_CCFC_CTX_VALID1, ctx_validation);
1720da090917STomer Tayar 
1721da090917STomer Tayar 	/* Enable validation for connection region 1: TCFC_CTX_VALID0[15:8] */
1722da090917STomer Tayar 	ctx_validation = CDU_VALIDATION_DEFAULT_CFG << 8;
1723da090917STomer Tayar 	qed_wr(p_hwfn, p_ptt, CDU_REG_TCFC_CTX_VALID0, ctx_validation);
1724d51e4af5SChopra, Manish }
1725d52c89f1SMichal Kalderon 
qed_get_protocol_type_str(u32 protocol_type)1726*7e9979e3SPrabhakar Kushwaha const char *qed_get_protocol_type_str(u32 protocol_type)
1727*7e9979e3SPrabhakar Kushwaha {
1728*7e9979e3SPrabhakar Kushwaha 	if (protocol_type >= ARRAY_SIZE(s_protocol_types))
1729*7e9979e3SPrabhakar Kushwaha 		return "Invalid protocol type";
1730*7e9979e3SPrabhakar Kushwaha 
1731*7e9979e3SPrabhakar Kushwaha 	return s_protocol_types[protocol_type];
1732*7e9979e3SPrabhakar Kushwaha }
1733*7e9979e3SPrabhakar Kushwaha 
qed_get_ramrod_cmd_id_str(u32 protocol_type,u32 ramrod_cmd_id)1734*7e9979e3SPrabhakar Kushwaha const char *qed_get_ramrod_cmd_id_str(u32 protocol_type, u32 ramrod_cmd_id)
1735*7e9979e3SPrabhakar Kushwaha {
1736*7e9979e3SPrabhakar Kushwaha 	const char *ramrod_cmd_id_str;
1737*7e9979e3SPrabhakar Kushwaha 
1738*7e9979e3SPrabhakar Kushwaha 	if (protocol_type >= ARRAY_SIZE(s_ramrod_cmd_ids))
1739*7e9979e3SPrabhakar Kushwaha 		return "Invalid protocol type";
1740*7e9979e3SPrabhakar Kushwaha 
1741*7e9979e3SPrabhakar Kushwaha 	if (ramrod_cmd_id >= ARRAY_SIZE(s_ramrod_cmd_ids[0]))
1742*7e9979e3SPrabhakar Kushwaha 		return "Invalid Ramrod command ID";
1743*7e9979e3SPrabhakar Kushwaha 
1744*7e9979e3SPrabhakar Kushwaha 	ramrod_cmd_id_str = s_ramrod_cmd_ids[protocol_type][ramrod_cmd_id];
1745*7e9979e3SPrabhakar Kushwaha 
1746*7e9979e3SPrabhakar Kushwaha 	if (!ramrod_cmd_id_str)
1747*7e9979e3SPrabhakar Kushwaha 		return "Invalid Ramrod command ID";
1748*7e9979e3SPrabhakar Kushwaha 
1749*7e9979e3SPrabhakar Kushwaha 	return ramrod_cmd_id_str;
1750*7e9979e3SPrabhakar Kushwaha }
1751*7e9979e3SPrabhakar Kushwaha 
qed_get_rdma_assert_ram_addr(struct qed_hwfn * p_hwfn,u8 storm_id)1752d52c89f1SMichal Kalderon static u32 qed_get_rdma_assert_ram_addr(struct qed_hwfn *p_hwfn, u8 storm_id)
1753d52c89f1SMichal Kalderon {
1754d52c89f1SMichal Kalderon 	switch (storm_id) {
1755d52c89f1SMichal Kalderon 	case 0:
1756d52c89f1SMichal Kalderon 		return TSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1757d52c89f1SMichal Kalderon 		    TSTORM_RDMA_ASSERT_LEVEL_OFFSET(p_hwfn->rel_pf_id);
1758d52c89f1SMichal Kalderon 	case 1:
1759d52c89f1SMichal Kalderon 		return MSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1760d52c89f1SMichal Kalderon 		    MSTORM_RDMA_ASSERT_LEVEL_OFFSET(p_hwfn->rel_pf_id);
1761d52c89f1SMichal Kalderon 	case 2:
1762d52c89f1SMichal Kalderon 		return USEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1763d52c89f1SMichal Kalderon 		    USTORM_RDMA_ASSERT_LEVEL_OFFSET(p_hwfn->rel_pf_id);
1764d52c89f1SMichal Kalderon 	case 3:
1765d52c89f1SMichal Kalderon 		return XSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1766d52c89f1SMichal Kalderon 		    XSTORM_RDMA_ASSERT_LEVEL_OFFSET(p_hwfn->rel_pf_id);
1767d52c89f1SMichal Kalderon 	case 4:
1768d52c89f1SMichal Kalderon 		return YSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1769d52c89f1SMichal Kalderon 		    YSTORM_RDMA_ASSERT_LEVEL_OFFSET(p_hwfn->rel_pf_id);
1770d52c89f1SMichal Kalderon 	case 5:
1771d52c89f1SMichal Kalderon 		return PSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1772d52c89f1SMichal Kalderon 		    PSTORM_RDMA_ASSERT_LEVEL_OFFSET(p_hwfn->rel_pf_id);
1773d52c89f1SMichal Kalderon 
1774d52c89f1SMichal Kalderon 	default:
1775d52c89f1SMichal Kalderon 		return 0;
1776d52c89f1SMichal Kalderon 	}
1777d52c89f1SMichal Kalderon }
1778d52c89f1SMichal Kalderon 
qed_set_rdma_error_level(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u8 assert_level[NUM_STORMS])1779d52c89f1SMichal Kalderon void qed_set_rdma_error_level(struct qed_hwfn *p_hwfn,
1780d52c89f1SMichal Kalderon 			      struct qed_ptt *p_ptt,
1781d52c89f1SMichal Kalderon 			      u8 assert_level[NUM_STORMS])
1782d52c89f1SMichal Kalderon {
1783d52c89f1SMichal Kalderon 	u8 storm_id;
1784d52c89f1SMichal Kalderon 
1785d52c89f1SMichal Kalderon 	for (storm_id = 0; storm_id < NUM_STORMS; storm_id++) {
1786d52c89f1SMichal Kalderon 		u32 ram_addr = qed_get_rdma_assert_ram_addr(p_hwfn, storm_id);
1787d52c89f1SMichal Kalderon 
1788d52c89f1SMichal Kalderon 		qed_wr(p_hwfn, p_ptt, ram_addr, assert_level[storm_id]);
1789d52c89f1SMichal Kalderon 	}
1790d52c89f1SMichal Kalderon }
179130d5f858SMichal Kalderon 
179230d5f858SMichal Kalderon #define PHYS_ADDR_DWORDS        DIV_ROUND_UP(sizeof(dma_addr_t), 4)
179330d5f858SMichal Kalderon #define OVERLAY_HDR_SIZE_DWORDS (sizeof(struct fw_overlay_buf_hdr) / 4)
179430d5f858SMichal Kalderon 
qed_get_overlay_addr_ram_addr(struct qed_hwfn * p_hwfn,u8 storm_id)179530d5f858SMichal Kalderon static u32 qed_get_overlay_addr_ram_addr(struct qed_hwfn *p_hwfn, u8 storm_id)
179630d5f858SMichal Kalderon {
179730d5f858SMichal Kalderon 	switch (storm_id) {
179830d5f858SMichal Kalderon 	case 0:
179930d5f858SMichal Kalderon 		return TSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
180030d5f858SMichal Kalderon 		    TSTORM_OVERLAY_BUF_ADDR_OFFSET;
180130d5f858SMichal Kalderon 	case 1:
180230d5f858SMichal Kalderon 		return MSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
180330d5f858SMichal Kalderon 		    MSTORM_OVERLAY_BUF_ADDR_OFFSET;
180430d5f858SMichal Kalderon 	case 2:
180530d5f858SMichal Kalderon 		return USEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
180630d5f858SMichal Kalderon 		    USTORM_OVERLAY_BUF_ADDR_OFFSET;
180730d5f858SMichal Kalderon 	case 3:
180830d5f858SMichal Kalderon 		return XSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
180930d5f858SMichal Kalderon 		    XSTORM_OVERLAY_BUF_ADDR_OFFSET;
181030d5f858SMichal Kalderon 	case 4:
181130d5f858SMichal Kalderon 		return YSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
181230d5f858SMichal Kalderon 		    YSTORM_OVERLAY_BUF_ADDR_OFFSET;
181330d5f858SMichal Kalderon 	case 5:
181430d5f858SMichal Kalderon 		return PSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
181530d5f858SMichal Kalderon 		    PSTORM_OVERLAY_BUF_ADDR_OFFSET;
181630d5f858SMichal Kalderon 
181730d5f858SMichal Kalderon 	default:
181830d5f858SMichal Kalderon 		return 0;
181930d5f858SMichal Kalderon 	}
182030d5f858SMichal Kalderon }
182130d5f858SMichal Kalderon 
qed_fw_overlay_mem_alloc(struct qed_hwfn * p_hwfn,const u32 * const fw_overlay_in_buf,u32 buf_size_in_bytes)182230d5f858SMichal Kalderon struct phys_mem_desc *qed_fw_overlay_mem_alloc(struct qed_hwfn *p_hwfn,
182330d5f858SMichal Kalderon 					       const u32 * const
182430d5f858SMichal Kalderon 					       fw_overlay_in_buf,
182530d5f858SMichal Kalderon 					       u32 buf_size_in_bytes)
182630d5f858SMichal Kalderon {
182730d5f858SMichal Kalderon 	u32 buf_size = buf_size_in_bytes / sizeof(u32), buf_offset = 0;
182830d5f858SMichal Kalderon 	struct phys_mem_desc *allocated_mem;
182930d5f858SMichal Kalderon 
183030d5f858SMichal Kalderon 	if (!buf_size)
183130d5f858SMichal Kalderon 		return NULL;
183230d5f858SMichal Kalderon 
183330d5f858SMichal Kalderon 	allocated_mem = kcalloc(NUM_STORMS, sizeof(struct phys_mem_desc),
183430d5f858SMichal Kalderon 				GFP_KERNEL);
183530d5f858SMichal Kalderon 	if (!allocated_mem)
183630d5f858SMichal Kalderon 		return NULL;
183730d5f858SMichal Kalderon 
183830d5f858SMichal Kalderon 	/* For each Storm, set physical address in RAM */
183930d5f858SMichal Kalderon 	while (buf_offset < buf_size) {
184030d5f858SMichal Kalderon 		struct phys_mem_desc *storm_mem_desc;
184130d5f858SMichal Kalderon 		struct fw_overlay_buf_hdr *hdr;
184230d5f858SMichal Kalderon 		u32 storm_buf_size;
184330d5f858SMichal Kalderon 		u8 storm_id;
184430d5f858SMichal Kalderon 
184530d5f858SMichal Kalderon 		hdr =
184630d5f858SMichal Kalderon 		    (struct fw_overlay_buf_hdr *)&fw_overlay_in_buf[buf_offset];
184730d5f858SMichal Kalderon 		storm_buf_size = GET_FIELD(hdr->data,
184830d5f858SMichal Kalderon 					   FW_OVERLAY_BUF_HDR_BUF_SIZE);
184930d5f858SMichal Kalderon 		storm_id = GET_FIELD(hdr->data, FW_OVERLAY_BUF_HDR_STORM_ID);
1850b90cb538SOmkar Kulkarni 		if (storm_id >= NUM_STORMS)
1851b90cb538SOmkar Kulkarni 			break;
185230d5f858SMichal Kalderon 		storm_mem_desc = allocated_mem + storm_id;
185330d5f858SMichal Kalderon 		storm_mem_desc->size = storm_buf_size * sizeof(u32);
185430d5f858SMichal Kalderon 
185530d5f858SMichal Kalderon 		/* Allocate physical memory for Storm's overlays buffer */
185630d5f858SMichal Kalderon 		storm_mem_desc->virt_addr =
185730d5f858SMichal Kalderon 		    dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
185830d5f858SMichal Kalderon 				       storm_mem_desc->size,
185930d5f858SMichal Kalderon 				       &storm_mem_desc->phys_addr, GFP_KERNEL);
186030d5f858SMichal Kalderon 		if (!storm_mem_desc->virt_addr)
186130d5f858SMichal Kalderon 			break;
186230d5f858SMichal Kalderon 
186330d5f858SMichal Kalderon 		/* Skip overlays buffer header */
186430d5f858SMichal Kalderon 		buf_offset += OVERLAY_HDR_SIZE_DWORDS;
186530d5f858SMichal Kalderon 
186630d5f858SMichal Kalderon 		/* Copy Storm's overlays buffer to allocated memory */
186730d5f858SMichal Kalderon 		memcpy(storm_mem_desc->virt_addr,
186830d5f858SMichal Kalderon 		       &fw_overlay_in_buf[buf_offset], storm_mem_desc->size);
186930d5f858SMichal Kalderon 
187030d5f858SMichal Kalderon 		/* Advance to next Storm */
187130d5f858SMichal Kalderon 		buf_offset += storm_buf_size;
187230d5f858SMichal Kalderon 	}
187330d5f858SMichal Kalderon 
187430d5f858SMichal Kalderon 	/* If memory allocation has failed, free all allocated memory */
187530d5f858SMichal Kalderon 	if (buf_offset < buf_size) {
1876fe40a830SPrabhakar Kushwaha 		qed_fw_overlay_mem_free(p_hwfn, &allocated_mem);
187730d5f858SMichal Kalderon 		return NULL;
187830d5f858SMichal Kalderon 	}
187930d5f858SMichal Kalderon 
188030d5f858SMichal Kalderon 	return allocated_mem;
188130d5f858SMichal Kalderon }
188230d5f858SMichal Kalderon 
qed_fw_overlay_init_ram(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,struct phys_mem_desc * fw_overlay_mem)188330d5f858SMichal Kalderon void qed_fw_overlay_init_ram(struct qed_hwfn *p_hwfn,
188430d5f858SMichal Kalderon 			     struct qed_ptt *p_ptt,
188530d5f858SMichal Kalderon 			     struct phys_mem_desc *fw_overlay_mem)
188630d5f858SMichal Kalderon {
188730d5f858SMichal Kalderon 	u8 storm_id;
188830d5f858SMichal Kalderon 
188930d5f858SMichal Kalderon 	for (storm_id = 0; storm_id < NUM_STORMS; storm_id++) {
189030d5f858SMichal Kalderon 		struct phys_mem_desc *storm_mem_desc =
189130d5f858SMichal Kalderon 		    (struct phys_mem_desc *)fw_overlay_mem + storm_id;
189230d5f858SMichal Kalderon 		u32 ram_addr, i;
189330d5f858SMichal Kalderon 
189430d5f858SMichal Kalderon 		/* Skip Storms with no FW overlays */
189530d5f858SMichal Kalderon 		if (!storm_mem_desc->virt_addr)
189630d5f858SMichal Kalderon 			continue;
189730d5f858SMichal Kalderon 
189830d5f858SMichal Kalderon 		/* Calculate overlay RAM GRC address of current PF */
189930d5f858SMichal Kalderon 		ram_addr = qed_get_overlay_addr_ram_addr(p_hwfn, storm_id) +
190030d5f858SMichal Kalderon 			   sizeof(dma_addr_t) * p_hwfn->rel_pf_id;
190130d5f858SMichal Kalderon 
190230d5f858SMichal Kalderon 		/* Write Storm's overlay physical address to RAM */
190330d5f858SMichal Kalderon 		for (i = 0; i < PHYS_ADDR_DWORDS; i++, ram_addr += sizeof(u32))
190430d5f858SMichal Kalderon 			qed_wr(p_hwfn, p_ptt, ram_addr,
190530d5f858SMichal Kalderon 			       ((u32 *)&storm_mem_desc->phys_addr)[i]);
190630d5f858SMichal Kalderon 	}
190730d5f858SMichal Kalderon }
190830d5f858SMichal Kalderon 
qed_fw_overlay_mem_free(struct qed_hwfn * p_hwfn,struct phys_mem_desc ** fw_overlay_mem)190930d5f858SMichal Kalderon void qed_fw_overlay_mem_free(struct qed_hwfn *p_hwfn,
1910fe40a830SPrabhakar Kushwaha 			     struct phys_mem_desc **fw_overlay_mem)
191130d5f858SMichal Kalderon {
191230d5f858SMichal Kalderon 	u8 storm_id;
191330d5f858SMichal Kalderon 
1914fe40a830SPrabhakar Kushwaha 	if (!fw_overlay_mem || !(*fw_overlay_mem))
191530d5f858SMichal Kalderon 		return;
191630d5f858SMichal Kalderon 
191730d5f858SMichal Kalderon 	for (storm_id = 0; storm_id < NUM_STORMS; storm_id++) {
191830d5f858SMichal Kalderon 		struct phys_mem_desc *storm_mem_desc =
1919fe40a830SPrabhakar Kushwaha 		    (struct phys_mem_desc *)*fw_overlay_mem + storm_id;
192030d5f858SMichal Kalderon 
192130d5f858SMichal Kalderon 		/* Free Storm's physical memory */
192230d5f858SMichal Kalderon 		if (storm_mem_desc->virt_addr)
192330d5f858SMichal Kalderon 			dma_free_coherent(&p_hwfn->cdev->pdev->dev,
192430d5f858SMichal Kalderon 					  storm_mem_desc->size,
192530d5f858SMichal Kalderon 					  storm_mem_desc->virt_addr,
192630d5f858SMichal Kalderon 					  storm_mem_desc->phys_addr);
192730d5f858SMichal Kalderon 	}
192830d5f858SMichal Kalderon 
192930d5f858SMichal Kalderon 	/* Free allocated virtual memory */
1930fe40a830SPrabhakar Kushwaha 	kfree(*fw_overlay_mem);
1931fe40a830SPrabhakar Kushwaha 	*fw_overlay_mem = NULL;
193230d5f858SMichal Kalderon }
1933