4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, v.1, (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://opensource.org/licenses/CDDL-1.0.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2014-2017 Cavium, Inc.
24 * The contents of this file are subject to the terms of the Common Development
25 * and Distribution License, v.1, (the "License").
27 * You may not use this file except in compliance with the License.
29 * You can obtain a copy of the License at available
30 * at http://opensource.org/licenses/CDDL-1.0
32 * See the License for the specific language governing permissions and
33 * limitations under the License.
36 /* include the precompiled configuration values - only once */
38 #include "ecore_hsi_common.h"
41 #include "ecore_status.h"
42 #include "ecore_rt_defs.h"
43 #include "ecore_init_fw_funcs.h"
45 #ifndef CONFIG_ECORE_BINARY_FW
46 #ifdef CONFIG_ECORE_ZIPPED_FW
47 #include "ecore_init_values_zipped.h"
49 #include "ecore_init_values.h"
53 #include "ecore_iro_values.h"
54 #include "ecore_sriov.h"
55 #include "ecore_gtt_values.h"
57 #include "ecore_init_ops.h"
59 #define ECORE_INIT_MAX_POLL_COUNT 100
60 #define ECORE_INIT_POLL_PERIOD_US 500
62 void ecore_init_iro_array(struct ecore_dev
*p_dev
)
64 p_dev
->iro_arr
= iro_arr
;
67 /* Runtime configuration helpers */
68 void ecore_init_clear_rt_data(struct ecore_hwfn
*p_hwfn
)
72 for (i
= 0; i
< RUNTIME_ARRAY_SIZE
; i
++)
73 p_hwfn
->rt_data
.b_valid
[i
] = false;
76 void ecore_init_store_rt_reg(struct ecore_hwfn
*p_hwfn
,
77 u32 rt_offset
, u32 val
)
79 p_hwfn
->rt_data
.init_val
[rt_offset
] = val
;
80 p_hwfn
->rt_data
.b_valid
[rt_offset
] = true;
83 void ecore_init_store_rt_agg(struct ecore_hwfn
*p_hwfn
,
84 u32 rt_offset
, u32
*p_val
,
89 for (i
= 0; i
< size
/ sizeof(u32
); i
++) {
90 p_hwfn
->rt_data
.init_val
[rt_offset
+ i
] = p_val
[i
];
91 p_hwfn
->rt_data
.b_valid
[rt_offset
+ i
] = true;
96 static enum _ecore_status_t
ecore_init_rt(struct ecore_hwfn
*p_hwfn
,
97 struct ecore_ptt
*p_ptt
,
103 u32
*p_init_val
= &p_hwfn
->rt_data
.init_val
[rt_offset
];
104 bool *p_valid
= &p_hwfn
->rt_data
.b_valid
[rt_offset
];
106 enum _ecore_status_t rc
= ECORE_SUCCESS
;
108 /* Since not all RT entries are initialized, go over the RT and
109 * for each segment of initialized values use DMA.
111 for (i
= 0; i
< size
; i
++) {
115 /* In case there isn't any wide-bus configuration here,
116 * simply write the data instead of using dmae.
119 ecore_wr(p_hwfn
, p_ptt
, addr
+ (i
<< 2),
124 /* Start of a new segment */
125 for (segment
= 1; i
+ segment
< size
; segment
++)
126 if (!p_valid
[i
+ segment
])
129 rc
= ecore_dmae_host2grc(p_hwfn
, p_ptt
,
130 (osal_uintptr_t
)(p_init_val
+ i
),
131 addr
+ (i
<< 2), segment
, 0);
132 if (rc
!= ECORE_SUCCESS
)
135 /* Jump over the entire segment, including invalid entry */
142 enum _ecore_status_t
ecore_init_alloc(struct ecore_hwfn
*p_hwfn
)
144 struct ecore_rt_data
*rt_data
= &p_hwfn
->rt_data
;
146 if (IS_VF(p_hwfn
->p_dev
))
147 return ECORE_SUCCESS
;
149 rt_data
->b_valid
= OSAL_ZALLOC(p_hwfn
->p_dev
, GFP_KERNEL
,
150 sizeof(bool) * RUNTIME_ARRAY_SIZE
);
151 if (!rt_data
->b_valid
)
154 rt_data
->init_val
= OSAL_ZALLOC(p_hwfn
->p_dev
, GFP_KERNEL
,
155 sizeof(u32
) * RUNTIME_ARRAY_SIZE
);
156 if (!rt_data
->init_val
) {
157 OSAL_FREE(p_hwfn
->p_dev
, rt_data
->b_valid
);
158 rt_data
->b_valid
= OSAL_NULL
;
162 return ECORE_SUCCESS
;
165 void ecore_init_free(struct ecore_hwfn
*p_hwfn
)
167 OSAL_FREE(p_hwfn
->p_dev
, p_hwfn
->rt_data
.init_val
);
168 p_hwfn
->rt_data
.init_val
= OSAL_NULL
;
169 OSAL_FREE(p_hwfn
->p_dev
, p_hwfn
->rt_data
.b_valid
);
170 p_hwfn
->rt_data
.b_valid
= OSAL_NULL
;
173 static enum _ecore_status_t
ecore_init_array_dmae(struct ecore_hwfn
*p_hwfn
,
174 struct ecore_ptt
*p_ptt
,
175 u32 addr
, u32 dmae_data_offset
,
176 u32 size
, const u32
*p_buf
,
177 bool b_must_dmae
, bool b_can_dmae
)
179 enum _ecore_status_t rc
= ECORE_SUCCESS
;
181 /* Perform DMAE only for lengthy enough sections or for wide-bus */
183 if ((CHIP_REV_IS_SLOW(p_hwfn
->p_dev
) && (size
< 16)) ||
184 !b_can_dmae
|| (!b_must_dmae
&& (size
< 16))) {
186 if (!b_can_dmae
|| (!b_must_dmae
&& (size
< 16))) {
188 const u32
*data
= p_buf
+ dmae_data_offset
;
191 for (i
= 0; i
< size
; i
++)
192 ecore_wr(p_hwfn
, p_ptt
, addr
+ (i
<< 2), data
[i
]);
194 rc
= ecore_dmae_host2grc(p_hwfn
, p_ptt
,
195 (osal_uintptr_t
)(p_buf
+
203 static enum _ecore_status_t
ecore_init_fill_dmae(struct ecore_hwfn
*p_hwfn
,
204 struct ecore_ptt
*p_ptt
,
208 static u32 zero_buffer
[DMAE_MAX_RW_SIZE
];
210 OSAL_MEMSET(zero_buffer
, 0, sizeof(u32
) * DMAE_MAX_RW_SIZE
);
212 return ecore_dmae_host2grc(p_hwfn
, p_ptt
,
213 (osal_uintptr_t
)(&(zero_buffer
[0])),
215 ECORE_DMAE_FLAG_RW_REPL_SRC
);
218 static void ecore_init_fill(struct ecore_hwfn
*p_hwfn
,
219 struct ecore_ptt
*p_ptt
,
220 u32 addr
, u32 fill
, u32 fill_count
)
224 for (i
= 0; i
< fill_count
; i
++, addr
+= sizeof(u32
))
225 ecore_wr(p_hwfn
, p_ptt
, addr
, fill
);
229 static enum _ecore_status_t
ecore_init_cmd_array(struct ecore_hwfn
*p_hwfn
,
230 struct ecore_ptt
*p_ptt
,
231 struct init_write_op
*cmd
,
235 u32 dmae_array_offset
= OSAL_LE32_TO_CPU(cmd
->args
.array_offset
);
236 u32 data
= OSAL_LE32_TO_CPU(cmd
->data
);
237 u32 addr
= GET_FIELD(data
, INIT_WRITE_OP_ADDRESS
) << 2;
238 #ifdef CONFIG_ECORE_ZIPPED_FW
239 u32 offset
, output_len
, input_len
, max_size
;
241 struct ecore_dev
*p_dev
= p_hwfn
->p_dev
;
242 union init_array_hdr
*hdr
;
243 const u32
*array_data
;
244 enum _ecore_status_t rc
= ECORE_SUCCESS
;
247 array_data
= p_dev
->fw_data
->arr_data
;
249 hdr
= (union init_array_hdr
*) (array_data
+
251 data
= OSAL_LE32_TO_CPU(hdr
->raw
.data
);
252 switch (GET_FIELD(data
, INIT_ARRAY_RAW_HDR_TYPE
)) {
253 case INIT_ARR_ZIPPED
:
254 #ifdef CONFIG_ECORE_ZIPPED_FW
255 offset
= dmae_array_offset
+ 1;
256 input_len
= GET_FIELD(data
,
257 INIT_ARRAY_ZIPPED_HDR_ZIPPED_SIZE
);
258 max_size
= MAX_ZIPPED_SIZE
* 4;
259 OSAL_MEMSET(p_hwfn
->unzip_buf
, 0, max_size
);
261 output_len
= OSAL_UNZIP_DATA(p_hwfn
, input_len
,
262 (u8
*)&array_data
[offset
],
263 max_size
, (u8
*)p_hwfn
->unzip_buf
);
265 rc
= ecore_init_array_dmae(p_hwfn
, p_ptt
, addr
, 0,
268 b_must_dmae
, b_can_dmae
);
270 DP_NOTICE(p_hwfn
, true,
271 "Failed to unzip dmae data\n");
275 DP_NOTICE(p_hwfn
, true,
276 "Using zipped firmware without config enabled\n");
280 case INIT_ARR_PATTERN
:
282 u32 repeats
= GET_FIELD(data
,
283 INIT_ARRAY_PATTERN_HDR_REPETITIONS
);
286 size
= GET_FIELD(data
,
287 INIT_ARRAY_PATTERN_HDR_PATTERN_SIZE
);
289 for (i
= 0; i
< repeats
; i
++, addr
+= size
<< 2) {
290 rc
= ecore_init_array_dmae(p_hwfn
, p_ptt
, addr
,
291 dmae_array_offset
+ 1,
293 b_must_dmae
, b_can_dmae
);
299 case INIT_ARR_STANDARD
:
300 size
= GET_FIELD(data
,
301 INIT_ARRAY_STANDARD_HDR_SIZE
);
302 rc
= ecore_init_array_dmae(p_hwfn
, p_ptt
, addr
,
303 dmae_array_offset
+ 1,
305 b_must_dmae
, b_can_dmae
);
312 /* init_ops write command */
313 static enum _ecore_status_t
ecore_init_cmd_wr(struct ecore_hwfn
*p_hwfn
,
314 struct ecore_ptt
*p_ptt
,
315 struct init_write_op
*p_cmd
,
318 u32 data
= OSAL_LE32_TO_CPU(p_cmd
->data
);
319 bool b_must_dmae
= GET_FIELD(data
, INIT_WRITE_OP_WIDE_BUS
);
320 u32 addr
= GET_FIELD(data
, INIT_WRITE_OP_ADDRESS
) << 2;
321 enum _ecore_status_t rc
= ECORE_SUCCESS
;
324 if (b_must_dmae
&& !b_can_dmae
) {
325 DP_NOTICE(p_hwfn
, true,
326 "Need to write to %08x for Wide-bus but DMAE isn't allowed\n",
331 switch (GET_FIELD(data
, INIT_WRITE_OP_SOURCE
)) {
332 case INIT_SRC_INLINE
:
333 data
= OSAL_LE32_TO_CPU(p_cmd
->args
.inline_val
);
334 ecore_wr(p_hwfn
, p_ptt
, addr
, data
);
337 data
= OSAL_LE32_TO_CPU(p_cmd
->args
.zeros_count
);
338 if (b_must_dmae
|| (b_can_dmae
&& (data
>= 64)))
339 rc
= ecore_init_fill_dmae(p_hwfn
, p_ptt
,
342 ecore_init_fill(p_hwfn
, p_ptt
, addr
, 0, data
);
345 rc
= ecore_init_cmd_array(p_hwfn
, p_ptt
, p_cmd
,
346 b_must_dmae
, b_can_dmae
);
348 case INIT_SRC_RUNTIME
:
349 ecore_init_rt(p_hwfn
, p_ptt
, addr
,
350 OSAL_LE16_TO_CPU(p_cmd
->args
.runtime
.offset
),
351 OSAL_LE16_TO_CPU(p_cmd
->args
.runtime
.size
),
359 static OSAL_INLINE
bool comp_eq(u32 val
, u32 expected_val
)
361 return (val
== expected_val
);
364 static OSAL_INLINE
bool comp_and(u32 val
, u32 expected_val
)
366 return (val
& expected_val
) == expected_val
;
369 static OSAL_INLINE
bool comp_or(u32 val
, u32 expected_val
)
371 return (val
| expected_val
) > 0;
374 /* init_ops read/poll commands */
375 static void ecore_init_cmd_rd(struct ecore_hwfn
*p_hwfn
,
376 struct ecore_ptt
*p_ptt
,
377 struct init_read_op
*cmd
)
379 bool (*comp_check
)(u32 val
, u32 expected_val
);
380 u32 delay
= ECORE_INIT_POLL_PERIOD_US
, val
;
381 u32 data
, addr
, poll
;
384 data
= OSAL_LE32_TO_CPU(cmd
->op_data
);
385 addr
= GET_FIELD(data
, INIT_READ_OP_ADDRESS
) << 2;
386 poll
= GET_FIELD(data
, INIT_READ_OP_POLL_TYPE
);
389 if (CHIP_REV_IS_EMUL(p_hwfn
->p_dev
))
393 val
= ecore_rd(p_hwfn
, p_ptt
, addr
);
395 if (poll
== INIT_POLL_NONE
)
400 comp_check
= comp_eq
;
403 comp_check
= comp_or
;
406 comp_check
= comp_and
;
409 DP_ERR(p_hwfn
, "Invalid poll comparison type %08x\n",
414 data
= OSAL_LE32_TO_CPU(cmd
->expected_val
);
416 i
< ECORE_INIT_MAX_POLL_COUNT
&& !comp_check(val
, data
);
419 val
= ecore_rd(p_hwfn
, p_ptt
, addr
);
422 if (i
== ECORE_INIT_MAX_POLL_COUNT
)
423 DP_ERR(p_hwfn
, "Timeout when polling reg: 0x%08x [ Waiting-for: %08x Got: %08x (comparsion %08x)]\n",
425 OSAL_LE32_TO_CPU(cmd
->expected_val
), val
,
426 OSAL_LE32_TO_CPU(cmd
->op_data
));
429 /* init_ops callbacks entry point */
430 static void ecore_init_cmd_cb(struct ecore_hwfn
*p_hwfn
,
431 struct ecore_ptt
*p_ptt
,
432 struct init_callback_op
*p_cmd
)
434 DP_NOTICE(p_hwfn
, true, "Currently init values have no need of callbacks\n");
437 static u8
ecore_init_cmd_mode_match(struct ecore_hwfn
*p_hwfn
,
438 u16
*p_offset
, int modes
)
440 struct ecore_dev
*p_dev
= p_hwfn
->p_dev
;
441 const u8
*modes_tree_buf
;
442 u8 arg1
, arg2
, tree_val
;
444 modes_tree_buf
= p_dev
->fw_data
->modes_tree_buf
;
445 tree_val
= modes_tree_buf
[(*p_offset
)++];
447 case INIT_MODE_OP_NOT
:
448 return ecore_init_cmd_mode_match(p_hwfn
, p_offset
, modes
) ^ 1;
449 case INIT_MODE_OP_OR
:
450 arg1
= ecore_init_cmd_mode_match(p_hwfn
, p_offset
, modes
);
451 arg2
= ecore_init_cmd_mode_match(p_hwfn
, p_offset
, modes
);
453 case INIT_MODE_OP_AND
:
454 arg1
= ecore_init_cmd_mode_match(p_hwfn
, p_offset
, modes
);
455 arg2
= ecore_init_cmd_mode_match(p_hwfn
, p_offset
, modes
);
458 tree_val
-= MAX_INIT_MODE_OPS
;
459 return (modes
& (1 << tree_val
)) ? 1 : 0;
463 static u32
ecore_init_cmd_mode(struct ecore_hwfn
*p_hwfn
,
464 struct init_if_mode_op
*p_cmd
, int modes
)
466 u16 offset
= OSAL_LE16_TO_CPU(p_cmd
->modes_buf_offset
);
468 if (ecore_init_cmd_mode_match(p_hwfn
, &offset
, modes
))
471 return GET_FIELD(OSAL_LE32_TO_CPU(p_cmd
->op_data
),
472 INIT_IF_MODE_OP_CMD_OFFSET
);
475 static u32
ecore_init_cmd_phase(struct ecore_hwfn
*p_hwfn
,
476 struct init_if_phase_op
*p_cmd
,
477 u32 phase
, u32 phase_id
)
479 u32 data
= OSAL_LE32_TO_CPU(p_cmd
->phase_data
);
481 if (!(GET_FIELD(data
, INIT_IF_PHASE_OP_PHASE
) == phase
&&
482 (GET_FIELD(data
, INIT_IF_PHASE_OP_PHASE_ID
) == ANY_PHASE_ID
||
483 GET_FIELD(data
, INIT_IF_PHASE_OP_PHASE_ID
) == phase_id
)))
484 return GET_FIELD(OSAL_LE32_TO_CPU(p_cmd
->op_data
),
485 INIT_IF_PHASE_OP_CMD_OFFSET
);
490 enum _ecore_status_t
ecore_init_run(struct ecore_hwfn
*p_hwfn
,
491 struct ecore_ptt
*p_ptt
,
496 struct ecore_dev
*p_dev
= p_hwfn
->p_dev
;
497 u32 cmd_num
, num_init_ops
;
498 union init_op
*init_ops
;
500 enum _ecore_status_t rc
= ECORE_SUCCESS
;
502 num_init_ops
= p_dev
->fw_data
->init_ops_size
;
503 init_ops
= p_dev
->fw_data
->init_ops
;
505 #ifdef CONFIG_ECORE_ZIPPED_FW
506 p_hwfn
->unzip_buf
= OSAL_ZALLOC(p_hwfn
->p_dev
, GFP_ATOMIC
,
507 MAX_ZIPPED_SIZE
* 4);
508 if (!p_hwfn
->unzip_buf
) {
509 DP_NOTICE(p_hwfn
, true, "Failed to allocate unzip buffer\n");
514 for (cmd_num
= 0; cmd_num
< num_init_ops
; cmd_num
++) {
515 union init_op
*cmd
= &init_ops
[cmd_num
];
516 u32 data
= OSAL_LE32_TO_CPU(cmd
->raw
.op_data
);
518 switch (GET_FIELD(data
, INIT_CALLBACK_OP_OP
)) {
520 rc
= ecore_init_cmd_wr(p_hwfn
, p_ptt
, &cmd
->write
,
525 ecore_init_cmd_rd(p_hwfn
, p_ptt
, &cmd
->read
);
528 case INIT_OP_IF_MODE
:
529 cmd_num
+= ecore_init_cmd_mode(p_hwfn
, &cmd
->if_mode
,
532 case INIT_OP_IF_PHASE
:
533 cmd_num
+= ecore_init_cmd_phase(p_hwfn
, &cmd
->if_phase
,
535 b_dmae
= GET_FIELD(data
,
536 INIT_IF_PHASE_OP_DMAE_ENABLE
);
539 /* ecore_init_run is always invoked from
542 OSAL_UDELAY(cmd
->delay
.delay
);
545 case INIT_OP_CALLBACK
:
546 ecore_init_cmd_cb(p_hwfn
, p_ptt
, &cmd
->callback
);
553 #ifdef CONFIG_ECORE_ZIPPED_FW
554 OSAL_FREE(p_hwfn
->p_dev
, p_hwfn
->unzip_buf
);
555 p_hwfn
->unzip_buf
= OSAL_NULL
;
560 void ecore_gtt_init(struct ecore_hwfn
*p_hwfn
)
566 if (CHIP_REV_IS_SLOW(p_hwfn
->p_dev
)) {
567 /* This is done by MFW on ASIC; regardless, this should only
568 * be done once per chip [i.e., common]. Implementation is
569 * not too bright, but it should work on the simple FPGA/EMUL
572 static bool initialized
= false;
576 /* initialize PTT/GTT (poll for completion) */
578 ecore_wr(p_hwfn
, p_hwfn
->p_main_ptt
,
579 PGLUE_B_REG_START_INIT_PTT_GTT
, 1);
584 /* ptt might be overrided by HW until this is done */
586 ecore_ptt_invalidate(p_hwfn
);
587 val
= ecore_rd(p_hwfn
, p_hwfn
->p_main_ptt
,
588 PGLUE_B_REG_INIT_DONE_PTT_GTT
);
589 } while ((val
!= 1) && --poll_cnt
);
592 DP_ERR(p_hwfn
, "PGLUE_B_REG_INIT_DONE didn't complete\n");
596 /* Set the global windows */
597 gtt_base
= PXP_PF_WINDOW_ADMIN_START
+ PXP_PF_WINDOW_ADMIN_GLOBAL_START
;
599 for (i
= 0; i
< OSAL_ARRAY_SIZE(pxp_global_win
); i
++)
600 if (pxp_global_win
[i
])
601 REG_WR(p_hwfn
, gtt_base
+ i
* PXP_GLOBAL_ENTRY_SIZE
,
605 enum _ecore_status_t
ecore_init_fw_data(struct ecore_dev
*p_dev
,
608 struct ecore_fw_data
*fw
= p_dev
->fw_data
;
610 #ifdef CONFIG_ECORE_BINARY_FW
611 struct bin_buffer_hdr
*buf_hdr
;
615 DP_NOTICE(p_dev
, true, "Invalid fw data\n");
619 buf_hdr
= (struct bin_buffer_hdr
*)data
;
621 offset
= buf_hdr
[BIN_BUF_INIT_FW_VER_INFO
].offset
;
622 fw
->fw_ver_info
= (struct fw_ver_info
*)(data
+ offset
);
624 offset
= buf_hdr
[BIN_BUF_INIT_CMD
].offset
;
625 fw
->init_ops
= (union init_op
*)(data
+ offset
);
627 offset
= buf_hdr
[BIN_BUF_INIT_VAL
].offset
;
628 fw
->arr_data
= (u32
*)(data
+ offset
);
630 offset
= buf_hdr
[BIN_BUF_INIT_MODE_TREE
].offset
;
631 fw
->modes_tree_buf
= (u8
*)(data
+ offset
);
632 len
= buf_hdr
[BIN_BUF_INIT_CMD
].length
;
633 fw
->init_ops_size
= len
/ sizeof(struct init_raw_op
);
635 fw
->init_ops
= (union init_op
*)init_ops
;
636 fw
->arr_data
= (u32
*)init_val
;
637 fw
->modes_tree_buf
= (u8
*)modes_tree_buf
;
638 fw
->init_ops_size
= init_ops_size
;
641 return ECORE_SUCCESS
;