1 /* 2 * Copyright (c) 2017-2018 Cavium, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 /* 29 * File : ecore_init_ops.c 30 */ 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 35 /* include the precompiled configuration values - only once */ 36 #include "bcm_osal.h" 37 #include "ecore_hsi_common.h" 38 #include "ecore.h" 39 #include "ecore_hw.h" 40 #include "ecore_status.h" 41 #include "ecore_rt_defs.h" 42 #include "ecore_init_fw_funcs.h" 43 44 #ifndef CONFIG_ECORE_BINARY_FW 45 #ifdef CONFIG_ECORE_ZIPPED_FW 46 #include "ecore_init_values_zipped.h" 47 #else 48 #include "ecore_init_values.h" 49 #endif 50 #endif 51 52 #include "ecore_iro_values.h" 53 #include "ecore_sriov.h" 54 #include "ecore_gtt_values.h" 55 #include "reg_addr.h" 56 #include "ecore_init_ops.h" 57 58 #define ECORE_INIT_MAX_POLL_COUNT 100 59 #define ECORE_INIT_POLL_PERIOD_US 500 60 61 void ecore_init_iro_array(struct ecore_dev *p_dev) 62 { 63 p_dev->iro_arr = iro_arr; 64 } 65 66 /* Runtime configuration helpers */ 67 void ecore_init_clear_rt_data(struct ecore_hwfn *p_hwfn) 68 { 69 int i; 70 71 for (i = 0; i < RUNTIME_ARRAY_SIZE; i++) 72 p_hwfn->rt_data.b_valid[i] = false; 73 } 74 75 void ecore_init_store_rt_reg(struct ecore_hwfn *p_hwfn, 76 u32 rt_offset, u32 val) 77 { 78 p_hwfn->rt_data.init_val[rt_offset] = val; 79 p_hwfn->rt_data.b_valid[rt_offset] = true; 80 } 81 82 void ecore_init_store_rt_agg(struct ecore_hwfn *p_hwfn, 83 u32 rt_offset, u32 *p_val, 84 osal_size_t size) 85 { 86 osal_size_t i; 87 88 for (i = 0; i < size / sizeof(u32); i++) { 89 p_hwfn->rt_data.init_val[rt_offset + i] = p_val[i]; 90 p_hwfn->rt_data.b_valid[rt_offset + i] = true; 91 92 } 93 } 94 95 static enum _ecore_status_t ecore_init_rt(struct ecore_hwfn *p_hwfn, 96 struct ecore_ptt *p_ptt, 97 u32 addr, 98 u16 rt_offset, 99 u16 size, 100 bool b_must_dmae) 101 { 102 u32 *p_init_val = &p_hwfn->rt_data.init_val[rt_offset]; 103 bool *p_valid = &p_hwfn->rt_data.b_valid[rt_offset]; 104 u16 i, segment; 105 enum _ecore_status_t rc = ECORE_SUCCESS; 106 107 /* Since not all RT entries are initialized, go over the RT and 108 * for each segment of initialized values use DMA. 109 */ 110 for (i = 0; i < size; i++) { 111 if (!p_valid[i]) 112 continue; 113 114 /* In case there isn't any wide-bus configuration here, 115 * simply write the data instead of using dmae. 116 */ 117 if (!b_must_dmae) { 118 ecore_wr(p_hwfn, p_ptt, addr + (i << 2), 119 p_init_val[i]); 120 continue; 121 } 122 123 /* Start of a new segment */ 124 for (segment = 1; i + segment < size; segment++) 125 if (!p_valid[i + segment]) 126 break; 127 128 rc = ecore_dmae_host2grc(p_hwfn, p_ptt, 129 (osal_uintptr_t)(p_init_val + i), 130 addr + (i << 2), segment, 0); 131 if (rc != ECORE_SUCCESS) 132 return rc; 133 134 /* Jump over the entire segment, including invalid entry */ 135 i += segment; 136 } 137 138 return rc; 139 } 140 141 enum _ecore_status_t ecore_init_alloc(struct ecore_hwfn *p_hwfn) 142 { 143 struct ecore_rt_data *rt_data = &p_hwfn->rt_data; 144 145 if (IS_VF(p_hwfn->p_dev)) 146 return ECORE_SUCCESS; 147 148 rt_data->b_valid = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL, 149 sizeof(bool) * RUNTIME_ARRAY_SIZE); 150 if (!rt_data->b_valid) 151 return ECORE_NOMEM; 152 153 rt_data->init_val = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL, 154 sizeof(u32) * RUNTIME_ARRAY_SIZE); 155 if (!rt_data->init_val) { 156 OSAL_FREE(p_hwfn->p_dev, rt_data->b_valid); 157 rt_data->b_valid = OSAL_NULL; 158 return ECORE_NOMEM; 159 } 160 161 return ECORE_SUCCESS; 162 } 163 164 void ecore_init_free(struct ecore_hwfn *p_hwfn) 165 { 166 OSAL_FREE(p_hwfn->p_dev, p_hwfn->rt_data.init_val); 167 p_hwfn->rt_data.init_val = OSAL_NULL; 168 OSAL_FREE(p_hwfn->p_dev, p_hwfn->rt_data.b_valid); 169 p_hwfn->rt_data.b_valid = OSAL_NULL; 170 } 171 172 static enum _ecore_status_t ecore_init_array_dmae(struct ecore_hwfn *p_hwfn, 173 struct ecore_ptt *p_ptt, 174 u32 addr, u32 dmae_data_offset, 175 u32 size, const u32 *p_buf, 176 bool b_must_dmae, bool b_can_dmae) 177 { 178 enum _ecore_status_t rc = ECORE_SUCCESS; 179 180 /* Perform DMAE only for lengthy enough sections or for wide-bus */ 181 #ifndef ASIC_ONLY 182 if ((CHIP_REV_IS_SLOW(p_hwfn->p_dev) && (size < 16)) || 183 !b_can_dmae || (!b_must_dmae && (size < 16))) { 184 #else 185 if (!b_can_dmae || (!b_must_dmae && (size < 16))) { 186 #endif 187 const u32 *data = p_buf + dmae_data_offset; 188 u32 i; 189 190 for (i = 0; i < size; i++) 191 ecore_wr(p_hwfn, p_ptt, addr + (i << 2), data[i]); 192 } else { 193 rc = ecore_dmae_host2grc(p_hwfn, p_ptt, 194 (osal_uintptr_t)(p_buf + 195 dmae_data_offset), 196 addr, size, 0); 197 } 198 199 return rc; 200 } 201 202 static enum _ecore_status_t ecore_init_fill_dmae(struct ecore_hwfn *p_hwfn, 203 struct ecore_ptt *p_ptt, 204 u32 addr, u32 fill, 205 u32 fill_count) 206 { 207 static u32 zero_buffer[DMAE_MAX_RW_SIZE]; 208 209 OSAL_MEMSET(zero_buffer, 0, sizeof(u32) * DMAE_MAX_RW_SIZE); 210 211 return ecore_dmae_host2grc(p_hwfn, p_ptt, 212 (osal_uintptr_t)(&(zero_buffer[0])), 213 addr, fill_count, 214 ECORE_DMAE_FLAG_RW_REPL_SRC); 215 } 216 217 static void ecore_init_fill(struct ecore_hwfn *p_hwfn, 218 struct ecore_ptt *p_ptt, 219 u32 addr, u32 fill, u32 fill_count) 220 { 221 u32 i; 222 223 for (i = 0; i < fill_count; i++, addr += sizeof(u32)) 224 ecore_wr(p_hwfn, p_ptt, addr, fill); 225 } 226 227 228 static enum _ecore_status_t ecore_init_cmd_array(struct ecore_hwfn *p_hwfn, 229 struct ecore_ptt *p_ptt, 230 struct init_write_op *cmd, 231 bool b_must_dmae, 232 bool b_can_dmae) 233 { 234 u32 dmae_array_offset = OSAL_LE32_TO_CPU(cmd->args.array_offset); 235 u32 data = OSAL_LE32_TO_CPU(cmd->data); 236 u32 addr = GET_FIELD(data, INIT_WRITE_OP_ADDRESS) << 2; 237 #ifdef CONFIG_ECORE_ZIPPED_FW 238 u32 offset, output_len, input_len, max_size; 239 #endif 240 struct ecore_dev *p_dev = p_hwfn->p_dev; 241 union init_array_hdr *hdr; 242 const u32 *array_data; 243 enum _ecore_status_t rc = ECORE_SUCCESS; 244 u32 size; 245 246 array_data = p_dev->fw_data->arr_data; 247 248 hdr = (union init_array_hdr *) (array_data + 249 dmae_array_offset); 250 data = OSAL_LE32_TO_CPU(hdr->raw.data); 251 switch (GET_FIELD(data, INIT_ARRAY_RAW_HDR_TYPE)) { 252 case INIT_ARR_ZIPPED: 253 #ifdef CONFIG_ECORE_ZIPPED_FW 254 offset = dmae_array_offset + 1; 255 input_len = GET_FIELD(data, 256 INIT_ARRAY_ZIPPED_HDR_ZIPPED_SIZE); 257 max_size = MAX_ZIPPED_SIZE * 4; 258 OSAL_MEMSET(p_hwfn->unzip_buf, 0, max_size); 259 260 output_len = OSAL_UNZIP_DATA(p_hwfn, input_len, 261 (u8 *)&array_data[offset], 262 max_size, (u8 *)p_hwfn->unzip_buf); 263 if (output_len) { 264 rc = ecore_init_array_dmae(p_hwfn, p_ptt, addr, 0, 265 output_len, 266 p_hwfn->unzip_buf, 267 b_must_dmae, b_can_dmae); 268 } else { 269 DP_NOTICE(p_hwfn, true, 270 "Failed to unzip dmae data\n"); 271 rc = ECORE_INVAL; 272 } 273 #else 274 DP_NOTICE(p_hwfn, true, 275 "Using zipped firmware without config enabled\n"); 276 rc = ECORE_INVAL; 277 #endif 278 break; 279 case INIT_ARR_PATTERN: 280 { 281 u32 repeats = GET_FIELD(data, 282 INIT_ARRAY_PATTERN_HDR_REPETITIONS); 283 u32 i; 284 285 size = GET_FIELD(data, 286 INIT_ARRAY_PATTERN_HDR_PATTERN_SIZE); 287 288 for (i = 0; i < repeats; i++, addr += size << 2) { 289 rc = ecore_init_array_dmae(p_hwfn, p_ptt, addr, 290 dmae_array_offset + 1, 291 size, array_data, 292 b_must_dmae, b_can_dmae); 293 if (rc) 294 break; 295 } 296 break; 297 } 298 case INIT_ARR_STANDARD: 299 size = GET_FIELD(data, 300 INIT_ARRAY_STANDARD_HDR_SIZE); 301 rc = ecore_init_array_dmae(p_hwfn, p_ptt, addr, 302 dmae_array_offset + 1, 303 size, array_data, 304 b_must_dmae, b_can_dmae); 305 break; 306 } 307 308 return rc; 309 } 310 311 /* init_ops write command */ 312 static enum _ecore_status_t ecore_init_cmd_wr(struct ecore_hwfn *p_hwfn, 313 struct ecore_ptt *p_ptt, 314 struct init_write_op *p_cmd, 315 bool b_can_dmae) 316 { 317 u32 data = OSAL_LE32_TO_CPU(p_cmd->data); 318 bool b_must_dmae = GET_FIELD(data, INIT_WRITE_OP_WIDE_BUS); 319 u32 addr = GET_FIELD(data, INIT_WRITE_OP_ADDRESS) << 2; 320 enum _ecore_status_t rc = ECORE_SUCCESS; 321 322 /* Sanitize */ 323 if (b_must_dmae && !b_can_dmae) { 324 DP_NOTICE(p_hwfn, true, 325 "Need to write to %08x for Wide-bus but DMAE isn't allowed\n", 326 addr); 327 return ECORE_INVAL; 328 } 329 330 switch (GET_FIELD(data, INIT_WRITE_OP_SOURCE)) { 331 case INIT_SRC_INLINE: 332 data = OSAL_LE32_TO_CPU(p_cmd->args.inline_val); 333 ecore_wr(p_hwfn, p_ptt, addr, data); 334 break; 335 case INIT_SRC_ZEROS: 336 data = OSAL_LE32_TO_CPU(p_cmd->args.zeros_count); 337 if (b_must_dmae || (b_can_dmae && (data >= 64))) 338 rc = ecore_init_fill_dmae(p_hwfn, p_ptt, 339 addr, 0, data); 340 else 341 ecore_init_fill(p_hwfn, p_ptt, addr, 0, data); 342 break; 343 case INIT_SRC_ARRAY: 344 rc = ecore_init_cmd_array(p_hwfn, p_ptt, p_cmd, 345 b_must_dmae, b_can_dmae); 346 break; 347 case INIT_SRC_RUNTIME: 348 ecore_init_rt(p_hwfn, p_ptt, addr, 349 OSAL_LE16_TO_CPU(p_cmd->args.runtime.offset), 350 OSAL_LE16_TO_CPU(p_cmd->args.runtime.size), 351 b_must_dmae); 352 break; 353 } 354 355 return rc; 356 } 357 358 static OSAL_INLINE bool comp_eq(u32 val, u32 expected_val) 359 { 360 return (val == expected_val); 361 } 362 363 static OSAL_INLINE bool comp_and(u32 val, u32 expected_val) 364 { 365 return (val & expected_val) == expected_val; 366 } 367 368 static OSAL_INLINE bool comp_or(u32 val, u32 expected_val) 369 { 370 return (val | expected_val) > 0; 371 } 372 373 /* init_ops read/poll commands */ 374 static void ecore_init_cmd_rd(struct ecore_hwfn *p_hwfn, 375 struct ecore_ptt *p_ptt, 376 struct init_read_op *cmd) 377 { 378 bool (*comp_check)(u32 val, u32 expected_val); 379 u32 delay = ECORE_INIT_POLL_PERIOD_US, val; 380 u32 data, addr, poll; 381 int i; 382 383 data = OSAL_LE32_TO_CPU(cmd->op_data); 384 addr = GET_FIELD(data, INIT_READ_OP_ADDRESS) << 2; 385 poll = GET_FIELD(data, INIT_READ_OP_POLL_TYPE); 386 387 #ifndef ASIC_ONLY 388 if (CHIP_REV_IS_EMUL(p_hwfn->p_dev)) 389 delay *= 100; 390 #endif 391 392 val = ecore_rd(p_hwfn, p_ptt, addr); 393 394 if (poll == INIT_POLL_NONE) 395 return; 396 397 switch (poll) { 398 case INIT_POLL_EQ: 399 comp_check = comp_eq; 400 break; 401 case INIT_POLL_OR: 402 comp_check = comp_or; 403 break; 404 case INIT_POLL_AND: 405 comp_check = comp_and; 406 break; 407 default: 408 DP_ERR(p_hwfn, "Invalid poll comparison type %08x\n", 409 cmd->op_data); 410 return; 411 } 412 413 data = OSAL_LE32_TO_CPU(cmd->expected_val); 414 for (i = 0; 415 i < ECORE_INIT_MAX_POLL_COUNT && !comp_check(val, data); 416 i++) { 417 OSAL_UDELAY(delay); 418 val = ecore_rd(p_hwfn, p_ptt, addr); 419 } 420 421 if (i == ECORE_INIT_MAX_POLL_COUNT) 422 DP_ERR(p_hwfn, "Timeout when polling reg: 0x%08x [ Waiting-for: %08x Got: %08x (comparsion %08x)]\n", 423 addr, 424 OSAL_LE32_TO_CPU(cmd->expected_val), val, 425 OSAL_LE32_TO_CPU(cmd->op_data)); 426 } 427 428 /* init_ops callbacks entry point */ 429 static void ecore_init_cmd_cb(struct ecore_hwfn *p_hwfn, 430 struct ecore_ptt *p_ptt, 431 struct init_callback_op *p_cmd) 432 { 433 DP_NOTICE(p_hwfn, true, "Currently init values have no need of callbacks\n"); 434 } 435 436 static u8 ecore_init_cmd_mode_match(struct ecore_hwfn *p_hwfn, 437 u16 *p_offset, int modes) 438 { 439 struct ecore_dev *p_dev = p_hwfn->p_dev; 440 const u8 *modes_tree_buf; 441 u8 arg1, arg2, tree_val; 442 443 modes_tree_buf = p_dev->fw_data->modes_tree_buf; 444 tree_val = modes_tree_buf[(*p_offset)++]; 445 switch(tree_val) { 446 case INIT_MODE_OP_NOT: 447 return ecore_init_cmd_mode_match(p_hwfn, p_offset, modes) ^ 1; 448 case INIT_MODE_OP_OR: 449 arg1 = ecore_init_cmd_mode_match(p_hwfn, p_offset, modes); 450 arg2 = ecore_init_cmd_mode_match(p_hwfn, p_offset, modes); 451 return arg1 | arg2; 452 case INIT_MODE_OP_AND: 453 arg1 = ecore_init_cmd_mode_match(p_hwfn, p_offset, modes); 454 arg2 = ecore_init_cmd_mode_match(p_hwfn, p_offset, modes); 455 return arg1 & arg2; 456 default: 457 tree_val -= MAX_INIT_MODE_OPS; 458 return (modes & (1 << tree_val)) ? 1 : 0; 459 } 460 } 461 462 static u32 ecore_init_cmd_mode(struct ecore_hwfn *p_hwfn, 463 struct init_if_mode_op *p_cmd, int modes) 464 { 465 u16 offset = OSAL_LE16_TO_CPU(p_cmd->modes_buf_offset); 466 467 if (ecore_init_cmd_mode_match(p_hwfn, &offset, modes)) 468 return 0; 469 else 470 return GET_FIELD(OSAL_LE32_TO_CPU(p_cmd->op_data), 471 INIT_IF_MODE_OP_CMD_OFFSET); 472 } 473 474 static u32 ecore_init_cmd_phase(struct ecore_hwfn *p_hwfn, 475 struct init_if_phase_op *p_cmd, 476 u32 phase, u32 phase_id) 477 { 478 u32 data = OSAL_LE32_TO_CPU(p_cmd->phase_data); 479 480 if (!(GET_FIELD(data, INIT_IF_PHASE_OP_PHASE) == phase && 481 (GET_FIELD(data, INIT_IF_PHASE_OP_PHASE_ID) == ANY_PHASE_ID || 482 GET_FIELD(data, INIT_IF_PHASE_OP_PHASE_ID) == phase_id))) 483 return GET_FIELD(OSAL_LE32_TO_CPU(p_cmd->op_data), 484 INIT_IF_PHASE_OP_CMD_OFFSET); 485 else 486 return 0; 487 } 488 489 enum _ecore_status_t ecore_init_run(struct ecore_hwfn *p_hwfn, 490 struct ecore_ptt *p_ptt, 491 int phase, 492 int phase_id, 493 int modes) 494 { 495 struct ecore_dev *p_dev = p_hwfn->p_dev; 496 u32 cmd_num, num_init_ops; 497 union init_op *init_ops; 498 bool b_dmae = false; 499 enum _ecore_status_t rc = ECORE_SUCCESS; 500 501 num_init_ops = p_dev->fw_data->init_ops_size; 502 init_ops = p_dev->fw_data->init_ops; 503 504 #ifdef CONFIG_ECORE_ZIPPED_FW 505 p_hwfn->unzip_buf = OSAL_ZALLOC(p_hwfn->p_dev, GFP_ATOMIC, 506 MAX_ZIPPED_SIZE * 4); 507 if (!p_hwfn->unzip_buf) { 508 DP_NOTICE(p_hwfn, true, "Failed to allocate unzip buffer\n"); 509 return ECORE_NOMEM; 510 } 511 #endif 512 513 for (cmd_num = 0; cmd_num < num_init_ops; cmd_num++) { 514 union init_op *cmd = &init_ops[cmd_num]; 515 u32 data = OSAL_LE32_TO_CPU(cmd->raw.op_data); 516 517 switch (GET_FIELD(data, INIT_CALLBACK_OP_OP)) { 518 case INIT_OP_WRITE: 519 rc = ecore_init_cmd_wr(p_hwfn, p_ptt, &cmd->write, 520 b_dmae); 521 break; 522 523 case INIT_OP_READ: 524 ecore_init_cmd_rd(p_hwfn, p_ptt, &cmd->read); 525 break; 526 527 case INIT_OP_IF_MODE: 528 cmd_num += ecore_init_cmd_mode(p_hwfn, &cmd->if_mode, 529 modes); 530 break; 531 case INIT_OP_IF_PHASE: 532 cmd_num += ecore_init_cmd_phase(p_hwfn, &cmd->if_phase, 533 phase, phase_id); 534 b_dmae = GET_FIELD(data, 535 INIT_IF_PHASE_OP_DMAE_ENABLE); 536 break; 537 case INIT_OP_DELAY: 538 /* ecore_init_run is always invoked from 539 * sleep-able context 540 */ 541 OSAL_UDELAY(cmd->delay.delay); 542 break; 543 544 case INIT_OP_CALLBACK: 545 ecore_init_cmd_cb(p_hwfn, p_ptt, &cmd->callback); 546 break; 547 } 548 549 if (rc) 550 break; 551 } 552 #ifdef CONFIG_ECORE_ZIPPED_FW 553 OSAL_FREE(p_hwfn->p_dev, p_hwfn->unzip_buf); 554 p_hwfn->unzip_buf = OSAL_NULL; 555 #endif 556 return rc; 557 } 558 559 void ecore_gtt_init(struct ecore_hwfn *p_hwfn) 560 { 561 u32 gtt_base; 562 u32 i; 563 564 #ifndef ASIC_ONLY 565 if (CHIP_REV_IS_SLOW(p_hwfn->p_dev)) { 566 /* This is done by MFW on ASIC; regardless, this should only 567 * be done once per chip [i.e., common]. Implementation is 568 * not too bright, but it should work on the simple FPGA/EMUL 569 * scenarios. 570 */ 571 static bool initialized = false; 572 int poll_cnt = 500; 573 u32 val; 574 575 /* initialize PTT/GTT (poll for completion) */ 576 if (!initialized) { 577 ecore_wr(p_hwfn, p_hwfn->p_main_ptt, 578 PGLUE_B_REG_START_INIT_PTT_GTT, 1); 579 initialized = true; 580 } 581 582 do { 583 /* ptt might be overrided by HW until this is done */ 584 OSAL_UDELAY(10); 585 ecore_ptt_invalidate(p_hwfn); 586 val = ecore_rd(p_hwfn, p_hwfn->p_main_ptt, 587 PGLUE_B_REG_INIT_DONE_PTT_GTT); 588 } while ((val != 1) && --poll_cnt); 589 590 if (!poll_cnt) 591 DP_ERR(p_hwfn, "PGLUE_B_REG_INIT_DONE didn't complete\n"); 592 } 593 #endif 594 595 /* Set the global windows */ 596 gtt_base = PXP_PF_WINDOW_ADMIN_START + PXP_PF_WINDOW_ADMIN_GLOBAL_START; 597 598 for (i = 0; i < OSAL_ARRAY_SIZE(pxp_global_win); i++) 599 if (pxp_global_win[i]) 600 REG_WR(p_hwfn, gtt_base + i * PXP_GLOBAL_ENTRY_SIZE, 601 pxp_global_win[i]); 602 } 603 604 enum _ecore_status_t ecore_init_fw_data(struct ecore_dev *p_dev, 605 const u8 *data) 606 { 607 struct ecore_fw_data *fw = p_dev->fw_data; 608 609 #ifdef CONFIG_ECORE_BINARY_FW 610 struct bin_buffer_hdr *buf_hdr; 611 u32 offset, len; 612 613 if (!data) { 614 DP_NOTICE(p_dev, true, "Invalid fw data\n"); 615 return ECORE_INVAL; 616 } 617 618 buf_hdr = (struct bin_buffer_hdr *)data; 619 620 offset = buf_hdr[BIN_BUF_INIT_FW_VER_INFO].offset; 621 fw->fw_ver_info = (struct fw_ver_info *)(data + offset); 622 623 offset = buf_hdr[BIN_BUF_INIT_CMD].offset; 624 fw->init_ops = (union init_op *)(data + offset); 625 626 offset = buf_hdr[BIN_BUF_INIT_VAL].offset; 627 fw->arr_data = (u32 *)(data + offset); 628 629 offset = buf_hdr[BIN_BUF_INIT_MODE_TREE].offset; 630 fw->modes_tree_buf = (u8 *)(data + offset); 631 len = buf_hdr[BIN_BUF_INIT_CMD].length; 632 fw->init_ops_size = len / sizeof(struct init_raw_op); 633 #else 634 fw->init_ops = (union init_op *)init_ops; 635 fw->arr_data = (u32 *)init_val; 636 fw->modes_tree_buf = (u8 *)modes_tree_buf; 637 fw->init_ops_size = init_ops_size; 638 #endif 639 640 return ECORE_SUCCESS; 641 } 642