diff options
Diffstat (limited to 'drivers/net/ethernet/qlogic/qed/qed_init_ops.c')
| -rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_init_ops.c | 187 |
1 files changed, 127 insertions, 60 deletions
diff --git a/drivers/net/ethernet/qlogic/qed/qed_init_ops.c b/drivers/net/ethernet/qlogic/qed/qed_init_ops.c index 34193c2f1699..b3bf9899c1a1 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_init_ops.c +++ b/drivers/net/ethernet/qlogic/qed/qed_init_ops.c @@ -1,33 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) /* QLogic qed NIC Driver * Copyright (c) 2015-2017 QLogic Corporation - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and /or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Copyright (c) 2019-2020 Marvell International Ltd. */ #include <linux/types.h> @@ -41,6 +15,7 @@ #include "qed_hsi.h" #include "qed_hw.h" #include "qed_init_ops.h" +#include "qed_iro_hsi.h" #include "qed_reg_addr.h" #include "qed_sriov.h" @@ -54,37 +29,110 @@ static u32 pxp_global_win[] = { 0x1c80, /* win 3: addr=0x1c80000, size=4096 bytes */ 0x1d00, /* win 4: addr=0x1d00000, size=4096 bytes */ 0x1d01, /* win 5: addr=0x1d01000, size=4096 bytes */ - 0x1d80, /* win 6: addr=0x1d80000, size=4096 bytes */ - 0x1d81, /* win 7: addr=0x1d81000, size=4096 bytes */ - 0x1d82, /* win 8: addr=0x1d82000, size=4096 bytes */ - 0x1e00, /* win 9: addr=0x1e00000, size=4096 bytes */ - 0x1e80, /* win 10: addr=0x1e80000, size=4096 bytes */ - 0x1f00, /* win 11: addr=0x1f00000, size=4096 bytes */ - 0, - 0, - 0, + 0x1d02, /* win 6: addr=0x1d02000, size=4096 bytes */ + 0x1d80, /* win 7: addr=0x1d80000, size=4096 bytes */ + 0x1d81, /* win 8: addr=0x1d81000, size=4096 bytes */ + 0x1d82, /* win 9: addr=0x1d82000, size=4096 bytes */ + 0x1e00, /* win 10: addr=0x1e00000, size=4096 bytes */ + 0x1e01, /* win 11: addr=0x1e01000, size=4096 bytes */ + 0x1e80, /* win 12: addr=0x1e80000, size=4096 bytes */ + 0x1f00, /* win 13: addr=0x1f00000, size=4096 bytes */ + 0x1c08, /* win 14: addr=0x1c08000, size=4096 bytes */ 0, 0, 0, 0, }; -void qed_init_iro_array(struct qed_dev *cdev) -{ - cdev->iro_arr = iro_arr; -} +/* IRO Array */ +static const u32 iro_arr[] = { + 0x00000000, 0x00000000, 0x00080000, + 0x00004478, 0x00000008, 0x00080000, + 0x00003288, 0x00000088, 0x00880000, + 0x000058a8, 0x00000020, 0x00200000, + 0x00003188, 0x00000008, 0x00080000, + 0x00000b00, 0x00000008, 0x00040000, + 0x00000a80, 0x00000008, 0x00040000, + 0x00000000, 0x00000008, 0x00020000, + 0x00000080, 0x00000008, 0x00040000, + 0x00000084, 0x00000008, 0x00020000, + 0x00005798, 0x00000004, 0x00040000, + 0x00004e50, 0x00000000, 0x00780000, + 0x00003e40, 0x00000000, 0x00780000, + 0x00004500, 0x00000000, 0x00780000, + 0x00003210, 0x00000000, 0x00780000, + 0x00003b50, 0x00000000, 0x00780000, + 0x00007f58, 0x00000000, 0x00780000, + 0x00005fd8, 0x00000000, 0x00080000, + 0x00007100, 0x00000000, 0x00080000, + 0x0000af20, 0x00000000, 0x00080000, + 0x00004398, 0x00000000, 0x00080000, + 0x0000a5a0, 0x00000000, 0x00080000, + 0x0000bde8, 0x00000000, 0x00080000, + 0x00000020, 0x00000004, 0x00040000, + 0x00005688, 0x00000010, 0x00100000, + 0x0000c210, 0x00000030, 0x00300000, + 0x0000b108, 0x00000038, 0x00380000, + 0x00003d20, 0x00000080, 0x00400000, + 0x0000bf60, 0x00000000, 0x00040000, + 0x00004560, 0x00040080, 0x00040000, + 0x000001f8, 0x00000004, 0x00040000, + 0x00003d60, 0x00000080, 0x00200000, + 0x00008960, 0x00000040, 0x00300000, + 0x0000e840, 0x00000060, 0x00600000, + 0x00004698, 0x00000080, 0x00380000, + 0x000107b8, 0x000000c0, 0x00c00000, + 0x000001f8, 0x00000002, 0x00020000, + 0x0000a260, 0x00000000, 0x01080000, + 0x0000a368, 0x00000008, 0x00080000, + 0x000001c0, 0x00000008, 0x00080000, + 0x000001f8, 0x00000008, 0x00080000, + 0x00000ac0, 0x00000008, 0x00080000, + 0x00002578, 0x00000008, 0x00080000, + 0x000024f8, 0x00000008, 0x00080000, + 0x00000280, 0x00000008, 0x00080000, + 0x00000680, 0x00080018, 0x00080000, + 0x00000b78, 0x00080018, 0x00020000, + 0x0000c600, 0x00000058, 0x003c0000, + 0x00012038, 0x00000020, 0x00100000, + 0x00011b00, 0x00000048, 0x00180000, + 0x00009650, 0x00000050, 0x00200000, + 0x00008b10, 0x00000040, 0x00280000, + 0x000116c0, 0x00000018, 0x00100000, + 0x0000c808, 0x00000048, 0x00380000, + 0x00011790, 0x00000020, 0x00200000, + 0x000046d0, 0x00000080, 0x00100000, + 0x00003618, 0x00000010, 0x00100000, + 0x0000a9e8, 0x00000008, 0x00010000, + 0x000097a0, 0x00000008, 0x00010000, + 0x00011a10, 0x00000008, 0x00010000, + 0x0000e9f8, 0x00000008, 0x00010000, + 0x00012648, 0x00000008, 0x00010000, + 0x000121c8, 0x00000008, 0x00010000, + 0x0000af08, 0x00000030, 0x00100000, + 0x0000d748, 0x00000028, 0x00280000, + 0x00009e68, 0x00000018, 0x00180000, + 0x00009fe8, 0x00000008, 0x00080000, + 0x00013ea8, 0x00000008, 0x00080000, + 0x00012f18, 0x00000018, 0x00180000, + 0x0000dfe8, 0x00500288, 0x00100000, + 0x000131a0, 0x00000138, 0x00280000, +}; -/* Runtime configuration helpers */ -void qed_init_clear_rt_data(struct qed_hwfn *p_hwfn) +void qed_init_iro_array(struct qed_dev *cdev) { - int i; - - for (i = 0; i < RUNTIME_ARRAY_SIZE; i++) - p_hwfn->rt_data.b_valid[i] = false; + cdev->iro_arr = iro_arr + E4_IRO_ARR_OFFSET; } void qed_init_store_rt_reg(struct qed_hwfn *p_hwfn, u32 rt_offset, u32 val) { + if (rt_offset >= RUNTIME_ARRAY_SIZE) { + DP_ERR(p_hwfn, + "Avoid storing %u in rt_data at index %u!\n", + val, rt_offset); + return; + } + p_hwfn->rt_data.init_val[rt_offset] = val; p_hwfn->rt_data.b_valid[rt_offset] = true; } @@ -94,6 +142,14 @@ void qed_init_store_rt_agg(struct qed_hwfn *p_hwfn, { size_t i; + if ((rt_offset + size - 1) >= RUNTIME_ARRAY_SIZE) { + DP_ERR(p_hwfn, + "Avoid storing values in rt_data at indices %u-%u!\n", + rt_offset, + (u32)(rt_offset + size - 1)); + return; + } + for (i = 0; i < size / sizeof(u32); i++) { p_hwfn->rt_data.init_val[rt_offset + i] = p_val[i]; p_hwfn->rt_data.b_valid[rt_offset + i] = true; @@ -106,7 +162,7 @@ static int qed_init_rt(struct qed_hwfn *p_hwfn, { u32 *p_init_val = &p_hwfn->rt_data.init_val[rt_offset]; bool *p_valid = &p_hwfn->rt_data.b_valid[rt_offset]; - u16 i, segment; + u16 i, j, segment; int rc = 0; /* Since not all RT entries are initialized, go over the RT and @@ -121,6 +177,7 @@ static int qed_init_rt(struct qed_hwfn *p_hwfn, */ if (!b_must_dmae) { qed_wr(p_hwfn, p_ptt, addr + (i << 2), p_init_val[i]); + p_valid[i] = false; continue; } @@ -131,10 +188,14 @@ static int qed_init_rt(struct qed_hwfn *p_hwfn, rc = qed_dmae_host2grc(p_hwfn, p_ptt, (uintptr_t)(p_init_val + i), - addr + (i << 2), segment, 0); + addr + (i << 2), segment, NULL); if (rc) return rc; + /* invalidate after writing */ + for (j = i; j < (u32)(i + segment); j++) + p_valid[j] = false; + /* Jump over the entire segment, including invalid entry */ i += segment; } @@ -194,7 +255,7 @@ static int qed_init_array_dmae(struct qed_hwfn *p_hwfn, } else { rc = qed_dmae_host2grc(p_hwfn, p_ptt, (uintptr_t)(buf + dmae_data_offset), - addr, size, 0); + addr, size, NULL); } return rc; @@ -202,9 +263,10 @@ static int qed_init_array_dmae(struct qed_hwfn *p_hwfn, static int qed_init_fill_dmae(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, - u32 addr, u32 fill, u32 fill_count) + u32 addr, u32 fill_count) { static u32 zero_buffer[DMAE_MAX_RW_SIZE]; + struct qed_dmae_params params = {}; memset(zero_buffer, 0, sizeof(u32) * DMAE_MAX_RW_SIZE); @@ -214,10 +276,10 @@ static int qed_init_fill_dmae(struct qed_hwfn *p_hwfn, * 3. p_hwfb->temp_data, * 4. fill_count */ - + SET_FIELD(params.flags, QED_DMAE_PARAMS_RW_REPL_SRC, 0x1); return qed_dmae_host2grc(p_hwfn, p_ptt, (uintptr_t)(&zero_buffer[0]), - addr, fill_count, QED_DMAE_FLAG_RW_REPL_SRC); + addr, fill_count, ¶ms); } static void qed_init_fill(struct qed_hwfn *p_hwfn, @@ -328,7 +390,7 @@ static int qed_init_cmd_wr(struct qed_hwfn *p_hwfn, case INIT_SRC_ZEROS: data = le32_to_cpu(p_cmd->args.zeros_count); if (b_must_dmae || (b_can_dmae && (data >= 64))) - rc = qed_init_fill_dmae(p_hwfn, p_ptt, addr, 0, data); + rc = qed_init_fill_dmae(p_hwfn, p_ptt, addr, data); else qed_init_fill(p_hwfn, p_ptt, addr, 0, data); break; @@ -375,7 +437,6 @@ static void qed_init_cmd_rd(struct qed_hwfn *p_hwfn, addr = GET_FIELD(data, INIT_READ_OP_ADDRESS) << 2; poll = GET_FIELD(data, INIT_READ_OP_POLL_TYPE); - val = qed_rd(p_hwfn, p_ptt, addr); if (poll == INIT_POLL_NONE) @@ -471,8 +532,7 @@ static u32 qed_init_cmd_mode(struct qed_hwfn *p_hwfn, INIT_IF_MODE_OP_CMD_OFFSET); } -static u32 qed_init_cmd_phase(struct qed_hwfn *p_hwfn, - struct init_if_phase_op *p_cmd, +static u32 qed_init_cmd_phase(struct init_if_phase_op *p_cmd, u32 phase, u32 phase_id) { u32 data = le32_to_cpu(p_cmd->phase_data); @@ -489,10 +549,10 @@ static u32 qed_init_cmd_phase(struct qed_hwfn *p_hwfn, int qed_init_run(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, int phase, int phase_id, int modes) { + bool b_dmae = (phase != PHASE_ENGINE); struct qed_dev *cdev = p_hwfn->cdev; u32 cmd_num, num_init_ops; union init_op *init_ops; - bool b_dmae = false; int rc = 0; num_init_ops = cdev->fw_data->init_ops_size; @@ -519,9 +579,8 @@ int qed_init_run(struct qed_hwfn *p_hwfn, modes); break; case INIT_OP_IF_PHASE: - cmd_num += qed_init_cmd_phase(p_hwfn, &cmd->if_phase, + cmd_num += qed_init_cmd_phase(&cmd->if_phase, phase, phase_id); - b_dmae = GET_FIELD(data, INIT_IF_PHASE_OP_DMAE_ENABLE); break; case INIT_OP_DELAY: /* qed_init_run is always invoked from @@ -532,6 +591,9 @@ int qed_init_run(struct qed_hwfn *p_hwfn, case INIT_OP_CALLBACK: rc = qed_init_cmd_cb(p_hwfn, p_ptt, &cmd->callback); + if (phase == PHASE_ENGINE && + cmd->callback.callback_id == DMAE_READY_CB) + b_dmae = true; break; } @@ -586,5 +648,10 @@ int qed_init_fw_data(struct qed_dev *cdev, const u8 *data) len = buf_hdr[BIN_BUF_INIT_CMD].length; fw->init_ops_size = len / sizeof(struct init_raw_op); + offset = buf_hdr[BIN_BUF_INIT_OVERLAYS].offset; + fw->fw_overlays = (u32 *)(data + offset); + len = buf_hdr[BIN_BUF_INIT_OVERLAYS].length; + fw->fw_overlays_len = len; + return 0; } |
