Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * QLogic qlcnic NIC Driver
0004  * Copyright (c) 2009-2013 QLogic Corporation
0005  */
0006 
0007 #include <linux/if_vlan.h>
0008 #include <linux/ipv6.h>
0009 #include <linux/ethtool.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/aer.h>
0012 
0013 #include "qlcnic.h"
0014 #include "qlcnic_sriov.h"
0015 
0016 static void __qlcnic_83xx_process_aen(struct qlcnic_adapter *);
0017 static int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *, u8);
0018 static void qlcnic_83xx_configure_mac(struct qlcnic_adapter *, u8 *, u8,
0019                       struct qlcnic_cmd_args *);
0020 static int qlcnic_83xx_get_port_config(struct qlcnic_adapter *);
0021 static irqreturn_t qlcnic_83xx_handle_aen(int, void *);
0022 static pci_ers_result_t qlcnic_83xx_io_error_detected(struct pci_dev *,
0023                               pci_channel_state_t);
0024 static int qlcnic_83xx_set_port_config(struct qlcnic_adapter *);
0025 static pci_ers_result_t qlcnic_83xx_io_slot_reset(struct pci_dev *);
0026 static void qlcnic_83xx_io_resume(struct pci_dev *);
0027 static int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *, u8);
0028 static void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *);
0029 static int qlcnic_83xx_resume(struct qlcnic_adapter *);
0030 static int qlcnic_83xx_shutdown(struct pci_dev *);
0031 static void qlcnic_83xx_get_beacon_state(struct qlcnic_adapter *);
0032 
0033 #define RSS_HASHTYPE_IP_TCP     0x3
0034 #define QLC_83XX_FW_MBX_CMD     0
0035 #define QLC_SKIP_INACTIVE_PCI_REGS  7
0036 #define QLC_MAX_LEGACY_FUNC_SUPP    8
0037 
0038 /* 83xx Module type */
0039 #define QLC_83XX_MODULE_FIBRE_10GBASE_LRM   0x1 /* 10GBase-LRM */
0040 #define QLC_83XX_MODULE_FIBRE_10GBASE_LR    0x2 /* 10GBase-LR */
0041 #define QLC_83XX_MODULE_FIBRE_10GBASE_SR    0x3 /* 10GBase-SR */
0042 #define QLC_83XX_MODULE_DA_10GE_PASSIVE_CP  0x4 /* 10GE passive
0043                              * copper(compliant)
0044                              */
0045 #define QLC_83XX_MODULE_DA_10GE_ACTIVE_CP   0x5 /* 10GE active limiting
0046                              * copper(compliant)
0047                              */
0048 #define QLC_83XX_MODULE_DA_10GE_LEGACY_CP   0x6 /* 10GE passive copper
0049                              * (legacy, best effort)
0050                              */
0051 #define QLC_83XX_MODULE_FIBRE_1000BASE_SX   0x7 /* 1000Base-SX */
0052 #define QLC_83XX_MODULE_FIBRE_1000BASE_LX   0x8 /* 1000Base-LX */
0053 #define QLC_83XX_MODULE_FIBRE_1000BASE_CX   0x9 /* 1000Base-CX */
0054 #define QLC_83XX_MODULE_TP_1000BASE_T       0xa /* 1000Base-T*/
0055 #define QLC_83XX_MODULE_DA_1GE_PASSIVE_CP   0xb /* 1GE passive copper
0056                              * (legacy, best effort)
0057                              */
0058 #define QLC_83XX_MODULE_UNKNOWN         0xf /* Unknown module type */
0059 
0060 /* Port types */
0061 #define QLC_83XX_10_CAPABLE  BIT_8
0062 #define QLC_83XX_100_CAPABLE     BIT_9
0063 #define QLC_83XX_1G_CAPABLE  BIT_10
0064 #define QLC_83XX_10G_CAPABLE     BIT_11
0065 #define QLC_83XX_AUTONEG_ENABLE  BIT_15
0066 
0067 static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
0068     {QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1},
0069     {QLCNIC_CMD_CONFIG_INTRPT, 18, 34},
0070     {QLCNIC_CMD_CREATE_RX_CTX, 136, 27},
0071     {QLCNIC_CMD_DESTROY_RX_CTX, 2, 1},
0072     {QLCNIC_CMD_CREATE_TX_CTX, 54, 18},
0073     {QLCNIC_CMD_DESTROY_TX_CTX, 2, 1},
0074     {QLCNIC_CMD_CONFIGURE_MAC_LEARNING, 2, 1},
0075     {QLCNIC_CMD_INTRPT_TEST, 22, 12},
0076     {QLCNIC_CMD_SET_MTU, 3, 1},
0077     {QLCNIC_CMD_READ_PHY, 4, 2},
0078     {QLCNIC_CMD_WRITE_PHY, 5, 1},
0079     {QLCNIC_CMD_READ_HW_REG, 4, 1},
0080     {QLCNIC_CMD_GET_FLOW_CTL, 4, 2},
0081     {QLCNIC_CMD_SET_FLOW_CTL, 4, 1},
0082     {QLCNIC_CMD_READ_MAX_MTU, 4, 2},
0083     {QLCNIC_CMD_READ_MAX_LRO, 4, 2},
0084     {QLCNIC_CMD_MAC_ADDRESS, 4, 3},
0085     {QLCNIC_CMD_GET_PCI_INFO, 1, 129},
0086     {QLCNIC_CMD_GET_NIC_INFO, 2, 19},
0087     {QLCNIC_CMD_SET_NIC_INFO, 32, 1},
0088     {QLCNIC_CMD_GET_ESWITCH_CAPABILITY, 4, 3},
0089     {QLCNIC_CMD_TOGGLE_ESWITCH, 4, 1},
0090     {QLCNIC_CMD_GET_ESWITCH_STATUS, 4, 3},
0091     {QLCNIC_CMD_SET_PORTMIRRORING, 4, 1},
0092     {QLCNIC_CMD_CONFIGURE_ESWITCH, 4, 1},
0093     {QLCNIC_CMD_GET_ESWITCH_PORT_CONFIG, 4, 3},
0094     {QLCNIC_CMD_GET_ESWITCH_STATS, 5, 1},
0095     {QLCNIC_CMD_CONFIG_PORT, 4, 1},
0096     {QLCNIC_CMD_TEMP_SIZE, 1, 4},
0097     {QLCNIC_CMD_GET_TEMP_HDR, 5, 5},
0098     {QLCNIC_CMD_GET_LINK_EVENT, 2, 1},
0099     {QLCNIC_CMD_CONFIG_MAC_VLAN, 4, 3},
0100     {QLCNIC_CMD_CONFIG_INTR_COAL, 6, 1},
0101     {QLCNIC_CMD_CONFIGURE_RSS, 14, 1},
0102     {QLCNIC_CMD_CONFIGURE_LED, 2, 1},
0103     {QLCNIC_CMD_CONFIGURE_MAC_RX_MODE, 2, 1},
0104     {QLCNIC_CMD_CONFIGURE_HW_LRO, 2, 1},
0105     {QLCNIC_CMD_GET_STATISTICS, 2, 80},
0106     {QLCNIC_CMD_SET_PORT_CONFIG, 2, 1},
0107     {QLCNIC_CMD_GET_PORT_CONFIG, 2, 2},
0108     {QLCNIC_CMD_GET_LINK_STATUS, 2, 4},
0109     {QLCNIC_CMD_IDC_ACK, 5, 1},
0110     {QLCNIC_CMD_INIT_NIC_FUNC, 3, 1},
0111     {QLCNIC_CMD_STOP_NIC_FUNC, 2, 1},
0112     {QLCNIC_CMD_SET_LED_CONFIG, 5, 1},
0113     {QLCNIC_CMD_GET_LED_CONFIG, 1, 5},
0114     {QLCNIC_CMD_83XX_SET_DRV_VER, 4, 1},
0115     {QLCNIC_CMD_ADD_RCV_RINGS, 130, 26},
0116     {QLCNIC_CMD_CONFIG_VPORT, 4, 4},
0117     {QLCNIC_CMD_BC_EVENT_SETUP, 2, 1},
0118     {QLCNIC_CMD_DCB_QUERY_CAP, 1, 2},
0119     {QLCNIC_CMD_DCB_QUERY_PARAM, 1, 50},
0120     {QLCNIC_CMD_SET_INGRESS_ENCAP, 2, 1},
0121     {QLCNIC_CMD_83XX_EXTEND_ISCSI_DUMP_CAP, 4, 1},
0122 };
0123 
0124 const u32 qlcnic_83xx_ext_reg_tbl[] = {
0125     0x38CC,     /* Global Reset */
0126     0x38F0,     /* Wildcard */
0127     0x38FC,     /* Informant */
0128     0x3038,     /* Host MBX ctrl */
0129     0x303C,     /* FW MBX ctrl */
0130     0x355C,     /* BOOT LOADER ADDRESS REG */
0131     0x3560,     /* BOOT LOADER SIZE REG */
0132     0x3564,     /* FW IMAGE ADDR REG */
0133     0x1000,     /* MBX intr enable */
0134     0x1200,     /* Default Intr mask */
0135     0x1204,     /* Default Interrupt ID */
0136     0x3780,     /* QLC_83XX_IDC_MAJ_VERSION */
0137     0x3784,     /* QLC_83XX_IDC_DEV_STATE */
0138     0x3788,     /* QLC_83XX_IDC_DRV_PRESENCE */
0139     0x378C,     /* QLC_83XX_IDC_DRV_ACK */
0140     0x3790,     /* QLC_83XX_IDC_CTRL */
0141     0x3794,     /* QLC_83XX_IDC_DRV_AUDIT */
0142     0x3798,     /* QLC_83XX_IDC_MIN_VERSION */
0143     0x379C,     /* QLC_83XX_RECOVER_DRV_LOCK */
0144     0x37A0,     /* QLC_83XX_IDC_PF_0 */
0145     0x37A4,     /* QLC_83XX_IDC_PF_1 */
0146     0x37A8,     /* QLC_83XX_IDC_PF_2 */
0147     0x37AC,     /* QLC_83XX_IDC_PF_3 */
0148     0x37B0,     /* QLC_83XX_IDC_PF_4 */
0149     0x37B4,     /* QLC_83XX_IDC_PF_5 */
0150     0x37B8,     /* QLC_83XX_IDC_PF_6 */
0151     0x37BC,     /* QLC_83XX_IDC_PF_7 */
0152     0x37C0,     /* QLC_83XX_IDC_PF_8 */
0153     0x37C4,     /* QLC_83XX_IDC_PF_9 */
0154     0x37C8,     /* QLC_83XX_IDC_PF_10 */
0155     0x37CC,     /* QLC_83XX_IDC_PF_11 */
0156     0x37D0,     /* QLC_83XX_IDC_PF_12 */
0157     0x37D4,     /* QLC_83XX_IDC_PF_13 */
0158     0x37D8,     /* QLC_83XX_IDC_PF_14 */
0159     0x37DC,     /* QLC_83XX_IDC_PF_15 */
0160     0x37E0,     /* QLC_83XX_IDC_DEV_PARTITION_INFO_1 */
0161     0x37E4,     /* QLC_83XX_IDC_DEV_PARTITION_INFO_2 */
0162     0x37F0,     /* QLC_83XX_DRV_OP_MODE */
0163     0x37F4,     /* QLC_83XX_VNIC_STATE */
0164     0x3868,     /* QLC_83XX_DRV_LOCK */
0165     0x386C,     /* QLC_83XX_DRV_UNLOCK */
0166     0x3504,     /* QLC_83XX_DRV_LOCK_ID */
0167     0x34A4,     /* QLC_83XX_ASIC_TEMP */
0168 };
0169 
0170 const u32 qlcnic_83xx_reg_tbl[] = {
0171     0x34A8,     /* PEG_HALT_STAT1 */
0172     0x34AC,     /* PEG_HALT_STAT2 */
0173     0x34B0,     /* FW_HEARTBEAT */
0174     0x3500,     /* FLASH LOCK_ID */
0175     0x3528,     /* FW_CAPABILITIES */
0176     0x3538,     /* Driver active, DRV_REG0 */
0177     0x3540,     /* Device state, DRV_REG1 */
0178     0x3544,     /* Driver state, DRV_REG2 */
0179     0x3548,     /* Driver scratch, DRV_REG3 */
0180     0x354C,     /* Device partition info, DRV_REG4 */
0181     0x3524,     /* Driver IDC ver, DRV_REG5 */
0182     0x3550,     /* FW_VER_MAJOR */
0183     0x3554,     /* FW_VER_MINOR */
0184     0x3558,     /* FW_VER_SUB */
0185     0x359C,     /* NPAR STATE */
0186     0x35FC,     /* FW_IMG_VALID */
0187     0x3650,     /* CMD_PEG_STATE */
0188     0x373C,     /* RCV_PEG_STATE */
0189     0x37B4,     /* ASIC TEMP */
0190     0x356C,     /* FW API */
0191     0x3570,     /* DRV OP MODE */
0192     0x3850,     /* FLASH LOCK */
0193     0x3854,     /* FLASH UNLOCK */
0194 };
0195 
0196 static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = {
0197     .read_crb           = qlcnic_83xx_read_crb,
0198     .write_crb          = qlcnic_83xx_write_crb,
0199     .read_reg           = qlcnic_83xx_rd_reg_indirect,
0200     .write_reg          = qlcnic_83xx_wrt_reg_indirect,
0201     .get_mac_address        = qlcnic_83xx_get_mac_address,
0202     .setup_intr         = qlcnic_83xx_setup_intr,
0203     .alloc_mbx_args         = qlcnic_83xx_alloc_mbx_args,
0204     .mbx_cmd            = qlcnic_83xx_issue_cmd,
0205     .get_func_no            = qlcnic_83xx_get_func_no,
0206     .api_lock           = qlcnic_83xx_cam_lock,
0207     .api_unlock         = qlcnic_83xx_cam_unlock,
0208     .add_sysfs          = qlcnic_83xx_add_sysfs,
0209     .remove_sysfs           = qlcnic_83xx_remove_sysfs,
0210     .process_lb_rcv_ring_diag   = qlcnic_83xx_process_rcv_ring_diag,
0211     .create_rx_ctx          = qlcnic_83xx_create_rx_ctx,
0212     .create_tx_ctx          = qlcnic_83xx_create_tx_ctx,
0213     .del_rx_ctx         = qlcnic_83xx_del_rx_ctx,
0214     .del_tx_ctx         = qlcnic_83xx_del_tx_ctx,
0215     .setup_link_event       = qlcnic_83xx_setup_link_event,
0216     .get_nic_info           = qlcnic_83xx_get_nic_info,
0217     .get_pci_info           = qlcnic_83xx_get_pci_info,
0218     .set_nic_info           = qlcnic_83xx_set_nic_info,
0219     .change_macvlan         = qlcnic_83xx_sre_macaddr_change,
0220     .napi_enable            = qlcnic_83xx_napi_enable,
0221     .napi_disable           = qlcnic_83xx_napi_disable,
0222     .config_intr_coal       = qlcnic_83xx_config_intr_coal,
0223     .config_rss         = qlcnic_83xx_config_rss,
0224     .config_hw_lro          = qlcnic_83xx_config_hw_lro,
0225     .config_promisc_mode        = qlcnic_83xx_nic_set_promisc,
0226     .change_l2_filter       = qlcnic_83xx_change_l2_filter,
0227     .get_board_info         = qlcnic_83xx_get_port_info,
0228     .set_mac_filter_count       = qlcnic_83xx_set_mac_filter_count,
0229     .free_mac_list          = qlcnic_82xx_free_mac_list,
0230     .io_error_detected      = qlcnic_83xx_io_error_detected,
0231     .io_slot_reset          = qlcnic_83xx_io_slot_reset,
0232     .io_resume          = qlcnic_83xx_io_resume,
0233     .get_beacon_state       = qlcnic_83xx_get_beacon_state,
0234     .enable_sds_intr        = qlcnic_83xx_enable_sds_intr,
0235     .disable_sds_intr       = qlcnic_83xx_disable_sds_intr,
0236     .enable_tx_intr         = qlcnic_83xx_enable_tx_intr,
0237     .disable_tx_intr        = qlcnic_83xx_disable_tx_intr,
0238     .get_saved_state        = qlcnic_83xx_get_saved_state,
0239     .set_saved_state        = qlcnic_83xx_set_saved_state,
0240     .cache_tmpl_hdr_values      = qlcnic_83xx_cache_tmpl_hdr_values,
0241     .get_cap_size           = qlcnic_83xx_get_cap_size,
0242     .set_sys_info           = qlcnic_83xx_set_sys_info,
0243     .store_cap_mask         = qlcnic_83xx_store_cap_mask,
0244     .encap_rx_offload       = qlcnic_83xx_encap_rx_offload,
0245     .encap_tx_offload       = qlcnic_83xx_encap_tx_offload,
0246 };
0247 
0248 static struct qlcnic_nic_template qlcnic_83xx_ops = {
0249     .config_bridged_mode    = qlcnic_config_bridged_mode,
0250     .config_led     = qlcnic_config_led,
0251     .request_reset          = qlcnic_83xx_idc_request_reset,
0252     .cancel_idc_work        = qlcnic_83xx_idc_exit,
0253     .napi_add       = qlcnic_83xx_napi_add,
0254     .napi_del       = qlcnic_83xx_napi_del,
0255     .config_ipaddr      = qlcnic_83xx_config_ipaddr,
0256     .clear_legacy_intr  = qlcnic_83xx_clear_legacy_intr,
0257     .shutdown       = qlcnic_83xx_shutdown,
0258     .resume         = qlcnic_83xx_resume,
0259 };
0260 
0261 void qlcnic_83xx_register_map(struct qlcnic_hardware_context *ahw)
0262 {
0263     ahw->hw_ops     = &qlcnic_83xx_hw_ops;
0264     ahw->reg_tbl        = (u32 *)qlcnic_83xx_reg_tbl;
0265     ahw->ext_reg_tbl    = (u32 *)qlcnic_83xx_ext_reg_tbl;
0266 }
0267 
0268 int qlcnic_83xx_get_fw_version(struct qlcnic_adapter *adapter)
0269 {
0270     u32 fw_major, fw_minor, fw_build;
0271     struct pci_dev *pdev = adapter->pdev;
0272 
0273     fw_major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR);
0274     fw_minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR);
0275     fw_build = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB);
0276     adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build);
0277 
0278     dev_info(&pdev->dev, "Driver v%s, firmware version %d.%d.%d\n",
0279          QLCNIC_LINUX_VERSIONID, fw_major, fw_minor, fw_build);
0280 
0281     return adapter->fw_version;
0282 }
0283 
0284 static int __qlcnic_set_win_base(struct qlcnic_adapter *adapter, u32 addr)
0285 {
0286     void __iomem *base;
0287     u32 val;
0288 
0289     base = adapter->ahw->pci_base0 +
0290            QLC_83XX_CRB_WIN_FUNC(adapter->ahw->pci_func);
0291     writel(addr, base);
0292     val = readl(base);
0293     if (val != addr)
0294         return -EIO;
0295 
0296     return 0;
0297 }
0298 
0299 int qlcnic_83xx_rd_reg_indirect(struct qlcnic_adapter *adapter, ulong addr,
0300                 int *err)
0301 {
0302     struct qlcnic_hardware_context *ahw = adapter->ahw;
0303 
0304     *err = __qlcnic_set_win_base(adapter, (u32) addr);
0305     if (!*err) {
0306         return QLCRDX(ahw, QLCNIC_WILDCARD);
0307     } else {
0308         dev_err(&adapter->pdev->dev,
0309             "%s failed, addr = 0x%lx\n", __func__, addr);
0310         return -EIO;
0311     }
0312 }
0313 
0314 int qlcnic_83xx_wrt_reg_indirect(struct qlcnic_adapter *adapter, ulong addr,
0315                  u32 data)
0316 {
0317     int err;
0318     struct qlcnic_hardware_context *ahw = adapter->ahw;
0319 
0320     err = __qlcnic_set_win_base(adapter, (u32) addr);
0321     if (!err) {
0322         QLCWRX(ahw, QLCNIC_WILDCARD, data);
0323         return 0;
0324     } else {
0325         dev_err(&adapter->pdev->dev,
0326             "%s failed, addr = 0x%x data = 0x%x\n",
0327             __func__, (int)addr, data);
0328         return err;
0329     }
0330 }
0331 
0332 static void qlcnic_83xx_enable_legacy(struct qlcnic_adapter *adapter)
0333 {
0334     struct qlcnic_hardware_context *ahw = adapter->ahw;
0335 
0336     /* MSI-X enablement failed, use legacy interrupt */
0337     adapter->tgt_status_reg = ahw->pci_base0 + QLC_83XX_INTX_PTR;
0338     adapter->tgt_mask_reg = ahw->pci_base0 + QLC_83XX_INTX_MASK;
0339     adapter->isr_int_vec = ahw->pci_base0 + QLC_83XX_INTX_TRGR;
0340     adapter->msix_entries[0].vector = adapter->pdev->irq;
0341     dev_info(&adapter->pdev->dev, "using legacy interrupt\n");
0342 }
0343 
0344 static int qlcnic_83xx_calculate_msix_vector(struct qlcnic_adapter *adapter)
0345 {
0346     int num_msix;
0347 
0348     num_msix = adapter->drv_sds_rings;
0349 
0350     /* account for AEN interrupt MSI-X based interrupts */
0351     num_msix += 1;
0352 
0353     if (!(adapter->flags & QLCNIC_TX_INTR_SHARED))
0354         num_msix += adapter->drv_tx_rings;
0355 
0356     return num_msix;
0357 }
0358 
0359 int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter)
0360 {
0361     struct qlcnic_hardware_context *ahw = adapter->ahw;
0362     int err, i, num_msix;
0363 
0364     if (adapter->flags & QLCNIC_TSS_RSS) {
0365         err = qlcnic_setup_tss_rss_intr(adapter);
0366         if (err < 0)
0367             return err;
0368         num_msix = ahw->num_msix;
0369     } else {
0370         num_msix = qlcnic_83xx_calculate_msix_vector(adapter);
0371 
0372         err = qlcnic_enable_msix(adapter, num_msix);
0373         if (err == -ENOMEM)
0374             return err;
0375 
0376         if (adapter->flags & QLCNIC_MSIX_ENABLED) {
0377             num_msix = ahw->num_msix;
0378         } else {
0379             if (qlcnic_sriov_vf_check(adapter))
0380                 return -EINVAL;
0381             num_msix = 1;
0382             adapter->drv_sds_rings = QLCNIC_SINGLE_RING;
0383             adapter->drv_tx_rings = QLCNIC_SINGLE_RING;
0384         }
0385     }
0386 
0387     /* setup interrupt mapping table for fw */
0388     ahw->intr_tbl =
0389         vzalloc(array_size(num_msix,
0390                    sizeof(struct qlcnic_intrpt_config)));
0391     if (!ahw->intr_tbl)
0392         return -ENOMEM;
0393 
0394     if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
0395         if (adapter->ahw->pci_func >= QLC_MAX_LEGACY_FUNC_SUPP) {
0396             dev_err(&adapter->pdev->dev, "PCI function number 8 and higher are not supported with legacy interrupt, func 0x%x\n",
0397                 ahw->pci_func);
0398             return -EOPNOTSUPP;
0399         }
0400 
0401         qlcnic_83xx_enable_legacy(adapter);
0402     }
0403 
0404     for (i = 0; i < num_msix; i++) {
0405         if (adapter->flags & QLCNIC_MSIX_ENABLED)
0406             ahw->intr_tbl[i].type = QLCNIC_INTRPT_MSIX;
0407         else
0408             ahw->intr_tbl[i].type = QLCNIC_INTRPT_INTX;
0409         ahw->intr_tbl[i].id = i;
0410         ahw->intr_tbl[i].src = 0;
0411     }
0412 
0413     return 0;
0414 }
0415 
0416 static inline void qlcnic_83xx_clear_legacy_intr_mask(struct qlcnic_adapter *adapter)
0417 {
0418     writel(0, adapter->tgt_mask_reg);
0419 }
0420 
0421 static inline void qlcnic_83xx_set_legacy_intr_mask(struct qlcnic_adapter *adapter)
0422 {
0423     if (adapter->tgt_mask_reg)
0424         writel(1, adapter->tgt_mask_reg);
0425 }
0426 
0427 static inline void qlcnic_83xx_enable_legacy_msix_mbx_intr(struct qlcnic_adapter
0428                             *adapter)
0429 {
0430     u32 mask;
0431 
0432     /* Mailbox in MSI-x mode and Legacy Interrupt share the same
0433      * source register. We could be here before contexts are created
0434      * and sds_ring->crb_intr_mask has not been initialized, calculate
0435      * BAR offset for Interrupt Source Register
0436      */
0437     mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
0438     writel(0, adapter->ahw->pci_base0 + mask);
0439 }
0440 
0441 void qlcnic_83xx_disable_mbx_intr(struct qlcnic_adapter *adapter)
0442 {
0443     u32 mask;
0444 
0445     mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
0446     writel(1, adapter->ahw->pci_base0 + mask);
0447     QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, 0);
0448 }
0449 
0450 static inline void qlcnic_83xx_get_mbx_data(struct qlcnic_adapter *adapter,
0451                      struct qlcnic_cmd_args *cmd)
0452 {
0453     int i;
0454 
0455     if (cmd->op_type == QLC_83XX_MBX_POST_BC_OP)
0456         return;
0457 
0458     for (i = 0; i < cmd->rsp.num; i++)
0459         cmd->rsp.arg[i] = readl(QLCNIC_MBX_FW(adapter->ahw, i));
0460 }
0461 
0462 irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *adapter)
0463 {
0464     u32 intr_val;
0465     struct qlcnic_hardware_context *ahw = adapter->ahw;
0466     int retries = 0;
0467 
0468     intr_val = readl(adapter->tgt_status_reg);
0469 
0470     if (!QLC_83XX_VALID_INTX_BIT31(intr_val))
0471         return IRQ_NONE;
0472 
0473     if (QLC_83XX_INTX_FUNC(intr_val) != adapter->ahw->pci_func) {
0474         adapter->stats.spurious_intr++;
0475         return IRQ_NONE;
0476     }
0477     /* The barrier is required to ensure writes to the registers */
0478     wmb();
0479 
0480     /* clear the interrupt trigger control register */
0481     writel_relaxed(0, adapter->isr_int_vec);
0482     intr_val = readl(adapter->isr_int_vec);
0483     do {
0484         intr_val = readl(adapter->tgt_status_reg);
0485         if (QLC_83XX_INTX_FUNC(intr_val) != ahw->pci_func)
0486             break;
0487         retries++;
0488     } while (QLC_83XX_VALID_INTX_BIT30(intr_val) &&
0489          (retries < QLC_83XX_LEGACY_INTX_MAX_RETRY));
0490 
0491     return IRQ_HANDLED;
0492 }
0493 
0494 static inline void qlcnic_83xx_notify_mbx_response(struct qlcnic_mailbox *mbx)
0495 {
0496     mbx->rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
0497     complete(&mbx->completion);
0498 }
0499 
0500 static void qlcnic_83xx_poll_process_aen(struct qlcnic_adapter *adapter)
0501 {
0502     u32 resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
0503     struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
0504     unsigned long flags;
0505 
0506     spin_lock_irqsave(&mbx->aen_lock, flags);
0507     resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
0508     if (!(resp & QLCNIC_SET_OWNER))
0509         goto out;
0510 
0511     event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
0512     if (event &  QLCNIC_MBX_ASYNC_EVENT) {
0513         __qlcnic_83xx_process_aen(adapter);
0514     } else {
0515         if (mbx->rsp_status != rsp_status)
0516             qlcnic_83xx_notify_mbx_response(mbx);
0517     }
0518 out:
0519     qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
0520     spin_unlock_irqrestore(&mbx->aen_lock, flags);
0521 }
0522 
0523 irqreturn_t qlcnic_83xx_intr(int irq, void *data)
0524 {
0525     struct qlcnic_adapter *adapter = data;
0526     struct qlcnic_host_sds_ring *sds_ring;
0527     struct qlcnic_hardware_context *ahw = adapter->ahw;
0528 
0529     if (qlcnic_83xx_clear_legacy_intr(adapter) == IRQ_NONE)
0530         return IRQ_NONE;
0531 
0532     qlcnic_83xx_poll_process_aen(adapter);
0533 
0534     if (ahw->diag_test) {
0535         if (ahw->diag_test == QLCNIC_INTERRUPT_TEST)
0536             ahw->diag_cnt++;
0537         qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
0538         return IRQ_HANDLED;
0539     }
0540 
0541     if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
0542         qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
0543     } else {
0544         sds_ring = &adapter->recv_ctx->sds_rings[0];
0545         napi_schedule(&sds_ring->napi);
0546     }
0547 
0548     return IRQ_HANDLED;
0549 }
0550 
0551 irqreturn_t qlcnic_83xx_tmp_intr(int irq, void *data)
0552 {
0553     struct qlcnic_host_sds_ring *sds_ring = data;
0554     struct qlcnic_adapter *adapter = sds_ring->adapter;
0555 
0556     if (adapter->flags & QLCNIC_MSIX_ENABLED)
0557         goto done;
0558 
0559     if (adapter->nic_ops->clear_legacy_intr(adapter) == IRQ_NONE)
0560         return IRQ_NONE;
0561 
0562 done:
0563     adapter->ahw->diag_cnt++;
0564     qlcnic_enable_sds_intr(adapter, sds_ring);
0565 
0566     return IRQ_HANDLED;
0567 }
0568 
0569 void qlcnic_83xx_free_mbx_intr(struct qlcnic_adapter *adapter)
0570 {
0571     u32 num_msix;
0572 
0573     if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
0574         qlcnic_83xx_set_legacy_intr_mask(adapter);
0575 
0576     qlcnic_83xx_disable_mbx_intr(adapter);
0577 
0578     if (adapter->flags & QLCNIC_MSIX_ENABLED)
0579         num_msix = adapter->ahw->num_msix - 1;
0580     else
0581         num_msix = 0;
0582 
0583     msleep(20);
0584 
0585     if (adapter->msix_entries) {
0586         synchronize_irq(adapter->msix_entries[num_msix].vector);
0587         free_irq(adapter->msix_entries[num_msix].vector, adapter);
0588     }
0589 }
0590 
0591 int qlcnic_83xx_setup_mbx_intr(struct qlcnic_adapter *adapter)
0592 {
0593     irq_handler_t handler;
0594     u32 val;
0595     int err = 0;
0596     unsigned long flags = 0;
0597 
0598     if (!(adapter->flags & QLCNIC_MSI_ENABLED) &&
0599         !(adapter->flags & QLCNIC_MSIX_ENABLED))
0600         flags |= IRQF_SHARED;
0601 
0602     if (adapter->flags & QLCNIC_MSIX_ENABLED) {
0603         handler = qlcnic_83xx_handle_aen;
0604         val = adapter->msix_entries[adapter->ahw->num_msix - 1].vector;
0605         err = request_irq(val, handler, flags, "qlcnic-MB", adapter);
0606         if (err) {
0607             dev_err(&adapter->pdev->dev,
0608                 "failed to register MBX interrupt\n");
0609             return err;
0610         }
0611     } else {
0612         handler = qlcnic_83xx_intr;
0613         val = adapter->msix_entries[0].vector;
0614         err = request_irq(val, handler, flags, "qlcnic", adapter);
0615         if (err) {
0616             dev_err(&adapter->pdev->dev,
0617                 "failed to register INTx interrupt\n");
0618             return err;
0619         }
0620         qlcnic_83xx_clear_legacy_intr_mask(adapter);
0621     }
0622 
0623     /* Enable mailbox interrupt */
0624     qlcnic_83xx_enable_mbx_interrupt(adapter);
0625 
0626     return err;
0627 }
0628 
0629 void qlcnic_83xx_get_func_no(struct qlcnic_adapter *adapter)
0630 {
0631     u32 val = QLCRDX(adapter->ahw, QLCNIC_INFORMANT);
0632     adapter->ahw->pci_func = (val >> 24) & 0xff;
0633 }
0634 
0635 int qlcnic_83xx_cam_lock(struct qlcnic_adapter *adapter)
0636 {
0637     void __iomem *addr;
0638     u32 val, limit = 0;
0639 
0640     struct qlcnic_hardware_context *ahw = adapter->ahw;
0641 
0642     addr = ahw->pci_base0 + QLC_83XX_SEM_LOCK_FUNC(ahw->pci_func);
0643     do {
0644         val = readl(addr);
0645         if (val) {
0646             /* write the function number to register */
0647             QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER,
0648                         ahw->pci_func);
0649             return 0;
0650         }
0651         usleep_range(1000, 2000);
0652     } while (++limit <= QLCNIC_PCIE_SEM_TIMEOUT);
0653 
0654     return -EIO;
0655 }
0656 
0657 void qlcnic_83xx_cam_unlock(struct qlcnic_adapter *adapter)
0658 {
0659     void __iomem *addr;
0660     struct qlcnic_hardware_context *ahw = adapter->ahw;
0661 
0662     addr = ahw->pci_base0 + QLC_83XX_SEM_UNLOCK_FUNC(ahw->pci_func);
0663     readl(addr);
0664 }
0665 
0666 void qlcnic_83xx_read_crb(struct qlcnic_adapter *adapter, char *buf,
0667               loff_t offset, size_t size)
0668 {
0669     int ret = 0;
0670     u32 data;
0671 
0672     if (qlcnic_api_lock(adapter)) {
0673         dev_err(&adapter->pdev->dev,
0674             "%s: failed to acquire lock. addr offset 0x%x\n",
0675             __func__, (u32)offset);
0676         return;
0677     }
0678 
0679     data = QLCRD32(adapter, (u32) offset, &ret);
0680     qlcnic_api_unlock(adapter);
0681 
0682     if (ret == -EIO) {
0683         dev_err(&adapter->pdev->dev,
0684             "%s: failed. addr offset 0x%x\n",
0685             __func__, (u32)offset);
0686         return;
0687     }
0688     memcpy(buf, &data, size);
0689 }
0690 
0691 void qlcnic_83xx_write_crb(struct qlcnic_adapter *adapter, char *buf,
0692                loff_t offset, size_t size)
0693 {
0694     u32 data;
0695 
0696     memcpy(&data, buf, size);
0697     qlcnic_83xx_wrt_reg_indirect(adapter, (u32) offset, data);
0698 }
0699 
0700 int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter)
0701 {
0702     struct qlcnic_hardware_context *ahw = adapter->ahw;
0703     int status;
0704 
0705     status = qlcnic_83xx_get_port_config(adapter);
0706     if (status) {
0707         dev_err(&adapter->pdev->dev,
0708             "Get Port Info failed\n");
0709     } else {
0710 
0711         if (ahw->port_config & QLC_83XX_10G_CAPABLE) {
0712             ahw->port_type = QLCNIC_XGBE;
0713         } else if (ahw->port_config & QLC_83XX_10_CAPABLE ||
0714                ahw->port_config & QLC_83XX_100_CAPABLE ||
0715                ahw->port_config & QLC_83XX_1G_CAPABLE) {
0716             ahw->port_type = QLCNIC_GBE;
0717         } else {
0718             ahw->port_type = QLCNIC_XGBE;
0719         }
0720 
0721         if (QLC_83XX_AUTONEG(ahw->port_config))
0722             ahw->link_autoneg = AUTONEG_ENABLE;
0723 
0724     }
0725     return status;
0726 }
0727 
0728 static void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *adapter)
0729 {
0730     struct qlcnic_hardware_context *ahw = adapter->ahw;
0731     u16 act_pci_fn = ahw->total_nic_func;
0732     u16 count;
0733 
0734     ahw->max_mc_count = QLC_83XX_MAX_MC_COUNT;
0735     if (act_pci_fn <= 2)
0736         count = (QLC_83XX_MAX_UC_COUNT - QLC_83XX_MAX_MC_COUNT) /
0737              act_pci_fn;
0738     else
0739         count = (QLC_83XX_LB_MAX_FILTERS - QLC_83XX_MAX_MC_COUNT) /
0740              act_pci_fn;
0741     ahw->max_uc_count = count;
0742 }
0743 
0744 void qlcnic_83xx_enable_mbx_interrupt(struct qlcnic_adapter *adapter)
0745 {
0746     u32 val;
0747 
0748     if (adapter->flags & QLCNIC_MSIX_ENABLED)
0749         val = BIT_2 | ((adapter->ahw->num_msix - 1) << 8);
0750     else
0751         val = BIT_2;
0752 
0753     QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, val);
0754     qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
0755 }
0756 
0757 void qlcnic_83xx_check_vf(struct qlcnic_adapter *adapter,
0758               const struct pci_device_id *ent)
0759 {
0760     u32 op_mode, priv_level;
0761     struct qlcnic_hardware_context *ahw = adapter->ahw;
0762 
0763     ahw->fw_hal_version = 2;
0764     qlcnic_get_func_no(adapter);
0765 
0766     if (qlcnic_sriov_vf_check(adapter)) {
0767         qlcnic_sriov_vf_set_ops(adapter);
0768         return;
0769     }
0770 
0771     /* Determine function privilege level */
0772     op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
0773     if (op_mode == QLC_83XX_DEFAULT_OPMODE)
0774         priv_level = QLCNIC_MGMT_FUNC;
0775     else
0776         priv_level = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode,
0777                              ahw->pci_func);
0778 
0779     if (priv_level == QLCNIC_NON_PRIV_FUNC) {
0780         ahw->op_mode = QLCNIC_NON_PRIV_FUNC;
0781         dev_info(&adapter->pdev->dev,
0782              "HAL Version: %d Non Privileged function\n",
0783              ahw->fw_hal_version);
0784         adapter->nic_ops = &qlcnic_vf_ops;
0785     } else {
0786         if (pci_find_ext_capability(adapter->pdev,
0787                         PCI_EXT_CAP_ID_SRIOV))
0788             set_bit(__QLCNIC_SRIOV_CAPABLE, &adapter->state);
0789         adapter->nic_ops = &qlcnic_83xx_ops;
0790     }
0791 }
0792 
0793 static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
0794                     u32 data[]);
0795 static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
0796                         u32 data[]);
0797 
0798 void qlcnic_dump_mbx(struct qlcnic_adapter *adapter,
0799              struct qlcnic_cmd_args *cmd)
0800 {
0801     int i;
0802 
0803     if (cmd->op_type == QLC_83XX_MBX_POST_BC_OP)
0804         return;
0805 
0806     dev_info(&adapter->pdev->dev,
0807          "Host MBX regs(%d)\n", cmd->req.num);
0808     for (i = 0; i < cmd->req.num; i++) {
0809         if (i && !(i % 8))
0810             pr_info("\n");
0811         pr_info("%08x ", cmd->req.arg[i]);
0812     }
0813     pr_info("\n");
0814     dev_info(&adapter->pdev->dev,
0815          "FW MBX regs(%d)\n", cmd->rsp.num);
0816     for (i = 0; i < cmd->rsp.num; i++) {
0817         if (i && !(i % 8))
0818             pr_info("\n");
0819         pr_info("%08x ", cmd->rsp.arg[i]);
0820     }
0821     pr_info("\n");
0822 }
0823 
0824 static void qlcnic_83xx_poll_for_mbx_completion(struct qlcnic_adapter *adapter,
0825                         struct qlcnic_cmd_args *cmd)
0826 {
0827     struct qlcnic_hardware_context *ahw = adapter->ahw;
0828     int opcode = LSW(cmd->req.arg[0]);
0829     unsigned long max_loops;
0830 
0831     max_loops = cmd->total_cmds * QLC_83XX_MBX_CMD_LOOP;
0832 
0833     for (; max_loops; max_loops--) {
0834         if (atomic_read(&cmd->rsp_status) ==
0835             QLC_83XX_MBX_RESPONSE_ARRIVED)
0836             return;
0837 
0838         udelay(1);
0839     }
0840 
0841     dev_err(&adapter->pdev->dev,
0842         "%s: Mailbox command timed out, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
0843         __func__, opcode, cmd->type, ahw->pci_func, ahw->op_mode);
0844     flush_workqueue(ahw->mailbox->work_q);
0845     return;
0846 }
0847 
0848 int qlcnic_83xx_issue_cmd(struct qlcnic_adapter *adapter,
0849               struct qlcnic_cmd_args *cmd)
0850 {
0851     struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
0852     struct qlcnic_hardware_context *ahw = adapter->ahw;
0853     int cmd_type, err, opcode;
0854     unsigned long timeout;
0855 
0856     if (!mbx)
0857         return -EIO;
0858 
0859     opcode = LSW(cmd->req.arg[0]);
0860     cmd_type = cmd->type;
0861     err = mbx->ops->enqueue_cmd(adapter, cmd, &timeout);
0862     if (err) {
0863         dev_err(&adapter->pdev->dev,
0864             "%s: Mailbox not available, cmd_op=0x%x, cmd_context=0x%x, pci_func=0x%x, op_mode=0x%x\n",
0865             __func__, opcode, cmd->type, ahw->pci_func,
0866             ahw->op_mode);
0867         return err;
0868     }
0869 
0870     switch (cmd_type) {
0871     case QLC_83XX_MBX_CMD_WAIT:
0872         if (!wait_for_completion_timeout(&cmd->completion, timeout)) {
0873             dev_err(&adapter->pdev->dev,
0874                 "%s: Mailbox command timed out, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
0875                 __func__, opcode, cmd_type, ahw->pci_func,
0876                 ahw->op_mode);
0877             flush_workqueue(mbx->work_q);
0878         }
0879         break;
0880     case QLC_83XX_MBX_CMD_NO_WAIT:
0881         return 0;
0882     case QLC_83XX_MBX_CMD_BUSY_WAIT:
0883         qlcnic_83xx_poll_for_mbx_completion(adapter, cmd);
0884         break;
0885     default:
0886         dev_err(&adapter->pdev->dev,
0887             "%s: Invalid mailbox command, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
0888             __func__, opcode, cmd_type, ahw->pci_func,
0889             ahw->op_mode);
0890         qlcnic_83xx_detach_mailbox_work(adapter);
0891     }
0892 
0893     return cmd->rsp_opcode;
0894 }
0895 
0896 int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx,
0897                    struct qlcnic_adapter *adapter, u32 type)
0898 {
0899     int i, size;
0900     u32 temp;
0901     const struct qlcnic_mailbox_metadata *mbx_tbl;
0902 
0903     memset(mbx, 0, sizeof(struct qlcnic_cmd_args));
0904     mbx_tbl = qlcnic_83xx_mbx_tbl;
0905     size = ARRAY_SIZE(qlcnic_83xx_mbx_tbl);
0906     for (i = 0; i < size; i++) {
0907         if (type == mbx_tbl[i].cmd) {
0908             mbx->op_type = QLC_83XX_FW_MBX_CMD;
0909             mbx->req.num = mbx_tbl[i].in_args;
0910             mbx->rsp.num = mbx_tbl[i].out_args;
0911             mbx->req.arg = kcalloc(mbx->req.num, sizeof(u32),
0912                            GFP_ATOMIC);
0913             if (!mbx->req.arg)
0914                 return -ENOMEM;
0915             mbx->rsp.arg = kcalloc(mbx->rsp.num, sizeof(u32),
0916                            GFP_ATOMIC);
0917             if (!mbx->rsp.arg) {
0918                 kfree(mbx->req.arg);
0919                 mbx->req.arg = NULL;
0920                 return -ENOMEM;
0921             }
0922             temp = adapter->ahw->fw_hal_version << 29;
0923             mbx->req.arg[0] = (type | (mbx->req.num << 16) | temp);
0924             mbx->cmd_op = type;
0925             return 0;
0926         }
0927     }
0928 
0929     dev_err(&adapter->pdev->dev, "%s: Invalid mailbox command opcode 0x%x\n",
0930         __func__, type);
0931     return -EINVAL;
0932 }
0933 
0934 void qlcnic_83xx_idc_aen_work(struct work_struct *work)
0935 {
0936     struct qlcnic_adapter *adapter;
0937     struct qlcnic_cmd_args cmd;
0938     int i, err = 0;
0939 
0940     adapter = container_of(work, struct qlcnic_adapter, idc_aen_work.work);
0941     err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_IDC_ACK);
0942     if (err)
0943         return;
0944 
0945     for (i = 1; i < QLC_83XX_MBX_AEN_CNT; i++)
0946         cmd.req.arg[i] = adapter->ahw->mbox_aen[i];
0947 
0948     err = qlcnic_issue_cmd(adapter, &cmd);
0949     if (err)
0950         dev_info(&adapter->pdev->dev,
0951              "%s: Mailbox IDC ACK failed.\n", __func__);
0952     qlcnic_free_mbx_args(&cmd);
0953 }
0954 
0955 static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
0956                         u32 data[])
0957 {
0958     dev_dbg(&adapter->pdev->dev, "Completion AEN:0x%x.\n",
0959         QLCNIC_MBX_RSP(data[0]));
0960     clear_bit(QLC_83XX_IDC_COMP_AEN, &adapter->ahw->idc.status);
0961     return;
0962 }
0963 
0964 static void __qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
0965 {
0966     struct qlcnic_hardware_context *ahw = adapter->ahw;
0967     u32 event[QLC_83XX_MBX_AEN_CNT];
0968     int i;
0969 
0970     for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
0971         event[i] = readl(QLCNIC_MBX_FW(ahw, i));
0972 
0973     switch (QLCNIC_MBX_RSP(event[0])) {
0974 
0975     case QLCNIC_MBX_LINK_EVENT:
0976         qlcnic_83xx_handle_link_aen(adapter, event);
0977         break;
0978     case QLCNIC_MBX_COMP_EVENT:
0979         qlcnic_83xx_handle_idc_comp_aen(adapter, event);
0980         break;
0981     case QLCNIC_MBX_REQUEST_EVENT:
0982         for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
0983             adapter->ahw->mbox_aen[i] = QLCNIC_MBX_RSP(event[i]);
0984         queue_delayed_work(adapter->qlcnic_wq,
0985                    &adapter->idc_aen_work, 0);
0986         break;
0987     case QLCNIC_MBX_TIME_EXTEND_EVENT:
0988         ahw->extend_lb_time = event[1] >> 8 & 0xf;
0989         break;
0990     case QLCNIC_MBX_BC_EVENT:
0991         qlcnic_sriov_handle_bc_event(adapter, event[1]);
0992         break;
0993     case QLCNIC_MBX_SFP_INSERT_EVENT:
0994         dev_info(&adapter->pdev->dev, "SFP+ Insert AEN:0x%x.\n",
0995              QLCNIC_MBX_RSP(event[0]));
0996         break;
0997     case QLCNIC_MBX_SFP_REMOVE_EVENT:
0998         dev_info(&adapter->pdev->dev, "SFP Removed AEN:0x%x.\n",
0999              QLCNIC_MBX_RSP(event[0]));
1000         break;
1001     case QLCNIC_MBX_DCBX_CONFIG_CHANGE_EVENT:
1002         qlcnic_dcb_aen_handler(adapter->dcb, (void *)&event[1]);
1003         break;
1004     default:
1005         dev_dbg(&adapter->pdev->dev, "Unsupported AEN:0x%x.\n",
1006             QLCNIC_MBX_RSP(event[0]));
1007         break;
1008     }
1009 
1010     QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
1011 }
1012 
1013 static void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
1014 {
1015     u32 resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
1016     struct qlcnic_hardware_context *ahw = adapter->ahw;
1017     struct qlcnic_mailbox *mbx = ahw->mailbox;
1018     unsigned long flags;
1019 
1020     spin_lock_irqsave(&mbx->aen_lock, flags);
1021     resp = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
1022     if (resp & QLCNIC_SET_OWNER) {
1023         event = readl(QLCNIC_MBX_FW(ahw, 0));
1024         if (event &  QLCNIC_MBX_ASYNC_EVENT) {
1025             __qlcnic_83xx_process_aen(adapter);
1026         } else {
1027             if (mbx->rsp_status != rsp_status)
1028                 qlcnic_83xx_notify_mbx_response(mbx);
1029         }
1030     }
1031     spin_unlock_irqrestore(&mbx->aen_lock, flags);
1032 }
1033 
1034 static void qlcnic_83xx_mbx_poll_work(struct work_struct *work)
1035 {
1036     struct qlcnic_adapter *adapter;
1037 
1038     adapter = container_of(work, struct qlcnic_adapter, mbx_poll_work.work);
1039 
1040     if (!test_bit(__QLCNIC_MBX_POLL_ENABLE, &adapter->state))
1041         return;
1042 
1043     qlcnic_83xx_process_aen(adapter);
1044     queue_delayed_work(adapter->qlcnic_wq, &adapter->mbx_poll_work,
1045                (HZ / 10));
1046 }
1047 
1048 void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *adapter)
1049 {
1050     if (test_and_set_bit(__QLCNIC_MBX_POLL_ENABLE, &adapter->state))
1051         return;
1052 
1053     INIT_DELAYED_WORK(&adapter->mbx_poll_work, qlcnic_83xx_mbx_poll_work);
1054     queue_delayed_work(adapter->qlcnic_wq, &adapter->mbx_poll_work, 0);
1055 }
1056 
1057 void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *adapter)
1058 {
1059     if (!test_and_clear_bit(__QLCNIC_MBX_POLL_ENABLE, &adapter->state))
1060         return;
1061     cancel_delayed_work_sync(&adapter->mbx_poll_work);
1062 }
1063 
1064 static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)
1065 {
1066     int index, i, err, sds_mbx_size;
1067     u32 *buf, intrpt_id, intr_mask;
1068     u16 context_id;
1069     u8 num_sds;
1070     struct qlcnic_cmd_args cmd;
1071     struct qlcnic_host_sds_ring *sds;
1072     struct qlcnic_sds_mbx sds_mbx;
1073     struct qlcnic_add_rings_mbx_out *mbx_out;
1074     struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1075     struct qlcnic_hardware_context *ahw = adapter->ahw;
1076 
1077     sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
1078     context_id = recv_ctx->context_id;
1079     num_sds = adapter->drv_sds_rings - QLCNIC_MAX_SDS_RINGS;
1080     err = ahw->hw_ops->alloc_mbx_args(&cmd, adapter,
1081                     QLCNIC_CMD_ADD_RCV_RINGS);
1082     if (err) {
1083         dev_err(&adapter->pdev->dev,
1084             "Failed to alloc mbx args %d\n", err);
1085         return err;
1086     }
1087 
1088     cmd.req.arg[1] = 0 | (num_sds << 8) | (context_id << 16);
1089 
1090     /* set up status rings, mbx 2-81 */
1091     index = 2;
1092     for (i = 8; i < adapter->drv_sds_rings; i++) {
1093         memset(&sds_mbx, 0, sds_mbx_size);
1094         sds = &recv_ctx->sds_rings[i];
1095         sds->consumer = 0;
1096         memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
1097         sds_mbx.phy_addr_low = LSD(sds->phys_addr);
1098         sds_mbx.phy_addr_high = MSD(sds->phys_addr);
1099         sds_mbx.sds_ring_size = sds->num_desc;
1100 
1101         if (adapter->flags & QLCNIC_MSIX_ENABLED)
1102             intrpt_id = ahw->intr_tbl[i].id;
1103         else
1104             intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
1105 
1106         if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
1107             sds_mbx.intrpt_id = intrpt_id;
1108         else
1109             sds_mbx.intrpt_id = 0xffff;
1110         sds_mbx.intrpt_val = 0;
1111         buf = &cmd.req.arg[index];
1112         memcpy(buf, &sds_mbx, sds_mbx_size);
1113         index += sds_mbx_size / sizeof(u32);
1114     }
1115 
1116     /* send the mailbox command */
1117     err = ahw->hw_ops->mbx_cmd(adapter, &cmd);
1118     if (err) {
1119         dev_err(&adapter->pdev->dev,
1120             "Failed to add rings %d\n", err);
1121         goto out;
1122     }
1123 
1124     mbx_out = (struct qlcnic_add_rings_mbx_out *)&cmd.rsp.arg[1];
1125     index = 0;
1126     /* status descriptor ring */
1127     for (i = 8; i < adapter->drv_sds_rings; i++) {
1128         sds = &recv_ctx->sds_rings[i];
1129         sds->crb_sts_consumer = ahw->pci_base0 +
1130                     mbx_out->host_csmr[index];
1131         if (adapter->flags & QLCNIC_MSIX_ENABLED)
1132             intr_mask = ahw->intr_tbl[i].src;
1133         else
1134             intr_mask = QLCRDX(ahw, QLCNIC_DEF_INT_MASK);
1135 
1136         sds->crb_intr_mask = ahw->pci_base0 + intr_mask;
1137         index++;
1138     }
1139 out:
1140     qlcnic_free_mbx_args(&cmd);
1141     return err;
1142 }
1143 
1144 void qlcnic_83xx_del_rx_ctx(struct qlcnic_adapter *adapter)
1145 {
1146     int err;
1147     u32 temp = 0;
1148     struct qlcnic_cmd_args cmd;
1149     struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1150 
1151     if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_RX_CTX))
1152         return;
1153 
1154     if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
1155         cmd.req.arg[0] |= (0x3 << 29);
1156 
1157     if (qlcnic_sriov_pf_check(adapter))
1158         qlcnic_pf_set_interface_id_del_rx_ctx(adapter, &temp);
1159 
1160     cmd.req.arg[1] = recv_ctx->context_id | temp;
1161     err = qlcnic_issue_cmd(adapter, &cmd);
1162     if (err)
1163         dev_err(&adapter->pdev->dev,
1164             "Failed to destroy rx ctx in firmware\n");
1165 
1166     recv_ctx->state = QLCNIC_HOST_CTX_STATE_FREED;
1167     qlcnic_free_mbx_args(&cmd);
1168 }
1169 
1170 int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter)
1171 {
1172     int i, err, index, sds_mbx_size, rds_mbx_size;
1173     u8 num_sds, num_rds;
1174     u32 *buf, intrpt_id, intr_mask, cap = 0;
1175     struct qlcnic_host_sds_ring *sds;
1176     struct qlcnic_host_rds_ring *rds;
1177     struct qlcnic_sds_mbx sds_mbx;
1178     struct qlcnic_rds_mbx rds_mbx;
1179     struct qlcnic_cmd_args cmd;
1180     struct qlcnic_rcv_mbx_out *mbx_out;
1181     struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1182     struct qlcnic_hardware_context *ahw = adapter->ahw;
1183     num_rds = adapter->max_rds_rings;
1184 
1185     if (adapter->drv_sds_rings <= QLCNIC_MAX_SDS_RINGS)
1186         num_sds = adapter->drv_sds_rings;
1187     else
1188         num_sds = QLCNIC_MAX_SDS_RINGS;
1189 
1190     sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
1191     rds_mbx_size = sizeof(struct qlcnic_rds_mbx);
1192     cap = QLCNIC_CAP0_LEGACY_CONTEXT;
1193 
1194     if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP)
1195         cap |= QLC_83XX_FW_CAP_LRO_MSS;
1196 
1197     /* set mailbox hdr and capabilities */
1198     err = qlcnic_alloc_mbx_args(&cmd, adapter,
1199                     QLCNIC_CMD_CREATE_RX_CTX);
1200     if (err)
1201         return err;
1202 
1203     if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
1204         cmd.req.arg[0] |= (0x3 << 29);
1205 
1206     cmd.req.arg[1] = cap;
1207     cmd.req.arg[5] = 1 | (num_rds << 5) | (num_sds << 8) |
1208              (QLC_83XX_HOST_RDS_MODE_UNIQUE << 16);
1209 
1210     if (qlcnic_sriov_pf_check(adapter))
1211         qlcnic_pf_set_interface_id_create_rx_ctx(adapter,
1212                              &cmd.req.arg[6]);
1213     /* set up status rings, mbx 8-57/87 */
1214     index = QLC_83XX_HOST_SDS_MBX_IDX;
1215     for (i = 0; i < num_sds; i++) {
1216         memset(&sds_mbx, 0, sds_mbx_size);
1217         sds = &recv_ctx->sds_rings[i];
1218         sds->consumer = 0;
1219         memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
1220         sds_mbx.phy_addr_low = LSD(sds->phys_addr);
1221         sds_mbx.phy_addr_high = MSD(sds->phys_addr);
1222         sds_mbx.sds_ring_size = sds->num_desc;
1223         if (adapter->flags & QLCNIC_MSIX_ENABLED)
1224             intrpt_id = ahw->intr_tbl[i].id;
1225         else
1226             intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
1227         if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
1228             sds_mbx.intrpt_id = intrpt_id;
1229         else
1230             sds_mbx.intrpt_id = 0xffff;
1231         sds_mbx.intrpt_val = 0;
1232         buf = &cmd.req.arg[index];
1233         memcpy(buf, &sds_mbx, sds_mbx_size);
1234         index += sds_mbx_size / sizeof(u32);
1235     }
1236     /* set up receive rings, mbx 88-111/135 */
1237     index = QLCNIC_HOST_RDS_MBX_IDX;
1238     rds = &recv_ctx->rds_rings[0];
1239     rds->producer = 0;
1240     memset(&rds_mbx, 0, rds_mbx_size);
1241     rds_mbx.phy_addr_reg_low = LSD(rds->phys_addr);
1242     rds_mbx.phy_addr_reg_high = MSD(rds->phys_addr);
1243     rds_mbx.reg_ring_sz = rds->dma_size;
1244     rds_mbx.reg_ring_len = rds->num_desc;
1245     /* Jumbo ring */
1246     rds = &recv_ctx->rds_rings[1];
1247     rds->producer = 0;
1248     rds_mbx.phy_addr_jmb_low = LSD(rds->phys_addr);
1249     rds_mbx.phy_addr_jmb_high = MSD(rds->phys_addr);
1250     rds_mbx.jmb_ring_sz = rds->dma_size;
1251     rds_mbx.jmb_ring_len = rds->num_desc;
1252     buf = &cmd.req.arg[index];
1253     memcpy(buf, &rds_mbx, rds_mbx_size);
1254 
1255     /* send the mailbox command */
1256     err = ahw->hw_ops->mbx_cmd(adapter, &cmd);
1257     if (err) {
1258         dev_err(&adapter->pdev->dev,
1259             "Failed to create Rx ctx in firmware%d\n", err);
1260         goto out;
1261     }
1262     mbx_out = (struct qlcnic_rcv_mbx_out *)&cmd.rsp.arg[1];
1263     recv_ctx->context_id = mbx_out->ctx_id;
1264     recv_ctx->state = mbx_out->state;
1265     recv_ctx->virt_port = mbx_out->vport_id;
1266     dev_info(&adapter->pdev->dev, "Rx Context[%d] Created, state:0x%x\n",
1267          recv_ctx->context_id, recv_ctx->state);
1268     /* Receive descriptor ring */
1269     /* Standard ring */
1270     rds = &recv_ctx->rds_rings[0];
1271     rds->crb_rcv_producer = ahw->pci_base0 +
1272                 mbx_out->host_prod[0].reg_buf;
1273     /* Jumbo ring */
1274     rds = &recv_ctx->rds_rings[1];
1275     rds->crb_rcv_producer = ahw->pci_base0 +
1276                 mbx_out->host_prod[0].jmb_buf;
1277     /* status descriptor ring */
1278     for (i = 0; i < num_sds; i++) {
1279         sds = &recv_ctx->sds_rings[i];
1280         sds->crb_sts_consumer = ahw->pci_base0 +
1281                     mbx_out->host_csmr[i];
1282         if (adapter->flags & QLCNIC_MSIX_ENABLED)
1283             intr_mask = ahw->intr_tbl[i].src;
1284         else
1285             intr_mask = QLCRDX(ahw, QLCNIC_DEF_INT_MASK);
1286         sds->crb_intr_mask = ahw->pci_base0 + intr_mask;
1287     }
1288 
1289     if (adapter->drv_sds_rings > QLCNIC_MAX_SDS_RINGS)
1290         err = qlcnic_83xx_add_rings(adapter);
1291 out:
1292     qlcnic_free_mbx_args(&cmd);
1293     return err;
1294 }
1295 
1296 void qlcnic_83xx_del_tx_ctx(struct qlcnic_adapter *adapter,
1297                 struct qlcnic_host_tx_ring *tx_ring)
1298 {
1299     struct qlcnic_cmd_args cmd;
1300     u32 temp = 0;
1301 
1302     if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_TX_CTX))
1303         return;
1304 
1305     if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
1306         cmd.req.arg[0] |= (0x3 << 29);
1307 
1308     if (qlcnic_sriov_pf_check(adapter))
1309         qlcnic_pf_set_interface_id_del_tx_ctx(adapter, &temp);
1310 
1311     cmd.req.arg[1] = tx_ring->ctx_id | temp;
1312     if (qlcnic_issue_cmd(adapter, &cmd))
1313         dev_err(&adapter->pdev->dev,
1314             "Failed to destroy tx ctx in firmware\n");
1315     qlcnic_free_mbx_args(&cmd);
1316 }
1317 
1318 int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
1319                   struct qlcnic_host_tx_ring *tx, int ring)
1320 {
1321     int err;
1322     u16 msix_id;
1323     u32 *buf, intr_mask, temp = 0;
1324     struct qlcnic_cmd_args cmd;
1325     struct qlcnic_tx_mbx mbx;
1326     struct qlcnic_tx_mbx_out *mbx_out;
1327     struct qlcnic_hardware_context *ahw = adapter->ahw;
1328     u32 msix_vector;
1329 
1330     /* Reset host resources */
1331     tx->producer = 0;
1332     tx->sw_consumer = 0;
1333     *(tx->hw_consumer) = 0;
1334 
1335     memset(&mbx, 0, sizeof(struct qlcnic_tx_mbx));
1336 
1337     /* setup mailbox inbox registerss */
1338     mbx.phys_addr_low = LSD(tx->phys_addr);
1339     mbx.phys_addr_high = MSD(tx->phys_addr);
1340     mbx.cnsmr_index_low = LSD(tx->hw_cons_phys_addr);
1341     mbx.cnsmr_index_high = MSD(tx->hw_cons_phys_addr);
1342     mbx.size = tx->num_desc;
1343     if (adapter->flags & QLCNIC_MSIX_ENABLED) {
1344         if (!(adapter->flags & QLCNIC_TX_INTR_SHARED))
1345             msix_vector = adapter->drv_sds_rings + ring;
1346         else
1347             msix_vector = adapter->drv_sds_rings - 1;
1348         msix_id = ahw->intr_tbl[msix_vector].id;
1349     } else {
1350         msix_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
1351     }
1352 
1353     if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
1354         mbx.intr_id = msix_id;
1355     else
1356         mbx.intr_id = 0xffff;
1357     mbx.src = 0;
1358 
1359     err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CREATE_TX_CTX);
1360     if (err)
1361         return err;
1362 
1363     if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
1364         cmd.req.arg[0] |= (0x3 << 29);
1365 
1366     if (qlcnic_sriov_pf_check(adapter))
1367         qlcnic_pf_set_interface_id_create_tx_ctx(adapter, &temp);
1368 
1369     cmd.req.arg[1] = QLCNIC_CAP0_LEGACY_CONTEXT;
1370     cmd.req.arg[5] = QLCNIC_SINGLE_RING | temp;
1371 
1372     buf = &cmd.req.arg[6];
1373     memcpy(buf, &mbx, sizeof(struct qlcnic_tx_mbx));
1374     /* send the mailbox command*/
1375     err = qlcnic_issue_cmd(adapter, &cmd);
1376     if (err) {
1377         netdev_err(adapter->netdev,
1378                "Failed to create Tx ctx in firmware 0x%x\n", err);
1379         goto out;
1380     }
1381     mbx_out = (struct qlcnic_tx_mbx_out *)&cmd.rsp.arg[2];
1382     tx->crb_cmd_producer = ahw->pci_base0 + mbx_out->host_prod;
1383     tx->ctx_id = mbx_out->ctx_id;
1384     if ((adapter->flags & QLCNIC_MSIX_ENABLED) &&
1385         !(adapter->flags & QLCNIC_TX_INTR_SHARED)) {
1386         intr_mask = ahw->intr_tbl[adapter->drv_sds_rings + ring].src;
1387         tx->crb_intr_mask = ahw->pci_base0 + intr_mask;
1388     }
1389     netdev_info(adapter->netdev,
1390             "Tx Context[0x%x] Created, state:0x%x\n",
1391             tx->ctx_id, mbx_out->state);
1392 out:
1393     qlcnic_free_mbx_args(&cmd);
1394     return err;
1395 }
1396 
1397 static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,
1398                       u8 num_sds_ring)
1399 {
1400     struct qlcnic_adapter *adapter = netdev_priv(netdev);
1401     struct qlcnic_host_sds_ring *sds_ring;
1402     struct qlcnic_host_rds_ring *rds_ring;
1403     u16 adapter_state = adapter->is_up;
1404     u8 ring;
1405     int ret;
1406 
1407     netif_device_detach(netdev);
1408 
1409     if (netif_running(netdev))
1410         __qlcnic_down(adapter, netdev);
1411 
1412     qlcnic_detach(adapter);
1413 
1414     adapter->drv_sds_rings = QLCNIC_SINGLE_RING;
1415     adapter->ahw->diag_test = test;
1416     adapter->ahw->linkup = 0;
1417 
1418     ret = qlcnic_attach(adapter);
1419     if (ret) {
1420         netif_device_attach(netdev);
1421         return ret;
1422     }
1423 
1424     ret = qlcnic_fw_create_ctx(adapter);
1425     if (ret) {
1426         qlcnic_detach(adapter);
1427         if (adapter_state == QLCNIC_ADAPTER_UP_MAGIC) {
1428             adapter->drv_sds_rings = num_sds_ring;
1429             qlcnic_attach(adapter);
1430         }
1431         netif_device_attach(netdev);
1432         return ret;
1433     }
1434 
1435     for (ring = 0; ring < adapter->max_rds_rings; ring++) {
1436         rds_ring = &adapter->recv_ctx->rds_rings[ring];
1437         qlcnic_post_rx_buffers(adapter, rds_ring, ring);
1438     }
1439 
1440     if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
1441         for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
1442             sds_ring = &adapter->recv_ctx->sds_rings[ring];
1443             qlcnic_enable_sds_intr(adapter, sds_ring);
1444         }
1445     }
1446 
1447     if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) {
1448         adapter->ahw->loopback_state = 0;
1449         adapter->ahw->hw_ops->setup_link_event(adapter, 1);
1450     }
1451 
1452     set_bit(__QLCNIC_DEV_UP, &adapter->state);
1453     return 0;
1454 }
1455 
1456 static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
1457                       u8 drv_sds_rings)
1458 {
1459     struct qlcnic_adapter *adapter = netdev_priv(netdev);
1460     struct qlcnic_host_sds_ring *sds_ring;
1461     int ring;
1462 
1463     clear_bit(__QLCNIC_DEV_UP, &adapter->state);
1464     if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
1465         for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
1466             sds_ring = &adapter->recv_ctx->sds_rings[ring];
1467             if (adapter->flags & QLCNIC_MSIX_ENABLED)
1468                 qlcnic_disable_sds_intr(adapter, sds_ring);
1469         }
1470     }
1471 
1472     qlcnic_fw_destroy_ctx(adapter);
1473     qlcnic_detach(adapter);
1474 
1475     adapter->ahw->diag_test = 0;
1476     adapter->drv_sds_rings = drv_sds_rings;
1477 
1478     if (qlcnic_attach(adapter))
1479         goto out;
1480 
1481     if (netif_running(netdev))
1482         __qlcnic_up(adapter, netdev);
1483 
1484 out:
1485     netif_device_attach(netdev);
1486 }
1487 
1488 static void qlcnic_83xx_get_beacon_state(struct qlcnic_adapter *adapter)
1489 {
1490     struct qlcnic_hardware_context *ahw = adapter->ahw;
1491     struct qlcnic_cmd_args cmd;
1492     u8 beacon_state;
1493     int err = 0;
1494 
1495     err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LED_CONFIG);
1496     if (!err) {
1497         err = qlcnic_issue_cmd(adapter, &cmd);
1498         if (!err) {
1499             beacon_state = cmd.rsp.arg[4];
1500             if (beacon_state == QLCNIC_BEACON_DISABLE)
1501                 ahw->beacon_state = QLC_83XX_BEACON_OFF;
1502             else if (beacon_state == QLC_83XX_ENABLE_BEACON)
1503                 ahw->beacon_state = QLC_83XX_BEACON_ON;
1504         }
1505     } else {
1506         netdev_err(adapter->netdev, "Get beacon state failed, err=%d\n",
1507                err);
1508     }
1509 
1510     qlcnic_free_mbx_args(&cmd);
1511 
1512     return;
1513 }
1514 
1515 int qlcnic_83xx_config_led(struct qlcnic_adapter *adapter, u32 state,
1516                u32 beacon)
1517 {
1518     struct qlcnic_cmd_args cmd;
1519     u32 mbx_in;
1520     int i, status = 0;
1521 
1522     if (state) {
1523         /* Get LED configuration */
1524         status = qlcnic_alloc_mbx_args(&cmd, adapter,
1525                            QLCNIC_CMD_GET_LED_CONFIG);
1526         if (status)
1527             return status;
1528 
1529         status = qlcnic_issue_cmd(adapter, &cmd);
1530         if (status) {
1531             dev_err(&adapter->pdev->dev,
1532                 "Get led config failed.\n");
1533             goto mbx_err;
1534         } else {
1535             for (i = 0; i < 4; i++)
1536                 adapter->ahw->mbox_reg[i] = cmd.rsp.arg[i+1];
1537         }
1538         qlcnic_free_mbx_args(&cmd);
1539         /* Set LED Configuration */
1540         mbx_in = (LSW(QLC_83XX_LED_CONFIG) << 16) |
1541               LSW(QLC_83XX_LED_CONFIG);
1542         status = qlcnic_alloc_mbx_args(&cmd, adapter,
1543                            QLCNIC_CMD_SET_LED_CONFIG);
1544         if (status)
1545             return status;
1546 
1547         cmd.req.arg[1] = mbx_in;
1548         cmd.req.arg[2] = mbx_in;
1549         cmd.req.arg[3] = mbx_in;
1550         if (beacon)
1551             cmd.req.arg[4] = QLC_83XX_ENABLE_BEACON;
1552         status = qlcnic_issue_cmd(adapter, &cmd);
1553         if (status) {
1554             dev_err(&adapter->pdev->dev,
1555                 "Set led config failed.\n");
1556         }
1557 mbx_err:
1558         qlcnic_free_mbx_args(&cmd);
1559         return status;
1560 
1561     } else {
1562         /* Restoring default LED configuration */
1563         status = qlcnic_alloc_mbx_args(&cmd, adapter,
1564                            QLCNIC_CMD_SET_LED_CONFIG);
1565         if (status)
1566             return status;
1567 
1568         cmd.req.arg[1] = adapter->ahw->mbox_reg[0];
1569         cmd.req.arg[2] = adapter->ahw->mbox_reg[1];
1570         cmd.req.arg[3] = adapter->ahw->mbox_reg[2];
1571         if (beacon)
1572             cmd.req.arg[4] = adapter->ahw->mbox_reg[3];
1573         status = qlcnic_issue_cmd(adapter, &cmd);
1574         if (status)
1575             dev_err(&adapter->pdev->dev,
1576                 "Restoring led config failed.\n");
1577         qlcnic_free_mbx_args(&cmd);
1578         return status;
1579     }
1580 }
1581 
1582 int  qlcnic_83xx_set_led(struct net_device *netdev,
1583              enum ethtool_phys_id_state state)
1584 {
1585     struct qlcnic_adapter *adapter = netdev_priv(netdev);
1586     int err = -EIO, active = 1;
1587 
1588     if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1589         netdev_warn(netdev,
1590                 "LED test is not supported in non-privileged mode\n");
1591         return -EOPNOTSUPP;
1592     }
1593 
1594     switch (state) {
1595     case ETHTOOL_ID_ACTIVE:
1596         if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state))
1597             return -EBUSY;
1598 
1599         if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1600             break;
1601 
1602         err = qlcnic_83xx_config_led(adapter, active, 0);
1603         if (err)
1604             netdev_err(netdev, "Failed to set LED blink state\n");
1605         break;
1606     case ETHTOOL_ID_INACTIVE:
1607         active = 0;
1608 
1609         if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1610             break;
1611 
1612         err = qlcnic_83xx_config_led(adapter, active, 0);
1613         if (err)
1614             netdev_err(netdev, "Failed to reset LED blink state\n");
1615         break;
1616 
1617     default:
1618         return -EINVAL;
1619     }
1620 
1621     if (!active || err)
1622         clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
1623 
1624     return err;
1625 }
1626 
1627 void qlcnic_83xx_initialize_nic(struct qlcnic_adapter *adapter, int enable)
1628 {
1629     struct qlcnic_cmd_args cmd;
1630     int status;
1631 
1632     if (qlcnic_sriov_vf_check(adapter))
1633         return;
1634 
1635     if (enable)
1636         status = qlcnic_alloc_mbx_args(&cmd, adapter,
1637                            QLCNIC_CMD_INIT_NIC_FUNC);
1638     else
1639         status = qlcnic_alloc_mbx_args(&cmd, adapter,
1640                            QLCNIC_CMD_STOP_NIC_FUNC);
1641 
1642     if (status)
1643         return;
1644 
1645     cmd.req.arg[1] = QLC_REGISTER_LB_IDC | QLC_INIT_FW_RESOURCES;
1646 
1647     if (adapter->dcb)
1648         cmd.req.arg[1] |= QLC_REGISTER_DCB_AEN;
1649 
1650     status = qlcnic_issue_cmd(adapter, &cmd);
1651     if (status)
1652         dev_err(&adapter->pdev->dev,
1653             "Failed to %s in NIC IDC function event.\n",
1654             (enable ? "register" : "unregister"));
1655 
1656     qlcnic_free_mbx_args(&cmd);
1657 }
1658 
1659 static int qlcnic_83xx_set_port_config(struct qlcnic_adapter *adapter)
1660 {
1661     struct qlcnic_cmd_args cmd;
1662     int err;
1663 
1664     err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_PORT_CONFIG);
1665     if (err)
1666         return err;
1667 
1668     cmd.req.arg[1] = adapter->ahw->port_config;
1669     err = qlcnic_issue_cmd(adapter, &cmd);
1670     if (err)
1671         dev_info(&adapter->pdev->dev, "Set Port Config failed.\n");
1672     qlcnic_free_mbx_args(&cmd);
1673     return err;
1674 }
1675 
1676 static int qlcnic_83xx_get_port_config(struct qlcnic_adapter *adapter)
1677 {
1678     struct qlcnic_cmd_args cmd;
1679     int err;
1680 
1681     err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PORT_CONFIG);
1682     if (err)
1683         return err;
1684 
1685     err = qlcnic_issue_cmd(adapter, &cmd);
1686     if (err)
1687         dev_info(&adapter->pdev->dev, "Get Port config failed\n");
1688     else
1689         adapter->ahw->port_config = cmd.rsp.arg[1];
1690     qlcnic_free_mbx_args(&cmd);
1691     return err;
1692 }
1693 
1694 int qlcnic_83xx_setup_link_event(struct qlcnic_adapter *adapter, int enable)
1695 {
1696     int err;
1697     u32 temp;
1698     struct qlcnic_cmd_args cmd;
1699 
1700     err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_EVENT);
1701     if (err)
1702         return err;
1703 
1704     temp = adapter->recv_ctx->context_id << 16;
1705     cmd.req.arg[1] = (enable ? 1 : 0) | BIT_8 | temp;
1706     err = qlcnic_issue_cmd(adapter, &cmd);
1707     if (err)
1708         dev_info(&adapter->pdev->dev,
1709              "Setup linkevent mailbox failed\n");
1710     qlcnic_free_mbx_args(&cmd);
1711     return err;
1712 }
1713 
1714 static void qlcnic_83xx_set_interface_id_promisc(struct qlcnic_adapter *adapter,
1715                          u32 *interface_id)
1716 {
1717     if (qlcnic_sriov_pf_check(adapter)) {
1718         qlcnic_alloc_lb_filters_mem(adapter);
1719         qlcnic_pf_set_interface_id_promisc(adapter, interface_id);
1720         adapter->rx_mac_learn = true;
1721     } else {
1722         if (!qlcnic_sriov_vf_check(adapter))
1723             *interface_id = adapter->recv_ctx->context_id << 16;
1724     }
1725 }
1726 
1727 int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
1728 {
1729     struct qlcnic_cmd_args *cmd = NULL;
1730     u32 temp = 0;
1731     int err;
1732 
1733     if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1734         return -EIO;
1735 
1736     cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
1737     if (!cmd)
1738         return -ENOMEM;
1739 
1740     err = qlcnic_alloc_mbx_args(cmd, adapter,
1741                     QLCNIC_CMD_CONFIGURE_MAC_RX_MODE);
1742     if (err)
1743         goto out;
1744 
1745     cmd->type = QLC_83XX_MBX_CMD_NO_WAIT;
1746     qlcnic_83xx_set_interface_id_promisc(adapter, &temp);
1747 
1748     if (qlcnic_84xx_check(adapter) && qlcnic_sriov_pf_check(adapter))
1749         mode = VPORT_MISS_MODE_ACCEPT_ALL;
1750 
1751     cmd->req.arg[1] = mode | temp;
1752     err = qlcnic_issue_cmd(adapter, cmd);
1753     if (!err)
1754         return err;
1755 
1756     qlcnic_free_mbx_args(cmd);
1757 
1758 out:
1759     kfree(cmd);
1760     return err;
1761 }
1762 
1763 int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
1764 {
1765     struct qlcnic_adapter *adapter = netdev_priv(netdev);
1766     struct qlcnic_hardware_context *ahw = adapter->ahw;
1767     u8 drv_sds_rings = adapter->drv_sds_rings;
1768     u8 drv_tx_rings = adapter->drv_tx_rings;
1769     int ret = 0, loop = 0;
1770 
1771     if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1772         netdev_warn(netdev,
1773                 "Loopback test not supported in non privileged mode\n");
1774         return -ENOTSUPP;
1775     }
1776 
1777     if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1778         netdev_info(netdev, "Device is resetting\n");
1779         return -EBUSY;
1780     }
1781 
1782     if (qlcnic_get_diag_lock(adapter)) {
1783         netdev_info(netdev, "Device is in diagnostics mode\n");
1784         return -EBUSY;
1785     }
1786 
1787     netdev_info(netdev, "%s loopback test in progress\n",
1788             mode == QLCNIC_ILB_MODE ? "internal" : "external");
1789 
1790     ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST,
1791                      drv_sds_rings);
1792     if (ret)
1793         goto fail_diag_alloc;
1794 
1795     ret = qlcnic_83xx_set_lb_mode(adapter, mode);
1796     if (ret)
1797         goto free_diag_res;
1798 
1799     /* Poll for link up event before running traffic */
1800     do {
1801         msleep(QLC_83XX_LB_MSLEEP_COUNT);
1802 
1803         if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1804             netdev_info(netdev,
1805                     "Device is resetting, free LB test resources\n");
1806             ret = -EBUSY;
1807             goto free_diag_res;
1808         }
1809         if (loop++ > QLC_83XX_LB_WAIT_COUNT) {
1810             netdev_info(netdev,
1811                     "Firmware didn't sent link up event to loopback request\n");
1812             ret = -ETIMEDOUT;
1813             qlcnic_83xx_clear_lb_mode(adapter, mode);
1814             goto free_diag_res;
1815         }
1816     } while ((adapter->ahw->linkup && ahw->has_link_events) != 1);
1817 
1818     ret = qlcnic_do_lb_test(adapter, mode);
1819 
1820     qlcnic_83xx_clear_lb_mode(adapter, mode);
1821 
1822 free_diag_res:
1823     qlcnic_83xx_diag_free_res(netdev, drv_sds_rings);
1824 
1825 fail_diag_alloc:
1826     adapter->drv_sds_rings = drv_sds_rings;
1827     adapter->drv_tx_rings = drv_tx_rings;
1828     qlcnic_release_diag_lock(adapter);
1829     return ret;
1830 }
1831 
1832 static void qlcnic_extend_lb_idc_cmpltn_wait(struct qlcnic_adapter *adapter,
1833                          u32 *max_wait_count)
1834 {
1835     struct qlcnic_hardware_context *ahw = adapter->ahw;
1836     int temp;
1837 
1838     netdev_info(adapter->netdev, "Received loopback IDC time extend event for 0x%x seconds\n",
1839             ahw->extend_lb_time);
1840     temp = ahw->extend_lb_time * 1000;
1841     *max_wait_count += temp / QLC_83XX_LB_MSLEEP_COUNT;
1842     ahw->extend_lb_time = 0;
1843 }
1844 
1845 static int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1846 {
1847     struct qlcnic_hardware_context *ahw = adapter->ahw;
1848     struct net_device *netdev = adapter->netdev;
1849     u32 config, max_wait_count;
1850     int status = 0, loop = 0;
1851 
1852     ahw->extend_lb_time = 0;
1853     max_wait_count = QLC_83XX_LB_WAIT_COUNT;
1854     status = qlcnic_83xx_get_port_config(adapter);
1855     if (status)
1856         return status;
1857 
1858     config = ahw->port_config;
1859 
1860     /* Check if port is already in loopback mode */
1861     if ((config & QLC_83XX_CFG_LOOPBACK_HSS) ||
1862         (config & QLC_83XX_CFG_LOOPBACK_EXT)) {
1863         netdev_err(netdev,
1864                "Port already in Loopback mode.\n");
1865         return -EINPROGRESS;
1866     }
1867 
1868     set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1869 
1870     if (mode == QLCNIC_ILB_MODE)
1871         ahw->port_config |= QLC_83XX_CFG_LOOPBACK_HSS;
1872     if (mode == QLCNIC_ELB_MODE)
1873         ahw->port_config |= QLC_83XX_CFG_LOOPBACK_EXT;
1874 
1875     status = qlcnic_83xx_set_port_config(adapter);
1876     if (status) {
1877         netdev_err(netdev,
1878                "Failed to Set Loopback Mode = 0x%x.\n",
1879                ahw->port_config);
1880         ahw->port_config = config;
1881         clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1882         return status;
1883     }
1884 
1885     /* Wait for Link and IDC Completion AEN */
1886     do {
1887         msleep(QLC_83XX_LB_MSLEEP_COUNT);
1888 
1889         if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1890             netdev_info(netdev,
1891                     "Device is resetting, free LB test resources\n");
1892             clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1893             return -EBUSY;
1894         }
1895 
1896         if (ahw->extend_lb_time)
1897             qlcnic_extend_lb_idc_cmpltn_wait(adapter,
1898                              &max_wait_count);
1899 
1900         if (loop++ > max_wait_count) {
1901             netdev_err(netdev, "%s: Did not receive loopback IDC completion AEN\n",
1902                    __func__);
1903             clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1904             qlcnic_83xx_clear_lb_mode(adapter, mode);
1905             return -ETIMEDOUT;
1906         }
1907     } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
1908 
1909     qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0,
1910                   QLCNIC_MAC_ADD);
1911     return status;
1912 }
1913 
1914 static int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1915 {
1916     struct qlcnic_hardware_context *ahw = adapter->ahw;
1917     u32 config = ahw->port_config, max_wait_count;
1918     struct net_device *netdev = adapter->netdev;
1919     int status = 0, loop = 0;
1920 
1921     ahw->extend_lb_time = 0;
1922     max_wait_count = QLC_83XX_LB_WAIT_COUNT;
1923     set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1924     if (mode == QLCNIC_ILB_MODE)
1925         ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_HSS;
1926     if (mode == QLCNIC_ELB_MODE)
1927         ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_EXT;
1928 
1929     status = qlcnic_83xx_set_port_config(adapter);
1930     if (status) {
1931         netdev_err(netdev,
1932                "Failed to Clear Loopback Mode = 0x%x.\n",
1933                ahw->port_config);
1934         ahw->port_config = config;
1935         clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1936         return status;
1937     }
1938 
1939     /* Wait for Link and IDC Completion AEN */
1940     do {
1941         msleep(QLC_83XX_LB_MSLEEP_COUNT);
1942 
1943         if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1944             netdev_info(netdev,
1945                     "Device is resetting, free LB test resources\n");
1946             clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1947             return -EBUSY;
1948         }
1949 
1950         if (ahw->extend_lb_time)
1951             qlcnic_extend_lb_idc_cmpltn_wait(adapter,
1952                              &max_wait_count);
1953 
1954         if (loop++ > max_wait_count) {
1955             netdev_err(netdev, "%s: Did not receive loopback IDC completion AEN\n",
1956                    __func__);
1957             clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1958             return -ETIMEDOUT;
1959         }
1960     } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
1961 
1962     qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0,
1963                   QLCNIC_MAC_DEL);
1964     return status;
1965 }
1966 
1967 static void qlcnic_83xx_set_interface_id_ipaddr(struct qlcnic_adapter *adapter,
1968                         u32 *interface_id)
1969 {
1970     if (qlcnic_sriov_pf_check(adapter)) {
1971         qlcnic_pf_set_interface_id_ipaddr(adapter, interface_id);
1972     } else {
1973         if (!qlcnic_sriov_vf_check(adapter))
1974             *interface_id = adapter->recv_ctx->context_id << 16;
1975     }
1976 }
1977 
1978 void qlcnic_83xx_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip,
1979                    int mode)
1980 {
1981     int err;
1982     u32 temp = 0, temp_ip;
1983     struct qlcnic_cmd_args cmd;
1984 
1985     err = qlcnic_alloc_mbx_args(&cmd, adapter,
1986                     QLCNIC_CMD_CONFIGURE_IP_ADDR);
1987     if (err)
1988         return;
1989 
1990     qlcnic_83xx_set_interface_id_ipaddr(adapter, &temp);
1991 
1992     if (mode == QLCNIC_IP_UP)
1993         cmd.req.arg[1] = 1 | temp;
1994     else
1995         cmd.req.arg[1] = 2 | temp;
1996 
1997     /*
1998      * Adapter needs IP address in network byte order.
1999      * But hardware mailbox registers go through writel(), hence IP address
2000      * gets swapped on big endian architecture.
2001      * To negate swapping of writel() on big endian architecture
2002      * use swab32(value).
2003      */
2004 
2005     temp_ip = swab32(ntohl(ip));
2006     memcpy(&cmd.req.arg[2], &temp_ip, sizeof(u32));
2007     err = qlcnic_issue_cmd(adapter, &cmd);
2008     if (err != QLCNIC_RCODE_SUCCESS)
2009         dev_err(&adapter->netdev->dev,
2010             "could not notify %s IP 0x%x request\n",
2011             (mode == QLCNIC_IP_UP) ? "Add" : "Remove", ip);
2012 
2013     qlcnic_free_mbx_args(&cmd);
2014 }
2015 
2016 int qlcnic_83xx_config_hw_lro(struct qlcnic_adapter *adapter, int mode)
2017 {
2018     int err;
2019     u32 temp, arg1;
2020     struct qlcnic_cmd_args cmd;
2021     int lro_bit_mask;
2022 
2023     lro_bit_mask = (mode ? (BIT_0 | BIT_1 | BIT_2 | BIT_3) : 0);
2024 
2025     if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
2026         return 0;
2027 
2028     err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_HW_LRO);
2029     if (err)
2030         return err;
2031 
2032     temp = adapter->recv_ctx->context_id << 16;
2033     arg1 = lro_bit_mask | temp;
2034     cmd.req.arg[1] = arg1;
2035 
2036     err = qlcnic_issue_cmd(adapter, &cmd);
2037     if (err)
2038         dev_info(&adapter->pdev->dev, "LRO config failed\n");
2039     qlcnic_free_mbx_args(&cmd);
2040 
2041     return err;
2042 }
2043 
2044 int qlcnic_83xx_config_rss(struct qlcnic_adapter *adapter, int enable)
2045 {
2046     int err;
2047     u32 word;
2048     struct qlcnic_cmd_args cmd;
2049     const u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
2050                 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
2051                 0x255b0ec26d5a56daULL };
2052 
2053     err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_RSS);
2054     if (err)
2055         return err;
2056     /*
2057      * RSS request:
2058      * bits 3-0: Rsvd
2059      *      5-4: hash_type_ipv4
2060      *  7-6: hash_type_ipv6
2061      *    8: enable
2062      *        9: use indirection table
2063      *    16-31: indirection table mask
2064      */
2065     word =  ((u32)(RSS_HASHTYPE_IP_TCP & 0x3) << 4) |
2066         ((u32)(RSS_HASHTYPE_IP_TCP & 0x3) << 6) |
2067         ((u32)(enable & 0x1) << 8) |
2068         ((0x7ULL) << 16);
2069     cmd.req.arg[1] = (adapter->recv_ctx->context_id);
2070     cmd.req.arg[2] = word;
2071     memcpy(&cmd.req.arg[4], key, sizeof(key));
2072 
2073     err = qlcnic_issue_cmd(adapter, &cmd);
2074 
2075     if (err)
2076         dev_info(&adapter->pdev->dev, "RSS config failed\n");
2077     qlcnic_free_mbx_args(&cmd);
2078 
2079     return err;
2080 
2081 }
2082 
2083 static void qlcnic_83xx_set_interface_id_macaddr(struct qlcnic_adapter *adapter,
2084                          u32 *interface_id)
2085 {
2086     if (qlcnic_sriov_pf_check(adapter)) {
2087         qlcnic_pf_set_interface_id_macaddr(adapter, interface_id);
2088     } else {
2089         if (!qlcnic_sriov_vf_check(adapter))
2090             *interface_id = adapter->recv_ctx->context_id << 16;
2091     }
2092 }
2093 
2094 int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
2095                    u16 vlan_id, u8 op)
2096 {
2097     struct qlcnic_cmd_args *cmd = NULL;
2098     struct qlcnic_macvlan_mbx mv;
2099     u32 *buf, temp = 0;
2100     int err;
2101 
2102     if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
2103         return -EIO;
2104 
2105     cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
2106     if (!cmd)
2107         return -ENOMEM;
2108 
2109     err = qlcnic_alloc_mbx_args(cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN);
2110     if (err)
2111         goto out;
2112 
2113     cmd->type = QLC_83XX_MBX_CMD_NO_WAIT;
2114 
2115     if (vlan_id)
2116         op = (op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ?
2117              QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL;
2118 
2119     cmd->req.arg[1] = op | (1 << 8);
2120     qlcnic_83xx_set_interface_id_macaddr(adapter, &temp);
2121     cmd->req.arg[1] |= temp;
2122     mv.vlan = vlan_id;
2123     mv.mac_addr0 = addr[0];
2124     mv.mac_addr1 = addr[1];
2125     mv.mac_addr2 = addr[2];
2126     mv.mac_addr3 = addr[3];
2127     mv.mac_addr4 = addr[4];
2128     mv.mac_addr5 = addr[5];
2129     buf = &cmd->req.arg[2];
2130     memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx));
2131     err = qlcnic_issue_cmd(adapter, cmd);
2132     if (!err)
2133         return err;
2134 
2135     qlcnic_free_mbx_args(cmd);
2136 out:
2137     kfree(cmd);
2138     return err;
2139 }
2140 
2141 void qlcnic_83xx_change_l2_filter(struct qlcnic_adapter *adapter, u64 *addr,
2142                   u16 vlan_id,
2143                   struct qlcnic_host_tx_ring *tx_ring)
2144 {
2145     u8 mac[ETH_ALEN];
2146     memcpy(&mac, addr, ETH_ALEN);
2147     qlcnic_83xx_sre_macaddr_change(adapter, mac, vlan_id, QLCNIC_MAC_ADD);
2148 }
2149 
2150 static void qlcnic_83xx_configure_mac(struct qlcnic_adapter *adapter, u8 *mac,
2151                       u8 type, struct qlcnic_cmd_args *cmd)
2152 {
2153     switch (type) {
2154     case QLCNIC_SET_STATION_MAC:
2155     case QLCNIC_SET_FAC_DEF_MAC:
2156         memcpy(&cmd->req.arg[2], mac, sizeof(u32));
2157         memcpy(&cmd->req.arg[3], &mac[4], sizeof(u16));
2158         break;
2159     }
2160     cmd->req.arg[1] = type;
2161 }
2162 
2163 int qlcnic_83xx_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac,
2164                 u8 function)
2165 {
2166     int err, i;
2167     struct qlcnic_cmd_args cmd;
2168     u32 mac_low, mac_high;
2169 
2170     err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_MAC_ADDRESS);
2171     if (err)
2172         return err;
2173 
2174     qlcnic_83xx_configure_mac(adapter, mac, QLCNIC_GET_CURRENT_MAC, &cmd);
2175     err = qlcnic_issue_cmd(adapter, &cmd);
2176 
2177     if (err == QLCNIC_RCODE_SUCCESS) {
2178         mac_low = cmd.rsp.arg[1];
2179         mac_high = cmd.rsp.arg[2];
2180 
2181         for (i = 0; i < 2; i++)
2182             mac[i] = (u8) (mac_high >> ((1 - i) * 8));
2183         for (i = 2; i < 6; i++)
2184             mac[i] = (u8) (mac_low >> ((5 - i) * 8));
2185     } else {
2186         dev_err(&adapter->pdev->dev, "Failed to get mac address%d\n",
2187             err);
2188         err = -EIO;
2189     }
2190     qlcnic_free_mbx_args(&cmd);
2191     return err;
2192 }
2193 
2194 static int qlcnic_83xx_set_rx_intr_coal(struct qlcnic_adapter *adapter)
2195 {
2196     struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
2197     struct qlcnic_cmd_args cmd;
2198     u16 temp;
2199     int err;
2200 
2201     err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
2202     if (err)
2203         return err;
2204 
2205     temp = adapter->recv_ctx->context_id;
2206     cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_RX | temp << 16;
2207     temp = coal->rx_time_us;
2208     cmd.req.arg[2] = coal->rx_packets | temp << 16;
2209     cmd.req.arg[3] = coal->flag;
2210 
2211     err = qlcnic_issue_cmd(adapter, &cmd);
2212     if (err != QLCNIC_RCODE_SUCCESS)
2213         netdev_err(adapter->netdev,
2214                "failed to set interrupt coalescing parameters\n");
2215 
2216     qlcnic_free_mbx_args(&cmd);
2217 
2218     return err;
2219 }
2220 
2221 static int qlcnic_83xx_set_tx_intr_coal(struct qlcnic_adapter *adapter)
2222 {
2223     struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
2224     struct qlcnic_cmd_args cmd;
2225     u16 temp;
2226     int err;
2227 
2228     err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
2229     if (err)
2230         return err;
2231 
2232     temp = adapter->tx_ring->ctx_id;
2233     cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_TX | temp << 16;
2234     temp = coal->tx_time_us;
2235     cmd.req.arg[2] = coal->tx_packets | temp << 16;
2236     cmd.req.arg[3] = coal->flag;
2237 
2238     err = qlcnic_issue_cmd(adapter, &cmd);
2239     if (err != QLCNIC_RCODE_SUCCESS)
2240         netdev_err(adapter->netdev,
2241                "failed to set interrupt coalescing  parameters\n");
2242 
2243     qlcnic_free_mbx_args(&cmd);
2244 
2245     return err;
2246 }
2247 
2248 int qlcnic_83xx_set_rx_tx_intr_coal(struct qlcnic_adapter *adapter)
2249 {
2250     int err = 0;
2251 
2252     err = qlcnic_83xx_set_rx_intr_coal(adapter);
2253     if (err)
2254         netdev_err(adapter->netdev,
2255                "failed to set Rx coalescing parameters\n");
2256 
2257     err = qlcnic_83xx_set_tx_intr_coal(adapter);
2258     if (err)
2259         netdev_err(adapter->netdev,
2260                "failed to set Tx coalescing parameters\n");
2261 
2262     return err;
2263 }
2264 
2265 int qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter,
2266                  struct ethtool_coalesce *ethcoal)
2267 {
2268     struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
2269     u32 rx_coalesce_usecs, rx_max_frames;
2270     u32 tx_coalesce_usecs, tx_max_frames;
2271     int err;
2272 
2273     if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
2274         return -EIO;
2275 
2276     tx_coalesce_usecs = ethcoal->tx_coalesce_usecs;
2277     tx_max_frames = ethcoal->tx_max_coalesced_frames;
2278     rx_coalesce_usecs = ethcoal->rx_coalesce_usecs;
2279     rx_max_frames = ethcoal->rx_max_coalesced_frames;
2280     coal->flag = QLCNIC_INTR_DEFAULT;
2281 
2282     if ((coal->rx_time_us == rx_coalesce_usecs) &&
2283         (coal->rx_packets == rx_max_frames)) {
2284         coal->type = QLCNIC_INTR_COAL_TYPE_TX;
2285         coal->tx_time_us = tx_coalesce_usecs;
2286         coal->tx_packets = tx_max_frames;
2287     } else if ((coal->tx_time_us == tx_coalesce_usecs) &&
2288            (coal->tx_packets == tx_max_frames)) {
2289         coal->type = QLCNIC_INTR_COAL_TYPE_RX;
2290         coal->rx_time_us = rx_coalesce_usecs;
2291         coal->rx_packets = rx_max_frames;
2292     } else {
2293         coal->type = QLCNIC_INTR_COAL_TYPE_RX_TX;
2294         coal->rx_time_us = rx_coalesce_usecs;
2295         coal->rx_packets = rx_max_frames;
2296         coal->tx_time_us = tx_coalesce_usecs;
2297         coal->tx_packets = tx_max_frames;
2298     }
2299 
2300     switch (coal->type) {
2301     case QLCNIC_INTR_COAL_TYPE_RX:
2302         err = qlcnic_83xx_set_rx_intr_coal(adapter);
2303         break;
2304     case QLCNIC_INTR_COAL_TYPE_TX:
2305         err = qlcnic_83xx_set_tx_intr_coal(adapter);
2306         break;
2307     case QLCNIC_INTR_COAL_TYPE_RX_TX:
2308         err = qlcnic_83xx_set_rx_tx_intr_coal(adapter);
2309         break;
2310     default:
2311         err = -EINVAL;
2312         netdev_err(adapter->netdev,
2313                "Invalid Interrupt coalescing type\n");
2314         break;
2315     }
2316 
2317     return err;
2318 }
2319 
2320 static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
2321                     u32 data[])
2322 {
2323     struct qlcnic_hardware_context *ahw = adapter->ahw;
2324     u8 link_status, duplex;
2325     /* link speed */
2326     link_status = LSB(data[3]) & 1;
2327     if (link_status) {
2328         ahw->link_speed = MSW(data[2]);
2329         duplex = LSB(MSW(data[3]));
2330         if (duplex)
2331             ahw->link_duplex = DUPLEX_FULL;
2332         else
2333             ahw->link_duplex = DUPLEX_HALF;
2334     } else {
2335         ahw->link_speed = SPEED_UNKNOWN;
2336         ahw->link_duplex = DUPLEX_UNKNOWN;
2337     }
2338 
2339     ahw->link_autoneg = MSB(MSW(data[3]));
2340     ahw->module_type = MSB(LSW(data[3]));
2341     ahw->has_link_events = 1;
2342     ahw->lb_mode = data[4] & QLCNIC_LB_MODE_MASK;
2343     qlcnic_advert_link_change(adapter, link_status);
2344 }
2345 
2346 static irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
2347 {
2348     u32 mask, resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
2349     struct qlcnic_adapter *adapter = data;
2350     struct qlcnic_mailbox *mbx;
2351     unsigned long flags;
2352 
2353     mbx = adapter->ahw->mailbox;
2354     spin_lock_irqsave(&mbx->aen_lock, flags);
2355     resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
2356     if (!(resp & QLCNIC_SET_OWNER))
2357         goto out;
2358 
2359     event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
2360     if (event &  QLCNIC_MBX_ASYNC_EVENT) {
2361         __qlcnic_83xx_process_aen(adapter);
2362     } else {
2363         if (mbx->rsp_status != rsp_status)
2364             qlcnic_83xx_notify_mbx_response(mbx);
2365         else
2366             adapter->stats.mbx_spurious_intr++;
2367     }
2368 
2369 out:
2370     mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
2371     writel(0, adapter->ahw->pci_base0 + mask);
2372     spin_unlock_irqrestore(&mbx->aen_lock, flags);
2373     return IRQ_HANDLED;
2374 }
2375 
2376 int qlcnic_83xx_set_nic_info(struct qlcnic_adapter *adapter,
2377                  struct qlcnic_info *nic)
2378 {
2379     int i, err = -EIO;
2380     struct qlcnic_cmd_args cmd;
2381 
2382     if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) {
2383         dev_err(&adapter->pdev->dev,
2384             "%s: Error, invoked by non management func\n",
2385             __func__);
2386         return err;
2387     }
2388 
2389     err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO);
2390     if (err)
2391         return err;
2392 
2393     cmd.req.arg[1] = (nic->pci_func << 16);
2394     cmd.req.arg[2] = 0x1 << 16;
2395     cmd.req.arg[3] = nic->phys_port | (nic->switch_mode << 16);
2396     cmd.req.arg[4] = nic->capabilities;
2397     cmd.req.arg[5] = (nic->max_mac_filters & 0xFF) | ((nic->max_mtu) << 16);
2398     cmd.req.arg[6] = (nic->max_tx_ques) | ((nic->max_rx_ques) << 16);
2399     cmd.req.arg[7] = (nic->min_tx_bw) | ((nic->max_tx_bw) << 16);
2400     for (i = 8; i < 32; i++)
2401         cmd.req.arg[i] = 0;
2402 
2403     err = qlcnic_issue_cmd(adapter, &cmd);
2404 
2405     if (err != QLCNIC_RCODE_SUCCESS) {
2406         dev_err(&adapter->pdev->dev, "Failed to set nic info%d\n",
2407             err);
2408         err = -EIO;
2409     }
2410 
2411     qlcnic_free_mbx_args(&cmd);
2412 
2413     return err;
2414 }
2415 
2416 int qlcnic_83xx_get_nic_info(struct qlcnic_adapter *adapter,
2417                  struct qlcnic_info *npar_info, u8 func_id)
2418 {
2419     int err;
2420     u32 temp;
2421     u8 op = 0;
2422     struct qlcnic_cmd_args cmd;
2423     struct qlcnic_hardware_context *ahw = adapter->ahw;
2424 
2425     err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_NIC_INFO);
2426     if (err)
2427         return err;
2428 
2429     if (func_id != ahw->pci_func) {
2430         temp = func_id << 16;
2431         cmd.req.arg[1] = op | BIT_31 | temp;
2432     } else {
2433         cmd.req.arg[1] = ahw->pci_func << 16;
2434     }
2435     err = qlcnic_issue_cmd(adapter, &cmd);
2436     if (err) {
2437         dev_info(&adapter->pdev->dev,
2438              "Failed to get nic info %d\n", err);
2439         goto out;
2440     }
2441 
2442     npar_info->op_type = cmd.rsp.arg[1];
2443     npar_info->pci_func = cmd.rsp.arg[2] & 0xFFFF;
2444     npar_info->op_mode = (cmd.rsp.arg[2] & 0xFFFF0000) >> 16;
2445     npar_info->phys_port = cmd.rsp.arg[3] & 0xFFFF;
2446     npar_info->switch_mode = (cmd.rsp.arg[3] & 0xFFFF0000) >> 16;
2447     npar_info->capabilities = cmd.rsp.arg[4];
2448     npar_info->max_mac_filters = cmd.rsp.arg[5] & 0xFF;
2449     npar_info->max_mtu = (cmd.rsp.arg[5] & 0xFFFF0000) >> 16;
2450     npar_info->max_tx_ques = cmd.rsp.arg[6] & 0xFFFF;
2451     npar_info->max_rx_ques = (cmd.rsp.arg[6] & 0xFFFF0000) >> 16;
2452     npar_info->min_tx_bw = cmd.rsp.arg[7] & 0xFFFF;
2453     npar_info->max_tx_bw = (cmd.rsp.arg[7] & 0xFFFF0000) >> 16;
2454     if (cmd.rsp.arg[8] & 0x1)
2455         npar_info->max_bw_reg_offset = (cmd.rsp.arg[8] & 0x7FFE) >> 1;
2456     if (cmd.rsp.arg[8] & 0x10000) {
2457         temp = (cmd.rsp.arg[8] & 0x7FFE0000) >> 17;
2458         npar_info->max_linkspeed_reg_offset = temp;
2459     }
2460 
2461     memcpy(ahw->extra_capability, &cmd.rsp.arg[16],
2462            sizeof(ahw->extra_capability));
2463 
2464 out:
2465     qlcnic_free_mbx_args(&cmd);
2466     return err;
2467 }
2468 
2469 int qlcnic_get_pci_func_type(struct qlcnic_adapter *adapter, u16 type,
2470                  u16 *nic, u16 *fcoe, u16 *iscsi)
2471 {
2472     struct device *dev = &adapter->pdev->dev;
2473     int err = 0;
2474 
2475     switch (type) {
2476     case QLCNIC_TYPE_NIC:
2477         (*nic)++;
2478         break;
2479     case QLCNIC_TYPE_FCOE:
2480         (*fcoe)++;
2481         break;
2482     case QLCNIC_TYPE_ISCSI:
2483         (*iscsi)++;
2484         break;
2485     default:
2486         dev_err(dev, "%s: Unknown PCI type[%x]\n",
2487             __func__, type);
2488         err = -EIO;
2489     }
2490 
2491     return err;
2492 }
2493 
2494 int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
2495                  struct qlcnic_pci_info *pci_info)
2496 {
2497     struct qlcnic_hardware_context *ahw = adapter->ahw;
2498     struct device *dev = &adapter->pdev->dev;
2499     u16 nic = 0, fcoe = 0, iscsi = 0;
2500     struct qlcnic_cmd_args cmd;
2501     int i, err = 0, j = 0;
2502     u32 temp;
2503 
2504     err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PCI_INFO);
2505     if (err)
2506         return err;
2507 
2508     err = qlcnic_issue_cmd(adapter, &cmd);
2509 
2510     ahw->total_nic_func = 0;
2511     if (err == QLCNIC_RCODE_SUCCESS) {
2512         ahw->max_pci_func = cmd.rsp.arg[1] & 0xFF;
2513         for (i = 2, j = 0; j < ahw->max_vnic_func; j++, pci_info++) {
2514             pci_info->id = cmd.rsp.arg[i] & 0xFFFF;
2515             pci_info->active = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
2516             i++;
2517             if (!pci_info->active) {
2518                 i += QLC_SKIP_INACTIVE_PCI_REGS;
2519                 continue;
2520             }
2521             pci_info->type = cmd.rsp.arg[i] & 0xFFFF;
2522             err = qlcnic_get_pci_func_type(adapter, pci_info->type,
2523                                &nic, &fcoe, &iscsi);
2524             temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
2525             pci_info->default_port = temp;
2526             i++;
2527             pci_info->tx_min_bw = cmd.rsp.arg[i] & 0xFFFF;
2528             temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
2529             pci_info->tx_max_bw = temp;
2530             i = i + 2;
2531             memcpy(pci_info->mac, &cmd.rsp.arg[i], ETH_ALEN - 2);
2532             i++;
2533             memcpy(pci_info->mac + sizeof(u32), &cmd.rsp.arg[i], 2);
2534             i = i + 3;
2535         }
2536     } else {
2537         dev_err(dev, "Failed to get PCI Info, error = %d\n", err);
2538         err = -EIO;
2539     }
2540 
2541     ahw->total_nic_func = nic;
2542     ahw->total_pci_func = nic + fcoe + iscsi;
2543     if (ahw->total_nic_func == 0 || ahw->total_pci_func == 0) {
2544         dev_err(dev, "%s: Invalid function count: total nic func[%x], total pci func[%x]\n",
2545             __func__, ahw->total_nic_func, ahw->total_pci_func);
2546         err = -EIO;
2547     }
2548     qlcnic_free_mbx_args(&cmd);
2549 
2550     return err;
2551 }
2552 
2553 int qlcnic_83xx_config_intrpt(struct qlcnic_adapter *adapter, bool op_type)
2554 {
2555     int i, index, err;
2556     u8 max_ints;
2557     u32 val, temp, type;
2558     struct qlcnic_cmd_args cmd;
2559 
2560     max_ints = adapter->ahw->num_msix - 1;
2561     err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTRPT);
2562     if (err)
2563         return err;
2564 
2565     cmd.req.arg[1] = max_ints;
2566 
2567     if (qlcnic_sriov_vf_check(adapter))
2568         cmd.req.arg[1] |= (adapter->ahw->pci_func << 8) | BIT_16;
2569 
2570     for (i = 0, index = 2; i < max_ints; i++) {
2571         type = op_type ? QLCNIC_INTRPT_ADD : QLCNIC_INTRPT_DEL;
2572         val = type | (adapter->ahw->intr_tbl[i].type << 4);
2573         if (adapter->ahw->intr_tbl[i].type == QLCNIC_INTRPT_MSIX)
2574             val |= (adapter->ahw->intr_tbl[i].id << 16);
2575         cmd.req.arg[index++] = val;
2576     }
2577     err = qlcnic_issue_cmd(adapter, &cmd);
2578     if (err) {
2579         dev_err(&adapter->pdev->dev,
2580             "Failed to configure interrupts 0x%x\n", err);
2581         goto out;
2582     }
2583 
2584     max_ints = cmd.rsp.arg[1];
2585     for (i = 0, index = 2; i < max_ints; i++, index += 2) {
2586         val = cmd.rsp.arg[index];
2587         if (LSB(val)) {
2588             dev_info(&adapter->pdev->dev,
2589                  "Can't configure interrupt %d\n",
2590                  adapter->ahw->intr_tbl[i].id);
2591             continue;
2592         }
2593         if (op_type) {
2594             adapter->ahw->intr_tbl[i].id = MSW(val);
2595             adapter->ahw->intr_tbl[i].enabled = 1;
2596             temp = cmd.rsp.arg[index + 1];
2597             adapter->ahw->intr_tbl[i].src = temp;
2598         } else {
2599             adapter->ahw->intr_tbl[i].id = i;
2600             adapter->ahw->intr_tbl[i].enabled = 0;
2601             adapter->ahw->intr_tbl[i].src = 0;
2602         }
2603     }
2604 out:
2605     qlcnic_free_mbx_args(&cmd);
2606     return err;
2607 }
2608 
2609 int qlcnic_83xx_lock_flash(struct qlcnic_adapter *adapter)
2610 {
2611     int id, timeout = 0;
2612     u32 status = 0;
2613 
2614     while (status == 0) {
2615         status = QLC_SHARED_REG_RD32(adapter, QLCNIC_FLASH_LOCK);
2616         if (status)
2617             break;
2618 
2619         if (++timeout >= QLC_83XX_FLASH_LOCK_TIMEOUT) {
2620             id = QLC_SHARED_REG_RD32(adapter,
2621                          QLCNIC_FLASH_LOCK_OWNER);
2622             dev_err(&adapter->pdev->dev,
2623                 "%s: failed, lock held by %d\n", __func__, id);
2624             return -EIO;
2625         }
2626         usleep_range(1000, 2000);
2627     }
2628 
2629     QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER, adapter->portnum);
2630     return 0;
2631 }
2632 
2633 void qlcnic_83xx_unlock_flash(struct qlcnic_adapter *adapter)
2634 {
2635     QLC_SHARED_REG_RD32(adapter, QLCNIC_FLASH_UNLOCK);
2636     QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER, 0xFF);
2637 }
2638 
2639 int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *adapter,
2640                       u32 flash_addr, u8 *p_data,
2641                       int count)
2642 {
2643     u32 word, range, flash_offset, addr = flash_addr, ret;
2644     ulong indirect_add, direct_window;
2645     int i, err = 0;
2646 
2647     flash_offset = addr & (QLCNIC_FLASH_SECTOR_SIZE - 1);
2648     if (addr & 0x3) {
2649         dev_err(&adapter->pdev->dev, "Illegal addr = 0x%x\n", addr);
2650         return -EIO;
2651     }
2652 
2653     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_DIRECT_WINDOW,
2654                      (addr & 0xFFFF0000));
2655 
2656     range = flash_offset + (count * sizeof(u32));
2657     /* Check if data is spread across multiple sectors */
2658     if (range > (QLCNIC_FLASH_SECTOR_SIZE - 1)) {
2659 
2660         /* Multi sector read */
2661         for (i = 0; i < count; i++) {
2662             indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr);
2663             ret = QLCRD32(adapter, indirect_add, &err);
2664             if (err == -EIO)
2665                 return err;
2666 
2667             word = ret;
2668             *(u32 *)p_data  = word;
2669             p_data = p_data + 4;
2670             addr = addr + 4;
2671             flash_offset = flash_offset + 4;
2672 
2673             if (flash_offset > (QLCNIC_FLASH_SECTOR_SIZE - 1)) {
2674                 direct_window = QLC_83XX_FLASH_DIRECT_WINDOW;
2675                 /* This write is needed once for each sector */
2676                 qlcnic_83xx_wrt_reg_indirect(adapter,
2677                                  direct_window,
2678                                  (addr));
2679                 flash_offset = 0;
2680             }
2681         }
2682     } else {
2683         /* Single sector read */
2684         for (i = 0; i < count; i++) {
2685             indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr);
2686             ret = QLCRD32(adapter, indirect_add, &err);
2687             if (err == -EIO)
2688                 return err;
2689 
2690             word = ret;
2691             *(u32 *)p_data  = word;
2692             p_data = p_data + 4;
2693             addr = addr + 4;
2694         }
2695     }
2696 
2697     return 0;
2698 }
2699 
2700 static int qlcnic_83xx_poll_flash_status_reg(struct qlcnic_adapter *adapter)
2701 {
2702     u32 status;
2703     int retries = QLC_83XX_FLASH_READ_RETRY_COUNT;
2704     int err = 0;
2705 
2706     do {
2707         status = QLCRD32(adapter, QLC_83XX_FLASH_STATUS, &err);
2708         if (err == -EIO)
2709             return err;
2710 
2711         if ((status & QLC_83XX_FLASH_STATUS_READY) ==
2712             QLC_83XX_FLASH_STATUS_READY)
2713             break;
2714 
2715         usleep_range(1000, 1100);
2716     } while (--retries);
2717 
2718     if (!retries)
2719         return -EIO;
2720 
2721     return 0;
2722 }
2723 
2724 int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *adapter)
2725 {
2726     int ret;
2727     u32 cmd;
2728     cmd = adapter->ahw->fdt.write_statusreg_cmd;
2729     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2730                      (QLC_83XX_FLASH_FDT_WRITE_DEF_SIG | cmd));
2731     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2732                      adapter->ahw->fdt.write_enable_bits);
2733     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2734                      QLC_83XX_FLASH_SECOND_ERASE_MS_VAL);
2735     ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2736     if (ret)
2737         return -EIO;
2738 
2739     return 0;
2740 }
2741 
2742 int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *adapter)
2743 {
2744     int ret;
2745 
2746     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2747                      (QLC_83XX_FLASH_FDT_WRITE_DEF_SIG |
2748                      adapter->ahw->fdt.write_statusreg_cmd));
2749     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2750                      adapter->ahw->fdt.write_disable_bits);
2751     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2752                      QLC_83XX_FLASH_SECOND_ERASE_MS_VAL);
2753     ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2754     if (ret)
2755         return -EIO;
2756 
2757     return 0;
2758 }
2759 
2760 int qlcnic_83xx_read_flash_mfg_id(struct qlcnic_adapter *adapter)
2761 {
2762     int ret, err = 0;
2763     u32 mfg_id;
2764 
2765     if (qlcnic_83xx_lock_flash(adapter))
2766         return -EIO;
2767 
2768     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2769                      QLC_83XX_FLASH_FDT_READ_MFG_ID_VAL);
2770     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2771                      QLC_83XX_FLASH_READ_CTRL);
2772     ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2773     if (ret) {
2774         qlcnic_83xx_unlock_flash(adapter);
2775         return -EIO;
2776     }
2777 
2778     mfg_id = QLCRD32(adapter, QLC_83XX_FLASH_RDDATA, &err);
2779     if (err == -EIO) {
2780         qlcnic_83xx_unlock_flash(adapter);
2781         return err;
2782     }
2783 
2784     adapter->flash_mfg_id = (mfg_id & 0xFF);
2785     qlcnic_83xx_unlock_flash(adapter);
2786 
2787     return 0;
2788 }
2789 
2790 int qlcnic_83xx_read_flash_descriptor_table(struct qlcnic_adapter *adapter)
2791 {
2792     int count, fdt_size, ret = 0;
2793 
2794     fdt_size = sizeof(struct qlcnic_fdt);
2795     count = fdt_size / sizeof(u32);
2796 
2797     if (qlcnic_83xx_lock_flash(adapter))
2798         return -EIO;
2799 
2800     memset(&adapter->ahw->fdt, 0, fdt_size);
2801     ret = qlcnic_83xx_lockless_flash_read32(adapter, QLCNIC_FDT_LOCATION,
2802                         (u8 *)&adapter->ahw->fdt,
2803                         count);
2804     qlcnic_swap32_buffer((u32 *)&adapter->ahw->fdt, count);
2805     qlcnic_83xx_unlock_flash(adapter);
2806     return ret;
2807 }
2808 
2809 int qlcnic_83xx_erase_flash_sector(struct qlcnic_adapter *adapter,
2810                    u32 sector_start_addr)
2811 {
2812     u32 reversed_addr, addr1, addr2, cmd;
2813     int ret = -EIO;
2814 
2815     if (qlcnic_83xx_lock_flash(adapter) != 0)
2816         return -EIO;
2817 
2818     if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
2819         ret = qlcnic_83xx_enable_flash_write(adapter);
2820         if (ret) {
2821             qlcnic_83xx_unlock_flash(adapter);
2822             dev_err(&adapter->pdev->dev,
2823                 "%s failed at %d\n",
2824                 __func__, __LINE__);
2825             return ret;
2826         }
2827     }
2828 
2829     ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2830     if (ret) {
2831         qlcnic_83xx_unlock_flash(adapter);
2832         dev_err(&adapter->pdev->dev,
2833             "%s: failed at %d\n", __func__, __LINE__);
2834         return -EIO;
2835     }
2836 
2837     addr1 = (sector_start_addr & 0xFF) << 16;
2838     addr2 = (sector_start_addr & 0xFF0000) >> 16;
2839     reversed_addr = addr1 | addr2 | (sector_start_addr & 0xFF00);
2840 
2841     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2842                      reversed_addr);
2843     cmd = QLC_83XX_FLASH_FDT_ERASE_DEF_SIG | adapter->ahw->fdt.erase_cmd;
2844     if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id)
2845         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR, cmd);
2846     else
2847         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2848                          QLC_83XX_FLASH_OEM_ERASE_SIG);
2849     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2850                      QLC_83XX_FLASH_LAST_ERASE_MS_VAL);
2851 
2852     ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2853     if (ret) {
2854         qlcnic_83xx_unlock_flash(adapter);
2855         dev_err(&adapter->pdev->dev,
2856             "%s: failed at %d\n", __func__, __LINE__);
2857         return -EIO;
2858     }
2859 
2860     if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
2861         ret = qlcnic_83xx_disable_flash_write(adapter);
2862         if (ret) {
2863             qlcnic_83xx_unlock_flash(adapter);
2864             dev_err(&adapter->pdev->dev,
2865                 "%s: failed at %d\n", __func__, __LINE__);
2866             return ret;
2867         }
2868     }
2869 
2870     qlcnic_83xx_unlock_flash(adapter);
2871 
2872     return 0;
2873 }
2874 
2875 int qlcnic_83xx_flash_write32(struct qlcnic_adapter *adapter, u32 addr,
2876                   u32 *p_data)
2877 {
2878     int ret = -EIO;
2879     u32 addr1 = 0x00800000 | (addr >> 2);
2880 
2881     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR, addr1);
2882     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data);
2883     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2884                      QLC_83XX_FLASH_LAST_ERASE_MS_VAL);
2885     ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2886     if (ret) {
2887         dev_err(&adapter->pdev->dev,
2888             "%s: failed at %d\n", __func__, __LINE__);
2889         return -EIO;
2890     }
2891 
2892     return 0;
2893 }
2894 
2895 int qlcnic_83xx_flash_bulk_write(struct qlcnic_adapter *adapter, u32 addr,
2896                  u32 *p_data, int count)
2897 {
2898     u32 temp;
2899     int ret = -EIO, err = 0;
2900 
2901     if ((count < QLC_83XX_FLASH_WRITE_MIN) ||
2902         (count > QLC_83XX_FLASH_WRITE_MAX)) {
2903         dev_err(&adapter->pdev->dev,
2904             "%s: Invalid word count\n", __func__);
2905         return -EIO;
2906     }
2907 
2908     temp = QLCRD32(adapter, QLC_83XX_FLASH_SPI_CONTROL, &err);
2909     if (err == -EIO)
2910         return err;
2911 
2912     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_SPI_CONTROL,
2913                      (temp | QLC_83XX_FLASH_SPI_CTRL));
2914     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2915                      QLC_83XX_FLASH_ADDR_TEMP_VAL);
2916 
2917     /* First DWORD write */
2918     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data++);
2919     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2920                      QLC_83XX_FLASH_FIRST_MS_PATTERN);
2921     ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2922     if (ret) {
2923         dev_err(&adapter->pdev->dev,
2924             "%s: failed at %d\n", __func__, __LINE__);
2925         return -EIO;
2926     }
2927 
2928     count--;
2929     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2930                      QLC_83XX_FLASH_ADDR_SECOND_TEMP_VAL);
2931     /* Second to N-1 DWORD writes */
2932     while (count != 1) {
2933         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2934                          *p_data++);
2935         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2936                          QLC_83XX_FLASH_SECOND_MS_PATTERN);
2937         ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2938         if (ret) {
2939             dev_err(&adapter->pdev->dev,
2940                 "%s: failed at %d\n", __func__, __LINE__);
2941             return -EIO;
2942         }
2943         count--;
2944     }
2945 
2946     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2947                      QLC_83XX_FLASH_ADDR_TEMP_VAL |
2948                      (addr >> 2));
2949     /* Last DWORD write */
2950     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data++);
2951     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2952                      QLC_83XX_FLASH_LAST_MS_PATTERN);
2953     ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2954     if (ret) {
2955         dev_err(&adapter->pdev->dev,
2956             "%s: failed at %d\n", __func__, __LINE__);
2957         return -EIO;
2958     }
2959 
2960     ret = QLCRD32(adapter, QLC_83XX_FLASH_SPI_STATUS, &err);
2961     if (err == -EIO)
2962         return err;
2963 
2964     if ((ret & QLC_83XX_FLASH_SPI_CTRL) == QLC_83XX_FLASH_SPI_CTRL) {
2965         dev_err(&adapter->pdev->dev, "%s: failed at %d\n",
2966             __func__, __LINE__);
2967         /* Operation failed, clear error bit */
2968         temp = QLCRD32(adapter, QLC_83XX_FLASH_SPI_CONTROL, &err);
2969         if (err == -EIO)
2970             return err;
2971 
2972         qlcnic_83xx_wrt_reg_indirect(adapter,
2973                          QLC_83XX_FLASH_SPI_CONTROL,
2974                          (temp | QLC_83XX_FLASH_SPI_CTRL));
2975     }
2976 
2977     return 0;
2978 }
2979 
2980 static void qlcnic_83xx_recover_driver_lock(struct qlcnic_adapter *adapter)
2981 {
2982     u32 val, id;
2983 
2984     val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK);
2985 
2986     /* Check if recovery need to be performed by the calling function */
2987     if ((val & QLC_83XX_DRV_LOCK_RECOVERY_STATUS_MASK) == 0) {
2988         val = val & ~0x3F;
2989         val = val | ((adapter->portnum << 2) |
2990                  QLC_83XX_NEED_DRV_LOCK_RECOVERY);
2991         QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
2992         dev_info(&adapter->pdev->dev,
2993              "%s: lock recovery initiated\n", __func__);
2994         msleep(QLC_83XX_DRV_LOCK_RECOVERY_DELAY);
2995         val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK);
2996         id = ((val >> 2) & 0xF);
2997         if (id == adapter->portnum) {
2998             val = val & ~QLC_83XX_DRV_LOCK_RECOVERY_STATUS_MASK;
2999             val = val | QLC_83XX_DRV_LOCK_RECOVERY_IN_PROGRESS;
3000             QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
3001             /* Force release the lock */
3002             QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
3003             /* Clear recovery bits */
3004             val = val & ~0x3F;
3005             QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
3006             dev_info(&adapter->pdev->dev,
3007                  "%s: lock recovery completed\n", __func__);
3008         } else {
3009             dev_info(&adapter->pdev->dev,
3010                  "%s: func %d to resume lock recovery process\n",
3011                  __func__, id);
3012         }
3013     } else {
3014         dev_info(&adapter->pdev->dev,
3015              "%s: lock recovery initiated by other functions\n",
3016              __func__);
3017     }
3018 }
3019 
3020 int qlcnic_83xx_lock_driver(struct qlcnic_adapter *adapter)
3021 {
3022     u32 lock_alive_counter, val, id, i = 0, status = 0, temp = 0;
3023     int max_attempt = 0;
3024 
3025     while (status == 0) {
3026         status = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK);
3027         if (status)
3028             break;
3029 
3030         msleep(QLC_83XX_DRV_LOCK_WAIT_DELAY);
3031         i++;
3032 
3033         if (i == 1)
3034             temp = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
3035 
3036         if (i == QLC_83XX_DRV_LOCK_WAIT_COUNTER) {
3037             val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
3038             if (val == temp) {
3039                 id = val & 0xFF;
3040                 dev_info(&adapter->pdev->dev,
3041                      "%s: lock to be recovered from %d\n",
3042                      __func__, id);
3043                 qlcnic_83xx_recover_driver_lock(adapter);
3044                 i = 0;
3045                 max_attempt++;
3046             } else {
3047                 dev_err(&adapter->pdev->dev,
3048                     "%s: failed to get lock\n", __func__);
3049                 return -EIO;
3050             }
3051         }
3052 
3053         /* Force exit from while loop after few attempts */
3054         if (max_attempt == QLC_83XX_MAX_DRV_LOCK_RECOVERY_ATTEMPT) {
3055             dev_err(&adapter->pdev->dev,
3056                 "%s: failed to get lock\n", __func__);
3057             return -EIO;
3058         }
3059     }
3060 
3061     val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
3062     lock_alive_counter = val >> 8;
3063     lock_alive_counter++;
3064     val = lock_alive_counter << 8 | adapter->portnum;
3065     QLCWRX(adapter->ahw, QLC_83XX_DRV_LOCK_ID, val);
3066 
3067     return 0;
3068 }
3069 
3070 void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *adapter)
3071 {
3072     u32 val, lock_alive_counter, id;
3073 
3074     val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
3075     id = val & 0xFF;
3076     lock_alive_counter = val >> 8;
3077 
3078     if (id != adapter->portnum)
3079         dev_err(&adapter->pdev->dev,
3080             "%s:Warning func %d is unlocking lock owned by %d\n",
3081             __func__, adapter->portnum, id);
3082 
3083     val = (lock_alive_counter << 8) | 0xFF;
3084     QLCWRX(adapter->ahw, QLC_83XX_DRV_LOCK_ID, val);
3085     QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
3086 }
3087 
3088 int qlcnic_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr,
3089                 u32 *data, u32 count)
3090 {
3091     int i, j, ret = 0;
3092     u32 temp;
3093 
3094     /* Check alignment */
3095     if (addr & 0xF)
3096         return -EIO;
3097 
3098     mutex_lock(&adapter->ahw->mem_lock);
3099     qlcnic_ind_wr(adapter, QLCNIC_MS_ADDR_HI, 0);
3100 
3101     for (i = 0; i < count; i++, addr += 16) {
3102         if (!((ADDR_IN_RANGE(addr, QLCNIC_ADDR_QDR_NET,
3103                      QLCNIC_ADDR_QDR_NET_MAX)) ||
3104               (ADDR_IN_RANGE(addr, QLCNIC_ADDR_DDR_NET,
3105                      QLCNIC_ADDR_DDR_NET_MAX)))) {
3106             mutex_unlock(&adapter->ahw->mem_lock);
3107             return -EIO;
3108         }
3109 
3110         qlcnic_ind_wr(adapter, QLCNIC_MS_ADDR_LO, addr);
3111         qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_LO, *data++);
3112         qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_HI, *data++);
3113         qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_ULO, *data++);
3114         qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_UHI, *data++);
3115         qlcnic_ind_wr(adapter, QLCNIC_MS_CTRL, QLCNIC_TA_WRITE_ENABLE);
3116         qlcnic_ind_wr(adapter, QLCNIC_MS_CTRL, QLCNIC_TA_WRITE_START);
3117 
3118         for (j = 0; j < MAX_CTL_CHECK; j++) {
3119             temp = qlcnic_ind_rd(adapter, QLCNIC_MS_CTRL);
3120 
3121             if ((temp & TA_CTL_BUSY) == 0)
3122                 break;
3123         }
3124 
3125         /* Status check failure */
3126         if (j >= MAX_CTL_CHECK) {
3127             printk_ratelimited(KERN_WARNING
3128                        "MS memory write failed\n");
3129             mutex_unlock(&adapter->ahw->mem_lock);
3130             return -EIO;
3131         }
3132     }
3133 
3134     mutex_unlock(&adapter->ahw->mem_lock);
3135 
3136     return ret;
3137 }
3138 
3139 int qlcnic_83xx_flash_read32(struct qlcnic_adapter *adapter, u32 flash_addr,
3140                  u8 *p_data, int count)
3141 {
3142     u32 word, addr = flash_addr, ret;
3143     ulong  indirect_addr;
3144     int i, err = 0;
3145 
3146     if (qlcnic_83xx_lock_flash(adapter) != 0)
3147         return -EIO;
3148 
3149     if (addr & 0x3) {
3150         dev_err(&adapter->pdev->dev, "Illegal addr = 0x%x\n", addr);
3151         qlcnic_83xx_unlock_flash(adapter);
3152         return -EIO;
3153     }
3154 
3155     for (i = 0; i < count; i++) {
3156         if (qlcnic_83xx_wrt_reg_indirect(adapter,
3157                          QLC_83XX_FLASH_DIRECT_WINDOW,
3158                          (addr))) {
3159             qlcnic_83xx_unlock_flash(adapter);
3160             return -EIO;
3161         }
3162 
3163         indirect_addr = QLC_83XX_FLASH_DIRECT_DATA(addr);
3164         ret = QLCRD32(adapter, indirect_addr, &err);
3165         if (err == -EIO) {
3166             qlcnic_83xx_unlock_flash(adapter);
3167             return err;
3168         }
3169 
3170         word = ret;
3171         *(u32 *)p_data  = word;
3172         p_data = p_data + 4;
3173         addr = addr + 4;
3174     }
3175 
3176     qlcnic_83xx_unlock_flash(adapter);
3177 
3178     return 0;
3179 }
3180 
3181 void qlcnic_83xx_get_port_type(struct qlcnic_adapter *adapter)
3182 {
3183     struct qlcnic_hardware_context *ahw = adapter->ahw;
3184     struct qlcnic_cmd_args cmd;
3185     u32 config;
3186     int err;
3187 
3188     err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_STATUS);
3189     if (err)
3190         return;
3191 
3192     err = qlcnic_issue_cmd(adapter, &cmd);
3193     if (err) {
3194         dev_info(&adapter->pdev->dev,
3195              "Get Link Status Command failed: 0x%x\n", err);
3196         goto out;
3197     } else {
3198         config = cmd.rsp.arg[3];
3199 
3200         switch (QLC_83XX_SFP_MODULE_TYPE(config)) {
3201         case QLC_83XX_MODULE_FIBRE_1000BASE_SX:
3202         case QLC_83XX_MODULE_FIBRE_1000BASE_LX:
3203         case QLC_83XX_MODULE_FIBRE_1000BASE_CX:
3204         case QLC_83XX_MODULE_TP_1000BASE_T:
3205             ahw->port_type = QLCNIC_GBE;
3206             break;
3207         default:
3208             ahw->port_type = QLCNIC_XGBE;
3209         }
3210     }
3211 out:
3212     qlcnic_free_mbx_args(&cmd);
3213 }
3214 
3215 int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter)
3216 {
3217     u8 pci_func;
3218     int err;
3219     u32 config = 0, state;
3220     struct qlcnic_cmd_args cmd;
3221     struct qlcnic_hardware_context *ahw = adapter->ahw;
3222 
3223     if (qlcnic_sriov_vf_check(adapter))
3224         pci_func = adapter->portnum;
3225     else
3226         pci_func = ahw->pci_func;
3227 
3228     state = readl(ahw->pci_base0 + QLC_83XX_LINK_STATE(pci_func));
3229     if (!QLC_83xx_FUNC_VAL(state, pci_func)) {
3230         dev_info(&adapter->pdev->dev, "link state down\n");
3231         return config;
3232     }
3233 
3234     err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_STATUS);
3235     if (err)
3236         return err;
3237 
3238     err = qlcnic_issue_cmd(adapter, &cmd);
3239     if (err) {
3240         dev_info(&adapter->pdev->dev,
3241              "Get Link Status Command failed: 0x%x\n", err);
3242         goto out;
3243     } else {
3244         config = cmd.rsp.arg[1];
3245         switch (QLC_83XX_CURRENT_LINK_SPEED(config)) {
3246         case QLC_83XX_10M_LINK:
3247             ahw->link_speed = SPEED_10;
3248             break;
3249         case QLC_83XX_100M_LINK:
3250             ahw->link_speed = SPEED_100;
3251             break;
3252         case QLC_83XX_1G_LINK:
3253             ahw->link_speed = SPEED_1000;
3254             break;
3255         case QLC_83XX_10G_LINK:
3256             ahw->link_speed = SPEED_10000;
3257             break;
3258         default:
3259             ahw->link_speed = 0;
3260             break;
3261         }
3262         config = cmd.rsp.arg[3];
3263         switch (QLC_83XX_SFP_MODULE_TYPE(config)) {
3264         case QLC_83XX_MODULE_FIBRE_10GBASE_LRM:
3265         case QLC_83XX_MODULE_FIBRE_10GBASE_LR:
3266         case QLC_83XX_MODULE_FIBRE_10GBASE_SR:
3267             ahw->supported_type = PORT_FIBRE;
3268             ahw->port_type = QLCNIC_XGBE;
3269             break;
3270         case QLC_83XX_MODULE_FIBRE_1000BASE_SX:
3271         case QLC_83XX_MODULE_FIBRE_1000BASE_LX:
3272         case QLC_83XX_MODULE_FIBRE_1000BASE_CX:
3273             ahw->supported_type = PORT_FIBRE;
3274             ahw->port_type = QLCNIC_GBE;
3275             break;
3276         case QLC_83XX_MODULE_TP_1000BASE_T:
3277             ahw->supported_type = PORT_TP;
3278             ahw->port_type = QLCNIC_GBE;
3279             break;
3280         case QLC_83XX_MODULE_DA_10GE_PASSIVE_CP:
3281         case QLC_83XX_MODULE_DA_10GE_ACTIVE_CP:
3282         case QLC_83XX_MODULE_DA_10GE_LEGACY_CP:
3283         case QLC_83XX_MODULE_DA_1GE_PASSIVE_CP:
3284             ahw->supported_type = PORT_DA;
3285             ahw->port_type = QLCNIC_XGBE;
3286             break;
3287         default:
3288             ahw->supported_type = PORT_OTHER;
3289             ahw->port_type = QLCNIC_XGBE;
3290         }
3291         if (config & 1)
3292             err = 1;
3293     }
3294 out:
3295     qlcnic_free_mbx_args(&cmd);
3296     return config;
3297 }
3298 
3299 int qlcnic_83xx_get_link_ksettings(struct qlcnic_adapter *adapter,
3300                    struct ethtool_link_ksettings *ecmd)
3301 {
3302     struct qlcnic_hardware_context *ahw = adapter->ahw;
3303     u32 config = 0;
3304     int status = 0;
3305     u32 supported, advertising;
3306 
3307     if (!test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) {
3308         /* Get port configuration info */
3309         status = qlcnic_83xx_get_port_info(adapter);
3310         /* Get Link Status related info */
3311         config = qlcnic_83xx_test_link(adapter);
3312         ahw->module_type = QLC_83XX_SFP_MODULE_TYPE(config);
3313     }
3314 
3315     /* hard code until there is a way to get it from flash */
3316     ahw->board_type = QLCNIC_BRDTYPE_83XX_10G;
3317 
3318     if (netif_running(adapter->netdev) && ahw->has_link_events) {
3319         ecmd->base.speed = ahw->link_speed;
3320         ecmd->base.duplex = ahw->link_duplex;
3321         ecmd->base.autoneg = ahw->link_autoneg;
3322     } else {
3323         ecmd->base.speed = SPEED_UNKNOWN;
3324         ecmd->base.duplex = DUPLEX_UNKNOWN;
3325         ecmd->base.autoneg = AUTONEG_DISABLE;
3326     }
3327 
3328     supported = (SUPPORTED_10baseT_Full |
3329                SUPPORTED_100baseT_Full |
3330                SUPPORTED_1000baseT_Full |
3331                SUPPORTED_10000baseT_Full |
3332                SUPPORTED_Autoneg);
3333 
3334     ethtool_convert_link_mode_to_legacy_u32(&advertising,
3335                         ecmd->link_modes.advertising);
3336 
3337     if (ecmd->base.autoneg == AUTONEG_ENABLE) {
3338         if (ahw->port_config & QLC_83XX_10_CAPABLE)
3339             advertising |= SUPPORTED_10baseT_Full;
3340         if (ahw->port_config & QLC_83XX_100_CAPABLE)
3341             advertising |= SUPPORTED_100baseT_Full;
3342         if (ahw->port_config & QLC_83XX_1G_CAPABLE)
3343             advertising |= SUPPORTED_1000baseT_Full;
3344         if (ahw->port_config & QLC_83XX_10G_CAPABLE)
3345             advertising |= SUPPORTED_10000baseT_Full;
3346         if (ahw->port_config & QLC_83XX_AUTONEG_ENABLE)
3347             advertising |= ADVERTISED_Autoneg;
3348     } else {
3349         switch (ahw->link_speed) {
3350         case SPEED_10:
3351             advertising = SUPPORTED_10baseT_Full;
3352             break;
3353         case SPEED_100:
3354             advertising = SUPPORTED_100baseT_Full;
3355             break;
3356         case SPEED_1000:
3357             advertising = SUPPORTED_1000baseT_Full;
3358             break;
3359         case SPEED_10000:
3360             advertising = SUPPORTED_10000baseT_Full;
3361             break;
3362         default:
3363             break;
3364         }
3365 
3366     }
3367 
3368     switch (ahw->supported_type) {
3369     case PORT_FIBRE:
3370         supported |= SUPPORTED_FIBRE;
3371         advertising |= ADVERTISED_FIBRE;
3372         ecmd->base.port = PORT_FIBRE;
3373         break;
3374     case PORT_TP:
3375         supported |= SUPPORTED_TP;
3376         advertising |= ADVERTISED_TP;
3377         ecmd->base.port = PORT_TP;
3378         break;
3379     case PORT_DA:
3380         supported |= SUPPORTED_FIBRE;
3381         advertising |= ADVERTISED_FIBRE;
3382         ecmd->base.port = PORT_DA;
3383         break;
3384     default:
3385         supported |= SUPPORTED_FIBRE;
3386         advertising |= ADVERTISED_FIBRE;
3387         ecmd->base.port = PORT_OTHER;
3388         break;
3389     }
3390     ecmd->base.phy_address = ahw->physical_port;
3391 
3392     ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.supported,
3393                         supported);
3394     ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.advertising,
3395                         advertising);
3396 
3397     return status;
3398 }
3399 
3400 int qlcnic_83xx_set_link_ksettings(struct qlcnic_adapter *adapter,
3401                    const struct ethtool_link_ksettings *ecmd)
3402 {
3403     struct qlcnic_hardware_context *ahw = adapter->ahw;
3404     u32 config = adapter->ahw->port_config;
3405     int status = 0;
3406 
3407     /* 83xx devices do not support Half duplex */
3408     if (ecmd->base.duplex == DUPLEX_HALF) {
3409         netdev_info(adapter->netdev,
3410                 "Half duplex mode not supported\n");
3411         return -EINVAL;
3412     }
3413 
3414     if (ecmd->base.autoneg) {
3415         ahw->port_config |= QLC_83XX_AUTONEG_ENABLE;
3416         ahw->port_config |= (QLC_83XX_100_CAPABLE |
3417                      QLC_83XX_1G_CAPABLE |
3418                      QLC_83XX_10G_CAPABLE);
3419     } else { /* force speed */
3420         ahw->port_config &= ~QLC_83XX_AUTONEG_ENABLE;
3421         switch (ecmd->base.speed) {
3422         case SPEED_10:
3423             ahw->port_config &= ~(QLC_83XX_100_CAPABLE |
3424                           QLC_83XX_1G_CAPABLE |
3425                           QLC_83XX_10G_CAPABLE);
3426             ahw->port_config |= QLC_83XX_10_CAPABLE;
3427             break;
3428         case SPEED_100:
3429             ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
3430                           QLC_83XX_1G_CAPABLE |
3431                           QLC_83XX_10G_CAPABLE);
3432             ahw->port_config |= QLC_83XX_100_CAPABLE;
3433             break;
3434         case SPEED_1000:
3435             ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
3436                           QLC_83XX_100_CAPABLE |
3437                           QLC_83XX_10G_CAPABLE);
3438             ahw->port_config |= QLC_83XX_1G_CAPABLE;
3439             break;
3440         case SPEED_10000:
3441             ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
3442                           QLC_83XX_100_CAPABLE |
3443                           QLC_83XX_1G_CAPABLE);
3444             ahw->port_config |= QLC_83XX_10G_CAPABLE;
3445             break;
3446         default:
3447             return -EINVAL;
3448         }
3449     }
3450     status = qlcnic_83xx_set_port_config(adapter);
3451     if (status) {
3452         netdev_info(adapter->netdev,
3453                 "Failed to Set Link Speed and autoneg.\n");
3454         ahw->port_config = config;
3455     }
3456 
3457     return status;
3458 }
3459 
3460 static inline u64 *qlcnic_83xx_copy_stats(struct qlcnic_cmd_args *cmd,
3461                       u64 *data, int index)
3462 {
3463     u32 low, hi;
3464     u64 val;
3465 
3466     low = cmd->rsp.arg[index];
3467     hi = cmd->rsp.arg[index + 1];
3468     val = (((u64) low) | (((u64) hi) << 32));
3469     *data++ = val;
3470     return data;
3471 }
3472 
3473 static u64 *qlcnic_83xx_fill_stats(struct qlcnic_adapter *adapter,
3474                    struct qlcnic_cmd_args *cmd, u64 *data,
3475                    int type, int *ret)
3476 {
3477     int err, k, total_regs;
3478 
3479     *ret = 0;
3480     err = qlcnic_issue_cmd(adapter, cmd);
3481     if (err != QLCNIC_RCODE_SUCCESS) {
3482         dev_info(&adapter->pdev->dev,
3483              "Error in get statistics mailbox command\n");
3484         *ret = -EIO;
3485         return data;
3486     }
3487     total_regs = cmd->rsp.num;
3488     switch (type) {
3489     case QLC_83XX_STAT_MAC:
3490         /* fill in MAC tx counters */
3491         for (k = 2; k < 28; k += 2)
3492             data = qlcnic_83xx_copy_stats(cmd, data, k);
3493         /* skip 24 bytes of reserved area */
3494         /* fill in MAC rx counters */
3495         for (k += 6; k < 60; k += 2)
3496             data = qlcnic_83xx_copy_stats(cmd, data, k);
3497         /* skip 24 bytes of reserved area */
3498         /* fill in MAC rx frame stats */
3499         for (k += 6; k < 80; k += 2)
3500             data = qlcnic_83xx_copy_stats(cmd, data, k);
3501         /* fill in eSwitch stats */
3502         for (; k < total_regs; k += 2)
3503             data = qlcnic_83xx_copy_stats(cmd, data, k);
3504         break;
3505     case QLC_83XX_STAT_RX:
3506         for (k = 2; k < 8; k += 2)
3507             data = qlcnic_83xx_copy_stats(cmd, data, k);
3508         /* skip 8 bytes of reserved data */
3509         for (k += 2; k < 24; k += 2)
3510             data = qlcnic_83xx_copy_stats(cmd, data, k);
3511         /* skip 8 bytes containing RE1FBQ error data */
3512         for (k += 2; k < total_regs; k += 2)
3513             data = qlcnic_83xx_copy_stats(cmd, data, k);
3514         break;
3515     case QLC_83XX_STAT_TX:
3516         for (k = 2; k < 10; k += 2)
3517             data = qlcnic_83xx_copy_stats(cmd, data, k);
3518         /* skip 8 bytes of reserved data */
3519         for (k += 2; k < total_regs; k += 2)
3520             data = qlcnic_83xx_copy_stats(cmd, data, k);
3521         break;
3522     default:
3523         dev_warn(&adapter->pdev->dev, "Unknown get statistics mode\n");
3524         *ret = -EIO;
3525     }
3526     return data;
3527 }
3528 
3529 void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data)
3530 {
3531     struct qlcnic_cmd_args cmd;
3532     struct net_device *netdev = adapter->netdev;
3533     int ret = 0;
3534 
3535     ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_STATISTICS);
3536     if (ret)
3537         return;
3538     /* Get Tx stats */
3539     cmd.req.arg[1] = BIT_1 | (adapter->tx_ring->ctx_id << 16);
3540     cmd.rsp.num = QLC_83XX_TX_STAT_REGS;
3541     data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
3542                       QLC_83XX_STAT_TX, &ret);
3543     if (ret) {
3544         netdev_err(netdev, "Error getting Tx stats\n");
3545         goto out;
3546     }
3547     /* Get MAC stats */
3548     cmd.req.arg[1] = BIT_2 | (adapter->portnum << 16);
3549     cmd.rsp.num = QLC_83XX_MAC_STAT_REGS;
3550     memset(cmd.rsp.arg, 0, sizeof(u32) * cmd.rsp.num);
3551     data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
3552                       QLC_83XX_STAT_MAC, &ret);
3553     if (ret) {
3554         netdev_err(netdev, "Error getting MAC stats\n");
3555         goto out;
3556     }
3557     /* Get Rx stats */
3558     cmd.req.arg[1] = adapter->recv_ctx->context_id << 16;
3559     cmd.rsp.num = QLC_83XX_RX_STAT_REGS;
3560     memset(cmd.rsp.arg, 0, sizeof(u32) * cmd.rsp.num);
3561     data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
3562                       QLC_83XX_STAT_RX, &ret);
3563     if (ret)
3564         netdev_err(netdev, "Error getting Rx stats\n");
3565 out:
3566     qlcnic_free_mbx_args(&cmd);
3567 }
3568 
3569 #define QLCNIC_83XX_ADD_PORT0       BIT_0
3570 #define QLCNIC_83XX_ADD_PORT1       BIT_1
3571 #define QLCNIC_83XX_EXTENDED_MEM_SIZE   13 /* In MB */
3572 int qlcnic_83xx_extend_md_capab(struct qlcnic_adapter *adapter)
3573 {
3574     struct qlcnic_cmd_args cmd;
3575     int err;
3576 
3577     err = qlcnic_alloc_mbx_args(&cmd, adapter,
3578                     QLCNIC_CMD_83XX_EXTEND_ISCSI_DUMP_CAP);
3579     if (err)
3580         return err;
3581 
3582     cmd.req.arg[1] = (QLCNIC_83XX_ADD_PORT0 | QLCNIC_83XX_ADD_PORT1);
3583     cmd.req.arg[2] = QLCNIC_83XX_EXTENDED_MEM_SIZE;
3584     cmd.req.arg[3] = QLCNIC_83XX_EXTENDED_MEM_SIZE;
3585 
3586     err = qlcnic_issue_cmd(adapter, &cmd);
3587     if (err)
3588         dev_err(&adapter->pdev->dev,
3589             "failed to issue extend iSCSI minidump capability\n");
3590 
3591     return err;
3592 }
3593 
3594 int qlcnic_83xx_reg_test(struct qlcnic_adapter *adapter)
3595 {
3596     u32 major, minor, sub;
3597 
3598     major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR);
3599     minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR);
3600     sub = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB);
3601 
3602     if (adapter->fw_version != QLCNIC_VERSION_CODE(major, minor, sub)) {
3603         dev_info(&adapter->pdev->dev, "%s: Reg test failed\n",
3604              __func__);
3605         return 1;
3606     }
3607     return 0;
3608 }
3609 
3610 inline int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *adapter)
3611 {
3612     return (ARRAY_SIZE(qlcnic_83xx_ext_reg_tbl) *
3613         sizeof(*adapter->ahw->ext_reg_tbl)) +
3614         (ARRAY_SIZE(qlcnic_83xx_reg_tbl) *
3615         sizeof(*adapter->ahw->reg_tbl));
3616 }
3617 
3618 int qlcnic_83xx_get_registers(struct qlcnic_adapter *adapter, u32 *regs_buff)
3619 {
3620     int i, j = 0;
3621 
3622     for (i = QLCNIC_DEV_INFO_SIZE + 1;
3623          j < ARRAY_SIZE(qlcnic_83xx_reg_tbl); i++, j++)
3624         regs_buff[i] = QLC_SHARED_REG_RD32(adapter, j);
3625 
3626     for (j = 0; j < ARRAY_SIZE(qlcnic_83xx_ext_reg_tbl); j++)
3627         regs_buff[i++] = QLCRDX(adapter->ahw, j);
3628     return i;
3629 }
3630 
3631 int qlcnic_83xx_interrupt_test(struct net_device *netdev)
3632 {
3633     struct qlcnic_adapter *adapter = netdev_priv(netdev);
3634     struct qlcnic_hardware_context *ahw = adapter->ahw;
3635     struct qlcnic_cmd_args cmd;
3636     u8 val, drv_sds_rings = adapter->drv_sds_rings;
3637     u8 drv_tx_rings = adapter->drv_tx_rings;
3638     u32 data;
3639     u16 intrpt_id, id;
3640     int ret;
3641 
3642     if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
3643         netdev_info(netdev, "Device is resetting\n");
3644         return -EBUSY;
3645     }
3646 
3647     if (qlcnic_get_diag_lock(adapter)) {
3648         netdev_info(netdev, "Device in diagnostics mode\n");
3649         return -EBUSY;
3650     }
3651 
3652     ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST,
3653                      drv_sds_rings);
3654     if (ret)
3655         goto fail_diag_irq;
3656 
3657     ahw->diag_cnt = 0;
3658     ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST);
3659     if (ret)
3660         goto fail_mbx_args;
3661 
3662     if (adapter->flags & QLCNIC_MSIX_ENABLED)
3663         intrpt_id = ahw->intr_tbl[0].id;
3664     else
3665         intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
3666 
3667     cmd.req.arg[1] = 1;
3668     cmd.req.arg[2] = intrpt_id;
3669     cmd.req.arg[3] = BIT_0;
3670 
3671     ret = qlcnic_issue_cmd(adapter, &cmd);
3672     data = cmd.rsp.arg[2];
3673     id = LSW(data);
3674     val = LSB(MSW(data));
3675     if (id != intrpt_id)
3676         dev_info(&adapter->pdev->dev,
3677              "Interrupt generated: 0x%x, requested:0x%x\n",
3678              id, intrpt_id);
3679     if (val)
3680         dev_err(&adapter->pdev->dev,
3681              "Interrupt test error: 0x%x\n", val);
3682     if (ret)
3683         goto done;
3684 
3685     msleep(20);
3686     ret = !ahw->diag_cnt;
3687 
3688 done:
3689     qlcnic_free_mbx_args(&cmd);
3690 
3691 fail_mbx_args:
3692     qlcnic_83xx_diag_free_res(netdev, drv_sds_rings);
3693 
3694 fail_diag_irq:
3695     adapter->drv_sds_rings = drv_sds_rings;
3696     adapter->drv_tx_rings = drv_tx_rings;
3697     qlcnic_release_diag_lock(adapter);
3698     return ret;
3699 }
3700 
3701 void qlcnic_83xx_get_pauseparam(struct qlcnic_adapter *adapter,
3702                 struct ethtool_pauseparam *pause)
3703 {
3704     struct qlcnic_hardware_context *ahw = adapter->ahw;
3705     int status = 0;
3706     u32 config;
3707 
3708     status = qlcnic_83xx_get_port_config(adapter);
3709     if (status) {
3710         dev_err(&adapter->pdev->dev,
3711             "%s: Get Pause Config failed\n", __func__);
3712         return;
3713     }
3714     config = ahw->port_config;
3715     if (config & QLC_83XX_CFG_STD_PAUSE) {
3716         switch (MSW(config)) {
3717         case QLC_83XX_TX_PAUSE:
3718             pause->tx_pause = 1;
3719             break;
3720         case QLC_83XX_RX_PAUSE:
3721             pause->rx_pause = 1;
3722             break;
3723         case QLC_83XX_TX_RX_PAUSE:
3724         default:
3725             /* Backward compatibility for existing
3726              * flash definitions
3727              */
3728             pause->tx_pause = 1;
3729             pause->rx_pause = 1;
3730         }
3731     }
3732 
3733     if (QLC_83XX_AUTONEG(config))
3734         pause->autoneg = 1;
3735 }
3736 
3737 int qlcnic_83xx_set_pauseparam(struct qlcnic_adapter *adapter,
3738                    struct ethtool_pauseparam *pause)
3739 {
3740     struct qlcnic_hardware_context *ahw = adapter->ahw;
3741     int status = 0;
3742     u32 config;
3743 
3744     status = qlcnic_83xx_get_port_config(adapter);
3745     if (status) {
3746         dev_err(&adapter->pdev->dev,
3747             "%s: Get Pause Config failed.\n", __func__);
3748         return status;
3749     }
3750     config = ahw->port_config;
3751 
3752     if (ahw->port_type == QLCNIC_GBE) {
3753         if (pause->autoneg)
3754             ahw->port_config |= QLC_83XX_ENABLE_AUTONEG;
3755         if (!pause->autoneg)
3756             ahw->port_config &= ~QLC_83XX_ENABLE_AUTONEG;
3757     } else if ((ahw->port_type == QLCNIC_XGBE) && (pause->autoneg)) {
3758         return -EOPNOTSUPP;
3759     }
3760 
3761     if (!(config & QLC_83XX_CFG_STD_PAUSE))
3762         ahw->port_config |= QLC_83XX_CFG_STD_PAUSE;
3763 
3764     if (pause->rx_pause && pause->tx_pause) {
3765         ahw->port_config |= QLC_83XX_CFG_STD_TX_RX_PAUSE;
3766     } else if (pause->rx_pause && !pause->tx_pause) {
3767         ahw->port_config &= ~QLC_83XX_CFG_STD_TX_PAUSE;
3768         ahw->port_config |= QLC_83XX_CFG_STD_RX_PAUSE;
3769     } else if (pause->tx_pause && !pause->rx_pause) {
3770         ahw->port_config &= ~QLC_83XX_CFG_STD_RX_PAUSE;
3771         ahw->port_config |= QLC_83XX_CFG_STD_TX_PAUSE;
3772     } else if (!pause->rx_pause && !pause->tx_pause) {
3773         ahw->port_config &= ~(QLC_83XX_CFG_STD_TX_RX_PAUSE |
3774                       QLC_83XX_CFG_STD_PAUSE);
3775     }
3776     status = qlcnic_83xx_set_port_config(adapter);
3777     if (status) {
3778         dev_err(&adapter->pdev->dev,
3779             "%s: Set Pause Config failed.\n", __func__);
3780         ahw->port_config = config;
3781     }
3782     return status;
3783 }
3784 
3785 static int qlcnic_83xx_read_flash_status_reg(struct qlcnic_adapter *adapter)
3786 {
3787     int ret, err = 0;
3788     u32 temp;
3789 
3790     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
3791                      QLC_83XX_FLASH_OEM_READ_SIG);
3792     qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
3793                      QLC_83XX_FLASH_READ_CTRL);
3794     ret = qlcnic_83xx_poll_flash_status_reg(adapter);
3795     if (ret)
3796         return -EIO;
3797 
3798     temp = QLCRD32(adapter, QLC_83XX_FLASH_RDDATA, &err);
3799     if (err == -EIO)
3800         return err;
3801 
3802     return temp & 0xFF;
3803 }
3804 
3805 int qlcnic_83xx_flash_test(struct qlcnic_adapter *adapter)
3806 {
3807     int status;
3808 
3809     status = qlcnic_83xx_read_flash_status_reg(adapter);
3810     if (status == -EIO) {
3811         dev_info(&adapter->pdev->dev, "%s: EEPROM test failed.\n",
3812              __func__);
3813         return 1;
3814     }
3815     return 0;
3816 }
3817 
3818 static int qlcnic_83xx_shutdown(struct pci_dev *pdev)
3819 {
3820     struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
3821     struct net_device *netdev = adapter->netdev;
3822 
3823     netif_device_detach(netdev);
3824     qlcnic_cancel_idc_work(adapter);
3825 
3826     if (netif_running(netdev))
3827         qlcnic_down(adapter, netdev);
3828 
3829     qlcnic_83xx_disable_mbx_intr(adapter);
3830     cancel_delayed_work_sync(&adapter->idc_aen_work);
3831 
3832     return pci_save_state(pdev);
3833 }
3834 
3835 static int qlcnic_83xx_resume(struct qlcnic_adapter *adapter)
3836 {
3837     struct qlcnic_hardware_context *ahw = adapter->ahw;
3838     struct qlc_83xx_idc *idc = &ahw->idc;
3839     int err = 0;
3840 
3841     err = qlcnic_83xx_idc_init(adapter);
3842     if (err)
3843         return err;
3844 
3845     if (ahw->nic_mode == QLCNIC_VNIC_MODE) {
3846         if (ahw->op_mode == QLCNIC_MGMT_FUNC) {
3847             qlcnic_83xx_set_vnic_opmode(adapter);
3848         } else {
3849             err = qlcnic_83xx_check_vnic_state(adapter);
3850             if (err)
3851                 return err;
3852         }
3853     }
3854 
3855     err = qlcnic_83xx_idc_reattach_driver(adapter);
3856     if (err)
3857         return err;
3858 
3859     qlcnic_schedule_work(adapter, qlcnic_83xx_idc_poll_dev_state,
3860                  idc->delay);
3861     return err;
3862 }
3863 
3864 void qlcnic_83xx_reinit_mbx_work(struct qlcnic_mailbox *mbx)
3865 {
3866     reinit_completion(&mbx->completion);
3867     set_bit(QLC_83XX_MBX_READY, &mbx->status);
3868 }
3869 
3870 void qlcnic_83xx_free_mailbox(struct qlcnic_mailbox *mbx)
3871 {
3872     if (!mbx)
3873         return;
3874 
3875     destroy_workqueue(mbx->work_q);
3876     kfree(mbx);
3877 }
3878 
3879 static inline void
3880 qlcnic_83xx_notify_cmd_completion(struct qlcnic_adapter *adapter,
3881                   struct qlcnic_cmd_args *cmd)
3882 {
3883     atomic_set(&cmd->rsp_status, QLC_83XX_MBX_RESPONSE_ARRIVED);
3884 
3885     if (cmd->type == QLC_83XX_MBX_CMD_NO_WAIT) {
3886         qlcnic_free_mbx_args(cmd);
3887         kfree(cmd);
3888         return;
3889     }
3890     complete(&cmd->completion);
3891 }
3892 
3893 static void qlcnic_83xx_flush_mbx_queue(struct qlcnic_adapter *adapter)
3894 {
3895     struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
3896     struct list_head *head = &mbx->cmd_q;
3897     struct qlcnic_cmd_args *cmd = NULL;
3898 
3899     spin_lock_bh(&mbx->queue_lock);
3900 
3901     while (!list_empty(head)) {
3902         cmd = list_entry(head->next, struct qlcnic_cmd_args, list);
3903         dev_info(&adapter->pdev->dev, "%s: Mailbox command 0x%x\n",
3904              __func__, cmd->cmd_op);
3905         list_del(&cmd->list);
3906         mbx->num_cmds--;
3907         qlcnic_83xx_notify_cmd_completion(adapter, cmd);
3908     }
3909 
3910     spin_unlock_bh(&mbx->queue_lock);
3911 }
3912 
3913 static int qlcnic_83xx_check_mbx_status(struct qlcnic_adapter *adapter)
3914 {
3915     struct qlcnic_hardware_context *ahw = adapter->ahw;
3916     struct qlcnic_mailbox *mbx = ahw->mailbox;
3917     u32 host_mbx_ctrl;
3918 
3919     if (!test_bit(QLC_83XX_MBX_READY, &mbx->status))
3920         return -EBUSY;
3921 
3922     host_mbx_ctrl = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
3923     if (host_mbx_ctrl) {
3924         clear_bit(QLC_83XX_MBX_READY, &mbx->status);
3925         ahw->idc.collect_dump = 1;
3926         return -EIO;
3927     }
3928 
3929     return 0;
3930 }
3931 
3932 static inline void qlcnic_83xx_signal_mbx_cmd(struct qlcnic_adapter *adapter,
3933                           u8 issue_cmd)
3934 {
3935     if (issue_cmd)
3936         QLCWRX(adapter->ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER);
3937     else
3938         QLCWRX(adapter->ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
3939 }
3940 
3941 static void qlcnic_83xx_dequeue_mbx_cmd(struct qlcnic_adapter *adapter,
3942                     struct qlcnic_cmd_args *cmd)
3943 {
3944     struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
3945 
3946     spin_lock_bh(&mbx->queue_lock);
3947 
3948     list_del(&cmd->list);
3949     mbx->num_cmds--;
3950 
3951     spin_unlock_bh(&mbx->queue_lock);
3952 
3953     qlcnic_83xx_notify_cmd_completion(adapter, cmd);
3954 }
3955 
3956 static void qlcnic_83xx_encode_mbx_cmd(struct qlcnic_adapter *adapter,
3957                        struct qlcnic_cmd_args *cmd)
3958 {
3959     u32 mbx_cmd, fw_hal_version, hdr_size, total_size, tmp;
3960     struct qlcnic_hardware_context *ahw = adapter->ahw;
3961     int i, j;
3962 
3963     if (cmd->op_type != QLC_83XX_MBX_POST_BC_OP) {
3964         mbx_cmd = cmd->req.arg[0];
3965         writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 0));
3966         for (i = 1; i < cmd->req.num; i++)
3967             writel(cmd->req.arg[i], QLCNIC_MBX_HOST(ahw, i));
3968     } else {
3969         fw_hal_version = ahw->fw_hal_version;
3970         hdr_size = sizeof(struct qlcnic_bc_hdr) / sizeof(u32);
3971         total_size = cmd->pay_size + hdr_size;
3972         tmp = QLCNIC_CMD_BC_EVENT_SETUP | total_size << 16;
3973         mbx_cmd = tmp | fw_hal_version << 29;
3974         writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 0));
3975 
3976         /* Back channel specific operations bits */
3977         mbx_cmd = 0x1 | 1 << 4;
3978 
3979         if (qlcnic_sriov_pf_check(adapter))
3980             mbx_cmd |= cmd->func_num << 5;
3981 
3982         writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 1));
3983 
3984         for (i = 2, j = 0; j < hdr_size; i++, j++)
3985             writel(*(cmd->hdr++), QLCNIC_MBX_HOST(ahw, i));
3986         for (j = 0; j < cmd->pay_size; j++, i++)
3987             writel(*(cmd->pay++), QLCNIC_MBX_HOST(ahw, i));
3988     }
3989 }
3990 
3991 void qlcnic_83xx_detach_mailbox_work(struct qlcnic_adapter *adapter)
3992 {
3993     struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
3994 
3995     if (!mbx)
3996         return;
3997 
3998     clear_bit(QLC_83XX_MBX_READY, &mbx->status);
3999     complete(&mbx->completion);
4000     cancel_work_sync(&mbx->work);
4001     flush_workqueue(mbx->work_q);
4002     qlcnic_83xx_flush_mbx_queue(adapter);
4003 }
4004 
4005 static int qlcnic_83xx_enqueue_mbx_cmd(struct qlcnic_adapter *adapter,
4006                        struct qlcnic_cmd_args *cmd,
4007                        unsigned long *timeout)
4008 {
4009     struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
4010 
4011     if (test_bit(QLC_83XX_MBX_READY, &mbx->status)) {
4012         atomic_set(&cmd->rsp_status, QLC_83XX_MBX_RESPONSE_WAIT);
4013         init_completion(&cmd->completion);
4014         cmd->rsp_opcode = QLC_83XX_MBX_RESPONSE_UNKNOWN;
4015 
4016         spin_lock_bh(&mbx->queue_lock);
4017 
4018         list_add_tail(&cmd->list, &mbx->cmd_q);
4019         mbx->num_cmds++;
4020         cmd->total_cmds = mbx->num_cmds;
4021         *timeout = cmd->total_cmds * QLC_83XX_MBX_TIMEOUT;
4022         queue_work(mbx->work_q, &mbx->work);
4023 
4024         spin_unlock_bh(&mbx->queue_lock);
4025 
4026         return 0;
4027     }
4028 
4029     return -EBUSY;
4030 }
4031 
4032 static int qlcnic_83xx_check_mac_rcode(struct qlcnic_adapter *adapter,
4033                        struct qlcnic_cmd_args *cmd)
4034 {
4035     u8 mac_cmd_rcode;
4036     u32 fw_data;
4037 
4038     if (cmd->cmd_op == QLCNIC_CMD_CONFIG_MAC_VLAN) {
4039         fw_data = readl(QLCNIC_MBX_FW(adapter->ahw, 2));
4040         mac_cmd_rcode = (u8)fw_data;
4041         if (mac_cmd_rcode == QLC_83XX_NO_NIC_RESOURCE ||
4042             mac_cmd_rcode == QLC_83XX_MAC_PRESENT ||
4043             mac_cmd_rcode == QLC_83XX_MAC_ABSENT) {
4044             cmd->rsp_opcode = QLCNIC_RCODE_SUCCESS;
4045             return QLCNIC_RCODE_SUCCESS;
4046         }
4047     }
4048 
4049     return -EINVAL;
4050 }
4051 
4052 static void qlcnic_83xx_decode_mbx_rsp(struct qlcnic_adapter *adapter,
4053                        struct qlcnic_cmd_args *cmd)
4054 {
4055     struct qlcnic_hardware_context *ahw = adapter->ahw;
4056     struct device *dev = &adapter->pdev->dev;
4057     u8 mbx_err_code;
4058     u32 fw_data;
4059 
4060     fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
4061     mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
4062     qlcnic_83xx_get_mbx_data(adapter, cmd);
4063 
4064     switch (mbx_err_code) {
4065     case QLCNIC_MBX_RSP_OK:
4066     case QLCNIC_MBX_PORT_RSP_OK:
4067         cmd->rsp_opcode = QLCNIC_RCODE_SUCCESS;
4068         break;
4069     default:
4070         if (!qlcnic_83xx_check_mac_rcode(adapter, cmd))
4071             break;
4072 
4073         dev_err(dev, "%s: Mailbox command failed, opcode=0x%x, cmd_type=0x%x, func=0x%x, op_mode=0x%x, error=0x%x\n",
4074             __func__, cmd->cmd_op, cmd->type, ahw->pci_func,
4075             ahw->op_mode, mbx_err_code);
4076         cmd->rsp_opcode = QLC_83XX_MBX_RESPONSE_FAILED;
4077         qlcnic_dump_mbx(adapter, cmd);
4078     }
4079 
4080     return;
4081 }
4082 
4083 static inline void qlcnic_dump_mailbox_registers(struct qlcnic_adapter *adapter)
4084 {
4085     struct qlcnic_hardware_context *ahw = adapter->ahw;
4086     u32 offset;
4087 
4088     offset = QLCRDX(ahw, QLCNIC_DEF_INT_MASK);
4089     dev_info(&adapter->pdev->dev, "Mbx interrupt mask=0x%x, Mbx interrupt enable=0x%x, Host mbx control=0x%x, Fw mbx control=0x%x",
4090          readl(ahw->pci_base0 + offset),
4091          QLCRDX(ahw, QLCNIC_MBX_INTR_ENBL),
4092          QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL),
4093          QLCRDX(ahw, QLCNIC_FW_MBX_CTRL));
4094 }
4095 
4096 static void qlcnic_83xx_mailbox_worker(struct work_struct *work)
4097 {
4098     struct qlcnic_mailbox *mbx = container_of(work, struct qlcnic_mailbox,
4099                           work);
4100     struct qlcnic_adapter *adapter = mbx->adapter;
4101     const struct qlcnic_mbx_ops *mbx_ops = mbx->ops;
4102     struct device *dev = &adapter->pdev->dev;
4103     struct list_head *head = &mbx->cmd_q;
4104     struct qlcnic_hardware_context *ahw;
4105     struct qlcnic_cmd_args *cmd = NULL;
4106     unsigned long flags;
4107 
4108     ahw = adapter->ahw;
4109 
4110     while (true) {
4111         if (qlcnic_83xx_check_mbx_status(adapter)) {
4112             qlcnic_83xx_flush_mbx_queue(adapter);
4113             return;
4114         }
4115 
4116         spin_lock_irqsave(&mbx->aen_lock, flags);
4117         mbx->rsp_status = QLC_83XX_MBX_RESPONSE_WAIT;
4118         spin_unlock_irqrestore(&mbx->aen_lock, flags);
4119 
4120         spin_lock_bh(&mbx->queue_lock);
4121 
4122         if (list_empty(head)) {
4123             spin_unlock_bh(&mbx->queue_lock);
4124             return;
4125         }
4126         cmd = list_entry(head->next, struct qlcnic_cmd_args, list);
4127 
4128         spin_unlock_bh(&mbx->queue_lock);
4129 
4130         mbx_ops->encode_cmd(adapter, cmd);
4131         mbx_ops->nofity_fw(adapter, QLC_83XX_MBX_REQUEST);
4132 
4133         if (wait_for_completion_timeout(&mbx->completion,
4134                         QLC_83XX_MBX_TIMEOUT)) {
4135             mbx_ops->decode_resp(adapter, cmd);
4136             mbx_ops->nofity_fw(adapter, QLC_83XX_MBX_COMPLETION);
4137         } else {
4138             dev_err(dev, "%s: Mailbox command timeout, opcode=0x%x, cmd_type=0x%x, func=0x%x, op_mode=0x%x\n",
4139                 __func__, cmd->cmd_op, cmd->type, ahw->pci_func,
4140                 ahw->op_mode);
4141             clear_bit(QLC_83XX_MBX_READY, &mbx->status);
4142             qlcnic_dump_mailbox_registers(adapter);
4143             qlcnic_83xx_get_mbx_data(adapter, cmd);
4144             qlcnic_dump_mbx(adapter, cmd);
4145             qlcnic_83xx_idc_request_reset(adapter,
4146                               QLCNIC_FORCE_FW_DUMP_KEY);
4147             cmd->rsp_opcode = QLCNIC_RCODE_TIMEOUT;
4148         }
4149         mbx_ops->dequeue_cmd(adapter, cmd);
4150     }
4151 }
4152 
4153 static const struct qlcnic_mbx_ops qlcnic_83xx_mbx_ops = {
4154     .enqueue_cmd    = qlcnic_83xx_enqueue_mbx_cmd,
4155     .dequeue_cmd    = qlcnic_83xx_dequeue_mbx_cmd,
4156     .decode_resp    = qlcnic_83xx_decode_mbx_rsp,
4157     .encode_cmd     = qlcnic_83xx_encode_mbx_cmd,
4158     .nofity_fw      = qlcnic_83xx_signal_mbx_cmd,
4159 };
4160 
4161 int qlcnic_83xx_init_mailbox_work(struct qlcnic_adapter *adapter)
4162 {
4163     struct qlcnic_hardware_context *ahw = adapter->ahw;
4164     struct qlcnic_mailbox *mbx;
4165 
4166     ahw->mailbox = kzalloc(sizeof(*mbx), GFP_KERNEL);
4167     if (!ahw->mailbox)
4168         return -ENOMEM;
4169 
4170     mbx = ahw->mailbox;
4171     mbx->ops = &qlcnic_83xx_mbx_ops;
4172     mbx->adapter = adapter;
4173 
4174     spin_lock_init(&mbx->queue_lock);
4175     spin_lock_init(&mbx->aen_lock);
4176     INIT_LIST_HEAD(&mbx->cmd_q);
4177     init_completion(&mbx->completion);
4178 
4179     mbx->work_q = create_singlethread_workqueue("qlcnic_mailbox");
4180     if (mbx->work_q == NULL) {
4181         kfree(mbx);
4182         return -ENOMEM;
4183     }
4184 
4185     INIT_WORK(&mbx->work, qlcnic_83xx_mailbox_worker);
4186     set_bit(QLC_83XX_MBX_READY, &mbx->status);
4187     return 0;
4188 }
4189 
4190 static pci_ers_result_t qlcnic_83xx_io_error_detected(struct pci_dev *pdev,
4191                               pci_channel_state_t state)
4192 {
4193     struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
4194 
4195     if (state == pci_channel_io_perm_failure)
4196         return PCI_ERS_RESULT_DISCONNECT;
4197 
4198     if (state == pci_channel_io_normal)
4199         return PCI_ERS_RESULT_RECOVERED;
4200 
4201     set_bit(__QLCNIC_AER, &adapter->state);
4202     set_bit(__QLCNIC_RESETTING, &adapter->state);
4203 
4204     qlcnic_83xx_aer_stop_poll_work(adapter);
4205 
4206     pci_save_state(pdev);
4207     pci_disable_device(pdev);
4208 
4209     return PCI_ERS_RESULT_NEED_RESET;
4210 }
4211 
4212 static pci_ers_result_t qlcnic_83xx_io_slot_reset(struct pci_dev *pdev)
4213 {
4214     struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
4215     int err = 0;
4216 
4217     pdev->error_state = pci_channel_io_normal;
4218     err = pci_enable_device(pdev);
4219     if (err)
4220         goto disconnect;
4221 
4222     pci_set_power_state(pdev, PCI_D0);
4223     pci_set_master(pdev);
4224     pci_restore_state(pdev);
4225 
4226     err = qlcnic_83xx_aer_reset(adapter);
4227     if (err == 0)
4228         return PCI_ERS_RESULT_RECOVERED;
4229 disconnect:
4230     clear_bit(__QLCNIC_AER, &adapter->state);
4231     clear_bit(__QLCNIC_RESETTING, &adapter->state);
4232     return PCI_ERS_RESULT_DISCONNECT;
4233 }
4234 
4235 static void qlcnic_83xx_io_resume(struct pci_dev *pdev)
4236 {
4237     struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
4238 
4239     if (test_and_clear_bit(__QLCNIC_AER, &adapter->state))
4240         qlcnic_83xx_aer_start_poll_work(adapter);
4241 }