16af45170SJohn Baldwin /*- 26af45170SJohn Baldwin * Copyright (c) 2016 Chelsio Communications, Inc. 36af45170SJohn Baldwin * All rights reserved. 46af45170SJohn Baldwin * 56af45170SJohn Baldwin * Redistribution and use in source and binary forms, with or without 66af45170SJohn Baldwin * modification, are permitted provided that the following conditions 76af45170SJohn Baldwin * are met: 86af45170SJohn Baldwin * 1. Redistributions of source code must retain the above copyright 96af45170SJohn Baldwin * notice, this list of conditions and the following disclaimer. 106af45170SJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright 116af45170SJohn Baldwin * notice, this list of conditions and the following disclaimer in the 126af45170SJohn Baldwin * documentation and/or other materials provided with the distribution. 136af45170SJohn Baldwin * 146af45170SJohn Baldwin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 156af45170SJohn Baldwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 166af45170SJohn Baldwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 176af45170SJohn Baldwin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 186af45170SJohn Baldwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 196af45170SJohn Baldwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 206af45170SJohn Baldwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 216af45170SJohn Baldwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 226af45170SJohn Baldwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 236af45170SJohn Baldwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 246af45170SJohn Baldwin * SUCH DAMAGE. 256af45170SJohn Baldwin */ 266af45170SJohn Baldwin 276af45170SJohn Baldwin #include <sys/cdefs.h> 286af45170SJohn Baldwin #include "common.h" 296af45170SJohn Baldwin #include "t4_regs.h" 300dbc6cfdSNavdeep Parhar #include "t4_regs_values.h" 316af45170SJohn Baldwin 326af45170SJohn Baldwin #undef msleep 336af45170SJohn Baldwin #define msleep(x) do { \ 346af45170SJohn Baldwin if (cold) \ 356af45170SJohn Baldwin DELAY((x) * 1000); \ 366af45170SJohn Baldwin else \ 376af45170SJohn Baldwin pause("t4hw", (x) * hz / 1000); \ 386af45170SJohn Baldwin } while (0) 396af45170SJohn Baldwin 406af45170SJohn Baldwin /* 416af45170SJohn Baldwin * Wait for the device to become ready (signified by our "who am I" register 426af45170SJohn Baldwin * returning a value other than all 1's). Return an error if it doesn't 436af45170SJohn Baldwin * become ready ... 446af45170SJohn Baldwin */ 456af45170SJohn Baldwin int t4vf_wait_dev_ready(struct adapter *adapter) 466af45170SJohn Baldwin { 476af45170SJohn Baldwin const u32 whoami = VF_PL_REG(A_PL_VF_WHOAMI); 486af45170SJohn Baldwin const u32 notready1 = 0xffffffff; 496af45170SJohn Baldwin const u32 notready2 = 0xeeeeeeee; 506af45170SJohn Baldwin u32 val; 516af45170SJohn Baldwin 526af45170SJohn Baldwin val = t4_read_reg(adapter, whoami); 536af45170SJohn Baldwin if (val != notready1 && val != notready2) 546af45170SJohn Baldwin return 0; 556af45170SJohn Baldwin msleep(500); 566af45170SJohn Baldwin val = t4_read_reg(adapter, whoami); 576af45170SJohn Baldwin if (val != notready1 && val != notready2) 586af45170SJohn Baldwin return 0; 596af45170SJohn Baldwin else 606af45170SJohn Baldwin return -EIO; 616af45170SJohn Baldwin } 626af45170SJohn Baldwin 636af45170SJohn Baldwin 646af45170SJohn Baldwin /** 656af45170SJohn Baldwin * t4vf_fw_reset - issue a reset to FW 666af45170SJohn Baldwin * @adapter: the adapter 676af45170SJohn Baldwin * 686af45170SJohn Baldwin * Issues a reset command to FW. For a Physical Function this would 696af45170SJohn Baldwin * result in the Firmware reseting all of its state. For a Virtual 706af45170SJohn Baldwin * Function this just resets the state associated with the VF. 716af45170SJohn Baldwin */ 726af45170SJohn Baldwin int t4vf_fw_reset(struct adapter *adapter) 736af45170SJohn Baldwin { 746af45170SJohn Baldwin struct fw_reset_cmd cmd; 756af45170SJohn Baldwin 766af45170SJohn Baldwin memset(&cmd, 0, sizeof(cmd)); 776af45170SJohn Baldwin cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_RESET_CMD) | 786af45170SJohn Baldwin F_FW_CMD_WRITE); 796af45170SJohn Baldwin cmd.retval_len16 = cpu_to_be32(V_FW_CMD_LEN16(FW_LEN16(cmd))); 806af45170SJohn Baldwin return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL); 816af45170SJohn Baldwin } 826af45170SJohn Baldwin 836af45170SJohn Baldwin /** 846af45170SJohn Baldwin * t4vf_get_sge_params - retrieve adapter Scatter gather Engine parameters 856af45170SJohn Baldwin * @adapter: the adapter 866af45170SJohn Baldwin * 876af45170SJohn Baldwin * Retrieves various core SGE parameters in the form of hardware SGE 886af45170SJohn Baldwin * register values. The caller is responsible for decoding these as 896af45170SJohn Baldwin * needed. The SGE parameters are stored in @adapter->params.sge. 906af45170SJohn Baldwin */ 916af45170SJohn Baldwin int t4vf_get_sge_params(struct adapter *adapter) 926af45170SJohn Baldwin { 936af45170SJohn Baldwin struct sge_params *sp = &adapter->params.sge; 946af45170SJohn Baldwin u32 params[7], vals[7]; 956af45170SJohn Baldwin u32 whoami; 966af45170SJohn Baldwin unsigned int pf, s_hps; 976af45170SJohn Baldwin int i, v; 986af45170SJohn Baldwin 996af45170SJohn Baldwin params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | 1006af45170SJohn Baldwin V_FW_PARAMS_PARAM_XYZ(A_SGE_CONTROL)); 1016af45170SJohn Baldwin params[1] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | 1026af45170SJohn Baldwin V_FW_PARAMS_PARAM_XYZ(A_SGE_HOST_PAGE_SIZE)); 1036af45170SJohn Baldwin params[2] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | 1046af45170SJohn Baldwin V_FW_PARAMS_PARAM_XYZ(A_SGE_TIMER_VALUE_0_AND_1)); 1056af45170SJohn Baldwin params[3] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | 1066af45170SJohn Baldwin V_FW_PARAMS_PARAM_XYZ(A_SGE_TIMER_VALUE_2_AND_3)); 1076af45170SJohn Baldwin params[4] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | 1086af45170SJohn Baldwin V_FW_PARAMS_PARAM_XYZ(A_SGE_TIMER_VALUE_4_AND_5)); 1096af45170SJohn Baldwin params[5] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | 1106af45170SJohn Baldwin V_FW_PARAMS_PARAM_XYZ(A_SGE_CONM_CTRL)); 1116af45170SJohn Baldwin params[6] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | 1126af45170SJohn Baldwin V_FW_PARAMS_PARAM_XYZ(A_SGE_INGRESS_RX_THRESHOLD)); 1136af45170SJohn Baldwin v = t4vf_query_params(adapter, 7, params, vals); 1146af45170SJohn Baldwin if (v != FW_SUCCESS) 1156af45170SJohn Baldwin return v; 1166af45170SJohn Baldwin 1176af45170SJohn Baldwin sp->sge_control = vals[0]; 1186af45170SJohn Baldwin sp->counter_val[0] = G_THRESHOLD_0(vals[6]); 1196af45170SJohn Baldwin sp->counter_val[1] = G_THRESHOLD_1(vals[6]); 1206af45170SJohn Baldwin sp->counter_val[2] = G_THRESHOLD_2(vals[6]); 1216af45170SJohn Baldwin sp->counter_val[3] = G_THRESHOLD_3(vals[6]); 1226af45170SJohn Baldwin sp->timer_val[0] = core_ticks_to_us(adapter, G_TIMERVALUE0(vals[2])); 1236af45170SJohn Baldwin sp->timer_val[1] = core_ticks_to_us(adapter, G_TIMERVALUE1(vals[2])); 1246af45170SJohn Baldwin sp->timer_val[2] = core_ticks_to_us(adapter, G_TIMERVALUE2(vals[3])); 1256af45170SJohn Baldwin sp->timer_val[3] = core_ticks_to_us(adapter, G_TIMERVALUE3(vals[3])); 1266af45170SJohn Baldwin sp->timer_val[4] = core_ticks_to_us(adapter, G_TIMERVALUE4(vals[4])); 1276af45170SJohn Baldwin sp->timer_val[5] = core_ticks_to_us(adapter, G_TIMERVALUE5(vals[4])); 1286af45170SJohn Baldwin 1296af45170SJohn Baldwin sp->fl_starve_threshold = G_EGRTHRESHOLD(vals[5]) * 2 + 1; 1306af45170SJohn Baldwin if (is_t4(adapter)) 1316af45170SJohn Baldwin sp->fl_starve_threshold2 = sp->fl_starve_threshold; 132774168beSNavdeep Parhar else if (is_t5(adapter)) 133774168beSNavdeep Parhar sp->fl_starve_threshold2 = G_EGRTHRESHOLDPACKING(vals[5]) * 2 + 1; 1346af45170SJohn Baldwin else 135774168beSNavdeep Parhar sp->fl_starve_threshold2 = G_T6_EGRTHRESHOLDPACKING(vals[5]) * 2 + 1; 1366af45170SJohn Baldwin 1376af45170SJohn Baldwin /* 1386af45170SJohn Baldwin * We need the Queues/Page and Host Page Size for our VF. 1396af45170SJohn Baldwin * This is based on the PF from which we're instantiated. 1406af45170SJohn Baldwin */ 1416af45170SJohn Baldwin whoami = t4_read_reg(adapter, VF_PL_REG(A_PL_VF_WHOAMI)); 142*d0fdafdbSNavdeep Parhar if (chip_id(adapter) <= CHELSIO_T5) 1436af45170SJohn Baldwin pf = G_SOURCEPF(whoami); 144*d0fdafdbSNavdeep Parhar else 145*d0fdafdbSNavdeep Parhar pf = G_T6_SOURCEPF(whoami); 1466af45170SJohn Baldwin 1476af45170SJohn Baldwin s_hps = (S_HOSTPAGESIZEPF0 + 1486af45170SJohn Baldwin (S_HOSTPAGESIZEPF1 - S_HOSTPAGESIZEPF0) * pf); 1496af45170SJohn Baldwin sp->page_shift = ((vals[1] >> s_hps) & M_HOSTPAGESIZEPF0) + 10; 1506af45170SJohn Baldwin 1516af45170SJohn Baldwin for (i = 0; i < SGE_FLBUF_SIZES; i++) { 1526af45170SJohn Baldwin params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | 1536af45170SJohn Baldwin V_FW_PARAMS_PARAM_XYZ(A_SGE_FL_BUFFER_SIZE0 + (4 * i))); 1546af45170SJohn Baldwin v = t4vf_query_params(adapter, 1, params, vals); 1556af45170SJohn Baldwin if (v != FW_SUCCESS) 1566af45170SJohn Baldwin return v; 1576af45170SJohn Baldwin 1586af45170SJohn Baldwin sp->sge_fl_buffer_size[i] = vals[0]; 1596af45170SJohn Baldwin } 1606af45170SJohn Baldwin 1616af45170SJohn Baldwin /* 1626af45170SJohn Baldwin * T4 uses a single control field to specify both the PCIe Padding and 1636af45170SJohn Baldwin * Packing Boundary. T5 introduced the ability to specify these 1646af45170SJohn Baldwin * separately with the Padding Boundary in SGE_CONTROL and and Packing 1656af45170SJohn Baldwin * Boundary in SGE_CONTROL2. So for T5 and later we need to grab 1666af45170SJohn Baldwin * SGE_CONTROL in order to determine how ingress packet data will be 1676af45170SJohn Baldwin * laid out in Packed Buffer Mode. Unfortunately, older versions of 1686af45170SJohn Baldwin * the firmware won't let us retrieve SGE_CONTROL2 so if we get a 1696af45170SJohn Baldwin * failure grabbing it we throw an error since we can't figure out the 1706af45170SJohn Baldwin * right value. 1716af45170SJohn Baldwin */ 1726af45170SJohn Baldwin sp->spg_len = sp->sge_control & F_EGRSTATUSPAGESIZE ? 128 : 64; 1736af45170SJohn Baldwin sp->fl_pktshift = G_PKTSHIFT(sp->sge_control); 1740dbc6cfdSNavdeep Parhar if (chip_id(adapter) <= CHELSIO_T5) { 1750dbc6cfdSNavdeep Parhar sp->pad_boundary = 1 << (G_INGPADBOUNDARY(sp->sge_control) + 1760dbc6cfdSNavdeep Parhar X_INGPADBOUNDARY_SHIFT); 1770dbc6cfdSNavdeep Parhar } else { 1780dbc6cfdSNavdeep Parhar sp->pad_boundary = 1 << (G_INGPADBOUNDARY(sp->sge_control) + 1790dbc6cfdSNavdeep Parhar X_T6_INGPADBOUNDARY_SHIFT); 1800dbc6cfdSNavdeep Parhar } 1816af45170SJohn Baldwin if (is_t4(adapter)) 1826af45170SJohn Baldwin sp->pack_boundary = sp->pad_boundary; 1836af45170SJohn Baldwin else { 1846af45170SJohn Baldwin params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | 1856af45170SJohn Baldwin V_FW_PARAMS_PARAM_XYZ(A_SGE_CONTROL2)); 1866af45170SJohn Baldwin v = t4vf_query_params(adapter, 1, params, vals); 1876af45170SJohn Baldwin if (v != FW_SUCCESS) { 1886af45170SJohn Baldwin CH_ERR(adapter, "Unable to get SGE Control2; " 1896af45170SJohn Baldwin "probably old firmware.\n"); 1906af45170SJohn Baldwin return v; 1916af45170SJohn Baldwin } 1926af45170SJohn Baldwin if (G_INGPACKBOUNDARY(vals[0]) == 0) 1936af45170SJohn Baldwin sp->pack_boundary = 16; 1946af45170SJohn Baldwin else 1956af45170SJohn Baldwin sp->pack_boundary = 1 << (G_INGPACKBOUNDARY(vals[0]) + 1966af45170SJohn Baldwin 5); 1976af45170SJohn Baldwin } 1986af45170SJohn Baldwin 1996af45170SJohn Baldwin /* 2006af45170SJohn Baldwin * For T5 and later we want to use the new BAR2 Doorbells. 2016af45170SJohn Baldwin * Unfortunately, older firmware didn't allow the this register to be 2026af45170SJohn Baldwin * read. 2036af45170SJohn Baldwin */ 2046af45170SJohn Baldwin if (!is_t4(adapter)) { 2056af45170SJohn Baldwin unsigned int s_qpp; 2066af45170SJohn Baldwin 2076af45170SJohn Baldwin params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | 2086af45170SJohn Baldwin V_FW_PARAMS_PARAM_XYZ(A_SGE_EGRESS_QUEUES_PER_PAGE_VF)); 2096af45170SJohn Baldwin params[1] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | 2106af45170SJohn Baldwin V_FW_PARAMS_PARAM_XYZ(A_SGE_INGRESS_QUEUES_PER_PAGE_VF)); 2116af45170SJohn Baldwin v = t4vf_query_params(adapter, 2, params, vals); 2126af45170SJohn Baldwin if (v != FW_SUCCESS) { 2136af45170SJohn Baldwin CH_WARN(adapter, "Unable to get VF SGE Queues/Page; " 2146af45170SJohn Baldwin "probably old firmware.\n"); 2156af45170SJohn Baldwin return v; 2166af45170SJohn Baldwin } 2176af45170SJohn Baldwin 2186af45170SJohn Baldwin s_qpp = (S_QUEUESPERPAGEPF0 + 2196af45170SJohn Baldwin (S_QUEUESPERPAGEPF1 - S_QUEUESPERPAGEPF0) * pf); 2206af45170SJohn Baldwin sp->eq_s_qpp = ((vals[0] >> s_qpp) & M_QUEUESPERPAGEPF0); 2216af45170SJohn Baldwin sp->iq_s_qpp = ((vals[1] >> s_qpp) & M_QUEUESPERPAGEPF0); 2226af45170SJohn Baldwin } 2236af45170SJohn Baldwin 2246af45170SJohn Baldwin return 0; 2256af45170SJohn Baldwin } 2266af45170SJohn Baldwin 2276af45170SJohn Baldwin /** 2286af45170SJohn Baldwin * t4vf_get_rss_glb_config - retrieve adapter RSS Global Configuration 2296af45170SJohn Baldwin * @adapter: the adapter 2306af45170SJohn Baldwin * 2316af45170SJohn Baldwin * Retrieves global RSS mode and parameters with which we have to live 2326af45170SJohn Baldwin * and stores them in the @adapter's RSS parameters. 2336af45170SJohn Baldwin */ 2346af45170SJohn Baldwin int t4vf_get_rss_glb_config(struct adapter *adapter) 2356af45170SJohn Baldwin { 2366af45170SJohn Baldwin struct rss_params *rss = &adapter->params.rss; 2376af45170SJohn Baldwin struct fw_rss_glb_config_cmd cmd, rpl; 2386af45170SJohn Baldwin int v; 2396af45170SJohn Baldwin 2406af45170SJohn Baldwin /* 2416af45170SJohn Baldwin * Execute an RSS Global Configuration read command to retrieve 2426af45170SJohn Baldwin * our RSS configuration. 2436af45170SJohn Baldwin */ 2446af45170SJohn Baldwin memset(&cmd, 0, sizeof(cmd)); 2456af45170SJohn Baldwin cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_RSS_GLB_CONFIG_CMD) | 2466af45170SJohn Baldwin F_FW_CMD_REQUEST | 2476af45170SJohn Baldwin F_FW_CMD_READ); 2486af45170SJohn Baldwin cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); 2496af45170SJohn Baldwin v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl); 2506af45170SJohn Baldwin if (v != FW_SUCCESS) 2516af45170SJohn Baldwin return v; 2526af45170SJohn Baldwin 2536af45170SJohn Baldwin /* 2546af45170SJohn Baldwin * Transate the big-endian RSS Global Configuration into our 2556af45170SJohn Baldwin * cpu-endian format based on the RSS mode. We also do first level 2566af45170SJohn Baldwin * filtering at this point to weed out modes which don't support 2576af45170SJohn Baldwin * VF Drivers ... 2586af45170SJohn Baldwin */ 2596af45170SJohn Baldwin rss->mode = G_FW_RSS_GLB_CONFIG_CMD_MODE( 2606af45170SJohn Baldwin be32_to_cpu(rpl.u.manual.mode_pkd)); 2616af45170SJohn Baldwin switch (rss->mode) { 2626af45170SJohn Baldwin case FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL: { 2636af45170SJohn Baldwin u32 word = be32_to_cpu( 2646af45170SJohn Baldwin rpl.u.basicvirtual.synmapen_to_hashtoeplitz); 2656af45170SJohn Baldwin 2666af45170SJohn Baldwin rss->u.basicvirtual.synmapen = 2676af45170SJohn Baldwin ((word & F_FW_RSS_GLB_CONFIG_CMD_SYNMAPEN) != 0); 2686af45170SJohn Baldwin rss->u.basicvirtual.syn4tupenipv6 = 2696af45170SJohn Baldwin ((word & F_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6) != 0); 2706af45170SJohn Baldwin rss->u.basicvirtual.syn2tupenipv6 = 2716af45170SJohn Baldwin ((word & F_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6) != 0); 2726af45170SJohn Baldwin rss->u.basicvirtual.syn4tupenipv4 = 2736af45170SJohn Baldwin ((word & F_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4) != 0); 2746af45170SJohn Baldwin rss->u.basicvirtual.syn2tupenipv4 = 2756af45170SJohn Baldwin ((word & F_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4) != 0); 2766af45170SJohn Baldwin 2776af45170SJohn Baldwin rss->u.basicvirtual.ofdmapen = 2786af45170SJohn Baldwin ((word & F_FW_RSS_GLB_CONFIG_CMD_OFDMAPEN) != 0); 2796af45170SJohn Baldwin 2806af45170SJohn Baldwin rss->u.basicvirtual.tnlmapen = 2816af45170SJohn Baldwin ((word & F_FW_RSS_GLB_CONFIG_CMD_TNLMAPEN) != 0); 2826af45170SJohn Baldwin rss->u.basicvirtual.tnlalllookup = 2836af45170SJohn Baldwin ((word & F_FW_RSS_GLB_CONFIG_CMD_TNLALLLKP) != 0); 2846af45170SJohn Baldwin 2856af45170SJohn Baldwin rss->u.basicvirtual.hashtoeplitz = 2866af45170SJohn Baldwin ((word & F_FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ) != 0); 2876af45170SJohn Baldwin 2886af45170SJohn Baldwin /* we need at least Tunnel Map Enable to be set */ 2896af45170SJohn Baldwin if (!rss->u.basicvirtual.tnlmapen) 2906af45170SJohn Baldwin return -EINVAL; 2916af45170SJohn Baldwin break; 2926af45170SJohn Baldwin } 2936af45170SJohn Baldwin 2946af45170SJohn Baldwin default: 2956af45170SJohn Baldwin /* all unknown/unsupported RSS modes result in an error */ 2966af45170SJohn Baldwin return -EINVAL; 2976af45170SJohn Baldwin } 2986af45170SJohn Baldwin 2996af45170SJohn Baldwin return 0; 3006af45170SJohn Baldwin } 3016af45170SJohn Baldwin 3026af45170SJohn Baldwin /** 3036af45170SJohn Baldwin * t4vf_get_vfres - retrieve VF resource limits 3046af45170SJohn Baldwin * @adapter: the adapter 3056af45170SJohn Baldwin * 3066af45170SJohn Baldwin * Retrieves configured resource limits and capabilities for a virtual 3076af45170SJohn Baldwin * function. The results are stored in @adapter->vfres. 3086af45170SJohn Baldwin */ 3096af45170SJohn Baldwin int t4vf_get_vfres(struct adapter *adapter) 3106af45170SJohn Baldwin { 3116af45170SJohn Baldwin struct vf_resources *vfres = &adapter->params.vfres; 3126af45170SJohn Baldwin struct fw_pfvf_cmd cmd, rpl; 3136af45170SJohn Baldwin int v; 3146af45170SJohn Baldwin u32 word; 3156af45170SJohn Baldwin 3166af45170SJohn Baldwin /* 3176af45170SJohn Baldwin * Execute PFVF Read command to get VF resource limits; bail out early 3186af45170SJohn Baldwin * with error on command failure. 3196af45170SJohn Baldwin */ 3206af45170SJohn Baldwin memset(&cmd, 0, sizeof(cmd)); 3216af45170SJohn Baldwin cmd.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_PFVF_CMD) | 3226af45170SJohn Baldwin F_FW_CMD_REQUEST | 3236af45170SJohn Baldwin F_FW_CMD_READ); 3246af45170SJohn Baldwin cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); 3256af45170SJohn Baldwin v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl); 3266af45170SJohn Baldwin if (v != FW_SUCCESS) 3276af45170SJohn Baldwin return v; 3286af45170SJohn Baldwin 3296af45170SJohn Baldwin /* 3306af45170SJohn Baldwin * Extract VF resource limits and return success. 3316af45170SJohn Baldwin */ 3326af45170SJohn Baldwin word = be32_to_cpu(rpl.niqflint_niq); 3336af45170SJohn Baldwin vfres->niqflint = G_FW_PFVF_CMD_NIQFLINT(word); 3346af45170SJohn Baldwin vfres->niq = G_FW_PFVF_CMD_NIQ(word); 3356af45170SJohn Baldwin 3366af45170SJohn Baldwin word = be32_to_cpu(rpl.type_to_neq); 3376af45170SJohn Baldwin vfres->neq = G_FW_PFVF_CMD_NEQ(word); 3386af45170SJohn Baldwin vfres->pmask = G_FW_PFVF_CMD_PMASK(word); 3396af45170SJohn Baldwin 3406af45170SJohn Baldwin word = be32_to_cpu(rpl.tc_to_nexactf); 3416af45170SJohn Baldwin vfres->tc = G_FW_PFVF_CMD_TC(word); 3426af45170SJohn Baldwin vfres->nvi = G_FW_PFVF_CMD_NVI(word); 3436af45170SJohn Baldwin vfres->nexactf = G_FW_PFVF_CMD_NEXACTF(word); 3446af45170SJohn Baldwin 3456af45170SJohn Baldwin word = be32_to_cpu(rpl.r_caps_to_nethctrl); 3466af45170SJohn Baldwin vfres->r_caps = G_FW_PFVF_CMD_R_CAPS(word); 3476af45170SJohn Baldwin vfres->wx_caps = G_FW_PFVF_CMD_WX_CAPS(word); 3486af45170SJohn Baldwin vfres->nethctrl = G_FW_PFVF_CMD_NETHCTRL(word); 3496af45170SJohn Baldwin 3506af45170SJohn Baldwin return 0; 3516af45170SJohn Baldwin } 3526af45170SJohn Baldwin 3536af45170SJohn Baldwin /** 3546af45170SJohn Baldwin */ 3556af45170SJohn Baldwin int t4vf_prep_adapter(struct adapter *adapter) 3566af45170SJohn Baldwin { 3576af45170SJohn Baldwin int err; 3586af45170SJohn Baldwin 3596af45170SJohn Baldwin /* 3606af45170SJohn Baldwin * Wait for the device to become ready before proceeding ... 3616af45170SJohn Baldwin */ 3626af45170SJohn Baldwin err = t4vf_wait_dev_ready(adapter); 3636af45170SJohn Baldwin if (err) 3646af45170SJohn Baldwin return err; 3656af45170SJohn Baldwin 3666af45170SJohn Baldwin adapter->params.chipid = pci_get_device(adapter->dev) >> 12; 3676af45170SJohn Baldwin if (adapter->params.chipid >= 0xa) { 3686af45170SJohn Baldwin adapter->params.chipid -= (0xa - 0x4); 3696af45170SJohn Baldwin adapter->params.fpga = 1; 3706af45170SJohn Baldwin } 3716af45170SJohn Baldwin 3726af45170SJohn Baldwin /* 3736af45170SJohn Baldwin * Default port and clock for debugging in case we can't reach 3746af45170SJohn Baldwin * firmware. 3756af45170SJohn Baldwin */ 3766af45170SJohn Baldwin adapter->params.nports = 1; 3776af45170SJohn Baldwin adapter->params.vfres.pmask = 1; 3786af45170SJohn Baldwin adapter->params.vpd.cclk = 50000; 3796af45170SJohn Baldwin 3806af45170SJohn Baldwin adapter->chip_params = t4_get_chip_params(chip_id(adapter)); 3816af45170SJohn Baldwin if (adapter->chip_params == NULL) 3826af45170SJohn Baldwin return -EINVAL; 3836af45170SJohn Baldwin 3846af45170SJohn Baldwin return 0; 3856af45170SJohn Baldwin } 386dc0800a9SNavdeep Parhar 387dc0800a9SNavdeep Parhar /* 388dc0800a9SNavdeep Parhar * t4vf_get_vf_mac - Get the MAC address to be set to the VI of this VF. 389dc0800a9SNavdeep Parhar * @adapter: The adapter 390dc0800a9SNavdeep Parhar * @port: The port associated with vf 391dc0800a9SNavdeep Parhar * @naddr: the number of ACL MAC addresses returned in addr 392dc0800a9SNavdeep Parhar * @addr: Placeholder for MAC addresses 393dc0800a9SNavdeep Parhar * 394dc0800a9SNavdeep Parhar * Find the MAC address to be set to the VF's VI. The requested MAC address 395dc0800a9SNavdeep Parhar * is from the host OS via callback in the PF driver. 396dc0800a9SNavdeep Parhar */ 397dc0800a9SNavdeep Parhar int t4vf_get_vf_mac(struct adapter *adapter, unsigned int port, 398dc0800a9SNavdeep Parhar unsigned int *naddr, u8 *addr) 399dc0800a9SNavdeep Parhar { 400dc0800a9SNavdeep Parhar struct fw_acl_mac_cmd cmd; 401dc0800a9SNavdeep Parhar int ret; 402dc0800a9SNavdeep Parhar 403dc0800a9SNavdeep Parhar memset(&cmd, 0, sizeof(cmd)); 404dc0800a9SNavdeep Parhar cmd.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_ACL_MAC_CMD) | 405dc0800a9SNavdeep Parhar F_FW_CMD_REQUEST | 406dc0800a9SNavdeep Parhar F_FW_CMD_READ); 407dc0800a9SNavdeep Parhar cmd.en_to_len16 = cpu_to_be32((unsigned int)FW_LEN16(cmd)); 408dc0800a9SNavdeep Parhar ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &cmd); 409dc0800a9SNavdeep Parhar if (ret) 410dc0800a9SNavdeep Parhar return ret; 411dc0800a9SNavdeep Parhar 412dc0800a9SNavdeep Parhar if (cmd.nmac < *naddr) 413dc0800a9SNavdeep Parhar *naddr = cmd.nmac; 414dc0800a9SNavdeep Parhar 415dc0800a9SNavdeep Parhar switch (port) { 416dc0800a9SNavdeep Parhar case 3: 417dc0800a9SNavdeep Parhar memcpy(addr, cmd.macaddr3, sizeof(cmd.macaddr3)); 418dc0800a9SNavdeep Parhar break; 419dc0800a9SNavdeep Parhar case 2: 420dc0800a9SNavdeep Parhar memcpy(addr, cmd.macaddr2, sizeof(cmd.macaddr2)); 421dc0800a9SNavdeep Parhar break; 422dc0800a9SNavdeep Parhar case 1: 423dc0800a9SNavdeep Parhar memcpy(addr, cmd.macaddr1, sizeof(cmd.macaddr1)); 424dc0800a9SNavdeep Parhar break; 425dc0800a9SNavdeep Parhar case 0: 426dc0800a9SNavdeep Parhar memcpy(addr, cmd.macaddr0, sizeof(cmd.macaddr0)); 427dc0800a9SNavdeep Parhar break; 428dc0800a9SNavdeep Parhar } 429dc0800a9SNavdeep Parhar 430dc0800a9SNavdeep Parhar return ret; 431dc0800a9SNavdeep Parhar } 432