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
4663eacd8SAlexander Lobakin  * Copyright (c) 2019-2020 Marvell International Ltd.
5fe56b9e6SYuval Mintz  */
6fe56b9e6SYuval Mintz 
7fe56b9e6SYuval Mintz #include <linux/types.h>
8fe56b9e6SYuval Mintz #include <linux/io.h>
9fe56b9e6SYuval Mintz #include <linux/delay.h>
10fe56b9e6SYuval Mintz #include <linux/errno.h>
11fe56b9e6SYuval Mintz #include <linux/kernel.h>
12fe56b9e6SYuval Mintz #include <linux/slab.h>
13fe56b9e6SYuval Mintz #include <linux/string.h>
14fe56b9e6SYuval Mintz #include "qed.h"
15fe56b9e6SYuval Mintz #include "qed_hsi.h"
16fe56b9e6SYuval Mintz #include "qed_hw.h"
17fe56b9e6SYuval Mintz #include "qed_init_ops.h"
18*b90cb538SOmkar Kulkarni #include "qed_iro_hsi.h"
19fe56b9e6SYuval Mintz #include "qed_reg_addr.h"
201408cc1fSYuval Mintz #include "qed_sriov.h"
21fe56b9e6SYuval Mintz 
22fe56b9e6SYuval Mintz #define QED_INIT_MAX_POLL_COUNT 100
23fe56b9e6SYuval Mintz #define QED_INIT_POLL_PERIOD_US 500
24fe56b9e6SYuval Mintz 
25fe56b9e6SYuval Mintz static u32 pxp_global_win[] = {
26fe56b9e6SYuval Mintz 	0,
27fe56b9e6SYuval Mintz 	0,
28fe56b9e6SYuval Mintz 	0x1c02, /* win 2: addr=0x1c02000, size=4096 bytes */
29fe56b9e6SYuval Mintz 	0x1c80, /* win 3: addr=0x1c80000, size=4096 bytes */
30fe56b9e6SYuval Mintz 	0x1d00, /* win 4: addr=0x1d00000, size=4096 bytes */
31fe56b9e6SYuval Mintz 	0x1d01, /* win 5: addr=0x1d01000, size=4096 bytes */
326aebde8dSMichal Kalderon 	0x1d02, /* win 6: addr=0x1d02000, size=4096 bytes */
336aebde8dSMichal Kalderon 	0x1d80, /* win 7: addr=0x1d80000, size=4096 bytes */
346aebde8dSMichal Kalderon 	0x1d81, /* win 8: addr=0x1d81000, size=4096 bytes */
356aebde8dSMichal Kalderon 	0x1d82, /* win 9: addr=0x1d82000, size=4096 bytes */
366aebde8dSMichal Kalderon 	0x1e00, /* win 10: addr=0x1e00000, size=4096 bytes */
376aebde8dSMichal Kalderon 	0x1e01, /* win 11: addr=0x1e01000, size=4096 bytes */
386aebde8dSMichal Kalderon 	0x1e80, /* win 12: addr=0x1e80000, size=4096 bytes */
396aebde8dSMichal Kalderon 	0x1f00, /* win 13: addr=0x1f00000, size=4096 bytes */
406aebde8dSMichal Kalderon 	0x1c08, /* win 14: addr=0x1c08000, size=4096 bytes */
41fe56b9e6SYuval Mintz 	0,
42fe56b9e6SYuval Mintz 	0,
43fe56b9e6SYuval Mintz 	0,
44fe56b9e6SYuval Mintz 	0,
45fe56b9e6SYuval Mintz };
46fe56b9e6SYuval Mintz 
470dfda108SAlexander Lobakin /* IRO Array */
480dfda108SAlexander Lobakin static const u32 iro_arr[] = {
490dfda108SAlexander Lobakin 	0x00000000, 0x00000000, 0x00080000,
50*b90cb538SOmkar Kulkarni 	0x00004478, 0x00000008, 0x00080000,
510dfda108SAlexander Lobakin 	0x00003288, 0x00000088, 0x00880000,
52*b90cb538SOmkar Kulkarni 	0x000058a8, 0x00000020, 0x00200000,
53*b90cb538SOmkar Kulkarni 	0x00003188, 0x00000008, 0x00080000,
540dfda108SAlexander Lobakin 	0x00000b00, 0x00000008, 0x00040000,
550dfda108SAlexander Lobakin 	0x00000a80, 0x00000008, 0x00040000,
560dfda108SAlexander Lobakin 	0x00000000, 0x00000008, 0x00020000,
570dfda108SAlexander Lobakin 	0x00000080, 0x00000008, 0x00040000,
580dfda108SAlexander Lobakin 	0x00000084, 0x00000008, 0x00020000,
59*b90cb538SOmkar Kulkarni 	0x00005798, 0x00000004, 0x00040000,
60*b90cb538SOmkar Kulkarni 	0x00004e50, 0x00000000, 0x00780000,
610dfda108SAlexander Lobakin 	0x00003e40, 0x00000000, 0x00780000,
62*b90cb538SOmkar Kulkarni 	0x00004500, 0x00000000, 0x00780000,
630dfda108SAlexander Lobakin 	0x00003210, 0x00000000, 0x00780000,
640dfda108SAlexander Lobakin 	0x00003b50, 0x00000000, 0x00780000,
650dfda108SAlexander Lobakin 	0x00007f58, 0x00000000, 0x00780000,
66*b90cb538SOmkar Kulkarni 	0x00005fd8, 0x00000000, 0x00080000,
670dfda108SAlexander Lobakin 	0x00007100, 0x00000000, 0x00080000,
68*b90cb538SOmkar Kulkarni 	0x0000af20, 0x00000000, 0x00080000,
690dfda108SAlexander Lobakin 	0x00004398, 0x00000000, 0x00080000,
700dfda108SAlexander Lobakin 	0x0000a5a0, 0x00000000, 0x00080000,
710dfda108SAlexander Lobakin 	0x0000bde8, 0x00000000, 0x00080000,
720dfda108SAlexander Lobakin 	0x00000020, 0x00000004, 0x00040000,
73*b90cb538SOmkar Kulkarni 	0x00005688, 0x00000010, 0x00100000,
740dfda108SAlexander Lobakin 	0x0000c210, 0x00000030, 0x00300000,
75*b90cb538SOmkar Kulkarni 	0x0000b108, 0x00000038, 0x00380000,
760dfda108SAlexander Lobakin 	0x00003d20, 0x00000080, 0x00400000,
770dfda108SAlexander Lobakin 	0x0000bf60, 0x00000000, 0x00040000,
780dfda108SAlexander Lobakin 	0x00004560, 0x00040080, 0x00040000,
790dfda108SAlexander Lobakin 	0x000001f8, 0x00000004, 0x00040000,
800dfda108SAlexander Lobakin 	0x00003d60, 0x00000080, 0x00200000,
810dfda108SAlexander Lobakin 	0x00008960, 0x00000040, 0x00300000,
820dfda108SAlexander Lobakin 	0x0000e840, 0x00000060, 0x00600000,
83*b90cb538SOmkar Kulkarni 	0x00004698, 0x00000080, 0x00380000,
84*b90cb538SOmkar Kulkarni 	0x000107b8, 0x000000c0, 0x00c00000,
850dfda108SAlexander Lobakin 	0x000001f8, 0x00000002, 0x00020000,
86*b90cb538SOmkar Kulkarni 	0x0000a260, 0x00000000, 0x01080000,
87*b90cb538SOmkar Kulkarni 	0x0000a368, 0x00000008, 0x00080000,
880dfda108SAlexander Lobakin 	0x000001c0, 0x00000008, 0x00080000,
890dfda108SAlexander Lobakin 	0x000001f8, 0x00000008, 0x00080000,
900dfda108SAlexander Lobakin 	0x00000ac0, 0x00000008, 0x00080000,
910dfda108SAlexander Lobakin 	0x00002578, 0x00000008, 0x00080000,
920dfda108SAlexander Lobakin 	0x000024f8, 0x00000008, 0x00080000,
930dfda108SAlexander Lobakin 	0x00000280, 0x00000008, 0x00080000,
940dfda108SAlexander Lobakin 	0x00000680, 0x00080018, 0x00080000,
950dfda108SAlexander Lobakin 	0x00000b78, 0x00080018, 0x00020000,
96*b90cb538SOmkar Kulkarni 	0x0000c600, 0x00000058, 0x003c0000,
97*b90cb538SOmkar Kulkarni 	0x00012038, 0x00000020, 0x00100000,
98*b90cb538SOmkar Kulkarni 	0x00011b00, 0x00000048, 0x00180000,
99*b90cb538SOmkar Kulkarni 	0x00009650, 0x00000050, 0x00200000,
1000dfda108SAlexander Lobakin 	0x00008b10, 0x00000040, 0x00280000,
101*b90cb538SOmkar Kulkarni 	0x000116c0, 0x00000018, 0x00100000,
102*b90cb538SOmkar Kulkarni 	0x0000c808, 0x00000048, 0x00380000,
103*b90cb538SOmkar Kulkarni 	0x00011790, 0x00000020, 0x00200000,
104*b90cb538SOmkar Kulkarni 	0x000046d0, 0x00000080, 0x00100000,
1050dfda108SAlexander Lobakin 	0x00003618, 0x00000010, 0x00100000,
106*b90cb538SOmkar Kulkarni 	0x0000a9e8, 0x00000008, 0x00010000,
1070dfda108SAlexander Lobakin 	0x000097a0, 0x00000008, 0x00010000,
108*b90cb538SOmkar Kulkarni 	0x00011a10, 0x00000008, 0x00010000,
109*b90cb538SOmkar Kulkarni 	0x0000e9f8, 0x00000008, 0x00010000,
110*b90cb538SOmkar Kulkarni 	0x00012648, 0x00000008, 0x00010000,
111*b90cb538SOmkar Kulkarni 	0x000121c8, 0x00000008, 0x00010000,
112*b90cb538SOmkar Kulkarni 	0x0000af08, 0x00000030, 0x00100000,
113*b90cb538SOmkar Kulkarni 	0x0000d748, 0x00000028, 0x00280000,
114*b90cb538SOmkar Kulkarni 	0x00009e68, 0x00000018, 0x00180000,
115*b90cb538SOmkar Kulkarni 	0x00009fe8, 0x00000008, 0x00080000,
116*b90cb538SOmkar Kulkarni 	0x00013ea8, 0x00000008, 0x00080000,
117*b90cb538SOmkar Kulkarni 	0x00012f18, 0x00000018, 0x00180000,
118*b90cb538SOmkar Kulkarni 	0x0000dfe8, 0x00500288, 0x00100000,
119*b90cb538SOmkar Kulkarni 	0x000131a0, 0x00000138, 0x00280000,
1200dfda108SAlexander Lobakin };
1210dfda108SAlexander Lobakin 
qed_init_iro_array(struct qed_dev * cdev)122fe56b9e6SYuval Mintz void qed_init_iro_array(struct qed_dev *cdev)
123fe56b9e6SYuval Mintz {
124*b90cb538SOmkar Kulkarni 	cdev->iro_arr = iro_arr + E4_IRO_ARR_OFFSET;
125fe56b9e6SYuval Mintz }
126fe56b9e6SYuval Mintz 
qed_init_store_rt_reg(struct qed_hwfn * p_hwfn,u32 rt_offset,u32 val)1271a635e48SYuval Mintz void qed_init_store_rt_reg(struct qed_hwfn *p_hwfn, u32 rt_offset, u32 val)
128fe56b9e6SYuval Mintz {
129*b90cb538SOmkar Kulkarni 	if (rt_offset >= RUNTIME_ARRAY_SIZE) {
130*b90cb538SOmkar Kulkarni 		DP_ERR(p_hwfn,
131*b90cb538SOmkar Kulkarni 		       "Avoid storing %u in rt_data at index %u!\n",
132*b90cb538SOmkar Kulkarni 		       val, rt_offset);
133*b90cb538SOmkar Kulkarni 		return;
134*b90cb538SOmkar Kulkarni 	}
135*b90cb538SOmkar Kulkarni 
136fc48b7a6SYuval Mintz 	p_hwfn->rt_data.init_val[rt_offset] = val;
137fc48b7a6SYuval Mintz 	p_hwfn->rt_data.b_valid[rt_offset] = true;
138fe56b9e6SYuval Mintz }
139fe56b9e6SYuval Mintz 
qed_init_store_rt_agg(struct qed_hwfn * p_hwfn,u32 rt_offset,u32 * p_val,size_t size)140fe56b9e6SYuval Mintz void qed_init_store_rt_agg(struct qed_hwfn *p_hwfn,
1411a635e48SYuval Mintz 			   u32 rt_offset, u32 *p_val, size_t size)
142fe56b9e6SYuval Mintz {
143fe56b9e6SYuval Mintz 	size_t i;
144fe56b9e6SYuval Mintz 
145*b90cb538SOmkar Kulkarni 	if ((rt_offset + size - 1) >= RUNTIME_ARRAY_SIZE) {
146*b90cb538SOmkar Kulkarni 		DP_ERR(p_hwfn,
147*b90cb538SOmkar Kulkarni 		       "Avoid storing values in rt_data at indices %u-%u!\n",
148*b90cb538SOmkar Kulkarni 		       rt_offset,
149*b90cb538SOmkar Kulkarni 		       (u32)(rt_offset + size - 1));
150*b90cb538SOmkar Kulkarni 		return;
151*b90cb538SOmkar Kulkarni 	}
152*b90cb538SOmkar Kulkarni 
153fe56b9e6SYuval Mintz 	for (i = 0; i < size / sizeof(u32); i++) {
154fc48b7a6SYuval Mintz 		p_hwfn->rt_data.init_val[rt_offset + i] = p_val[i];
155fc48b7a6SYuval Mintz 		p_hwfn->rt_data.b_valid[rt_offset + i]	= true;
156fe56b9e6SYuval Mintz 	}
157fe56b9e6SYuval Mintz }
158fe56b9e6SYuval Mintz 
qed_init_rt(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u32 addr,u16 rt_offset,u16 size,bool b_must_dmae)159fc48b7a6SYuval Mintz static int qed_init_rt(struct qed_hwfn	*p_hwfn,
160fe56b9e6SYuval Mintz 		       struct qed_ptt *p_ptt,
1611a635e48SYuval Mintz 		       u32 addr, u16 rt_offset, u16 size, bool b_must_dmae)
162fe56b9e6SYuval Mintz {
163fc48b7a6SYuval Mintz 	u32 *p_init_val = &p_hwfn->rt_data.init_val[rt_offset];
164fc48b7a6SYuval Mintz 	bool *p_valid = &p_hwfn->rt_data.b_valid[rt_offset];
1656bc82d9bSMichal Kalderon 	u16 i, j, segment;
166fc48b7a6SYuval Mintz 	int rc = 0;
167fe56b9e6SYuval Mintz 
168fc48b7a6SYuval Mintz 	/* Since not all RT entries are initialized, go over the RT and
169fc48b7a6SYuval Mintz 	 * for each segment of initialized values use DMA.
170fc48b7a6SYuval Mintz 	 */
171fe56b9e6SYuval Mintz 	for (i = 0; i < size; i++) {
172fc48b7a6SYuval Mintz 		if (!p_valid[i])
173fe56b9e6SYuval Mintz 			continue;
174fc48b7a6SYuval Mintz 
175fc48b7a6SYuval Mintz 		/* In case there isn't any wide-bus configuration here,
176fc48b7a6SYuval Mintz 		 * simply write the data instead of using dmae.
177fc48b7a6SYuval Mintz 		 */
178fc48b7a6SYuval Mintz 		if (!b_must_dmae) {
1791a635e48SYuval Mintz 			qed_wr(p_hwfn, p_ptt, addr + (i << 2), p_init_val[i]);
1806bc82d9bSMichal Kalderon 			p_valid[i] = false;
181fc48b7a6SYuval Mintz 			continue;
182fe56b9e6SYuval Mintz 		}
183fc48b7a6SYuval Mintz 
184fc48b7a6SYuval Mintz 		/* Start of a new segment */
185fc48b7a6SYuval Mintz 		for (segment = 1; i + segment < size; segment++)
186fc48b7a6SYuval Mintz 			if (!p_valid[i + segment])
187fc48b7a6SYuval Mintz 				break;
188fc48b7a6SYuval Mintz 
189fc48b7a6SYuval Mintz 		rc = qed_dmae_host2grc(p_hwfn, p_ptt,
190fc48b7a6SYuval Mintz 				       (uintptr_t)(p_init_val + i),
19183bf76e3SMichal Kalderon 				       addr + (i << 2), segment, NULL);
1921a635e48SYuval Mintz 		if (rc)
193fc48b7a6SYuval Mintz 			return rc;
194fc48b7a6SYuval Mintz 
1956bc82d9bSMichal Kalderon 		/* invalidate after writing */
196*b90cb538SOmkar Kulkarni 		for (j = i; j < (u32)(i + segment); j++)
1976bc82d9bSMichal Kalderon 			p_valid[j] = false;
1986bc82d9bSMichal Kalderon 
199fc48b7a6SYuval Mintz 		/* Jump over the entire segment, including invalid entry */
200fc48b7a6SYuval Mintz 		i += segment;
201fc48b7a6SYuval Mintz 	}
202fc48b7a6SYuval Mintz 
203fc48b7a6SYuval Mintz 	return rc;
204fe56b9e6SYuval Mintz }
205fe56b9e6SYuval Mintz 
qed_init_alloc(struct qed_hwfn * p_hwfn)206fe56b9e6SYuval Mintz int qed_init_alloc(struct qed_hwfn *p_hwfn)
207fe56b9e6SYuval Mintz {
208fc48b7a6SYuval Mintz 	struct qed_rt_data *rt_data = &p_hwfn->rt_data;
209fe56b9e6SYuval Mintz 
2101408cc1fSYuval Mintz 	if (IS_VF(p_hwfn->cdev))
2111408cc1fSYuval Mintz 		return 0;
2121408cc1fSYuval Mintz 
2136396bb22SKees Cook 	rt_data->b_valid = kcalloc(RUNTIME_ARRAY_SIZE, sizeof(bool),
214fc48b7a6SYuval Mintz 				   GFP_KERNEL);
215fc48b7a6SYuval Mintz 	if (!rt_data->b_valid)
216fe56b9e6SYuval Mintz 		return -ENOMEM;
217fe56b9e6SYuval Mintz 
2186396bb22SKees Cook 	rt_data->init_val = kcalloc(RUNTIME_ARRAY_SIZE, sizeof(u32),
219fc48b7a6SYuval Mintz 				    GFP_KERNEL);
220fc48b7a6SYuval Mintz 	if (!rt_data->init_val) {
221fc48b7a6SYuval Mintz 		kfree(rt_data->b_valid);
2223587cb87STomer Tayar 		rt_data->b_valid = NULL;
223fc48b7a6SYuval Mintz 		return -ENOMEM;
224fc48b7a6SYuval Mintz 	}
225fe56b9e6SYuval Mintz 
226fe56b9e6SYuval Mintz 	return 0;
227fe56b9e6SYuval Mintz }
228fe56b9e6SYuval Mintz 
qed_init_free(struct qed_hwfn * p_hwfn)229fe56b9e6SYuval Mintz void qed_init_free(struct qed_hwfn *p_hwfn)
230fe56b9e6SYuval Mintz {
231fc48b7a6SYuval Mintz 	kfree(p_hwfn->rt_data.init_val);
2323587cb87STomer Tayar 	p_hwfn->rt_data.init_val = NULL;
233fc48b7a6SYuval Mintz 	kfree(p_hwfn->rt_data.b_valid);
2343587cb87STomer Tayar 	p_hwfn->rt_data.b_valid = NULL;
235fe56b9e6SYuval Mintz }
236fe56b9e6SYuval Mintz 
qed_init_array_dmae(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u32 addr,u32 dmae_data_offset,u32 size,const u32 * buf,bool b_must_dmae,bool b_can_dmae)237fe56b9e6SYuval Mintz static int qed_init_array_dmae(struct qed_hwfn *p_hwfn,
238fe56b9e6SYuval Mintz 			       struct qed_ptt *p_ptt,
239fe56b9e6SYuval Mintz 			       u32 addr,
240fe56b9e6SYuval Mintz 			       u32 dmae_data_offset,
241fe56b9e6SYuval Mintz 			       u32 size,
242fe56b9e6SYuval Mintz 			       const u32 *buf,
243fe56b9e6SYuval Mintz 			       bool b_must_dmae,
244fe56b9e6SYuval Mintz 			       bool b_can_dmae)
245fe56b9e6SYuval Mintz {
246fe56b9e6SYuval Mintz 	int rc = 0;
247fe56b9e6SYuval Mintz 
248fe56b9e6SYuval Mintz 	/* Perform DMAE only for lengthy enough sections or for wide-bus */
249fe56b9e6SYuval Mintz 	if (!b_can_dmae || (!b_must_dmae && (size < 16))) {
250fe56b9e6SYuval Mintz 		const u32 *data = buf + dmae_data_offset;
251fe56b9e6SYuval Mintz 		u32 i;
252fe56b9e6SYuval Mintz 
253fe56b9e6SYuval Mintz 		for (i = 0; i < size; i++)
254fe56b9e6SYuval Mintz 			qed_wr(p_hwfn, p_ptt, addr + (i << 2), data[i]);
255fe56b9e6SYuval Mintz 	} else {
256fe56b9e6SYuval Mintz 		rc = qed_dmae_host2grc(p_hwfn, p_ptt,
257fe56b9e6SYuval Mintz 				       (uintptr_t)(buf + dmae_data_offset),
25883bf76e3SMichal Kalderon 				       addr, size, NULL);
259fe56b9e6SYuval Mintz 	}
260fe56b9e6SYuval Mintz 
261fe56b9e6SYuval Mintz 	return rc;
262fe56b9e6SYuval Mintz }
263fe56b9e6SYuval Mintz 
qed_init_fill_dmae(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u32 addr,u32 fill_count)264fe56b9e6SYuval Mintz static int qed_init_fill_dmae(struct qed_hwfn *p_hwfn,
265fe56b9e6SYuval Mintz 			      struct qed_ptt *p_ptt,
266*b90cb538SOmkar Kulkarni 			      u32 addr, u32 fill_count)
267fe56b9e6SYuval Mintz {
268fe56b9e6SYuval Mintz 	static u32 zero_buffer[DMAE_MAX_RW_SIZE];
26983bf76e3SMichal Kalderon 	struct qed_dmae_params params = {};
270fe56b9e6SYuval Mintz 
271fe56b9e6SYuval Mintz 	memset(zero_buffer, 0, sizeof(u32) * DMAE_MAX_RW_SIZE);
272fe56b9e6SYuval Mintz 
273fe56b9e6SYuval Mintz 	/* invoke the DMAE virtual/physical buffer API with
274fe56b9e6SYuval Mintz 	 * 1. DMAE init channel
275fe56b9e6SYuval Mintz 	 * 2. addr,
276fe56b9e6SYuval Mintz 	 * 3. p_hwfb->temp_data,
277fe56b9e6SYuval Mintz 	 * 4. fill_count
278fe56b9e6SYuval Mintz 	 */
279804c5702SMichal Kalderon 	SET_FIELD(params.flags, QED_DMAE_PARAMS_RW_REPL_SRC, 0x1);
280fe56b9e6SYuval Mintz 	return qed_dmae_host2grc(p_hwfn, p_ptt,
281fe56b9e6SYuval Mintz 				 (uintptr_t)(&zero_buffer[0]),
28283bf76e3SMichal Kalderon 				 addr, fill_count, &params);
283fe56b9e6SYuval Mintz }
284fe56b9e6SYuval Mintz 
qed_init_fill(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,u32 addr,u32 fill,u32 fill_count)285fe56b9e6SYuval Mintz static void qed_init_fill(struct qed_hwfn *p_hwfn,
286fe56b9e6SYuval Mintz 			  struct qed_ptt *p_ptt,
2871a635e48SYuval Mintz 			  u32 addr, u32 fill, u32 fill_count)
288fe56b9e6SYuval Mintz {
289fe56b9e6SYuval Mintz 	u32 i;
290fe56b9e6SYuval Mintz 
291fe56b9e6SYuval Mintz 	for (i = 0; i < fill_count; i++, addr += sizeof(u32))
292fe56b9e6SYuval Mintz 		qed_wr(p_hwfn, p_ptt, addr, fill);
293fe56b9e6SYuval Mintz }
294fe56b9e6SYuval Mintz 
qed_init_cmd_array(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,struct init_write_op * cmd,bool b_must_dmae,bool b_can_dmae)295fe56b9e6SYuval Mintz static int qed_init_cmd_array(struct qed_hwfn *p_hwfn,
296fe56b9e6SYuval Mintz 			      struct qed_ptt *p_ptt,
297fe56b9e6SYuval Mintz 			      struct init_write_op *cmd,
2981a635e48SYuval Mintz 			      bool b_must_dmae, bool b_can_dmae)
299fe56b9e6SYuval Mintz {
3001a635e48SYuval Mintz 	u32 dmae_array_offset = le32_to_cpu(cmd->args.array_offset);
301fe56b9e6SYuval Mintz 	u32 data = le32_to_cpu(cmd->data);
302fe56b9e6SYuval Mintz 	u32 addr = GET_FIELD(data, INIT_WRITE_OP_ADDRESS) << 2;
3031a635e48SYuval Mintz 
304fe56b9e6SYuval Mintz 	u32 offset, output_len, input_len, max_size;
305fe56b9e6SYuval Mintz 	struct qed_dev *cdev = p_hwfn->cdev;
306fe56b9e6SYuval Mintz 	union init_array_hdr *hdr;
307fe56b9e6SYuval Mintz 	const u32 *array_data;
308fe56b9e6SYuval Mintz 	int rc = 0;
309fe56b9e6SYuval Mintz 	u32 size;
310fe56b9e6SYuval Mintz 
311fe56b9e6SYuval Mintz 	array_data = cdev->fw_data->arr_data;
312fe56b9e6SYuval Mintz 
3131a635e48SYuval Mintz 	hdr = (union init_array_hdr *)(array_data + dmae_array_offset);
314fe56b9e6SYuval Mintz 	data = le32_to_cpu(hdr->raw.data);
315fe56b9e6SYuval Mintz 	switch (GET_FIELD(data, INIT_ARRAY_RAW_HDR_TYPE)) {
316fe56b9e6SYuval Mintz 	case INIT_ARR_ZIPPED:
317fe56b9e6SYuval Mintz 		offset = dmae_array_offset + 1;
318fe56b9e6SYuval Mintz 		input_len = GET_FIELD(data,
319fe56b9e6SYuval Mintz 				      INIT_ARRAY_ZIPPED_HDR_ZIPPED_SIZE);
320fe56b9e6SYuval Mintz 		max_size = MAX_ZIPPED_SIZE * 4;
321fe56b9e6SYuval Mintz 		memset(p_hwfn->unzip_buf, 0, max_size);
322fe56b9e6SYuval Mintz 
323fe56b9e6SYuval Mintz 		output_len = qed_unzip_data(p_hwfn, input_len,
324fe56b9e6SYuval Mintz 					    (u8 *)&array_data[offset],
325fe56b9e6SYuval Mintz 					    max_size, (u8 *)p_hwfn->unzip_buf);
326fe56b9e6SYuval Mintz 		if (output_len) {
327fe56b9e6SYuval Mintz 			rc = qed_init_array_dmae(p_hwfn, p_ptt, addr, 0,
328fe56b9e6SYuval Mintz 						 output_len,
329fe56b9e6SYuval Mintz 						 p_hwfn->unzip_buf,
330fe56b9e6SYuval Mintz 						 b_must_dmae, b_can_dmae);
331fe56b9e6SYuval Mintz 		} else {
332fe56b9e6SYuval Mintz 			DP_NOTICE(p_hwfn, "Failed to unzip dmae data\n");
333fe56b9e6SYuval Mintz 			rc = -EINVAL;
334fe56b9e6SYuval Mintz 		}
335fe56b9e6SYuval Mintz 		break;
336fe56b9e6SYuval Mintz 	case INIT_ARR_PATTERN:
337fe56b9e6SYuval Mintz 	{
338fe56b9e6SYuval Mintz 		u32 repeats = GET_FIELD(data,
339fe56b9e6SYuval Mintz 					INIT_ARRAY_PATTERN_HDR_REPETITIONS);
340fe56b9e6SYuval Mintz 		u32 i;
341fe56b9e6SYuval Mintz 
342fe56b9e6SYuval Mintz 		size = GET_FIELD(data, INIT_ARRAY_PATTERN_HDR_PATTERN_SIZE);
343fe56b9e6SYuval Mintz 
344fe56b9e6SYuval Mintz 		for (i = 0; i < repeats; i++, addr += size << 2) {
345fe56b9e6SYuval Mintz 			rc = qed_init_array_dmae(p_hwfn, p_ptt, addr,
346fe56b9e6SYuval Mintz 						 dmae_array_offset + 1,
347fe56b9e6SYuval Mintz 						 size, array_data,
348fe56b9e6SYuval Mintz 						 b_must_dmae, b_can_dmae);
349fe56b9e6SYuval Mintz 			if (rc)
350fe56b9e6SYuval Mintz 				break;
351fe56b9e6SYuval Mintz 		}
352fe56b9e6SYuval Mintz 		break;
353fe56b9e6SYuval Mintz 	}
354fe56b9e6SYuval Mintz 	case INIT_ARR_STANDARD:
355fe56b9e6SYuval Mintz 		size = GET_FIELD(data, INIT_ARRAY_STANDARD_HDR_SIZE);
356fe56b9e6SYuval Mintz 		rc = qed_init_array_dmae(p_hwfn, p_ptt, addr,
357fe56b9e6SYuval Mintz 					 dmae_array_offset + 1,
358fe56b9e6SYuval Mintz 					 size, array_data,
359fe56b9e6SYuval Mintz 					 b_must_dmae, b_can_dmae);
360fe56b9e6SYuval Mintz 		break;
361fe56b9e6SYuval Mintz 	}
362fe56b9e6SYuval Mintz 
363fe56b9e6SYuval Mintz 	return rc;
364fe56b9e6SYuval Mintz }
365fe56b9e6SYuval Mintz 
366fe56b9e6SYuval Mintz /* init_ops write command */
qed_init_cmd_wr(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,struct init_write_op * p_cmd,bool b_can_dmae)367fe56b9e6SYuval Mintz static int qed_init_cmd_wr(struct qed_hwfn *p_hwfn,
368fe56b9e6SYuval Mintz 			   struct qed_ptt *p_ptt,
3691a635e48SYuval Mintz 			   struct init_write_op *p_cmd, bool b_can_dmae)
370fe56b9e6SYuval Mintz {
3711a635e48SYuval Mintz 	u32 data = le32_to_cpu(p_cmd->data);
372fe56b9e6SYuval Mintz 	bool b_must_dmae = GET_FIELD(data, INIT_WRITE_OP_WIDE_BUS);
3731a635e48SYuval Mintz 	u32 addr = GET_FIELD(data, INIT_WRITE_OP_ADDRESS) << 2;
3741a635e48SYuval Mintz 	union init_write_args *arg = &p_cmd->args;
375fe56b9e6SYuval Mintz 	int rc = 0;
376fe56b9e6SYuval Mintz 
377fe56b9e6SYuval Mintz 	/* Sanitize */
378fe56b9e6SYuval Mintz 	if (b_must_dmae && !b_can_dmae) {
379fe56b9e6SYuval Mintz 		DP_NOTICE(p_hwfn,
380fe56b9e6SYuval Mintz 			  "Need to write to %08x for Wide-bus but DMAE isn't allowed\n",
381fe56b9e6SYuval Mintz 			  addr);
382fe56b9e6SYuval Mintz 		return -EINVAL;
383fe56b9e6SYuval Mintz 	}
384fe56b9e6SYuval Mintz 
385fe56b9e6SYuval Mintz 	switch (GET_FIELD(data, INIT_WRITE_OP_SOURCE)) {
386fe56b9e6SYuval Mintz 	case INIT_SRC_INLINE:
38783aeb933SYuval Mintz 		data = le32_to_cpu(p_cmd->args.inline_val);
38883aeb933SYuval Mintz 		qed_wr(p_hwfn, p_ptt, addr, data);
389fe56b9e6SYuval Mintz 		break;
390fe56b9e6SYuval Mintz 	case INIT_SRC_ZEROS:
39183aeb933SYuval Mintz 		data = le32_to_cpu(p_cmd->args.zeros_count);
39283aeb933SYuval Mintz 		if (b_must_dmae || (b_can_dmae && (data >= 64)))
393*b90cb538SOmkar Kulkarni 			rc = qed_init_fill_dmae(p_hwfn, p_ptt, addr, data);
394fe56b9e6SYuval Mintz 		else
39583aeb933SYuval Mintz 			qed_init_fill(p_hwfn, p_ptt, addr, 0, data);
396fe56b9e6SYuval Mintz 		break;
397fe56b9e6SYuval Mintz 	case INIT_SRC_ARRAY:
3981a635e48SYuval Mintz 		rc = qed_init_cmd_array(p_hwfn, p_ptt, p_cmd,
399fe56b9e6SYuval Mintz 					b_must_dmae, b_can_dmae);
400fe56b9e6SYuval Mintz 		break;
401fe56b9e6SYuval Mintz 	case INIT_SRC_RUNTIME:
402fe56b9e6SYuval Mintz 		qed_init_rt(p_hwfn, p_ptt, addr,
403fe56b9e6SYuval Mintz 			    le16_to_cpu(arg->runtime.offset),
404fc48b7a6SYuval Mintz 			    le16_to_cpu(arg->runtime.size),
405fc48b7a6SYuval Mintz 			    b_must_dmae);
406fe56b9e6SYuval Mintz 		break;
407fe56b9e6SYuval Mintz 	}
408fe56b9e6SYuval Mintz 
409fe56b9e6SYuval Mintz 	return rc;
410fe56b9e6SYuval Mintz }
411fe56b9e6SYuval Mintz 
comp_eq(u32 val,u32 expected_val)412fe56b9e6SYuval Mintz static inline bool comp_eq(u32 val, u32 expected_val)
413fe56b9e6SYuval Mintz {
414fe56b9e6SYuval Mintz 	return val == expected_val;
415fe56b9e6SYuval Mintz }
416fe56b9e6SYuval Mintz 
comp_and(u32 val,u32 expected_val)417fe56b9e6SYuval Mintz static inline bool comp_and(u32 val, u32 expected_val)
418fe56b9e6SYuval Mintz {
419fe56b9e6SYuval Mintz 	return (val & expected_val) == expected_val;
420fe56b9e6SYuval Mintz }
421fe56b9e6SYuval Mintz 
comp_or(u32 val,u32 expected_val)422fe56b9e6SYuval Mintz static inline bool comp_or(u32 val, u32 expected_val)
423fe56b9e6SYuval Mintz {
424fe56b9e6SYuval Mintz 	return (val | expected_val) > 0;
425fe56b9e6SYuval Mintz }
426fe56b9e6SYuval Mintz 
427fe56b9e6SYuval Mintz /* init_ops read/poll commands */
qed_init_cmd_rd(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,struct init_read_op * cmd)428fe56b9e6SYuval Mintz static void qed_init_cmd_rd(struct qed_hwfn *p_hwfn,
4291a635e48SYuval Mintz 			    struct qed_ptt *p_ptt, struct init_read_op *cmd)
430fe56b9e6SYuval Mintz {
431fc48b7a6SYuval Mintz 	bool (*comp_check)(u32 val, u32 expected_val);
432fe56b9e6SYuval Mintz 	u32 delay = QED_INIT_POLL_PERIOD_US, val;
433fc48b7a6SYuval Mintz 	u32 data, addr, poll;
434fc48b7a6SYuval Mintz 	int i;
435fc48b7a6SYuval Mintz 
436fc48b7a6SYuval Mintz 	data = le32_to_cpu(cmd->op_data);
437fc48b7a6SYuval Mintz 	addr = GET_FIELD(data, INIT_READ_OP_ADDRESS) << 2;
438fc48b7a6SYuval Mintz 	poll = GET_FIELD(data, INIT_READ_OP_POLL_TYPE);
439fc48b7a6SYuval Mintz 
440fe56b9e6SYuval Mintz 	val = qed_rd(p_hwfn, p_ptt, addr);
441fe56b9e6SYuval Mintz 
442fc48b7a6SYuval Mintz 	if (poll == INIT_POLL_NONE)
443fc48b7a6SYuval Mintz 		return;
444fe56b9e6SYuval Mintz 
445fc48b7a6SYuval Mintz 	switch (poll) {
446fc48b7a6SYuval Mintz 	case INIT_POLL_EQ:
447fe56b9e6SYuval Mintz 		comp_check = comp_eq;
448fe56b9e6SYuval Mintz 		break;
449fc48b7a6SYuval Mintz 	case INIT_POLL_OR:
450fe56b9e6SYuval Mintz 		comp_check = comp_or;
451fe56b9e6SYuval Mintz 		break;
452fc48b7a6SYuval Mintz 	case INIT_POLL_AND:
453fe56b9e6SYuval Mintz 		comp_check = comp_and;
454fe56b9e6SYuval Mintz 		break;
455fe56b9e6SYuval Mintz 	default:
456fe56b9e6SYuval Mintz 		DP_ERR(p_hwfn, "Invalid poll comparison type %08x\n",
457fc48b7a6SYuval Mintz 		       cmd->op_data);
458fe56b9e6SYuval Mintz 		return;
459fe56b9e6SYuval Mintz 	}
460fe56b9e6SYuval Mintz 
461fc48b7a6SYuval Mintz 	data = le32_to_cpu(cmd->expected_val);
462fe56b9e6SYuval Mintz 	for (i = 0;
463fc48b7a6SYuval Mintz 	     i < QED_INIT_MAX_POLL_COUNT && !comp_check(val, data);
464fe56b9e6SYuval Mintz 	     i++) {
465fe56b9e6SYuval Mintz 		udelay(delay);
466fe56b9e6SYuval Mintz 		val = qed_rd(p_hwfn, p_ptt, addr);
467fe56b9e6SYuval Mintz 	}
468fe56b9e6SYuval Mintz 
469fc48b7a6SYuval Mintz 	if (i == QED_INIT_MAX_POLL_COUNT) {
470fe56b9e6SYuval Mintz 		DP_ERR(p_hwfn,
471e75d039aSColin Ian King 		       "Timeout when polling reg: 0x%08x [ Waiting-for: %08x Got: %08x (comparison %08x)]\n",
472fe56b9e6SYuval Mintz 		       addr, le32_to_cpu(cmd->expected_val),
473fc48b7a6SYuval Mintz 		       val, le32_to_cpu(cmd->op_data));
474fe56b9e6SYuval Mintz 	}
475fe56b9e6SYuval Mintz }
476fe56b9e6SYuval Mintz 
477fe56b9e6SYuval Mintz /* init_ops callbacks entry point */
qed_init_cmd_cb(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,struct init_callback_op * p_cmd)478da090917STomer Tayar static int qed_init_cmd_cb(struct qed_hwfn *p_hwfn,
479fe56b9e6SYuval Mintz 			   struct qed_ptt *p_ptt,
480fe56b9e6SYuval Mintz 			   struct init_callback_op *p_cmd)
481fe56b9e6SYuval Mintz {
482da090917STomer Tayar 	int rc;
483da090917STomer Tayar 
484da090917STomer Tayar 	switch (p_cmd->callback_id) {
485da090917STomer Tayar 	case DMAE_READY_CB:
486da090917STomer Tayar 		rc = qed_dmae_sanity(p_hwfn, p_ptt, "engine_phase");
487da090917STomer Tayar 		break;
488da090917STomer Tayar 	default:
489da090917STomer Tayar 		DP_NOTICE(p_hwfn, "Unexpected init op callback ID %d\n",
490da090917STomer Tayar 			  p_cmd->callback_id);
491da090917STomer Tayar 		return -EINVAL;
492da090917STomer Tayar 	}
493da090917STomer Tayar 
494da090917STomer Tayar 	return rc;
495fe56b9e6SYuval Mintz }
496fe56b9e6SYuval Mintz 
qed_init_cmd_mode_match(struct qed_hwfn * p_hwfn,u16 * p_offset,int modes)497fe56b9e6SYuval Mintz static u8 qed_init_cmd_mode_match(struct qed_hwfn *p_hwfn,
4981a635e48SYuval Mintz 				  u16 *p_offset, int modes)
499fe56b9e6SYuval Mintz {
500fe56b9e6SYuval Mintz 	struct qed_dev *cdev = p_hwfn->cdev;
501fe56b9e6SYuval Mintz 	const u8 *modes_tree_buf;
502fe56b9e6SYuval Mintz 	u8 arg1, arg2, tree_val;
503fe56b9e6SYuval Mintz 
504fe56b9e6SYuval Mintz 	modes_tree_buf = cdev->fw_data->modes_tree_buf;
5051a635e48SYuval Mintz 	tree_val = modes_tree_buf[(*p_offset)++];
506fe56b9e6SYuval Mintz 	switch (tree_val) {
507fe56b9e6SYuval Mintz 	case INIT_MODE_OP_NOT:
5081a635e48SYuval Mintz 		return qed_init_cmd_mode_match(p_hwfn, p_offset, modes) ^ 1;
509fe56b9e6SYuval Mintz 	case INIT_MODE_OP_OR:
5101a635e48SYuval Mintz 		arg1 = qed_init_cmd_mode_match(p_hwfn, p_offset, modes);
5111a635e48SYuval Mintz 		arg2 = qed_init_cmd_mode_match(p_hwfn, p_offset, modes);
512fe56b9e6SYuval Mintz 		return arg1 | arg2;
513fe56b9e6SYuval Mintz 	case INIT_MODE_OP_AND:
5141a635e48SYuval Mintz 		arg1 = qed_init_cmd_mode_match(p_hwfn, p_offset, modes);
5151a635e48SYuval Mintz 		arg2 = qed_init_cmd_mode_match(p_hwfn, p_offset, modes);
516fe56b9e6SYuval Mintz 		return arg1 & arg2;
517fe56b9e6SYuval Mintz 	default:
518fe56b9e6SYuval Mintz 		tree_val -= MAX_INIT_MODE_OPS;
5191a635e48SYuval Mintz 		return (modes & BIT(tree_val)) ? 1 : 0;
520fe56b9e6SYuval Mintz 	}
521fe56b9e6SYuval Mintz }
522fe56b9e6SYuval Mintz 
qed_init_cmd_mode(struct qed_hwfn * p_hwfn,struct init_if_mode_op * p_cmd,int modes)523fe56b9e6SYuval Mintz static u32 qed_init_cmd_mode(struct qed_hwfn *p_hwfn,
5241a635e48SYuval Mintz 			     struct init_if_mode_op *p_cmd, int modes)
525fe56b9e6SYuval Mintz {
526fe56b9e6SYuval Mintz 	u16 offset = le16_to_cpu(p_cmd->modes_buf_offset);
527fe56b9e6SYuval Mintz 
528fe56b9e6SYuval Mintz 	if (qed_init_cmd_mode_match(p_hwfn, &offset, modes))
529fe56b9e6SYuval Mintz 		return 0;
530fe56b9e6SYuval Mintz 	else
531fe56b9e6SYuval Mintz 		return GET_FIELD(le32_to_cpu(p_cmd->op_data),
532fe56b9e6SYuval Mintz 				 INIT_IF_MODE_OP_CMD_OFFSET);
533fe56b9e6SYuval Mintz }
534fe56b9e6SYuval Mintz 
qed_init_cmd_phase(struct init_if_phase_op * p_cmd,u32 phase,u32 phase_id)535*b90cb538SOmkar Kulkarni static u32 qed_init_cmd_phase(struct init_if_phase_op *p_cmd,
5361a635e48SYuval Mintz 			      u32 phase, u32 phase_id)
537fe56b9e6SYuval Mintz {
538fe56b9e6SYuval Mintz 	u32 data = le32_to_cpu(p_cmd->phase_data);
539fe56b9e6SYuval Mintz 	u32 op_data = le32_to_cpu(p_cmd->op_data);
540fe56b9e6SYuval Mintz 
541fe56b9e6SYuval Mintz 	if (!(GET_FIELD(data, INIT_IF_PHASE_OP_PHASE) == phase &&
542fe56b9e6SYuval Mintz 	      (GET_FIELD(data, INIT_IF_PHASE_OP_PHASE_ID) == ANY_PHASE_ID ||
543fe56b9e6SYuval Mintz 	       GET_FIELD(data, INIT_IF_PHASE_OP_PHASE_ID) == phase_id)))
544fe56b9e6SYuval Mintz 		return GET_FIELD(op_data, INIT_IF_PHASE_OP_CMD_OFFSET);
545fe56b9e6SYuval Mintz 	else
546fe56b9e6SYuval Mintz 		return 0;
547fe56b9e6SYuval Mintz }
548fe56b9e6SYuval Mintz 
qed_init_run(struct qed_hwfn * p_hwfn,struct qed_ptt * p_ptt,int phase,int phase_id,int modes)549fe56b9e6SYuval Mintz int qed_init_run(struct qed_hwfn *p_hwfn,
5501a635e48SYuval Mintz 		 struct qed_ptt *p_ptt, int phase, int phase_id, int modes)
551fe56b9e6SYuval Mintz {
5520500a70dSMichal Kalderon 	bool b_dmae = (phase != PHASE_ENGINE);
553fe56b9e6SYuval Mintz 	struct qed_dev *cdev = p_hwfn->cdev;
554fe56b9e6SYuval Mintz 	u32 cmd_num, num_init_ops;
555fe56b9e6SYuval Mintz 	union init_op *init_ops;
556fe56b9e6SYuval Mintz 	int rc = 0;
557fe56b9e6SYuval Mintz 
558fe56b9e6SYuval Mintz 	num_init_ops = cdev->fw_data->init_ops_size;
559fe56b9e6SYuval Mintz 	init_ops = cdev->fw_data->init_ops;
560fe56b9e6SYuval Mintz 
561fe56b9e6SYuval Mintz 	p_hwfn->unzip_buf = kzalloc(MAX_ZIPPED_SIZE * 4, GFP_ATOMIC);
5622591c280SJoe Perches 	if (!p_hwfn->unzip_buf)
563fe56b9e6SYuval Mintz 		return -ENOMEM;
564fe56b9e6SYuval Mintz 
565fe56b9e6SYuval Mintz 	for (cmd_num = 0; cmd_num < num_init_ops; cmd_num++) {
566fe56b9e6SYuval Mintz 		union init_op *cmd = &init_ops[cmd_num];
567fe56b9e6SYuval Mintz 		u32 data = le32_to_cpu(cmd->raw.op_data);
568fe56b9e6SYuval Mintz 
569fe56b9e6SYuval Mintz 		switch (GET_FIELD(data, INIT_CALLBACK_OP_OP)) {
570fe56b9e6SYuval Mintz 		case INIT_OP_WRITE:
571fe56b9e6SYuval Mintz 			rc = qed_init_cmd_wr(p_hwfn, p_ptt, &cmd->write,
572fe56b9e6SYuval Mintz 					     b_dmae);
573fe56b9e6SYuval Mintz 			break;
574fe56b9e6SYuval Mintz 		case INIT_OP_READ:
575fe56b9e6SYuval Mintz 			qed_init_cmd_rd(p_hwfn, p_ptt, &cmd->read);
576fe56b9e6SYuval Mintz 			break;
577fe56b9e6SYuval Mintz 		case INIT_OP_IF_MODE:
578fe56b9e6SYuval Mintz 			cmd_num += qed_init_cmd_mode(p_hwfn, &cmd->if_mode,
579fe56b9e6SYuval Mintz 						     modes);
580fe56b9e6SYuval Mintz 			break;
581fe56b9e6SYuval Mintz 		case INIT_OP_IF_PHASE:
582*b90cb538SOmkar Kulkarni 			cmd_num += qed_init_cmd_phase(&cmd->if_phase,
583fe56b9e6SYuval Mintz 						      phase, phase_id);
584fe56b9e6SYuval Mintz 			break;
585fe56b9e6SYuval Mintz 		case INIT_OP_DELAY:
586fe56b9e6SYuval Mintz 			/* qed_init_run is always invoked from
587fe56b9e6SYuval Mintz 			 * sleep-able context
588fe56b9e6SYuval Mintz 			 */
589fe56b9e6SYuval Mintz 			udelay(le32_to_cpu(cmd->delay.delay));
590fe56b9e6SYuval Mintz 			break;
591fe56b9e6SYuval Mintz 
592fe56b9e6SYuval Mintz 		case INIT_OP_CALLBACK:
593da090917STomer Tayar 			rc = qed_init_cmd_cb(p_hwfn, p_ptt, &cmd->callback);
5940500a70dSMichal Kalderon 			if (phase == PHASE_ENGINE &&
5950500a70dSMichal Kalderon 			    cmd->callback.callback_id == DMAE_READY_CB)
5960500a70dSMichal Kalderon 				b_dmae = true;
597fe56b9e6SYuval Mintz 			break;
598fe56b9e6SYuval Mintz 		}
599fe56b9e6SYuval Mintz 
600fe56b9e6SYuval Mintz 		if (rc)
601fe56b9e6SYuval Mintz 			break;
602fe56b9e6SYuval Mintz 	}
603fe56b9e6SYuval Mintz 
604fe56b9e6SYuval Mintz 	kfree(p_hwfn->unzip_buf);
6053587cb87STomer Tayar 	p_hwfn->unzip_buf = NULL;
606fe56b9e6SYuval Mintz 	return rc;
607fe56b9e6SYuval Mintz }
608fe56b9e6SYuval Mintz 
qed_gtt_init(struct qed_hwfn * p_hwfn)609fe56b9e6SYuval Mintz void qed_gtt_init(struct qed_hwfn *p_hwfn)
610fe56b9e6SYuval Mintz {
611fe56b9e6SYuval Mintz 	u32 gtt_base;
612fe56b9e6SYuval Mintz 	u32 i;
613fe56b9e6SYuval Mintz 
614fe56b9e6SYuval Mintz 	/* Set the global windows */
615fe56b9e6SYuval Mintz 	gtt_base = PXP_PF_WINDOW_ADMIN_START + PXP_PF_WINDOW_ADMIN_GLOBAL_START;
616fe56b9e6SYuval Mintz 
617fe56b9e6SYuval Mintz 	for (i = 0; i < ARRAY_SIZE(pxp_global_win); i++)
618fe56b9e6SYuval Mintz 		if (pxp_global_win[i])
619fe56b9e6SYuval Mintz 			REG_WR(p_hwfn, gtt_base + i * PXP_GLOBAL_ENTRY_SIZE,
620fe56b9e6SYuval Mintz 			       pxp_global_win[i]);
621fe56b9e6SYuval Mintz }
622fe56b9e6SYuval Mintz 
qed_init_fw_data(struct qed_dev * cdev,const u8 * data)623351a4dedSYuval Mintz int qed_init_fw_data(struct qed_dev *cdev, const u8 *data)
624fe56b9e6SYuval Mintz {
625fe56b9e6SYuval Mintz 	struct qed_fw_data *fw = cdev->fw_data;
626fe56b9e6SYuval Mintz 	struct bin_buffer_hdr *buf_hdr;
627fe56b9e6SYuval Mintz 	u32 offset, len;
628fe56b9e6SYuval Mintz 
629fe56b9e6SYuval Mintz 	if (!data) {
630fe56b9e6SYuval Mintz 		DP_NOTICE(cdev, "Invalid fw data\n");
631fe56b9e6SYuval Mintz 		return -EINVAL;
632fe56b9e6SYuval Mintz 	}
633fe56b9e6SYuval Mintz 
634351a4dedSYuval Mintz 	/* First Dword contains metadata and should be skipped */
635be086e7cSMintz, Yuval 	buf_hdr = (struct bin_buffer_hdr *)data;
636351a4dedSYuval Mintz 
63705fafbfbSYuval Mintz 	offset = buf_hdr[BIN_BUF_INIT_FW_VER_INFO].offset;
638351a4dedSYuval Mintz 	fw->fw_ver_info = (struct fw_ver_info *)(data + offset);
639fe56b9e6SYuval Mintz 
640fe56b9e6SYuval Mintz 	offset = buf_hdr[BIN_BUF_INIT_CMD].offset;
641fe56b9e6SYuval Mintz 	fw->init_ops = (union init_op *)(data + offset);
642fe56b9e6SYuval Mintz 
643fe56b9e6SYuval Mintz 	offset = buf_hdr[BIN_BUF_INIT_VAL].offset;
644fe56b9e6SYuval Mintz 	fw->arr_data = (u32 *)(data + offset);
645fe56b9e6SYuval Mintz 
646fe56b9e6SYuval Mintz 	offset = buf_hdr[BIN_BUF_INIT_MODE_TREE].offset;
647fe56b9e6SYuval Mintz 	fw->modes_tree_buf = (u8 *)(data + offset);
648fe56b9e6SYuval Mintz 	len = buf_hdr[BIN_BUF_INIT_CMD].length;
649fe56b9e6SYuval Mintz 	fw->init_ops_size = len / sizeof(struct init_raw_op);
650fe56b9e6SYuval Mintz 
65130d5f858SMichal Kalderon 	offset = buf_hdr[BIN_BUF_INIT_OVERLAYS].offset;
65230d5f858SMichal Kalderon 	fw->fw_overlays = (u32 *)(data + offset);
65330d5f858SMichal Kalderon 	len = buf_hdr[BIN_BUF_INIT_OVERLAYS].length;
65430d5f858SMichal Kalderon 	fw->fw_overlays_len = len;
65530d5f858SMichal Kalderon 
656fe56b9e6SYuval Mintz 	return 0;
657fe56b9e6SYuval Mintz }
658