Linux Audio

Check our new training course

Loading...
v6.13.7
  1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
  2/* QLogic qed NIC Driver
  3 * Copyright (c) 2015-2017  QLogic Corporation
  4 * Copyright (c) 2019-2020 Marvell International Ltd.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  5 */
  6
  7#include <linux/types.h>
  8#include <linux/io.h>
  9#include <linux/delay.h>
 10#include <linux/errno.h>
 11#include <linux/kernel.h>
 12#include <linux/slab.h>
 13#include <linux/string.h>
 14#include "qed.h"
 15#include "qed_hsi.h"
 16#include "qed_hw.h"
 17#include "qed_init_ops.h"
 18#include "qed_iro_hsi.h"
 19#include "qed_reg_addr.h"
 20#include "qed_sriov.h"
 21
 22#define QED_INIT_MAX_POLL_COUNT 100
 23#define QED_INIT_POLL_PERIOD_US 500
 24
 25static u32 pxp_global_win[] = {
 26	0,
 27	0,
 28	0x1c02, /* win 2: addr=0x1c02000, size=4096 bytes */
 29	0x1c80, /* win 3: addr=0x1c80000, size=4096 bytes */
 30	0x1d00, /* win 4: addr=0x1d00000, size=4096 bytes */
 31	0x1d01, /* win 5: addr=0x1d01000, size=4096 bytes */
 32	0x1d02, /* win 6: addr=0x1d02000, size=4096 bytes */
 33	0x1d80, /* win 7: addr=0x1d80000, size=4096 bytes */
 34	0x1d81, /* win 8: addr=0x1d81000, size=4096 bytes */
 35	0x1d82, /* win 9: addr=0x1d82000, size=4096 bytes */
 36	0x1e00, /* win 10: addr=0x1e00000, size=4096 bytes */
 37	0x1e01, /* win 11: addr=0x1e01000, size=4096 bytes */
 38	0x1e80, /* win 12: addr=0x1e80000, size=4096 bytes */
 39	0x1f00, /* win 13: addr=0x1f00000, size=4096 bytes */
 40	0x1c08, /* win 14: addr=0x1c08000, size=4096 bytes */
 41	0,
 42	0,
 43	0,
 44	0,
 45};
 46
 47/* IRO Array */
 48static const u32 iro_arr[] = {
 49	0x00000000, 0x00000000, 0x00080000,
 50	0x00004478, 0x00000008, 0x00080000,
 51	0x00003288, 0x00000088, 0x00880000,
 52	0x000058a8, 0x00000020, 0x00200000,
 53	0x00003188, 0x00000008, 0x00080000,
 54	0x00000b00, 0x00000008, 0x00040000,
 55	0x00000a80, 0x00000008, 0x00040000,
 56	0x00000000, 0x00000008, 0x00020000,
 57	0x00000080, 0x00000008, 0x00040000,
 58	0x00000084, 0x00000008, 0x00020000,
 59	0x00005798, 0x00000004, 0x00040000,
 60	0x00004e50, 0x00000000, 0x00780000,
 61	0x00003e40, 0x00000000, 0x00780000,
 62	0x00004500, 0x00000000, 0x00780000,
 63	0x00003210, 0x00000000, 0x00780000,
 64	0x00003b50, 0x00000000, 0x00780000,
 65	0x00007f58, 0x00000000, 0x00780000,
 66	0x00005fd8, 0x00000000, 0x00080000,
 67	0x00007100, 0x00000000, 0x00080000,
 68	0x0000af20, 0x00000000, 0x00080000,
 69	0x00004398, 0x00000000, 0x00080000,
 70	0x0000a5a0, 0x00000000, 0x00080000,
 71	0x0000bde8, 0x00000000, 0x00080000,
 72	0x00000020, 0x00000004, 0x00040000,
 73	0x00005688, 0x00000010, 0x00100000,
 74	0x0000c210, 0x00000030, 0x00300000,
 75	0x0000b108, 0x00000038, 0x00380000,
 76	0x00003d20, 0x00000080, 0x00400000,
 77	0x0000bf60, 0x00000000, 0x00040000,
 78	0x00004560, 0x00040080, 0x00040000,
 79	0x000001f8, 0x00000004, 0x00040000,
 80	0x00003d60, 0x00000080, 0x00200000,
 81	0x00008960, 0x00000040, 0x00300000,
 82	0x0000e840, 0x00000060, 0x00600000,
 83	0x00004698, 0x00000080, 0x00380000,
 84	0x000107b8, 0x000000c0, 0x00c00000,
 85	0x000001f8, 0x00000002, 0x00020000,
 86	0x0000a260, 0x00000000, 0x01080000,
 87	0x0000a368, 0x00000008, 0x00080000,
 88	0x000001c0, 0x00000008, 0x00080000,
 89	0x000001f8, 0x00000008, 0x00080000,
 90	0x00000ac0, 0x00000008, 0x00080000,
 91	0x00002578, 0x00000008, 0x00080000,
 92	0x000024f8, 0x00000008, 0x00080000,
 93	0x00000280, 0x00000008, 0x00080000,
 94	0x00000680, 0x00080018, 0x00080000,
 95	0x00000b78, 0x00080018, 0x00020000,
 96	0x0000c600, 0x00000058, 0x003c0000,
 97	0x00012038, 0x00000020, 0x00100000,
 98	0x00011b00, 0x00000048, 0x00180000,
 99	0x00009650, 0x00000050, 0x00200000,
100	0x00008b10, 0x00000040, 0x00280000,
101	0x000116c0, 0x00000018, 0x00100000,
102	0x0000c808, 0x00000048, 0x00380000,
103	0x00011790, 0x00000020, 0x00200000,
104	0x000046d0, 0x00000080, 0x00100000,
105	0x00003618, 0x00000010, 0x00100000,
106	0x0000a9e8, 0x00000008, 0x00010000,
107	0x000097a0, 0x00000008, 0x00010000,
108	0x00011a10, 0x00000008, 0x00010000,
109	0x0000e9f8, 0x00000008, 0x00010000,
110	0x00012648, 0x00000008, 0x00010000,
111	0x000121c8, 0x00000008, 0x00010000,
112	0x0000af08, 0x00000030, 0x00100000,
113	0x0000d748, 0x00000028, 0x00280000,
114	0x00009e68, 0x00000018, 0x00180000,
115	0x00009fe8, 0x00000008, 0x00080000,
116	0x00013ea8, 0x00000008, 0x00080000,
117	0x00012f18, 0x00000018, 0x00180000,
118	0x0000dfe8, 0x00500288, 0x00100000,
119	0x000131a0, 0x00000138, 0x00280000,
120};
121
122void qed_init_iro_array(struct qed_dev *cdev)
123{
124	cdev->iro_arr = iro_arr + E4_IRO_ARR_OFFSET;
125}
126
127void qed_init_store_rt_reg(struct qed_hwfn *p_hwfn, u32 rt_offset, u32 val)
 
