1*f173c2b7SSean Bruno /* 2*f173c2b7SSean Bruno * BSD LICENSE 3*f173c2b7SSean Bruno * 4*f173c2b7SSean Bruno * Copyright(c) 2017 Cavium, Inc.. All rights reserved. 5*f173c2b7SSean Bruno * All rights reserved. 6*f173c2b7SSean Bruno * 7*f173c2b7SSean Bruno * Redistribution and use in source and binary forms, with or without 8*f173c2b7SSean Bruno * modification, are permitted provided that the following conditions 9*f173c2b7SSean Bruno * are met: 10*f173c2b7SSean Bruno * 11*f173c2b7SSean Bruno * * Redistributions of source code must retain the above copyright 12*f173c2b7SSean Bruno * notice, this list of conditions and the following disclaimer. 13*f173c2b7SSean Bruno * * Redistributions in binary form must reproduce the above copyright 14*f173c2b7SSean Bruno * notice, this list of conditions and the following disclaimer in 15*f173c2b7SSean Bruno * the documentation and/or other materials provided with the 16*f173c2b7SSean Bruno * distribution. 17*f173c2b7SSean Bruno * * Neither the name of Cavium, Inc. nor the names of its 18*f173c2b7SSean Bruno * contributors may be used to endorse or promote products derived 19*f173c2b7SSean Bruno * from this software without specific prior written permission. 20*f173c2b7SSean Bruno * 21*f173c2b7SSean Bruno * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22*f173c2b7SSean Bruno * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23*f173c2b7SSean Bruno * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24*f173c2b7SSean Bruno * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25*f173c2b7SSean Bruno * OWNER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26*f173c2b7SSean Bruno * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27*f173c2b7SSean Bruno * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28*f173c2b7SSean Bruno * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29*f173c2b7SSean Bruno * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30*f173c2b7SSean Bruno * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31*f173c2b7SSean Bruno * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32*f173c2b7SSean Bruno */ 33*f173c2b7SSean Bruno /*$FreeBSD$*/ 34*f173c2b7SSean Bruno 35*f173c2b7SSean Bruno #include "lio_bsd.h" 36*f173c2b7SSean Bruno #include "lio_common.h" 37*f173c2b7SSean Bruno #include "lio_droq.h" 38*f173c2b7SSean Bruno #include "lio_iq.h" 39*f173c2b7SSean Bruno #include "lio_response_manager.h" 40*f173c2b7SSean Bruno #include "lio_device.h" 41*f173c2b7SSean Bruno #include "cn23xx_pf_device.h" 42*f173c2b7SSean Bruno #include "lio_main.h" 43*f173c2b7SSean Bruno #include "lio_rss.h" 44*f173c2b7SSean Bruno 45*f173c2b7SSean Bruno static int 46*f173c2b7SSean Bruno lio_cn23xx_pf_soft_reset(struct octeon_device *oct) 47*f173c2b7SSean Bruno { 48*f173c2b7SSean Bruno 49*f173c2b7SSean Bruno lio_write_csr64(oct, LIO_CN23XX_SLI_WIN_WR_MASK_REG, 0xFF); 50*f173c2b7SSean Bruno 51*f173c2b7SSean Bruno lio_dev_dbg(oct, "BIST enabled for CN23XX soft reset\n"); 52*f173c2b7SSean Bruno 53*f173c2b7SSean Bruno lio_write_csr64(oct, LIO_CN23XX_SLI_SCRATCH1, 0x1234ULL); 54*f173c2b7SSean Bruno 55*f173c2b7SSean Bruno /* Initiate chip-wide soft reset */ 56*f173c2b7SSean Bruno lio_pci_readq(oct, LIO_CN23XX_RST_SOFT_RST); 57*f173c2b7SSean Bruno lio_pci_writeq(oct, 1, LIO_CN23XX_RST_SOFT_RST); 58*f173c2b7SSean Bruno 59*f173c2b7SSean Bruno /* Wait for 100ms as Octeon resets. */ 60*f173c2b7SSean Bruno lio_mdelay(100); 61*f173c2b7SSean Bruno 62*f173c2b7SSean Bruno if (lio_read_csr64(oct, LIO_CN23XX_SLI_SCRATCH1)) { 63*f173c2b7SSean Bruno lio_dev_err(oct, "Soft reset failed\n"); 64*f173c2b7SSean Bruno return (1); 65*f173c2b7SSean Bruno } 66*f173c2b7SSean Bruno 67*f173c2b7SSean Bruno lio_dev_dbg(oct, "Reset completed\n"); 68*f173c2b7SSean Bruno 69*f173c2b7SSean Bruno /* restore the reset value */ 70*f173c2b7SSean Bruno lio_write_csr64(oct, LIO_CN23XX_SLI_WIN_WR_MASK_REG, 0xFF); 71*f173c2b7SSean Bruno 72*f173c2b7SSean Bruno return (0); 73*f173c2b7SSean Bruno } 74*f173c2b7SSean Bruno 75*f173c2b7SSean Bruno static void 76*f173c2b7SSean Bruno lio_cn23xx_pf_enable_error_reporting(struct octeon_device *oct) 77*f173c2b7SSean Bruno { 78*f173c2b7SSean Bruno uint32_t corrtable_err_status, uncorrectable_err_mask, regval; 79*f173c2b7SSean Bruno 80*f173c2b7SSean Bruno regval = lio_read_pci_cfg(oct, LIO_CN23XX_CFG_PCIE_DEVCTL); 81*f173c2b7SSean Bruno if (regval & LIO_CN23XX_CFG_PCIE_DEVCTL_MASK) { 82*f173c2b7SSean Bruno uncorrectable_err_mask = 0; 83*f173c2b7SSean Bruno corrtable_err_status = 0; 84*f173c2b7SSean Bruno uncorrectable_err_mask = 85*f173c2b7SSean Bruno lio_read_pci_cfg(oct, 86*f173c2b7SSean Bruno LIO_CN23XX_CFG_PCIE_UNCORRECT_ERR_MASK); 87*f173c2b7SSean Bruno corrtable_err_status = 88*f173c2b7SSean Bruno lio_read_pci_cfg(oct, 89*f173c2b7SSean Bruno LIO_CN23XX_CFG_PCIE_CORRECT_ERR_STATUS); 90*f173c2b7SSean Bruno lio_dev_err(oct, "PCI-E Fatal error detected;\n" 91*f173c2b7SSean Bruno "\tdev_ctl_status_reg = 0x%08x\n" 92*f173c2b7SSean Bruno "\tuncorrectable_error_mask_reg = 0x%08x\n" 93*f173c2b7SSean Bruno "\tcorrectable_error_status_reg = 0x%08x\n", 94*f173c2b7SSean Bruno regval, uncorrectable_err_mask, 95*f173c2b7SSean Bruno corrtable_err_status); 96*f173c2b7SSean Bruno } 97*f173c2b7SSean Bruno 98*f173c2b7SSean Bruno regval |= 0xf; /* Enable Link error reporting */ 99*f173c2b7SSean Bruno 100*f173c2b7SSean Bruno lio_dev_dbg(oct, "Enabling PCI-E error reporting..\n"); 101*f173c2b7SSean Bruno lio_write_pci_cfg(oct, LIO_CN23XX_CFG_PCIE_DEVCTL, regval); 102*f173c2b7SSean Bruno } 103*f173c2b7SSean Bruno 104*f173c2b7SSean Bruno static uint32_t 105*f173c2b7SSean Bruno lio_cn23xx_pf_coprocessor_clock(struct octeon_device *oct) 106*f173c2b7SSean Bruno { 107*f173c2b7SSean Bruno /* 108*f173c2b7SSean Bruno * Bits 29:24 of RST_BOOT[PNR_MUL] holds the ref.clock MULTIPLIER 109*f173c2b7SSean Bruno * for SLI. 110*f173c2b7SSean Bruno */ 111*f173c2b7SSean Bruno 112*f173c2b7SSean Bruno /* TBD: get the info in Hand-shake */ 113*f173c2b7SSean Bruno return (((lio_pci_readq(oct, LIO_CN23XX_RST_BOOT) >> 24) & 0x3f) * 50); 114*f173c2b7SSean Bruno } 115*f173c2b7SSean Bruno 116*f173c2b7SSean Bruno uint32_t 117*f173c2b7SSean Bruno lio_cn23xx_pf_get_oq_ticks(struct octeon_device *oct, uint32_t time_intr_in_us) 118*f173c2b7SSean Bruno { 119*f173c2b7SSean Bruno /* This gives the SLI clock per microsec */ 120*f173c2b7SSean Bruno uint32_t oqticks_per_us = lio_cn23xx_pf_coprocessor_clock(oct); 121*f173c2b7SSean Bruno 122*f173c2b7SSean Bruno oct->pfvf_hsword.coproc_tics_per_us = oqticks_per_us; 123*f173c2b7SSean Bruno 124*f173c2b7SSean Bruno /* This gives the clock cycles per millisecond */ 125*f173c2b7SSean Bruno oqticks_per_us *= 1000; 126*f173c2b7SSean Bruno 127*f173c2b7SSean Bruno /* This gives the oq ticks (1024 core clock cycles) per millisecond */ 128*f173c2b7SSean Bruno oqticks_per_us /= 1024; 129*f173c2b7SSean Bruno 130*f173c2b7SSean Bruno /* 131*f173c2b7SSean Bruno * time_intr is in microseconds. The next 2 steps gives the oq ticks 132*f173c2b7SSean Bruno * corresponding to time_intr. 133*f173c2b7SSean Bruno */ 134*f173c2b7SSean Bruno oqticks_per_us *= time_intr_in_us; 135*f173c2b7SSean Bruno oqticks_per_us /= 1000; 136*f173c2b7SSean Bruno 137*f173c2b7SSean Bruno return (oqticks_per_us); 138*f173c2b7SSean Bruno } 139*f173c2b7SSean Bruno 140*f173c2b7SSean Bruno static void 141*f173c2b7SSean Bruno lio_cn23xx_pf_setup_global_mac_regs(struct octeon_device *oct) 142*f173c2b7SSean Bruno { 143*f173c2b7SSean Bruno uint64_t reg_val; 144*f173c2b7SSean Bruno uint16_t mac_no = oct->pcie_port; 145*f173c2b7SSean Bruno uint16_t pf_num = oct->pf_num; 146*f173c2b7SSean Bruno /* programming SRN and TRS for each MAC(0..3) */ 147*f173c2b7SSean Bruno 148*f173c2b7SSean Bruno lio_dev_dbg(oct, "%s: Using pcie port %d\n", __func__, mac_no); 149*f173c2b7SSean Bruno /* By default, mapping all 64 IOQs to a single MACs */ 150*f173c2b7SSean Bruno 151*f173c2b7SSean Bruno reg_val = 152*f173c2b7SSean Bruno lio_read_csr64(oct, LIO_CN23XX_SLI_PKT_MAC_RINFO64(mac_no, pf_num)); 153*f173c2b7SSean Bruno 154*f173c2b7SSean Bruno /* setting SRN <6:0> */ 155*f173c2b7SSean Bruno reg_val = pf_num * LIO_CN23XX_PF_MAX_RINGS; 156*f173c2b7SSean Bruno 157*f173c2b7SSean Bruno /* setting TRS <23:16> */ 158*f173c2b7SSean Bruno reg_val = reg_val | 159*f173c2b7SSean Bruno (oct->sriov_info.trs << LIO_CN23XX_PKT_MAC_CTL_RINFO_TRS_BIT_POS); 160*f173c2b7SSean Bruno 161*f173c2b7SSean Bruno /* write these settings to MAC register */ 162*f173c2b7SSean Bruno lio_write_csr64(oct, LIO_CN23XX_SLI_PKT_MAC_RINFO64(mac_no, pf_num), 163*f173c2b7SSean Bruno reg_val); 164*f173c2b7SSean Bruno 165*f173c2b7SSean Bruno lio_dev_dbg(oct, "SLI_PKT_MAC(%d)_PF(%d)_RINFO : 0x%016lx\n", mac_no, 166*f173c2b7SSean Bruno pf_num, 167*f173c2b7SSean Bruno lio_read_csr64(oct, 168*f173c2b7SSean Bruno LIO_CN23XX_SLI_PKT_MAC_RINFO64(mac_no, 169*f173c2b7SSean Bruno pf_num))); 170*f173c2b7SSean Bruno } 171*f173c2b7SSean Bruno 172*f173c2b7SSean Bruno static int 173*f173c2b7SSean Bruno lio_cn23xx_pf_reset_io_queues(struct octeon_device *oct) 174*f173c2b7SSean Bruno { 175*f173c2b7SSean Bruno uint64_t d64; 176*f173c2b7SSean Bruno uint32_t ern, loop = BUSY_READING_REG_PF_LOOP_COUNT; 177*f173c2b7SSean Bruno uint32_t q_no, srn; 178*f173c2b7SSean Bruno int ret_val = 0; 179*f173c2b7SSean Bruno 180*f173c2b7SSean Bruno srn = oct->sriov_info.pf_srn; 181*f173c2b7SSean Bruno ern = srn + oct->sriov_info.num_pf_rings; 182*f173c2b7SSean Bruno 183*f173c2b7SSean Bruno /* As per HRM reg description, s/w cant write 0 to ENB. */ 184*f173c2b7SSean Bruno /* to make the queue off, need to set the RST bit. */ 185*f173c2b7SSean Bruno 186*f173c2b7SSean Bruno /* Reset the Enable bit for all the 64 IQs. */ 187*f173c2b7SSean Bruno for (q_no = srn; q_no < ern; q_no++) { 188*f173c2b7SSean Bruno /* set RST bit to 1. This bit applies to both IQ and OQ */ 189*f173c2b7SSean Bruno d64 = lio_read_csr64(oct, 190*f173c2b7SSean Bruno LIO_CN23XX_SLI_IQ_PKT_CONTROL64(q_no)); 191*f173c2b7SSean Bruno d64 = d64 | LIO_CN23XX_PKT_INPUT_CTL_RST; 192*f173c2b7SSean Bruno lio_write_csr64(oct, 193*f173c2b7SSean Bruno LIO_CN23XX_SLI_IQ_PKT_CONTROL64(q_no), d64); 194*f173c2b7SSean Bruno } 195*f173c2b7SSean Bruno 196*f173c2b7SSean Bruno /* wait until the RST bit is clear or the RST and quiet bits are set */ 197*f173c2b7SSean Bruno for (q_no = srn; q_no < ern; q_no++) { 198*f173c2b7SSean Bruno volatile uint64_t reg_val = 199*f173c2b7SSean Bruno lio_read_csr64(oct, 200*f173c2b7SSean Bruno LIO_CN23XX_SLI_IQ_PKT_CONTROL64(q_no)); 201*f173c2b7SSean Bruno while ((reg_val & LIO_CN23XX_PKT_INPUT_CTL_RST) && 202*f173c2b7SSean Bruno !(reg_val & LIO_CN23XX_PKT_INPUT_CTL_QUIET) && 203*f173c2b7SSean Bruno loop) { 204*f173c2b7SSean Bruno reg_val = lio_read_csr64(oct, 205*f173c2b7SSean Bruno LIO_CN23XX_SLI_IQ_PKT_CONTROL64(q_no)); 206*f173c2b7SSean Bruno loop--; 207*f173c2b7SSean Bruno } 208*f173c2b7SSean Bruno 209*f173c2b7SSean Bruno if (!loop) { 210*f173c2b7SSean Bruno lio_dev_err(oct, 211*f173c2b7SSean Bruno "clearing the reset reg failed or setting the quiet reg failed for qno: %u\n", 212*f173c2b7SSean Bruno q_no); 213*f173c2b7SSean Bruno return (-1); 214*f173c2b7SSean Bruno } 215*f173c2b7SSean Bruno 216*f173c2b7SSean Bruno reg_val &= ~LIO_CN23XX_PKT_INPUT_CTL_RST; 217*f173c2b7SSean Bruno lio_write_csr64(oct, LIO_CN23XX_SLI_IQ_PKT_CONTROL64(q_no), 218*f173c2b7SSean Bruno reg_val); 219*f173c2b7SSean Bruno 220*f173c2b7SSean Bruno reg_val = lio_read_csr64(oct, 221*f173c2b7SSean Bruno LIO_CN23XX_SLI_IQ_PKT_CONTROL64(q_no)); 222*f173c2b7SSean Bruno if (reg_val & LIO_CN23XX_PKT_INPUT_CTL_RST) { 223*f173c2b7SSean Bruno lio_dev_err(oct, "clearing the reset failed for qno: %u\n", 224*f173c2b7SSean Bruno q_no); 225*f173c2b7SSean Bruno ret_val = -1; 226*f173c2b7SSean Bruno } 227*f173c2b7SSean Bruno } 228*f173c2b7SSean Bruno 229*f173c2b7SSean Bruno return (ret_val); 230*f173c2b7SSean Bruno } 231*f173c2b7SSean Bruno 232*f173c2b7SSean Bruno static int 233*f173c2b7SSean Bruno lio_cn23xx_pf_setup_global_input_regs(struct octeon_device *oct) 234*f173c2b7SSean Bruno { 235*f173c2b7SSean Bruno struct lio_cn23xx_pf *cn23xx = (struct lio_cn23xx_pf *)oct->chip; 236*f173c2b7SSean Bruno struct lio_instr_queue *iq; 237*f173c2b7SSean Bruno uint64_t intr_threshold; 238*f173c2b7SSean Bruno uint64_t pf_num, reg_val; 239*f173c2b7SSean Bruno uint32_t q_no, ern, srn; 240*f173c2b7SSean Bruno 241*f173c2b7SSean Bruno pf_num = oct->pf_num; 242*f173c2b7SSean Bruno 243*f173c2b7SSean Bruno srn = oct->sriov_info.pf_srn; 244*f173c2b7SSean Bruno ern = srn + oct->sriov_info.num_pf_rings; 245*f173c2b7SSean Bruno 246*f173c2b7SSean Bruno if (lio_cn23xx_pf_reset_io_queues(oct)) 247*f173c2b7SSean Bruno return (-1); 248*f173c2b7SSean Bruno 249*f173c2b7SSean Bruno /* 250*f173c2b7SSean Bruno * Set the MAC_NUM and PVF_NUM in IQ_PKT_CONTROL reg 251*f173c2b7SSean Bruno * for all queues.Only PF can set these bits. 252*f173c2b7SSean Bruno * bits 29:30 indicate the MAC num. 253*f173c2b7SSean Bruno * bits 32:47 indicate the PVF num. 254*f173c2b7SSean Bruno */ 255*f173c2b7SSean Bruno for (q_no = 0; q_no < ern; q_no++) { 256*f173c2b7SSean Bruno reg_val = oct->pcie_port << 257*f173c2b7SSean Bruno LIO_CN23XX_PKT_INPUT_CTL_MAC_NUM_POS; 258*f173c2b7SSean Bruno 259*f173c2b7SSean Bruno reg_val |= pf_num << LIO_CN23XX_PKT_INPUT_CTL_PF_NUM_POS; 260*f173c2b7SSean Bruno 261*f173c2b7SSean Bruno lio_write_csr64(oct, LIO_CN23XX_SLI_IQ_PKT_CONTROL64(q_no), 262*f173c2b7SSean Bruno reg_val); 263*f173c2b7SSean Bruno } 264*f173c2b7SSean Bruno 265*f173c2b7SSean Bruno /* 266*f173c2b7SSean Bruno * Select ES, RO, NS, RDSIZE,DPTR Fomat#0 for 267*f173c2b7SSean Bruno * pf queues 268*f173c2b7SSean Bruno */ 269*f173c2b7SSean Bruno for (q_no = srn; q_no < ern; q_no++) { 270*f173c2b7SSean Bruno uint32_t inst_cnt_reg; 271*f173c2b7SSean Bruno 272*f173c2b7SSean Bruno iq = oct->instr_queue[q_no]; 273*f173c2b7SSean Bruno if (iq != NULL) 274*f173c2b7SSean Bruno inst_cnt_reg = iq->inst_cnt_reg; 275*f173c2b7SSean Bruno else 276*f173c2b7SSean Bruno inst_cnt_reg = LIO_CN23XX_SLI_IQ_INSTR_COUNT64(q_no); 277*f173c2b7SSean Bruno 278*f173c2b7SSean Bruno reg_val = 279*f173c2b7SSean Bruno lio_read_csr64(oct, LIO_CN23XX_SLI_IQ_PKT_CONTROL64(q_no)); 280*f173c2b7SSean Bruno 281*f173c2b7SSean Bruno reg_val |= LIO_CN23XX_PKT_INPUT_CTL_MASK; 282*f173c2b7SSean Bruno 283*f173c2b7SSean Bruno lio_write_csr64(oct, LIO_CN23XX_SLI_IQ_PKT_CONTROL64(q_no), 284*f173c2b7SSean Bruno reg_val); 285*f173c2b7SSean Bruno 286*f173c2b7SSean Bruno /* Set WMARK level for triggering PI_INT */ 287*f173c2b7SSean Bruno /* intr_threshold = LIO_CN23XX_DEF_IQ_INTR_THRESHOLD & */ 288*f173c2b7SSean Bruno intr_threshold = LIO_GET_IQ_INTR_PKT_CFG(cn23xx->conf) & 289*f173c2b7SSean Bruno LIO_CN23XX_PKT_IN_DONE_WMARK_MASK; 290*f173c2b7SSean Bruno 291*f173c2b7SSean Bruno lio_write_csr64(oct, inst_cnt_reg, 292*f173c2b7SSean Bruno (lio_read_csr64(oct, inst_cnt_reg) & 293*f173c2b7SSean Bruno ~(LIO_CN23XX_PKT_IN_DONE_WMARK_MASK << 294*f173c2b7SSean Bruno LIO_CN23XX_PKT_IN_DONE_WMARK_BIT_POS)) | 295*f173c2b7SSean Bruno (intr_threshold << 296*f173c2b7SSean Bruno LIO_CN23XX_PKT_IN_DONE_WMARK_BIT_POS)); 297*f173c2b7SSean Bruno } 298*f173c2b7SSean Bruno return (0); 299*f173c2b7SSean Bruno } 300*f173c2b7SSean Bruno 301*f173c2b7SSean Bruno static void 302*f173c2b7SSean Bruno lio_cn23xx_pf_setup_global_output_regs(struct octeon_device *oct) 303*f173c2b7SSean Bruno { 304*f173c2b7SSean Bruno struct lio_cn23xx_pf *cn23xx = (struct lio_cn23xx_pf *)oct->chip; 305*f173c2b7SSean Bruno uint64_t time_threshold; 306*f173c2b7SSean Bruno uint32_t ern, q_no, reg_val, srn; 307*f173c2b7SSean Bruno 308*f173c2b7SSean Bruno srn = oct->sriov_info.pf_srn; 309*f173c2b7SSean Bruno ern = srn + oct->sriov_info.num_pf_rings; 310*f173c2b7SSean Bruno 311*f173c2b7SSean Bruno if (LIO_GET_IS_SLI_BP_ON_CFG(cn23xx->conf)) { 312*f173c2b7SSean Bruno lio_write_csr64(oct, LIO_CN23XX_SLI_OQ_WMARK, 32); 313*f173c2b7SSean Bruno } else { 314*f173c2b7SSean Bruno /* Set Output queue watermark to 0 to disable backpressure */ 315*f173c2b7SSean Bruno lio_write_csr64(oct, LIO_CN23XX_SLI_OQ_WMARK, 0); 316*f173c2b7SSean Bruno } 317*f173c2b7SSean Bruno 318*f173c2b7SSean Bruno for (q_no = srn; q_no < ern; q_no++) { 319*f173c2b7SSean Bruno reg_val = lio_read_csr32(oct, 320*f173c2b7SSean Bruno LIO_CN23XX_SLI_OQ_PKT_CONTROL(q_no)); 321*f173c2b7SSean Bruno 322*f173c2b7SSean Bruno /* set IPTR & DPTR */ 323*f173c2b7SSean Bruno reg_val |= LIO_CN23XX_PKT_OUTPUT_CTL_DPTR; 324*f173c2b7SSean Bruno 325*f173c2b7SSean Bruno /* reset BMODE */ 326*f173c2b7SSean Bruno reg_val &= ~(LIO_CN23XX_PKT_OUTPUT_CTL_BMODE); 327*f173c2b7SSean Bruno 328*f173c2b7SSean Bruno /* 329*f173c2b7SSean Bruno * No Relaxed Ordering, No Snoop, 64-bit Byte swap for 330*f173c2b7SSean Bruno * Output Queue ScatterList reset ROR_P, NSR_P 331*f173c2b7SSean Bruno */ 332*f173c2b7SSean Bruno reg_val &= ~(LIO_CN23XX_PKT_OUTPUT_CTL_ROR_P); 333*f173c2b7SSean Bruno reg_val &= ~(LIO_CN23XX_PKT_OUTPUT_CTL_NSR_P); 334*f173c2b7SSean Bruno 335*f173c2b7SSean Bruno #if BYTE_ORDER == LITTLE_ENDIAN 336*f173c2b7SSean Bruno reg_val &= ~(LIO_CN23XX_PKT_OUTPUT_CTL_ES_P); 337*f173c2b7SSean Bruno #else /* BYTE_ORDER != LITTLE_ENDIAN */ 338*f173c2b7SSean Bruno reg_val |= (LIO_CN23XX_PKT_OUTPUT_CTL_ES_P); 339*f173c2b7SSean Bruno #endif /* BYTE_ORDER == LITTLE_ENDIAN */ 340*f173c2b7SSean Bruno 341*f173c2b7SSean Bruno /* 342*f173c2b7SSean Bruno * No Relaxed Ordering, No Snoop, 64-bit Byte swap for 343*f173c2b7SSean Bruno * Output Queue Data reset ROR, NSR 344*f173c2b7SSean Bruno */ 345*f173c2b7SSean Bruno reg_val &= ~(LIO_CN23XX_PKT_OUTPUT_CTL_ROR); 346*f173c2b7SSean Bruno reg_val &= ~(LIO_CN23XX_PKT_OUTPUT_CTL_NSR); 347*f173c2b7SSean Bruno /* set the ES bit */ 348*f173c2b7SSean Bruno reg_val |= (LIO_CN23XX_PKT_OUTPUT_CTL_ES); 349*f173c2b7SSean Bruno 350*f173c2b7SSean Bruno /* write all the selected settings */ 351*f173c2b7SSean Bruno lio_write_csr32(oct, LIO_CN23XX_SLI_OQ_PKT_CONTROL(q_no), 352*f173c2b7SSean Bruno reg_val); 353*f173c2b7SSean Bruno 354*f173c2b7SSean Bruno /* 355*f173c2b7SSean Bruno * Enabling these interrupt in oct->fn_list.enable_interrupt() 356*f173c2b7SSean Bruno * routine which called after IOQ init. 357*f173c2b7SSean Bruno * Set up interrupt packet and time thresholds 358*f173c2b7SSean Bruno * for all the OQs 359*f173c2b7SSean Bruno */ 360*f173c2b7SSean Bruno time_threshold =lio_cn23xx_pf_get_oq_ticks( 361*f173c2b7SSean Bruno oct, (uint32_t)LIO_GET_OQ_INTR_TIME_CFG(cn23xx->conf)); 362*f173c2b7SSean Bruno 363*f173c2b7SSean Bruno lio_write_csr64(oct, LIO_CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no), 364*f173c2b7SSean Bruno (LIO_GET_OQ_INTR_PKT_CFG(cn23xx->conf) | 365*f173c2b7SSean Bruno (time_threshold << 32))); 366*f173c2b7SSean Bruno } 367*f173c2b7SSean Bruno 368*f173c2b7SSean Bruno /* Setting the water mark level for pko back pressure * */ 369*f173c2b7SSean Bruno lio_write_csr64(oct, LIO_CN23XX_SLI_OQ_WMARK, 0x40); 370*f173c2b7SSean Bruno 371*f173c2b7SSean Bruno /* Enable channel-level backpressure */ 372*f173c2b7SSean Bruno if (oct->pf_num) 373*f173c2b7SSean Bruno lio_write_csr64(oct, LIO_CN23XX_SLI_OUT_BP_EN2_W1S, 374*f173c2b7SSean Bruno 0xffffffffffffffffULL); 375*f173c2b7SSean Bruno else 376*f173c2b7SSean Bruno lio_write_csr64(oct, LIO_CN23XX_SLI_OUT_BP_EN_W1S, 377*f173c2b7SSean Bruno 0xffffffffffffffffULL); 378*f173c2b7SSean Bruno } 379*f173c2b7SSean Bruno 380*f173c2b7SSean Bruno static int 381*f173c2b7SSean Bruno lio_cn23xx_pf_setup_device_regs(struct octeon_device *oct) 382*f173c2b7SSean Bruno { 383*f173c2b7SSean Bruno 384*f173c2b7SSean Bruno lio_cn23xx_pf_enable_error_reporting(oct); 385*f173c2b7SSean Bruno 386*f173c2b7SSean Bruno /* program the MAC(0..3)_RINFO before setting up input/output regs */ 387*f173c2b7SSean Bruno lio_cn23xx_pf_setup_global_mac_regs(oct); 388*f173c2b7SSean Bruno 389*f173c2b7SSean Bruno if (lio_cn23xx_pf_setup_global_input_regs(oct)) 390*f173c2b7SSean Bruno return (-1); 391*f173c2b7SSean Bruno 392*f173c2b7SSean Bruno lio_cn23xx_pf_setup_global_output_regs(oct); 393*f173c2b7SSean Bruno 394*f173c2b7SSean Bruno /* 395*f173c2b7SSean Bruno * Default error timeout value should be 0x200000 to avoid host hang 396*f173c2b7SSean Bruno * when reads invalid register 397*f173c2b7SSean Bruno */ 398*f173c2b7SSean Bruno lio_write_csr64(oct, LIO_CN23XX_SLI_WINDOW_CTL, 399*f173c2b7SSean Bruno LIO_CN23XX_SLI_WINDOW_CTL_DEFAULT); 400*f173c2b7SSean Bruno 401*f173c2b7SSean Bruno /* set SLI_PKT_IN_JABBER to handle large VXLAN packets */ 402*f173c2b7SSean Bruno lio_write_csr64(oct, LIO_CN23XX_SLI_PKT_IN_JABBER, 403*f173c2b7SSean Bruno LIO_CN23XX_MAX_INPUT_JABBER); 404*f173c2b7SSean Bruno return (0); 405*f173c2b7SSean Bruno } 406*f173c2b7SSean Bruno 407*f173c2b7SSean Bruno static void 408*f173c2b7SSean Bruno lio_cn23xx_pf_setup_iq_regs(struct octeon_device *oct, uint32_t iq_no) 409*f173c2b7SSean Bruno { 410*f173c2b7SSean Bruno struct lio_instr_queue *iq = oct->instr_queue[iq_no]; 411*f173c2b7SSean Bruno uint64_t pkt_in_done; 412*f173c2b7SSean Bruno 413*f173c2b7SSean Bruno iq_no += oct->sriov_info.pf_srn; 414*f173c2b7SSean Bruno 415*f173c2b7SSean Bruno /* Write the start of the input queue's ring and its size */ 416*f173c2b7SSean Bruno lio_write_csr64(oct, LIO_CN23XX_SLI_IQ_BASE_ADDR64(iq_no), 417*f173c2b7SSean Bruno iq->base_addr_dma); 418*f173c2b7SSean Bruno lio_write_csr32(oct, LIO_CN23XX_SLI_IQ_SIZE(iq_no), iq->max_count); 419*f173c2b7SSean Bruno 420*f173c2b7SSean Bruno /* 421*f173c2b7SSean Bruno * Remember the doorbell & instruction count register addr 422*f173c2b7SSean Bruno * for this queue 423*f173c2b7SSean Bruno */ 424*f173c2b7SSean Bruno iq->doorbell_reg = LIO_CN23XX_SLI_IQ_DOORBELL(iq_no); 425*f173c2b7SSean Bruno iq->inst_cnt_reg = LIO_CN23XX_SLI_IQ_INSTR_COUNT64(iq_no); 426*f173c2b7SSean Bruno lio_dev_dbg(oct, "InstQ[%d]:dbell reg @ 0x%x instcnt_reg @ 0x%x\n", 427*f173c2b7SSean Bruno iq_no, iq->doorbell_reg, iq->inst_cnt_reg); 428*f173c2b7SSean Bruno 429*f173c2b7SSean Bruno /* 430*f173c2b7SSean Bruno * Store the current instruction counter (used in flush_iq 431*f173c2b7SSean Bruno * calculation) 432*f173c2b7SSean Bruno */ 433*f173c2b7SSean Bruno pkt_in_done = lio_read_csr64(oct, iq->inst_cnt_reg); 434*f173c2b7SSean Bruno 435*f173c2b7SSean Bruno if (oct->msix_on) { 436*f173c2b7SSean Bruno /* Set CINT_ENB to enable IQ interrupt */ 437*f173c2b7SSean Bruno lio_write_csr64(oct, iq->inst_cnt_reg, 438*f173c2b7SSean Bruno (pkt_in_done | LIO_CN23XX_INTR_CINT_ENB)); 439*f173c2b7SSean Bruno } else { 440*f173c2b7SSean Bruno /* 441*f173c2b7SSean Bruno * Clear the count by writing back what we read, but don't 442*f173c2b7SSean Bruno * enable interrupts 443*f173c2b7SSean Bruno */ 444*f173c2b7SSean Bruno lio_write_csr64(oct, iq->inst_cnt_reg, pkt_in_done); 445*f173c2b7SSean Bruno } 446*f173c2b7SSean Bruno 447*f173c2b7SSean Bruno iq->reset_instr_cnt = 0; 448*f173c2b7SSean Bruno } 449*f173c2b7SSean Bruno 450*f173c2b7SSean Bruno static void 451*f173c2b7SSean Bruno lio_cn23xx_pf_setup_oq_regs(struct octeon_device *oct, uint32_t oq_no) 452*f173c2b7SSean Bruno { 453*f173c2b7SSean Bruno struct lio_droq *droq = oct->droq[oq_no]; 454*f173c2b7SSean Bruno struct lio_cn23xx_pf *cn23xx = (struct lio_cn23xx_pf *)oct->chip; 455*f173c2b7SSean Bruno uint64_t cnt_threshold; 456*f173c2b7SSean Bruno uint64_t time_threshold; 457*f173c2b7SSean Bruno uint32_t reg_val; 458*f173c2b7SSean Bruno 459*f173c2b7SSean Bruno oq_no += oct->sriov_info.pf_srn; 460*f173c2b7SSean Bruno 461*f173c2b7SSean Bruno lio_write_csr64(oct, LIO_CN23XX_SLI_OQ_BASE_ADDR64(oq_no), 462*f173c2b7SSean Bruno droq->desc_ring_dma); 463*f173c2b7SSean Bruno lio_write_csr32(oct, LIO_CN23XX_SLI_OQ_SIZE(oq_no), droq->max_count); 464*f173c2b7SSean Bruno 465*f173c2b7SSean Bruno lio_write_csr32(oct, LIO_CN23XX_SLI_OQ_BUFF_INFO_SIZE(oq_no), 466*f173c2b7SSean Bruno droq->buffer_size); 467*f173c2b7SSean Bruno 468*f173c2b7SSean Bruno /* pkt_sent and pkts_credit regs */ 469*f173c2b7SSean Bruno droq->pkts_sent_reg = LIO_CN23XX_SLI_OQ_PKTS_SENT(oq_no); 470*f173c2b7SSean Bruno droq->pkts_credit_reg = LIO_CN23XX_SLI_OQ_PKTS_CREDIT(oq_no); 471*f173c2b7SSean Bruno 472*f173c2b7SSean Bruno if (!oct->msix_on) { 473*f173c2b7SSean Bruno /* 474*f173c2b7SSean Bruno * Enable this output queue to generate Packet Timer 475*f173c2b7SSean Bruno * Interrupt 476*f173c2b7SSean Bruno */ 477*f173c2b7SSean Bruno reg_val = 478*f173c2b7SSean Bruno lio_read_csr32(oct, LIO_CN23XX_SLI_OQ_PKT_CONTROL(oq_no)); 479*f173c2b7SSean Bruno reg_val |= LIO_CN23XX_PKT_OUTPUT_CTL_TENB; 480*f173c2b7SSean Bruno lio_write_csr32(oct, LIO_CN23XX_SLI_OQ_PKT_CONTROL(oq_no), 481*f173c2b7SSean Bruno reg_val); 482*f173c2b7SSean Bruno 483*f173c2b7SSean Bruno /* 484*f173c2b7SSean Bruno * Enable this output queue to generate Packet Count 485*f173c2b7SSean Bruno * Interrupt 486*f173c2b7SSean Bruno */ 487*f173c2b7SSean Bruno reg_val = 488*f173c2b7SSean Bruno lio_read_csr32(oct, LIO_CN23XX_SLI_OQ_PKT_CONTROL(oq_no)); 489*f173c2b7SSean Bruno reg_val |= LIO_CN23XX_PKT_OUTPUT_CTL_CENB; 490*f173c2b7SSean Bruno lio_write_csr32(oct, LIO_CN23XX_SLI_OQ_PKT_CONTROL(oq_no), 491*f173c2b7SSean Bruno reg_val); 492*f173c2b7SSean Bruno } else { 493*f173c2b7SSean Bruno time_threshold = lio_cn23xx_pf_get_oq_ticks(oct, 494*f173c2b7SSean Bruno (uint32_t)LIO_GET_OQ_INTR_TIME_CFG(cn23xx->conf)); 495*f173c2b7SSean Bruno cnt_threshold = (uint32_t)LIO_GET_OQ_INTR_PKT_CFG(cn23xx->conf); 496*f173c2b7SSean Bruno 497*f173c2b7SSean Bruno lio_write_csr64(oct, LIO_CN23XX_SLI_OQ_PKT_INT_LEVELS(oq_no), 498*f173c2b7SSean Bruno ((time_threshold << 32 | cnt_threshold))); 499*f173c2b7SSean Bruno } 500*f173c2b7SSean Bruno } 501*f173c2b7SSean Bruno 502*f173c2b7SSean Bruno 503*f173c2b7SSean Bruno static int 504*f173c2b7SSean Bruno lio_cn23xx_pf_enable_io_queues(struct octeon_device *oct) 505*f173c2b7SSean Bruno { 506*f173c2b7SSean Bruno uint64_t reg_val; 507*f173c2b7SSean Bruno uint32_t ern, loop = BUSY_READING_REG_PF_LOOP_COUNT; 508*f173c2b7SSean Bruno uint32_t q_no, srn; 509*f173c2b7SSean Bruno 510*f173c2b7SSean Bruno srn = oct->sriov_info.pf_srn; 511*f173c2b7SSean Bruno ern = srn + oct->num_iqs; 512*f173c2b7SSean Bruno 513*f173c2b7SSean Bruno for (q_no = srn; q_no < ern; q_no++) { 514*f173c2b7SSean Bruno /* set the corresponding IQ IS_64B bit */ 515*f173c2b7SSean Bruno if (oct->io_qmask.iq64B & BIT_ULL(q_no - srn)) { 516*f173c2b7SSean Bruno reg_val = lio_read_csr64(oct, 517*f173c2b7SSean Bruno LIO_CN23XX_SLI_IQ_PKT_CONTROL64(q_no)); 518*f173c2b7SSean Bruno reg_val = reg_val | LIO_CN23XX_PKT_INPUT_CTL_IS_64B; 519*f173c2b7SSean Bruno lio_write_csr64(oct, 520*f173c2b7SSean Bruno LIO_CN23XX_SLI_IQ_PKT_CONTROL64(q_no), 521*f173c2b7SSean Bruno reg_val); 522*f173c2b7SSean Bruno } 523*f173c2b7SSean Bruno /* set the corresponding IQ ENB bit */ 524*f173c2b7SSean Bruno if (oct->io_qmask.iq & BIT_ULL(q_no - srn)) { 525*f173c2b7SSean Bruno /* 526*f173c2b7SSean Bruno * IOQs are in reset by default in PEM2 mode, 527*f173c2b7SSean Bruno * clearing reset bit 528*f173c2b7SSean Bruno */ 529*f173c2b7SSean Bruno reg_val = lio_read_csr64(oct, 530*f173c2b7SSean Bruno LIO_CN23XX_SLI_IQ_PKT_CONTROL64(q_no)); 531*f173c2b7SSean Bruno 532*f173c2b7SSean Bruno if (reg_val & LIO_CN23XX_PKT_INPUT_CTL_RST) { 533*f173c2b7SSean Bruno while ((reg_val & 534*f173c2b7SSean Bruno LIO_CN23XX_PKT_INPUT_CTL_RST) && 535*f173c2b7SSean Bruno !(reg_val & 536*f173c2b7SSean Bruno LIO_CN23XX_PKT_INPUT_CTL_QUIET) && 537*f173c2b7SSean Bruno loop) { 538*f173c2b7SSean Bruno reg_val = lio_read_csr64(oct, 539*f173c2b7SSean Bruno LIO_CN23XX_SLI_IQ_PKT_CONTROL64(q_no)); 540*f173c2b7SSean Bruno loop--; 541*f173c2b7SSean Bruno } 542*f173c2b7SSean Bruno if (!loop) { 543*f173c2b7SSean Bruno lio_dev_err(oct, "clearing the reset reg failed or setting the quiet reg failed for qno: %u\n", 544*f173c2b7SSean Bruno q_no); 545*f173c2b7SSean Bruno return (-1); 546*f173c2b7SSean Bruno } 547*f173c2b7SSean Bruno reg_val = reg_val & 548*f173c2b7SSean Bruno ~LIO_CN23XX_PKT_INPUT_CTL_RST; 549*f173c2b7SSean Bruno lio_write_csr64(oct, 550*f173c2b7SSean Bruno LIO_CN23XX_SLI_IQ_PKT_CONTROL64(q_no), 551*f173c2b7SSean Bruno reg_val); 552*f173c2b7SSean Bruno 553*f173c2b7SSean Bruno reg_val = lio_read_csr64(oct, 554*f173c2b7SSean Bruno LIO_CN23XX_SLI_IQ_PKT_CONTROL64(q_no)); 555*f173c2b7SSean Bruno if (reg_val & LIO_CN23XX_PKT_INPUT_CTL_RST) { 556*f173c2b7SSean Bruno lio_dev_err(oct, "clearing the reset failed for qno: %u\n", 557*f173c2b7SSean Bruno q_no); 558*f173c2b7SSean Bruno return (-1); 559*f173c2b7SSean Bruno } 560*f173c2b7SSean Bruno } 561*f173c2b7SSean Bruno reg_val = lio_read_csr64(oct, 562*f173c2b7SSean Bruno LIO_CN23XX_SLI_IQ_PKT_CONTROL64(q_no)); 563*f173c2b7SSean Bruno reg_val = reg_val | LIO_CN23XX_PKT_INPUT_CTL_RING_ENB; 564*f173c2b7SSean Bruno lio_write_csr64(oct, 565*f173c2b7SSean Bruno LIO_CN23XX_SLI_IQ_PKT_CONTROL64(q_no), 566*f173c2b7SSean Bruno reg_val); 567*f173c2b7SSean Bruno } 568*f173c2b7SSean Bruno } 569*f173c2b7SSean Bruno for (q_no = srn; q_no < ern; q_no++) { 570*f173c2b7SSean Bruno uint32_t reg_val; 571*f173c2b7SSean Bruno /* set the corresponding OQ ENB bit */ 572*f173c2b7SSean Bruno if (oct->io_qmask.oq & BIT_ULL(q_no - srn)) { 573*f173c2b7SSean Bruno reg_val = lio_read_csr32(oct, 574*f173c2b7SSean Bruno LIO_CN23XX_SLI_OQ_PKT_CONTROL(q_no)); 575*f173c2b7SSean Bruno reg_val = reg_val | LIO_CN23XX_PKT_OUTPUT_CTL_RING_ENB; 576*f173c2b7SSean Bruno lio_write_csr32(oct, 577*f173c2b7SSean Bruno LIO_CN23XX_SLI_OQ_PKT_CONTROL(q_no), 578*f173c2b7SSean Bruno reg_val); 579*f173c2b7SSean Bruno } 580*f173c2b7SSean Bruno } 581*f173c2b7SSean Bruno return (0); 582*f173c2b7SSean Bruno } 583*f173c2b7SSean Bruno 584*f173c2b7SSean Bruno static void 585*f173c2b7SSean Bruno lio_cn23xx_pf_disable_io_queues(struct octeon_device *oct) 586*f173c2b7SSean Bruno { 587*f173c2b7SSean Bruno volatile uint64_t d64; 588*f173c2b7SSean Bruno volatile uint32_t d32; 589*f173c2b7SSean Bruno int loop; 590*f173c2b7SSean Bruno unsigned int q_no; 591*f173c2b7SSean Bruno uint32_t ern, srn; 592*f173c2b7SSean Bruno 593*f173c2b7SSean Bruno srn = oct->sriov_info.pf_srn; 594*f173c2b7SSean Bruno ern = srn + oct->num_iqs; 595*f173c2b7SSean Bruno 596*f173c2b7SSean Bruno /* Disable Input Queues. */ 597*f173c2b7SSean Bruno for (q_no = srn; q_no < ern; q_no++) { 598*f173c2b7SSean Bruno loop = lio_ms_to_ticks(1000); 599*f173c2b7SSean Bruno 600*f173c2b7SSean Bruno /* start the Reset for a particular ring */ 601*f173c2b7SSean Bruno d64 = lio_read_csr64(oct, 602*f173c2b7SSean Bruno LIO_CN23XX_SLI_IQ_PKT_CONTROL64(q_no)); 603*f173c2b7SSean Bruno d64 &= ~LIO_CN23XX_PKT_INPUT_CTL_RING_ENB; 604*f173c2b7SSean Bruno d64 |= LIO_CN23XX_PKT_INPUT_CTL_RST; 605*f173c2b7SSean Bruno lio_write_csr64(oct, LIO_CN23XX_SLI_IQ_PKT_CONTROL64(q_no), 606*f173c2b7SSean Bruno d64); 607*f173c2b7SSean Bruno 608*f173c2b7SSean Bruno /* 609*f173c2b7SSean Bruno * Wait until hardware indicates that the particular IQ 610*f173c2b7SSean Bruno * is out of reset. 611*f173c2b7SSean Bruno */ 612*f173c2b7SSean Bruno d64 = lio_read_csr64(oct, LIO_CN23XX_SLI_PKT_IOQ_RING_RST); 613*f173c2b7SSean Bruno while (!(d64 & BIT_ULL(q_no)) && loop--) { 614*f173c2b7SSean Bruno d64 = lio_read_csr64(oct, 615*f173c2b7SSean Bruno LIO_CN23XX_SLI_PKT_IOQ_RING_RST); 616*f173c2b7SSean Bruno lio_sleep_timeout(1); 617*f173c2b7SSean Bruno loop--; 618*f173c2b7SSean Bruno } 619*f173c2b7SSean Bruno 620*f173c2b7SSean Bruno /* Reset the doorbell register for this Input Queue. */ 621*f173c2b7SSean Bruno lio_write_csr32(oct, LIO_CN23XX_SLI_IQ_DOORBELL(q_no), 622*f173c2b7SSean Bruno 0xFFFFFFFF); 623*f173c2b7SSean Bruno while (((lio_read_csr64(oct, 624*f173c2b7SSean Bruno LIO_CN23XX_SLI_IQ_DOORBELL(q_no))) != 625*f173c2b7SSean Bruno 0ULL) && loop--) { 626*f173c2b7SSean Bruno lio_sleep_timeout(1); 627*f173c2b7SSean Bruno } 628*f173c2b7SSean Bruno } 629*f173c2b7SSean Bruno 630*f173c2b7SSean Bruno /* Disable Output Queues. */ 631*f173c2b7SSean Bruno for (q_no = srn; q_no < ern; q_no++) { 632*f173c2b7SSean Bruno loop = lio_ms_to_ticks(1000); 633*f173c2b7SSean Bruno 634*f173c2b7SSean Bruno /* 635*f173c2b7SSean Bruno * Wait until hardware indicates that the particular IQ 636*f173c2b7SSean Bruno * is out of reset.It given that SLI_PKT_RING_RST is 637*f173c2b7SSean Bruno * common for both IQs and OQs 638*f173c2b7SSean Bruno */ 639*f173c2b7SSean Bruno d64 = lio_read_csr64(oct, LIO_CN23XX_SLI_PKT_IOQ_RING_RST); 640*f173c2b7SSean Bruno while (!(d64 & BIT_ULL(q_no)) && loop--) { 641*f173c2b7SSean Bruno d64 = lio_read_csr64(oct, 642*f173c2b7SSean Bruno LIO_CN23XX_SLI_PKT_IOQ_RING_RST); 643*f173c2b7SSean Bruno lio_sleep_timeout(1); 644*f173c2b7SSean Bruno loop--; 645*f173c2b7SSean Bruno } 646*f173c2b7SSean Bruno 647*f173c2b7SSean Bruno /* Reset the doorbell register for this Output Queue. */ 648*f173c2b7SSean Bruno lio_write_csr32(oct, LIO_CN23XX_SLI_OQ_PKTS_CREDIT(q_no), 649*f173c2b7SSean Bruno 0xFFFFFFFF); 650*f173c2b7SSean Bruno while ((lio_read_csr64(oct, 651*f173c2b7SSean Bruno LIO_CN23XX_SLI_OQ_PKTS_CREDIT(q_no)) != 652*f173c2b7SSean Bruno 0ULL) && loop--) { 653*f173c2b7SSean Bruno lio_sleep_timeout(1); 654*f173c2b7SSean Bruno } 655*f173c2b7SSean Bruno 656*f173c2b7SSean Bruno /* clear the SLI_PKT(0..63)_CNTS[CNT] reg value */ 657*f173c2b7SSean Bruno d32 = lio_read_csr32(oct, LIO_CN23XX_SLI_OQ_PKTS_SENT(q_no)); 658*f173c2b7SSean Bruno lio_write_csr32(oct, LIO_CN23XX_SLI_OQ_PKTS_SENT(q_no), d32); 659*f173c2b7SSean Bruno } 660*f173c2b7SSean Bruno } 661*f173c2b7SSean Bruno 662*f173c2b7SSean Bruno static uint64_t 663*f173c2b7SSean Bruno lio_cn23xx_pf_msix_interrupt_handler(void *dev) 664*f173c2b7SSean Bruno { 665*f173c2b7SSean Bruno struct lio_ioq_vector *ioq_vector = (struct lio_ioq_vector *)dev; 666*f173c2b7SSean Bruno struct octeon_device *oct = ioq_vector->oct_dev; 667*f173c2b7SSean Bruno struct lio_droq *droq = oct->droq[ioq_vector->droq_index]; 668*f173c2b7SSean Bruno uint64_t pkts_sent; 669*f173c2b7SSean Bruno uint64_t ret = 0; 670*f173c2b7SSean Bruno 671*f173c2b7SSean Bruno if (droq == NULL) { 672*f173c2b7SSean Bruno lio_dev_err(oct, "23XX bringup FIXME: oct pfnum:%d ioq_vector->ioq_num :%d droq is NULL\n", 673*f173c2b7SSean Bruno oct->pf_num, ioq_vector->ioq_num); 674*f173c2b7SSean Bruno return (0); 675*f173c2b7SSean Bruno } 676*f173c2b7SSean Bruno pkts_sent = lio_read_csr64(oct, droq->pkts_sent_reg); 677*f173c2b7SSean Bruno 678*f173c2b7SSean Bruno /* 679*f173c2b7SSean Bruno * If our device has interrupted, then proceed. Also check 680*f173c2b7SSean Bruno * for all f's if interrupt was triggered on an error 681*f173c2b7SSean Bruno * and the PCI read fails. 682*f173c2b7SSean Bruno */ 683*f173c2b7SSean Bruno if (!pkts_sent || (pkts_sent == 0xFFFFFFFFFFFFFFFFULL)) 684*f173c2b7SSean Bruno return (ret); 685*f173c2b7SSean Bruno 686*f173c2b7SSean Bruno /* Write count reg in sli_pkt_cnts to clear these int. */ 687*f173c2b7SSean Bruno if (pkts_sent & LIO_CN23XX_INTR_PO_INT) 688*f173c2b7SSean Bruno ret |= LIO_MSIX_PO_INT; 689*f173c2b7SSean Bruno 690*f173c2b7SSean Bruno if (pkts_sent & LIO_CN23XX_INTR_PI_INT) 691*f173c2b7SSean Bruno /* We will clear the count when we update the read_index. */ 692*f173c2b7SSean Bruno ret |= LIO_MSIX_PI_INT; 693*f173c2b7SSean Bruno 694*f173c2b7SSean Bruno /* 695*f173c2b7SSean Bruno * Never need to handle msix mbox intr for pf. They arrive on the last 696*f173c2b7SSean Bruno * msix 697*f173c2b7SSean Bruno */ 698*f173c2b7SSean Bruno return (ret); 699*f173c2b7SSean Bruno } 700*f173c2b7SSean Bruno 701*f173c2b7SSean Bruno static void 702*f173c2b7SSean Bruno lio_cn23xx_pf_interrupt_handler(void *dev) 703*f173c2b7SSean Bruno { 704*f173c2b7SSean Bruno struct octeon_device *oct = (struct octeon_device *)dev; 705*f173c2b7SSean Bruno struct lio_cn23xx_pf *cn23xx = (struct lio_cn23xx_pf *)oct->chip; 706*f173c2b7SSean Bruno uint64_t intr64; 707*f173c2b7SSean Bruno 708*f173c2b7SSean Bruno lio_dev_dbg(oct, "In %s octeon_dev @ %p\n", __func__, oct); 709*f173c2b7SSean Bruno intr64 = lio_read_csr64(oct, cn23xx->intr_sum_reg64); 710*f173c2b7SSean Bruno 711*f173c2b7SSean Bruno oct->int_status = 0; 712*f173c2b7SSean Bruno 713*f173c2b7SSean Bruno if (intr64 & LIO_CN23XX_INTR_ERR) 714*f173c2b7SSean Bruno lio_dev_err(oct, "Error Intr: 0x%016llx\n", 715*f173c2b7SSean Bruno LIO_CAST64(intr64)); 716*f173c2b7SSean Bruno 717*f173c2b7SSean Bruno if (oct->msix_on != LIO_FLAG_MSIX_ENABLED) { 718*f173c2b7SSean Bruno if (intr64 & LIO_CN23XX_INTR_PKT_DATA) 719*f173c2b7SSean Bruno oct->int_status |= LIO_DEV_INTR_PKT_DATA; 720*f173c2b7SSean Bruno } 721*f173c2b7SSean Bruno 722*f173c2b7SSean Bruno if (intr64 & (LIO_CN23XX_INTR_DMA0_FORCE)) 723*f173c2b7SSean Bruno oct->int_status |= LIO_DEV_INTR_DMA0_FORCE; 724*f173c2b7SSean Bruno 725*f173c2b7SSean Bruno if (intr64 & (LIO_CN23XX_INTR_DMA1_FORCE)) 726*f173c2b7SSean Bruno oct->int_status |= LIO_DEV_INTR_DMA1_FORCE; 727*f173c2b7SSean Bruno 728*f173c2b7SSean Bruno /* Clear the current interrupts */ 729*f173c2b7SSean Bruno lio_write_csr64(oct, cn23xx->intr_sum_reg64, intr64); 730*f173c2b7SSean Bruno } 731*f173c2b7SSean Bruno 732*f173c2b7SSean Bruno static void 733*f173c2b7SSean Bruno lio_cn23xx_pf_bar1_idx_setup(struct octeon_device *oct, uint64_t core_addr, 734*f173c2b7SSean Bruno uint32_t idx, int valid) 735*f173c2b7SSean Bruno { 736*f173c2b7SSean Bruno volatile uint64_t bar1; 737*f173c2b7SSean Bruno uint64_t reg_adr; 738*f173c2b7SSean Bruno 739*f173c2b7SSean Bruno if (!valid) { 740*f173c2b7SSean Bruno reg_adr = lio_pci_readq(oct, 741*f173c2b7SSean Bruno LIO_CN23XX_PEM_BAR1_INDEX_REG(oct->pcie_port, 742*f173c2b7SSean Bruno idx)); 743*f173c2b7SSean Bruno bar1 = reg_adr; 744*f173c2b7SSean Bruno lio_pci_writeq(oct, (bar1 & 0xFFFFFFFEULL), 745*f173c2b7SSean Bruno LIO_CN23XX_PEM_BAR1_INDEX_REG(oct->pcie_port, 746*f173c2b7SSean Bruno idx)); 747*f173c2b7SSean Bruno reg_adr = lio_pci_readq(oct, 748*f173c2b7SSean Bruno LIO_CN23XX_PEM_BAR1_INDEX_REG(oct->pcie_port, 749*f173c2b7SSean Bruno idx)); 750*f173c2b7SSean Bruno bar1 = reg_adr; 751*f173c2b7SSean Bruno return; 752*f173c2b7SSean Bruno } 753*f173c2b7SSean Bruno /* 754*f173c2b7SSean Bruno * The PEM(0..3)_BAR1_INDEX(0..15)[ADDR_IDX]<23:4> stores 755*f173c2b7SSean Bruno * bits <41:22> of the Core Addr 756*f173c2b7SSean Bruno */ 757*f173c2b7SSean Bruno lio_pci_writeq(oct, (((core_addr >> 22) << 4) | LIO_PCI_BAR1_MASK), 758*f173c2b7SSean Bruno LIO_CN23XX_PEM_BAR1_INDEX_REG(oct->pcie_port, idx)); 759*f173c2b7SSean Bruno 760*f173c2b7SSean Bruno bar1 = lio_pci_readq(oct, LIO_CN23XX_PEM_BAR1_INDEX_REG(oct->pcie_port, 761*f173c2b7SSean Bruno idx)); 762*f173c2b7SSean Bruno } 763*f173c2b7SSean Bruno 764*f173c2b7SSean Bruno static void 765*f173c2b7SSean Bruno lio_cn23xx_pf_bar1_idx_write(struct octeon_device *oct, uint32_t idx, 766*f173c2b7SSean Bruno uint32_t mask) 767*f173c2b7SSean Bruno { 768*f173c2b7SSean Bruno 769*f173c2b7SSean Bruno lio_pci_writeq(oct, mask, 770*f173c2b7SSean Bruno LIO_CN23XX_PEM_BAR1_INDEX_REG(oct->pcie_port, idx)); 771*f173c2b7SSean Bruno } 772*f173c2b7SSean Bruno 773*f173c2b7SSean Bruno static uint32_t 774*f173c2b7SSean Bruno lio_cn23xx_pf_bar1_idx_read(struct octeon_device *oct, uint32_t idx) 775*f173c2b7SSean Bruno { 776*f173c2b7SSean Bruno 777*f173c2b7SSean Bruno return ((uint32_t)lio_pci_readq(oct, 778*f173c2b7SSean Bruno LIO_CN23XX_PEM_BAR1_INDEX_REG(oct->pcie_port, 779*f173c2b7SSean Bruno idx))); 780*f173c2b7SSean Bruno } 781*f173c2b7SSean Bruno 782*f173c2b7SSean Bruno /* always call with lock held */ 783*f173c2b7SSean Bruno static uint32_t 784*f173c2b7SSean Bruno lio_cn23xx_pf_update_read_index(struct lio_instr_queue *iq) 785*f173c2b7SSean Bruno { 786*f173c2b7SSean Bruno struct octeon_device *oct = iq->oct_dev; 787*f173c2b7SSean Bruno uint32_t new_idx; 788*f173c2b7SSean Bruno uint32_t last_done; 789*f173c2b7SSean Bruno uint32_t pkt_in_done = lio_read_csr32(oct, iq->inst_cnt_reg); 790*f173c2b7SSean Bruno 791*f173c2b7SSean Bruno last_done = pkt_in_done - iq->pkt_in_done; 792*f173c2b7SSean Bruno iq->pkt_in_done = pkt_in_done; 793*f173c2b7SSean Bruno 794*f173c2b7SSean Bruno /* 795*f173c2b7SSean Bruno * Modulo of the new index with the IQ size will give us 796*f173c2b7SSean Bruno * the new index. The iq->reset_instr_cnt is always zero for 797*f173c2b7SSean Bruno * cn23xx, so no extra adjustments are needed. 798*f173c2b7SSean Bruno */ 799*f173c2b7SSean Bruno new_idx = (iq->octeon_read_index + 800*f173c2b7SSean Bruno ((uint32_t)(last_done & LIO_CN23XX_PKT_IN_DONE_CNT_MASK))) % 801*f173c2b7SSean Bruno iq->max_count; 802*f173c2b7SSean Bruno 803*f173c2b7SSean Bruno return (new_idx); 804*f173c2b7SSean Bruno } 805*f173c2b7SSean Bruno 806*f173c2b7SSean Bruno static void 807*f173c2b7SSean Bruno lio_cn23xx_pf_enable_interrupt(struct octeon_device *oct, uint8_t intr_flag) 808*f173c2b7SSean Bruno { 809*f173c2b7SSean Bruno struct lio_cn23xx_pf *cn23xx = (struct lio_cn23xx_pf *)oct->chip; 810*f173c2b7SSean Bruno uint64_t intr_val = 0; 811*f173c2b7SSean Bruno 812*f173c2b7SSean Bruno /* Divide the single write to multiple writes based on the flag. */ 813*f173c2b7SSean Bruno /* Enable Interrupt */ 814*f173c2b7SSean Bruno if (intr_flag == OCTEON_ALL_INTR) { 815*f173c2b7SSean Bruno lio_write_csr64(oct, cn23xx->intr_enb_reg64, 816*f173c2b7SSean Bruno cn23xx->intr_mask64); 817*f173c2b7SSean Bruno } else if (intr_flag & OCTEON_OUTPUT_INTR) { 818*f173c2b7SSean Bruno intr_val = lio_read_csr64(oct, cn23xx->intr_enb_reg64); 819*f173c2b7SSean Bruno intr_val |= LIO_CN23XX_INTR_PKT_DATA; 820*f173c2b7SSean Bruno lio_write_csr64(oct, cn23xx->intr_enb_reg64, intr_val); 821*f173c2b7SSean Bruno } 822*f173c2b7SSean Bruno } 823*f173c2b7SSean Bruno 824*f173c2b7SSean Bruno static void 825*f173c2b7SSean Bruno lio_cn23xx_pf_disable_interrupt(struct octeon_device *oct, uint8_t intr_flag) 826*f173c2b7SSean Bruno { 827*f173c2b7SSean Bruno struct lio_cn23xx_pf *cn23xx = (struct lio_cn23xx_pf *)oct->chip; 828*f173c2b7SSean Bruno uint64_t intr_val = 0; 829*f173c2b7SSean Bruno 830*f173c2b7SSean Bruno /* Disable Interrupts */ 831*f173c2b7SSean Bruno if (intr_flag == OCTEON_ALL_INTR) { 832*f173c2b7SSean Bruno lio_write_csr64(oct, cn23xx->intr_enb_reg64, 0); 833*f173c2b7SSean Bruno } else if (intr_flag & OCTEON_OUTPUT_INTR) { 834*f173c2b7SSean Bruno intr_val = lio_read_csr64(oct, cn23xx->intr_enb_reg64); 835*f173c2b7SSean Bruno intr_val &= ~LIO_CN23XX_INTR_PKT_DATA; 836*f173c2b7SSean Bruno lio_write_csr64(oct, cn23xx->intr_enb_reg64, intr_val); 837*f173c2b7SSean Bruno } 838*f173c2b7SSean Bruno } 839*f173c2b7SSean Bruno 840*f173c2b7SSean Bruno static void 841*f173c2b7SSean Bruno lio_cn23xx_pf_get_pcie_qlmport(struct octeon_device *oct) 842*f173c2b7SSean Bruno { 843*f173c2b7SSean Bruno oct->pcie_port = (lio_read_csr32(oct, 844*f173c2b7SSean Bruno LIO_CN23XX_SLI_MAC_NUMBER)) & 0xff; 845*f173c2b7SSean Bruno 846*f173c2b7SSean Bruno lio_dev_dbg(oct, "CN23xx uses PCIE Port %d\n", 847*f173c2b7SSean Bruno oct->pcie_port); 848*f173c2b7SSean Bruno } 849*f173c2b7SSean Bruno 850*f173c2b7SSean Bruno static void 851*f173c2b7SSean Bruno lio_cn23xx_pf_get_pf_num(struct octeon_device *oct) 852*f173c2b7SSean Bruno { 853*f173c2b7SSean Bruno uint32_t fdl_bit; 854*f173c2b7SSean Bruno 855*f173c2b7SSean Bruno /* Read Function Dependency Link reg to get the function number */ 856*f173c2b7SSean Bruno fdl_bit = lio_read_pci_cfg(oct, LIO_CN23XX_PCIE_SRIOV_FDL); 857*f173c2b7SSean Bruno oct->pf_num = ((fdl_bit >> LIO_CN23XX_PCIE_SRIOV_FDL_BIT_POS) & 858*f173c2b7SSean Bruno LIO_CN23XX_PCIE_SRIOV_FDL_MASK); 859*f173c2b7SSean Bruno } 860*f173c2b7SSean Bruno 861*f173c2b7SSean Bruno static void 862*f173c2b7SSean Bruno lio_cn23xx_pf_setup_reg_address(struct octeon_device *oct) 863*f173c2b7SSean Bruno { 864*f173c2b7SSean Bruno struct lio_cn23xx_pf *cn23xx = (struct lio_cn23xx_pf *)oct->chip; 865*f173c2b7SSean Bruno 866*f173c2b7SSean Bruno oct->reg_list.pci_win_wr_addr = LIO_CN23XX_SLI_WIN_WR_ADDR64; 867*f173c2b7SSean Bruno 868*f173c2b7SSean Bruno oct->reg_list.pci_win_rd_addr_hi = LIO_CN23XX_SLI_WIN_RD_ADDR_HI; 869*f173c2b7SSean Bruno oct->reg_list.pci_win_rd_addr_lo = LIO_CN23XX_SLI_WIN_RD_ADDR64; 870*f173c2b7SSean Bruno oct->reg_list.pci_win_rd_addr = LIO_CN23XX_SLI_WIN_RD_ADDR64; 871*f173c2b7SSean Bruno 872*f173c2b7SSean Bruno oct->reg_list.pci_win_wr_data_hi = LIO_CN23XX_SLI_WIN_WR_DATA_HI; 873*f173c2b7SSean Bruno oct->reg_list.pci_win_wr_data_lo = LIO_CN23XX_SLI_WIN_WR_DATA_LO; 874*f173c2b7SSean Bruno oct->reg_list.pci_win_wr_data = LIO_CN23XX_SLI_WIN_WR_DATA64; 875*f173c2b7SSean Bruno 876*f173c2b7SSean Bruno oct->reg_list.pci_win_rd_data = LIO_CN23XX_SLI_WIN_RD_DATA64; 877*f173c2b7SSean Bruno 878*f173c2b7SSean Bruno lio_cn23xx_pf_get_pcie_qlmport(oct); 879*f173c2b7SSean Bruno 880*f173c2b7SSean Bruno cn23xx->intr_mask64 = LIO_CN23XX_INTR_MASK; 881*f173c2b7SSean Bruno if (!oct->msix_on) 882*f173c2b7SSean Bruno cn23xx->intr_mask64 |= LIO_CN23XX_INTR_PKT_TIME; 883*f173c2b7SSean Bruno 884*f173c2b7SSean Bruno cn23xx->intr_sum_reg64 = 885*f173c2b7SSean Bruno LIO_CN23XX_SLI_MAC_PF_INT_SUM64(oct->pcie_port, oct->pf_num); 886*f173c2b7SSean Bruno cn23xx->intr_enb_reg64 = 887*f173c2b7SSean Bruno LIO_CN23XX_SLI_MAC_PF_INT_ENB64(oct->pcie_port, oct->pf_num); 888*f173c2b7SSean Bruno } 889*f173c2b7SSean Bruno 890*f173c2b7SSean Bruno static int 891*f173c2b7SSean Bruno lio_cn23xx_pf_sriov_config(struct octeon_device *oct) 892*f173c2b7SSean Bruno { 893*f173c2b7SSean Bruno struct lio_cn23xx_pf *cn23xx = (struct lio_cn23xx_pf *)oct->chip; 894*f173c2b7SSean Bruno uint32_t num_pf_rings, total_rings, max_rings; 895*f173c2b7SSean Bruno cn23xx->conf = (struct lio_config *)lio_get_config_info(oct, LIO_23XX); 896*f173c2b7SSean Bruno 897*f173c2b7SSean Bruno max_rings = LIO_CN23XX_PF_MAX_RINGS; 898*f173c2b7SSean Bruno 899*f173c2b7SSean Bruno if (oct->sriov_info.num_pf_rings) { 900*f173c2b7SSean Bruno num_pf_rings = oct->sriov_info.num_pf_rings; 901*f173c2b7SSean Bruno if (num_pf_rings > max_rings) { 902*f173c2b7SSean Bruno num_pf_rings = min(mp_ncpus, max_rings); 903*f173c2b7SSean Bruno lio_dev_warn(oct, "num_queues_per_pf requested %u is more than available rings (%u). Reducing to %u\n", 904*f173c2b7SSean Bruno oct->sriov_info.num_pf_rings, 905*f173c2b7SSean Bruno max_rings, num_pf_rings); 906*f173c2b7SSean Bruno } 907*f173c2b7SSean Bruno } else { 908*f173c2b7SSean Bruno #ifdef RSS 909*f173c2b7SSean Bruno num_pf_rings = min(rss_getnumbuckets(), mp_ncpus); 910*f173c2b7SSean Bruno #else 911*f173c2b7SSean Bruno num_pf_rings = min(mp_ncpus, max_rings); 912*f173c2b7SSean Bruno #endif 913*f173c2b7SSean Bruno 914*f173c2b7SSean Bruno } 915*f173c2b7SSean Bruno 916*f173c2b7SSean Bruno total_rings = num_pf_rings; 917*f173c2b7SSean Bruno oct->sriov_info.trs = total_rings; 918*f173c2b7SSean Bruno oct->sriov_info.pf_srn = total_rings - num_pf_rings; 919*f173c2b7SSean Bruno oct->sriov_info.num_pf_rings = num_pf_rings; 920*f173c2b7SSean Bruno 921*f173c2b7SSean Bruno lio_dev_dbg(oct, "trs:%d pf_srn:%d num_pf_rings:%d\n", 922*f173c2b7SSean Bruno oct->sriov_info.trs, oct->sriov_info.pf_srn, 923*f173c2b7SSean Bruno oct->sriov_info.num_pf_rings); 924*f173c2b7SSean Bruno 925*f173c2b7SSean Bruno return (0); 926*f173c2b7SSean Bruno } 927*f173c2b7SSean Bruno 928*f173c2b7SSean Bruno int 929*f173c2b7SSean Bruno lio_cn23xx_pf_setup_device(struct octeon_device *oct) 930*f173c2b7SSean Bruno { 931*f173c2b7SSean Bruno uint64_t BAR0, BAR1; 932*f173c2b7SSean Bruno uint32_t data32; 933*f173c2b7SSean Bruno 934*f173c2b7SSean Bruno data32 = lio_read_pci_cfg(oct, 0x10); 935*f173c2b7SSean Bruno BAR0 = (uint64_t)(data32 & ~0xf); 936*f173c2b7SSean Bruno data32 = lio_read_pci_cfg(oct, 0x14); 937*f173c2b7SSean Bruno BAR0 |= ((uint64_t)data32 << 32); 938*f173c2b7SSean Bruno data32 = lio_read_pci_cfg(oct, 0x18); 939*f173c2b7SSean Bruno BAR1 = (uint64_t)(data32 & ~0xf); 940*f173c2b7SSean Bruno data32 = lio_read_pci_cfg(oct, 0x1c); 941*f173c2b7SSean Bruno BAR1 |= ((uint64_t)data32 << 32); 942*f173c2b7SSean Bruno 943*f173c2b7SSean Bruno if (!BAR0 || !BAR1) { 944*f173c2b7SSean Bruno if (!BAR0) 945*f173c2b7SSean Bruno lio_dev_err(oct, "Device BAR0 unassigned\n"); 946*f173c2b7SSean Bruno 947*f173c2b7SSean Bruno if (!BAR1) 948*f173c2b7SSean Bruno lio_dev_err(oct, "Device BAR1 unassigned\n"); 949*f173c2b7SSean Bruno 950*f173c2b7SSean Bruno return (1); 951*f173c2b7SSean Bruno } 952*f173c2b7SSean Bruno 953*f173c2b7SSean Bruno if (lio_map_pci_barx(oct, 0)) 954*f173c2b7SSean Bruno return (1); 955*f173c2b7SSean Bruno 956*f173c2b7SSean Bruno if (lio_map_pci_barx(oct, 1)) { 957*f173c2b7SSean Bruno lio_dev_err(oct, "%s CN23XX BAR1 map failed\n", __func__); 958*f173c2b7SSean Bruno lio_unmap_pci_barx(oct, 0); 959*f173c2b7SSean Bruno return (1); 960*f173c2b7SSean Bruno } 961*f173c2b7SSean Bruno 962*f173c2b7SSean Bruno lio_cn23xx_pf_get_pf_num(oct); 963*f173c2b7SSean Bruno 964*f173c2b7SSean Bruno if (lio_cn23xx_pf_sriov_config(oct)) { 965*f173c2b7SSean Bruno lio_unmap_pci_barx(oct, 0); 966*f173c2b7SSean Bruno lio_unmap_pci_barx(oct, 1); 967*f173c2b7SSean Bruno return (1); 968*f173c2b7SSean Bruno } 969*f173c2b7SSean Bruno lio_write_csr64(oct, LIO_CN23XX_SLI_MAC_CREDIT_CNT, 970*f173c2b7SSean Bruno 0x3F802080802080ULL); 971*f173c2b7SSean Bruno 972*f173c2b7SSean Bruno oct->fn_list.setup_iq_regs = lio_cn23xx_pf_setup_iq_regs; 973*f173c2b7SSean Bruno oct->fn_list.setup_oq_regs = lio_cn23xx_pf_setup_oq_regs; 974*f173c2b7SSean Bruno oct->fn_list.process_interrupt_regs = lio_cn23xx_pf_interrupt_handler; 975*f173c2b7SSean Bruno oct->fn_list.msix_interrupt_handler = 976*f173c2b7SSean Bruno lio_cn23xx_pf_msix_interrupt_handler; 977*f173c2b7SSean Bruno 978*f173c2b7SSean Bruno oct->fn_list.soft_reset = lio_cn23xx_pf_soft_reset; 979*f173c2b7SSean Bruno oct->fn_list.setup_device_regs = lio_cn23xx_pf_setup_device_regs; 980*f173c2b7SSean Bruno oct->fn_list.update_iq_read_idx = lio_cn23xx_pf_update_read_index; 981*f173c2b7SSean Bruno 982*f173c2b7SSean Bruno oct->fn_list.bar1_idx_setup = lio_cn23xx_pf_bar1_idx_setup; 983*f173c2b7SSean Bruno oct->fn_list.bar1_idx_write = lio_cn23xx_pf_bar1_idx_write; 984*f173c2b7SSean Bruno oct->fn_list.bar1_idx_read = lio_cn23xx_pf_bar1_idx_read; 985*f173c2b7SSean Bruno 986*f173c2b7SSean Bruno oct->fn_list.enable_interrupt = lio_cn23xx_pf_enable_interrupt; 987*f173c2b7SSean Bruno oct->fn_list.disable_interrupt = lio_cn23xx_pf_disable_interrupt; 988*f173c2b7SSean Bruno 989*f173c2b7SSean Bruno oct->fn_list.enable_io_queues = lio_cn23xx_pf_enable_io_queues; 990*f173c2b7SSean Bruno oct->fn_list.disable_io_queues = lio_cn23xx_pf_disable_io_queues; 991*f173c2b7SSean Bruno 992*f173c2b7SSean Bruno lio_cn23xx_pf_setup_reg_address(oct); 993*f173c2b7SSean Bruno 994*f173c2b7SSean Bruno oct->coproc_clock_rate = 1000000ULL * 995*f173c2b7SSean Bruno lio_cn23xx_pf_coprocessor_clock(oct); 996*f173c2b7SSean Bruno 997*f173c2b7SSean Bruno return (0); 998*f173c2b7SSean Bruno } 999*f173c2b7SSean Bruno 1000*f173c2b7SSean Bruno int 1001*f173c2b7SSean Bruno lio_cn23xx_pf_fw_loaded(struct octeon_device *oct) 1002*f173c2b7SSean Bruno { 1003*f173c2b7SSean Bruno uint64_t val; 1004*f173c2b7SSean Bruno 1005*f173c2b7SSean Bruno val = lio_read_csr64(oct, LIO_CN23XX_SLI_SCRATCH2); 1006*f173c2b7SSean Bruno return ((val >> SCR2_BIT_FW_LOADED) & 1ULL); 1007*f173c2b7SSean Bruno } 1008*f173c2b7SSean Bruno 1009