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