128{
129	if (rt_offset >= RUNTIME_ARRAY_SIZE) {
130		DP_ERR(p_hwfn,
131		       "Avoid storing %u in rt_data at index %u!\n",
132		       val, rt_offset);
133		return;
134	}
135
 
 
 
 
 
 
136	p_hwfn->rt_data.init_val[rt_offset] = val;
137	p_hwfn->rt_data.b_valid[rt_offset] = true;
138}
139
140void qed_init_store_rt_agg(struct qed_hwfn *p_hwfn,
141			   u32 rt_offset, u32 *p_val, size_t size)
142{
143	size_t i;
144
145	if ((rt_offset + size - 1) >= RUNTIME_ARRAY_SIZE) {
146		DP_ERR(p_hwfn,
147		       "Avoid storing values in rt_data at indices %u-%u!\n",
148		       rt_offset,
149		       (u32)(rt_offset + size - 1));
150		return;
151	}
152
153	for (i = 0; i < size / sizeof(u32); i++) {
154		p_hwfn->rt_data.init_val[rt_offset + i] = p_val[i];
155		p_hwfn->rt_data.b_valid[rt_offset + i]	= true;
156	}
157}
158
159static int qed_init_rt(struct qed_hwfn	*p_hwfn,
160		       struct qed_ptt *p_ptt,
161		       u32 addr, u16 rt_offset, u16 size, bool b_must_dmae)
162{
163	u32 *p_init_val = &p_hwfn->rt_data.init_val[rt_offset];
164	bool *p_valid = &p_hwfn->rt_data.b_valid[rt_offset];
165	u16 i, j, segment;
166	int rc = 0;
167
168	/* Since not all RT entries are initialized, go over the RT and
169	 * for each segment of initialized values use DMA.
170	 */
171	for (i = 0; i < size; i++) {
172		if (!p_valid[i])
173			continue;
174
175		/* In case there isn't any wide-bus configuration here,
176		 * simply write the data instead of using dmae.
177		 */
178		if (!b_must_dmae) {
179			qed_wr(p_hwfn, p_ptt, addr + (i << 2), p_init_val[i]);
180			p_valid[i] = false;
181			continue;
182		}
183
184		/* Start of a new segment */
185		for (segment = 1; i + segment < size; segment++)
186			if (!p_valid[i + segment])
187				break;
188
189		rc = qed_dmae_host2grc(p_hwfn, p_ptt,
190				       (uintptr_t)(p_init_val + i),
191				       addr + (i << 2), segment, NULL);
192		if (rc)
193			return rc;
194
195		/* invalidate after writing */
196		for (j = i; j < (u32)(i + segment); j++)
197			p_valid[j] = false;
198
199		/* Jump over the entire segment, including invalid entry */
200		i += segment;
201	}
202
203	return rc;
204}
205
206int qed_init_alloc(struct qed_hwfn *p_hwfn)
207{
208	struct qed_rt_data *rt_data = &p_hwfn->rt_data;
209
210	if (IS_VF(p_hwfn->cdev))
211		return 0;
212
213	rt_data->b_valid = kcalloc(RUNTIME_ARRAY_SIZE, sizeof(bool),
214				   GFP_KERNEL);
215	if (!rt_data->b_valid)
216		return -ENOMEM;
217
218	rt_data->init_val = kcalloc(RUNTIME_ARRAY_SIZE, sizeof(u32),
219				    GFP_KERNEL);
220	if (!rt_data->init_val) {
221		kfree(rt_data->b_valid);
222		rt_data->b_valid = NULL;
223		return -ENOMEM;
224	}
225
226	return 0;
227}
228
229void qed_init_free(struct qed_hwfn *p_hwfn)
230{
231	kfree(p_hwfn->rt_data.init_val);
232	p_hwfn->rt_data.init_val = NULL;
233	kfree(p_hwfn->rt_data.b_valid);
234	p_hwfn->rt_data.b_valid = NULL;
235}
236
237static int qed_init_array_dmae(struct qed_hwfn *p_hwfn,
238			       struct qed_ptt *p_ptt,
239			       u32 addr,
240			       u32 dmae_data_offset,
241			       u32 size,
242			       const u32 *buf,
243			       bool b_must_dmae,
244			       bool b_can_dmae)
245{
246	int rc = 0;
247
248	/* Perform DMAE only for lengthy enough sections or for wide-bus */
249	if (!b_can_dmae || (!b_must_dmae && (size < 16))) {
250		const u32 *data = buf + dmae_data_offset;
251		u32 i;
252
253		for (i = 0; i < size; i++)
254			qed_wr(p_hwfn, p_ptt, addr + (i << 2), data[i]);
255	} else {
256		rc = qed_dmae_host2grc(p_hwfn, p_ptt,
257				       (uintptr_t)(buf + dmae_data_offset),
258				       addr, size, NULL);
259	}
260
261	return rc;
262}
263
264static int qed_init_fill_dmae(struct qed_hwfn *p_hwfn,
265			      struct qed_ptt *p_ptt,
266			      u32 addr, u32 fill_count)
267{
268	static u32 zero_buffer[DMAE_MAX_RW_SIZE];
269	struct qed_dmae_params params = {};
270
271	memset(zero_buffer, 0, sizeof(u32) * DMAE_MAX_RW_SIZE);
272
273	/* invoke the DMAE virtual/physical buffer API with
274	 * 1. DMAE init channel
275	 * 2. addr,
276	 * 3. p_hwfb->temp_data,
277	 * 4. fill_count
278	 */
279	SET_FIELD(params.flags, QED_DMAE_PARAMS_RW_REPL_SRC, 0x1);
280	return qed_dmae_host2grc(p_hwfn, p_ptt,
281				 (uintptr_t)(&zero_buffer[0]),
282				 addr, fill_count, &params);
283}
284
285static void qed_init_fill(struct qed_hwfn *p_hwfn,
286			  struct qed_ptt *p_ptt,
287			  u32 addr, u32 fill, u32 fill_count)
288{
289	u32 i;
290
291	for (i = 0; i < fill_count; i++, addr += sizeof(u32))
292		qed_wr(p_hwfn, p_ptt, addr, fill);
293}
294
295static int qed_init_cmd_array(struct qed_hwfn *p_hwfn,
296			      struct qed_ptt *p_ptt,
297			      struct init_write_op *cmd,
298			      bool b_must_dmae, bool b_can_dmae)
299{
300	u32 dmae_array_offset = le32_to_cpu(cmd->args.array_offset);
301	u32 data = le32_to_cpu(cmd->data);
302	u32 addr = GET_FIELD(data, INIT_WRITE_OP_ADDRESS) << 2;
303
304	u32 offset, output_len, input_len, max_size;
305	struct qed_dev *cdev = p_hwfn->cdev;
306	union init_array_hdr *hdr;
307	const u32 *array_data;
308	int rc = 0;
309	u32 size;
310
311	array_data = cdev->fw_data->arr_data;
312
313	hdr = (union init_array_hdr *)(array_data + dmae_array_offset);
314	data = le32_to_cpu(hdr->raw.data);
315	switch (GET_FIELD(data, INIT_ARRAY_RAW_HDR_TYPE)) {
316	case INIT_ARR_ZIPPED:
317		offset = dmae_array_offset + 1;
318		input_len = GET_FIELD(data,
319				      INIT_ARRAY_ZIPPED_HDR_ZIPPED_SIZE);
320		max_size = MAX_ZIPPED_SIZE * 4;
321		memset(p_hwfn->unzip_buf, 0, max_size);
322
323		output_len = qed_unzip_data(p_hwfn, input_len,
324					    (u8 *)&array_data[offset],
325					    max_size, (u8 *)p_hwfn->unzip_buf);
326		if (output_len) {
327			rc = qed_init_array_dmae(p_hwfn, p_ptt, addr, 0,
328						 output_len,
329						 p_hwfn->unzip_buf,
330						 b_must_dmae, b_can_dmae);
331		} else {
332			DP_NOTICE(p_hwfn, "Failed to unzip dmae data\n");
333			rc = -EINVAL;
334		}
335		break;
336	case INIT_ARR_PATTERN:
337	{
338		u32 repeats = GET_FIELD(data,
339					INIT_ARRAY_PATTERN_HDR_REPETITIONS);
340		u32 i;
341
342		size = GET_FIELD(data, INIT_ARRAY_PATTERN_HDR_PATTERN_SIZE);
343
344		for (i = 0; i < repeats; i++, addr += size << 2) {
345			rc = qed_init_array_dmae(p_hwfn, p_ptt, addr,
346						 dmae_array_offset + 1,
347						 size, array_data,
348						 b_must_dmae, b_can_dmae);
349			if (rc)
350				break;
351		}
352		break;
353	}
354	case INIT_ARR_STANDARD:
355		size = GET_FIELD(data, INIT_ARRAY_STANDARD_HDR_SIZE);
356		rc = qed_init_array_dmae(p_hwfn, p_ptt, addr,
357					 dmae_array_offset + 1,
358					 size, array_data,
359					 b_must_dmae, b_can_dmae);
360		break;
361	}
362
363	return rc;
364}
365
366/* init_ops write command */
367static int qed_init_cmd_wr(struct qed_hwfn *p_hwfn,
368			   struct qed_ptt *p_ptt,
369			   struct init_write_op *p_cmd, bool b_can_dmae)
370{
371	u32 data = le32_to_cpu(p_cmd->data);
372	bool b_must_dmae = GET_FIELD(data, INIT_WRITE_OP_WIDE_BUS);
373	u32 addr = GET_FIELD(data, INIT_WRITE_OP_ADDRESS) << 2;
374	union init_write_args *arg = &p_cmd->args;
375	int rc = 0;
376
377	/* Sanitize */
378	if (b_must_dmae && !b_can_dmae) {
379		DP_NOTICE(p_hwfn,
380			  "Need to write to %08x for Wide-bus but DMAE isn't allowed\n",
381			  addr);
382		return -EINVAL;
383	}
384
385	switch (GET_FIELD(data, INIT_WRITE_OP_SOURCE)) {
386	case INIT_SRC_INLINE:
387		data = le32_to_cpu(p_cmd->args.inline_val);
388		qed_wr(p_hwfn, p_ptt, addr, data);
389		break;
390	case INIT_SRC_ZEROS:
391		data = le32_to_cpu(p_cmd->args.zeros_count);
392		if (b_must_dmae || (b_can_dmae && (data >= 64)))
393			rc = qed_init_fill_dmae(p_hwfn, p_ptt, addr, data);
394		else
395			qed_init_fill(p_hwfn, p_ptt, addr, 0, data);
396		break;
397	case INIT_SRC_ARRAY:
398		rc = qed_init_cmd_array(p_hwfn, p_ptt, p_cmd,
399					b_must_dmae, b_can_dmae);
400		break;
401	case INIT_SRC_RUNTIME:
402		qed_init_rt(p_hwfn, p_ptt, addr,
403			    le16_to_cpu(arg->runtime.offset),
404			    le16_to_cpu(arg->runtime.size),
405			    b_must_dmae);
406		break;
407	}
408
409	return rc;
410}
411
412static inline bool comp_eq(u32 val, u32 expected_val)
413{
414	return val == expected_val;
415}
416
417static inline bool comp_and(u32 val, u32 expected_val)
418{
419	return (val & expected_val) == expected_val;
420}
421
422static inline bool comp_or(u32 val, u32 expected_val)
423{
424	return (val | expected_val) > 0;
425}
426
427/* init_ops read/poll commands */
428static void qed_init_cmd_rd(struct qed_hwfn *p_hwfn,
429			    struct qed_ptt *p_ptt, struct init_read_op *cmd)
430{
431	bool (*comp_check)(u32 val, u32 expected_val);
432	u32 delay = QED_INIT_POLL_PERIOD_US, val;
433	u32 data, addr, poll;
434	int i;
435
436	data = le32_to_cpu(cmd->op_data);
437	addr = GET_FIELD(data, INIT_READ_OP_ADDRESS) << 2;
438	poll = GET_FIELD(data, INIT_READ_OP_POLL_TYPE);
439
 
440	val = qed_rd(p_hwfn, p_ptt, addr);
441
442	if (poll == INIT_POLL_NONE)
443		return;
444
445	switch (poll) {
446	case INIT_POLL_EQ:
447		comp_check = comp_eq;
448		break;
449	case INIT_POLL_OR:
450		comp_check = comp_or;
451		break;
452	case INIT_POLL_AND:
453		comp_check = comp_and;
454		break;
455	default:
456		DP_ERR(p_hwfn, "Invalid poll comparison type %08x\n",
457		       cmd->op_data);
458		return;
459	}
460
461	data = le32_to_cpu(cmd->expected_val);
462	for (i = 0;
463	     i < QED_INIT_MAX_POLL_COUNT && !comp_check(val, data);
464	     i++) {
465		udelay(delay);
466		val = qed_rd(p_hwfn, p_ptt, addr);
467	}
468
469	if (i == QED_INIT_MAX_POLL_COUNT) {
470		DP_ERR(p_hwfn,
471		       "Timeout when polling reg: 0x%08x [ Waiting-for: %08x Got: %08x (comparison %08x)]\n",
472		       addr, le32_to_cpu(cmd->expected_val),
473		       val, le32_to_cpu(cmd->op_data));
474	}
475}
476
477/* init_ops callbacks entry point */
478static int qed_init_cmd_cb(struct qed_hwfn *p_hwfn,
479			   struct qed_ptt *p_ptt,
480			   struct init_callback_op *p_cmd)
481{
482	int rc;
483
484	switch (p_cmd->callback_id) {
485	case DMAE_READY_CB:
486		rc = qed_dmae_sanity(p_hwfn, p_ptt, "engine_phase");
487		break;
488	default:
489		DP_NOTICE(p_hwfn, "Unexpected init op callback ID %d\n",
490			  p_cmd->callback_id);
491		return -EINVAL;
492	}
493
494	return rc;
495}
496
497static u8 qed_init_cmd_mode_match(struct qed_hwfn *p_hwfn,
498				  u16 *p_offset, int modes)
499{
500	struct qed_dev *cdev = p_hwfn->cdev;
501	const u8 *modes_tree_buf;
502	u8 arg1, arg2, tree_val;
503
504	modes_tree_buf = cdev->fw_data->modes_tree_buf;
505	tree_val = modes_tree_buf[(*p_offset)++];
506	switch (tree_val) {
507	case INIT_MODE_OP_NOT:
508		return qed_init_cmd_mode_match(p_hwfn, p_offset, modes) ^ 1;
509	case INIT_MODE_OP_OR:
510		arg1 = qed_init_cmd_mode_match(p_hwfn, p_offset, modes);
511		arg2 = qed_init_cmd_mode_match(p_hwfn, p_offset, modes);
512		return arg1 | arg2;
513	case INIT_MODE_OP_AND:
514		arg1 = qed_init_cmd_mode_match(p_hwfn, p_offset, modes);
515		arg2 = qed_init_cmd_mode_match(p_hwfn, p_offset, modes);
516		return arg1 & arg2;
517	default:
518		tree_val -= MAX_INIT_MODE_OPS;
519		return (modes & BIT(tree_val)) ? 1 : 0;
520	}
521}
522
523static u32 qed_init_cmd_mode(struct qed_hwfn *p_hwfn,
524			     struct init_if_mode_op *p_cmd, int modes)
525{
526	u16 offset = le16_to_cpu(p_cmd->modes_buf_offset);
527
528	if (qed_init_cmd_mode_match(p_hwfn, &offset, modes))
529		return 0;
530	else
531		return GET_FIELD(le32_to_cpu(p_cmd->op_data),
532				 INIT_IF_MODE_OP_CMD_OFFSET);
533}
534
535static u32 qed_init_cmd_phase(struct init_if_phase_op *p_cmd,
 
536			      u32 phase, u32 phase_id)
537{
538	u32 data = le32_to_cpu(p_cmd->phase_data);
539	u32 op_data = le32_to_cpu(p_cmd->op_data);
540
541	if (!(GET_FIELD(data, INIT_IF_PHASE_OP_PHASE) == phase &&
542	      (GET_FIELD(data, INIT_IF_PHASE_OP_PHASE_ID) == ANY_PHASE_ID ||
543	       GET_FIELD(data, INIT_IF_PHASE_OP_PHASE_ID) == phase_id)))
544		return GET_FIELD(op_data, INIT_IF_PHASE_OP_CMD_OFFSET);
545	else
546		return 0;
547}
548
549int qed_init_run(struct qed_hwfn *p_hwfn,
550		 struct qed_ptt *p_ptt, int phase, int phase_id, int modes)
551{
552	bool b_dmae = (phase != PHASE_ENGINE);
553	struct qed_dev *cdev = p_hwfn->cdev;
554	u32 cmd_num, num_init_ops;
555	union init_op *init_ops;
 
556	int rc = 0;
557
558	num_init_ops = cdev->fw_data->init_ops_size;
559	init_ops = cdev->fw_data->init_ops;
560
561	p_hwfn->unzip_buf = kzalloc(MAX_ZIPPED_SIZE * 4, GFP_ATOMIC);
562	if (!p_hwfn->unzip_buf)
563		return -ENOMEM;
564
565	for (cmd_num = 0; cmd_num < num_init_ops; cmd_num++) {
566		union init_op *cmd = &init_ops[cmd_num];
567		u32 data = le32_to_cpu(cmd->raw.op_data);
568
569		switch (GET_FIELD(data, INIT_CALLBACK_OP_OP)) {
570		case INIT_OP_WRITE:
571			rc = qed_init_cmd_wr(p_hwfn, p_ptt, &cmd->write,
572					     b_dmae);
573			break;
574		case INIT_OP_READ:
575			qed_init_cmd_rd(p_hwfn, p_ptt, &cmd->read);
576			break;
577		case INIT_OP_IF_MODE:
578			cmd_num += qed_init_cmd_mode(p_hwfn, &cmd->if_mode,
579						     modes);
580			break;
581		case INIT_OP_IF_PHASE:
582			cmd_num += qed_init_cmd_phase(&cmd->if_phase,
583						      phase, phase_id);
 
584			break;
585		case INIT_OP_DELAY:
586			/* qed_init_run is always invoked from
587			 * sleep-able context
588			 */
589			udelay(le32_to_cpu(cmd->delay.delay));
590			break;
591
592		case INIT_OP_CALLBACK:
593			rc = qed_init_cmd_cb(p_hwfn, p_ptt, &cmd->callback);
594			if (phase == PHASE_ENGINE &&
595			    cmd->callback.callback_id == DMAE_READY_CB)
596				b_dmae = true;
597			break;
598		}
599
600		if (rc)
601			break;
602	}
603
604	kfree(p_hwfn->unzip_buf);
605	p_hwfn->unzip_buf = NULL;
606	return rc;
607}
608
609void qed_gtt_init(struct qed_hwfn *p_hwfn)
610{
611	u32 gtt_base;
612	u32 i;
613
614	/* Set the global windows */
615	gtt_base = PXP_PF_WINDOW_ADMIN_START + PXP_PF_WINDOW_ADMIN_GLOBAL_START;
616
617	for (i = 0; i < ARRAY_SIZE(pxp_global_win); i++)
618		if (pxp_global_win[i])
619			REG_WR(p_hwfn, gtt_base + i * PXP_GLOBAL_ENTRY_SIZE,
620			       pxp_global_win[i]);
621}
622
623int qed_init_fw_data(struct qed_dev *cdev, const u8 *data)
624{
625	struct qed_fw_data *fw = cdev->fw_data;
626	struct bin_buffer_hdr *buf_hdr;
627	u32 offset, len;
628
629	if (!data) {
630		DP_NOTICE(cdev, "Invalid fw data\n");
631		return -EINVAL;
632	}
633
634	/* First Dword contains metadata and should be skipped */
635	buf_hdr = (struct bin_buffer_hdr *)data;
636
637	offset = buf_hdr[BIN_BUF_INIT_FW_VER_INFO].offset;
638	fw->fw_ver_info = (struct fw_ver_info *)(data + offset);
639
640	offset = buf_hdr[BIN_BUF_INIT_CMD].offset;
641	fw->init_ops = (union init_op *)(data + offset);
642
643	offset = buf_hdr[BIN_BUF_INIT_VAL].offset;
644	fw->arr_data = (u32 *)(data + offset);
645
646	offset = buf_hdr[BIN_BUF_INIT_MODE_TREE].offset;
647	fw->modes_tree_buf = (u8 *)(data + offset);
648	len = buf_hdr[BIN_BUF_INIT_CMD].length;
649	fw->init_ops_size = len / sizeof(struct init_raw_op);
650
651	offset = buf_hdr[BIN_BUF_INIT_OVERLAYS].offset;
652	fw->fw_overlays = (u32 *)(data + offset);
653	len = buf_hdr[BIN_BUF_INIT_OVERLAYS].length;
654	fw->fw_overlays_len = len;
655
656	return 0;
657}
v5.4
 
  1/* QLogic qed NIC Driver
  2 * Copyright (c) 2015-2017  QLogic Corporation
  3 *
  4 * This software is available to you under a choice of one of two
  5 * licenses.  You may choose to be licensed under the terms of the GNU
  6 * General Public License (GPL) Version 2, available from the file
  7 * COPYING in the main directory of this source tree, or the
  8 * OpenIB.org BSD license below:
  9 *
 10 *     Redistribution and use in source and binary forms, with or
 11 *     without modification, are permitted provided that the following
 12 *     conditions are met:
 13 *
 14 *      - Redistributions of source code must retain the above
 15 *        copyright notice, this list of conditions and the following
 16 *        disclaimer.
 17 *
 18 *      - Redistributions in binary form must reproduce the above
 19 *        copyright notice, this list of conditions and the following
 20 *        disclaimer in the documentation and /or other materials
 21 *        provided with the distribution.
 22 *
 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 30 * SOFTWARE.
 31 */
 32
 33#include <linux/types.h>
 34#include <linux/io.h>
 35#include <linux/delay.h>
 36#include <linux/errno.h>
 37#include <linux/kernel.h>
 38#include <linux/slab.h>
 39#include <linux/string.h>
 40#include "qed.h"
 41#include "qed_hsi.h"
 42#include "qed_hw.h"
 43#include "qed_init_ops.h"
 
 44#include "qed_reg_addr.h"
 45#include "qed_sriov.h"
 46
 47#define QED_INIT_MAX_POLL_COUNT 100
 48#define QED_INIT_POLL_PERIOD_US 500
 49
 50static u32 pxp_global_win[] = {
 51	0,
 52	0,
 53	0x1c02, /* win 2: addr=0x1c02000, size=4096 bytes */
 54	0x1c80, /* win 3: addr=0x1c80000, size=4096 bytes */
 55	0x1d00, /* win 4: addr=0x1d00000, size=4096 bytes */
 56	0x1d01, /* win 5: addr=0x1d01000, size=4096 bytes */
 57	0x1d80, /* win 6: addr=0x1d80000, size=4096 bytes */
 58	0x1d81, /* win 7: addr=0x1d81000, size=4096 bytes */
 59	0x1d82, /* win 8: addr=0x1d82000, size=4096 bytes */
 60	0x1e00, /* win 9: addr=0x1e00000, size=4096 bytes */
 61	0x1e80, /* win 10: addr=0x1e80000, size=4096 bytes */
 62	0x1f00, /* win 11: addr=0x1f00000, size=4096 bytes */
 63	0,
 64	0,
 65	0,
 66	0,
 67	0,
 68	0,
 69	0,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 70};
 71
 72void qed_init_iro_array(struct qed_dev *cdev)
 73{
 74	cdev->iro_arr = iro_arr;
 75}
 76
 77/* Runtime configuration helpers */
 78void qed_init_clear_rt_data(struct qed_hwfn *p_hwfn)
 79{
 80	int i;
 
 
 
 
 
 81
 82	for (i = 0; i < RUNTIME_ARRAY_SIZE; i++)
 83		p_hwfn->rt_data.b_valid[i] = false;
 84}
 85
 86void qed_init_store_rt_reg(struct qed_hwfn *p_hwfn, u32 rt_offset, u32 val)
 87{
 88	p_hwfn->rt_data.init_val[rt_offset] = val;
 89	p_hwfn->rt_data.b_valid[rt_offset] = true;
 90}
 91
 92void qed_init_store_rt_agg(struct qed_hwfn *p_hwfn,
 93			   u32 rt_offset, u32 *p_val, size_t size)
 94{
 95	size_t i;
 96
 
 
 
 
 
 
 
 
 97	for (i = 0; i < size / sizeof(u32); i++) {
 98		p_hwfn->rt_data.init_val[rt_offset + i] = p_val[i];
 99		p_hwfn->rt_data.b_valid[rt_offset + i]	= true;
100	}
101}
102
103static int qed_init_rt(struct qed_hwfn	*p_hwfn,
104		       struct qed_ptt *p_ptt,
105		       u32 addr, u16 rt_offset, u16 size, bool b_must_dmae)
106{
107	u32 *p_init_val = &p_hwfn->rt_data.init_val[rt_offset];
108	bool *p_valid = &p_hwfn->rt_data.b_valid[rt_offset];
109	u16 i, segment;
110	int rc = 0;
111
112	/* Since not all RT entries are initialized, go over the RT and
113	 * for each segment of initialized values use DMA.
114	 */
115	for (i = 0; i < size; i++) {
116		if (!p_valid[i])
117			continue;
118
119		/* In case there isn't any wide-bus configuration here,
120		 * simply write the data instead of using dmae.
121		 */
122		if (!b_must_dmae) {
123			qed_wr(p_hwfn, p_ptt, addr + (i << 2), p_init_val[i]);
 
124			continue;
125		}
126
127		/* Start of a new segment */
128		for (segment = 1; i + segment < size; segment++)
129			if (!p_valid[i + segment])
130				break;
131
132		rc = qed_dmae_host2grc(p_hwfn, p_ptt,
133				       (uintptr_t)(p_init_val + i),
134				       addr + (i << 2), segment, NULL);
135		if (rc)
136			return rc;
137
 
 
 
 
138		/* Jump over the entire segment, including invalid entry */
139		i += segment;
140	}
141
142	return rc;
143}
144
145int qed_init_alloc(struct qed_hwfn *p_hwfn)
146{
147	struct qed_rt_data *rt_data = &p_hwfn->rt_data;
148
149	if (IS_VF(p_hwfn->cdev))
150		return 0;
151
152	rt_data->b_valid = kcalloc(RUNTIME_ARRAY_SIZE, sizeof(bool),
153				   GFP_KERNEL);
154	if (!rt_data->b_valid)
155		return -ENOMEM;
156
157	rt_data->init_val = kcalloc(RUNTIME_ARRAY_SIZE, sizeof(u32),
158				    GFP_KERNEL);
159	if (!rt_data->init_val) {
160		kfree(rt_data->b_valid);
161		rt_data->b_valid = NULL;
162		return -ENOMEM;
163	}
164
165	return 0;
166}
167
168void qed_init_free(struct qed_hwfn *p_hwfn)
169{
170	kfree(p_hwfn->rt_data.init_val);
171	p_hwfn->rt_data.init_val = NULL;
172	kfree(p_hwfn->rt_data.b_valid);
173	p_hwfn->rt_data.b_valid = NULL;
174}
175
176static int qed_init_array_dmae(struct qed_hwfn *p_hwfn,
177			       struct qed_ptt *p_ptt,
178			       u32 addr,
179			       u32 dmae_data_offset,
180			       u32 size,
181			       const u32 *buf,
182			       bool b_must_dmae,
183			       bool b_can_dmae)
184{
185	int rc = 0;
186
187	/* Perform DMAE only for lengthy enough sections or for wide-bus */
188	if (!b_can_dmae || (!b_must_dmae && (size < 16))) {
189		const u32 *data = buf + dmae_data_offset;
190		u32 i;
191
192		for (i = 0; i < size; i++)
193			qed_wr(p_hwfn, p_ptt, addr + (i << 2), data[i]);
194	} else {
195		rc = qed_dmae_host2grc(p_hwfn, p_ptt,
196				       (uintptr_t)(buf + dmae_data_offset),
197				       addr, size, NULL);
198	}
199
200	return rc;
201}
202
203static int qed_init_fill_dmae(struct qed_hwfn *p_hwfn,
204			      struct qed_ptt *p_ptt,
205			      u32 addr, u32 fill, u32 fill_count)
206{
207	static u32 zero_buffer[DMAE_MAX_RW_SIZE];
208	struct qed_dmae_params params = {};
209
210	memset(zero_buffer, 0, sizeof(u32) * DMAE_MAX_RW_SIZE);
211
212	/* invoke the DMAE virtual/physical buffer API with
213	 * 1. DMAE init channel
214	 * 2. addr,
215	 * 3. p_hwfb->temp_data,
216	 * 4. fill_count
217	 */
218	params.flags = QED_DMAE_FLAG_RW_REPL_SRC;
219	return qed_dmae_host2grc(p_hwfn, p_ptt,
220				 (uintptr_t)(&zero_buffer[0]),
221				 addr, fill_count, &params);
222}
223
224static void qed_init_fill(struct qed_hwfn *p_hwfn,
225			  struct qed_ptt *p_ptt,
226			  u32 addr, u32 fill, u32 fill_count)
227{
228	u32 i;
229
230	for (i = 0; i < fill_count; i++, addr += sizeof(u32))
231		qed_wr(p_hwfn, p_ptt, addr, fill);
232}
233
234static int qed_init_cmd_array(struct qed_hwfn *p_hwfn,
235			      struct qed_ptt *p_ptt,
236			      struct init_write_op *cmd,
237			      bool b_must_dmae, bool b_can_dmae)
238{
239	u32 dmae_array_offset = le32_to_cpu(cmd->args.array_offset);
240	u32 data = le32_to_cpu(cmd->data);
241	u32 addr = GET_FIELD(data, INIT_WRITE_OP_ADDRESS) << 2;
242
243	u32 offset, output_len, input_len, max_size;
244	struct qed_dev *cdev = p_hwfn->cdev;
245	union init_array_hdr *hdr;
246	const u32 *array_data;
247	int rc = 0;
248	u32 size;
249
250	array_data = cdev->fw_data->arr_data;
251
252	hdr = (union init_array_hdr *)(array_data + dmae_array_offset);
253	data = le32_to_cpu(hdr->raw.data);
254	switch (GET_FIELD(data, INIT_ARRAY_RAW_HDR_TYPE)) {
255	case INIT_ARR_ZIPPED:
256		offset = dmae_array_offset + 1;
257		input_len = GET_FIELD(data,
258				      INIT_ARRAY_ZIPPED_HDR_ZIPPED_SIZE);
259		max_size = MAX_ZIPPED_SIZE * 4;
260		memset(p_hwfn->unzip_buf, 0, max_size);
261
262		output_len = qed_unzip_data(p_hwfn, input_len,
263					    (u8 *)&array_data[offset],
264					    max_size, (u8 *)p_hwfn->unzip_buf);
265		if (output_len) {
266			rc = qed_init_array_dmae(p_hwfn, p_ptt, addr, 0,
267						 output_len,
268						 p_hwfn->unzip_buf,
269						 b_must_dmae, b_can_dmae);
270		} else {
271			DP_NOTICE(p_hwfn, "Failed to unzip dmae data\n");
272			rc = -EINVAL;
273		}
274		break;
275	case INIT_ARR_PATTERN:
276	{
277		u32 repeats = GET_FIELD(data,
278					INIT_ARRAY_PATTERN_HDR_REPETITIONS);
279		u32 i;
280
281		size = GET_FIELD(data, INIT_ARRAY_PATTERN_HDR_PATTERN_SIZE);
282
283		for (i = 0; i < repeats; i++, addr += size << 2) {
284			rc = qed_init_array_dmae(p_hwfn, p_ptt, addr,
285						 dmae_array_offset + 1,
286						 size, array_data,
287						 b_must_dmae, b_can_dmae);
288			if (rc)
289				break;
290		}
291		break;
292	}
293	case INIT_ARR_STANDARD:
294		size = GET_FIELD(data, INIT_ARRAY_STANDARD_HDR_SIZE);
295		rc = qed_init_array_dmae(p_hwfn, p_ptt, addr,
296					 dmae_array_offset + 1,
297					 size, array_data,
298					 b_must_dmae, b_can_dmae);
299		break;
300	}
301
302	return rc;
303}
304
305/* init_ops write command */
306static int qed_init_cmd_wr(struct qed_hwfn *p_hwfn,
307			   struct qed_ptt *p_ptt,
308			   struct init_write_op *p_cmd, bool b_can_dmae)
309{
310	u32 data = le32_to_cpu(p_cmd->data);
311	bool b_must_dmae = GET_FIELD(data, INIT_WRITE_OP_WIDE_BUS);
312	u32 addr = GET_FIELD(data, INIT_WRITE_OP_ADDRESS) << 2;
313	union init_write_args *arg = &p_cmd->args;
314	int rc = 0;
315
316	/* Sanitize */
317	if (b_must_dmae && !b_can_dmae) {
318		DP_NOTICE(p_hwfn,
319			  "Need to write to %08x for Wide-bus but DMAE isn't allowed\n",
320			  addr);
321		return -EINVAL;
322	}
323
324	switch (GET_FIELD(data, INIT_WRITE_OP_SOURCE)) {
325	case INIT_SRC_INLINE:
326		data = le32_to_cpu(p_cmd->args.inline_val);
327		qed_wr(p_hwfn, p_ptt, addr, data);
328		break;
329	case INIT_SRC_ZEROS:
330		data = le32_to_cpu(p_cmd->args.zeros_count);
331		if (b_must_dmae || (b_can_dmae && (data >= 64)))
332			rc = qed_init_fill_dmae(p_hwfn, p_ptt, addr, 0, data);
333		else
334			qed_init_fill(p_hwfn, p_ptt, addr, 0, data);
335		break;
336	case INIT_SRC_ARRAY:
337		rc = qed_init_cmd_array(p_hwfn, p_ptt, p_cmd,
338					b_must_dmae, b_can_dmae);
339		break;
340	case INIT_SRC_RUNTIME:
341		qed_init_rt(p_hwfn, p_ptt, addr,
342			    le16_to_cpu(arg->runtime.offset),
343			    le16_to_cpu(arg->runtime.size),
344			    b_must_dmae);
345		break;
346	}
347
348	return rc;
349}
350
351static inline bool comp_eq(u32 val, u32 expected_val)
352{
353	return val == expected_val;
354}
355
356static inline bool comp_and(u32 val, u32 expected_val)
357{
358	return (val & expected_val) == expected_val;
359}
360
361static inline bool comp_or(u32 val, u32 expected_val)
362{
363	return (val | expected_val) > 0;
364}
365
366/* init_ops read/poll commands */
367static void qed_init_cmd_rd(struct qed_hwfn *p_hwfn,
368			    struct qed_ptt *p_ptt, struct init_read_op *cmd)
369{
370	bool (*comp_check)(u32 val, u32 expected_val);
371	u32 delay = QED_INIT_POLL_PERIOD_US, val;
372	u32 data, addr, poll;
373	int i;
374
375	data = le32_to_cpu(cmd->op_data);
376	addr = GET_FIELD(data, INIT_READ_OP_ADDRESS) << 2;
377	poll = GET_FIELD(data, INIT_READ_OP_POLL_TYPE);
378
379
380	val = qed_rd(p_hwfn, p_ptt, addr);
381
382	if (poll == INIT_POLL_NONE)
383		return;
384
385	switch (poll) {
386	case INIT_POLL_EQ:
387		comp_check = comp_eq;
388		break;
389	case INIT_POLL_OR:
390		comp_check = comp_or;
391		break;
392	case INIT_POLL_AND:
393		comp_check = comp_and;
394		break;
395	default:
396		DP_ERR(p_hwfn, "Invalid poll comparison type %08x\n",
397		       cmd->op_data);
398		return;
399	}
400
401	data = le32_to_cpu(cmd->expected_val);
402	for (i = 0;
403	     i < QED_INIT_MAX_POLL_COUNT && !comp_check(val, data);
404	     i++) {
405		udelay(delay);
406		val = qed_rd(p_hwfn, p_ptt, addr);
407	}
408
409	if (i == QED_INIT_MAX_POLL_COUNT) {
410		DP_ERR(p_hwfn,
411		       "Timeout when polling reg: 0x%08x [ Waiting-for: %08x Got: %08x (comparison %08x)]\n",
412		       addr, le32_to_cpu(cmd->expected_val),
413		       val, le32_to_cpu(cmd->op_data));
414	}
415}
416
417/* init_ops callbacks entry point */
418static int qed_init_cmd_cb(struct qed_hwfn *p_hwfn,
419			   struct qed_ptt *p_ptt,
420			   struct init_callback_op *p_cmd)
421{
422	int rc;
423
424	switch (p_cmd->callback_id) {
425	case DMAE_READY_CB:
426		rc = qed_dmae_sanity(p_hwfn, p_ptt, "engine_phase");
427		break;
428	default:
429		DP_NOTICE(p_hwfn, "Unexpected init op callback ID %d\n",
430			  p_cmd->callback_id);
431		return -EINVAL;
432	}
433
434	return rc;
435}
436
437static u8 qed_init_cmd_mode_match(struct qed_hwfn *p_hwfn,
438				  u16 *p_offset, int modes)
439{
440	struct qed_dev *cdev = p_hwfn->cdev;
441	const u8 *modes_tree_buf;
442	u8 arg1, arg2, tree_val;
443
444	modes_tree_buf = cdev->fw_data->modes_tree_buf;
445	tree_val = modes_tree_buf[(*p_offset)++];
446	switch (tree_val) {
447	case INIT_MODE_OP_NOT:
448		return qed_init_cmd_mode_match(p_hwfn, p_offset, modes) ^ 1;
449	case INIT_MODE_OP_OR:
450		arg1 = qed_init_cmd_mode_match(p_hwfn, p_offset, modes);
451		arg2 = qed_init_cmd_mode_match(p_hwfn, p_offset, modes);
452		return arg1 | arg2;
453	case INIT_MODE_OP_AND:
454		arg1 = qed_init_cmd_mode_match(p_hwfn, p_offset, modes);
455		arg2 = qed_init_cmd_mode_match(p_hwfn, p_offset, modes);
456		return arg1 & arg2;
457	default:
458		tree_val -= MAX_INIT_MODE_OPS;
459		return (modes & BIT(tree_val)) ? 1 : 0;
460	}
461}
462
463static u32 qed_init_cmd_mode(struct qed_hwfn *p_hwfn,
464			     struct init_if_mode_op *p_cmd, int modes)
465{
466	u16 offset = le16_to_cpu(p_cmd->modes_buf_offset);
467
468	if (qed_init_cmd_mode_match(p_hwfn, &offset, modes))
469		return 0;
470	else
471		return GET_FIELD(le32_to_cpu(p_cmd->op_data),
472				 INIT_IF_MODE_OP_CMD_OFFSET);
473}
474
475static u32 qed_init_cmd_phase(struct qed_hwfn *p_hwfn,
476			      struct init_if_phase_op *p_cmd,
477			      u32 phase, u32 phase_id)
478{
479	u32 data = le32_to_cpu(p_cmd->phase_data);
480	u32 op_data = le32_to_cpu(p_cmd->op_data);
481
482	if (!(GET_FIELD(data, INIT_IF_PHASE_OP_PHASE) == phase &&
483	      (GET_FIELD(data, INIT_IF_PHASE_OP_PHASE_ID) == ANY_PHASE_ID ||
484	       GET_FIELD(data, INIT_IF_PHASE_OP_PHASE_ID) == phase_id)))
485		return GET_FIELD(op_data, INIT_IF_PHASE_OP_CMD_OFFSET);
486	else
487		return 0;
488}
489
490int qed_init_run(struct qed_hwfn *p_hwfn,
491		 struct qed_ptt *p_ptt, int phase, int phase_id, int modes)
492{
 
493	struct qed_dev *cdev = p_hwfn->cdev;
494	u32 cmd_num, num_init_ops;
495	union init_op *init_ops;
496	bool b_dmae = false;
497	int rc = 0;
498
499	num_init_ops = cdev->fw_data->init_ops_size;
500	init_ops = cdev->fw_data->init_ops;
501
502	p_hwfn->unzip_buf = kzalloc(MAX_ZIPPED_SIZE * 4, GFP_ATOMIC);
503	if (!p_hwfn->unzip_buf)
504		return -ENOMEM;
505
506	for (cmd_num = 0; cmd_num < num_init_ops; cmd_num++) {
507		union init_op *cmd = &init_ops[cmd_num];
508		u32 data = le32_to_cpu(cmd->raw.op_data);
509
510		switch (GET_FIELD(data, INIT_CALLBACK_OP_OP)) {
511		case INIT_OP_WRITE:
512			rc = qed_init_cmd_wr(p_hwfn, p_ptt, &cmd->write,
513					     b_dmae);
514			break;
515		case INIT_OP_READ:
516			qed_init_cmd_rd(p_hwfn, p_ptt, &cmd->read);
517			break;
518		case INIT_OP_IF_MODE:
519			cmd_num += qed_init_cmd_mode(p_hwfn, &cmd->if_mode,
520						     modes);
521			break;
522		case INIT_OP_IF_PHASE:
523			cmd_num += qed_init_cmd_phase(p_hwfn, &cmd->if_phase,
524						      phase, phase_id);
525			b_dmae = GET_FIELD(data, INIT_IF_PHASE_OP_DMAE_ENABLE);
526			break;
527		case INIT_OP_DELAY:
528			/* qed_init_run is always invoked from
529			 * sleep-able context
530			 */
531			udelay(le32_to_cpu(cmd->delay.delay));
532			break;
533
534		case INIT_OP_CALLBACK:
535			rc = qed_init_cmd_cb(p_hwfn, p_ptt, &cmd->callback);
 
 
 
536			break;
537		}
538
539		if (rc)
540			break;
541	}
542
543	kfree(p_hwfn->unzip_buf);
544	p_hwfn->unzip_buf = NULL;
545	return rc;
546}
547
548void qed_gtt_init(struct qed_hwfn *p_hwfn)
549{
550	u32 gtt_base;
551	u32 i;
552
553	/* Set the global windows */
554	gtt_base = PXP_PF_WINDOW_ADMIN_START + PXP_PF_WINDOW_ADMIN_GLOBAL_START;
555
556	for (i = 0; i < ARRAY_SIZE(pxp_global_win); i++)
557		if (pxp_global_win[i])
558			REG_WR(p_hwfn, gtt_base + i * PXP_GLOBAL_ENTRY_SIZE,
559			       pxp_global_win[i]);
560}
561
562int qed_init_fw_data(struct qed_dev *cdev, const u8 *data)
563{
564	struct qed_fw_data *fw = cdev->fw_data;
565	struct bin_buffer_hdr *buf_hdr;
566	u32 offset, len;
567
568	if (!data) {
569		DP_NOTICE(cdev, "Invalid fw data\n");
570		return -EINVAL;
571	}
572
573	/* First Dword contains metadata and should be skipped */
574	buf_hdr = (struct bin_buffer_hdr *)data;
575
576	offset = buf_hdr[BIN_BUF_INIT_FW_VER_INFO].offset;
577	fw->fw_ver_info = (struct fw_ver_info *)(data + offset);
578
579	offset = buf_hdr[BIN_BUF_INIT_CMD].offset;
580	fw->init_ops = (union init_op *)(data + offset);
581
582	offset = buf_hdr[BIN_BUF_INIT_VAL].offset;
583	fw->arr_data = (u32 *)(data + offset);
584
585	offset = buf_hdr[BIN_BUF_INIT_MODE_TREE].offset;
586	fw->modes_tree_buf = (u8 *)(data + offset);
587	len = buf_hdr[BIN_BUF_INIT_CMD].length;
588	fw->init_ops_size = len / sizeof(struct init_raw_op);
 
 
 
 
 
589
590	return 0;
591}