1*14b24e2bSVaishali Kulkarni /* 2*14b24e2bSVaishali Kulkarni * CDDL HEADER START 3*14b24e2bSVaishali Kulkarni * 4*14b24e2bSVaishali Kulkarni * The contents of this file are subject to the terms of the 5*14b24e2bSVaishali Kulkarni * Common Development and Distribution License, v.1, (the "License"). 6*14b24e2bSVaishali Kulkarni * You may not use this file except in compliance with the License. 7*14b24e2bSVaishali Kulkarni * 8*14b24e2bSVaishali Kulkarni * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*14b24e2bSVaishali Kulkarni * or http://opensource.org/licenses/CDDL-1.0. 10*14b24e2bSVaishali Kulkarni * See the License for the specific language governing permissions 11*14b24e2bSVaishali Kulkarni * and limitations under the License. 12*14b24e2bSVaishali Kulkarni * 13*14b24e2bSVaishali Kulkarni * When distributing Covered Code, include this CDDL HEADER in each 14*14b24e2bSVaishali Kulkarni * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*14b24e2bSVaishali Kulkarni * If applicable, add the following below this CDDL HEADER, with the 16*14b24e2bSVaishali Kulkarni * fields enclosed by brackets "[]" replaced with your own identifying 17*14b24e2bSVaishali Kulkarni * information: Portions Copyright [yyyy] [name of copyright owner] 18*14b24e2bSVaishali Kulkarni * 19*14b24e2bSVaishali Kulkarni * CDDL HEADER END 20*14b24e2bSVaishali Kulkarni */ 21*14b24e2bSVaishali Kulkarni 22*14b24e2bSVaishali Kulkarni /* 23*14b24e2bSVaishali Kulkarni * Copyright 2014-2017 Cavium, Inc. 24*14b24e2bSVaishali Kulkarni * The contents of this file are subject to the terms of the Common Development 25*14b24e2bSVaishali Kulkarni * and Distribution License, v.1, (the "License"). 26*14b24e2bSVaishali Kulkarni 27*14b24e2bSVaishali Kulkarni * You may not use this file except in compliance with the License. 28*14b24e2bSVaishali Kulkarni 29*14b24e2bSVaishali Kulkarni * You can obtain a copy of the License at available 30*14b24e2bSVaishali Kulkarni * at http://opensource.org/licenses/CDDL-1.0 31*14b24e2bSVaishali Kulkarni 32*14b24e2bSVaishali Kulkarni * See the License for the specific language governing permissions and 33*14b24e2bSVaishali Kulkarni * limitations under the License. 34*14b24e2bSVaishali Kulkarni */ 35*14b24e2bSVaishali Kulkarni 36*14b24e2bSVaishali Kulkarni #include "bcm_osal.h" 37*14b24e2bSVaishali Kulkarni #include "ecore_hw.h" 38*14b24e2bSVaishali Kulkarni #include "ecore_init_ops.h" 39*14b24e2bSVaishali Kulkarni #include "reg_addr.h" 40*14b24e2bSVaishali Kulkarni #include "ecore_rt_defs.h" 41*14b24e2bSVaishali Kulkarni #include "ecore_hsi_common.h" 42*14b24e2bSVaishali Kulkarni #include "ecore_hsi_init_func.h" 43*14b24e2bSVaishali Kulkarni #include "ecore_hsi_eth.h" 44*14b24e2bSVaishali Kulkarni #include "ecore_hsi_init_tool.h" 45*14b24e2bSVaishali Kulkarni #include "ecore_iro.h" 46*14b24e2bSVaishali Kulkarni #include "ecore_init_fw_funcs.h" 47*14b24e2bSVaishali Kulkarni 48*14b24e2bSVaishali Kulkarni #define CDU_VALIDATION_DEFAULT_CFG 61 49*14b24e2bSVaishali Kulkarni 50*14b24e2bSVaishali Kulkarni static u16 con_region_offsets[3][E4_NUM_OF_CONNECTION_TYPES] = { 51*14b24e2bSVaishali Kulkarni { 400, 336, 352, 304, 304, 384, 416, 352}, /* region 3 offsets */ 52*14b24e2bSVaishali Kulkarni { 528, 496, 416, 448, 448, 512, 544, 480}, /* region 4 offsets */ 53*14b24e2bSVaishali Kulkarni { 608, 544, 496, 512, 576, 592, 624, 560} /* region 5 offsets */ 54*14b24e2bSVaishali Kulkarni }; 55*14b24e2bSVaishali Kulkarni static u16 task_region_offsets[1][E4_NUM_OF_CONNECTION_TYPES] = { 56*14b24e2bSVaishali Kulkarni { 240, 240, 112, 0, 0, 0, 0, 96} /* region 1 offsets */ 57*14b24e2bSVaishali Kulkarni }; 58*14b24e2bSVaishali Kulkarni 59*14b24e2bSVaishali Kulkarni /* General constants */ 60*14b24e2bSVaishali Kulkarni #define QM_PQ_MEM_4KB(pq_size) (pq_size ? DIV_ROUND_UP((pq_size + 1) * QM_PQ_ELEMENT_SIZE, 0x1000) : 0) 61*14b24e2bSVaishali Kulkarni #define QM_PQ_SIZE_256B(pq_size) (pq_size ? DIV_ROUND_UP(pq_size, 0x100) - 1 : 0) 62*14b24e2bSVaishali Kulkarni #define QM_INVALID_PQ_ID 0xffff 63*14b24e2bSVaishali Kulkarni 64*14b24e2bSVaishali Kulkarni /* Feature enable */ 65*14b24e2bSVaishali Kulkarni #define QM_BYPASS_EN 1 66*14b24e2bSVaishali Kulkarni #define QM_BYTE_CRD_EN 1 67*14b24e2bSVaishali Kulkarni 68*14b24e2bSVaishali Kulkarni /* Other PQ constants */ 69*14b24e2bSVaishali Kulkarni #define QM_OTHER_PQS_PER_PF 4 70*14b24e2bSVaishali Kulkarni 71*14b24e2bSVaishali Kulkarni /* WFQ constants: */ 72*14b24e2bSVaishali Kulkarni 73*14b24e2bSVaishali Kulkarni /* Upper bound in MB, 10 * burst size of 1ms in 50Gbps */ 74*14b24e2bSVaishali Kulkarni #define QM_WFQ_UPPER_BOUND 62500000 75*14b24e2bSVaishali Kulkarni 76*14b24e2bSVaishali Kulkarni /* Bit of VOQ in WFQ VP PQ map */ 77*14b24e2bSVaishali Kulkarni #define QM_WFQ_VP_PQ_VOQ_SHIFT 0 78*14b24e2bSVaishali Kulkarni 79*14b24e2bSVaishali Kulkarni /* Bit of PF in WFQ VP PQ map */ 80*14b24e2bSVaishali Kulkarni #define QM_WFQ_VP_PQ_PF_SHIFT 5 81*14b24e2bSVaishali Kulkarni 82*14b24e2bSVaishali Kulkarni /* 0x9000 = 4*9*1024 */ 83*14b24e2bSVaishali Kulkarni #define QM_WFQ_INC_VAL(weight) ((weight) * 0x9000) 84*14b24e2bSVaishali Kulkarni 85*14b24e2bSVaishali Kulkarni /* 0.7 * upper bound (62500000) */ 86*14b24e2bSVaishali Kulkarni #define QM_WFQ_MAX_INC_VAL 43750000 87*14b24e2bSVaishali Kulkarni 88*14b24e2bSVaishali Kulkarni /* RL constants: */ 89*14b24e2bSVaishali Kulkarni 90*14b24e2bSVaishali Kulkarni /* Upper bound is set to 10 * burst size of 1ms in 50Gbps */ 91*14b24e2bSVaishali Kulkarni #define QM_RL_UPPER_BOUND 62500000 92*14b24e2bSVaishali Kulkarni 93*14b24e2bSVaishali Kulkarni /* Period in us */ 94*14b24e2bSVaishali Kulkarni #define QM_RL_PERIOD 5 95*14b24e2bSVaishali Kulkarni 96*14b24e2bSVaishali Kulkarni /* Period in 25MHz cycles */ 97*14b24e2bSVaishali Kulkarni #define QM_RL_PERIOD_CLK_25M (25 * QM_RL_PERIOD) 98*14b24e2bSVaishali Kulkarni 99*14b24e2bSVaishali Kulkarni /* 0.7 * upper bound (62500000) */ 100*14b24e2bSVaishali Kulkarni #define QM_RL_MAX_INC_VAL 43750000 101*14b24e2bSVaishali Kulkarni 102*14b24e2bSVaishali Kulkarni /* RL increment value - rate is specified in mbps. the factor of 1.01 was 103*14b24e2bSVaishali Kulkarni * added after seeing only 99% factor reached in a 25Gbps port with DPDK RFC 104*14b24e2bSVaishali Kulkarni * 2544 test. In this scenario the PF RL was reducing the line rate to 99% 105*14b24e2bSVaishali Kulkarni * although the credit increment value was the correct one and FW calculated 106*14b24e2bSVaishali Kulkarni * correct packet sizes. The reason for the inaccuracy of the RL is unknown at 107*14b24e2bSVaishali Kulkarni * this point. 108*14b24e2bSVaishali Kulkarni */ 109*14b24e2bSVaishali Kulkarni #define QM_RL_INC_VAL(rate) OSAL_MAX_T(u32, (u32)(((rate ? rate : 1000000) * QM_RL_PERIOD * 101) / (8 * 100)), 1) 110*14b24e2bSVaishali Kulkarni 111*14b24e2bSVaishali Kulkarni /* AFullOprtnstcCrdMask constants */ 112*14b24e2bSVaishali Kulkarni #define QM_OPPOR_LINE_VOQ_DEF 1 113*14b24e2bSVaishali Kulkarni #define QM_OPPOR_FW_STOP_DEF 0 114*14b24e2bSVaishali Kulkarni #define QM_OPPOR_PQ_EMPTY_DEF 1 115*14b24e2bSVaishali Kulkarni 116*14b24e2bSVaishali Kulkarni /* Command Queue constants: */ 117*14b24e2bSVaishali Kulkarni 118*14b24e2bSVaishali Kulkarni /* Pure LB CmdQ lines (+spare) */ 119*14b24e2bSVaishali Kulkarni #define PBF_CMDQ_PURE_LB_LINES 150 120*14b24e2bSVaishali Kulkarni 121*14b24e2bSVaishali Kulkarni #define PBF_CMDQ_LINES_RT_OFFSET(voq) (PBF_REG_YCMD_QS_NUM_LINES_VOQ0_RT_OFFSET + voq * (PBF_REG_YCMD_QS_NUM_LINES_VOQ1_RT_OFFSET - PBF_REG_YCMD_QS_NUM_LINES_VOQ0_RT_OFFSET)) 122*14b24e2bSVaishali Kulkarni 123*14b24e2bSVaishali Kulkarni #define PBF_BTB_GUARANTEED_RT_OFFSET(voq) (PBF_REG_BTB_GUARANTEED_VOQ0_RT_OFFSET + voq * (PBF_REG_BTB_GUARANTEED_VOQ1_RT_OFFSET - PBF_REG_BTB_GUARANTEED_VOQ0_RT_OFFSET)) 124*14b24e2bSVaishali Kulkarni 125*14b24e2bSVaishali Kulkarni #define QM_VOQ_LINE_CRD(pbf_cmd_lines) ((((pbf_cmd_lines) - 4) * 2) | QM_LINE_CRD_REG_SIGN_BIT) 126*14b24e2bSVaishali Kulkarni 127*14b24e2bSVaishali Kulkarni /* BTB: blocks constants (block size = 256B) */ 128*14b24e2bSVaishali Kulkarni 129*14b24e2bSVaishali Kulkarni /* 256B blocks in 9700B packet */ 130*14b24e2bSVaishali Kulkarni #define BTB_JUMBO_PKT_BLOCKS 38 131*14b24e2bSVaishali Kulkarni 132*14b24e2bSVaishali Kulkarni /* Headroom per-port */ 133*14b24e2bSVaishali Kulkarni #define BTB_HEADROOM_BLOCKS BTB_JUMBO_PKT_BLOCKS 134*14b24e2bSVaishali Kulkarni #define BTB_PURE_LB_FACTOR 10 135*14b24e2bSVaishali Kulkarni 136*14b24e2bSVaishali Kulkarni /* Factored (hence really 0.7) */ 137*14b24e2bSVaishali Kulkarni #define BTB_PURE_LB_RATIO 7 138*14b24e2bSVaishali Kulkarni 139*14b24e2bSVaishali Kulkarni /* QM stop command constants */ 140*14b24e2bSVaishali Kulkarni #define QM_STOP_PQ_MASK_WIDTH 32 141*14b24e2bSVaishali Kulkarni #define QM_STOP_CMD_ADDR 2 142*14b24e2bSVaishali Kulkarni #define QM_STOP_CMD_STRUCT_SIZE 2 143*14b24e2bSVaishali Kulkarni #define QM_STOP_CMD_PAUSE_MASK_OFFSET 0 144*14b24e2bSVaishali Kulkarni #define QM_STOP_CMD_PAUSE_MASK_SHIFT 0 145*14b24e2bSVaishali Kulkarni #define QM_STOP_CMD_PAUSE_MASK_MASK -1 146*14b24e2bSVaishali Kulkarni #define QM_STOP_CMD_GROUP_ID_OFFSET 1 147*14b24e2bSVaishali Kulkarni #define QM_STOP_CMD_GROUP_ID_SHIFT 16 148*14b24e2bSVaishali Kulkarni #define QM_STOP_CMD_GROUP_ID_MASK 15 149*14b24e2bSVaishali Kulkarni #define QM_STOP_CMD_PQ_TYPE_OFFSET 1 150*14b24e2bSVaishali Kulkarni #define QM_STOP_CMD_PQ_TYPE_SHIFT 24 151*14b24e2bSVaishali Kulkarni #define QM_STOP_CMD_PQ_TYPE_MASK 1 152*14b24e2bSVaishali Kulkarni #define QM_STOP_CMD_MAX_POLL_COUNT 100 153*14b24e2bSVaishali Kulkarni #define QM_STOP_CMD_POLL_PERIOD_US 500 154*14b24e2bSVaishali Kulkarni 155*14b24e2bSVaishali Kulkarni /* QM command macros */ 156*14b24e2bSVaishali Kulkarni #define QM_CMD_STRUCT_SIZE(cmd) cmd##_STRUCT_SIZE 157*14b24e2bSVaishali Kulkarni #define QM_CMD_SET_FIELD(var, cmd, field, value) SET_FIELD(var[cmd##_##field##_OFFSET], cmd##_##field, value) 158*14b24e2bSVaishali Kulkarni 159*14b24e2bSVaishali Kulkarni /* QM: VOQ macros */ 160*14b24e2bSVaishali Kulkarni #define PHYS_VOQ(port, tc, max_phys_tcs_per_port) ((port) * (max_phys_tcs_per_port) + (tc)) 161*14b24e2bSVaishali Kulkarni #define LB_VOQ(port) (MAX_PHYS_VOQS + (port)) 162*14b24e2bSVaishali Kulkarni #define VOQ(port, tc, max_phys_tcs_per_port) ((tc) < LB_TC ? PHYS_VOQ(port, tc, max_phys_tcs_per_port) : LB_VOQ(port)) 163*14b24e2bSVaishali Kulkarni 164*14b24e2bSVaishali Kulkarni 165*14b24e2bSVaishali Kulkarni /******************** INTERNAL IMPLEMENTATION *********************/ 166*14b24e2bSVaishali Kulkarni 167*14b24e2bSVaishali Kulkarni /* Prepare PF RL enable/disable runtime init values */ 168*14b24e2bSVaishali Kulkarni static void ecore_enable_pf_rl(struct ecore_hwfn *p_hwfn, 169*14b24e2bSVaishali Kulkarni bool pf_rl_en) 170*14b24e2bSVaishali Kulkarni { 171*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_RLPFENABLE_RT_OFFSET, pf_rl_en ? 1 : 0); 172*14b24e2bSVaishali Kulkarni if (pf_rl_en) { 173*14b24e2bSVaishali Kulkarni 174*14b24e2bSVaishali Kulkarni /* Enable RLs for all VOQs */ 175*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_RLPFVOQENABLE_RT_OFFSET, (1 << MAX_NUM_VOQS) - 1); 176*14b24e2bSVaishali Kulkarni 177*14b24e2bSVaishali Kulkarni /* Write RL period */ 178*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_RLPFPERIOD_RT_OFFSET, QM_RL_PERIOD_CLK_25M); 179*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_RLPFPERIODTIMER_RT_OFFSET, QM_RL_PERIOD_CLK_25M); 180*14b24e2bSVaishali Kulkarni 181*14b24e2bSVaishali Kulkarni /* Set credit threshold for QM bypass flow */ 182*14b24e2bSVaishali Kulkarni if (QM_BYPASS_EN) 183*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_AFULLQMBYPTHRPFRL_RT_OFFSET, QM_RL_UPPER_BOUND); 184*14b24e2bSVaishali Kulkarni } 185*14b24e2bSVaishali Kulkarni } 186*14b24e2bSVaishali Kulkarni 187*14b24e2bSVaishali Kulkarni /* Prepare PF WFQ enable/disable runtime init values */ 188*14b24e2bSVaishali Kulkarni static void ecore_enable_pf_wfq(struct ecore_hwfn *p_hwfn, 189*14b24e2bSVaishali Kulkarni bool pf_wfq_en) 190*14b24e2bSVaishali Kulkarni { 191*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_WFQPFENABLE_RT_OFFSET, pf_wfq_en ? 1 : 0); 192*14b24e2bSVaishali Kulkarni 193*14b24e2bSVaishali Kulkarni /* Set credit threshold for QM bypass flow */ 194*14b24e2bSVaishali Kulkarni if (pf_wfq_en && QM_BYPASS_EN) 195*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_AFULLQMBYPTHRPFWFQ_RT_OFFSET, QM_WFQ_UPPER_BOUND); 196*14b24e2bSVaishali Kulkarni } 197*14b24e2bSVaishali Kulkarni 198*14b24e2bSVaishali Kulkarni /* Prepare VPORT RL enable/disable runtime init values */ 199*14b24e2bSVaishali Kulkarni static void ecore_enable_vport_rl(struct ecore_hwfn *p_hwfn, 200*14b24e2bSVaishali Kulkarni bool vport_rl_en) 201*14b24e2bSVaishali Kulkarni { 202*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_RLGLBLENABLE_RT_OFFSET, vport_rl_en ? 1 : 0); 203*14b24e2bSVaishali Kulkarni if (vport_rl_en) { 204*14b24e2bSVaishali Kulkarni 205*14b24e2bSVaishali Kulkarni /* Write RL period (use timer 0 only) */ 206*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_RLGLBLPERIOD_0_RT_OFFSET, QM_RL_PERIOD_CLK_25M); 207*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_RLGLBLPERIODTIMER_0_RT_OFFSET, QM_RL_PERIOD_CLK_25M); 208*14b24e2bSVaishali Kulkarni 209*14b24e2bSVaishali Kulkarni /* Set credit threshold for QM bypass flow */ 210*14b24e2bSVaishali Kulkarni if (QM_BYPASS_EN) 211*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_AFULLQMBYPTHRGLBLRL_RT_OFFSET, QM_RL_UPPER_BOUND); 212*14b24e2bSVaishali Kulkarni } 213*14b24e2bSVaishali Kulkarni } 214*14b24e2bSVaishali Kulkarni 215*14b24e2bSVaishali Kulkarni /* Prepare VPORT WFQ enable/disable runtime init values */ 216*14b24e2bSVaishali Kulkarni static void ecore_enable_vport_wfq(struct ecore_hwfn *p_hwfn, 217*14b24e2bSVaishali Kulkarni bool vport_wfq_en) 218*14b24e2bSVaishali Kulkarni { 219*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_WFQVPENABLE_RT_OFFSET, vport_wfq_en ? 1 : 0); 220*14b24e2bSVaishali Kulkarni 221*14b24e2bSVaishali Kulkarni /* Set credit threshold for QM bypass flow */ 222*14b24e2bSVaishali Kulkarni if (vport_wfq_en && QM_BYPASS_EN) 223*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_AFULLQMBYPTHRVPWFQ_RT_OFFSET, QM_WFQ_UPPER_BOUND); 224*14b24e2bSVaishali Kulkarni } 225*14b24e2bSVaishali Kulkarni 226*14b24e2bSVaishali Kulkarni /* Prepare runtime init values to allocate PBF command queue lines for 227*14b24e2bSVaishali Kulkarni * the specified VOQ. 228*14b24e2bSVaishali Kulkarni */ 229*14b24e2bSVaishali Kulkarni static void ecore_cmdq_lines_voq_rt_init(struct ecore_hwfn *p_hwfn, 230*14b24e2bSVaishali Kulkarni u8 voq, 231*14b24e2bSVaishali Kulkarni u16 cmdq_lines) 232*14b24e2bSVaishali Kulkarni { 233*14b24e2bSVaishali Kulkarni u32 qm_line_crd; 234*14b24e2bSVaishali Kulkarni 235*14b24e2bSVaishali Kulkarni qm_line_crd = QM_VOQ_LINE_CRD(cmdq_lines); 236*14b24e2bSVaishali Kulkarni 237*14b24e2bSVaishali Kulkarni OVERWRITE_RT_REG(p_hwfn, PBF_CMDQ_LINES_RT_OFFSET(voq), (u32)cmdq_lines); 238*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_VOQCRDLINE_RT_OFFSET + voq, qm_line_crd); 239*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_VOQINITCRDLINE_RT_OFFSET + voq, qm_line_crd); 240*14b24e2bSVaishali Kulkarni } 241*14b24e2bSVaishali Kulkarni 242*14b24e2bSVaishali Kulkarni /* Prepare runtime init values to allocate PBF command queue lines. */ 243*14b24e2bSVaishali Kulkarni static void ecore_cmdq_lines_rt_init(struct ecore_hwfn *p_hwfn, 244*14b24e2bSVaishali Kulkarni u8 max_ports_per_engine, 245*14b24e2bSVaishali Kulkarni u8 max_phys_tcs_per_port, 246*14b24e2bSVaishali Kulkarni struct init_qm_port_params port_params[MAX_NUM_PORTS]) 247*14b24e2bSVaishali Kulkarni { 248*14b24e2bSVaishali Kulkarni u8 tc, voq, port_id, num_tcs_in_port; 249*14b24e2bSVaishali Kulkarni 250*14b24e2bSVaishali Kulkarni /* Clear PBF lines for all VOQs */ 251*14b24e2bSVaishali Kulkarni for (voq = 0; voq < MAX_NUM_VOQS; voq++) 252*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, PBF_CMDQ_LINES_RT_OFFSET(voq), 0); 253*14b24e2bSVaishali Kulkarni 254*14b24e2bSVaishali Kulkarni for (port_id = 0; port_id < max_ports_per_engine; port_id++) { 255*14b24e2bSVaishali Kulkarni u16 phys_lines, phys_lines_per_tc; 256*14b24e2bSVaishali Kulkarni 257*14b24e2bSVaishali Kulkarni if (!port_params[port_id].active) 258*14b24e2bSVaishali Kulkarni continue; 259*14b24e2bSVaishali Kulkarni 260*14b24e2bSVaishali Kulkarni /* Find #lines to divide between the active physical TCs */ 261*14b24e2bSVaishali Kulkarni phys_lines = port_params[port_id].num_pbf_cmd_lines - PBF_CMDQ_PURE_LB_LINES; 262*14b24e2bSVaishali Kulkarni 263*14b24e2bSVaishali Kulkarni /* Find #lines per active physical TC */ 264*14b24e2bSVaishali Kulkarni num_tcs_in_port = 0; 265*14b24e2bSVaishali Kulkarni for (tc = 0; tc < NUM_OF_PHYS_TCS; tc++) 266*14b24e2bSVaishali Kulkarni if (((port_params[port_id].active_phys_tcs >> tc) & 0x1) == 1) 267*14b24e2bSVaishali Kulkarni num_tcs_in_port++; 268*14b24e2bSVaishali Kulkarni phys_lines_per_tc = phys_lines / num_tcs_in_port; 269*14b24e2bSVaishali Kulkarni 270*14b24e2bSVaishali Kulkarni /* Init registers per active TC */ 271*14b24e2bSVaishali Kulkarni for (tc = 0; tc < NUM_OF_PHYS_TCS; tc++) { 272*14b24e2bSVaishali Kulkarni if (((port_params[port_id].active_phys_tcs >> tc) & 0x1) == 1) { 273*14b24e2bSVaishali Kulkarni voq = PHYS_VOQ(port_id, tc, max_phys_tcs_per_port); 274*14b24e2bSVaishali Kulkarni ecore_cmdq_lines_voq_rt_init(p_hwfn, voq, phys_lines_per_tc); 275*14b24e2bSVaishali Kulkarni } 276*14b24e2bSVaishali Kulkarni } 277*14b24e2bSVaishali Kulkarni 278*14b24e2bSVaishali Kulkarni /* Init registers for pure LB TC */ 279*14b24e2bSVaishali Kulkarni ecore_cmdq_lines_voq_rt_init(p_hwfn, LB_VOQ(port_id), PBF_CMDQ_PURE_LB_LINES); 280*14b24e2bSVaishali Kulkarni } 281*14b24e2bSVaishali Kulkarni } 282*14b24e2bSVaishali Kulkarni 283*14b24e2bSVaishali Kulkarni /* Prepare runtime init values to allocate guaranteed BTB blocks for the 284*14b24e2bSVaishali Kulkarni * specified port. The guaranteed BTB space is divided between the TCs as 285*14b24e2bSVaishali Kulkarni * follows (shared space Is currently not used): 286*14b24e2bSVaishali Kulkarni * 1. Parameters: 287*14b24e2bSVaishali Kulkarni * B - BTB blocks for this port 288*14b24e2bSVaishali Kulkarni * C - Number of physical TCs for this port 289*14b24e2bSVaishali Kulkarni * 2. Calculation: 290*14b24e2bSVaishali Kulkarni * a. 38 blocks (9700B jumbo frame) are allocated for global per port 291*14b24e2bSVaishali Kulkarni * headroom. 292*14b24e2bSVaishali Kulkarni * b. B = B - 38 (remainder after global headroom allocation). 293*14b24e2bSVaishali Kulkarni * c. MAX(38,B/(C+0.7)) blocks are allocated for the pure LB VOQ. 294*14b24e2bSVaishali Kulkarni * d. B = B � MAX(38, B/(C+0.7)) (remainder after pure LB allocation). 295*14b24e2bSVaishali Kulkarni * e. B/C blocks are allocated for each physical TC. 296*14b24e2bSVaishali Kulkarni * Assumptions: 297*14b24e2bSVaishali Kulkarni * - MTU is up to 9700 bytes (38 blocks) 298*14b24e2bSVaishali Kulkarni * - All TCs are considered symmetrical (same rate and packet size) 299*14b24e2bSVaishali Kulkarni * - No optimization for lossy TC (all are considered lossless). Shared space 300*14b24e2bSVaishali Kulkarni * is not enabled and allocated for each TC. 301*14b24e2bSVaishali Kulkarni */ 302*14b24e2bSVaishali Kulkarni static void ecore_btb_blocks_rt_init(struct ecore_hwfn *p_hwfn, 303*14b24e2bSVaishali Kulkarni u8 max_ports_per_engine, 304*14b24e2bSVaishali Kulkarni u8 max_phys_tcs_per_port, 305*14b24e2bSVaishali Kulkarni struct init_qm_port_params port_params[MAX_NUM_PORTS]) 306*14b24e2bSVaishali Kulkarni { 307*14b24e2bSVaishali Kulkarni u32 usable_blocks, pure_lb_blocks, phys_blocks; 308*14b24e2bSVaishali Kulkarni u8 tc, voq, port_id, num_tcs_in_port; 309*14b24e2bSVaishali Kulkarni 310*14b24e2bSVaishali Kulkarni for (port_id = 0; port_id < max_ports_per_engine; port_id++) { 311*14b24e2bSVaishali Kulkarni if (!port_params[port_id].active) 312*14b24e2bSVaishali Kulkarni continue; 313*14b24e2bSVaishali Kulkarni 314*14b24e2bSVaishali Kulkarni /* Subtract headroom blocks */ 315*14b24e2bSVaishali Kulkarni usable_blocks = port_params[port_id].num_btb_blocks - BTB_HEADROOM_BLOCKS; 316*14b24e2bSVaishali Kulkarni 317*14b24e2bSVaishali Kulkarni /* Find blocks per physical TC. use factor to avoid floating 318*14b24e2bSVaishali Kulkarni * arithmethic. 319*14b24e2bSVaishali Kulkarni */ 320*14b24e2bSVaishali Kulkarni num_tcs_in_port = 0; 321*14b24e2bSVaishali Kulkarni for (tc = 0; tc < NUM_OF_PHYS_TCS; tc++) 322*14b24e2bSVaishali Kulkarni if (((port_params[port_id].active_phys_tcs >> tc) & 0x1) == 1) 323*14b24e2bSVaishali Kulkarni num_tcs_in_port++; 324*14b24e2bSVaishali Kulkarni 325*14b24e2bSVaishali Kulkarni pure_lb_blocks = (usable_blocks * BTB_PURE_LB_FACTOR) / (num_tcs_in_port * BTB_PURE_LB_FACTOR + BTB_PURE_LB_RATIO); 326*14b24e2bSVaishali Kulkarni pure_lb_blocks = OSAL_MAX_T(u32, BTB_JUMBO_PKT_BLOCKS, pure_lb_blocks / BTB_PURE_LB_FACTOR); 327*14b24e2bSVaishali Kulkarni phys_blocks = (usable_blocks - pure_lb_blocks) / num_tcs_in_port; 328*14b24e2bSVaishali Kulkarni 329*14b24e2bSVaishali Kulkarni /* Init physical TCs */ 330*14b24e2bSVaishali Kulkarni for (tc = 0; tc < NUM_OF_PHYS_TCS; tc++) { 331*14b24e2bSVaishali Kulkarni if (((port_params[port_id].active_phys_tcs >> tc) & 0x1) == 1) { 332*14b24e2bSVaishali Kulkarni voq = PHYS_VOQ(port_id, tc, max_phys_tcs_per_port); 333*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, PBF_BTB_GUARANTEED_RT_OFFSET(voq), phys_blocks); 334*14b24e2bSVaishali Kulkarni } 335*14b24e2bSVaishali Kulkarni } 336*14b24e2bSVaishali Kulkarni 337*14b24e2bSVaishali Kulkarni /* Init pure LB TC */ 338*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, PBF_BTB_GUARANTEED_RT_OFFSET(LB_VOQ(port_id)), pure_lb_blocks); 339*14b24e2bSVaishali Kulkarni } 340*14b24e2bSVaishali Kulkarni } 341*14b24e2bSVaishali Kulkarni 342*14b24e2bSVaishali Kulkarni /* Prepare Tx PQ mapping runtime init values for the specified PF */ 343*14b24e2bSVaishali Kulkarni static void ecore_tx_pq_map_rt_init(struct ecore_hwfn *p_hwfn, 344*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, 345*14b24e2bSVaishali Kulkarni u8 port_id, 346*14b24e2bSVaishali Kulkarni u8 pf_id, 347*14b24e2bSVaishali Kulkarni u8 max_phys_tcs_per_port, 348*14b24e2bSVaishali Kulkarni bool is_first_pf, 349*14b24e2bSVaishali Kulkarni u32 num_pf_cids, 350*14b24e2bSVaishali Kulkarni u32 num_vf_cids, 351*14b24e2bSVaishali Kulkarni u16 start_pq, 352*14b24e2bSVaishali Kulkarni u16 num_pf_pqs, 353*14b24e2bSVaishali Kulkarni u16 num_vf_pqs, 354*14b24e2bSVaishali Kulkarni u8 start_vport, 355*14b24e2bSVaishali Kulkarni u32 base_mem_addr_4kb, 356*14b24e2bSVaishali Kulkarni struct init_qm_pq_params *pq_params, 357*14b24e2bSVaishali Kulkarni struct init_qm_vport_params *vport_params) 358*14b24e2bSVaishali Kulkarni { 359*14b24e2bSVaishali Kulkarni /* A bit per Tx PQ indicating if the PQ is associated with a VF */ 360*14b24e2bSVaishali Kulkarni u32 tx_pq_vf_mask[MAX_QM_TX_QUEUES / QM_PF_QUEUE_GROUP_SIZE] = { 0 }; 361*14b24e2bSVaishali Kulkarni u32 num_tx_pq_vf_masks = MAX_QM_TX_QUEUES / QM_PF_QUEUE_GROUP_SIZE; 362*14b24e2bSVaishali Kulkarni u16 num_pqs, first_pq_group, last_pq_group, i, pq_id, pq_group; 363*14b24e2bSVaishali Kulkarni u32 pq_mem_4kb, vport_pq_mem_4kb, mem_addr_4kb; 364*14b24e2bSVaishali Kulkarni 365*14b24e2bSVaishali Kulkarni num_pqs = num_pf_pqs + num_vf_pqs; 366*14b24e2bSVaishali Kulkarni 367*14b24e2bSVaishali Kulkarni first_pq_group = start_pq / QM_PF_QUEUE_GROUP_SIZE; 368*14b24e2bSVaishali Kulkarni last_pq_group = (start_pq + num_pqs - 1) / QM_PF_QUEUE_GROUP_SIZE; 369*14b24e2bSVaishali Kulkarni 370*14b24e2bSVaishali Kulkarni pq_mem_4kb = QM_PQ_MEM_4KB(num_pf_cids); 371*14b24e2bSVaishali Kulkarni vport_pq_mem_4kb = QM_PQ_MEM_4KB(num_vf_cids); 372*14b24e2bSVaishali Kulkarni mem_addr_4kb = base_mem_addr_4kb; 373*14b24e2bSVaishali Kulkarni 374*14b24e2bSVaishali Kulkarni /* Set mapping from PQ group to PF */ 375*14b24e2bSVaishali Kulkarni for (pq_group = first_pq_group; pq_group <= last_pq_group; pq_group++) 376*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_PQTX2PF_0_RT_OFFSET + pq_group, (u32)(pf_id)); 377*14b24e2bSVaishali Kulkarni 378*14b24e2bSVaishali Kulkarni /* Set PQ sizes */ 379*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_MAXPQSIZE_0_RT_OFFSET, QM_PQ_SIZE_256B(num_pf_cids)); 380*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_MAXPQSIZE_1_RT_OFFSET, QM_PQ_SIZE_256B(num_vf_cids)); 381*14b24e2bSVaishali Kulkarni 382*14b24e2bSVaishali Kulkarni /* Go over all Tx PQs */ 383*14b24e2bSVaishali Kulkarni for (i = 0, pq_id = start_pq; i < num_pqs; i++, pq_id++) { 384*14b24e2bSVaishali Kulkarni u32 max_qm_global_rls = MAX_QM_GLOBAL_RLS; 385*14b24e2bSVaishali Kulkarni struct qm_rf_pq_map tx_pq_map; 386*14b24e2bSVaishali Kulkarni bool is_vf_pq, rl_valid; 387*14b24e2bSVaishali Kulkarni u8 voq, vport_id_in_pf; 388*14b24e2bSVaishali Kulkarni u16 first_tx_pq_id; 389*14b24e2bSVaishali Kulkarni 390*14b24e2bSVaishali Kulkarni voq = VOQ(port_id, pq_params[i].tc_id, max_phys_tcs_per_port); 391*14b24e2bSVaishali Kulkarni is_vf_pq = (i >= num_pf_pqs); 392*14b24e2bSVaishali Kulkarni rl_valid = pq_params[i].rl_valid && pq_params[i].vport_id < max_qm_global_rls; 393*14b24e2bSVaishali Kulkarni 394*14b24e2bSVaishali Kulkarni /* Update first Tx PQ of VPORT/TC */ 395*14b24e2bSVaishali Kulkarni vport_id_in_pf = pq_params[i].vport_id - start_vport; 396*14b24e2bSVaishali Kulkarni first_tx_pq_id = vport_params[vport_id_in_pf].first_tx_pq_id[pq_params[i].tc_id]; 397*14b24e2bSVaishali Kulkarni if (first_tx_pq_id == QM_INVALID_PQ_ID) { 398*14b24e2bSVaishali Kulkarni 399*14b24e2bSVaishali Kulkarni /* Create new VP PQ */ 400*14b24e2bSVaishali Kulkarni vport_params[vport_id_in_pf].first_tx_pq_id[pq_params[i].tc_id] = pq_id; 401*14b24e2bSVaishali Kulkarni first_tx_pq_id = pq_id; 402*14b24e2bSVaishali Kulkarni 403*14b24e2bSVaishali Kulkarni /* Map VP PQ to VOQ and PF */ 404*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_WFQVPMAP_RT_OFFSET + first_tx_pq_id, (voq << QM_WFQ_VP_PQ_VOQ_SHIFT) | (pf_id << QM_WFQ_VP_PQ_PF_SHIFT)); 405*14b24e2bSVaishali Kulkarni } 406*14b24e2bSVaishali Kulkarni 407*14b24e2bSVaishali Kulkarni /* Check RL ID */ 408*14b24e2bSVaishali Kulkarni if (pq_params[i].rl_valid && pq_params[i].vport_id >= max_qm_global_rls) 409*14b24e2bSVaishali Kulkarni DP_NOTICE(p_hwfn, true, "Invalid VPORT ID for rate limiter configuration\n"); 410*14b24e2bSVaishali Kulkarni 411*14b24e2bSVaishali Kulkarni /* Fill PQ map entry */ 412*14b24e2bSVaishali Kulkarni OSAL_MEMSET(&tx_pq_map, 0, sizeof(tx_pq_map)); 413*14b24e2bSVaishali Kulkarni SET_FIELD(tx_pq_map.reg, QM_RF_PQ_MAP_PQ_VALID, 1); 414*14b24e2bSVaishali Kulkarni SET_FIELD(tx_pq_map.reg, QM_RF_PQ_MAP_RL_VALID, rl_valid ? 1 : 0); 415*14b24e2bSVaishali Kulkarni SET_FIELD(tx_pq_map.reg, QM_RF_PQ_MAP_VP_PQ_ID, first_tx_pq_id); 416*14b24e2bSVaishali Kulkarni SET_FIELD(tx_pq_map.reg, QM_RF_PQ_MAP_RL_ID, rl_valid ? pq_params[i].vport_id : 0); 417*14b24e2bSVaishali Kulkarni SET_FIELD(tx_pq_map.reg, QM_RF_PQ_MAP_VOQ, voq); 418*14b24e2bSVaishali Kulkarni SET_FIELD(tx_pq_map.reg, QM_RF_PQ_MAP_WRR_WEIGHT_GROUP, pq_params[i].wrr_group); 419*14b24e2bSVaishali Kulkarni 420*14b24e2bSVaishali Kulkarni /* Write PQ map entry to CAM */ 421*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_TXPQMAP_RT_OFFSET + pq_id, *((u32*)&tx_pq_map)); 422*14b24e2bSVaishali Kulkarni 423*14b24e2bSVaishali Kulkarni /* Set base address */ 424*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_BASEADDRTXPQ_RT_OFFSET + pq_id, mem_addr_4kb); 425*14b24e2bSVaishali Kulkarni 426*14b24e2bSVaishali Kulkarni /* If VF PQ, add indication to PQ VF mask */ 427*14b24e2bSVaishali Kulkarni if (is_vf_pq) { 428*14b24e2bSVaishali Kulkarni tx_pq_vf_mask[pq_id / QM_PF_QUEUE_GROUP_SIZE] |= (1 << (pq_id % QM_PF_QUEUE_GROUP_SIZE)); 429*14b24e2bSVaishali Kulkarni mem_addr_4kb += vport_pq_mem_4kb; 430*14b24e2bSVaishali Kulkarni } 431*14b24e2bSVaishali Kulkarni else { 432*14b24e2bSVaishali Kulkarni mem_addr_4kb += pq_mem_4kb; 433*14b24e2bSVaishali Kulkarni } 434*14b24e2bSVaishali Kulkarni } 435*14b24e2bSVaishali Kulkarni 436*14b24e2bSVaishali Kulkarni /* Store Tx PQ VF mask to size select register */ 437*14b24e2bSVaishali Kulkarni for (i = 0; i < num_tx_pq_vf_masks; i++) 438*14b24e2bSVaishali Kulkarni if (tx_pq_vf_mask[i]) 439*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_MAXPQSIZETXSEL_0_RT_OFFSET + i, tx_pq_vf_mask[i]); 440*14b24e2bSVaishali Kulkarni } 441*14b24e2bSVaishali Kulkarni 442*14b24e2bSVaishali Kulkarni /* Prepare Other PQ mapping runtime init values for the specified PF */ 443*14b24e2bSVaishali Kulkarni static void ecore_other_pq_map_rt_init(struct ecore_hwfn *p_hwfn, 444*14b24e2bSVaishali Kulkarni u8 port_id, 445*14b24e2bSVaishali Kulkarni u8 pf_id, 446*14b24e2bSVaishali Kulkarni u32 num_pf_cids, 447*14b24e2bSVaishali Kulkarni u32 num_tids, 448*14b24e2bSVaishali Kulkarni u32 base_mem_addr_4kb) 449*14b24e2bSVaishali Kulkarni { 450*14b24e2bSVaishali Kulkarni u32 pq_size, pq_mem_4kb, mem_addr_4kb; 451*14b24e2bSVaishali Kulkarni u16 i, pq_id, pq_group; 452*14b24e2bSVaishali Kulkarni 453*14b24e2bSVaishali Kulkarni /* A single other PQ group is used in each PF, where PQ group i is used 454*14b24e2bSVaishali Kulkarni * in PF i. 455*14b24e2bSVaishali Kulkarni */ 456*14b24e2bSVaishali Kulkarni pq_group = pf_id; 457*14b24e2bSVaishali Kulkarni pq_size = num_pf_cids + num_tids; 458*14b24e2bSVaishali Kulkarni pq_mem_4kb = QM_PQ_MEM_4KB(pq_size); 459*14b24e2bSVaishali Kulkarni mem_addr_4kb = base_mem_addr_4kb; 460*14b24e2bSVaishali Kulkarni 461*14b24e2bSVaishali Kulkarni /* Map PQ group to PF */ 462*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_PQOTHER2PF_0_RT_OFFSET + pq_group, (u32)(pf_id)); 463*14b24e2bSVaishali Kulkarni 464*14b24e2bSVaishali Kulkarni /* Set PQ sizes */ 465*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_MAXPQSIZE_2_RT_OFFSET, QM_PQ_SIZE_256B(pq_size)); 466*14b24e2bSVaishali Kulkarni 467*14b24e2bSVaishali Kulkarni /* Set base address */ 468*14b24e2bSVaishali Kulkarni for (i = 0, pq_id = pf_id * QM_PF_QUEUE_GROUP_SIZE; i < QM_OTHER_PQS_PER_PF; i++, pq_id++) { 469*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_BASEADDROTHERPQ_RT_OFFSET + pq_id, mem_addr_4kb); 470*14b24e2bSVaishali Kulkarni mem_addr_4kb += pq_mem_4kb; 471*14b24e2bSVaishali Kulkarni } 472*14b24e2bSVaishali Kulkarni } 473*14b24e2bSVaishali Kulkarni 474*14b24e2bSVaishali Kulkarni /* Prepare PF WFQ runtime init values for the specified PF. 475*14b24e2bSVaishali Kulkarni * Return -1 on error. 476*14b24e2bSVaishali Kulkarni */ 477*14b24e2bSVaishali Kulkarni static int ecore_pf_wfq_rt_init(struct ecore_hwfn *p_hwfn, 478*14b24e2bSVaishali Kulkarni u8 port_id, 479*14b24e2bSVaishali Kulkarni u8 pf_id, 480*14b24e2bSVaishali Kulkarni u16 pf_wfq, 481*14b24e2bSVaishali Kulkarni u8 max_phys_tcs_per_port, 482*14b24e2bSVaishali Kulkarni u16 num_tx_pqs, 483*14b24e2bSVaishali Kulkarni struct init_qm_pq_params *pq_params) 484*14b24e2bSVaishali Kulkarni { 485*14b24e2bSVaishali Kulkarni u32 inc_val, crd_reg_offset; 486*14b24e2bSVaishali Kulkarni u8 voq; 487*14b24e2bSVaishali Kulkarni u16 i; 488*14b24e2bSVaishali Kulkarni 489*14b24e2bSVaishali Kulkarni crd_reg_offset = (pf_id < MAX_NUM_PFS_BB ? QM_REG_WFQPFCRD_RT_OFFSET : QM_REG_WFQPFCRD_MSB_RT_OFFSET) + (pf_id % MAX_NUM_PFS_BB); 490*14b24e2bSVaishali Kulkarni 491*14b24e2bSVaishali Kulkarni inc_val = QM_WFQ_INC_VAL(pf_wfq); 492*14b24e2bSVaishali Kulkarni if (!inc_val || inc_val > QM_WFQ_MAX_INC_VAL) { 493*14b24e2bSVaishali Kulkarni DP_NOTICE(p_hwfn, true, "Invalid PF WFQ weight configuration\n"); 494*14b24e2bSVaishali Kulkarni return -1; 495*14b24e2bSVaishali Kulkarni } 496*14b24e2bSVaishali Kulkarni 497*14b24e2bSVaishali Kulkarni for(i = 0; i < num_tx_pqs; i++) { 498*14b24e2bSVaishali Kulkarni voq = VOQ(port_id, pq_params[i].tc_id, max_phys_tcs_per_port); 499*14b24e2bSVaishali Kulkarni OVERWRITE_RT_REG(p_hwfn, crd_reg_offset + voq * MAX_NUM_PFS_BB, (u32)QM_WFQ_CRD_REG_SIGN_BIT); 500*14b24e2bSVaishali Kulkarni } 501*14b24e2bSVaishali Kulkarni 502*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_WFQPFUPPERBOUND_RT_OFFSET + pf_id, QM_WFQ_UPPER_BOUND | (u32)QM_WFQ_CRD_REG_SIGN_BIT); 503*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_WFQPFWEIGHT_RT_OFFSET + pf_id, inc_val); 504*14b24e2bSVaishali Kulkarni 505*14b24e2bSVaishali Kulkarni return 0; 506*14b24e2bSVaishali Kulkarni } 507*14b24e2bSVaishali Kulkarni 508*14b24e2bSVaishali Kulkarni /* Prepare PF RL runtime init values for the specified PF. 509*14b24e2bSVaishali Kulkarni * Return -1 on error. 510*14b24e2bSVaishali Kulkarni */ 511*14b24e2bSVaishali Kulkarni static int ecore_pf_rl_rt_init(struct ecore_hwfn *p_hwfn, 512*14b24e2bSVaishali Kulkarni u8 pf_id, 513*14b24e2bSVaishali Kulkarni u32 pf_rl) 514*14b24e2bSVaishali Kulkarni { 515*14b24e2bSVaishali Kulkarni u32 inc_val; 516*14b24e2bSVaishali Kulkarni 517*14b24e2bSVaishali Kulkarni inc_val = QM_RL_INC_VAL(pf_rl); 518*14b24e2bSVaishali Kulkarni if (inc_val > QM_RL_MAX_INC_VAL) { 519*14b24e2bSVaishali Kulkarni DP_NOTICE(p_hwfn, true, "Invalid PF rate limit configuration\n"); 520*14b24e2bSVaishali Kulkarni return -1; 521*14b24e2bSVaishali Kulkarni } 522*14b24e2bSVaishali Kulkarni 523*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_RLPFCRD_RT_OFFSET + pf_id, (u32)QM_RL_CRD_REG_SIGN_BIT); 524*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_RLPFUPPERBOUND_RT_OFFSET + pf_id, QM_RL_UPPER_BOUND | (u32)QM_RL_CRD_REG_SIGN_BIT); 525*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_RLPFINCVAL_RT_OFFSET + pf_id, inc_val); 526*14b24e2bSVaishali Kulkarni 527*14b24e2bSVaishali Kulkarni return 0; 528*14b24e2bSVaishali Kulkarni } 529*14b24e2bSVaishali Kulkarni 530*14b24e2bSVaishali Kulkarni /* Prepare VPORT WFQ runtime init values for the specified VPORTs. 531*14b24e2bSVaishali Kulkarni * Return -1 on error. 532*14b24e2bSVaishali Kulkarni */ 533*14b24e2bSVaishali Kulkarni static int ecore_vp_wfq_rt_init(struct ecore_hwfn *p_hwfn, 534*14b24e2bSVaishali Kulkarni u8 num_vports, 535*14b24e2bSVaishali Kulkarni struct init_qm_vport_params *vport_params) 536*14b24e2bSVaishali Kulkarni { 537*14b24e2bSVaishali Kulkarni u16 vport_pq_id; 538*14b24e2bSVaishali Kulkarni u32 inc_val; 539*14b24e2bSVaishali Kulkarni u8 tc, i; 540*14b24e2bSVaishali Kulkarni 541*14b24e2bSVaishali Kulkarni /* Go over all PF VPORTs */ 542*14b24e2bSVaishali Kulkarni for (i = 0; i < num_vports; i++) { 543*14b24e2bSVaishali Kulkarni if (!vport_params[i].vport_wfq) 544*14b24e2bSVaishali Kulkarni continue; 545*14b24e2bSVaishali Kulkarni 546*14b24e2bSVaishali Kulkarni inc_val = QM_WFQ_INC_VAL(vport_params[i].vport_wfq); 547*14b24e2bSVaishali Kulkarni if (inc_val > QM_WFQ_MAX_INC_VAL) { 548*14b24e2bSVaishali Kulkarni DP_NOTICE(p_hwfn, true, "Invalid VPORT WFQ weight configuration\n"); 549*14b24e2bSVaishali Kulkarni return -1; 550*14b24e2bSVaishali Kulkarni } 551*14b24e2bSVaishali Kulkarni 552*14b24e2bSVaishali Kulkarni /* Each VPORT can have several VPORT PQ IDs for various TCs */ 553*14b24e2bSVaishali Kulkarni for (tc = 0; tc < NUM_OF_TCS; tc++) { 554*14b24e2bSVaishali Kulkarni vport_pq_id = vport_params[i].first_tx_pq_id[tc]; 555*14b24e2bSVaishali Kulkarni if (vport_pq_id != QM_INVALID_PQ_ID) { 556*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_WFQVPCRD_RT_OFFSET + vport_pq_id, (u32)QM_WFQ_CRD_REG_SIGN_BIT); 557*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_WFQVPWEIGHT_RT_OFFSET + vport_pq_id, inc_val); 558*14b24e2bSVaishali Kulkarni } 559*14b24e2bSVaishali Kulkarni } 560*14b24e2bSVaishali Kulkarni } 561*14b24e2bSVaishali Kulkarni 562*14b24e2bSVaishali Kulkarni return 0; 563*14b24e2bSVaishali Kulkarni } 564*14b24e2bSVaishali Kulkarni 565*14b24e2bSVaishali Kulkarni /* Prepare VPORT RL runtime init values for the specified VPORTs. 566*14b24e2bSVaishali Kulkarni * Return -1 on error. 567*14b24e2bSVaishali Kulkarni */ 568*14b24e2bSVaishali Kulkarni static int ecore_vport_rl_rt_init(struct ecore_hwfn *p_hwfn, 569*14b24e2bSVaishali Kulkarni u8 start_vport, 570*14b24e2bSVaishali Kulkarni u8 num_vports, 571*14b24e2bSVaishali Kulkarni struct init_qm_vport_params *vport_params) 572*14b24e2bSVaishali Kulkarni { 573*14b24e2bSVaishali Kulkarni u8 i, vport_id; 574*14b24e2bSVaishali Kulkarni u32 inc_val; 575*14b24e2bSVaishali Kulkarni 576*14b24e2bSVaishali Kulkarni if (start_vport + num_vports >= MAX_QM_GLOBAL_RLS) { 577*14b24e2bSVaishali Kulkarni DP_NOTICE(p_hwfn, true, "Invalid VPORT ID for rate limiter configuration\n"); 578*14b24e2bSVaishali Kulkarni return -1; 579*14b24e2bSVaishali Kulkarni } 580*14b24e2bSVaishali Kulkarni 581*14b24e2bSVaishali Kulkarni /* Go over all PF VPORTs */ 582*14b24e2bSVaishali Kulkarni for (i = 0, vport_id = start_vport; i < num_vports; i++, vport_id++) { 583*14b24e2bSVaishali Kulkarni inc_val = QM_RL_INC_VAL(vport_params[i].vport_rl); 584*14b24e2bSVaishali Kulkarni if (inc_val > QM_RL_MAX_INC_VAL) { 585*14b24e2bSVaishali Kulkarni DP_NOTICE(p_hwfn, true, "Invalid VPORT rate-limit configuration\n"); 586*14b24e2bSVaishali Kulkarni return -1; 587*14b24e2bSVaishali Kulkarni } 588*14b24e2bSVaishali Kulkarni 589*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_RLGLBLCRD_RT_OFFSET + vport_id, (u32)QM_RL_CRD_REG_SIGN_BIT); 590*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_RLGLBLUPPERBOUND_RT_OFFSET + vport_id, QM_RL_UPPER_BOUND | (u32)QM_RL_CRD_REG_SIGN_BIT); 591*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_RLGLBLINCVAL_RT_OFFSET + vport_id, inc_val); 592*14b24e2bSVaishali Kulkarni } 593*14b24e2bSVaishali Kulkarni 594*14b24e2bSVaishali Kulkarni return 0; 595*14b24e2bSVaishali Kulkarni } 596*14b24e2bSVaishali Kulkarni 597*14b24e2bSVaishali Kulkarni static bool ecore_poll_on_qm_cmd_ready(struct ecore_hwfn *p_hwfn, 598*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt) 599*14b24e2bSVaishali Kulkarni { 600*14b24e2bSVaishali Kulkarni u32 reg_val, i; 601*14b24e2bSVaishali Kulkarni 602*14b24e2bSVaishali Kulkarni for (i = 0, reg_val = 0; i < QM_STOP_CMD_MAX_POLL_COUNT && !reg_val; i++) { 603*14b24e2bSVaishali Kulkarni OSAL_UDELAY(QM_STOP_CMD_POLL_PERIOD_US); 604*14b24e2bSVaishali Kulkarni reg_val = ecore_rd(p_hwfn, p_ptt, QM_REG_SDMCMDREADY); 605*14b24e2bSVaishali Kulkarni } 606*14b24e2bSVaishali Kulkarni 607*14b24e2bSVaishali Kulkarni /* Check if timeout while waiting for SDM command ready */ 608*14b24e2bSVaishali Kulkarni if (i == QM_STOP_CMD_MAX_POLL_COUNT) { 609*14b24e2bSVaishali Kulkarni DP_VERBOSE(p_hwfn, ECORE_MSG_DEBUG, "Timeout when waiting for QM SDM command ready signal\n"); 610*14b24e2bSVaishali Kulkarni return false; 611*14b24e2bSVaishali Kulkarni } 612*14b24e2bSVaishali Kulkarni 613*14b24e2bSVaishali Kulkarni return true; 614*14b24e2bSVaishali Kulkarni } 615*14b24e2bSVaishali Kulkarni 616*14b24e2bSVaishali Kulkarni static bool ecore_send_qm_cmd(struct ecore_hwfn *p_hwfn, 617*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, 618*14b24e2bSVaishali Kulkarni u32 cmd_addr, 619*14b24e2bSVaishali Kulkarni u32 cmd_data_lsb, 620*14b24e2bSVaishali Kulkarni u32 cmd_data_msb) 621*14b24e2bSVaishali Kulkarni { 622*14b24e2bSVaishali Kulkarni if (!ecore_poll_on_qm_cmd_ready(p_hwfn, p_ptt)) 623*14b24e2bSVaishali Kulkarni return false; 624*14b24e2bSVaishali Kulkarni 625*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, QM_REG_SDMCMDADDR, cmd_addr); 626*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, QM_REG_SDMCMDDATALSB, cmd_data_lsb); 627*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, QM_REG_SDMCMDDATAMSB, cmd_data_msb); 628*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, QM_REG_SDMCMDGO, 1); 629*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, QM_REG_SDMCMDGO, 0); 630*14b24e2bSVaishali Kulkarni 631*14b24e2bSVaishali Kulkarni return ecore_poll_on_qm_cmd_ready(p_hwfn, p_ptt); 632*14b24e2bSVaishali Kulkarni } 633*14b24e2bSVaishali Kulkarni 634*14b24e2bSVaishali Kulkarni 635*14b24e2bSVaishali Kulkarni /******************** INTERFACE IMPLEMENTATION *********************/ 636*14b24e2bSVaishali Kulkarni 637*14b24e2bSVaishali Kulkarni u32 ecore_qm_pf_mem_size(u8 pf_id, 638*14b24e2bSVaishali Kulkarni u32 num_pf_cids, 639*14b24e2bSVaishali Kulkarni u32 num_vf_cids, 640*14b24e2bSVaishali Kulkarni u32 num_tids, 641*14b24e2bSVaishali Kulkarni u16 num_pf_pqs, 642*14b24e2bSVaishali Kulkarni u16 num_vf_pqs) 643*14b24e2bSVaishali Kulkarni { 644*14b24e2bSVaishali Kulkarni return QM_PQ_MEM_4KB(num_pf_cids) * num_pf_pqs + 645*14b24e2bSVaishali Kulkarni QM_PQ_MEM_4KB(num_vf_cids) * num_vf_pqs + 646*14b24e2bSVaishali Kulkarni QM_PQ_MEM_4KB(num_pf_cids + num_tids) * QM_OTHER_PQS_PER_PF; 647*14b24e2bSVaishali Kulkarni } 648*14b24e2bSVaishali Kulkarni 649*14b24e2bSVaishali Kulkarni int ecore_qm_common_rt_init(struct ecore_hwfn *p_hwfn, 650*14b24e2bSVaishali Kulkarni u8 max_ports_per_engine, 651*14b24e2bSVaishali Kulkarni u8 max_phys_tcs_per_port, 652*14b24e2bSVaishali Kulkarni bool pf_rl_en, 653*14b24e2bSVaishali Kulkarni bool pf_wfq_en, 654*14b24e2bSVaishali Kulkarni bool vport_rl_en, 655*14b24e2bSVaishali Kulkarni bool vport_wfq_en, 656*14b24e2bSVaishali Kulkarni struct init_qm_port_params port_params[MAX_NUM_PORTS]) 657*14b24e2bSVaishali Kulkarni { 658*14b24e2bSVaishali Kulkarni u32 mask; 659*14b24e2bSVaishali Kulkarni 660*14b24e2bSVaishali Kulkarni /* Init AFullOprtnstcCrdMask */ 661*14b24e2bSVaishali Kulkarni mask = (QM_OPPOR_LINE_VOQ_DEF << QM_RF_OPPORTUNISTIC_MASK_LINEVOQ_SHIFT) | 662*14b24e2bSVaishali Kulkarni (QM_BYTE_CRD_EN << QM_RF_OPPORTUNISTIC_MASK_BYTEVOQ_SHIFT) | 663*14b24e2bSVaishali Kulkarni (pf_wfq_en << QM_RF_OPPORTUNISTIC_MASK_PFWFQ_SHIFT) | 664*14b24e2bSVaishali Kulkarni (vport_wfq_en << QM_RF_OPPORTUNISTIC_MASK_VPWFQ_SHIFT) | 665*14b24e2bSVaishali Kulkarni (pf_rl_en << QM_RF_OPPORTUNISTIC_MASK_PFRL_SHIFT) | 666*14b24e2bSVaishali Kulkarni (vport_rl_en << QM_RF_OPPORTUNISTIC_MASK_VPQCNRL_SHIFT) | 667*14b24e2bSVaishali Kulkarni (QM_OPPOR_FW_STOP_DEF << QM_RF_OPPORTUNISTIC_MASK_FWPAUSE_SHIFT) | 668*14b24e2bSVaishali Kulkarni (QM_OPPOR_PQ_EMPTY_DEF << QM_RF_OPPORTUNISTIC_MASK_QUEUEEMPTY_SHIFT); 669*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, QM_REG_AFULLOPRTNSTCCRDMASK_RT_OFFSET, mask); 670*14b24e2bSVaishali Kulkarni 671*14b24e2bSVaishali Kulkarni /* Enable/disable PF RL */ 672*14b24e2bSVaishali Kulkarni ecore_enable_pf_rl(p_hwfn, pf_rl_en); 673*14b24e2bSVaishali Kulkarni 674*14b24e2bSVaishali Kulkarni /* Enable/disable PF WFQ */ 675*14b24e2bSVaishali Kulkarni ecore_enable_pf_wfq(p_hwfn, pf_wfq_en); 676*14b24e2bSVaishali Kulkarni 677*14b24e2bSVaishali Kulkarni /* Enable/disable VPORT RL */ 678*14b24e2bSVaishali Kulkarni ecore_enable_vport_rl(p_hwfn, vport_rl_en); 679*14b24e2bSVaishali Kulkarni 680*14b24e2bSVaishali Kulkarni /* Enable/disable VPORT WFQ */ 681*14b24e2bSVaishali Kulkarni ecore_enable_vport_wfq(p_hwfn, vport_wfq_en); 682*14b24e2bSVaishali Kulkarni 683*14b24e2bSVaishali Kulkarni /* Init PBF CMDQ line credit */ 684*14b24e2bSVaishali Kulkarni ecore_cmdq_lines_rt_init(p_hwfn, max_ports_per_engine, max_phys_tcs_per_port, port_params); 685*14b24e2bSVaishali Kulkarni 686*14b24e2bSVaishali Kulkarni /* Init BTB blocks in PBF */ 687*14b24e2bSVaishali Kulkarni ecore_btb_blocks_rt_init(p_hwfn, max_ports_per_engine, max_phys_tcs_per_port, port_params); 688*14b24e2bSVaishali Kulkarni 689*14b24e2bSVaishali Kulkarni return 0; 690*14b24e2bSVaishali Kulkarni } 691*14b24e2bSVaishali Kulkarni 692*14b24e2bSVaishali Kulkarni int ecore_qm_pf_rt_init(struct ecore_hwfn *p_hwfn, 693*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, 694*14b24e2bSVaishali Kulkarni u8 port_id, 695*14b24e2bSVaishali Kulkarni u8 pf_id, 696*14b24e2bSVaishali Kulkarni u8 max_phys_tcs_per_port, 697*14b24e2bSVaishali Kulkarni bool is_first_pf, 698*14b24e2bSVaishali Kulkarni u32 num_pf_cids, 699*14b24e2bSVaishali Kulkarni u32 num_vf_cids, 700*14b24e2bSVaishali Kulkarni u32 num_tids, 701*14b24e2bSVaishali Kulkarni u16 start_pq, 702*14b24e2bSVaishali Kulkarni u16 num_pf_pqs, 703*14b24e2bSVaishali Kulkarni u16 num_vf_pqs, 704*14b24e2bSVaishali Kulkarni u8 start_vport, 705*14b24e2bSVaishali Kulkarni u8 num_vports, 706*14b24e2bSVaishali Kulkarni u16 pf_wfq, 707*14b24e2bSVaishali Kulkarni u32 pf_rl, 708*14b24e2bSVaishali Kulkarni struct init_qm_pq_params *pq_params, 709*14b24e2bSVaishali Kulkarni struct init_qm_vport_params *vport_params) 710*14b24e2bSVaishali Kulkarni { 711*14b24e2bSVaishali Kulkarni u32 other_mem_size_4kb; 712*14b24e2bSVaishali Kulkarni u8 tc, i; 713*14b24e2bSVaishali Kulkarni 714*14b24e2bSVaishali Kulkarni other_mem_size_4kb = QM_PQ_MEM_4KB(num_pf_cids + num_tids) * QM_OTHER_PQS_PER_PF; 715*14b24e2bSVaishali Kulkarni 716*14b24e2bSVaishali Kulkarni /* Clear first Tx PQ ID array for each VPORT */ 717*14b24e2bSVaishali Kulkarni for(i = 0; i < num_vports; i++) 718*14b24e2bSVaishali Kulkarni for(tc = 0; tc < NUM_OF_TCS; tc++) 719*14b24e2bSVaishali Kulkarni vport_params[i].first_tx_pq_id[tc] = QM_INVALID_PQ_ID; 720*14b24e2bSVaishali Kulkarni 721*14b24e2bSVaishali Kulkarni /* Map Other PQs (if any) */ 722*14b24e2bSVaishali Kulkarni #if QM_OTHER_PQS_PER_PF > 0 723*14b24e2bSVaishali Kulkarni ecore_other_pq_map_rt_init(p_hwfn, port_id, pf_id, num_pf_cids, num_tids, 0); 724*14b24e2bSVaishali Kulkarni #endif 725*14b24e2bSVaishali Kulkarni 726*14b24e2bSVaishali Kulkarni /* Map Tx PQs */ 727*14b24e2bSVaishali Kulkarni ecore_tx_pq_map_rt_init(p_hwfn, p_ptt, port_id, pf_id, max_phys_tcs_per_port, is_first_pf, num_pf_cids, num_vf_cids, 728*14b24e2bSVaishali Kulkarni start_pq, num_pf_pqs, num_vf_pqs, start_vport, other_mem_size_4kb, pq_params, vport_params); 729*14b24e2bSVaishali Kulkarni 730*14b24e2bSVaishali Kulkarni /* Init PF WFQ */ 731*14b24e2bSVaishali Kulkarni if (pf_wfq) 732*14b24e2bSVaishali Kulkarni if (ecore_pf_wfq_rt_init(p_hwfn, port_id, pf_id, pf_wfq, max_phys_tcs_per_port, num_pf_pqs + num_vf_pqs, pq_params)) 733*14b24e2bSVaishali Kulkarni return -1; 734*14b24e2bSVaishali Kulkarni 735*14b24e2bSVaishali Kulkarni /* Init PF RL */ 736*14b24e2bSVaishali Kulkarni if (ecore_pf_rl_rt_init(p_hwfn, pf_id, pf_rl)) 737*14b24e2bSVaishali Kulkarni return -1; 738*14b24e2bSVaishali Kulkarni 739*14b24e2bSVaishali Kulkarni /* Set VPORT WFQ */ 740*14b24e2bSVaishali Kulkarni if (ecore_vp_wfq_rt_init(p_hwfn, num_vports, vport_params)) 741*14b24e2bSVaishali Kulkarni return -1; 742*14b24e2bSVaishali Kulkarni 743*14b24e2bSVaishali Kulkarni /* Set VPORT RL */ 744*14b24e2bSVaishali Kulkarni if (ecore_vport_rl_rt_init(p_hwfn, start_vport, num_vports, vport_params)) 745*14b24e2bSVaishali Kulkarni return -1; 746*14b24e2bSVaishali Kulkarni 747*14b24e2bSVaishali Kulkarni return 0; 748*14b24e2bSVaishali Kulkarni } 749*14b24e2bSVaishali Kulkarni 750*14b24e2bSVaishali Kulkarni int ecore_init_pf_wfq(struct ecore_hwfn *p_hwfn, 751*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, 752*14b24e2bSVaishali Kulkarni u8 pf_id, 753*14b24e2bSVaishali Kulkarni u16 pf_wfq) 754*14b24e2bSVaishali Kulkarni { 755*14b24e2bSVaishali Kulkarni u32 inc_val; 756*14b24e2bSVaishali Kulkarni 757*14b24e2bSVaishali Kulkarni inc_val = QM_WFQ_INC_VAL(pf_wfq); 758*14b24e2bSVaishali Kulkarni if (!inc_val || inc_val > QM_WFQ_MAX_INC_VAL) { 759*14b24e2bSVaishali Kulkarni DP_NOTICE(p_hwfn, true, "Invalid PF WFQ weight configuration\n"); 760*14b24e2bSVaishali Kulkarni return -1; 761*14b24e2bSVaishali Kulkarni } 762*14b24e2bSVaishali Kulkarni 763*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, QM_REG_WFQPFWEIGHT + pf_id * 4, inc_val); 764*14b24e2bSVaishali Kulkarni 765*14b24e2bSVaishali Kulkarni return 0; 766*14b24e2bSVaishali Kulkarni } 767*14b24e2bSVaishali Kulkarni 768*14b24e2bSVaishali Kulkarni int ecore_init_pf_rl(struct ecore_hwfn *p_hwfn, 769*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, 770*14b24e2bSVaishali Kulkarni u8 pf_id, 771*14b24e2bSVaishali Kulkarni u32 pf_rl) 772*14b24e2bSVaishali Kulkarni { 773*14b24e2bSVaishali Kulkarni u32 inc_val; 774*14b24e2bSVaishali Kulkarni 775*14b24e2bSVaishali Kulkarni inc_val = QM_RL_INC_VAL(pf_rl); 776*14b24e2bSVaishali Kulkarni if (inc_val > QM_RL_MAX_INC_VAL) { 777*14b24e2bSVaishali Kulkarni DP_NOTICE(p_hwfn, true, "Invalid PF rate limit configuration\n"); 778*14b24e2bSVaishali Kulkarni return -1; 779*14b24e2bSVaishali Kulkarni } 780*14b24e2bSVaishali Kulkarni 781*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, QM_REG_RLPFCRD + pf_id * 4, (u32)QM_RL_CRD_REG_SIGN_BIT); 782*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, QM_REG_RLPFINCVAL + pf_id * 4, inc_val); 783*14b24e2bSVaishali Kulkarni 784*14b24e2bSVaishali Kulkarni return 0; 785*14b24e2bSVaishali Kulkarni } 786*14b24e2bSVaishali Kulkarni 787*14b24e2bSVaishali Kulkarni int ecore_init_vport_wfq(struct ecore_hwfn *p_hwfn, 788*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, 789*14b24e2bSVaishali Kulkarni u16 first_tx_pq_id[NUM_OF_TCS], 790*14b24e2bSVaishali Kulkarni u16 vport_wfq) 791*14b24e2bSVaishali Kulkarni { 792*14b24e2bSVaishali Kulkarni u16 vport_pq_id; 793*14b24e2bSVaishali Kulkarni u32 inc_val; 794*14b24e2bSVaishali Kulkarni u8 tc; 795*14b24e2bSVaishali Kulkarni 796*14b24e2bSVaishali Kulkarni inc_val = QM_WFQ_INC_VAL(vport_wfq); 797*14b24e2bSVaishali Kulkarni if (!inc_val || inc_val > QM_WFQ_MAX_INC_VAL) { 798*14b24e2bSVaishali Kulkarni DP_NOTICE(p_hwfn, true, "Invalid VPORT WFQ weight configuration\n"); 799*14b24e2bSVaishali Kulkarni return -1; 800*14b24e2bSVaishali Kulkarni } 801*14b24e2bSVaishali Kulkarni 802*14b24e2bSVaishali Kulkarni for (tc = 0; tc < NUM_OF_TCS; tc++) { 803*14b24e2bSVaishali Kulkarni vport_pq_id = first_tx_pq_id[tc]; 804*14b24e2bSVaishali Kulkarni if (vport_pq_id != QM_INVALID_PQ_ID) { 805*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, QM_REG_WFQVPWEIGHT + vport_pq_id * 4, inc_val); 806*14b24e2bSVaishali Kulkarni } 807*14b24e2bSVaishali Kulkarni } 808*14b24e2bSVaishali Kulkarni 809*14b24e2bSVaishali Kulkarni return 0; 810*14b24e2bSVaishali Kulkarni } 811*14b24e2bSVaishali Kulkarni 812*14b24e2bSVaishali Kulkarni int ecore_init_vport_rl(struct ecore_hwfn *p_hwfn, 813*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, 814*14b24e2bSVaishali Kulkarni u8 vport_id, 815*14b24e2bSVaishali Kulkarni u32 vport_rl) 816*14b24e2bSVaishali Kulkarni { 817*14b24e2bSVaishali Kulkarni u32 inc_val, max_qm_global_rls = MAX_QM_GLOBAL_RLS; 818*14b24e2bSVaishali Kulkarni 819*14b24e2bSVaishali Kulkarni if (vport_id >= max_qm_global_rls) { 820*14b24e2bSVaishali Kulkarni DP_NOTICE(p_hwfn, true, "Invalid VPORT ID for rate limiter configuration\n"); 821*14b24e2bSVaishali Kulkarni return -1; 822*14b24e2bSVaishali Kulkarni } 823*14b24e2bSVaishali Kulkarni 824*14b24e2bSVaishali Kulkarni inc_val = QM_RL_INC_VAL(vport_rl); 825*14b24e2bSVaishali Kulkarni if (inc_val > QM_RL_MAX_INC_VAL) { 826*14b24e2bSVaishali Kulkarni DP_NOTICE(p_hwfn, true, "Invalid VPORT rate-limit configuration\n"); 827*14b24e2bSVaishali Kulkarni return -1; 828*14b24e2bSVaishali Kulkarni } 829*14b24e2bSVaishali Kulkarni 830*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, QM_REG_RLGLBLCRD + vport_id * 4, (u32)QM_RL_CRD_REG_SIGN_BIT); 831*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, QM_REG_RLGLBLINCVAL + vport_id * 4, inc_val); 832*14b24e2bSVaishali Kulkarni 833*14b24e2bSVaishali Kulkarni return 0; 834*14b24e2bSVaishali Kulkarni } 835*14b24e2bSVaishali Kulkarni 836*14b24e2bSVaishali Kulkarni bool ecore_send_qm_stop_cmd(struct ecore_hwfn *p_hwfn, 837*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, 838*14b24e2bSVaishali Kulkarni bool is_release_cmd, 839*14b24e2bSVaishali Kulkarni bool is_tx_pq, 840*14b24e2bSVaishali Kulkarni u16 start_pq, 841*14b24e2bSVaishali Kulkarni u16 num_pqs) 842*14b24e2bSVaishali Kulkarni { 843*14b24e2bSVaishali Kulkarni u32 cmd_arr[QM_CMD_STRUCT_SIZE(QM_STOP_CMD)] = {0}; 844*14b24e2bSVaishali Kulkarni u32 pq_mask = 0, last_pq, pq_id; 845*14b24e2bSVaishali Kulkarni 846*14b24e2bSVaishali Kulkarni last_pq = start_pq + num_pqs - 1; 847*14b24e2bSVaishali Kulkarni 848*14b24e2bSVaishali Kulkarni /* Set command's PQ type */ 849*14b24e2bSVaishali Kulkarni QM_CMD_SET_FIELD(cmd_arr, QM_STOP_CMD, PQ_TYPE, is_tx_pq ? 0 : 1); 850*14b24e2bSVaishali Kulkarni 851*14b24e2bSVaishali Kulkarni /* Go over requested PQs */ 852*14b24e2bSVaishali Kulkarni for (pq_id = start_pq; pq_id <= last_pq; pq_id++) { 853*14b24e2bSVaishali Kulkarni 854*14b24e2bSVaishali Kulkarni /* Set PQ bit in mask (stop command only) */ 855*14b24e2bSVaishali Kulkarni if (!is_release_cmd) 856*14b24e2bSVaishali Kulkarni pq_mask |= (1 << (pq_id % QM_STOP_PQ_MASK_WIDTH)); 857*14b24e2bSVaishali Kulkarni 858*14b24e2bSVaishali Kulkarni /* If last PQ or end of PQ mask, write command */ 859*14b24e2bSVaishali Kulkarni if ((pq_id == last_pq) || (pq_id % QM_STOP_PQ_MASK_WIDTH == (QM_STOP_PQ_MASK_WIDTH - 1))) { 860*14b24e2bSVaishali Kulkarni QM_CMD_SET_FIELD(cmd_arr, QM_STOP_CMD, PAUSE_MASK, pq_mask); 861*14b24e2bSVaishali Kulkarni QM_CMD_SET_FIELD(cmd_arr, QM_STOP_CMD, GROUP_ID, pq_id / QM_STOP_PQ_MASK_WIDTH); 862*14b24e2bSVaishali Kulkarni if (!ecore_send_qm_cmd(p_hwfn, p_ptt, QM_STOP_CMD_ADDR, cmd_arr[0], cmd_arr[1])) 863*14b24e2bSVaishali Kulkarni return false; 864*14b24e2bSVaishali Kulkarni pq_mask = 0; 865*14b24e2bSVaishali Kulkarni } 866*14b24e2bSVaishali Kulkarni } 867*14b24e2bSVaishali Kulkarni 868*14b24e2bSVaishali Kulkarni return true; 869*14b24e2bSVaishali Kulkarni } 870*14b24e2bSVaishali Kulkarni 871*14b24e2bSVaishali Kulkarni #ifndef UNUSED_HSI_FUNC 872*14b24e2bSVaishali Kulkarni 873*14b24e2bSVaishali Kulkarni /* NIG: ETS configuration constants */ 874*14b24e2bSVaishali Kulkarni #define NIG_TX_ETS_CLIENT_OFFSET 4 875*14b24e2bSVaishali Kulkarni #define NIG_LB_ETS_CLIENT_OFFSET 1 876*14b24e2bSVaishali Kulkarni #define NIG_ETS_MIN_WFQ_BYTES 1600 877*14b24e2bSVaishali Kulkarni 878*14b24e2bSVaishali Kulkarni /* NIG: ETS constants */ 879*14b24e2bSVaishali Kulkarni #define NIG_ETS_UP_BOUND(weight,mtu) (2 * ((weight) > (mtu) ? (weight) : (mtu))) 880*14b24e2bSVaishali Kulkarni 881*14b24e2bSVaishali Kulkarni /* NIG: RL constants */ 882*14b24e2bSVaishali Kulkarni 883*14b24e2bSVaishali Kulkarni /* Byte base type value */ 884*14b24e2bSVaishali Kulkarni #define NIG_RL_BASE_TYPE 1 885*14b24e2bSVaishali Kulkarni 886*14b24e2bSVaishali Kulkarni /* Period in us */ 887*14b24e2bSVaishali Kulkarni #define NIG_RL_PERIOD 1 888*14b24e2bSVaishali Kulkarni 889*14b24e2bSVaishali Kulkarni /* Period in 25MHz cycles */ 890*14b24e2bSVaishali Kulkarni #define NIG_RL_PERIOD_CLK_25M (25 * NIG_RL_PERIOD) 891*14b24e2bSVaishali Kulkarni 892*14b24e2bSVaishali Kulkarni /* Rate in mbps */ 893*14b24e2bSVaishali Kulkarni #define NIG_RL_INC_VAL(rate) (((rate) * NIG_RL_PERIOD) / 8) 894*14b24e2bSVaishali Kulkarni 895*14b24e2bSVaishali Kulkarni #define NIG_RL_MAX_VAL(inc_val,mtu) (2 * ((inc_val) > (mtu) ? (inc_val) : (mtu))) 896*14b24e2bSVaishali Kulkarni 897*14b24e2bSVaishali Kulkarni /* NIG: packet prioritry configuration constants */ 898*14b24e2bSVaishali Kulkarni #define NIG_PRIORITY_MAP_TC_BITS 4 899*14b24e2bSVaishali Kulkarni 900*14b24e2bSVaishali Kulkarni 901*14b24e2bSVaishali Kulkarni void ecore_init_nig_ets(struct ecore_hwfn *p_hwfn, 902*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, 903*14b24e2bSVaishali Kulkarni struct init_ets_req* req, 904*14b24e2bSVaishali Kulkarni bool is_lb) 905*14b24e2bSVaishali Kulkarni { 906*14b24e2bSVaishali Kulkarni u32 min_weight, tc_weight_base_addr, tc_weight_addr_diff; 907*14b24e2bSVaishali Kulkarni u32 tc_bound_base_addr, tc_bound_addr_diff; 908*14b24e2bSVaishali Kulkarni u8 sp_tc_map = 0, wfq_tc_map = 0; 909*14b24e2bSVaishali Kulkarni u8 tc, num_tc, tc_client_offset; 910*14b24e2bSVaishali Kulkarni 911*14b24e2bSVaishali Kulkarni num_tc = is_lb ? NUM_OF_TCS : NUM_OF_PHYS_TCS; 912*14b24e2bSVaishali Kulkarni tc_client_offset = is_lb ? NIG_LB_ETS_CLIENT_OFFSET : NIG_TX_ETS_CLIENT_OFFSET; 913*14b24e2bSVaishali Kulkarni min_weight = 0xffffffff; 914*14b24e2bSVaishali Kulkarni tc_weight_base_addr = is_lb ? NIG_REG_LB_ARB_CREDIT_WEIGHT_0 : NIG_REG_TX_ARB_CREDIT_WEIGHT_0; 915*14b24e2bSVaishali Kulkarni tc_weight_addr_diff = is_lb ? NIG_REG_LB_ARB_CREDIT_WEIGHT_1 - NIG_REG_LB_ARB_CREDIT_WEIGHT_0 : 916*14b24e2bSVaishali Kulkarni NIG_REG_TX_ARB_CREDIT_WEIGHT_1 - NIG_REG_TX_ARB_CREDIT_WEIGHT_0; 917*14b24e2bSVaishali Kulkarni tc_bound_base_addr = is_lb ? NIG_REG_LB_ARB_CREDIT_UPPER_BOUND_0 : NIG_REG_TX_ARB_CREDIT_UPPER_BOUND_0; 918*14b24e2bSVaishali Kulkarni tc_bound_addr_diff = is_lb ? NIG_REG_LB_ARB_CREDIT_UPPER_BOUND_1 - NIG_REG_LB_ARB_CREDIT_UPPER_BOUND_0 : 919*14b24e2bSVaishali Kulkarni NIG_REG_TX_ARB_CREDIT_UPPER_BOUND_1 - NIG_REG_TX_ARB_CREDIT_UPPER_BOUND_0; 920*14b24e2bSVaishali Kulkarni 921*14b24e2bSVaishali Kulkarni for (tc = 0; tc < num_tc; tc++) { 922*14b24e2bSVaishali Kulkarni struct init_ets_tc_req *tc_req = &req->tc_req[tc]; 923*14b24e2bSVaishali Kulkarni 924*14b24e2bSVaishali Kulkarni /* Update SP map */ 925*14b24e2bSVaishali Kulkarni if (tc_req->use_sp) 926*14b24e2bSVaishali Kulkarni sp_tc_map |= (1 << tc); 927*14b24e2bSVaishali Kulkarni 928*14b24e2bSVaishali Kulkarni if (!tc_req->use_wfq) 929*14b24e2bSVaishali Kulkarni continue; 930*14b24e2bSVaishali Kulkarni 931*14b24e2bSVaishali Kulkarni /* Update WFQ map */ 932*14b24e2bSVaishali Kulkarni wfq_tc_map |= (1 << tc); 933*14b24e2bSVaishali Kulkarni 934*14b24e2bSVaishali Kulkarni /* Find minimal weight */ 935*14b24e2bSVaishali Kulkarni if (tc_req->weight < min_weight) 936*14b24e2bSVaishali Kulkarni min_weight = tc_req->weight; 937*14b24e2bSVaishali Kulkarni } 938*14b24e2bSVaishali Kulkarni 939*14b24e2bSVaishali Kulkarni /* Write SP map */ 940*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, is_lb ? NIG_REG_LB_ARB_CLIENT_IS_STRICT : NIG_REG_TX_ARB_CLIENT_IS_STRICT, (sp_tc_map << tc_client_offset)); 941*14b24e2bSVaishali Kulkarni 942*14b24e2bSVaishali Kulkarni /* Write WFQ map */ 943*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, is_lb ? NIG_REG_LB_ARB_CLIENT_IS_SUBJECT2WFQ : NIG_REG_TX_ARB_CLIENT_IS_SUBJECT2WFQ, (wfq_tc_map << tc_client_offset)); 944*14b24e2bSVaishali Kulkarni 945*14b24e2bSVaishali Kulkarni /* Write WFQ weights */ 946*14b24e2bSVaishali Kulkarni for (tc = 0; tc < num_tc; tc++, tc_client_offset++) { 947*14b24e2bSVaishali Kulkarni struct init_ets_tc_req *tc_req = &req->tc_req[tc]; 948*14b24e2bSVaishali Kulkarni u32 byte_weight; 949*14b24e2bSVaishali Kulkarni 950*14b24e2bSVaishali Kulkarni if (!tc_req->use_wfq) 951*14b24e2bSVaishali Kulkarni continue; 952*14b24e2bSVaishali Kulkarni 953*14b24e2bSVaishali Kulkarni /* Translate weight to bytes */ 954*14b24e2bSVaishali Kulkarni byte_weight = (NIG_ETS_MIN_WFQ_BYTES * tc_req->weight) / min_weight; 955*14b24e2bSVaishali Kulkarni 956*14b24e2bSVaishali Kulkarni /* Write WFQ weight */ 957*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, tc_weight_base_addr + tc_weight_addr_diff * tc_client_offset, byte_weight); 958*14b24e2bSVaishali Kulkarni 959*14b24e2bSVaishali Kulkarni /* Write WFQ upper bound */ 960*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, tc_bound_base_addr + tc_bound_addr_diff * tc_client_offset, NIG_ETS_UP_BOUND(byte_weight, req->mtu)); 961*14b24e2bSVaishali Kulkarni } 962*14b24e2bSVaishali Kulkarni } 963*14b24e2bSVaishali Kulkarni 964*14b24e2bSVaishali Kulkarni void ecore_init_nig_lb_rl(struct ecore_hwfn *p_hwfn, 965*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, 966*14b24e2bSVaishali Kulkarni struct init_nig_lb_rl_req* req) 967*14b24e2bSVaishali Kulkarni { 968*14b24e2bSVaishali Kulkarni u32 ctrl, inc_val, reg_offset; 969*14b24e2bSVaishali Kulkarni u8 tc; 970*14b24e2bSVaishali Kulkarni 971*14b24e2bSVaishali Kulkarni /* Disable global MAC+LB RL */ 972*14b24e2bSVaishali Kulkarni ctrl = NIG_RL_BASE_TYPE << NIG_REG_TX_LB_GLBRATELIMIT_CTRL_TX_LB_GLBRATELIMIT_BASE_TYPE_SHIFT; 973*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_TX_LB_GLBRATELIMIT_CTRL, ctrl); 974*14b24e2bSVaishali Kulkarni 975*14b24e2bSVaishali Kulkarni /* Configure and enable global MAC+LB RL */ 976*14b24e2bSVaishali Kulkarni if (req->lb_mac_rate) { 977*14b24e2bSVaishali Kulkarni 978*14b24e2bSVaishali Kulkarni /* Configure */ 979*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_TX_LB_GLBRATELIMIT_INC_PERIOD, NIG_RL_PERIOD_CLK_25M); 980*14b24e2bSVaishali Kulkarni inc_val = NIG_RL_INC_VAL(req->lb_mac_rate); 981*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_TX_LB_GLBRATELIMIT_INC_VALUE, inc_val); 982*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_TX_LB_GLBRATELIMIT_MAX_VALUE, NIG_RL_MAX_VAL(inc_val, req->mtu)); 983*14b24e2bSVaishali Kulkarni 984*14b24e2bSVaishali Kulkarni /* Enable */ 985*14b24e2bSVaishali Kulkarni ctrl |= 1 << NIG_REG_TX_LB_GLBRATELIMIT_CTRL_TX_LB_GLBRATELIMIT_EN_SHIFT; 986*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_TX_LB_GLBRATELIMIT_CTRL, ctrl); 987*14b24e2bSVaishali Kulkarni } 988*14b24e2bSVaishali Kulkarni 989*14b24e2bSVaishali Kulkarni /* Disable global LB-only RL */ 990*14b24e2bSVaishali Kulkarni ctrl = NIG_RL_BASE_TYPE << NIG_REG_LB_BRBRATELIMIT_CTRL_LB_BRBRATELIMIT_BASE_TYPE_SHIFT; 991*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_LB_BRBRATELIMIT_CTRL, ctrl); 992*14b24e2bSVaishali Kulkarni 993*14b24e2bSVaishali Kulkarni /* Configure and enable global LB-only RL */ 994*14b24e2bSVaishali Kulkarni if (req->lb_rate) { 995*14b24e2bSVaishali Kulkarni 996*14b24e2bSVaishali Kulkarni /* Configure */ 997*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_LB_BRBRATELIMIT_INC_PERIOD, NIG_RL_PERIOD_CLK_25M); 998*14b24e2bSVaishali Kulkarni inc_val = NIG_RL_INC_VAL(req->lb_rate); 999*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_LB_BRBRATELIMIT_INC_VALUE, inc_val); 1000*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_LB_BRBRATELIMIT_MAX_VALUE, NIG_RL_MAX_VAL(inc_val, req->mtu)); 1001*14b24e2bSVaishali Kulkarni 1002*14b24e2bSVaishali Kulkarni /* Enable */ 1003*14b24e2bSVaishali Kulkarni ctrl |= 1 << NIG_REG_LB_BRBRATELIMIT_CTRL_LB_BRBRATELIMIT_EN_SHIFT; 1004*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_LB_BRBRATELIMIT_CTRL, ctrl); 1005*14b24e2bSVaishali Kulkarni } 1006*14b24e2bSVaishali Kulkarni 1007*14b24e2bSVaishali Kulkarni /* Per-TC RLs */ 1008*14b24e2bSVaishali Kulkarni for (tc = 0, reg_offset = 0; tc < NUM_OF_PHYS_TCS; tc++, reg_offset += 4) { 1009*14b24e2bSVaishali Kulkarni 1010*14b24e2bSVaishali Kulkarni /* Disable TC RL */ 1011*14b24e2bSVaishali Kulkarni ctrl = NIG_RL_BASE_TYPE << NIG_REG_LB_TCRATELIMIT_CTRL_0_LB_TCRATELIMIT_BASE_TYPE_0_SHIFT; 1012*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_LB_TCRATELIMIT_CTRL_0 + reg_offset, ctrl); 1013*14b24e2bSVaishali Kulkarni 1014*14b24e2bSVaishali Kulkarni /* Configure and enable TC RL */ 1015*14b24e2bSVaishali Kulkarni if (!req->tc_rate[tc]) 1016*14b24e2bSVaishali Kulkarni continue; 1017*14b24e2bSVaishali Kulkarni 1018*14b24e2bSVaishali Kulkarni /* Configure */ 1019*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_LB_TCRATELIMIT_INC_PERIOD_0 + reg_offset, NIG_RL_PERIOD_CLK_25M); 1020*14b24e2bSVaishali Kulkarni inc_val = NIG_RL_INC_VAL(req->tc_rate[tc]); 1021*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_LB_TCRATELIMIT_INC_VALUE_0 + reg_offset, inc_val); 1022*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_LB_TCRATELIMIT_MAX_VALUE_0 + reg_offset, NIG_RL_MAX_VAL(inc_val, req->mtu)); 1023*14b24e2bSVaishali Kulkarni 1024*14b24e2bSVaishali Kulkarni /* Enable */ 1025*14b24e2bSVaishali Kulkarni ctrl |= 1 << NIG_REG_LB_TCRATELIMIT_CTRL_0_LB_TCRATELIMIT_EN_0_SHIFT; 1026*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_LB_TCRATELIMIT_CTRL_0 + reg_offset, ctrl); 1027*14b24e2bSVaishali Kulkarni } 1028*14b24e2bSVaishali Kulkarni } 1029*14b24e2bSVaishali Kulkarni 1030*14b24e2bSVaishali Kulkarni void ecore_init_nig_pri_tc_map(struct ecore_hwfn *p_hwfn, 1031*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, 1032*14b24e2bSVaishali Kulkarni struct init_nig_pri_tc_map_req* req) 1033*14b24e2bSVaishali Kulkarni { 1034*14b24e2bSVaishali Kulkarni u8 tc_pri_mask[NUM_OF_PHYS_TCS] = { 0 }; 1035*14b24e2bSVaishali Kulkarni u32 pri_tc_mask = 0; 1036*14b24e2bSVaishali Kulkarni u8 pri, tc; 1037*14b24e2bSVaishali Kulkarni 1038*14b24e2bSVaishali Kulkarni for (pri = 0; pri < NUM_OF_VLAN_PRIORITIES; pri++) { 1039*14b24e2bSVaishali Kulkarni if (!req->pri[pri].valid) 1040*14b24e2bSVaishali Kulkarni continue; 1041*14b24e2bSVaishali Kulkarni 1042*14b24e2bSVaishali Kulkarni pri_tc_mask |= (req->pri[pri].tc_id << (pri * NIG_PRIORITY_MAP_TC_BITS)); 1043*14b24e2bSVaishali Kulkarni tc_pri_mask[req->pri[pri].tc_id] |= (1 << pri); 1044*14b24e2bSVaishali Kulkarni } 1045*14b24e2bSVaishali Kulkarni 1046*14b24e2bSVaishali Kulkarni /* Write priority -> TC mask */ 1047*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_PKT_PRIORITY_TO_TC, pri_tc_mask); 1048*14b24e2bSVaishali Kulkarni 1049*14b24e2bSVaishali Kulkarni /* Write TC -> priority mask */ 1050*14b24e2bSVaishali Kulkarni for (tc = 0; tc < NUM_OF_PHYS_TCS; tc++) { 1051*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_PRIORITY_FOR_TC_0 + tc * 4, tc_pri_mask[tc]); 1052*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_RX_TC0_PRIORITY_MASK + tc * 4, tc_pri_mask[tc]); 1053*14b24e2bSVaishali Kulkarni } 1054*14b24e2bSVaishali Kulkarni } 1055*14b24e2bSVaishali Kulkarni 1056*14b24e2bSVaishali Kulkarni #endif /* UNUSED_HSI_FUNC */ 1057*14b24e2bSVaishali Kulkarni 1058*14b24e2bSVaishali Kulkarni #ifndef UNUSED_HSI_FUNC 1059*14b24e2bSVaishali Kulkarni 1060*14b24e2bSVaishali Kulkarni /* PRS: ETS configuration constants */ 1061*14b24e2bSVaishali Kulkarni #define PRS_ETS_MIN_WFQ_BYTES 1600 1062*14b24e2bSVaishali Kulkarni #define PRS_ETS_UP_BOUND(weight,mtu) (2 * ((weight) > (mtu) ? (weight) : (mtu))) 1063*14b24e2bSVaishali Kulkarni 1064*14b24e2bSVaishali Kulkarni 1065*14b24e2bSVaishali Kulkarni void ecore_init_prs_ets(struct ecore_hwfn *p_hwfn, 1066*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, 1067*14b24e2bSVaishali Kulkarni struct init_ets_req* req) 1068*14b24e2bSVaishali Kulkarni { 1069*14b24e2bSVaishali Kulkarni u32 tc_weight_addr_diff, tc_bound_addr_diff, min_weight = 0xffffffff; 1070*14b24e2bSVaishali Kulkarni u8 tc, sp_tc_map = 0, wfq_tc_map = 0; 1071*14b24e2bSVaishali Kulkarni 1072*14b24e2bSVaishali Kulkarni tc_weight_addr_diff = PRS_REG_ETS_ARB_CREDIT_WEIGHT_1 - PRS_REG_ETS_ARB_CREDIT_WEIGHT_0; 1073*14b24e2bSVaishali Kulkarni tc_bound_addr_diff = PRS_REG_ETS_ARB_CREDIT_UPPER_BOUND_1 - PRS_REG_ETS_ARB_CREDIT_UPPER_BOUND_0; 1074*14b24e2bSVaishali Kulkarni 1075*14b24e2bSVaishali Kulkarni for (tc = 0; tc < NUM_OF_TCS; tc++) { 1076*14b24e2bSVaishali Kulkarni struct init_ets_tc_req *tc_req = &req->tc_req[tc]; 1077*14b24e2bSVaishali Kulkarni 1078*14b24e2bSVaishali Kulkarni /* Update SP map */ 1079*14b24e2bSVaishali Kulkarni if (tc_req->use_sp) 1080*14b24e2bSVaishali Kulkarni sp_tc_map |= (1 << tc); 1081*14b24e2bSVaishali Kulkarni 1082*14b24e2bSVaishali Kulkarni if (!tc_req->use_wfq) 1083*14b24e2bSVaishali Kulkarni continue; 1084*14b24e2bSVaishali Kulkarni 1085*14b24e2bSVaishali Kulkarni /* Update WFQ map */ 1086*14b24e2bSVaishali Kulkarni wfq_tc_map |= (1 << tc); 1087*14b24e2bSVaishali Kulkarni 1088*14b24e2bSVaishali Kulkarni /* Find minimal weight */ 1089*14b24e2bSVaishali Kulkarni if (tc_req->weight < min_weight) 1090*14b24e2bSVaishali Kulkarni min_weight = tc_req->weight; 1091*14b24e2bSVaishali Kulkarni } 1092*14b24e2bSVaishali Kulkarni 1093*14b24e2bSVaishali Kulkarni /* Write SP map */ 1094*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_ETS_ARB_CLIENT_IS_STRICT, sp_tc_map); 1095*14b24e2bSVaishali Kulkarni 1096*14b24e2bSVaishali Kulkarni /* Write WFQ map */ 1097*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ, wfq_tc_map); 1098*14b24e2bSVaishali Kulkarni 1099*14b24e2bSVaishali Kulkarni /* Write WFQ weights */ 1100*14b24e2bSVaishali Kulkarni for (tc = 0; tc < NUM_OF_TCS; tc++) { 1101*14b24e2bSVaishali Kulkarni struct init_ets_tc_req *tc_req = &req->tc_req[tc]; 1102*14b24e2bSVaishali Kulkarni u32 byte_weight; 1103*14b24e2bSVaishali Kulkarni 1104*14b24e2bSVaishali Kulkarni if (!tc_req->use_wfq) 1105*14b24e2bSVaishali Kulkarni continue; 1106*14b24e2bSVaishali Kulkarni 1107*14b24e2bSVaishali Kulkarni /* Translate weight to bytes */ 1108*14b24e2bSVaishali Kulkarni byte_weight = (PRS_ETS_MIN_WFQ_BYTES * tc_req->weight) / min_weight; 1109*14b24e2bSVaishali Kulkarni 1110*14b24e2bSVaishali Kulkarni /* Write WFQ weight */ 1111*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_ETS_ARB_CREDIT_WEIGHT_0 + tc * tc_weight_addr_diff, byte_weight); 1112*14b24e2bSVaishali Kulkarni 1113*14b24e2bSVaishali Kulkarni /* Write WFQ upper bound */ 1114*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_ETS_ARB_CREDIT_UPPER_BOUND_0 + tc * tc_bound_addr_diff, PRS_ETS_UP_BOUND(byte_weight, req->mtu)); 1115*14b24e2bSVaishali Kulkarni } 1116*14b24e2bSVaishali Kulkarni } 1117*14b24e2bSVaishali Kulkarni 1118*14b24e2bSVaishali Kulkarni #endif /* UNUSED_HSI_FUNC */ 1119*14b24e2bSVaishali Kulkarni #ifndef UNUSED_HSI_FUNC 1120*14b24e2bSVaishali Kulkarni 1121*14b24e2bSVaishali Kulkarni /* BRB: RAM configuration constants */ 1122*14b24e2bSVaishali Kulkarni #define BRB_TOTAL_RAM_BLOCKS_BB 4800 1123*14b24e2bSVaishali Kulkarni #define BRB_TOTAL_RAM_BLOCKS_K2 5632 1124*14b24e2bSVaishali Kulkarni #define BRB_BLOCK_SIZE 128 1125*14b24e2bSVaishali Kulkarni #define BRB_MIN_BLOCKS_PER_TC 9 1126*14b24e2bSVaishali Kulkarni #define BRB_HYST_BYTES 10240 1127*14b24e2bSVaishali Kulkarni #define BRB_HYST_BLOCKS (BRB_HYST_BYTES / BRB_BLOCK_SIZE) 1128*14b24e2bSVaishali Kulkarni 1129*14b24e2bSVaishali Kulkarni /* Temporary big RAM allocation - should be updated */ 1130*14b24e2bSVaishali Kulkarni void ecore_init_brb_ram(struct ecore_hwfn *p_hwfn, 1131*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, 1132*14b24e2bSVaishali Kulkarni struct init_brb_ram_req* req) 1133*14b24e2bSVaishali Kulkarni { 1134*14b24e2bSVaishali Kulkarni u32 tc_headroom_blocks, min_pkt_size_blocks, total_blocks; 1135*14b24e2bSVaishali Kulkarni u32 active_port_blocks, reg_offset = 0; 1136*14b24e2bSVaishali Kulkarni u8 port, active_ports = 0; 1137*14b24e2bSVaishali Kulkarni 1138*14b24e2bSVaishali Kulkarni tc_headroom_blocks = (u32)DIV_ROUND_UP(req->headroom_per_tc, BRB_BLOCK_SIZE); 1139*14b24e2bSVaishali Kulkarni min_pkt_size_blocks = (u32)DIV_ROUND_UP(req->min_pkt_size, BRB_BLOCK_SIZE); 1140*14b24e2bSVaishali Kulkarni total_blocks = ECORE_IS_K2(p_hwfn->p_dev) ? BRB_TOTAL_RAM_BLOCKS_K2 : BRB_TOTAL_RAM_BLOCKS_BB; 1141*14b24e2bSVaishali Kulkarni 1142*14b24e2bSVaishali Kulkarni /* Find number of active ports */ 1143*14b24e2bSVaishali Kulkarni for (port = 0; port < MAX_NUM_PORTS; port++) 1144*14b24e2bSVaishali Kulkarni if (req->num_active_tcs[port]) 1145*14b24e2bSVaishali Kulkarni active_ports++; 1146*14b24e2bSVaishali Kulkarni 1147*14b24e2bSVaishali Kulkarni active_port_blocks = (u32)(total_blocks / active_ports); 1148*14b24e2bSVaishali Kulkarni 1149*14b24e2bSVaishali Kulkarni for (port = 0; port < req->max_ports_per_engine; port++) { 1150*14b24e2bSVaishali Kulkarni u32 port_blocks, port_shared_blocks, port_guaranteed_blocks; 1151*14b24e2bSVaishali Kulkarni u32 full_xoff_th, full_xon_th, pause_xoff_th, pause_xon_th; 1152*14b24e2bSVaishali Kulkarni u32 tc_guaranteed_blocks; 1153*14b24e2bSVaishali Kulkarni u8 tc; 1154*14b24e2bSVaishali Kulkarni 1155*14b24e2bSVaishali Kulkarni /* Calculate per-port sizes */ 1156*14b24e2bSVaishali Kulkarni tc_guaranteed_blocks = (u32)DIV_ROUND_UP(req->guranteed_per_tc, BRB_BLOCK_SIZE); 1157*14b24e2bSVaishali Kulkarni port_blocks = req->num_active_tcs[port] ? active_port_blocks : 0; 1158*14b24e2bSVaishali Kulkarni port_guaranteed_blocks = req->num_active_tcs[port] * tc_guaranteed_blocks; 1159*14b24e2bSVaishali Kulkarni port_shared_blocks = port_blocks - port_guaranteed_blocks; 1160*14b24e2bSVaishali Kulkarni full_xoff_th = req->num_active_tcs[port] * BRB_MIN_BLOCKS_PER_TC; 1161*14b24e2bSVaishali Kulkarni full_xon_th = full_xoff_th + min_pkt_size_blocks; 1162*14b24e2bSVaishali Kulkarni pause_xoff_th = tc_headroom_blocks; 1163*14b24e2bSVaishali Kulkarni pause_xon_th = pause_xoff_th + min_pkt_size_blocks; 1164*14b24e2bSVaishali Kulkarni 1165*14b24e2bSVaishali Kulkarni /* Init total size per port */ 1166*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, BRB_REG_TOTAL_MAC_SIZE + port * 4, port_blocks); 1167*14b24e2bSVaishali Kulkarni 1168*14b24e2bSVaishali Kulkarni /* Init shared size per port */ 1169*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, BRB_REG_SHARED_HR_AREA + port * 4, port_shared_blocks); 1170*14b24e2bSVaishali Kulkarni 1171*14b24e2bSVaishali Kulkarni for (tc = 0; tc < NUM_OF_TCS; tc++, reg_offset += 4) { 1172*14b24e2bSVaishali Kulkarni /* Clear init values for non-active TCs */ 1173*14b24e2bSVaishali Kulkarni if (tc == req->num_active_tcs[port]) { 1174*14b24e2bSVaishali Kulkarni tc_guaranteed_blocks = 0; 1175*14b24e2bSVaishali Kulkarni full_xoff_th = 0; 1176*14b24e2bSVaishali Kulkarni full_xon_th = 0; 1177*14b24e2bSVaishali Kulkarni pause_xoff_th = 0; 1178*14b24e2bSVaishali Kulkarni pause_xon_th = 0; 1179*14b24e2bSVaishali Kulkarni } 1180*14b24e2bSVaishali Kulkarni 1181*14b24e2bSVaishali Kulkarni /* Init guaranteed size per TC */ 1182*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, BRB_REG_TC_GUARANTIED_0 + reg_offset, tc_guaranteed_blocks); 1183*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, BRB_REG_MAIN_TC_GUARANTIED_HYST_0 + reg_offset, BRB_HYST_BLOCKS); 1184*14b24e2bSVaishali Kulkarni 1185*14b24e2bSVaishali Kulkarni /* Init pause/full thresholds per physical TC - for 1186*14b24e2bSVaishali Kulkarni * loopback traffic. 1187*14b24e2bSVaishali Kulkarni */ 1188*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, BRB_REG_LB_TC_FULL_XOFF_THRESHOLD_0 + reg_offset, full_xoff_th); 1189*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, BRB_REG_LB_TC_FULL_XON_THRESHOLD_0 + reg_offset, full_xon_th); 1190*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, BRB_REG_LB_TC_PAUSE_XOFF_THRESHOLD_0 + reg_offset, pause_xoff_th); 1191*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, BRB_REG_LB_TC_PAUSE_XON_THRESHOLD_0 + reg_offset, pause_xon_th); 1192*14b24e2bSVaishali Kulkarni 1193*14b24e2bSVaishali Kulkarni /* Init pause/full thresholds per physical TC - for 1194*14b24e2bSVaishali Kulkarni * main traffic. 1195*14b24e2bSVaishali Kulkarni */ 1196*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, BRB_REG_MAIN_TC_FULL_XOFF_THRESHOLD_0 + reg_offset, full_xoff_th); 1197*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, BRB_REG_MAIN_TC_FULL_XON_THRESHOLD_0 + reg_offset, full_xon_th); 1198*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, BRB_REG_MAIN_TC_PAUSE_XOFF_THRESHOLD_0 + reg_offset, pause_xoff_th); 1199*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, BRB_REG_MAIN_TC_PAUSE_XON_THRESHOLD_0 + reg_offset, pause_xon_th); 1200*14b24e2bSVaishali Kulkarni } 1201*14b24e2bSVaishali Kulkarni } 1202*14b24e2bSVaishali Kulkarni } 1203*14b24e2bSVaishali Kulkarni 1204*14b24e2bSVaishali Kulkarni #endif /* UNUSED_HSI_FUNC */ 1205*14b24e2bSVaishali Kulkarni #ifndef UNUSED_HSI_FUNC 1206*14b24e2bSVaishali Kulkarni 1207*14b24e2bSVaishali Kulkarni /* In MF, should be called once per engine to set EtherType of OuterTag */ 1208*14b24e2bSVaishali Kulkarni void ecore_set_engine_mf_ovlan_eth_type(struct ecore_hwfn *p_hwfn, 1209*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, u32 ethType) 1210*14b24e2bSVaishali Kulkarni { 1211*14b24e2bSVaishali Kulkarni /* Update PRS register */ 1212*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, PRS_REG_TAG_ETHERTYPE_0_RT_OFFSET, ethType); 1213*14b24e2bSVaishali Kulkarni 1214*14b24e2bSVaishali Kulkarni /* Update NIG register */ 1215*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, NIG_REG_TAG_ETHERTYPE_0_RT_OFFSET, ethType); 1216*14b24e2bSVaishali Kulkarni 1217*14b24e2bSVaishali Kulkarni /* Update PBF register */ 1218*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, PBF_REG_TAG_ETHERTYPE_0_RT_OFFSET, ethType); 1219*14b24e2bSVaishali Kulkarni } 1220*14b24e2bSVaishali Kulkarni 1221*14b24e2bSVaishali Kulkarni /* In MF, should be called once per port to set EtherType of OuterTag */ 1222*14b24e2bSVaishali Kulkarni void ecore_set_port_mf_ovlan_eth_type(struct ecore_hwfn *p_hwfn, 1223*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, u32 ethType) 1224*14b24e2bSVaishali Kulkarni { 1225*14b24e2bSVaishali Kulkarni /* Update DORQ register */ 1226*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, DORQ_REG_TAG1_ETHERTYPE_RT_OFFSET, ethType); 1227*14b24e2bSVaishali Kulkarni } 1228*14b24e2bSVaishali Kulkarni 1229*14b24e2bSVaishali Kulkarni #endif /* UNUSED_HSI_FUNC */ 1230*14b24e2bSVaishali Kulkarni 1231*14b24e2bSVaishali Kulkarni 1232*14b24e2bSVaishali Kulkarni #define SET_TUNNEL_TYPE_ENABLE_BIT(var,offset,enable) var = ((var) & ~(1 << (offset))) | ( (enable) ? (1 << (offset)) : 0) 1233*14b24e2bSVaishali Kulkarni #define PRS_ETH_TUNN_FIC_FORMAT -188897008 1234*14b24e2bSVaishali Kulkarni 1235*14b24e2bSVaishali Kulkarni void ecore_set_vxlan_dest_port(struct ecore_hwfn *p_hwfn, 1236*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, 1237*14b24e2bSVaishali Kulkarni u16 dest_port) 1238*14b24e2bSVaishali Kulkarni { 1239*14b24e2bSVaishali Kulkarni /* Update PRS register */ 1240*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_VXLAN_PORT, dest_port); 1241*14b24e2bSVaishali Kulkarni 1242*14b24e2bSVaishali Kulkarni /* Update NIG register */ 1243*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_VXLAN_CTRL, dest_port); 1244*14b24e2bSVaishali Kulkarni 1245*14b24e2bSVaishali Kulkarni /* Update PBF register */ 1246*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PBF_REG_VXLAN_PORT, dest_port); 1247*14b24e2bSVaishali Kulkarni } 1248*14b24e2bSVaishali Kulkarni 1249*14b24e2bSVaishali Kulkarni void ecore_set_vxlan_enable(struct ecore_hwfn *p_hwfn, 1250*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, 1251*14b24e2bSVaishali Kulkarni bool vxlan_enable) 1252*14b24e2bSVaishali Kulkarni { 1253*14b24e2bSVaishali Kulkarni u32 reg_val; 1254*14b24e2bSVaishali Kulkarni 1255*14b24e2bSVaishali Kulkarni /* Update PRS register */ 1256*14b24e2bSVaishali Kulkarni reg_val = ecore_rd(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN); 1257*14b24e2bSVaishali Kulkarni SET_TUNNEL_TYPE_ENABLE_BIT(reg_val, PRS_REG_ENCAPSULATION_TYPE_EN_VXLAN_ENABLE_SHIFT, vxlan_enable); 1258*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN, reg_val); 1259*14b24e2bSVaishali Kulkarni if (reg_val) /* TODO: handle E5 init */ 1260*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0_BB_K2, (u32)PRS_ETH_TUNN_FIC_FORMAT); 1261*14b24e2bSVaishali Kulkarni 1262*14b24e2bSVaishali Kulkarni /* Update NIG register */ 1263*14b24e2bSVaishali Kulkarni reg_val = ecore_rd(p_hwfn, p_ptt, NIG_REG_ENC_TYPE_ENABLE); 1264*14b24e2bSVaishali Kulkarni SET_TUNNEL_TYPE_ENABLE_BIT(reg_val, NIG_REG_ENC_TYPE_ENABLE_VXLAN_ENABLE_SHIFT, vxlan_enable); 1265*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_ENC_TYPE_ENABLE, reg_val); 1266*14b24e2bSVaishali Kulkarni 1267*14b24e2bSVaishali Kulkarni /* Update DORQ register */ 1268*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, DORQ_REG_L2_EDPM_TUNNEL_VXLAN_EN, vxlan_enable ? 1 : 0); 1269*14b24e2bSVaishali Kulkarni } 1270*14b24e2bSVaishali Kulkarni 1271*14b24e2bSVaishali Kulkarni void ecore_set_gre_enable(struct ecore_hwfn *p_hwfn, 1272*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, 1273*14b24e2bSVaishali Kulkarni bool eth_gre_enable, 1274*14b24e2bSVaishali Kulkarni bool ip_gre_enable) 1275*14b24e2bSVaishali Kulkarni { 1276*14b24e2bSVaishali Kulkarni u32 reg_val; 1277*14b24e2bSVaishali Kulkarni 1278*14b24e2bSVaishali Kulkarni /* Update PRS register */ 1279*14b24e2bSVaishali Kulkarni reg_val = ecore_rd(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN); 1280*14b24e2bSVaishali Kulkarni SET_TUNNEL_TYPE_ENABLE_BIT(reg_val, PRS_REG_ENCAPSULATION_TYPE_EN_ETH_OVER_GRE_ENABLE_SHIFT, eth_gre_enable); 1281*14b24e2bSVaishali Kulkarni SET_TUNNEL_TYPE_ENABLE_BIT(reg_val, PRS_REG_ENCAPSULATION_TYPE_EN_IP_OVER_GRE_ENABLE_SHIFT, ip_gre_enable); 1282*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN, reg_val); 1283*14b24e2bSVaishali Kulkarni if (reg_val) /* TODO: handle E5 init */ 1284*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0_BB_K2, (u32)PRS_ETH_TUNN_FIC_FORMAT); 1285*14b24e2bSVaishali Kulkarni 1286*14b24e2bSVaishali Kulkarni /* Update NIG register */ 1287*14b24e2bSVaishali Kulkarni reg_val = ecore_rd(p_hwfn, p_ptt, NIG_REG_ENC_TYPE_ENABLE); 1288*14b24e2bSVaishali Kulkarni SET_TUNNEL_TYPE_ENABLE_BIT(reg_val, NIG_REG_ENC_TYPE_ENABLE_ETH_OVER_GRE_ENABLE_SHIFT, eth_gre_enable); 1289*14b24e2bSVaishali Kulkarni SET_TUNNEL_TYPE_ENABLE_BIT(reg_val, NIG_REG_ENC_TYPE_ENABLE_IP_OVER_GRE_ENABLE_SHIFT, ip_gre_enable); 1290*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_ENC_TYPE_ENABLE, reg_val); 1291*14b24e2bSVaishali Kulkarni 1292*14b24e2bSVaishali Kulkarni /* Update DORQ registers */ 1293*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, DORQ_REG_L2_EDPM_TUNNEL_GRE_ETH_EN, eth_gre_enable ? 1 : 0); 1294*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, DORQ_REG_L2_EDPM_TUNNEL_GRE_IP_EN, ip_gre_enable ? 1 : 0); 1295*14b24e2bSVaishali Kulkarni } 1296*14b24e2bSVaishali Kulkarni 1297*14b24e2bSVaishali Kulkarni void ecore_set_geneve_dest_port(struct ecore_hwfn *p_hwfn, 1298*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, 1299*14b24e2bSVaishali Kulkarni u16 dest_port) 1300*14b24e2bSVaishali Kulkarni 1301*14b24e2bSVaishali Kulkarni { 1302*14b24e2bSVaishali Kulkarni /* Update PRS register */ 1303*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_NGE_PORT, dest_port); 1304*14b24e2bSVaishali Kulkarni 1305*14b24e2bSVaishali Kulkarni /* Update NIG register */ 1306*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_NGE_PORT, dest_port); 1307*14b24e2bSVaishali Kulkarni 1308*14b24e2bSVaishali Kulkarni /* Update PBF register */ 1309*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PBF_REG_NGE_PORT, dest_port); 1310*14b24e2bSVaishali Kulkarni } 1311*14b24e2bSVaishali Kulkarni 1312*14b24e2bSVaishali Kulkarni void ecore_set_geneve_enable(struct ecore_hwfn *p_hwfn, 1313*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, 1314*14b24e2bSVaishali Kulkarni bool eth_geneve_enable, 1315*14b24e2bSVaishali Kulkarni bool ip_geneve_enable) 1316*14b24e2bSVaishali Kulkarni { 1317*14b24e2bSVaishali Kulkarni u32 reg_val; 1318*14b24e2bSVaishali Kulkarni 1319*14b24e2bSVaishali Kulkarni /* Update PRS register */ 1320*14b24e2bSVaishali Kulkarni reg_val = ecore_rd(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN); 1321*14b24e2bSVaishali Kulkarni SET_TUNNEL_TYPE_ENABLE_BIT(reg_val, PRS_REG_ENCAPSULATION_TYPE_EN_ETH_OVER_GENEVE_ENABLE_SHIFT, eth_geneve_enable); 1322*14b24e2bSVaishali Kulkarni SET_TUNNEL_TYPE_ENABLE_BIT(reg_val, PRS_REG_ENCAPSULATION_TYPE_EN_IP_OVER_GENEVE_ENABLE_SHIFT, ip_geneve_enable); 1323*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN, reg_val); 1324*14b24e2bSVaishali Kulkarni if (reg_val) /* TODO: handle E5 init */ 1325*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0_BB_K2, (u32)PRS_ETH_TUNN_FIC_FORMAT); 1326*14b24e2bSVaishali Kulkarni 1327*14b24e2bSVaishali Kulkarni /* Update NIG register */ 1328*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_NGE_ETH_ENABLE, eth_geneve_enable ? 1 : 0); 1329*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, NIG_REG_NGE_IP_ENABLE, ip_geneve_enable ? 1 : 0); 1330*14b24e2bSVaishali Kulkarni 1331*14b24e2bSVaishali Kulkarni /* EDPM with geneve tunnel not supported in BB */ 1332*14b24e2bSVaishali Kulkarni if (ECORE_IS_BB_B0(p_hwfn->p_dev)) 1333*14b24e2bSVaishali Kulkarni return; 1334*14b24e2bSVaishali Kulkarni 1335*14b24e2bSVaishali Kulkarni /* Update DORQ registers */ 1336*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, DORQ_REG_L2_EDPM_TUNNEL_NGE_ETH_EN_K2_E5, eth_geneve_enable ? 1 : 0); 1337*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, DORQ_REG_L2_EDPM_TUNNEL_NGE_IP_EN_K2_E5, ip_geneve_enable ? 1 : 0); 1338*14b24e2bSVaishali Kulkarni } 1339*14b24e2bSVaishali Kulkarni 1340*14b24e2bSVaishali Kulkarni #ifndef UNUSED_HSI_FUNC 1341*14b24e2bSVaishali Kulkarni 1342*14b24e2bSVaishali Kulkarni #define T_ETH_PACKET_ACTION_GFT_EVENTID 23 1343*14b24e2bSVaishali Kulkarni #define PARSER_ETH_CONN_GFT_ACTION_CM_HDR 272 1344*14b24e2bSVaishali Kulkarni #define T_ETH_PACKET_MATCH_RFS_EVENTID 25 1345*14b24e2bSVaishali Kulkarni #define PARSER_ETH_CONN_CM_HDR 0 1346*14b24e2bSVaishali Kulkarni #define CAM_LINE_SIZE sizeof(u32) 1347*14b24e2bSVaishali Kulkarni #define RAM_LINE_SIZE sizeof(u64) 1348*14b24e2bSVaishali Kulkarni #define REG_SIZE sizeof(u32) 1349*14b24e2bSVaishali Kulkarni 1350*14b24e2bSVaishali Kulkarni 1351*14b24e2bSVaishali Kulkarni void ecore_set_rfs_mode_disable(struct ecore_hwfn *p_hwfn, 1352*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, 1353*14b24e2bSVaishali Kulkarni u16 pf_id) 1354*14b24e2bSVaishali Kulkarni { 1355*14b24e2bSVaishali Kulkarni union gft_cam_line_union cam_line; 1356*14b24e2bSVaishali Kulkarni struct gft_ram_line ram_line; 1357*14b24e2bSVaishali Kulkarni u32 i, *ram_line_ptr; 1358*14b24e2bSVaishali Kulkarni 1359*14b24e2bSVaishali Kulkarni ram_line_ptr = (u32*)&ram_line; 1360*14b24e2bSVaishali Kulkarni 1361*14b24e2bSVaishali Kulkarni /* Stop using gft logic, disable gft search */ 1362*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_SEARCH_GFT, 0); 1363*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_CM_HDR_GFT, 0x0); 1364*14b24e2bSVaishali Kulkarni 1365*14b24e2bSVaishali Kulkarni /* Clean ram & cam for next rfs/gft session*/ 1366*14b24e2bSVaishali Kulkarni 1367*14b24e2bSVaishali Kulkarni /* Zero camline */ 1368*14b24e2bSVaishali Kulkarni OSAL_MEMSET(&cam_line, 0, sizeof(cam_line)); 1369*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_GFT_CAM + CAM_LINE_SIZE*pf_id, cam_line.cam_line_mapped.camline); 1370*14b24e2bSVaishali Kulkarni 1371*14b24e2bSVaishali Kulkarni /* Zero ramline */ 1372*14b24e2bSVaishali Kulkarni OSAL_MEMSET(&ram_line, 0, sizeof(ram_line)); 1373*14b24e2bSVaishali Kulkarni 1374*14b24e2bSVaishali Kulkarni /* Each iteration write to reg */ 1375*14b24e2bSVaishali Kulkarni for (i = 0; i < RAM_LINE_SIZE / REG_SIZE; i++) 1376*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE*pf_id + i*REG_SIZE, *(ram_line_ptr + i)); 1377*14b24e2bSVaishali Kulkarni } 1378*14b24e2bSVaishali Kulkarni 1379*14b24e2bSVaishali Kulkarni 1380*14b24e2bSVaishali Kulkarni void ecore_set_gft_event_id_cm_hdr (struct ecore_hwfn *p_hwfn, 1381*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt) 1382*14b24e2bSVaishali Kulkarni { 1383*14b24e2bSVaishali Kulkarni u32 rfs_cm_hdr_event_id; 1384*14b24e2bSVaishali Kulkarni 1385*14b24e2bSVaishali Kulkarni /* Set RFS event ID to be awakened i Tstorm By Prs */ 1386*14b24e2bSVaishali Kulkarni rfs_cm_hdr_event_id = ecore_rd(p_hwfn, p_ptt, PRS_REG_CM_HDR_GFT); 1387*14b24e2bSVaishali Kulkarni rfs_cm_hdr_event_id |= T_ETH_PACKET_ACTION_GFT_EVENTID << PRS_REG_CM_HDR_GFT_EVENT_ID_SHIFT; 1388*14b24e2bSVaishali Kulkarni rfs_cm_hdr_event_id |= PARSER_ETH_CONN_GFT_ACTION_CM_HDR << PRS_REG_CM_HDR_GFT_CM_HDR_SHIFT; 1389*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_CM_HDR_GFT, rfs_cm_hdr_event_id); 1390*14b24e2bSVaishali Kulkarni } 1391*14b24e2bSVaishali Kulkarni 1392*14b24e2bSVaishali Kulkarni void ecore_set_rfs_mode_enable(struct ecore_hwfn *p_hwfn, 1393*14b24e2bSVaishali Kulkarni struct ecore_ptt *p_ptt, 1394*14b24e2bSVaishali Kulkarni u16 pf_id, 1395*14b24e2bSVaishali Kulkarni bool tcp, 1396*14b24e2bSVaishali Kulkarni bool udp, 1397*14b24e2bSVaishali Kulkarni bool ipv4, 1398*14b24e2bSVaishali Kulkarni bool ipv6) 1399*14b24e2bSVaishali Kulkarni { 1400*14b24e2bSVaishali Kulkarni u32 rfs_cm_hdr_event_id, *ram_line_ptr; 1401*14b24e2bSVaishali Kulkarni union gft_cam_line_union cam_line; 1402*14b24e2bSVaishali Kulkarni struct gft_ram_line ram_line; 1403*14b24e2bSVaishali Kulkarni int i; 1404*14b24e2bSVaishali Kulkarni 1405*14b24e2bSVaishali Kulkarni rfs_cm_hdr_event_id = ecore_rd(p_hwfn, p_ptt, PRS_REG_CM_HDR_GFT); 1406*14b24e2bSVaishali Kulkarni ram_line_ptr = (u32*)&ram_line; 1407*14b24e2bSVaishali Kulkarni 1408*14b24e2bSVaishali Kulkarni if (!ipv6 && !ipv4) 1409*14b24e2bSVaishali Kulkarni DP_NOTICE(p_hwfn, true, "set_rfs_mode_enable: must accept at least on of - ipv4 or ipv6\n"); 1410*14b24e2bSVaishali Kulkarni if (!tcp && !udp) 1411*14b24e2bSVaishali Kulkarni DP_NOTICE(p_hwfn, true, "set_rfs_mode_enable: must accept at least on of - udp or tcp\n"); 1412*14b24e2bSVaishali Kulkarni 1413*14b24e2bSVaishali Kulkarni /* Set RFS event ID to be awakened i Tstorm By Prs */ 1414*14b24e2bSVaishali Kulkarni rfs_cm_hdr_event_id |= T_ETH_PACKET_MATCH_RFS_EVENTID << PRS_REG_CM_HDR_GFT_EVENT_ID_SHIFT; 1415*14b24e2bSVaishali Kulkarni rfs_cm_hdr_event_id |= PARSER_ETH_CONN_CM_HDR << PRS_REG_CM_HDR_GFT_CM_HDR_SHIFT; 1416*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_CM_HDR_GFT, rfs_cm_hdr_event_id); 1417*14b24e2bSVaishali Kulkarni 1418*14b24e2bSVaishali Kulkarni /* Configure Registers for RFS mode */ 1419*14b24e2bSVaishali Kulkarni 1420*14b24e2bSVaishali Kulkarni /* Enable gft search */ 1421*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_SEARCH_GFT, 1); 1422*14b24e2bSVaishali Kulkarni 1423*14b24e2bSVaishali Kulkarni /* Do not load context only cid in PRS on match. */ 1424*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_LOAD_L2_FILTER, 0); 1425*14b24e2bSVaishali Kulkarni 1426*14b24e2bSVaishali Kulkarni /* Cam line is now valid!! */ 1427*14b24e2bSVaishali Kulkarni cam_line.cam_line_mapped.camline = 0; 1428*14b24e2bSVaishali Kulkarni SET_FIELD(cam_line.cam_line_mapped.camline, GFT_CAM_LINE_MAPPED_VALID, 1); 1429*14b24e2bSVaishali Kulkarni 1430*14b24e2bSVaishali Kulkarni /* Filters are per PF!! */ 1431*14b24e2bSVaishali Kulkarni SET_FIELD(cam_line.cam_line_mapped.camline, GFT_CAM_LINE_MAPPED_PF_ID_MASK, GFT_CAM_LINE_MAPPED_PF_ID_MASK_MASK); 1432*14b24e2bSVaishali Kulkarni SET_FIELD(cam_line.cam_line_mapped.camline, GFT_CAM_LINE_MAPPED_PF_ID, pf_id); 1433*14b24e2bSVaishali Kulkarni 1434*14b24e2bSVaishali Kulkarni if (!(tcp && udp)) { 1435*14b24e2bSVaishali Kulkarni SET_FIELD(cam_line.cam_line_mapped.camline, GFT_CAM_LINE_MAPPED_UPPER_PROTOCOL_TYPE_MASK, GFT_CAM_LINE_MAPPED_UPPER_PROTOCOL_TYPE_MASK_MASK); 1436*14b24e2bSVaishali Kulkarni if (tcp) 1437*14b24e2bSVaishali Kulkarni SET_FIELD(cam_line.cam_line_mapped.camline, GFT_CAM_LINE_MAPPED_UPPER_PROTOCOL_TYPE, GFT_PROFILE_TCP_PROTOCOL); 1438*14b24e2bSVaishali Kulkarni else 1439*14b24e2bSVaishali Kulkarni SET_FIELD(cam_line.cam_line_mapped.camline, GFT_CAM_LINE_MAPPED_UPPER_PROTOCOL_TYPE, GFT_PROFILE_UDP_PROTOCOL); 1440*14b24e2bSVaishali Kulkarni } 1441*14b24e2bSVaishali Kulkarni 1442*14b24e2bSVaishali Kulkarni if (!(ipv4 && ipv6)) { 1443*14b24e2bSVaishali Kulkarni SET_FIELD(cam_line.cam_line_mapped.camline, GFT_CAM_LINE_MAPPED_IP_VERSION_MASK, 1); 1444*14b24e2bSVaishali Kulkarni if (ipv4) 1445*14b24e2bSVaishali Kulkarni SET_FIELD(cam_line.cam_line_mapped.camline, GFT_CAM_LINE_MAPPED_IP_VERSION, GFT_PROFILE_IPV4); 1446*14b24e2bSVaishali Kulkarni else 1447*14b24e2bSVaishali Kulkarni SET_FIELD(cam_line.cam_line_mapped.camline, GFT_CAM_LINE_MAPPED_IP_VERSION, GFT_PROFILE_IPV6); 1448*14b24e2bSVaishali Kulkarni } 1449*14b24e2bSVaishali Kulkarni 1450*14b24e2bSVaishali Kulkarni /* Write characteristics to cam */ 1451*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_GFT_CAM + CAM_LINE_SIZE*pf_id, cam_line.cam_line_mapped.camline); 1452*14b24e2bSVaishali Kulkarni cam_line.cam_line_mapped.camline = ecore_rd(p_hwfn, p_ptt, PRS_REG_GFT_CAM + CAM_LINE_SIZE*pf_id); 1453*14b24e2bSVaishali Kulkarni 1454*14b24e2bSVaishali Kulkarni /* Write line to RAM - compare to filter 4 tuple */ 1455*14b24e2bSVaishali Kulkarni ram_line.lo = 0; 1456*14b24e2bSVaishali Kulkarni ram_line.hi= 0; 1457*14b24e2bSVaishali Kulkarni SET_FIELD(ram_line.hi, GFT_RAM_LINE_DST_IP, 1); 1458*14b24e2bSVaishali Kulkarni SET_FIELD(ram_line.hi, GFT_RAM_LINE_SRC_IP, 1); 1459*14b24e2bSVaishali Kulkarni SET_FIELD(ram_line.hi, GFT_RAM_LINE_OVER_IP_PROTOCOL, 1); 1460*14b24e2bSVaishali Kulkarni SET_FIELD(ram_line.lo, GFT_RAM_LINE_ETHERTYPE, 1); 1461*14b24e2bSVaishali Kulkarni SET_FIELD(ram_line.lo, GFT_RAM_LINE_SRC_PORT, 1); 1462*14b24e2bSVaishali Kulkarni SET_FIELD(ram_line.lo, GFT_RAM_LINE_DST_PORT, 1); 1463*14b24e2bSVaishali Kulkarni 1464*14b24e2bSVaishali Kulkarni 1465*14b24e2bSVaishali Kulkarni /* Each iteration write to reg */ 1466*14b24e2bSVaishali Kulkarni for (i = 0; i < RAM_LINE_SIZE / REG_SIZE; i++) 1467*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE*pf_id + i*REG_SIZE, *(ram_line_ptr + i)); 1468*14b24e2bSVaishali Kulkarni 1469*14b24e2bSVaishali Kulkarni /* Set default profile so that no filter match will happen */ 1470*14b24e2bSVaishali Kulkarni ram_line.lo = 0xffffffff; 1471*14b24e2bSVaishali Kulkarni ram_line.hi = 0x3ff; 1472*14b24e2bSVaishali Kulkarni 1473*14b24e2bSVaishali Kulkarni for (i = 0; i < RAM_LINE_SIZE / REG_SIZE; i++) 1474*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE*PRS_GFT_CAM_LINES_NO_MATCH + i*REG_SIZE, *(ram_line_ptr + i)); 1475*14b24e2bSVaishali Kulkarni } 1476*14b24e2bSVaishali Kulkarni 1477*14b24e2bSVaishali Kulkarni 1478*14b24e2bSVaishali Kulkarni #endif /* UNUSED_HSI_FUNC */ 1479*14b24e2bSVaishali Kulkarni 1480*14b24e2bSVaishali Kulkarni /* Configure VF zone size mode*/ 1481*14b24e2bSVaishali Kulkarni void ecore_config_vf_zone_size_mode(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, u16 mode, bool runtime_init) 1482*14b24e2bSVaishali Kulkarni { 1483*14b24e2bSVaishali Kulkarni u32 msdm_vf_size_log = MSTORM_VF_ZONE_DEFAULT_SIZE_LOG; 1484*14b24e2bSVaishali Kulkarni u32 msdm_vf_offset_mask; 1485*14b24e2bSVaishali Kulkarni 1486*14b24e2bSVaishali Kulkarni if (mode == VF_ZONE_SIZE_MODE_DOUBLE) 1487*14b24e2bSVaishali Kulkarni msdm_vf_size_log += 1; 1488*14b24e2bSVaishali Kulkarni else if (mode == VF_ZONE_SIZE_MODE_QUAD) 1489*14b24e2bSVaishali Kulkarni msdm_vf_size_log += 2; 1490*14b24e2bSVaishali Kulkarni 1491*14b24e2bSVaishali Kulkarni msdm_vf_offset_mask = (1 << msdm_vf_size_log) - 1; 1492*14b24e2bSVaishali Kulkarni 1493*14b24e2bSVaishali Kulkarni if (runtime_init) { 1494*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, PGLUE_REG_B_MSDM_VF_SHIFT_B_RT_OFFSET, msdm_vf_size_log); 1495*14b24e2bSVaishali Kulkarni STORE_RT_REG(p_hwfn, PGLUE_REG_B_MSDM_OFFSET_MASK_B_RT_OFFSET, msdm_vf_offset_mask); 1496*14b24e2bSVaishali Kulkarni } 1497*14b24e2bSVaishali Kulkarni else { 1498*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PGLUE_B_REG_MSDM_VF_SHIFT_B, msdm_vf_size_log); 1499*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, PGLUE_B_REG_MSDM_OFFSET_MASK_B, msdm_vf_offset_mask); 1500*14b24e2bSVaishali Kulkarni } 1501*14b24e2bSVaishali Kulkarni } 1502*14b24e2bSVaishali Kulkarni 1503*14b24e2bSVaishali Kulkarni /* Get mstorm statistics for offset by VF zone size mode */ 1504*14b24e2bSVaishali Kulkarni u32 ecore_get_mstorm_queue_stat_offset(struct ecore_hwfn *p_hwfn, u16 stat_cnt_id, u16 vf_zone_size_mode) 1505*14b24e2bSVaishali Kulkarni { 1506*14b24e2bSVaishali Kulkarni u32 offset = MSTORM_QUEUE_STAT_OFFSET(stat_cnt_id); 1507*14b24e2bSVaishali Kulkarni 1508*14b24e2bSVaishali Kulkarni if ((vf_zone_size_mode != VF_ZONE_SIZE_MODE_DEFAULT) && (stat_cnt_id > MAX_NUM_PFS)) { 1509*14b24e2bSVaishali Kulkarni if (vf_zone_size_mode == VF_ZONE_SIZE_MODE_DOUBLE) 1510*14b24e2bSVaishali Kulkarni offset += (1 << MSTORM_VF_ZONE_DEFAULT_SIZE_LOG) * (stat_cnt_id - MAX_NUM_PFS); 1511*14b24e2bSVaishali Kulkarni else if (vf_zone_size_mode == VF_ZONE_SIZE_MODE_QUAD) 1512*14b24e2bSVaishali Kulkarni offset += 3 * (1 << MSTORM_VF_ZONE_DEFAULT_SIZE_LOG) * (stat_cnt_id - MAX_NUM_PFS); 1513*14b24e2bSVaishali Kulkarni } 1514*14b24e2bSVaishali Kulkarni 1515*14b24e2bSVaishali Kulkarni return offset; 1516*14b24e2bSVaishali Kulkarni } 1517*14b24e2bSVaishali Kulkarni 1518*14b24e2bSVaishali Kulkarni /* Get mstorm VF producer offset by VF zone size mode */ 1519*14b24e2bSVaishali Kulkarni u32 ecore_get_mstorm_eth_vf_prods_offset(struct ecore_hwfn *p_hwfn, u8 vf_id, u8 vf_queue_id, u16 vf_zone_size_mode) 1520*14b24e2bSVaishali Kulkarni { 1521*14b24e2bSVaishali Kulkarni u32 offset = MSTORM_ETH_VF_PRODS_OFFSET(vf_id, vf_queue_id); 1522*14b24e2bSVaishali Kulkarni 1523*14b24e2bSVaishali Kulkarni if (vf_zone_size_mode != VF_ZONE_SIZE_MODE_DEFAULT) { 1524*14b24e2bSVaishali Kulkarni if (vf_zone_size_mode == VF_ZONE_SIZE_MODE_DOUBLE) 1525*14b24e2bSVaishali Kulkarni offset += (1 << MSTORM_VF_ZONE_DEFAULT_SIZE_LOG) * vf_id; 1526*14b24e2bSVaishali Kulkarni else if (vf_zone_size_mode == VF_ZONE_SIZE_MODE_QUAD) 1527*14b24e2bSVaishali Kulkarni offset += 3 * (1 << MSTORM_VF_ZONE_DEFAULT_SIZE_LOG) * vf_id; 1528*14b24e2bSVaishali Kulkarni } 1529*14b24e2bSVaishali Kulkarni 1530*14b24e2bSVaishali Kulkarni return offset; 1531*14b24e2bSVaishali Kulkarni } 1532*14b24e2bSVaishali Kulkarni 1533*14b24e2bSVaishali Kulkarni #ifndef LINUX_REMOVE 1534*14b24e2bSVaishali Kulkarni #define CRC8_INIT_VALUE 0xFF 1535*14b24e2bSVaishali Kulkarni #endif 1536*14b24e2bSVaishali Kulkarni static u8 cdu_crc8_table[CRC8_TABLE_SIZE]; 1537*14b24e2bSVaishali Kulkarni 1538*14b24e2bSVaishali Kulkarni /* Calculate and return CDU validation byte per connection type/region/cid */ 1539*14b24e2bSVaishali Kulkarni static u8 ecore_calc_cdu_validation_byte(struct ecore_hwfn * p_hwfn, u8 conn_type, 1540*14b24e2bSVaishali Kulkarni u8 region, u32 cid) 1541*14b24e2bSVaishali Kulkarni { 1542*14b24e2bSVaishali Kulkarni const u8 validation_cfg = CDU_VALIDATION_DEFAULT_CFG; 1543*14b24e2bSVaishali Kulkarni 1544*14b24e2bSVaishali Kulkarni static u8 crc8_table_valid; /*automatically initialized to 0*/ 1545*14b24e2bSVaishali Kulkarni u8 crc, validation_byte = 0; 1546*14b24e2bSVaishali Kulkarni u32 validation_string = 0; 1547*14b24e2bSVaishali Kulkarni u32 data_to_crc; 1548*14b24e2bSVaishali Kulkarni 1549*14b24e2bSVaishali Kulkarni if (crc8_table_valid == 0) { 1550*14b24e2bSVaishali Kulkarni OSAL_CRC8_POPULATE(cdu_crc8_table, 0x07); 1551*14b24e2bSVaishali Kulkarni crc8_table_valid = 1; 1552*14b24e2bSVaishali Kulkarni } 1553*14b24e2bSVaishali Kulkarni 1554*14b24e2bSVaishali Kulkarni /* The CRC is calculated on the String-to-compress: 1555*14b24e2bSVaishali Kulkarni * [31:8] = {CID[31:20],CID[11:0]} 1556*14b24e2bSVaishali Kulkarni * [7:4] = Region 1557*14b24e2bSVaishali Kulkarni * [3:0] = Type 1558*14b24e2bSVaishali Kulkarni */ 1559*14b24e2bSVaishali Kulkarni if ((validation_cfg >> CDU_CONTEXT_VALIDATION_CFG_USE_CID) & 1) 1560*14b24e2bSVaishali Kulkarni validation_string |= (cid & 0xFFF00000) | ((cid & 0xFFF) << 8); 1561*14b24e2bSVaishali Kulkarni 1562*14b24e2bSVaishali Kulkarni if ((validation_cfg >> CDU_CONTEXT_VALIDATION_CFG_USE_REGION) & 1) 1563*14b24e2bSVaishali Kulkarni validation_string |= ((region & 0xF) << 4); 1564*14b24e2bSVaishali Kulkarni 1565*14b24e2bSVaishali Kulkarni if ((validation_cfg >> CDU_CONTEXT_VALIDATION_CFG_USE_TYPE) & 1) 1566*14b24e2bSVaishali Kulkarni validation_string |= (conn_type & 0xF); 1567*14b24e2bSVaishali Kulkarni 1568*14b24e2bSVaishali Kulkarni /* Convert to big-endian and calculate CRC8*/ 1569*14b24e2bSVaishali Kulkarni data_to_crc = OSAL_BE32_TO_CPU(validation_string); 1570*14b24e2bSVaishali Kulkarni 1571*14b24e2bSVaishali Kulkarni crc = OSAL_CRC8(cdu_crc8_table, (u8 *)&data_to_crc, sizeof(data_to_crc), CRC8_INIT_VALUE); 1572*14b24e2bSVaishali Kulkarni 1573*14b24e2bSVaishali Kulkarni /* The validation byte [7:0] is composed: 1574*14b24e2bSVaishali Kulkarni * for type A validation 1575*14b24e2bSVaishali Kulkarni * [7] = active configuration bit 1576*14b24e2bSVaishali Kulkarni * [6:0] = crc[6:0] 1577*14b24e2bSVaishali Kulkarni * 1578*14b24e2bSVaishali Kulkarni * for type B validation 1579*14b24e2bSVaishali Kulkarni * [7] = active configuration bit 1580*14b24e2bSVaishali Kulkarni * [6:3] = connection_type[3:0] 1581*14b24e2bSVaishali Kulkarni * [2:0] = crc[2:0] 1582*14b24e2bSVaishali Kulkarni */ 1583*14b24e2bSVaishali Kulkarni validation_byte |= ((validation_cfg >> CDU_CONTEXT_VALIDATION_CFG_USE_ACTIVE) & 1) << 7; 1584*14b24e2bSVaishali Kulkarni 1585*14b24e2bSVaishali Kulkarni if ((validation_cfg >> CDU_CONTEXT_VALIDATION_CFG_VALIDATION_TYPE_SHIFT) & 1) 1586*14b24e2bSVaishali Kulkarni validation_byte |= ((conn_type & 0xF) << 3) | (crc & 0x7); 1587*14b24e2bSVaishali Kulkarni else 1588*14b24e2bSVaishali Kulkarni validation_byte |= crc & 0x7F; 1589*14b24e2bSVaishali Kulkarni 1590*14b24e2bSVaishali Kulkarni return validation_byte; 1591*14b24e2bSVaishali Kulkarni } 1592*14b24e2bSVaishali Kulkarni 1593*14b24e2bSVaishali Kulkarni /* Calcualte and set validation bytes for session context */ 1594*14b24e2bSVaishali Kulkarni void ecore_calc_session_ctx_validation(struct ecore_hwfn * p_hwfn, void *p_ctx_mem, 1595*14b24e2bSVaishali Kulkarni u16 ctx_size, u8 ctx_type, u32 cid) 1596*14b24e2bSVaishali Kulkarni { 1597*14b24e2bSVaishali Kulkarni u8 *x_val_ptr, *t_val_ptr, *u_val_ptr, *p_ctx; 1598*14b24e2bSVaishali Kulkarni 1599*14b24e2bSVaishali Kulkarni p_ctx = (u8* const)p_ctx_mem; 1600*14b24e2bSVaishali Kulkarni x_val_ptr = &p_ctx[con_region_offsets[0][ctx_type]]; 1601*14b24e2bSVaishali Kulkarni t_val_ptr = &p_ctx[con_region_offsets[1][ctx_type]]; 1602*14b24e2bSVaishali Kulkarni u_val_ptr = &p_ctx[con_region_offsets[2][ctx_type]]; 1603*14b24e2bSVaishali Kulkarni 1604*14b24e2bSVaishali Kulkarni OSAL_MEMSET(p_ctx, 0, ctx_size); 1605*14b24e2bSVaishali Kulkarni 1606*14b24e2bSVaishali Kulkarni *x_val_ptr = ecore_calc_cdu_validation_byte(p_hwfn, ctx_type, 3, cid); 1607*14b24e2bSVaishali Kulkarni *t_val_ptr = ecore_calc_cdu_validation_byte(p_hwfn, ctx_type, 4, cid); 1608*14b24e2bSVaishali Kulkarni *u_val_ptr = ecore_calc_cdu_validation_byte(p_hwfn, ctx_type, 5, cid); 1609*14b24e2bSVaishali Kulkarni } 1610*14b24e2bSVaishali Kulkarni 1611*14b24e2bSVaishali Kulkarni /* Calcualte and set validation bytes for task context */ 1612*14b24e2bSVaishali Kulkarni void ecore_calc_task_ctx_validation(struct ecore_hwfn * p_hwfn, void *p_ctx_mem, 1613*14b24e2bSVaishali Kulkarni u16 ctx_size, u8 ctx_type, u32 tid) 1614*14b24e2bSVaishali Kulkarni { 1615*14b24e2bSVaishali Kulkarni u8 *p_ctx, *region1_val_ptr; 1616*14b24e2bSVaishali Kulkarni 1617*14b24e2bSVaishali Kulkarni p_ctx = (u8* const)p_ctx_mem; 1618*14b24e2bSVaishali Kulkarni region1_val_ptr = &p_ctx[task_region_offsets[0][ctx_type]]; 1619*14b24e2bSVaishali Kulkarni 1620*14b24e2bSVaishali Kulkarni OSAL_MEMSET(p_ctx, 0, ctx_size); 1621*14b24e2bSVaishali Kulkarni 1622*14b24e2bSVaishali Kulkarni *region1_val_ptr = ecore_calc_cdu_validation_byte(p_hwfn, ctx_type, 1623*14b24e2bSVaishali Kulkarni 1, tid); 1624*14b24e2bSVaishali Kulkarni } 1625*14b24e2bSVaishali Kulkarni 1626*14b24e2bSVaishali Kulkarni /* Memset session context to 0 while preserving validation bytes */ 1627*14b24e2bSVaishali Kulkarni void ecore_memset_session_ctx(void *p_ctx_mem, u32 ctx_size, u8 ctx_type) 1628*14b24e2bSVaishali Kulkarni { 1629*14b24e2bSVaishali Kulkarni u8 *x_val_ptr, *t_val_ptr, *u_val_ptr, *p_ctx; 1630*14b24e2bSVaishali Kulkarni u8 x_val, t_val, u_val; 1631*14b24e2bSVaishali Kulkarni 1632*14b24e2bSVaishali Kulkarni p_ctx = (u8* const)p_ctx_mem; 1633*14b24e2bSVaishali Kulkarni x_val_ptr = &p_ctx[con_region_offsets[0][ctx_type]]; 1634*14b24e2bSVaishali Kulkarni t_val_ptr = &p_ctx[con_region_offsets[1][ctx_type]]; 1635*14b24e2bSVaishali Kulkarni u_val_ptr = &p_ctx[con_region_offsets[2][ctx_type]]; 1636*14b24e2bSVaishali Kulkarni 1637*14b24e2bSVaishali Kulkarni x_val = *x_val_ptr; 1638*14b24e2bSVaishali Kulkarni t_val = *t_val_ptr; 1639*14b24e2bSVaishali Kulkarni u_val = *u_val_ptr; 1640*14b24e2bSVaishali Kulkarni 1641*14b24e2bSVaishali Kulkarni OSAL_MEMSET(p_ctx, 0, ctx_size); 1642*14b24e2bSVaishali Kulkarni 1643*14b24e2bSVaishali Kulkarni *x_val_ptr = x_val; 1644*14b24e2bSVaishali Kulkarni *t_val_ptr = t_val; 1645*14b24e2bSVaishali Kulkarni *u_val_ptr = u_val; 1646*14b24e2bSVaishali Kulkarni } 1647*14b24e2bSVaishali Kulkarni 1648*14b24e2bSVaishali Kulkarni /* Memset task context to 0 while preserving validation bytes */ 1649*14b24e2bSVaishali Kulkarni void ecore_memset_task_ctx(void *p_ctx_mem, u32 ctx_size, u8 ctx_type) 1650*14b24e2bSVaishali Kulkarni { 1651*14b24e2bSVaishali Kulkarni u8 *p_ctx, *region1_val_ptr; 1652*14b24e2bSVaishali Kulkarni u8 region1_val; 1653*14b24e2bSVaishali Kulkarni 1654*14b24e2bSVaishali Kulkarni p_ctx = (u8* const)p_ctx_mem; 1655*14b24e2bSVaishali Kulkarni region1_val_ptr = &p_ctx[task_region_offsets[0][ctx_type]]; 1656*14b24e2bSVaishali Kulkarni 1657*14b24e2bSVaishali Kulkarni region1_val = *region1_val_ptr; 1658*14b24e2bSVaishali Kulkarni 1659*14b24e2bSVaishali Kulkarni OSAL_MEMSET(p_ctx, 0, ctx_size); 1660*14b24e2bSVaishali Kulkarni 1661*14b24e2bSVaishali Kulkarni *region1_val_ptr = region1_val; 1662*14b24e2bSVaishali Kulkarni } 1663*14b24e2bSVaishali Kulkarni 1664*14b24e2bSVaishali Kulkarni /* Enable and configure context validation */ 1665*14b24e2bSVaishali Kulkarni void ecore_enable_context_validation(struct ecore_hwfn * p_hwfn, struct ecore_ptt *p_ptt) 1666*14b24e2bSVaishali Kulkarni { 1667*14b24e2bSVaishali Kulkarni u32 ctx_validation; 1668*14b24e2bSVaishali Kulkarni 1669*14b24e2bSVaishali Kulkarni /* Enable validation for connection region 3: CCFC_CTX_VALID0[31:24] */ 1670*14b24e2bSVaishali Kulkarni ctx_validation = CDU_VALIDATION_DEFAULT_CFG << 24; 1671*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, CDU_REG_CCFC_CTX_VALID0, ctx_validation); 1672*14b24e2bSVaishali Kulkarni 1673*14b24e2bSVaishali Kulkarni /* Enable validation for connection region 5: CCFC_CTX_VALID1[15:8] */ 1674*14b24e2bSVaishali Kulkarni ctx_validation = CDU_VALIDATION_DEFAULT_CFG << 8; 1675*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, CDU_REG_CCFC_CTX_VALID1, ctx_validation); 1676*14b24e2bSVaishali Kulkarni 1677*14b24e2bSVaishali Kulkarni /* Enable validation for connection region 1: TCFC_CTX_VALID0[15:8] */ 1678*14b24e2bSVaishali Kulkarni ctx_validation = CDU_VALIDATION_DEFAULT_CFG << 8; 1679*14b24e2bSVaishali Kulkarni ecore_wr(p_hwfn, p_ptt, CDU_REG_TCFC_CTX_VALID0, ctx_validation); 1680*14b24e2bSVaishali Kulkarni } 1681