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.
7 #include <linux/types.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>
17 #include "qed_init_ops.h"
18 #include "qed_iro_hsi.h"
19 #include "qed_reg_addr.h"
20 #include "qed_sriov.h"
22 #define QED_INIT_MAX_POLL_COUNT 100
23 #define QED_INIT_POLL_PERIOD_US 500
25 static u32 pxp_global_win
[] = {
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 */
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,
122 void qed_init_iro_array(struct qed_dev
*cdev
)
124 cdev
->iro_arr
= iro_arr
+ E4_IRO_ARR_OFFSET
;
127 void qed_init_store_rt_reg(struct qed_hwfn
*p_hwfn
, u32 rt_offset
, u32 val
)
129 if (rt_offset
>= RUNTIME_ARRAY_SIZE
) {
131 "Avoid storing %u in rt_data at index %u!\n",
136 p_hwfn
->rt_data
.init_val
[rt_offset
] = val
;
137 p_hwfn
->rt_data
.b_valid
[rt_offset
] = true;
140 void qed_init_store_rt_agg(struct qed_hwfn
*p_hwfn
,
141 u32 rt_offset
, u32
*p_val
, size_t size
)
145 if ((rt_offset
+ size
- 1) >= RUNTIME_ARRAY_SIZE
) {
147 "Avoid storing values in rt_data at indices %u-%u!\n",
149 (u32
)(rt_offset
+ size
- 1));
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;
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
)
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
];
168 /* Since not all RT entries are initialized, go over the RT and
169 * for each segment of initialized values use DMA.
171 for (i
= 0; i
< size
; i
++) {
175 /* In case there isn't any wide-bus configuration here,
176 * simply write the data instead of using dmae.
179 qed_wr(p_hwfn
, p_ptt
, addr
+ (i
<< 2), p_init_val
[i
]);
184 /* Start of a new segment */
185 for (segment
= 1; i
+ segment
< size
; segment
++)
186 if (!p_valid
[i
+ segment
])
189 rc
= qed_dmae_host2grc(p_hwfn
, p_ptt
,
190 (uintptr_t)(p_init_val
+ i
),
191 addr
+ (i
<< 2), segment
, NULL
);
195 /* invalidate after writing */
196 for (j
= i
; j
< (u32
)(i
+ segment
); j
++)
199 /* Jump over the entire segment, including invalid entry */
206 int qed_init_alloc(struct qed_hwfn
*p_hwfn
)
208 struct qed_rt_data
*rt_data
= &p_hwfn
->rt_data
;
210 if (IS_VF(p_hwfn
->cdev
))
213 rt_data
->b_valid
= kcalloc(RUNTIME_ARRAY_SIZE
, sizeof(bool),
215 if (!rt_data
->b_valid
)
218 rt_data
->init_val
= kcalloc(RUNTIME_ARRAY_SIZE
, sizeof(u32
),
220 if (!rt_data
->init_val
) {
221 kfree(rt_data
->b_valid
);
222 rt_data
->b_valid
= NULL
;
229 void qed_init_free(struct qed_hwfn
*p_hwfn
)
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
;
237 static int qed_init_array_dmae(struct qed_hwfn
*p_hwfn
,
238 struct qed_ptt
*p_ptt
,
240 u32 dmae_data_offset
,
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
;
253 for (i
= 0; i
< size
; i
++)
254 qed_wr(p_hwfn
, p_ptt
, addr
+ (i
<< 2), data
[i
]);
256 rc
= qed_dmae_host2grc(p_hwfn
, p_ptt
,
257 (uintptr_t)(buf
+ dmae_data_offset
),
264 static int qed_init_fill_dmae(struct qed_hwfn
*p_hwfn
,
265 struct qed_ptt
*p_ptt
,
266 u32 addr
, u32 fill_count
)
268 static u32 zero_buffer
[DMAE_MAX_RW_SIZE
];
269 struct qed_dmae_params params
= {};
271 memset(zero_buffer
, 0, sizeof(u32
) * DMAE_MAX_RW_SIZE
);
273 /* invoke the DMAE virtual/physical buffer API with
274 * 1. DMAE init channel
276 * 3. p_hwfb->temp_data,
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
, ¶ms
);
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
)
291 for (i
= 0; i
< fill_count
; i
++, addr
+= sizeof(u32
))
292 qed_wr(p_hwfn
, p_ptt
, addr
, fill
);
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
)
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;
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
;
311 array_data
= cdev
->fw_data
->arr_data
;
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
);
323 output_len
= qed_unzip_data(p_hwfn
, input_len
,
324 (u8
*)&array_data
[offset
],
325 max_size
, (u8
*)p_hwfn
->unzip_buf
);
327 rc
= qed_init_array_dmae(p_hwfn
, p_ptt
, addr
, 0,
330 b_must_dmae
, b_can_dmae
);
332 DP_NOTICE(p_hwfn
, "Failed to unzip dmae data\n");
336 case INIT_ARR_PATTERN
:
338 u32 repeats
= GET_FIELD(data
,
339 INIT_ARRAY_PATTERN_HDR_REPETITIONS
);
342 size
= GET_FIELD(data
, INIT_ARRAY_PATTERN_HDR_PATTERN_SIZE
);
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,
348 b_must_dmae
, b_can_dmae
);
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,
359 b_must_dmae
, b_can_dmae
);
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
)
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
;
378 if (b_must_dmae
&& !b_can_dmae
) {
380 "Need to write to %08x for Wide-bus but DMAE isn't allowed\n",
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
);
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
);
395 qed_init_fill(p_hwfn
, p_ptt
, addr
, 0, data
);
398 rc
= qed_init_cmd_array(p_hwfn
, p_ptt
, p_cmd
,
399 b_must_dmae
, b_can_dmae
);
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
),
412 static inline bool comp_eq(u32 val
, u32 expected_val
)
414 return val
== expected_val
;
417 static inline bool comp_and(u32 val
, u32 expected_val
)
419 return (val
& expected_val
) == expected_val
;
422 static inline bool comp_or(u32 val
, u32 expected_val
)
424 return (val
| expected_val
) > 0;
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
)
431 bool (*comp_check
)(u32 val
, u32 expected_val
);
432 u32 delay
= QED_INIT_POLL_PERIOD_US
, val
;
433 u32 data
, addr
, poll
;
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
);
440 val
= qed_rd(p_hwfn
, p_ptt
, addr
);
442 if (poll
== INIT_POLL_NONE
)
447 comp_check
= comp_eq
;
450 comp_check
= comp_or
;
453 comp_check
= comp_and
;
456 DP_ERR(p_hwfn
, "Invalid poll comparison type %08x\n",
461 data
= le32_to_cpu(cmd
->expected_val
);
463 i
< QED_INIT_MAX_POLL_COUNT
&& !comp_check(val
, data
);
466 val
= qed_rd(p_hwfn
, p_ptt
, addr
);
469 if (i
== QED_INIT_MAX_POLL_COUNT
) {
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
));
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
)
484 switch (p_cmd
->callback_id
) {
486 rc
= qed_dmae_sanity(p_hwfn
, p_ptt
, "engine_phase");
489 DP_NOTICE(p_hwfn
, "Unexpected init op callback ID %d\n",
497 static u8
qed_init_cmd_mode_match(struct qed_hwfn
*p_hwfn
,
498 u16
*p_offset
, int modes
)
500 struct qed_dev
*cdev
= p_hwfn
->cdev
;
501 const u8
*modes_tree_buf
;
502 u8 arg1
, arg2
, tree_val
;
504 modes_tree_buf
= cdev
->fw_data
->modes_tree_buf
;
505 tree_val
= modes_tree_buf
[(*p_offset
)++];
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
);
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
);
518 tree_val
-= MAX_INIT_MODE_OPS
;
519 return (modes
& BIT(tree_val
)) ? 1 : 0;
523 static u32
qed_init_cmd_mode(struct qed_hwfn
*p_hwfn
,
524 struct init_if_mode_op
*p_cmd
, int modes
)
526 u16 offset
= le16_to_cpu(p_cmd
->modes_buf_offset
);
528 if (qed_init_cmd_mode_match(p_hwfn
, &offset
, modes
))
531 return GET_FIELD(le32_to_cpu(p_cmd
->op_data
),
532 INIT_IF_MODE_OP_CMD_OFFSET
);
535 static u32
qed_init_cmd_phase(struct init_if_phase_op
*p_cmd
,
536 u32 phase
, u32 phase_id
)
538 u32 data
= le32_to_cpu(p_cmd
->phase_data
);
539 u32 op_data
= le32_to_cpu(p_cmd
->op_data
);
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
);
549 int qed_init_run(struct qed_hwfn
*p_hwfn
,
550 struct qed_ptt
*p_ptt
, int phase
, int phase_id
, int modes
)
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
;
558 num_init_ops
= cdev
->fw_data
->init_ops_size
;
559 init_ops
= cdev
->fw_data
->init_ops
;
561 p_hwfn
->unzip_buf
= kzalloc(MAX_ZIPPED_SIZE
* 4, GFP_ATOMIC
);
562 if (!p_hwfn
->unzip_buf
)
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
);
569 switch (GET_FIELD(data
, INIT_CALLBACK_OP_OP
)) {
571 rc
= qed_init_cmd_wr(p_hwfn
, p_ptt
, &cmd
->write
,
575 qed_init_cmd_rd(p_hwfn
, p_ptt
, &cmd
->read
);
577 case INIT_OP_IF_MODE
:
578 cmd_num
+= qed_init_cmd_mode(p_hwfn
, &cmd
->if_mode
,
581 case INIT_OP_IF_PHASE
:
582 cmd_num
+= qed_init_cmd_phase(&cmd
->if_phase
,
586 /* qed_init_run is always invoked from
589 udelay(le32_to_cpu(cmd
->delay
.delay
));
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
)
604 kfree(p_hwfn
->unzip_buf
);
605 p_hwfn
->unzip_buf
= NULL
;
609 void qed_gtt_init(struct qed_hwfn
*p_hwfn
)
614 /* Set the global windows */
615 gtt_base
= PXP_PF_WINDOW_ADMIN_START
+ PXP_PF_WINDOW_ADMIN_GLOBAL_START
;
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
,
623 int qed_init_fw_data(struct qed_dev
*cdev
, const u8
*data
)
625 struct qed_fw_data
*fw
= cdev
->fw_data
;
626 struct bin_buffer_hdr
*buf_hdr
;
630 DP_NOTICE(cdev
, "Invalid fw data\n");
634 /* First Dword contains metadata and should be skipped */
635 buf_hdr
= (struct bin_buffer_hdr
*)data
;
637 offset
= buf_hdr
[BIN_BUF_INIT_FW_VER_INFO
].offset
;
638 fw
->fw_ver_info
= (struct fw_ver_info
*)(data
+ offset
);
640 offset
= buf_hdr
[BIN_BUF_INIT_CMD
].offset
;
641 fw
->init_ops
= (union init_op
*)(data
+ offset
);
643 offset
= buf_hdr
[BIN_BUF_INIT_VAL
].offset
;
644 fw
->arr_data
= (u32
*)(data
+ offset
);
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
);
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
;