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