1aa43c215SJeff Kirsher /* 2aa43c215SJeff Kirsher * QLogic qlcnic NIC Driver 3577ae39dSJitendra Kalsaria * Copyright (c) 2009-2013 QLogic Corporation 4aa43c215SJeff Kirsher * 5aa43c215SJeff Kirsher * See LICENSE.qlcnic for copyright and licensing details. 6aa43c215SJeff Kirsher */ 7aa43c215SJeff Kirsher 8aa43c215SJeff Kirsher #include <linux/vmalloc.h> 9aa43c215SJeff Kirsher #include <linux/interrupt.h> 10aa43c215SJeff Kirsher #include <linux/swab.h> 11aa43c215SJeff Kirsher #include <linux/dma-mapping.h> 1213159183SSony Chacko #include <linux/if_vlan.h> 13aa43c215SJeff Kirsher #include <net/ip.h> 14aa43c215SJeff Kirsher #include <linux/ipv6.h> 15aa43c215SJeff Kirsher #include <linux/inetdevice.h> 16aa43c215SJeff Kirsher #include <linux/aer.h> 17aa43c215SJeff Kirsher #include <linux/log2.h> 1847caf255SStephen Rothwell #include <linux/pci.h> 192b3d7b75SShahed Shaikh #include <net/vxlan.h> 20aa43c215SJeff Kirsher 21a930a463SHarish Patil #include "qlcnic.h" 22a930a463SHarish Patil #include "qlcnic_sriov.h" 23a930a463SHarish Patil #include "qlcnic_hw.h" 24a930a463SHarish Patil 25aa43c215SJeff Kirsher MODULE_DESCRIPTION("QLogic 1/10 GbE Converged/Intelligent Ethernet Driver"); 26aa43c215SJeff Kirsher MODULE_LICENSE("GPL"); 27aa43c215SJeff Kirsher MODULE_VERSION(QLCNIC_LINUX_VERSIONID); 28aa43c215SJeff Kirsher MODULE_FIRMWARE(QLCNIC_UNIFIED_ROMIMAGE_NAME); 29aa43c215SJeff Kirsher 30aa43c215SJeff Kirsher char qlcnic_driver_name[] = "qlcnic"; 31aa43c215SJeff Kirsher static const char qlcnic_driver_string[] = "QLogic 1/10 GbE " 32aa43c215SJeff Kirsher "Converged/Intelligent Ethernet Driver v" QLCNIC_LINUX_VERSIONID; 33aa43c215SJeff Kirsher 34aa43c215SJeff Kirsher static int qlcnic_mac_learn; 35aa43c215SJeff Kirsher module_param(qlcnic_mac_learn, int, 0444); 36fe1adc6bSJitendra Kalsaria MODULE_PARM_DESC(qlcnic_mac_learn, 37fe1adc6bSJitendra Kalsaria "Mac Filter (0=learning is disabled, 1=Driver learning is enabled, 2=FDB learning is enabled)"); 38aa43c215SJeff Kirsher 39629263acSSony Chacko int qlcnic_use_msi = 1; 409fd13331SHimanshu Madhani MODULE_PARM_DESC(use_msi, "MSI interrupt (0=disabled, 1=enabled)"); 41099f7aa7SSony Chacko module_param_named(use_msi, qlcnic_use_msi, int, 0444); 42aa43c215SJeff Kirsher 43629263acSSony Chacko int qlcnic_use_msi_x = 1; 449fd13331SHimanshu Madhani MODULE_PARM_DESC(use_msi_x, "MSI-X interrupt (0=disabled, 1=enabled)"); 45099f7aa7SSony Chacko module_param_named(use_msi_x, qlcnic_use_msi_x, int, 0444); 46aa43c215SJeff Kirsher 47629263acSSony Chacko int qlcnic_auto_fw_reset = 1; 489fd13331SHimanshu Madhani MODULE_PARM_DESC(auto_fw_reset, "Auto firmware reset (0=disabled, 1=enabled)"); 49099f7aa7SSony Chacko module_param_named(auto_fw_reset, qlcnic_auto_fw_reset, int, 0644); 50aa43c215SJeff Kirsher 51629263acSSony Chacko int qlcnic_load_fw_file; 523ced0a88SShahed Shaikh MODULE_PARM_DESC(load_fw_file, "Load firmware from (0=flash, 1=file, 2=POST in fast mode, 3= POST in medium mode, 4=POST in slow mode)"); 53099f7aa7SSony Chacko module_param_named(load_fw_file, qlcnic_load_fw_file, int, 0444); 54aa43c215SJeff Kirsher 551dd06ae8SGreg Kroah-Hartman static int qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent); 566bb58bb0SBill Pemberton static void qlcnic_remove(struct pci_dev *pdev); 57aa43c215SJeff Kirsher static int qlcnic_open(struct net_device *netdev); 58aa43c215SJeff Kirsher static int qlcnic_close(struct net_device *netdev); 59aa43c215SJeff Kirsher static void qlcnic_tx_timeout(struct net_device *netdev); 60aa43c215SJeff Kirsher static void qlcnic_attach_work(struct work_struct *work); 61aa43c215SJeff Kirsher static void qlcnic_fwinit_work(struct work_struct *work); 62aa43c215SJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 63aa43c215SJeff Kirsher static void qlcnic_poll_controller(struct net_device *netdev); 64aa43c215SJeff Kirsher #endif 65aa43c215SJeff Kirsher 66aa43c215SJeff Kirsher static void qlcnic_idc_debug_info(struct qlcnic_adapter *adapter, u8 encoding); 67aa43c215SJeff Kirsher static int qlcnic_can_start_firmware(struct qlcnic_adapter *adapter); 68aa43c215SJeff Kirsher 69aa43c215SJeff Kirsher static irqreturn_t qlcnic_tmp_intr(int irq, void *data); 70aa43c215SJeff Kirsher static irqreturn_t qlcnic_intr(int irq, void *data); 71aa43c215SJeff Kirsher static irqreturn_t qlcnic_msi_intr(int irq, void *data); 72aa43c215SJeff Kirsher static irqreturn_t qlcnic_msix_intr(int irq, void *data); 7313159183SSony Chacko static irqreturn_t qlcnic_msix_tx_intr(int irq, void *data); 74aa43c215SJeff Kirsher 75aa43c215SJeff Kirsher static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev); 76aa43c215SJeff Kirsher static int qlcnic_start_firmware(struct qlcnic_adapter *); 77aa43c215SJeff Kirsher 78aa43c215SJeff Kirsher static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter); 79aa43c215SJeff Kirsher static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *); 80aa43c215SJeff Kirsher static int qlcnicvf_start_firmware(struct qlcnic_adapter *); 8180d5c368SPatrick McHardy static int qlcnic_vlan_rx_add(struct net_device *, __be16, u16); 8280d5c368SPatrick McHardy static int qlcnic_vlan_rx_del(struct net_device *, __be16, u16); 83aa43c215SJeff Kirsher 8421041400Sstephen hemminger static int qlcnic_82xx_setup_intr(struct qlcnic_adapter *); 8521041400Sstephen hemminger static void qlcnic_82xx_dev_request_reset(struct qlcnic_adapter *, u32); 8621041400Sstephen hemminger static irqreturn_t qlcnic_82xx_clear_legacy_intr(struct qlcnic_adapter *); 8721041400Sstephen hemminger static pci_ers_result_t qlcnic_82xx_io_slot_reset(struct pci_dev *); 8821041400Sstephen hemminger static int qlcnic_82xx_start_firmware(struct qlcnic_adapter *); 8921041400Sstephen hemminger static void qlcnic_82xx_io_resume(struct pci_dev *); 9021041400Sstephen hemminger static void qlcnic_82xx_set_mac_filter_count(struct qlcnic_adapter *); 9121041400Sstephen hemminger static pci_ers_result_t qlcnic_82xx_io_error_detected(struct pci_dev *, 9221041400Sstephen hemminger pci_channel_state_t); 9313159183SSony Chacko static u32 qlcnic_vlan_tx_check(struct qlcnic_adapter *adapter) 9413159183SSony Chacko { 9513159183SSony Chacko struct qlcnic_hardware_context *ahw = adapter->ahw; 9613159183SSony Chacko 9713159183SSony Chacko if (adapter->pdev->device == PCI_DEVICE_ID_QLOGIC_QLE824X) 9813159183SSony Chacko return ahw->capabilities & QLCNIC_FW_CAPABILITY_FVLANTX; 9913159183SSony Chacko else 10013159183SSony Chacko return 1; 10113159183SSony Chacko } 10213159183SSony Chacko 103aa43c215SJeff Kirsher /* PCI Device ID Table */ 104aa43c215SJeff Kirsher #define ENTRY(device) \ 105aa43c215SJeff Kirsher {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \ 106aa43c215SJeff Kirsher .class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0} 107aa43c215SJeff Kirsher 1089baa3c34SBenoit Taine static const struct pci_device_id qlcnic_pci_tbl[] = { 109aa43c215SJeff Kirsher ENTRY(PCI_DEVICE_ID_QLOGIC_QLE824X), 11013159183SSony Chacko ENTRY(PCI_DEVICE_ID_QLOGIC_QLE834X), 111f8468331SRajesh Borundia ENTRY(PCI_DEVICE_ID_QLOGIC_VF_QLE834X), 112da286a6fSShahed Shaikh ENTRY(PCI_DEVICE_ID_QLOGIC_QLE8830), 113da286a6fSShahed Shaikh ENTRY(PCI_DEVICE_ID_QLOGIC_VF_QLE8C30), 11415ca140fSManish Chopra ENTRY(PCI_DEVICE_ID_QLOGIC_QLE844X), 11515ca140fSManish Chopra ENTRY(PCI_DEVICE_ID_QLOGIC_VF_QLE844X), 116aa43c215SJeff Kirsher {0,} 117aa43c215SJeff Kirsher }; 118aa43c215SJeff Kirsher 119aa43c215SJeff Kirsher MODULE_DEVICE_TABLE(pci, qlcnic_pci_tbl); 120aa43c215SJeff Kirsher 121aa43c215SJeff Kirsher 1225ad6ff9dSSony Chacko inline void qlcnic_update_cmd_producer(struct qlcnic_host_tx_ring *tx_ring) 123aa43c215SJeff Kirsher { 124aa43c215SJeff Kirsher writel(tx_ring->producer, tx_ring->crb_cmd_producer); 125aa43c215SJeff Kirsher } 126aa43c215SJeff Kirsher 127aa43c215SJeff Kirsher static const u32 msi_tgt_status[8] = { 128aa43c215SJeff Kirsher ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1, 129aa43c215SJeff Kirsher ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3, 130aa43c215SJeff Kirsher ISR_INT_TARGET_STATUS_F4, ISR_INT_TARGET_STATUS_F5, 131aa43c215SJeff Kirsher ISR_INT_TARGET_STATUS_F6, ISR_INT_TARGET_STATUS_F7 132aa43c215SJeff Kirsher }; 133aa43c215SJeff Kirsher 1347e2cf4feSSony Chacko static const u32 qlcnic_reg_tbl[] = { 1357e2cf4feSSony Chacko 0x1B20A8, /* PEG_HALT_STAT1 */ 1367e2cf4feSSony Chacko 0x1B20AC, /* PEG_HALT_STAT2 */ 1377e2cf4feSSony Chacko 0x1B20B0, /* FW_HEARTBEAT */ 1387e2cf4feSSony Chacko 0x1B2100, /* LOCK ID */ 1397e2cf4feSSony Chacko 0x1B2128, /* FW_CAPABILITIES */ 1407e2cf4feSSony Chacko 0x1B2138, /* drv active */ 1417e2cf4feSSony Chacko 0x1B2140, /* dev state */ 1427e2cf4feSSony Chacko 0x1B2144, /* drv state */ 1437e2cf4feSSony Chacko 0x1B2148, /* drv scratch */ 1447e2cf4feSSony Chacko 0x1B214C, /* dev partition info */ 1457e2cf4feSSony Chacko 0x1B2174, /* drv idc ver */ 1467e2cf4feSSony Chacko 0x1B2150, /* fw version major */ 1477e2cf4feSSony Chacko 0x1B2154, /* fw version minor */ 1487e2cf4feSSony Chacko 0x1B2158, /* fw version sub */ 1497e2cf4feSSony Chacko 0x1B219C, /* npar state */ 1507e2cf4feSSony Chacko 0x1B21FC, /* FW_IMG_VALID */ 1517e2cf4feSSony Chacko 0x1B2250, /* CMD_PEG_STATE */ 1527e2cf4feSSony Chacko 0x1B233C, /* RCV_PEG_STATE */ 1537e2cf4feSSony Chacko 0x1B23B4, /* ASIC TEMP */ 1547e2cf4feSSony Chacko 0x1B216C, /* FW api */ 1557e2cf4feSSony Chacko 0x1B2170, /* drv op mode */ 1567e2cf4feSSony Chacko 0x13C010, /* flash lock */ 1577e2cf4feSSony Chacko 0x13C014, /* flash unlock */ 1587e2cf4feSSony Chacko }; 1597e2cf4feSSony Chacko 16022999798SSony Chacko static const struct qlcnic_board_info qlcnic_boards[] = { 161e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 16215ca140fSManish Chopra PCI_DEVICE_ID_QLOGIC_QLE844X, 16315ca140fSManish Chopra 0x0, 16415ca140fSManish Chopra 0x0, 16515ca140fSManish Chopra "8400 series 10GbE Converged Network Adapter (TCP/IP Networking)" }, 16615ca140fSManish Chopra { PCI_VENDOR_ID_QLOGIC, 167e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 168e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 169e386cd4aSHimanshu Madhani 0x24e, 170e386cd4aSHimanshu Madhani "8300 Series Dual Port 10GbE Converged Network Adapter " 171e386cd4aSHimanshu Madhani "(TCP/IP Networking)" }, 172e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 173e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 174e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 175e386cd4aSHimanshu Madhani 0x243, 176e386cd4aSHimanshu Madhani "8300 Series Single Port 10GbE Converged Network Adapter " 177e386cd4aSHimanshu Madhani "(TCP/IP Networking)" }, 178e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 179e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 180e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 181e386cd4aSHimanshu Madhani 0x24a, 182e386cd4aSHimanshu Madhani "8300 Series Dual Port 10GbE Converged Network Adapter " 183e386cd4aSHimanshu Madhani "(TCP/IP Networking)" }, 184e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 185e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 186e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 187e386cd4aSHimanshu Madhani 0x246, 188e386cd4aSHimanshu Madhani "8300 Series Dual Port 10GbE Converged Network Adapter " 189e386cd4aSHimanshu Madhani "(TCP/IP Networking)" }, 190e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 191e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 192e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 193e386cd4aSHimanshu Madhani 0x252, 194e386cd4aSHimanshu Madhani "8300 Series Dual Port 10GbE Converged Network Adapter " 195e386cd4aSHimanshu Madhani "(TCP/IP Networking)" }, 196e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 197e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 198e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 199e386cd4aSHimanshu Madhani 0x26e, 200e386cd4aSHimanshu Madhani "8300 Series Dual Port 10GbE Converged Network Adapter " 201e386cd4aSHimanshu Madhani "(TCP/IP Networking)" }, 202e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 203e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 204e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 205e386cd4aSHimanshu Madhani 0x260, 206e386cd4aSHimanshu Madhani "8300 Series Dual Port 10GbE Converged Network Adapter " 207e386cd4aSHimanshu Madhani "(TCP/IP Networking)" }, 208e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 209e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 210e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 211e386cd4aSHimanshu Madhani 0x266, 212e386cd4aSHimanshu Madhani "8300 Series Single Port 10GbE Converged Network Adapter " 213e386cd4aSHimanshu Madhani "(TCP/IP Networking)" }, 214e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 215e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 216e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 217e386cd4aSHimanshu Madhani 0x269, 218e386cd4aSHimanshu Madhani "8300 Series Dual Port 10GbE Converged Network Adapter " 219e386cd4aSHimanshu Madhani "(TCP/IP Networking)" }, 220e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 221e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 222e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 223e386cd4aSHimanshu Madhani 0x271, 224e386cd4aSHimanshu Madhani "8300 Series Dual Port 10GbE Converged Network Adapter " 225e386cd4aSHimanshu Madhani "(TCP/IP Networking)" }, 226e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 227e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 228e386cd4aSHimanshu Madhani 0x0, 0x0, "8300 Series 1/10GbE Controller" }, 229e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 23040e2b8edSShahed Shaikh PCI_DEVICE_ID_QLOGIC_QLE8830, 23140e2b8edSShahed Shaikh 0x0, 23240e2b8edSShahed Shaikh 0x0, 23340e2b8edSShahed Shaikh "8830 Series 1/10GbE Controller" }, 23440e2b8edSShahed Shaikh { PCI_VENDOR_ID_QLOGIC, 235e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE824X, 236e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 237e386cd4aSHimanshu Madhani 0x203, 23822999798SSony Chacko "8200 Series Single Port 10GbE Converged Network Adapter" 23922999798SSony Chacko "(TCP/IP Networking)" }, 240e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 241e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE824X, 242e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 243e386cd4aSHimanshu Madhani 0x207, 24422999798SSony Chacko "8200 Series Dual Port 10GbE Converged Network Adapter" 24522999798SSony Chacko "(TCP/IP Networking)" }, 246e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 247e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE824X, 248e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 249e386cd4aSHimanshu Madhani 0x20b, 25022999798SSony Chacko "3200 Series Dual Port 10Gb Intelligent Ethernet Adapter" }, 251e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 252e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE824X, 253e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 254e386cd4aSHimanshu Madhani 0x20c, 25522999798SSony Chacko "3200 Series Quad Port 1Gb Intelligent Ethernet Adapter" }, 256e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 257e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE824X, 258e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 259e386cd4aSHimanshu Madhani 0x20f, 26022999798SSony Chacko "3200 Series Single Port 10Gb Intelligent Ethernet Adapter" }, 261e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 262e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE824X, 263e386cd4aSHimanshu Madhani 0x103c, 0x3733, 26422999798SSony Chacko "NC523SFP 10Gb 2-port Server Adapter" }, 265e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 266e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE824X, 267e386cd4aSHimanshu Madhani 0x103c, 0x3346, 26822999798SSony Chacko "CN1000Q Dual Port Converged Network Adapter" }, 269e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 270e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE824X, 271e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 272e386cd4aSHimanshu Madhani 0x210, 27322999798SSony Chacko "QME8242-k 10GbE Dual Port Mezzanine Card" }, 274e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 275e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE824X, 276e386cd4aSHimanshu Madhani 0x0, 0x0, "cLOM8214 1/10GbE Controller" }, 27722999798SSony Chacko }; 27822999798SSony Chacko 27922999798SSony Chacko #define NUM_SUPPORTED_BOARDS ARRAY_SIZE(qlcnic_boards) 28022999798SSony Chacko 281aa43c215SJeff Kirsher static const 282aa43c215SJeff Kirsher struct qlcnic_legacy_intr_set legacy_intr[] = QLCNIC_LEGACY_INTR_CONFIG; 283aa43c215SJeff Kirsher 284c70001a9SSony Chacko int qlcnic_alloc_sds_rings(struct qlcnic_recv_context *recv_ctx, int count) 285aa43c215SJeff Kirsher { 286aa43c215SJeff Kirsher int size = sizeof(struct qlcnic_host_sds_ring) * count; 287aa43c215SJeff Kirsher 288aa43c215SJeff Kirsher recv_ctx->sds_rings = kzalloc(size, GFP_KERNEL); 289aa43c215SJeff Kirsher 290aa43c215SJeff Kirsher return recv_ctx->sds_rings == NULL; 291aa43c215SJeff Kirsher } 292aa43c215SJeff Kirsher 293c70001a9SSony Chacko void qlcnic_free_sds_rings(struct qlcnic_recv_context *recv_ctx) 294aa43c215SJeff Kirsher { 295aa43c215SJeff Kirsher kfree(recv_ctx->sds_rings); 296aa43c215SJeff Kirsher recv_ctx->sds_rings = NULL; 297aa43c215SJeff Kirsher } 298aa43c215SJeff Kirsher 299f8468331SRajesh Borundia int qlcnic_read_mac_addr(struct qlcnic_adapter *adapter) 300aa43c215SJeff Kirsher { 301aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 302aa43c215SJeff Kirsher struct pci_dev *pdev = adapter->pdev; 30307a251c8SShahed Shaikh u8 mac_addr[ETH_ALEN]; 30407a251c8SShahed Shaikh int ret; 305aa43c215SJeff Kirsher 30607a251c8SShahed Shaikh ret = qlcnic_get_mac_address(adapter, mac_addr, 30707a251c8SShahed Shaikh adapter->ahw->pci_func); 30807a251c8SShahed Shaikh if (ret) 30907a251c8SShahed Shaikh return ret; 310aa43c215SJeff Kirsher 311aa43c215SJeff Kirsher memcpy(netdev->dev_addr, mac_addr, ETH_ALEN); 312aa43c215SJeff Kirsher memcpy(adapter->mac_addr, netdev->dev_addr, netdev->addr_len); 313aa43c215SJeff Kirsher 314aa43c215SJeff Kirsher /* set station address */ 315aa43c215SJeff Kirsher 316aaeb6cdfSJiri Pirko if (!is_valid_ether_addr(netdev->dev_addr)) 317aa43c215SJeff Kirsher dev_warn(&pdev->dev, "Bad MAC address %pM.\n", 318aa43c215SJeff Kirsher netdev->dev_addr); 319aa43c215SJeff Kirsher 320aa43c215SJeff Kirsher return 0; 321aa43c215SJeff Kirsher } 322aa43c215SJeff Kirsher 323cffe52f3SManish Chopra static void qlcnic_delete_adapter_mac(struct qlcnic_adapter *adapter) 324cffe52f3SManish Chopra { 325154d0c81SManish Chopra struct qlcnic_mac_vlan_list *cur; 326cffe52f3SManish Chopra struct list_head *head; 327cffe52f3SManish Chopra 328cffe52f3SManish Chopra list_for_each(head, &adapter->mac_list) { 329154d0c81SManish Chopra cur = list_entry(head, struct qlcnic_mac_vlan_list, list); 3306878f79aSdingtianhong if (ether_addr_equal_unaligned(adapter->mac_addr, cur->mac_addr)) { 331cffe52f3SManish Chopra qlcnic_sre_macaddr_change(adapter, cur->mac_addr, 332cffe52f3SManish Chopra 0, QLCNIC_MAC_DEL); 333cffe52f3SManish Chopra list_del(&cur->list); 334cffe52f3SManish Chopra kfree(cur); 335cffe52f3SManish Chopra return; 336cffe52f3SManish Chopra } 337cffe52f3SManish Chopra } 338cffe52f3SManish Chopra } 339cffe52f3SManish Chopra 340aa43c215SJeff Kirsher static int qlcnic_set_mac(struct net_device *netdev, void *p) 341aa43c215SJeff Kirsher { 342aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 343aa43c215SJeff Kirsher struct sockaddr *addr = p; 344aa43c215SJeff Kirsher 3457cb03b23SRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) 3467cb03b23SRajesh Borundia return -EINVAL; 3477cb03b23SRajesh Borundia 348aa43c215SJeff Kirsher if ((adapter->flags & QLCNIC_MAC_OVERRIDE_DISABLED)) 349aa43c215SJeff Kirsher return -EOPNOTSUPP; 350aa43c215SJeff Kirsher 351aa43c215SJeff Kirsher if (!is_valid_ether_addr(addr->sa_data)) 35213159183SSony Chacko return -EINVAL; 353aa43c215SJeff Kirsher 354e824de8aSJarod Wilson if (ether_addr_equal_unaligned(adapter->mac_addr, addr->sa_data) && 355e824de8aSJarod Wilson ether_addr_equal_unaligned(netdev->dev_addr, addr->sa_data)) 356cffe52f3SManish Chopra return 0; 357cffe52f3SManish Chopra 358aa43c215SJeff Kirsher if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) { 359aa43c215SJeff Kirsher netif_device_detach(netdev); 360aa43c215SJeff Kirsher qlcnic_napi_disable(adapter); 361aa43c215SJeff Kirsher } 362aa43c215SJeff Kirsher 363cffe52f3SManish Chopra qlcnic_delete_adapter_mac(adapter); 364aa43c215SJeff Kirsher memcpy(adapter->mac_addr, addr->sa_data, netdev->addr_len); 365aa43c215SJeff Kirsher memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); 366aa43c215SJeff Kirsher qlcnic_set_multi(adapter->netdev); 367aa43c215SJeff Kirsher 368aa43c215SJeff Kirsher if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) { 369aa43c215SJeff Kirsher netif_device_attach(netdev); 370aa43c215SJeff Kirsher qlcnic_napi_enable(adapter); 371aa43c215SJeff Kirsher } 372aa43c215SJeff Kirsher return 0; 373aa43c215SJeff Kirsher } 374aa43c215SJeff Kirsher 3751690be63SVlad Yasevich static int qlcnic_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], 376f6f6424bSJiri Pirko struct net_device *netdev, 377f6f6424bSJiri Pirko const unsigned char *addr, u16 vid) 378fe1adc6bSJitendra Kalsaria { 379fe1adc6bSJitendra Kalsaria struct qlcnic_adapter *adapter = netdev_priv(netdev); 380fe1adc6bSJitendra Kalsaria int err = -EOPNOTSUPP; 381fe1adc6bSJitendra Kalsaria 3823e5c112fSVlad Yasevich if (!adapter->fdb_mac_learn) 383f6f6424bSJiri Pirko return ndo_dflt_fdb_del(ndm, tb, netdev, addr, vid); 384fe1adc6bSJitendra Kalsaria 385d747c333SRajesh Borundia if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) || 386d747c333SRajesh Borundia qlcnic_sriov_check(adapter)) { 38752e493d0SJitendra Kalsaria if (is_unicast_ether_addr(addr)) { 38852e493d0SJitendra Kalsaria err = dev_uc_del(netdev, addr); 38952e493d0SJitendra Kalsaria if (!err) 390fe1adc6bSJitendra Kalsaria err = qlcnic_nic_del_mac(adapter, addr); 39152e493d0SJitendra Kalsaria } else if (is_multicast_ether_addr(addr)) { 392fe1adc6bSJitendra Kalsaria err = dev_mc_del(netdev, addr); 39352e493d0SJitendra Kalsaria } else { 394fe1adc6bSJitendra Kalsaria err = -EINVAL; 395fe1adc6bSJitendra Kalsaria } 39652e493d0SJitendra Kalsaria } 397fe1adc6bSJitendra Kalsaria return err; 398fe1adc6bSJitendra Kalsaria } 399fe1adc6bSJitendra Kalsaria 400fe1adc6bSJitendra Kalsaria static int qlcnic_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], 401fe1adc6bSJitendra Kalsaria struct net_device *netdev, 402f6f6424bSJiri Pirko const unsigned char *addr, u16 vid, u16 flags) 403fe1adc6bSJitendra Kalsaria { 404fe1adc6bSJitendra Kalsaria struct qlcnic_adapter *adapter = netdev_priv(netdev); 405fe1adc6bSJitendra Kalsaria int err = 0; 406fe1adc6bSJitendra Kalsaria 4073e5c112fSVlad Yasevich if (!adapter->fdb_mac_learn) 408f6f6424bSJiri Pirko return ndo_dflt_fdb_add(ndm, tb, netdev, addr, vid, flags); 409fe1adc6bSJitendra Kalsaria 410d747c333SRajesh Borundia if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) && 411d747c333SRajesh Borundia !qlcnic_sriov_check(adapter)) { 412fe1adc6bSJitendra Kalsaria pr_info("%s: FDB e-switch is not enabled\n", __func__); 413fe1adc6bSJitendra Kalsaria return -EOPNOTSUPP; 414fe1adc6bSJitendra Kalsaria } 415fe1adc6bSJitendra Kalsaria 416fe1adc6bSJitendra Kalsaria if (ether_addr_equal(addr, adapter->mac_addr)) 417fe1adc6bSJitendra Kalsaria return err; 418fe1adc6bSJitendra Kalsaria 41952e493d0SJitendra Kalsaria if (is_unicast_ether_addr(addr)) { 42052e493d0SJitendra Kalsaria if (netdev_uc_count(netdev) < adapter->ahw->max_uc_count) 42152e493d0SJitendra Kalsaria err = dev_uc_add_excl(netdev, addr); 422fe1adc6bSJitendra Kalsaria else 42352e493d0SJitendra Kalsaria err = -ENOMEM; 42452e493d0SJitendra Kalsaria } else if (is_multicast_ether_addr(addr)) { 42552e493d0SJitendra Kalsaria err = dev_mc_add_excl(netdev, addr); 42652e493d0SJitendra Kalsaria } else { 427fe1adc6bSJitendra Kalsaria err = -EINVAL; 42852e493d0SJitendra Kalsaria } 429fe1adc6bSJitendra Kalsaria 430fe1adc6bSJitendra Kalsaria return err; 431fe1adc6bSJitendra Kalsaria } 432fe1adc6bSJitendra Kalsaria 433fe1adc6bSJitendra Kalsaria static int qlcnic_fdb_dump(struct sk_buff *skb, struct netlink_callback *ncb, 4345d5eacb3SJamal Hadi Salim struct net_device *netdev, 435d297653dSRoopa Prabhu struct net_device *filter_dev, int *idx) 436fe1adc6bSJitendra Kalsaria { 437fe1adc6bSJitendra Kalsaria struct qlcnic_adapter *adapter = netdev_priv(netdev); 438d297653dSRoopa Prabhu int err = 0; 439fe1adc6bSJitendra Kalsaria 4403e5c112fSVlad Yasevich if (!adapter->fdb_mac_learn) 4415d5eacb3SJamal Hadi Salim return ndo_dflt_fdb_dump(skb, ncb, netdev, filter_dev, idx); 442fe1adc6bSJitendra Kalsaria 443d747c333SRajesh Borundia if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) || 444d747c333SRajesh Borundia qlcnic_sriov_check(adapter)) 445d297653dSRoopa Prabhu err = ndo_dflt_fdb_dump(skb, ncb, netdev, filter_dev, idx); 446fe1adc6bSJitendra Kalsaria 447d297653dSRoopa Prabhu return err; 448fe1adc6bSJitendra Kalsaria } 449fe1adc6bSJitendra Kalsaria 4507e2cf4feSSony Chacko static void qlcnic_82xx_cancel_idc_work(struct qlcnic_adapter *adapter) 4517e2cf4feSSony Chacko { 4527e2cf4feSSony Chacko while (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) 4537e2cf4feSSony Chacko usleep_range(10000, 11000); 4547e2cf4feSSony Chacko 45566451615SSucheta Chakraborty if (!adapter->fw_work.work.func) 45666451615SSucheta Chakraborty return; 45766451615SSucheta Chakraborty 4587e2cf4feSSony Chacko cancel_delayed_work_sync(&adapter->fw_work); 4597e2cf4feSSony Chacko } 4607e2cf4feSSony Chacko 46107a251c8SShahed Shaikh static int qlcnic_get_phys_port_id(struct net_device *netdev, 46202637fceSJiri Pirko struct netdev_phys_item_id *ppid) 46307a251c8SShahed Shaikh { 46407a251c8SShahed Shaikh struct qlcnic_adapter *adapter = netdev_priv(netdev); 46507a251c8SShahed Shaikh struct qlcnic_hardware_context *ahw = adapter->ahw; 46607a251c8SShahed Shaikh 46707a251c8SShahed Shaikh if (!(adapter->flags & QLCNIC_HAS_PHYS_PORT_ID)) 46807a251c8SShahed Shaikh return -EOPNOTSUPP; 46907a251c8SShahed Shaikh 47007a251c8SShahed Shaikh ppid->id_len = sizeof(ahw->phys_port_id); 47107a251c8SShahed Shaikh memcpy(ppid->id, ahw->phys_port_id, ppid->id_len); 47207a251c8SShahed Shaikh 47307a251c8SShahed Shaikh return 0; 47407a251c8SShahed Shaikh } 47507a251c8SShahed Shaikh 4762b3d7b75SShahed Shaikh static void qlcnic_add_vxlan_port(struct net_device *netdev, 4775e44f8e2SAlexander Duyck struct udp_tunnel_info *ti) 4782b3d7b75SShahed Shaikh { 4792b3d7b75SShahed Shaikh struct qlcnic_adapter *adapter = netdev_priv(netdev); 4802b3d7b75SShahed Shaikh struct qlcnic_hardware_context *ahw = adapter->ahw; 4812b3d7b75SShahed Shaikh 4825e44f8e2SAlexander Duyck if (ti->type != UDP_TUNNEL_TYPE_VXLAN) 4835e44f8e2SAlexander Duyck return; 4845e44f8e2SAlexander Duyck 4852b3d7b75SShahed Shaikh /* Adapter supports only one VXLAN port. Use very first port 4862b3d7b75SShahed Shaikh * for enabling offload 4872b3d7b75SShahed Shaikh */ 488378fddc2SJiri Benc if (!qlcnic_encap_rx_offload(adapter)) 4892b3d7b75SShahed Shaikh return; 490378fddc2SJiri Benc if (!ahw->vxlan_port_count) { 491378fddc2SJiri Benc ahw->vxlan_port_count = 1; 4925e44f8e2SAlexander Duyck ahw->vxlan_port = ntohs(ti->port); 4932b3d7b75SShahed Shaikh adapter->flags |= QLCNIC_ADD_VXLAN_PORT; 494378fddc2SJiri Benc return; 495378fddc2SJiri Benc } 4965e44f8e2SAlexander Duyck if (ahw->vxlan_port == ntohs(ti->port)) 497378fddc2SJiri Benc ahw->vxlan_port_count++; 498378fddc2SJiri Benc 4992b3d7b75SShahed Shaikh } 5002b3d7b75SShahed Shaikh 5012b3d7b75SShahed Shaikh static void qlcnic_del_vxlan_port(struct net_device *netdev, 5025e44f8e2SAlexander Duyck struct udp_tunnel_info *ti) 5032b3d7b75SShahed Shaikh { 5042b3d7b75SShahed Shaikh struct qlcnic_adapter *adapter = netdev_priv(netdev); 5052b3d7b75SShahed Shaikh struct qlcnic_hardware_context *ahw = adapter->ahw; 5062b3d7b75SShahed Shaikh 5075e44f8e2SAlexander Duyck if (ti->type != UDP_TUNNEL_TYPE_VXLAN) 5085e44f8e2SAlexander Duyck return; 5095e44f8e2SAlexander Duyck 510378fddc2SJiri Benc if (!qlcnic_encap_rx_offload(adapter) || !ahw->vxlan_port_count || 5115e44f8e2SAlexander Duyck (ahw->vxlan_port != ntohs(ti->port))) 5122b3d7b75SShahed Shaikh return; 5132b3d7b75SShahed Shaikh 514378fddc2SJiri Benc ahw->vxlan_port_count--; 515378fddc2SJiri Benc if (!ahw->vxlan_port_count) 5162b3d7b75SShahed Shaikh adapter->flags |= QLCNIC_DEL_VXLAN_PORT; 5172b3d7b75SShahed Shaikh } 518795a05c1SJoe Stringer 5195f35227eSJesse Gross static netdev_features_t qlcnic_features_check(struct sk_buff *skb, 5205f35227eSJesse Gross struct net_device *dev, 5215f35227eSJesse Gross netdev_features_t features) 522795a05c1SJoe Stringer { 5238cb65d00SToshiaki Makita features = vlan_features_check(skb, features); 5245f35227eSJesse Gross return vxlan_features_check(skb, features); 525795a05c1SJoe Stringer } 5262b3d7b75SShahed Shaikh 527aa43c215SJeff Kirsher static const struct net_device_ops qlcnic_netdev_ops = { 528aa43c215SJeff Kirsher .ndo_open = qlcnic_open, 529aa43c215SJeff Kirsher .ndo_stop = qlcnic_close, 530aa43c215SJeff Kirsher .ndo_start_xmit = qlcnic_xmit_frame, 531aa43c215SJeff Kirsher .ndo_get_stats = qlcnic_get_stats, 532aa43c215SJeff Kirsher .ndo_validate_addr = eth_validate_addr, 533afc4b13dSJiri Pirko .ndo_set_rx_mode = qlcnic_set_multi, 534aa43c215SJeff Kirsher .ndo_set_mac_address = qlcnic_set_mac, 535aa43c215SJeff Kirsher .ndo_change_mtu = qlcnic_change_mtu, 536aa43c215SJeff Kirsher .ndo_fix_features = qlcnic_fix_features, 537aa43c215SJeff Kirsher .ndo_set_features = qlcnic_set_features, 538aa43c215SJeff Kirsher .ndo_tx_timeout = qlcnic_tx_timeout, 539aa43c215SJeff Kirsher .ndo_vlan_rx_add_vid = qlcnic_vlan_rx_add, 540aa43c215SJeff Kirsher .ndo_vlan_rx_kill_vid = qlcnic_vlan_rx_del, 541fe1adc6bSJitendra Kalsaria .ndo_fdb_add = qlcnic_fdb_add, 542fe1adc6bSJitendra Kalsaria .ndo_fdb_del = qlcnic_fdb_del, 543fe1adc6bSJitendra Kalsaria .ndo_fdb_dump = qlcnic_fdb_dump, 54407a251c8SShahed Shaikh .ndo_get_phys_port_id = qlcnic_get_phys_port_id, 5455e44f8e2SAlexander Duyck .ndo_udp_tunnel_add = qlcnic_add_vxlan_port, 5465e44f8e2SAlexander Duyck .ndo_udp_tunnel_del = qlcnic_del_vxlan_port, 5475f35227eSJesse Gross .ndo_features_check = qlcnic_features_check, 548aa43c215SJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 549aa43c215SJeff Kirsher .ndo_poll_controller = qlcnic_poll_controller, 550aa43c215SJeff Kirsher #endif 5514000e7a7SRajesh Borundia #ifdef CONFIG_QLCNIC_SRIOV 5524000e7a7SRajesh Borundia .ndo_set_vf_mac = qlcnic_sriov_set_vf_mac, 553ed616689SSucheta Chakraborty .ndo_set_vf_rate = qlcnic_sriov_set_vf_tx_rate, 5544000e7a7SRajesh Borundia .ndo_get_vf_config = qlcnic_sriov_get_vf_config, 55591b7282bSRajesh Borundia .ndo_set_vf_vlan = qlcnic_sriov_set_vf_vlan, 556a80be5a5SRajesh Borundia .ndo_set_vf_spoofchk = qlcnic_sriov_set_vf_spoofchk, 5574000e7a7SRajesh Borundia #endif 558aa43c215SJeff Kirsher }; 559aa43c215SJeff Kirsher 560b43e5ee7SSucheta Chakraborty static const struct net_device_ops qlcnic_netdev_failed_ops = { 561b43e5ee7SSucheta Chakraborty .ndo_open = qlcnic_open, 562b43e5ee7SSucheta Chakraborty }; 563b43e5ee7SSucheta Chakraborty 564aa43c215SJeff Kirsher static struct qlcnic_nic_template qlcnic_ops = { 565aa43c215SJeff Kirsher .config_bridged_mode = qlcnic_config_bridged_mode, 5667e2cf4feSSony Chacko .config_led = qlcnic_82xx_config_led, 5677e2cf4feSSony Chacko .start_firmware = qlcnic_82xx_start_firmware, 5687e2cf4feSSony Chacko .request_reset = qlcnic_82xx_dev_request_reset, 5697e2cf4feSSony Chacko .cancel_idc_work = qlcnic_82xx_cancel_idc_work, 5707e2cf4feSSony Chacko .napi_add = qlcnic_82xx_napi_add, 5714be41e92SSony Chacko .napi_del = qlcnic_82xx_napi_del, 5727e2cf4feSSony Chacko .config_ipaddr = qlcnic_82xx_config_ipaddr, 573486a5bc7SRajesh Borundia .shutdown = qlcnic_82xx_shutdown, 574486a5bc7SRajesh Borundia .resume = qlcnic_82xx_resume, 5757e2cf4feSSony Chacko .clear_legacy_intr = qlcnic_82xx_clear_legacy_intr, 576aa43c215SJeff Kirsher }; 577aa43c215SJeff Kirsher 5787e2cf4feSSony Chacko struct qlcnic_nic_template qlcnic_vf_ops = { 579aa43c215SJeff Kirsher .config_bridged_mode = qlcnicvf_config_bridged_mode, 580aa43c215SJeff Kirsher .config_led = qlcnicvf_config_led, 581aa43c215SJeff Kirsher .start_firmware = qlcnicvf_start_firmware 582aa43c215SJeff Kirsher }; 583aa43c215SJeff Kirsher 5847e2cf4feSSony Chacko static struct qlcnic_hardware_ops qlcnic_hw_ops = { 5857e2cf4feSSony Chacko .read_crb = qlcnic_82xx_read_crb, 5867e2cf4feSSony Chacko .write_crb = qlcnic_82xx_write_crb, 5877e2cf4feSSony Chacko .read_reg = qlcnic_82xx_hw_read_wx_2M, 5887e2cf4feSSony Chacko .write_reg = qlcnic_82xx_hw_write_wx_2M, 5897e2cf4feSSony Chacko .get_mac_address = qlcnic_82xx_get_mac_address, 5907e2cf4feSSony Chacko .setup_intr = qlcnic_82xx_setup_intr, 5917e2cf4feSSony Chacko .alloc_mbx_args = qlcnic_82xx_alloc_mbx_args, 5927e2cf4feSSony Chacko .mbx_cmd = qlcnic_82xx_issue_cmd, 5937e2cf4feSSony Chacko .get_func_no = qlcnic_82xx_get_func_no, 5947e2cf4feSSony Chacko .api_lock = qlcnic_82xx_api_lock, 5957e2cf4feSSony Chacko .api_unlock = qlcnic_82xx_api_unlock, 5967e2cf4feSSony Chacko .add_sysfs = qlcnic_82xx_add_sysfs, 5977e2cf4feSSony Chacko .remove_sysfs = qlcnic_82xx_remove_sysfs, 5987e2cf4feSSony Chacko .process_lb_rcv_ring_diag = qlcnic_82xx_process_rcv_ring_diag, 5997e2cf4feSSony Chacko .create_rx_ctx = qlcnic_82xx_fw_cmd_create_rx_ctx, 6007e2cf4feSSony Chacko .create_tx_ctx = qlcnic_82xx_fw_cmd_create_tx_ctx, 6017cb03b23SRajesh Borundia .del_rx_ctx = qlcnic_82xx_fw_cmd_del_rx_ctx, 6027cb03b23SRajesh Borundia .del_tx_ctx = qlcnic_82xx_fw_cmd_del_tx_ctx, 6037e2cf4feSSony Chacko .setup_link_event = qlcnic_82xx_linkevent_request, 6047e2cf4feSSony Chacko .get_nic_info = qlcnic_82xx_get_nic_info, 6057e2cf4feSSony Chacko .get_pci_info = qlcnic_82xx_get_pci_info, 6067e2cf4feSSony Chacko .set_nic_info = qlcnic_82xx_set_nic_info, 6077e2cf4feSSony Chacko .change_macvlan = qlcnic_82xx_sre_macaddr_change, 6087e2cf4feSSony Chacko .napi_enable = qlcnic_82xx_napi_enable, 6097e2cf4feSSony Chacko .napi_disable = qlcnic_82xx_napi_disable, 6107e2cf4feSSony Chacko .config_intr_coal = qlcnic_82xx_config_intr_coalesce, 6117e2cf4feSSony Chacko .config_rss = qlcnic_82xx_config_rss, 6127e2cf4feSSony Chacko .config_hw_lro = qlcnic_82xx_config_hw_lro, 6137e2cf4feSSony Chacko .config_loopback = qlcnic_82xx_set_lb_mode, 6147e2cf4feSSony Chacko .clear_loopback = qlcnic_82xx_clear_lb_mode, 6157e2cf4feSSony Chacko .config_promisc_mode = qlcnic_82xx_nic_set_promisc, 6167e2cf4feSSony Chacko .change_l2_filter = qlcnic_82xx_change_filter, 6177e2cf4feSSony Chacko .get_board_info = qlcnic_82xx_get_board_info, 61852e493d0SJitendra Kalsaria .set_mac_filter_count = qlcnic_82xx_set_mac_filter_count, 61991b7282bSRajesh Borundia .free_mac_list = qlcnic_82xx_free_mac_list, 62007a251c8SShahed Shaikh .read_phys_port_id = qlcnic_82xx_read_phys_port_id, 6214460f2e8SPratik Pujar .io_error_detected = qlcnic_82xx_io_error_detected, 6224460f2e8SPratik Pujar .io_slot_reset = qlcnic_82xx_io_slot_reset, 6234460f2e8SPratik Pujar .io_resume = qlcnic_82xx_io_resume, 624a0431589SHimanshu Madhani .get_beacon_state = qlcnic_82xx_get_beacon_state, 6252cc5752eSManish chopra .enable_sds_intr = qlcnic_82xx_enable_sds_intr, 6262cc5752eSManish chopra .disable_sds_intr = qlcnic_82xx_disable_sds_intr, 6272cc5752eSManish chopra .enable_tx_intr = qlcnic_82xx_enable_tx_intr, 6282cc5752eSManish chopra .disable_tx_intr = qlcnic_82xx_disable_tx_intr, 629225837a0SShahed Shaikh .get_saved_state = qlcnic_82xx_get_saved_state, 630225837a0SShahed Shaikh .set_saved_state = qlcnic_82xx_set_saved_state, 631225837a0SShahed Shaikh .cache_tmpl_hdr_values = qlcnic_82xx_cache_tmpl_hdr_values, 632225837a0SShahed Shaikh .get_cap_size = qlcnic_82xx_get_cap_size, 633225837a0SShahed Shaikh .set_sys_info = qlcnic_82xx_set_sys_info, 634225837a0SShahed Shaikh .store_cap_mask = qlcnic_82xx_store_cap_mask, 6354bd7ef0bSChopra, Manish .encap_rx_offload = qlcnic_82xx_encap_rx_offload, 6364bd7ef0bSChopra, Manish .encap_tx_offload = qlcnic_82xx_encap_tx_offload, 6377e2cf4feSSony Chacko }; 6387e2cf4feSSony Chacko 63934e8c406SHimanshu Madhani static int qlcnic_check_multi_tx_capability(struct qlcnic_adapter *adapter) 640012ec812SHimanshu Madhani { 641012ec812SHimanshu Madhani struct qlcnic_hardware_context *ahw = adapter->ahw; 642012ec812SHimanshu Madhani 64334e8c406SHimanshu Madhani if (qlcnic_82xx_check(adapter) && 644012ec812SHimanshu Madhani (ahw->extra_capability[0] & QLCNIC_FW_CAPABILITY_2_MULTI_TX)) { 64534e8c406SHimanshu Madhani test_and_set_bit(__QLCNIC_MULTI_TX_UNIQUE, &adapter->state); 64634e8c406SHimanshu Madhani return 0; 647012ec812SHimanshu Madhani } else { 64834e8c406SHimanshu Madhani return 1; 649012ec812SHimanshu Madhani } 650012ec812SHimanshu Madhani } 651012ec812SHimanshu Madhani 65234e8c406SHimanshu Madhani static int qlcnic_max_rings(struct qlcnic_adapter *adapter, u8 ring_cnt, 65334e8c406SHimanshu Madhani int queue_type) 65434e8c406SHimanshu Madhani { 65534e8c406SHimanshu Madhani int num_rings, max_rings = QLCNIC_MAX_SDS_RINGS; 65634e8c406SHimanshu Madhani 65734e8c406SHimanshu Madhani if (queue_type == QLCNIC_RX_QUEUE) 65834e8c406SHimanshu Madhani max_rings = adapter->max_sds_rings; 65934e8c406SHimanshu Madhani else if (queue_type == QLCNIC_TX_QUEUE) 66034e8c406SHimanshu Madhani max_rings = adapter->max_tx_rings; 66134e8c406SHimanshu Madhani 66234e8c406SHimanshu Madhani num_rings = rounddown_pow_of_two(min_t(int, num_online_cpus(), 66334e8c406SHimanshu Madhani max_rings)); 66434e8c406SHimanshu Madhani 66534e8c406SHimanshu Madhani if (ring_cnt > num_rings) 66634e8c406SHimanshu Madhani return num_rings; 66734e8c406SHimanshu Madhani else 66834e8c406SHimanshu Madhani return ring_cnt; 66934e8c406SHimanshu Madhani } 67034e8c406SHimanshu Madhani 67134e8c406SHimanshu Madhani void qlcnic_set_tx_ring_count(struct qlcnic_adapter *adapter, u8 tx_cnt) 67234e8c406SHimanshu Madhani { 67334e8c406SHimanshu Madhani /* 83xx adapter does not have max_tx_rings intialized in probe */ 67434e8c406SHimanshu Madhani if (adapter->max_tx_rings) 67534e8c406SHimanshu Madhani adapter->drv_tx_rings = qlcnic_max_rings(adapter, tx_cnt, 67634e8c406SHimanshu Madhani QLCNIC_TX_QUEUE); 67734e8c406SHimanshu Madhani else 67834e8c406SHimanshu Madhani adapter->drv_tx_rings = tx_cnt; 67934e8c406SHimanshu Madhani } 68034e8c406SHimanshu Madhani 68134e8c406SHimanshu Madhani void qlcnic_set_sds_ring_count(struct qlcnic_adapter *adapter, u8 rx_cnt) 68234e8c406SHimanshu Madhani { 68334e8c406SHimanshu Madhani /* 83xx adapter does not have max_sds_rings intialized in probe */ 68434e8c406SHimanshu Madhani if (adapter->max_sds_rings) 68534e8c406SHimanshu Madhani adapter->drv_sds_rings = qlcnic_max_rings(adapter, rx_cnt, 68634e8c406SHimanshu Madhani QLCNIC_RX_QUEUE); 68734e8c406SHimanshu Madhani else 68834e8c406SHimanshu Madhani adapter->drv_sds_rings = rx_cnt; 68934e8c406SHimanshu Madhani } 69034e8c406SHimanshu Madhani 691cb9327d5SHimanshu Madhani int qlcnic_setup_tss_rss_intr(struct qlcnic_adapter *adapter) 692aa43c215SJeff Kirsher { 693aa43c215SJeff Kirsher struct pci_dev *pdev = adapter->pdev; 694cb9327d5SHimanshu Madhani int num_msix = 0, err = 0, vector; 695da6c8063SRajesh Borundia 696cb9327d5SHimanshu Madhani adapter->flags &= ~QLCNIC_TSS_RSS; 697cb9327d5SHimanshu Madhani 698cb9327d5SHimanshu Madhani if (adapter->drv_tss_rings > 0) 699cb9327d5SHimanshu Madhani num_msix += adapter->drv_tss_rings; 700cb9327d5SHimanshu Madhani else 701cb9327d5SHimanshu Madhani num_msix += adapter->drv_tx_rings; 702cb9327d5SHimanshu Madhani 703cb9327d5SHimanshu Madhani if (adapter->drv_rss_rings > 0) 704cb9327d5SHimanshu Madhani num_msix += adapter->drv_rss_rings; 705cb9327d5SHimanshu Madhani else 706cb9327d5SHimanshu Madhani num_msix += adapter->drv_sds_rings; 707cb9327d5SHimanshu Madhani 708cb9327d5SHimanshu Madhani if (qlcnic_83xx_check(adapter)) 709cb9327d5SHimanshu Madhani num_msix += 1; 71013159183SSony Chacko 71113159183SSony Chacko if (!adapter->msix_entries) { 71213159183SSony Chacko adapter->msix_entries = kcalloc(num_msix, 71313159183SSony Chacko sizeof(struct msix_entry), 71413159183SSony Chacko GFP_KERNEL); 715b2adaca9SJoe Perches if (!adapter->msix_entries) 71613159183SSony Chacko return -ENOMEM; 71713159183SSony Chacko } 718aa43c215SJeff Kirsher 719cb9327d5SHimanshu Madhani for (vector = 0; vector < num_msix; vector++) 720cb9327d5SHimanshu Madhani adapter->msix_entries[vector].entry = vector; 721cb9327d5SHimanshu Madhani 7228564ae09SAlexander Gordeev restore: 723f7167750SAlexander Gordeev err = pci_enable_msix_exact(pdev, adapter->msix_entries, num_msix); 724f7167750SAlexander Gordeev if (err == -ENOSPC) { 7258564ae09SAlexander Gordeev if (!adapter->drv_tss_rings && !adapter->drv_rss_rings) 726f7167750SAlexander Gordeev return err; 727cb9327d5SHimanshu Madhani 728cb9327d5SHimanshu Madhani netdev_info(adapter->netdev, 729cb9327d5SHimanshu Madhani "Unable to allocate %d MSI-X vectors, Available vectors %d\n", 730cb9327d5SHimanshu Madhani num_msix, err); 731cb9327d5SHimanshu Madhani 732cb9327d5SHimanshu Madhani num_msix = adapter->drv_tx_rings + adapter->drv_sds_rings; 733cb9327d5SHimanshu Madhani 734cb9327d5SHimanshu Madhani /* Set rings to 0 so we can restore original TSS/RSS count */ 735cb9327d5SHimanshu Madhani adapter->drv_tss_rings = 0; 736cb9327d5SHimanshu Madhani adapter->drv_rss_rings = 0; 737cb9327d5SHimanshu Madhani 738cb9327d5SHimanshu Madhani if (qlcnic_83xx_check(adapter)) 739cb9327d5SHimanshu Madhani num_msix += 1; 740cb9327d5SHimanshu Madhani 741cb9327d5SHimanshu Madhani netdev_info(adapter->netdev, 742cb9327d5SHimanshu Madhani "Restoring %d Tx, %d SDS rings for total %d vectors.\n", 743cb9327d5SHimanshu Madhani adapter->drv_tx_rings, adapter->drv_sds_rings, 744cb9327d5SHimanshu Madhani num_msix); 745cb9327d5SHimanshu Madhani 7468564ae09SAlexander Gordeev goto restore; 7478564ae09SAlexander Gordeev } else if (err < 0) { 7488564ae09SAlexander Gordeev return err; 749cb9327d5SHimanshu Madhani } 750cb9327d5SHimanshu Madhani 7518564ae09SAlexander Gordeev adapter->ahw->num_msix = num_msix; 7528564ae09SAlexander Gordeev if (adapter->drv_tss_rings > 0) 7538564ae09SAlexander Gordeev adapter->drv_tx_rings = adapter->drv_tss_rings; 7548564ae09SAlexander Gordeev 7558564ae09SAlexander Gordeev if (adapter->drv_rss_rings > 0) 7568564ae09SAlexander Gordeev adapter->drv_sds_rings = adapter->drv_rss_rings; 7578564ae09SAlexander Gordeev 7588564ae09SAlexander Gordeev return 0; 759cb9327d5SHimanshu Madhani } 760cb9327d5SHimanshu Madhani 761cb9327d5SHimanshu Madhani int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) 762cb9327d5SHimanshu Madhani { 763cb9327d5SHimanshu Madhani struct pci_dev *pdev = adapter->pdev; 76474a1fa45SAlexander Gordeev int err, vector; 765cb9327d5SHimanshu Madhani 766cb9327d5SHimanshu Madhani if (!adapter->msix_entries) { 767cb9327d5SHimanshu Madhani adapter->msix_entries = kcalloc(num_msix, 768cb9327d5SHimanshu Madhani sizeof(struct msix_entry), 769cb9327d5SHimanshu Madhani GFP_KERNEL); 770cb9327d5SHimanshu Madhani if (!adapter->msix_entries) 771cb9327d5SHimanshu Madhani return -ENOMEM; 772cb9327d5SHimanshu Madhani } 773cb9327d5SHimanshu Madhani 774aa43c215SJeff Kirsher adapter->flags &= ~(QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED); 775aa43c215SJeff Kirsher 77679788450SSony Chacko if (adapter->ahw->msix_supported) { 777aa43c215SJeff Kirsher enable_msix: 778cb9327d5SHimanshu Madhani for (vector = 0; vector < num_msix; vector++) 779cb9327d5SHimanshu Madhani adapter->msix_entries[vector].entry = vector; 780cb9327d5SHimanshu Madhani 7819732ec06SAlexander Gordeev err = pci_enable_msix_range(pdev, 7829732ec06SAlexander Gordeev adapter->msix_entries, 1, num_msix); 7839732ec06SAlexander Gordeev 7849732ec06SAlexander Gordeev if (err == num_msix) { 785aa43c215SJeff Kirsher adapter->flags |= QLCNIC_MSIX_ENABLED; 78613159183SSony Chacko adapter->ahw->num_msix = num_msix; 787aa43c215SJeff Kirsher dev_info(&pdev->dev, "using msi-x interrupts\n"); 78874a1fa45SAlexander Gordeev return 0; 78913159183SSony Chacko } else if (err > 0) { 7909732ec06SAlexander Gordeev pci_disable_msix(pdev); 7919732ec06SAlexander Gordeev 79213159183SSony Chacko dev_info(&pdev->dev, 793cb9327d5SHimanshu Madhani "Unable to allocate %d MSI-X vectors, Available vectors %d\n", 794cb9327d5SHimanshu Madhani num_msix, err); 795cb9327d5SHimanshu Madhani 796cb9327d5SHimanshu Madhani if (qlcnic_82xx_check(adapter)) { 797aa43c215SJeff Kirsher num_msix = rounddown_pow_of_two(err); 798cb9327d5SHimanshu Madhani if (err < QLCNIC_82XX_MINIMUM_VECTOR) 79974a1fa45SAlexander Gordeev return -ENOSPC; 80013159183SSony Chacko } else { 801cb9327d5SHimanshu Madhani num_msix = rounddown_pow_of_two(err - 1); 802cb9327d5SHimanshu Madhani num_msix += 1; 803cb9327d5SHimanshu Madhani if (err < QLCNIC_83XX_MINIMUM_VECTOR) 80474a1fa45SAlexander Gordeev return -ENOSPC; 805cb9327d5SHimanshu Madhani } 806cb9327d5SHimanshu Madhani 807cb9327d5SHimanshu Madhani if (qlcnic_82xx_check(adapter) && 808cb9327d5SHimanshu Madhani !qlcnic_check_multi_tx(adapter)) { 809cb9327d5SHimanshu Madhani adapter->drv_sds_rings = num_msix; 810cb9327d5SHimanshu Madhani adapter->drv_tx_rings = QLCNIC_SINGLE_RING; 811cb9327d5SHimanshu Madhani } else { 812cb9327d5SHimanshu Madhani /* Distribute vectors equally */ 813cb9327d5SHimanshu Madhani adapter->drv_tx_rings = num_msix / 2; 814cb9327d5SHimanshu Madhani adapter->drv_sds_rings = adapter->drv_tx_rings; 81513159183SSony Chacko } 81613159183SSony Chacko 81713159183SSony Chacko if (num_msix) { 81813159183SSony Chacko dev_info(&pdev->dev, 819dce056cbSManish Chopra "Trying to allocate %d MSI-X interrupt vectors\n", 82013159183SSony Chacko num_msix); 821aa43c215SJeff Kirsher goto enable_msix; 822aa43c215SJeff Kirsher } 82313159183SSony Chacko } else { 824dce056cbSManish Chopra dev_info(&pdev->dev, 825cb9327d5SHimanshu Madhani "Unable to allocate %d MSI-X vectors, err=%d\n", 826cb9327d5SHimanshu Madhani num_msix, err); 827cb9327d5SHimanshu Madhani return err; 828aa43c215SJeff Kirsher } 82913159183SSony Chacko } 83013159183SSony Chacko 83174a1fa45SAlexander Gordeev return -EIO; 832aa43c215SJeff Kirsher } 833aa43c215SJeff Kirsher 834cb9327d5SHimanshu Madhani static int qlcnic_82xx_calculate_msix_vector(struct qlcnic_adapter *adapter) 835cb9327d5SHimanshu Madhani { 836cb9327d5SHimanshu Madhani int num_msix; 837cb9327d5SHimanshu Madhani 838cb9327d5SHimanshu Madhani num_msix = adapter->drv_sds_rings; 839cb9327d5SHimanshu Madhani 840cb9327d5SHimanshu Madhani if (qlcnic_check_multi_tx(adapter)) 841cb9327d5SHimanshu Madhani num_msix += adapter->drv_tx_rings; 842cb9327d5SHimanshu Madhani else 843cb9327d5SHimanshu Madhani num_msix += QLCNIC_SINGLE_RING; 844cb9327d5SHimanshu Madhani 845cb9327d5SHimanshu Madhani return num_msix; 846cb9327d5SHimanshu Madhani } 847cb9327d5SHimanshu Madhani 8489a97e705SManish chopra static int qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter) 849aa43c215SJeff Kirsher { 8509a97e705SManish chopra int err = 0; 85115087c2bSSony Chacko u32 offset, mask_reg; 852aa43c215SJeff Kirsher const struct qlcnic_legacy_intr_set *legacy_intrp; 85315087c2bSSony Chacko struct qlcnic_hardware_context *ahw = adapter->ahw; 854aa43c215SJeff Kirsher struct pci_dev *pdev = adapter->pdev; 855aa43c215SJeff Kirsher 856099f7aa7SSony Chacko if (qlcnic_use_msi && !pci_enable_msi(pdev)) { 857aa43c215SJeff Kirsher adapter->flags |= QLCNIC_MSI_ENABLED; 85815087c2bSSony Chacko offset = msi_tgt_status[adapter->ahw->pci_func]; 85915087c2bSSony Chacko adapter->tgt_status_reg = qlcnic_get_ioaddr(adapter->ahw, 86015087c2bSSony Chacko offset); 861aa43c215SJeff Kirsher dev_info(&pdev->dev, "using msi interrupts\n"); 862aa43c215SJeff Kirsher adapter->msix_entries[0].vector = pdev->irq; 8639a97e705SManish chopra return err; 864aa43c215SJeff Kirsher } 865012ec812SHimanshu Madhani 8669a97e705SManish chopra if (qlcnic_use_msi || qlcnic_use_msi_x) 8679a97e705SManish chopra return -EOPNOTSUPP; 868aa43c215SJeff Kirsher 869aa43c215SJeff Kirsher legacy_intrp = &legacy_intr[adapter->ahw->pci_func]; 87079788450SSony Chacko adapter->ahw->int_vec_bit = legacy_intrp->int_vec_bit; 87115087c2bSSony Chacko offset = legacy_intrp->tgt_status_reg; 87215087c2bSSony Chacko adapter->tgt_status_reg = qlcnic_get_ioaddr(ahw, offset); 87315087c2bSSony Chacko mask_reg = legacy_intrp->tgt_mask_reg; 87415087c2bSSony Chacko adapter->tgt_mask_reg = qlcnic_get_ioaddr(ahw, mask_reg); 87515087c2bSSony Chacko adapter->isr_int_vec = qlcnic_get_ioaddr(ahw, ISR_INT_VECTOR); 87615087c2bSSony Chacko adapter->crb_int_state_reg = qlcnic_get_ioaddr(ahw, ISR_INT_STATE_REG); 877aa43c215SJeff Kirsher dev_info(&pdev->dev, "using legacy interrupts\n"); 878aa43c215SJeff Kirsher adapter->msix_entries[0].vector = pdev->irq; 8799a97e705SManish chopra return err; 880aa43c215SJeff Kirsher } 881aa43c215SJeff Kirsher 88221041400Sstephen hemminger static int qlcnic_82xx_setup_intr(struct qlcnic_adapter *adapter) 883aa43c215SJeff Kirsher { 8849a97e705SManish chopra int num_msix, err = 0; 885aa43c215SJeff Kirsher 886cb9327d5SHimanshu Madhani if (adapter->flags & QLCNIC_TSS_RSS) { 887cb9327d5SHimanshu Madhani err = qlcnic_setup_tss_rss_intr(adapter); 888cb9327d5SHimanshu Madhani if (err < 0) 889cb9327d5SHimanshu Madhani return err; 890cb9327d5SHimanshu Madhani num_msix = adapter->ahw->num_msix; 891cb9327d5SHimanshu Madhani } else { 892cb9327d5SHimanshu Madhani num_msix = qlcnic_82xx_calculate_msix_vector(adapter); 893aa43c215SJeff Kirsher 8947e2cf4feSSony Chacko err = qlcnic_enable_msix(adapter, num_msix); 895012ec812SHimanshu Madhani if (err == -ENOMEM) 8967e2cf4feSSony Chacko return err; 897aa43c215SJeff Kirsher 898012ec812SHimanshu Madhani if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) { 899012ec812SHimanshu Madhani qlcnic_disable_multi_tx(adapter); 90042beb3f2SRajesh Borundia adapter->drv_sds_rings = QLCNIC_SINGLE_RING; 901012ec812SHimanshu Madhani 9029a97e705SManish chopra err = qlcnic_enable_msi_legacy(adapter); 903fc49beaeSShahed Shaikh if (err) 9049a97e705SManish chopra return err; 905012ec812SHimanshu Madhani } 906cb9327d5SHimanshu Madhani } 9079a97e705SManish chopra 908012ec812SHimanshu Madhani return 0; 909012ec812SHimanshu Madhani } 910012ec812SHimanshu Madhani 911012ec812SHimanshu Madhani int qlcnic_82xx_mq_intrpt(struct qlcnic_adapter *adapter, int op_type) 912012ec812SHimanshu Madhani { 913012ec812SHimanshu Madhani struct qlcnic_hardware_context *ahw = adapter->ahw; 914012ec812SHimanshu Madhani int err, i; 915012ec812SHimanshu Madhani 916012ec812SHimanshu Madhani if (qlcnic_check_multi_tx(adapter) && 917c2c5e3a0SHimanshu Madhani !ahw->diag_test && 918012ec812SHimanshu Madhani (adapter->flags & QLCNIC_MSIX_ENABLED)) { 919012ec812SHimanshu Madhani ahw->intr_tbl = vzalloc(ahw->num_msix * 920012ec812SHimanshu Madhani sizeof(struct qlcnic_intrpt_config)); 921012ec812SHimanshu Madhani if (!ahw->intr_tbl) 922012ec812SHimanshu Madhani return -ENOMEM; 923012ec812SHimanshu Madhani 924012ec812SHimanshu Madhani for (i = 0; i < ahw->num_msix; i++) { 925012ec812SHimanshu Madhani ahw->intr_tbl[i].type = QLCNIC_INTRPT_MSIX; 926012ec812SHimanshu Madhani ahw->intr_tbl[i].id = i; 927012ec812SHimanshu Madhani ahw->intr_tbl[i].src = 0; 928012ec812SHimanshu Madhani } 929012ec812SHimanshu Madhani 930012ec812SHimanshu Madhani err = qlcnic_82xx_config_intrpt(adapter, 1); 931012ec812SHimanshu Madhani if (err) 932012ec812SHimanshu Madhani dev_err(&adapter->pdev->dev, 933012ec812SHimanshu Madhani "Failed to configure Interrupt for %d vector\n", 934012ec812SHimanshu Madhani ahw->num_msix); 935012ec812SHimanshu Madhani return err; 936012ec812SHimanshu Madhani } 937012ec812SHimanshu Madhani 938012ec812SHimanshu Madhani return 0; 939aa43c215SJeff Kirsher } 94013159183SSony Chacko 941319ecf12SSony Chacko void qlcnic_teardown_intr(struct qlcnic_adapter *adapter) 942aa43c215SJeff Kirsher { 943aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_MSIX_ENABLED) 944aa43c215SJeff Kirsher pci_disable_msix(adapter->pdev); 945aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_MSI_ENABLED) 946aa43c215SJeff Kirsher pci_disable_msi(adapter->pdev); 94713159183SSony Chacko 94813159183SSony Chacko kfree(adapter->msix_entries); 94913159183SSony Chacko adapter->msix_entries = NULL; 95013159183SSony Chacko 95113159183SSony Chacko if (adapter->ahw->intr_tbl) { 95213159183SSony Chacko vfree(adapter->ahw->intr_tbl); 95313159183SSony Chacko adapter->ahw->intr_tbl = NULL; 95413159183SSony Chacko } 955aa43c215SJeff Kirsher } 956aa43c215SJeff Kirsher 957f1a094a8SRajesh Borundia static void qlcnic_cleanup_pci_map(struct qlcnic_hardware_context *ahw) 958aa43c215SJeff Kirsher { 959f1a094a8SRajesh Borundia if (ahw->pci_base0 != NULL) 960f1a094a8SRajesh Borundia iounmap(ahw->pci_base0); 961aa43c215SJeff Kirsher } 962aa43c215SJeff Kirsher 9637e2cf4feSSony Chacko static int qlcnic_get_act_pci_func(struct qlcnic_adapter *adapter) 9647e2cf4feSSony Chacko { 9652f514c52SJitendra Kalsaria struct qlcnic_hardware_context *ahw = adapter->ahw; 9667e2cf4feSSony Chacko struct qlcnic_pci_info *pci_info; 9677e2cf4feSSony Chacko int ret; 9687e2cf4feSSony Chacko 9697e2cf4feSSony Chacko if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) { 9702f514c52SJitendra Kalsaria switch (ahw->port_type) { 9717e2cf4feSSony Chacko case QLCNIC_GBE: 9722f514c52SJitendra Kalsaria ahw->total_nic_func = QLCNIC_NIU_MAX_GBE_PORTS; 9737e2cf4feSSony Chacko break; 9747e2cf4feSSony Chacko case QLCNIC_XGBE: 9752f514c52SJitendra Kalsaria ahw->total_nic_func = QLCNIC_NIU_MAX_XG_PORTS; 9767e2cf4feSSony Chacko break; 9777e2cf4feSSony Chacko } 9787e2cf4feSSony Chacko return 0; 9797e2cf4feSSony Chacko } 9807e2cf4feSSony Chacko 9812f514c52SJitendra Kalsaria if (ahw->op_mode == QLCNIC_MGMT_FUNC) 9827e2cf4feSSony Chacko return 0; 9837e2cf4feSSony Chacko 9842f514c52SJitendra Kalsaria pci_info = kcalloc(ahw->max_vnic_func, sizeof(*pci_info), GFP_KERNEL); 9857e2cf4feSSony Chacko if (!pci_info) 9867e2cf4feSSony Chacko return -ENOMEM; 9877e2cf4feSSony Chacko 9887e2cf4feSSony Chacko ret = qlcnic_get_pci_info(adapter, pci_info); 9897e2cf4feSSony Chacko kfree(pci_info); 9907e2cf4feSSony Chacko return ret; 9917e2cf4feSSony Chacko } 992d71170fbSSony Chacko 99335dafcb0SSony Chacko static bool qlcnic_port_eswitch_cfg_capability(struct qlcnic_adapter *adapter) 99435dafcb0SSony Chacko { 99535dafcb0SSony Chacko bool ret = false; 99635dafcb0SSony Chacko 99735dafcb0SSony Chacko if (qlcnic_84xx_check(adapter)) { 99835dafcb0SSony Chacko ret = true; 99935dafcb0SSony Chacko } else if (qlcnic_83xx_check(adapter)) { 100035dafcb0SSony Chacko if (adapter->ahw->extra_capability[0] & 100135dafcb0SSony Chacko QLCNIC_FW_CAPABILITY_2_PER_PORT_ESWITCH_CFG) 100235dafcb0SSony Chacko ret = true; 100335dafcb0SSony Chacko else 100435dafcb0SSony Chacko ret = false; 100535dafcb0SSony Chacko } 100635dafcb0SSony Chacko 100735dafcb0SSony Chacko return ret; 100835dafcb0SSony Chacko } 100935dafcb0SSony Chacko 1010d71170fbSSony Chacko int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) 1011aa43c215SJeff Kirsher { 10122f514c52SJitendra Kalsaria struct qlcnic_hardware_context *ahw = adapter->ahw; 1013aa43c215SJeff Kirsher struct qlcnic_pci_info *pci_info; 10144c776aadSSony Chacko int i, id = 0, ret = 0, j = 0; 1015bff57d8eSSony Chacko u16 act_pci_func; 1016aa43c215SJeff Kirsher u8 pfn; 1017aa43c215SJeff Kirsher 10182f514c52SJitendra Kalsaria pci_info = kcalloc(ahw->max_vnic_func, sizeof(*pci_info), GFP_KERNEL); 1019aa43c215SJeff Kirsher if (!pci_info) 1020aa43c215SJeff Kirsher return -ENOMEM; 1021aa43c215SJeff Kirsher 1022bff57d8eSSony Chacko ret = qlcnic_get_pci_info(adapter, pci_info); 1023bff57d8eSSony Chacko if (ret) 1024bff57d8eSSony Chacko goto err_pci_info; 1025bff57d8eSSony Chacko 10262f514c52SJitendra Kalsaria act_pci_func = ahw->total_nic_func; 1027bff57d8eSSony Chacko 10286396bb22SKees Cook adapter->npars = kcalloc(act_pci_func, 10296396bb22SKees Cook sizeof(struct qlcnic_npar_info), 10306396bb22SKees Cook GFP_KERNEL); 1031aa43c215SJeff Kirsher if (!adapter->npars) { 1032aa43c215SJeff Kirsher ret = -ENOMEM; 1033aa43c215SJeff Kirsher goto err_pci_info; 1034aa43c215SJeff Kirsher } 1035aa43c215SJeff Kirsher 10366396bb22SKees Cook adapter->eswitch = kcalloc(QLCNIC_NIU_MAX_XG_PORTS, 10376396bb22SKees Cook sizeof(struct qlcnic_eswitch), 10386396bb22SKees Cook GFP_KERNEL); 1039aa43c215SJeff Kirsher if (!adapter->eswitch) { 1040aa43c215SJeff Kirsher ret = -ENOMEM; 1041aa43c215SJeff Kirsher goto err_npars; 1042aa43c215SJeff Kirsher } 1043aa43c215SJeff Kirsher 10442f514c52SJitendra Kalsaria for (i = 0; i < ahw->max_vnic_func; i++) { 1045aa43c215SJeff Kirsher pfn = pci_info[i].id; 1046bff57d8eSSony Chacko 10472f514c52SJitendra Kalsaria if (pfn >= ahw->max_vnic_func) { 1048d7a32b6eSVladimir Zapolskiy ret = -EINVAL; 1049c65762fcSSucheta Chakraborty dev_err(&adapter->pdev->dev, "%s: Invalid function 0x%x, max 0x%x\n", 1050c65762fcSSucheta Chakraborty __func__, pfn, ahw->max_vnic_func); 1051aa43c215SJeff Kirsher goto err_eswitch; 1052aa43c215SJeff Kirsher } 1053bff57d8eSSony Chacko 1054bff57d8eSSony Chacko if (!pci_info[i].active || 1055bff57d8eSSony Chacko (pci_info[i].type != QLCNIC_TYPE_NIC)) 1056bff57d8eSSony Chacko continue; 1057bff57d8eSSony Chacko 105835dafcb0SSony Chacko if (qlcnic_port_eswitch_cfg_capability(adapter)) { 10594c776aadSSony Chacko if (!qlcnic_83xx_set_port_eswitch_status(adapter, pfn, 10604c776aadSSony Chacko &id)) 106135dafcb0SSony Chacko adapter->npars[j].eswitch_status = true; 106235dafcb0SSony Chacko else 106335dafcb0SSony Chacko continue; 106435dafcb0SSony Chacko } else { 106535dafcb0SSony Chacko adapter->npars[j].eswitch_status = true; 106635dafcb0SSony Chacko } 106735dafcb0SSony Chacko 1068bff57d8eSSony Chacko adapter->npars[j].pci_func = pfn; 1069bff57d8eSSony Chacko adapter->npars[j].active = (u8)pci_info[i].active; 1070bff57d8eSSony Chacko adapter->npars[j].type = (u8)pci_info[i].type; 1071bff57d8eSSony Chacko adapter->npars[j].phy_port = (u8)pci_info[i].default_port; 1072bff57d8eSSony Chacko adapter->npars[j].min_bw = pci_info[i].tx_min_bw; 1073bff57d8eSSony Chacko adapter->npars[j].max_bw = pci_info[i].tx_max_bw; 107435dafcb0SSony Chacko 10759e630955SSucheta Chakraborty memcpy(&adapter->npars[j].mac, &pci_info[i].mac, ETH_ALEN); 1076bff57d8eSSony Chacko j++; 1077aa43c215SJeff Kirsher } 1078aa43c215SJeff Kirsher 10794c776aadSSony Chacko /* Update eSwitch status for adapters without per port eSwitch 10804c776aadSSony Chacko * configuration capability 10814c776aadSSony Chacko */ 10824c776aadSSony Chacko if (!qlcnic_port_eswitch_cfg_capability(adapter)) { 108335dafcb0SSony Chacko for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++) 1084aa43c215SJeff Kirsher adapter->eswitch[i].flags |= QLCNIC_SWITCH_ENABLE; 108513159183SSony Chacko } 1086aa43c215SJeff Kirsher 1087aa43c215SJeff Kirsher kfree(pci_info); 1088aa43c215SJeff Kirsher return 0; 1089aa43c215SJeff Kirsher 1090aa43c215SJeff Kirsher err_eswitch: 1091aa43c215SJeff Kirsher kfree(adapter->eswitch); 1092aa43c215SJeff Kirsher adapter->eswitch = NULL; 1093aa43c215SJeff Kirsher err_npars: 1094aa43c215SJeff Kirsher kfree(adapter->npars); 1095aa43c215SJeff Kirsher adapter->npars = NULL; 1096aa43c215SJeff Kirsher err_pci_info: 1097aa43c215SJeff Kirsher kfree(pci_info); 1098aa43c215SJeff Kirsher 1099aa43c215SJeff Kirsher return ret; 1100aa43c215SJeff Kirsher } 1101aa43c215SJeff Kirsher 1102aa43c215SJeff Kirsher static int 1103aa43c215SJeff Kirsher qlcnic_set_function_modes(struct qlcnic_adapter *adapter) 1104aa43c215SJeff Kirsher { 1105aa43c215SJeff Kirsher u8 id; 11067e8fd003SShahed Shaikh int ret; 1107aa43c215SJeff Kirsher u32 data = QLCNIC_MGMT_FUNC; 1108bff57d8eSSony Chacko struct qlcnic_hardware_context *ahw = adapter->ahw; 1109aa43c215SJeff Kirsher 1110aa43c215SJeff Kirsher ret = qlcnic_api_lock(adapter); 1111aa43c215SJeff Kirsher if (ret) 1112aa43c215SJeff Kirsher goto err_lock; 1113aa43c215SJeff Kirsher 11147e8fd003SShahed Shaikh id = ahw->pci_func; 1115a15ebd37SHimanshu Madhani data = QLC_SHARED_REG_RD32(adapter, QLCNIC_DRV_OP_MODE); 11167e8fd003SShahed Shaikh data = (data & ~QLC_DEV_SET_DRV(0xf, id)) | 11177e8fd003SShahed Shaikh QLC_DEV_SET_DRV(QLCNIC_MGMT_FUNC, id); 1118a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_DRV_OP_MODE, data); 1119aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 1120aa43c215SJeff Kirsher err_lock: 1121aa43c215SJeff Kirsher return ret; 1122aa43c215SJeff Kirsher } 1123aa43c215SJeff Kirsher 112413159183SSony Chacko static void qlcnic_check_vf(struct qlcnic_adapter *adapter, 112513159183SSony Chacko const struct pci_device_id *ent) 1126aa43c215SJeff Kirsher { 1127aa43c215SJeff Kirsher u32 op_mode, priv_level; 1128aa43c215SJeff Kirsher 1129aa43c215SJeff Kirsher /* Determine FW API version */ 113013159183SSony Chacko adapter->ahw->fw_hal_version = QLC_SHARED_REG_RD32(adapter, 1131aa43c215SJeff Kirsher QLCNIC_FW_API); 1132aa43c215SJeff Kirsher 1133aa43c215SJeff Kirsher /* Find PCI function number */ 113413159183SSony Chacko qlcnic_get_func_no(adapter); 1135aa43c215SJeff Kirsher 1136aa43c215SJeff Kirsher /* Determine function privilege level */ 113713159183SSony Chacko op_mode = QLC_SHARED_REG_RD32(adapter, QLCNIC_DRV_OP_MODE); 1138aa43c215SJeff Kirsher if (op_mode == QLC_DEV_DRV_DEFAULT) 1139aa43c215SJeff Kirsher priv_level = QLCNIC_MGMT_FUNC; 1140aa43c215SJeff Kirsher else 1141aa43c215SJeff Kirsher priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func); 1142aa43c215SJeff Kirsher 1143aa43c215SJeff Kirsher if (priv_level == QLCNIC_NON_PRIV_FUNC) { 114479788450SSony Chacko adapter->ahw->op_mode = QLCNIC_NON_PRIV_FUNC; 1145aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, 1146aa43c215SJeff Kirsher "HAL Version: %d Non Privileged function\n", 114779788450SSony Chacko adapter->ahw->fw_hal_version); 1148aa43c215SJeff Kirsher adapter->nic_ops = &qlcnic_vf_ops; 1149aa43c215SJeff Kirsher } else 1150aa43c215SJeff Kirsher adapter->nic_ops = &qlcnic_ops; 1151aa43c215SJeff Kirsher } 1152aa43c215SJeff Kirsher 115315087c2bSSony Chacko #define QLCNIC_82XX_BAR0_LENGTH 0x00200000UL 115413159183SSony Chacko #define QLCNIC_83XX_BAR0_LENGTH 0x4000 115515087c2bSSony Chacko static void qlcnic_get_bar_length(u32 dev_id, ulong *bar) 1156aa43c215SJeff Kirsher { 115715087c2bSSony Chacko switch (dev_id) { 115815087c2bSSony Chacko case PCI_DEVICE_ID_QLOGIC_QLE824X: 115915087c2bSSony Chacko *bar = QLCNIC_82XX_BAR0_LENGTH; 116015087c2bSSony Chacko break; 116113159183SSony Chacko case PCI_DEVICE_ID_QLOGIC_QLE834X: 116240e2b8edSShahed Shaikh case PCI_DEVICE_ID_QLOGIC_QLE8830: 116315ca140fSManish Chopra case PCI_DEVICE_ID_QLOGIC_QLE844X: 1164f8468331SRajesh Borundia case PCI_DEVICE_ID_QLOGIC_VF_QLE834X: 116515ca140fSManish Chopra case PCI_DEVICE_ID_QLOGIC_VF_QLE844X: 1166da286a6fSShahed Shaikh case PCI_DEVICE_ID_QLOGIC_VF_QLE8C30: 116713159183SSony Chacko *bar = QLCNIC_83XX_BAR0_LENGTH; 116813159183SSony Chacko break; 116915087c2bSSony Chacko default: 117015087c2bSSony Chacko *bar = 0; 117115087c2bSSony Chacko } 117215087c2bSSony Chacko } 117315087c2bSSony Chacko 117415087c2bSSony Chacko static int qlcnic_setup_pci_map(struct pci_dev *pdev, 117515087c2bSSony Chacko struct qlcnic_hardware_context *ahw) 117615087c2bSSony Chacko { 117715087c2bSSony Chacko u32 offset; 1178aa43c215SJeff Kirsher void __iomem *mem_ptr0 = NULL; 117915087c2bSSony Chacko unsigned long mem_len, pci_len0 = 0, bar0_len; 1180aa43c215SJeff Kirsher 1181aa43c215SJeff Kirsher /* remap phys address */ 1182aa43c215SJeff Kirsher mem_len = pci_resource_len(pdev, 0); 1183aa43c215SJeff Kirsher 118415087c2bSSony Chacko qlcnic_get_bar_length(pdev->device, &bar0_len); 118515087c2bSSony Chacko if (mem_len >= bar0_len) { 1186aa43c215SJeff Kirsher 1187aa43c215SJeff Kirsher mem_ptr0 = pci_ioremap_bar(pdev, 0); 1188aa43c215SJeff Kirsher if (mem_ptr0 == NULL) { 1189aa43c215SJeff Kirsher dev_err(&pdev->dev, "failed to map PCI bar 0\n"); 1190aa43c215SJeff Kirsher return -EIO; 1191aa43c215SJeff Kirsher } 1192aa43c215SJeff Kirsher pci_len0 = mem_len; 1193aa43c215SJeff Kirsher } else { 1194aa43c215SJeff Kirsher return -EIO; 1195aa43c215SJeff Kirsher } 1196aa43c215SJeff Kirsher 1197f8468331SRajesh Borundia dev_info(&pdev->dev, "%dKB memory map\n", (int)(mem_len >> 10)); 11987e2cf4feSSony Chacko 119915087c2bSSony Chacko ahw->pci_base0 = mem_ptr0; 120015087c2bSSony Chacko ahw->pci_len0 = pci_len0; 120115087c2bSSony Chacko offset = QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(ahw->pci_func)); 120215087c2bSSony Chacko qlcnic_get_ioaddr(ahw, offset); 1203aa43c215SJeff Kirsher 1204aa43c215SJeff Kirsher return 0; 1205aa43c215SJeff Kirsher } 1206aa43c215SJeff Kirsher 120760dcbcb0SManish Chopra static bool qlcnic_validate_subsystem_id(struct qlcnic_adapter *adapter, 12082343f06aSManish Chopra int index) 12092343f06aSManish Chopra { 12102343f06aSManish Chopra struct pci_dev *pdev = adapter->pdev; 12112343f06aSManish Chopra unsigned short subsystem_vendor; 12122343f06aSManish Chopra bool ret = true; 12132343f06aSManish Chopra 12142343f06aSManish Chopra subsystem_vendor = pdev->subsystem_vendor; 12152343f06aSManish Chopra 12162343f06aSManish Chopra if (pdev->device == PCI_DEVICE_ID_QLOGIC_QLE824X || 12172343f06aSManish Chopra pdev->device == PCI_DEVICE_ID_QLOGIC_QLE834X) { 12182343f06aSManish Chopra if (qlcnic_boards[index].sub_vendor == subsystem_vendor && 12192343f06aSManish Chopra qlcnic_boards[index].sub_device == pdev->subsystem_device) 12202343f06aSManish Chopra ret = true; 12212343f06aSManish Chopra else 12222343f06aSManish Chopra ret = false; 12232343f06aSManish Chopra } 12242343f06aSManish Chopra 12252343f06aSManish Chopra return ret; 12262343f06aSManish Chopra } 12272343f06aSManish Chopra 122822999798SSony Chacko static void qlcnic_get_board_name(struct qlcnic_adapter *adapter, char *name) 1229aa43c215SJeff Kirsher { 1230aa43c215SJeff Kirsher struct pci_dev *pdev = adapter->pdev; 1231aa43c215SJeff Kirsher int i, found = 0; 1232aa43c215SJeff Kirsher 1233aa43c215SJeff Kirsher for (i = 0; i < NUM_SUPPORTED_BOARDS; ++i) { 1234aa43c215SJeff Kirsher if (qlcnic_boards[i].vendor == pdev->vendor && 1235aa43c215SJeff Kirsher qlcnic_boards[i].device == pdev->device && 12362343f06aSManish Chopra qlcnic_validate_subsystem_id(adapter, i)) { 1237aa43c215SJeff Kirsher found = 1; 1238aa43c215SJeff Kirsher break; 1239aa43c215SJeff Kirsher } 1240aa43c215SJeff Kirsher } 1241aa43c215SJeff Kirsher 1242aa43c215SJeff Kirsher if (!found) 1243aa43c215SJeff Kirsher sprintf(name, "%pM Gigabit Ethernet", adapter->mac_addr); 12442343f06aSManish Chopra else 12452343f06aSManish Chopra sprintf(name, "%pM: %s" , adapter->mac_addr, 12462343f06aSManish Chopra qlcnic_boards[i].short_name); 1247aa43c215SJeff Kirsher } 1248aa43c215SJeff Kirsher 1249aa43c215SJeff Kirsher static void 1250aa43c215SJeff Kirsher qlcnic_check_options(struct qlcnic_adapter *adapter) 1251aa43c215SJeff Kirsher { 1252a15ebd37SHimanshu Madhani int err; 1253aa43c215SJeff Kirsher u32 fw_major, fw_minor, fw_build, prev_fw_version; 1254aa43c215SJeff Kirsher struct pci_dev *pdev = adapter->pdev; 1255a15ebd37SHimanshu Madhani struct qlcnic_hardware_context *ahw = adapter->ahw; 1256a15ebd37SHimanshu Madhani struct qlcnic_fw_dump *fw_dump = &ahw->fw_dump; 1257aa43c215SJeff Kirsher 1258aa43c215SJeff Kirsher prev_fw_version = adapter->fw_version; 1259aa43c215SJeff Kirsher 1260a15ebd37SHimanshu Madhani fw_major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR); 1261a15ebd37SHimanshu Madhani fw_minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR); 1262a15ebd37SHimanshu Madhani fw_build = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB); 1263aa43c215SJeff Kirsher 1264aa43c215SJeff Kirsher adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build); 1265aa43c215SJeff Kirsher 1266a15ebd37SHimanshu Madhani err = qlcnic_get_board_info(adapter); 1267a15ebd37SHimanshu Madhani if (err) { 1268a15ebd37SHimanshu Madhani dev_err(&pdev->dev, "Error getting board config info.\n"); 1269a15ebd37SHimanshu Madhani return; 1270a15ebd37SHimanshu Madhani } 1271a15ebd37SHimanshu Madhani if (ahw->op_mode != QLCNIC_NON_PRIV_FUNC) { 1272aa43c215SJeff Kirsher if (fw_dump->tmpl_hdr == NULL || 1273aa43c215SJeff Kirsher adapter->fw_version > prev_fw_version) { 1274aa43c215SJeff Kirsher vfree(fw_dump->tmpl_hdr); 1275aa43c215SJeff Kirsher if (!qlcnic_fw_cmd_get_minidump_temp(adapter)) 1276aa43c215SJeff Kirsher dev_info(&pdev->dev, 1277aa43c215SJeff Kirsher "Supports FW dump capability\n"); 1278aa43c215SJeff Kirsher } 1279aa43c215SJeff Kirsher } 1280aa43c215SJeff Kirsher 128113159183SSony Chacko dev_info(&pdev->dev, "Driver v%s, firmware v%d.%d.%d\n", 128213159183SSony Chacko QLCNIC_LINUX_VERSIONID, fw_major, fw_minor, fw_build); 128313159183SSony Chacko 1284aa43c215SJeff Kirsher if (adapter->ahw->port_type == QLCNIC_XGBE) { 1285aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_ESWITCH_ENABLED) { 1286aa43c215SJeff Kirsher adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_VF; 1287aa43c215SJeff Kirsher adapter->max_rxd = MAX_RCV_DESCRIPTORS_VF; 1288aa43c215SJeff Kirsher } else { 1289aa43c215SJeff Kirsher adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_10G; 1290aa43c215SJeff Kirsher adapter->max_rxd = MAX_RCV_DESCRIPTORS_10G; 1291aa43c215SJeff Kirsher } 1292aa43c215SJeff Kirsher 1293aa43c215SJeff Kirsher adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G; 1294aa43c215SJeff Kirsher adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G; 1295aa43c215SJeff Kirsher 1296aa43c215SJeff Kirsher } else if (adapter->ahw->port_type == QLCNIC_GBE) { 1297aa43c215SJeff Kirsher adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_1G; 1298aa43c215SJeff Kirsher adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G; 1299aa43c215SJeff Kirsher adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G; 1300aa43c215SJeff Kirsher adapter->max_rxd = MAX_RCV_DESCRIPTORS_1G; 1301aa43c215SJeff Kirsher } 1302aa43c215SJeff Kirsher 1303099f7aa7SSony Chacko adapter->ahw->msix_supported = !!qlcnic_use_msi_x; 1304aa43c215SJeff Kirsher 1305aa43c215SJeff Kirsher adapter->num_txd = MAX_CMD_DESCRIPTORS; 1306aa43c215SJeff Kirsher 1307aa43c215SJeff Kirsher adapter->max_rds_rings = MAX_RDS_RINGS; 1308aa43c215SJeff Kirsher } 1309aa43c215SJeff Kirsher 1310aa43c215SJeff Kirsher static int 1311aa43c215SJeff Kirsher qlcnic_initialize_nic(struct qlcnic_adapter *adapter) 1312aa43c215SJeff Kirsher { 1313aa43c215SJeff Kirsher struct qlcnic_info nic_info; 13144bd8e738SHimanshu Madhani int err = 0; 1315aa43c215SJeff Kirsher 1316bff57d8eSSony Chacko memset(&nic_info, 0, sizeof(struct qlcnic_info)); 1317aa43c215SJeff Kirsher err = qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw->pci_func); 1318aa43c215SJeff Kirsher if (err) 1319aa43c215SJeff Kirsher return err; 1320aa43c215SJeff Kirsher 132179788450SSony Chacko adapter->ahw->physical_port = (u8)nic_info.phys_port; 132279788450SSony Chacko adapter->ahw->switch_mode = nic_info.switch_mode; 132379788450SSony Chacko adapter->ahw->max_tx_ques = nic_info.max_tx_ques; 132479788450SSony Chacko adapter->ahw->max_rx_ques = nic_info.max_rx_ques; 132579788450SSony Chacko adapter->ahw->capabilities = nic_info.capabilities; 1326776e7bdeSShahed Shaikh 1327776e7bdeSShahed Shaikh if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_MORE_CAPS) { 1328776e7bdeSShahed Shaikh u32 temp; 13294bd8e738SHimanshu Madhani temp = QLCRD32(adapter, CRB_FW_CAPABILITIES_2, &err); 13304bd8e738SHimanshu Madhani if (err == -EIO) 13314bd8e738SHimanshu Madhani return err; 1332db131786SPratik Pujar adapter->ahw->extra_capability[0] = temp; 1333d6994ca7SShahed Shaikh } else { 1334d6994ca7SShahed Shaikh adapter->ahw->extra_capability[0] = 0; 1335776e7bdeSShahed Shaikh } 1336d6994ca7SShahed Shaikh 133779788450SSony Chacko adapter->ahw->max_mac_filters = nic_info.max_mac_filters; 133879788450SSony Chacko adapter->ahw->max_mtu = nic_info.max_mtu; 1339aa43c215SJeff Kirsher 134034e8c406SHimanshu Madhani if (adapter->ahw->capabilities & BIT_6) { 1341aa43c215SJeff Kirsher adapter->flags |= QLCNIC_ESWITCH_ENABLED; 134234e8c406SHimanshu Madhani adapter->ahw->nic_mode = QLCNIC_VNIC_MODE; 134334e8c406SHimanshu Madhani adapter->max_tx_rings = QLCNIC_MAX_HW_VNIC_TX_RINGS; 134434e8c406SHimanshu Madhani adapter->max_sds_rings = QLCNIC_MAX_VNIC_SDS_RINGS; 134534e8c406SHimanshu Madhani 134634e8c406SHimanshu Madhani dev_info(&adapter->pdev->dev, "vNIC mode enabled.\n"); 134734e8c406SHimanshu Madhani } else { 134834e8c406SHimanshu Madhani adapter->ahw->nic_mode = QLCNIC_DEFAULT_MODE; 134934e8c406SHimanshu Madhani adapter->max_tx_rings = QLCNIC_MAX_HW_TX_RINGS; 1350f9566265SHimanshu Madhani adapter->max_sds_rings = QLCNIC_MAX_SDS_RINGS; 1351aa43c215SJeff Kirsher adapter->flags &= ~QLCNIC_ESWITCH_ENABLED; 135234e8c406SHimanshu Madhani } 1353aa43c215SJeff Kirsher 1354aa43c215SJeff Kirsher return err; 1355aa43c215SJeff Kirsher } 1356aa43c215SJeff Kirsher 1357ec079a07SSony Chacko void qlcnic_set_vlan_config(struct qlcnic_adapter *adapter, 1358aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg *esw_cfg) 1359aa43c215SJeff Kirsher { 1360aa43c215SJeff Kirsher if (esw_cfg->discard_tagged) 1361aa43c215SJeff Kirsher adapter->flags &= ~QLCNIC_TAGGING_ENABLED; 1362aa43c215SJeff Kirsher else 1363aa43c215SJeff Kirsher adapter->flags |= QLCNIC_TAGGING_ENABLED; 1364aa43c215SJeff Kirsher 136591b7282bSRajesh Borundia if (esw_cfg->vlan_id) { 136691b7282bSRajesh Borundia adapter->rx_pvid = esw_cfg->vlan_id; 136791b7282bSRajesh Borundia adapter->tx_pvid = esw_cfg->vlan_id; 136891b7282bSRajesh Borundia } else { 136991b7282bSRajesh Borundia adapter->rx_pvid = 0; 137091b7282bSRajesh Borundia adapter->tx_pvid = 0; 137191b7282bSRajesh Borundia } 1372aa43c215SJeff Kirsher } 1373aa43c215SJeff Kirsher 13748e586137SJiri Pirko static int 137580d5c368SPatrick McHardy qlcnic_vlan_rx_add(struct net_device *netdev, __be16 proto, u16 vid) 1376aa43c215SJeff Kirsher { 1377aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 137891b7282bSRajesh Borundia int err; 137991b7282bSRajesh Borundia 138091b7282bSRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) { 138191b7282bSRajesh Borundia err = qlcnic_sriov_cfg_vf_guest_vlan(adapter, vid, 1); 138291b7282bSRajesh Borundia if (err) { 138391b7282bSRajesh Borundia netdev_err(netdev, 138491b7282bSRajesh Borundia "Cannot add VLAN filter for VLAN id %d, err=%d", 138591b7282bSRajesh Borundia vid, err); 138691b7282bSRajesh Borundia return err; 138791b7282bSRajesh Borundia } 138891b7282bSRajesh Borundia } 138991b7282bSRajesh Borundia 1390aa43c215SJeff Kirsher set_bit(vid, adapter->vlans); 13918e586137SJiri Pirko return 0; 1392aa43c215SJeff Kirsher } 1393aa43c215SJeff Kirsher 13948e586137SJiri Pirko static int 139580d5c368SPatrick McHardy qlcnic_vlan_rx_del(struct net_device *netdev, __be16 proto, u16 vid) 1396aa43c215SJeff Kirsher { 1397aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 139891b7282bSRajesh Borundia int err; 139991b7282bSRajesh Borundia 140091b7282bSRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) { 140191b7282bSRajesh Borundia err = qlcnic_sriov_cfg_vf_guest_vlan(adapter, vid, 0); 140291b7282bSRajesh Borundia if (err) { 140391b7282bSRajesh Borundia netdev_err(netdev, 140491b7282bSRajesh Borundia "Cannot delete VLAN filter for VLAN id %d, err=%d", 140591b7282bSRajesh Borundia vid, err); 140691b7282bSRajesh Borundia return err; 140791b7282bSRajesh Borundia } 140891b7282bSRajesh Borundia } 1409aa43c215SJeff Kirsher 1410aa43c215SJeff Kirsher qlcnic_restore_indev_addr(netdev, NETDEV_DOWN); 1411aa43c215SJeff Kirsher clear_bit(vid, adapter->vlans); 14128e586137SJiri Pirko return 0; 1413aa43c215SJeff Kirsher } 1414aa43c215SJeff Kirsher 1415ec079a07SSony Chacko void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter, 1416aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg *esw_cfg) 1417aa43c215SJeff Kirsher { 1418aa43c215SJeff Kirsher adapter->flags &= ~(QLCNIC_MACSPOOF | QLCNIC_MAC_OVERRIDE_DISABLED | 1419aa43c215SJeff Kirsher QLCNIC_PROMISC_DISABLED); 1420aa43c215SJeff Kirsher 1421aa43c215SJeff Kirsher if (esw_cfg->mac_anti_spoof) 1422aa43c215SJeff Kirsher adapter->flags |= QLCNIC_MACSPOOF; 1423aa43c215SJeff Kirsher 1424aa43c215SJeff Kirsher if (!esw_cfg->mac_override) 1425aa43c215SJeff Kirsher adapter->flags |= QLCNIC_MAC_OVERRIDE_DISABLED; 1426aa43c215SJeff Kirsher 1427aa43c215SJeff Kirsher if (!esw_cfg->promisc_mode) 1428aa43c215SJeff Kirsher adapter->flags |= QLCNIC_PROMISC_DISABLED; 1429aa43c215SJeff Kirsher } 1430aa43c215SJeff Kirsher 1431d71170fbSSony Chacko int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter) 1432aa43c215SJeff Kirsher { 1433aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg esw_cfg; 1434aa43c215SJeff Kirsher 1435aa43c215SJeff Kirsher if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) 1436aa43c215SJeff Kirsher return 0; 1437aa43c215SJeff Kirsher 1438aa43c215SJeff Kirsher esw_cfg.pci_func = adapter->ahw->pci_func; 1439aa43c215SJeff Kirsher if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg)) 1440aa43c215SJeff Kirsher return -EIO; 1441aa43c215SJeff Kirsher qlcnic_set_vlan_config(adapter, &esw_cfg); 1442aa43c215SJeff Kirsher qlcnic_set_eswitch_port_features(adapter, &esw_cfg); 1443147a9088SShahed Shaikh qlcnic_set_netdev_features(adapter, &esw_cfg); 1444aa43c215SJeff Kirsher 1445aa43c215SJeff Kirsher return 0; 1446aa43c215SJeff Kirsher } 1447aa43c215SJeff Kirsher 1448147a9088SShahed Shaikh void qlcnic_set_netdev_features(struct qlcnic_adapter *adapter, 1449aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg *esw_cfg) 1450aa43c215SJeff Kirsher { 1451aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 1452aa43c215SJeff Kirsher 145313159183SSony Chacko if (qlcnic_83xx_check(adapter)) 145413159183SSony Chacko return; 145513159183SSony Chacko 1456147a9088SShahed Shaikh adapter->offload_flags = esw_cfg->offload_flags; 1457147a9088SShahed Shaikh adapter->flags |= QLCNIC_APP_CHANGED_FLAGS; 1458147a9088SShahed Shaikh netdev_update_features(netdev); 1459147a9088SShahed Shaikh adapter->flags &= ~QLCNIC_APP_CHANGED_FLAGS; 1460aa43c215SJeff Kirsher } 1461aa43c215SJeff Kirsher 1462aa43c215SJeff Kirsher static int 1463aa43c215SJeff Kirsher qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter) 1464aa43c215SJeff Kirsher { 1465aa43c215SJeff Kirsher u32 op_mode, priv_level; 1466aa43c215SJeff Kirsher int err = 0; 1467aa43c215SJeff Kirsher 1468aa43c215SJeff Kirsher err = qlcnic_initialize_nic(adapter); 1469aa43c215SJeff Kirsher if (err) 1470aa43c215SJeff Kirsher return err; 1471aa43c215SJeff Kirsher 1472aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_ADAPTER_INITIALIZED) 1473aa43c215SJeff Kirsher return 0; 1474aa43c215SJeff Kirsher 147513159183SSony Chacko op_mode = QLC_SHARED_REG_RD32(adapter, QLCNIC_DRV_OP_MODE); 1476aa43c215SJeff Kirsher priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func); 1477aa43c215SJeff Kirsher 1478aa43c215SJeff Kirsher if (op_mode == QLC_DEV_DRV_DEFAULT) 1479aa43c215SJeff Kirsher priv_level = QLCNIC_MGMT_FUNC; 1480aa43c215SJeff Kirsher else 1481aa43c215SJeff Kirsher priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func); 1482aa43c215SJeff Kirsher 1483aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_ESWITCH_ENABLED) { 1484aa43c215SJeff Kirsher if (priv_level == QLCNIC_MGMT_FUNC) { 148579788450SSony Chacko adapter->ahw->op_mode = QLCNIC_MGMT_FUNC; 1486aa43c215SJeff Kirsher err = qlcnic_init_pci_info(adapter); 1487aa43c215SJeff Kirsher if (err) 1488aa43c215SJeff Kirsher return err; 1489aa43c215SJeff Kirsher /* Set privilege level for other functions */ 1490aa43c215SJeff Kirsher qlcnic_set_function_modes(adapter); 1491aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, 1492aa43c215SJeff Kirsher "HAL Version: %d, Management function\n", 149379788450SSony Chacko adapter->ahw->fw_hal_version); 1494aa43c215SJeff Kirsher } else if (priv_level == QLCNIC_PRIV_FUNC) { 149579788450SSony Chacko adapter->ahw->op_mode = QLCNIC_PRIV_FUNC; 1496aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, 1497aa43c215SJeff Kirsher "HAL Version: %d, Privileged function\n", 149879788450SSony Chacko adapter->ahw->fw_hal_version); 1499aa43c215SJeff Kirsher } 150034e8c406SHimanshu Madhani } else { 150134e8c406SHimanshu Madhani adapter->ahw->nic_mode = QLCNIC_DEFAULT_MODE; 1502aa43c215SJeff Kirsher } 1503aa43c215SJeff Kirsher 1504aa43c215SJeff Kirsher adapter->flags |= QLCNIC_ADAPTER_INITIALIZED; 1505aa43c215SJeff Kirsher 1506aa43c215SJeff Kirsher return err; 1507aa43c215SJeff Kirsher } 1508aa43c215SJeff Kirsher 1509d71170fbSSony Chacko int qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter) 1510aa43c215SJeff Kirsher { 1511aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg esw_cfg; 1512aa43c215SJeff Kirsher struct qlcnic_npar_info *npar; 1513aa43c215SJeff Kirsher u8 i; 1514aa43c215SJeff Kirsher 1515aa43c215SJeff Kirsher if (adapter->need_fw_reset) 1516aa43c215SJeff Kirsher return 0; 1517aa43c215SJeff Kirsher 15182f514c52SJitendra Kalsaria for (i = 0; i < adapter->ahw->total_nic_func; i++) { 151935dafcb0SSony Chacko if (!adapter->npars[i].eswitch_status) 152035dafcb0SSony Chacko continue; 152135dafcb0SSony Chacko 1522aa43c215SJeff Kirsher memset(&esw_cfg, 0, sizeof(struct qlcnic_esw_func_cfg)); 1523bff57d8eSSony Chacko esw_cfg.pci_func = adapter->npars[i].pci_func; 1524aa43c215SJeff Kirsher esw_cfg.mac_override = BIT_0; 1525aa43c215SJeff Kirsher esw_cfg.promisc_mode = BIT_0; 1526bff57d8eSSony Chacko if (qlcnic_82xx_check(adapter)) { 1527bff57d8eSSony Chacko esw_cfg.offload_flags = BIT_0; 1528bff57d8eSSony Chacko if (QLCNIC_IS_TSO_CAPABLE(adapter)) 1529aa43c215SJeff Kirsher esw_cfg.offload_flags |= (BIT_1 | BIT_2); 1530bff57d8eSSony Chacko } 1531aa43c215SJeff Kirsher if (qlcnic_config_switch_port(adapter, &esw_cfg)) 1532aa43c215SJeff Kirsher return -EIO; 1533aa43c215SJeff Kirsher npar = &adapter->npars[i]; 1534aa43c215SJeff Kirsher npar->pvid = esw_cfg.vlan_id; 1535aa43c215SJeff Kirsher npar->mac_override = esw_cfg.mac_override; 1536aa43c215SJeff Kirsher npar->mac_anti_spoof = esw_cfg.mac_anti_spoof; 1537aa43c215SJeff Kirsher npar->discard_tagged = esw_cfg.discard_tagged; 1538aa43c215SJeff Kirsher npar->promisc_mode = esw_cfg.promisc_mode; 1539aa43c215SJeff Kirsher npar->offload_flags = esw_cfg.offload_flags; 1540aa43c215SJeff Kirsher } 1541aa43c215SJeff Kirsher 1542aa43c215SJeff Kirsher return 0; 1543aa43c215SJeff Kirsher } 1544aa43c215SJeff Kirsher 154513159183SSony Chacko 1546aa43c215SJeff Kirsher static int 1547aa43c215SJeff Kirsher qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter, 1548aa43c215SJeff Kirsher struct qlcnic_npar_info *npar, int pci_func) 1549aa43c215SJeff Kirsher { 1550aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg esw_cfg; 1551aa43c215SJeff Kirsher esw_cfg.op_mode = QLCNIC_PORT_DEFAULTS; 1552aa43c215SJeff Kirsher esw_cfg.pci_func = pci_func; 1553aa43c215SJeff Kirsher esw_cfg.vlan_id = npar->pvid; 1554aa43c215SJeff Kirsher esw_cfg.mac_override = npar->mac_override; 1555aa43c215SJeff Kirsher esw_cfg.discard_tagged = npar->discard_tagged; 1556aa43c215SJeff Kirsher esw_cfg.mac_anti_spoof = npar->mac_anti_spoof; 1557aa43c215SJeff Kirsher esw_cfg.offload_flags = npar->offload_flags; 1558aa43c215SJeff Kirsher esw_cfg.promisc_mode = npar->promisc_mode; 1559aa43c215SJeff Kirsher if (qlcnic_config_switch_port(adapter, &esw_cfg)) 1560aa43c215SJeff Kirsher return -EIO; 1561aa43c215SJeff Kirsher 1562aa43c215SJeff Kirsher esw_cfg.op_mode = QLCNIC_ADD_VLAN; 1563aa43c215SJeff Kirsher if (qlcnic_config_switch_port(adapter, &esw_cfg)) 1564aa43c215SJeff Kirsher return -EIO; 1565aa43c215SJeff Kirsher 1566aa43c215SJeff Kirsher return 0; 1567aa43c215SJeff Kirsher } 1568aa43c215SJeff Kirsher 1569d71170fbSSony Chacko int qlcnic_reset_npar_config(struct qlcnic_adapter *adapter) 1570aa43c215SJeff Kirsher { 1571aa43c215SJeff Kirsher int i, err; 1572aa43c215SJeff Kirsher struct qlcnic_npar_info *npar; 1573aa43c215SJeff Kirsher struct qlcnic_info nic_info; 1574bff57d8eSSony Chacko u8 pci_func; 1575aa43c215SJeff Kirsher 1576bff57d8eSSony Chacko if (qlcnic_82xx_check(adapter)) 1577aa43c215SJeff Kirsher if (!adapter->need_fw_reset) 1578aa43c215SJeff Kirsher return 0; 1579aa43c215SJeff Kirsher 1580aa43c215SJeff Kirsher /* Set the NPAR config data after FW reset */ 15812f514c52SJitendra Kalsaria for (i = 0; i < adapter->ahw->total_nic_func; i++) { 1582aa43c215SJeff Kirsher npar = &adapter->npars[i]; 1583bff57d8eSSony Chacko pci_func = npar->pci_func; 158435dafcb0SSony Chacko if (!adapter->npars[i].eswitch_status) 158535dafcb0SSony Chacko continue; 158635dafcb0SSony Chacko 1587bff57d8eSSony Chacko memset(&nic_info, 0, sizeof(struct qlcnic_info)); 158813159183SSony Chacko err = qlcnic_get_nic_info(adapter, &nic_info, pci_func); 1589aa43c215SJeff Kirsher if (err) 1590aa43c215SJeff Kirsher return err; 1591aa43c215SJeff Kirsher nic_info.min_tx_bw = npar->min_bw; 1592aa43c215SJeff Kirsher nic_info.max_tx_bw = npar->max_bw; 1593aa43c215SJeff Kirsher err = qlcnic_set_nic_info(adapter, &nic_info); 1594aa43c215SJeff Kirsher if (err) 1595aa43c215SJeff Kirsher return err; 1596aa43c215SJeff Kirsher 1597aa43c215SJeff Kirsher if (npar->enable_pm) { 1598aa43c215SJeff Kirsher err = qlcnic_config_port_mirroring(adapter, 1599bff57d8eSSony Chacko npar->dest_npar, 1, 1600bff57d8eSSony Chacko pci_func); 1601aa43c215SJeff Kirsher if (err) 1602aa43c215SJeff Kirsher return err; 1603aa43c215SJeff Kirsher } 1604bff57d8eSSony Chacko err = qlcnic_reset_eswitch_config(adapter, npar, pci_func); 1605aa43c215SJeff Kirsher if (err) 1606aa43c215SJeff Kirsher return err; 1607aa43c215SJeff Kirsher } 1608aa43c215SJeff Kirsher return 0; 1609aa43c215SJeff Kirsher } 1610aa43c215SJeff Kirsher 1611aa43c215SJeff Kirsher static int qlcnic_check_npar_opertional(struct qlcnic_adapter *adapter) 1612aa43c215SJeff Kirsher { 1613aa43c215SJeff Kirsher u8 npar_opt_timeo = QLCNIC_DEV_NPAR_OPER_TIMEO; 1614aa43c215SJeff Kirsher u32 npar_state; 1615aa43c215SJeff Kirsher 161679788450SSony Chacko if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) 1617aa43c215SJeff Kirsher return 0; 1618aa43c215SJeff Kirsher 1619a15ebd37SHimanshu Madhani npar_state = QLC_SHARED_REG_RD32(adapter, 1620a15ebd37SHimanshu Madhani QLCNIC_CRB_DEV_NPAR_STATE); 1621aa43c215SJeff Kirsher while (npar_state != QLCNIC_DEV_NPAR_OPER && --npar_opt_timeo) { 1622aa43c215SJeff Kirsher msleep(1000); 1623a15ebd37SHimanshu Madhani npar_state = QLC_SHARED_REG_RD32(adapter, 1624a15ebd37SHimanshu Madhani QLCNIC_CRB_DEV_NPAR_STATE); 1625aa43c215SJeff Kirsher } 1626aa43c215SJeff Kirsher if (!npar_opt_timeo) { 1627aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, 16288a168ca7SMasanari Iida "Waiting for NPAR state to operational timeout\n"); 1629aa43c215SJeff Kirsher return -EIO; 1630aa43c215SJeff Kirsher } 1631aa43c215SJeff Kirsher return 0; 1632aa43c215SJeff Kirsher } 1633aa43c215SJeff Kirsher 1634aa43c215SJeff Kirsher static int 1635aa43c215SJeff Kirsher qlcnic_set_mgmt_operations(struct qlcnic_adapter *adapter) 1636aa43c215SJeff Kirsher { 1637aa43c215SJeff Kirsher int err; 1638aa43c215SJeff Kirsher 1639aa43c215SJeff Kirsher if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || 164079788450SSony Chacko adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) 1641aa43c215SJeff Kirsher return 0; 1642aa43c215SJeff Kirsher 1643aa43c215SJeff Kirsher err = qlcnic_set_default_offload_settings(adapter); 1644aa43c215SJeff Kirsher if (err) 1645aa43c215SJeff Kirsher return err; 1646aa43c215SJeff Kirsher 1647aa43c215SJeff Kirsher err = qlcnic_reset_npar_config(adapter); 1648aa43c215SJeff Kirsher if (err) 1649aa43c215SJeff Kirsher return err; 1650aa43c215SJeff Kirsher 1651aa43c215SJeff Kirsher qlcnic_dev_set_npar_ready(adapter); 1652aa43c215SJeff Kirsher 1653aa43c215SJeff Kirsher return err; 1654aa43c215SJeff Kirsher } 1655aa43c215SJeff Kirsher 165621041400Sstephen hemminger static int qlcnic_82xx_start_firmware(struct qlcnic_adapter *adapter) 1657aa43c215SJeff Kirsher { 1658aa43c215SJeff Kirsher int err; 1659aa43c215SJeff Kirsher 1660aa43c215SJeff Kirsher err = qlcnic_can_start_firmware(adapter); 1661aa43c215SJeff Kirsher if (err < 0) 1662aa43c215SJeff Kirsher return err; 1663aa43c215SJeff Kirsher else if (!err) 1664aa43c215SJeff Kirsher goto check_fw_status; 1665aa43c215SJeff Kirsher 1666099f7aa7SSony Chacko if (qlcnic_load_fw_file) 1667aa43c215SJeff Kirsher qlcnic_request_firmware(adapter); 1668aa43c215SJeff Kirsher else { 1669aa43c215SJeff Kirsher err = qlcnic_check_flash_fw_ver(adapter); 1670aa43c215SJeff Kirsher if (err) 1671aa43c215SJeff Kirsher goto err_out; 1672aa43c215SJeff Kirsher 167379788450SSony Chacko adapter->ahw->fw_type = QLCNIC_FLASH_ROMIMAGE; 1674aa43c215SJeff Kirsher } 1675aa43c215SJeff Kirsher 1676aa43c215SJeff Kirsher err = qlcnic_need_fw_reset(adapter); 1677aa43c215SJeff Kirsher if (err == 0) 1678aa43c215SJeff Kirsher goto check_fw_status; 1679aa43c215SJeff Kirsher 1680aa43c215SJeff Kirsher err = qlcnic_pinit_from_rom(adapter); 1681aa43c215SJeff Kirsher if (err) 1682aa43c215SJeff Kirsher goto err_out; 1683aa43c215SJeff Kirsher 1684aa43c215SJeff Kirsher err = qlcnic_load_firmware(adapter); 1685aa43c215SJeff Kirsher if (err) 1686aa43c215SJeff Kirsher goto err_out; 1687aa43c215SJeff Kirsher 1688aa43c215SJeff Kirsher qlcnic_release_firmware(adapter); 1689aa43c215SJeff Kirsher QLCWR32(adapter, CRB_DRIVER_VERSION, QLCNIC_DRIVER_VERSION); 1690aa43c215SJeff Kirsher 1691aa43c215SJeff Kirsher check_fw_status: 1692aa43c215SJeff Kirsher err = qlcnic_check_fw_status(adapter); 1693aa43c215SJeff Kirsher if (err) 1694aa43c215SJeff Kirsher goto err_out; 1695aa43c215SJeff Kirsher 1696a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); 1697aa43c215SJeff Kirsher qlcnic_idc_debug_info(adapter, 1); 1698aa43c215SJeff Kirsher err = qlcnic_check_eswitch_mode(adapter); 1699aa43c215SJeff Kirsher if (err) { 1700aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, 1701aa43c215SJeff Kirsher "Memory allocation failed for eswitch\n"); 1702aa43c215SJeff Kirsher goto err_out; 1703aa43c215SJeff Kirsher } 1704aa43c215SJeff Kirsher err = qlcnic_set_mgmt_operations(adapter); 1705aa43c215SJeff Kirsher if (err) 1706aa43c215SJeff Kirsher goto err_out; 1707aa43c215SJeff Kirsher 1708aa43c215SJeff Kirsher qlcnic_check_options(adapter); 1709aa43c215SJeff Kirsher adapter->need_fw_reset = 0; 1710aa43c215SJeff Kirsher 1711aa43c215SJeff Kirsher qlcnic_release_firmware(adapter); 1712aa43c215SJeff Kirsher return 0; 1713aa43c215SJeff Kirsher 1714aa43c215SJeff Kirsher err_out: 1715a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_FAILED); 1716aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, "Device state set to failed\n"); 1717aa43c215SJeff Kirsher 1718aa43c215SJeff Kirsher qlcnic_release_firmware(adapter); 1719aa43c215SJeff Kirsher return err; 1720aa43c215SJeff Kirsher } 1721aa43c215SJeff Kirsher 1722aa43c215SJeff Kirsher static int 1723aa43c215SJeff Kirsher qlcnic_request_irq(struct qlcnic_adapter *adapter) 1724aa43c215SJeff Kirsher { 1725aa43c215SJeff Kirsher irq_handler_t handler; 1726aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring; 172713159183SSony Chacko struct qlcnic_host_tx_ring *tx_ring; 1728ddb2e174SHimanshu Madhani int err, ring, num_sds_rings; 1729aa43c215SJeff Kirsher 1730aa43c215SJeff Kirsher unsigned long flags = 0; 1731aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 1732aa43c215SJeff Kirsher struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; 1733aa43c215SJeff Kirsher 173479788450SSony Chacko if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { 173513159183SSony Chacko if (qlcnic_82xx_check(adapter)) 1736aa43c215SJeff Kirsher handler = qlcnic_tmp_intr; 1737c2534384SManish Chopra else 1738c2534384SManish Chopra handler = qlcnic_83xx_tmp_intr; 1739aa43c215SJeff Kirsher if (!QLCNIC_IS_MSI_FAMILY(adapter)) 1740aa43c215SJeff Kirsher flags |= IRQF_SHARED; 1741aa43c215SJeff Kirsher 1742aa43c215SJeff Kirsher } else { 1743aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_MSIX_ENABLED) 1744aa43c215SJeff Kirsher handler = qlcnic_msix_intr; 1745aa43c215SJeff Kirsher else if (adapter->flags & QLCNIC_MSI_ENABLED) 1746aa43c215SJeff Kirsher handler = qlcnic_msi_intr; 1747aa43c215SJeff Kirsher else { 1748aa43c215SJeff Kirsher flags |= IRQF_SHARED; 1749ac166700SHimanshu Madhani if (qlcnic_82xx_check(adapter)) 1750aa43c215SJeff Kirsher handler = qlcnic_intr; 1751ac166700SHimanshu Madhani else 1752ac166700SHimanshu Madhani handler = qlcnic_83xx_intr; 1753aa43c215SJeff Kirsher } 1754aa43c215SJeff Kirsher } 1755aa43c215SJeff Kirsher adapter->irq = netdev->irq; 1756aa43c215SJeff Kirsher 175713159183SSony Chacko if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST) { 1758ac166700SHimanshu Madhani if (qlcnic_82xx_check(adapter) || 1759ac166700SHimanshu Madhani (qlcnic_83xx_check(adapter) && 1760ac166700SHimanshu Madhani (adapter->flags & QLCNIC_MSIX_ENABLED))) { 176134e8c406SHimanshu Madhani num_sds_rings = adapter->drv_sds_rings; 1762ddb2e174SHimanshu Madhani for (ring = 0; ring < num_sds_rings; ring++) { 1763aa43c215SJeff Kirsher sds_ring = &recv_ctx->sds_rings[ring]; 1764ddb2e174SHimanshu Madhani if (qlcnic_82xx_check(adapter) && 1765012ec812SHimanshu Madhani !qlcnic_check_multi_tx(adapter) && 1766aa2a8034SHimanshu Madhani (ring == (num_sds_rings - 1))) { 1767aa2a8034SHimanshu Madhani if (!(adapter->flags & 1768aa2a8034SHimanshu Madhani QLCNIC_MSIX_ENABLED)) 1769ddb2e174SHimanshu Madhani snprintf(sds_ring->name, 1770ddb2e174SHimanshu Madhani sizeof(sds_ring->name), 1771aa2a8034SHimanshu Madhani "qlcnic"); 1772ddb2e174SHimanshu Madhani else 1773ddb2e174SHimanshu Madhani snprintf(sds_ring->name, 1774ddb2e174SHimanshu Madhani sizeof(sds_ring->name), 1775aa2a8034SHimanshu Madhani "%s-tx-0-rx-%d", 1776ddb2e174SHimanshu Madhani netdev->name, ring); 1777aa2a8034SHimanshu Madhani } else { 1778aa2a8034SHimanshu Madhani snprintf(sds_ring->name, 1779aa2a8034SHimanshu Madhani sizeof(sds_ring->name), 1780aa2a8034SHimanshu Madhani "%s-rx-%d", 1781aa2a8034SHimanshu Madhani netdev->name, ring); 1782aa2a8034SHimanshu Madhani } 178313159183SSony Chacko err = request_irq(sds_ring->irq, handler, flags, 178413159183SSony Chacko sds_ring->name, sds_ring); 1785aa43c215SJeff Kirsher if (err) 1786aa43c215SJeff Kirsher return err; 1787aa43c215SJeff Kirsher } 1788ac166700SHimanshu Madhani } 1789012ec812SHimanshu Madhani if ((qlcnic_82xx_check(adapter) && 1790012ec812SHimanshu Madhani qlcnic_check_multi_tx(adapter)) || 1791012ec812SHimanshu Madhani (qlcnic_83xx_check(adapter) && 1792da6c8063SRajesh Borundia (adapter->flags & QLCNIC_MSIX_ENABLED) && 1793012ec812SHimanshu Madhani !(adapter->flags & QLCNIC_TX_INTR_SHARED))) { 179413159183SSony Chacko handler = qlcnic_msix_tx_intr; 179534e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; 179613159183SSony Chacko ring++) { 179713159183SSony Chacko tx_ring = &adapter->tx_ring[ring]; 1798ddb2e174SHimanshu Madhani snprintf(tx_ring->name, sizeof(tx_ring->name), 1799aa2a8034SHimanshu Madhani "%s-tx-%d", netdev->name, ring); 180013159183SSony Chacko err = request_irq(tx_ring->irq, handler, flags, 180113159183SSony Chacko tx_ring->name, tx_ring); 180213159183SSony Chacko if (err) 180313159183SSony Chacko return err; 180413159183SSony Chacko } 180513159183SSony Chacko } 180613159183SSony Chacko } 1807aa43c215SJeff Kirsher return 0; 1808aa43c215SJeff Kirsher } 1809aa43c215SJeff Kirsher 1810aa43c215SJeff Kirsher static void 1811aa43c215SJeff Kirsher qlcnic_free_irq(struct qlcnic_adapter *adapter) 1812aa43c215SJeff Kirsher { 1813aa43c215SJeff Kirsher int ring; 1814aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring; 181513159183SSony Chacko struct qlcnic_host_tx_ring *tx_ring; 1816aa43c215SJeff Kirsher 1817aa43c215SJeff Kirsher struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; 1818aa43c215SJeff Kirsher 181913159183SSony Chacko if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST) { 1820ac166700SHimanshu Madhani if (qlcnic_82xx_check(adapter) || 1821ac166700SHimanshu Madhani (qlcnic_83xx_check(adapter) && 1822ac166700SHimanshu Madhani (adapter->flags & QLCNIC_MSIX_ENABLED))) { 182334e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 1824aa43c215SJeff Kirsher sds_ring = &recv_ctx->sds_rings[ring]; 1825aa43c215SJeff Kirsher free_irq(sds_ring->irq, sds_ring); 1826aa43c215SJeff Kirsher } 1827ac166700SHimanshu Madhani } 1828012ec812SHimanshu Madhani if ((qlcnic_83xx_check(adapter) && 1829012ec812SHimanshu Madhani !(adapter->flags & QLCNIC_TX_INTR_SHARED)) || 1830012ec812SHimanshu Madhani (qlcnic_82xx_check(adapter) && 1831012ec812SHimanshu Madhani qlcnic_check_multi_tx(adapter))) { 183234e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; 183313159183SSony Chacko ring++) { 183413159183SSony Chacko tx_ring = &adapter->tx_ring[ring]; 183513159183SSony Chacko if (tx_ring->irq) 183613159183SSony Chacko free_irq(tx_ring->irq, tx_ring); 183713159183SSony Chacko } 183813159183SSony Chacko } 183913159183SSony Chacko } 1840aa43c215SJeff Kirsher } 1841aa43c215SJeff Kirsher 184299e85879SShahed Shaikh static void qlcnic_get_lro_mss_capability(struct qlcnic_adapter *adapter) 184399e85879SShahed Shaikh { 184499e85879SShahed Shaikh u32 capab = 0; 184599e85879SShahed Shaikh 184699e85879SShahed Shaikh if (qlcnic_82xx_check(adapter)) { 1847db131786SPratik Pujar if (adapter->ahw->extra_capability[0] & 184899e85879SShahed Shaikh QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG) 184999e85879SShahed Shaikh adapter->flags |= QLCNIC_FW_LRO_MSS_CAP; 185099e85879SShahed Shaikh } else { 185199e85879SShahed Shaikh capab = adapter->ahw->capabilities; 185299e85879SShahed Shaikh if (QLC_83XX_GET_FW_LRO_MSS_CAPABILITY(capab)) 185399e85879SShahed Shaikh adapter->flags |= QLCNIC_FW_LRO_MSS_CAP; 185499e85879SShahed Shaikh } 185599e85879SShahed Shaikh } 185699e85879SShahed Shaikh 1857a514722aSHimanshu Madhani static int qlcnic_config_def_intr_coalesce(struct qlcnic_adapter *adapter) 1858a514722aSHimanshu Madhani { 1859a514722aSHimanshu Madhani struct qlcnic_hardware_context *ahw = adapter->ahw; 1860a514722aSHimanshu Madhani int err; 1861a514722aSHimanshu Madhani 1862a514722aSHimanshu Madhani /* Initialize interrupt coalesce parameters */ 1863a514722aSHimanshu Madhani ahw->coal.flag = QLCNIC_INTR_DEFAULT; 1864a514722aSHimanshu Madhani 1865a514722aSHimanshu Madhani if (qlcnic_83xx_check(adapter)) { 1866a514722aSHimanshu Madhani ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX_TX; 1867a514722aSHimanshu Madhani ahw->coal.tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US; 1868a514722aSHimanshu Madhani ahw->coal.tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS; 1869a514722aSHimanshu Madhani ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US; 1870a514722aSHimanshu Madhani ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS; 1871a514722aSHimanshu Madhani 1872a514722aSHimanshu Madhani err = qlcnic_83xx_set_rx_tx_intr_coal(adapter); 1873a514722aSHimanshu Madhani } else { 1874a514722aSHimanshu Madhani ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX; 1875a514722aSHimanshu Madhani ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US; 1876a514722aSHimanshu Madhani ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS; 1877a514722aSHimanshu Madhani 1878a514722aSHimanshu Madhani err = qlcnic_82xx_set_rx_coalesce(adapter); 1879a514722aSHimanshu Madhani } 1880a514722aSHimanshu Madhani 1881a514722aSHimanshu Madhani return err; 1882a514722aSHimanshu Madhani } 1883a514722aSHimanshu Madhani 1884319ecf12SSony Chacko int __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) 1885aa43c215SJeff Kirsher { 1886aa43c215SJeff Kirsher int ring; 1887aa43c215SJeff Kirsher struct qlcnic_host_rds_ring *rds_ring; 1888aa43c215SJeff Kirsher 1889aa43c215SJeff Kirsher if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) 1890aa43c215SJeff Kirsher return -EIO; 1891aa43c215SJeff Kirsher 1892aa43c215SJeff Kirsher if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) 1893aa43c215SJeff Kirsher return 0; 1894012ec812SHimanshu Madhani 1895aa43c215SJeff Kirsher if (qlcnic_set_eswitch_port_config(adapter)) 1896aa43c215SJeff Kirsher return -EIO; 1897012ec812SHimanshu Madhani 189899e85879SShahed Shaikh qlcnic_get_lro_mss_capability(adapter); 1899cae82d49SRajesh Borundia 1900aa43c215SJeff Kirsher if (qlcnic_fw_create_ctx(adapter)) 1901aa43c215SJeff Kirsher return -EIO; 1902aa43c215SJeff Kirsher 1903aa43c215SJeff Kirsher for (ring = 0; ring < adapter->max_rds_rings; ring++) { 1904aa43c215SJeff Kirsher rds_ring = &adapter->recv_ctx->rds_rings[ring]; 19054be41e92SSony Chacko qlcnic_post_rx_buffers(adapter, rds_ring, ring); 1906aa43c215SJeff Kirsher } 1907aa43c215SJeff Kirsher 1908aa43c215SJeff Kirsher qlcnic_set_multi(netdev); 1909aa43c215SJeff Kirsher qlcnic_fw_cmd_set_mtu(adapter, netdev->mtu); 1910aa43c215SJeff Kirsher 1911aa43c215SJeff Kirsher adapter->ahw->linkup = 0; 1912aa43c215SJeff Kirsher 191334e8c406SHimanshu Madhani if (adapter->drv_sds_rings > 1) 1914aa43c215SJeff Kirsher qlcnic_config_rss(adapter, 1); 1915aa43c215SJeff Kirsher 1916a514722aSHimanshu Madhani qlcnic_config_def_intr_coalesce(adapter); 1917aa43c215SJeff Kirsher 1918aa43c215SJeff Kirsher if (netdev->features & NETIF_F_LRO) 1919aa43c215SJeff Kirsher qlcnic_config_hw_lro(adapter, QLCNIC_LRO_ENABLED); 1920aa43c215SJeff Kirsher 1921cfacb172SPratik Pujar set_bit(__QLCNIC_DEV_UP, &adapter->state); 1922aa43c215SJeff Kirsher qlcnic_napi_enable(adapter); 1923aa43c215SJeff Kirsher 1924aa43c215SJeff Kirsher qlcnic_linkevent_request(adapter, 1); 1925aa43c215SJeff Kirsher 192679788450SSony Chacko adapter->ahw->reset_context = 0; 1927060d0564SRajesh Borundia netif_tx_start_all_queues(netdev); 1928aa43c215SJeff Kirsher return 0; 1929aa43c215SJeff Kirsher } 1930aa43c215SJeff Kirsher 1931629263acSSony Chacko int qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) 1932aa43c215SJeff Kirsher { 1933aa43c215SJeff Kirsher int err = 0; 1934aa43c215SJeff Kirsher 1935aa43c215SJeff Kirsher rtnl_lock(); 1936aa43c215SJeff Kirsher if (netif_running(netdev)) 1937aa43c215SJeff Kirsher err = __qlcnic_up(adapter, netdev); 1938aa43c215SJeff Kirsher rtnl_unlock(); 1939aa43c215SJeff Kirsher 1940aa43c215SJeff Kirsher return err; 1941aa43c215SJeff Kirsher } 1942aa43c215SJeff Kirsher 1943319ecf12SSony Chacko void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) 1944aa43c215SJeff Kirsher { 1945012ec812SHimanshu Madhani int ring; 1946012ec812SHimanshu Madhani 1947aa43c215SJeff Kirsher if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) 1948aa43c215SJeff Kirsher return; 1949aa43c215SJeff Kirsher 1950aa43c215SJeff Kirsher if (!test_and_clear_bit(__QLCNIC_DEV_UP, &adapter->state)) 1951aa43c215SJeff Kirsher return; 1952aa43c215SJeff Kirsher 1953aa43c215SJeff Kirsher smp_mb(); 1954aa43c215SJeff Kirsher netif_carrier_off(netdev); 19550a46bac0SShahed Shaikh adapter->ahw->linkup = 0; 1956aa43c215SJeff Kirsher netif_tx_disable(netdev); 1957aa43c215SJeff Kirsher 1958aa43c215SJeff Kirsher qlcnic_free_mac_list(adapter); 1959aa43c215SJeff Kirsher 1960aa43c215SJeff Kirsher if (adapter->fhash.fnum) 1961aa43c215SJeff Kirsher qlcnic_delete_lb_filters(adapter); 1962aa43c215SJeff Kirsher 1963aa43c215SJeff Kirsher qlcnic_nic_set_promisc(adapter, QLCNIC_NIU_NON_PROMISC_MODE); 196474b7ba1aSRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) 196574b7ba1aSRajesh Borundia qlcnic_sriov_cleanup_async_list(&adapter->ahw->sriov->bc); 1966aa43c215SJeff Kirsher 1967aa43c215SJeff Kirsher qlcnic_napi_disable(adapter); 1968aa43c215SJeff Kirsher 1969aa43c215SJeff Kirsher qlcnic_fw_destroy_ctx(adapter); 1970cae82d49SRajesh Borundia adapter->flags &= ~QLCNIC_FW_LRO_MSS_CAP; 1971aa43c215SJeff Kirsher 1972aa43c215SJeff Kirsher qlcnic_reset_rx_buffers_list(adapter); 1973012ec812SHimanshu Madhani 197434e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; ring++) 1975012ec812SHimanshu Madhani qlcnic_release_tx_buffers(adapter, &adapter->tx_ring[ring]); 1976aa43c215SJeff Kirsher } 1977aa43c215SJeff Kirsher 1978aa43c215SJeff Kirsher /* Usage: During suspend and firmware recovery module */ 1979aa43c215SJeff Kirsher 1980629263acSSony Chacko void qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) 1981aa43c215SJeff Kirsher { 1982aa43c215SJeff Kirsher rtnl_lock(); 1983aa43c215SJeff Kirsher if (netif_running(netdev)) 1984aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 1985aa43c215SJeff Kirsher rtnl_unlock(); 1986aa43c215SJeff Kirsher 1987aa43c215SJeff Kirsher } 1988aa43c215SJeff Kirsher 1989319ecf12SSony Chacko int 1990aa43c215SJeff Kirsher qlcnic_attach(struct qlcnic_adapter *adapter) 1991aa43c215SJeff Kirsher { 1992aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 1993aa43c215SJeff Kirsher struct pci_dev *pdev = adapter->pdev; 1994aa43c215SJeff Kirsher int err; 1995aa43c215SJeff Kirsher 1996aa43c215SJeff Kirsher if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC) 1997aa43c215SJeff Kirsher return 0; 1998aa43c215SJeff Kirsher 1999aa43c215SJeff Kirsher err = qlcnic_napi_add(adapter, netdev); 2000aa43c215SJeff Kirsher if (err) 2001aa43c215SJeff Kirsher return err; 2002aa43c215SJeff Kirsher 2003aa43c215SJeff Kirsher err = qlcnic_alloc_sw_resources(adapter); 2004aa43c215SJeff Kirsher if (err) { 2005aa43c215SJeff Kirsher dev_err(&pdev->dev, "Error in setting sw resources\n"); 2006aa43c215SJeff Kirsher goto err_out_napi_del; 2007aa43c215SJeff Kirsher } 2008aa43c215SJeff Kirsher 2009aa43c215SJeff Kirsher err = qlcnic_alloc_hw_resources(adapter); 2010aa43c215SJeff Kirsher if (err) { 2011aa43c215SJeff Kirsher dev_err(&pdev->dev, "Error in setting hw resources\n"); 2012aa43c215SJeff Kirsher goto err_out_free_sw; 2013aa43c215SJeff Kirsher } 2014aa43c215SJeff Kirsher 2015aa43c215SJeff Kirsher err = qlcnic_request_irq(adapter); 2016aa43c215SJeff Kirsher if (err) { 2017aa43c215SJeff Kirsher dev_err(&pdev->dev, "failed to setup interrupt\n"); 2018aa43c215SJeff Kirsher goto err_out_free_hw; 2019aa43c215SJeff Kirsher } 2020aa43c215SJeff Kirsher 2021aa43c215SJeff Kirsher qlcnic_create_sysfs_entries(adapter); 2022aa43c215SJeff Kirsher 20232b3d7b75SShahed Shaikh if (qlcnic_encap_rx_offload(adapter)) 20245e44f8e2SAlexander Duyck udp_tunnel_get_rx_info(netdev); 20252b3d7b75SShahed Shaikh 2026aa43c215SJeff Kirsher adapter->is_up = QLCNIC_ADAPTER_UP_MAGIC; 2027aa43c215SJeff Kirsher return 0; 2028aa43c215SJeff Kirsher 2029aa43c215SJeff Kirsher err_out_free_hw: 2030aa43c215SJeff Kirsher qlcnic_free_hw_resources(adapter); 2031aa43c215SJeff Kirsher err_out_free_sw: 2032aa43c215SJeff Kirsher qlcnic_free_sw_resources(adapter); 2033aa43c215SJeff Kirsher err_out_napi_del: 2034aa43c215SJeff Kirsher qlcnic_napi_del(adapter); 2035aa43c215SJeff Kirsher return err; 2036aa43c215SJeff Kirsher } 2037aa43c215SJeff Kirsher 2038319ecf12SSony Chacko void qlcnic_detach(struct qlcnic_adapter *adapter) 2039aa43c215SJeff Kirsher { 2040aa43c215SJeff Kirsher if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) 2041aa43c215SJeff Kirsher return; 2042aa43c215SJeff Kirsher 2043aa43c215SJeff Kirsher qlcnic_remove_sysfs_entries(adapter); 2044aa43c215SJeff Kirsher 2045aa43c215SJeff Kirsher qlcnic_free_hw_resources(adapter); 2046aa43c215SJeff Kirsher qlcnic_release_rx_buffers(adapter); 2047aa43c215SJeff Kirsher qlcnic_free_irq(adapter); 2048aa43c215SJeff Kirsher qlcnic_napi_del(adapter); 2049aa43c215SJeff Kirsher qlcnic_free_sw_resources(adapter); 2050aa43c215SJeff Kirsher 2051aa43c215SJeff Kirsher adapter->is_up = 0; 2052aa43c215SJeff Kirsher } 2053aa43c215SJeff Kirsher 205434e8c406SHimanshu Madhani void qlcnic_diag_free_res(struct net_device *netdev, int drv_sds_rings) 2055aa43c215SJeff Kirsher { 2056aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 2057aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring; 205834e8c406SHimanshu Madhani int drv_tx_rings = adapter->drv_tx_rings; 2059aa43c215SJeff Kirsher int ring; 2060aa43c215SJeff Kirsher 2061aa43c215SJeff Kirsher clear_bit(__QLCNIC_DEV_UP, &adapter->state); 206279788450SSony Chacko if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { 206334e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 2064aa43c215SJeff Kirsher sds_ring = &adapter->recv_ctx->sds_rings[ring]; 20652cc5752eSManish chopra qlcnic_disable_sds_intr(adapter, sds_ring); 2066aa43c215SJeff Kirsher } 2067aa43c215SJeff Kirsher } 2068aa43c215SJeff Kirsher 2069aa43c215SJeff Kirsher qlcnic_fw_destroy_ctx(adapter); 2070aa43c215SJeff Kirsher 2071aa43c215SJeff Kirsher qlcnic_detach(adapter); 2072aa43c215SJeff Kirsher 207379788450SSony Chacko adapter->ahw->diag_test = 0; 207434e8c406SHimanshu Madhani adapter->drv_sds_rings = drv_sds_rings; 207534e8c406SHimanshu Madhani adapter->drv_tx_rings = drv_tx_rings; 2076aa43c215SJeff Kirsher 2077aa43c215SJeff Kirsher if (qlcnic_attach(adapter)) 2078aa43c215SJeff Kirsher goto out; 2079aa43c215SJeff Kirsher 2080aa43c215SJeff Kirsher if (netif_running(netdev)) 2081aa43c215SJeff Kirsher __qlcnic_up(adapter, netdev); 2082aa43c215SJeff Kirsher out: 2083aa43c215SJeff Kirsher netif_device_attach(netdev); 2084aa43c215SJeff Kirsher } 2085aa43c215SJeff Kirsher 2086aa43c215SJeff Kirsher static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) 2087aa43c215SJeff Kirsher { 2088868e9144SSucheta Chakraborty struct qlcnic_hardware_context *ahw = adapter->ahw; 2089aa43c215SJeff Kirsher int err = 0; 2090be273dc1SHimanshu Madhani 2091aa43c215SJeff Kirsher adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context), 2092aa43c215SJeff Kirsher GFP_KERNEL); 2093aa43c215SJeff Kirsher if (!adapter->recv_ctx) { 2094aa43c215SJeff Kirsher err = -ENOMEM; 2095aa43c215SJeff Kirsher goto err_out; 2096aa43c215SJeff Kirsher } 2097a514722aSHimanshu Madhani 2098868e9144SSucheta Chakraborty if (qlcnic_83xx_check(adapter)) { 2099868e9144SSucheta Chakraborty ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX_TX; 2100868e9144SSucheta Chakraborty ahw->coal.tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US; 2101868e9144SSucheta Chakraborty ahw->coal.tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS; 2102868e9144SSucheta Chakraborty ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US; 2103868e9144SSucheta Chakraborty ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS; 2104868e9144SSucheta Chakraborty } else { 2105868e9144SSucheta Chakraborty ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX; 2106868e9144SSucheta Chakraborty ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US; 2107868e9144SSucheta Chakraborty ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS; 2108868e9144SSucheta Chakraborty } 2109868e9144SSucheta Chakraborty 21104be41e92SSony Chacko /* clear stats */ 21114be41e92SSony Chacko memset(&adapter->stats, 0, sizeof(adapter->stats)); 2112aa43c215SJeff Kirsher err_out: 2113aa43c215SJeff Kirsher return err; 2114aa43c215SJeff Kirsher } 2115aa43c215SJeff Kirsher 2116aa43c215SJeff Kirsher static void qlcnic_free_adapter_resources(struct qlcnic_adapter *adapter) 2117aa43c215SJeff Kirsher { 21184da005cfSShahed Shaikh struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump; 21194da005cfSShahed Shaikh 2120aa43c215SJeff Kirsher kfree(adapter->recv_ctx); 2121aa43c215SJeff Kirsher adapter->recv_ctx = NULL; 2122aa43c215SJeff Kirsher 21234da005cfSShahed Shaikh if (fw_dump->tmpl_hdr) { 21244da005cfSShahed Shaikh vfree(fw_dump->tmpl_hdr); 21254da005cfSShahed Shaikh fw_dump->tmpl_hdr = NULL; 21264da005cfSShahed Shaikh } 21274da005cfSShahed Shaikh 21284da005cfSShahed Shaikh if (fw_dump->dma_buffer) { 21294da005cfSShahed Shaikh dma_free_coherent(&adapter->pdev->dev, QLC_PEX_DMA_READ_SIZE, 21304da005cfSShahed Shaikh fw_dump->dma_buffer, fw_dump->phys_addr); 21314da005cfSShahed Shaikh fw_dump->dma_buffer = NULL; 2132aa43c215SJeff Kirsher } 21334be41e92SSony Chacko 213481d0aeb0SSony Chacko kfree(adapter->ahw->reset.buff); 21354be41e92SSony Chacko adapter->ahw->fw_dump.tmpl_hdr = NULL; 2136aa43c215SJeff Kirsher } 2137aa43c215SJeff Kirsher 2138aa43c215SJeff Kirsher int qlcnic_diag_alloc_res(struct net_device *netdev, int test) 2139aa43c215SJeff Kirsher { 2140aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 2141aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring; 2142aa43c215SJeff Kirsher struct qlcnic_host_rds_ring *rds_ring; 2143aa43c215SJeff Kirsher int ring; 2144aa43c215SJeff Kirsher int ret; 2145aa43c215SJeff Kirsher 2146aa43c215SJeff Kirsher netif_device_detach(netdev); 2147aa43c215SJeff Kirsher 2148aa43c215SJeff Kirsher if (netif_running(netdev)) 2149aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 2150aa43c215SJeff Kirsher 2151aa43c215SJeff Kirsher qlcnic_detach(adapter); 2152aa43c215SJeff Kirsher 215334e8c406SHimanshu Madhani adapter->drv_sds_rings = QLCNIC_SINGLE_RING; 215479788450SSony Chacko adapter->ahw->diag_test = test; 21554be41e92SSony Chacko adapter->ahw->linkup = 0; 2156aa43c215SJeff Kirsher 2157aa43c215SJeff Kirsher ret = qlcnic_attach(adapter); 2158aa43c215SJeff Kirsher if (ret) { 2159aa43c215SJeff Kirsher netif_device_attach(netdev); 2160aa43c215SJeff Kirsher return ret; 2161aa43c215SJeff Kirsher } 2162aa43c215SJeff Kirsher 2163aa43c215SJeff Kirsher ret = qlcnic_fw_create_ctx(adapter); 2164aa43c215SJeff Kirsher if (ret) { 2165aa43c215SJeff Kirsher qlcnic_detach(adapter); 2166aa43c215SJeff Kirsher netif_device_attach(netdev); 2167aa43c215SJeff Kirsher return ret; 2168aa43c215SJeff Kirsher } 2169aa43c215SJeff Kirsher 2170aa43c215SJeff Kirsher for (ring = 0; ring < adapter->max_rds_rings; ring++) { 2171aa43c215SJeff Kirsher rds_ring = &adapter->recv_ctx->rds_rings[ring]; 21724be41e92SSony Chacko qlcnic_post_rx_buffers(adapter, rds_ring, ring); 2173aa43c215SJeff Kirsher } 2174aa43c215SJeff Kirsher 217579788450SSony Chacko if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { 217634e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 2177aa43c215SJeff Kirsher sds_ring = &adapter->recv_ctx->sds_rings[ring]; 21782cc5752eSManish chopra qlcnic_enable_sds_intr(adapter, sds_ring); 2179aa43c215SJeff Kirsher } 2180aa43c215SJeff Kirsher } 2181aa43c215SJeff Kirsher 218279788450SSony Chacko if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) { 2183aa43c215SJeff Kirsher adapter->ahw->loopback_state = 0; 2184aa43c215SJeff Kirsher qlcnic_linkevent_request(adapter, 1); 2185aa43c215SJeff Kirsher } 2186aa43c215SJeff Kirsher 2187aa43c215SJeff Kirsher set_bit(__QLCNIC_DEV_UP, &adapter->state); 2188aa43c215SJeff Kirsher 2189aa43c215SJeff Kirsher return 0; 2190aa43c215SJeff Kirsher } 2191aa43c215SJeff Kirsher 2192aa43c215SJeff Kirsher /* Reset context in hardware only */ 2193aa43c215SJeff Kirsher static int 2194aa43c215SJeff Kirsher qlcnic_reset_hw_context(struct qlcnic_adapter *adapter) 2195aa43c215SJeff Kirsher { 2196aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 2197aa43c215SJeff Kirsher 2198aa43c215SJeff Kirsher if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) 2199aa43c215SJeff Kirsher return -EBUSY; 2200aa43c215SJeff Kirsher 2201aa43c215SJeff Kirsher netif_device_detach(netdev); 2202aa43c215SJeff Kirsher 2203aa43c215SJeff Kirsher qlcnic_down(adapter, netdev); 2204aa43c215SJeff Kirsher 2205aa43c215SJeff Kirsher qlcnic_up(adapter, netdev); 2206aa43c215SJeff Kirsher 2207aa43c215SJeff Kirsher netif_device_attach(netdev); 2208aa43c215SJeff Kirsher 2209aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 221095b3890aSHimanshu Madhani netdev_info(adapter->netdev, "%s: soft reset complete\n", __func__); 2211aa43c215SJeff Kirsher return 0; 2212aa43c215SJeff Kirsher } 2213aa43c215SJeff Kirsher 2214aa43c215SJeff Kirsher int 2215aa43c215SJeff Kirsher qlcnic_reset_context(struct qlcnic_adapter *adapter) 2216aa43c215SJeff Kirsher { 2217aa43c215SJeff Kirsher int err = 0; 2218aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 2219aa43c215SJeff Kirsher 2220aa43c215SJeff Kirsher if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) 2221aa43c215SJeff Kirsher return -EBUSY; 2222aa43c215SJeff Kirsher 2223aa43c215SJeff Kirsher if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC) { 2224aa43c215SJeff Kirsher 2225aa43c215SJeff Kirsher netif_device_detach(netdev); 2226aa43c215SJeff Kirsher 2227aa43c215SJeff Kirsher if (netif_running(netdev)) 2228aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 2229aa43c215SJeff Kirsher 2230aa43c215SJeff Kirsher qlcnic_detach(adapter); 2231aa43c215SJeff Kirsher 2232aa43c215SJeff Kirsher if (netif_running(netdev)) { 2233aa43c215SJeff Kirsher err = qlcnic_attach(adapter); 22341d5c88e3SAnirban Chakraborty if (!err) { 2235aa43c215SJeff Kirsher __qlcnic_up(adapter, netdev); 22361d5c88e3SAnirban Chakraborty qlcnic_restore_indev_addr(netdev, NETDEV_UP); 22371d5c88e3SAnirban Chakraborty } 2238aa43c215SJeff Kirsher } 2239aa43c215SJeff Kirsher 2240aa43c215SJeff Kirsher netif_device_attach(netdev); 2241aa43c215SJeff Kirsher } 2242aa43c215SJeff Kirsher 2243aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 2244aa43c215SJeff Kirsher return err; 2245aa43c215SJeff Kirsher } 2246aa43c215SJeff Kirsher 224721041400Sstephen hemminger static void qlcnic_82xx_set_mac_filter_count(struct qlcnic_adapter *adapter) 224852e493d0SJitendra Kalsaria { 224952e493d0SJitendra Kalsaria struct qlcnic_hardware_context *ahw = adapter->ahw; 22502f514c52SJitendra Kalsaria u16 act_pci_fn = ahw->total_nic_func; 225152e493d0SJitendra Kalsaria u16 count; 225252e493d0SJitendra Kalsaria 225352e493d0SJitendra Kalsaria ahw->max_mc_count = QLCNIC_MAX_MC_COUNT; 225452e493d0SJitendra Kalsaria if (act_pci_fn <= 2) 225552e493d0SJitendra Kalsaria count = (QLCNIC_MAX_UC_COUNT - QLCNIC_MAX_MC_COUNT) / 225652e493d0SJitendra Kalsaria act_pci_fn; 225752e493d0SJitendra Kalsaria else 225852e493d0SJitendra Kalsaria count = (QLCNIC_LB_MAX_FILTERS - QLCNIC_MAX_MC_COUNT) / 225952e493d0SJitendra Kalsaria act_pci_fn; 226052e493d0SJitendra Kalsaria ahw->max_uc_count = count; 226152e493d0SJitendra Kalsaria } 226252e493d0SJitendra Kalsaria 226384d7ad2cSShahed Shaikh static int qlcnic_set_real_num_queues(struct qlcnic_adapter *adapter, 226484d7ad2cSShahed Shaikh u8 tx_queues, u8 rx_queues) 226584d7ad2cSShahed Shaikh { 226684d7ad2cSShahed Shaikh struct net_device *netdev = adapter->netdev; 226784d7ad2cSShahed Shaikh int err = 0; 226884d7ad2cSShahed Shaikh 226984d7ad2cSShahed Shaikh if (tx_queues) { 227084d7ad2cSShahed Shaikh err = netif_set_real_num_tx_queues(netdev, tx_queues); 227184d7ad2cSShahed Shaikh if (err) { 227284d7ad2cSShahed Shaikh netdev_err(netdev, "failed to set %d Tx queues\n", 227384d7ad2cSShahed Shaikh tx_queues); 227484d7ad2cSShahed Shaikh return err; 227584d7ad2cSShahed Shaikh } 227684d7ad2cSShahed Shaikh } 227784d7ad2cSShahed Shaikh 227884d7ad2cSShahed Shaikh if (rx_queues) { 227984d7ad2cSShahed Shaikh err = netif_set_real_num_rx_queues(netdev, rx_queues); 228084d7ad2cSShahed Shaikh if (err) 228184d7ad2cSShahed Shaikh netdev_err(netdev, "failed to set %d Rx queues\n", 228284d7ad2cSShahed Shaikh rx_queues); 228384d7ad2cSShahed Shaikh } 228484d7ad2cSShahed Shaikh 228584d7ad2cSShahed Shaikh return err; 228684d7ad2cSShahed Shaikh } 228784d7ad2cSShahed Shaikh 2288f8468331SRajesh Borundia int 22895ad6ff9dSSony Chacko qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev, 22905ad6ff9dSSony Chacko int pci_using_dac) 2291aa43c215SJeff Kirsher { 2292aa43c215SJeff Kirsher int err; 2293aa43c215SJeff Kirsher struct pci_dev *pdev = adapter->pdev; 2294aa43c215SJeff Kirsher 229513159183SSony Chacko adapter->rx_csum = 1; 229679788450SSony Chacko adapter->ahw->mc_enabled = 0; 229752e493d0SJitendra Kalsaria qlcnic_set_mac_filter_count(adapter); 2298aa43c215SJeff Kirsher 2299aa43c215SJeff Kirsher netdev->netdev_ops = &qlcnic_netdev_ops; 230013159183SSony Chacko netdev->watchdog_timeo = QLCNIC_WATCHDOG_TIMEOUTVALUE * HZ; 2301aa43c215SJeff Kirsher 2302aa43c215SJeff Kirsher qlcnic_change_mtu(netdev, netdev->mtu); 2303aa43c215SJeff Kirsher 23047ad24ea4SWilfried Klaebe netdev->ethtool_ops = (qlcnic_sriov_vf_check(adapter)) ? 23057ad24ea4SWilfried Klaebe &qlcnic_sriov_vf_ethtool_ops : &qlcnic_ethtool_ops; 2306aa43c215SJeff Kirsher 23077e38d04bSSony Chacko netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM | 230813159183SSony Chacko NETIF_F_IPV6_CSUM | NETIF_F_GRO | 2309f646968fSPatrick McHardy NETIF_F_HW_VLAN_CTAG_RX); 231013159183SSony Chacko netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | 231113159183SSony Chacko NETIF_F_IPV6_CSUM); 2312aa43c215SJeff Kirsher 231313159183SSony Chacko if (QLCNIC_IS_TSO_CAPABLE(adapter)) { 231413159183SSony Chacko netdev->features |= (NETIF_F_TSO | NETIF_F_TSO6); 231513159183SSony Chacko netdev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6); 231613159183SSony Chacko } 2317aa43c215SJeff Kirsher 231813159183SSony Chacko if (pci_using_dac) { 231913159183SSony Chacko netdev->features |= NETIF_F_HIGHDMA; 232013159183SSony Chacko netdev->vlan_features |= NETIF_F_HIGHDMA; 232113159183SSony Chacko } 2322aa43c215SJeff Kirsher 232313159183SSony Chacko if (qlcnic_vlan_tx_check(adapter)) 2324f646968fSPatrick McHardy netdev->features |= (NETIF_F_HW_VLAN_CTAG_TX); 232513159183SSony Chacko 232691b7282bSRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) 232791b7282bSRajesh Borundia netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; 232891b7282bSRajesh Borundia 232979788450SSony Chacko if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO) 233013159183SSony Chacko netdev->features |= NETIF_F_LRO; 2331aa43c215SJeff Kirsher 2332381709deSShahed Shaikh if (qlcnic_encap_tx_offload(adapter)) { 2333381709deSShahed Shaikh netdev->features |= NETIF_F_GSO_UDP_TUNNEL; 2334381709deSShahed Shaikh 2335381709deSShahed Shaikh /* encapsulation Tx offload supported by Adapter */ 2336381709deSShahed Shaikh netdev->hw_enc_features = NETIF_F_IP_CSUM | 2337381709deSShahed Shaikh NETIF_F_GSO_UDP_TUNNEL | 2338381709deSShahed Shaikh NETIF_F_TSO | 2339381709deSShahed Shaikh NETIF_F_TSO6; 2340381709deSShahed Shaikh } 2341381709deSShahed Shaikh 23422b3d7b75SShahed Shaikh if (qlcnic_encap_rx_offload(adapter)) 23432b3d7b75SShahed Shaikh netdev->hw_enc_features |= NETIF_F_RXCSUM; 23442b3d7b75SShahed Shaikh 23457e38d04bSSony Chacko netdev->hw_features = netdev->features; 234652e493d0SJitendra Kalsaria netdev->priv_flags |= IFF_UNICAST_FLT; 2347aa43c215SJeff Kirsher netdev->irq = adapter->msix_entries[0].vector; 2348aa43c215SJeff Kirsher 2349caff2a87SJarod Wilson /* MTU range: 68 - 9600 */ 2350caff2a87SJarod Wilson netdev->min_mtu = P3P_MIN_MTU; 2351caff2a87SJarod Wilson netdev->max_mtu = P3P_MAX_MTU; 2352caff2a87SJarod Wilson 235384d7ad2cSShahed Shaikh err = qlcnic_set_real_num_queues(adapter, adapter->drv_tx_rings, 235484d7ad2cSShahed Shaikh adapter->drv_sds_rings); 2355012ec812SHimanshu Madhani if (err) 2356012ec812SHimanshu Madhani return err; 2357012ec812SHimanshu Madhani 2358cd1560e2SRajesh Borundia qlcnic_dcb_init_dcbnl_ops(adapter->dcb); 2359cd1560e2SRajesh Borundia 2360aa43c215SJeff Kirsher err = register_netdev(netdev); 2361aa43c215SJeff Kirsher if (err) { 2362aa43c215SJeff Kirsher dev_err(&pdev->dev, "failed to register net device\n"); 2363aa43c215SJeff Kirsher return err; 2364aa43c215SJeff Kirsher } 2365aa43c215SJeff Kirsher 2366aa43c215SJeff Kirsher return 0; 2367aa43c215SJeff Kirsher } 2368aa43c215SJeff Kirsher 23695ad6ff9dSSony Chacko static int qlcnic_set_dma_mask(struct pci_dev *pdev, int *pci_using_dac) 2370aa43c215SJeff Kirsher { 2371aa43c215SJeff Kirsher if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && 2372aa43c215SJeff Kirsher !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) 2373aa43c215SJeff Kirsher *pci_using_dac = 1; 2374aa43c215SJeff Kirsher else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) && 2375aa43c215SJeff Kirsher !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) 2376aa43c215SJeff Kirsher *pci_using_dac = 0; 2377aa43c215SJeff Kirsher else { 2378aa43c215SJeff Kirsher dev_err(&pdev->dev, "Unable to set DMA mask, aborting\n"); 2379aa43c215SJeff Kirsher return -EIO; 2380aa43c215SJeff Kirsher } 2381aa43c215SJeff Kirsher 2382aa43c215SJeff Kirsher return 0; 2383aa43c215SJeff Kirsher } 2384aa43c215SJeff Kirsher 23854be41e92SSony Chacko void qlcnic_free_tx_rings(struct qlcnic_adapter *adapter) 23864be41e92SSony Chacko { 23874be41e92SSony Chacko int ring; 23884be41e92SSony Chacko struct qlcnic_host_tx_ring *tx_ring; 23894be41e92SSony Chacko 239034e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; ring++) { 23914be41e92SSony Chacko tx_ring = &adapter->tx_ring[ring]; 23927061b2bdSMarkus Elfring if (tx_ring) { 23934be41e92SSony Chacko vfree(tx_ring->cmd_buf_arr); 23944be41e92SSony Chacko tx_ring->cmd_buf_arr = NULL; 23954be41e92SSony Chacko } 23964be41e92SSony Chacko } 23974be41e92SSony Chacko kfree(adapter->tx_ring); 23984be41e92SSony Chacko } 23994be41e92SSony Chacko 24004be41e92SSony Chacko int qlcnic_alloc_tx_rings(struct qlcnic_adapter *adapter, 24014be41e92SSony Chacko struct net_device *netdev) 24024be41e92SSony Chacko { 2403b2adaca9SJoe Perches int ring, vector, index; 24044be41e92SSony Chacko struct qlcnic_host_tx_ring *tx_ring; 24054be41e92SSony Chacko struct qlcnic_cmd_buffer *cmd_buf_arr; 24064be41e92SSony Chacko 240734e8c406SHimanshu Madhani tx_ring = kcalloc(adapter->drv_tx_rings, 2408b2adaca9SJoe Perches sizeof(struct qlcnic_host_tx_ring), GFP_KERNEL); 2409b2adaca9SJoe Perches if (tx_ring == NULL) 24104be41e92SSony Chacko return -ENOMEM; 2411b2adaca9SJoe Perches 24124be41e92SSony Chacko adapter->tx_ring = tx_ring; 24134be41e92SSony Chacko 241434e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; ring++) { 24154be41e92SSony Chacko tx_ring = &adapter->tx_ring[ring]; 24164be41e92SSony Chacko tx_ring->num_desc = adapter->num_txd; 24174be41e92SSony Chacko tx_ring->txq = netdev_get_tx_queue(netdev, ring); 24184be41e92SSony Chacko cmd_buf_arr = vzalloc(TX_BUFF_RINGSIZE(tx_ring)); 24194be41e92SSony Chacko if (cmd_buf_arr == NULL) { 24204be41e92SSony Chacko qlcnic_free_tx_rings(adapter); 24214be41e92SSony Chacko return -ENOMEM; 24224be41e92SSony Chacko } 24234be41e92SSony Chacko tx_ring->cmd_buf_arr = cmd_buf_arr; 2424a02bdd42SShahed Shaikh spin_lock_init(&tx_ring->tx_clean_lock); 24254be41e92SSony Chacko } 24264be41e92SSony Chacko 2427012ec812SHimanshu Madhani if (qlcnic_83xx_check(adapter) || 2428012ec812SHimanshu Madhani (qlcnic_82xx_check(adapter) && qlcnic_check_multi_tx(adapter))) { 242934e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; ring++) { 24304be41e92SSony Chacko tx_ring = &adapter->tx_ring[ring]; 24314be41e92SSony Chacko tx_ring->adapter = adapter; 24324be41e92SSony Chacko if (adapter->flags & QLCNIC_MSIX_ENABLED) { 243334e8c406SHimanshu Madhani index = adapter->drv_sds_rings + ring; 24344be41e92SSony Chacko vector = adapter->msix_entries[index].vector; 24354be41e92SSony Chacko tx_ring->irq = vector; 24364be41e92SSony Chacko } 24374be41e92SSony Chacko } 24384be41e92SSony Chacko } 2439012ec812SHimanshu Madhani 24404be41e92SSony Chacko return 0; 24414be41e92SSony Chacko } 24424be41e92SSony Chacko 24438af3f33dSPratik Pujar void qlcnic_set_drv_version(struct qlcnic_adapter *adapter) 24448af3f33dSPratik Pujar { 24458af3f33dSPratik Pujar struct qlcnic_hardware_context *ahw = adapter->ahw; 24468af3f33dSPratik Pujar u32 fw_cmd = 0; 24478af3f33dSPratik Pujar 24488af3f33dSPratik Pujar if (qlcnic_82xx_check(adapter)) 24498af3f33dSPratik Pujar fw_cmd = QLCNIC_CMD_82XX_SET_DRV_VER; 24508af3f33dSPratik Pujar else if (qlcnic_83xx_check(adapter)) 24518af3f33dSPratik Pujar fw_cmd = QLCNIC_CMD_83XX_SET_DRV_VER; 24528af3f33dSPratik Pujar 2453d6994ca7SShahed Shaikh if (ahw->extra_capability[0] & QLCNIC_FW_CAPABILITY_SET_DRV_VER) 24548af3f33dSPratik Pujar qlcnic_fw_cmd_set_drv_version(adapter, fw_cmd); 24558af3f33dSPratik Pujar } 24568af3f33dSPratik Pujar 24572c97e9e2SSony Chacko /* Reset firmware API lock */ 24582c97e9e2SSony Chacko static void qlcnic_reset_api_lock(struct qlcnic_adapter *adapter) 24592c97e9e2SSony Chacko { 24602c97e9e2SSony Chacko qlcnic_api_lock(adapter); 24612c97e9e2SSony Chacko qlcnic_api_unlock(adapter); 24622c97e9e2SSony Chacko } 24632c97e9e2SSony Chacko 24642c97e9e2SSony Chacko 24656bb58bb0SBill Pemberton static int 2466aa43c215SJeff Kirsher qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 2467aa43c215SJeff Kirsher { 2468aa43c215SJeff Kirsher struct net_device *netdev = NULL; 2469aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = NULL; 24707e2cf4feSSony Chacko struct qlcnic_hardware_context *ahw; 24715ad6ff9dSSony Chacko int err, pci_using_dac = -1; 24727bc48646SDan Carpenter char board_name[QLCNIC_MAX_BOARD_NAME_LEN + 19]; /* MAC + ": " + name */ 2473aa43c215SJeff Kirsher 2474aa43c215SJeff Kirsher err = pci_enable_device(pdev); 2475aa43c215SJeff Kirsher if (err) 2476aa43c215SJeff Kirsher return err; 2477aa43c215SJeff Kirsher 2478aa43c215SJeff Kirsher if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { 2479aa43c215SJeff Kirsher err = -ENODEV; 2480aa43c215SJeff Kirsher goto err_out_disable_pdev; 2481aa43c215SJeff Kirsher } 2482aa43c215SJeff Kirsher 2483aa43c215SJeff Kirsher err = qlcnic_set_dma_mask(pdev, &pci_using_dac); 2484aa43c215SJeff Kirsher if (err) 2485aa43c215SJeff Kirsher goto err_out_disable_pdev; 2486aa43c215SJeff Kirsher 2487aa43c215SJeff Kirsher err = pci_request_regions(pdev, qlcnic_driver_name); 2488aa43c215SJeff Kirsher if (err) 2489aa43c215SJeff Kirsher goto err_out_disable_pdev; 2490aa43c215SJeff Kirsher 2491aa43c215SJeff Kirsher pci_set_master(pdev); 2492aa43c215SJeff Kirsher pci_enable_pcie_error_reporting(pdev); 2493aa43c215SJeff Kirsher 24947e2cf4feSSony Chacko ahw = kzalloc(sizeof(struct qlcnic_hardware_context), GFP_KERNEL); 249502135582SSony Chacko if (!ahw) { 249602135582SSony Chacko err = -ENOMEM; 24977e2cf4feSSony Chacko goto err_out_free_res; 249802135582SSony Chacko } 24997e2cf4feSSony Chacko 2500f8468331SRajesh Borundia switch (ent->device) { 2501f8468331SRajesh Borundia case PCI_DEVICE_ID_QLOGIC_QLE824X: 25027e2cf4feSSony Chacko ahw->hw_ops = &qlcnic_hw_ops; 25037e2cf4feSSony Chacko ahw->reg_tbl = (u32 *) qlcnic_reg_tbl; 2504f8468331SRajesh Borundia break; 2505f8468331SRajesh Borundia case PCI_DEVICE_ID_QLOGIC_QLE834X: 250640e2b8edSShahed Shaikh case PCI_DEVICE_ID_QLOGIC_QLE8830: 250715ca140fSManish Chopra case PCI_DEVICE_ID_QLOGIC_QLE844X: 250813159183SSony Chacko qlcnic_83xx_register_map(ahw); 2509f8468331SRajesh Borundia break; 2510f8468331SRajesh Borundia case PCI_DEVICE_ID_QLOGIC_VF_QLE834X: 2511da286a6fSShahed Shaikh case PCI_DEVICE_ID_QLOGIC_VF_QLE8C30: 251215ca140fSManish Chopra case PCI_DEVICE_ID_QLOGIC_VF_QLE844X: 2513f8468331SRajesh Borundia qlcnic_sriov_vf_register_map(ahw); 2514f8468331SRajesh Borundia break; 2515f8468331SRajesh Borundia default: 251613159183SSony Chacko goto err_out_free_hw_res; 25177e2cf4feSSony Chacko } 25187e2cf4feSSony Chacko 25197e2cf4feSSony Chacko err = qlcnic_setup_pci_map(pdev, ahw); 25207e2cf4feSSony Chacko if (err) 25217e2cf4feSSony Chacko goto err_out_free_hw_res; 25227e2cf4feSSony Chacko 2523012ec812SHimanshu Madhani netdev = alloc_etherdev_mq(sizeof(struct qlcnic_adapter), 2524012ec812SHimanshu Madhani QLCNIC_MAX_TX_RINGS); 2525aa43c215SJeff Kirsher if (!netdev) { 2526aa43c215SJeff Kirsher err = -ENOMEM; 25277e2cf4feSSony Chacko goto err_out_iounmap; 2528aa43c215SJeff Kirsher } 2529aa43c215SJeff Kirsher 2530aa43c215SJeff Kirsher SET_NETDEV_DEV(netdev, &pdev->dev); 2531aa43c215SJeff Kirsher 2532aa43c215SJeff Kirsher adapter = netdev_priv(netdev); 2533aa43c215SJeff Kirsher adapter->netdev = netdev; 2534aa43c215SJeff Kirsher adapter->pdev = pdev; 253513159183SSony Chacko adapter->ahw = ahw; 253613159183SSony Chacko 253713159183SSony Chacko adapter->qlcnic_wq = create_singlethread_workqueue("qlcnic"); 253813159183SSony Chacko if (adapter->qlcnic_wq == NULL) { 253902135582SSony Chacko err = -ENOMEM; 254013159183SSony Chacko dev_err(&pdev->dev, "Failed to create workqueue\n"); 254113159183SSony Chacko goto err_out_free_netdev; 254213159183SSony Chacko } 2543aa43c215SJeff Kirsher 25442dfc9671SPeter Senna Tschudin err = qlcnic_alloc_adapter_resources(adapter); 25452dfc9671SPeter Senna Tschudin if (err) 25462b1f18a4SWei Yongjun goto err_out_free_wq; 2547aa43c215SJeff Kirsher 2548aa43c215SJeff Kirsher adapter->dev_rst_time = jiffies; 25492f514c52SJitendra Kalsaria ahw->revision_id = pdev->revision; 25502f514c52SJitendra Kalsaria ahw->max_vnic_func = qlcnic_get_vnic_func_count(adapter); 2551fe1adc6bSJitendra Kalsaria if (qlcnic_mac_learn == FDB_MAC_LEARN) 2552fe1adc6bSJitendra Kalsaria adapter->fdb_mac_learn = true; 2553fe1adc6bSJitendra Kalsaria else if (qlcnic_mac_learn == DRV_MAC_LEARN) 2554fe1adc6bSJitendra Kalsaria adapter->drv_mac_learn = true; 2555aa43c215SJeff Kirsher 2556aa43c215SJeff Kirsher rwlock_init(&adapter->ahw->crb_lock); 2557aa43c215SJeff Kirsher mutex_init(&adapter->ahw->mem_lock); 2558aa43c215SJeff Kirsher 2559aa43c215SJeff Kirsher INIT_LIST_HEAD(&adapter->mac_list); 2560aa43c215SJeff Kirsher 256114d385b9SSucheta Chakraborty qlcnic_register_dcb(adapter); 256214d385b9SSucheta Chakraborty 25637e2cf4feSSony Chacko if (qlcnic_82xx_check(adapter)) { 256413159183SSony Chacko qlcnic_check_vf(adapter, ent); 2565aa43c215SJeff Kirsher adapter->portnum = adapter->ahw->pci_func; 25662c97e9e2SSony Chacko qlcnic_reset_api_lock(adapter); 25677e2cf4feSSony Chacko err = qlcnic_start_firmware(adapter); 2568aa43c215SJeff Kirsher if (err) { 256966451615SSucheta Chakraborty dev_err(&pdev->dev, "Loading fw failed.Please Reboot\n" 257066451615SSucheta Chakraborty "\t\tIf reboot doesn't help, try flashing the card\n"); 257166451615SSucheta Chakraborty goto err_out_maintenance_mode; 2572aa43c215SJeff Kirsher } 2573aa43c215SJeff Kirsher 257434e8c406SHimanshu Madhani /* compute and set default and max tx/sds rings */ 257534e8c406SHimanshu Madhani if (adapter->ahw->msix_supported) { 257634e8c406SHimanshu Madhani if (qlcnic_check_multi_tx_capability(adapter) == 1) 257734e8c406SHimanshu Madhani qlcnic_set_tx_ring_count(adapter, 257834e8c406SHimanshu Madhani QLCNIC_SINGLE_RING); 257934e8c406SHimanshu Madhani else 258034e8c406SHimanshu Madhani qlcnic_set_tx_ring_count(adapter, 258134e8c406SHimanshu Madhani QLCNIC_DEF_TX_RINGS); 258234e8c406SHimanshu Madhani qlcnic_set_sds_ring_count(adapter, 258334e8c406SHimanshu Madhani QLCNIC_DEF_SDS_RINGS); 258434e8c406SHimanshu Madhani } else { 258534e8c406SHimanshu Madhani qlcnic_set_tx_ring_count(adapter, QLCNIC_SINGLE_RING); 258634e8c406SHimanshu Madhani qlcnic_set_sds_ring_count(adapter, QLCNIC_SINGLE_RING); 2587012ec812SHimanshu Madhani } 2588012ec812SHimanshu Madhani 2589aa43c215SJeff Kirsher err = qlcnic_setup_idc_param(adapter); 2590aa43c215SJeff Kirsher if (err) 25917e2cf4feSSony Chacko goto err_out_free_hw; 2592aa43c215SJeff Kirsher 2593aa43c215SJeff Kirsher adapter->flags |= QLCNIC_NEED_FLR; 259414d385b9SSucheta Chakraborty 259513159183SSony Chacko } else if (qlcnic_83xx_check(adapter)) { 259613159183SSony Chacko qlcnic_83xx_check_vf(adapter, ent); 259713159183SSony Chacko adapter->portnum = adapter->ahw->pci_func; 2598f8468331SRajesh Borundia err = qlcnic_83xx_init(adapter, pci_using_dac); 2599629263acSSony Chacko if (err) { 260078ea2d97SSucheta Chakraborty switch (err) { 260178ea2d97SSucheta Chakraborty case -ENOTRECOVERABLE: 26022a355aecSSucheta Chakraborty dev_err(&pdev->dev, "Adapter initialization failed due to a faulty hardware\n"); 26032a355aecSSucheta Chakraborty dev_err(&pdev->dev, "Please replace the adapter with new one and return the faulty adapter for repair\n"); 2604629263acSSony Chacko goto err_out_free_hw; 260578ea2d97SSucheta Chakraborty case -ENOMEM: 260678ea2d97SSucheta Chakraborty dev_err(&pdev->dev, "Adapter initialization failed. Please reboot\n"); 260778ea2d97SSucheta Chakraborty goto err_out_free_hw; 2608aaecf51cSSucheta Chakraborty case -EOPNOTSUPP: 2609aaecf51cSSucheta Chakraborty dev_err(&pdev->dev, "Adapter initialization failed\n"); 2610aaecf51cSSucheta Chakraborty goto err_out_free_hw; 261178ea2d97SSucheta Chakraborty default: 2612c65762fcSSucheta Chakraborty dev_err(&pdev->dev, "Adapter initialization failed. Driver will load in maintenance mode to recover the adapter using the application\n"); 261378ea2d97SSucheta Chakraborty goto err_out_maintenance_mode; 2614629263acSSony Chacko } 261578ea2d97SSucheta Chakraborty } 261678ea2d97SSucheta Chakraborty 2617f8468331SRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) 2618f8468331SRajesh Borundia return 0; 261913159183SSony Chacko } else { 262013159183SSony Chacko dev_err(&pdev->dev, 262113159183SSony Chacko "%s: failed. Please Reboot\n", __func__); 26227824acd9SYongjian Xu err = -ENODEV; 262313159183SSony Chacko goto err_out_free_hw; 2624aa43c215SJeff Kirsher } 2625aa43c215SJeff Kirsher 2626aa43c215SJeff Kirsher if (qlcnic_read_mac_addr(adapter)) 2627aa43c215SJeff Kirsher dev_warn(&pdev->dev, "failed to read mac addr\n"); 2628aa43c215SJeff Kirsher 262907a251c8SShahed Shaikh qlcnic_read_phys_port_id(adapter); 263007a251c8SShahed Shaikh 2631aa43c215SJeff Kirsher if (adapter->portnum == 0) { 263222999798SSony Chacko qlcnic_get_board_name(adapter, board_name); 263313159183SSony Chacko 2634aa43c215SJeff Kirsher pr_info("%s: %s Board Chip rev 0x%x\n", 2635aa43c215SJeff Kirsher module_name(THIS_MODULE), 263622999798SSony Chacko board_name, adapter->ahw->revision_id); 2637aa43c215SJeff Kirsher } 2638460374f7SHimanshu Madhani 2639460374f7SHimanshu Madhani if (qlcnic_83xx_check(adapter) && !qlcnic_use_msi_x && 2640460374f7SHimanshu Madhani !!qlcnic_use_msi) 2641460374f7SHimanshu Madhani dev_warn(&pdev->dev, 264201b91f4cSPratik Pujar "Device does not support MSI interrupts\n"); 2643460374f7SHimanshu Madhani 2644068a8d19SManish Chopra if (qlcnic_82xx_check(adapter)) { 26454d52e1e8SSucheta Chakraborty qlcnic_dcb_enable(adapter->dcb); 26464d52e1e8SSucheta Chakraborty qlcnic_dcb_get_info(adapter->dcb); 264734e8c406SHimanshu Madhani err = qlcnic_setup_intr(adapter); 26484d52e1e8SSucheta Chakraborty 26499a97e705SManish chopra if (err) { 26509a97e705SManish chopra dev_err(&pdev->dev, "Failed to setup interrupt\n"); 26517e2cf4feSSony Chacko goto err_out_disable_msi; 26529a97e705SManish chopra } 265313159183SSony Chacko } 2654aa43c215SJeff Kirsher 265502135582SSony Chacko err = qlcnic_get_act_pci_func(adapter); 265602135582SSony Chacko if (err) 265702135582SSony Chacko goto err_out_disable_mbx_intr; 265802135582SSony Chacko 2659bf63014fSRajesh Borundia if (adapter->portnum == 0) 2660bf63014fSRajesh Borundia qlcnic_set_drv_version(adapter); 2661bf63014fSRajesh Borundia 2662aa43c215SJeff Kirsher err = qlcnic_setup_netdev(adapter, netdev, pci_using_dac); 2663aa43c215SJeff Kirsher if (err) 26647e2cf4feSSony Chacko goto err_out_disable_mbx_intr; 2665aa43c215SJeff Kirsher 2666aa43c215SJeff Kirsher pci_set_drvdata(pdev, adapter); 2667aa43c215SJeff Kirsher 266897ee45ebSSony Chacko if (qlcnic_82xx_check(adapter)) 266997ee45ebSSony Chacko qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, 267097ee45ebSSony Chacko FW_POLL_DELAY); 2671aa43c215SJeff Kirsher 2672aa43c215SJeff Kirsher switch (adapter->ahw->port_type) { 2673aa43c215SJeff Kirsher case QLCNIC_GBE: 2674aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n", 2675aa43c215SJeff Kirsher adapter->netdev->name); 2676aa43c215SJeff Kirsher break; 2677aa43c215SJeff Kirsher case QLCNIC_XGBE: 2678aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n", 2679aa43c215SJeff Kirsher adapter->netdev->name); 2680aa43c215SJeff Kirsher break; 2681aa43c215SJeff Kirsher } 2682aa43c215SJeff Kirsher 2683fe1adc6bSJitendra Kalsaria if (adapter->drv_mac_learn) 2684aa43c215SJeff Kirsher qlcnic_alloc_lb_filters_mem(adapter); 2685aa43c215SJeff Kirsher 26867e2cf4feSSony Chacko qlcnic_add_sysfs(adapter); 26871f0f467bSHarish Patil qlcnic_register_hwmon_dev(adapter); 2688aa43c215SJeff Kirsher return 0; 2689aa43c215SJeff Kirsher 26907e2cf4feSSony Chacko err_out_disable_mbx_intr: 26917dd90cf1SSucheta Chakraborty if (qlcnic_83xx_check(adapter)) 269213159183SSony Chacko qlcnic_83xx_free_mbx_intr(adapter); 26937e2cf4feSSony Chacko 2694aa43c215SJeff Kirsher err_out_disable_msi: 2695aa43c215SJeff Kirsher qlcnic_teardown_intr(adapter); 26967e2cf4feSSony Chacko qlcnic_cancel_idc_work(adapter); 2697aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 0); 2698aa43c215SJeff Kirsher 2699aa43c215SJeff Kirsher err_out_free_hw: 2700aa43c215SJeff Kirsher qlcnic_free_adapter_resources(adapter); 2701aa43c215SJeff Kirsher 27022b1f18a4SWei Yongjun err_out_free_wq: 27032b1f18a4SWei Yongjun destroy_workqueue(adapter->qlcnic_wq); 27042b1f18a4SWei Yongjun 2705aa43c215SJeff Kirsher err_out_free_netdev: 2706aa43c215SJeff Kirsher free_netdev(netdev); 2707aa43c215SJeff Kirsher 27087e2cf4feSSony Chacko err_out_iounmap: 2709f1a094a8SRajesh Borundia qlcnic_cleanup_pci_map(ahw); 27107e2cf4feSSony Chacko 27117e2cf4feSSony Chacko err_out_free_hw_res: 27127e2cf4feSSony Chacko kfree(ahw); 27137e2cf4feSSony Chacko 2714aa43c215SJeff Kirsher err_out_free_res: 2715aa43c215SJeff Kirsher pci_release_regions(pdev); 2716aa43c215SJeff Kirsher 2717aa43c215SJeff Kirsher err_out_disable_pdev: 2718aa43c215SJeff Kirsher pci_disable_device(pdev); 2719aa43c215SJeff Kirsher return err; 272066451615SSucheta Chakraborty 272166451615SSucheta Chakraborty err_out_maintenance_mode: 272278ea2d97SSucheta Chakraborty set_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state); 272366451615SSucheta Chakraborty netdev->netdev_ops = &qlcnic_netdev_failed_ops; 27247ad24ea4SWilfried Klaebe netdev->ethtool_ops = &qlcnic_ethtool_failed_ops; 272578ea2d97SSucheta Chakraborty ahw->port_type = QLCNIC_XGBE; 272678ea2d97SSucheta Chakraborty 272778ea2d97SSucheta Chakraborty if (qlcnic_83xx_check(adapter)) 272878ea2d97SSucheta Chakraborty adapter->tgt_status_reg = NULL; 272978ea2d97SSucheta Chakraborty else 273078ea2d97SSucheta Chakraborty ahw->board_type = QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS; 273178ea2d97SSucheta Chakraborty 273266451615SSucheta Chakraborty err = register_netdev(netdev); 273366451615SSucheta Chakraborty 273466451615SSucheta Chakraborty if (err) { 273566451615SSucheta Chakraborty dev_err(&pdev->dev, "Failed to register net device\n"); 273666451615SSucheta Chakraborty qlcnic_clr_all_drv_state(adapter, 0); 273766451615SSucheta Chakraborty goto err_out_free_hw; 273866451615SSucheta Chakraborty } 273966451615SSucheta Chakraborty 274066451615SSucheta Chakraborty pci_set_drvdata(pdev, adapter); 274166451615SSucheta Chakraborty qlcnic_add_sysfs(adapter); 274266451615SSucheta Chakraborty 274366451615SSucheta Chakraborty return 0; 2744aa43c215SJeff Kirsher } 2745aa43c215SJeff Kirsher 27466bb58bb0SBill Pemberton static void qlcnic_remove(struct pci_dev *pdev) 2747aa43c215SJeff Kirsher { 2748aa43c215SJeff Kirsher struct qlcnic_adapter *adapter; 2749aa43c215SJeff Kirsher struct net_device *netdev; 275013159183SSony Chacko struct qlcnic_hardware_context *ahw; 2751aa43c215SJeff Kirsher 2752aa43c215SJeff Kirsher adapter = pci_get_drvdata(pdev); 2753aa43c215SJeff Kirsher if (adapter == NULL) 2754aa43c215SJeff Kirsher return; 2755aa43c215SJeff Kirsher 2756aa43c215SJeff Kirsher netdev = adapter->netdev; 2757aa43c215SJeff Kirsher 275813159183SSony Chacko qlcnic_cancel_idc_work(adapter); 2759132a3f2bSRajesh Borundia qlcnic_sriov_pf_disable(adapter); 276013159183SSony Chacko ahw = adapter->ahw; 2761aa43c215SJeff Kirsher 2762aa43c215SJeff Kirsher unregister_netdev(netdev); 276302feda17SRajesh Borundia qlcnic_sriov_cleanup(adapter); 2764aa43c215SJeff Kirsher 276513159183SSony Chacko if (qlcnic_83xx_check(adapter)) { 27669b0fff2aSSucheta Chakraborty qlcnic_83xx_initialize_nic(adapter, 0); 27673d73b5fdSJitendra Kalsaria cancel_delayed_work_sync(&adapter->idc_aen_work); 2768068a8d19SManish Chopra qlcnic_83xx_free_mbx_intr(adapter); 2769068a8d19SManish Chopra qlcnic_83xx_detach_mailbox_work(adapter); 2770068a8d19SManish Chopra qlcnic_83xx_free_mailbox(ahw->mailbox); 27717000078aSPratik Pujar kfree(ahw->fw_info); 277213159183SSony Chacko } 277313159183SSony Chacko 27743720bf79SSucheta Chakraborty qlcnic_dcb_free(adapter->dcb); 2775aa43c215SJeff Kirsher qlcnic_detach(adapter); 2776aa43c215SJeff Kirsher kfree(adapter->npars); 2777aa43c215SJeff Kirsher kfree(adapter->eswitch); 2778aa43c215SJeff Kirsher 277997ee45ebSSony Chacko if (qlcnic_82xx_check(adapter)) 2780aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 0); 2781aa43c215SJeff Kirsher 2782aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 2783aa43c215SJeff Kirsher 2784aa43c215SJeff Kirsher qlcnic_free_lb_filters_mem(adapter); 2785aa43c215SJeff Kirsher 2786aa43c215SJeff Kirsher qlcnic_teardown_intr(adapter); 2787aa43c215SJeff Kirsher 278813159183SSony Chacko qlcnic_remove_sysfs(adapter); 2789aa43c215SJeff Kirsher 27901f0f467bSHarish Patil qlcnic_unregister_hwmon_dev(adapter); 27911f0f467bSHarish Patil 2792f1a094a8SRajesh Borundia qlcnic_cleanup_pci_map(adapter->ahw); 2793aa43c215SJeff Kirsher 2794aa43c215SJeff Kirsher qlcnic_release_firmware(adapter); 2795aa43c215SJeff Kirsher 2796aa43c215SJeff Kirsher pci_disable_pcie_error_reporting(pdev); 2797aa43c215SJeff Kirsher pci_release_regions(pdev); 2798aa43c215SJeff Kirsher pci_disable_device(pdev); 2799aa43c215SJeff Kirsher 280013159183SSony Chacko if (adapter->qlcnic_wq) { 280113159183SSony Chacko destroy_workqueue(adapter->qlcnic_wq); 280213159183SSony Chacko adapter->qlcnic_wq = NULL; 280313159183SSony Chacko } 280414d385b9SSucheta Chakraborty 2805aa43c215SJeff Kirsher qlcnic_free_adapter_resources(adapter); 280613159183SSony Chacko kfree(ahw); 2807aa43c215SJeff Kirsher free_netdev(netdev); 2808aa43c215SJeff Kirsher } 2809aa43c215SJeff Kirsher 2810aa43c215SJeff Kirsher static void qlcnic_shutdown(struct pci_dev *pdev) 2811aa43c215SJeff Kirsher { 2812aa43c215SJeff Kirsher if (__qlcnic_shutdown(pdev)) 2813aa43c215SJeff Kirsher return; 2814aa43c215SJeff Kirsher 2815aa43c215SJeff Kirsher pci_disable_device(pdev); 2816aa43c215SJeff Kirsher } 2817aa43c215SJeff Kirsher 2818aa43c215SJeff Kirsher #ifdef CONFIG_PM 2819486a5bc7SRajesh Borundia static int qlcnic_suspend(struct pci_dev *pdev, pm_message_t state) 2820aa43c215SJeff Kirsher { 2821aa43c215SJeff Kirsher int retval; 2822aa43c215SJeff Kirsher 2823aa43c215SJeff Kirsher retval = __qlcnic_shutdown(pdev); 2824aa43c215SJeff Kirsher if (retval) 2825aa43c215SJeff Kirsher return retval; 2826aa43c215SJeff Kirsher 2827aa43c215SJeff Kirsher pci_set_power_state(pdev, pci_choose_state(pdev, state)); 2828aa43c215SJeff Kirsher return 0; 2829aa43c215SJeff Kirsher } 2830aa43c215SJeff Kirsher 2831486a5bc7SRajesh Borundia static int qlcnic_resume(struct pci_dev *pdev) 2832aa43c215SJeff Kirsher { 2833aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 2834aa43c215SJeff Kirsher int err; 2835aa43c215SJeff Kirsher 2836aa43c215SJeff Kirsher err = pci_enable_device(pdev); 2837aa43c215SJeff Kirsher if (err) 2838aa43c215SJeff Kirsher return err; 2839aa43c215SJeff Kirsher 2840aa43c215SJeff Kirsher pci_set_power_state(pdev, PCI_D0); 2841aa43c215SJeff Kirsher pci_set_master(pdev); 2842aa43c215SJeff Kirsher pci_restore_state(pdev); 2843aa43c215SJeff Kirsher 2844486a5bc7SRajesh Borundia return __qlcnic_resume(adapter); 2845aa43c215SJeff Kirsher } 2846aa43c215SJeff Kirsher #endif 2847aa43c215SJeff Kirsher 2848aa43c215SJeff Kirsher static int qlcnic_open(struct net_device *netdev) 2849aa43c215SJeff Kirsher { 2850aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 2851aa43c215SJeff Kirsher int err; 2852aa43c215SJeff Kirsher 285378ea2d97SSucheta Chakraborty if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) { 285478ea2d97SSucheta Chakraborty netdev_err(netdev, "%s: Device is in non-operational state\n", 285578ea2d97SSucheta Chakraborty __func__); 285666451615SSucheta Chakraborty 285766451615SSucheta Chakraborty return -EIO; 285866451615SSucheta Chakraborty } 285966451615SSucheta Chakraborty 2860aa43c215SJeff Kirsher netif_carrier_off(netdev); 2861aa43c215SJeff Kirsher 2862aa43c215SJeff Kirsher err = qlcnic_attach(adapter); 2863aa43c215SJeff Kirsher if (err) 2864aa43c215SJeff Kirsher return err; 2865aa43c215SJeff Kirsher 2866aa43c215SJeff Kirsher err = __qlcnic_up(adapter, netdev); 2867aa43c215SJeff Kirsher if (err) 2868aa43c215SJeff Kirsher qlcnic_detach(adapter); 2869060d0564SRajesh Borundia 2870aa43c215SJeff Kirsher return err; 2871aa43c215SJeff Kirsher } 2872aa43c215SJeff Kirsher 2873aa43c215SJeff Kirsher /* 2874aa43c215SJeff Kirsher * qlcnic_close - Disables a network interface entry point 2875aa43c215SJeff Kirsher */ 2876aa43c215SJeff Kirsher static int qlcnic_close(struct net_device *netdev) 2877aa43c215SJeff Kirsher { 2878aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 2879aa43c215SJeff Kirsher 2880aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 288113159183SSony Chacko 2882aa43c215SJeff Kirsher return 0; 2883aa43c215SJeff Kirsher } 2884aa43c215SJeff Kirsher 2885d747c333SRajesh Borundia #define QLCNIC_VF_LB_BUCKET_SIZE 1 2886d747c333SRajesh Borundia 2887aa43c215SJeff Kirsher void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) 2888aa43c215SJeff Kirsher { 2889aa43c215SJeff Kirsher void *head; 2890aa43c215SJeff Kirsher int i; 289113159183SSony Chacko struct net_device *netdev = adapter->netdev; 289213159183SSony Chacko u32 filter_size = 0; 289313159183SSony Chacko u16 act_pci_func = 0; 2894aa43c215SJeff Kirsher 2895aa43c215SJeff Kirsher if (adapter->fhash.fmax && adapter->fhash.fhead) 2896aa43c215SJeff Kirsher return; 2897aa43c215SJeff Kirsher 28982f514c52SJitendra Kalsaria act_pci_func = adapter->ahw->total_nic_func; 2899aa43c215SJeff Kirsher spin_lock_init(&adapter->mac_learn_lock); 290053643a75SShahed Shaikh spin_lock_init(&adapter->rx_mac_learn_lock); 2901aa43c215SJeff Kirsher 2902d747c333SRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) { 2903d747c333SRajesh Borundia filter_size = QLCNIC_83XX_SRIOV_VF_MAX_MAC - 1; 2904d747c333SRajesh Borundia adapter->fhash.fbucket_size = QLCNIC_VF_LB_BUCKET_SIZE; 2905d747c333SRajesh Borundia } else if (qlcnic_82xx_check(adapter)) { 290613159183SSony Chacko filter_size = QLCNIC_LB_MAX_FILTERS; 290713159183SSony Chacko adapter->fhash.fbucket_size = QLCNIC_LB_BUCKET_SIZE; 290813159183SSony Chacko } else { 290913159183SSony Chacko filter_size = QLC_83XX_LB_MAX_FILTERS; 291013159183SSony Chacko adapter->fhash.fbucket_size = QLC_83XX_LB_BUCKET_SIZE; 291113159183SSony Chacko } 291213159183SSony Chacko 291313159183SSony Chacko head = kcalloc(adapter->fhash.fbucket_size, 29141d9219ddSJitendra Kalsaria sizeof(struct hlist_head), GFP_ATOMIC); 291513159183SSony Chacko 2916aa43c215SJeff Kirsher if (!head) 2917aa43c215SJeff Kirsher return; 2918aa43c215SJeff Kirsher 291913159183SSony Chacko adapter->fhash.fmax = (filter_size / act_pci_func); 2920aa43c215SJeff Kirsher adapter->fhash.fhead = head; 2921aa43c215SJeff Kirsher 292213159183SSony Chacko netdev_info(netdev, "active nic func = %d, mac filter size=%d\n", 292313159183SSony Chacko act_pci_func, adapter->fhash.fmax); 292413159183SSony Chacko 292513159183SSony Chacko for (i = 0; i < adapter->fhash.fbucket_size; i++) 2926aa43c215SJeff Kirsher INIT_HLIST_HEAD(&adapter->fhash.fhead[i]); 292753643a75SShahed Shaikh 292853643a75SShahed Shaikh adapter->rx_fhash.fbucket_size = adapter->fhash.fbucket_size; 292953643a75SShahed Shaikh 293053643a75SShahed Shaikh head = kcalloc(adapter->rx_fhash.fbucket_size, 293153643a75SShahed Shaikh sizeof(struct hlist_head), GFP_ATOMIC); 293253643a75SShahed Shaikh 293353643a75SShahed Shaikh if (!head) 293453643a75SShahed Shaikh return; 293553643a75SShahed Shaikh 293653643a75SShahed Shaikh adapter->rx_fhash.fmax = (filter_size / act_pci_func); 293753643a75SShahed Shaikh adapter->rx_fhash.fhead = head; 293853643a75SShahed Shaikh 293953643a75SShahed Shaikh for (i = 0; i < adapter->rx_fhash.fbucket_size; i++) 294053643a75SShahed Shaikh INIT_HLIST_HEAD(&adapter->rx_fhash.fhead[i]); 2941aa43c215SJeff Kirsher } 2942aa43c215SJeff Kirsher 2943aa43c215SJeff Kirsher static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter) 2944aa43c215SJeff Kirsher { 29457061b2bdSMarkus Elfring if (adapter->fhash.fmax) 2946aa43c215SJeff Kirsher kfree(adapter->fhash.fhead); 2947aa43c215SJeff Kirsher 2948aa43c215SJeff Kirsher adapter->fhash.fhead = NULL; 2949aa43c215SJeff Kirsher adapter->fhash.fmax = 0; 295053643a75SShahed Shaikh 29517061b2bdSMarkus Elfring if (adapter->rx_fhash.fmax) 295253643a75SShahed Shaikh kfree(adapter->rx_fhash.fhead); 295353643a75SShahed Shaikh 295453643a75SShahed Shaikh adapter->rx_fhash.fmax = 0; 295553643a75SShahed Shaikh adapter->rx_fhash.fhead = NULL; 2956aa43c215SJeff Kirsher } 2957aa43c215SJeff Kirsher 2958629263acSSony Chacko int qlcnic_check_temp(struct qlcnic_adapter *adapter) 2959aa43c215SJeff Kirsher { 2960aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 296197ee45ebSSony Chacko u32 temp_state, temp_val, temp = 0; 2962aa43c215SJeff Kirsher int rv = 0; 2963aa43c215SJeff Kirsher 296413159183SSony Chacko if (qlcnic_83xx_check(adapter)) 296513159183SSony Chacko temp = QLCRDX(adapter->ahw, QLC_83XX_ASIC_TEMP); 296613159183SSony Chacko 296797ee45ebSSony Chacko if (qlcnic_82xx_check(adapter)) 2968a15ebd37SHimanshu Madhani temp = QLC_SHARED_REG_RD32(adapter, QLCNIC_ASIC_TEMP); 2969aa43c215SJeff Kirsher 2970aa43c215SJeff Kirsher temp_state = qlcnic_get_temp_state(temp); 2971aa43c215SJeff Kirsher temp_val = qlcnic_get_temp_val(temp); 2972aa43c215SJeff Kirsher 2973aa43c215SJeff Kirsher if (temp_state == QLCNIC_TEMP_PANIC) { 2974aa43c215SJeff Kirsher dev_err(&netdev->dev, 2975aa43c215SJeff Kirsher "Device temperature %d degrees C exceeds" 2976aa43c215SJeff Kirsher " maximum allowed. Hardware has been shut down.\n", 2977aa43c215SJeff Kirsher temp_val); 2978aa43c215SJeff Kirsher rv = 1; 2979aa43c215SJeff Kirsher } else if (temp_state == QLCNIC_TEMP_WARN) { 298079788450SSony Chacko if (adapter->ahw->temp == QLCNIC_TEMP_NORMAL) { 2981aa43c215SJeff Kirsher dev_err(&netdev->dev, 2982aa43c215SJeff Kirsher "Device temperature %d degrees C " 2983aa43c215SJeff Kirsher "exceeds operating range." 2984aa43c215SJeff Kirsher " Immediate action needed.\n", 2985aa43c215SJeff Kirsher temp_val); 2986aa43c215SJeff Kirsher } 2987aa43c215SJeff Kirsher } else { 298879788450SSony Chacko if (adapter->ahw->temp == QLCNIC_TEMP_WARN) { 2989aa43c215SJeff Kirsher dev_info(&netdev->dev, 2990aa43c215SJeff Kirsher "Device temperature is now %d degrees C" 2991aa43c215SJeff Kirsher " in normal range.\n", temp_val); 2992aa43c215SJeff Kirsher } 2993aa43c215SJeff Kirsher } 299479788450SSony Chacko adapter->ahw->temp = temp_state; 2995aa43c215SJeff Kirsher return rv; 2996aa43c215SJeff Kirsher } 2997aa43c215SJeff Kirsher 299895b3890aSHimanshu Madhani static inline void dump_tx_ring_desc(struct qlcnic_host_tx_ring *tx_ring) 299995b3890aSHimanshu Madhani { 300095b3890aSHimanshu Madhani int i; 300195b3890aSHimanshu Madhani struct cmd_desc_type0 *tx_desc_info; 300295b3890aSHimanshu Madhani 300395b3890aSHimanshu Madhani for (i = 0; i < tx_ring->num_desc; i++) { 300495b3890aSHimanshu Madhani tx_desc_info = &tx_ring->desc_head[i]; 300595b3890aSHimanshu Madhani pr_info("TX Desc: %d\n", i); 300695b3890aSHimanshu Madhani print_hex_dump(KERN_INFO, "TX: ", DUMP_PREFIX_OFFSET, 16, 1, 300795b3890aSHimanshu Madhani &tx_ring->desc_head[i], 300895b3890aSHimanshu Madhani sizeof(struct cmd_desc_type0), true); 300995b3890aSHimanshu Madhani } 301095b3890aSHimanshu Madhani } 301195b3890aSHimanshu Madhani 3012665d1ecaSHarish Patil static void qlcnic_dump_rings(struct qlcnic_adapter *adapter) 301395b3890aSHimanshu Madhani { 3014665d1ecaSHarish Patil struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; 301595b3890aSHimanshu Madhani struct net_device *netdev = adapter->netdev; 3016665d1ecaSHarish Patil struct qlcnic_host_rds_ring *rds_ring; 3017665d1ecaSHarish Patil struct qlcnic_host_sds_ring *sds_ring; 301895b3890aSHimanshu Madhani struct qlcnic_host_tx_ring *tx_ring; 301995b3890aSHimanshu Madhani int ring; 302095b3890aSHimanshu Madhani 302195b3890aSHimanshu Madhani if (!netdev || !netif_running(netdev)) 302295b3890aSHimanshu Madhani return; 302395b3890aSHimanshu Madhani 3024665d1ecaSHarish Patil for (ring = 0; ring < adapter->max_rds_rings; ring++) { 3025665d1ecaSHarish Patil rds_ring = &recv_ctx->rds_rings[ring]; 3026665d1ecaSHarish Patil if (!rds_ring) 3027665d1ecaSHarish Patil continue; 3028665d1ecaSHarish Patil netdev_info(netdev, 3029665d1ecaSHarish Patil "rds_ring=%d crb_rcv_producer=%d producer=%u num_desc=%u\n", 3030665d1ecaSHarish Patil ring, readl(rds_ring->crb_rcv_producer), 3031665d1ecaSHarish Patil rds_ring->producer, rds_ring->num_desc); 3032665d1ecaSHarish Patil } 3033665d1ecaSHarish Patil 3034665d1ecaSHarish Patil for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 3035665d1ecaSHarish Patil sds_ring = &(recv_ctx->sds_rings[ring]); 3036665d1ecaSHarish Patil if (!sds_ring) 3037665d1ecaSHarish Patil continue; 3038665d1ecaSHarish Patil netdev_info(netdev, 3039665d1ecaSHarish Patil "sds_ring=%d crb_sts_consumer=%d consumer=%u crb_intr_mask=%d num_desc=%u\n", 3040665d1ecaSHarish Patil ring, readl(sds_ring->crb_sts_consumer), 3041665d1ecaSHarish Patil sds_ring->consumer, readl(sds_ring->crb_intr_mask), 3042665d1ecaSHarish Patil sds_ring->num_desc); 3043665d1ecaSHarish Patil } 3044665d1ecaSHarish Patil 304595b3890aSHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; ring++) { 304695b3890aSHimanshu Madhani tx_ring = &adapter->tx_ring[ring]; 3047665d1ecaSHarish Patil if (!tx_ring) 3048665d1ecaSHarish Patil continue; 304995b3890aSHimanshu Madhani netdev_info(netdev, "Tx ring=%d Context Id=0x%x\n", 305095b3890aSHimanshu Madhani ring, tx_ring->ctx_id); 305195b3890aSHimanshu Madhani netdev_info(netdev, 305295b3890aSHimanshu Madhani "xmit_finished=%llu, xmit_called=%llu, xmit_on=%llu, xmit_off=%llu\n", 305395b3890aSHimanshu Madhani tx_ring->tx_stats.xmit_finished, 305495b3890aSHimanshu Madhani tx_ring->tx_stats.xmit_called, 305595b3890aSHimanshu Madhani tx_ring->tx_stats.xmit_on, 305695b3890aSHimanshu Madhani tx_ring->tx_stats.xmit_off); 3057d5d2bf3eSManish Chopra 3058d5d2bf3eSManish Chopra if (tx_ring->crb_intr_mask) 3059d5d2bf3eSManish Chopra netdev_info(netdev, "crb_intr_mask=%d\n", 3060d5d2bf3eSManish Chopra readl(tx_ring->crb_intr_mask)); 3061d5d2bf3eSManish Chopra 306295b3890aSHimanshu Madhani netdev_info(netdev, 3063d5d2bf3eSManish Chopra "hw_producer=%d, sw_producer=%d sw_consumer=%d, hw_consumer=%d\n", 306495b3890aSHimanshu Madhani readl(tx_ring->crb_cmd_producer), 306595b3890aSHimanshu Madhani tx_ring->producer, tx_ring->sw_consumer, 306695b3890aSHimanshu Madhani le32_to_cpu(*(tx_ring->hw_consumer))); 306795b3890aSHimanshu Madhani 306895b3890aSHimanshu Madhani netdev_info(netdev, "Total desc=%d, Available desc=%d\n", 306995b3890aSHimanshu Madhani tx_ring->num_desc, qlcnic_tx_avail(tx_ring)); 307095b3890aSHimanshu Madhani 3071665d1ecaSHarish Patil if (netif_msg_tx_err(adapter->ahw)) 307295b3890aSHimanshu Madhani dump_tx_ring_desc(tx_ring); 307395b3890aSHimanshu Madhani } 3074665d1ecaSHarish Patil 307595b3890aSHimanshu Madhani } 307695b3890aSHimanshu Madhani 3077aa43c215SJeff Kirsher static void qlcnic_tx_timeout(struct net_device *netdev) 3078aa43c215SJeff Kirsher { 3079aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 3080aa43c215SJeff Kirsher 3081aa43c215SJeff Kirsher if (test_bit(__QLCNIC_RESETTING, &adapter->state)) 3082aa43c215SJeff Kirsher return; 3083aa43c215SJeff Kirsher 3084665d1ecaSHarish Patil qlcnic_dump_rings(adapter); 3085665d1ecaSHarish Patil 3086665d1ecaSHarish Patil if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS || 3087665d1ecaSHarish Patil netif_msg_tx_err(adapter->ahw)) { 3088665d1ecaSHarish Patil netdev_err(netdev, "Tx timeout, reset the adapter.\n"); 3089536faa61SSony Chacko if (qlcnic_82xx_check(adapter)) 3090aa43c215SJeff Kirsher adapter->need_fw_reset = 1; 3091536faa61SSony Chacko else if (qlcnic_83xx_check(adapter)) 3092536faa61SSony Chacko qlcnic_83xx_idc_request_reset(adapter, 3093536faa61SSony Chacko QLCNIC_FORCE_FW_DUMP_KEY); 3094536faa61SSony Chacko } else { 3095665d1ecaSHarish Patil netdev_err(netdev, "Tx timeout, reset adapter context.\n"); 309679788450SSony Chacko adapter->ahw->reset_context = 1; 3097aa43c215SJeff Kirsher } 3098536faa61SSony Chacko } 3099aa43c215SJeff Kirsher 3100aa43c215SJeff Kirsher static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev) 3101aa43c215SJeff Kirsher { 3102aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 3103aa43c215SJeff Kirsher struct net_device_stats *stats = &netdev->stats; 3104aa43c215SJeff Kirsher 31051ac6762aSManish Chopra if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) 31061ac6762aSManish Chopra qlcnic_update_stats(adapter); 31071ac6762aSManish Chopra 3108aa43c215SJeff Kirsher stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts; 3109aa43c215SJeff Kirsher stats->tx_packets = adapter->stats.xmitfinished; 3110aa43c215SJeff Kirsher stats->rx_bytes = adapter->stats.rxbytes + adapter->stats.lrobytes; 3111aa43c215SJeff Kirsher stats->tx_bytes = adapter->stats.txbytes; 3112aa43c215SJeff Kirsher stats->rx_dropped = adapter->stats.rxdropped; 3113aa43c215SJeff Kirsher stats->tx_dropped = adapter->stats.txdropped; 3114aa43c215SJeff Kirsher 3115aa43c215SJeff Kirsher return stats; 3116aa43c215SJeff Kirsher } 3117aa43c215SJeff Kirsher 311821041400Sstephen hemminger static irqreturn_t qlcnic_82xx_clear_legacy_intr(struct qlcnic_adapter *adapter) 3119aa43c215SJeff Kirsher { 3120aa43c215SJeff Kirsher u32 status; 3121aa43c215SJeff Kirsher 3122aa43c215SJeff Kirsher status = readl(adapter->isr_int_vec); 3123aa43c215SJeff Kirsher 312479788450SSony Chacko if (!(status & adapter->ahw->int_vec_bit)) 3125aa43c215SJeff Kirsher return IRQ_NONE; 3126aa43c215SJeff Kirsher 3127aa43c215SJeff Kirsher /* check interrupt state machine, to be sure */ 3128aa43c215SJeff Kirsher status = readl(adapter->crb_int_state_reg); 3129aa43c215SJeff Kirsher if (!ISR_LEGACY_INT_TRIGGERED(status)) 3130aa43c215SJeff Kirsher return IRQ_NONE; 3131aa43c215SJeff Kirsher 3132aa43c215SJeff Kirsher writel(0xffffffff, adapter->tgt_status_reg); 3133aa43c215SJeff Kirsher /* read twice to ensure write is flushed */ 3134aa43c215SJeff Kirsher readl(adapter->isr_int_vec); 3135aa43c215SJeff Kirsher readl(adapter->isr_int_vec); 3136aa43c215SJeff Kirsher 3137aa43c215SJeff Kirsher return IRQ_HANDLED; 3138aa43c215SJeff Kirsher } 3139aa43c215SJeff Kirsher 3140aa43c215SJeff Kirsher static irqreturn_t qlcnic_tmp_intr(int irq, void *data) 3141aa43c215SJeff Kirsher { 3142aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring = data; 3143aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = sds_ring->adapter; 3144aa43c215SJeff Kirsher 3145aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_MSIX_ENABLED) 3146aa43c215SJeff Kirsher goto done; 3147aa43c215SJeff Kirsher else if (adapter->flags & QLCNIC_MSI_ENABLED) { 3148aa43c215SJeff Kirsher writel(0xffffffff, adapter->tgt_status_reg); 3149aa43c215SJeff Kirsher goto done; 3150aa43c215SJeff Kirsher } 3151aa43c215SJeff Kirsher 3152aa43c215SJeff Kirsher if (qlcnic_clear_legacy_intr(adapter) == IRQ_NONE) 3153aa43c215SJeff Kirsher return IRQ_NONE; 3154aa43c215SJeff Kirsher 3155aa43c215SJeff Kirsher done: 315679788450SSony Chacko adapter->ahw->diag_cnt++; 31572cc5752eSManish chopra qlcnic_enable_sds_intr(adapter, sds_ring); 3158aa43c215SJeff Kirsher return IRQ_HANDLED; 3159aa43c215SJeff Kirsher } 3160aa43c215SJeff Kirsher 3161aa43c215SJeff Kirsher static irqreturn_t qlcnic_intr(int irq, void *data) 3162aa43c215SJeff Kirsher { 3163aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring = data; 3164aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = sds_ring->adapter; 3165aa43c215SJeff Kirsher 3166aa43c215SJeff Kirsher if (qlcnic_clear_legacy_intr(adapter) == IRQ_NONE) 3167aa43c215SJeff Kirsher return IRQ_NONE; 3168aa43c215SJeff Kirsher 3169aa43c215SJeff Kirsher napi_schedule(&sds_ring->napi); 3170aa43c215SJeff Kirsher 3171aa43c215SJeff Kirsher return IRQ_HANDLED; 3172aa43c215SJeff Kirsher } 3173aa43c215SJeff Kirsher 3174aa43c215SJeff Kirsher static irqreturn_t qlcnic_msi_intr(int irq, void *data) 3175aa43c215SJeff Kirsher { 3176aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring = data; 3177aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = sds_ring->adapter; 3178aa43c215SJeff Kirsher 3179aa43c215SJeff Kirsher /* clear interrupt */ 3180aa43c215SJeff Kirsher writel(0xffffffff, adapter->tgt_status_reg); 3181aa43c215SJeff Kirsher 3182aa43c215SJeff Kirsher napi_schedule(&sds_ring->napi); 3183aa43c215SJeff Kirsher return IRQ_HANDLED; 3184aa43c215SJeff Kirsher } 3185aa43c215SJeff Kirsher 3186aa43c215SJeff Kirsher static irqreturn_t qlcnic_msix_intr(int irq, void *data) 3187aa43c215SJeff Kirsher { 3188aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring = data; 3189aa43c215SJeff Kirsher 3190aa43c215SJeff Kirsher napi_schedule(&sds_ring->napi); 3191aa43c215SJeff Kirsher return IRQ_HANDLED; 3192aa43c215SJeff Kirsher } 3193aa43c215SJeff Kirsher 319413159183SSony Chacko static irqreturn_t qlcnic_msix_tx_intr(int irq, void *data) 319513159183SSony Chacko { 319613159183SSony Chacko struct qlcnic_host_tx_ring *tx_ring = data; 319713159183SSony Chacko 319813159183SSony Chacko napi_schedule(&tx_ring->napi); 319913159183SSony Chacko return IRQ_HANDLED; 320013159183SSony Chacko } 320113159183SSony Chacko 3202aa43c215SJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 3203aa43c215SJeff Kirsher static void qlcnic_poll_controller(struct net_device *netdev) 3204aa43c215SJeff Kirsher { 3205aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 32062b018ad9SManish chopra struct qlcnic_host_sds_ring *sds_ring; 32072b018ad9SManish chopra struct qlcnic_recv_context *recv_ctx; 32082b018ad9SManish chopra struct qlcnic_host_tx_ring *tx_ring; 32092b018ad9SManish chopra int ring; 3210aa43c215SJeff Kirsher 32112b018ad9SManish chopra if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) 32122b018ad9SManish chopra return; 32132b018ad9SManish chopra 32142b018ad9SManish chopra recv_ctx = adapter->recv_ctx; 32152b018ad9SManish chopra 321634e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 3217aa43c215SJeff Kirsher sds_ring = &recv_ctx->sds_rings[ring]; 32182b018ad9SManish chopra qlcnic_disable_sds_intr(adapter, sds_ring); 32192b018ad9SManish chopra napi_schedule(&sds_ring->napi); 3220aa43c215SJeff Kirsher } 32212b018ad9SManish chopra 32222b018ad9SManish chopra if (adapter->flags & QLCNIC_MSIX_ENABLED) { 32232b018ad9SManish chopra /* Only Multi-Tx queue capable devices need to 32242b018ad9SManish chopra * schedule NAPI for TX rings 32252b018ad9SManish chopra */ 32262b018ad9SManish chopra if ((qlcnic_83xx_check(adapter) && 32272b018ad9SManish chopra (adapter->flags & QLCNIC_TX_INTR_SHARED)) || 32282b018ad9SManish chopra (qlcnic_82xx_check(adapter) && 32292b018ad9SManish chopra !qlcnic_check_multi_tx(adapter))) 32302b018ad9SManish chopra return; 32312b018ad9SManish chopra 32322b018ad9SManish chopra for (ring = 0; ring < adapter->drv_tx_rings; ring++) { 32332b018ad9SManish chopra tx_ring = &adapter->tx_ring[ring]; 32342b018ad9SManish chopra qlcnic_disable_tx_intr(adapter, tx_ring); 32352b018ad9SManish chopra napi_schedule(&tx_ring->napi); 32362b018ad9SManish chopra } 32372b018ad9SManish chopra } 3238aa43c215SJeff Kirsher } 3239aa43c215SJeff Kirsher #endif 3240aa43c215SJeff Kirsher 3241aa43c215SJeff Kirsher static void 3242aa43c215SJeff Kirsher qlcnic_idc_debug_info(struct qlcnic_adapter *adapter, u8 encoding) 3243aa43c215SJeff Kirsher { 3244aa43c215SJeff Kirsher u32 val; 3245aa43c215SJeff Kirsher 3246aa43c215SJeff Kirsher val = adapter->portnum & 0xf; 3247aa43c215SJeff Kirsher val |= encoding << 7; 3248aa43c215SJeff Kirsher val |= (jiffies - adapter->dev_rst_time) << 8; 3249aa43c215SJeff Kirsher 3250a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_SCRATCH, val); 3251aa43c215SJeff Kirsher adapter->dev_rst_time = jiffies; 3252aa43c215SJeff Kirsher } 3253aa43c215SJeff Kirsher 3254aa43c215SJeff Kirsher static int 3255aa43c215SJeff Kirsher qlcnic_set_drv_state(struct qlcnic_adapter *adapter, u8 state) 3256aa43c215SJeff Kirsher { 3257aa43c215SJeff Kirsher u32 val; 3258aa43c215SJeff Kirsher 3259aa43c215SJeff Kirsher WARN_ON(state != QLCNIC_DEV_NEED_RESET && 3260aa43c215SJeff Kirsher state != QLCNIC_DEV_NEED_QUISCENT); 3261aa43c215SJeff Kirsher 3262aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3263aa43c215SJeff Kirsher return -EIO; 3264aa43c215SJeff Kirsher 3265a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 3266aa43c215SJeff Kirsher 3267aa43c215SJeff Kirsher if (state == QLCNIC_DEV_NEED_RESET) 3268aa43c215SJeff Kirsher QLC_DEV_SET_RST_RDY(val, adapter->portnum); 3269aa43c215SJeff Kirsher else if (state == QLCNIC_DEV_NEED_QUISCENT) 3270aa43c215SJeff Kirsher QLC_DEV_SET_QSCNT_RDY(val, adapter->portnum); 3271aa43c215SJeff Kirsher 3272a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 3273aa43c215SJeff Kirsher 3274aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3275aa43c215SJeff Kirsher 3276aa43c215SJeff Kirsher return 0; 3277aa43c215SJeff Kirsher } 3278aa43c215SJeff Kirsher 3279aa43c215SJeff Kirsher static int 3280aa43c215SJeff Kirsher qlcnic_clr_drv_state(struct qlcnic_adapter *adapter) 3281aa43c215SJeff Kirsher { 3282aa43c215SJeff Kirsher u32 val; 3283aa43c215SJeff Kirsher 3284aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3285aa43c215SJeff Kirsher return -EBUSY; 3286aa43c215SJeff Kirsher 3287a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 3288aa43c215SJeff Kirsher QLC_DEV_CLR_RST_QSCNT(val, adapter->portnum); 3289a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 3290aa43c215SJeff Kirsher 3291aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3292aa43c215SJeff Kirsher 3293aa43c215SJeff Kirsher return 0; 3294aa43c215SJeff Kirsher } 3295aa43c215SJeff Kirsher 3296486a5bc7SRajesh Borundia void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed) 3297aa43c215SJeff Kirsher { 3298aa43c215SJeff Kirsher u32 val; 3299aa43c215SJeff Kirsher 3300aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3301aa43c215SJeff Kirsher goto err; 3302aa43c215SJeff Kirsher 3303a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_ACTIVE); 3304aa43c215SJeff Kirsher QLC_DEV_CLR_REF_CNT(val, adapter->portnum); 3305a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_ACTIVE, val); 3306aa43c215SJeff Kirsher 3307aa43c215SJeff Kirsher if (failed) { 3308a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 3309a15ebd37SHimanshu Madhani QLCNIC_DEV_FAILED); 3310aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, 3311aa43c215SJeff Kirsher "Device state set to Failed. Please Reboot\n"); 3312aa43c215SJeff Kirsher } else if (!(val & 0x11111111)) 3313a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 3314a15ebd37SHimanshu Madhani QLCNIC_DEV_COLD); 3315aa43c215SJeff Kirsher 3316a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 3317aa43c215SJeff Kirsher QLC_DEV_CLR_RST_QSCNT(val, adapter->portnum); 3318a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 3319aa43c215SJeff Kirsher 3320aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3321aa43c215SJeff Kirsher err: 3322aa43c215SJeff Kirsher adapter->fw_fail_cnt = 0; 3323aa43c215SJeff Kirsher adapter->flags &= ~QLCNIC_FW_HANG; 3324aa43c215SJeff Kirsher clear_bit(__QLCNIC_START_FW, &adapter->state); 3325aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 3326aa43c215SJeff Kirsher } 3327aa43c215SJeff Kirsher 3328aa43c215SJeff Kirsher /* Grab api lock, before checking state */ 3329aa43c215SJeff Kirsher static int 3330aa43c215SJeff Kirsher qlcnic_check_drv_state(struct qlcnic_adapter *adapter) 3331aa43c215SJeff Kirsher { 3332aa43c215SJeff Kirsher int act, state, active_mask; 3333a15ebd37SHimanshu Madhani struct qlcnic_hardware_context *ahw = adapter->ahw; 3334aa43c215SJeff Kirsher 3335a15ebd37SHimanshu Madhani state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 3336a15ebd37SHimanshu Madhani act = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_ACTIVE); 3337aa43c215SJeff Kirsher 3338aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_FW_RESET_OWNER) { 3339a15ebd37SHimanshu Madhani active_mask = (~(1 << (ahw->pci_func * 4))); 3340aa43c215SJeff Kirsher act = act & active_mask; 3341aa43c215SJeff Kirsher } 3342aa43c215SJeff Kirsher 3343aa43c215SJeff Kirsher if (((state & 0x11111111) == (act & 0x11111111)) || 3344aa43c215SJeff Kirsher ((act & 0x11111111) == ((state >> 1) & 0x11111111))) 3345aa43c215SJeff Kirsher return 0; 3346aa43c215SJeff Kirsher else 3347aa43c215SJeff Kirsher return 1; 3348aa43c215SJeff Kirsher } 3349aa43c215SJeff Kirsher 3350aa43c215SJeff Kirsher static int qlcnic_check_idc_ver(struct qlcnic_adapter *adapter) 3351aa43c215SJeff Kirsher { 3352a15ebd37SHimanshu Madhani u32 val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_IDC_VER); 3353aa43c215SJeff Kirsher 3354aa43c215SJeff Kirsher if (val != QLCNIC_DRV_IDC_VER) { 3355aa43c215SJeff Kirsher dev_warn(&adapter->pdev->dev, "IDC Version mismatch, driver's" 3356aa43c215SJeff Kirsher " idc ver = %x; reqd = %x\n", QLCNIC_DRV_IDC_VER, val); 3357aa43c215SJeff Kirsher } 3358aa43c215SJeff Kirsher 3359aa43c215SJeff Kirsher return 0; 3360aa43c215SJeff Kirsher } 3361aa43c215SJeff Kirsher 3362aa43c215SJeff Kirsher static int 3363aa43c215SJeff Kirsher qlcnic_can_start_firmware(struct qlcnic_adapter *adapter) 3364aa43c215SJeff Kirsher { 3365aa43c215SJeff Kirsher u32 val, prev_state; 3366aa43c215SJeff Kirsher u8 dev_init_timeo = adapter->dev_init_timeo; 3367aa43c215SJeff Kirsher u8 portnum = adapter->portnum; 3368aa43c215SJeff Kirsher u8 ret; 3369aa43c215SJeff Kirsher 3370aa43c215SJeff Kirsher if (test_and_clear_bit(__QLCNIC_START_FW, &adapter->state)) 3371aa43c215SJeff Kirsher return 1; 3372aa43c215SJeff Kirsher 3373aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3374aa43c215SJeff Kirsher return -1; 3375aa43c215SJeff Kirsher 3376a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_ACTIVE); 3377aa43c215SJeff Kirsher if (!(val & (1 << (portnum * 4)))) { 3378aa43c215SJeff Kirsher QLC_DEV_SET_REF_CNT(val, portnum); 3379a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_ACTIVE, val); 3380aa43c215SJeff Kirsher } 3381aa43c215SJeff Kirsher 3382a15ebd37SHimanshu Madhani prev_state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3383aa43c215SJeff Kirsher QLCDB(adapter, HW, "Device state = %u\n", prev_state); 3384aa43c215SJeff Kirsher 3385aa43c215SJeff Kirsher switch (prev_state) { 3386aa43c215SJeff Kirsher case QLCNIC_DEV_COLD: 3387a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 3388a15ebd37SHimanshu Madhani QLCNIC_DEV_INITIALIZING); 3389a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_IDC_VER, 3390a15ebd37SHimanshu Madhani QLCNIC_DRV_IDC_VER); 3391aa43c215SJeff Kirsher qlcnic_idc_debug_info(adapter, 0); 3392aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3393aa43c215SJeff Kirsher return 1; 3394aa43c215SJeff Kirsher 3395aa43c215SJeff Kirsher case QLCNIC_DEV_READY: 3396aa43c215SJeff Kirsher ret = qlcnic_check_idc_ver(adapter); 3397aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3398aa43c215SJeff Kirsher return ret; 3399aa43c215SJeff Kirsher 3400aa43c215SJeff Kirsher case QLCNIC_DEV_NEED_RESET: 3401a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 3402aa43c215SJeff Kirsher QLC_DEV_SET_RST_RDY(val, portnum); 3403a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 3404aa43c215SJeff Kirsher break; 3405aa43c215SJeff Kirsher 3406aa43c215SJeff Kirsher case QLCNIC_DEV_NEED_QUISCENT: 3407a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 3408aa43c215SJeff Kirsher QLC_DEV_SET_QSCNT_RDY(val, portnum); 3409a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 3410aa43c215SJeff Kirsher break; 3411aa43c215SJeff Kirsher 3412aa43c215SJeff Kirsher case QLCNIC_DEV_FAILED: 3413aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, "Device in failed state.\n"); 3414aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3415aa43c215SJeff Kirsher return -1; 3416aa43c215SJeff Kirsher 3417aa43c215SJeff Kirsher case QLCNIC_DEV_INITIALIZING: 3418aa43c215SJeff Kirsher case QLCNIC_DEV_QUISCENT: 3419aa43c215SJeff Kirsher break; 3420aa43c215SJeff Kirsher } 3421aa43c215SJeff Kirsher 3422aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3423aa43c215SJeff Kirsher 3424aa43c215SJeff Kirsher do { 3425aa43c215SJeff Kirsher msleep(1000); 3426a15ebd37SHimanshu Madhani prev_state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3427aa43c215SJeff Kirsher 3428aa43c215SJeff Kirsher if (prev_state == QLCNIC_DEV_QUISCENT) 3429aa43c215SJeff Kirsher continue; 3430aa43c215SJeff Kirsher } while ((prev_state != QLCNIC_DEV_READY) && --dev_init_timeo); 3431aa43c215SJeff Kirsher 3432aa43c215SJeff Kirsher if (!dev_init_timeo) { 3433aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, 3434aa43c215SJeff Kirsher "Waiting for device to initialize timeout\n"); 3435aa43c215SJeff Kirsher return -1; 3436aa43c215SJeff Kirsher } 3437aa43c215SJeff Kirsher 3438aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3439aa43c215SJeff Kirsher return -1; 3440aa43c215SJeff Kirsher 3441a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 3442aa43c215SJeff Kirsher QLC_DEV_CLR_RST_QSCNT(val, portnum); 3443a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 3444aa43c215SJeff Kirsher 3445aa43c215SJeff Kirsher ret = qlcnic_check_idc_ver(adapter); 3446aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3447aa43c215SJeff Kirsher 3448aa43c215SJeff Kirsher return ret; 3449aa43c215SJeff Kirsher } 3450aa43c215SJeff Kirsher 3451aa43c215SJeff Kirsher static void 3452aa43c215SJeff Kirsher qlcnic_fwinit_work(struct work_struct *work) 3453aa43c215SJeff Kirsher { 3454aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = container_of(work, 3455aa43c215SJeff Kirsher struct qlcnic_adapter, fw_work.work); 3456aa43c215SJeff Kirsher u32 dev_state = 0xf; 3457aa43c215SJeff Kirsher u32 val; 3458aa43c215SJeff Kirsher 3459aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3460aa43c215SJeff Kirsher goto err_ret; 3461aa43c215SJeff Kirsher 3462a15ebd37SHimanshu Madhani dev_state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3463aa43c215SJeff Kirsher if (dev_state == QLCNIC_DEV_QUISCENT || 3464aa43c215SJeff Kirsher dev_state == QLCNIC_DEV_NEED_QUISCENT) { 3465aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3466aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_fwinit_work, 3467aa43c215SJeff Kirsher FW_POLL_DELAY * 2); 3468aa43c215SJeff Kirsher return; 3469aa43c215SJeff Kirsher } 3470aa43c215SJeff Kirsher 347179788450SSony Chacko if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) { 3472aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3473aa43c215SJeff Kirsher goto wait_npar; 3474aa43c215SJeff Kirsher } 3475aa43c215SJeff Kirsher 347616e3cf73SSritej Velaga if (dev_state == QLCNIC_DEV_INITIALIZING || 347716e3cf73SSritej Velaga dev_state == QLCNIC_DEV_READY) { 347816e3cf73SSritej Velaga dev_info(&adapter->pdev->dev, "Detected state change from " 347916e3cf73SSritej Velaga "DEV_NEED_RESET, skipping ack check\n"); 348016e3cf73SSritej Velaga goto skip_ack_check; 348116e3cf73SSritej Velaga } 348216e3cf73SSritej Velaga 3483aa43c215SJeff Kirsher if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) { 348416e3cf73SSritej Velaga dev_info(&adapter->pdev->dev, "Reset:Failed to get ack %d sec\n", 3485aa43c215SJeff Kirsher adapter->reset_ack_timeo); 3486aa43c215SJeff Kirsher goto skip_ack_check; 3487aa43c215SJeff Kirsher } 3488aa43c215SJeff Kirsher 3489aa43c215SJeff Kirsher if (!qlcnic_check_drv_state(adapter)) { 3490aa43c215SJeff Kirsher skip_ack_check: 3491a15ebd37SHimanshu Madhani dev_state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3492aa43c215SJeff Kirsher 3493aa43c215SJeff Kirsher if (dev_state == QLCNIC_DEV_NEED_RESET) { 3494a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 3495aa43c215SJeff Kirsher QLCNIC_DEV_INITIALIZING); 3496aa43c215SJeff Kirsher set_bit(__QLCNIC_START_FW, &adapter->state); 3497aa43c215SJeff Kirsher QLCDB(adapter, DRV, "Restarting fw\n"); 3498aa43c215SJeff Kirsher qlcnic_idc_debug_info(adapter, 0); 3499a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, 3500a15ebd37SHimanshu Madhani QLCNIC_CRB_DRV_STATE); 3501aa43c215SJeff Kirsher QLC_DEV_SET_RST_RDY(val, adapter->portnum); 3502a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, 3503a15ebd37SHimanshu Madhani QLCNIC_CRB_DRV_STATE, val); 3504aa43c215SJeff Kirsher } 3505aa43c215SJeff Kirsher 3506aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3507aa43c215SJeff Kirsher 3508aa43c215SJeff Kirsher rtnl_lock(); 3509890b6e02SShahed Shaikh if (qlcnic_check_fw_dump_state(adapter) && 3510aa43c215SJeff Kirsher (adapter->flags & QLCNIC_FW_RESET_OWNER)) { 3511aa43c215SJeff Kirsher QLCDB(adapter, DRV, "Take FW dump\n"); 3512aa43c215SJeff Kirsher qlcnic_dump_fw(adapter); 3513aa43c215SJeff Kirsher adapter->flags |= QLCNIC_FW_HANG; 3514aa43c215SJeff Kirsher } 3515aa43c215SJeff Kirsher rtnl_unlock(); 3516aa43c215SJeff Kirsher 3517aa43c215SJeff Kirsher adapter->flags &= ~QLCNIC_FW_RESET_OWNER; 3518aa43c215SJeff Kirsher if (!adapter->nic_ops->start_firmware(adapter)) { 3519aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); 3520aa43c215SJeff Kirsher adapter->fw_wait_cnt = 0; 3521aa43c215SJeff Kirsher return; 3522aa43c215SJeff Kirsher } 3523aa43c215SJeff Kirsher goto err_ret; 3524aa43c215SJeff Kirsher } 3525aa43c215SJeff Kirsher 3526aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3527aa43c215SJeff Kirsher 3528aa43c215SJeff Kirsher wait_npar: 3529a15ebd37SHimanshu Madhani dev_state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3530aa43c215SJeff Kirsher QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state); 3531aa43c215SJeff Kirsher 3532aa43c215SJeff Kirsher switch (dev_state) { 3533aa43c215SJeff Kirsher case QLCNIC_DEV_READY: 35347e2cf4feSSony Chacko if (!qlcnic_start_firmware(adapter)) { 3535aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); 3536aa43c215SJeff Kirsher adapter->fw_wait_cnt = 0; 3537aa43c215SJeff Kirsher return; 3538aa43c215SJeff Kirsher } 3539aa43c215SJeff Kirsher case QLCNIC_DEV_FAILED: 3540aa43c215SJeff Kirsher break; 3541aa43c215SJeff Kirsher default: 3542aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, 3543aa43c215SJeff Kirsher qlcnic_fwinit_work, FW_POLL_DELAY); 3544aa43c215SJeff Kirsher return; 3545aa43c215SJeff Kirsher } 3546aa43c215SJeff Kirsher 3547aa43c215SJeff Kirsher err_ret: 3548aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, "Fwinit work failed state=%u " 3549aa43c215SJeff Kirsher "fw_wait_cnt=%u\n", dev_state, adapter->fw_wait_cnt); 3550aa43c215SJeff Kirsher netif_device_attach(adapter->netdev); 3551aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 0); 3552aa43c215SJeff Kirsher } 3553aa43c215SJeff Kirsher 3554aa43c215SJeff Kirsher static void 3555aa43c215SJeff Kirsher qlcnic_detach_work(struct work_struct *work) 3556aa43c215SJeff Kirsher { 3557aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = container_of(work, 3558aa43c215SJeff Kirsher struct qlcnic_adapter, fw_work.work); 3559aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 3560aa43c215SJeff Kirsher u32 status; 3561aa43c215SJeff Kirsher 3562aa43c215SJeff Kirsher netif_device_detach(netdev); 3563aa43c215SJeff Kirsher 3564aa43c215SJeff Kirsher /* Dont grab rtnl lock during Quiscent mode */ 3565aa43c215SJeff Kirsher if (adapter->dev_state == QLCNIC_DEV_NEED_QUISCENT) { 3566aa43c215SJeff Kirsher if (netif_running(netdev)) 3567aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 3568aa43c215SJeff Kirsher } else 3569aa43c215SJeff Kirsher qlcnic_down(adapter, netdev); 3570aa43c215SJeff Kirsher 3571a15ebd37SHimanshu Madhani status = QLC_SHARED_REG_RD32(adapter, QLCNIC_PEG_HALT_STATUS1); 3572aa43c215SJeff Kirsher 357344f65b29SSony Chacko if (status & QLCNIC_RCODE_FATAL_ERROR) { 357444f65b29SSony Chacko dev_err(&adapter->pdev->dev, 357544f65b29SSony Chacko "Detaching the device: peg halt status1=0x%x\n", 357644f65b29SSony Chacko status); 3577aa43c215SJeff Kirsher 357844f65b29SSony Chacko if (QLCNIC_FWERROR_CODE(status) == QLCNIC_FWERROR_FAN_FAILURE) { 357944f65b29SSony Chacko dev_err(&adapter->pdev->dev, 358044f65b29SSony Chacko "On board active cooling fan failed. " 358144f65b29SSony Chacko "Device has been halted.\n"); 358244f65b29SSony Chacko dev_err(&adapter->pdev->dev, 358344f65b29SSony Chacko "Replace the adapter.\n"); 358444f65b29SSony Chacko } 358544f65b29SSony Chacko 3586aa43c215SJeff Kirsher goto err_ret; 358744f65b29SSony Chacko } 358844f65b29SSony Chacko 358979788450SSony Chacko if (adapter->ahw->temp == QLCNIC_TEMP_PANIC) { 359044f65b29SSony Chacko dev_err(&adapter->pdev->dev, "Detaching the device: temp=%d\n", 359179788450SSony Chacko adapter->ahw->temp); 359244f65b29SSony Chacko goto err_ret; 359344f65b29SSony Chacko } 359444f65b29SSony Chacko 3595aa43c215SJeff Kirsher /* Dont ack if this instance is the reset owner */ 3596aa43c215SJeff Kirsher if (!(adapter->flags & QLCNIC_FW_RESET_OWNER)) { 359744f65b29SSony Chacko if (qlcnic_set_drv_state(adapter, adapter->dev_state)) { 359844f65b29SSony Chacko dev_err(&adapter->pdev->dev, 359944f65b29SSony Chacko "Failed to set driver state," 360044f65b29SSony Chacko "detaching the device.\n"); 3601aa43c215SJeff Kirsher goto err_ret; 3602aa43c215SJeff Kirsher } 360344f65b29SSony Chacko } 3604aa43c215SJeff Kirsher 3605aa43c215SJeff Kirsher adapter->fw_wait_cnt = 0; 3606aa43c215SJeff Kirsher 3607aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_fwinit_work, FW_POLL_DELAY); 3608aa43c215SJeff Kirsher 3609aa43c215SJeff Kirsher return; 3610aa43c215SJeff Kirsher 3611aa43c215SJeff Kirsher err_ret: 3612aa43c215SJeff Kirsher netif_device_attach(netdev); 3613aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 1); 3614aa43c215SJeff Kirsher } 3615aa43c215SJeff Kirsher 3616aa43c215SJeff Kirsher /*Transit NPAR state to NON Operational */ 3617aa43c215SJeff Kirsher static void 3618aa43c215SJeff Kirsher qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter) 3619aa43c215SJeff Kirsher { 3620aa43c215SJeff Kirsher u32 state; 3621aa43c215SJeff Kirsher 3622a15ebd37SHimanshu Madhani state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); 3623aa43c215SJeff Kirsher if (state == QLCNIC_DEV_NPAR_NON_OPER) 3624aa43c215SJeff Kirsher return; 3625aa43c215SJeff Kirsher 3626aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3627aa43c215SJeff Kirsher return; 3628a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, 3629a15ebd37SHimanshu Madhani QLCNIC_DEV_NPAR_NON_OPER); 3630aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3631aa43c215SJeff Kirsher } 3632aa43c215SJeff Kirsher 363321041400Sstephen hemminger static void qlcnic_82xx_dev_request_reset(struct qlcnic_adapter *adapter, 363421041400Sstephen hemminger u32 key) 3635aa43c215SJeff Kirsher { 3636646779f1SSritej Velaga u32 state, xg_val = 0, gb_val = 0; 3637aa43c215SJeff Kirsher 3638646779f1SSritej Velaga qlcnic_xg_set_xg0_mask(xg_val); 3639646779f1SSritej Velaga qlcnic_xg_set_xg1_mask(xg_val); 3640646779f1SSritej Velaga QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, xg_val); 3641646779f1SSritej Velaga qlcnic_gb_set_gb0_mask(gb_val); 3642646779f1SSritej Velaga qlcnic_gb_set_gb1_mask(gb_val); 3643646779f1SSritej Velaga qlcnic_gb_set_gb2_mask(gb_val); 3644646779f1SSritej Velaga qlcnic_gb_set_gb3_mask(gb_val); 3645646779f1SSritej Velaga QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, gb_val); 3646646779f1SSritej Velaga dev_info(&adapter->pdev->dev, "Pause control frames disabled" 3647646779f1SSritej Velaga " on all ports\n"); 3648aa43c215SJeff Kirsher adapter->need_fw_reset = 1; 364913159183SSony Chacko 3650aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3651aa43c215SJeff Kirsher return; 3652aa43c215SJeff Kirsher 365313159183SSony Chacko state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 365478ea2d97SSucheta Chakraborty 365578ea2d97SSucheta Chakraborty if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) { 365678ea2d97SSucheta Chakraborty netdev_err(adapter->netdev, "%s: Device is in non-operational state\n", 365766451615SSucheta Chakraborty __func__); 365866451615SSucheta Chakraborty qlcnic_api_unlock(adapter); 365966451615SSucheta Chakraborty 366066451615SSucheta Chakraborty return; 366166451615SSucheta Chakraborty } 3662aa43c215SJeff Kirsher 3663aa43c215SJeff Kirsher if (state == QLCNIC_DEV_READY) { 366413159183SSony Chacko QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 366513159183SSony Chacko QLCNIC_DEV_NEED_RESET); 3666aa43c215SJeff Kirsher adapter->flags |= QLCNIC_FW_RESET_OWNER; 3667aa43c215SJeff Kirsher QLCDB(adapter, DRV, "NEED_RESET state set\n"); 3668aa43c215SJeff Kirsher qlcnic_idc_debug_info(adapter, 0); 3669aa43c215SJeff Kirsher } 3670aa43c215SJeff Kirsher 367113159183SSony Chacko QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, 367213159183SSony Chacko QLCNIC_DEV_NPAR_NON_OPER); 3673aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3674aa43c215SJeff Kirsher } 3675aa43c215SJeff Kirsher 3676aa43c215SJeff Kirsher /* Transit to NPAR READY state from NPAR NOT READY state */ 3677aa43c215SJeff Kirsher static void 3678aa43c215SJeff Kirsher qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter) 3679aa43c215SJeff Kirsher { 3680aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3681aa43c215SJeff Kirsher return; 3682aa43c215SJeff Kirsher 3683a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, 3684a15ebd37SHimanshu Madhani QLCNIC_DEV_NPAR_OPER); 3685aa43c215SJeff Kirsher QLCDB(adapter, DRV, "NPAR operational state set\n"); 3686aa43c215SJeff Kirsher 3687aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3688aa43c215SJeff Kirsher } 3689aa43c215SJeff Kirsher 369013159183SSony Chacko void qlcnic_schedule_work(struct qlcnic_adapter *adapter, 3691aa43c215SJeff Kirsher work_func_t func, int delay) 3692aa43c215SJeff Kirsher { 3693aa43c215SJeff Kirsher if (test_bit(__QLCNIC_AER, &adapter->state)) 3694aa43c215SJeff Kirsher return; 3695aa43c215SJeff Kirsher 3696aa43c215SJeff Kirsher INIT_DELAYED_WORK(&adapter->fw_work, func); 369713159183SSony Chacko queue_delayed_work(adapter->qlcnic_wq, &adapter->fw_work, 3698aa43c215SJeff Kirsher round_jiffies_relative(delay)); 3699aa43c215SJeff Kirsher } 3700aa43c215SJeff Kirsher 3701aa43c215SJeff Kirsher static void 3702aa43c215SJeff Kirsher qlcnic_attach_work(struct work_struct *work) 3703aa43c215SJeff Kirsher { 3704aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = container_of(work, 3705aa43c215SJeff Kirsher struct qlcnic_adapter, fw_work.work); 3706aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 3707aa43c215SJeff Kirsher u32 npar_state; 3708aa43c215SJeff Kirsher 370979788450SSony Chacko if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) { 3710a15ebd37SHimanshu Madhani npar_state = QLC_SHARED_REG_RD32(adapter, 3711a15ebd37SHimanshu Madhani QLCNIC_CRB_DEV_NPAR_STATE); 3712aa43c215SJeff Kirsher if (adapter->fw_wait_cnt++ > QLCNIC_DEV_NPAR_OPER_TIMEO) 3713aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 0); 3714aa43c215SJeff Kirsher else if (npar_state != QLCNIC_DEV_NPAR_OPER) 3715aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_attach_work, 3716aa43c215SJeff Kirsher FW_POLL_DELAY); 3717aa43c215SJeff Kirsher else 3718aa43c215SJeff Kirsher goto attach; 3719aa43c215SJeff Kirsher QLCDB(adapter, DRV, "Waiting for NPAR state to operational\n"); 3720aa43c215SJeff Kirsher return; 3721aa43c215SJeff Kirsher } 3722aa43c215SJeff Kirsher attach: 37231de899d3SSucheta Chakraborty qlcnic_dcb_get_info(adapter->dcb); 372414d385b9SSucheta Chakraborty 3725aa43c215SJeff Kirsher if (netif_running(netdev)) { 3726aa43c215SJeff Kirsher if (qlcnic_up(adapter, netdev)) 3727aa43c215SJeff Kirsher goto done; 3728aa43c215SJeff Kirsher 3729aa43c215SJeff Kirsher qlcnic_restore_indev_addr(netdev, NETDEV_UP); 3730aa43c215SJeff Kirsher } 3731aa43c215SJeff Kirsher 3732aa43c215SJeff Kirsher done: 3733aa43c215SJeff Kirsher netif_device_attach(netdev); 3734aa43c215SJeff Kirsher adapter->fw_fail_cnt = 0; 3735aa43c215SJeff Kirsher adapter->flags &= ~QLCNIC_FW_HANG; 3736aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 373724866d15SHimanshu Madhani if (adapter->portnum == 0) 37388af3f33dSPratik Pujar qlcnic_set_drv_version(adapter); 3739aa43c215SJeff Kirsher 3740aa43c215SJeff Kirsher if (!qlcnic_clr_drv_state(adapter)) 3741aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, 3742aa43c215SJeff Kirsher FW_POLL_DELAY); 3743aa43c215SJeff Kirsher } 3744aa43c215SJeff Kirsher 3745aa43c215SJeff Kirsher static int 3746aa43c215SJeff Kirsher qlcnic_check_health(struct qlcnic_adapter *adapter) 3747aa43c215SJeff Kirsher { 3748891e71b1SPratik Pujar struct qlcnic_hardware_context *ahw = adapter->ahw; 3749891e71b1SPratik Pujar struct qlcnic_fw_dump *fw_dump = &ahw->fw_dump; 3750aa43c215SJeff Kirsher u32 state = 0, heartbeat; 3751853d4bcaSAmeen Rahman u32 peg_status; 37524bd8e738SHimanshu Madhani int err = 0; 3753aa43c215SJeff Kirsher 3754aa43c215SJeff Kirsher if (qlcnic_check_temp(adapter)) 3755aa43c215SJeff Kirsher goto detach; 3756aa43c215SJeff Kirsher 3757aa43c215SJeff Kirsher if (adapter->need_fw_reset) 37587e2cf4feSSony Chacko qlcnic_dev_request_reset(adapter, 0); 3759aa43c215SJeff Kirsher 3760a15ebd37SHimanshu Madhani state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3761aa43c215SJeff Kirsher if (state == QLCNIC_DEV_NEED_RESET) { 3762aa43c215SJeff Kirsher qlcnic_set_npar_non_operational(adapter); 3763aa43c215SJeff Kirsher adapter->need_fw_reset = 1; 3764aa43c215SJeff Kirsher } else if (state == QLCNIC_DEV_NEED_QUISCENT) 3765aa43c215SJeff Kirsher goto detach; 3766aa43c215SJeff Kirsher 3767a15ebd37SHimanshu Madhani heartbeat = QLC_SHARED_REG_RD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); 3768aa43c215SJeff Kirsher if (heartbeat != adapter->heartbeat) { 3769aa43c215SJeff Kirsher adapter->heartbeat = heartbeat; 3770aa43c215SJeff Kirsher adapter->fw_fail_cnt = 0; 3771aa43c215SJeff Kirsher if (adapter->need_fw_reset) 3772aa43c215SJeff Kirsher goto detach; 3773aa43c215SJeff Kirsher 3774891e71b1SPratik Pujar if (ahw->reset_context && qlcnic_auto_fw_reset) 3775aa43c215SJeff Kirsher qlcnic_reset_hw_context(adapter); 3776aa43c215SJeff Kirsher 3777aa43c215SJeff Kirsher return 0; 3778aa43c215SJeff Kirsher } 3779aa43c215SJeff Kirsher 3780aa43c215SJeff Kirsher if (++adapter->fw_fail_cnt < FW_FAIL_THRESH) 3781aa43c215SJeff Kirsher return 0; 3782aa43c215SJeff Kirsher 3783aa43c215SJeff Kirsher adapter->flags |= QLCNIC_FW_HANG; 3784aa43c215SJeff Kirsher 37857e2cf4feSSony Chacko qlcnic_dev_request_reset(adapter, 0); 3786aa43c215SJeff Kirsher 3787099f7aa7SSony Chacko if (qlcnic_auto_fw_reset) 3788aa43c215SJeff Kirsher clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state); 3789aa43c215SJeff Kirsher 3790853d4bcaSAmeen Rahman dev_err(&adapter->pdev->dev, "firmware hang detected\n"); 3791a15ebd37SHimanshu Madhani peg_status = QLC_SHARED_REG_RD32(adapter, QLCNIC_PEG_HALT_STATUS1); 3792853d4bcaSAmeen Rahman dev_err(&adapter->pdev->dev, "Dumping hw/fw registers\n" 3793aa43c215SJeff Kirsher "PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,\n" 3794aa43c215SJeff Kirsher "PEG_NET_0_PC: 0x%x, PEG_NET_1_PC: 0x%x,\n" 3795aa43c215SJeff Kirsher "PEG_NET_2_PC: 0x%x, PEG_NET_3_PC: 0x%x,\n" 3796aa43c215SJeff Kirsher "PEG_NET_4_PC: 0x%x\n", 3797a15ebd37SHimanshu Madhani peg_status, 3798a15ebd37SHimanshu Madhani QLC_SHARED_REG_RD32(adapter, QLCNIC_PEG_HALT_STATUS2), 37994bd8e738SHimanshu Madhani QLCRD32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x3c, &err), 38004bd8e738SHimanshu Madhani QLCRD32(adapter, QLCNIC_CRB_PEG_NET_1 + 0x3c, &err), 38014bd8e738SHimanshu Madhani QLCRD32(adapter, QLCNIC_CRB_PEG_NET_2 + 0x3c, &err), 38024bd8e738SHimanshu Madhani QLCRD32(adapter, QLCNIC_CRB_PEG_NET_3 + 0x3c, &err), 38034bd8e738SHimanshu Madhani QLCRD32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x3c, &err)); 380497048a1fSSritej Velaga if (QLCNIC_FWERROR_CODE(peg_status) == 0x67) 3805853d4bcaSAmeen Rahman dev_err(&adapter->pdev->dev, 3806853d4bcaSAmeen Rahman "Firmware aborted with error code 0x00006700. " 3807853d4bcaSAmeen Rahman "Device is being reset.\n"); 3808aa43c215SJeff Kirsher detach: 3809aa43c215SJeff Kirsher adapter->dev_state = (state == QLCNIC_DEV_NEED_QUISCENT) ? state : 3810aa43c215SJeff Kirsher QLCNIC_DEV_NEED_RESET; 3811aa43c215SJeff Kirsher 3812099f7aa7SSony Chacko if (qlcnic_auto_fw_reset && !test_and_set_bit(__QLCNIC_RESETTING, 3813099f7aa7SSony Chacko &adapter->state)) { 3814aa43c215SJeff Kirsher 3815aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_detach_work, 0); 3816aa43c215SJeff Kirsher QLCDB(adapter, DRV, "fw recovery scheduled.\n"); 3817891e71b1SPratik Pujar } else if (!qlcnic_auto_fw_reset && fw_dump->enable && 3818891e71b1SPratik Pujar adapter->flags & QLCNIC_FW_RESET_OWNER) { 3819891e71b1SPratik Pujar qlcnic_dump_fw(adapter); 3820aa43c215SJeff Kirsher } 3821aa43c215SJeff Kirsher 3822aa43c215SJeff Kirsher return 1; 3823aa43c215SJeff Kirsher } 3824aa43c215SJeff Kirsher 3825486a5bc7SRajesh Borundia void qlcnic_fw_poll_work(struct work_struct *work) 3826aa43c215SJeff Kirsher { 3827aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = container_of(work, 3828aa43c215SJeff Kirsher struct qlcnic_adapter, fw_work.work); 3829aa43c215SJeff Kirsher 3830aa43c215SJeff Kirsher if (test_bit(__QLCNIC_RESETTING, &adapter->state)) 3831aa43c215SJeff Kirsher goto reschedule; 3832aa43c215SJeff Kirsher 3833aa43c215SJeff Kirsher 3834aa43c215SJeff Kirsher if (qlcnic_check_health(adapter)) 3835aa43c215SJeff Kirsher return; 3836aa43c215SJeff Kirsher 3837aa43c215SJeff Kirsher if (adapter->fhash.fnum) 3838aa43c215SJeff Kirsher qlcnic_prune_lb_filters(adapter); 3839aa43c215SJeff Kirsher 3840aa43c215SJeff Kirsher reschedule: 3841aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY); 3842aa43c215SJeff Kirsher } 3843aa43c215SJeff Kirsher 3844aa43c215SJeff Kirsher static int qlcnic_is_first_func(struct pci_dev *pdev) 3845aa43c215SJeff Kirsher { 3846aa43c215SJeff Kirsher struct pci_dev *oth_pdev; 3847aa43c215SJeff Kirsher int val = pdev->devfn; 3848aa43c215SJeff Kirsher 3849aa43c215SJeff Kirsher while (val-- > 0) { 3850aa43c215SJeff Kirsher oth_pdev = pci_get_domain_bus_and_slot(pci_domain_nr 3851aa43c215SJeff Kirsher (pdev->bus), pdev->bus->number, 3852aa43c215SJeff Kirsher PCI_DEVFN(PCI_SLOT(pdev->devfn), val)); 3853aa43c215SJeff Kirsher if (!oth_pdev) 3854aa43c215SJeff Kirsher continue; 3855aa43c215SJeff Kirsher 3856aa43c215SJeff Kirsher if (oth_pdev->current_state != PCI_D3cold) { 3857aa43c215SJeff Kirsher pci_dev_put(oth_pdev); 3858aa43c215SJeff Kirsher return 0; 3859aa43c215SJeff Kirsher } 3860aa43c215SJeff Kirsher pci_dev_put(oth_pdev); 3861aa43c215SJeff Kirsher } 3862aa43c215SJeff Kirsher return 1; 3863aa43c215SJeff Kirsher } 3864aa43c215SJeff Kirsher 3865aa43c215SJeff Kirsher static int qlcnic_attach_func(struct pci_dev *pdev) 3866aa43c215SJeff Kirsher { 3867aa43c215SJeff Kirsher int err, first_func; 3868aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 3869aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 3870aa43c215SJeff Kirsher 3871aa43c215SJeff Kirsher pdev->error_state = pci_channel_io_normal; 3872aa43c215SJeff Kirsher 3873aa43c215SJeff Kirsher err = pci_enable_device(pdev); 3874aa43c215SJeff Kirsher if (err) 3875aa43c215SJeff Kirsher return err; 3876aa43c215SJeff Kirsher 3877aa43c215SJeff Kirsher pci_set_master(pdev); 3878aa43c215SJeff Kirsher pci_restore_state(pdev); 3879aa43c215SJeff Kirsher 3880aa43c215SJeff Kirsher first_func = qlcnic_is_first_func(pdev); 3881aa43c215SJeff Kirsher 3882aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3883aa43c215SJeff Kirsher return -EINVAL; 3884aa43c215SJeff Kirsher 388579788450SSony Chacko if (adapter->ahw->op_mode != QLCNIC_NON_PRIV_FUNC && first_func) { 3886aa43c215SJeff Kirsher adapter->need_fw_reset = 1; 3887aa43c215SJeff Kirsher set_bit(__QLCNIC_START_FW, &adapter->state); 3888a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 3889a15ebd37SHimanshu Madhani QLCNIC_DEV_INITIALIZING); 3890aa43c215SJeff Kirsher QLCDB(adapter, DRV, "Restarting fw\n"); 3891aa43c215SJeff Kirsher } 3892aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3893aa43c215SJeff Kirsher 389413159183SSony Chacko err = qlcnic_start_firmware(adapter); 3895aa43c215SJeff Kirsher if (err) 3896aa43c215SJeff Kirsher return err; 3897aa43c215SJeff Kirsher 3898aa43c215SJeff Kirsher qlcnic_clr_drv_state(adapter); 389913159183SSony Chacko kfree(adapter->msix_entries); 390013159183SSony Chacko adapter->msix_entries = NULL; 390134e8c406SHimanshu Madhani err = qlcnic_setup_intr(adapter); 390213159183SSony Chacko 39039a97e705SManish chopra if (err) { 39049a97e705SManish chopra kfree(adapter->msix_entries); 39059a97e705SManish chopra netdev_err(netdev, "failed to setup interrupt\n"); 39069a97e705SManish chopra return err; 39079a97e705SManish chopra } 39089a97e705SManish chopra 3909aa43c215SJeff Kirsher if (netif_running(netdev)) { 3910aa43c215SJeff Kirsher err = qlcnic_attach(adapter); 3911aa43c215SJeff Kirsher if (err) { 3912aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 1); 3913aa43c215SJeff Kirsher clear_bit(__QLCNIC_AER, &adapter->state); 3914aa43c215SJeff Kirsher netif_device_attach(netdev); 3915aa43c215SJeff Kirsher return err; 3916aa43c215SJeff Kirsher } 3917aa43c215SJeff Kirsher 3918aa43c215SJeff Kirsher err = qlcnic_up(adapter, netdev); 3919aa43c215SJeff Kirsher if (err) 3920aa43c215SJeff Kirsher goto done; 3921aa43c215SJeff Kirsher 3922aa43c215SJeff Kirsher qlcnic_restore_indev_addr(netdev, NETDEV_UP); 3923aa43c215SJeff Kirsher } 3924aa43c215SJeff Kirsher done: 3925aa43c215SJeff Kirsher netif_device_attach(netdev); 3926aa43c215SJeff Kirsher return err; 3927aa43c215SJeff Kirsher } 3928aa43c215SJeff Kirsher 392921041400Sstephen hemminger static pci_ers_result_t qlcnic_82xx_io_error_detected(struct pci_dev *pdev, 3930aa43c215SJeff Kirsher pci_channel_state_t state) 3931aa43c215SJeff Kirsher { 3932aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 3933aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 3934aa43c215SJeff Kirsher 3935aa43c215SJeff Kirsher if (state == pci_channel_io_perm_failure) 3936aa43c215SJeff Kirsher return PCI_ERS_RESULT_DISCONNECT; 3937aa43c215SJeff Kirsher 3938aa43c215SJeff Kirsher if (state == pci_channel_io_normal) 3939aa43c215SJeff Kirsher return PCI_ERS_RESULT_RECOVERED; 3940aa43c215SJeff Kirsher 3941aa43c215SJeff Kirsher set_bit(__QLCNIC_AER, &adapter->state); 3942aa43c215SJeff Kirsher netif_device_detach(netdev); 3943aa43c215SJeff Kirsher 3944aa43c215SJeff Kirsher cancel_delayed_work_sync(&adapter->fw_work); 3945aa43c215SJeff Kirsher 3946aa43c215SJeff Kirsher if (netif_running(netdev)) 3947aa43c215SJeff Kirsher qlcnic_down(adapter, netdev); 3948aa43c215SJeff Kirsher 3949aa43c215SJeff Kirsher qlcnic_detach(adapter); 3950aa43c215SJeff Kirsher qlcnic_teardown_intr(adapter); 3951aa43c215SJeff Kirsher 3952aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 3953aa43c215SJeff Kirsher 3954aa43c215SJeff Kirsher pci_save_state(pdev); 3955aa43c215SJeff Kirsher pci_disable_device(pdev); 3956aa43c215SJeff Kirsher 3957aa43c215SJeff Kirsher return PCI_ERS_RESULT_NEED_RESET; 3958aa43c215SJeff Kirsher } 3959aa43c215SJeff Kirsher 396021041400Sstephen hemminger static pci_ers_result_t qlcnic_82xx_io_slot_reset(struct pci_dev *pdev) 3961aa43c215SJeff Kirsher { 396250d65d78SHannes Frederic Sowa pci_ers_result_t res; 396350d65d78SHannes Frederic Sowa 396450d65d78SHannes Frederic Sowa rtnl_lock(); 396550d65d78SHannes Frederic Sowa res = qlcnic_attach_func(pdev) ? PCI_ERS_RESULT_DISCONNECT : 3966aa43c215SJeff Kirsher PCI_ERS_RESULT_RECOVERED; 396750d65d78SHannes Frederic Sowa rtnl_unlock(); 396850d65d78SHannes Frederic Sowa 396950d65d78SHannes Frederic Sowa return res; 3970aa43c215SJeff Kirsher } 3971aa43c215SJeff Kirsher 397221041400Sstephen hemminger static void qlcnic_82xx_io_resume(struct pci_dev *pdev) 3973aa43c215SJeff Kirsher { 3974a15ebd37SHimanshu Madhani u32 state; 3975aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 3976aa43c215SJeff Kirsher 3977aa43c215SJeff Kirsher pci_cleanup_aer_uncorrect_error_status(pdev); 3978a15ebd37SHimanshu Madhani state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3979a15ebd37SHimanshu Madhani if (state == QLCNIC_DEV_READY && test_and_clear_bit(__QLCNIC_AER, 3980a15ebd37SHimanshu Madhani &adapter->state)) 3981aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, 3982aa43c215SJeff Kirsher FW_POLL_DELAY); 3983aa43c215SJeff Kirsher } 3984aa43c215SJeff Kirsher 39854460f2e8SPratik Pujar static pci_ers_result_t qlcnic_io_error_detected(struct pci_dev *pdev, 39864460f2e8SPratik Pujar pci_channel_state_t state) 39874460f2e8SPratik Pujar { 39884460f2e8SPratik Pujar struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 39894460f2e8SPratik Pujar struct qlcnic_hardware_ops *hw_ops = adapter->ahw->hw_ops; 39904460f2e8SPratik Pujar 39914460f2e8SPratik Pujar if (hw_ops->io_error_detected) { 39924460f2e8SPratik Pujar return hw_ops->io_error_detected(pdev, state); 39934460f2e8SPratik Pujar } else { 39944460f2e8SPratik Pujar dev_err(&pdev->dev, "AER error_detected handler not registered.\n"); 39954460f2e8SPratik Pujar return PCI_ERS_RESULT_DISCONNECT; 39964460f2e8SPratik Pujar } 39974460f2e8SPratik Pujar } 39984460f2e8SPratik Pujar 39994460f2e8SPratik Pujar static pci_ers_result_t qlcnic_io_slot_reset(struct pci_dev *pdev) 40004460f2e8SPratik Pujar { 40014460f2e8SPratik Pujar struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 40024460f2e8SPratik Pujar struct qlcnic_hardware_ops *hw_ops = adapter->ahw->hw_ops; 40034460f2e8SPratik Pujar 40044460f2e8SPratik Pujar if (hw_ops->io_slot_reset) { 40054460f2e8SPratik Pujar return hw_ops->io_slot_reset(pdev); 40064460f2e8SPratik Pujar } else { 40074460f2e8SPratik Pujar dev_err(&pdev->dev, "AER slot_reset handler not registered.\n"); 40084460f2e8SPratik Pujar return PCI_ERS_RESULT_DISCONNECT; 40094460f2e8SPratik Pujar } 40104460f2e8SPratik Pujar } 40114460f2e8SPratik Pujar 40124460f2e8SPratik Pujar static void qlcnic_io_resume(struct pci_dev *pdev) 40134460f2e8SPratik Pujar { 40144460f2e8SPratik Pujar struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 40154460f2e8SPratik Pujar struct qlcnic_hardware_ops *hw_ops = adapter->ahw->hw_ops; 40164460f2e8SPratik Pujar 40174460f2e8SPratik Pujar if (hw_ops->io_resume) 40184460f2e8SPratik Pujar hw_ops->io_resume(pdev); 40194460f2e8SPratik Pujar else 40204460f2e8SPratik Pujar dev_err(&pdev->dev, "AER resume handler not registered.\n"); 40214460f2e8SPratik Pujar } 40224460f2e8SPratik Pujar 40234460f2e8SPratik Pujar 4024aa43c215SJeff Kirsher static int 4025aa43c215SJeff Kirsher qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) 4026aa43c215SJeff Kirsher { 4027aa43c215SJeff Kirsher int err; 4028aa43c215SJeff Kirsher 4029aa43c215SJeff Kirsher err = qlcnic_can_start_firmware(adapter); 4030aa43c215SJeff Kirsher if (err) 4031aa43c215SJeff Kirsher return err; 4032aa43c215SJeff Kirsher 4033aa43c215SJeff Kirsher err = qlcnic_check_npar_opertional(adapter); 4034aa43c215SJeff Kirsher if (err) 4035aa43c215SJeff Kirsher return err; 4036aa43c215SJeff Kirsher 4037aa43c215SJeff Kirsher err = qlcnic_initialize_nic(adapter); 4038aa43c215SJeff Kirsher if (err) 4039aa43c215SJeff Kirsher return err; 4040aa43c215SJeff Kirsher 4041aa43c215SJeff Kirsher qlcnic_check_options(adapter); 4042aa43c215SJeff Kirsher 4043aa43c215SJeff Kirsher err = qlcnic_set_eswitch_port_config(adapter); 4044aa43c215SJeff Kirsher if (err) 4045aa43c215SJeff Kirsher return err; 4046aa43c215SJeff Kirsher 4047aa43c215SJeff Kirsher adapter->need_fw_reset = 0; 4048aa43c215SJeff Kirsher 4049aa43c215SJeff Kirsher return err; 4050aa43c215SJeff Kirsher } 4051aa43c215SJeff Kirsher 405234e8c406SHimanshu Madhani int qlcnic_validate_rings(struct qlcnic_adapter *adapter, __u32 ring_cnt, 405334e8c406SHimanshu Madhani int queue_type) 4054aa4a1f7dSHimanshu Madhani { 4055aa4a1f7dSHimanshu Madhani struct net_device *netdev = adapter->netdev; 405634e8c406SHimanshu Madhani u8 max_hw_rings = 0; 405734e8c406SHimanshu Madhani char buf[8]; 405834e8c406SHimanshu Madhani int cur_rings; 405934e8c406SHimanshu Madhani 406034e8c406SHimanshu Madhani if (queue_type == QLCNIC_RX_QUEUE) { 406134e8c406SHimanshu Madhani max_hw_rings = adapter->max_sds_rings; 406234e8c406SHimanshu Madhani cur_rings = adapter->drv_sds_rings; 406334e8c406SHimanshu Madhani strcpy(buf, "SDS"); 406434e8c406SHimanshu Madhani } else if (queue_type == QLCNIC_TX_QUEUE) { 406534e8c406SHimanshu Madhani max_hw_rings = adapter->max_tx_rings; 406634e8c406SHimanshu Madhani cur_rings = adapter->drv_tx_rings; 406734e8c406SHimanshu Madhani strcpy(buf, "Tx"); 406834e8c406SHimanshu Madhani } 4069aa4a1f7dSHimanshu Madhani 407034e8c406SHimanshu Madhani if (!is_power_of_2(ring_cnt)) { 407134e8c406SHimanshu Madhani netdev_err(netdev, "%s rings value should be a power of 2\n", 407234e8c406SHimanshu Madhani buf); 407334e8c406SHimanshu Madhani return -EINVAL; 407434e8c406SHimanshu Madhani } 407534e8c406SHimanshu Madhani 407634e8c406SHimanshu Madhani if (qlcnic_82xx_check(adapter) && (queue_type == QLCNIC_TX_QUEUE) && 407734e8c406SHimanshu Madhani !qlcnic_check_multi_tx(adapter)) { 407834e8c406SHimanshu Madhani netdev_err(netdev, "No Multi Tx queue support\n"); 407934e8c406SHimanshu Madhani return -EINVAL; 408034e8c406SHimanshu Madhani } 408134e8c406SHimanshu Madhani 408234e8c406SHimanshu Madhani if (ring_cnt > num_online_cpus()) { 4083aa4a1f7dSHimanshu Madhani netdev_err(netdev, 408434e8c406SHimanshu Madhani "%s value[%u] should not be higher than, number of online CPUs\n", 408534e8c406SHimanshu Madhani buf, num_online_cpus()); 4086aa4a1f7dSHimanshu Madhani return -EINVAL; 4087aa4a1f7dSHimanshu Madhani } 4088aa4a1f7dSHimanshu Madhani 4089aa4a1f7dSHimanshu Madhani return 0; 4090aa4a1f7dSHimanshu Madhani } 4091aa4a1f7dSHimanshu Madhani 4092cb9327d5SHimanshu Madhani int qlcnic_setup_rings(struct qlcnic_adapter *adapter) 4093aa43c215SJeff Kirsher { 40946389b76dSManish Chopra struct net_device *netdev = adapter->netdev; 409584d7ad2cSShahed Shaikh u8 tx_rings, rx_rings; 409613159183SSony Chacko int err; 4097aa43c215SJeff Kirsher 4098319ecf12SSony Chacko if (test_bit(__QLCNIC_RESETTING, &adapter->state)) 4099319ecf12SSony Chacko return -EBUSY; 4100319ecf12SSony Chacko 410184d7ad2cSShahed Shaikh tx_rings = adapter->drv_tss_rings; 410284d7ad2cSShahed Shaikh rx_rings = adapter->drv_rss_rings; 410384d7ad2cSShahed Shaikh 4104aa43c215SJeff Kirsher netif_device_detach(netdev); 410584d7ad2cSShahed Shaikh 410684d7ad2cSShahed Shaikh err = qlcnic_set_real_num_queues(adapter, tx_rings, rx_rings); 410784d7ad2cSShahed Shaikh if (err) 410884d7ad2cSShahed Shaikh goto done; 410984d7ad2cSShahed Shaikh 4110aa43c215SJeff Kirsher if (netif_running(netdev)) 4111aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 411213159183SSony Chacko 4113aa43c215SJeff Kirsher qlcnic_detach(adapter); 41147dd90cf1SSucheta Chakraborty 41157ed3ce48SRajesh Borundia if (qlcnic_83xx_check(adapter)) { 41167dd90cf1SSucheta Chakraborty qlcnic_83xx_free_mbx_intr(adapter); 41177ed3ce48SRajesh Borundia qlcnic_83xx_enable_mbx_poll(adapter); 41187ed3ce48SRajesh Borundia } 41197dd90cf1SSucheta Chakraborty 4120aa43c215SJeff Kirsher qlcnic_teardown_intr(adapter); 4121aa4a1f7dSHimanshu Madhani 412234e8c406SHimanshu Madhani err = qlcnic_setup_intr(adapter); 41239a97e705SManish chopra if (err) { 41249a97e705SManish chopra kfree(adapter->msix_entries); 41259a97e705SManish chopra netdev_err(netdev, "failed to setup interrupt\n"); 41269a97e705SManish chopra return err; 41279a97e705SManish chopra } 4128aa43c215SJeff Kirsher 412984d7ad2cSShahed Shaikh /* Check if we need to update real_num_{tx|rx}_queues because 413084d7ad2cSShahed Shaikh * qlcnic_setup_intr() may change Tx/Rx rings size 413184d7ad2cSShahed Shaikh */ 413284d7ad2cSShahed Shaikh if ((tx_rings != adapter->drv_tx_rings) || 413384d7ad2cSShahed Shaikh (rx_rings != adapter->drv_sds_rings)) { 413484d7ad2cSShahed Shaikh err = qlcnic_set_real_num_queues(adapter, 413584d7ad2cSShahed Shaikh adapter->drv_tx_rings, 413684d7ad2cSShahed Shaikh adapter->drv_sds_rings); 413784d7ad2cSShahed Shaikh if (err) 413884d7ad2cSShahed Shaikh goto done; 413984d7ad2cSShahed Shaikh } 4140cb9327d5SHimanshu Madhani 414113159183SSony Chacko if (qlcnic_83xx_check(adapter)) { 41429b0fff2aSSucheta Chakraborty qlcnic_83xx_initialize_nic(adapter, 1); 414313159183SSony Chacko err = qlcnic_83xx_setup_mbx_intr(adapter); 41447ed3ce48SRajesh Borundia qlcnic_83xx_disable_mbx_poll(adapter); 414513159183SSony Chacko if (err) { 414613159183SSony Chacko dev_err(&adapter->pdev->dev, 414713159183SSony Chacko "failed to setup mbx interrupt\n"); 414813159183SSony Chacko goto done; 414913159183SSony Chacko } 4150aa43c215SJeff Kirsher } 4151aa43c215SJeff Kirsher 4152aa43c215SJeff Kirsher if (netif_running(netdev)) { 4153aa43c215SJeff Kirsher err = qlcnic_attach(adapter); 4154aa43c215SJeff Kirsher if (err) 4155aa43c215SJeff Kirsher goto done; 4156aa43c215SJeff Kirsher err = __qlcnic_up(adapter, netdev); 4157aa43c215SJeff Kirsher if (err) 4158aa43c215SJeff Kirsher goto done; 4159aa43c215SJeff Kirsher qlcnic_restore_indev_addr(netdev, NETDEV_UP); 4160aa43c215SJeff Kirsher } 4161aa43c215SJeff Kirsher done: 4162aa43c215SJeff Kirsher netif_device_attach(netdev); 4163aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 4164aa43c215SJeff Kirsher return err; 4165aa43c215SJeff Kirsher } 4166aa43c215SJeff Kirsher 4167aa43c215SJeff Kirsher #ifdef CONFIG_INET 4168aa43c215SJeff Kirsher 4169aa43c215SJeff Kirsher #define is_qlcnic_netdev(dev) (dev->netdev_ops == &qlcnic_netdev_ops) 4170aa43c215SJeff Kirsher 4171aa43c215SJeff Kirsher static void 4172aa43c215SJeff Kirsher qlcnic_config_indev_addr(struct qlcnic_adapter *adapter, 4173aa43c215SJeff Kirsher struct net_device *dev, unsigned long event) 4174aa43c215SJeff Kirsher { 4175aa43c215SJeff Kirsher struct in_device *indev; 4176aa43c215SJeff Kirsher 4177aa43c215SJeff Kirsher indev = in_dev_get(dev); 4178aa43c215SJeff Kirsher if (!indev) 4179aa43c215SJeff Kirsher return; 4180aa43c215SJeff Kirsher 4181aa43c215SJeff Kirsher for_ifa(indev) { 4182aa43c215SJeff Kirsher switch (event) { 4183aa43c215SJeff Kirsher case NETDEV_UP: 4184aa43c215SJeff Kirsher qlcnic_config_ipaddr(adapter, 4185aa43c215SJeff Kirsher ifa->ifa_address, QLCNIC_IP_UP); 4186aa43c215SJeff Kirsher break; 4187aa43c215SJeff Kirsher case NETDEV_DOWN: 4188aa43c215SJeff Kirsher qlcnic_config_ipaddr(adapter, 4189aa43c215SJeff Kirsher ifa->ifa_address, QLCNIC_IP_DOWN); 4190aa43c215SJeff Kirsher break; 4191aa43c215SJeff Kirsher default: 4192aa43c215SJeff Kirsher break; 4193aa43c215SJeff Kirsher } 4194aa43c215SJeff Kirsher } endfor_ifa(indev); 4195aa43c215SJeff Kirsher 4196aa43c215SJeff Kirsher in_dev_put(indev); 4197aa43c215SJeff Kirsher } 4198aa43c215SJeff Kirsher 4199319ecf12SSony Chacko void qlcnic_restore_indev_addr(struct net_device *netdev, unsigned long event) 4200aa43c215SJeff Kirsher { 4201aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 4202aa43c215SJeff Kirsher struct net_device *dev; 4203aa43c215SJeff Kirsher u16 vid; 4204aa43c215SJeff Kirsher 4205aa43c215SJeff Kirsher qlcnic_config_indev_addr(adapter, netdev, event); 4206aa43c215SJeff Kirsher 420743c00a75SJiri Pirko rcu_read_lock(); 4208aa43c215SJeff Kirsher for_each_set_bit(vid, adapter->vlans, VLAN_N_VID) { 4209f06c7f9fSdingtianhong dev = __vlan_find_dev_deep_rcu(netdev, htons(ETH_P_8021Q), vid); 4210aa43c215SJeff Kirsher if (!dev) 4211aa43c215SJeff Kirsher continue; 4212aa43c215SJeff Kirsher qlcnic_config_indev_addr(adapter, dev, event); 4213aa43c215SJeff Kirsher } 421443c00a75SJiri Pirko rcu_read_unlock(); 4215aa43c215SJeff Kirsher } 4216aa43c215SJeff Kirsher 4217aa43c215SJeff Kirsher static int qlcnic_netdev_event(struct notifier_block *this, 4218aa43c215SJeff Kirsher unsigned long event, void *ptr) 4219aa43c215SJeff Kirsher { 4220aa43c215SJeff Kirsher struct qlcnic_adapter *adapter; 4221351638e7SJiri Pirko struct net_device *dev = netdev_notifier_info_to_dev(ptr); 4222aa43c215SJeff Kirsher 4223aa43c215SJeff Kirsher recheck: 4224aa43c215SJeff Kirsher if (dev == NULL) 4225aa43c215SJeff Kirsher goto done; 4226aa43c215SJeff Kirsher 4227d0d7b10bSParav Pandit if (is_vlan_dev(dev)) { 4228aa43c215SJeff Kirsher dev = vlan_dev_real_dev(dev); 4229aa43c215SJeff Kirsher goto recheck; 4230aa43c215SJeff Kirsher } 4231aa43c215SJeff Kirsher 4232aa43c215SJeff Kirsher if (!is_qlcnic_netdev(dev)) 4233aa43c215SJeff Kirsher goto done; 4234aa43c215SJeff Kirsher 4235aa43c215SJeff Kirsher adapter = netdev_priv(dev); 4236aa43c215SJeff Kirsher 4237aa43c215SJeff Kirsher if (!adapter) 4238aa43c215SJeff Kirsher goto done; 4239aa43c215SJeff Kirsher 4240aa43c215SJeff Kirsher if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) 4241aa43c215SJeff Kirsher goto done; 4242aa43c215SJeff Kirsher 4243aa43c215SJeff Kirsher qlcnic_config_indev_addr(adapter, dev, event); 4244aa43c215SJeff Kirsher done: 4245aa43c215SJeff Kirsher return NOTIFY_DONE; 4246aa43c215SJeff Kirsher } 4247aa43c215SJeff Kirsher 4248aa43c215SJeff Kirsher static int 4249aa43c215SJeff Kirsher qlcnic_inetaddr_event(struct notifier_block *this, 4250aa43c215SJeff Kirsher unsigned long event, void *ptr) 4251aa43c215SJeff Kirsher { 4252aa43c215SJeff Kirsher struct qlcnic_adapter *adapter; 4253aa43c215SJeff Kirsher struct net_device *dev; 4254aa43c215SJeff Kirsher 4255aa43c215SJeff Kirsher struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; 4256aa43c215SJeff Kirsher 4257aa43c215SJeff Kirsher dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL; 4258aa43c215SJeff Kirsher 4259aa43c215SJeff Kirsher recheck: 4260aa43c215SJeff Kirsher if (dev == NULL) 4261aa43c215SJeff Kirsher goto done; 4262aa43c215SJeff Kirsher 4263d0d7b10bSParav Pandit if (is_vlan_dev(dev)) { 4264aa43c215SJeff Kirsher dev = vlan_dev_real_dev(dev); 4265aa43c215SJeff Kirsher goto recheck; 4266aa43c215SJeff Kirsher } 4267aa43c215SJeff Kirsher 4268aa43c215SJeff Kirsher if (!is_qlcnic_netdev(dev)) 4269aa43c215SJeff Kirsher goto done; 4270aa43c215SJeff Kirsher 4271aa43c215SJeff Kirsher adapter = netdev_priv(dev); 4272aa43c215SJeff Kirsher 4273aa43c215SJeff Kirsher if (!adapter) 4274aa43c215SJeff Kirsher goto done; 4275aa43c215SJeff Kirsher 4276aa43c215SJeff Kirsher if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) 4277aa43c215SJeff Kirsher goto done; 4278aa43c215SJeff Kirsher 4279aa43c215SJeff Kirsher switch (event) { 4280aa43c215SJeff Kirsher case NETDEV_UP: 4281aa43c215SJeff Kirsher qlcnic_config_ipaddr(adapter, ifa->ifa_address, QLCNIC_IP_UP); 428213159183SSony Chacko 4283aa43c215SJeff Kirsher break; 4284aa43c215SJeff Kirsher case NETDEV_DOWN: 4285aa43c215SJeff Kirsher qlcnic_config_ipaddr(adapter, ifa->ifa_address, QLCNIC_IP_DOWN); 428613159183SSony Chacko 4287aa43c215SJeff Kirsher break; 4288aa43c215SJeff Kirsher default: 4289aa43c215SJeff Kirsher break; 4290aa43c215SJeff Kirsher } 4291aa43c215SJeff Kirsher 4292aa43c215SJeff Kirsher done: 4293aa43c215SJeff Kirsher return NOTIFY_DONE; 4294aa43c215SJeff Kirsher } 4295aa43c215SJeff Kirsher 4296aa43c215SJeff Kirsher static struct notifier_block qlcnic_netdev_cb = { 4297aa43c215SJeff Kirsher .notifier_call = qlcnic_netdev_event, 4298aa43c215SJeff Kirsher }; 4299aa43c215SJeff Kirsher 4300aa43c215SJeff Kirsher static struct notifier_block qlcnic_inetaddr_cb = { 4301aa43c215SJeff Kirsher .notifier_call = qlcnic_inetaddr_event, 4302aa43c215SJeff Kirsher }; 4303aa43c215SJeff Kirsher #else 4304f8ca2b6fSSony Chacko void qlcnic_restore_indev_addr(struct net_device *dev, unsigned long event) 4305aa43c215SJeff Kirsher { } 4306aa43c215SJeff Kirsher #endif 4307fec9dd15SStephen Hemminger static const struct pci_error_handlers qlcnic_err_handler = { 4308aa43c215SJeff Kirsher .error_detected = qlcnic_io_error_detected, 4309aa43c215SJeff Kirsher .slot_reset = qlcnic_io_slot_reset, 4310aa43c215SJeff Kirsher .resume = qlcnic_io_resume, 4311aa43c215SJeff Kirsher }; 4312aa43c215SJeff Kirsher 4313aa43c215SJeff Kirsher static struct pci_driver qlcnic_driver = { 4314aa43c215SJeff Kirsher .name = qlcnic_driver_name, 4315aa43c215SJeff Kirsher .id_table = qlcnic_pci_tbl, 4316aa43c215SJeff Kirsher .probe = qlcnic_probe, 43176bb58bb0SBill Pemberton .remove = qlcnic_remove, 4318aa43c215SJeff Kirsher #ifdef CONFIG_PM 4319aa43c215SJeff Kirsher .suspend = qlcnic_suspend, 4320aa43c215SJeff Kirsher .resume = qlcnic_resume, 4321aa43c215SJeff Kirsher #endif 4322aa43c215SJeff Kirsher .shutdown = qlcnic_shutdown, 432302feda17SRajesh Borundia .err_handler = &qlcnic_err_handler, 432402feda17SRajesh Borundia #ifdef CONFIG_QLCNIC_SRIOV 432502feda17SRajesh Borundia .sriov_configure = qlcnic_pci_sriov_configure, 432602feda17SRajesh Borundia #endif 4327aa43c215SJeff Kirsher 4328aa43c215SJeff Kirsher }; 4329aa43c215SJeff Kirsher 4330aa43c215SJeff Kirsher static int __init qlcnic_init_module(void) 4331aa43c215SJeff Kirsher { 4332aa43c215SJeff Kirsher int ret; 4333aa43c215SJeff Kirsher 4334aa43c215SJeff Kirsher printk(KERN_INFO "%s\n", qlcnic_driver_string); 4335aa43c215SJeff Kirsher 4336aa43c215SJeff Kirsher #ifdef CONFIG_INET 4337aa43c215SJeff Kirsher register_netdevice_notifier(&qlcnic_netdev_cb); 4338aa43c215SJeff Kirsher register_inetaddr_notifier(&qlcnic_inetaddr_cb); 4339aa43c215SJeff Kirsher #endif 4340aa43c215SJeff Kirsher 4341aa43c215SJeff Kirsher ret = pci_register_driver(&qlcnic_driver); 4342aa43c215SJeff Kirsher if (ret) { 4343aa43c215SJeff Kirsher #ifdef CONFIG_INET 4344aa43c215SJeff Kirsher unregister_inetaddr_notifier(&qlcnic_inetaddr_cb); 4345aa43c215SJeff Kirsher unregister_netdevice_notifier(&qlcnic_netdev_cb); 4346aa43c215SJeff Kirsher #endif 4347aa43c215SJeff Kirsher } 4348aa43c215SJeff Kirsher 4349aa43c215SJeff Kirsher return ret; 4350aa43c215SJeff Kirsher } 4351aa43c215SJeff Kirsher 4352aa43c215SJeff Kirsher module_init(qlcnic_init_module); 4353aa43c215SJeff Kirsher 4354aa43c215SJeff Kirsher static void __exit qlcnic_exit_module(void) 4355aa43c215SJeff Kirsher { 4356aa43c215SJeff Kirsher pci_unregister_driver(&qlcnic_driver); 4357aa43c215SJeff Kirsher 4358aa43c215SJeff Kirsher #ifdef CONFIG_INET 4359aa43c215SJeff Kirsher unregister_inetaddr_notifier(&qlcnic_inetaddr_cb); 4360aa43c215SJeff Kirsher unregister_netdevice_notifier(&qlcnic_netdev_cb); 4361aa43c215SJeff Kirsher #endif 4362aa43c215SJeff Kirsher } 4363aa43c215SJeff Kirsher 4364aa43c215SJeff Kirsher module_exit(qlcnic_exit_module); 4365