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"
18fe56b9e6SYuval Mintz #include "qed_reg_addr.h"
191408cc1fSYuval Mintz #include "qed_sriov.h"
20fe56b9e6SYuval Mintz 
21fe56b9e6SYuval Mintz #define QED_INIT_MAX_POLL_COUNT 100
22fe56b9e6SYuval Mintz #define QED_INIT_POLL_PERIOD_US 500
23fe56b9e6SYuval Mintz 
24fe56b9e6SYuval Mintz static u32 pxp_global_win[] = {
25fe56b9e6SYuval Mintz 	0,
26fe56b9e6SYuval Mintz 	0,
27fe56b9e6SYuval Mintz 	0x1c02, /* win 2: addr=0x1c02000, size=4096 bytes */
28fe56b9e6SYuval Mintz 	0x1c80, /* win 3: addr=0x1c80000, size=4096 bytes */
29fe56b9e6SYuval Mintz 	0x1d00, /* win 4: addr=0x1d00000, size=4096 bytes */
30fe56b9e6SYuval Mintz 	0x1d01, /* win 5: addr=0x1d01000, size=4096 bytes */
316aebde8dSMichal Kalderon 	0x1d02, /* win 6: addr=0x1d02000, size=4096 bytes */
326aebde8dSMichal Kalderon 	0x1d80, /* win 7: addr=0x1d80000, size=4096 bytes */
336aebde8dSMichal Kalderon 	0x1d81, /* win 8: addr=0x1d81000, size=4096 bytes */
346aebde8dSMichal Kalderon 	0x1d82, /* win 9: addr=0x1d82000, size=4096 bytes */
356aebde8dSMichal Kalderon 	0x1e00, /* win 10: addr=0x1e00000, size=4096 bytes */
366aebde8dSMichal Kalderon 	0x1e01, /* win 11: addr=0x1e01000, size=4096 bytes */
376aebde8dSMichal Kalderon 	0x1e80, /* win 12: addr=0x1e80000, size=4096 bytes */
386aebde8dSMichal Kalderon 	0x1f00, /* win 13: addr=0x1f00000, size=4096 bytes */
396aebde8dSMichal Kalderon 	0x1c08, /* win 14: addr=0x1c08000, size=4096 bytes */
40fe56b9e6SYuval Mintz 	0,
41fe56b9e6SYuval Mintz 	0,
42fe56b9e6SYuval Mintz 	0,
43fe56b9e6SYuval Mintz 	0,
44fe56b9e6SYuval Mintz };
45fe56b9e6SYuval Mintz 
460dfda108SAlexander Lobakin /* IRO Array */
470dfda108SAlexander Lobakin static const u32 iro_arr[] = {
480dfda108SAlexander Lobakin 	0x00000000, 0x00000000, 0x00080000,
490dfda108SAlexander Lobakin 	0x00003288, 0x00000088, 0x00880000,
500dfda108SAlexander Lobakin 	0x000058e8, 0x00000020, 0x00200000,
510dfda108SAlexander Lobakin 	0x00000b00, 0x00000008, 0x00040000,
520dfda108SAlexander Lobakin 	0x00000a80, 0x00000008, 0x00040000,
530dfda108SAlexander Lobakin 	0x00000000, 0x00000008, 0x00020000,
540dfda108SAlexander Lobakin 	0x00000080, 0x00000008, 0x00040000,
550dfda108SAlexander Lobakin 	0x00000084, 0x00000008, 0x00020000,
560dfda108SAlexander Lobakin 	0x00005718, 0x00000004, 0x00040000,
570dfda108SAlexander Lobakin 	0x00004dd0, 0x00000000, 0x00780000,
580dfda108SAlexander Lobakin 	0x00003e40, 0x00000000, 0x00780000,
590dfda108SAlexander Lobakin 	0x00004480, 0x00000000, 0x00780000,
600dfda108SAlexander Lobakin 	0x00003210, 0x00000000, 0x00780000,
610dfda108SAlexander Lobakin 	0x00003b50, 0x00000000, 0x00780000,
620dfda108SAlexander Lobakin 	0x00007f58, 0x00000000, 0x00780000,
630dfda108SAlexander Lobakin 	0x00005f58, 0x00000000, 0x00080000,
640dfda108SAlexander Lobakin 	0x00007100, 0x00000000, 0x00080000,
650dfda108SAlexander Lobakin 	0x0000aea0, 0x00000000, 0x00080000,
660dfda108SAlexander Lobakin 	0x00004398, 0x00000000, 0x00080000,
670dfda108SAlexander Lobakin 	0x0000a5a0, 0x00000000, 0x00080000,
680dfda108SAlexander Lobakin 	0x0000bde8, 0x00000000, 0x00080000,
690dfda108SAlexander Lobakin 	0x00000020, 0x00000004, 0x00040000,
700dfda108SAlexander Lobakin 	0x000056c8, 0x00000010, 0x00100000,
710dfda108SAlexander Lobakin 	0x0000c210, 0x00000030, 0x00300000,
720dfda108SAlexander Lobakin 	0x0000b088, 0x00000038, 0x00380000,
730dfda108SAlexander Lobakin 	0x00003d20, 0x00000080, 0x00400000,
740dfda108SAlexander Lobakin 	0x0000bf60, 0x00000000, 0x00040000,
750dfda108SAlexander Lobakin 	0x00004560, 0x00040080, 0x00040000,
760dfda108SAlexander Lobakin 	0x000001f8, 0x00000004, 0x00040000,
770dfda108SAlexander Lobakin 	0x00003d60, 0x00000080, 0x00200000,
780dfda108SAlexander Lobakin 	0x00008960, 0x00000040, 0x00300000,
790dfda108SAlexander Lobakin 	0x0000e840, 0x00000060, 0x00600000,
800dfda108SAlexander Lobakin 	0x00004618, 0x00000080, 0x00380000,
810dfda108SAlexander Lobakin 	0x00010738, 0x000000c0, 0x00c00000,
820dfda108SAlexander Lobakin 	0x000001f8, 0x00000002, 0x00020000,
830dfda108SAlexander Lobakin 	0x0000a2a0, 0x00000000, 0x01080000,
840dfda108SAlexander Lobakin 	0x0000a3a8, 0x00000008, 0x00080000,
850dfda108SAlexander Lobakin 	0x000001c0, 0x00000008, 0x00080000,
860dfda108SAlexander Lobakin 	0x000001f8, 0x00000008, 0x00080000,
870dfda108SAlexander Lobakin 	0x00000ac0, 0x00000008, 0x00080000,
880dfda108SAlexander Lobakin 	0x00002578, 0x00000008, 0x00080000,
890dfda108SAlexander Lobakin 	0x000024f8, 0x00000008, 0x00080000,
900dfda108SAlexander Lobakin 	0x00000280, 0x00000008, 0x00080000,
910dfda108SAlexander Lobakin 	0x00000680, 0x00080018, 0x00080000,
920dfda108SAlexander Lobakin 	0x00000b78, 0x00080018, 0x00020000,
930dfda108SAlexander Lobakin 	0x0000c640, 0x00000050, 0x003c0000,
940dfda108SAlexander Lobakin 	0x00012038, 0x00000018, 0x00100000,
950dfda108SAlexander Lobakin 	0x00011b00, 0x00000040, 0x00180000,
960dfda108SAlexander Lobakin 	0x000095d0, 0x00000050, 0x00200000,
970dfda108SAlexander Lobakin 	0x00008b10, 0x00000040, 0x00280000,
980dfda108SAlexander Lobakin 	0x00011640, 0x00000018, 0x00100000,
990dfda108SAlexander Lobakin 	0x0000c828, 0x00000048, 0x00380000,
1000dfda108SAlexander Lobakin 	0x00011710, 0x00000020, 0x00200000,
1010dfda108SAlexander Lobakin 	0x00004650, 0x00000080, 0x00100000,
1020dfda108SAlexander Lobakin 	0x00003618, 0x00000010, 0x00100000,
1030dfda108SAlexander Lobakin 	0x0000a968, 0x00000008, 0x00010000,
1040dfda108SAlexander Lobakin 	0x000097a0, 0x00000008, 0x00010000,
1050dfda108SAlexander Lobakin 	0x00011990, 0x00000008, 0x00010000,
1060dfda108SAlexander Lobakin 	0x0000f018, 0x00000008, 0x00010000,
1070dfda108SAlexander Lobakin 	0x00012628, 0x00000008, 0x00010000,
1080dfda108SAlexander Lobakin 	0x00011da8, 0x00000008, 0x00010000,
1090dfda108SAlexander Lobakin 	0x0000aa78, 0x00000030, 0x00100000,
1100dfda108SAlexander Lobakin 	0x0000d768, 0x00000028, 0x00280000,
1110dfda108SAlexander Lobakin 	0x00009a58, 0x00000018, 0x00180000,
1120dfda108SAlexander Lobakin 	0x00009bd8, 0x00000008, 0x00080000,
1130dfda108SAlexander Lobakin 	0x00013a18, 0x00000008, 0x00080000,
1140dfda108SAlexander Lobakin 	0x000126e8, 0x00000018, 0x00180000,
1150dfda108SAlexander Lobakin 	0x0000e608, 0x00500288, 0x00100000,
1160dfda108SAlexander Lobakin 	0x00012970, 0x00000138, 0x00280000,
1170dfda108SAlexander Lobakin };
1180dfda108SAlexander Lobakin 
119fe56b9e6SYuval Mintz void qed_init_iro_array(struct qed_dev *cdev)
120fe56b9e6SYuval Mintz {
121fe56b9e6SYuval Mintz 	cdev->iro_arr = iro_arr;
122fe56b9e6SYuval Mintz }
123fe56b9e6SYuval Mintz 
1241a635e48SYuval Mintz void qed_init_store_rt_reg(struct qed_hwfn *p_hwfn, u32 rt_offset, u32 val)
125fe56b9e6SYuval Mintz {
126fc48b7a6SYuval Mintz 	p_hwfn->rt_data.init_val[rt_offset] = val;
127fc48b7a6SYuval Mintz 	p_hwfn->rt_data.b_valid[rt_offset] = true;
128fe56b9e6SYuval Mintz }
129fe56b9e6SYuval Mintz 
130fe56b9e6SYuval Mintz void qed_init_store_rt_agg(struct qed_hwfn *p_hwfn,
1311a635e48SYuval Mintz 			   u32 rt_offset, u32 *p_val, size_t size)
132fe56b9e6SYuval Mintz {
133fe56b9e6SYuval Mintz 	size_t i;
134fe56b9e6SYuval Mintz 
135fe56b9e6SYuval Mintz 	for (i = 0; i < size / sizeof(u32); i++) {
136fc48b7a6SYuval Mintz 		p_hwfn->rt_data.init_val[rt_offset + i] = p_val[i];
137fc48b7a6SYuval Mintz 		p_hwfn->rt_data.b_valid[rt_offset + i]	= true;
138fe56b9e6SYuval Mintz 	}
139fe56b9e6SYuval Mintz }
140fe56b9e6SYuval Mintz 
141fc48b7a6SYuval Mintz static int qed_init_rt(struct qed_hwfn	*p_hwfn,
142fe56b9e6SYuval Mintz 		       struct qed_ptt *p_ptt,
1431a635e48SYuval Mintz 		       u32 addr, u16 rt_offset, u16 size, bool b_must_dmae)
144fe56b9e6SYuval Mintz {
145fc48b7a6SYuval Mintz 	u32 *p_init_val = &p_hwfn->rt_data.init_val[rt_offset];
146fc48b7a6SYuval Mintz 	bool *p_valid = &p_hwfn->rt_data.b_valid[rt_offset];
1476bc82d9bSMichal Kalderon 	u16 i, j, segment;
148fc48b7a6SYuval Mintz 	int rc = 0;
149fe56b9e6SYuval Mintz 
150fc48b7a6SYuval Mintz 	/* Since not all RT entries are initialized, go over the RT and
151fc48b7a6SYuval Mintz 	 * for each segment of initialized values use DMA.
152fc48b7a6SYuval Mintz 	 */
153fe56b9e6SYuval Mintz 	for (i = 0; i < size; i++) {
154fc48b7a6SYuval Mintz 		if (!p_valid[i])
155fe56b9e6SYuval Mintz 			continue;
156fc48b7a6SYuval Mintz 
157fc48b7a6SYuval Mintz 		/* In case there isn't any wide-bus configuration here,
158fc48b7a6SYuval Mintz 		 * simply write the data instead of using dmae.
159fc48b7a6SYuval Mintz 		 */
160fc48b7a6SYuval Mintz 		if (!b_must_dmae) {
1611a635e48SYuval Mintz 			qed_wr(p_hwfn, p_ptt, addr + (i << 2), p_init_val[i]);
1626bc82d9bSMichal Kalderon 			p_valid[i] = false;
163fc48b7a6SYuval Mintz 			continue;
164fe56b9e6SYuval Mintz 		}
165fc48b7a6SYuval Mintz 
166fc48b7a6SYuval Mintz 		/* Start of a new segment */
167fc48b7a6SYuval Mintz 		for (segment = 1; i + segment < size; segment++)
168fc48b7a6SYuval Mintz 			if (!p_valid[i + segment])
169fc48b7a6SYuval Mintz 				break;
170fc48b7a6SYuval Mintz 
171fc48b7a6SYuval Mintz 		rc = qed_dmae_host2grc(p_hwfn, p_ptt,
172fc48b7a6SYuval Mintz 				       (uintptr_t)(p_init_val + i),
17383bf76e3SMichal Kalderon 				       addr + (i << 2), segment, NULL);
1741a635e48SYuval Mintz 		if (rc)
175fc48b7a6SYuval Mintz 			return rc;
176fc48b7a6SYuval Mintz 
1776bc82d9bSMichal Kalderon 		/* invalidate after writing */
1786bc82d9bSMichal Kalderon 		for (j = i; j < i + segment; j++)
1796bc82d9bSMichal Kalderon 			p_valid[j] = false;
1806bc82d9bSMichal Kalderon 
181fc48b7a6SYuval Mintz 		/* Jump over the entire segment, including invalid entry */
182fc48b7a6SYuval Mintz 		i += segment;
183fc48b7a6SYuval Mintz 	}
184fc48b7a6SYuval Mintz 
185fc48b7a6SYuval Mintz 	return rc;
186fe56b9e6SYuval Mintz }
187fe56b9e6SYuval Mintz 
188fe56b9e6SYuval Mintz int qed_init_alloc(struct qed_hwfn *p_hwfn)
189fe56b9e6SYuval Mintz {
190fc48b7a6SYuval Mintz 	struct qed_rt_data *rt_data = &p_hwfn->rt_data;
191fe56b9e6SYuval Mintz 
1921408cc1fSYuval Mintz 	if (IS_VF(p_hwfn->cdev))
1931408cc1fSYuval Mintz 		return 0;
1941408cc1fSYuval Mintz 
1956396bb22SKees Cook 	rt_data->b_valid = kcalloc(RUNTIME_ARRAY_SIZE, sizeof(bool),
196fc48b7a6SYuval Mintz 				   GFP_KERNEL);
197fc48b7a6SYuval Mintz 	if (!rt_data->b_valid)
198fe56b9e6SYuval Mintz 		return -ENOMEM;
199fe56b9e6SYuval Mintz 
2006396bb22SKees Cook 	rt_data->init_val = kcalloc(RUNTIME_ARRAY_SIZE, sizeof(u32),
201fc48b7a6SYuval Mintz 				    GFP_KERNEL);
202fc48b7a6SYuval Mintz 	if (!rt_data->init_val) {
203fc48b7a6SYuval Mintz 		kfree(rt_data->b_valid);
2043587cb87STomer Tayar 		rt_data->b_valid = NULL;
205fc48b7a6SYuval Mintz 		return -ENOMEM;
206fc48b7a6SYuval Mintz 	}
207fe56b9e6SYuval Mintz 
208fe56b9e6SYuval Mintz 	return 0;
209fe56b9e6SYuval Mintz }
210fe56b9e6SYuval Mintz 
211fe56b9e6SYuval Mintz void qed_init_free(struct qed_hwfn *p_hwfn)
212fe56b9e6SYuval Mintz {
213fc48b7a6SYuval Mintz 	kfree(p_hwfn->rt_data.init_val);
2143587cb87STomer Tayar 	p_hwfn->rt_data.init_val = NULL;
215fc48b7a6SYuval Mintz 	kfree(p_hwfn->rt_data.b_valid);
2163587cb87STomer Tayar 	p_hwfn->rt_data.b_valid = NULL;
217fe56b9e6SYuval Mintz }
218fe56b9e6SYuval Mintz 
219fe56b9e6SYuval Mintz static int qed_init_array_dmae(struct qed_hwfn *p_hwfn,
220fe56b9e6SYuval Mintz 			       struct qed_ptt *p_ptt,
221fe56b9e6SYuval Mintz 			       u32 addr,
222fe56b9e6SYuval Mintz 			       u32 dmae_data_offset,
223fe56b9e6SYuval Mintz 			       u32 size,
224fe56b9e6SYuval Mintz 			       const u32 *buf,
225fe56b9e6SYuval Mintz 			       bool b_must_dmae,
226fe56b9e6SYuval Mintz 			       bool b_can_dmae)
227fe56b9e6SYuval Mintz {
228fe56b9e6SYuval Mintz 	int rc = 0;
229fe56b9e6SYuval Mintz 
230fe56b9e6SYuval Mintz 	/* Perform DMAE only for lengthy enough sections or for wide-bus */
231fe56b9e6SYuval Mintz 	if (!b_can_dmae || (!b_must_dmae && (size < 16))) {
232fe56b9e6SYuval Mintz 		const u32 *data = buf + dmae_data_offset;
233fe56b9e6SYuval Mintz 		u32 i;
234fe56b9e6SYuval Mintz 
235fe56b9e6SYuval Mintz 		for (i = 0; i < size; i++)
236fe56b9e6SYuval Mintz 			qed_wr(p_hwfn, p_ptt, addr + (i << 2), data[i]);
237fe56b9e6SYuval Mintz 	} else {
238fe56b9e6SYuval Mintz 		rc = qed_dmae_host2grc(p_hwfn, p_ptt,
239fe56b9e6SYuval Mintz 				       (uintptr_t)(buf + dmae_data_offset),
24083bf76e3SMichal Kalderon 				       addr, size, NULL);
241fe56b9e6SYuval Mintz 	}
242fe56b9e6SYuval Mintz 
243fe56b9e6SYuval Mintz 	return rc;
244fe56b9e6SYuval Mintz }
245fe56b9e6SYuval Mintz 
246fe56b9e6SYuval Mintz static int qed_init_fill_dmae(struct qed_hwfn *p_hwfn,
247fe56b9e6SYuval Mintz 			      struct qed_ptt *p_ptt,
2481a635e48SYuval Mintz 			      u32 addr, u32 fill, u32 fill_count)
249fe56b9e6SYuval Mintz {
250fe56b9e6SYuval Mintz 	static u32 zero_buffer[DMAE_MAX_RW_SIZE];
25183bf76e3SMichal Kalderon 	struct qed_dmae_params params = {};
252fe56b9e6SYuval Mintz 
253fe56b9e6SYuval Mintz 	memset(zero_buffer, 0, sizeof(u32) * DMAE_MAX_RW_SIZE);
254fe56b9e6SYuval Mintz 
255fe56b9e6SYuval Mintz 	/* invoke the DMAE virtual/physical buffer API with
256fe56b9e6SYuval Mintz 	 * 1. DMAE init channel
257fe56b9e6SYuval Mintz 	 * 2. addr,
258fe56b9e6SYuval Mintz 	 * 3. p_hwfb->temp_data,
259fe56b9e6SYuval Mintz 	 * 4. fill_count
260fe56b9e6SYuval Mintz 	 */
261804c5702SMichal Kalderon 	SET_FIELD(params.flags, QED_DMAE_PARAMS_RW_REPL_SRC, 0x1);
262fe56b9e6SYuval Mintz 	return qed_dmae_host2grc(p_hwfn, p_ptt,
263fe56b9e6SYuval Mintz 				 (uintptr_t)(&zero_buffer[0]),
26483bf76e3SMichal Kalderon 				 addr, fill_count, &params);
265fe56b9e6SYuval Mintz }
266fe56b9e6SYuval Mintz 
267fe56b9e6SYuval Mintz static void qed_init_fill(struct qed_hwfn *p_hwfn,
268fe56b9e6SYuval Mintz 			  struct qed_ptt *p_ptt,
2691a635e48SYuval Mintz 			  u32 addr, u32 fill, u32 fill_count)
270fe56b9e6SYuval Mintz {
271fe56b9e6SYuval Mintz 	u32 i;
272fe56b9e6SYuval Mintz 
273fe56b9e6SYuval Mintz 	for (i = 0; i < fill_count; i++, addr += sizeof(u32))
274fe56b9e6SYuval Mintz 		qed_wr(p_hwfn, p_ptt, addr, fill);
275fe56b9e6SYuval Mintz }
276fe56b9e6SYuval Mintz 
277fe56b9e6SYuval Mintz static int qed_init_cmd_array(struct qed_hwfn *p_hwfn,
278fe56b9e6SYuval Mintz 			      struct qed_ptt *p_ptt,
279fe56b9e6SYuval Mintz 			      struct init_write_op *cmd,
2801a635e48SYuval Mintz 			      bool b_must_dmae, bool b_can_dmae)
281fe56b9e6SYuval Mintz {
2821a635e48SYuval Mintz 	u32 dmae_array_offset = le32_to_cpu(cmd->args.array_offset);
283fe56b9e6SYuval Mintz 	u32 data = le32_to_cpu(cmd->data);
284fe56b9e6SYuval Mintz 	u32 addr = GET_FIELD(data, INIT_WRITE_OP_ADDRESS) << 2;
2851a635e48SYuval Mintz 
286fe56b9e6SYuval Mintz 	u32 offset, output_len, input_len, max_size;
287fe56b9e6SYuval Mintz 	struct qed_dev *cdev = p_hwfn->cdev;
288fe56b9e6SYuval Mintz 	union init_array_hdr *hdr;
289fe56b9e6SYuval Mintz 	const u32 *array_data;
290fe56b9e6SYuval Mintz 	int rc = 0;
291fe56b9e6SYuval Mintz 	u32 size;
292fe56b9e6SYuval Mintz 
293fe56b9e6SYuval Mintz 	array_data = cdev->fw_data->arr_data;
294fe56b9e6SYuval Mintz 
2951a635e48SYuval Mintz 	hdr = (union init_array_hdr *)(array_data + dmae_array_offset);
296fe56b9e6SYuval Mintz 	data = le32_to_cpu(hdr->raw.data);
297fe56b9e6SYuval Mintz 	switch (GET_FIELD(data, INIT_ARRAY_RAW_HDR_TYPE)) {
298fe56b9e6SYuval Mintz 	case INIT_ARR_ZIPPED:
299fe56b9e6SYuval Mintz 		offset = dmae_array_offset + 1;
300fe56b9e6SYuval Mintz 		input_len = GET_FIELD(data,
301fe56b9e6SYuval Mintz 				      INIT_ARRAY_ZIPPED_HDR_ZIPPED_SIZE);
302fe56b9e6SYuval Mintz 		max_size = MAX_ZIPPED_SIZE * 4;
303fe56b9e6SYuval Mintz 		memset(p_hwfn->unzip_buf, 0, max_size);
304fe56b9e6SYuval Mintz 
305fe56b9e6SYuval Mintz 		output_len = qed_unzip_data(p_hwfn, input_len,
306fe56b9e6SYuval Mintz 					    (u8 *)&array_data[offset],
307fe56b9e6SYuval Mintz 					    max_size, (u8 *)p_hwfn->unzip_buf);
308fe56b9e6SYuval Mintz 		if (output_len) {
309fe56b9e6SYuval Mintz 			rc = qed_init_array_dmae(p_hwfn, p_ptt, addr, 0,
310fe56b9e6SYuval Mintz 						 output_len,
311fe56b9e6SYuval Mintz 						 p_hwfn->unzip_buf,
312fe56b9e6SYuval Mintz 						 b_must_dmae, b_can_dmae);
313fe56b9e6SYuval Mintz 		} else {
314fe56b9e6SYuval Mintz 			DP_NOTICE(p_hwfn, "Failed to unzip dmae data\n");
315fe56b9e6SYuval Mintz 			rc = -EINVAL;
316fe56b9e6SYuval Mintz 		}
317fe56b9e6SYuval Mintz 		break;
318fe56b9e6SYuval Mintz 	case INIT_ARR_PATTERN:
319fe56b9e6SYuval Mintz 	{
320fe56b9e6SYuval Mintz 		u32 repeats = GET_FIELD(data,
321fe56b9e6SYuval Mintz 					INIT_ARRAY_PATTERN_HDR_REPETITIONS);
322fe56b9e6SYuval Mintz 		u32 i;
323fe56b9e6SYuval Mintz 
324fe56b9e6SYuval Mintz 		size = GET_FIELD(data, INIT_ARRAY_PATTERN_HDR_PATTERN_SIZE);
325fe56b9e6SYuval Mintz 
326fe56b9e6SYuval Mintz 		for (i = 0; i < repeats; i++, addr += size << 2) {
327fe56b9e6SYuval Mintz 			rc = qed_init_array_dmae(p_hwfn, p_ptt, addr,
328fe56b9e6SYuval Mintz 						 dmae_array_offset + 1,
329fe56b9e6SYuval Mintz 						 size, array_data,
330fe56b9e6SYuval Mintz 						 b_must_dmae, b_can_dmae);
331fe56b9e6SYuval Mintz 			if (rc)
332fe56b9e6SYuval Mintz 				break;
333fe56b9e6SYuval Mintz 		}
334fe56b9e6SYuval Mintz 		break;
335fe56b9e6SYuval Mintz 	}
336fe56b9e6SYuval Mintz 	case INIT_ARR_STANDARD:
337fe56b9e6SYuval Mintz 		size = GET_FIELD(data, INIT_ARRAY_STANDARD_HDR_SIZE);
338fe56b9e6SYuval Mintz 		rc = qed_init_array_dmae(p_hwfn, p_ptt, addr,
339fe56b9e6SYuval Mintz 					 dmae_array_offset + 1,
340fe56b9e6SYuval Mintz 					 size, array_data,
341fe56b9e6SYuval Mintz 					 b_must_dmae, b_can_dmae);
342fe56b9e6SYuval Mintz 		break;
343fe56b9e6SYuval Mintz 	}
344fe56b9e6SYuval Mintz 
345fe56b9e6SYuval Mintz 	return rc;
346fe56b9e6SYuval Mintz }
347fe56b9e6SYuval Mintz 
348fe56b9e6SYuval Mintz /* init_ops write command */
349fe56b9e6SYuval Mintz static int qed_init_cmd_wr(struct qed_hwfn *p_hwfn,
350fe56b9e6SYuval Mintz 			   struct qed_ptt *p_ptt,
3511a635e48SYuval Mintz 			   struct init_write_op *p_cmd, bool b_can_dmae)
352fe56b9e6SYuval Mintz {
3531a635e48SYuval Mintz 	u32 data = le32_to_cpu(p_cmd->data);
354fe56b9e6SYuval Mintz 	bool b_must_dmae = GET_FIELD(data, INIT_WRITE_OP_WIDE_BUS);
3551a635e48SYuval Mintz 	u32 addr = GET_FIELD(data, INIT_WRITE_OP_ADDRESS) << 2;
3561a635e48SYuval Mintz 	union init_write_args *arg = &p_cmd->args;
357fe56b9e6SYuval Mintz 	int rc = 0;
358fe56b9e6SYuval Mintz 
359fe56b9e6SYuval Mintz 	/* Sanitize */
360fe56b9e6SYuval Mintz 	if (b_must_dmae && !b_can_dmae) {
361fe56b9e6SYuval Mintz 		DP_NOTICE(p_hwfn,
362fe56b9e6SYuval Mintz 			  "Need to write to %08x for Wide-bus but DMAE isn't allowed\n",
363fe56b9e6SYuval Mintz 			  addr);
364fe56b9e6SYuval Mintz 		return -EINVAL;
365fe56b9e6SYuval Mintz 	}
366fe56b9e6SYuval Mintz 
367fe56b9e6SYuval Mintz 	switch (GET_FIELD(data, INIT_WRITE_OP_SOURCE)) {
368fe56b9e6SYuval Mintz 	case INIT_SRC_INLINE:
36983aeb933SYuval Mintz 		data = le32_to_cpu(p_cmd->args.inline_val);
37083aeb933SYuval Mintz 		qed_wr(p_hwfn, p_ptt, addr, data);
371fe56b9e6SYuval Mintz 		break;
372fe56b9e6SYuval Mintz 	case INIT_SRC_ZEROS:
37383aeb933SYuval Mintz 		data = le32_to_cpu(p_cmd->args.zeros_count);
37483aeb933SYuval Mintz 		if (b_must_dmae || (b_can_dmae && (data >= 64)))
37583aeb933SYuval Mintz 			rc = qed_init_fill_dmae(p_hwfn, p_ptt, addr, 0, data);
376fe56b9e6SYuval Mintz 		else
37783aeb933SYuval Mintz 			qed_init_fill(p_hwfn, p_ptt, addr, 0, data);
378fe56b9e6SYuval Mintz 		break;
379fe56b9e6SYuval Mintz 	case INIT_SRC_ARRAY:
3801a635e48SYuval Mintz 		rc = qed_init_cmd_array(p_hwfn, p_ptt, p_cmd,
381fe56b9e6SYuval Mintz 					b_must_dmae, b_can_dmae);
382fe56b9e6SYuval Mintz 		break;
383fe56b9e6SYuval Mintz 	case INIT_SRC_RUNTIME:
384fe56b9e6SYuval Mintz 		qed_init_rt(p_hwfn, p_ptt, addr,
385fe56b9e6SYuval Mintz 			    le16_to_cpu(arg->runtime.offset),
386fc48b7a6SYuval Mintz 			    le16_to_cpu(arg->runtime.size),
387fc48b7a6SYuval Mintz 			    b_must_dmae);
388fe56b9e6SYuval Mintz 		break;
389fe56b9e6SYuval Mintz 	}
390fe56b9e6SYuval Mintz 
391fe56b9e6SYuval Mintz 	return rc;
392fe56b9e6SYuval Mintz }
393fe56b9e6SYuval Mintz 
394fe56b9e6SYuval Mintz static inline bool comp_eq(u32 val, u32 expected_val)
395fe56b9e6SYuval Mintz {
396fe56b9e6SYuval Mintz 	return val == expected_val;
397fe56b9e6SYuval Mintz }
398fe56b9e6SYuval Mintz 
399fe56b9e6SYuval Mintz static inline bool comp_and(u32 val, u32 expected_val)
400fe56b9e6SYuval Mintz {
401fe56b9e6SYuval Mintz 	return (val & expected_val) == expected_val;
402fe56b9e6SYuval Mintz }
403fe56b9e6SYuval Mintz 
404fe56b9e6SYuval Mintz static inline bool comp_or(u32 val, u32 expected_val)
405fe56b9e6SYuval Mintz {
406fe56b9e6SYuval Mintz 	return (val | expected_val) > 0;
407fe56b9e6SYuval Mintz }
408fe56b9e6SYuval Mintz 
409fe56b9e6SYuval Mintz /* init_ops read/poll commands */
410fe56b9e6SYuval Mintz static void qed_init_cmd_rd(struct qed_hwfn *p_hwfn,
4111a635e48SYuval Mintz 			    struct qed_ptt *p_ptt, struct init_read_op *cmd)
412fe56b9e6SYuval Mintz {
413fc48b7a6SYuval Mintz 	bool (*comp_check)(u32 val, u32 expected_val);
414fe56b9e6SYuval Mintz 	u32 delay = QED_INIT_POLL_PERIOD_US, val;
415fc48b7a6SYuval Mintz 	u32 data, addr, poll;
416fc48b7a6SYuval Mintz 	int i;
417fc48b7a6SYuval Mintz 
418fc48b7a6SYuval Mintz 	data = le32_to_cpu(cmd->op_data);
419fc48b7a6SYuval Mintz 	addr = GET_FIELD(data, INIT_READ_OP_ADDRESS) << 2;
420fc48b7a6SYuval Mintz 	poll = GET_FIELD(data, INIT_READ_OP_POLL_TYPE);
421fc48b7a6SYuval Mintz 
422fe56b9e6SYuval Mintz 
423fe56b9e6SYuval Mintz 	val = qed_rd(p_hwfn, p_ptt, addr);
424fe56b9e6SYuval Mintz 
425fc48b7a6SYuval Mintz 	if (poll == INIT_POLL_NONE)
426fc48b7a6SYuval Mintz 		return;
427fe56b9e6SYuval Mintz 
428fc48b7a6SYuval Mintz 	switch (poll) {
429fc48b7a6SYuval Mintz 	case INIT_POLL_EQ:
430fe56b9e6SYuval Mintz 		comp_check = comp_eq;
431fe56b9e6SYuval Mintz 		break;
432fc48b7a6SYuval Mintz 	case INIT_POLL_OR:
433fe56b9e6SYuval Mintz 		comp_check = comp_or;
434fe56b9e6SYuval Mintz 		break;
435fc48b7a6SYuval Mintz 	case INIT_POLL_AND:
436fe56b9e6SYuval Mintz 		comp_check = comp_and;
437fe56b9e6SYuval Mintz 		break;
438fe56b9e6SYuval Mintz 	default:
439fe56b9e6SYuval Mintz 		DP_ERR(p_hwfn, "Invalid poll comparison type %08x\n",
440fc48b7a6SYuval Mintz 		       cmd->op_data);
441fe56b9e6SYuval Mintz 		return;
442fe56b9e6SYuval Mintz 	}
443fe56b9e6SYuval Mintz 
444fc48b7a6SYuval Mintz 	data = le32_to_cpu(cmd->expected_val);
445fe56b9e6SYuval Mintz 	for (i = 0;
446fc48b7a6SYuval Mintz 	     i < QED_INIT_MAX_POLL_COUNT && !comp_check(val, data);
447fe56b9e6SYuval Mintz 	     i++) {
448fe56b9e6SYuval Mintz 		udelay(delay);
449fe56b9e6SYuval Mintz 		val = qed_rd(p_hwfn, p_ptt, addr);
450fe56b9e6SYuval Mintz 	}
451fe56b9e6SYuval Mintz 
452fc48b7a6SYuval Mintz 	if (i == QED_INIT_MAX_POLL_COUNT) {
453fe56b9e6SYuval Mintz 		DP_ERR(p_hwfn,
454e75d039aSColin Ian King 		       "Timeout when polling reg: 0x%08x [ Waiting-for: %08x Got: %08x (comparison %08x)]\n",
455fe56b9e6SYuval Mintz 		       addr, le32_to_cpu(cmd->expected_val),
456fc48b7a6SYuval Mintz 		       val, le32_to_cpu(cmd->op_data));
457fe56b9e6SYuval Mintz 	}
458fe56b9e6SYuval Mintz }
459fe56b9e6SYuval Mintz 
460fe56b9e6SYuval Mintz /* init_ops callbacks entry point */
461da090917STomer Tayar static int qed_init_cmd_cb(struct qed_hwfn *p_hwfn,
462fe56b9e6SYuval Mintz 			   struct qed_ptt *p_ptt,
463fe56b9e6SYuval Mintz 			   struct init_callback_op *p_cmd)
464fe56b9e6SYuval Mintz {
465da090917STomer Tayar 	int rc;
466da090917STomer Tayar 
467da090917STomer Tayar 	switch (p_cmd->callback_id) {
468da090917STomer Tayar 	case DMAE_READY_CB:
469da090917STomer Tayar 		rc = qed_dmae_sanity(p_hwfn, p_ptt, "engine_phase");
470da090917STomer Tayar 		break;
471da090917STomer Tayar 	default:
472da090917STomer Tayar 		DP_NOTICE(p_hwfn, "Unexpected init op callback ID %d\n",
473da090917STomer Tayar 			  p_cmd->callback_id);
474da090917STomer Tayar 		return -EINVAL;
475da090917STomer Tayar 	}
476da090917STomer Tayar 
477da090917STomer Tayar 	return rc;
478fe56b9e6SYuval Mintz }
479fe56b9e6SYuval Mintz 
480fe56b9e6SYuval Mintz static u8 qed_init_cmd_mode_match(struct qed_hwfn *p_hwfn,
4811a635e48SYuval Mintz 				  u16 *p_offset, int modes)
482fe56b9e6SYuval Mintz {
483fe56b9e6SYuval Mintz 	struct qed_dev *cdev = p_hwfn->cdev;
484fe56b9e6SYuval Mintz 	const u8 *modes_tree_buf;
485fe56b9e6SYuval Mintz 	u8 arg1, arg2, tree_val;
486fe56b9e6SYuval Mintz 
487fe56b9e6SYuval Mintz 	modes_tree_buf = cdev->fw_data->modes_tree_buf;
4881a635e48SYuval Mintz 	tree_val = modes_tree_buf[(*p_offset)++];
489fe56b9e6SYuval Mintz 	switch (tree_val) {
490fe56b9e6SYuval Mintz 	case INIT_MODE_OP_NOT:
4911a635e48SYuval Mintz 		return qed_init_cmd_mode_match(p_hwfn, p_offset, modes) ^ 1;
492fe56b9e6SYuval Mintz 	case INIT_MODE_OP_OR:
4931a635e48SYuval Mintz 		arg1 = qed_init_cmd_mode_match(p_hwfn, p_offset, modes);
4941a635e48SYuval Mintz 		arg2 = qed_init_cmd_mode_match(p_hwfn, p_offset, modes);
495fe56b9e6SYuval Mintz 		return arg1 | arg2;
496fe56b9e6SYuval Mintz 	case INIT_MODE_OP_AND:
4971a635e48SYuval Mintz 		arg1 = qed_init_cmd_mode_match(p_hwfn, p_offset, modes);
4981a635e48SYuval Mintz 		arg2 = qed_init_cmd_mode_match(p_hwfn, p_offset, modes);
499fe56b9e6SYuval Mintz 		return arg1 & arg2;
500fe56b9e6SYuval Mintz 	default:
501fe56b9e6SYuval Mintz 		tree_val -= MAX_INIT_MODE_OPS;
5021a635e48SYuval Mintz 		return (modes & BIT(tree_val)) ? 1 : 0;
503fe56b9e6SYuval Mintz 	}
504fe56b9e6SYuval Mintz }
505fe56b9e6SYuval Mintz 
506fe56b9e6SYuval Mintz static u32 qed_init_cmd_mode(struct qed_hwfn *p_hwfn,
5071a635e48SYuval Mintz 			     struct init_if_mode_op *p_cmd, int modes)
508fe56b9e6SYuval Mintz {
509fe56b9e6SYuval Mintz 	u16 offset = le16_to_cpu(p_cmd->modes_buf_offset);
510fe56b9e6SYuval Mintz 
511fe56b9e6SYuval Mintz 	if (qed_init_cmd_mode_match(p_hwfn, &offset, modes))
512fe56b9e6SYuval Mintz 		return 0;
513fe56b9e6SYuval Mintz 	else
514fe56b9e6SYuval Mintz 		return GET_FIELD(le32_to_cpu(p_cmd->op_data),
515fe56b9e6SYuval Mintz 				 INIT_IF_MODE_OP_CMD_OFFSET);
516fe56b9e6SYuval Mintz }
517fe56b9e6SYuval Mintz 
518fe56b9e6SYuval Mintz static u32 qed_init_cmd_phase(struct qed_hwfn *p_hwfn,
519fe56b9e6SYuval Mintz 			      struct init_if_phase_op *p_cmd,
5201a635e48SYuval Mintz 			      u32 phase, u32 phase_id)
521fe56b9e6SYuval Mintz {
522fe56b9e6SYuval Mintz 	u32 data = le32_to_cpu(p_cmd->phase_data);
523fe56b9e6SYuval Mintz 	u32 op_data = le32_to_cpu(p_cmd->op_data);
524fe56b9e6SYuval Mintz 
525fe56b9e6SYuval Mintz 	if (!(GET_FIELD(data, INIT_IF_PHASE_OP_PHASE) == phase &&
526fe56b9e6SYuval Mintz 	      (GET_FIELD(data, INIT_IF_PHASE_OP_PHASE_ID) == ANY_PHASE_ID ||
527fe56b9e6SYuval Mintz 	       GET_FIELD(data, INIT_IF_PHASE_OP_PHASE_ID) == phase_id)))
528fe56b9e6SYuval Mintz 		return GET_FIELD(op_data, INIT_IF_PHASE_OP_CMD_OFFSET);
529fe56b9e6SYuval Mintz 	else
530fe56b9e6SYuval Mintz 		return 0;
531fe56b9e6SYuval Mintz }
532fe56b9e6SYuval Mintz 
533fe56b9e6SYuval Mintz int qed_init_run(struct qed_hwfn *p_hwfn,
5341a635e48SYuval Mintz 		 struct qed_ptt *p_ptt, int phase, int phase_id, int modes)
535fe56b9e6SYuval Mintz {
5360500a70dSMichal Kalderon 	bool b_dmae = (phase != PHASE_ENGINE);
537fe56b9e6SYuval Mintz 	struct qed_dev *cdev = p_hwfn->cdev;
538fe56b9e6SYuval Mintz 	u32 cmd_num, num_init_ops;
539fe56b9e6SYuval Mintz 	union init_op *init_ops;
540fe56b9e6SYuval Mintz 	int rc = 0;
541fe56b9e6SYuval Mintz 
542fe56b9e6SYuval Mintz 	num_init_ops = cdev->fw_data->init_ops_size;
543fe56b9e6SYuval Mintz 	init_ops = cdev->fw_data->init_ops;
544fe56b9e6SYuval Mintz 
545fe56b9e6SYuval Mintz 	p_hwfn->unzip_buf = kzalloc(MAX_ZIPPED_SIZE * 4, GFP_ATOMIC);
5462591c280SJoe Perches 	if (!p_hwfn->unzip_buf)
547fe56b9e6SYuval Mintz 		return -ENOMEM;
548fe56b9e6SYuval Mintz 
549fe56b9e6SYuval Mintz 	for (cmd_num = 0; cmd_num < num_init_ops; cmd_num++) {
550fe56b9e6SYuval Mintz 		union init_op *cmd = &init_ops[cmd_num];
551fe56b9e6SYuval Mintz 		u32 data = le32_to_cpu(cmd->raw.op_data);
552fe56b9e6SYuval Mintz 
553fe56b9e6SYuval Mintz 		switch (GET_FIELD(data, INIT_CALLBACK_OP_OP)) {
554fe56b9e6SYuval Mintz 		case INIT_OP_WRITE:
555fe56b9e6SYuval Mintz 			rc = qed_init_cmd_wr(p_hwfn, p_ptt, &cmd->write,
556fe56b9e6SYuval Mintz 					     b_dmae);
557fe56b9e6SYuval Mintz 			break;
558fe56b9e6SYuval Mintz 		case INIT_OP_READ:
559fe56b9e6SYuval Mintz 			qed_init_cmd_rd(p_hwfn, p_ptt, &cmd->read);
560fe56b9e6SYuval Mintz 			break;
561fe56b9e6SYuval Mintz 		case INIT_OP_IF_MODE:
562fe56b9e6SYuval Mintz 			cmd_num += qed_init_cmd_mode(p_hwfn, &cmd->if_mode,
563fe56b9e6SYuval Mintz 						     modes);
564fe56b9e6SYuval Mintz 			break;
565fe56b9e6SYuval Mintz 		case INIT_OP_IF_PHASE:
566fe56b9e6SYuval Mintz 			cmd_num += qed_init_cmd_phase(p_hwfn, &cmd->if_phase,
567fe56b9e6SYuval Mintz 						      phase, phase_id);
568fe56b9e6SYuval Mintz 			break;
569fe56b9e6SYuval Mintz 		case INIT_OP_DELAY:
570fe56b9e6SYuval Mintz 			/* qed_init_run is always invoked from
571fe56b9e6SYuval Mintz 			 * sleep-able context
572fe56b9e6SYuval Mintz 			 */
573fe56b9e6SYuval Mintz 			udelay(le32_to_cpu(cmd->delay.delay));
574fe56b9e6SYuval Mintz 			break;
575fe56b9e6SYuval Mintz 
576fe56b9e6SYuval Mintz 		case INIT_OP_CALLBACK:
577da090917STomer Tayar 			rc = qed_init_cmd_cb(p_hwfn, p_ptt, &cmd->callback);
5780500a70dSMichal Kalderon 			if (phase == PHASE_ENGINE &&
5790500a70dSMichal Kalderon 			    cmd->callback.callback_id == DMAE_READY_CB)
5800500a70dSMichal Kalderon 				b_dmae = true;
581fe56b9e6SYuval Mintz 			break;
582fe56b9e6SYuval Mintz 		}
583fe56b9e6SYuval Mintz 
584fe56b9e6SYuval Mintz 		if (rc)
585fe56b9e6SYuval Mintz 			break;
586fe56b9e6SYuval Mintz 	}
587fe56b9e6SYuval Mintz 
588fe56b9e6SYuval Mintz 	kfree(p_hwfn->unzip_buf);
5893587cb87STomer Tayar 	p_hwfn->unzip_buf = NULL;
590fe56b9e6SYuval Mintz 	return rc;
591fe56b9e6SYuval Mintz }
592fe56b9e6SYuval Mintz 
593fe56b9e6SYuval Mintz void qed_gtt_init(struct qed_hwfn *p_hwfn)
594fe56b9e6SYuval Mintz {
595fe56b9e6SYuval Mintz 	u32 gtt_base;
596fe56b9e6SYuval Mintz 	u32 i;
597fe56b9e6SYuval Mintz 
598fe56b9e6SYuval Mintz 	/* Set the global windows */
599fe56b9e6SYuval Mintz 	gtt_base = PXP_PF_WINDOW_ADMIN_START + PXP_PF_WINDOW_ADMIN_GLOBAL_START;
600fe56b9e6SYuval Mintz 
601fe56b9e6SYuval Mintz 	for (i = 0; i < ARRAY_SIZE(pxp_global_win); i++)
602fe56b9e6SYuval Mintz 		if (pxp_global_win[i])
603fe56b9e6SYuval Mintz 			REG_WR(p_hwfn, gtt_base + i * PXP_GLOBAL_ENTRY_SIZE,
604fe56b9e6SYuval Mintz 			       pxp_global_win[i]);
605fe56b9e6SYuval Mintz }
606fe56b9e6SYuval Mintz 
607351a4dedSYuval Mintz int qed_init_fw_data(struct qed_dev *cdev, const u8 *data)
608fe56b9e6SYuval Mintz {
609fe56b9e6SYuval Mintz 	struct qed_fw_data *fw = cdev->fw_data;
610fe56b9e6SYuval Mintz 	struct bin_buffer_hdr *buf_hdr;
611fe56b9e6SYuval Mintz 	u32 offset, len;
612fe56b9e6SYuval Mintz 
613fe56b9e6SYuval Mintz 	if (!data) {
614fe56b9e6SYuval Mintz 		DP_NOTICE(cdev, "Invalid fw data\n");
615fe56b9e6SYuval Mintz 		return -EINVAL;
616fe56b9e6SYuval Mintz 	}
617fe56b9e6SYuval Mintz 
618351a4dedSYuval Mintz 	/* First Dword contains metadata and should be skipped */
619be086e7cSMintz, Yuval 	buf_hdr = (struct bin_buffer_hdr *)data;
620351a4dedSYuval Mintz 
62105fafbfbSYuval Mintz 	offset = buf_hdr[BIN_BUF_INIT_FW_VER_INFO].offset;
622351a4dedSYuval Mintz 	fw->fw_ver_info = (struct fw_ver_info *)(data + offset);
623fe56b9e6SYuval Mintz 
624fe56b9e6SYuval Mintz 	offset = buf_hdr[BIN_BUF_INIT_CMD].offset;
625fe56b9e6SYuval Mintz 	fw->init_ops = (union init_op *)(data + offset);
626fe56b9e6SYuval Mintz 
627fe56b9e6SYuval Mintz 	offset = buf_hdr[BIN_BUF_INIT_VAL].offset;
628fe56b9e6SYuval Mintz 	fw->arr_data = (u32 *)(data + offset);
629fe56b9e6SYuval Mintz 
630fe56b9e6SYuval Mintz 	offset = buf_hdr[BIN_BUF_INIT_MODE_TREE].offset;
631fe56b9e6SYuval Mintz 	fw->modes_tree_buf = (u8 *)(data + offset);
632fe56b9e6SYuval Mintz 	len = buf_hdr[BIN_BUF_INIT_CMD].length;
633fe56b9e6SYuval Mintz 	fw->init_ops_size = len / sizeof(struct init_raw_op);
634fe56b9e6SYuval Mintz 
63530d5f858SMichal Kalderon 	offset = buf_hdr[BIN_BUF_INIT_OVERLAYS].offset;
63630d5f858SMichal Kalderon 	fw->fw_overlays = (u32 *)(data + offset);
63730d5f858SMichal Kalderon 	len = buf_hdr[BIN_BUF_INIT_OVERLAYS].length;
63830d5f858SMichal Kalderon 	fw->fw_overlays_len = len;
63930d5f858SMichal Kalderon 
640fe56b9e6SYuval Mintz 	return 0;
641fe56b9e6SYuval Mintz }
642