1fe56b9e6SYuval Mintz /* QLogic qed NIC Driver 2e8f1cb50SMintz, Yuval * Copyright (c) 2015-2017 QLogic Corporation 3fe56b9e6SYuval Mintz * 4e8f1cb50SMintz, Yuval * This software is available to you under a choice of one of two 5e8f1cb50SMintz, Yuval * licenses. You may choose to be licensed under the terms of the GNU 6e8f1cb50SMintz, Yuval * General Public License (GPL) Version 2, available from the file 7e8f1cb50SMintz, Yuval * COPYING in the main directory of this source tree, or the 8e8f1cb50SMintz, Yuval * OpenIB.org BSD license below: 9e8f1cb50SMintz, Yuval * 10e8f1cb50SMintz, Yuval * Redistribution and use in source and binary forms, with or 11e8f1cb50SMintz, Yuval * without modification, are permitted provided that the following 12e8f1cb50SMintz, Yuval * conditions are met: 13e8f1cb50SMintz, Yuval * 14e8f1cb50SMintz, Yuval * - Redistributions of source code must retain the above 15e8f1cb50SMintz, Yuval * copyright notice, this list of conditions and the following 16e8f1cb50SMintz, Yuval * disclaimer. 17e8f1cb50SMintz, Yuval * 18e8f1cb50SMintz, Yuval * - Redistributions in binary form must reproduce the above 19e8f1cb50SMintz, Yuval * copyright notice, this list of conditions and the following 20e8f1cb50SMintz, Yuval * disclaimer in the documentation and /or other materials 21e8f1cb50SMintz, Yuval * provided with the distribution. 22e8f1cb50SMintz, Yuval * 23e8f1cb50SMintz, Yuval * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24e8f1cb50SMintz, Yuval * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25e8f1cb50SMintz, Yuval * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26e8f1cb50SMintz, Yuval * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27e8f1cb50SMintz, Yuval * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28e8f1cb50SMintz, Yuval * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29e8f1cb50SMintz, Yuval * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30e8f1cb50SMintz, Yuval * SOFTWARE. 31fe56b9e6SYuval Mintz */ 32fe56b9e6SYuval Mintz 33fe56b9e6SYuval Mintz #include <linux/types.h> 34fe56b9e6SYuval Mintz #include <linux/delay.h> 35fe56b9e6SYuval Mintz #include <linux/kernel.h> 36fe56b9e6SYuval Mintz #include <linux/slab.h> 37fe56b9e6SYuval Mintz #include <linux/string.h> 38fe56b9e6SYuval Mintz #include "qed_hsi.h" 39fe56b9e6SYuval Mintz #include "qed_hw.h" 40fe56b9e6SYuval Mintz #include "qed_init_ops.h" 41fe56b9e6SYuval Mintz #include "qed_reg_addr.h" 42fe56b9e6SYuval Mintz 43fe56b9e6SYuval Mintz enum cminterface { 44fe56b9e6SYuval Mintz MCM_SEC, 45fe56b9e6SYuval Mintz MCM_PRI, 46fe56b9e6SYuval Mintz UCM_SEC, 47fe56b9e6SYuval Mintz UCM_PRI, 48fe56b9e6SYuval Mintz TCM_SEC, 49fe56b9e6SYuval Mintz TCM_PRI, 50fe56b9e6SYuval Mintz YCM_SEC, 51fe56b9e6SYuval Mintz YCM_PRI, 52fe56b9e6SYuval Mintz XCM_SEC, 53fe56b9e6SYuval Mintz XCM_PRI, 54fe56b9e6SYuval Mintz NUM_OF_CM_INTERFACES 55fe56b9e6SYuval Mintz }; 56fe56b9e6SYuval Mintz 57fe56b9e6SYuval Mintz /* general constants */ 58fe56b9e6SYuval Mintz #define QM_PQ_MEM_4KB(pq_size) (pq_size ? DIV_ROUND_UP((pq_size + 1) * \ 59fe56b9e6SYuval Mintz QM_PQ_ELEMENT_SIZE, \ 60fe56b9e6SYuval Mintz 0x1000) : 0) 61fe56b9e6SYuval Mintz #define QM_PQ_SIZE_256B(pq_size) (pq_size ? DIV_ROUND_UP(pq_size, \ 62fe56b9e6SYuval Mintz 0x100) - 1 : 0) 63fe56b9e6SYuval Mintz #define QM_INVALID_PQ_ID 0xffff 64fe56b9e6SYuval Mintz /* feature enable */ 65fe56b9e6SYuval Mintz #define QM_BYPASS_EN 1 66fe56b9e6SYuval Mintz #define QM_BYTE_CRD_EN 1 67fe56b9e6SYuval Mintz /* other PQ constants */ 68fe56b9e6SYuval Mintz #define QM_OTHER_PQS_PER_PF 4 69fe56b9e6SYuval Mintz /* WFQ constants */ 70351a4dedSYuval Mintz #define QM_WFQ_UPPER_BOUND 62500000 71fe56b9e6SYuval Mintz #define QM_WFQ_VP_PQ_VOQ_SHIFT 0 72fe56b9e6SYuval Mintz #define QM_WFQ_VP_PQ_PF_SHIFT 5 73fe56b9e6SYuval Mintz #define QM_WFQ_INC_VAL(weight) ((weight) * 0x9000) 74351a4dedSYuval Mintz #define QM_WFQ_MAX_INC_VAL 43750000 75351a4dedSYuval Mintz 76fe56b9e6SYuval Mintz /* RL constants */ 77351a4dedSYuval Mintz #define QM_RL_UPPER_BOUND 62500000 78fe56b9e6SYuval Mintz #define QM_RL_PERIOD 5 /* in us */ 79fe56b9e6SYuval Mintz #define QM_RL_PERIOD_CLK_25M (25 * QM_RL_PERIOD) 80351a4dedSYuval Mintz #define QM_RL_MAX_INC_VAL 43750000 81fe56b9e6SYuval Mintz #define QM_RL_INC_VAL(rate) max_t(u32, \ 82351a4dedSYuval Mintz (u32)(((rate ? rate : \ 83351a4dedSYuval Mintz 1000000) * \ 84351a4dedSYuval Mintz QM_RL_PERIOD * \ 85351a4dedSYuval Mintz 101) / (8 * 100)), 1) 86fe56b9e6SYuval Mintz /* AFullOprtnstcCrdMask constants */ 87fe56b9e6SYuval Mintz #define QM_OPPOR_LINE_VOQ_DEF 1 88fe56b9e6SYuval Mintz #define QM_OPPOR_FW_STOP_DEF 0 89fe56b9e6SYuval Mintz #define QM_OPPOR_PQ_EMPTY_DEF 1 90fe56b9e6SYuval Mintz /* Command Queue constants */ 91fe56b9e6SYuval Mintz #define PBF_CMDQ_PURE_LB_LINES 150 92fe56b9e6SYuval Mintz #define PBF_CMDQ_LINES_RT_OFFSET(voq) ( \ 93fe56b9e6SYuval Mintz PBF_REG_YCMD_QS_NUM_LINES_VOQ0_RT_OFFSET + voq * \ 94fe56b9e6SYuval Mintz (PBF_REG_YCMD_QS_NUM_LINES_VOQ1_RT_OFFSET - \ 95fe56b9e6SYuval Mintz PBF_REG_YCMD_QS_NUM_LINES_VOQ0_RT_OFFSET)) 96fe56b9e6SYuval Mintz #define PBF_BTB_GUARANTEED_RT_OFFSET(voq) ( \ 97fe56b9e6SYuval Mintz PBF_REG_BTB_GUARANTEED_VOQ0_RT_OFFSET + voq * \ 98fe56b9e6SYuval Mintz (PBF_REG_BTB_GUARANTEED_VOQ1_RT_OFFSET - \ 99fe56b9e6SYuval Mintz PBF_REG_BTB_GUARANTEED_VOQ0_RT_OFFSET)) 100fe56b9e6SYuval Mintz #define QM_VOQ_LINE_CRD(pbf_cmd_lines) ((((pbf_cmd_lines) - \ 101fe56b9e6SYuval Mintz 4) * \ 102fe56b9e6SYuval Mintz 2) | QM_LINE_CRD_REG_SIGN_BIT) 103fe56b9e6SYuval Mintz /* BTB: blocks constants (block size = 256B) */ 104fe56b9e6SYuval Mintz #define BTB_JUMBO_PKT_BLOCKS 38 105fe56b9e6SYuval Mintz #define BTB_HEADROOM_BLOCKS BTB_JUMBO_PKT_BLOCKS 106fe56b9e6SYuval Mintz #define BTB_PURE_LB_FACTOR 10 107fe56b9e6SYuval Mintz #define BTB_PURE_LB_RATIO 7 108fe56b9e6SYuval Mintz /* QM stop command constants */ 109fe56b9e6SYuval Mintz #define QM_STOP_PQ_MASK_WIDTH 32 110fe56b9e6SYuval Mintz #define QM_STOP_CMD_ADDR 0x2 111fe56b9e6SYuval Mintz #define QM_STOP_CMD_STRUCT_SIZE 2 112fe56b9e6SYuval Mintz #define QM_STOP_CMD_PAUSE_MASK_OFFSET 0 113fe56b9e6SYuval Mintz #define QM_STOP_CMD_PAUSE_MASK_SHIFT 0 114fe56b9e6SYuval Mintz #define QM_STOP_CMD_PAUSE_MASK_MASK -1 115fe56b9e6SYuval Mintz #define QM_STOP_CMD_GROUP_ID_OFFSET 1 116fe56b9e6SYuval Mintz #define QM_STOP_CMD_GROUP_ID_SHIFT 16 117fe56b9e6SYuval Mintz #define QM_STOP_CMD_GROUP_ID_MASK 15 118fe56b9e6SYuval Mintz #define QM_STOP_CMD_PQ_TYPE_OFFSET 1 119fe56b9e6SYuval Mintz #define QM_STOP_CMD_PQ_TYPE_SHIFT 24 120fe56b9e6SYuval Mintz #define QM_STOP_CMD_PQ_TYPE_MASK 1 121fe56b9e6SYuval Mintz #define QM_STOP_CMD_MAX_POLL_COUNT 100 122fe56b9e6SYuval Mintz #define QM_STOP_CMD_POLL_PERIOD_US 500 123fe56b9e6SYuval Mintz /* QM command macros */ 124fe56b9e6SYuval Mintz #define QM_CMD_STRUCT_SIZE(cmd) cmd ## \ 125fe56b9e6SYuval Mintz _STRUCT_SIZE 126fe56b9e6SYuval Mintz #define QM_CMD_SET_FIELD(var, cmd, field, \ 127fe56b9e6SYuval Mintz value) SET_FIELD(var[cmd ## _ ## field ## \ 128fe56b9e6SYuval Mintz _OFFSET], \ 129fe56b9e6SYuval Mintz cmd ## _ ## field, \ 130fe56b9e6SYuval Mintz value) 131fe56b9e6SYuval Mintz /* QM: VOQ macros */ 132351a4dedSYuval Mintz #define PHYS_VOQ(port, tc, max_phys_tcs_per_port) ((port) * \ 133351a4dedSYuval Mintz (max_phys_tcs_per_port) + \ 134351a4dedSYuval Mintz (tc)) 135fe56b9e6SYuval Mintz #define LB_VOQ(port) ( \ 136fe56b9e6SYuval Mintz MAX_PHYS_VOQS + (port)) 137fe56b9e6SYuval Mintz #define VOQ(port, tc, max_phy_tcs_pr_port) \ 138fe56b9e6SYuval Mintz ((tc) < \ 139fe56b9e6SYuval Mintz LB_TC ? PHYS_VOQ(port, \ 140fe56b9e6SYuval Mintz tc, \ 141fe56b9e6SYuval Mintz max_phy_tcs_pr_port) \ 142fe56b9e6SYuval Mintz : LB_VOQ(port)) 143fe56b9e6SYuval Mintz /******************** INTERNAL IMPLEMENTATION *********************/ 144fe56b9e6SYuval Mintz /* Prepare PF RL enable/disable runtime init values */ 145351a4dedSYuval Mintz static void qed_enable_pf_rl(struct qed_hwfn *p_hwfn, bool pf_rl_en) 146fe56b9e6SYuval Mintz { 147fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_RLPFENABLE_RT_OFFSET, pf_rl_en ? 1 : 0); 148fe56b9e6SYuval Mintz if (pf_rl_en) { 149fe56b9e6SYuval Mintz /* enable RLs for all VOQs */ 150fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_RLPFVOQENABLE_RT_OFFSET, 151fe56b9e6SYuval Mintz (1 << MAX_NUM_VOQS) - 1); 152fe56b9e6SYuval Mintz /* write RL period */ 153fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 154351a4dedSYuval Mintz QM_REG_RLPFPERIOD_RT_OFFSET, QM_RL_PERIOD_CLK_25M); 155fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 156fe56b9e6SYuval Mintz QM_REG_RLPFPERIODTIMER_RT_OFFSET, 157fe56b9e6SYuval Mintz QM_RL_PERIOD_CLK_25M); 158fe56b9e6SYuval Mintz /* set credit threshold for QM bypass flow */ 159fe56b9e6SYuval Mintz if (QM_BYPASS_EN) 160fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 161fe56b9e6SYuval Mintz QM_REG_AFULLQMBYPTHRPFRL_RT_OFFSET, 162fe56b9e6SYuval Mintz QM_RL_UPPER_BOUND); 163fe56b9e6SYuval Mintz } 164fe56b9e6SYuval Mintz } 165fe56b9e6SYuval Mintz 166fe56b9e6SYuval Mintz /* Prepare PF WFQ enable/disable runtime init values */ 167351a4dedSYuval Mintz static void qed_enable_pf_wfq(struct qed_hwfn *p_hwfn, bool pf_wfq_en) 168fe56b9e6SYuval Mintz { 169fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_WFQPFENABLE_RT_OFFSET, pf_wfq_en ? 1 : 0); 170fe56b9e6SYuval Mintz /* set credit threshold for QM bypass flow */ 171fe56b9e6SYuval Mintz if (pf_wfq_en && QM_BYPASS_EN) 172fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 173fe56b9e6SYuval Mintz QM_REG_AFULLQMBYPTHRPFWFQ_RT_OFFSET, 174fe56b9e6SYuval Mintz QM_WFQ_UPPER_BOUND); 175fe56b9e6SYuval Mintz } 176fe56b9e6SYuval Mintz 177fe56b9e6SYuval Mintz /* Prepare VPORT RL enable/disable runtime init values */ 178351a4dedSYuval Mintz static void qed_enable_vport_rl(struct qed_hwfn *p_hwfn, bool vport_rl_en) 179fe56b9e6SYuval Mintz { 180fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_RLGLBLENABLE_RT_OFFSET, 181fe56b9e6SYuval Mintz vport_rl_en ? 1 : 0); 182fe56b9e6SYuval Mintz if (vport_rl_en) { 183fe56b9e6SYuval Mintz /* write RL period (use timer 0 only) */ 184fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 185fe56b9e6SYuval Mintz QM_REG_RLGLBLPERIOD_0_RT_OFFSET, 186fe56b9e6SYuval Mintz QM_RL_PERIOD_CLK_25M); 187fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 188fe56b9e6SYuval Mintz QM_REG_RLGLBLPERIODTIMER_0_RT_OFFSET, 189fe56b9e6SYuval Mintz QM_RL_PERIOD_CLK_25M); 190fe56b9e6SYuval Mintz /* set credit threshold for QM bypass flow */ 191fe56b9e6SYuval Mintz if (QM_BYPASS_EN) 192fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 193fe56b9e6SYuval Mintz QM_REG_AFULLQMBYPTHRGLBLRL_RT_OFFSET, 194fe56b9e6SYuval Mintz QM_RL_UPPER_BOUND); 195fe56b9e6SYuval Mintz } 196fe56b9e6SYuval Mintz } 197fe56b9e6SYuval Mintz 198fe56b9e6SYuval Mintz /* Prepare VPORT WFQ enable/disable runtime init values */ 199351a4dedSYuval Mintz static void qed_enable_vport_wfq(struct qed_hwfn *p_hwfn, bool vport_wfq_en) 200fe56b9e6SYuval Mintz { 201fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_WFQVPENABLE_RT_OFFSET, 202fe56b9e6SYuval Mintz vport_wfq_en ? 1 : 0); 203fe56b9e6SYuval Mintz /* set credit threshold for QM bypass flow */ 204fe56b9e6SYuval Mintz if (vport_wfq_en && QM_BYPASS_EN) 205fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 206fe56b9e6SYuval Mintz QM_REG_AFULLQMBYPTHRVPWFQ_RT_OFFSET, 207fe56b9e6SYuval Mintz QM_WFQ_UPPER_BOUND); 208fe56b9e6SYuval Mintz } 209fe56b9e6SYuval Mintz 210fe56b9e6SYuval Mintz /* Prepare runtime init values to allocate PBF command queue lines for 211fe56b9e6SYuval Mintz * the specified VOQ 212fe56b9e6SYuval Mintz */ 213fe56b9e6SYuval Mintz static void qed_cmdq_lines_voq_rt_init(struct qed_hwfn *p_hwfn, 214351a4dedSYuval Mintz u8 voq, u16 cmdq_lines) 215fe56b9e6SYuval Mintz { 216fe56b9e6SYuval Mintz u32 qm_line_crd; 217fe56b9e6SYuval Mintz 218fe56b9e6SYuval Mintz /* In A0 - Limit the size of pbf queue so that only 511 commands with 219fe56b9e6SYuval Mintz * the minimum size of 4 (FCoE minimum size) 220fe56b9e6SYuval Mintz */ 221fe56b9e6SYuval Mintz bool is_bb_a0 = QED_IS_BB_A0(p_hwfn->cdev); 222fe56b9e6SYuval Mintz 223fe56b9e6SYuval Mintz if (is_bb_a0) 224fe56b9e6SYuval Mintz cmdq_lines = min_t(u32, cmdq_lines, 1022); 225fe56b9e6SYuval Mintz qm_line_crd = QM_VOQ_LINE_CRD(cmdq_lines); 226fe56b9e6SYuval Mintz OVERWRITE_RT_REG(p_hwfn, PBF_CMDQ_LINES_RT_OFFSET(voq), 227fe56b9e6SYuval Mintz (u32)cmdq_lines); 228fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_VOQCRDLINE_RT_OFFSET + voq, qm_line_crd); 229fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_VOQINITCRDLINE_RT_OFFSET + voq, 230fe56b9e6SYuval Mintz qm_line_crd); 231fe56b9e6SYuval Mintz } 232fe56b9e6SYuval Mintz 233fe56b9e6SYuval Mintz /* Prepare runtime init values to allocate PBF command queue lines. */ 234fe56b9e6SYuval Mintz static void qed_cmdq_lines_rt_init( 235fe56b9e6SYuval Mintz struct qed_hwfn *p_hwfn, 236fe56b9e6SYuval Mintz u8 max_ports_per_engine, 237fe56b9e6SYuval Mintz u8 max_phys_tcs_per_port, 238fe56b9e6SYuval Mintz struct init_qm_port_params port_params[MAX_NUM_PORTS]) 239fe56b9e6SYuval Mintz { 240351a4dedSYuval Mintz u8 tc, voq, port_id, num_tcs_in_port; 241fe56b9e6SYuval Mintz 242fe56b9e6SYuval Mintz /* clear PBF lines for all VOQs */ 243fe56b9e6SYuval Mintz for (voq = 0; voq < MAX_NUM_VOQS; voq++) 244fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, PBF_CMDQ_LINES_RT_OFFSET(voq), 0); 245fe56b9e6SYuval Mintz for (port_id = 0; port_id < max_ports_per_engine; port_id++) { 246fe56b9e6SYuval Mintz if (port_params[port_id].active) { 247fe56b9e6SYuval Mintz u16 phys_lines, phys_lines_per_tc; 248fe56b9e6SYuval Mintz 249351a4dedSYuval Mintz /* find #lines to divide between active phys TCs */ 250fe56b9e6SYuval Mintz phys_lines = port_params[port_id].num_pbf_cmd_lines - 251fe56b9e6SYuval Mintz PBF_CMDQ_PURE_LB_LINES; 252fe56b9e6SYuval Mintz /* find #lines per active physical TC */ 253351a4dedSYuval Mintz num_tcs_in_port = 0; 254351a4dedSYuval Mintz for (tc = 0; tc < NUM_OF_PHYS_TCS; tc++) { 255351a4dedSYuval Mintz if (((port_params[port_id].active_phys_tcs >> 256351a4dedSYuval Mintz tc) & 0x1) == 1) 257351a4dedSYuval Mintz num_tcs_in_port++; 258351a4dedSYuval Mintz } 259351a4dedSYuval Mintz 260351a4dedSYuval Mintz phys_lines_per_tc = phys_lines / num_tcs_in_port; 261fe56b9e6SYuval Mintz /* init registers per active TC */ 262351a4dedSYuval Mintz for (tc = 0; tc < NUM_OF_PHYS_TCS; tc++) { 263351a4dedSYuval Mintz if (((port_params[port_id].active_phys_tcs >> 264351a4dedSYuval Mintz tc) & 0x1) != 1) 265351a4dedSYuval Mintz continue; 266351a4dedSYuval Mintz 267fe56b9e6SYuval Mintz voq = PHYS_VOQ(port_id, tc, 268fe56b9e6SYuval Mintz max_phys_tcs_per_port); 269fe56b9e6SYuval Mintz qed_cmdq_lines_voq_rt_init(p_hwfn, voq, 270fe56b9e6SYuval Mintz phys_lines_per_tc); 271fe56b9e6SYuval Mintz } 272351a4dedSYuval Mintz 273fe56b9e6SYuval Mintz /* init registers for pure LB TC */ 274fe56b9e6SYuval Mintz qed_cmdq_lines_voq_rt_init(p_hwfn, LB_VOQ(port_id), 275fe56b9e6SYuval Mintz PBF_CMDQ_PURE_LB_LINES); 276fe56b9e6SYuval Mintz } 277fe56b9e6SYuval Mintz } 278fe56b9e6SYuval Mintz } 279fe56b9e6SYuval Mintz 280fe56b9e6SYuval Mintz static void qed_btb_blocks_rt_init( 281fe56b9e6SYuval Mintz struct qed_hwfn *p_hwfn, 282fe56b9e6SYuval Mintz u8 max_ports_per_engine, 283fe56b9e6SYuval Mintz u8 max_phys_tcs_per_port, 284fe56b9e6SYuval Mintz struct init_qm_port_params port_params[MAX_NUM_PORTS]) 285fe56b9e6SYuval Mintz { 286fe56b9e6SYuval Mintz u32 usable_blocks, pure_lb_blocks, phys_blocks; 287351a4dedSYuval Mintz u8 tc, voq, port_id, num_tcs_in_port; 288fe56b9e6SYuval Mintz 289fe56b9e6SYuval Mintz for (port_id = 0; port_id < max_ports_per_engine; port_id++) { 290fe56b9e6SYuval Mintz u32 temp; 291fe56b9e6SYuval Mintz 292fe56b9e6SYuval Mintz if (!port_params[port_id].active) 293fe56b9e6SYuval Mintz continue; 294fe56b9e6SYuval Mintz 295fe56b9e6SYuval Mintz /* subtract headroom blocks */ 296fe56b9e6SYuval Mintz usable_blocks = port_params[port_id].num_btb_blocks - 297fe56b9e6SYuval Mintz BTB_HEADROOM_BLOCKS; 298fe56b9e6SYuval Mintz 299351a4dedSYuval Mintz /* find blocks per physical TC */ 300351a4dedSYuval Mintz num_tcs_in_port = 0; 301351a4dedSYuval Mintz for (tc = 0; tc < NUM_OF_PHYS_TCS; tc++) { 302351a4dedSYuval Mintz if (((port_params[port_id].active_phys_tcs >> 303351a4dedSYuval Mintz tc) & 0x1) == 1) 304351a4dedSYuval Mintz num_tcs_in_port++; 305351a4dedSYuval Mintz } 306351a4dedSYuval Mintz 307fe56b9e6SYuval Mintz pure_lb_blocks = (usable_blocks * BTB_PURE_LB_FACTOR) / 308351a4dedSYuval Mintz (num_tcs_in_port * BTB_PURE_LB_FACTOR + 309fe56b9e6SYuval Mintz BTB_PURE_LB_RATIO); 310fe56b9e6SYuval Mintz pure_lb_blocks = max_t(u32, BTB_JUMBO_PKT_BLOCKS, 311fe56b9e6SYuval Mintz pure_lb_blocks / BTB_PURE_LB_FACTOR); 312351a4dedSYuval Mintz phys_blocks = (usable_blocks - pure_lb_blocks) / 313351a4dedSYuval Mintz num_tcs_in_port; 314fe56b9e6SYuval Mintz 315fe56b9e6SYuval Mintz /* init physical TCs */ 316351a4dedSYuval Mintz for (tc = 0; tc < NUM_OF_PHYS_TCS; tc++) { 317351a4dedSYuval Mintz if (((port_params[port_id].active_phys_tcs >> 318351a4dedSYuval Mintz tc) & 0x1) != 1) 319351a4dedSYuval Mintz continue; 320351a4dedSYuval Mintz 321351a4dedSYuval Mintz voq = PHYS_VOQ(port_id, tc, 322351a4dedSYuval Mintz max_phys_tcs_per_port); 323fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, PBF_BTB_GUARANTEED_RT_OFFSET(voq), 324fe56b9e6SYuval Mintz phys_blocks); 325fe56b9e6SYuval Mintz } 326fe56b9e6SYuval Mintz 327fe56b9e6SYuval Mintz /* init pure LB TC */ 328fe56b9e6SYuval Mintz temp = LB_VOQ(port_id); 329fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, PBF_BTB_GUARANTEED_RT_OFFSET(temp), 330fe56b9e6SYuval Mintz pure_lb_blocks); 331fe56b9e6SYuval Mintz } 332fe56b9e6SYuval Mintz } 333fe56b9e6SYuval Mintz 334fe56b9e6SYuval Mintz /* Prepare Tx PQ mapping runtime init values for the specified PF */ 335fe56b9e6SYuval Mintz static void qed_tx_pq_map_rt_init( 336fe56b9e6SYuval Mintz struct qed_hwfn *p_hwfn, 337fe56b9e6SYuval Mintz struct qed_ptt *p_ptt, 338fe56b9e6SYuval Mintz struct qed_qm_pf_rt_init_params *p_params, 339fe56b9e6SYuval Mintz u32 base_mem_addr_4kb) 340fe56b9e6SYuval Mintz { 341fe56b9e6SYuval Mintz struct init_qm_vport_params *vport_params = p_params->vport_params; 342fe56b9e6SYuval Mintz u16 num_pqs = p_params->num_pf_pqs + p_params->num_vf_pqs; 343fe56b9e6SYuval Mintz u16 first_pq_group = p_params->start_pq / QM_PF_QUEUE_GROUP_SIZE; 344fe56b9e6SYuval Mintz u16 last_pq_group = (p_params->start_pq + num_pqs - 1) / 345fe56b9e6SYuval Mintz QM_PF_QUEUE_GROUP_SIZE; 346fe56b9e6SYuval Mintz bool is_bb_a0 = QED_IS_BB_A0(p_hwfn->cdev); 347fe56b9e6SYuval Mintz u16 i, pq_id, pq_group; 348fe56b9e6SYuval Mintz 349fe56b9e6SYuval Mintz /* a bit per Tx PQ indicating if the PQ is associated with a VF */ 350fe56b9e6SYuval Mintz u32 tx_pq_vf_mask[MAX_QM_TX_QUEUES / QM_PF_QUEUE_GROUP_SIZE] = { 0 }; 351fe56b9e6SYuval Mintz u32 tx_pq_vf_mask_width = is_bb_a0 ? 32 : QM_PF_QUEUE_GROUP_SIZE; 352fe56b9e6SYuval Mintz u32 num_tx_pq_vf_masks = MAX_QM_TX_QUEUES / tx_pq_vf_mask_width; 353fe56b9e6SYuval Mintz u32 pq_mem_4kb = QM_PQ_MEM_4KB(p_params->num_pf_cids); 354fe56b9e6SYuval Mintz u32 vport_pq_mem_4kb = QM_PQ_MEM_4KB(p_params->num_vf_cids); 355fe56b9e6SYuval Mintz u32 mem_addr_4kb = base_mem_addr_4kb; 356fe56b9e6SYuval Mintz 357fe56b9e6SYuval Mintz /* set mapping from PQ group to PF */ 358fe56b9e6SYuval Mintz for (pq_group = first_pq_group; pq_group <= last_pq_group; pq_group++) 359fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_PQTX2PF_0_RT_OFFSET + pq_group, 360fe56b9e6SYuval Mintz (u32)(p_params->pf_id)); 361fe56b9e6SYuval Mintz /* set PQ sizes */ 362fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_MAXPQSIZE_0_RT_OFFSET, 363fe56b9e6SYuval Mintz QM_PQ_SIZE_256B(p_params->num_pf_cids)); 364fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_MAXPQSIZE_1_RT_OFFSET, 365fe56b9e6SYuval Mintz QM_PQ_SIZE_256B(p_params->num_vf_cids)); 366fe56b9e6SYuval Mintz 367fe56b9e6SYuval Mintz /* go over all Tx PQs */ 368fe56b9e6SYuval Mintz for (i = 0, pq_id = p_params->start_pq; i < num_pqs; i++, pq_id++) { 369fe56b9e6SYuval Mintz u8 voq = VOQ(p_params->port_id, p_params->pq_params[i].tc_id, 370fe56b9e6SYuval Mintz p_params->max_phys_tcs_per_port); 371fe56b9e6SYuval Mintz bool is_vf_pq = (i >= p_params->num_pf_pqs); 372fe56b9e6SYuval Mintz struct qm_rf_pq_map tx_pq_map; 373fe56b9e6SYuval Mintz 374fe56b9e6SYuval Mintz /* update first Tx PQ of VPORT/TC */ 375fe56b9e6SYuval Mintz u8 vport_id_in_pf = p_params->pq_params[i].vport_id - 376fe56b9e6SYuval Mintz p_params->start_vport; 377fe56b9e6SYuval Mintz u16 *pq_ids = &vport_params[vport_id_in_pf].first_tx_pq_id[0]; 378fe56b9e6SYuval Mintz u16 first_tx_pq_id = pq_ids[p_params->pq_params[i].tc_id]; 379fe56b9e6SYuval Mintz 380fe56b9e6SYuval Mintz if (first_tx_pq_id == QM_INVALID_PQ_ID) { 381fe56b9e6SYuval Mintz /* create new VP PQ */ 382fe56b9e6SYuval Mintz pq_ids[p_params->pq_params[i].tc_id] = pq_id; 383fe56b9e6SYuval Mintz first_tx_pq_id = pq_id; 384fe56b9e6SYuval Mintz /* map VP PQ to VOQ and PF */ 385fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 386fe56b9e6SYuval Mintz QM_REG_WFQVPMAP_RT_OFFSET + 387fe56b9e6SYuval Mintz first_tx_pq_id, 388fe56b9e6SYuval Mintz (voq << QM_WFQ_VP_PQ_VOQ_SHIFT) | 389fe56b9e6SYuval Mintz (p_params->pf_id << 390fe56b9e6SYuval Mintz QM_WFQ_VP_PQ_PF_SHIFT)); 391fe56b9e6SYuval Mintz } 392fe56b9e6SYuval Mintz /* fill PQ map entry */ 393fe56b9e6SYuval Mintz memset(&tx_pq_map, 0, sizeof(tx_pq_map)); 394fe56b9e6SYuval Mintz SET_FIELD(tx_pq_map.reg, QM_RF_PQ_MAP_PQ_VALID, 1); 395fe56b9e6SYuval Mintz SET_FIELD(tx_pq_map.reg, QM_RF_PQ_MAP_RL_VALID, 396351a4dedSYuval Mintz p_params->pq_params[i].rl_valid ? 1 : 0); 397fe56b9e6SYuval Mintz SET_FIELD(tx_pq_map.reg, QM_RF_PQ_MAP_VP_PQ_ID, first_tx_pq_id); 398fe56b9e6SYuval Mintz SET_FIELD(tx_pq_map.reg, QM_RF_PQ_MAP_RL_ID, 399351a4dedSYuval Mintz p_params->pq_params[i].rl_valid ? 400351a4dedSYuval Mintz p_params->pq_params[i].vport_id : 0); 401fe56b9e6SYuval Mintz SET_FIELD(tx_pq_map.reg, QM_RF_PQ_MAP_VOQ, voq); 402fe56b9e6SYuval Mintz SET_FIELD(tx_pq_map.reg, QM_RF_PQ_MAP_WRR_WEIGHT_GROUP, 403fe56b9e6SYuval Mintz p_params->pq_params[i].wrr_group); 404fe56b9e6SYuval Mintz /* write PQ map entry to CAM */ 405fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_TXPQMAP_RT_OFFSET + pq_id, 406fe56b9e6SYuval Mintz *((u32 *)&tx_pq_map)); 407fe56b9e6SYuval Mintz /* set base address */ 408fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 409fe56b9e6SYuval Mintz QM_REG_BASEADDRTXPQ_RT_OFFSET + pq_id, 410fe56b9e6SYuval Mintz mem_addr_4kb); 411fe56b9e6SYuval Mintz /* check if VF PQ */ 412fe56b9e6SYuval Mintz if (is_vf_pq) { 413fe56b9e6SYuval Mintz /* if PQ is associated with a VF, add indication 414fe56b9e6SYuval Mintz * to PQ VF mask 415fe56b9e6SYuval Mintz */ 416fe56b9e6SYuval Mintz tx_pq_vf_mask[pq_id / tx_pq_vf_mask_width] |= 417fe56b9e6SYuval Mintz (1 << (pq_id % tx_pq_vf_mask_width)); 418fe56b9e6SYuval Mintz mem_addr_4kb += vport_pq_mem_4kb; 419fe56b9e6SYuval Mintz } else { 420fe56b9e6SYuval Mintz mem_addr_4kb += pq_mem_4kb; 421fe56b9e6SYuval Mintz } 422fe56b9e6SYuval Mintz } 423fe56b9e6SYuval Mintz 424fe56b9e6SYuval Mintz /* store Tx PQ VF mask to size select register */ 425fe56b9e6SYuval Mintz for (i = 0; i < num_tx_pq_vf_masks; i++) { 426fe56b9e6SYuval Mintz if (tx_pq_vf_mask[i]) { 427fe56b9e6SYuval Mintz u32 addr; 428fe56b9e6SYuval Mintz 429fe56b9e6SYuval Mintz addr = QM_REG_MAXPQSIZETXSEL_0_RT_OFFSET + i; 430fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, addr, 431fe56b9e6SYuval Mintz tx_pq_vf_mask[i]); 432fe56b9e6SYuval Mintz } 433fe56b9e6SYuval Mintz } 434fe56b9e6SYuval Mintz } 435fe56b9e6SYuval Mintz 436fe56b9e6SYuval Mintz /* Prepare Other PQ mapping runtime init values for the specified PF */ 437fe56b9e6SYuval Mintz static void qed_other_pq_map_rt_init(struct qed_hwfn *p_hwfn, 438fe56b9e6SYuval Mintz u8 port_id, 439fe56b9e6SYuval Mintz u8 pf_id, 440fe56b9e6SYuval Mintz u32 num_pf_cids, 441351a4dedSYuval Mintz u32 num_tids, u32 base_mem_addr_4kb) 442fe56b9e6SYuval Mintz { 443fe56b9e6SYuval Mintz u16 i, pq_id; 444fe56b9e6SYuval Mintz 445fe56b9e6SYuval Mintz /* a single other PQ group is used in each PF, 446fe56b9e6SYuval Mintz * where PQ group i is used in PF i. 447fe56b9e6SYuval Mintz */ 448fe56b9e6SYuval Mintz u16 pq_group = pf_id; 449fe56b9e6SYuval Mintz u32 pq_size = num_pf_cids + num_tids; 450fe56b9e6SYuval Mintz u32 pq_mem_4kb = QM_PQ_MEM_4KB(pq_size); 451fe56b9e6SYuval Mintz u32 mem_addr_4kb = base_mem_addr_4kb; 452fe56b9e6SYuval Mintz 453fe56b9e6SYuval Mintz /* map PQ group to PF */ 454fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_PQOTHER2PF_0_RT_OFFSET + pq_group, 455fe56b9e6SYuval Mintz (u32)(pf_id)); 456fe56b9e6SYuval Mintz /* set PQ sizes */ 457fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_MAXPQSIZE_2_RT_OFFSET, 458fe56b9e6SYuval Mintz QM_PQ_SIZE_256B(pq_size)); 459fe56b9e6SYuval Mintz /* set base address */ 460fe56b9e6SYuval Mintz for (i = 0, pq_id = pf_id * QM_PF_QUEUE_GROUP_SIZE; 461fe56b9e6SYuval Mintz i < QM_OTHER_PQS_PER_PF; i++, pq_id++) { 462fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 463fe56b9e6SYuval Mintz QM_REG_BASEADDROTHERPQ_RT_OFFSET + pq_id, 464fe56b9e6SYuval Mintz mem_addr_4kb); 465fe56b9e6SYuval Mintz mem_addr_4kb += pq_mem_4kb; 466fe56b9e6SYuval Mintz } 467fe56b9e6SYuval Mintz } 468fe56b9e6SYuval Mintz 469fe56b9e6SYuval Mintz /* Prepare PF WFQ runtime init values for the specified PF. 470fe56b9e6SYuval Mintz * Return -1 on error. 471fe56b9e6SYuval Mintz */ 472fe56b9e6SYuval Mintz static int qed_pf_wfq_rt_init(struct qed_hwfn *p_hwfn, 473fe56b9e6SYuval Mintz struct qed_qm_pf_rt_init_params *p_params) 474fe56b9e6SYuval Mintz { 475fe56b9e6SYuval Mintz u16 num_tx_pqs = p_params->num_pf_pqs + p_params->num_vf_pqs; 476fe56b9e6SYuval Mintz u32 crd_reg_offset; 477fe56b9e6SYuval Mintz u32 inc_val; 478fe56b9e6SYuval Mintz u16 i; 479fe56b9e6SYuval Mintz 480fe56b9e6SYuval Mintz if (p_params->pf_id < MAX_NUM_PFS_BB) 481fe56b9e6SYuval Mintz crd_reg_offset = QM_REG_WFQPFCRD_RT_OFFSET; 482fe56b9e6SYuval Mintz else 483fe56b9e6SYuval Mintz crd_reg_offset = QM_REG_WFQPFCRD_MSB_RT_OFFSET + 484fe56b9e6SYuval Mintz (p_params->pf_id % MAX_NUM_PFS_BB); 485fe56b9e6SYuval Mintz 486fe56b9e6SYuval Mintz inc_val = QM_WFQ_INC_VAL(p_params->pf_wfq); 487351a4dedSYuval Mintz if (!inc_val || inc_val > QM_WFQ_MAX_INC_VAL) { 488fe56b9e6SYuval Mintz DP_NOTICE(p_hwfn, "Invalid PF WFQ weight configuration"); 489fe56b9e6SYuval Mintz return -1; 490fe56b9e6SYuval Mintz } 491fe56b9e6SYuval Mintz 492fe56b9e6SYuval Mintz for (i = 0; i < num_tx_pqs; i++) { 493fe56b9e6SYuval Mintz u8 voq = VOQ(p_params->port_id, p_params->pq_params[i].tc_id, 494fe56b9e6SYuval Mintz p_params->max_phys_tcs_per_port); 495fe56b9e6SYuval Mintz 496fe56b9e6SYuval Mintz OVERWRITE_RT_REG(p_hwfn, 497fe56b9e6SYuval Mintz crd_reg_offset + voq * MAX_NUM_PFS_BB, 498fe56b9e6SYuval Mintz QM_WFQ_CRD_REG_SIGN_BIT); 499fe56b9e6SYuval Mintz } 500fe56b9e6SYuval Mintz 501351a4dedSYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_WFQPFWEIGHT_RT_OFFSET + p_params->pf_id, 502351a4dedSYuval Mintz inc_val); 503351a4dedSYuval Mintz STORE_RT_REG(p_hwfn, 504351a4dedSYuval Mintz QM_REG_WFQPFUPPERBOUND_RT_OFFSET + p_params->pf_id, 505351a4dedSYuval Mintz QM_WFQ_UPPER_BOUND | QM_WFQ_CRD_REG_SIGN_BIT); 506fe56b9e6SYuval Mintz return 0; 507fe56b9e6SYuval Mintz } 508fe56b9e6SYuval Mintz 509fe56b9e6SYuval Mintz /* Prepare PF RL runtime init values for the specified PF. 510fe56b9e6SYuval Mintz * Return -1 on error. 511fe56b9e6SYuval Mintz */ 512351a4dedSYuval Mintz static int qed_pf_rl_rt_init(struct qed_hwfn *p_hwfn, u8 pf_id, u32 pf_rl) 513fe56b9e6SYuval Mintz { 514fe56b9e6SYuval Mintz u32 inc_val = QM_RL_INC_VAL(pf_rl); 515fe56b9e6SYuval Mintz 516fe56b9e6SYuval Mintz if (inc_val > QM_RL_MAX_INC_VAL) { 517fe56b9e6SYuval Mintz DP_NOTICE(p_hwfn, "Invalid PF rate limit configuration"); 518fe56b9e6SYuval Mintz return -1; 519fe56b9e6SYuval Mintz } 520fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_RLPFCRD_RT_OFFSET + pf_id, 521fe56b9e6SYuval Mintz QM_RL_CRD_REG_SIGN_BIT); 522fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_RLPFUPPERBOUND_RT_OFFSET + pf_id, 523fe56b9e6SYuval Mintz QM_RL_UPPER_BOUND | QM_RL_CRD_REG_SIGN_BIT); 524fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_RLPFINCVAL_RT_OFFSET + pf_id, inc_val); 525fe56b9e6SYuval Mintz return 0; 526fe56b9e6SYuval Mintz } 527fe56b9e6SYuval Mintz 528fe56b9e6SYuval Mintz /* Prepare VPORT WFQ runtime init values for the specified VPORTs. 529fe56b9e6SYuval Mintz * Return -1 on error. 530fe56b9e6SYuval Mintz */ 531fe56b9e6SYuval Mintz static int qed_vp_wfq_rt_init(struct qed_hwfn *p_hwfn, 532fe56b9e6SYuval Mintz u8 num_vports, 533fe56b9e6SYuval Mintz struct init_qm_vport_params *vport_params) 534fe56b9e6SYuval Mintz { 535fe56b9e6SYuval Mintz u32 inc_val; 536fc48b7a6SYuval Mintz u8 tc, i; 537fe56b9e6SYuval Mintz 538fe56b9e6SYuval Mintz /* go over all PF VPORTs */ 539fc48b7a6SYuval Mintz for (i = 0; i < num_vports; i++) { 540fe56b9e6SYuval Mintz 541fe56b9e6SYuval Mintz if (!vport_params[i].vport_wfq) 542fe56b9e6SYuval Mintz continue; 543fe56b9e6SYuval Mintz 544fe56b9e6SYuval Mintz inc_val = QM_WFQ_INC_VAL(vport_params[i].vport_wfq); 545fe56b9e6SYuval Mintz if (inc_val > QM_WFQ_MAX_INC_VAL) { 546fe56b9e6SYuval Mintz DP_NOTICE(p_hwfn, 547fe56b9e6SYuval Mintz "Invalid VPORT WFQ weight configuration"); 548fe56b9e6SYuval Mintz return -1; 549fe56b9e6SYuval Mintz } 550fe56b9e6SYuval Mintz 551fe56b9e6SYuval Mintz /* each VPORT can have several VPORT PQ IDs for 552fe56b9e6SYuval Mintz * different TCs 553fe56b9e6SYuval Mintz */ 554fe56b9e6SYuval Mintz for (tc = 0; tc < NUM_OF_TCS; tc++) { 555fc48b7a6SYuval Mintz u16 vport_pq_id = vport_params[i].first_tx_pq_id[tc]; 556fe56b9e6SYuval Mintz 557fe56b9e6SYuval Mintz if (vport_pq_id != QM_INVALID_PQ_ID) { 558fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 559fe56b9e6SYuval Mintz QM_REG_WFQVPCRD_RT_OFFSET + 560fe56b9e6SYuval Mintz vport_pq_id, 561fe56b9e6SYuval Mintz QM_WFQ_CRD_REG_SIGN_BIT); 562fc48b7a6SYuval Mintz STORE_RT_REG(p_hwfn, 563fc48b7a6SYuval Mintz QM_REG_WFQVPWEIGHT_RT_OFFSET + 564fc48b7a6SYuval Mintz vport_pq_id, inc_val); 565fe56b9e6SYuval Mintz } 566fe56b9e6SYuval Mintz } 567fe56b9e6SYuval Mintz } 568fe56b9e6SYuval Mintz 569fe56b9e6SYuval Mintz return 0; 570fe56b9e6SYuval Mintz } 571fe56b9e6SYuval Mintz 572fe56b9e6SYuval Mintz static int qed_vport_rl_rt_init(struct qed_hwfn *p_hwfn, 573fe56b9e6SYuval Mintz u8 start_vport, 574fe56b9e6SYuval Mintz u8 num_vports, 575fe56b9e6SYuval Mintz struct init_qm_vport_params *vport_params) 576fe56b9e6SYuval Mintz { 577fe56b9e6SYuval Mintz u8 i, vport_id; 578fe56b9e6SYuval Mintz 579fe56b9e6SYuval Mintz /* go over all PF VPORTs */ 580fe56b9e6SYuval Mintz for (i = 0, vport_id = start_vport; i < num_vports; i++, vport_id++) { 581fe56b9e6SYuval Mintz u32 inc_val = QM_RL_INC_VAL(vport_params[i].vport_rl); 582fe56b9e6SYuval Mintz 583fe56b9e6SYuval Mintz if (inc_val > QM_RL_MAX_INC_VAL) { 584fe56b9e6SYuval Mintz DP_NOTICE(p_hwfn, 585fe56b9e6SYuval Mintz "Invalid VPORT rate-limit configuration"); 586fe56b9e6SYuval Mintz return -1; 587fe56b9e6SYuval Mintz } 588fe56b9e6SYuval Mintz 589fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 590fe56b9e6SYuval Mintz QM_REG_RLGLBLCRD_RT_OFFSET + vport_id, 591fe56b9e6SYuval Mintz QM_RL_CRD_REG_SIGN_BIT); 592fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 593fe56b9e6SYuval Mintz QM_REG_RLGLBLUPPERBOUND_RT_OFFSET + vport_id, 594fe56b9e6SYuval Mintz QM_RL_UPPER_BOUND | QM_RL_CRD_REG_SIGN_BIT); 595fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 596fe56b9e6SYuval Mintz QM_REG_RLGLBLINCVAL_RT_OFFSET + vport_id, 597fe56b9e6SYuval Mintz inc_val); 598fe56b9e6SYuval Mintz } 599fe56b9e6SYuval Mintz 600fe56b9e6SYuval Mintz return 0; 601fe56b9e6SYuval Mintz } 602fe56b9e6SYuval Mintz 603fe56b9e6SYuval Mintz static bool qed_poll_on_qm_cmd_ready(struct qed_hwfn *p_hwfn, 604fe56b9e6SYuval Mintz struct qed_ptt *p_ptt) 605fe56b9e6SYuval Mintz { 606fe56b9e6SYuval Mintz u32 reg_val, i; 607fe56b9e6SYuval Mintz 608fe56b9e6SYuval Mintz for (i = 0, reg_val = 0; i < QM_STOP_CMD_MAX_POLL_COUNT && reg_val == 0; 609fe56b9e6SYuval Mintz i++) { 610fe56b9e6SYuval Mintz udelay(QM_STOP_CMD_POLL_PERIOD_US); 611fe56b9e6SYuval Mintz reg_val = qed_rd(p_hwfn, p_ptt, QM_REG_SDMCMDREADY); 612fe56b9e6SYuval Mintz } 613fe56b9e6SYuval Mintz 614fe56b9e6SYuval Mintz /* check if timeout while waiting for SDM command ready */ 615fe56b9e6SYuval Mintz if (i == QM_STOP_CMD_MAX_POLL_COUNT) { 616fe56b9e6SYuval Mintz DP_VERBOSE(p_hwfn, NETIF_MSG_HW, 617fe56b9e6SYuval Mintz "Timeout when waiting for QM SDM command ready signal\n"); 618fe56b9e6SYuval Mintz return false; 619fe56b9e6SYuval Mintz } 620fe56b9e6SYuval Mintz 621fe56b9e6SYuval Mintz return true; 622fe56b9e6SYuval Mintz } 623fe56b9e6SYuval Mintz 624fe56b9e6SYuval Mintz static bool qed_send_qm_cmd(struct qed_hwfn *p_hwfn, 625fe56b9e6SYuval Mintz struct qed_ptt *p_ptt, 626351a4dedSYuval Mintz u32 cmd_addr, u32 cmd_data_lsb, u32 cmd_data_msb) 627fe56b9e6SYuval Mintz { 628fe56b9e6SYuval Mintz if (!qed_poll_on_qm_cmd_ready(p_hwfn, p_ptt)) 629fe56b9e6SYuval Mintz return false; 630fe56b9e6SYuval Mintz 631fe56b9e6SYuval Mintz qed_wr(p_hwfn, p_ptt, QM_REG_SDMCMDADDR, cmd_addr); 632fe56b9e6SYuval Mintz qed_wr(p_hwfn, p_ptt, QM_REG_SDMCMDDATALSB, cmd_data_lsb); 633fe56b9e6SYuval Mintz qed_wr(p_hwfn, p_ptt, QM_REG_SDMCMDDATAMSB, cmd_data_msb); 634fe56b9e6SYuval Mintz qed_wr(p_hwfn, p_ptt, QM_REG_SDMCMDGO, 1); 635fe56b9e6SYuval Mintz qed_wr(p_hwfn, p_ptt, QM_REG_SDMCMDGO, 0); 636fe56b9e6SYuval Mintz 637fe56b9e6SYuval Mintz return qed_poll_on_qm_cmd_ready(p_hwfn, p_ptt); 638fe56b9e6SYuval Mintz } 639fe56b9e6SYuval Mintz 640fe56b9e6SYuval Mintz /******************** INTERFACE IMPLEMENTATION *********************/ 641fe56b9e6SYuval Mintz u32 qed_qm_pf_mem_size(u8 pf_id, 642fe56b9e6SYuval Mintz u32 num_pf_cids, 643fe56b9e6SYuval Mintz u32 num_vf_cids, 644351a4dedSYuval Mintz u32 num_tids, u16 num_pf_pqs, u16 num_vf_pqs) 645fe56b9e6SYuval Mintz { 646fe56b9e6SYuval Mintz return QM_PQ_MEM_4KB(num_pf_cids) * num_pf_pqs + 647fe56b9e6SYuval Mintz QM_PQ_MEM_4KB(num_vf_cids) * num_vf_pqs + 648fe56b9e6SYuval Mintz QM_PQ_MEM_4KB(num_pf_cids + num_tids) * QM_OTHER_PQS_PER_PF; 649fe56b9e6SYuval Mintz } 650fe56b9e6SYuval Mintz 651fe56b9e6SYuval Mintz int qed_qm_common_rt_init( 652fe56b9e6SYuval Mintz struct qed_hwfn *p_hwfn, 653fe56b9e6SYuval Mintz struct qed_qm_common_rt_init_params *p_params) 654fe56b9e6SYuval Mintz { 655fe56b9e6SYuval Mintz /* init AFullOprtnstcCrdMask */ 656fe56b9e6SYuval Mintz u32 mask = (QM_OPPOR_LINE_VOQ_DEF << 657fe56b9e6SYuval Mintz QM_RF_OPPORTUNISTIC_MASK_LINEVOQ_SHIFT) | 658fe56b9e6SYuval Mintz (QM_BYTE_CRD_EN << QM_RF_OPPORTUNISTIC_MASK_BYTEVOQ_SHIFT) | 659fe56b9e6SYuval Mintz (p_params->pf_wfq_en << 660fe56b9e6SYuval Mintz QM_RF_OPPORTUNISTIC_MASK_PFWFQ_SHIFT) | 661fe56b9e6SYuval Mintz (p_params->vport_wfq_en << 662fe56b9e6SYuval Mintz QM_RF_OPPORTUNISTIC_MASK_VPWFQ_SHIFT) | 663fe56b9e6SYuval Mintz (p_params->pf_rl_en << 664fe56b9e6SYuval Mintz QM_RF_OPPORTUNISTIC_MASK_PFRL_SHIFT) | 665fe56b9e6SYuval Mintz (p_params->vport_rl_en << 666fe56b9e6SYuval Mintz QM_RF_OPPORTUNISTIC_MASK_VPQCNRL_SHIFT) | 667fe56b9e6SYuval Mintz (QM_OPPOR_FW_STOP_DEF << 668fe56b9e6SYuval Mintz QM_RF_OPPORTUNISTIC_MASK_FWPAUSE_SHIFT) | 669fe56b9e6SYuval Mintz (QM_OPPOR_PQ_EMPTY_DEF << 670fe56b9e6SYuval Mintz QM_RF_OPPORTUNISTIC_MASK_QUEUEEMPTY_SHIFT); 671fe56b9e6SYuval Mintz 672fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_AFULLOPRTNSTCCRDMASK_RT_OFFSET, mask); 673fe56b9e6SYuval Mintz qed_enable_pf_rl(p_hwfn, p_params->pf_rl_en); 674fe56b9e6SYuval Mintz qed_enable_pf_wfq(p_hwfn, p_params->pf_wfq_en); 675fe56b9e6SYuval Mintz qed_enable_vport_rl(p_hwfn, p_params->vport_rl_en); 676fe56b9e6SYuval Mintz qed_enable_vport_wfq(p_hwfn, p_params->vport_wfq_en); 677fe56b9e6SYuval Mintz qed_cmdq_lines_rt_init(p_hwfn, 678fe56b9e6SYuval Mintz p_params->max_ports_per_engine, 679fe56b9e6SYuval Mintz p_params->max_phys_tcs_per_port, 680fe56b9e6SYuval Mintz p_params->port_params); 681fe56b9e6SYuval Mintz qed_btb_blocks_rt_init(p_hwfn, 682fe56b9e6SYuval Mintz p_params->max_ports_per_engine, 683fe56b9e6SYuval Mintz p_params->max_phys_tcs_per_port, 684fe56b9e6SYuval Mintz p_params->port_params); 685fe56b9e6SYuval Mintz return 0; 686fe56b9e6SYuval Mintz } 687fe56b9e6SYuval Mintz 688fe56b9e6SYuval Mintz int qed_qm_pf_rt_init(struct qed_hwfn *p_hwfn, 689fe56b9e6SYuval Mintz struct qed_ptt *p_ptt, 690fe56b9e6SYuval Mintz struct qed_qm_pf_rt_init_params *p_params) 691fe56b9e6SYuval Mintz { 692fe56b9e6SYuval Mintz struct init_qm_vport_params *vport_params = p_params->vport_params; 693fe56b9e6SYuval Mintz u32 other_mem_size_4kb = QM_PQ_MEM_4KB(p_params->num_pf_cids + 694fe56b9e6SYuval Mintz p_params->num_tids) * 695fe56b9e6SYuval Mintz QM_OTHER_PQS_PER_PF; 696fe56b9e6SYuval Mintz u8 tc, i; 697fe56b9e6SYuval Mintz 698fe56b9e6SYuval Mintz /* clear first Tx PQ ID array for each VPORT */ 699fe56b9e6SYuval Mintz for (i = 0; i < p_params->num_vports; i++) 700fe56b9e6SYuval Mintz for (tc = 0; tc < NUM_OF_TCS; tc++) 701fe56b9e6SYuval Mintz vport_params[i].first_tx_pq_id[tc] = QM_INVALID_PQ_ID; 702fe56b9e6SYuval Mintz 703fe56b9e6SYuval Mintz /* map Other PQs (if any) */ 704fe56b9e6SYuval Mintz qed_other_pq_map_rt_init(p_hwfn, p_params->port_id, p_params->pf_id, 705fe56b9e6SYuval Mintz p_params->num_pf_cids, p_params->num_tids, 0); 706fe56b9e6SYuval Mintz 707fe56b9e6SYuval Mintz /* map Tx PQs */ 708fe56b9e6SYuval Mintz qed_tx_pq_map_rt_init(p_hwfn, p_ptt, p_params, other_mem_size_4kb); 709fe56b9e6SYuval Mintz 710fe56b9e6SYuval Mintz if (p_params->pf_wfq) 711fe56b9e6SYuval Mintz if (qed_pf_wfq_rt_init(p_hwfn, p_params)) 712fe56b9e6SYuval Mintz return -1; 713fe56b9e6SYuval Mintz 714fe56b9e6SYuval Mintz if (qed_pf_rl_rt_init(p_hwfn, p_params->pf_id, p_params->pf_rl)) 715fe56b9e6SYuval Mintz return -1; 716fe56b9e6SYuval Mintz 717fc48b7a6SYuval Mintz if (qed_vp_wfq_rt_init(p_hwfn, p_params->num_vports, vport_params)) 718fe56b9e6SYuval Mintz return -1; 719fe56b9e6SYuval Mintz 720fe56b9e6SYuval Mintz if (qed_vport_rl_rt_init(p_hwfn, p_params->start_vport, 721fe56b9e6SYuval Mintz p_params->num_vports, vport_params)) 722fe56b9e6SYuval Mintz return -1; 723fe56b9e6SYuval Mintz 724fe56b9e6SYuval Mintz return 0; 725fe56b9e6SYuval Mintz } 726fe56b9e6SYuval Mintz 727a64b02d5SManish Chopra int qed_init_pf_wfq(struct qed_hwfn *p_hwfn, 728351a4dedSYuval Mintz struct qed_ptt *p_ptt, u8 pf_id, u16 pf_wfq) 729a64b02d5SManish Chopra { 730a64b02d5SManish Chopra u32 inc_val = QM_WFQ_INC_VAL(pf_wfq); 731a64b02d5SManish Chopra 732a64b02d5SManish Chopra if (!inc_val || inc_val > QM_WFQ_MAX_INC_VAL) { 733a64b02d5SManish Chopra DP_NOTICE(p_hwfn, "Invalid PF WFQ weight configuration"); 734a64b02d5SManish Chopra return -1; 735a64b02d5SManish Chopra } 736a64b02d5SManish Chopra 737a64b02d5SManish Chopra qed_wr(p_hwfn, p_ptt, QM_REG_WFQPFWEIGHT + pf_id * 4, inc_val); 738a64b02d5SManish Chopra return 0; 739a64b02d5SManish Chopra } 740a64b02d5SManish Chopra 741fe56b9e6SYuval Mintz int qed_init_pf_rl(struct qed_hwfn *p_hwfn, 742351a4dedSYuval Mintz struct qed_ptt *p_ptt, u8 pf_id, u32 pf_rl) 743fe56b9e6SYuval Mintz { 744fe56b9e6SYuval Mintz u32 inc_val = QM_RL_INC_VAL(pf_rl); 745fe56b9e6SYuval Mintz 746fe56b9e6SYuval Mintz if (inc_val > QM_RL_MAX_INC_VAL) { 747fe56b9e6SYuval Mintz DP_NOTICE(p_hwfn, "Invalid PF rate limit configuration"); 748fe56b9e6SYuval Mintz return -1; 749fe56b9e6SYuval Mintz } 750fe56b9e6SYuval Mintz 751fe56b9e6SYuval Mintz qed_wr(p_hwfn, p_ptt, 752fe56b9e6SYuval Mintz QM_REG_RLPFCRD + pf_id * 4, 753fe56b9e6SYuval Mintz QM_RL_CRD_REG_SIGN_BIT); 754fe56b9e6SYuval Mintz qed_wr(p_hwfn, p_ptt, QM_REG_RLPFINCVAL + pf_id * 4, inc_val); 755fe56b9e6SYuval Mintz 756fe56b9e6SYuval Mintz return 0; 757fe56b9e6SYuval Mintz } 758fe56b9e6SYuval Mintz 759bcd197c8SManish Chopra int qed_init_vport_wfq(struct qed_hwfn *p_hwfn, 760bcd197c8SManish Chopra struct qed_ptt *p_ptt, 761351a4dedSYuval Mintz u16 first_tx_pq_id[NUM_OF_TCS], u16 vport_wfq) 762bcd197c8SManish Chopra { 763bcd197c8SManish Chopra u32 inc_val = QM_WFQ_INC_VAL(vport_wfq); 764bcd197c8SManish Chopra u8 tc; 765bcd197c8SManish Chopra 766bcd197c8SManish Chopra if (!inc_val || inc_val > QM_WFQ_MAX_INC_VAL) { 767bcd197c8SManish Chopra DP_NOTICE(p_hwfn, "Invalid VPORT WFQ weight configuration"); 768bcd197c8SManish Chopra return -1; 769bcd197c8SManish Chopra } 770bcd197c8SManish Chopra 771bcd197c8SManish Chopra for (tc = 0; tc < NUM_OF_TCS; tc++) { 772bcd197c8SManish Chopra u16 vport_pq_id = first_tx_pq_id[tc]; 773bcd197c8SManish Chopra 774bcd197c8SManish Chopra if (vport_pq_id != QM_INVALID_PQ_ID) 775bcd197c8SManish Chopra qed_wr(p_hwfn, p_ptt, 776bcd197c8SManish Chopra QM_REG_WFQVPWEIGHT + vport_pq_id * 4, 777bcd197c8SManish Chopra inc_val); 778bcd197c8SManish Chopra } 779bcd197c8SManish Chopra 780bcd197c8SManish Chopra return 0; 781bcd197c8SManish Chopra } 782bcd197c8SManish Chopra 783fe56b9e6SYuval Mintz int qed_init_vport_rl(struct qed_hwfn *p_hwfn, 784351a4dedSYuval Mintz struct qed_ptt *p_ptt, u8 vport_id, u32 vport_rl) 785fe56b9e6SYuval Mintz { 786fe56b9e6SYuval Mintz u32 inc_val = QM_RL_INC_VAL(vport_rl); 787fe56b9e6SYuval Mintz 788fe56b9e6SYuval Mintz if (inc_val > QM_RL_MAX_INC_VAL) { 789fe56b9e6SYuval Mintz DP_NOTICE(p_hwfn, "Invalid VPORT rate-limit configuration"); 790fe56b9e6SYuval Mintz return -1; 791fe56b9e6SYuval Mintz } 792fe56b9e6SYuval Mintz 793fe56b9e6SYuval Mintz qed_wr(p_hwfn, p_ptt, 794fe56b9e6SYuval Mintz QM_REG_RLGLBLCRD + vport_id * 4, 795fe56b9e6SYuval Mintz QM_RL_CRD_REG_SIGN_BIT); 796fe56b9e6SYuval Mintz qed_wr(p_hwfn, p_ptt, QM_REG_RLGLBLINCVAL + vport_id * 4, inc_val); 797fe56b9e6SYuval Mintz 798fe56b9e6SYuval Mintz return 0; 799fe56b9e6SYuval Mintz } 800fe56b9e6SYuval Mintz 801fe56b9e6SYuval Mintz bool qed_send_qm_stop_cmd(struct qed_hwfn *p_hwfn, 802fe56b9e6SYuval Mintz struct qed_ptt *p_ptt, 803fe56b9e6SYuval Mintz bool is_release_cmd, 804351a4dedSYuval Mintz bool is_tx_pq, u16 start_pq, u16 num_pqs) 805fe56b9e6SYuval Mintz { 806fe56b9e6SYuval Mintz u32 cmd_arr[QM_CMD_STRUCT_SIZE(QM_STOP_CMD)] = { 0 }; 807fe56b9e6SYuval Mintz u32 pq_mask = 0, last_pq = start_pq + num_pqs - 1, pq_id; 808fe56b9e6SYuval Mintz 809fe56b9e6SYuval Mintz /* set command's PQ type */ 810fe56b9e6SYuval Mintz QM_CMD_SET_FIELD(cmd_arr, QM_STOP_CMD, PQ_TYPE, is_tx_pq ? 0 : 1); 811fe56b9e6SYuval Mintz 812fe56b9e6SYuval Mintz for (pq_id = start_pq; pq_id <= last_pq; pq_id++) { 813fe56b9e6SYuval Mintz /* set PQ bit in mask (stop command only) */ 814fe56b9e6SYuval Mintz if (!is_release_cmd) 815fe56b9e6SYuval Mintz pq_mask |= (1 << (pq_id % QM_STOP_PQ_MASK_WIDTH)); 816fe56b9e6SYuval Mintz 817fe56b9e6SYuval Mintz /* if last PQ or end of PQ mask, write command */ 818fe56b9e6SYuval Mintz if ((pq_id == last_pq) || 819fe56b9e6SYuval Mintz (pq_id % QM_STOP_PQ_MASK_WIDTH == 820fe56b9e6SYuval Mintz (QM_STOP_PQ_MASK_WIDTH - 1))) { 821fe56b9e6SYuval Mintz QM_CMD_SET_FIELD(cmd_arr, QM_STOP_CMD, 822fe56b9e6SYuval Mintz PAUSE_MASK, pq_mask); 823fe56b9e6SYuval Mintz QM_CMD_SET_FIELD(cmd_arr, QM_STOP_CMD, 824fe56b9e6SYuval Mintz GROUP_ID, 825fe56b9e6SYuval Mintz pq_id / QM_STOP_PQ_MASK_WIDTH); 826fe56b9e6SYuval Mintz if (!qed_send_qm_cmd(p_hwfn, p_ptt, QM_STOP_CMD_ADDR, 827fe56b9e6SYuval Mintz cmd_arr[0], cmd_arr[1])) 828fe56b9e6SYuval Mintz return false; 829fe56b9e6SYuval Mintz pq_mask = 0; 830fe56b9e6SYuval Mintz } 831fe56b9e6SYuval Mintz } 832fe56b9e6SYuval Mintz 833fe56b9e6SYuval Mintz return true; 834fe56b9e6SYuval Mintz } 835464f6645SManish Chopra 836464f6645SManish Chopra static void 837464f6645SManish Chopra qed_set_tunnel_type_enable_bit(unsigned long *var, int bit, bool enable) 838464f6645SManish Chopra { 839464f6645SManish Chopra if (enable) 840464f6645SManish Chopra set_bit(bit, var); 841464f6645SManish Chopra else 842464f6645SManish Chopra clear_bit(bit, var); 843464f6645SManish Chopra } 844464f6645SManish Chopra 845464f6645SManish Chopra #define PRS_ETH_TUNN_FIC_FORMAT -188897008 846464f6645SManish Chopra 847464f6645SManish Chopra void qed_set_vxlan_dest_port(struct qed_hwfn *p_hwfn, 848351a4dedSYuval Mintz struct qed_ptt *p_ptt, u16 dest_port) 849464f6645SManish Chopra { 850464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PRS_REG_VXLAN_PORT, dest_port); 851351a4dedSYuval Mintz qed_wr(p_hwfn, p_ptt, NIG_REG_VXLAN_CTRL, dest_port); 852464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PBF_REG_VXLAN_PORT, dest_port); 853464f6645SManish Chopra } 854464f6645SManish Chopra 855464f6645SManish Chopra void qed_set_vxlan_enable(struct qed_hwfn *p_hwfn, 856351a4dedSYuval Mintz struct qed_ptt *p_ptt, bool vxlan_enable) 857464f6645SManish Chopra { 858464f6645SManish Chopra unsigned long reg_val = 0; 859464f6645SManish Chopra u8 shift; 860464f6645SManish Chopra 861464f6645SManish Chopra reg_val = qed_rd(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN); 862464f6645SManish Chopra shift = PRS_REG_ENCAPSULATION_TYPE_EN_VXLAN_ENABLE_SHIFT; 863464f6645SManish Chopra qed_set_tunnel_type_enable_bit(®_val, shift, vxlan_enable); 864464f6645SManish Chopra 865464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN, reg_val); 866464f6645SManish Chopra 867464f6645SManish Chopra if (reg_val) 868464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0, 869464f6645SManish Chopra PRS_ETH_TUNN_FIC_FORMAT); 870464f6645SManish Chopra 871464f6645SManish Chopra reg_val = qed_rd(p_hwfn, p_ptt, NIG_REG_ENC_TYPE_ENABLE); 872464f6645SManish Chopra shift = NIG_REG_ENC_TYPE_ENABLE_VXLAN_ENABLE_SHIFT; 873464f6645SManish Chopra qed_set_tunnel_type_enable_bit(®_val, shift, vxlan_enable); 874464f6645SManish Chopra 875464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, NIG_REG_ENC_TYPE_ENABLE, reg_val); 876464f6645SManish Chopra 877464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, DORQ_REG_L2_EDPM_TUNNEL_VXLAN_EN, 878464f6645SManish Chopra vxlan_enable ? 1 : 0); 879464f6645SManish Chopra } 880464f6645SManish Chopra 881464f6645SManish Chopra void qed_set_gre_enable(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, 882464f6645SManish Chopra bool eth_gre_enable, bool ip_gre_enable) 883464f6645SManish Chopra { 884464f6645SManish Chopra unsigned long reg_val = 0; 885464f6645SManish Chopra u8 shift; 886464f6645SManish Chopra 887464f6645SManish Chopra reg_val = qed_rd(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN); 888464f6645SManish Chopra shift = PRS_REG_ENCAPSULATION_TYPE_EN_ETH_OVER_GRE_ENABLE_SHIFT; 889464f6645SManish Chopra qed_set_tunnel_type_enable_bit(®_val, shift, eth_gre_enable); 890464f6645SManish Chopra 891464f6645SManish Chopra shift = PRS_REG_ENCAPSULATION_TYPE_EN_IP_OVER_GRE_ENABLE_SHIFT; 892464f6645SManish Chopra qed_set_tunnel_type_enable_bit(®_val, shift, ip_gre_enable); 893464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN, reg_val); 894464f6645SManish Chopra if (reg_val) 895464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0, 896464f6645SManish Chopra PRS_ETH_TUNN_FIC_FORMAT); 897464f6645SManish Chopra 898464f6645SManish Chopra reg_val = qed_rd(p_hwfn, p_ptt, NIG_REG_ENC_TYPE_ENABLE); 899464f6645SManish Chopra shift = NIG_REG_ENC_TYPE_ENABLE_ETH_OVER_GRE_ENABLE_SHIFT; 900464f6645SManish Chopra qed_set_tunnel_type_enable_bit(®_val, shift, eth_gre_enable); 901464f6645SManish Chopra 902464f6645SManish Chopra shift = NIG_REG_ENC_TYPE_ENABLE_IP_OVER_GRE_ENABLE_SHIFT; 903464f6645SManish Chopra qed_set_tunnel_type_enable_bit(®_val, shift, ip_gre_enable); 904464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, NIG_REG_ENC_TYPE_ENABLE, reg_val); 905464f6645SManish Chopra 906464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, DORQ_REG_L2_EDPM_TUNNEL_GRE_ETH_EN, 907464f6645SManish Chopra eth_gre_enable ? 1 : 0); 908464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, DORQ_REG_L2_EDPM_TUNNEL_GRE_IP_EN, 909464f6645SManish Chopra ip_gre_enable ? 1 : 0); 910464f6645SManish Chopra } 911464f6645SManish Chopra 912464f6645SManish Chopra void qed_set_geneve_dest_port(struct qed_hwfn *p_hwfn, 913351a4dedSYuval Mintz struct qed_ptt *p_ptt, u16 dest_port) 914464f6645SManish Chopra { 915464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PRS_REG_NGE_PORT, dest_port); 916464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, NIG_REG_NGE_PORT, dest_port); 917464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PBF_REG_NGE_PORT, dest_port); 918464f6645SManish Chopra } 919464f6645SManish Chopra 920464f6645SManish Chopra void qed_set_geneve_enable(struct qed_hwfn *p_hwfn, 921464f6645SManish Chopra struct qed_ptt *p_ptt, 922351a4dedSYuval Mintz bool eth_geneve_enable, bool ip_geneve_enable) 923464f6645SManish Chopra { 924464f6645SManish Chopra unsigned long reg_val = 0; 925464f6645SManish Chopra u8 shift; 926464f6645SManish Chopra 927464f6645SManish Chopra reg_val = qed_rd(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN); 928464f6645SManish Chopra shift = PRS_REG_ENCAPSULATION_TYPE_EN_ETH_OVER_GENEVE_ENABLE_SHIFT; 929464f6645SManish Chopra qed_set_tunnel_type_enable_bit(®_val, shift, eth_geneve_enable); 930464f6645SManish Chopra 931464f6645SManish Chopra shift = PRS_REG_ENCAPSULATION_TYPE_EN_IP_OVER_GENEVE_ENABLE_SHIFT; 932464f6645SManish Chopra qed_set_tunnel_type_enable_bit(®_val, shift, ip_geneve_enable); 933464f6645SManish Chopra 934464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN, reg_val); 935464f6645SManish Chopra if (reg_val) 936464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0, 937464f6645SManish Chopra PRS_ETH_TUNN_FIC_FORMAT); 938464f6645SManish Chopra 939464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, NIG_REG_NGE_ETH_ENABLE, 940464f6645SManish Chopra eth_geneve_enable ? 1 : 0); 941464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, NIG_REG_NGE_IP_ENABLE, ip_geneve_enable ? 1 : 0); 942464f6645SManish Chopra 943464f6645SManish Chopra /* comp ver */ 944464f6645SManish Chopra reg_val = (ip_geneve_enable || eth_geneve_enable) ? 1 : 0; 945464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, NIG_REG_NGE_COMP_VER, reg_val); 946464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PBF_REG_NGE_COMP_VER, reg_val); 947464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PRS_REG_NGE_COMP_VER, reg_val); 948464f6645SManish Chopra 949464f6645SManish Chopra /* EDPM with geneve tunnel not supported in BB_B0 */ 950464f6645SManish Chopra if (QED_IS_BB_B0(p_hwfn->cdev)) 951464f6645SManish Chopra return; 952464f6645SManish Chopra 953464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, DORQ_REG_L2_EDPM_TUNNEL_NGE_ETH_EN, 954464f6645SManish Chopra eth_geneve_enable ? 1 : 0); 955464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, DORQ_REG_L2_EDPM_TUNNEL_NGE_IP_EN, 956464f6645SManish Chopra ip_geneve_enable ? 1 : 0); 957464f6645SManish Chopra } 958