1fe56b9e6SYuval Mintz /* QLogic qed NIC Driver 2fe56b9e6SYuval Mintz * Copyright (c) 2015 QLogic Corporation 3fe56b9e6SYuval Mintz * 4fe56b9e6SYuval Mintz * This software is available under the terms of the GNU General Public License 5fe56b9e6SYuval Mintz * (GPL) Version 2, available from the file COPYING in the main directory of 6fe56b9e6SYuval Mintz * this source tree. 7fe56b9e6SYuval Mintz */ 8fe56b9e6SYuval Mintz 9fe56b9e6SYuval Mintz #include <linux/types.h> 10fe56b9e6SYuval Mintz #include <linux/delay.h> 11fe56b9e6SYuval Mintz #include <linux/kernel.h> 12fe56b9e6SYuval Mintz #include <linux/slab.h> 13fe56b9e6SYuval Mintz #include <linux/string.h> 14fe56b9e6SYuval Mintz #include "qed_hsi.h" 15fe56b9e6SYuval Mintz #include "qed_hw.h" 16fe56b9e6SYuval Mintz #include "qed_init_ops.h" 17fe56b9e6SYuval Mintz #include "qed_reg_addr.h" 18fe56b9e6SYuval Mintz 19fe56b9e6SYuval Mintz enum cminterface { 20fe56b9e6SYuval Mintz MCM_SEC, 21fe56b9e6SYuval Mintz MCM_PRI, 22fe56b9e6SYuval Mintz UCM_SEC, 23fe56b9e6SYuval Mintz UCM_PRI, 24fe56b9e6SYuval Mintz TCM_SEC, 25fe56b9e6SYuval Mintz TCM_PRI, 26fe56b9e6SYuval Mintz YCM_SEC, 27fe56b9e6SYuval Mintz YCM_PRI, 28fe56b9e6SYuval Mintz XCM_SEC, 29fe56b9e6SYuval Mintz XCM_PRI, 30fe56b9e6SYuval Mintz NUM_OF_CM_INTERFACES 31fe56b9e6SYuval Mintz }; 32fe56b9e6SYuval Mintz 33fe56b9e6SYuval Mintz /* general constants */ 34fe56b9e6SYuval Mintz #define QM_PQ_MEM_4KB(pq_size) (pq_size ? DIV_ROUND_UP((pq_size + 1) * \ 35fe56b9e6SYuval Mintz QM_PQ_ELEMENT_SIZE, \ 36fe56b9e6SYuval Mintz 0x1000) : 0) 37fe56b9e6SYuval Mintz #define QM_PQ_SIZE_256B(pq_size) (pq_size ? DIV_ROUND_UP(pq_size, \ 38fe56b9e6SYuval Mintz 0x100) - 1 : 0) 39fe56b9e6SYuval Mintz #define QM_INVALID_PQ_ID 0xffff 40fe56b9e6SYuval Mintz /* feature enable */ 41fe56b9e6SYuval Mintz #define QM_BYPASS_EN 1 42fe56b9e6SYuval Mintz #define QM_BYTE_CRD_EN 1 43fe56b9e6SYuval Mintz /* other PQ constants */ 44fe56b9e6SYuval Mintz #define QM_OTHER_PQS_PER_PF 4 45fe56b9e6SYuval Mintz /* WFQ constants */ 46351a4dedSYuval Mintz #define QM_WFQ_UPPER_BOUND 62500000 47fe56b9e6SYuval Mintz #define QM_WFQ_VP_PQ_VOQ_SHIFT 0 48fe56b9e6SYuval Mintz #define QM_WFQ_VP_PQ_PF_SHIFT 5 49fe56b9e6SYuval Mintz #define QM_WFQ_INC_VAL(weight) ((weight) * 0x9000) 50351a4dedSYuval Mintz #define QM_WFQ_MAX_INC_VAL 43750000 51351a4dedSYuval Mintz 52fe56b9e6SYuval Mintz /* RL constants */ 53351a4dedSYuval Mintz #define QM_RL_UPPER_BOUND 62500000 54fe56b9e6SYuval Mintz #define QM_RL_PERIOD 5 /* in us */ 55fe56b9e6SYuval Mintz #define QM_RL_PERIOD_CLK_25M (25 * QM_RL_PERIOD) 56351a4dedSYuval Mintz #define QM_RL_MAX_INC_VAL 43750000 57fe56b9e6SYuval Mintz #define QM_RL_INC_VAL(rate) max_t(u32, \ 58351a4dedSYuval Mintz (u32)(((rate ? rate : \ 59351a4dedSYuval Mintz 1000000) * \ 60351a4dedSYuval Mintz QM_RL_PERIOD * \ 61351a4dedSYuval Mintz 101) / (8 * 100)), 1) 62fe56b9e6SYuval Mintz /* AFullOprtnstcCrdMask constants */ 63fe56b9e6SYuval Mintz #define QM_OPPOR_LINE_VOQ_DEF 1 64fe56b9e6SYuval Mintz #define QM_OPPOR_FW_STOP_DEF 0 65fe56b9e6SYuval Mintz #define QM_OPPOR_PQ_EMPTY_DEF 1 66fe56b9e6SYuval Mintz /* Command Queue constants */ 67fe56b9e6SYuval Mintz #define PBF_CMDQ_PURE_LB_LINES 150 68fe56b9e6SYuval Mintz #define PBF_CMDQ_LINES_RT_OFFSET(voq) ( \ 69fe56b9e6SYuval Mintz PBF_REG_YCMD_QS_NUM_LINES_VOQ0_RT_OFFSET + voq * \ 70fe56b9e6SYuval Mintz (PBF_REG_YCMD_QS_NUM_LINES_VOQ1_RT_OFFSET - \ 71fe56b9e6SYuval Mintz PBF_REG_YCMD_QS_NUM_LINES_VOQ0_RT_OFFSET)) 72fe56b9e6SYuval Mintz #define PBF_BTB_GUARANTEED_RT_OFFSET(voq) ( \ 73fe56b9e6SYuval Mintz PBF_REG_BTB_GUARANTEED_VOQ0_RT_OFFSET + voq * \ 74fe56b9e6SYuval Mintz (PBF_REG_BTB_GUARANTEED_VOQ1_RT_OFFSET - \ 75fe56b9e6SYuval Mintz PBF_REG_BTB_GUARANTEED_VOQ0_RT_OFFSET)) 76fe56b9e6SYuval Mintz #define QM_VOQ_LINE_CRD(pbf_cmd_lines) ((((pbf_cmd_lines) - \ 77fe56b9e6SYuval Mintz 4) * \ 78fe56b9e6SYuval Mintz 2) | QM_LINE_CRD_REG_SIGN_BIT) 79fe56b9e6SYuval Mintz /* BTB: blocks constants (block size = 256B) */ 80fe56b9e6SYuval Mintz #define BTB_JUMBO_PKT_BLOCKS 38 81fe56b9e6SYuval Mintz #define BTB_HEADROOM_BLOCKS BTB_JUMBO_PKT_BLOCKS 82fe56b9e6SYuval Mintz #define BTB_PURE_LB_FACTOR 10 83fe56b9e6SYuval Mintz #define BTB_PURE_LB_RATIO 7 84fe56b9e6SYuval Mintz /* QM stop command constants */ 85fe56b9e6SYuval Mintz #define QM_STOP_PQ_MASK_WIDTH 32 86fe56b9e6SYuval Mintz #define QM_STOP_CMD_ADDR 0x2 87fe56b9e6SYuval Mintz #define QM_STOP_CMD_STRUCT_SIZE 2 88fe56b9e6SYuval Mintz #define QM_STOP_CMD_PAUSE_MASK_OFFSET 0 89fe56b9e6SYuval Mintz #define QM_STOP_CMD_PAUSE_MASK_SHIFT 0 90fe56b9e6SYuval Mintz #define QM_STOP_CMD_PAUSE_MASK_MASK -1 91fe56b9e6SYuval Mintz #define QM_STOP_CMD_GROUP_ID_OFFSET 1 92fe56b9e6SYuval Mintz #define QM_STOP_CMD_GROUP_ID_SHIFT 16 93fe56b9e6SYuval Mintz #define QM_STOP_CMD_GROUP_ID_MASK 15 94fe56b9e6SYuval Mintz #define QM_STOP_CMD_PQ_TYPE_OFFSET 1 95fe56b9e6SYuval Mintz #define QM_STOP_CMD_PQ_TYPE_SHIFT 24 96fe56b9e6SYuval Mintz #define QM_STOP_CMD_PQ_TYPE_MASK 1 97fe56b9e6SYuval Mintz #define QM_STOP_CMD_MAX_POLL_COUNT 100 98fe56b9e6SYuval Mintz #define QM_STOP_CMD_POLL_PERIOD_US 500 99fe56b9e6SYuval Mintz /* QM command macros */ 100fe56b9e6SYuval Mintz #define QM_CMD_STRUCT_SIZE(cmd) cmd ## \ 101fe56b9e6SYuval Mintz _STRUCT_SIZE 102fe56b9e6SYuval Mintz #define QM_CMD_SET_FIELD(var, cmd, field, \ 103fe56b9e6SYuval Mintz value) SET_FIELD(var[cmd ## _ ## field ## \ 104fe56b9e6SYuval Mintz _OFFSET], \ 105fe56b9e6SYuval Mintz cmd ## _ ## field, \ 106fe56b9e6SYuval Mintz value) 107fe56b9e6SYuval Mintz /* QM: VOQ macros */ 108351a4dedSYuval Mintz #define PHYS_VOQ(port, tc, max_phys_tcs_per_port) ((port) * \ 109351a4dedSYuval Mintz (max_phys_tcs_per_port) + \ 110351a4dedSYuval Mintz (tc)) 111fe56b9e6SYuval Mintz #define LB_VOQ(port) ( \ 112fe56b9e6SYuval Mintz MAX_PHYS_VOQS + (port)) 113fe56b9e6SYuval Mintz #define VOQ(port, tc, max_phy_tcs_pr_port) \ 114fe56b9e6SYuval Mintz ((tc) < \ 115fe56b9e6SYuval Mintz LB_TC ? PHYS_VOQ(port, \ 116fe56b9e6SYuval Mintz tc, \ 117fe56b9e6SYuval Mintz max_phy_tcs_pr_port) \ 118fe56b9e6SYuval Mintz : LB_VOQ(port)) 119fe56b9e6SYuval Mintz /******************** INTERNAL IMPLEMENTATION *********************/ 120fe56b9e6SYuval Mintz /* Prepare PF RL enable/disable runtime init values */ 121351a4dedSYuval Mintz static void qed_enable_pf_rl(struct qed_hwfn *p_hwfn, bool pf_rl_en) 122fe56b9e6SYuval Mintz { 123fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_RLPFENABLE_RT_OFFSET, pf_rl_en ? 1 : 0); 124fe56b9e6SYuval Mintz if (pf_rl_en) { 125fe56b9e6SYuval Mintz /* enable RLs for all VOQs */ 126fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_RLPFVOQENABLE_RT_OFFSET, 127fe56b9e6SYuval Mintz (1 << MAX_NUM_VOQS) - 1); 128fe56b9e6SYuval Mintz /* write RL period */ 129fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 130351a4dedSYuval Mintz QM_REG_RLPFPERIOD_RT_OFFSET, QM_RL_PERIOD_CLK_25M); 131fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 132fe56b9e6SYuval Mintz QM_REG_RLPFPERIODTIMER_RT_OFFSET, 133fe56b9e6SYuval Mintz QM_RL_PERIOD_CLK_25M); 134fe56b9e6SYuval Mintz /* set credit threshold for QM bypass flow */ 135fe56b9e6SYuval Mintz if (QM_BYPASS_EN) 136fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 137fe56b9e6SYuval Mintz QM_REG_AFULLQMBYPTHRPFRL_RT_OFFSET, 138fe56b9e6SYuval Mintz QM_RL_UPPER_BOUND); 139fe56b9e6SYuval Mintz } 140fe56b9e6SYuval Mintz } 141fe56b9e6SYuval Mintz 142fe56b9e6SYuval Mintz /* Prepare PF WFQ enable/disable runtime init values */ 143351a4dedSYuval Mintz static void qed_enable_pf_wfq(struct qed_hwfn *p_hwfn, bool pf_wfq_en) 144fe56b9e6SYuval Mintz { 145fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_WFQPFENABLE_RT_OFFSET, pf_wfq_en ? 1 : 0); 146fe56b9e6SYuval Mintz /* set credit threshold for QM bypass flow */ 147fe56b9e6SYuval Mintz if (pf_wfq_en && QM_BYPASS_EN) 148fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 149fe56b9e6SYuval Mintz QM_REG_AFULLQMBYPTHRPFWFQ_RT_OFFSET, 150fe56b9e6SYuval Mintz QM_WFQ_UPPER_BOUND); 151fe56b9e6SYuval Mintz } 152fe56b9e6SYuval Mintz 153fe56b9e6SYuval Mintz /* Prepare VPORT RL enable/disable runtime init values */ 154351a4dedSYuval Mintz static void qed_enable_vport_rl(struct qed_hwfn *p_hwfn, bool vport_rl_en) 155fe56b9e6SYuval Mintz { 156fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_RLGLBLENABLE_RT_OFFSET, 157fe56b9e6SYuval Mintz vport_rl_en ? 1 : 0); 158fe56b9e6SYuval Mintz if (vport_rl_en) { 159fe56b9e6SYuval Mintz /* write RL period (use timer 0 only) */ 160fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 161fe56b9e6SYuval Mintz QM_REG_RLGLBLPERIOD_0_RT_OFFSET, 162fe56b9e6SYuval Mintz QM_RL_PERIOD_CLK_25M); 163fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 164fe56b9e6SYuval Mintz QM_REG_RLGLBLPERIODTIMER_0_RT_OFFSET, 165fe56b9e6SYuval Mintz QM_RL_PERIOD_CLK_25M); 166fe56b9e6SYuval Mintz /* set credit threshold for QM bypass flow */ 167fe56b9e6SYuval Mintz if (QM_BYPASS_EN) 168fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 169fe56b9e6SYuval Mintz QM_REG_AFULLQMBYPTHRGLBLRL_RT_OFFSET, 170fe56b9e6SYuval Mintz QM_RL_UPPER_BOUND); 171fe56b9e6SYuval Mintz } 172fe56b9e6SYuval Mintz } 173fe56b9e6SYuval Mintz 174fe56b9e6SYuval Mintz /* Prepare VPORT WFQ enable/disable runtime init values */ 175351a4dedSYuval Mintz static void qed_enable_vport_wfq(struct qed_hwfn *p_hwfn, bool vport_wfq_en) 176fe56b9e6SYuval Mintz { 177fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_WFQVPENABLE_RT_OFFSET, 178fe56b9e6SYuval Mintz vport_wfq_en ? 1 : 0); 179fe56b9e6SYuval Mintz /* set credit threshold for QM bypass flow */ 180fe56b9e6SYuval Mintz if (vport_wfq_en && QM_BYPASS_EN) 181fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 182fe56b9e6SYuval Mintz QM_REG_AFULLQMBYPTHRVPWFQ_RT_OFFSET, 183fe56b9e6SYuval Mintz QM_WFQ_UPPER_BOUND); 184fe56b9e6SYuval Mintz } 185fe56b9e6SYuval Mintz 186fe56b9e6SYuval Mintz /* Prepare runtime init values to allocate PBF command queue lines for 187fe56b9e6SYuval Mintz * the specified VOQ 188fe56b9e6SYuval Mintz */ 189fe56b9e6SYuval Mintz static void qed_cmdq_lines_voq_rt_init(struct qed_hwfn *p_hwfn, 190351a4dedSYuval Mintz u8 voq, u16 cmdq_lines) 191fe56b9e6SYuval Mintz { 192fe56b9e6SYuval Mintz u32 qm_line_crd; 193fe56b9e6SYuval Mintz 194fe56b9e6SYuval Mintz /* In A0 - Limit the size of pbf queue so that only 511 commands with 195fe56b9e6SYuval Mintz * the minimum size of 4 (FCoE minimum size) 196fe56b9e6SYuval Mintz */ 197fe56b9e6SYuval Mintz bool is_bb_a0 = QED_IS_BB_A0(p_hwfn->cdev); 198fe56b9e6SYuval Mintz 199fe56b9e6SYuval Mintz if (is_bb_a0) 200fe56b9e6SYuval Mintz cmdq_lines = min_t(u32, cmdq_lines, 1022); 201fe56b9e6SYuval Mintz qm_line_crd = QM_VOQ_LINE_CRD(cmdq_lines); 202fe56b9e6SYuval Mintz OVERWRITE_RT_REG(p_hwfn, PBF_CMDQ_LINES_RT_OFFSET(voq), 203fe56b9e6SYuval Mintz (u32)cmdq_lines); 204fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_VOQCRDLINE_RT_OFFSET + voq, qm_line_crd); 205fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_VOQINITCRDLINE_RT_OFFSET + voq, 206fe56b9e6SYuval Mintz qm_line_crd); 207fe56b9e6SYuval Mintz } 208fe56b9e6SYuval Mintz 209fe56b9e6SYuval Mintz /* Prepare runtime init values to allocate PBF command queue lines. */ 210fe56b9e6SYuval Mintz static void qed_cmdq_lines_rt_init( 211fe56b9e6SYuval Mintz struct qed_hwfn *p_hwfn, 212fe56b9e6SYuval Mintz u8 max_ports_per_engine, 213fe56b9e6SYuval Mintz u8 max_phys_tcs_per_port, 214fe56b9e6SYuval Mintz struct init_qm_port_params port_params[MAX_NUM_PORTS]) 215fe56b9e6SYuval Mintz { 216351a4dedSYuval Mintz u8 tc, voq, port_id, num_tcs_in_port; 217fe56b9e6SYuval Mintz 218fe56b9e6SYuval Mintz /* clear PBF lines for all VOQs */ 219fe56b9e6SYuval Mintz for (voq = 0; voq < MAX_NUM_VOQS; voq++) 220fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, PBF_CMDQ_LINES_RT_OFFSET(voq), 0); 221fe56b9e6SYuval Mintz for (port_id = 0; port_id < max_ports_per_engine; port_id++) { 222fe56b9e6SYuval Mintz if (port_params[port_id].active) { 223fe56b9e6SYuval Mintz u16 phys_lines, phys_lines_per_tc; 224fe56b9e6SYuval Mintz 225351a4dedSYuval Mintz /* find #lines to divide between active phys TCs */ 226fe56b9e6SYuval Mintz phys_lines = port_params[port_id].num_pbf_cmd_lines - 227fe56b9e6SYuval Mintz PBF_CMDQ_PURE_LB_LINES; 228fe56b9e6SYuval Mintz /* find #lines per active physical TC */ 229351a4dedSYuval Mintz num_tcs_in_port = 0; 230351a4dedSYuval Mintz for (tc = 0; tc < NUM_OF_PHYS_TCS; tc++) { 231351a4dedSYuval Mintz if (((port_params[port_id].active_phys_tcs >> 232351a4dedSYuval Mintz tc) & 0x1) == 1) 233351a4dedSYuval Mintz num_tcs_in_port++; 234351a4dedSYuval Mintz } 235351a4dedSYuval Mintz 236351a4dedSYuval Mintz phys_lines_per_tc = phys_lines / num_tcs_in_port; 237fe56b9e6SYuval Mintz /* init registers per active TC */ 238351a4dedSYuval Mintz for (tc = 0; tc < NUM_OF_PHYS_TCS; tc++) { 239351a4dedSYuval Mintz if (((port_params[port_id].active_phys_tcs >> 240351a4dedSYuval Mintz tc) & 0x1) != 1) 241351a4dedSYuval Mintz continue; 242351a4dedSYuval Mintz 243fe56b9e6SYuval Mintz voq = PHYS_VOQ(port_id, tc, 244fe56b9e6SYuval Mintz max_phys_tcs_per_port); 245fe56b9e6SYuval Mintz qed_cmdq_lines_voq_rt_init(p_hwfn, voq, 246fe56b9e6SYuval Mintz phys_lines_per_tc); 247fe56b9e6SYuval Mintz } 248351a4dedSYuval Mintz 249fe56b9e6SYuval Mintz /* init registers for pure LB TC */ 250fe56b9e6SYuval Mintz qed_cmdq_lines_voq_rt_init(p_hwfn, LB_VOQ(port_id), 251fe56b9e6SYuval Mintz PBF_CMDQ_PURE_LB_LINES); 252fe56b9e6SYuval Mintz } 253fe56b9e6SYuval Mintz } 254fe56b9e6SYuval Mintz } 255fe56b9e6SYuval Mintz 256fe56b9e6SYuval Mintz static void qed_btb_blocks_rt_init( 257fe56b9e6SYuval Mintz struct qed_hwfn *p_hwfn, 258fe56b9e6SYuval Mintz u8 max_ports_per_engine, 259fe56b9e6SYuval Mintz u8 max_phys_tcs_per_port, 260fe56b9e6SYuval Mintz struct init_qm_port_params port_params[MAX_NUM_PORTS]) 261fe56b9e6SYuval Mintz { 262fe56b9e6SYuval Mintz u32 usable_blocks, pure_lb_blocks, phys_blocks; 263351a4dedSYuval Mintz u8 tc, voq, port_id, num_tcs_in_port; 264fe56b9e6SYuval Mintz 265fe56b9e6SYuval Mintz for (port_id = 0; port_id < max_ports_per_engine; port_id++) { 266fe56b9e6SYuval Mintz u32 temp; 267fe56b9e6SYuval Mintz 268fe56b9e6SYuval Mintz if (!port_params[port_id].active) 269fe56b9e6SYuval Mintz continue; 270fe56b9e6SYuval Mintz 271fe56b9e6SYuval Mintz /* subtract headroom blocks */ 272fe56b9e6SYuval Mintz usable_blocks = port_params[port_id].num_btb_blocks - 273fe56b9e6SYuval Mintz BTB_HEADROOM_BLOCKS; 274fe56b9e6SYuval Mintz 275351a4dedSYuval Mintz /* find blocks per physical TC */ 276351a4dedSYuval Mintz num_tcs_in_port = 0; 277351a4dedSYuval Mintz for (tc = 0; tc < NUM_OF_PHYS_TCS; tc++) { 278351a4dedSYuval Mintz if (((port_params[port_id].active_phys_tcs >> 279351a4dedSYuval Mintz tc) & 0x1) == 1) 280351a4dedSYuval Mintz num_tcs_in_port++; 281351a4dedSYuval Mintz } 282351a4dedSYuval Mintz 283fe56b9e6SYuval Mintz pure_lb_blocks = (usable_blocks * BTB_PURE_LB_FACTOR) / 284351a4dedSYuval Mintz (num_tcs_in_port * BTB_PURE_LB_FACTOR + 285fe56b9e6SYuval Mintz BTB_PURE_LB_RATIO); 286fe56b9e6SYuval Mintz pure_lb_blocks = max_t(u32, BTB_JUMBO_PKT_BLOCKS, 287fe56b9e6SYuval Mintz pure_lb_blocks / BTB_PURE_LB_FACTOR); 288351a4dedSYuval Mintz phys_blocks = (usable_blocks - pure_lb_blocks) / 289351a4dedSYuval Mintz num_tcs_in_port; 290fe56b9e6SYuval Mintz 291fe56b9e6SYuval Mintz /* init physical TCs */ 292351a4dedSYuval Mintz for (tc = 0; tc < NUM_OF_PHYS_TCS; tc++) { 293351a4dedSYuval Mintz if (((port_params[port_id].active_phys_tcs >> 294351a4dedSYuval Mintz tc) & 0x1) != 1) 295351a4dedSYuval Mintz continue; 296351a4dedSYuval Mintz 297351a4dedSYuval Mintz voq = PHYS_VOQ(port_id, tc, 298351a4dedSYuval Mintz max_phys_tcs_per_port); 299fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, PBF_BTB_GUARANTEED_RT_OFFSET(voq), 300fe56b9e6SYuval Mintz phys_blocks); 301fe56b9e6SYuval Mintz } 302fe56b9e6SYuval Mintz 303fe56b9e6SYuval Mintz /* init pure LB TC */ 304fe56b9e6SYuval Mintz temp = LB_VOQ(port_id); 305fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, PBF_BTB_GUARANTEED_RT_OFFSET(temp), 306fe56b9e6SYuval Mintz pure_lb_blocks); 307fe56b9e6SYuval Mintz } 308fe56b9e6SYuval Mintz } 309fe56b9e6SYuval Mintz 310fe56b9e6SYuval Mintz /* Prepare Tx PQ mapping runtime init values for the specified PF */ 311fe56b9e6SYuval Mintz static void qed_tx_pq_map_rt_init( 312fe56b9e6SYuval Mintz struct qed_hwfn *p_hwfn, 313fe56b9e6SYuval Mintz struct qed_ptt *p_ptt, 314fe56b9e6SYuval Mintz struct qed_qm_pf_rt_init_params *p_params, 315fe56b9e6SYuval Mintz u32 base_mem_addr_4kb) 316fe56b9e6SYuval Mintz { 317fe56b9e6SYuval Mintz struct init_qm_vport_params *vport_params = p_params->vport_params; 318fe56b9e6SYuval Mintz u16 num_pqs = p_params->num_pf_pqs + p_params->num_vf_pqs; 319fe56b9e6SYuval Mintz u16 first_pq_group = p_params->start_pq / QM_PF_QUEUE_GROUP_SIZE; 320fe56b9e6SYuval Mintz u16 last_pq_group = (p_params->start_pq + num_pqs - 1) / 321fe56b9e6SYuval Mintz QM_PF_QUEUE_GROUP_SIZE; 322fe56b9e6SYuval Mintz bool is_bb_a0 = QED_IS_BB_A0(p_hwfn->cdev); 323fe56b9e6SYuval Mintz u16 i, pq_id, pq_group; 324fe56b9e6SYuval Mintz 325fe56b9e6SYuval Mintz /* a bit per Tx PQ indicating if the PQ is associated with a VF */ 326fe56b9e6SYuval Mintz u32 tx_pq_vf_mask[MAX_QM_TX_QUEUES / QM_PF_QUEUE_GROUP_SIZE] = { 0 }; 327fe56b9e6SYuval Mintz u32 tx_pq_vf_mask_width = is_bb_a0 ? 32 : QM_PF_QUEUE_GROUP_SIZE; 328fe56b9e6SYuval Mintz u32 num_tx_pq_vf_masks = MAX_QM_TX_QUEUES / tx_pq_vf_mask_width; 329fe56b9e6SYuval Mintz u32 pq_mem_4kb = QM_PQ_MEM_4KB(p_params->num_pf_cids); 330fe56b9e6SYuval Mintz u32 vport_pq_mem_4kb = QM_PQ_MEM_4KB(p_params->num_vf_cids); 331fe56b9e6SYuval Mintz u32 mem_addr_4kb = base_mem_addr_4kb; 332fe56b9e6SYuval Mintz 333fe56b9e6SYuval Mintz /* set mapping from PQ group to PF */ 334fe56b9e6SYuval Mintz for (pq_group = first_pq_group; pq_group <= last_pq_group; pq_group++) 335fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_PQTX2PF_0_RT_OFFSET + pq_group, 336fe56b9e6SYuval Mintz (u32)(p_params->pf_id)); 337fe56b9e6SYuval Mintz /* set PQ sizes */ 338fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_MAXPQSIZE_0_RT_OFFSET, 339fe56b9e6SYuval Mintz QM_PQ_SIZE_256B(p_params->num_pf_cids)); 340fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_MAXPQSIZE_1_RT_OFFSET, 341fe56b9e6SYuval Mintz QM_PQ_SIZE_256B(p_params->num_vf_cids)); 342fe56b9e6SYuval Mintz 343fe56b9e6SYuval Mintz /* go over all Tx PQs */ 344fe56b9e6SYuval Mintz for (i = 0, pq_id = p_params->start_pq; i < num_pqs; i++, pq_id++) { 345fe56b9e6SYuval Mintz u8 voq = VOQ(p_params->port_id, p_params->pq_params[i].tc_id, 346fe56b9e6SYuval Mintz p_params->max_phys_tcs_per_port); 347fe56b9e6SYuval Mintz bool is_vf_pq = (i >= p_params->num_pf_pqs); 348fe56b9e6SYuval Mintz struct qm_rf_pq_map tx_pq_map; 349fe56b9e6SYuval Mintz 350fe56b9e6SYuval Mintz /* update first Tx PQ of VPORT/TC */ 351fe56b9e6SYuval Mintz u8 vport_id_in_pf = p_params->pq_params[i].vport_id - 352fe56b9e6SYuval Mintz p_params->start_vport; 353fe56b9e6SYuval Mintz u16 *pq_ids = &vport_params[vport_id_in_pf].first_tx_pq_id[0]; 354fe56b9e6SYuval Mintz u16 first_tx_pq_id = pq_ids[p_params->pq_params[i].tc_id]; 355fe56b9e6SYuval Mintz 356fe56b9e6SYuval Mintz if (first_tx_pq_id == QM_INVALID_PQ_ID) { 357fe56b9e6SYuval Mintz /* create new VP PQ */ 358fe56b9e6SYuval Mintz pq_ids[p_params->pq_params[i].tc_id] = pq_id; 359fe56b9e6SYuval Mintz first_tx_pq_id = pq_id; 360fe56b9e6SYuval Mintz /* map VP PQ to VOQ and PF */ 361fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 362fe56b9e6SYuval Mintz QM_REG_WFQVPMAP_RT_OFFSET + 363fe56b9e6SYuval Mintz first_tx_pq_id, 364fe56b9e6SYuval Mintz (voq << QM_WFQ_VP_PQ_VOQ_SHIFT) | 365fe56b9e6SYuval Mintz (p_params->pf_id << 366fe56b9e6SYuval Mintz QM_WFQ_VP_PQ_PF_SHIFT)); 367fe56b9e6SYuval Mintz } 368fe56b9e6SYuval Mintz /* fill PQ map entry */ 369fe56b9e6SYuval Mintz memset(&tx_pq_map, 0, sizeof(tx_pq_map)); 370fe56b9e6SYuval Mintz SET_FIELD(tx_pq_map.reg, QM_RF_PQ_MAP_PQ_VALID, 1); 371fe56b9e6SYuval Mintz SET_FIELD(tx_pq_map.reg, QM_RF_PQ_MAP_RL_VALID, 372351a4dedSYuval Mintz p_params->pq_params[i].rl_valid ? 1 : 0); 373fe56b9e6SYuval Mintz SET_FIELD(tx_pq_map.reg, QM_RF_PQ_MAP_VP_PQ_ID, first_tx_pq_id); 374fe56b9e6SYuval Mintz SET_FIELD(tx_pq_map.reg, QM_RF_PQ_MAP_RL_ID, 375351a4dedSYuval Mintz p_params->pq_params[i].rl_valid ? 376351a4dedSYuval Mintz p_params->pq_params[i].vport_id : 0); 377fe56b9e6SYuval Mintz SET_FIELD(tx_pq_map.reg, QM_RF_PQ_MAP_VOQ, voq); 378fe56b9e6SYuval Mintz SET_FIELD(tx_pq_map.reg, QM_RF_PQ_MAP_WRR_WEIGHT_GROUP, 379fe56b9e6SYuval Mintz p_params->pq_params[i].wrr_group); 380fe56b9e6SYuval Mintz /* write PQ map entry to CAM */ 381fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_TXPQMAP_RT_OFFSET + pq_id, 382fe56b9e6SYuval Mintz *((u32 *)&tx_pq_map)); 383fe56b9e6SYuval Mintz /* set base address */ 384fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 385fe56b9e6SYuval Mintz QM_REG_BASEADDRTXPQ_RT_OFFSET + pq_id, 386fe56b9e6SYuval Mintz mem_addr_4kb); 387fe56b9e6SYuval Mintz /* check if VF PQ */ 388fe56b9e6SYuval Mintz if (is_vf_pq) { 389fe56b9e6SYuval Mintz /* if PQ is associated with a VF, add indication 390fe56b9e6SYuval Mintz * to PQ VF mask 391fe56b9e6SYuval Mintz */ 392fe56b9e6SYuval Mintz tx_pq_vf_mask[pq_id / tx_pq_vf_mask_width] |= 393fe56b9e6SYuval Mintz (1 << (pq_id % tx_pq_vf_mask_width)); 394fe56b9e6SYuval Mintz mem_addr_4kb += vport_pq_mem_4kb; 395fe56b9e6SYuval Mintz } else { 396fe56b9e6SYuval Mintz mem_addr_4kb += pq_mem_4kb; 397fe56b9e6SYuval Mintz } 398fe56b9e6SYuval Mintz } 399fe56b9e6SYuval Mintz 400fe56b9e6SYuval Mintz /* store Tx PQ VF mask to size select register */ 401fe56b9e6SYuval Mintz for (i = 0; i < num_tx_pq_vf_masks; i++) { 402fe56b9e6SYuval Mintz if (tx_pq_vf_mask[i]) { 403fe56b9e6SYuval Mintz u32 addr; 404fe56b9e6SYuval Mintz 405fe56b9e6SYuval Mintz addr = QM_REG_MAXPQSIZETXSEL_0_RT_OFFSET + i; 406fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, addr, 407fe56b9e6SYuval Mintz tx_pq_vf_mask[i]); 408fe56b9e6SYuval Mintz } 409fe56b9e6SYuval Mintz } 410fe56b9e6SYuval Mintz } 411fe56b9e6SYuval Mintz 412fe56b9e6SYuval Mintz /* Prepare Other PQ mapping runtime init values for the specified PF */ 413fe56b9e6SYuval Mintz static void qed_other_pq_map_rt_init(struct qed_hwfn *p_hwfn, 414fe56b9e6SYuval Mintz u8 port_id, 415fe56b9e6SYuval Mintz u8 pf_id, 416fe56b9e6SYuval Mintz u32 num_pf_cids, 417351a4dedSYuval Mintz u32 num_tids, u32 base_mem_addr_4kb) 418fe56b9e6SYuval Mintz { 419fe56b9e6SYuval Mintz u16 i, pq_id; 420fe56b9e6SYuval Mintz 421fe56b9e6SYuval Mintz /* a single other PQ group is used in each PF, 422fe56b9e6SYuval Mintz * where PQ group i is used in PF i. 423fe56b9e6SYuval Mintz */ 424fe56b9e6SYuval Mintz u16 pq_group = pf_id; 425fe56b9e6SYuval Mintz u32 pq_size = num_pf_cids + num_tids; 426fe56b9e6SYuval Mintz u32 pq_mem_4kb = QM_PQ_MEM_4KB(pq_size); 427fe56b9e6SYuval Mintz u32 mem_addr_4kb = base_mem_addr_4kb; 428fe56b9e6SYuval Mintz 429fe56b9e6SYuval Mintz /* map PQ group to PF */ 430fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_PQOTHER2PF_0_RT_OFFSET + pq_group, 431fe56b9e6SYuval Mintz (u32)(pf_id)); 432fe56b9e6SYuval Mintz /* set PQ sizes */ 433fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_MAXPQSIZE_2_RT_OFFSET, 434fe56b9e6SYuval Mintz QM_PQ_SIZE_256B(pq_size)); 435fe56b9e6SYuval Mintz /* set base address */ 436fe56b9e6SYuval Mintz for (i = 0, pq_id = pf_id * QM_PF_QUEUE_GROUP_SIZE; 437fe56b9e6SYuval Mintz i < QM_OTHER_PQS_PER_PF; i++, pq_id++) { 438fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 439fe56b9e6SYuval Mintz QM_REG_BASEADDROTHERPQ_RT_OFFSET + pq_id, 440fe56b9e6SYuval Mintz mem_addr_4kb); 441fe56b9e6SYuval Mintz mem_addr_4kb += pq_mem_4kb; 442fe56b9e6SYuval Mintz } 443fe56b9e6SYuval Mintz } 444fe56b9e6SYuval Mintz 445fe56b9e6SYuval Mintz /* Prepare PF WFQ runtime init values for the specified PF. 446fe56b9e6SYuval Mintz * Return -1 on error. 447fe56b9e6SYuval Mintz */ 448fe56b9e6SYuval Mintz static int qed_pf_wfq_rt_init(struct qed_hwfn *p_hwfn, 449fe56b9e6SYuval Mintz struct qed_qm_pf_rt_init_params *p_params) 450fe56b9e6SYuval Mintz { 451fe56b9e6SYuval Mintz u16 num_tx_pqs = p_params->num_pf_pqs + p_params->num_vf_pqs; 452fe56b9e6SYuval Mintz u32 crd_reg_offset; 453fe56b9e6SYuval Mintz u32 inc_val; 454fe56b9e6SYuval Mintz u16 i; 455fe56b9e6SYuval Mintz 456fe56b9e6SYuval Mintz if (p_params->pf_id < MAX_NUM_PFS_BB) 457fe56b9e6SYuval Mintz crd_reg_offset = QM_REG_WFQPFCRD_RT_OFFSET; 458fe56b9e6SYuval Mintz else 459fe56b9e6SYuval Mintz crd_reg_offset = QM_REG_WFQPFCRD_MSB_RT_OFFSET + 460fe56b9e6SYuval Mintz (p_params->pf_id % MAX_NUM_PFS_BB); 461fe56b9e6SYuval Mintz 462fe56b9e6SYuval Mintz inc_val = QM_WFQ_INC_VAL(p_params->pf_wfq); 463351a4dedSYuval Mintz if (!inc_val || inc_val > QM_WFQ_MAX_INC_VAL) { 464fe56b9e6SYuval Mintz DP_NOTICE(p_hwfn, "Invalid PF WFQ weight configuration"); 465fe56b9e6SYuval Mintz return -1; 466fe56b9e6SYuval Mintz } 467fe56b9e6SYuval Mintz 468fe56b9e6SYuval Mintz for (i = 0; i < num_tx_pqs; i++) { 469fe56b9e6SYuval Mintz u8 voq = VOQ(p_params->port_id, p_params->pq_params[i].tc_id, 470fe56b9e6SYuval Mintz p_params->max_phys_tcs_per_port); 471fe56b9e6SYuval Mintz 472fe56b9e6SYuval Mintz OVERWRITE_RT_REG(p_hwfn, 473fe56b9e6SYuval Mintz crd_reg_offset + voq * MAX_NUM_PFS_BB, 474fe56b9e6SYuval Mintz QM_WFQ_CRD_REG_SIGN_BIT); 475fe56b9e6SYuval Mintz } 476fe56b9e6SYuval Mintz 477351a4dedSYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_WFQPFWEIGHT_RT_OFFSET + p_params->pf_id, 478351a4dedSYuval Mintz inc_val); 479351a4dedSYuval Mintz STORE_RT_REG(p_hwfn, 480351a4dedSYuval Mintz QM_REG_WFQPFUPPERBOUND_RT_OFFSET + p_params->pf_id, 481351a4dedSYuval Mintz QM_WFQ_UPPER_BOUND | QM_WFQ_CRD_REG_SIGN_BIT); 482fe56b9e6SYuval Mintz return 0; 483fe56b9e6SYuval Mintz } 484fe56b9e6SYuval Mintz 485fe56b9e6SYuval Mintz /* Prepare PF RL runtime init values for the specified PF. 486fe56b9e6SYuval Mintz * Return -1 on error. 487fe56b9e6SYuval Mintz */ 488351a4dedSYuval Mintz static int qed_pf_rl_rt_init(struct qed_hwfn *p_hwfn, u8 pf_id, u32 pf_rl) 489fe56b9e6SYuval Mintz { 490fe56b9e6SYuval Mintz u32 inc_val = QM_RL_INC_VAL(pf_rl); 491fe56b9e6SYuval Mintz 492fe56b9e6SYuval Mintz if (inc_val > QM_RL_MAX_INC_VAL) { 493fe56b9e6SYuval Mintz DP_NOTICE(p_hwfn, "Invalid PF rate limit configuration"); 494fe56b9e6SYuval Mintz return -1; 495fe56b9e6SYuval Mintz } 496fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_RLPFCRD_RT_OFFSET + pf_id, 497fe56b9e6SYuval Mintz QM_RL_CRD_REG_SIGN_BIT); 498fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_RLPFUPPERBOUND_RT_OFFSET + pf_id, 499fe56b9e6SYuval Mintz QM_RL_UPPER_BOUND | QM_RL_CRD_REG_SIGN_BIT); 500fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_RLPFINCVAL_RT_OFFSET + pf_id, inc_val); 501fe56b9e6SYuval Mintz return 0; 502fe56b9e6SYuval Mintz } 503fe56b9e6SYuval Mintz 504fe56b9e6SYuval Mintz /* Prepare VPORT WFQ runtime init values for the specified VPORTs. 505fe56b9e6SYuval Mintz * Return -1 on error. 506fe56b9e6SYuval Mintz */ 507fe56b9e6SYuval Mintz static int qed_vp_wfq_rt_init(struct qed_hwfn *p_hwfn, 508fe56b9e6SYuval Mintz u8 num_vports, 509fe56b9e6SYuval Mintz struct init_qm_vport_params *vport_params) 510fe56b9e6SYuval Mintz { 511fe56b9e6SYuval Mintz u32 inc_val; 512fc48b7a6SYuval Mintz u8 tc, i; 513fe56b9e6SYuval Mintz 514fe56b9e6SYuval Mintz /* go over all PF VPORTs */ 515fc48b7a6SYuval Mintz for (i = 0; i < num_vports; i++) { 516fe56b9e6SYuval Mintz 517fe56b9e6SYuval Mintz if (!vport_params[i].vport_wfq) 518fe56b9e6SYuval Mintz continue; 519fe56b9e6SYuval Mintz 520fe56b9e6SYuval Mintz inc_val = QM_WFQ_INC_VAL(vport_params[i].vport_wfq); 521fe56b9e6SYuval Mintz if (inc_val > QM_WFQ_MAX_INC_VAL) { 522fe56b9e6SYuval Mintz DP_NOTICE(p_hwfn, 523fe56b9e6SYuval Mintz "Invalid VPORT WFQ weight configuration"); 524fe56b9e6SYuval Mintz return -1; 525fe56b9e6SYuval Mintz } 526fe56b9e6SYuval Mintz 527fe56b9e6SYuval Mintz /* each VPORT can have several VPORT PQ IDs for 528fe56b9e6SYuval Mintz * different TCs 529fe56b9e6SYuval Mintz */ 530fe56b9e6SYuval Mintz for (tc = 0; tc < NUM_OF_TCS; tc++) { 531fc48b7a6SYuval Mintz u16 vport_pq_id = vport_params[i].first_tx_pq_id[tc]; 532fe56b9e6SYuval Mintz 533fe56b9e6SYuval Mintz if (vport_pq_id != QM_INVALID_PQ_ID) { 534fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 535fe56b9e6SYuval Mintz QM_REG_WFQVPCRD_RT_OFFSET + 536fe56b9e6SYuval Mintz vport_pq_id, 537fe56b9e6SYuval Mintz QM_WFQ_CRD_REG_SIGN_BIT); 538fc48b7a6SYuval Mintz STORE_RT_REG(p_hwfn, 539fc48b7a6SYuval Mintz QM_REG_WFQVPWEIGHT_RT_OFFSET + 540fc48b7a6SYuval Mintz vport_pq_id, inc_val); 541fe56b9e6SYuval Mintz } 542fe56b9e6SYuval Mintz } 543fe56b9e6SYuval Mintz } 544fe56b9e6SYuval Mintz 545fe56b9e6SYuval Mintz return 0; 546fe56b9e6SYuval Mintz } 547fe56b9e6SYuval Mintz 548fe56b9e6SYuval Mintz static int qed_vport_rl_rt_init(struct qed_hwfn *p_hwfn, 549fe56b9e6SYuval Mintz u8 start_vport, 550fe56b9e6SYuval Mintz u8 num_vports, 551fe56b9e6SYuval Mintz struct init_qm_vport_params *vport_params) 552fe56b9e6SYuval Mintz { 553fe56b9e6SYuval Mintz u8 i, vport_id; 554fe56b9e6SYuval Mintz 555fe56b9e6SYuval Mintz /* go over all PF VPORTs */ 556fe56b9e6SYuval Mintz for (i = 0, vport_id = start_vport; i < num_vports; i++, vport_id++) { 557fe56b9e6SYuval Mintz u32 inc_val = QM_RL_INC_VAL(vport_params[i].vport_rl); 558fe56b9e6SYuval Mintz 559fe56b9e6SYuval Mintz if (inc_val > QM_RL_MAX_INC_VAL) { 560fe56b9e6SYuval Mintz DP_NOTICE(p_hwfn, 561fe56b9e6SYuval Mintz "Invalid VPORT rate-limit configuration"); 562fe56b9e6SYuval Mintz return -1; 563fe56b9e6SYuval Mintz } 564fe56b9e6SYuval Mintz 565fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 566fe56b9e6SYuval Mintz QM_REG_RLGLBLCRD_RT_OFFSET + vport_id, 567fe56b9e6SYuval Mintz QM_RL_CRD_REG_SIGN_BIT); 568fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 569fe56b9e6SYuval Mintz QM_REG_RLGLBLUPPERBOUND_RT_OFFSET + vport_id, 570fe56b9e6SYuval Mintz QM_RL_UPPER_BOUND | QM_RL_CRD_REG_SIGN_BIT); 571fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, 572fe56b9e6SYuval Mintz QM_REG_RLGLBLINCVAL_RT_OFFSET + vport_id, 573fe56b9e6SYuval Mintz inc_val); 574fe56b9e6SYuval Mintz } 575fe56b9e6SYuval Mintz 576fe56b9e6SYuval Mintz return 0; 577fe56b9e6SYuval Mintz } 578fe56b9e6SYuval Mintz 579fe56b9e6SYuval Mintz static bool qed_poll_on_qm_cmd_ready(struct qed_hwfn *p_hwfn, 580fe56b9e6SYuval Mintz struct qed_ptt *p_ptt) 581fe56b9e6SYuval Mintz { 582fe56b9e6SYuval Mintz u32 reg_val, i; 583fe56b9e6SYuval Mintz 584fe56b9e6SYuval Mintz for (i = 0, reg_val = 0; i < QM_STOP_CMD_MAX_POLL_COUNT && reg_val == 0; 585fe56b9e6SYuval Mintz i++) { 586fe56b9e6SYuval Mintz udelay(QM_STOP_CMD_POLL_PERIOD_US); 587fe56b9e6SYuval Mintz reg_val = qed_rd(p_hwfn, p_ptt, QM_REG_SDMCMDREADY); 588fe56b9e6SYuval Mintz } 589fe56b9e6SYuval Mintz 590fe56b9e6SYuval Mintz /* check if timeout while waiting for SDM command ready */ 591fe56b9e6SYuval Mintz if (i == QM_STOP_CMD_MAX_POLL_COUNT) { 592fe56b9e6SYuval Mintz DP_VERBOSE(p_hwfn, NETIF_MSG_HW, 593fe56b9e6SYuval Mintz "Timeout when waiting for QM SDM command ready signal\n"); 594fe56b9e6SYuval Mintz return false; 595fe56b9e6SYuval Mintz } 596fe56b9e6SYuval Mintz 597fe56b9e6SYuval Mintz return true; 598fe56b9e6SYuval Mintz } 599fe56b9e6SYuval Mintz 600fe56b9e6SYuval Mintz static bool qed_send_qm_cmd(struct qed_hwfn *p_hwfn, 601fe56b9e6SYuval Mintz struct qed_ptt *p_ptt, 602351a4dedSYuval Mintz u32 cmd_addr, u32 cmd_data_lsb, u32 cmd_data_msb) 603fe56b9e6SYuval Mintz { 604fe56b9e6SYuval Mintz if (!qed_poll_on_qm_cmd_ready(p_hwfn, p_ptt)) 605fe56b9e6SYuval Mintz return false; 606fe56b9e6SYuval Mintz 607fe56b9e6SYuval Mintz qed_wr(p_hwfn, p_ptt, QM_REG_SDMCMDADDR, cmd_addr); 608fe56b9e6SYuval Mintz qed_wr(p_hwfn, p_ptt, QM_REG_SDMCMDDATALSB, cmd_data_lsb); 609fe56b9e6SYuval Mintz qed_wr(p_hwfn, p_ptt, QM_REG_SDMCMDDATAMSB, cmd_data_msb); 610fe56b9e6SYuval Mintz qed_wr(p_hwfn, p_ptt, QM_REG_SDMCMDGO, 1); 611fe56b9e6SYuval Mintz qed_wr(p_hwfn, p_ptt, QM_REG_SDMCMDGO, 0); 612fe56b9e6SYuval Mintz 613fe56b9e6SYuval Mintz return qed_poll_on_qm_cmd_ready(p_hwfn, p_ptt); 614fe56b9e6SYuval Mintz } 615fe56b9e6SYuval Mintz 616fe56b9e6SYuval Mintz /******************** INTERFACE IMPLEMENTATION *********************/ 617fe56b9e6SYuval Mintz u32 qed_qm_pf_mem_size(u8 pf_id, 618fe56b9e6SYuval Mintz u32 num_pf_cids, 619fe56b9e6SYuval Mintz u32 num_vf_cids, 620351a4dedSYuval Mintz u32 num_tids, u16 num_pf_pqs, u16 num_vf_pqs) 621fe56b9e6SYuval Mintz { 622fe56b9e6SYuval Mintz return QM_PQ_MEM_4KB(num_pf_cids) * num_pf_pqs + 623fe56b9e6SYuval Mintz QM_PQ_MEM_4KB(num_vf_cids) * num_vf_pqs + 624fe56b9e6SYuval Mintz QM_PQ_MEM_4KB(num_pf_cids + num_tids) * QM_OTHER_PQS_PER_PF; 625fe56b9e6SYuval Mintz } 626fe56b9e6SYuval Mintz 627fe56b9e6SYuval Mintz int qed_qm_common_rt_init( 628fe56b9e6SYuval Mintz struct qed_hwfn *p_hwfn, 629fe56b9e6SYuval Mintz struct qed_qm_common_rt_init_params *p_params) 630fe56b9e6SYuval Mintz { 631fe56b9e6SYuval Mintz /* init AFullOprtnstcCrdMask */ 632fe56b9e6SYuval Mintz u32 mask = (QM_OPPOR_LINE_VOQ_DEF << 633fe56b9e6SYuval Mintz QM_RF_OPPORTUNISTIC_MASK_LINEVOQ_SHIFT) | 634fe56b9e6SYuval Mintz (QM_BYTE_CRD_EN << QM_RF_OPPORTUNISTIC_MASK_BYTEVOQ_SHIFT) | 635fe56b9e6SYuval Mintz (p_params->pf_wfq_en << 636fe56b9e6SYuval Mintz QM_RF_OPPORTUNISTIC_MASK_PFWFQ_SHIFT) | 637fe56b9e6SYuval Mintz (p_params->vport_wfq_en << 638fe56b9e6SYuval Mintz QM_RF_OPPORTUNISTIC_MASK_VPWFQ_SHIFT) | 639fe56b9e6SYuval Mintz (p_params->pf_rl_en << 640fe56b9e6SYuval Mintz QM_RF_OPPORTUNISTIC_MASK_PFRL_SHIFT) | 641fe56b9e6SYuval Mintz (p_params->vport_rl_en << 642fe56b9e6SYuval Mintz QM_RF_OPPORTUNISTIC_MASK_VPQCNRL_SHIFT) | 643fe56b9e6SYuval Mintz (QM_OPPOR_FW_STOP_DEF << 644fe56b9e6SYuval Mintz QM_RF_OPPORTUNISTIC_MASK_FWPAUSE_SHIFT) | 645fe56b9e6SYuval Mintz (QM_OPPOR_PQ_EMPTY_DEF << 646fe56b9e6SYuval Mintz QM_RF_OPPORTUNISTIC_MASK_QUEUEEMPTY_SHIFT); 647fe56b9e6SYuval Mintz 648fe56b9e6SYuval Mintz STORE_RT_REG(p_hwfn, QM_REG_AFULLOPRTNSTCCRDMASK_RT_OFFSET, mask); 649fe56b9e6SYuval Mintz qed_enable_pf_rl(p_hwfn, p_params->pf_rl_en); 650fe56b9e6SYuval Mintz qed_enable_pf_wfq(p_hwfn, p_params->pf_wfq_en); 651fe56b9e6SYuval Mintz qed_enable_vport_rl(p_hwfn, p_params->vport_rl_en); 652fe56b9e6SYuval Mintz qed_enable_vport_wfq(p_hwfn, p_params->vport_wfq_en); 653fe56b9e6SYuval Mintz qed_cmdq_lines_rt_init(p_hwfn, 654fe56b9e6SYuval Mintz p_params->max_ports_per_engine, 655fe56b9e6SYuval Mintz p_params->max_phys_tcs_per_port, 656fe56b9e6SYuval Mintz p_params->port_params); 657fe56b9e6SYuval Mintz qed_btb_blocks_rt_init(p_hwfn, 658fe56b9e6SYuval Mintz p_params->max_ports_per_engine, 659fe56b9e6SYuval Mintz p_params->max_phys_tcs_per_port, 660fe56b9e6SYuval Mintz p_params->port_params); 661fe56b9e6SYuval Mintz return 0; 662fe56b9e6SYuval Mintz } 663fe56b9e6SYuval Mintz 664fe56b9e6SYuval Mintz int qed_qm_pf_rt_init(struct qed_hwfn *p_hwfn, 665fe56b9e6SYuval Mintz struct qed_ptt *p_ptt, 666fe56b9e6SYuval Mintz struct qed_qm_pf_rt_init_params *p_params) 667fe56b9e6SYuval Mintz { 668fe56b9e6SYuval Mintz struct init_qm_vport_params *vport_params = p_params->vport_params; 669fe56b9e6SYuval Mintz u32 other_mem_size_4kb = QM_PQ_MEM_4KB(p_params->num_pf_cids + 670fe56b9e6SYuval Mintz p_params->num_tids) * 671fe56b9e6SYuval Mintz QM_OTHER_PQS_PER_PF; 672fe56b9e6SYuval Mintz u8 tc, i; 673fe56b9e6SYuval Mintz 674fe56b9e6SYuval Mintz /* clear first Tx PQ ID array for each VPORT */ 675fe56b9e6SYuval Mintz for (i = 0; i < p_params->num_vports; i++) 676fe56b9e6SYuval Mintz for (tc = 0; tc < NUM_OF_TCS; tc++) 677fe56b9e6SYuval Mintz vport_params[i].first_tx_pq_id[tc] = QM_INVALID_PQ_ID; 678fe56b9e6SYuval Mintz 679fe56b9e6SYuval Mintz /* map Other PQs (if any) */ 680fe56b9e6SYuval Mintz qed_other_pq_map_rt_init(p_hwfn, p_params->port_id, p_params->pf_id, 681fe56b9e6SYuval Mintz p_params->num_pf_cids, p_params->num_tids, 0); 682fe56b9e6SYuval Mintz 683fe56b9e6SYuval Mintz /* map Tx PQs */ 684fe56b9e6SYuval Mintz qed_tx_pq_map_rt_init(p_hwfn, p_ptt, p_params, other_mem_size_4kb); 685fe56b9e6SYuval Mintz 686fe56b9e6SYuval Mintz if (p_params->pf_wfq) 687fe56b9e6SYuval Mintz if (qed_pf_wfq_rt_init(p_hwfn, p_params)) 688fe56b9e6SYuval Mintz return -1; 689fe56b9e6SYuval Mintz 690fe56b9e6SYuval Mintz if (qed_pf_rl_rt_init(p_hwfn, p_params->pf_id, p_params->pf_rl)) 691fe56b9e6SYuval Mintz return -1; 692fe56b9e6SYuval Mintz 693fc48b7a6SYuval Mintz if (qed_vp_wfq_rt_init(p_hwfn, p_params->num_vports, vport_params)) 694fe56b9e6SYuval Mintz return -1; 695fe56b9e6SYuval Mintz 696fe56b9e6SYuval Mintz if (qed_vport_rl_rt_init(p_hwfn, p_params->start_vport, 697fe56b9e6SYuval Mintz p_params->num_vports, vport_params)) 698fe56b9e6SYuval Mintz return -1; 699fe56b9e6SYuval Mintz 700fe56b9e6SYuval Mintz return 0; 701fe56b9e6SYuval Mintz } 702fe56b9e6SYuval Mintz 703a64b02d5SManish Chopra int qed_init_pf_wfq(struct qed_hwfn *p_hwfn, 704351a4dedSYuval Mintz struct qed_ptt *p_ptt, u8 pf_id, u16 pf_wfq) 705a64b02d5SManish Chopra { 706a64b02d5SManish Chopra u32 inc_val = QM_WFQ_INC_VAL(pf_wfq); 707a64b02d5SManish Chopra 708a64b02d5SManish Chopra if (!inc_val || inc_val > QM_WFQ_MAX_INC_VAL) { 709a64b02d5SManish Chopra DP_NOTICE(p_hwfn, "Invalid PF WFQ weight configuration"); 710a64b02d5SManish Chopra return -1; 711a64b02d5SManish Chopra } 712a64b02d5SManish Chopra 713a64b02d5SManish Chopra qed_wr(p_hwfn, p_ptt, QM_REG_WFQPFWEIGHT + pf_id * 4, inc_val); 714a64b02d5SManish Chopra return 0; 715a64b02d5SManish Chopra } 716a64b02d5SManish Chopra 717fe56b9e6SYuval Mintz int qed_init_pf_rl(struct qed_hwfn *p_hwfn, 718351a4dedSYuval Mintz struct qed_ptt *p_ptt, u8 pf_id, u32 pf_rl) 719fe56b9e6SYuval Mintz { 720fe56b9e6SYuval Mintz u32 inc_val = QM_RL_INC_VAL(pf_rl); 721fe56b9e6SYuval Mintz 722fe56b9e6SYuval Mintz if (inc_val > QM_RL_MAX_INC_VAL) { 723fe56b9e6SYuval Mintz DP_NOTICE(p_hwfn, "Invalid PF rate limit configuration"); 724fe56b9e6SYuval Mintz return -1; 725fe56b9e6SYuval Mintz } 726fe56b9e6SYuval Mintz 727fe56b9e6SYuval Mintz qed_wr(p_hwfn, p_ptt, 728fe56b9e6SYuval Mintz QM_REG_RLPFCRD + pf_id * 4, 729fe56b9e6SYuval Mintz QM_RL_CRD_REG_SIGN_BIT); 730fe56b9e6SYuval Mintz qed_wr(p_hwfn, p_ptt, QM_REG_RLPFINCVAL + pf_id * 4, inc_val); 731fe56b9e6SYuval Mintz 732fe56b9e6SYuval Mintz return 0; 733fe56b9e6SYuval Mintz } 734fe56b9e6SYuval Mintz 735bcd197c8SManish Chopra int qed_init_vport_wfq(struct qed_hwfn *p_hwfn, 736bcd197c8SManish Chopra struct qed_ptt *p_ptt, 737351a4dedSYuval Mintz u16 first_tx_pq_id[NUM_OF_TCS], u16 vport_wfq) 738bcd197c8SManish Chopra { 739bcd197c8SManish Chopra u32 inc_val = QM_WFQ_INC_VAL(vport_wfq); 740bcd197c8SManish Chopra u8 tc; 741bcd197c8SManish Chopra 742bcd197c8SManish Chopra if (!inc_val || inc_val > QM_WFQ_MAX_INC_VAL) { 743bcd197c8SManish Chopra DP_NOTICE(p_hwfn, "Invalid VPORT WFQ weight configuration"); 744bcd197c8SManish Chopra return -1; 745bcd197c8SManish Chopra } 746bcd197c8SManish Chopra 747bcd197c8SManish Chopra for (tc = 0; tc < NUM_OF_TCS; tc++) { 748bcd197c8SManish Chopra u16 vport_pq_id = first_tx_pq_id[tc]; 749bcd197c8SManish Chopra 750bcd197c8SManish Chopra if (vport_pq_id != QM_INVALID_PQ_ID) 751bcd197c8SManish Chopra qed_wr(p_hwfn, p_ptt, 752bcd197c8SManish Chopra QM_REG_WFQVPWEIGHT + vport_pq_id * 4, 753bcd197c8SManish Chopra inc_val); 754bcd197c8SManish Chopra } 755bcd197c8SManish Chopra 756bcd197c8SManish Chopra return 0; 757bcd197c8SManish Chopra } 758bcd197c8SManish Chopra 759fe56b9e6SYuval Mintz int qed_init_vport_rl(struct qed_hwfn *p_hwfn, 760351a4dedSYuval Mintz struct qed_ptt *p_ptt, u8 vport_id, u32 vport_rl) 761fe56b9e6SYuval Mintz { 762fe56b9e6SYuval Mintz u32 inc_val = QM_RL_INC_VAL(vport_rl); 763fe56b9e6SYuval Mintz 764fe56b9e6SYuval Mintz if (inc_val > QM_RL_MAX_INC_VAL) { 765fe56b9e6SYuval Mintz DP_NOTICE(p_hwfn, "Invalid VPORT rate-limit configuration"); 766fe56b9e6SYuval Mintz return -1; 767fe56b9e6SYuval Mintz } 768fe56b9e6SYuval Mintz 769fe56b9e6SYuval Mintz qed_wr(p_hwfn, p_ptt, 770fe56b9e6SYuval Mintz QM_REG_RLGLBLCRD + vport_id * 4, 771fe56b9e6SYuval Mintz QM_RL_CRD_REG_SIGN_BIT); 772fe56b9e6SYuval Mintz qed_wr(p_hwfn, p_ptt, QM_REG_RLGLBLINCVAL + vport_id * 4, inc_val); 773fe56b9e6SYuval Mintz 774fe56b9e6SYuval Mintz return 0; 775fe56b9e6SYuval Mintz } 776fe56b9e6SYuval Mintz 777fe56b9e6SYuval Mintz bool qed_send_qm_stop_cmd(struct qed_hwfn *p_hwfn, 778fe56b9e6SYuval Mintz struct qed_ptt *p_ptt, 779fe56b9e6SYuval Mintz bool is_release_cmd, 780351a4dedSYuval Mintz bool is_tx_pq, u16 start_pq, u16 num_pqs) 781fe56b9e6SYuval Mintz { 782fe56b9e6SYuval Mintz u32 cmd_arr[QM_CMD_STRUCT_SIZE(QM_STOP_CMD)] = { 0 }; 783fe56b9e6SYuval Mintz u32 pq_mask = 0, last_pq = start_pq + num_pqs - 1, pq_id; 784fe56b9e6SYuval Mintz 785fe56b9e6SYuval Mintz /* set command's PQ type */ 786fe56b9e6SYuval Mintz QM_CMD_SET_FIELD(cmd_arr, QM_STOP_CMD, PQ_TYPE, is_tx_pq ? 0 : 1); 787fe56b9e6SYuval Mintz 788fe56b9e6SYuval Mintz for (pq_id = start_pq; pq_id <= last_pq; pq_id++) { 789fe56b9e6SYuval Mintz /* set PQ bit in mask (stop command only) */ 790fe56b9e6SYuval Mintz if (!is_release_cmd) 791fe56b9e6SYuval Mintz pq_mask |= (1 << (pq_id % QM_STOP_PQ_MASK_WIDTH)); 792fe56b9e6SYuval Mintz 793fe56b9e6SYuval Mintz /* if last PQ or end of PQ mask, write command */ 794fe56b9e6SYuval Mintz if ((pq_id == last_pq) || 795fe56b9e6SYuval Mintz (pq_id % QM_STOP_PQ_MASK_WIDTH == 796fe56b9e6SYuval Mintz (QM_STOP_PQ_MASK_WIDTH - 1))) { 797fe56b9e6SYuval Mintz QM_CMD_SET_FIELD(cmd_arr, QM_STOP_CMD, 798fe56b9e6SYuval Mintz PAUSE_MASK, pq_mask); 799fe56b9e6SYuval Mintz QM_CMD_SET_FIELD(cmd_arr, QM_STOP_CMD, 800fe56b9e6SYuval Mintz GROUP_ID, 801fe56b9e6SYuval Mintz pq_id / QM_STOP_PQ_MASK_WIDTH); 802fe56b9e6SYuval Mintz if (!qed_send_qm_cmd(p_hwfn, p_ptt, QM_STOP_CMD_ADDR, 803fe56b9e6SYuval Mintz cmd_arr[0], cmd_arr[1])) 804fe56b9e6SYuval Mintz return false; 805fe56b9e6SYuval Mintz pq_mask = 0; 806fe56b9e6SYuval Mintz } 807fe56b9e6SYuval Mintz } 808fe56b9e6SYuval Mintz 809fe56b9e6SYuval Mintz return true; 810fe56b9e6SYuval Mintz } 811464f6645SManish Chopra 812464f6645SManish Chopra static void 813464f6645SManish Chopra qed_set_tunnel_type_enable_bit(unsigned long *var, int bit, bool enable) 814464f6645SManish Chopra { 815464f6645SManish Chopra if (enable) 816464f6645SManish Chopra set_bit(bit, var); 817464f6645SManish Chopra else 818464f6645SManish Chopra clear_bit(bit, var); 819464f6645SManish Chopra } 820464f6645SManish Chopra 821464f6645SManish Chopra #define PRS_ETH_TUNN_FIC_FORMAT -188897008 822464f6645SManish Chopra 823464f6645SManish Chopra void qed_set_vxlan_dest_port(struct qed_hwfn *p_hwfn, 824351a4dedSYuval Mintz struct qed_ptt *p_ptt, u16 dest_port) 825464f6645SManish Chopra { 826464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PRS_REG_VXLAN_PORT, dest_port); 827351a4dedSYuval Mintz qed_wr(p_hwfn, p_ptt, NIG_REG_VXLAN_CTRL, dest_port); 828464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PBF_REG_VXLAN_PORT, dest_port); 829464f6645SManish Chopra } 830464f6645SManish Chopra 831464f6645SManish Chopra void qed_set_vxlan_enable(struct qed_hwfn *p_hwfn, 832351a4dedSYuval Mintz struct qed_ptt *p_ptt, bool vxlan_enable) 833464f6645SManish Chopra { 834464f6645SManish Chopra unsigned long reg_val = 0; 835464f6645SManish Chopra u8 shift; 836464f6645SManish Chopra 837464f6645SManish Chopra reg_val = qed_rd(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN); 838464f6645SManish Chopra shift = PRS_REG_ENCAPSULATION_TYPE_EN_VXLAN_ENABLE_SHIFT; 839464f6645SManish Chopra qed_set_tunnel_type_enable_bit(®_val, shift, vxlan_enable); 840464f6645SManish Chopra 841464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN, reg_val); 842464f6645SManish Chopra 843464f6645SManish Chopra if (reg_val) 844464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0, 845464f6645SManish Chopra PRS_ETH_TUNN_FIC_FORMAT); 846464f6645SManish Chopra 847464f6645SManish Chopra reg_val = qed_rd(p_hwfn, p_ptt, NIG_REG_ENC_TYPE_ENABLE); 848464f6645SManish Chopra shift = NIG_REG_ENC_TYPE_ENABLE_VXLAN_ENABLE_SHIFT; 849464f6645SManish Chopra qed_set_tunnel_type_enable_bit(®_val, shift, vxlan_enable); 850464f6645SManish Chopra 851464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, NIG_REG_ENC_TYPE_ENABLE, reg_val); 852464f6645SManish Chopra 853464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, DORQ_REG_L2_EDPM_TUNNEL_VXLAN_EN, 854464f6645SManish Chopra vxlan_enable ? 1 : 0); 855464f6645SManish Chopra } 856464f6645SManish Chopra 857464f6645SManish Chopra void qed_set_gre_enable(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, 858464f6645SManish Chopra bool eth_gre_enable, bool ip_gre_enable) 859464f6645SManish Chopra { 860464f6645SManish Chopra unsigned long reg_val = 0; 861464f6645SManish Chopra u8 shift; 862464f6645SManish Chopra 863464f6645SManish Chopra reg_val = qed_rd(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN); 864464f6645SManish Chopra shift = PRS_REG_ENCAPSULATION_TYPE_EN_ETH_OVER_GRE_ENABLE_SHIFT; 865464f6645SManish Chopra qed_set_tunnel_type_enable_bit(®_val, shift, eth_gre_enable); 866464f6645SManish Chopra 867464f6645SManish Chopra shift = PRS_REG_ENCAPSULATION_TYPE_EN_IP_OVER_GRE_ENABLE_SHIFT; 868464f6645SManish Chopra qed_set_tunnel_type_enable_bit(®_val, shift, ip_gre_enable); 869464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN, reg_val); 870464f6645SManish Chopra if (reg_val) 871464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0, 872464f6645SManish Chopra PRS_ETH_TUNN_FIC_FORMAT); 873464f6645SManish Chopra 874464f6645SManish Chopra reg_val = qed_rd(p_hwfn, p_ptt, NIG_REG_ENC_TYPE_ENABLE); 875464f6645SManish Chopra shift = NIG_REG_ENC_TYPE_ENABLE_ETH_OVER_GRE_ENABLE_SHIFT; 876464f6645SManish Chopra qed_set_tunnel_type_enable_bit(®_val, shift, eth_gre_enable); 877464f6645SManish Chopra 878464f6645SManish Chopra shift = NIG_REG_ENC_TYPE_ENABLE_IP_OVER_GRE_ENABLE_SHIFT; 879464f6645SManish Chopra qed_set_tunnel_type_enable_bit(®_val, shift, ip_gre_enable); 880464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, NIG_REG_ENC_TYPE_ENABLE, reg_val); 881464f6645SManish Chopra 882464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, DORQ_REG_L2_EDPM_TUNNEL_GRE_ETH_EN, 883464f6645SManish Chopra eth_gre_enable ? 1 : 0); 884464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, DORQ_REG_L2_EDPM_TUNNEL_GRE_IP_EN, 885464f6645SManish Chopra ip_gre_enable ? 1 : 0); 886464f6645SManish Chopra } 887464f6645SManish Chopra 888464f6645SManish Chopra void qed_set_geneve_dest_port(struct qed_hwfn *p_hwfn, 889351a4dedSYuval Mintz struct qed_ptt *p_ptt, u16 dest_port) 890464f6645SManish Chopra { 891464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PRS_REG_NGE_PORT, dest_port); 892464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, NIG_REG_NGE_PORT, dest_port); 893464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PBF_REG_NGE_PORT, dest_port); 894464f6645SManish Chopra } 895464f6645SManish Chopra 896464f6645SManish Chopra void qed_set_geneve_enable(struct qed_hwfn *p_hwfn, 897464f6645SManish Chopra struct qed_ptt *p_ptt, 898351a4dedSYuval Mintz bool eth_geneve_enable, bool ip_geneve_enable) 899464f6645SManish Chopra { 900464f6645SManish Chopra unsigned long reg_val = 0; 901464f6645SManish Chopra u8 shift; 902464f6645SManish Chopra 903464f6645SManish Chopra reg_val = qed_rd(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN); 904464f6645SManish Chopra shift = PRS_REG_ENCAPSULATION_TYPE_EN_ETH_OVER_GENEVE_ENABLE_SHIFT; 905464f6645SManish Chopra qed_set_tunnel_type_enable_bit(®_val, shift, eth_geneve_enable); 906464f6645SManish Chopra 907464f6645SManish Chopra shift = PRS_REG_ENCAPSULATION_TYPE_EN_IP_OVER_GENEVE_ENABLE_SHIFT; 908464f6645SManish Chopra qed_set_tunnel_type_enable_bit(®_val, shift, ip_geneve_enable); 909464f6645SManish Chopra 910464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PRS_REG_ENCAPSULATION_TYPE_EN, reg_val); 911464f6645SManish Chopra if (reg_val) 912464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PRS_REG_OUTPUT_FORMAT_4_0, 913464f6645SManish Chopra PRS_ETH_TUNN_FIC_FORMAT); 914464f6645SManish Chopra 915464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, NIG_REG_NGE_ETH_ENABLE, 916464f6645SManish Chopra eth_geneve_enable ? 1 : 0); 917464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, NIG_REG_NGE_IP_ENABLE, ip_geneve_enable ? 1 : 0); 918464f6645SManish Chopra 919464f6645SManish Chopra /* comp ver */ 920464f6645SManish Chopra reg_val = (ip_geneve_enable || eth_geneve_enable) ? 1 : 0; 921464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, NIG_REG_NGE_COMP_VER, reg_val); 922464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PBF_REG_NGE_COMP_VER, reg_val); 923464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, PRS_REG_NGE_COMP_VER, reg_val); 924464f6645SManish Chopra 925464f6645SManish Chopra /* EDPM with geneve tunnel not supported in BB_B0 */ 926464f6645SManish Chopra if (QED_IS_BB_B0(p_hwfn->cdev)) 927464f6645SManish Chopra return; 928464f6645SManish Chopra 929464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, DORQ_REG_L2_EDPM_TUNNEL_NGE_ETH_EN, 930464f6645SManish Chopra eth_geneve_enable ? 1 : 0); 931464f6645SManish Chopra qed_wr(p_hwfn, p_ptt, DORQ_REG_L2_EDPM_TUNNEL_NGE_IP_EN, 932464f6645SManish Chopra ip_geneve_enable ? 1 : 0); 933464f6645SManish Chopra } 934