linux/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
<<
>>
Prefs
   1/*
   2 * QLogic qlcnic NIC Driver
   3 * Copyright (c) 2009-2013 QLogic Corporation
   4 *
   5 * See LICENSE.qlcnic for copyright and licensing details.
   6 */
   7
   8#include <linux/if_vlan.h>
   9#include <linux/ipv6.h>
  10#include <linux/ethtool.h>
  11#include <linux/interrupt.h>
  12#include <linux/aer.h>
  13
  14#include "qlcnic.h"
  15#include "qlcnic_sriov.h"
  16
  17static void __qlcnic_83xx_process_aen(struct qlcnic_adapter *);
  18static int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *, u8);
  19static void qlcnic_83xx_configure_mac(struct qlcnic_adapter *, u8 *, u8,
  20                                      struct qlcnic_cmd_args *);
  21static int qlcnic_83xx_get_port_config(struct qlcnic_adapter *);
  22static irqreturn_t qlcnic_83xx_handle_aen(int, void *);
  23static pci_ers_result_t qlcnic_83xx_io_error_detected(struct pci_dev *,
  24                                                      pci_channel_state_t);
  25static int qlcnic_83xx_set_port_config(struct qlcnic_adapter *);
  26static pci_ers_result_t qlcnic_83xx_io_slot_reset(struct pci_dev *);
  27static void qlcnic_83xx_io_resume(struct pci_dev *);
  28static int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *, u8);
  29static void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *);
  30static int qlcnic_83xx_resume(struct qlcnic_adapter *);
  31static int qlcnic_83xx_shutdown(struct pci_dev *);
  32static void qlcnic_83xx_get_beacon_state(struct qlcnic_adapter *);
  33
  34#define RSS_HASHTYPE_IP_TCP             0x3
  35#define QLC_83XX_FW_MBX_CMD             0
  36#define QLC_SKIP_INACTIVE_PCI_REGS      7
  37#define QLC_MAX_LEGACY_FUNC_SUPP        8
  38
  39/* 83xx Module type */
  40#define QLC_83XX_MODULE_FIBRE_10GBASE_LRM       0x1 /* 10GBase-LRM */
  41#define QLC_83XX_MODULE_FIBRE_10GBASE_LR        0x2 /* 10GBase-LR */
  42#define QLC_83XX_MODULE_FIBRE_10GBASE_SR        0x3 /* 10GBase-SR */
  43#define QLC_83XX_MODULE_DA_10GE_PASSIVE_CP      0x4 /* 10GE passive
  44                                                     * copper(compliant)
  45                                                     */
  46#define QLC_83XX_MODULE_DA_10GE_ACTIVE_CP       0x5 /* 10GE active limiting
  47                                                     * copper(compliant)
  48                                                     */
  49#define QLC_83XX_MODULE_DA_10GE_LEGACY_CP       0x6 /* 10GE passive copper
  50                                                     * (legacy, best effort)
  51                                                     */
  52#define QLC_83XX_MODULE_FIBRE_1000BASE_SX       0x7 /* 1000Base-SX */
  53#define QLC_83XX_MODULE_FIBRE_1000BASE_LX       0x8 /* 1000Base-LX */
  54#define QLC_83XX_MODULE_FIBRE_1000BASE_CX       0x9 /* 1000Base-CX */
  55#define QLC_83XX_MODULE_TP_1000BASE_T           0xa /* 1000Base-T*/
  56#define QLC_83XX_MODULE_DA_1GE_PASSIVE_CP       0xb /* 1GE passive copper
  57                                                     * (legacy, best effort)
  58                                                     */
  59#define QLC_83XX_MODULE_UNKNOWN                 0xf /* Unknown module type */
  60
  61/* Port types */
  62#define QLC_83XX_10_CAPABLE      BIT_8
  63#define QLC_83XX_100_CAPABLE     BIT_9
  64#define QLC_83XX_1G_CAPABLE      BIT_10
  65#define QLC_83XX_10G_CAPABLE     BIT_11
  66#define QLC_83XX_AUTONEG_ENABLE  BIT_15
  67
  68static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
  69        {QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1},
  70        {QLCNIC_CMD_CONFIG_INTRPT, 18, 34},
  71        {QLCNIC_CMD_CREATE_RX_CTX, 136, 27},
  72        {QLCNIC_CMD_DESTROY_RX_CTX, 2, 1},
  73        {QLCNIC_CMD_CREATE_TX_CTX, 54, 18},
  74        {QLCNIC_CMD_DESTROY_TX_CTX, 2, 1},
  75        {QLCNIC_CMD_CONFIGURE_MAC_LEARNING, 2, 1},
  76        {QLCNIC_CMD_INTRPT_TEST, 22, 12},
  77        {QLCNIC_CMD_SET_MTU, 3, 1},
  78        {QLCNIC_CMD_READ_PHY, 4, 2},
  79        {QLCNIC_CMD_WRITE_PHY, 5, 1},
  80        {QLCNIC_CMD_READ_HW_REG, 4, 1},
  81        {QLCNIC_CMD_GET_FLOW_CTL, 4, 2},
  82        {QLCNIC_CMD_SET_FLOW_CTL, 4, 1},
  83        {QLCNIC_CMD_READ_MAX_MTU, 4, 2},
  84        {QLCNIC_CMD_READ_MAX_LRO, 4, 2},
  85        {QLCNIC_CMD_MAC_ADDRESS, 4, 3},
  86        {QLCNIC_CMD_GET_PCI_INFO, 1, 129},
  87        {QLCNIC_CMD_GET_NIC_INFO, 2, 19},
  88        {QLCNIC_CMD_SET_NIC_INFO, 32, 1},
  89        {QLCNIC_CMD_GET_ESWITCH_CAPABILITY, 4, 3},
  90        {QLCNIC_CMD_TOGGLE_ESWITCH, 4, 1},
  91        {QLCNIC_CMD_GET_ESWITCH_STATUS, 4, 3},
  92        {QLCNIC_CMD_SET_PORTMIRRORING, 4, 1},
  93        {QLCNIC_CMD_CONFIGURE_ESWITCH, 4, 1},
  94        {QLCNIC_CMD_GET_ESWITCH_PORT_CONFIG, 4, 3},
  95        {QLCNIC_CMD_GET_ESWITCH_STATS, 5, 1},
  96        {QLCNIC_CMD_CONFIG_PORT, 4, 1},
  97        {QLCNIC_CMD_TEMP_SIZE, 1, 4},
  98        {QLCNIC_CMD_GET_TEMP_HDR, 5, 5},
  99        {QLCNIC_CMD_GET_LINK_EVENT, 2, 1},
 100        {QLCNIC_CMD_CONFIG_MAC_VLAN, 4, 3},
 101        {QLCNIC_CMD_CONFIG_INTR_COAL, 6, 1},
 102        {QLCNIC_CMD_CONFIGURE_RSS, 14, 1},
 103        {QLCNIC_CMD_CONFIGURE_LED, 2, 1},
 104        {QLCNIC_CMD_CONFIGURE_MAC_RX_MODE, 2, 1},
 105        {QLCNIC_CMD_CONFIGURE_HW_LRO, 2, 1},
 106        {QLCNIC_CMD_GET_STATISTICS, 2, 80},
 107        {QLCNIC_CMD_SET_PORT_CONFIG, 2, 1},
 108        {QLCNIC_CMD_GET_PORT_CONFIG, 2, 2},
 109        {QLCNIC_CMD_GET_LINK_STATUS, 2, 4},
 110        {QLCNIC_CMD_IDC_ACK, 5, 1},
 111        {QLCNIC_CMD_INIT_NIC_FUNC, 3, 1},
 112        {QLCNIC_CMD_STOP_NIC_FUNC, 2, 1},
 113        {QLCNIC_CMD_SET_LED_CONFIG, 5, 1},
 114        {QLCNIC_CMD_GET_LED_CONFIG, 1, 5},
 115        {QLCNIC_CMD_83XX_SET_DRV_VER, 4, 1},
 116        {QLCNIC_CMD_ADD_RCV_RINGS, 130, 26},
 117        {QLCNIC_CMD_CONFIG_VPORT, 4, 4},
 118        {QLCNIC_CMD_BC_EVENT_SETUP, 2, 1},
 119        {QLCNIC_CMD_DCB_QUERY_CAP, 1, 2},
 120        {QLCNIC_CMD_DCB_QUERY_PARAM, 1, 50},
 121        {QLCNIC_CMD_SET_INGRESS_ENCAP, 2, 1},
 122        {QLCNIC_CMD_83XX_EXTEND_ISCSI_DUMP_CAP, 4, 1},
 123};
 124
 125const u32 qlcnic_83xx_ext_reg_tbl[] = {
 126        0x38CC,         /* Global Reset */
 127        0x38F0,         /* Wildcard */
 128        0x38FC,         /* Informant */
 129        0x3038,         /* Host MBX ctrl */
 130        0x303C,         /* FW MBX ctrl */
 131        0x355C,         /* BOOT LOADER ADDRESS REG */
 132        0x3560,         /* BOOT LOADER SIZE REG */
 133        0x3564,         /* FW IMAGE ADDR REG */
 134        0x1000,         /* MBX intr enable */
 135        0x1200,         /* Default Intr mask */
 136        0x1204,         /* Default Interrupt ID */
 137        0x3780,         /* QLC_83XX_IDC_MAJ_VERSION */
 138        0x3784,         /* QLC_83XX_IDC_DEV_STATE */
 139        0x3788,         /* QLC_83XX_IDC_DRV_PRESENCE */
 140        0x378C,         /* QLC_83XX_IDC_DRV_ACK */
 141        0x3790,         /* QLC_83XX_IDC_CTRL */
 142        0x3794,         /* QLC_83XX_IDC_DRV_AUDIT */
 143        0x3798,         /* QLC_83XX_IDC_MIN_VERSION */
 144        0x379C,         /* QLC_83XX_RECOVER_DRV_LOCK */
 145        0x37A0,         /* QLC_83XX_IDC_PF_0 */
 146        0x37A4,         /* QLC_83XX_IDC_PF_1 */
 147        0x37A8,         /* QLC_83XX_IDC_PF_2 */
 148        0x37AC,         /* QLC_83XX_IDC_PF_3 */
 149        0x37B0,         /* QLC_83XX_IDC_PF_4 */
 150        0x37B4,         /* QLC_83XX_IDC_PF_5 */
 151        0x37B8,         /* QLC_83XX_IDC_PF_6 */
 152        0x37BC,         /* QLC_83XX_IDC_PF_7 */
 153        0x37C0,         /* QLC_83XX_IDC_PF_8 */
 154        0x37C4,         /* QLC_83XX_IDC_PF_9 */
 155        0x37C8,         /* QLC_83XX_IDC_PF_10 */
 156        0x37CC,         /* QLC_83XX_IDC_PF_11 */
 157        0x37D0,         /* QLC_83XX_IDC_PF_12 */
 158        0x37D4,         /* QLC_83XX_IDC_PF_13 */
 159        0x37D8,         /* QLC_83XX_IDC_PF_14 */
 160        0x37DC,         /* QLC_83XX_IDC_PF_15 */
 161        0x37E0,         /* QLC_83XX_IDC_DEV_PARTITION_INFO_1 */
 162        0x37E4,         /* QLC_83XX_IDC_DEV_PARTITION_INFO_2 */
 163        0x37F0,         /* QLC_83XX_DRV_OP_MODE */
 164        0x37F4,         /* QLC_83XX_VNIC_STATE */
 165        0x3868,         /* QLC_83XX_DRV_LOCK */
 166        0x386C,         /* QLC_83XX_DRV_UNLOCK */
 167        0x3504,         /* QLC_83XX_DRV_LOCK_ID */
 168        0x34A4,         /* QLC_83XX_ASIC_TEMP */
 169};
 170
 171const u32 qlcnic_83xx_reg_tbl[] = {
 172        0x34A8,         /* PEG_HALT_STAT1 */
 173        0x34AC,         /* PEG_HALT_STAT2 */
 174        0x34B0,         /* FW_HEARTBEAT */
 175        0x3500,         /* FLASH LOCK_ID */
 176        0x3528,         /* FW_CAPABILITIES */
 177        0x3538,         /* Driver active, DRV_REG0 */
 178        0x3540,         /* Device state, DRV_REG1 */
 179        0x3544,         /* Driver state, DRV_REG2 */
 180        0x3548,         /* Driver scratch, DRV_REG3 */
 181        0x354C,         /* Device partiton info, DRV_REG4 */
 182        0x3524,         /* Driver IDC ver, DRV_REG5 */
 183        0x3550,         /* FW_VER_MAJOR */
 184        0x3554,         /* FW_VER_MINOR */
 185        0x3558,         /* FW_VER_SUB */
 186        0x359C,         /* NPAR STATE */
 187        0x35FC,         /* FW_IMG_VALID */
 188        0x3650,         /* CMD_PEG_STATE */
 189        0x373C,         /* RCV_PEG_STATE */
 190        0x37B4,         /* ASIC TEMP */
 191        0x356C,         /* FW API */
 192        0x3570,         /* DRV OP MODE */
 193        0x3850,         /* FLASH LOCK */
 194        0x3854,         /* FLASH UNLOCK */
 195};
 196
 197static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = {
 198        .read_crb                       = qlcnic_83xx_read_crb,
 199        .write_crb                      = qlcnic_83xx_write_crb,
 200        .read_reg                       = qlcnic_83xx_rd_reg_indirect,
 201        .write_reg                      = qlcnic_83xx_wrt_reg_indirect,
 202        .get_mac_address                = qlcnic_83xx_get_mac_address,
 203        .setup_intr                     = qlcnic_83xx_setup_intr,
 204        .alloc_mbx_args                 = qlcnic_83xx_alloc_mbx_args,
 205        .mbx_cmd                        = qlcnic_83xx_issue_cmd,
 206        .get_func_no                    = qlcnic_83xx_get_func_no,
 207        .api_lock                       = qlcnic_83xx_cam_lock,
 208        .api_unlock                     = qlcnic_83xx_cam_unlock,
 209        .add_sysfs                      = qlcnic_83xx_add_sysfs,
 210        .remove_sysfs                   = qlcnic_83xx_remove_sysfs,
 211        .process_lb_rcv_ring_diag       = qlcnic_83xx_process_rcv_ring_diag,
 212        .create_rx_ctx                  = qlcnic_83xx_create_rx_ctx,
 213        .create_tx_ctx                  = qlcnic_83xx_create_tx_ctx,
 214        .del_rx_ctx                     = qlcnic_83xx_del_rx_ctx,
 215        .del_tx_ctx                     = qlcnic_83xx_del_tx_ctx,
 216        .setup_link_event               = qlcnic_83xx_setup_link_event,
 217        .get_nic_info                   = qlcnic_83xx_get_nic_info,
 218        .get_pci_info                   = qlcnic_83xx_get_pci_info,
 219        .set_nic_info                   = qlcnic_83xx_set_nic_info,
 220        .change_macvlan                 = qlcnic_83xx_sre_macaddr_change,
 221        .napi_enable                    = qlcnic_83xx_napi_enable,
 222        .napi_disable                   = qlcnic_83xx_napi_disable,
 223        .config_intr_coal               = qlcnic_83xx_config_intr_coal,
 224        .config_rss                     = qlcnic_83xx_config_rss,
 225        .config_hw_lro                  = qlcnic_83xx_config_hw_lro,
 226        .config_promisc_mode            = qlcnic_83xx_nic_set_promisc,
 227        .change_l2_filter               = qlcnic_83xx_change_l2_filter,
 228        .get_board_info                 = qlcnic_83xx_get_port_info,
 229        .set_mac_filter_count           = qlcnic_83xx_set_mac_filter_count,
 230        .free_mac_list                  = qlcnic_82xx_free_mac_list,
 231        .io_error_detected              = qlcnic_83xx_io_error_detected,
 232        .io_slot_reset                  = qlcnic_83xx_io_slot_reset,
 233        .io_resume                      = qlcnic_83xx_io_resume,
 234        .get_beacon_state               = qlcnic_83xx_get_beacon_state,
 235        .enable_sds_intr                = qlcnic_83xx_enable_sds_intr,
 236        .disable_sds_intr               = qlcnic_83xx_disable_sds_intr,
 237        .enable_tx_intr                 = qlcnic_83xx_enable_tx_intr,
 238        .disable_tx_intr                = qlcnic_83xx_disable_tx_intr,
 239        .get_saved_state                = qlcnic_83xx_get_saved_state,
 240        .set_saved_state                = qlcnic_83xx_set_saved_state,
 241        .cache_tmpl_hdr_values          = qlcnic_83xx_cache_tmpl_hdr_values,
 242        .get_cap_size                   = qlcnic_83xx_get_cap_size,
 243        .set_sys_info                   = qlcnic_83xx_set_sys_info,
 244        .store_cap_mask                 = qlcnic_83xx_store_cap_mask,
 245};
 246
 247static struct qlcnic_nic_template qlcnic_83xx_ops = {
 248        .config_bridged_mode    = qlcnic_config_bridged_mode,
 249        .config_led             = qlcnic_config_led,
 250        .request_reset          = qlcnic_83xx_idc_request_reset,
 251        .cancel_idc_work        = qlcnic_83xx_idc_exit,
 252        .napi_add               = qlcnic_83xx_napi_add,
 253        .napi_del               = qlcnic_83xx_napi_del,
 254        .config_ipaddr          = qlcnic_83xx_config_ipaddr,
 255        .clear_legacy_intr      = qlcnic_83xx_clear_legacy_intr,
 256        .shutdown               = qlcnic_83xx_shutdown,
 257        .resume                 = qlcnic_83xx_resume,
 258};
 259
 260void qlcnic_83xx_register_map(struct qlcnic_hardware_context *ahw)
 261{
 262        ahw->hw_ops             = &qlcnic_83xx_hw_ops;
 263        ahw->reg_tbl            = (u32 *)qlcnic_83xx_reg_tbl;
 264        ahw->ext_reg_tbl        = (u32 *)qlcnic_83xx_ext_reg_tbl;
 265}
 266
 267int qlcnic_83xx_get_fw_version(struct qlcnic_adapter *adapter)
 268{
 269        u32 fw_major, fw_minor, fw_build;
 270        struct pci_dev *pdev = adapter->pdev;
 271
 272        fw_major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR);
 273        fw_minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR);
 274        fw_build = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB);
 275        adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build);
 276
 277        dev_info(&pdev->dev, "Driver v%s, firmware version %d.%d.%d\n",
 278                 QLCNIC_LINUX_VERSIONID, fw_major, fw_minor, fw_build);
 279
 280        return adapter->fw_version;
 281}
 282
 283static int __qlcnic_set_win_base(struct qlcnic_adapter *adapter, u32 addr)
 284{
 285        void __iomem *base;
 286        u32 val;
 287
 288        base = adapter->ahw->pci_base0 +
 289               QLC_83XX_CRB_WIN_FUNC(adapter->ahw->pci_func);
 290        writel(addr, base);
 291        val = readl(base);
 292        if (val != addr)
 293                return -EIO;
 294
 295        return 0;
 296}
 297
 298int qlcnic_83xx_rd_reg_indirect(struct qlcnic_adapter *adapter, ulong addr,
 299                                int *err)
 300{
 301        struct qlcnic_hardware_context *ahw = adapter->ahw;
 302
 303        *err = __qlcnic_set_win_base(adapter, (u32) addr);
 304        if (!*err) {
 305                return QLCRDX(ahw, QLCNIC_WILDCARD);
 306        } else {
 307                dev_err(&adapter->pdev->dev,
 308                        "%s failed, addr = 0x%lx\n", __func__, addr);
 309                return -EIO;
 310        }
 311}
 312
 313int qlcnic_83xx_wrt_reg_indirect(struct qlcnic_adapter *adapter, ulong addr,
 314                                 u32 data)
 315{
 316        int err;
 317        struct qlcnic_hardware_context *ahw = adapter->ahw;
 318
 319        err = __qlcnic_set_win_base(adapter, (u32) addr);
 320        if (!err) {
 321                QLCWRX(ahw, QLCNIC_WILDCARD, data);
 322                return 0;
 323        } else {
 324                dev_err(&adapter->pdev->dev,
 325                        "%s failed, addr = 0x%x data = 0x%x\n",
 326                        __func__, (int)addr, data);
 327                return err;
 328        }
 329}
 330
 331static void qlcnic_83xx_enable_legacy(struct qlcnic_adapter *adapter)
 332{
 333        struct qlcnic_hardware_context *ahw = adapter->ahw;
 334
 335        /* MSI-X enablement failed, use legacy interrupt */
 336        adapter->tgt_status_reg = ahw->pci_base0 + QLC_83XX_INTX_PTR;
 337        adapter->tgt_mask_reg = ahw->pci_base0 + QLC_83XX_INTX_MASK;
 338        adapter->isr_int_vec = ahw->pci_base0 + QLC_83XX_INTX_TRGR;
 339        adapter->msix_entries[0].vector = adapter->pdev->irq;
 340        dev_info(&adapter->pdev->dev, "using legacy interrupt\n");
 341}
 342
 343static int qlcnic_83xx_calculate_msix_vector(struct qlcnic_adapter *adapter)
 344{
 345        int num_msix;
 346
 347        num_msix = adapter->drv_sds_rings;
 348
 349        /* account for AEN interrupt MSI-X based interrupts */
 350        num_msix += 1;
 351
 352        if (!(adapter->flags & QLCNIC_TX_INTR_SHARED))
 353                num_msix += adapter->drv_tx_rings;
 354
 355        return num_msix;
 356}
 357
 358int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter)
 359{
 360        struct qlcnic_hardware_context *ahw = adapter->ahw;
 361        int err, i, num_msix;
 362
 363        if (adapter->flags & QLCNIC_TSS_RSS) {
 364                err = qlcnic_setup_tss_rss_intr(adapter);
 365                if (err < 0)
 366                        return err;
 367                num_msix = ahw->num_msix;
 368        } else {
 369                num_msix = qlcnic_83xx_calculate_msix_vector(adapter);
 370
 371                err = qlcnic_enable_msix(adapter, num_msix);
 372                if (err == -ENOMEM)
 373                        return err;
 374
 375                if (adapter->flags & QLCNIC_MSIX_ENABLED) {
 376                        num_msix = ahw->num_msix;
 377                } else {
 378                        if (qlcnic_sriov_vf_check(adapter))
 379                                return -EINVAL;
 380                        num_msix = 1;
 381                        adapter->drv_sds_rings = QLCNIC_SINGLE_RING;
 382                        adapter->drv_tx_rings = QLCNIC_SINGLE_RING;
 383                }
 384        }
 385
 386        /* setup interrupt mapping table for fw */
 387        ahw->intr_tbl = vzalloc(num_msix *
 388                                sizeof(struct qlcnic_intrpt_config));
 389        if (!ahw->intr_tbl)
 390                return -ENOMEM;
 391
 392        if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
 393                if (adapter->ahw->pci_func >= QLC_MAX_LEGACY_FUNC_SUPP) {
 394                        dev_err(&adapter->pdev->dev, "PCI function number 8 and higher are not supported with legacy interrupt, func 0x%x\n",
 395                                ahw->pci_func);
 396                        return -EOPNOTSUPP;
 397                }
 398
 399                qlcnic_83xx_enable_legacy(adapter);
 400        }
 401
 402        for (i = 0; i < num_msix; i++) {
 403                if (adapter->flags & QLCNIC_MSIX_ENABLED)
 404                        ahw->intr_tbl[i].type = QLCNIC_INTRPT_MSIX;
 405                else
 406                        ahw->intr_tbl[i].type = QLCNIC_INTRPT_INTX;
 407                ahw->intr_tbl[i].id = i;
 408                ahw->intr_tbl[i].src = 0;
 409        }
 410
 411        return 0;
 412}
 413
 414static inline void qlcnic_83xx_clear_legacy_intr_mask(struct qlcnic_adapter *adapter)
 415{
 416        writel(0, adapter->tgt_mask_reg);
 417}
 418
 419static inline void qlcnic_83xx_set_legacy_intr_mask(struct qlcnic_adapter *adapter)
 420{
 421        if (adapter->tgt_mask_reg)
 422                writel(1, adapter->tgt_mask_reg);
 423}
 424
 425static inline void qlcnic_83xx_enable_legacy_msix_mbx_intr(struct qlcnic_adapter
 426                                                    *adapter)
 427{
 428        u32 mask;
 429
 430        /* Mailbox in MSI-x mode and Legacy Interrupt share the same
 431         * source register. We could be here before contexts are created
 432         * and sds_ring->crb_intr_mask has not been initialized, calculate
 433         * BAR offset for Interrupt Source Register
 434         */
 435        mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
 436        writel(0, adapter->ahw->pci_base0 + mask);
 437}
 438
 439void qlcnic_83xx_disable_mbx_intr(struct qlcnic_adapter *adapter)
 440{
 441        u32 mask;
 442
 443        mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
 444        writel(1, adapter->ahw->pci_base0 + mask);
 445        QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, 0);
 446}
 447
 448static inline void qlcnic_83xx_get_mbx_data(struct qlcnic_adapter *adapter,
 449                                     struct qlcnic_cmd_args *cmd)
 450{
 451        int i;
 452
 453        if (cmd->op_type == QLC_83XX_MBX_POST_BC_OP)
 454                return;
 455
 456        for (i = 0; i < cmd->rsp.num; i++)
 457                cmd->rsp.arg[i] = readl(QLCNIC_MBX_FW(adapter->ahw, i));
 458}
 459
 460irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *adapter)
 461{
 462        u32 intr_val;
 463        struct qlcnic_hardware_context *ahw = adapter->ahw;
 464        int retries = 0;
 465
 466        intr_val = readl(adapter->tgt_status_reg);
 467
 468        if (!QLC_83XX_VALID_INTX_BIT31(intr_val))
 469                return IRQ_NONE;
 470
 471        if (QLC_83XX_INTX_FUNC(intr_val) != adapter->ahw->pci_func) {
 472                adapter->stats.spurious_intr++;
 473                return IRQ_NONE;
 474        }
 475        /* The barrier is required to ensure writes to the registers */
 476        wmb();
 477
 478        /* clear the interrupt trigger control register */
 479        writel(0, adapter->isr_int_vec);
 480        intr_val = readl(adapter->isr_int_vec);
 481        do {
 482                intr_val = readl(adapter->tgt_status_reg);
 483                if (QLC_83XX_INTX_FUNC(intr_val) != ahw->pci_func)
 484                        break;
 485                retries++;
 486        } while (QLC_83XX_VALID_INTX_BIT30(intr_val) &&
 487                 (retries < QLC_83XX_LEGACY_INTX_MAX_RETRY));
 488
 489        return IRQ_HANDLED;
 490}
 491
 492static inline void qlcnic_83xx_notify_mbx_response(struct qlcnic_mailbox *mbx)
 493{
 494        mbx->rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
 495        complete(&mbx->completion);
 496}
 497
 498static void qlcnic_83xx_poll_process_aen(struct qlcnic_adapter *adapter)
 499{
 500        u32 resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
 501        struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
 502        unsigned long flags;
 503
 504        spin_lock_irqsave(&mbx->aen_lock, flags);
 505        resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
 506        if (!(resp & QLCNIC_SET_OWNER))
 507                goto out;
 508
 509        event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
 510        if (event &  QLCNIC_MBX_ASYNC_EVENT) {
 511                __qlcnic_83xx_process_aen(adapter);
 512        } else {
 513                if (mbx->rsp_status != rsp_status)
 514                        qlcnic_83xx_notify_mbx_response(mbx);
 515        }
 516out:
 517        qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
 518        spin_unlock_irqrestore(&mbx->aen_lock, flags);
 519}
 520
 521irqreturn_t qlcnic_83xx_intr(int irq, void *data)
 522{
 523        struct qlcnic_adapter *adapter = data;
 524        struct qlcnic_host_sds_ring *sds_ring;
 525        struct qlcnic_hardware_context *ahw = adapter->ahw;
 526
 527        if (qlcnic_83xx_clear_legacy_intr(adapter) == IRQ_NONE)
 528                return IRQ_NONE;
 529
 530        qlcnic_83xx_poll_process_aen(adapter);
 531
 532        if (ahw->diag_test) {
 533                if (ahw->diag_test == QLCNIC_INTERRUPT_TEST)
 534                        ahw->diag_cnt++;
 535                qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
 536                return IRQ_HANDLED;
 537        }
 538
 539        if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
 540                qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
 541        } else {
 542                sds_ring = &adapter->recv_ctx->sds_rings[0];
 543                napi_schedule(&sds_ring->napi);
 544        }
 545
 546        return IRQ_HANDLED;
 547}
 548
 549irqreturn_t qlcnic_83xx_tmp_intr(int irq, void *data)
 550{
 551        struct qlcnic_host_sds_ring *sds_ring = data;
 552        struct qlcnic_adapter *adapter = sds_ring->adapter;
 553
 554        if (adapter->flags & QLCNIC_MSIX_ENABLED)
 555                goto done;
 556
 557        if (adapter->nic_ops->clear_legacy_intr(adapter) == IRQ_NONE)
 558                return IRQ_NONE;
 559
 560done:
 561        adapter->ahw->diag_cnt++;
 562        qlcnic_enable_sds_intr(adapter, sds_ring);
 563
 564        return IRQ_HANDLED;
 565}
 566
 567void qlcnic_83xx_free_mbx_intr(struct qlcnic_adapter *adapter)
 568{
 569        u32 num_msix;
 570
 571        if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
 572                qlcnic_83xx_set_legacy_intr_mask(adapter);
 573
 574        qlcnic_83xx_disable_mbx_intr(adapter);
 575
 576        if (adapter->flags & QLCNIC_MSIX_ENABLED)
 577                num_msix = adapter->ahw->num_msix - 1;
 578        else
 579                num_msix = 0;
 580
 581        msleep(20);
 582
 583        if (adapter->msix_entries) {
 584                synchronize_irq(adapter->msix_entries[num_msix].vector);
 585                free_irq(adapter->msix_entries[num_msix].vector, adapter);
 586        }
 587}
 588
 589int qlcnic_83xx_setup_mbx_intr(struct qlcnic_adapter *adapter)
 590{
 591        irq_handler_t handler;
 592        u32 val;
 593        int err = 0;
 594        unsigned long flags = 0;
 595
 596        if (!(adapter->flags & QLCNIC_MSI_ENABLED) &&
 597            !(adapter->flags & QLCNIC_MSIX_ENABLED))
 598                flags |= IRQF_SHARED;
 599
 600        if (adapter->flags & QLCNIC_MSIX_ENABLED) {
 601                handler = qlcnic_83xx_handle_aen;
 602                val = adapter->msix_entries[adapter->ahw->num_msix - 1].vector;
 603                err = request_irq(val, handler, flags, "qlcnic-MB", adapter);
 604                if (err) {
 605                        dev_err(&adapter->pdev->dev,
 606                                "failed to register MBX interrupt\n");
 607                        return err;
 608                }
 609        } else {
 610                handler = qlcnic_83xx_intr;
 611                val = adapter->msix_entries[0].vector;
 612                err = request_irq(val, handler, flags, "qlcnic", adapter);
 613                if (err) {
 614                        dev_err(&adapter->pdev->dev,
 615                                "failed to register INTx interrupt\n");
 616                        return err;
 617                }
 618                qlcnic_83xx_clear_legacy_intr_mask(adapter);
 619        }
 620
 621        /* Enable mailbox interrupt */
 622        qlcnic_83xx_enable_mbx_interrupt(adapter);
 623
 624        return err;
 625}
 626
 627void qlcnic_83xx_get_func_no(struct qlcnic_adapter *adapter)
 628{
 629        u32 val = QLCRDX(adapter->ahw, QLCNIC_INFORMANT);
 630        adapter->ahw->pci_func = (val >> 24) & 0xff;
 631}
 632
 633int qlcnic_83xx_cam_lock(struct qlcnic_adapter *adapter)
 634{
 635        void __iomem *addr;
 636        u32 val, limit = 0;
 637
 638        struct qlcnic_hardware_context *ahw = adapter->ahw;
 639
 640        addr = ahw->pci_base0 + QLC_83XX_SEM_LOCK_FUNC(ahw->pci_func);
 641        do {
 642                val = readl(addr);
 643                if (val) {
 644                        /* write the function number to register */
 645                        QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER,
 646                                            ahw->pci_func);
 647                        return 0;
 648                }
 649                usleep_range(1000, 2000);
 650        } while (++limit <= QLCNIC_PCIE_SEM_TIMEOUT);
 651
 652        return -EIO;
 653}
 654
 655void qlcnic_83xx_cam_unlock(struct qlcnic_adapter *adapter)
 656{
 657        void __iomem *addr;
 658        u32 val;
 659        struct qlcnic_hardware_context *ahw = adapter->ahw;
 660
 661        addr = ahw->pci_base0 + QLC_83XX_SEM_UNLOCK_FUNC(ahw->pci_func);
 662        val = readl(addr);
 663}
 664
 665void qlcnic_83xx_read_crb(struct qlcnic_adapter *adapter, char *buf,
 666                          loff_t offset, size_t size)
 667{
 668        int ret = 0;
 669        u32 data;
 670
 671        if (qlcnic_api_lock(adapter)) {
 672                dev_err(&adapter->pdev->dev,
 673                        "%s: failed to acquire lock. addr offset 0x%x\n",
 674                        __func__, (u32)offset);
 675                return;
 676        }
 677
 678        data = QLCRD32(adapter, (u32) offset, &ret);
 679        qlcnic_api_unlock(adapter);
 680
 681        if (ret == -EIO) {
 682                dev_err(&adapter->pdev->dev,
 683                        "%s: failed. addr offset 0x%x\n",
 684                        __func__, (u32)offset);
 685                return;
 686        }
 687        memcpy(buf, &data, size);
 688}
 689
 690void qlcnic_83xx_write_crb(struct qlcnic_adapter *adapter, char *buf,
 691                           loff_t offset, size_t size)
 692{
 693        u32 data;
 694
 695        memcpy(&data, buf, size);
 696        qlcnic_83xx_wrt_reg_indirect(adapter, (u32) offset, data);
 697}
 698
 699int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter)
 700{
 701        struct qlcnic_hardware_context *ahw = adapter->ahw;
 702        int status;
 703
 704        status = qlcnic_83xx_get_port_config(adapter);
 705        if (status) {
 706                dev_err(&adapter->pdev->dev,
 707                        "Get Port Info failed\n");
 708        } else {
 709
 710                if (ahw->port_config & QLC_83XX_10G_CAPABLE) {
 711                        ahw->port_type = QLCNIC_XGBE;
 712                } else if (ahw->port_config & QLC_83XX_10_CAPABLE ||
 713                           ahw->port_config & QLC_83XX_100_CAPABLE ||
 714                           ahw->port_config & QLC_83XX_1G_CAPABLE) {
 715                        ahw->port_type = QLCNIC_GBE;
 716                } else {
 717                        ahw->port_type = QLCNIC_XGBE;
 718                }
 719
 720                if (QLC_83XX_AUTONEG(ahw->port_config))
 721                        ahw->link_autoneg = AUTONEG_ENABLE;
 722
 723        }
 724        return status;
 725}
 726
 727static void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *adapter)
 728{
 729        struct qlcnic_hardware_context *ahw = adapter->ahw;
 730        u16 act_pci_fn = ahw->total_nic_func;
 731        u16 count;
 732
 733        ahw->max_mc_count = QLC_83XX_MAX_MC_COUNT;
 734        if (act_pci_fn <= 2)
 735                count = (QLC_83XX_MAX_UC_COUNT - QLC_83XX_MAX_MC_COUNT) /
 736                         act_pci_fn;
 737        else
 738                count = (QLC_83XX_LB_MAX_FILTERS - QLC_83XX_MAX_MC_COUNT) /
 739                         act_pci_fn;
 740        ahw->max_uc_count = count;
 741}
 742
 743void qlcnic_83xx_enable_mbx_interrupt(struct qlcnic_adapter *adapter)
 744{
 745        u32 val;
 746
 747        if (adapter->flags & QLCNIC_MSIX_ENABLED)
 748                val = BIT_2 | ((adapter->ahw->num_msix - 1) << 8);
 749        else
 750                val = BIT_2;
 751
 752        QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, val);
 753        qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
 754}
 755
 756void qlcnic_83xx_check_vf(struct qlcnic_adapter *adapter,
 757                          const struct pci_device_id *ent)
 758{
 759        u32 op_mode, priv_level;
 760        struct qlcnic_hardware_context *ahw = adapter->ahw;
 761
 762        ahw->fw_hal_version = 2;
 763        qlcnic_get_func_no(adapter);
 764
 765        if (qlcnic_sriov_vf_check(adapter)) {
 766                qlcnic_sriov_vf_set_ops(adapter);
 767                return;
 768        }
 769
 770        /* Determine function privilege level */
 771        op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
 772        if (op_mode == QLC_83XX_DEFAULT_OPMODE)
 773                priv_level = QLCNIC_MGMT_FUNC;
 774        else
 775                priv_level = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode,
 776                                                         ahw->pci_func);
 777
 778        if (priv_level == QLCNIC_NON_PRIV_FUNC) {
 779                ahw->op_mode = QLCNIC_NON_PRIV_FUNC;
 780                dev_info(&adapter->pdev->dev,
 781                         "HAL Version: %d Non Privileged function\n",
 782                         ahw->fw_hal_version);
 783                adapter->nic_ops = &qlcnic_vf_ops;
 784        } else {
 785                if (pci_find_ext_capability(adapter->pdev,
 786                                            PCI_EXT_CAP_ID_SRIOV))
 787                        set_bit(__QLCNIC_SRIOV_CAPABLE, &adapter->state);
 788                adapter->nic_ops = &qlcnic_83xx_ops;
 789        }
 790}
 791
 792static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
 793                                        u32 data[]);
 794static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
 795                                            u32 data[]);
 796
 797void qlcnic_dump_mbx(struct qlcnic_adapter *adapter,
 798                     struct qlcnic_cmd_args *cmd)
 799{
 800        int i;
 801
 802        if (cmd->op_type == QLC_83XX_MBX_POST_BC_OP)
 803                return;
 804
 805        dev_info(&adapter->pdev->dev,
 806                 "Host MBX regs(%d)\n", cmd->req.num);
 807        for (i = 0; i < cmd->req.num; i++) {
 808                if (i && !(i % 8))
 809                        pr_info("\n");
 810                pr_info("%08x ", cmd->req.arg[i]);
 811        }
 812        pr_info("\n");
 813        dev_info(&adapter->pdev->dev,
 814                 "FW MBX regs(%d)\n", cmd->rsp.num);
 815        for (i = 0; i < cmd->rsp.num; i++) {
 816                if (i && !(i % 8))
 817                        pr_info("\n");
 818                pr_info("%08x ", cmd->rsp.arg[i]);
 819        }
 820        pr_info("\n");
 821}
 822
 823static void qlcnic_83xx_poll_for_mbx_completion(struct qlcnic_adapter *adapter,
 824                                                struct qlcnic_cmd_args *cmd)
 825{
 826        struct qlcnic_hardware_context *ahw = adapter->ahw;
 827        int opcode = LSW(cmd->req.arg[0]);
 828        unsigned long max_loops;
 829
 830        max_loops = cmd->total_cmds * QLC_83XX_MBX_CMD_LOOP;
 831
 832        for (; max_loops; max_loops--) {
 833                if (atomic_read(&cmd->rsp_status) ==
 834                    QLC_83XX_MBX_RESPONSE_ARRIVED)
 835                        return;
 836
 837                udelay(1);
 838        }
 839
 840        dev_err(&adapter->pdev->dev,
 841                "%s: Mailbox command timed out, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
 842                __func__, opcode, cmd->type, ahw->pci_func, ahw->op_mode);
 843        flush_workqueue(ahw->mailbox->work_q);
 844        return;
 845}
 846
 847int qlcnic_83xx_issue_cmd(struct qlcnic_adapter *adapter,
 848                          struct qlcnic_cmd_args *cmd)
 849{
 850        struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
 851        struct qlcnic_hardware_context *ahw = adapter->ahw;
 852        int cmd_type, err, opcode;
 853        unsigned long timeout;
 854
 855        if (!mbx)
 856                return -EIO;
 857
 858        opcode = LSW(cmd->req.arg[0]);
 859        cmd_type = cmd->type;
 860        err = mbx->ops->enqueue_cmd(adapter, cmd, &timeout);
 861        if (err) {
 862                dev_err(&adapter->pdev->dev,
 863                        "%s: Mailbox not available, cmd_op=0x%x, cmd_context=0x%x, pci_func=0x%x, op_mode=0x%x\n",
 864                        __func__, opcode, cmd->type, ahw->pci_func,
 865                        ahw->op_mode);
 866                return err;
 867        }
 868
 869        switch (cmd_type) {
 870        case QLC_83XX_MBX_CMD_WAIT:
 871                if (!wait_for_completion_timeout(&cmd->completion, timeout)) {
 872                        dev_err(&adapter->pdev->dev,
 873                                "%s: Mailbox command timed out, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
 874                                __func__, opcode, cmd_type, ahw->pci_func,
 875                                ahw->op_mode);
 876                        flush_workqueue(mbx->work_q);
 877                }
 878                break;
 879        case QLC_83XX_MBX_CMD_NO_WAIT:
 880                return 0;
 881        case QLC_83XX_MBX_CMD_BUSY_WAIT:
 882                qlcnic_83xx_poll_for_mbx_completion(adapter, cmd);
 883                break;
 884        default:
 885                dev_err(&adapter->pdev->dev,
 886                        "%s: Invalid mailbox command, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
 887                        __func__, opcode, cmd_type, ahw->pci_func,
 888                        ahw->op_mode);
 889                qlcnic_83xx_detach_mailbox_work(adapter);
 890        }
 891
 892        return cmd->rsp_opcode;
 893}
 894
 895int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx,
 896                               struct qlcnic_adapter *adapter, u32 type)
 897{
 898        int i, size;
 899        u32 temp;
 900        const struct qlcnic_mailbox_metadata *mbx_tbl;
 901
 902        memset(mbx, 0, sizeof(struct qlcnic_cmd_args));
 903        mbx_tbl = qlcnic_83xx_mbx_tbl;
 904        size = ARRAY_SIZE(qlcnic_83xx_mbx_tbl);
 905        for (i = 0; i < size; i++) {
 906                if (type == mbx_tbl[i].cmd) {
 907                        mbx->op_type = QLC_83XX_FW_MBX_CMD;
 908                        mbx->req.num = mbx_tbl[i].in_args;
 909                        mbx->rsp.num = mbx_tbl[i].out_args;
 910                        mbx->req.arg = kcalloc(mbx->req.num, sizeof(u32),
 911                                               GFP_ATOMIC);
 912                        if (!mbx->req.arg)
 913                                return -ENOMEM;
 914                        mbx->rsp.arg = kcalloc(mbx->rsp.num, sizeof(u32),
 915                                               GFP_ATOMIC);
 916                        if (!mbx->rsp.arg) {
 917                                kfree(mbx->req.arg);
 918                                mbx->req.arg = NULL;
 919                                return -ENOMEM;
 920                        }
 921                        temp = adapter->ahw->fw_hal_version << 29;
 922                        mbx->req.arg[0] = (type | (mbx->req.num << 16) | temp);
 923                        mbx->cmd_op = type;
 924                        return 0;
 925                }
 926        }
 927
 928        dev_err(&adapter->pdev->dev, "%s: Invalid mailbox command opcode 0x%x\n",
 929                __func__, type);
 930        return -EINVAL;
 931}
 932
 933void qlcnic_83xx_idc_aen_work(struct work_struct *work)
 934{
 935        struct qlcnic_adapter *adapter;
 936        struct qlcnic_cmd_args cmd;
 937        int i, err = 0;
 938
 939        adapter = container_of(work, struct qlcnic_adapter, idc_aen_work.work);
 940        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_IDC_ACK);
 941        if (err)
 942                return;
 943
 944        for (i = 1; i < QLC_83XX_MBX_AEN_CNT; i++)
 945                cmd.req.arg[i] = adapter->ahw->mbox_aen[i];
 946
 947        err = qlcnic_issue_cmd(adapter, &cmd);
 948        if (err)
 949                dev_info(&adapter->pdev->dev,
 950                         "%s: Mailbox IDC ACK failed.\n", __func__);
 951        qlcnic_free_mbx_args(&cmd);
 952}
 953
 954static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
 955                                            u32 data[])
 956{
 957        dev_dbg(&adapter->pdev->dev, "Completion AEN:0x%x.\n",
 958                QLCNIC_MBX_RSP(data[0]));
 959        clear_bit(QLC_83XX_IDC_COMP_AEN, &adapter->ahw->idc.status);
 960        return;
 961}
 962
 963static void __qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
 964{
 965        struct qlcnic_hardware_context *ahw = adapter->ahw;
 966        u32 event[QLC_83XX_MBX_AEN_CNT];
 967        int i;
 968
 969        for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
 970                event[i] = readl(QLCNIC_MBX_FW(ahw, i));
 971
 972        switch (QLCNIC_MBX_RSP(event[0])) {
 973
 974        case QLCNIC_MBX_LINK_EVENT:
 975                qlcnic_83xx_handle_link_aen(adapter, event);
 976                break;
 977        case QLCNIC_MBX_COMP_EVENT:
 978                qlcnic_83xx_handle_idc_comp_aen(adapter, event);
 979                break;
 980        case QLCNIC_MBX_REQUEST_EVENT:
 981                for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
 982                        adapter->ahw->mbox_aen[i] = QLCNIC_MBX_RSP(event[i]);
 983                queue_delayed_work(adapter->qlcnic_wq,
 984                                   &adapter->idc_aen_work, 0);
 985                break;
 986        case QLCNIC_MBX_TIME_EXTEND_EVENT:
 987                ahw->extend_lb_time = event[1] >> 8 & 0xf;
 988                break;
 989        case QLCNIC_MBX_BC_EVENT:
 990                qlcnic_sriov_handle_bc_event(adapter, event[1]);
 991                break;
 992        case QLCNIC_MBX_SFP_INSERT_EVENT:
 993                dev_info(&adapter->pdev->dev, "SFP+ Insert AEN:0x%x.\n",
 994                         QLCNIC_MBX_RSP(event[0]));
 995                break;
 996        case QLCNIC_MBX_SFP_REMOVE_EVENT:
 997                dev_info(&adapter->pdev->dev, "SFP Removed AEN:0x%x.\n",
 998                         QLCNIC_MBX_RSP(event[0]));
 999                break;
1000        case QLCNIC_MBX_DCBX_CONFIG_CHANGE_EVENT:
1001                qlcnic_dcb_aen_handler(adapter->dcb, (void *)&event[1]);
1002                break;
1003        default:
1004                dev_dbg(&adapter->pdev->dev, "Unsupported AEN:0x%x.\n",
1005                        QLCNIC_MBX_RSP(event[0]));
1006                break;
1007        }
1008
1009        QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
1010}
1011
1012static void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
1013{
1014        u32 resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
1015        struct qlcnic_hardware_context *ahw = adapter->ahw;
1016        struct qlcnic_mailbox *mbx = ahw->mailbox;
1017        unsigned long flags;
1018
1019        spin_lock_irqsave(&mbx->aen_lock, flags);
1020        resp = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
1021        if (resp & QLCNIC_SET_OWNER) {
1022                event = readl(QLCNIC_MBX_FW(ahw, 0));
1023                if (event &  QLCNIC_MBX_ASYNC_EVENT) {
1024                        __qlcnic_83xx_process_aen(adapter);
1025                } else {
1026                        if (mbx->rsp_status != rsp_status)
1027                                qlcnic_83xx_notify_mbx_response(mbx);
1028                }
1029        }
1030        spin_unlock_irqrestore(&mbx->aen_lock, flags);
1031}
1032
1033static void qlcnic_83xx_mbx_poll_work(struct work_struct *work)
1034{
1035        struct qlcnic_adapter *adapter;
1036
1037        adapter = container_of(work, struct qlcnic_adapter, mbx_poll_work.work);
1038
1039        if (!test_bit(__QLCNIC_MBX_POLL_ENABLE, &adapter->state))
1040                return;
1041
1042        qlcnic_83xx_process_aen(adapter);
1043        queue_delayed_work(adapter->qlcnic_wq, &adapter->mbx_poll_work,
1044                           (HZ / 10));
1045}
1046
1047void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *adapter)
1048{
1049        if (test_and_set_bit(__QLCNIC_MBX_POLL_ENABLE, &adapter->state))
1050                return;
1051
1052        INIT_DELAYED_WORK(&adapter->mbx_poll_work, qlcnic_83xx_mbx_poll_work);
1053        queue_delayed_work(adapter->qlcnic_wq, &adapter->mbx_poll_work, 0);
1054}
1055
1056void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *adapter)
1057{
1058        if (!test_and_clear_bit(__QLCNIC_MBX_POLL_ENABLE, &adapter->state))
1059                return;
1060        cancel_delayed_work_sync(&adapter->mbx_poll_work);
1061}
1062
1063static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)
1064{
1065        int index, i, err, sds_mbx_size;
1066        u32 *buf, intrpt_id, intr_mask;
1067        u16 context_id;
1068        u8 num_sds;
1069        struct qlcnic_cmd_args cmd;
1070        struct qlcnic_host_sds_ring *sds;
1071        struct qlcnic_sds_mbx sds_mbx;
1072        struct qlcnic_add_rings_mbx_out *mbx_out;
1073        struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1074        struct qlcnic_hardware_context *ahw = adapter->ahw;
1075
1076        sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
1077        context_id = recv_ctx->context_id;
1078        num_sds = adapter->drv_sds_rings - QLCNIC_MAX_SDS_RINGS;
1079        ahw->hw_ops->alloc_mbx_args(&cmd, adapter,
1080                                    QLCNIC_CMD_ADD_RCV_RINGS);
1081        cmd.req.arg[1] = 0 | (num_sds << 8) | (context_id << 16);
1082
1083        /* set up status rings, mbx 2-81 */
1084        index = 2;
1085        for (i = 8; i < adapter->drv_sds_rings; i++) {
1086                memset(&sds_mbx, 0, sds_mbx_size);
1087                sds = &recv_ctx->sds_rings[i];
1088                sds->consumer = 0;
1089                memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
1090                sds_mbx.phy_addr_low = LSD(sds->phys_addr);
1091                sds_mbx.phy_addr_high = MSD(sds->phys_addr);
1092                sds_mbx.sds_ring_size = sds->num_desc;
1093
1094                if (adapter->flags & QLCNIC_MSIX_ENABLED)
1095                        intrpt_id = ahw->intr_tbl[i].id;
1096                else
1097                        intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
1098
1099                if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
1100                        sds_mbx.intrpt_id = intrpt_id;
1101                else
1102                        sds_mbx.intrpt_id = 0xffff;
1103                sds_mbx.intrpt_val = 0;
1104                buf = &cmd.req.arg[index];
1105                memcpy(buf, &sds_mbx, sds_mbx_size);
1106                index += sds_mbx_size / sizeof(u32);
1107        }
1108
1109        /* send the mailbox command */
1110        err = ahw->hw_ops->mbx_cmd(adapter, &cmd);
1111        if (err) {
1112                dev_err(&adapter->pdev->dev,
1113                        "Failed to add rings %d\n", err);
1114                goto out;
1115        }
1116
1117        mbx_out = (struct qlcnic_add_rings_mbx_out *)&cmd.rsp.arg[1];
1118        index = 0;
1119        /* status descriptor ring */
1120        for (i = 8; i < adapter->drv_sds_rings; i++) {
1121                sds = &recv_ctx->sds_rings[i];
1122                sds->crb_sts_consumer = ahw->pci_base0 +
1123                                        mbx_out->host_csmr[index];
1124                if (adapter->flags & QLCNIC_MSIX_ENABLED)
1125                        intr_mask = ahw->intr_tbl[i].src;
1126                else
1127                        intr_mask = QLCRDX(ahw, QLCNIC_DEF_INT_MASK);
1128
1129                sds->crb_intr_mask = ahw->pci_base0 + intr_mask;
1130                index++;
1131        }
1132out:
1133        qlcnic_free_mbx_args(&cmd);
1134        return err;
1135}
1136
1137void qlcnic_83xx_del_rx_ctx(struct qlcnic_adapter *adapter)
1138{
1139        int err;
1140        u32 temp = 0;
1141        struct qlcnic_cmd_args cmd;
1142        struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1143
1144        if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_RX_CTX))
1145                return;
1146
1147        if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
1148                cmd.req.arg[0] |= (0x3 << 29);
1149
1150        if (qlcnic_sriov_pf_check(adapter))
1151                qlcnic_pf_set_interface_id_del_rx_ctx(adapter, &temp);
1152
1153        cmd.req.arg[1] = recv_ctx->context_id | temp;
1154        err = qlcnic_issue_cmd(adapter, &cmd);
1155        if (err)
1156                dev_err(&adapter->pdev->dev,
1157                        "Failed to destroy rx ctx in firmware\n");
1158
1159        recv_ctx->state = QLCNIC_HOST_CTX_STATE_FREED;
1160        qlcnic_free_mbx_args(&cmd);
1161}
1162
1163int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter)
1164{
1165        int i, err, index, sds_mbx_size, rds_mbx_size;
1166        u8 num_sds, num_rds;
1167        u32 *buf, intrpt_id, intr_mask, cap = 0;
1168        struct qlcnic_host_sds_ring *sds;
1169        struct qlcnic_host_rds_ring *rds;
1170        struct qlcnic_sds_mbx sds_mbx;
1171        struct qlcnic_rds_mbx rds_mbx;
1172        struct qlcnic_cmd_args cmd;
1173        struct qlcnic_rcv_mbx_out *mbx_out;
1174        struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1175        struct qlcnic_hardware_context *ahw = adapter->ahw;
1176        num_rds = adapter->max_rds_rings;
1177
1178        if (adapter->drv_sds_rings <= QLCNIC_MAX_SDS_RINGS)
1179                num_sds = adapter->drv_sds_rings;
1180        else
1181                num_sds = QLCNIC_MAX_SDS_RINGS;
1182
1183        sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
1184        rds_mbx_size = sizeof(struct qlcnic_rds_mbx);
1185        cap = QLCNIC_CAP0_LEGACY_CONTEXT;
1186
1187        if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP)
1188                cap |= QLC_83XX_FW_CAP_LRO_MSS;
1189
1190        /* set mailbox hdr and capabilities */
1191        err = qlcnic_alloc_mbx_args(&cmd, adapter,
1192                                    QLCNIC_CMD_CREATE_RX_CTX);
1193        if (err)
1194                return err;
1195
1196        if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
1197                cmd.req.arg[0] |= (0x3 << 29);
1198
1199        cmd.req.arg[1] = cap;
1200        cmd.req.arg[5] = 1 | (num_rds << 5) | (num_sds << 8) |
1201                         (QLC_83XX_HOST_RDS_MODE_UNIQUE << 16);
1202
1203        if (qlcnic_sriov_pf_check(adapter))
1204                qlcnic_pf_set_interface_id_create_rx_ctx(adapter,
1205                                                         &cmd.req.arg[6]);
1206        /* set up status rings, mbx 8-57/87 */
1207        index = QLC_83XX_HOST_SDS_MBX_IDX;
1208        for (i = 0; i < num_sds; i++) {
1209                memset(&sds_mbx, 0, sds_mbx_size);
1210                sds = &recv_ctx->sds_rings[i];
1211                sds->consumer = 0;
1212                memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
1213                sds_mbx.phy_addr_low = LSD(sds->phys_addr);
1214                sds_mbx.phy_addr_high = MSD(sds->phys_addr);
1215                sds_mbx.sds_ring_size = sds->num_desc;
1216                if (adapter->flags & QLCNIC_MSIX_ENABLED)
1217                        intrpt_id = ahw->intr_tbl[i].id;
1218                else
1219                        intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
1220                if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
1221                        sds_mbx.intrpt_id = intrpt_id;
1222                else
1223                        sds_mbx.intrpt_id = 0xffff;
1224                sds_mbx.intrpt_val = 0;
1225                buf = &cmd.req.arg[index];
1226                memcpy(buf, &sds_mbx, sds_mbx_size);
1227                index += sds_mbx_size / sizeof(u32);
1228        }
1229        /* set up receive rings, mbx 88-111/135 */
1230        index = QLCNIC_HOST_RDS_MBX_IDX;
1231        rds = &recv_ctx->rds_rings[0];
1232        rds->producer = 0;
1233        memset(&rds_mbx, 0, rds_mbx_size);
1234        rds_mbx.phy_addr_reg_low = LSD(rds->phys_addr);
1235        rds_mbx.phy_addr_reg_high = MSD(rds->phys_addr);
1236        rds_mbx.reg_ring_sz = rds->dma_size;
1237        rds_mbx.reg_ring_len = rds->num_desc;
1238        /* Jumbo ring */
1239        rds = &recv_ctx->rds_rings[1];
1240        rds->producer = 0;
1241        rds_mbx.phy_addr_jmb_low = LSD(rds->phys_addr);
1242        rds_mbx.phy_addr_jmb_high = MSD(rds->phys_addr);
1243        rds_mbx.jmb_ring_sz = rds->dma_size;
1244        rds_mbx.jmb_ring_len = rds->num_desc;
1245        buf = &cmd.req.arg[index];
1246        memcpy(buf, &rds_mbx, rds_mbx_size);
1247
1248        /* send the mailbox command */
1249        err = ahw->hw_ops->mbx_cmd(adapter, &cmd);
1250        if (err) {
1251                dev_err(&adapter->pdev->dev,
1252                        "Failed to create Rx ctx in firmware%d\n", err);
1253                goto out;
1254        }
1255        mbx_out = (struct qlcnic_rcv_mbx_out *)&cmd.rsp.arg[1];
1256        recv_ctx->context_id = mbx_out->ctx_id;
1257        recv_ctx->state = mbx_out->state;
1258        recv_ctx->virt_port = mbx_out->vport_id;
1259        dev_info(&adapter->pdev->dev, "Rx Context[%d] Created, state:0x%x\n",
1260                 recv_ctx->context_id, recv_ctx->state);
1261        /* Receive descriptor ring */
1262        /* Standard ring */
1263        rds = &recv_ctx->rds_rings[0];
1264        rds->crb_rcv_producer = ahw->pci_base0 +
1265                                mbx_out->host_prod[0].reg_buf;
1266        /* Jumbo ring */
1267        rds = &recv_ctx->rds_rings[1];
1268        rds->crb_rcv_producer = ahw->pci_base0 +
1269                                mbx_out->host_prod[0].jmb_buf;
1270        /* status descriptor ring */
1271        for (i = 0; i < num_sds; i++) {
1272                sds = &recv_ctx->sds_rings[i];
1273                sds->crb_sts_consumer = ahw->pci_base0 +
1274                                        mbx_out->host_csmr[i];
1275                if (adapter->flags & QLCNIC_MSIX_ENABLED)
1276                        intr_mask = ahw->intr_tbl[i].src;
1277                else
1278                        intr_mask = QLCRDX(ahw, QLCNIC_DEF_INT_MASK);
1279                sds->crb_intr_mask = ahw->pci_base0 + intr_mask;
1280        }
1281
1282        if (adapter->drv_sds_rings > QLCNIC_MAX_SDS_RINGS)
1283                err = qlcnic_83xx_add_rings(adapter);
1284out:
1285        qlcnic_free_mbx_args(&cmd);
1286        return err;
1287}
1288
1289void qlcnic_83xx_del_tx_ctx(struct qlcnic_adapter *adapter,
1290                            struct qlcnic_host_tx_ring *tx_ring)
1291{
1292        struct qlcnic_cmd_args cmd;
1293        u32 temp = 0;
1294
1295        if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_TX_CTX))
1296                return;
1297
1298        if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
1299                cmd.req.arg[0] |= (0x3 << 29);
1300
1301        if (qlcnic_sriov_pf_check(adapter))
1302                qlcnic_pf_set_interface_id_del_tx_ctx(adapter, &temp);
1303
1304        cmd.req.arg[1] = tx_ring->ctx_id | temp;
1305        if (qlcnic_issue_cmd(adapter, &cmd))
1306                dev_err(&adapter->pdev->dev,
1307                        "Failed to destroy tx ctx in firmware\n");
1308        qlcnic_free_mbx_args(&cmd);
1309}
1310
1311int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
1312                              struct qlcnic_host_tx_ring *tx, int ring)
1313{
1314        int err;
1315        u16 msix_id;
1316        u32 *buf, intr_mask, temp = 0;
1317        struct qlcnic_cmd_args cmd;
1318        struct qlcnic_tx_mbx mbx;
1319        struct qlcnic_tx_mbx_out *mbx_out;
1320        struct qlcnic_hardware_context *ahw = adapter->ahw;
1321        u32 msix_vector;
1322
1323        /* Reset host resources */
1324        tx->producer = 0;
1325        tx->sw_consumer = 0;
1326        *(tx->hw_consumer) = 0;
1327
1328        memset(&mbx, 0, sizeof(struct qlcnic_tx_mbx));
1329
1330        /* setup mailbox inbox registerss */
1331        mbx.phys_addr_low = LSD(tx->phys_addr);
1332        mbx.phys_addr_high = MSD(tx->phys_addr);
1333        mbx.cnsmr_index_low = LSD(tx->hw_cons_phys_addr);
1334        mbx.cnsmr_index_high = MSD(tx->hw_cons_phys_addr);
1335        mbx.size = tx->num_desc;
1336        if (adapter->flags & QLCNIC_MSIX_ENABLED) {
1337                if (!(adapter->flags & QLCNIC_TX_INTR_SHARED))
1338                        msix_vector = adapter->drv_sds_rings + ring;
1339                else
1340                        msix_vector = adapter->drv_sds_rings - 1;
1341                msix_id = ahw->intr_tbl[msix_vector].id;
1342        } else {
1343                msix_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
1344        }
1345
1346        if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
1347                mbx.intr_id = msix_id;
1348        else
1349                mbx.intr_id = 0xffff;
1350        mbx.src = 0;
1351
1352        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CREATE_TX_CTX);
1353        if (err)
1354                return err;
1355
1356        if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
1357                cmd.req.arg[0] |= (0x3 << 29);
1358
1359        if (qlcnic_sriov_pf_check(adapter))
1360                qlcnic_pf_set_interface_id_create_tx_ctx(adapter, &temp);
1361
1362        cmd.req.arg[1] = QLCNIC_CAP0_LEGACY_CONTEXT;
1363        cmd.req.arg[5] = QLCNIC_SINGLE_RING | temp;
1364
1365        buf = &cmd.req.arg[6];
1366        memcpy(buf, &mbx, sizeof(struct qlcnic_tx_mbx));
1367        /* send the mailbox command*/
1368        err = qlcnic_issue_cmd(adapter, &cmd);
1369        if (err) {
1370                netdev_err(adapter->netdev,
1371                           "Failed to create Tx ctx in firmware 0x%x\n", err);
1372                goto out;
1373        }
1374        mbx_out = (struct qlcnic_tx_mbx_out *)&cmd.rsp.arg[2];
1375        tx->crb_cmd_producer = ahw->pci_base0 + mbx_out->host_prod;
1376        tx->ctx_id = mbx_out->ctx_id;
1377        if ((adapter->flags & QLCNIC_MSIX_ENABLED) &&
1378            !(adapter->flags & QLCNIC_TX_INTR_SHARED)) {
1379                intr_mask = ahw->intr_tbl[adapter->drv_sds_rings + ring].src;
1380                tx->crb_intr_mask = ahw->pci_base0 + intr_mask;
1381        }
1382        netdev_info(adapter->netdev,
1383                    "Tx Context[0x%x] Created, state:0x%x\n",
1384                    tx->ctx_id, mbx_out->state);
1385out:
1386        qlcnic_free_mbx_args(&cmd);
1387        return err;
1388}
1389
1390static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,
1391                                      u8 num_sds_ring)
1392{
1393        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1394        struct qlcnic_host_sds_ring *sds_ring;
1395        struct qlcnic_host_rds_ring *rds_ring;
1396        u16 adapter_state = adapter->is_up;
1397        u8 ring;
1398        int ret;
1399
1400        netif_device_detach(netdev);
1401
1402        if (netif_running(netdev))
1403                __qlcnic_down(adapter, netdev);
1404
1405        qlcnic_detach(adapter);
1406
1407        adapter->drv_sds_rings = QLCNIC_SINGLE_RING;
1408        adapter->ahw->diag_test = test;
1409        adapter->ahw->linkup = 0;
1410
1411        ret = qlcnic_attach(adapter);
1412        if (ret) {
1413                netif_device_attach(netdev);
1414                return ret;
1415        }
1416
1417        ret = qlcnic_fw_create_ctx(adapter);
1418        if (ret) {
1419                qlcnic_detach(adapter);
1420                if (adapter_state == QLCNIC_ADAPTER_UP_MAGIC) {
1421                        adapter->drv_sds_rings = num_sds_ring;
1422                        qlcnic_attach(adapter);
1423                }
1424                netif_device_attach(netdev);
1425                return ret;
1426        }
1427
1428        for (ring = 0; ring < adapter->max_rds_rings; ring++) {
1429                rds_ring = &adapter->recv_ctx->rds_rings[ring];
1430                qlcnic_post_rx_buffers(adapter, rds_ring, ring);
1431        }
1432
1433        if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
1434                for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
1435                        sds_ring = &adapter->recv_ctx->sds_rings[ring];
1436                        qlcnic_enable_sds_intr(adapter, sds_ring);
1437                }
1438        }
1439
1440        if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) {
1441                adapter->ahw->loopback_state = 0;
1442                adapter->ahw->hw_ops->setup_link_event(adapter, 1);
1443        }
1444
1445        set_bit(__QLCNIC_DEV_UP, &adapter->state);
1446        return 0;
1447}
1448
1449static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
1450                                      u8 drv_sds_rings)
1451{
1452        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1453        struct qlcnic_host_sds_ring *sds_ring;
1454        int ring;
1455
1456        clear_bit(__QLCNIC_DEV_UP, &adapter->state);
1457        if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
1458                for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
1459                        sds_ring = &adapter->recv_ctx->sds_rings[ring];
1460                        if (adapter->flags & QLCNIC_MSIX_ENABLED)
1461                                qlcnic_disable_sds_intr(adapter, sds_ring);
1462                }
1463        }
1464
1465        qlcnic_fw_destroy_ctx(adapter);
1466        qlcnic_detach(adapter);
1467
1468        adapter->ahw->diag_test = 0;
1469        adapter->drv_sds_rings = drv_sds_rings;
1470
1471        if (qlcnic_attach(adapter))
1472                goto out;
1473
1474        if (netif_running(netdev))
1475                __qlcnic_up(adapter, netdev);
1476
1477out:
1478        netif_device_attach(netdev);
1479}
1480
1481static void qlcnic_83xx_get_beacon_state(struct qlcnic_adapter *adapter)
1482{
1483        struct qlcnic_hardware_context *ahw = adapter->ahw;
1484        struct qlcnic_cmd_args cmd;
1485        u8 beacon_state;
1486        int err = 0;
1487
1488        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LED_CONFIG);
1489        if (!err) {
1490                err = qlcnic_issue_cmd(adapter, &cmd);
1491                if (!err) {
1492                        beacon_state = cmd.rsp.arg[4];
1493                        if (beacon_state == QLCNIC_BEACON_DISABLE)
1494                                ahw->beacon_state = QLC_83XX_BEACON_OFF;
1495                        else if (beacon_state == QLC_83XX_ENABLE_BEACON)
1496                                ahw->beacon_state = QLC_83XX_BEACON_ON;
1497                }
1498        } else {
1499                netdev_err(adapter->netdev, "Get beacon state failed, err=%d\n",
1500                           err);
1501        }
1502
1503        qlcnic_free_mbx_args(&cmd);
1504
1505        return;
1506}
1507
1508int qlcnic_83xx_config_led(struct qlcnic_adapter *adapter, u32 state,
1509                           u32 beacon)
1510{
1511        struct qlcnic_cmd_args cmd;
1512        u32 mbx_in;
1513        int i, status = 0;
1514
1515        if (state) {
1516                /* Get LED configuration */
1517                status = qlcnic_alloc_mbx_args(&cmd, adapter,
1518                                               QLCNIC_CMD_GET_LED_CONFIG);
1519                if (status)
1520                        return status;
1521
1522                status = qlcnic_issue_cmd(adapter, &cmd);
1523                if (status) {
1524                        dev_err(&adapter->pdev->dev,
1525                                "Get led config failed.\n");
1526                        goto mbx_err;
1527                } else {
1528                        for (i = 0; i < 4; i++)
1529                                adapter->ahw->mbox_reg[i] = cmd.rsp.arg[i+1];
1530                }
1531                qlcnic_free_mbx_args(&cmd);
1532                /* Set LED Configuration */
1533                mbx_in = (LSW(QLC_83XX_LED_CONFIG) << 16) |
1534                          LSW(QLC_83XX_LED_CONFIG);
1535                status = qlcnic_alloc_mbx_args(&cmd, adapter,
1536                                               QLCNIC_CMD_SET_LED_CONFIG);
1537                if (status)
1538                        return status;
1539
1540                cmd.req.arg[1] = mbx_in;
1541                cmd.req.arg[2] = mbx_in;
1542                cmd.req.arg[3] = mbx_in;
1543                if (beacon)
1544                        cmd.req.arg[4] = QLC_83XX_ENABLE_BEACON;
1545                status = qlcnic_issue_cmd(adapter, &cmd);
1546                if (status) {
1547                        dev_err(&adapter->pdev->dev,
1548                                "Set led config failed.\n");
1549                }
1550mbx_err:
1551                qlcnic_free_mbx_args(&cmd);
1552                return status;
1553
1554        } else {
1555                /* Restoring default LED configuration */
1556                status = qlcnic_alloc_mbx_args(&cmd, adapter,
1557                                               QLCNIC_CMD_SET_LED_CONFIG);
1558                if (status)
1559                        return status;
1560
1561                cmd.req.arg[1] = adapter->ahw->mbox_reg[0];
1562                cmd.req.arg[2] = adapter->ahw->mbox_reg[1];
1563                cmd.req.arg[3] = adapter->ahw->mbox_reg[2];
1564                if (beacon)
1565                        cmd.req.arg[4] = adapter->ahw->mbox_reg[3];
1566                status = qlcnic_issue_cmd(adapter, &cmd);
1567                if (status)
1568                        dev_err(&adapter->pdev->dev,
1569                                "Restoring led config failed.\n");
1570                qlcnic_free_mbx_args(&cmd);
1571                return status;
1572        }
1573}
1574
1575int  qlcnic_83xx_set_led(struct net_device *netdev,
1576                         enum ethtool_phys_id_state state)
1577{
1578        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1579        int err = -EIO, active = 1;
1580
1581        if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1582                netdev_warn(netdev,
1583                            "LED test is not supported in non-privileged mode\n");
1584                return -EOPNOTSUPP;
1585        }
1586
1587        switch (state) {
1588        case ETHTOOL_ID_ACTIVE:
1589                if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state))
1590                        return -EBUSY;
1591
1592                if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1593                        break;
1594
1595                err = qlcnic_83xx_config_led(adapter, active, 0);
1596                if (err)
1597                        netdev_err(netdev, "Failed to set LED blink state\n");
1598                break;
1599        case ETHTOOL_ID_INACTIVE:
1600                active = 0;
1601
1602                if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1603                        break;
1604
1605                err = qlcnic_83xx_config_led(adapter, active, 0);
1606                if (err)
1607                        netdev_err(netdev, "Failed to reset LED blink state\n");
1608                break;
1609
1610        default:
1611                return -EINVAL;
1612        }
1613
1614        if (!active || err)
1615                clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
1616
1617        return err;
1618}
1619
1620void qlcnic_83xx_initialize_nic(struct qlcnic_adapter *adapter, int enable)
1621{
1622        struct qlcnic_cmd_args cmd;
1623        int status;
1624
1625        if (qlcnic_sriov_vf_check(adapter))
1626                return;
1627
1628        if (enable)
1629                status = qlcnic_alloc_mbx_args(&cmd, adapter,
1630                                               QLCNIC_CMD_INIT_NIC_FUNC);
1631        else
1632                status = qlcnic_alloc_mbx_args(&cmd, adapter,
1633                                               QLCNIC_CMD_STOP_NIC_FUNC);
1634
1635        if (status)
1636                return;
1637
1638        cmd.req.arg[1] = QLC_REGISTER_LB_IDC | QLC_INIT_FW_RESOURCES;
1639
1640        if (adapter->dcb)
1641                cmd.req.arg[1] |= QLC_REGISTER_DCB_AEN;
1642
1643        status = qlcnic_issue_cmd(adapter, &cmd);
1644        if (status)
1645                dev_err(&adapter->pdev->dev,
1646                        "Failed to %s in NIC IDC function event.\n",
1647                        (enable ? "register" : "unregister"));
1648
1649        qlcnic_free_mbx_args(&cmd);
1650}
1651
1652static int qlcnic_83xx_set_port_config(struct qlcnic_adapter *adapter)
1653{
1654        struct qlcnic_cmd_args cmd;
1655        int err;
1656
1657        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_PORT_CONFIG);
1658        if (err)
1659                return err;
1660
1661        cmd.req.arg[1] = adapter->ahw->port_config;
1662        err = qlcnic_issue_cmd(adapter, &cmd);
1663        if (err)
1664                dev_info(&adapter->pdev->dev, "Set Port Config failed.\n");
1665        qlcnic_free_mbx_args(&cmd);
1666        return err;
1667}
1668
1669static int qlcnic_83xx_get_port_config(struct qlcnic_adapter *adapter)
1670{
1671        struct qlcnic_cmd_args cmd;
1672        int err;
1673
1674        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PORT_CONFIG);
1675        if (err)
1676                return err;
1677
1678        err = qlcnic_issue_cmd(adapter, &cmd);
1679        if (err)
1680                dev_info(&adapter->pdev->dev, "Get Port config failed\n");
1681        else
1682                adapter->ahw->port_config = cmd.rsp.arg[1];
1683        qlcnic_free_mbx_args(&cmd);
1684        return err;
1685}
1686
1687int qlcnic_83xx_setup_link_event(struct qlcnic_adapter *adapter, int enable)
1688{
1689        int err;
1690        u32 temp;
1691        struct qlcnic_cmd_args cmd;
1692
1693        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_EVENT);
1694        if (err)
1695                return err;
1696
1697        temp = adapter->recv_ctx->context_id << 16;
1698        cmd.req.arg[1] = (enable ? 1 : 0) | BIT_8 | temp;
1699        err = qlcnic_issue_cmd(adapter, &cmd);
1700        if (err)
1701                dev_info(&adapter->pdev->dev,
1702                         "Setup linkevent mailbox failed\n");
1703        qlcnic_free_mbx_args(&cmd);
1704        return err;
1705}
1706
1707static void qlcnic_83xx_set_interface_id_promisc(struct qlcnic_adapter *adapter,
1708                                                 u32 *interface_id)
1709{
1710        if (qlcnic_sriov_pf_check(adapter)) {
1711                qlcnic_alloc_lb_filters_mem(adapter);
1712                qlcnic_pf_set_interface_id_promisc(adapter, interface_id);
1713                adapter->rx_mac_learn = true;
1714        } else {
1715                if (!qlcnic_sriov_vf_check(adapter))
1716                        *interface_id = adapter->recv_ctx->context_id << 16;
1717        }
1718}
1719
1720int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
1721{
1722        struct qlcnic_cmd_args *cmd = NULL;
1723        u32 temp = 0;
1724        int err;
1725
1726        if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1727                return -EIO;
1728
1729        cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
1730        if (!cmd)
1731                return -ENOMEM;
1732
1733        err = qlcnic_alloc_mbx_args(cmd, adapter,
1734                                    QLCNIC_CMD_CONFIGURE_MAC_RX_MODE);
1735        if (err)
1736                goto out;
1737
1738        cmd->type = QLC_83XX_MBX_CMD_NO_WAIT;
1739        qlcnic_83xx_set_interface_id_promisc(adapter, &temp);
1740
1741        if (qlcnic_84xx_check(adapter) && qlcnic_sriov_pf_check(adapter))
1742                mode = VPORT_MISS_MODE_ACCEPT_ALL;
1743
1744        cmd->req.arg[1] = mode | temp;
1745        err = qlcnic_issue_cmd(adapter, cmd);
1746        if (!err)
1747                return err;
1748
1749        qlcnic_free_mbx_args(cmd);
1750
1751out:
1752        kfree(cmd);
1753        return err;
1754}
1755
1756int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
1757{
1758        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1759        struct qlcnic_hardware_context *ahw = adapter->ahw;
1760        u8 drv_sds_rings = adapter->drv_sds_rings;
1761        u8 drv_tx_rings = adapter->drv_tx_rings;
1762        int ret = 0, loop = 0;
1763
1764        if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1765                netdev_warn(netdev,
1766                            "Loopback test not supported in non privileged mode\n");
1767                return -ENOTSUPP;
1768        }
1769
1770        if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1771                netdev_info(netdev, "Device is resetting\n");
1772                return -EBUSY;
1773        }
1774
1775        if (qlcnic_get_diag_lock(adapter)) {
1776                netdev_info(netdev, "Device is in diagnostics mode\n");
1777                return -EBUSY;
1778        }
1779
1780        netdev_info(netdev, "%s loopback test in progress\n",
1781                    mode == QLCNIC_ILB_MODE ? "internal" : "external");
1782
1783        ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST,
1784                                         drv_sds_rings);
1785        if (ret)
1786                goto fail_diag_alloc;
1787
1788        ret = qlcnic_83xx_set_lb_mode(adapter, mode);
1789        if (ret)
1790                goto free_diag_res;
1791
1792        /* Poll for link up event before running traffic */
1793        do {
1794                msleep(QLC_83XX_LB_MSLEEP_COUNT);
1795
1796                if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1797                        netdev_info(netdev,
1798                                    "Device is resetting, free LB test resources\n");
1799                        ret = -EBUSY;
1800                        goto free_diag_res;
1801                }
1802                if (loop++ > QLC_83XX_LB_WAIT_COUNT) {
1803                        netdev_info(netdev,
1804                                    "Firmware didn't sent link up event to loopback request\n");
1805                        ret = -ETIMEDOUT;
1806                        qlcnic_83xx_clear_lb_mode(adapter, mode);
1807                        goto free_diag_res;
1808                }
1809        } while ((adapter->ahw->linkup && ahw->has_link_events) != 1);
1810
1811        ret = qlcnic_do_lb_test(adapter, mode);
1812
1813        qlcnic_83xx_clear_lb_mode(adapter, mode);
1814
1815free_diag_res:
1816        qlcnic_83xx_diag_free_res(netdev, drv_sds_rings);
1817
1818fail_diag_alloc:
1819        adapter->drv_sds_rings = drv_sds_rings;
1820        adapter->drv_tx_rings = drv_tx_rings;
1821        qlcnic_release_diag_lock(adapter);
1822        return ret;
1823}
1824
1825static void qlcnic_extend_lb_idc_cmpltn_wait(struct qlcnic_adapter *adapter,
1826                                             u32 *max_wait_count)
1827{
1828        struct qlcnic_hardware_context *ahw = adapter->ahw;
1829        int temp;
1830
1831        netdev_info(adapter->netdev, "Received loopback IDC time extend event for 0x%x seconds\n",
1832                    ahw->extend_lb_time);
1833        temp = ahw->extend_lb_time * 1000;
1834        *max_wait_count += temp / QLC_83XX_LB_MSLEEP_COUNT;
1835        ahw->extend_lb_time = 0;
1836}
1837
1838static int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1839{
1840        struct qlcnic_hardware_context *ahw = adapter->ahw;
1841        struct net_device *netdev = adapter->netdev;
1842        u32 config, max_wait_count;
1843        int status = 0, loop = 0;
1844
1845        ahw->extend_lb_time = 0;
1846        max_wait_count = QLC_83XX_LB_WAIT_COUNT;
1847        status = qlcnic_83xx_get_port_config(adapter);
1848        if (status)
1849                return status;
1850
1851        config = ahw->port_config;
1852
1853        /* Check if port is already in loopback mode */
1854        if ((config & QLC_83XX_CFG_LOOPBACK_HSS) ||
1855            (config & QLC_83XX_CFG_LOOPBACK_EXT)) {
1856                netdev_err(netdev,
1857                           "Port already in Loopback mode.\n");
1858                return -EINPROGRESS;
1859        }
1860
1861        set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1862
1863        if (mode == QLCNIC_ILB_MODE)
1864                ahw->port_config |= QLC_83XX_CFG_LOOPBACK_HSS;
1865        if (mode == QLCNIC_ELB_MODE)
1866                ahw->port_config |= QLC_83XX_CFG_LOOPBACK_EXT;
1867
1868        status = qlcnic_83xx_set_port_config(adapter);
1869        if (status) {
1870                netdev_err(netdev,
1871                           "Failed to Set Loopback Mode = 0x%x.\n",
1872                           ahw->port_config);
1873                ahw->port_config = config;
1874                clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1875                return status;
1876        }
1877
1878        /* Wait for Link and IDC Completion AEN */
1879        do {
1880                msleep(QLC_83XX_LB_MSLEEP_COUNT);
1881
1882                if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1883                        netdev_info(netdev,
1884                                    "Device is resetting, free LB test resources\n");
1885                        clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1886                        return -EBUSY;
1887                }
1888
1889                if (ahw->extend_lb_time)
1890                        qlcnic_extend_lb_idc_cmpltn_wait(adapter,
1891                                                         &max_wait_count);
1892
1893                if (loop++ > max_wait_count) {
1894                        netdev_err(netdev, "%s: Did not receive loopback IDC completion AEN\n",
1895                                   __func__);
1896                        clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1897                        qlcnic_83xx_clear_lb_mode(adapter, mode);
1898                        return -ETIMEDOUT;
1899                }
1900        } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
1901
1902        qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0,
1903                                  QLCNIC_MAC_ADD);
1904        return status;
1905}
1906
1907static int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1908{
1909        struct qlcnic_hardware_context *ahw = adapter->ahw;
1910        u32 config = ahw->port_config, max_wait_count;
1911        struct net_device *netdev = adapter->netdev;
1912        int status = 0, loop = 0;
1913
1914        ahw->extend_lb_time = 0;
1915        max_wait_count = QLC_83XX_LB_WAIT_COUNT;
1916        set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1917        if (mode == QLCNIC_ILB_MODE)
1918                ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_HSS;
1919        if (mode == QLCNIC_ELB_MODE)
1920                ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_EXT;
1921
1922        status = qlcnic_83xx_set_port_config(adapter);
1923        if (status) {
1924                netdev_err(netdev,
1925                           "Failed to Clear Loopback Mode = 0x%x.\n",
1926                           ahw->port_config);
1927                ahw->port_config = config;
1928                clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1929                return status;
1930        }
1931
1932        /* Wait for Link and IDC Completion AEN */
1933        do {
1934                msleep(QLC_83XX_LB_MSLEEP_COUNT);
1935
1936                if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1937                        netdev_info(netdev,
1938                                    "Device is resetting, free LB test resources\n");
1939                        clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1940                        return -EBUSY;
1941                }
1942
1943                if (ahw->extend_lb_time)
1944                        qlcnic_extend_lb_idc_cmpltn_wait(adapter,
1945                                                         &max_wait_count);
1946
1947                if (loop++ > max_wait_count) {
1948                        netdev_err(netdev, "%s: Did not receive loopback IDC completion AEN\n",
1949                                   __func__);
1950                        clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1951                        return -ETIMEDOUT;
1952                }
1953        } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
1954
1955        qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0,
1956                                  QLCNIC_MAC_DEL);
1957        return status;
1958}
1959
1960static void qlcnic_83xx_set_interface_id_ipaddr(struct qlcnic_adapter *adapter,
1961                                                u32 *interface_id)
1962{
1963        if (qlcnic_sriov_pf_check(adapter)) {
1964                qlcnic_pf_set_interface_id_ipaddr(adapter, interface_id);
1965        } else {
1966                if (!qlcnic_sriov_vf_check(adapter))
1967                        *interface_id = adapter->recv_ctx->context_id << 16;
1968        }
1969}
1970
1971void qlcnic_83xx_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip,
1972                               int mode)
1973{
1974        int err;
1975        u32 temp = 0, temp_ip;
1976        struct qlcnic_cmd_args cmd;
1977
1978        err = qlcnic_alloc_mbx_args(&cmd, adapter,
1979                                    QLCNIC_CMD_CONFIGURE_IP_ADDR);
1980        if (err)
1981                return;
1982
1983        qlcnic_83xx_set_interface_id_ipaddr(adapter, &temp);
1984
1985        if (mode == QLCNIC_IP_UP)
1986                cmd.req.arg[1] = 1 | temp;
1987        else
1988                cmd.req.arg[1] = 2 | temp;
1989
1990        /*
1991         * Adapter needs IP address in network byte order.
1992         * But hardware mailbox registers go through writel(), hence IP address
1993         * gets swapped on big endian architecture.
1994         * To negate swapping of writel() on big endian architecture
1995         * use swab32(value).
1996         */
1997
1998        temp_ip = swab32(ntohl(ip));
1999        memcpy(&cmd.req.arg[2], &temp_ip, sizeof(u32));
2000        err = qlcnic_issue_cmd(adapter, &cmd);
2001        if (err != QLCNIC_RCODE_SUCCESS)
2002                dev_err(&adapter->netdev->dev,
2003                        "could not notify %s IP 0x%x request\n",
2004                        (mode == QLCNIC_IP_UP) ? "Add" : "Remove", ip);
2005
2006        qlcnic_free_mbx_args(&cmd);
2007}
2008
2009int qlcnic_83xx_config_hw_lro(struct qlcnic_adapter *adapter, int mode)
2010{
2011        int err;
2012        u32 temp, arg1;
2013        struct qlcnic_cmd_args cmd;
2014        int lro_bit_mask;
2015
2016        lro_bit_mask = (mode ? (BIT_0 | BIT_1 | BIT_2 | BIT_3) : 0);
2017
2018        if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
2019                return 0;
2020
2021        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_HW_LRO);
2022        if (err)
2023                return err;
2024
2025        temp = adapter->recv_ctx->context_id << 16;
2026        arg1 = lro_bit_mask | temp;
2027        cmd.req.arg[1] = arg1;
2028
2029        err = qlcnic_issue_cmd(adapter, &cmd);
2030        if (err)
2031                dev_info(&adapter->pdev->dev, "LRO config failed\n");
2032        qlcnic_free_mbx_args(&cmd);
2033
2034        return err;
2035}
2036
2037int qlcnic_83xx_config_rss(struct qlcnic_adapter *adapter, int enable)
2038{
2039        int err;
2040        u32 word;
2041        struct qlcnic_cmd_args cmd;
2042        const u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
2043                            0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
2044                            0x255b0ec26d5a56daULL };
2045
2046        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_RSS);
2047        if (err)
2048                return err;
2049        /*
2050         * RSS request:
2051         * bits 3-0: Rsvd
2052         *      5-4: hash_type_ipv4
2053         *      7-6: hash_type_ipv6
2054         *        8: enable
2055         *        9: use indirection table
2056         *    16-31: indirection table mask
2057         */
2058        word =  ((u32)(RSS_HASHTYPE_IP_TCP & 0x3) << 4) |
2059                ((u32)(RSS_HASHTYPE_IP_TCP & 0x3) << 6) |
2060                ((u32)(enable & 0x1) << 8) |
2061                ((0x7ULL) << 16);
2062        cmd.req.arg[1] = (adapter->recv_ctx->context_id);
2063        cmd.req.arg[2] = word;
2064        memcpy(&cmd.req.arg[4], key, sizeof(key));
2065
2066        err = qlcnic_issue_cmd(adapter, &cmd);
2067
2068        if (err)
2069                dev_info(&adapter->pdev->dev, "RSS config failed\n");
2070        qlcnic_free_mbx_args(&cmd);
2071
2072        return err;
2073
2074}
2075
2076static void qlcnic_83xx_set_interface_id_macaddr(struct qlcnic_adapter *adapter,
2077                                                 u32 *interface_id)
2078{
2079        if (qlcnic_sriov_pf_check(adapter)) {
2080                qlcnic_pf_set_interface_id_macaddr(adapter, interface_id);
2081        } else {
2082                if (!qlcnic_sriov_vf_check(adapter))
2083                        *interface_id = adapter->recv_ctx->context_id << 16;
2084        }
2085}
2086
2087int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
2088                                   u16 vlan_id, u8 op)
2089{
2090        struct qlcnic_cmd_args *cmd = NULL;
2091        struct qlcnic_macvlan_mbx mv;
2092        u32 *buf, temp = 0;
2093        int err;
2094
2095        if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
2096                return -EIO;
2097
2098        cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
2099        if (!cmd)
2100                return -ENOMEM;
2101
2102        err = qlcnic_alloc_mbx_args(cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN);
2103        if (err)
2104                goto out;
2105
2106        cmd->type = QLC_83XX_MBX_CMD_NO_WAIT;
2107
2108        if (vlan_id)
2109                op = (op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ?
2110                     QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL;
2111
2112        cmd->req.arg[1] = op | (1 << 8);
2113        qlcnic_83xx_set_interface_id_macaddr(adapter, &temp);
2114        cmd->req.arg[1] |= temp;
2115        mv.vlan = vlan_id;
2116        mv.mac_addr0 = addr[0];
2117        mv.mac_addr1 = addr[1];
2118        mv.mac_addr2 = addr[2];
2119        mv.mac_addr3 = addr[3];
2120        mv.mac_addr4 = addr[4];
2121        mv.mac_addr5 = addr[5];
2122        buf = &cmd->req.arg[2];
2123        memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx));
2124        err = qlcnic_issue_cmd(adapter, cmd);
2125        if (!err)
2126                return err;
2127
2128        qlcnic_free_mbx_args(cmd);
2129out:
2130        kfree(cmd);
2131        return err;
2132}
2133
2134void qlcnic_83xx_change_l2_filter(struct qlcnic_adapter *adapter, u64 *addr,
2135                                  u16 vlan_id)
2136{
2137        u8 mac[ETH_ALEN];
2138        memcpy(&mac, addr, ETH_ALEN);
2139        qlcnic_83xx_sre_macaddr_change(adapter, mac, vlan_id, QLCNIC_MAC_ADD);
2140}
2141
2142static void qlcnic_83xx_configure_mac(struct qlcnic_adapter *adapter, u8 *mac,
2143                                      u8 type, struct qlcnic_cmd_args *cmd)
2144{
2145        switch (type) {
2146        case QLCNIC_SET_STATION_MAC:
2147        case QLCNIC_SET_FAC_DEF_MAC:
2148                memcpy(&cmd->req.arg[2], mac, sizeof(u32));
2149                memcpy(&cmd->req.arg[3], &mac[4], sizeof(u16));
2150                break;
2151        }
2152        cmd->req.arg[1] = type;
2153}
2154
2155int qlcnic_83xx_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac,
2156                                u8 function)
2157{
2158        int err, i;
2159        struct qlcnic_cmd_args cmd;
2160        u32 mac_low, mac_high;
2161
2162        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_MAC_ADDRESS);
2163        if (err)
2164                return err;
2165
2166        qlcnic_83xx_configure_mac(adapter, mac, QLCNIC_GET_CURRENT_MAC, &cmd);
2167        err = qlcnic_issue_cmd(adapter, &cmd);
2168
2169        if (err == QLCNIC_RCODE_SUCCESS) {
2170                mac_low = cmd.rsp.arg[1];
2171                mac_high = cmd.rsp.arg[2];
2172
2173                for (i = 0; i < 2; i++)
2174                        mac[i] = (u8) (mac_high >> ((1 - i) * 8));
2175                for (i = 2; i < 6; i++)
2176                        mac[i] = (u8) (mac_low >> ((5 - i) * 8));
2177        } else {
2178                dev_err(&adapter->pdev->dev, "Failed to get mac address%d\n",
2179                        err);
2180                err = -EIO;
2181        }
2182        qlcnic_free_mbx_args(&cmd);
2183        return err;
2184}
2185
2186static int qlcnic_83xx_set_rx_intr_coal(struct qlcnic_adapter *adapter)
2187{
2188        struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
2189        struct qlcnic_cmd_args cmd;
2190        u16 temp;
2191        int err;
2192
2193        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
2194        if (err)
2195                return err;
2196
2197        temp = adapter->recv_ctx->context_id;
2198        cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_RX | temp << 16;
2199        temp = coal->rx_time_us;
2200        cmd.req.arg[2] = coal->rx_packets | temp << 16;
2201        cmd.req.arg[3] = coal->flag;
2202
2203        err = qlcnic_issue_cmd(adapter, &cmd);
2204        if (err != QLCNIC_RCODE_SUCCESS)
2205                netdev_err(adapter->netdev,
2206                           "failed to set interrupt coalescing parameters\n");
2207
2208        qlcnic_free_mbx_args(&cmd);
2209
2210        return err;
2211}
2212
2213static int qlcnic_83xx_set_tx_intr_coal(struct qlcnic_adapter *adapter)
2214{
2215        struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
2216        struct qlcnic_cmd_args cmd;
2217        u16 temp;
2218        int err;
2219
2220        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
2221        if (err)
2222                return err;
2223
2224        temp = adapter->tx_ring->ctx_id;
2225        cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_TX | temp << 16;
2226        temp = coal->tx_time_us;
2227        cmd.req.arg[2] = coal->tx_packets | temp << 16;
2228        cmd.req.arg[3] = coal->flag;
2229
2230        err = qlcnic_issue_cmd(adapter, &cmd);
2231        if (err != QLCNIC_RCODE_SUCCESS)
2232                netdev_err(adapter->netdev,
2233                           "failed to set interrupt coalescing  parameters\n");
2234
2235        qlcnic_free_mbx_args(&cmd);
2236
2237        return err;
2238}
2239
2240int qlcnic_83xx_set_rx_tx_intr_coal(struct qlcnic_adapter *adapter)
2241{
2242        int err = 0;
2243
2244        err = qlcnic_83xx_set_rx_intr_coal(adapter);
2245        if (err)
2246                netdev_err(adapter->netdev,
2247                           "failed to set Rx coalescing parameters\n");
2248
2249        err = qlcnic_83xx_set_tx_intr_coal(adapter);
2250        if (err)
2251                netdev_err(adapter->netdev,
2252                           "failed to set Tx coalescing parameters\n");
2253
2254        return err;
2255}
2256
2257int qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter,
2258                                 struct ethtool_coalesce *ethcoal)
2259{
2260        struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
2261        u32 rx_coalesce_usecs, rx_max_frames;
2262        u32 tx_coalesce_usecs, tx_max_frames;
2263        int err;
2264
2265        if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
2266                return -EIO;
2267
2268        tx_coalesce_usecs = ethcoal->tx_coalesce_usecs;
2269        tx_max_frames = ethcoal->tx_max_coalesced_frames;
2270        rx_coalesce_usecs = ethcoal->rx_coalesce_usecs;
2271        rx_max_frames = ethcoal->rx_max_coalesced_frames;
2272        coal->flag = QLCNIC_INTR_DEFAULT;
2273
2274        if ((coal->rx_time_us == rx_coalesce_usecs) &&
2275            (coal->rx_packets == rx_max_frames)) {
2276                coal->type = QLCNIC_INTR_COAL_TYPE_TX;
2277                coal->tx_time_us = tx_coalesce_usecs;
2278                coal->tx_packets = tx_max_frames;
2279        } else if ((coal->tx_time_us == tx_coalesce_usecs) &&
2280                   (coal->tx_packets == tx_max_frames)) {
2281                coal->type = QLCNIC_INTR_COAL_TYPE_RX;
2282                coal->rx_time_us = rx_coalesce_usecs;
2283                coal->rx_packets = rx_max_frames;
2284        } else {
2285                coal->type = QLCNIC_INTR_COAL_TYPE_RX_TX;
2286                coal->rx_time_us = rx_coalesce_usecs;
2287                coal->rx_packets = rx_max_frames;
2288                coal->tx_time_us = tx_coalesce_usecs;
2289                coal->tx_packets = tx_max_frames;
2290        }
2291
2292        switch (coal->type) {
2293        case QLCNIC_INTR_COAL_TYPE_RX:
2294                err = qlcnic_83xx_set_rx_intr_coal(adapter);
2295                break;
2296        case QLCNIC_INTR_COAL_TYPE_TX:
2297                err = qlcnic_83xx_set_tx_intr_coal(adapter);
2298                break;
2299        case QLCNIC_INTR_COAL_TYPE_RX_TX:
2300                err = qlcnic_83xx_set_rx_tx_intr_coal(adapter);
2301                break;
2302        default:
2303                err = -EINVAL;
2304                netdev_err(adapter->netdev,
2305                           "Invalid Interrupt coalescing type\n");
2306                break;
2307        }
2308
2309        return err;
2310}
2311
2312static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
2313                                        u32 data[])
2314{
2315        struct qlcnic_hardware_context *ahw = adapter->ahw;
2316        u8 link_status, duplex;
2317        /* link speed */
2318        link_status = LSB(data[3]) & 1;
2319        if (link_status) {
2320                ahw->link_speed = MSW(data[2]);
2321                duplex = LSB(MSW(data[3]));
2322                if (duplex)
2323                        ahw->link_duplex = DUPLEX_FULL;
2324                else
2325                        ahw->link_duplex = DUPLEX_HALF;
2326        } else {
2327                ahw->link_speed = SPEED_UNKNOWN;
2328                ahw->link_duplex = DUPLEX_UNKNOWN;
2329        }
2330
2331        ahw->link_autoneg = MSB(MSW(data[3]));
2332        ahw->module_type = MSB(LSW(data[3]));
2333        ahw->has_link_events = 1;
2334        ahw->lb_mode = data[4] & QLCNIC_LB_MODE_MASK;
2335        qlcnic_advert_link_change(adapter, link_status);
2336}
2337
2338static irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
2339{
2340        u32 mask, resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
2341        struct qlcnic_adapter *adapter = data;
2342        struct qlcnic_mailbox *mbx;
2343        unsigned long flags;
2344
2345        mbx = adapter->ahw->mailbox;
2346        spin_lock_irqsave(&mbx->aen_lock, flags);
2347        resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
2348        if (!(resp & QLCNIC_SET_OWNER))
2349                goto out;
2350
2351        event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
2352        if (event &  QLCNIC_MBX_ASYNC_EVENT) {
2353                __qlcnic_83xx_process_aen(adapter);
2354        } else {
2355                if (mbx->rsp_status != rsp_status)
2356                        qlcnic_83xx_notify_mbx_response(mbx);
2357                else
2358                        adapter->stats.mbx_spurious_intr++;
2359        }
2360
2361out:
2362        mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
2363        writel(0, adapter->ahw->pci_base0 + mask);
2364        spin_unlock_irqrestore(&mbx->aen_lock, flags);
2365        return IRQ_HANDLED;
2366}
2367
2368int qlcnic_83xx_set_nic_info(struct qlcnic_adapter *adapter,
2369                             struct qlcnic_info *nic)
2370{
2371        int i, err = -EIO;
2372        struct qlcnic_cmd_args cmd;
2373
2374        if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) {
2375                dev_err(&adapter->pdev->dev,
2376                        "%s: Error, invoked by non management func\n",
2377                        __func__);
2378                return err;
2379        }
2380
2381        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO);
2382        if (err)
2383                return err;
2384
2385        cmd.req.arg[1] = (nic->pci_func << 16);
2386        cmd.req.arg[2] = 0x1 << 16;
2387        cmd.req.arg[3] = nic->phys_port | (nic->switch_mode << 16);
2388        cmd.req.arg[4] = nic->capabilities;
2389        cmd.req.arg[5] = (nic->max_mac_filters & 0xFF) | ((nic->max_mtu) << 16);
2390        cmd.req.arg[6] = (nic->max_tx_ques) | ((nic->max_rx_ques) << 16);
2391        cmd.req.arg[7] = (nic->min_tx_bw) | ((nic->max_tx_bw) << 16);
2392        for (i = 8; i < 32; i++)
2393                cmd.req.arg[i] = 0;
2394
2395        err = qlcnic_issue_cmd(adapter, &cmd);
2396
2397        if (err != QLCNIC_RCODE_SUCCESS) {
2398                dev_err(&adapter->pdev->dev, "Failed to set nic info%d\n",
2399                        err);
2400                err = -EIO;
2401        }
2402
2403        qlcnic_free_mbx_args(&cmd);
2404
2405        return err;
2406}
2407
2408int qlcnic_83xx_get_nic_info(struct qlcnic_adapter *adapter,
2409                             struct qlcnic_info *npar_info, u8 func_id)
2410{
2411        int err;
2412        u32 temp;
2413        u8 op = 0;
2414        struct qlcnic_cmd_args cmd;
2415        struct qlcnic_hardware_context *ahw = adapter->ahw;
2416
2417        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_NIC_INFO);
2418        if (err)
2419                return err;
2420
2421        if (func_id != ahw->pci_func) {
2422                temp = func_id << 16;
2423                cmd.req.arg[1] = op | BIT_31 | temp;
2424        } else {
2425                cmd.req.arg[1] = ahw->pci_func << 16;
2426        }
2427        err = qlcnic_issue_cmd(adapter, &cmd);
2428        if (err) {
2429                dev_info(&adapter->pdev->dev,
2430                         "Failed to get nic info %d\n", err);
2431                goto out;
2432        }
2433
2434        npar_info->op_type = cmd.rsp.arg[1];
2435        npar_info->pci_func = cmd.rsp.arg[2] & 0xFFFF;
2436        npar_info->op_mode = (cmd.rsp.arg[2] & 0xFFFF0000) >> 16;
2437        npar_info->phys_port = cmd.rsp.arg[3] & 0xFFFF;
2438        npar_info->switch_mode = (cmd.rsp.arg[3] & 0xFFFF0000) >> 16;
2439        npar_info->capabilities = cmd.rsp.arg[4];
2440        npar_info->max_mac_filters = cmd.rsp.arg[5] & 0xFF;
2441        npar_info->max_mtu = (cmd.rsp.arg[5] & 0xFFFF0000) >> 16;
2442        npar_info->max_tx_ques = cmd.rsp.arg[6] & 0xFFFF;
2443        npar_info->max_rx_ques = (cmd.rsp.arg[6] & 0xFFFF0000) >> 16;
2444        npar_info->min_tx_bw = cmd.rsp.arg[7] & 0xFFFF;
2445        npar_info->max_tx_bw = (cmd.rsp.arg[7] & 0xFFFF0000) >> 16;
2446        if (cmd.rsp.arg[8] & 0x1)
2447                npar_info->max_bw_reg_offset = (cmd.rsp.arg[8] & 0x7FFE) >> 1;
2448        if (cmd.rsp.arg[8] & 0x10000) {
2449                temp = (cmd.rsp.arg[8] & 0x7FFE0000) >> 17;
2450                npar_info->max_linkspeed_reg_offset = temp;
2451        }
2452
2453        memcpy(ahw->extra_capability, &cmd.rsp.arg[16],
2454               sizeof(ahw->extra_capability));
2455
2456out:
2457        qlcnic_free_mbx_args(&cmd);
2458        return err;
2459}
2460
2461int qlcnic_get_pci_func_type(struct qlcnic_adapter *adapter, u16 type,
2462                             u16 *nic, u16 *fcoe, u16 *iscsi)
2463{
2464        struct device *dev = &adapter->pdev->dev;
2465        int err = 0;
2466
2467        switch (type) {
2468        case QLCNIC_TYPE_NIC:
2469                (*nic)++;
2470                break;
2471        case QLCNIC_TYPE_FCOE:
2472                (*fcoe)++;
2473                break;
2474        case QLCNIC_TYPE_ISCSI:
2475                (*iscsi)++;
2476                break;
2477        default:
2478                dev_err(dev, "%s: Unknown PCI type[%x]\n",
2479                        __func__, type);
2480                err = -EIO;
2481        }
2482
2483        return err;
2484}
2485
2486int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
2487                             struct qlcnic_pci_info *pci_info)
2488{
2489        struct qlcnic_hardware_context *ahw = adapter->ahw;
2490        struct device *dev = &adapter->pdev->dev;
2491        u16 nic = 0, fcoe = 0, iscsi = 0;
2492        struct qlcnic_cmd_args cmd;
2493        int i, err = 0, j = 0;
2494        u32 temp;
2495
2496        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PCI_INFO);
2497        if (err)
2498                return err;
2499
2500        err = qlcnic_issue_cmd(adapter, &cmd);
2501
2502        ahw->total_nic_func = 0;
2503        if (err == QLCNIC_RCODE_SUCCESS) {
2504                ahw->max_pci_func = cmd.rsp.arg[1] & 0xFF;
2505                for (i = 2, j = 0; j < ahw->max_vnic_func; j++, pci_info++) {
2506                        pci_info->id = cmd.rsp.arg[i] & 0xFFFF;
2507                        pci_info->active = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
2508                        i++;
2509                        if (!pci_info->active) {
2510                                i += QLC_SKIP_INACTIVE_PCI_REGS;
2511                                continue;
2512                        }
2513                        pci_info->type = cmd.rsp.arg[i] & 0xFFFF;
2514                        err = qlcnic_get_pci_func_type(adapter, pci_info->type,
2515                                                       &nic, &fcoe, &iscsi);
2516                        temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
2517                        pci_info->default_port = temp;
2518                        i++;
2519                        pci_info->tx_min_bw = cmd.rsp.arg[i] & 0xFFFF;
2520                        temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
2521                        pci_info->tx_max_bw = temp;
2522                        i = i + 2;
2523                        memcpy(pci_info->mac, &cmd.rsp.arg[i], ETH_ALEN - 2);
2524                        i++;
2525                        memcpy(pci_info->mac + sizeof(u32), &cmd.rsp.arg[i], 2);
2526                        i = i + 3;
2527                }
2528        } else {
2529                dev_err(dev, "Failed to get PCI Info, error = %d\n", err);
2530                err = -EIO;
2531        }
2532
2533        ahw->total_nic_func = nic;
2534        ahw->total_pci_func = nic + fcoe + iscsi;
2535        if (ahw->total_nic_func == 0 || ahw->total_pci_func == 0) {
2536                dev_err(dev, "%s: Invalid function count: total nic func[%x], total pci func[%x]\n",
2537                        __func__, ahw->total_nic_func, ahw->total_pci_func);
2538                err = -EIO;
2539        }
2540        qlcnic_free_mbx_args(&cmd);
2541
2542        return err;
2543}
2544
2545int qlcnic_83xx_config_intrpt(struct qlcnic_adapter *adapter, bool op_type)
2546{
2547        int i, index, err;
2548        u8 max_ints;
2549        u32 val, temp, type;
2550        struct qlcnic_cmd_args cmd;
2551
2552        max_ints = adapter->ahw->num_msix - 1;
2553        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTRPT);
2554        if (err)
2555                return err;
2556
2557        cmd.req.arg[1] = max_ints;
2558
2559        if (qlcnic_sriov_vf_check(adapter))
2560                cmd.req.arg[1] |= (adapter->ahw->pci_func << 8) | BIT_16;
2561
2562        for (i = 0, index = 2; i < max_ints; i++) {
2563                type = op_type ? QLCNIC_INTRPT_ADD : QLCNIC_INTRPT_DEL;
2564                val = type | (adapter->ahw->intr_tbl[i].type << 4);
2565                if (adapter->ahw->intr_tbl[i].type == QLCNIC_INTRPT_MSIX)
2566                        val |= (adapter->ahw->intr_tbl[i].id << 16);
2567                cmd.req.arg[index++] = val;
2568        }
2569        err = qlcnic_issue_cmd(adapter, &cmd);
2570        if (err) {
2571                dev_err(&adapter->pdev->dev,
2572                        "Failed to configure interrupts 0x%x\n", err);
2573                goto out;
2574        }
2575
2576        max_ints = cmd.rsp.arg[1];
2577        for (i = 0, index = 2; i < max_ints; i++, index += 2) {
2578                val = cmd.rsp.arg[index];
2579                if (LSB(val)) {
2580                        dev_info(&adapter->pdev->dev,
2581                                 "Can't configure interrupt %d\n",
2582                                 adapter->ahw->intr_tbl[i].id);
2583                        continue;
2584                }
2585                if (op_type) {
2586                        adapter->ahw->intr_tbl[i].id = MSW(val);
2587                        adapter->ahw->intr_tbl[i].enabled = 1;
2588                        temp = cmd.rsp.arg[index + 1];
2589                        adapter->ahw->intr_tbl[i].src = temp;
2590                } else {
2591                        adapter->ahw->intr_tbl[i].id = i;
2592                        adapter->ahw->intr_tbl[i].enabled = 0;
2593                        adapter->ahw->intr_tbl[i].src = 0;
2594                }
2595        }
2596out:
2597        qlcnic_free_mbx_args(&cmd);
2598        return err;
2599}
2600
2601int qlcnic_83xx_lock_flash(struct qlcnic_adapter *adapter)
2602{
2603        int id, timeout = 0;
2604        u32 status = 0;
2605
2606        while (status == 0) {
2607                status = QLC_SHARED_REG_RD32(adapter, QLCNIC_FLASH_LOCK);
2608                if (status)
2609                        break;
2610
2611                if (++timeout >= QLC_83XX_FLASH_LOCK_TIMEOUT) {
2612                        id = QLC_SHARED_REG_RD32(adapter,
2613                                                 QLCNIC_FLASH_LOCK_OWNER);
2614                        dev_err(&adapter->pdev->dev,
2615                                "%s: failed, lock held by %d\n", __func__, id);
2616                        return -EIO;
2617                }
2618                usleep_range(1000, 2000);
2619        }
2620
2621        QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER, adapter->portnum);
2622        return 0;
2623}
2624
2625void qlcnic_83xx_unlock_flash(struct qlcnic_adapter *adapter)
2626{
2627        QLC_SHARED_REG_RD32(adapter, QLCNIC_FLASH_UNLOCK);
2628        QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER, 0xFF);
2629}
2630
2631int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *adapter,
2632                                      u32 flash_addr, u8 *p_data,
2633                                      int count)
2634{
2635        u32 word, range, flash_offset, addr = flash_addr, ret;
2636        ulong indirect_add, direct_window;
2637        int i, err = 0;
2638
2639        flash_offset = addr & (QLCNIC_FLASH_SECTOR_SIZE - 1);
2640        if (addr & 0x3) {
2641                dev_err(&adapter->pdev->dev, "Illegal addr = 0x%x\n", addr);
2642                return -EIO;
2643        }
2644
2645        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_DIRECT_WINDOW,
2646                                     (addr & 0xFFFF0000));
2647
2648        range = flash_offset + (count * sizeof(u32));
2649        /* Check if data is spread across multiple sectors */
2650        if (range > (QLCNIC_FLASH_SECTOR_SIZE - 1)) {
2651
2652                /* Multi sector read */
2653                for (i = 0; i < count; i++) {
2654                        indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr);
2655                        ret = QLCRD32(adapter, indirect_add, &err);
2656                        if (err == -EIO)
2657                                return err;
2658
2659                        word = ret;
2660                        *(u32 *)p_data  = word;
2661                        p_data = p_data + 4;
2662                        addr = addr + 4;
2663                        flash_offset = flash_offset + 4;
2664
2665                        if (flash_offset > (QLCNIC_FLASH_SECTOR_SIZE - 1)) {
2666                                direct_window = QLC_83XX_FLASH_DIRECT_WINDOW;
2667                                /* This write is needed once for each sector */
2668                                qlcnic_83xx_wrt_reg_indirect(adapter,
2669                                                             direct_window,
2670                                                             (addr));
2671                                flash_offset = 0;
2672                        }
2673                }
2674        } else {
2675                /* Single sector read */
2676                for (i = 0; i < count; i++) {
2677                        indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr);
2678                        ret = QLCRD32(adapter, indirect_add, &err);
2679                        if (err == -EIO)
2680                                return err;
2681
2682                        word = ret;
2683                        *(u32 *)p_data  = word;
2684                        p_data = p_data + 4;
2685                        addr = addr + 4;
2686                }
2687        }
2688
2689        return 0;
2690}
2691
2692static int qlcnic_83xx_poll_flash_status_reg(struct qlcnic_adapter *adapter)
2693{
2694        u32 status;
2695        int retries = QLC_83XX_FLASH_READ_RETRY_COUNT;
2696        int err = 0;
2697
2698        do {
2699                status = QLCRD32(adapter, QLC_83XX_FLASH_STATUS, &err);
2700                if (err == -EIO)
2701                        return err;
2702
2703                if ((status & QLC_83XX_FLASH_STATUS_READY) ==
2704                    QLC_83XX_FLASH_STATUS_READY)
2705                        break;
2706
2707                usleep_range(1000, 1100);
2708        } while (--retries);
2709
2710        if (!retries)
2711                return -EIO;
2712
2713        return 0;
2714}
2715
2716int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *adapter)
2717{
2718        int ret;
2719        u32 cmd;
2720        cmd = adapter->ahw->fdt.write_statusreg_cmd;
2721        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2722                                     (QLC_83XX_FLASH_FDT_WRITE_DEF_SIG | cmd));
2723        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2724                                     adapter->ahw->fdt.write_enable_bits);
2725        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2726                                     QLC_83XX_FLASH_SECOND_ERASE_MS_VAL);
2727        ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2728        if (ret)
2729                return -EIO;
2730
2731        return 0;
2732}
2733
2734int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *adapter)
2735{
2736        int ret;
2737
2738        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2739                                     (QLC_83XX_FLASH_FDT_WRITE_DEF_SIG |
2740                                     adapter->ahw->fdt.write_statusreg_cmd));
2741        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2742                                     adapter->ahw->fdt.write_disable_bits);
2743        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2744                                     QLC_83XX_FLASH_SECOND_ERASE_MS_VAL);
2745        ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2746        if (ret)
2747                return -EIO;
2748
2749        return 0;
2750}
2751
2752int qlcnic_83xx_read_flash_mfg_id(struct qlcnic_adapter *adapter)
2753{
2754        int ret, err = 0;
2755        u32 mfg_id;
2756
2757        if (qlcnic_83xx_lock_flash(adapter))
2758                return -EIO;
2759
2760        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2761                                     QLC_83XX_FLASH_FDT_READ_MFG_ID_VAL);
2762        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2763                                     QLC_83XX_FLASH_READ_CTRL);
2764        ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2765        if (ret) {
2766                qlcnic_83xx_unlock_flash(adapter);
2767                return -EIO;
2768        }
2769
2770        mfg_id = QLCRD32(adapter, QLC_83XX_FLASH_RDDATA, &err);
2771        if (err == -EIO) {
2772                qlcnic_83xx_unlock_flash(adapter);
2773                return err;
2774        }
2775
2776        adapter->flash_mfg_id = (mfg_id & 0xFF);
2777        qlcnic_83xx_unlock_flash(adapter);
2778
2779        return 0;
2780}
2781
2782int qlcnic_83xx_read_flash_descriptor_table(struct qlcnic_adapter *adapter)
2783{
2784        int count, fdt_size, ret = 0;
2785
2786        fdt_size = sizeof(struct qlcnic_fdt);
2787        count = fdt_size / sizeof(u32);
2788
2789        if (qlcnic_83xx_lock_flash(adapter))
2790                return -EIO;
2791
2792        memset(&adapter->ahw->fdt, 0, fdt_size);
2793        ret = qlcnic_83xx_lockless_flash_read32(adapter, QLCNIC_FDT_LOCATION,
2794                                                (u8 *)&adapter->ahw->fdt,
2795                                                count);
2796        qlcnic_swap32_buffer((u32 *)&adapter->ahw->fdt, count);
2797        qlcnic_83xx_unlock_flash(adapter);
2798        return ret;
2799}
2800
2801int qlcnic_83xx_erase_flash_sector(struct qlcnic_adapter *adapter,
2802                                   u32 sector_start_addr)
2803{
2804        u32 reversed_addr, addr1, addr2, cmd;
2805        int ret = -EIO;
2806
2807        if (qlcnic_83xx_lock_flash(adapter) != 0)
2808                return -EIO;
2809
2810        if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
2811                ret = qlcnic_83xx_enable_flash_write(adapter);
2812                if (ret) {
2813                        qlcnic_83xx_unlock_flash(adapter);
2814                        dev_err(&adapter->pdev->dev,
2815                                "%s failed at %d\n",
2816                                __func__, __LINE__);
2817                        return ret;
2818                }
2819        }
2820
2821        ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2822        if (ret) {
2823                qlcnic_83xx_unlock_flash(adapter);
2824                dev_err(&adapter->pdev->dev,
2825                        "%s: failed at %d\n", __func__, __LINE__);
2826                return -EIO;
2827        }
2828
2829        addr1 = (sector_start_addr & 0xFF) << 16;
2830        addr2 = (sector_start_addr & 0xFF0000) >> 16;
2831        reversed_addr = addr1 | addr2 | (sector_start_addr & 0xFF00);
2832
2833        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2834                                     reversed_addr);
2835        cmd = QLC_83XX_FLASH_FDT_ERASE_DEF_SIG | adapter->ahw->fdt.erase_cmd;
2836        if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id)
2837                qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR, cmd);
2838        else
2839                qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2840                                             QLC_83XX_FLASH_OEM_ERASE_SIG);
2841        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2842                                     QLC_83XX_FLASH_LAST_ERASE_MS_VAL);
2843
2844        ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2845        if (ret) {
2846                qlcnic_83xx_unlock_flash(adapter);
2847                dev_err(&adapter->pdev->dev,
2848                        "%s: failed at %d\n", __func__, __LINE__);
2849                return -EIO;
2850        }
2851
2852        if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
2853                ret = qlcnic_83xx_disable_flash_write(adapter);
2854                if (ret) {
2855                        qlcnic_83xx_unlock_flash(adapter);
2856                        dev_err(&adapter->pdev->dev,
2857                                "%s: failed at %d\n", __func__, __LINE__);
2858                        return ret;
2859                }
2860        }
2861
2862        qlcnic_83xx_unlock_flash(adapter);
2863
2864        return 0;
2865}
2866
2867int qlcnic_83xx_flash_write32(struct qlcnic_adapter *adapter, u32 addr,
2868                              u32 *p_data)
2869{
2870        int ret = -EIO;
2871        u32 addr1 = 0x00800000 | (addr >> 2);
2872
2873        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR, addr1);
2874        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data);
2875        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2876                                     QLC_83XX_FLASH_LAST_ERASE_MS_VAL);
2877        ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2878        if (ret) {
2879                dev_err(&adapter->pdev->dev,
2880                        "%s: failed at %d\n", __func__, __LINE__);
2881                return -EIO;
2882        }
2883
2884        return 0;
2885}
2886
2887int qlcnic_83xx_flash_bulk_write(struct qlcnic_adapter *adapter, u32 addr,
2888                                 u32 *p_data, int count)
2889{
2890        u32 temp;
2891        int ret = -EIO, err = 0;
2892
2893        if ((count < QLC_83XX_FLASH_WRITE_MIN) ||
2894            (count > QLC_83XX_FLASH_WRITE_MAX)) {
2895                dev_err(&adapter->pdev->dev,
2896                        "%s: Invalid word count\n", __func__);
2897                return -EIO;
2898        }
2899
2900        temp = QLCRD32(adapter, QLC_83XX_FLASH_SPI_CONTROL, &err);
2901        if (err == -EIO)
2902                return err;
2903
2904        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_SPI_CONTROL,
2905                                     (temp | QLC_83XX_FLASH_SPI_CTRL));
2906        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2907                                     QLC_83XX_FLASH_ADDR_TEMP_VAL);
2908
2909        /* First DWORD write */
2910        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data++);
2911        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2912                                     QLC_83XX_FLASH_FIRST_MS_PATTERN);
2913        ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2914        if (ret) {
2915                dev_err(&adapter->pdev->dev,
2916                        "%s: failed at %d\n", __func__, __LINE__);
2917                return -EIO;
2918        }
2919
2920        count--;
2921        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2922                                     QLC_83XX_FLASH_ADDR_SECOND_TEMP_VAL);
2923        /* Second to N-1 DWORD writes */
2924        while (count != 1) {
2925                qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2926                                             *p_data++);
2927                qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2928                                             QLC_83XX_FLASH_SECOND_MS_PATTERN);
2929                ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2930                if (ret) {
2931                        dev_err(&adapter->pdev->dev,
2932                                "%s: failed at %d\n", __func__, __LINE__);
2933                        return -EIO;
2934                }
2935                count--;
2936        }
2937
2938        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2939                                     QLC_83XX_FLASH_ADDR_TEMP_VAL |
2940                                     (addr >> 2));
2941        /* Last DWORD write */
2942        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data++);
2943        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2944                                     QLC_83XX_FLASH_LAST_MS_PATTERN);
2945        ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2946        if (ret) {
2947                dev_err(&adapter->pdev->dev,
2948                        "%s: failed at %d\n", __func__, __LINE__);
2949                return -EIO;
2950        }
2951
2952        ret = QLCRD32(adapter, QLC_83XX_FLASH_SPI_STATUS, &err);
2953        if (err == -EIO)
2954                return err;
2955
2956        if ((ret & QLC_83XX_FLASH_SPI_CTRL) == QLC_83XX_FLASH_SPI_CTRL) {
2957                dev_err(&adapter->pdev->dev, "%s: failed at %d\n",
2958                        __func__, __LINE__);
2959                /* Operation failed, clear error bit */
2960                temp = QLCRD32(adapter, QLC_83XX_FLASH_SPI_CONTROL, &err);
2961                if (err == -EIO)
2962                        return err;
2963
2964                qlcnic_83xx_wrt_reg_indirect(adapter,
2965                                             QLC_83XX_FLASH_SPI_CONTROL,
2966                                             (temp | QLC_83XX_FLASH_SPI_CTRL));
2967        }
2968
2969        return 0;
2970}
2971
2972static void qlcnic_83xx_recover_driver_lock(struct qlcnic_adapter *adapter)
2973{
2974        u32 val, id;
2975
2976        val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK);
2977
2978        /* Check if recovery need to be performed by the calling function */
2979        if ((val & QLC_83XX_DRV_LOCK_RECOVERY_STATUS_MASK) == 0) {
2980                val = val & ~0x3F;
2981                val = val | ((adapter->portnum << 2) |
2982                             QLC_83XX_NEED_DRV_LOCK_RECOVERY);
2983                QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
2984                dev_info(&adapter->pdev->dev,
2985                         "%s: lock recovery initiated\n", __func__);
2986                msleep(QLC_83XX_DRV_LOCK_RECOVERY_DELAY);
2987                val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK);
2988                id = ((val >> 2) & 0xF);
2989                if (id == adapter->portnum) {
2990                        val = val & ~QLC_83XX_DRV_LOCK_RECOVERY_STATUS_MASK;
2991                        val = val | QLC_83XX_DRV_LOCK_RECOVERY_IN_PROGRESS;
2992                        QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
2993                        /* Force release the lock */
2994                        QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
2995                        /* Clear recovery bits */
2996                        val = val & ~0x3F;
2997                        QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
2998                        dev_info(&adapter->pdev->dev,
2999                                 "%s: lock recovery completed\n", __func__);
3000                } else {
3001                        dev_info(&adapter->pdev->dev,
3002                                 "%s: func %d to resume lock recovery process\n",
3003                                 __func__, id);
3004                }
3005        } else {
3006                dev_info(&adapter->pdev->dev,
3007                         "%s: lock recovery initiated by other functions\n",
3008                         __func__);
3009        }
3010}
3011
3012int qlcnic_83xx_lock_driver(struct qlcnic_adapter *adapter)
3013{
3014        u32 lock_alive_counter, val, id, i = 0, status = 0, temp = 0;
3015        int max_attempt = 0;
3016
3017        while (status == 0) {
3018                status = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK);
3019                if (status)
3020                        break;
3021
3022                msleep(QLC_83XX_DRV_LOCK_WAIT_DELAY);
3023                i++;
3024
3025                if (i == 1)
3026                        temp = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
3027
3028                if (i == QLC_83XX_DRV_LOCK_WAIT_COUNTER) {
3029                        val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
3030                        if (val == temp) {
3031                                id = val & 0xFF;
3032                                dev_info(&adapter->pdev->dev,
3033                                         "%s: lock to be recovered from %d\n",
3034                                         __func__, id);
3035                                qlcnic_83xx_recover_driver_lock(adapter);
3036                                i = 0;
3037                                max_attempt++;
3038                        } else {
3039                                dev_err(&adapter->pdev->dev,
3040                                        "%s: failed to get lock\n", __func__);
3041                                return -EIO;
3042                        }
3043                }
3044
3045                /* Force exit from while loop after few attempts */
3046                if (max_attempt == QLC_83XX_MAX_DRV_LOCK_RECOVERY_ATTEMPT) {
3047                        dev_err(&adapter->pdev->dev,
3048                                "%s: failed to get lock\n", __func__);
3049                        return -EIO;
3050                }
3051        }
3052
3053        val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
3054        lock_alive_counter = val >> 8;
3055        lock_alive_counter++;
3056        val = lock_alive_counter << 8 | adapter->portnum;
3057        QLCWRX(adapter->ahw, QLC_83XX_DRV_LOCK_ID, val);
3058
3059        return 0;
3060}
3061
3062void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *adapter)
3063{
3064        u32 val, lock_alive_counter, id;
3065
3066        val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
3067        id = val & 0xFF;
3068        lock_alive_counter = val >> 8;
3069
3070        if (id != adapter->portnum)
3071                dev_err(&adapter->pdev->dev,
3072                        "%s:Warning func %d is unlocking lock owned by %d\n",
3073                        __func__, adapter->portnum, id);
3074
3075        val = (lock_alive_counter << 8) | 0xFF;
3076        QLCWRX(adapter->ahw, QLC_83XX_DRV_LOCK_ID, val);
3077        QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
3078}
3079
3080int qlcnic_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr,
3081                                u32 *data, u32 count)
3082{
3083        int i, j, ret = 0;
3084        u32 temp;
3085
3086        /* Check alignment */
3087        if (addr & 0xF)
3088                return -EIO;
3089
3090        mutex_lock(&adapter->ahw->mem_lock);
3091        qlcnic_ind_wr(adapter, QLCNIC_MS_ADDR_HI, 0);
3092
3093        for (i = 0; i < count; i++, addr += 16) {
3094                if (!((ADDR_IN_RANGE(addr, QLCNIC_ADDR_QDR_NET,
3095                                     QLCNIC_ADDR_QDR_NET_MAX)) ||
3096                      (ADDR_IN_RANGE(addr, QLCNIC_ADDR_DDR_NET,
3097                                     QLCNIC_ADDR_DDR_NET_MAX)))) {
3098                        mutex_unlock(&adapter->ahw->mem_lock);
3099                        return -EIO;
3100                }
3101
3102                qlcnic_ind_wr(adapter, QLCNIC_MS_ADDR_LO, addr);
3103                qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_LO, *data++);
3104                qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_HI, *data++);
3105                qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_ULO, *data++);
3106                qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_UHI, *data++);
3107                qlcnic_ind_wr(adapter, QLCNIC_MS_CTRL, QLCNIC_TA_WRITE_ENABLE);
3108                qlcnic_ind_wr(adapter, QLCNIC_MS_CTRL, QLCNIC_TA_WRITE_START);
3109
3110                for (j = 0; j < MAX_CTL_CHECK; j++) {
3111                        temp = qlcnic_ind_rd(adapter, QLCNIC_MS_CTRL);
3112
3113                        if ((temp & TA_CTL_BUSY) == 0)
3114                                break;
3115                }
3116
3117                /* Status check failure */
3118                if (j >= MAX_CTL_CHECK) {
3119                        printk_ratelimited(KERN_WARNING
3120                                           "MS memory write failed\n");
3121                        mutex_unlock(&adapter->ahw->mem_lock);
3122                        return -EIO;
3123                }
3124        }
3125
3126        mutex_unlock(&adapter->ahw->mem_lock);
3127
3128        return ret;
3129}
3130
3131int qlcnic_83xx_flash_read32(struct qlcnic_adapter *adapter, u32 flash_addr,
3132                             u8 *p_data, int count)
3133{
3134        u32 word, addr = flash_addr, ret;
3135        ulong  indirect_addr;
3136        int i, err = 0;
3137
3138        if (qlcnic_83xx_lock_flash(adapter) != 0)
3139                return -EIO;
3140
3141        if (addr & 0x3) {
3142                dev_err(&adapter->pdev->dev, "Illegal addr = 0x%x\n", addr);
3143                qlcnic_83xx_unlock_flash(adapter);
3144                return -EIO;
3145        }
3146
3147        for (i = 0; i < count; i++) {
3148                if (qlcnic_83xx_wrt_reg_indirect(adapter,
3149                                                 QLC_83XX_FLASH_DIRECT_WINDOW,
3150                                                 (addr))) {
3151                        qlcnic_83xx_unlock_flash(adapter);
3152                        return -EIO;
3153                }
3154
3155                indirect_addr = QLC_83XX_FLASH_DIRECT_DATA(addr);
3156                ret = QLCRD32(adapter, indirect_addr, &err);
3157                if (err == -EIO)
3158                        return err;
3159
3160                word = ret;
3161                *(u32 *)p_data  = word;
3162                p_data = p_data + 4;
3163                addr = addr + 4;
3164        }
3165
3166        qlcnic_83xx_unlock_flash(adapter);
3167
3168        return 0;
3169}
3170
3171int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter)
3172{
3173        u8 pci_func;
3174        int err;
3175        u32 config = 0, state;
3176        struct qlcnic_cmd_args cmd;
3177        struct qlcnic_hardware_context *ahw = adapter->ahw;
3178
3179        if (qlcnic_sriov_vf_check(adapter))
3180                pci_func = adapter->portnum;
3181        else
3182                pci_func = ahw->pci_func;
3183
3184        state = readl(ahw->pci_base0 + QLC_83XX_LINK_STATE(pci_func));
3185        if (!QLC_83xx_FUNC_VAL(state, pci_func)) {
3186                dev_info(&adapter->pdev->dev, "link state down\n");
3187                return config;
3188        }
3189
3190        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_STATUS);
3191        if (err)
3192                return err;
3193
3194        err = qlcnic_issue_cmd(adapter, &cmd);
3195        if (err) {
3196                dev_info(&adapter->pdev->dev,
3197                         "Get Link Status Command failed: 0x%x\n", err);
3198                goto out;
3199        } else {
3200                config = cmd.rsp.arg[1];
3201                switch (QLC_83XX_CURRENT_LINK_SPEED(config)) {
3202                case QLC_83XX_10M_LINK:
3203                        ahw->link_speed = SPEED_10;
3204                        break;
3205                case QLC_83XX_100M_LINK:
3206                        ahw->link_speed = SPEED_100;
3207                        break;
3208                case QLC_83XX_1G_LINK:
3209                        ahw->link_speed = SPEED_1000;
3210                        break;
3211                case QLC_83XX_10G_LINK:
3212                        ahw->link_speed = SPEED_10000;
3213                        break;
3214                default:
3215                        ahw->link_speed = 0;
3216                        break;
3217                }
3218                config = cmd.rsp.arg[3];
3219                switch (QLC_83XX_SFP_MODULE_TYPE(config)) {
3220                case QLC_83XX_MODULE_FIBRE_10GBASE_LRM:
3221                case QLC_83XX_MODULE_FIBRE_10GBASE_LR:
3222                case QLC_83XX_MODULE_FIBRE_10GBASE_SR:
3223                        ahw->supported_type = PORT_FIBRE;
3224                        ahw->port_type = QLCNIC_XGBE;
3225                        break;
3226                case QLC_83XX_MODULE_FIBRE_1000BASE_SX:
3227                case QLC_83XX_MODULE_FIBRE_1000BASE_LX:
3228                case QLC_83XX_MODULE_FIBRE_1000BASE_CX:
3229                        ahw->supported_type = PORT_FIBRE;
3230                        ahw->port_type = QLCNIC_GBE;
3231                        break;
3232                case QLC_83XX_MODULE_TP_1000BASE_T:
3233                        ahw->supported_type = PORT_TP;
3234                        ahw->port_type = QLCNIC_GBE;
3235                        break;
3236                case QLC_83XX_MODULE_DA_10GE_PASSIVE_CP:
3237                case QLC_83XX_MODULE_DA_10GE_ACTIVE_CP:
3238                case QLC_83XX_MODULE_DA_10GE_LEGACY_CP:
3239                case QLC_83XX_MODULE_DA_1GE_PASSIVE_CP:
3240                        ahw->supported_type = PORT_DA;
3241                        ahw->port_type = QLCNIC_XGBE;
3242                        break;
3243                default:
3244                        ahw->supported_type = PORT_OTHER;
3245                        ahw->port_type = QLCNIC_XGBE;
3246                }
3247                if (config & 1)
3248                        err = 1;
3249        }
3250out:
3251        qlcnic_free_mbx_args(&cmd);
3252        return config;
3253}
3254
3255int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter,
3256                             struct ethtool_cmd *ecmd)
3257{
3258        struct qlcnic_hardware_context *ahw = adapter->ahw;
3259        u32 config = 0;
3260        int status = 0;
3261
3262        if (!test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) {
3263                /* Get port configuration info */
3264                status = qlcnic_83xx_get_port_info(adapter);
3265                /* Get Link Status related info */
3266                config = qlcnic_83xx_test_link(adapter);
3267                ahw->module_type = QLC_83XX_SFP_MODULE_TYPE(config);
3268        }
3269
3270        /* hard code until there is a way to get it from flash */
3271        ahw->board_type = QLCNIC_BRDTYPE_83XX_10G;
3272
3273        if (netif_running(adapter->netdev) && ahw->has_link_events) {
3274                ethtool_cmd_speed_set(ecmd, ahw->link_speed);
3275                ecmd->duplex = ahw->link_duplex;
3276                ecmd->autoneg = ahw->link_autoneg;
3277        } else {
3278                ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
3279                ecmd->duplex = DUPLEX_UNKNOWN;
3280                ecmd->autoneg = AUTONEG_DISABLE;
3281        }
3282
3283        ecmd->supported = (SUPPORTED_10baseT_Full |
3284                           SUPPORTED_100baseT_Full |
3285                           SUPPORTED_1000baseT_Full |
3286                           SUPPORTED_10000baseT_Full |
3287                           SUPPORTED_Autoneg);
3288
3289        if (ecmd->autoneg == AUTONEG_ENABLE) {
3290                if (ahw->port_config & QLC_83XX_10_CAPABLE)
3291                        ecmd->advertising |= SUPPORTED_10baseT_Full;
3292                if (ahw->port_config & QLC_83XX_100_CAPABLE)
3293                        ecmd->advertising |= SUPPORTED_100baseT_Full;
3294                if (ahw->port_config & QLC_83XX_1G_CAPABLE)
3295                        ecmd->advertising |= SUPPORTED_1000baseT_Full;
3296                if (ahw->port_config & QLC_83XX_10G_CAPABLE)
3297                        ecmd->advertising |= SUPPORTED_10000baseT_Full;
3298                if (ahw->port_config & QLC_83XX_AUTONEG_ENABLE)
3299                        ecmd->advertising |= ADVERTISED_Autoneg;
3300        } else {
3301                switch (ahw->link_speed) {
3302                case SPEED_10:
3303                        ecmd->advertising = SUPPORTED_10baseT_Full;
3304                        break;
3305                case SPEED_100:
3306                        ecmd->advertising = SUPPORTED_100baseT_Full;
3307                        break;
3308                case SPEED_1000:
3309                        ecmd->advertising = SUPPORTED_1000baseT_Full;
3310                        break;
3311                case SPEED_10000:
3312                        ecmd->advertising = SUPPORTED_10000baseT_Full;
3313                        break;
3314                default:
3315                        break;
3316                }
3317
3318        }
3319
3320        switch (ahw->supported_type) {
3321        case PORT_FIBRE:
3322                ecmd->supported |= SUPPORTED_FIBRE;
3323                ecmd->advertising |= ADVERTISED_FIBRE;
3324                ecmd->port = PORT_FIBRE;
3325                ecmd->transceiver = XCVR_EXTERNAL;
3326                break;
3327        case PORT_TP:
3328                ecmd->supported |= SUPPORTED_TP;
3329                ecmd->advertising |= ADVERTISED_TP;
3330                ecmd->port = PORT_TP;
3331                ecmd->transceiver = XCVR_INTERNAL;
3332                break;
3333        case PORT_DA:
3334                ecmd->supported |= SUPPORTED_FIBRE;
3335                ecmd->advertising |= ADVERTISED_FIBRE;
3336                ecmd->port = PORT_DA;
3337                ecmd->transceiver = XCVR_EXTERNAL;
3338                break;
3339        default:
3340                ecmd->supported |= SUPPORTED_FIBRE;
3341                ecmd->advertising |= ADVERTISED_FIBRE;
3342                ecmd->port = PORT_OTHER;
3343                ecmd->transceiver = XCVR_EXTERNAL;
3344                break;
3345        }
3346        ecmd->phy_address = ahw->physical_port;
3347        return status;
3348}
3349
3350int qlcnic_83xx_set_settings(struct qlcnic_adapter *adapter,
3351                             struct ethtool_cmd *ecmd)
3352{
3353        struct qlcnic_hardware_context *ahw = adapter->ahw;
3354        u32 config = adapter->ahw->port_config;
3355        int status = 0;
3356
3357        /* 83xx devices do not support Half duplex */
3358        if (ecmd->duplex == DUPLEX_HALF) {
3359                        netdev_info(adapter->netdev,
3360                                    "Half duplex mode not supported\n");
3361                        return -EINVAL;
3362        }
3363
3364        if (ecmd->autoneg) {
3365                ahw->port_config |= QLC_83XX_AUTONEG_ENABLE;
3366                ahw->port_config |= (QLC_83XX_100_CAPABLE |
3367                                     QLC_83XX_1G_CAPABLE |
3368                                     QLC_83XX_10G_CAPABLE);
3369        } else { /* force speed */
3370                ahw->port_config &= ~QLC_83XX_AUTONEG_ENABLE;
3371                switch (ethtool_cmd_speed(ecmd)) {
3372                case SPEED_10:
3373                        ahw->port_config &= ~(QLC_83XX_100_CAPABLE |
3374                                              QLC_83XX_1G_CAPABLE |
3375                                              QLC_83XX_10G_CAPABLE);
3376                        ahw->port_config |= QLC_83XX_10_CAPABLE;
3377                        break;
3378                case SPEED_100:
3379                        ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
3380                                              QLC_83XX_1G_CAPABLE |
3381                                              QLC_83XX_10G_CAPABLE);
3382                        ahw->port_config |= QLC_83XX_100_CAPABLE;
3383                        break;
3384                case SPEED_1000:
3385                        ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
3386                                              QLC_83XX_100_CAPABLE |
3387                                              QLC_83XX_10G_CAPABLE);
3388                        ahw->port_config |= QLC_83XX_1G_CAPABLE;
3389                        break;
3390                case SPEED_10000:
3391                        ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
3392                                              QLC_83XX_100_CAPABLE |
3393                                              QLC_83XX_1G_CAPABLE);
3394                        ahw->port_config |= QLC_83XX_10G_CAPABLE;
3395                        break;
3396                default:
3397                        return -EINVAL;
3398                }
3399        }
3400        status = qlcnic_83xx_set_port_config(adapter);
3401        if (status) {
3402                netdev_info(adapter->netdev,
3403                            "Failed to Set Link Speed and autoneg.\n");
3404                ahw->port_config = config;
3405        }
3406
3407        return status;
3408}
3409
3410static inline u64 *qlcnic_83xx_copy_stats(struct qlcnic_cmd_args *cmd,
3411                                          u64 *data, int index)
3412{
3413        u32 low, hi;
3414        u64 val;
3415
3416        low = cmd->rsp.arg[index];
3417        hi = cmd->rsp.arg[index + 1];
3418        val = (((u64) low) | (((u64) hi) << 32));
3419        *data++ = val;
3420        return data;
3421}
3422
3423static u64 *qlcnic_83xx_fill_stats(struct qlcnic_adapter *adapter,
3424                                   struct qlcnic_cmd_args *cmd, u64 *data,
3425                                   int type, int *ret)
3426{
3427        int err, k, total_regs;
3428
3429        *ret = 0;
3430        err = qlcnic_issue_cmd(adapter, cmd);
3431        if (err != QLCNIC_RCODE_SUCCESS) {
3432                dev_info(&adapter->pdev->dev,
3433                         "Error in get statistics mailbox command\n");
3434                *ret = -EIO;
3435                return data;
3436        }
3437        total_regs = cmd->rsp.num;
3438        switch (type) {
3439        case QLC_83XX_STAT_MAC:
3440                /* fill in MAC tx counters */
3441                for (k = 2; k < 28; k += 2)
3442                        data = qlcnic_83xx_copy_stats(cmd, data, k);
3443                /* skip 24 bytes of reserved area */
3444                /* fill in MAC rx counters */
3445                for (k += 6; k < 60; k += 2)
3446                        data = qlcnic_83xx_copy_stats(cmd, data, k);
3447                /* skip 24 bytes of reserved area */
3448                /* fill in MAC rx frame stats */
3449                for (k += 6; k < 80; k += 2)
3450                        data = qlcnic_83xx_copy_stats(cmd, data, k);
3451                /* fill in eSwitch stats */
3452                for (; k < total_regs; k += 2)
3453                        data = qlcnic_83xx_copy_stats(cmd, data, k);
3454                break;
3455        case QLC_83XX_STAT_RX:
3456                for (k = 2; k < 8; k += 2)
3457                        data = qlcnic_83xx_copy_stats(cmd, data, k);
3458                /* skip 8 bytes of reserved data */
3459                for (k += 2; k < 24; k += 2)
3460                        data = qlcnic_83xx_copy_stats(cmd, data, k);
3461                /* skip 8 bytes containing RE1FBQ error data */
3462                for (k += 2; k < total_regs; k += 2)
3463                        data = qlcnic_83xx_copy_stats(cmd, data, k);
3464                break;
3465        case QLC_83XX_STAT_TX:
3466                for (k = 2; k < 10; k += 2)
3467                        data = qlcnic_83xx_copy_stats(cmd, data, k);
3468                /* skip 8 bytes of reserved data */
3469                for (k += 2; k < total_regs; k += 2)
3470                        data = qlcnic_83xx_copy_stats(cmd, data, k);
3471                break;
3472        default:
3473                dev_warn(&adapter->pdev->dev, "Unknown get statistics mode\n");
3474                *ret = -EIO;
3475        }
3476        return data;
3477}
3478
3479void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data)
3480{
3481        struct qlcnic_cmd_args cmd;
3482        struct net_device *netdev = adapter->netdev;
3483        int ret = 0;
3484
3485        ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_STATISTICS);
3486        if (ret)
3487                return;
3488        /* Get Tx stats */
3489        cmd.req.arg[1] = BIT_1 | (adapter->tx_ring->ctx_id << 16);
3490        cmd.rsp.num = QLC_83XX_TX_STAT_REGS;
3491        data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
3492                                      QLC_83XX_STAT_TX, &ret);
3493        if (ret) {
3494                netdev_err(netdev, "Error getting Tx stats\n");
3495                goto out;
3496        }
3497        /* Get MAC stats */
3498        cmd.req.arg[1] = BIT_2 | (adapter->portnum << 16);
3499        cmd.rsp.num = QLC_83XX_MAC_STAT_REGS;
3500        memset(cmd.rsp.arg, 0, sizeof(u32) * cmd.rsp.num);
3501        data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
3502                                      QLC_83XX_STAT_MAC, &ret);
3503        if (ret) {
3504                netdev_err(netdev, "Error getting MAC stats\n");
3505                goto out;
3506        }
3507        /* Get Rx stats */
3508        cmd.req.arg[1] = adapter->recv_ctx->context_id << 16;
3509        cmd.rsp.num = QLC_83XX_RX_STAT_REGS;
3510        memset(cmd.rsp.arg, 0, sizeof(u32) * cmd.rsp.num);
3511        data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
3512                                      QLC_83XX_STAT_RX, &ret);
3513        if (ret)
3514                netdev_err(netdev, "Error getting Rx stats\n");
3515out:
3516        qlcnic_free_mbx_args(&cmd);
3517}
3518
3519#define QLCNIC_83XX_ADD_PORT0           BIT_0
3520#define QLCNIC_83XX_ADD_PORT1           BIT_1
3521#define QLCNIC_83XX_EXTENDED_MEM_SIZE   13 /* In MB */
3522int qlcnic_83xx_extend_md_capab(struct qlcnic_adapter *adapter)
3523{
3524        struct qlcnic_cmd_args cmd;
3525        int err;
3526
3527        err = qlcnic_alloc_mbx_args(&cmd, adapter,
3528                                    QLCNIC_CMD_83XX_EXTEND_ISCSI_DUMP_CAP);
3529        if (err)
3530                return err;
3531
3532        cmd.req.arg[1] = (QLCNIC_83XX_ADD_PORT0 | QLCNIC_83XX_ADD_PORT1);
3533        cmd.req.arg[2] = QLCNIC_83XX_EXTENDED_MEM_SIZE;
3534        cmd.req.arg[3] = QLCNIC_83XX_EXTENDED_MEM_SIZE;
3535
3536        err = qlcnic_issue_cmd(adapter, &cmd);
3537        if (err)
3538                dev_err(&adapter->pdev->dev,
3539                        "failed to issue extend iSCSI minidump capability\n");
3540
3541        return err;
3542}
3543
3544int qlcnic_83xx_reg_test(struct qlcnic_adapter *adapter)
3545{
3546        u32 major, minor, sub;
3547
3548        major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR);
3549        minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR);
3550        sub = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB);
3551
3552        if (adapter->fw_version != QLCNIC_VERSION_CODE(major, minor, sub)) {
3553                dev_info(&adapter->pdev->dev, "%s: Reg test failed\n",
3554                         __func__);
3555                return 1;
3556        }
3557        return 0;
3558}
3559
3560inline int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *adapter)
3561{
3562        return (ARRAY_SIZE(qlcnic_83xx_ext_reg_tbl) *
3563                sizeof(*adapter->ahw->ext_reg_tbl)) +
3564                (ARRAY_SIZE(qlcnic_83xx_reg_tbl) *
3565                sizeof(*adapter->ahw->reg_tbl));
3566}
3567
3568int qlcnic_83xx_get_registers(struct qlcnic_adapter *adapter, u32 *regs_buff)
3569{
3570        int i, j = 0;
3571
3572        for (i = QLCNIC_DEV_INFO_SIZE + 1;
3573             j < ARRAY_SIZE(qlcnic_83xx_reg_tbl); i++, j++)
3574                regs_buff[i] = QLC_SHARED_REG_RD32(adapter, j);
3575
3576        for (j = 0; j < ARRAY_SIZE(qlcnic_83xx_ext_reg_tbl); j++)
3577                regs_buff[i++] = QLCRDX(adapter->ahw, j);
3578        return i;
3579}
3580
3581int qlcnic_83xx_interrupt_test(struct net_device *netdev)
3582{
3583        struct qlcnic_adapter *adapter = netdev_priv(netdev);
3584        struct qlcnic_hardware_context *ahw = adapter->ahw;
3585        struct qlcnic_cmd_args cmd;
3586        u8 val, drv_sds_rings = adapter->drv_sds_rings;
3587        u8 drv_tx_rings = adapter->drv_tx_rings;
3588        u32 data;
3589        u16 intrpt_id, id;
3590        int ret;
3591
3592        if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
3593                netdev_info(netdev, "Device is resetting\n");
3594                return -EBUSY;
3595        }
3596
3597        if (qlcnic_get_diag_lock(adapter)) {
3598                netdev_info(netdev, "Device in diagnostics mode\n");
3599                return -EBUSY;
3600        }
3601
3602        ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST,
3603                                         drv_sds_rings);
3604        if (ret)
3605                goto fail_diag_irq;
3606
3607        ahw->diag_cnt = 0;
3608        ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST);
3609        if (ret)
3610                goto fail_diag_irq;
3611
3612        if (adapter->flags & QLCNIC_MSIX_ENABLED)
3613                intrpt_id = ahw->intr_tbl[0].id;
3614        else
3615                intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
3616
3617        cmd.req.arg[1] = 1;
3618        cmd.req.arg[2] = intrpt_id;
3619        cmd.req.arg[3] = BIT_0;
3620
3621        ret = qlcnic_issue_cmd(adapter, &cmd);
3622        data = cmd.rsp.arg[2];
3623        id = LSW(data);
3624        val = LSB(MSW(data));
3625        if (id != intrpt_id)
3626                dev_info(&adapter->pdev->dev,
3627                         "Interrupt generated: 0x%x, requested:0x%x\n",
3628                         id, intrpt_id);
3629        if (val)
3630                dev_err(&adapter->pdev->dev,
3631                         "Interrupt test error: 0x%x\n", val);
3632        if (ret)
3633                goto done;
3634
3635        msleep(20);
3636        ret = !ahw->diag_cnt;
3637
3638done:
3639        qlcnic_free_mbx_args(&cmd);
3640        qlcnic_83xx_diag_free_res(netdev, drv_sds_rings);
3641
3642fail_diag_irq:
3643        adapter->drv_sds_rings = drv_sds_rings;
3644        adapter->drv_tx_rings = drv_tx_rings;
3645        qlcnic_release_diag_lock(adapter);
3646        return ret;
3647}
3648
3649void qlcnic_83xx_get_pauseparam(struct qlcnic_adapter *adapter,
3650                                struct ethtool_pauseparam *pause)
3651{
3652        struct qlcnic_hardware_context *ahw = adapter->ahw;
3653        int status = 0;
3654        u32 config;
3655
3656        status = qlcnic_83xx_get_port_config(adapter);
3657        if (status) {
3658                dev_err(&adapter->pdev->dev,
3659                        "%s: Get Pause Config failed\n", __func__);
3660                return;
3661        }
3662        config = ahw->port_config;
3663        if (config & QLC_83XX_CFG_STD_PAUSE) {
3664                switch (MSW(config)) {
3665                case QLC_83XX_TX_PAUSE:
3666                        pause->tx_pause = 1;
3667                        break;
3668                case QLC_83XX_RX_PAUSE:
3669                        pause->rx_pause = 1;
3670                        break;
3671                case QLC_83XX_TX_RX_PAUSE:
3672                default:
3673                        /* Backward compatibility for existing
3674                         * flash definitions
3675                         */
3676                        pause->tx_pause = 1;
3677                        pause->rx_pause = 1;
3678                }
3679        }
3680
3681        if (QLC_83XX_AUTONEG(config))
3682                pause->autoneg = 1;
3683}
3684
3685int qlcnic_83xx_set_pauseparam(struct qlcnic_adapter *adapter,
3686                               struct ethtool_pauseparam *pause)
3687{
3688        struct qlcnic_hardware_context *ahw = adapter->ahw;
3689        int status = 0;
3690        u32 config;
3691
3692        status = qlcnic_83xx_get_port_config(adapter);
3693        if (status) {
3694                dev_err(&adapter->pdev->dev,
3695                        "%s: Get Pause Config failed.\n", __func__);
3696                return status;
3697        }
3698        config = ahw->port_config;
3699
3700        if (ahw->port_type == QLCNIC_GBE) {
3701                if (pause->autoneg)
3702                        ahw->port_config |= QLC_83XX_ENABLE_AUTONEG;
3703                if (!pause->autoneg)
3704                        ahw->port_config &= ~QLC_83XX_ENABLE_AUTONEG;
3705        } else if ((ahw->port_type == QLCNIC_XGBE) && (pause->autoneg)) {
3706                return -EOPNOTSUPP;
3707        }
3708
3709        if (!(config & QLC_83XX_CFG_STD_PAUSE))
3710                ahw->port_config |= QLC_83XX_CFG_STD_PAUSE;
3711
3712        if (pause->rx_pause && pause->tx_pause) {
3713                ahw->port_config |= QLC_83XX_CFG_STD_TX_RX_PAUSE;
3714        } else if (pause->rx_pause && !pause->tx_pause) {
3715                ahw->port_config &= ~QLC_83XX_CFG_STD_TX_PAUSE;
3716                ahw->port_config |= QLC_83XX_CFG_STD_RX_PAUSE;
3717        } else if (pause->tx_pause && !pause->rx_pause) {
3718                ahw->port_config &= ~QLC_83XX_CFG_STD_RX_PAUSE;
3719                ahw->port_config |= QLC_83XX_CFG_STD_TX_PAUSE;
3720        } else if (!pause->rx_pause && !pause->tx_pause) {
3721                ahw->port_config &= ~(QLC_83XX_CFG_STD_TX_RX_PAUSE |
3722                                      QLC_83XX_CFG_STD_PAUSE);
3723        }
3724        status = qlcnic_83xx_set_port_config(adapter);
3725        if (status) {
3726                dev_err(&adapter->pdev->dev,
3727                        "%s: Set Pause Config failed.\n", __func__);
3728                ahw->port_config = config;
3729        }
3730        return status;
3731}
3732
3733static int qlcnic_83xx_read_flash_status_reg(struct qlcnic_adapter *adapter)
3734{
3735        int ret, err = 0;
3736        u32 temp;
3737
3738        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
3739                                     QLC_83XX_FLASH_OEM_READ_SIG);
3740        qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
3741                                     QLC_83XX_FLASH_READ_CTRL);
3742        ret = qlcnic_83xx_poll_flash_status_reg(adapter);
3743        if (ret)
3744                return -EIO;
3745
3746        temp = QLCRD32(adapter, QLC_83XX_FLASH_RDDATA, &err);
3747        if (err == -EIO)
3748                return err;
3749
3750        return temp & 0xFF;
3751}
3752
3753int qlcnic_83xx_flash_test(struct qlcnic_adapter *adapter)
3754{
3755        int status;
3756
3757        status = qlcnic_83xx_read_flash_status_reg(adapter);
3758        if (status == -EIO) {
3759                dev_info(&adapter->pdev->dev, "%s: EEPROM test failed.\n",
3760                         __func__);
3761                return 1;
3762        }
3763        return 0;
3764}
3765
3766static int qlcnic_83xx_shutdown(struct pci_dev *pdev)
3767{
3768        struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
3769        struct net_device *netdev = adapter->netdev;
3770        int retval;
3771
3772        netif_device_detach(netdev);
3773        qlcnic_cancel_idc_work(adapter);
3774
3775        if (netif_running(netdev))
3776                qlcnic_down(adapter, netdev);
3777
3778        qlcnic_83xx_disable_mbx_intr(adapter);
3779        cancel_delayed_work_sync(&adapter->idc_aen_work);
3780
3781        retval = pci_save_state(pdev);
3782        if (retval)
3783                return retval;
3784
3785        return 0;
3786}
3787
3788static int qlcnic_83xx_resume(struct qlcnic_adapter *adapter)
3789{
3790        struct qlcnic_hardware_context *ahw = adapter->ahw;
3791        struct qlc_83xx_idc *idc = &ahw->idc;
3792        int err = 0;
3793
3794        err = qlcnic_83xx_idc_init(adapter);
3795        if (err)
3796                return err;
3797
3798        if (ahw->nic_mode == QLCNIC_VNIC_MODE) {
3799                if (ahw->op_mode == QLCNIC_MGMT_FUNC) {
3800                        qlcnic_83xx_set_vnic_opmode(adapter);
3801                } else {
3802                        err = qlcnic_83xx_check_vnic_state(adapter);
3803                        if (err)
3804                                return err;
3805                }
3806        }
3807
3808        err = qlcnic_83xx_idc_reattach_driver(adapter);
3809        if (err)
3810                return err;
3811
3812        qlcnic_schedule_work(adapter, qlcnic_83xx_idc_poll_dev_state,
3813                             idc->delay);
3814        return err;
3815}
3816
3817void qlcnic_83xx_reinit_mbx_work(struct qlcnic_mailbox *mbx)
3818{
3819        reinit_completion(&mbx->completion);
3820        set_bit(QLC_83XX_MBX_READY, &mbx->status);
3821}
3822
3823void qlcnic_83xx_free_mailbox(struct qlcnic_mailbox *mbx)
3824{
3825        if (!mbx)
3826                return;
3827
3828        destroy_workqueue(mbx->work_q);
3829        kfree(mbx);
3830}
3831
3832static inline void
3833qlcnic_83xx_notify_cmd_completion(struct qlcnic_adapter *adapter,
3834                                  struct qlcnic_cmd_args *cmd)
3835{
3836        atomic_set(&cmd->rsp_status, QLC_83XX_MBX_RESPONSE_ARRIVED);
3837
3838        if (cmd->type == QLC_83XX_MBX_CMD_NO_WAIT) {
3839                qlcnic_free_mbx_args(cmd);
3840                kfree(cmd);
3841                return;
3842        }
3843        complete(&cmd->completion);
3844}
3845
3846static void qlcnic_83xx_flush_mbx_queue(struct qlcnic_adapter *adapter)
3847{
3848        struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
3849        struct list_head *head = &mbx->cmd_q;
3850        struct qlcnic_cmd_args *cmd = NULL;
3851
3852        spin_lock(&mbx->queue_lock);
3853
3854        while (!list_empty(head)) {
3855                cmd = list_entry(head->next, struct qlcnic_cmd_args, list);
3856                dev_info(&adapter->pdev->dev, "%s: Mailbox command 0x%x\n",
3857                         __func__, cmd->cmd_op);
3858                list_del(&cmd->list);
3859                mbx->num_cmds--;
3860                qlcnic_83xx_notify_cmd_completion(adapter, cmd);
3861        }
3862
3863        spin_unlock(&mbx->queue_lock);
3864}
3865
3866static int qlcnic_83xx_check_mbx_status(struct qlcnic_adapter *adapter)
3867{
3868        struct qlcnic_hardware_context *ahw = adapter->ahw;
3869        struct qlcnic_mailbox *mbx = ahw->mailbox;
3870        u32 host_mbx_ctrl;
3871
3872        if (!test_bit(QLC_83XX_MBX_READY, &mbx->status))
3873                return -EBUSY;
3874
3875        host_mbx_ctrl = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
3876        if (host_mbx_ctrl) {
3877                clear_bit(QLC_83XX_MBX_READY, &mbx->status);
3878                ahw->idc.collect_dump = 1;
3879                return -EIO;
3880        }
3881
3882        return 0;
3883}
3884
3885static inline void qlcnic_83xx_signal_mbx_cmd(struct qlcnic_adapter *adapter,
3886                                              u8 issue_cmd)
3887{
3888        if (issue_cmd)
3889                QLCWRX(adapter->ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER);
3890        else
3891                QLCWRX(adapter->ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
3892}
3893
3894static void qlcnic_83xx_dequeue_mbx_cmd(struct qlcnic_adapter *adapter,
3895                                        struct qlcnic_cmd_args *cmd)
3896{
3897        struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
3898
3899        spin_lock(&mbx->queue_lock);
3900
3901        list_del(&cmd->list);
3902        mbx->num_cmds--;
3903
3904        spin_unlock(&mbx->queue_lock);
3905
3906        qlcnic_83xx_notify_cmd_completion(adapter, cmd);
3907}
3908
3909static void qlcnic_83xx_encode_mbx_cmd(struct qlcnic_adapter *adapter,
3910                                       struct qlcnic_cmd_args *cmd)
3911{
3912        u32 mbx_cmd, fw_hal_version, hdr_size, total_size, tmp;
3913        struct qlcnic_hardware_context *ahw = adapter->ahw;
3914        int i, j;
3915
3916        if (cmd->op_type != QLC_83XX_MBX_POST_BC_OP) {
3917                mbx_cmd = cmd->req.arg[0];
3918                writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 0));
3919                for (i = 1; i < cmd->req.num; i++)
3920                        writel(cmd->req.arg[i], QLCNIC_MBX_HOST(ahw, i));
3921        } else {
3922                fw_hal_version = ahw->fw_hal_version;
3923                hdr_size = sizeof(struct qlcnic_bc_hdr) / sizeof(u32);
3924                total_size = cmd->pay_size + hdr_size;
3925                tmp = QLCNIC_CMD_BC_EVENT_SETUP | total_size << 16;
3926                mbx_cmd = tmp | fw_hal_version << 29;
3927                writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 0));
3928
3929                /* Back channel specific operations bits */
3930                mbx_cmd = 0x1 | 1 << 4;
3931
3932                if (qlcnic_sriov_pf_check(adapter))
3933                        mbx_cmd |= cmd->func_num << 5;
3934
3935                writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 1));
3936
3937                for (i = 2, j = 0; j < hdr_size; i++, j++)
3938                        writel(*(cmd->hdr++), QLCNIC_MBX_HOST(ahw, i));
3939                for (j = 0; j < cmd->pay_size; j++, i++)
3940                        writel(*(cmd->pay++), QLCNIC_MBX_HOST(ahw, i));
3941        }
3942}
3943
3944void qlcnic_83xx_detach_mailbox_work(struct qlcnic_adapter *adapter)
3945{
3946        struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
3947
3948        if (!mbx)
3949                return;
3950
3951        clear_bit(QLC_83XX_MBX_READY, &mbx->status);
3952        complete(&mbx->completion);
3953        cancel_work_sync(&mbx->work);
3954        flush_workqueue(mbx->work_q);
3955        qlcnic_83xx_flush_mbx_queue(adapter);
3956}
3957
3958static int qlcnic_83xx_enqueue_mbx_cmd(struct qlcnic_adapter *adapter,
3959                                       struct qlcnic_cmd_args *cmd,
3960                                       unsigned long *timeout)
3961{
3962        struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
3963
3964        if (test_bit(QLC_83XX_MBX_READY, &mbx->status)) {
3965                atomic_set(&cmd->rsp_status, QLC_83XX_MBX_RESPONSE_WAIT);
3966                init_completion(&cmd->completion);
3967                cmd->rsp_opcode = QLC_83XX_MBX_RESPONSE_UNKNOWN;
3968
3969                spin_lock(&mbx->queue_lock);
3970
3971                list_add_tail(&cmd->list, &mbx->cmd_q);
3972                mbx->num_cmds++;
3973                cmd->total_cmds = mbx->num_cmds;
3974                *timeout = cmd->total_cmds * QLC_83XX_MBX_TIMEOUT;
3975                queue_work(mbx->work_q, &mbx->work);
3976
3977                spin_unlock(&mbx->queue_lock);
3978
3979                return 0;
3980        }
3981
3982        return -EBUSY;
3983}
3984
3985static int qlcnic_83xx_check_mac_rcode(struct qlcnic_adapter *adapter,
3986                                       struct qlcnic_cmd_args *cmd)
3987{
3988        u8 mac_cmd_rcode;
3989        u32 fw_data;
3990
3991        if (cmd->cmd_op == QLCNIC_CMD_CONFIG_MAC_VLAN) {
3992                fw_data = readl(QLCNIC_MBX_FW(adapter->ahw, 2));
3993                mac_cmd_rcode = (u8)fw_data;
3994                if (mac_cmd_rcode == QLC_83XX_NO_NIC_RESOURCE ||
3995                    mac_cmd_rcode == QLC_83XX_MAC_PRESENT ||
3996                    mac_cmd_rcode == QLC_83XX_MAC_ABSENT) {
3997                        cmd->rsp_opcode = QLCNIC_RCODE_SUCCESS;
3998                        return QLCNIC_RCODE_SUCCESS;
3999                }
4000        }
4001
4002        return -EINVAL;
4003}
4004
4005static void qlcnic_83xx_decode_mbx_rsp(struct qlcnic_adapter *adapter,
4006                                       struct qlcnic_cmd_args *cmd)
4007{
4008        struct qlcnic_hardware_context *ahw = adapter->ahw;
4009        struct device *dev = &adapter->pdev->dev;
4010        u8 mbx_err_code;
4011        u32 fw_data;
4012
4013        fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
4014        mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
4015        qlcnic_83xx_get_mbx_data(adapter, cmd);
4016
4017        switch (mbx_err_code) {
4018        case QLCNIC_MBX_RSP_OK:
4019        case QLCNIC_MBX_PORT_RSP_OK:
4020                cmd->rsp_opcode = QLCNIC_RCODE_SUCCESS;
4021                break;
4022        default:
4023                if (!qlcnic_83xx_check_mac_rcode(adapter, cmd))
4024                        break;
4025
4026                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",
4027                        __func__, cmd->cmd_op, cmd->type, ahw->pci_func,
4028                        ahw->op_mode, mbx_err_code);
4029                cmd->rsp_opcode = QLC_83XX_MBX_RESPONSE_FAILED;
4030                qlcnic_dump_mbx(adapter, cmd);
4031        }
4032
4033        return;
4034}
4035
4036static inline void qlcnic_dump_mailbox_registers(struct qlcnic_adapter *adapter)
4037{
4038        struct qlcnic_hardware_context *ahw = adapter->ahw;
4039        u32 offset;
4040
4041        offset = QLCRDX(ahw, QLCNIC_DEF_INT_MASK);
4042        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",
4043                 readl(ahw->pci_base0 + offset),
4044                 QLCRDX(ahw, QLCNIC_MBX_INTR_ENBL),
4045                 QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL),
4046                 QLCRDX(ahw, QLCNIC_FW_MBX_CTRL));
4047}
4048
4049static void qlcnic_83xx_mailbox_worker(struct work_struct *work)
4050{
4051        struct qlcnic_mailbox *mbx = container_of(work, struct qlcnic_mailbox,
4052                                                  work);
4053        struct qlcnic_adapter *adapter = mbx->adapter;
4054        const struct qlcnic_mbx_ops *mbx_ops = mbx->ops;
4055        struct device *dev = &adapter->pdev->dev;
4056        struct list_head *head = &mbx->cmd_q;
4057        struct qlcnic_hardware_context *ahw;
4058        struct qlcnic_cmd_args *cmd = NULL;
4059        unsigned long flags;
4060
4061        ahw = adapter->ahw;
4062
4063        while (true) {
4064                if (qlcnic_83xx_check_mbx_status(adapter)) {
4065                        qlcnic_83xx_flush_mbx_queue(adapter);
4066                        return;
4067                }
4068
4069                spin_lock_irqsave(&mbx->aen_lock, flags);
4070                mbx->rsp_status = QLC_83XX_MBX_RESPONSE_WAIT;
4071                spin_unlock_irqrestore(&mbx->aen_lock, flags);
4072
4073                spin_lock(&mbx->queue_lock);
4074
4075                if (list_empty(head)) {
4076                        spin_unlock(&mbx->queue_lock);
4077                        return;
4078                }
4079                cmd = list_entry(head->next, struct qlcnic_cmd_args, list);
4080
4081                spin_unlock(&mbx->queue_lock);
4082
4083                mbx_ops->encode_cmd(adapter, cmd);
4084                mbx_ops->nofity_fw(adapter, QLC_83XX_MBX_REQUEST);
4085
4086                if (wait_for_completion_timeout(&mbx->completion,
4087                                                QLC_83XX_MBX_TIMEOUT)) {
4088                        mbx_ops->decode_resp(adapter, cmd);
4089                        mbx_ops->nofity_fw(adapter, QLC_83XX_MBX_COMPLETION);
4090                } else {
4091                        dev_err(dev, "%s: Mailbox command timeout, opcode=0x%x, cmd_type=0x%x, func=0x%x, op_mode=0x%x\n",
4092                                __func__, cmd->cmd_op, cmd->type, ahw->pci_func,
4093                                ahw->op_mode);
4094                        clear_bit(QLC_83XX_MBX_READY, &mbx->status);
4095                        qlcnic_dump_mailbox_registers(adapter);
4096                        qlcnic_83xx_get_mbx_data(adapter, cmd);
4097                        qlcnic_dump_mbx(adapter, cmd);
4098                        qlcnic_83xx_idc_request_reset(adapter,
4099                                                      QLCNIC_FORCE_FW_DUMP_KEY);
4100                        cmd->rsp_opcode = QLCNIC_RCODE_TIMEOUT;
4101                }
4102                mbx_ops->dequeue_cmd(adapter, cmd);
4103        }
4104}
4105
4106static const struct qlcnic_mbx_ops qlcnic_83xx_mbx_ops = {
4107        .enqueue_cmd    = qlcnic_83xx_enqueue_mbx_cmd,
4108        .dequeue_cmd    = qlcnic_83xx_dequeue_mbx_cmd,
4109        .decode_resp    = qlcnic_83xx_decode_mbx_rsp,
4110        .encode_cmd     = qlcnic_83xx_encode_mbx_cmd,
4111        .nofity_fw      = qlcnic_83xx_signal_mbx_cmd,
4112};
4113
4114int qlcnic_83xx_init_mailbox_work(struct qlcnic_adapter *adapter)
4115{
4116        struct qlcnic_hardware_context *ahw = adapter->ahw;
4117        struct qlcnic_mailbox *mbx;
4118
4119        ahw->mailbox = kzalloc(sizeof(*mbx), GFP_KERNEL);
4120        if (!ahw->mailbox)
4121                return -ENOMEM;
4122
4123        mbx = ahw->mailbox;
4124        mbx->ops = &qlcnic_83xx_mbx_ops;
4125        mbx->adapter = adapter;
4126
4127        spin_lock_init(&mbx->queue_lock);
4128        spin_lock_init(&mbx->aen_lock);
4129        INIT_LIST_HEAD(&mbx->cmd_q);
4130        init_completion(&mbx->completion);
4131
4132        mbx->work_q = create_singlethread_workqueue("qlcnic_mailbox");
4133        if (mbx->work_q == NULL) {
4134                kfree(mbx);
4135                return -ENOMEM;
4136        }
4137
4138        INIT_WORK(&mbx->work, qlcnic_83xx_mailbox_worker);
4139        set_bit(QLC_83XX_MBX_READY, &mbx->status);
4140        return 0;
4141}
4142
4143static pci_ers_result_t qlcnic_83xx_io_error_detected(struct pci_dev *pdev,
4144                                                      pci_channel_state_t state)
4145{
4146        struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
4147
4148        if (state == pci_channel_io_perm_failure)
4149                return PCI_ERS_RESULT_DISCONNECT;
4150
4151        if (state == pci_channel_io_normal)
4152                return PCI_ERS_RESULT_RECOVERED;
4153
4154        set_bit(__QLCNIC_AER, &adapter->state);
4155        set_bit(__QLCNIC_RESETTING, &adapter->state);
4156
4157        qlcnic_83xx_aer_stop_poll_work(adapter);
4158
4159        pci_save_state(pdev);
4160        pci_disable_device(pdev);
4161
4162        return PCI_ERS_RESULT_NEED_RESET;
4163}
4164
4165static pci_ers_result_t qlcnic_83xx_io_slot_reset(struct pci_dev *pdev)
4166{
4167        struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
4168        int err = 0;
4169
4170        pdev->error_state = pci_channel_io_normal;
4171        err = pci_enable_device(pdev);
4172        if (err)
4173                goto disconnect;
4174
4175        pci_set_power_state(pdev, PCI_D0);
4176        pci_set_master(pdev);
4177        pci_restore_state(pdev);
4178
4179        err = qlcnic_83xx_aer_reset(adapter);
4180        if (err == 0)
4181                return PCI_ERS_RESULT_RECOVERED;
4182disconnect:
4183        clear_bit(__QLCNIC_AER, &adapter->state);
4184        clear_bit(__QLCNIC_RESETTING, &adapter->state);
4185        return PCI_ERS_RESULT_DISCONNECT;
4186}
4187
4188static void qlcnic_83xx_io_resume(struct pci_dev *pdev)
4189{
4190        struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
4191
4192        pci_cleanup_aer_uncorrect_error_status(pdev);
4193        if (test_and_clear_bit(__QLCNIC_AER, &adapter->state))
4194                qlcnic_83xx_aer_start_poll_work(adapter);
4195}
4196