Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
[linux-2.6-microblaze.git] / drivers / net / ethernet / qlogic / qed / qed_init_ops.c
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
25 static 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 */
48 static 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
122 void qed_init_iro_array(struct qed_dev *cdev)
123 {
124         cdev->iro_arr = iro_arr + E4_IRO_ARR_OFFSET;
125 }
126
127 void 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
140 void 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
159 static 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
206 int 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
229 void 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
237 static 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
264 static 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
285 static 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
295 static 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 */
367 static 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
412 static inline bool comp_eq(u32 val, u32 expected_val)
413 {
414         return val == expected_val;
415 }
416
417 static inline bool comp_and(u32 val, u32 expected_val)
418 {
419         return (val & expected_val) == expected_val;
420 }
421
422 static inline bool comp_or(u32 val, u32 expected_val)
423 {
424         return (val | expected_val) > 0;
425 }
426
427 /* init_ops read/poll commands */
428 static 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 */
478 static 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
497 static 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
523 static 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
535 static 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
549 int 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
609 void 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
623 int 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 }